8217878: ENVELOPING XML signature no longer works in JDK 11

8218629: XML Digital Signature throws NAMESPACE_ERR exception on OpenJDK 11, works 8/9/10

Backout and restore previous XML signature marshalling implementation

Reviewed-by: weijun
This commit is contained in:
Sean Mullan 2019-03-05 08:24:58 -05:00
parent 321d7d386a
commit 9d9edee86e
44 changed files with 913 additions and 1241 deletions

View File

@ -148,7 +148,8 @@ public class Base64 {
* @return String with Base64 encoding
*/
public static final String encode(BigInteger big) {
return encode(getBytes(big, big.bitLength()));
byte[] bytes = XMLUtils.getBytes(big, big.bitLength());
return XMLUtils.encodeToString(bytes);
}
/**
@ -214,9 +215,9 @@ public class Base64 {
* @return a decoded BigInteger
* @throws Base64DecodingException
*/
public static BigInteger decodeBigIntegerFromString(String base64str)
throws Base64DecodingException {
return new BigInteger(1, Base64.decode(base64str));
public static final BigInteger decodeBigIntegerFromText(Text text)
throws Base64DecodingException {
return new BigInteger(1, Base64.decode(text.getData()));
}
/**

View File

@ -28,6 +28,7 @@ import java.math.BigInteger;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@ -443,6 +444,25 @@ public final class XMLUtils {
}
}
public static String encodeToString(byte[] bytes) {
if (ignoreLineBreaks) {
return Base64.getEncoder().encodeToString(bytes);
}
return Base64.getMimeEncoder().encodeToString(bytes);
}
public static byte[] decode(String encodedString) {
return Base64.getMimeDecoder().decode(encodedString);
}
public static byte[] decode(byte[] encodedBytes) {
return Base64.getMimeDecoder().decode(encodedBytes);
}
public static boolean isIgnoreLineBreaks() {
return ignoreLineBreaks;
}
/**
* Method convertNodelistToSet
*

View File

@ -29,19 +29,23 @@ import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.security.spec.AlgorithmParameterSpec;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignContext;
import javax.xml.crypto.dsig.XMLValidateContext;
import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* An abstract class representing a SignatureMethod. Subclasses implement
* a specific XML DSig signature algorithm.
*/
abstract class AbstractDOMSignatureMethod extends BaseStructure
abstract class AbstractDOMSignatureMethod extends DOMStructure
implements SignatureMethod {
// denotes the type of signature algorithm
@ -65,7 +69,7 @@ abstract class AbstractDOMSignatureMethod extends BaseStructure
* as the passed in signature is improperly encoded
* @throws XMLSignatureException if an unexpected error occurs
*/
abstract boolean verify(Key key, DOMSignedInfo si, byte[] sig,
abstract boolean verify(Key key, SignedInfo si, byte[] sig,
XMLValidateContext context)
throws InvalidKeyException, SignatureException, XMLSignatureException;
@ -83,7 +87,7 @@ abstract class AbstractDOMSignatureMethod extends BaseStructure
* the wrong type, or parameters are missing, etc
* @throws XMLSignatureException if an unexpected error occurs
*/
abstract byte[] sign(Key key, DOMSignedInfo si, XMLSignContext context)
abstract byte[] sign(Key key, SignedInfo si, XMLSignContext context)
throws InvalidKeyException, XMLSignatureException;
/**
@ -101,16 +105,21 @@ abstract class AbstractDOMSignatureMethod extends BaseStructure
* This method invokes the {@link #marshalParams marshalParams}
* method to marshal any algorithm-specific parameters.
*/
public void marshal(XmlWriter xwriter, String dsPrefix)
@Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
xwriter.writeStartElement(dsPrefix, "SignatureMethod", XMLSignature.XMLNS);
xwriter.writeAttribute("", "", "Algorithm", getAlgorithm());
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element smElem = DOMUtils.createElement(ownerDoc, "SignatureMethod",
XMLSignature.XMLNS, dsPrefix);
DOMUtils.setAttribute(smElem, "Algorithm", getAlgorithm());
if (getParameterSpec() != null) {
marshalParams(xwriter, dsPrefix);
marshalParams(smElem, dsPrefix);
}
xwriter.writeEndElement(); // "SignatureMethod"
parent.appendChild(smElem);
}
/**
@ -123,7 +132,7 @@ abstract class AbstractDOMSignatureMethod extends BaseStructure
* @param paramsPrefix the algorithm parameters prefix to use
* @throws MarshalException if the parameters cannot be marshalled
*/
void marshalParams(XmlWriter xwriter, String paramsPrefix)
void marshalParams(Element parent, String paramsPrefix)
throws MarshalException
{
throw new MarshalException("no parameters should " +

View File

@ -69,7 +69,6 @@ public abstract class ApacheCanonicalizer extends TransformService {
return params;
}
@Override
public void init(XMLStructure parent, XMLCryptoContext context)
throws InvalidAlgorithmParameterException
{
@ -88,7 +87,6 @@ public abstract class ApacheCanonicalizer extends TransformService {
ownerDoc = DOMUtils.getOwnerDocument(transformElem);
}
@Override
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
throws MarshalException
{

View File

@ -45,7 +45,6 @@ public class ApacheOctetStreamData extends OctetStreamData
this.xi = xi;
}
@Override
public XMLSignatureInput getXMLSignatureInput() {
return xi;
}

View File

@ -67,7 +67,6 @@ public abstract class ApacheTransform extends TransformService {
return params;
}
@Override
public void init(XMLStructure parent, XMLCryptoContext context)
throws InvalidAlgorithmParameterException
{
@ -86,7 +85,6 @@ public abstract class ApacheTransform extends TransformService {
ownerDoc = DOMUtils.getOwnerDocument(transformElem);
}
@Override
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
throws MarshalException
{
@ -105,7 +103,6 @@ public abstract class ApacheTransform extends TransformService {
ownerDoc = DOMUtils.getOwnerDocument(transformElem);
}
@Override
public Data transform(Data data, XMLCryptoContext xc)
throws TransformException
{
@ -115,7 +112,6 @@ public abstract class ApacheTransform extends TransformService {
return transformIt(data, xc, null);
}
@Override
public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
throws TransformException
{
@ -206,7 +202,6 @@ public abstract class ApacheTransform extends TransformService {
}
}
@Override
public final boolean isFeatureSupported(String feature) {
if (feature == null) {
throw new NullPointerException();

View File

@ -1,49 +0,0 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/**
* 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.
*/
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.XMLStructure;
import org.w3c.dom.Node;
public abstract class BaseStructure implements XMLStructure {
/**
* Just return the text of the immediate child of a node.
*
* @param node
* @return the text of a Node
*/
public static String textOfNode(Node node) {
return node.getFirstChild().getNodeValue();
}
public final boolean isFeatureSupported(String feature) {
if (feature == null) {
throw new NullPointerException();
} else {
return false;
}
}
}

View File

@ -48,7 +48,6 @@ public final class DOMCanonicalXMLC14N11Method extends ApacheCanonicalizer {
public static final String C14N_11_WITH_COMMENTS
= "http://www.w3.org/2006/12/xml-c14n11#WithComments";
@Override
public void init(TransformParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {
@ -57,7 +56,6 @@ public final class DOMCanonicalXMLC14N11Method extends ApacheCanonicalizer {
}
}
@Override
public Data transform(Data data, XMLCryptoContext xc)
throws TransformException {

View File

@ -44,7 +44,6 @@ import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerExcepti
*/
public final class DOMCanonicalXMLC14NMethod extends ApacheCanonicalizer {
@Override
public void init(TransformParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {
@ -53,7 +52,6 @@ public final class DOMCanonicalXMLC14NMethod extends ApacheCanonicalizer {
}
}
@Override
public Data transform(Data data, XMLCryptoContext xc)
throws TransformException {

View File

@ -0,0 +1,101 @@
/**
* 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 2005 Sun Microsystems, Inc. All rights reserved.
*/
/*
* $Id$
*/
package org.jcp.xml.dsig.internal.dom;
import java.math.BigInteger;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
/**
* A DOM-based representation of the XML <code>CryptoBinary</code> simple type
* as defined in the W3C specification for XML-Signature Syntax and Processing.
* The XML Schema Definition is defined as:
*
* <xmp>
* <simpleType name="CryptoBinary">
* <restriction base = "base64Binary">
* </restriction>
* </simpleType>
* </xmp>
*
* @author Sean Mullan
*/
public final class DOMCryptoBinary extends DOMStructure {
private final BigInteger bigNum;
private final String value;
/**
* Create a <code>DOMCryptoBinary</code> instance from the specified
* <code>BigInteger</code>
*
* @param bigNum the arbitrary-length integer
* @throws NullPointerException if <code>bigNum</code> is <code>null</code>
*/
public DOMCryptoBinary(BigInteger bigNum) {
if (bigNum == null) {
throw new NullPointerException("bigNum is null");
}
this.bigNum = bigNum;
// convert to bitstring
byte[] bytes = XMLUtils.getBytes(bigNum, bigNum.bitLength());
value = XMLUtils.encodeToString(bytes);
}
/**
* Creates a <code>DOMCryptoBinary</code> from a node.
*
* @param cbNode a CryptoBinary text node
* @throws MarshalException if value cannot be decoded (invalid format)
*/
public DOMCryptoBinary(Node cbNode) throws MarshalException {
value = cbNode.getNodeValue();
try {
bigNum = new BigInteger(1, XMLUtils.decode(((Text) cbNode).getData()));
} catch (Exception ex) {
throw new MarshalException(ex);
}
}
/**
* Returns the <code>BigInteger</code> that this object contains.
*
* @return the <code>BigInteger</code> that this object contains
*/
public BigInteger getBigNum() {
return bigNum;
}
@Override
public void marshal(Node parent, String prefix, DOMCryptoContext context)
throws MarshalException {
parent.appendChild
(DOMUtils.getOwnerDocument(parent).createTextNode(value));
}
}

View File

@ -29,18 +29,21 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.spec.AlgorithmParameterSpec;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* DOM-based abstract implementation of DigestMethod.
*
*/
public abstract class DOMDigestMethod extends BaseStructure
public abstract class DOMDigestMethod extends DOMStructure
implements DigestMethod {
static final String SHA224 =
@ -147,7 +150,6 @@ public abstract class DOMDigestMethod extends BaseStructure
}
}
@Override
public final AlgorithmParameterSpec getParameterSpec() {
return params;
}
@ -175,17 +177,21 @@ public abstract class DOMDigestMethod extends BaseStructure
* This method invokes the abstract {@link #marshalParams marshalParams}
* method to marshal any algorithm-specific parameters.
*/
public static void marshal(XmlWriter xwriter, DigestMethod digest, String prefix)
@Override
public void marshal(Node parent, String prefix, DOMCryptoContext context)
throws MarshalException
{
xwriter.writeStartElement(prefix, "DigestMethod", XMLSignature.XMLNS);
xwriter.writeAttribute("", "", "Algorithm", digest.getAlgorithm());
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
// this is totally over-engineered - nothing implements marshalParams.
if (digest.getParameterSpec() != null && digest instanceof DOMDigestMethod) {
( (DOMDigestMethod) digest).marshalParams(xwriter, prefix);
Element dmElem = DOMUtils.createElement(ownerDoc, "DigestMethod",
XMLSignature.XMLNS, prefix);
DOMUtils.setAttribute(dmElem, "Algorithm", getAlgorithm());
if (params != null) {
marshalParams(dmElem, prefix);
}
xwriter.writeEndElement(); // "DigestMethod"
parent.appendChild(dmElem);
}
@Override
@ -226,7 +232,7 @@ public abstract class DOMDigestMethod extends BaseStructure
* @param the namespace prefix to use
* @throws MarshalException if the parameters cannot be marshalled
*/
void marshalParams(XmlWriter xwriter, String prefix)
void marshalParams(Element parent, String prefix)
throws MarshalException
{
throw new MarshalException("no parameters should " +
@ -248,11 +254,9 @@ public abstract class DOMDigestMethod extends BaseStructure
SHA1(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return DigestMethod.SHA1;
}
@Override
String getMessageDigestAlgorithm() {
return "SHA-1";
}
@ -284,11 +288,9 @@ public abstract class DOMDigestMethod extends BaseStructure
SHA256(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return DigestMethod.SHA256;
}
@Override
String getMessageDigestAlgorithm() {
return "SHA-256";
}
@ -302,11 +304,9 @@ public abstract class DOMDigestMethod extends BaseStructure
SHA384(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return SHA384;
}
@Override
String getMessageDigestAlgorithm() {
return "SHA-384";
}
@ -320,11 +320,9 @@ public abstract class DOMDigestMethod extends BaseStructure
SHA512(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return DigestMethod.SHA512;
}
@Override
String getMessageDigestAlgorithm() {
return "SHA-512";
}

View File

@ -38,7 +38,6 @@ import javax.xml.crypto.dsig.spec.TransformParameterSpec;
*/
public final class DOMEnvelopedTransform extends ApacheTransform {
@Override
public void init(TransformParameterSpec params)
throws InvalidAlgorithmParameterException {
if (params != null) {

View File

@ -50,7 +50,6 @@ import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerExcepti
*/
public final class DOMExcC14NMethod extends ApacheCanonicalizer {
@Override
public void init(TransformParameterSpec params)
throws InvalidAlgorithmParameterException
{
@ -63,7 +62,6 @@ public final class DOMExcC14NMethod extends ApacheCanonicalizer {
}
}
@Override
public void init(XMLStructure parent, XMLCryptoContext context)
throws InvalidAlgorithmParameterException
{
@ -109,12 +107,20 @@ public final class DOMExcC14NMethod extends ApacheCanonicalizer {
return;
}
XmlWriterToTree xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), transformElem);
String prefix =
DOMUtils.getNSPrefix(context, CanonicalizationMethod.EXCLUSIVE);
xwriter.writeStartElement(prefix, "InclusiveNamespaces", CanonicalizationMethod.EXCLUSIVE);
xwriter.writeNamespace(prefix, CanonicalizationMethod.EXCLUSIVE);
String prefix = DOMUtils.getNSPrefix(context,
CanonicalizationMethod.EXCLUSIVE);
Element eElem = DOMUtils.createElement(ownerDoc,
"InclusiveNamespaces",
CanonicalizationMethod.EXCLUSIVE,
prefix);
if (prefix == null || prefix.length() == 0) {
eElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
CanonicalizationMethod.EXCLUSIVE);
} else {
eElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns:" + prefix,
CanonicalizationMethod.EXCLUSIVE);
}
ExcC14NParameterSpec params = (ExcC14NParameterSpec)spec;
StringBuilder prefixListAttr = new StringBuilder("");
@ -125,16 +131,15 @@ public final class DOMExcC14NMethod extends ApacheCanonicalizer {
prefixListAttr.append(" ");
}
}
xwriter.writeAttribute("", "", "PrefixList", prefixListAttr.toString());
DOMUtils.setAttribute(eElem, "PrefixList", prefixListAttr.toString());
this.inclusiveNamespaces = prefixListAttr.toString();
xwriter.writeEndElement(); // "InclusiveNamespaces"
transformElem.appendChild(eElem);
}
public String getParamsNSURI() {
return CanonicalizationMethod.EXCLUSIVE;
}
@Override
public Data transform(Data data, XMLCryptoContext xc)
throws TransformException
{

View File

@ -42,6 +42,7 @@ import java.security.SignatureException;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.jcp.xml.dsig.internal.MacOutputStream;
@ -117,30 +118,32 @@ public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod
}
}
@Override
public final AlgorithmParameterSpec getParameterSpec() {
return params;
}
@Override
SignatureMethodParameterSpec unmarshalParams(Element paramsElem)
throws MarshalException
{
outputLength = Integer.parseInt(textOfNode(paramsElem));
outputLength = Integer.parseInt(paramsElem.getFirstChild().getNodeValue());
outputLengthSet = true;
LOG.debug("unmarshalled outputLength: {}", outputLength);
return new HMACParameterSpec(outputLength);
}
@Override
void marshalParams(XmlWriter xwriter, String prefix)
void marshalParams(Element parent, String prefix)
throws MarshalException
{
xwriter.writeTextElement(prefix, "HMACOutputLength", XMLSignature.XMLNS, String.valueOf(outputLength));
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element hmacElem = DOMUtils.createElement(ownerDoc, "HMACOutputLength",
XMLSignature.XMLNS, prefix);
hmacElem.appendChild(ownerDoc.createTextNode
(String.valueOf(outputLength)));
parent.appendChild(hmacElem);
}
@Override
boolean verify(Key key, DOMSignedInfo si, byte[] sig,
boolean verify(Key key, SignedInfo si, byte[] sig,
XMLValidateContext context)
throws InvalidKeyException, SignatureException, XMLSignatureException
{
@ -162,14 +165,13 @@ public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod
("HMACOutputLength must not be less than " + getDigestLength());
}
hmac.init(key);
si.canonicalize(context, new MacOutputStream(hmac));
((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
byte[] result = hmac.doFinal();
return MessageDigest.isEqual(sig, result);
}
@Override
byte[] sign(Key key, DOMSignedInfo si, XMLSignContext context)
byte[] sign(Key key, SignedInfo si, XMLSignContext context)
throws InvalidKeyException, XMLSignatureException
{
if (key == null || si == null) {
@ -190,11 +192,10 @@ public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod
("HMACOutputLength must not be less than " + getDigestLength());
}
hmac.init(key);
si.canonicalize(context, new MacOutputStream(hmac));
((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
return hmac.doFinal();
}
@Override
boolean paramsEqual(AlgorithmParameterSpec spec) {
if (getParameterSpec() == spec) {
return true;
@ -207,7 +208,6 @@ public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod
return outputLength == ospec.getOutputLength();
}
@Override
Type getAlgorithmType() {
return Type.HMAC;
}
@ -225,15 +225,12 @@ public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod
SHA1(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return SignatureMethod.HMAC_SHA1;
}
@Override
String getJCAAlgorithm() {
return "HmacSHA1";
}
@Override
int getDigestLength() {
return 160;
}
@ -269,15 +266,12 @@ public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod
SHA256(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return HMAC_SHA256;
}
@Override
String getJCAAlgorithm() {
return "HmacSHA256";
}
@Override
int getDigestLength() {
return 256;
}
@ -291,15 +285,12 @@ public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod
SHA384(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return HMAC_SHA384;
}
@Override
String getJCAAlgorithm() {
return "HmacSHA384";
}
@Override
int getDigestLength() {
return 384;
}
@ -313,15 +304,12 @@ public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod
SHA512(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return HMAC_SHA512;
}
@Override
String getJCAAlgorithm() {
return "HmacSHA512";
}
@Override
int getDigestLength() {
return 512;
}

View File

@ -36,10 +36,13 @@ import java.util.List;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -47,7 +50,7 @@ import org.w3c.dom.Node;
* DOM-based implementation of KeyInfo.
*
*/
public final class DOMKeyInfo extends BaseStructure implements KeyInfo {
public final class DOMKeyInfo extends DOMStructure implements KeyInfo {
private final String id;
private final List<XMLStructure> keyInfoTypes;
@ -101,7 +104,14 @@ public final class DOMKeyInfo extends BaseStructure implements KeyInfo {
Provider provider)
throws MarshalException
{
id = DOMUtils.getIdAttributeValue(kiElem, "Id");
// get Id attribute, if specified
Attr attr = kiElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
id = attr.getValue();
kiElem.setIdAttributeNode(attr, true);
} else {
id = null;
}
// get all children nodes
List<XMLStructure> content = new ArrayList<>();
@ -134,17 +144,14 @@ public final class DOMKeyInfo extends BaseStructure implements KeyInfo {
keyInfoTypes = Collections.unmodifiableList(content);
}
@Override
public String getId() {
return id;
}
@Override
public List<XMLStructure> getContent() {
return keyInfoTypes;
}
@Override
public void marshal(XMLStructure parent, XMLCryptoContext context)
throws MarshalException
{
@ -155,44 +162,62 @@ public final class DOMKeyInfo extends BaseStructure implements KeyInfo {
throw new ClassCastException("parent must be of type DOMStructure");
}
internalMarshal( (javax.xml.crypto.dom.DOMStructure) parent, context);
}
private void internalMarshal(javax.xml.crypto.dom.DOMStructure parent, XMLCryptoContext context)
throws MarshalException {
Node pNode = parent.getNode();
Node pNode = ((javax.xml.crypto.dom.DOMStructure)parent).getNode();
String dsPrefix = DOMUtils.getSignaturePrefix(context);
Element kiElem = DOMUtils.createElement
(DOMUtils.getOwnerDocument(pNode), "KeyInfo",
XMLSignature.XMLNS, dsPrefix);
if (dsPrefix == null || dsPrefix.length() == 0) {
kiElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns", XMLSignature.XMLNS);
} else {
kiElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns:" + dsPrefix, XMLSignature.XMLNS);
}
Node nextSibling = null;
if (context instanceof DOMSignContext) {
nextSibling = ((DOMSignContext)context).getNextSibling();
}
XmlWriterToTree xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), pNode, nextSibling);
marshalInternal(xwriter, this, dsPrefix, context, true);
marshal(pNode, kiElem, nextSibling, dsPrefix, (DOMCryptoContext)context);
}
public static void marshal(XmlWriter xwriter, KeyInfo ki, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
marshalInternal(xwriter, ki, dsPrefix, context, false);
@Override
public void marshal(Node parent, String dsPrefix,
DOMCryptoContext context)
throws MarshalException
{
marshal(parent, null, dsPrefix, context);
}
private static void marshalInternal(XmlWriter xwriter, KeyInfo ki,
String dsPrefix, XMLCryptoContext context, boolean declareNamespace) throws MarshalException {
public void marshal(Node parent, Node nextSibling, String dsPrefix,
DOMCryptoContext context)
throws MarshalException
{
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element kiElem = DOMUtils.createElement(ownerDoc, "KeyInfo",
XMLSignature.XMLNS, dsPrefix);
marshal(parent, kiElem, nextSibling, dsPrefix, context);
}
xwriter.writeStartElement(dsPrefix, "KeyInfo", XMLSignature.XMLNS);
if (declareNamespace) {
xwriter.writeNamespace(dsPrefix, XMLSignature.XMLNS);
}
xwriter.writeIdAttribute("", "", "Id", ki.getId());
private void marshal(Node parent, Element kiElem, Node nextSibling,
String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
// create and append KeyInfoType elements
List<XMLStructure> keyInfoTypes = getContent(ki);
for (XMLStructure kiType : keyInfoTypes) {
xwriter.marshalStructure(kiType, dsPrefix, context);
if (kiType instanceof DOMStructure) {
((DOMStructure)kiType).marshal(kiElem, dsPrefix, context);
} else {
DOMUtils.appendChild(kiElem,
((javax.xml.crypto.dom.DOMStructure)kiType).getNode());
}
}
xwriter.writeEndElement(); // "KeyInfo"
// append id attribute
DOMUtils.setAttributeID(kiElem, "Id", id);
parent.insertBefore(kiElem, nextSibling);
}
@Override

View File

@ -31,15 +31,24 @@ package org.jcp.xml.dsig.internal.dom;
import java.math.BigInteger;
import java.security.KeyException;
import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.List;
import javax.xml.crypto.*;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.KeyName;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.keyinfo.PGPData;
import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@ -53,24 +62,20 @@ public final class DOMKeyInfoFactory extends KeyInfoFactory {
public DOMKeyInfoFactory() { }
@Override
@SuppressWarnings("rawtypes")
public KeyInfo newKeyInfo(List content) {
return newKeyInfo(content, null);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public KeyInfo newKeyInfo(List content, String id) {
return new DOMKeyInfo(content, id);
}
@Override
public KeyName newKeyName(String name) {
return new DOMKeyName(name);
}
@Override
public KeyValue newKeyValue(PublicKey key) throws KeyException {
String algorithm = key.getAlgorithm();
if ("DSA".equals(algorithm)) {
@ -84,30 +89,25 @@ public final class DOMKeyInfoFactory extends KeyInfoFactory {
}
}
@Override
public PGPData newPGPData(byte[] keyId) {
return newPGPData(keyId, null, null);
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public PGPData newPGPData(byte[] keyId, byte[] keyPacket, List other) {
return new DOMPGPData(keyId, keyPacket, other);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
@SuppressWarnings({ "rawtypes", "unchecked" })
public PGPData newPGPData(byte[] keyPacket, List other) {
return new DOMPGPData(keyPacket, other);
}
@Override
public RetrievalMethod newRetrievalMethod(String uri) {
return newRetrievalMethod(uri, null, null);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
@SuppressWarnings({ "rawtypes", "unchecked" })
public RetrievalMethod newRetrievalMethod(String uri, String type,
List transforms) {
if (uri == null) {
@ -116,8 +116,7 @@ public final class DOMKeyInfoFactory extends KeyInfoFactory {
return new DOMRetrievalMethod(uri, type, transforms);
}
@Override
@SuppressWarnings("rawtypes")
@SuppressWarnings({ "rawtypes" })
public X509Data newX509Data(List content) {
return new DOMX509Data(content);
}
@ -128,7 +127,6 @@ public final class DOMKeyInfoFactory extends KeyInfoFactory {
return new DOMX509IssuerSerial(issuerName, serialNumber);
}
@Override
public boolean isFeatureSupported(String feature) {
if (feature == null) {
throw new NullPointerException();
@ -137,7 +135,6 @@ public final class DOMKeyInfoFactory extends KeyInfoFactory {
}
}
@Override
public URIDereferencer getURIDereferencer() {
return DOMURIDereferencer.INSTANCE;
}

View File

@ -28,15 +28,20 @@
*/
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.keyinfo.KeyName;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* DOM-based implementation of KeyName.
*
*/
public final class DOMKeyName extends BaseStructure implements KeyName {
public final class DOMKeyName extends DOMStructure implements KeyName {
private final String name;
@ -59,12 +64,23 @@ public final class DOMKeyName extends BaseStructure implements KeyName {
* @param knElem a KeyName element
*/
public DOMKeyName(Element knElem) {
name = textOfNode(knElem);
name = knElem.getFirstChild().getNodeValue();
}
public String getName() {
return name;
}
@Override
public String getName() {
return name;
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
// prepend namespace prefix, if necessary
Element knElem = DOMUtils.createElement(ownerDoc, "KeyName",
XMLSignature.XMLNS, dsPrefix);
knElem.appendChild(ownerDoc.createTextNode(name));
parent.appendChild(knElem);
}
@Override

View File

@ -29,6 +29,7 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
@ -53,16 +54,17 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Arrays;
import java.util.Base64;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* DOM-based implementation of KeyValue.
*
*/
public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure implements KeyValue {
public abstract class DOMKeyValue<K extends PublicKey> extends DOMStructure implements KeyValue {
private static final String XMLDSIG_11_XMLNS
= "http://www.w3.org/2009/xmldsig11#";
@ -102,7 +104,6 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
}
}
@Override
public PublicKey getPublicKey() throws KeyException {
if (publicKey == null) {
throw new KeyException("can't convert KeyValue to PublicKey");
@ -111,17 +112,22 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
}
}
public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
@Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
// create KeyValue element
xwriter.writeStartElement(dsPrefix, "KeyValue", XMLSignature.XMLNS);
marshalPublicKey(xwriter, publicKey, dsPrefix, context);
xwriter.writeEndElement(); // "KeyValue"
Element kvElem = DOMUtils.createElement(ownerDoc, "KeyValue",
XMLSignature.XMLNS, dsPrefix);
marshalPublicKey(kvElem, ownerDoc, dsPrefix, context);
parent.appendChild(kvElem);
}
abstract void marshalPublicKey(XmlWriter xwriter, K key, String dsPrefix,
XMLCryptoContext context) throws MarshalException;
abstract void marshalPublicKey(Node parent, Document doc, String dsPrefix,
DOMCryptoContext context) throws MarshalException;
abstract K unmarshalKeyValue(Element kvtElem)
throws MarshalException;
@ -162,25 +168,13 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
public static BigInteger decode(Element elem) throws MarshalException {
try {
String base64str = BaseStructure.textOfNode(elem);
return new BigInteger(1, Base64.getMimeDecoder().decode(base64str));
String base64str = elem.getFirstChild().getNodeValue();
return new BigInteger(1, XMLUtils.decode(base64str));
} catch (Exception ex) {
throw new MarshalException(ex);
}
}
public static void writeBase64BigIntegerElement(
XmlWriter xwriter, String prefix, String localName, String namespaceURI, BigInteger value
) {
byte[] bytes = XMLUtils.getBytes(value, value.bitLength());
xwriter.writeTextElement(prefix, localName, namespaceURI, Base64.getMimeEncoder().encodeToString(bytes));
}
public static void marshal(XmlWriter xwriter, BigInteger bigNum) {
byte[] bytes = XMLUtils.getBytes(bigNum, bigNum.bitLength());
xwriter.writeCharacters(Base64.getMimeEncoder().encodeToString(bytes));
}
@Override
public int hashCode() {
int result = 17;
@ -193,25 +187,36 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
static final class RSA extends DOMKeyValue<RSAPublicKey> {
// RSAKeyValue CryptoBinaries
private DOMCryptoBinary modulus, exponent;
private KeyFactory rsakf;
RSA(RSAPublicKey key) throws KeyException {
super(key);
RSAPublicKey rkey = key;
exponent = new DOMCryptoBinary(rkey.getPublicExponent());
modulus = new DOMCryptoBinary(rkey.getModulus());
}
RSA(Element elem) throws MarshalException {
super(elem);
}
@Override
void marshalPublicKey(XmlWriter xwriter, RSAPublicKey publicKey, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
xwriter.writeStartElement(dsPrefix, "RSAKeyValue", XMLSignature.XMLNS);
writeBase64BigIntegerElement(xwriter, dsPrefix, "Modulus", XMLSignature.XMLNS, publicKey.getModulus());
writeBase64BigIntegerElement(xwriter, dsPrefix, "Exponent", XMLSignature.XMLNS, publicKey.getPublicExponent());
xwriter.writeEndElement(); // "RSAKeyValue"
void marshalPublicKey(Node parent, Document doc, String dsPrefix,
DOMCryptoContext context) throws MarshalException {
Element rsaElem = DOMUtils.createElement(doc, "RSAKeyValue",
XMLSignature.XMLNS,
dsPrefix);
Element modulusElem = DOMUtils.createElement(doc, "Modulus",
XMLSignature.XMLNS,
dsPrefix);
Element exponentElem = DOMUtils.createElement(doc, "Exponent",
XMLSignature.XMLNS,
dsPrefix);
modulus.marshal(modulusElem, dsPrefix, context);
exponent.marshal(exponentElem, dsPrefix, context);
rsaElem.appendChild(modulusElem);
rsaElem.appendChild(exponentElem);
parent.appendChild(rsaElem);
}
@Override
@ -241,10 +246,17 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
static final class DSA extends DOMKeyValue<DSAPublicKey> {
// DSAKeyValue CryptoBinaries
private DOMCryptoBinary p, q, g, y; //, seed, pgen;
private KeyFactory dsakf;
DSA(DSAPublicKey key) throws KeyException {
super(key);
DSAPublicKey dkey = key;
DSAParams params = dkey.getParams();
p = new DOMCryptoBinary(params.getP());
q = new DOMCryptoBinary(params.getQ());
g = new DOMCryptoBinary(params.getG());
y = new DOMCryptoBinary(dkey.getY());
}
DSA(Element elem) throws MarshalException {
@ -252,21 +264,31 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
}
@Override
void marshalPublicKey(XmlWriter xwriter, DSAPublicKey publicKey, String dsPrefix,
XMLCryptoContext context)
void marshalPublicKey(Node parent, Document doc, String dsPrefix,
DOMCryptoContext context)
throws MarshalException
{
DSAParams params = publicKey.getParams();
xwriter.writeStartElement(dsPrefix, "DSAKeyValue", XMLSignature.XMLNS);
Element dsaElem = DOMUtils.createElement(doc, "DSAKeyValue",
XMLSignature.XMLNS,
dsPrefix);
// parameters J, Seed & PgenCounter are not included
writeBase64BigIntegerElement(xwriter, dsPrefix, "P", XMLSignature.XMLNS, params.getP());
writeBase64BigIntegerElement(xwriter, dsPrefix, "Q", XMLSignature.XMLNS, params.getQ());
writeBase64BigIntegerElement(xwriter, dsPrefix, "G", XMLSignature.XMLNS, params.getG());
writeBase64BigIntegerElement(xwriter, dsPrefix, "Y", XMLSignature.XMLNS, publicKey.getY() );
xwriter.writeEndElement(); // "DSAKeyValue"
Element pElem = DOMUtils.createElement(doc, "P", XMLSignature.XMLNS,
dsPrefix);
Element qElem = DOMUtils.createElement(doc, "Q", XMLSignature.XMLNS,
dsPrefix);
Element gElem = DOMUtils.createElement(doc, "G", XMLSignature.XMLNS,
dsPrefix);
Element yElem = DOMUtils.createElement(doc, "Y", XMLSignature.XMLNS,
dsPrefix);
p.marshal(pElem, dsPrefix, context);
q.marshal(qElem, dsPrefix, context);
g.marshal(gElem, dsPrefix, context);
y.marshal(yElem, dsPrefix, context);
dsaElem.appendChild(pElem);
dsaElem.appendChild(qElem);
dsaElem.appendChild(gElem);
dsaElem.appendChild(yElem);
parent.appendChild(dsaElem);
}
@Override
@ -316,8 +338,7 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
}
static final class EC extends DOMKeyValue<ECPublicKey> {
// ECKeyValue CryptoBinaries
// ECKeyValue CryptoBinaries
private byte[] ecPublicKey;
private KeyFactory eckf;
private ECParameterSpec ecParams;
@ -460,27 +481,35 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
}
@Override
void marshalPublicKey(XmlWriter xwriter, ECPublicKey publicKey, String dsPrefix,
XMLCryptoContext context)
void marshalPublicKey(Node parent, Document doc, String dsPrefix,
DOMCryptoContext context)
throws MarshalException
{
String prefix = DOMUtils.getNSPrefix(context, XMLDSIG_11_XMLNS);
xwriter.writeStartElement(prefix, "ECKeyValue", XMLDSIG_11_XMLNS);
xwriter.writeStartElement(prefix, "NamedCurve", XMLDSIG_11_XMLNS);
xwriter.writeNamespace(prefix, XMLDSIG_11_XMLNS);
Element ecKeyValueElem = DOMUtils.createElement(doc, "ECKeyValue",
XMLDSIG_11_XMLNS,
prefix);
Element namedCurveElem = DOMUtils.createElement(doc, "NamedCurve",
XMLDSIG_11_XMLNS,
prefix);
Element publicKeyElem = DOMUtils.createElement(doc, "PublicKey",
XMLDSIG_11_XMLNS,
prefix);
String oid = getCurveOid(ecParams);
if (oid == null) {
throw new MarshalException("Invalid ECParameterSpec");
}
xwriter.writeAttribute("", "", "URI", "urn:oid:" + oid);
xwriter.writeEndElement();
xwriter.writeStartElement(prefix, "PublicKey", XMLDSIG_11_XMLNS);
String encoded = Base64.getMimeEncoder().encodeToString(ecPublicKey);
xwriter.writeCharacters(encoded);
xwriter.writeEndElement(); // "PublicKey"
xwriter.writeEndElement(); // "ECKeyValue"
DOMUtils.setAttribute(namedCurveElem, "URI", "urn:oid:" + oid);
String qname = (prefix == null || prefix.length() == 0)
? "xmlns" : "xmlns:" + prefix;
namedCurveElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
qname, XMLDSIG_11_XMLNS);
ecKeyValueElem.appendChild(namedCurveElem);
String encoded = XMLUtils.encodeToString(ecPublicKey);
publicKeyElem.appendChild
(DOMUtils.getOwnerDocument(publicKeyElem).createTextNode(encoded));
ecKeyValueElem.appendChild(publicKeyElem);
parent.appendChild(ecKeyValueElem);
}
@Override
@ -526,7 +555,7 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
try {
String content = XMLUtils.getFullTextChildrenFromElement(curElem);
ecPoint = decodePoint(Base64.getMimeDecoder().decode(content),
ecPoint = decodePoint(XMLUtils.decode(content),
ecParams.getCurve());
} catch (IOException ioe) {
throw new MarshalException("Invalid EC Point", ioe);
@ -574,21 +603,23 @@ public abstract class DOMKeyValue<K extends PublicKey> extends BaseStructure imp
}
static final class Unknown extends DOMKeyValue<PublicKey> {
private XMLStructure externalPublicKey;
private javax.xml.crypto.dom.DOMStructure externalPublicKey;
Unknown(Element elem) throws MarshalException {
super(elem);
}
@Override
PublicKey unmarshalKeyValue(Element kvElem) throws MarshalException {
externalPublicKey = new javax.xml.crypto.dom.DOMStructure(kvElem);
return null;
}
@Override
void marshalPublicKey(XmlWriter xwriter, PublicKey publicKey, String dsPrefix,
XMLCryptoContext context)
void marshalPublicKey(Node parent, Document doc, String dsPrefix,
DOMCryptoContext context)
throws MarshalException
{
xwriter.marshalStructure(externalPublicKey, dsPrefix, context);
parent.appendChild(externalPublicKey.getNode());
}
}
}

View File

@ -29,18 +29,21 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import java.security.Provider;
import java.util.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* DOM-based implementation of Manifest.
*
*/
public final class DOMManifest extends BaseStructure implements Manifest {
public final class DOMManifest extends DOMStructure implements Manifest {
private final List<Reference> references;
private final String id;
@ -58,7 +61,7 @@ public final class DOMManifest extends BaseStructure implements Manifest {
* @throws ClassCastException if {@code references} contains any
* entries that are not of type {@link Reference}
*/
public DOMManifest(List<DOMReference> references, String id) {
public DOMManifest(List<? extends Reference> references, String id) {
if (references == null) {
throw new NullPointerException("references cannot be null");
}
@ -114,7 +117,6 @@ public final class DOMManifest extends BaseStructure implements Manifest {
this.references = Collections.unmodifiableList(refs);
}
@Override
public String getId() {
return id;
}
@ -129,18 +131,21 @@ public final class DOMManifest extends BaseStructure implements Manifest {
return references;
}
public static void marshal(XmlWriter xwriter, Manifest manif, String dsPrefix, XMLCryptoContext context)
throws MarshalException {
xwriter.writeStartElement(dsPrefix, "Manifest", XMLSignature.XMLNS);
xwriter.writeIdAttribute("", "", "Id", manif.getId());
@Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element manElem = DOMUtils.createElement(ownerDoc, "Manifest",
XMLSignature.XMLNS, dsPrefix);
DOMUtils.setAttributeID(manElem, "Id", id);
// add references
@SuppressWarnings("unchecked")
List<Reference> references = manif.getReferences();
for (Reference ref : references) {
((DOMReference)ref).marshal(xwriter, dsPrefix, context);
((DOMReference)ref).marshal(manElem, dsPrefix, context);
}
xwriter.writeEndElement(); // "Manifest"
parent.appendChild(manElem);
}
@Override

View File

@ -31,9 +31,11 @@ package org.jcp.xml.dsig.internal.dom;
import java.util.*;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.keyinfo.PGPData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -43,7 +45,7 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
* DOM-based implementation of PGPData.
*
*/
public final class DOMPGPData extends BaseStructure implements PGPData {
public final class DOMPGPData extends DOMStructure implements PGPData {
private final byte[] keyId;
private final byte[] keyPacket;
@ -156,10 +158,10 @@ public final class DOMPGPData extends BaseStructure implements PGPData {
String namespace = childElem.getNamespaceURI();
if ("PGPKeyID".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
String content = XMLUtils.getFullTextChildrenFromElement(childElem);
pgpKeyId = Base64.getMimeDecoder().decode(content);
pgpKeyId = XMLUtils.decode(content);
} else if ("PGPKeyPacket".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
String content = XMLUtils.getFullTextChildrenFromElement(childElem);
pgpKeyPacket = Base64.getMimeDecoder().decode(content);
pgpKeyPacket = XMLUtils.decode(content);
} else {
other.add
(new javax.xml.crypto.dom.DOMStructure(childElem));
@ -172,21 +174,56 @@ public final class DOMPGPData extends BaseStructure implements PGPData {
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;
}
@Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element pdElem = DOMUtils.createElement(ownerDoc, "PGPData",
XMLSignature.XMLNS, dsPrefix);
// create and append PGPKeyID element
if (keyId != null) {
Element keyIdElem = DOMUtils.createElement(ownerDoc, "PGPKeyID",
XMLSignature.XMLNS,
dsPrefix);
keyIdElem.appendChild
(ownerDoc.createTextNode(XMLUtils.encodeToString(keyId)));
pdElem.appendChild(keyIdElem);
}
// create and append PGPKeyPacket element
if (keyPacket != null) {
Element keyPktElem = DOMUtils.createElement(ownerDoc,
"PGPKeyPacket",
XMLSignature.XMLNS,
dsPrefix);
keyPktElem.appendChild
(ownerDoc.createTextNode(XMLUtils.encodeToString(keyPacket)));
pdElem.appendChild(keyPktElem);
}
// create and append any elements
for (XMLStructure extElem : externalElements) {
DOMUtils.appendChild(pdElem, ((javax.xml.crypto.dom.DOMStructure)
extElem).getNode());
}
parent.appendChild(pdElem);
}
/**
* We assume packets use the new format packet syntax, as specified in
* section 4 of RFC 2440.

View File

@ -37,6 +37,7 @@ package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dom.DOMURIReference;
import java.io.*;
@ -46,6 +47,7 @@ import java.security.*;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -54,6 +56,7 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.jcp.xml.dsig.internal.DigesterOutputStream;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
/**
* DOM-based implementation of Reference.
@ -242,7 +245,7 @@ public final class DOMReference extends DOMStructure
// unmarshal DigestValue
Element dvElem = DOMUtils.getNextSiblingElement(dmElem, "DigestValue", XMLSignature.XMLNS);
String content = XMLUtils.getFullTextChildrenFromElement(dvElem);
this.digestValue = Base64.getMimeDecoder().decode(content);
this.digestValue = XMLUtils.decode(content);
// check for extra elements
if (DOMUtils.getNextSiblingElement(dvElem) != null) {
@ -252,7 +255,14 @@ public final class DOMReference extends DOMStructure
// unmarshal attributes
this.uri = DOMUtils.getAttributeValue(refElem, "URI");
this.id = DOMUtils.getIdAttributeValue(refElem, "Id");
Attr attr = refElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
this.id = attr.getValue();
refElem.setIdAttributeNode(attr, true);
} else {
this.id = null;
}
this.type = DOMUtils.getAttributeValue(refElem, "Type");
this.here = refElem.getAttributeNodeNS(null, "URI");
@ -263,76 +273,80 @@ public final class DOMReference extends DOMStructure
this.provider = provider;
}
@Override
public DigestMethod getDigestMethod() {
return digestMethod;
}
@Override
public String getId() {
return id;
}
@Override
public String getURI() {
return uri;
}
@Override
public String getType() {
return type;
}
@Override
public List<Transform> getTransforms() {
return Collections.unmodifiableList(allTransforms);
}
@Override
public byte[] getDigestValue() {
return digestValue == null ? null : digestValue.clone();
}
@Override
public byte[] getCalculatedDigestValue() {
return calcDigestValue == null ? null
: calcDigestValue.clone();
}
@Override
public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
LOG.debug("Marshalling Reference");
xwriter.writeStartElement(dsPrefix, "Reference", XMLSignature.XMLNS);
XMLStructure refStruct = xwriter.getCurrentNodeAsStructure();
refElem = (Element) ((javax.xml.crypto.dom.DOMStructure) refStruct).getNode();
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
refElem = DOMUtils.createElement(ownerDoc, "Reference",
XMLSignature.XMLNS, dsPrefix);
// set attributes
xwriter.writeIdAttribute("", "", "Id", id);
here = xwriter.writeAttribute("", "", "URI", uri);
xwriter.writeAttribute("", "", "Type", type);
DOMUtils.setAttributeID(refElem, "Id", id);
DOMUtils.setAttribute(refElem, "URI", uri);
DOMUtils.setAttribute(refElem, "Type", type);
// create and append Transforms element
if (!allTransforms.isEmpty()) {
xwriter.writeStartElement(dsPrefix, "Transforms", XMLSignature.XMLNS);
Element transformsElem = DOMUtils.createElement(ownerDoc,
"Transforms",
XMLSignature.XMLNS,
dsPrefix);
refElem.appendChild(transformsElem);
for (Transform transform : allTransforms) {
xwriter.marshalStructure(transform, dsPrefix, context);
((DOMStructure)transform).marshal(transformsElem,
dsPrefix, context);
}
xwriter.writeEndElement(); // "Transforms"
}
// create and append DigestMethod element
DOMDigestMethod.marshal(xwriter, digestMethod, dsPrefix);
((DOMDigestMethod)digestMethod).marshal(refElem, dsPrefix, context);
// create and append DigestValue element
LOG.debug("Adding digestValueElem");
xwriter.writeStartElement(dsPrefix, "DigestValue", XMLSignature.XMLNS);
Element digestValueElem = DOMUtils.createElement(ownerDoc,
"DigestValue",
XMLSignature.XMLNS,
dsPrefix);
if (digestValue != null) {
xwriter.writeCharacters(Base64.getMimeEncoder().encodeToString(digestValue));
digestValueElem.appendChild
(ownerDoc.createTextNode(XMLUtils.encodeToString(digestValue)));
}
xwriter.writeEndElement(); // "DigestValue"
xwriter.writeEndElement(); // "Reference"
refElem.appendChild(digestValueElem);
parent.appendChild(refElem);
here = refElem.getAttributeNodeNS(null, "URI");
}
public void digest(XMLSignContext signContext)
@ -347,7 +361,7 @@ public final class DOMReference extends DOMStructure
digestValue = transform(data, signContext);
// insert digestValue into DigestValue element
String encodedDV = Base64.getMimeEncoder().encodeToString(digestValue);
String encodedDV = XMLUtils.encodeToString(digestValue);
LOG.debug("Reference object uri = {}", uri);
Element digestElem = DOMUtils.getLastChildElement(refElem);
if (digestElem == null) {
@ -361,7 +375,6 @@ public final class DOMReference extends DOMStructure
LOG.debug("Reference digesting completed");
}
@Override
public boolean validate(XMLValidateContext validateContext)
throws XMLSignatureException
{
@ -375,8 +388,8 @@ public final class DOMReference extends DOMStructure
calcDigestValue = transform(data, validateContext);
if (LOG.isDebugEnabled()) {
LOG.debug("Expected digest: " + Base64.getMimeEncoder().encodeToString(digestValue));
LOG.debug("Actual digest: " + Base64.getMimeEncoder().encodeToString(calcDigestValue));
LOG.debug("Expected digest: " + XMLUtils.encodeToString(digestValue));
LOG.debug("Actual digest: " + XMLUtils.encodeToString(calcDigestValue));
}
validationStatus = Arrays.equals(digestValue, calcDigestValue);
@ -384,12 +397,10 @@ public final class DOMReference extends DOMStructure
return validationStatus;
}
@Override
public Data getDereferencedData() {
return derefData;
}
@Override
public InputStream getDigestInputStream() {
return dis;
}
@ -516,8 +527,8 @@ public final class DOMReference extends DOMStructure
} else {
transformsElem = DOMUtils.getFirstChildElement(refElem);
}
XmlWriter xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), transformsElem);
t.marshal(xwriter, dsPrefix, context);
t.marshal(transformsElem, dsPrefix,
(DOMCryptoContext)context);
allTransforms.add(t);
xi.updateOutputStream(os, true);
} else {
@ -550,7 +561,6 @@ public final class DOMReference extends DOMStructure
}
}
@Override
public Node getHere() {
return here;
}
@ -614,7 +624,6 @@ public final class DOMReference extends DOMStructure
try {
final Set<Node> s = xsi.getNodeSet();
return new NodeSetData<Node>() {
@Override
public Iterator<Node> iterator() { return s.iterator(); }
};
} catch (Exception e) {

View File

@ -52,6 +52,7 @@ import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.URIReferenceException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dom.DOMURIReference;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
@ -179,50 +180,53 @@ public final class DOMRetrievalMethod extends DOMStructure
}
}
@Override
public String getURI() {
return uri;
}
@Override
public String getType() {
return type;
}
@Override
public List<Transform> getTransforms() {
return transforms;
}
@Override
public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
xwriter.writeStartElement(dsPrefix, "RetrievalMethod", XMLSignature.XMLNS);
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element rmElem = DOMUtils.createElement(ownerDoc, "RetrievalMethod",
XMLSignature.XMLNS, dsPrefix);
// TODO - see whether it is important to capture the "here" attribute as part of the
// marshalling - do any of the tests fail?
// add URI and Type attributes
here = xwriter.writeAttribute("", "", "URI", uri);
xwriter.writeAttribute("", "", "Type", type);
DOMUtils.setAttribute(rmElem, "URI", uri);
DOMUtils.setAttribute(rmElem, "Type", type);
// add Transforms elements
if (!transforms.isEmpty()) {
xwriter.writeStartElement(dsPrefix, "Transforms", XMLSignature.XMLNS);
Element transformsElem = DOMUtils.createElement(ownerDoc,
"Transforms",
XMLSignature.XMLNS,
dsPrefix);
rmElem.appendChild(transformsElem);
for (Transform transform : transforms) {
((DOMTransform)transform).marshal(xwriter, dsPrefix, context);
((DOMTransform)transform).marshal(transformsElem,
dsPrefix, context);
}
xwriter.writeEndElement(); // "Transforms"
}
xwriter.writeEndElement(); // "RetrievalMethod"
parent.appendChild(rmElem);
// save here node
here = rmElem.getAttributeNodeNS(null, "URI");
}
@Override
public Node getHere() {
return here;
}
@Override
public Data dereference(XMLCryptoContext context)
throws URIReferenceException
{
@ -244,7 +248,7 @@ public final class DOMRetrievalMethod extends DOMStructure
// pass dereferenced data through Transforms
try {
for (Transform transform : transforms) {
data = transform.transform(data, context);
data = ((DOMTransform)transform).transform(data, context);
}
} catch (Exception e) {
throw new URIReferenceException(e);

View File

@ -224,7 +224,6 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
}
}
@Override
public final AlgorithmParameterSpec getParameterSpec() {
return params;
}
@ -246,8 +245,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
: Signature.getInstance(getJCAAlgorithm(), p);
}
@Override
boolean verify(Key key, DOMSignedInfo si, byte[] sig,
boolean verify(Key key, SignedInfo si, byte[] sig,
XMLValidateContext context)
throws InvalidKeyException, SignatureException, XMLSignatureException
{
@ -276,7 +274,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
byte[] s;
try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
si.canonicalize(context, outputStream);
((DOMSignedInfo)si).canonicalize(context, outputStream);
// Do any necessary format conversions
s = preVerifyFormat(key, sig);
} catch (IOException ioe) {
@ -314,8 +312,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
}
}
@Override
byte[] sign(Key key, DOMSignedInfo si, XMLSignContext context)
byte[] sign(Key key, SignedInfo si, XMLSignContext context)
throws InvalidKeyException, XMLSignatureException
{
if (key == null || si == null) {
@ -341,7 +338,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
LOG.debug("JCA Algorithm: {}", getJCAAlgorithm());
try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
si.canonicalize(context, outputStream);
((DOMSignedInfo)si).canonicalize(context, outputStream);
// Return signature with any necessary format conversions
return postSignFormat(key, signature.sign());
} catch (SignatureException | IOException ex){
@ -570,15 +567,12 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
SHA224withRSA(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return RSA_SHA224;
}
@Override
String getJCAAlgorithm() {
return "SHA224withRSA";
}
@Override
Type getAlgorithmType() {
return Type.RSA;
}
@ -592,15 +586,12 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
SHA256withRSA(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return RSA_SHA256;
}
@Override
String getJCAAlgorithm() {
return "SHA256withRSA";
}
@Override
Type getAlgorithmType() {
return Type.RSA;
}
@ -614,15 +605,12 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
SHA384withRSA(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return RSA_SHA384;
}
@Override
String getJCAAlgorithm() {
return "SHA384withRSA";
}
@Override
Type getAlgorithmType() {
return Type.RSA;
}
@ -636,15 +624,12 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
SHA512withRSA(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return RSA_SHA512;
}
@Override
String getJCAAlgorithm() {
return "SHA512withRSA";
}
@Override
Type getAlgorithmType() {
return Type.RSA;
}
@ -857,18 +842,15 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
SHA1withDSA(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return SignatureMethod.DSA_SHA1;
}
@Override
String getJCAAlgorithm() {
return "SHA1withDSAinP1363Format";
}
String getJCAFallbackAlgorithm() {
return "SHA1withDSA";
}
@Override
Type getAlgorithmType() {
return Type.DSA;
}
@ -904,18 +886,15 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
SHA1withECDSA(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return ECDSA_SHA1;
}
@Override
String getJCAAlgorithm() {
return "SHA1withECDSAinP1363Format";
}
String getJCAFallbackAlgorithm() {
return "SHA1withECDSA";
}
@Override
Type getAlgorithmType() {
return Type.ECDSA;
}
@ -954,18 +933,15 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
SHA256withECDSA(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return ECDSA_SHA256;
}
@Override
String getJCAAlgorithm() {
return "SHA256withECDSAinP1363Format";
}
String getJCAFallbackAlgorithm() {
return "SHA256withECDSA";
}
@Override
Type getAlgorithmType() {
return Type.ECDSA;
}
@ -979,18 +955,15 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
SHA384withECDSA(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return ECDSA_SHA384;
}
@Override
String getJCAAlgorithm() {
return "SHA384withECDSAinP1363Format";
}
String getJCAFallbackAlgorithm() {
return "SHA384withECDSA";
}
@Override
Type getAlgorithmType() {
return Type.ECDSA;
}
@ -1004,18 +977,15 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
SHA512withECDSA(Element dmElem) throws MarshalException {
super(dmElem);
}
@Override
public String getAlgorithm() {
return ECDSA_SHA512;
}
@Override
String getJCAAlgorithm() {
return "SHA512withECDSAinP1363Format";
}
String getJCAFallbackAlgorithm() {
return "SHA512withECDSA";
}
@Override
Type getAlgorithmType() {
return Type.ECDSA;
}

View File

@ -29,10 +29,13 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -40,7 +43,7 @@ import org.w3c.dom.Node;
* DOM-based implementation of SignatureProperties.
*
*/
public final class DOMSignatureProperties extends BaseStructure
public final class DOMSignatureProperties extends DOMStructure
implements SignatureProperties {
private final String id;
@ -58,7 +61,7 @@ public final class DOMSignatureProperties extends BaseStructure
* @throws IllegalArgumentException if {@code properties} is empty
* @throws NullPointerException if {@code properties}
*/
public DOMSignatureProperties(List<DOMSignatureProperty> properties,
public DOMSignatureProperties(List<? extends SignatureProperty> properties,
String id)
{
if (properties == null) {
@ -88,7 +91,13 @@ public final class DOMSignatureProperties extends BaseStructure
throws MarshalException
{
// unmarshal attributes
id = DOMUtils.getIdAttributeValue(propsElem, "Id");
Attr attr = propsElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
id = attr.getValue();
propsElem.setIdAttributeNode(attr, true);
} else {
id = null;
}
List<SignatureProperty> newProperties = new ArrayList<>();
Node firstChild = propsElem.getFirstChild();
@ -111,32 +120,34 @@ public final class DOMSignatureProperties extends BaseStructure
}
}
@Override
public List<SignatureProperty> getProperties() {
return properties;
}
@Override
public String getId() {
return id;
}
public static void marshal(XmlWriter xwriter, SignatureProperties sigProps, String dsPrefix, XMLCryptoContext context)
@Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
xwriter.writeStartElement(dsPrefix, "SignatureProperties", XMLSignature.XMLNS);
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element propsElem = DOMUtils.createElement(ownerDoc,
"SignatureProperties",
XMLSignature.XMLNS,
dsPrefix);
// set attributes
xwriter.writeIdAttribute("", "", "Id", sigProps.getId());
DOMUtils.setAttributeID(propsElem, "Id", id);
// create and append any properties
@SuppressWarnings("unchecked")
List<SignatureProperty> properties = sigProps.getProperties();
for (SignatureProperty property : properties) {
DOMSignatureProperty.marshal(xwriter, property, dsPrefix, context);
((DOMSignatureProperty)property).marshal(propsElem, dsPrefix,
context);
}
xwriter.writeEndElement(); // "SignatureProperties"
parent.appendChild(propsElem);
}
@Override

View File

@ -29,10 +29,13 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -40,7 +43,7 @@ import org.w3c.dom.Node;
* DOM-based implementation of SignatureProperty.
*
*/
public final class DOMSignatureProperty extends BaseStructure
public final class DOMSignatureProperty extends DOMStructure
implements SignatureProperty {
private final String id;
@ -96,7 +99,13 @@ public final class DOMSignatureProperty extends BaseStructure
if (target == null) {
throw new MarshalException("target cannot be null");
}
id = DOMUtils.getIdAttributeValue(propElem, "Id");
Attr attr = propElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
id = attr.getValue();
propElem.setIdAttributeNode(attr, true);
} else {
id = null;
}
List<XMLStructure> newContent = new ArrayList<>();
Node firstChild = propElem.getFirstChild();
@ -111,37 +120,37 @@ public final class DOMSignatureProperty extends BaseStructure
}
}
@Override
public List<XMLStructure> getContent() {
return content;
}
@Override
public String getId() {
return id;
}
@Override
public String getTarget() {
return target;
}
public static void marshal(XmlWriter xwriter, SignatureProperty sigProp, String dsPrefix, XMLCryptoContext context)
@Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
xwriter.writeStartElement(dsPrefix, "SignatureProperty", XMLSignature.XMLNS);
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element propElem = DOMUtils.createElement(ownerDoc, "SignatureProperty",
XMLSignature.XMLNS, dsPrefix);
// set attributes
xwriter.writeIdAttribute("", "", "Id", sigProp.getId());
xwriter.writeAttribute("", "", "Target", sigProp.getTarget());
DOMUtils.setAttributeID(propElem, "Id", id);
DOMUtils.setAttribute(propElem, "Target", target);
// create and append any elements and mixed content
List<XMLStructure> content = getContent(sigProp);
for (XMLStructure property : content) {
xwriter.marshalStructure(property, dsPrefix, context);
DOMUtils.appendChild(propElem,
((javax.xml.crypto.dom.DOMStructure)property).getNode());
}
xwriter.writeEndElement(); // "SignatureProperty"
parent.appendChild(propElem);
}
@Override
@ -176,10 +185,6 @@ public final class DOMSignatureProperty extends BaseStructure
return result;
}
@SuppressWarnings("unchecked")
private static List<XMLStructure> getContent(SignatureProperty prop) {
return prop.getContent();
}
private boolean equalsContent(List<XMLStructure> otherContent) {
int osize = otherContent.size();
if (content.size() != osize) {

View File

@ -29,6 +29,7 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import java.io.ByteArrayInputStream;
@ -39,8 +40,11 @@ import java.io.IOException;
import java.security.Provider;
import java.util.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
/**
* DOM-based implementation of SignedInfo.
@ -55,6 +59,7 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
private CanonicalizationMethod canonicalizationMethod;
private SignatureMethod signatureMethod;
private String id;
private Document ownerDoc;
private Element localSiElem;
private InputStream canonData;
@ -123,6 +128,7 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
public DOMSignedInfo(Element siElem, XMLCryptoContext context, Provider provider)
throws MarshalException {
localSiElem = siElem;
ownerDoc = siElem.getOwnerDocument();
// get Id attribute, if specified
id = DOMUtils.getAttributeValue(siElem, "Id");
@ -175,27 +181,22 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
references = Collections.unmodifiableList(refList);
}
@Override
public CanonicalizationMethod getCanonicalizationMethod() {
return canonicalizationMethod;
}
@Override
public SignatureMethod getSignatureMethod() {
return signatureMethod;
}
@Override
public String getId() {
return id;
}
@Override
public List<Reference> getReferences() {
return references;
}
@Override
public InputStream getCanonicalizedData() {
return canonData;
}
@ -223,7 +224,7 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
sb.append((char)signedInfoBytes[i]);
}
LOG.debug(sb.toString());
LOG.debug("Data to be signed/verified:" + Base64.getMimeEncoder().encodeToString(signedInfoBytes));
LOG.debug("Data to be signed/verified:" + XMLUtils.encodeToString(signedInfoBytes));
}
this.canonData = new ByteArrayInputStream(signedInfoBytes);
@ -236,32 +237,31 @@ public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
}
@Override
public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
xwriter.writeStartElement(dsPrefix, "SignedInfo", XMLSignature.XMLNS);
XMLStructure siStruct = xwriter.getCurrentNodeAsStructure();
localSiElem = (Element) ((javax.xml.crypto.dom.DOMStructure) siStruct).getNode();
// append Id attribute
xwriter.writeIdAttribute("", "", "Id", id);
ownerDoc = DOMUtils.getOwnerDocument(parent);
Element siElem = DOMUtils.createElement(ownerDoc, "SignedInfo",
XMLSignature.XMLNS, dsPrefix);
// create and append CanonicalizationMethod element
DOMCanonicalizationMethod dcm =
(DOMCanonicalizationMethod)canonicalizationMethod;
dcm.marshal(xwriter, dsPrefix, context);
dcm.marshal(siElem, dsPrefix, context);
// create and append SignatureMethod element
((AbstractDOMSignatureMethod)signatureMethod).marshal(xwriter, dsPrefix);
((DOMStructure)signatureMethod).marshal(siElem, dsPrefix, context);
// create and append Reference elements
for (Reference reference : references) {
// TODO - either suppress warning here, or figure out how to get rid of the cast.
DOMReference domRef = (DOMReference)reference;
domRef.marshal(xwriter, dsPrefix, context);
((DOMReference)reference).marshal(siElem, dsPrefix, context);
}
xwriter.writeEndElement(); // "SignedInfo"
// append Id attribute
DOMUtils.setAttributeID(siElem, "Id", id);
parent.appendChild(siElem);
localSiElem = siElem;
}
@Override

View File

@ -29,13 +29,24 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMCryptoContext;
import org.w3c.dom.Node;
/**
* DOM-based abstract implementation of XMLStructure.
*
*/
public abstract class DOMStructure extends BaseStructure {
public abstract class DOMStructure implements XMLStructure {
public abstract void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context) throws MarshalException;
public final boolean isFeatureSupported(String feature) {
if (feature == null) {
throw new NullPointerException();
} else {
return false;
}
}
public abstract void marshal(Node parent, String dsPrefix,
DOMCryptoContext context) throws MarshalException;
}

View File

@ -82,7 +82,6 @@ public class DOMSubTreeData implements NodeSetData<Node> {
this.withComments = !excludeComments;
}
@Override
public boolean hasNext() {
if (nodeSet == null) {
nodeSet = dereferenceSameDocumentURI(root);
@ -91,7 +90,6 @@ public class DOMSubTreeData implements NodeSetData<Node> {
return li.hasNext();
}
@Override
public Node next() {
if (nodeSet == null) {
nodeSet = dereferenceSameDocumentURI(root);
@ -104,7 +102,6 @@ public class DOMSubTreeData implements NodeSetData<Node> {
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}

View File

@ -37,12 +37,14 @@ import java.security.spec.AlgorithmParameterSpec;
import javax.xml.crypto.Data;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.TransformException;
import javax.xml.crypto.dsig.TransformService;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -50,7 +52,7 @@ import org.w3c.dom.Node;
* DOM-based abstract implementation of Transform.
*
*/
public class DOMTransform extends BaseStructure implements Transform {
public class DOMTransform extends DOMStructure implements Transform {
protected TransformService spi;
@ -74,6 +76,7 @@ public class DOMTransform extends BaseStructure implements Transform {
throws MarshalException
{
String algorithm = DOMUtils.getAttributeValue(transElem, "Algorithm");
if (provider == null) {
try {
spi = TransformService.getInstance(algorithm, "DOM");
@ -98,12 +101,10 @@ public class DOMTransform extends BaseStructure implements Transform {
}
}
@Override
public final AlgorithmParameterSpec getParameterSpec() {
return spi.getParameterSpec();
}
@Override
public final String getAlgorithm() {
return spi.getAlgorithm();
}
@ -111,18 +112,29 @@ public class DOMTransform extends BaseStructure implements Transform {
/**
* This method marshals any algorithm-specific parameters.
*/
public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
@Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
String parentLocalName = xwriter.getCurrentLocalName();
String localName = "Transforms".equals(parentLocalName) ? "Transform" : "CanonicalizationMethod";
xwriter.writeStartElement(dsPrefix, localName, XMLSignature.XMLNS);
xwriter.writeAttribute("", "", "Algorithm", getAlgorithm());
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
javax.xml.crypto.XMLStructure xmlStruct = xwriter.getCurrentNodeAsStructure();
spi.marshalParams(xmlStruct, context);
Element transformElem = null;
if (parent.getLocalName().equals("Transforms")) {
transformElem = DOMUtils.createElement(ownerDoc, "Transform",
XMLSignature.XMLNS,
dsPrefix);
} else {
transformElem = DOMUtils.createElement(ownerDoc,
"CanonicalizationMethod",
XMLSignature.XMLNS,
dsPrefix);
}
DOMUtils.setAttribute(transformElem, "Algorithm", getAlgorithm());
xwriter.writeEndElement(); // "Transforms" or "CanonicalizationMethod"
spi.marshalParams(new javax.xml.crypto.dom.DOMStructure(transformElem),
context);
parent.appendChild(transformElem);
}
/**
@ -136,7 +148,6 @@ public class DOMTransform extends BaseStructure implements Transform {
* @throws XMLSignatureException if an unexpected error occurs while
* executing the transform
*/
@Override
public Data transform(Data data, XMLCryptoContext xc)
throws TransformException
{
@ -156,7 +167,6 @@ public class DOMTransform extends BaseStructure implements Transform {
* @throws XMLSignatureException if an unexpected error occurs while
* executing the transform
*/
@Override
public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
throws TransformException
{
@ -210,9 +220,8 @@ public class DOMTransform extends BaseStructure implements Transform {
Data transform(Data data, XMLCryptoContext xc, DOMSignContext context)
throws MarshalException, TransformException
{
Node parent = context.getParent();
XmlWriter xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), parent);
marshal(xwriter, DOMUtils.getSignaturePrefix(context), context);
marshal(context.getParent(),
DOMUtils.getSignaturePrefix(context), context);
return transform(data, xc);
}
}

View File

@ -54,7 +54,6 @@ public final class DOMURIDereferencer implements URIDereferencer {
Init.init();
}
@Override
public Data dereference(URIReference uriRef, XMLCryptoContext context)
throws URIReferenceException {

View File

@ -92,7 +92,9 @@ public final class DOMUtils {
public static Element createElement(Document doc, String tag,
String nsURI, String prefix)
{
return doc.createElementNS(nsURI, getQNameString(prefix, tag));
String qName = (prefix == null || prefix.length() == 0)
? tag : prefix + ":" + tag;
return doc.createElementNS(nsURI, qName);
}
/**
@ -335,25 +337,20 @@ public final class DOMUtils {
this.nl = nl;
}
@Override
public int size() { return nl.getLength(); }
@Override
public Iterator<Node> iterator() {
return new Iterator<Node>() {
private int index;
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public Node next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return nl.item(index++);
}
@Override
public boolean hasNext() {
return index < nl.getLength();
}

View File

@ -34,10 +34,13 @@ import java.security.cert.*;
import java.util.*;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
import javax.security.auth.x500.X500Principal;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -48,7 +51,7 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
*
*/
//@@@ check for illegal combinations of data violating MUSTs in W3c spec
public final class DOMX509Data extends BaseStructure implements X509Data {
public final class DOMX509Data extends DOMStructure implements X509Data {
private final List<Object> content;
private CertificateFactory cf;
@ -113,7 +116,7 @@ public final class DOMX509Data extends BaseStructure implements X509Data {
newContent.add(childElem.getFirstChild().getNodeValue());
} else if ("X509SKI".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
String content = XMLUtils.getFullTextChildrenFromElement(childElem);
newContent.add(Base64.getMimeDecoder().decode(content));
newContent.add(XMLUtils.decode(content));
} else if ("X509CRL".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
newContent.add(unmarshalX509CRL(childElem));
} else {
@ -125,68 +128,89 @@ public final class DOMX509Data extends BaseStructure implements X509Data {
this.content = Collections.unmodifiableList(newContent);
}
@Override
public List<Object> getContent() {
return content;
}
public static void marshal(XmlWriter xwriter, X509Data x509Data, String dsPrefix, XMLCryptoContext context)
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
xwriter.writeStartElement(dsPrefix, "X509Data", XMLSignature.XMLNS);
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element xdElem = DOMUtils.createElement(ownerDoc, "X509Data",
XMLSignature.XMLNS, dsPrefix);
List<?> content = x509Data.getContent();
// append children and preserve order
for (int i = 0, size = content.size(); i < size; i++) {
Object object = content.get(i);
if (object instanceof X509Certificate) {
marshalCert(xwriter, (X509Certificate) object, dsPrefix);
marshalCert((X509Certificate)object,xdElem,ownerDoc,dsPrefix);
} else if (object instanceof XMLStructure) {
xwriter.marshalStructure((XMLStructure) object, dsPrefix, context);
if (object instanceof X509IssuerSerial) {
((DOMX509IssuerSerial)object).marshal
(xdElem, dsPrefix, context);
} else {
javax.xml.crypto.dom.DOMStructure domContent =
(javax.xml.crypto.dom.DOMStructure)object;
DOMUtils.appendChild(xdElem, domContent.getNode());
}
} else if (object instanceof byte[]) {
marshalSKI(xwriter, (byte[]) object, dsPrefix);
marshalSKI((byte[])object, xdElem, ownerDoc, dsPrefix);
} else if (object instanceof String) {
marshalSubjectName(xwriter, (String) object, dsPrefix);
marshalSubjectName((String)object, xdElem, ownerDoc,dsPrefix);
} else if (object instanceof X509CRL) {
marshalCRL(xwriter, (X509CRL) object, dsPrefix);
marshalCRL((X509CRL)object, xdElem, ownerDoc, dsPrefix);
}
}
xwriter.writeEndElement(); // "X509Data"
parent.appendChild(xdElem);
}
private static void marshalSKI(XmlWriter xwriter, byte[] skid, String dsPrefix)
private void marshalSKI(byte[] skid, Node parent, Document doc,
String dsPrefix)
{
xwriter.writeTextElement(dsPrefix, "X509SKI", XMLSignature.XMLNS,
Base64.getMimeEncoder().encodeToString(skid));
Element skidElem = DOMUtils.createElement(doc, "X509SKI",
XMLSignature.XMLNS, dsPrefix);
skidElem.appendChild(doc.createTextNode(XMLUtils.encodeToString(skid)));
parent.appendChild(skidElem);
}
private static void marshalSubjectName(XmlWriter xwriter, String name, String dsPrefix)
private void marshalSubjectName(String name, Node parent, Document doc,
String dsPrefix)
{
xwriter.writeTextElement(dsPrefix, "X509SubjectName", XMLSignature.XMLNS, name);
Element snElem = DOMUtils.createElement(doc, "X509SubjectName",
XMLSignature.XMLNS, dsPrefix);
snElem.appendChild(doc.createTextNode(name));
parent.appendChild(snElem);
}
private static void marshalCert(XmlWriter xwriter, X509Certificate cert, String dsPrefix)
private void marshalCert(X509Certificate cert, Node parent, Document doc,
String dsPrefix)
throws MarshalException
{
Element certElem = DOMUtils.createElement(doc, "X509Certificate",
XMLSignature.XMLNS, dsPrefix);
try {
byte[] encoded = cert.getEncoded();
xwriter.writeTextElement(dsPrefix, "X509Certificate", XMLSignature.XMLNS,
Base64.getMimeEncoder().encodeToString(encoded));
certElem.appendChild(doc.createTextNode
(XMLUtils.encodeToString(cert.getEncoded())));
} catch (CertificateEncodingException e) {
throw new MarshalException("Error encoding X509Certificate", e);
}
parent.appendChild(certElem);
}
private static void marshalCRL(XmlWriter xwriter, X509CRL crl, String dsPrefix)
private void marshalCRL(X509CRL crl, Node parent, Document doc,
String dsPrefix)
throws MarshalException
{
Element crlElem = DOMUtils.createElement(doc, "X509CRL",
XMLSignature.XMLNS, dsPrefix);
try {
byte[] encoded = crl.getEncoded();
xwriter.writeTextElement(dsPrefix, "X509CRL", XMLSignature.XMLNS,
Base64.getMimeEncoder().encodeToString(encoded));
crlElem.appendChild(doc.createTextNode
(XMLUtils.encodeToString(crl.getEncoded())));
} catch (CRLException e) {
throw new MarshalException("Error encoding X509CRL", e);
}
parent.appendChild(crlElem);
}
private X509Certificate unmarshalX509Certificate(Element elem)
@ -218,7 +242,7 @@ public final class DOMX509Data extends BaseStructure implements X509Data {
cf = CertificateFactory.getInstance("X.509");
}
String content = XMLUtils.getFullTextChildrenFromElement(elem);
return new ByteArrayInputStream(Base64.getMimeDecoder().decode(content));
return new ByteArrayInputStream(XMLUtils.decode(content));
} catch (CertificateException e) {
throw new MarshalException("Cannot create CertificateFactory", e);
}

View File

@ -29,20 +29,22 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
import java.math.BigInteger;
import javax.security.auth.x500.X500Principal;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* DOM-based implementation of X509IssuerSerial.
*
*/
public final class DOMX509IssuerSerial extends BaseStructure
public final class DOMX509IssuerSerial extends DOMStructure
implements X509IssuerSerial {
private final String issuerName;
@ -89,16 +91,33 @@ public final class DOMX509IssuerSerial extends BaseStructure
serialNumber = new BigInteger(sNElem.getFirstChild().getNodeValue());
}
@Override
public String getIssuerName() {
return issuerName;
}
@Override
public BigInteger getSerialNumber() {
return serialNumber;
}
@Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
Element isElem = DOMUtils.createElement(ownerDoc, "X509IssuerSerial",
XMLSignature.XMLNS, dsPrefix);
Element inElem = DOMUtils.createElement(ownerDoc, "X509IssuerName",
XMLSignature.XMLNS, dsPrefix);
Element snElem = DOMUtils.createElement(ownerDoc, "X509SerialNumber",
XMLSignature.XMLNS, dsPrefix);
inElem.appendChild(ownerDoc.createTextNode(issuerName));
snElem.appendChild(ownerDoc.createTextNode(serialNumber.toString()));
isElem.appendChild(inElem);
isElem.appendChild(snElem);
parent.appendChild(isElem);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {

View File

@ -29,12 +29,14 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
import javax.xml.crypto.dsig.*;
import java.security.Provider;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
@ -43,12 +45,13 @@ import org.w3c.dom.Node;
* DOM-based implementation of XMLObject.
*
*/
public final class DOMXMLObject extends BaseStructure implements XMLObject {
public final class DOMXMLObject extends DOMStructure implements XMLObject {
private final String id;
private final String mimeType;
private final String encoding;
private final List<XMLStructure> content;
private Element objectElem;
/**
* Creates an {@code XMLObject} from the specified parameters.
@ -142,51 +145,56 @@ public final class DOMXMLObject extends BaseStructure implements XMLObject {
} else {
this.content = Collections.unmodifiableList(newContent);
}
this.objectElem = objElem;
}
@Override
public List<XMLStructure> getContent() {
return content;
}
@Override
public String getId() {
return id;
}
@Override
public String getMimeType() {
return mimeType;
}
@Override
public String getEncoding() {
return encoding;
}
public static void marshal(XmlWriter xwriter, XMLObject xmlObj, String dsPrefix, XMLCryptoContext context)
@Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException {
xwriter.writeStartElement(dsPrefix, "Object", XMLSignature.XMLNS);
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
// set attributes
xwriter.writeIdAttribute("", "", "Id", xmlObj.getId());
xwriter.writeAttribute("", "", "MimeType", xmlObj.getMimeType());
xwriter.writeAttribute("", "", "Encoding", xmlObj.getEncoding());
Element objElem = objectElem != null ? objectElem : null;
if (objElem == null) {
objElem = DOMUtils.createElement(ownerDoc, "Object",
XMLSignature.XMLNS, dsPrefix);
// create and append any elements and mixed content, if necessary
@SuppressWarnings("unchecked")
List<XMLStructure> content = xmlObj.getContent();
for (XMLStructure object : content) {
xwriter.marshalStructure(object, dsPrefix, context);
// set attributes
DOMUtils.setAttributeID(objElem, "Id", id);
DOMUtils.setAttribute(objElem, "MimeType", mimeType);
DOMUtils.setAttribute(objElem, "Encoding", encoding);
// create and append any elements and mixed content, if necessary
for (XMLStructure object : content) {
if (object instanceof DOMStructure) {
((DOMStructure)object).marshal(objElem, dsPrefix, context);
} else {
javax.xml.crypto.dom.DOMStructure domObject =
(javax.xml.crypto.dom.DOMStructure)object;
DOMUtils.appendChild(objElem, domObject.getNode());
}
}
}
xwriter.writeEndElement(); // "Object"
parent.appendChild(objElem);
}
@SuppressWarnings("unchecked")
public static List<XMLStructure> getXmlObjectContent(XMLObject xo) {
return xo.getContent();
}
@Override
public boolean equals(Object o) {
if (this == o) {
@ -208,7 +216,7 @@ public final class DOMXMLObject extends BaseStructure implements XMLObject {
: mimeType.equals(oxo.getMimeType());
return idsEqual && encodingsEqual && mimeTypesEqual &&
equalsContent(getXmlObjectContent(oxo));
equalsContent(oxo.getContent());
}
@Override

View File

@ -36,6 +36,7 @@
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
@ -46,11 +47,12 @@ import java.security.Key;
import java.security.Provider;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -70,6 +72,9 @@ public final class DOMXMLSignature extends DOMStructure
private KeyInfo ki;
private List<XMLObject> objects;
private SignedInfo si;
private Document ownerDoc = null;
private Element localSigElem = null;
private Element sigElem = null;
private boolean validationStatus;
private boolean validated = false;
private KeySelectorResult ksr;
@ -127,7 +132,8 @@ public final class DOMXMLSignature extends DOMStructure
Provider provider)
throws MarshalException
{
Element localSigElem = sigElem;
localSigElem = sigElem;
ownerDoc = localSigElem.getOwnerDocument();
// get Id attribute, if specified
id = DOMUtils.getAttributeValue(localSigElem, "Id");
@ -171,69 +177,74 @@ public final class DOMXMLSignature extends DOMStructure
}
}
@Override
public String getId() {
return id;
}
@Override
public KeyInfo getKeyInfo() {
return ki;
}
@Override
public SignedInfo getSignedInfo() {
return si;
}
@Override
public List<XMLObject> getObjects() {
return objects;
}
@Override
public SignatureValue getSignatureValue() {
return sv;
}
@Override
public KeySelectorResult getKeySelectorResult() {
return ksr;
}
@Override
public void marshal(XmlWriter xwriter, String dsPrefix, XMLCryptoContext context)
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
// rationalize the prefix.
String prefix = dsPrefix;
if (prefix == null) {
prefix = "";
marshal(parent, null, dsPrefix, context);
}
public void marshal(Node parent, Node nextSibling, String dsPrefix,
DOMCryptoContext context)
throws MarshalException
{
ownerDoc = DOMUtils.getOwnerDocument(parent);
sigElem = DOMUtils.createElement(ownerDoc, "Signature",
XMLSignature.XMLNS, dsPrefix);
// append xmlns attribute
if (dsPrefix == null || dsPrefix.length() == 0) {
sigElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
XMLSignature.XMLNS);
} else {
sigElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" +
dsPrefix, XMLSignature.XMLNS);
}
xwriter.writeStartElement(prefix, "Signature", XMLSignature.XMLNS);
xwriter.writeNamespace(prefix, XMLSignature.XMLNS);
// append Id attribute
xwriter.writeIdAttribute("", "", "Id", id);
// create and append SignedInfo element
((DOMSignedInfo) si).marshal(xwriter, prefix, context);
((DOMSignedInfo)si).marshal(sigElem, dsPrefix, context);
// create and append SignatureValue element
((DOMSignatureValue) sv).marshal(xwriter, prefix, context);
((DOMSignatureValue)sv).marshal(sigElem, dsPrefix, context);
// create and append KeyInfo element if necessary
if (ki != null) {
DOMKeyInfo.marshal(xwriter, ki, prefix, context);
((DOMKeyInfo)ki).marshal(sigElem, null, dsPrefix, context);
}
// create and append Object elements if necessary
for (XMLObject xmlObj : objects) {
DOMXMLObject.marshal(xwriter, xmlObj, prefix, context);
for (int i = 0, size = objects.size(); i < size; i++) {
((DOMXMLObject)objects.get(i)).marshal(sigElem, dsPrefix, context);
}
xwriter.writeEndElement(); // "Signature"
// append Id attribute
DOMUtils.setAttributeID(sigElem, "Id", id);
parent.insertBefore(sigElem, nextSibling);
}
@Override
@ -262,7 +273,8 @@ public final class DOMXMLSignature extends DOMStructure
}
// validate all References
List<Reference> refs = DOMSignedInfo.getSignedInfoReferences(this.si);
@SuppressWarnings("unchecked")
List<Reference> refs = this.si.getReferences();
boolean validateRefs = true;
for (int i = 0, size = refs.size(); validateRefs && i < size; i++) {
Reference ref = refs.get(i);
@ -284,14 +296,16 @@ public final class DOMXMLSignature extends DOMStructure
{
for (int i=0, size=objects.size(); validateMans && i < size; i++) {
XMLObject xo = objects.get(i);
List<XMLStructure> content = DOMXMLObject.getXmlObjectContent(xo);
@SuppressWarnings("unchecked")
List<XMLStructure> content = xo.getContent();
int csize = content.size();
for (int j = 0; validateMans && j < csize; j++) {
XMLStructure xs = content.get(j);
if (xs instanceof Manifest) {
LOG.debug("validating manifest");
Manifest man = (Manifest)xs;
List<Reference> manRefs = DOMManifest.getManifestReferences(man);
@SuppressWarnings("unchecked")
List<Reference> manRefs = man.getReferences();
int rsize = manRefs.size();
for (int k = 0; validateMans && k < rsize; k++) {
Reference ref = manRefs.get(k);
@ -319,13 +333,8 @@ public final class DOMXMLSignature extends DOMStructure
throw new NullPointerException("signContext cannot be null");
}
DOMSignContext context = (DOMSignContext)signContext;
Node nextSibling = context.getNextSibling();
XmlWriterToTree xwriter = new XmlWriterToTree(Marshaller.getMarshallers(), context.getParent(), nextSibling);
marshal(xwriter,
DOMUtils.getSignaturePrefix(signContext), signContext);
Element sigElem = xwriter.getCreatedElement();
marshal(context.getParent(), context.getNextSibling(),
DOMUtils.getSignaturePrefix(context), context);
// generate references and signature value
List<Reference> allReferences = new ArrayList<>();
@ -335,18 +344,21 @@ public final class DOMXMLSignature extends DOMStructure
signatureIdMap = new HashMap<>();
signatureIdMap.put(id, this);
signatureIdMap.put(si.getId(), si);
List<Reference> refs = DOMSignedInfo.getSignedInfoReferences(si);
@SuppressWarnings("unchecked")
List<Reference> refs = si.getReferences();
for (Reference ref : refs) {
signatureIdMap.put(ref.getId(), ref);
}
for (XMLObject obj : objects) {
signatureIdMap.put(obj.getId(), obj);
List<XMLStructure> content = DOMXMLObject.getXmlObjectContent(obj);
@SuppressWarnings("unchecked")
List<XMLStructure> content = obj.getContent();
for (XMLStructure xs : content) {
if (xs instanceof Manifest) {
Manifest man = (Manifest)xs;
signatureIdMap.put(man.getId(), man);
List<Reference> manRefs = DOMManifest.getManifestReferences(man);
@SuppressWarnings("unchecked")
List<Reference> manRefs = man.getReferences();
for (Reference ref : manRefs) {
allReferences.add(ref);
signatureIdMap.put(ref.getId(), ref);
@ -389,14 +401,14 @@ public final class DOMXMLSignature extends DOMStructure
// calculate signature value
try {
Element sigValue = (Element) sigElem.getElementsByTagNameNS(XMLSignature.XMLNS, "SignatureValue").item(0);
xwriter.resetToNewParent(sigValue);
byte[] val = ((AbstractDOMSignatureMethod)
si.getSignatureMethod()).sign(signingKey, (DOMSignedInfo) si, signContext);
((DOMSignatureValue)sv).setValue(xwriter, val);
si.getSignatureMethod()).sign(signingKey, si, signContext);
((DOMSignatureValue)sv).setValue(val);
} catch (InvalidKeyException ike) {
throw new XMLSignatureException(ike);
}
this.localSigElem = sigElem;
}
@Override
@ -484,6 +496,7 @@ public final class DOMXMLSignature extends DOMStructure
private String id;
private byte[] value;
private String valueBase64;
private Element sigValueElem;
private boolean validated = false;
private boolean validationStatus;
@ -496,17 +509,22 @@ public final class DOMXMLSignature extends DOMStructure
{
// base64 decode signatureValue
String content = XMLUtils.getFullTextChildrenFromElement(sigValueElem);
value = Base64.getMimeDecoder().decode(content);
value = XMLUtils.decode(content);
id = DOMUtils.getIdAttributeValue(sigValueElem, "Id");
Attr attr = sigValueElem.getAttributeNodeNS(null, "Id");
if (attr != null) {
id = attr.getValue();
sigValueElem.setIdAttributeNode(attr, true);
} else {
id = null;
}
this.sigValueElem = sigValueElem;
}
@Override
public String getId() {
return id;
}
@Override
public byte[] getValue() {
return (value == null) ? null : value.clone();
}
@ -552,7 +570,7 @@ public final class DOMXMLSignature extends DOMStructure
// canonicalize SignedInfo and verify signature
try {
validationStatus = ((AbstractDOMSignatureMethod)sm).verify
(validationKey, (DOMSignedInfo) si, value, validateContext);
(validationKey, si, value, validateContext);
} catch (Exception e) {
throw new XMLSignatureException(e);
}
@ -590,29 +608,25 @@ public final class DOMXMLSignature extends DOMStructure
return result;
}
@Override
public void marshal(XmlWriter xwriter, String dsPrefix,
XMLCryptoContext context)
public void marshal(Node parent, String dsPrefix,
DOMCryptoContext context)
throws MarshalException
{
// create SignatureValue element
xwriter.writeStartElement(dsPrefix, "SignatureValue", XMLSignature.XMLNS);
sigValueElem = DOMUtils.createElement(ownerDoc, "SignatureValue",
XMLSignature.XMLNS, dsPrefix);
if (valueBase64 != null) {
sigValueElem.appendChild(ownerDoc.createTextNode(valueBase64));
}
// append Id attribute, if specified
xwriter.writeIdAttribute("", "", "Id", id);
if (valueBase64 != null) {
xwriter.writeCharacters(valueBase64);
}
xwriter.writeEndElement(); // "SignatureValue"
DOMUtils.setAttributeID(sigValueElem, "Id", id);
parent.appendChild(sigValueElem);
}
void setValue(XmlWriter xwriter, byte[] value) {
void setValue(byte[] value) {
this.value = value;
valueBase64 = Base64.getMimeEncoder().encodeToString(value);
if (xwriter != null) {
xwriter.writeCharacters(valueBase64);
}
valueBase64 = XMLUtils.encodeToString(value);
sigValueElem.appendChild(ownerDoc.createTextNode(valueBase64));
}
}
}

View File

@ -54,24 +54,20 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
*/
public DOMXMLSignatureFactory() {}
@Override
public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki) {
return new DOMXMLSignature(si, ki, null, null, null);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki,
List objects, String id, String signatureValueId) {
return new DOMXMLSignature(si, ki, objects, id, signatureValueId);
}
@Override
public Reference newReference(String uri, DigestMethod dm) {
return newReference(uri, dm, null, null, null);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public Reference newReference(String uri, DigestMethod dm, List transforms,
String type, String id) {
@ -96,7 +92,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
(uri, type, dm, appliedTransforms, result, transforms, id, getProvider());
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public Reference newReference(String uri, DigestMethod dm, List transforms,
String type, String id, byte[] digestValue) {
@ -107,14 +102,12 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
(uri, type, dm, null, null, transforms, id, digestValue, getProvider());
}
@Override
@SuppressWarnings({ "rawtypes" })
public SignedInfo newSignedInfo(CanonicalizationMethod cm,
SignatureMethod sm, List references) {
return newSignedInfo(cm, sm, references, null);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public SignedInfo newSignedInfo(CanonicalizationMethod cm,
SignatureMethod sm, List references, String id) {
@ -122,39 +115,33 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
}
// Object factory methods
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public XMLObject newXMLObject(List content, String id, String mimeType,
String encoding) {
return new DOMXMLObject(content, id, mimeType, encoding);
}
@Override
@SuppressWarnings({ "rawtypes" })
public Manifest newManifest(List references) {
return newManifest(references, null);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public Manifest newManifest(List references, String id) {
return new DOMManifest(references, id);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public SignatureProperties newSignatureProperties(List props, String id) {
return new DOMSignatureProperties(props, id);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public SignatureProperty newSignatureProperty
(List info, String target, String id) {
return new DOMSignatureProperty(info, target, id);
}
@Override
public XMLSignature unmarshalXMLSignature(XMLValidateContext context)
throws MarshalException {
@ -164,7 +151,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
return unmarshal(((DOMValidateContext) context).getNode(), context);
}
@Override
public XMLSignature unmarshalXMLSignature(XMLStructure xmlStructure)
throws MarshalException {
@ -212,7 +198,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
}
}
@Override
public boolean isFeatureSupported(String feature) {
if (feature == null) {
throw new NullPointerException();
@ -221,7 +206,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
}
}
@Override
public DigestMethod newDigestMethod(String algorithm,
DigestMethodParameterSpec params) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
@ -255,7 +239,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
}
}
@Override
public SignatureMethod newSignatureMethod(String algorithm,
SignatureMethodParameterSpec params) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
@ -321,7 +304,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
}
}
@Override
public Transform newTransform(String algorithm,
TransformParameterSpec params) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
@ -341,7 +323,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
return new DOMTransform(spi);
}
@Override
public Transform newTransform(String algorithm,
XMLStructure params) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
@ -364,7 +345,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
return new DOMTransform(spi);
}
@Override
public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
C14NMethodParameterSpec params) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
@ -383,7 +363,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
return new DOMCanonicalizationMethod(spi);
}
@Override
public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
XMLStructure params) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
@ -406,7 +385,6 @@ public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
return new DOMCanonicalizationMethod(spi);
}
@Override
public URIDereferencer getURIDereferencer() {
return DOMURIDereferencer.INSTANCE;
}

View File

@ -57,7 +57,6 @@ import org.w3c.dom.NamedNodeMap;
*/
public final class DOMXPathFilter2Transform extends ApacheTransform {
@Override
public void init(TransformParameterSpec params)
throws InvalidAlgorithmParameterException
{
@ -70,7 +69,6 @@ public final class DOMXPathFilter2Transform extends ApacheTransform {
this.params = params;
}
@Override
public void init(XMLStructure parent, XMLCryptoContext context)
throws InvalidAlgorithmParameterException
{
@ -126,7 +124,6 @@ public final class DOMXPathFilter2Transform extends ApacheTransform {
this.params = new XPathFilter2ParameterSpec(list);
}
@Override
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
throws MarshalException
{

View File

@ -60,7 +60,6 @@ public final class DOMXPathTransform extends ApacheTransform {
this.params = params;
}
@Override
public void init(XMLStructure parent, XMLCryptoContext context)
throws InvalidAlgorithmParameterException
{
@ -89,7 +88,6 @@ public final class DOMXPathTransform extends ApacheTransform {
}
}
@Override
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
throws MarshalException
{

View File

@ -55,7 +55,6 @@ public final class DOMXSLTTransform extends ApacheTransform {
this.params = params;
}
@Override
public void init(XMLStructure parent, XMLCryptoContext context)
throws InvalidAlgorithmParameterException {
@ -68,7 +67,6 @@ public final class DOMXSLTTransform extends ApacheTransform {
(new javax.xml.crypto.dom.DOMStructure(sheet));
}
@Override
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
throws MarshalException {
super.marshalParams(parent, context);

View File

@ -1,353 +0,0 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/**
* 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.
*/
package org.jcp.xml.dsig.internal.dom;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Manifest;
import javax.xml.crypto.dsig.SignatureProperties;
import javax.xml.crypto.dsig.SignatureProperty;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyName;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.keyinfo.PGPData;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* Defines the individual marshallers for each of the different javax.xml.crypto structures.
*/
class Marshaller {
private Marshaller() {
// complete
}
public static List<XmlWriter.ToMarshal<? extends XMLStructure>> getMarshallers() {
return MARSHALLERS;
}
/**
* Marshals a {@link KeyName}.
*
* @param xwriter
* @param keyName
* @param dsPrefix
*/
public static void marshalKeyName(XmlWriter xwriter, KeyName keyName, String dsPrefix) {
xwriter.writeTextElement(dsPrefix, "KeyName", XMLSignature.XMLNS, keyName.getName());
}
/**
* Marshals a {@link PGPData}
*
* @param xwriter
* @param pgpData
* @param dsPrefix
* @param context
* @throws MarshalException
*/
public static void marshalPGPData(XmlWriter xwriter, PGPData pgpData, String dsPrefix, XMLCryptoContext context)
throws MarshalException {
xwriter.writeStartElement(dsPrefix, "PGPData", XMLSignature.XMLNS);
// create and append PGPKeyID element
byte[] keyId = pgpData.getKeyId();
if (keyId != null) {
xwriter.writeTextElement(dsPrefix, "PGPKeyID", XMLSignature.XMLNS,
Base64.getMimeEncoder().encodeToString(keyId));
}
// create and append PGPKeyPacket element
byte[] keyPacket = pgpData.getKeyPacket();
if (keyPacket != null) {
xwriter.writeTextElement(dsPrefix, "XMLSignature.XMLNS", XMLSignature.XMLNS,
Base64.getMimeEncoder().encodeToString(keyPacket));
}
// create and append any elements
@SuppressWarnings("unchecked")
List<XMLStructure> externalElements = pgpData.getExternalElements();
for (XMLStructure externalItem : externalElements) {
xwriter.marshalStructure(externalItem, dsPrefix, context);
}
xwriter.writeEndElement(); // "PGPData"
}
/**
* Marshals an {@link X509IssuerSerial}
*
* @param xwriter
* @param issuerSerial
* @param dsPrefix
*/
public static void marshalX509IssuerSerial(XmlWriter xwriter, X509IssuerSerial issuerSerial, String dsPrefix) {
xwriter.writeStartElement(dsPrefix, "X509IssuerSerial", XMLSignature.XMLNS);
xwriter.writeTextElement(dsPrefix, "X509IssuerName", XMLSignature.XMLNS,
issuerSerial.getIssuerName());
xwriter.writeTextElement(dsPrefix, "X509SerialNumber", XMLSignature.XMLNS,
issuerSerial.getSerialNumber().toString());
xwriter.writeEndElement(); // "X509IssuerSerial"
}
private static XmlWriter.ToMarshal<KeyName> Marshal_KeyName = new XmlWriter.ToMarshal<KeyName>(KeyName.class) {
@Override
public void marshalObject(XmlWriter xwriter, KeyName toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
Marshaller.marshalKeyName(xwriter, toMarshal, dsPrefix);
}
};
private static XmlWriter.ToMarshal<KeyInfo> Marshal_KeyInfo = new XmlWriter.ToMarshal<KeyInfo>(KeyInfo.class) {
@Override
public void marshalObject(XmlWriter xwriter, KeyInfo toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
DOMKeyInfo.marshal(xwriter, toMarshal, dsPrefix, context);
}
};
private static XmlWriter.ToMarshal<KeyValue> Marshal_KeyValue = new XmlWriter.ToMarshal<KeyValue>(KeyValue.class) {
@Override
public void marshalObject(XmlWriter xwriter, KeyValue toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
// Since DOMKeyValue allows for deserializing unrecognized keys, and that
// capability isn't available via the KeyValue interface, this must continue
// to cast to DOMKeyValue.
DOMKeyValue<?> dkv = (DOMKeyValue<?>) toMarshal;
dkv.marshal( xwriter, dsPrefix, context);
}
};
private static XmlWriter.ToMarshal<X509IssuerSerial> Marshal_X509IssuerSerial =
new XmlWriter.ToMarshal<X509IssuerSerial>(X509IssuerSerial.class) {
@Override
public void marshalObject(XmlWriter xwriter, X509IssuerSerial toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
Marshaller.marshalX509IssuerSerial( xwriter, toMarshal, dsPrefix);
}
};
private static XmlWriter.ToMarshal<X509Data> Marshal_X509Data =
new XmlWriter.ToMarshal<X509Data>(X509Data.class) {
@Override
public void marshalObject(XmlWriter xwriter, X509Data toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
DOMX509Data.marshal( xwriter, toMarshal, dsPrefix, context);
}
};
private static XmlWriter.ToMarshal<DigestMethod> Marshal_DigestMethod =
new XmlWriter.ToMarshal<DigestMethod>(DigestMethod.class) {
@Override
public void marshalObject(XmlWriter xwriter, DigestMethod toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
DOMDigestMethod.marshal( xwriter, toMarshal, dsPrefix);
}
};
private static XmlWriter.ToMarshal<PGPData> Marshal_PGPData =
new XmlWriter.ToMarshal<PGPData>(PGPData.class) {
@Override
public void marshalObject(XmlWriter xwriter, PGPData toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
Marshaller.marshalPGPData( xwriter, toMarshal, dsPrefix, context);
}
};
private static XmlWriter.ToMarshal<SignatureProperty> Marshal_SignatureProperty =
new XmlWriter.ToMarshal<SignatureProperty>(SignatureProperty.class) {
@Override
public void marshalObject(XmlWriter xwriter, SignatureProperty toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
DOMSignatureProperty.marshal(xwriter, toMarshal, dsPrefix, context);
}
};
private static XmlWriter.ToMarshal<SignatureProperties> Marshal_SignatureProperties =
new XmlWriter.ToMarshal<SignatureProperties>(SignatureProperties.class) {
@Override
public void marshalObject(XmlWriter xwriter, SignatureProperties toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
DOMSignatureProperties.marshal(xwriter, toMarshal, dsPrefix, context);
}
};
private static XmlWriter.ToMarshal<DOMSignatureMethod> Marshal_DOMSignatureMethod =
new XmlWriter.ToMarshal<DOMSignatureMethod>(DOMSignatureMethod.class) {
@Override
public void marshalObject(XmlWriter xwriter, DOMSignatureMethod toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
toMarshal.marshal(xwriter, dsPrefix);
}
};
private static XmlWriter.ToMarshal<DOMTransform> Marshal_DOMTransform =
new XmlWriter.ToMarshal<DOMTransform>(DOMTransform.class) {
@Override
public void marshalObject(XmlWriter xwriter, DOMTransform toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
toMarshal.marshal(xwriter, dsPrefix, context);
}
};
private static XmlWriter.ToMarshal<Manifest> Marshal_Manifest =
new XmlWriter.ToMarshal<Manifest>(Manifest.class) {
@Override
public void marshalObject(XmlWriter xwriter, Manifest toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
DOMManifest.marshal(xwriter, toMarshal, dsPrefix, context);
}
};
private static XmlWriter.ToMarshal<DOMStructure> Marshal_DOMStructure =
new XmlWriter.ToMarshal<DOMStructure>(DOMStructure.class) {
@Override
public void marshalObject(XmlWriter xwriter, DOMStructure toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
toMarshal.marshal(xwriter, dsPrefix, context);
}
};
private static XmlWriter.ToMarshal<javax.xml.crypto.dom.DOMStructure> Marshal_JavaXDOMStructure =
new XmlWriter.ToMarshal<javax.xml.crypto.dom.DOMStructure>(javax.xml.crypto.dom.DOMStructure.class) {
@Override
public void marshalObject(XmlWriter xwriter, javax.xml.crypto.dom.DOMStructure toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException {
marshalGenericNode(xwriter, toMarshal);
}
};
private static final List<XmlWriter.ToMarshal<? extends XMLStructure>> MARSHALLERS =
new ArrayList<XmlWriter.ToMarshal<? extends XMLStructure>>();
static {
MARSHALLERS.add(Marshal_KeyName);
MARSHALLERS.add(Marshal_KeyInfo);
MARSHALLERS.add(Marshal_KeyValue);
MARSHALLERS.add(Marshal_X509IssuerSerial);
MARSHALLERS.add(Marshal_X509Data);
MARSHALLERS.add(Marshal_DigestMethod);
MARSHALLERS.add(Marshal_PGPData);
MARSHALLERS.add(Marshal_SignatureProperty);
MARSHALLERS.add(Marshal_SignatureProperties);
MARSHALLERS.add(Marshal_DOMSignatureMethod);
MARSHALLERS.add(Marshal_DOMTransform);
MARSHALLERS.add(Marshal_Manifest);
MARSHALLERS.add(Marshal_DOMStructure);
MARSHALLERS.add(Marshal_JavaXDOMStructure);
}
private static void marshalGenericNode(XmlWriter xwriter, javax.xml.crypto.dom.DOMStructure xmlStruct) {
Node node = xmlStruct.getNode();
// if it is a namespace, make a copy.
if (DOMUtils.isNamespace(node)) {
xwriter.writeNamespace(node.getLocalName(), node.getTextContent());
}
else if (Node.ATTRIBUTE_NODE == node.getNodeType() ) {
sendAttributeToWriter(xwriter, (Attr) node);
}
else {
marshalGenericNode(xwriter, node);
}
}
private static void marshalGenericNode(XmlWriter xwriter, Node node) {
short nodeType = node.getNodeType();
if (DOMUtils.isNamespace(node)) {
xwriter.writeNamespace(node.getLocalName(), node.getTextContent());
}
else if (nodeType == Node.ATTRIBUTE_NODE) {
// if it is an attribute, make a copy.
sendAttributeToWriter(xwriter, (Attr) node);
}
else {
switch (nodeType) {
case Node.ELEMENT_NODE:
xwriter.writeStartElement(node.getPrefix(), node.getLocalName(), node.getNamespaceURI());
// emit all the namespaces and attributes.
NamedNodeMap nnm = node.getAttributes();
for (int idx = 0 ; idx < nnm.getLength() ; idx++) {
Attr attr = (Attr) nnm.item(idx);
// is this a namespace node?
if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(node.getNamespaceURI())) {
xwriter.writeNamespace(attr.getLocalName(), attr.getValue());
}
else {
// nope - standard attribute.
sendAttributeToWriter(xwriter, attr);
}
}
// now loop through all the children.
for (Node child = node.getFirstChild() ; child != null ; child = child.getNextSibling()) {
marshalGenericNode(xwriter, child);
}
xwriter.writeEndElement();
break;
case Node.COMMENT_NODE:
xwriter.writeComment(node.getTextContent());
break;
case Node.TEXT_NODE:
xwriter.writeCharacters(node.getTextContent());
break;
default:
// unhandled - don't care to deal with processing instructions.
break;
}
}
}
private static void sendAttributeToWriter(XmlWriter xwriter, Attr attr) {
if (attr.isId()) {
xwriter.writeIdAttribute(attr.getPrefix(), attr.getNamespaceURI(),
attr.getLocalName(), attr.getTextContent());
}
else {
if (attr.getNamespaceURI() == null && attr.getLocalName() == null) {
// Level 1 DOM attribute
xwriter.writeAttribute(null, null, attr.getName(), attr.getTextContent());
} else {
xwriter.writeAttribute(attr.getPrefix(), attr.getNamespaceURI(), attr.getLocalName(),
attr.getTextContent());
}
}
}
}

View File

@ -1,112 +0,0 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/**
* 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.
*/
package org.jcp.xml.dsig.internal.dom;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import org.w3c.dom.Attr;
/**
* This interface is used to construct XML via a sequence of API calls.
*
* <p>This is written to be similar to javax.xml.stream.XMLStreamWriter, but
* has slightly different requirements. Specifically, we need to be able to create
* an "ID" type attribute, and get the current node.
* </p>
*/
public interface XmlWriter {
/**
* Utility class that brings together the class, and the method for marshaling an
* instance of said class.
*
* @param <CLZ>
*/
abstract static class ToMarshal<CLZ extends XMLStructure> { //NOPMD
public final Class<CLZ> clazzToMatch;
public ToMarshal(Class<CLZ> clazzToMatch) {
this.clazzToMatch = clazzToMatch;
}
public abstract void marshalObject(XmlWriter xwriter, CLZ toMarshal, String dsPrefix,
XMLCryptoContext context) throws MarshalException;
}
/**
*
* @param prefix What prefix to use?
* @param localName What local name to use?
* @param namespaceURI What namespace URI?
*
* See also {@link javax.xml.stream.XMLStreamWriter#writeStartElement(String, String, String)}
*/
void writeStartElement(String prefix, String localName, String namespaceURI);
/**
* See also {@link javax.xml.stream.XMLStreamWriter#writeEndElement()}
*/
void writeEndElement();
/**
* Convenience method that writes both a start and end tag, with text contents as
* provided.
*
* @param prefix
* @param localName
* @param namespaceURI
* @param value
*/
void writeTextElement(String prefix, String localName, String namespaceURI, String value);
void writeNamespace(String prefix, String namespaceURI);
void writeCharacters(String text);
void writeComment(String text);
Attr writeAttribute(String prefix, String namespaceURI, String localName, String value);
void writeIdAttribute(String prefix, String namespaceURI, String localName, String value);
/**
* Get the local name of the current element.
* @return the local name of the current element.
*/
String getCurrentLocalName();
XMLStructure getCurrentNodeAsStructure();
/**
* This method marshals a structure, and relies on implementation specific details for how
* an instance of a particular class maps to the method that actually does the marshaling.
*
* @param toMarshal The object to be marshaled.
* @param dsPrefix The digital signature prefix.
* @param context The context for marshaling.
* @throws MarshalException Thrown if something goes wrong during the marshaling.
*/
void marshalStructure(XMLStructure toMarshal, String dsPrefix, XMLCryptoContext context) throws MarshalException;
}

View File

@ -1,208 +0,0 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/**
* 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.
*/
package org.jcp.xml.dsig.internal.dom;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMStructure;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
/**
* Manifestation of XmlWriter interface designed to write to a tree.
*/
public class XmlWriterToTree implements XmlWriter {
private Document factory;
private Element createdElement;
private Node nextSibling;
private Node currentNode;
private List<XmlWriter.ToMarshal<? extends XMLStructure>> m_marshallers;
public XmlWriterToTree(List<XmlWriter.ToMarshal<? extends XMLStructure>> marshallers, Node parent) {
m_marshallers = marshallers;
factory = parent instanceof Document ? (Document)parent : parent.getOwnerDocument();
currentNode = parent;
}
/**
* Reset to a new parent so that the writer can be re-used.
* @param newParent
*/
public void resetToNewParent(Node newParent) {
currentNode = newParent;
createdElement = null;
}
/**
* Get the root element created with this writer.
* @return the root element created with this writer.
*/
public Element getCreatedElement() {
return createdElement;
}
/**
* In cases where the serialization is supposed to precede a specific
* element, we add an extra parameter to capture that. Only affects the
* first element insertion (obviously?).
*
* @param marshallers
* @param parent
* @param nextSibling The first element created will be created *before* this element.
*/
public XmlWriterToTree(List<XmlWriter.ToMarshal<? extends XMLStructure>> marshallers, Node parent, Node nextSibling) {
this(marshallers, parent);
this.nextSibling = nextSibling;
}
@Override
public void writeStartElement(String prefix, String localName, String namespaceURI) {
if ("".equals(namespaceURI)) {
// Map global namespace from StAX to DOM
namespaceURI = null;
}
Element newElem = factory.createElementNS(namespaceURI, DOMUtils.getQNameString(prefix, localName));
if (nextSibling != null) {
newElem = (Element)nextSibling.getParentNode().insertBefore(newElem, nextSibling);
}
else {
newElem = (Element)currentNode.appendChild(newElem);
}
nextSibling = null;
currentNode = newElem;
if (createdElement == null) {
createdElement = newElem;
}
}
@Override
public void writeEndElement() {
currentNode = currentNode.getParentNode();
}
@Override
public void writeTextElement(String prefix, String localName, String namespaceURI, String value) {
writeStartElement(prefix, localName, namespaceURI);
writeCharacters(value);
writeEndElement();
}
@Override
public void writeNamespace(String prefix, String namespaceURI) {
if ("".equals(prefix) || prefix == null) {
writeAttribute(null, XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", namespaceURI);
}
else {
writeAttribute("xmlns", XMLConstants.XMLNS_ATTRIBUTE_NS_URI, prefix, namespaceURI);
}
}
@Override
public void writeCharacters(String text) {
Text textNode = factory.createTextNode(text);
currentNode.appendChild(textNode);
}
@Override
public void writeComment(String text) {
Comment commentNode = factory.createComment(text);
currentNode.appendChild(commentNode);
}
@Override
public Attr writeAttribute(String prefix, String namespaceURI, String localName, String value) {
Attr result = null;
if (value != null) {
if ("".equals(namespaceURI)) {
// Map global namespace from StAX to DOM
namespaceURI = null;
}
result = factory.createAttributeNS(namespaceURI, DOMUtils.getQNameString(prefix, localName));
result.setTextContent(value);
if (! (currentNode instanceof Element)) {
throw new IllegalStateException(
"Attempting to add an attribute to something other than an element node. Node is "
+ currentNode.toString());
}
( (Element)currentNode).setAttributeNodeNS(result);
}
return result;
}
@Override
public void writeIdAttribute(String prefix, String namespaceURI, String localName, String value) {
if (value == null) {
return;
}
Attr newAttr = writeAttribute(prefix, namespaceURI, localName, value);
( (Element)currentNode).setIdAttributeNode(newAttr, true);
}
@Override
public String getCurrentLocalName() {
return currentNode.getLocalName();
}
@Override
public XMLStructure getCurrentNodeAsStructure() {
return new DOMStructure(currentNode);
}
@Override
public void marshalStructure(XMLStructure toMarshal, String dsPrefix, XMLCryptoContext context) throws MarshalException {
// look for the first isInstance match, and marshal to that.
for (int idx = 0 ; idx < m_marshallers.size() ; idx++) {
@SuppressWarnings("unchecked")
XmlWriter.ToMarshal<XMLStructure> marshaller = (ToMarshal<XMLStructure>) m_marshallers.get(idx);
if (marshaller.clazzToMatch.isInstance(toMarshal)) {
marshaller.marshalObject(this, toMarshal, dsPrefix, context);
return;
}
}
throw new IllegalArgumentException("Unable to marshal unexpected object of class " + toMarshal.getClass().toString());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,7 @@
/**
* @test
* @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349 8046949
* 8046724 8079693 8177334 8205507 8210736
* 8046724 8079693 8177334 8205507 8210736 8217878
* @summary Basic unit tests for generating XML Signatures with JSR 105
* @modules java.base/sun.security.util
* java.base/sun.security.x509
@ -126,8 +126,12 @@ public class GenerationTests {
private final static String CRL =
DATA_DIR + System.getProperty("file.separator") + "certs" +
System.getProperty("file.separator") + "crl";
// XML Document with a DOCTYPE declaration
private final static String ENVELOPE =
DATA_DIR + System.getProperty("file.separator") + "envelope.xml";
// XML Document without a DOCTYPE declaration
private final static String ENVELOPE2 =
DATA_DIR + System.getProperty("file.separator") + "envelope2.xml";
private static URIDereferencer httpUd = null;
private final static String STYLESHEET =
"http://www.w3.org/TR/xml-stylesheet";
@ -328,6 +332,10 @@ public class GenerationTests {
test_create_signature_reference_dependency();
test_create_signature_with_attr_in_no_namespace();
test_create_signature_with_empty_id();
test_create_signature_enveloping_over_doc(ENVELOPE, true);
test_create_signature_enveloping_over_doc(ENVELOPE2, true);
test_create_signature_enveloping_over_doc(ENVELOPE, false);
test_create_signature_enveloping_dom_level1();
// run tests for detached signatures with local http server
try (Http server = Http.startServer()) {
@ -1038,6 +1046,109 @@ public class GenerationTests {
"signature", null);
DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 512), doc);
sig.sign(dsc);
System.out.println();
}
static void test_create_signature_enveloping_over_doc(String filename,
boolean pass) throws Exception
{
System.out.println("* Generating signature-enveloping-over-doc.xml");
// create reference
Reference ref = fac.newReference("#object", sha256);
// create SignedInfo
SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha256,
Collections.singletonList(ref));
// create object
Document doc = null;
try (FileInputStream fis = new FileInputStream(filename)) {
doc = db.parse(fis);
}
DOMStructure ds = pass ? new DOMStructure(doc.getDocumentElement())
: new DOMStructure(doc);
XMLObject obj = fac.newXMLObject(Collections.singletonList(ds),
"object", null, "UTF-8");
// This creates an enveloping signature over the entire XML Document
XMLSignature sig = fac.newXMLSignature(si, rsa,
Collections.singletonList(obj),
"signature", null);
DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 1024), doc);
try {
sig.sign(dsc);
if (!pass) {
// A Document node can only exist at the root of the doc so this
// should fail
throw new Exception("Test unexpectedly passed");
}
} catch (Exception e) {
if (!pass) {
System.out.println("Test failed as expected: " + e);
} else {
throw e;
}
}
if (pass) {
DOMValidateContext dvc = new DOMValidateContext
(getPublicKey("RSA", 1024), doc.getDocumentElement());
XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
if (sig.equals(sig2) == false) {
throw new Exception
("Unmarshalled signature is not equal to generated signature");
}
if (sig2.validate(dvc) == false) {
throw new Exception("Validation of generated signature failed");
}
}
System.out.println();
}
static void test_create_signature_enveloping_dom_level1() throws Exception {
System.out.println("* Generating signature-enveloping-dom-level1.xml");
// create reference
Reference ref = fac.newReference("#object", sha256);
// create SignedInfo
SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha256,
Collections.singletonList(ref));
// create object using DOM Level 1 methods
Document doc = db.newDocument();
Element child = doc.createElement("Child");
child.setAttribute("Version", "1.0");
child.setAttribute("Id", "child");
child.setIdAttribute("Id", true);
child.appendChild(doc.createComment("Comment"));
XMLObject obj = fac.newXMLObject(
Collections.singletonList(new DOMStructure(child)),
"object", null, "UTF-8");
XMLSignature sig = fac.newXMLSignature(si, rsa,
Collections.singletonList(obj),
"signature", null);
DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 1024), doc);
sig.sign(dsc);
DOMValidateContext dvc = new DOMValidateContext
(getPublicKey("RSA", 1024), doc.getDocumentElement());
XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
if (sig.equals(sig2) == false) {
throw new Exception
("Unmarshalled signature is not equal to generated signature");
}
if (sig2.validate(dvc) == false) {
throw new Exception("Validation of generated signature failed");
}
System.out.println();
}
static void test_create_signature() throws Exception {

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Preamble -->
<Envelope xmlns:foo="http://example.org/foo" xmlns="http://example.org/usps">
<DearSir>foo</DearSir>
<Body>bar</Body>
<YoursSincerely>
</YoursSincerely>
<PostScript>bar</PostScript>
<Notaries xmlns="" Id="notaries">
<Notary name="Great, A. T." />
<Notary name="Hun, A. T." />
</Notaries>
<!-- Commentary -->
</Envelope>
<!-- Postamble -->