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:
parent
321d7d386a
commit
9d9edee86e
@ -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()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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 " +
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -45,7 +45,6 @@ public class ApacheOctetStreamData extends OctetStreamData
|
||||
this.xi = xi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XMLSignatureInput getXMLSignatureInput() {
|
||||
return xi;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,6 @@ public final class DOMURIDereferencer implements URIDereferencer {
|
||||
Init.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Data dereference(URIReference uriRef, XMLCryptoContext context)
|
||||
throws URIReferenceException {
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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 {
|
||||
|
15
test/jdk/javax/xml/crypto/dsig/data/envelope2.xml
Normal file
15
test/jdk/javax/xml/crypto/dsig/data/envelope2.xml
Normal 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 -->
|
Loading…
x
Reference in New Issue
Block a user