|
|
|
|
|
|
|
*/ |
|
/** |
|
* Licensed to the Apache Software Foundation (ASF) under one |
|
* or more contributor license agreements. See the NOTICE file |
|
* distributed with this work for additional information |
|
* regarding copyright ownership. The ASF licenses this file |
|
* to you under the Apache License, Version 2.0 (the |
|
* "License"); you may not use this file except in compliance |
|
* with the License. You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, |
|
* software distributed under the License is distributed on an |
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
* KIND, either express or implied. See the License for the |
|
* specific language governing permissions and limitations |
|
* under the License. |
|
*/ |
|
/* |
|
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. |
|
*/ |
|
|
|
|
|
*/ |
|
package org.jcp.xml.dsig.internal.dom; |
|
|
|
import java.util.*; |
|
|
|
import javax.xml.crypto.*; |
|
import javax.xml.crypto.dsig.XMLSignature; |
|
import javax.xml.crypto.dsig.keyinfo.PGPData; |
|
|
|
import org.w3c.dom.Element; |
|
import org.w3c.dom.Node; |
|
|
|
import com.sun.org.apache.xml.internal.security.utils.XMLUtils; |
|
|
|
|
|
|
|
|
|
*/ |
|
public final class DOMPGPData extends BaseStructure implements PGPData { |
|
|
|
private final byte[] keyId; |
|
private final byte[] keyPacket; |
|
private final List<XMLStructure> externalElements; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public DOMPGPData(byte[] keyPacket, List<? extends XMLStructure> other) { |
|
if (keyPacket == null) { |
|
throw new NullPointerException("keyPacket cannot be null"); |
|
} |
|
if (other == null || other.isEmpty()) { |
|
this.externalElements = Collections.emptyList(); |
|
} else { |
|
this.externalElements = |
|
Collections.unmodifiableList(new ArrayList<>(other)); |
|
for (int i = 0, size = this.externalElements.size(); i < size; i++) { |
|
if (!(this.externalElements.get(i) instanceof XMLStructure)) { |
|
throw new ClassCastException |
|
("other["+i+"] is not a valid PGPData type"); |
|
} |
|
} |
|
} |
|
this.keyPacket = keyPacket.clone(); |
|
checkKeyPacket(keyPacket); |
|
this.keyId = null; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public DOMPGPData(byte[] keyId, byte[] keyPacket, |
|
List<? extends XMLStructure> other) |
|
{ |
|
if (keyId == null) { |
|
throw new NullPointerException("keyId cannot be null"); |
|
} |
|
|
|
if (keyId.length != 8) { |
|
throw new IllegalArgumentException("keyId must be 8 bytes long"); |
|
} |
|
if (other == null || other.isEmpty()) { |
|
this.externalElements = Collections.emptyList(); |
|
} else { |
|
this.externalElements = |
|
Collections.unmodifiableList(new ArrayList<>(other)); |
|
for (int i = 0, size = this.externalElements.size(); i < size; i++) { |
|
if (!(this.externalElements.get(i) instanceof XMLStructure)) { |
|
throw new ClassCastException |
|
("other["+i+"] is not a valid PGPData type"); |
|
} |
|
} |
|
} |
|
this.keyId = keyId.clone(); |
|
this.keyPacket = keyPacket == null ? null |
|
: keyPacket.clone(); |
|
if (keyPacket != null) { |
|
checkKeyPacket(keyPacket); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public DOMPGPData(Element pdElem) throws MarshalException { |
|
|
|
byte[] pgpKeyId = null; |
|
byte[] pgpKeyPacket = null; |
|
|
|
List<XMLStructure> other = new ArrayList<>(); |
|
Node firstChild = pdElem.getFirstChild(); |
|
while (firstChild != null) { |
|
if (firstChild.getNodeType() == Node.ELEMENT_NODE) { |
|
Element childElem = (Element)firstChild; |
|
String localName = childElem.getLocalName(); |
|
String namespace = childElem.getNamespaceURI(); |
|
if ("PGPKeyID".equals(localName) && XMLSignature.XMLNS.equals(namespace)) { |
|
String content = XMLUtils.getFullTextChildrenFromElement(childElem); |
|
pgpKeyId = Base64.getMimeDecoder().decode(content); |
|
} else if ("PGPKeyPacket".equals(localName) && XMLSignature.XMLNS.equals(namespace)) { |
|
String content = XMLUtils.getFullTextChildrenFromElement(childElem); |
|
pgpKeyPacket = Base64.getMimeDecoder().decode(content); |
|
} else { |
|
other.add |
|
(new javax.xml.crypto.dom.DOMStructure(childElem)); |
|
} |
|
} |
|
firstChild = firstChild.getNextSibling(); |
|
} |
|
this.keyId = pgpKeyId; |
|
this.keyPacket = pgpKeyPacket; |
|
this.externalElements = Collections.unmodifiableList(other); |
|
} |
|
|
|
@Override |
|
public byte[] getKeyId() { |
|
return keyId == null ? null : keyId.clone(); |
|
} |
|
|
|
@Override |
|
public byte[] getKeyPacket() { |
|
return keyPacket == null ? null : keyPacket.clone(); |
|
} |
|
|
|
@Override |
|
public List<XMLStructure> getExternalElements() { |
|
return externalElements; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private void checkKeyPacket(byte[] keyPacket) { |
|
// length must be at least 3 (one byte for tag, one byte for length, |
|
|
|
if (keyPacket.length < 3) { |
|
throw new IllegalArgumentException("keypacket must be at least " + |
|
"3 bytes long"); |
|
} |
|
|
|
int tag = keyPacket[0]; |
|
|
|
if ((tag & 128) != 128) { |
|
throw new IllegalArgumentException("keypacket tag is invalid: " + |
|
"bit 7 is not set"); |
|
} |
|
|
|
if ((tag & 64) != 64) { |
|
throw new IllegalArgumentException("old keypacket tag format is " + |
|
"unsupported"); |
|
} |
|
|
|
|
|
if ((tag & 6) != 6 && (tag & 14) != 14 && |
|
(tag & 5) != 5 && (tag & 7) != 7) { |
|
throw new IllegalArgumentException("keypacket tag is invalid: " + |
|
"must be 6, 14, 5, or 7"); |
|
} |
|
} |
|
} |