feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
125
jdkSrc/jdk8/org/jcp/xml/dsig/internal/DigesterOutputStream.java
Normal file
125
jdkSrc/jdk8/org/jcp/xml/dsig/internal/DigesterOutputStream.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DigesterOutputStream.java, v 1.5 2005/12/20 20:02:39 mullan Exp $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.utils.UnsyncByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* This class has been modified slightly to use java.security.MessageDigest
|
||||
* objects as input, rather than
|
||||
* com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm objects.
|
||||
* It also optionally caches the input bytes.
|
||||
*
|
||||
*/
|
||||
public class DigesterOutputStream extends OutputStream {
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(DigesterOutputStream.class);
|
||||
|
||||
private final boolean buffer;
|
||||
private UnsyncByteArrayOutputStream bos;
|
||||
private final MessageDigest md;
|
||||
|
||||
/**
|
||||
* Creates a DigesterOutputStream.
|
||||
*
|
||||
* @param md the MessageDigest
|
||||
*/
|
||||
public DigesterOutputStream(MessageDigest md) {
|
||||
this(md, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DigesterOutputStream.
|
||||
*
|
||||
* @param md the MessageDigest
|
||||
* @param buffer if true, caches the input bytes
|
||||
*/
|
||||
public DigesterOutputStream(MessageDigest md, boolean buffer) {
|
||||
this.md = md;
|
||||
this.buffer = buffer;
|
||||
if (buffer) {
|
||||
bos = new UnsyncByteArrayOutputStream();
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int input) {
|
||||
if (buffer) {
|
||||
bos.write(input);
|
||||
}
|
||||
md.update((byte)input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] input, int offset, int len) {
|
||||
if (buffer) {
|
||||
bos.write(input, offset, len);
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Pre-digested input:");
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = offset; i < (offset + len); i++) {
|
||||
sb.append((char)input[i]);
|
||||
}
|
||||
LOG.debug(sb.toString());
|
||||
}
|
||||
md.update(input, offset, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the digest value
|
||||
*/
|
||||
public byte[] getDigestValue() {
|
||||
return md.digest();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an input stream containing the cached bytes, or
|
||||
* null if not cached
|
||||
*/
|
||||
public InputStream getInputStream() {
|
||||
if (buffer) {
|
||||
return new ByteArrayInputStream(bos.toByteArray());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (buffer) {
|
||||
bos.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
52
jdkSrc/jdk8/org/jcp/xml/dsig/internal/MacOutputStream.java
Normal file
52
jdkSrc/jdk8/org/jcp/xml/dsig/internal/MacOutputStream.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import javax.crypto.Mac;
|
||||
|
||||
/**
|
||||
* Derived from Apache sources and changed to use Mac objects instead of
|
||||
* com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm objects.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class MacOutputStream extends ByteArrayOutputStream {
|
||||
private final Mac mac;
|
||||
|
||||
public MacOutputStream(Mac mac) {
|
||||
this.mac = mac;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int arg0) {
|
||||
super.write(arg0);
|
||||
mac.update((byte) arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] arg0, int arg1, int arg2) {
|
||||
super.write(arg0, arg1, arg2);
|
||||
mac.update(arg0, arg1, arg2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: SignerOutputStream.java, v 1.2 2005/09/15 14:29:02 mullan Exp $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
|
||||
/**
|
||||
* Derived from Apache sources and changed to use java.security.Signature
|
||||
* objects as input instead of
|
||||
* com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm objects.
|
||||
*
|
||||
*/
|
||||
public class SignerOutputStream extends ByteArrayOutputStream {
|
||||
private final Signature sig;
|
||||
|
||||
public SignerOutputStream(Signature sig) {
|
||||
this.sig = sig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int arg0) {
|
||||
super.write(arg0);
|
||||
try {
|
||||
sig.update((byte)arg0);
|
||||
} catch (SignatureException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] arg0, int arg1, int arg2) {
|
||||
super.write(arg0, arg1, arg2);
|
||||
try {
|
||||
sig.update(arg0, arg1, arg2);
|
||||
} catch (SignatureException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* 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.security.Key;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
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 DOMStructure
|
||||
implements SignatureMethod {
|
||||
|
||||
// denotes the type of signature algorithm
|
||||
enum Type { DSA, RSA, ECDSA, HMAC }
|
||||
|
||||
/**
|
||||
* Verifies the passed-in signature with the specified key, using the
|
||||
* underlying Signature or Mac algorithm.
|
||||
*
|
||||
* @param key the verification key
|
||||
* @param si the SignedInfo
|
||||
* @param sig the signature bytes to be verified
|
||||
* @param context the XMLValidateContext
|
||||
* @return {@code true} if the signature verified successfully,
|
||||
* {@code false} if not
|
||||
* @throws NullPointerException if {@code key}, {@code si} or
|
||||
* {@code sig} are {@code null}
|
||||
* @throws InvalidKeyException if the key is improperly encoded, of
|
||||
* the wrong type, or parameters are missing, etc
|
||||
* @throws SignatureException if an unexpected error occurs, such
|
||||
* as the passed in signature is improperly encoded
|
||||
* @throws XMLSignatureException if an unexpected error occurs
|
||||
*/
|
||||
abstract boolean verify(Key key, SignedInfo si, byte[] sig,
|
||||
XMLValidateContext context)
|
||||
throws InvalidKeyException, SignatureException, XMLSignatureException;
|
||||
|
||||
/**
|
||||
* Signs the bytes with the specified key, using the underlying
|
||||
* Signature or Mac algorithm.
|
||||
*
|
||||
* @param key the signing key
|
||||
* @param si the SignedInfo
|
||||
* @param context the XMLSignContext
|
||||
* @return the signature
|
||||
* @throws NullPointerException if {@code key} or
|
||||
* {@code si} are {@code null}
|
||||
* @throws InvalidKeyException if the key is improperly encoded, of
|
||||
* the wrong type, or parameters are missing, etc
|
||||
* @throws XMLSignatureException if an unexpected error occurs
|
||||
*/
|
||||
abstract byte[] sign(Key key, SignedInfo si, XMLSignContext context)
|
||||
throws InvalidKeyException, XMLSignatureException;
|
||||
|
||||
/**
|
||||
* Returns the java.security.Signature or javax.crypto.Mac standard
|
||||
* algorithm name.
|
||||
*/
|
||||
abstract String getJCAAlgorithm();
|
||||
|
||||
/**
|
||||
* Returns the type of signature algorithm.
|
||||
*/
|
||||
abstract Type getAlgorithmType();
|
||||
|
||||
/**
|
||||
* This method invokes the {@link #marshalParams marshalParams}
|
||||
* method to marshal any algorithm-specific parameters.
|
||||
*/
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
|
||||
Element smElem = DOMUtils.createElement(ownerDoc, "SignatureMethod",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
DOMUtils.setAttribute(smElem, "Algorithm", getAlgorithm());
|
||||
|
||||
if (getParameterSpec() != null) {
|
||||
marshalParams(smElem, dsPrefix);
|
||||
}
|
||||
|
||||
parent.appendChild(smElem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshals the algorithm-specific parameters to an Element and
|
||||
* appends it to the specified parent element. By default, this method
|
||||
* throws an exception since most SignatureMethod algorithms do not have
|
||||
* parameters. Subclasses should override it if they have parameters.
|
||||
*
|
||||
* @param parent the parent element to append the parameters to
|
||||
* @param paramsPrefix the algorithm parameters prefix to use
|
||||
* @throws MarshalException if the parameters cannot be marshalled
|
||||
*/
|
||||
void marshalParams(Element parent, String paramsPrefix)
|
||||
throws MarshalException
|
||||
{
|
||||
throw new MarshalException("no parameters should " +
|
||||
"be specified for the " + getAlgorithm() +
|
||||
" SignatureMethod algorithm");
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshals {@code SignatureMethodParameterSpec} from the specified
|
||||
* {@code Element}. By default, this method throws an exception since
|
||||
* most SignatureMethod algorithms do not have parameters. Subclasses should
|
||||
* override it if they have parameters.
|
||||
*
|
||||
* @param paramsElem the {@code Element} holding the input params
|
||||
* @return the algorithm-specific {@code SignatureMethodParameterSpec}
|
||||
* @throws MarshalException if the parameters cannot be unmarshalled
|
||||
*/
|
||||
SignatureMethodParameterSpec unmarshalParams(Element paramsElem)
|
||||
throws MarshalException
|
||||
{
|
||||
throw new MarshalException("no parameters should " +
|
||||
"be specified for the " + getAlgorithm() +
|
||||
" SignatureMethod algorithm");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified parameters are valid for this algorithm. By
|
||||
* default, this method throws an exception if parameters are specified
|
||||
* since most SignatureMethod algorithms do not have parameters. Subclasses
|
||||
* should override it if they have parameters.
|
||||
*
|
||||
* @param params the algorithm-specific params (may be {@code null})
|
||||
* @throws InvalidAlgorithmParameterException if the parameters are not
|
||||
* appropriate for this signature method
|
||||
*/
|
||||
void checkParams(SignatureMethodParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (params != null) {
|
||||
throw new InvalidAlgorithmParameterException("no parameters " +
|
||||
"should be specified for the " + getAlgorithm() +
|
||||
" SignatureMethod algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof SignatureMethod)) {
|
||||
return false;
|
||||
}
|
||||
SignatureMethod osm = (SignatureMethod)o;
|
||||
|
||||
return getAlgorithm().equals(osm.getAlgorithm()) &&
|
||||
paramsEqual(osm.getParameterSpec());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + getAlgorithm().hashCode();
|
||||
AlgorithmParameterSpec spec = getParameterSpec();
|
||||
if (spec != null) {
|
||||
result = 31 * result + spec.hashCode();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if parameters are equal; false otherwise.
|
||||
*
|
||||
* Subclasses should override this method to compare algorithm-specific
|
||||
* parameters.
|
||||
*/
|
||||
boolean paramsEqual(AlgorithmParameterSpec spec)
|
||||
{
|
||||
return getParameterSpec() == spec;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: ApacheCanonicalizer.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dom.DOMCryptoContext;
|
||||
import javax.xml.crypto.dsig.TransformException;
|
||||
import javax.xml.crypto.dsig.TransformService;
|
||||
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
|
||||
import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
|
||||
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
||||
import com.sun.org.apache.xml.internal.security.transforms.Transform;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
public abstract class ApacheCanonicalizer extends TransformService {
|
||||
|
||||
static {
|
||||
com.sun.org.apache.xml.internal.security.Init.init();
|
||||
}
|
||||
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(ApacheCanonicalizer.class);
|
||||
protected Canonicalizer apacheCanonicalizer;
|
||||
private Transform apacheTransform;
|
||||
protected String inclusiveNamespaces;
|
||||
protected C14NMethodParameterSpec params;
|
||||
protected Document ownerDoc;
|
||||
protected Element transformElem;
|
||||
|
||||
public final AlgorithmParameterSpec getParameterSpec()
|
||||
{
|
||||
return params;
|
||||
}
|
||||
|
||||
public void init(XMLStructure parent, XMLCryptoContext context)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (context != null && !(context instanceof DOMCryptoContext)) {
|
||||
throw new ClassCastException
|
||||
("context must be of type DOMCryptoContext");
|
||||
}
|
||||
if (parent == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
throw new ClassCastException("parent must be of type DOMStructure");
|
||||
}
|
||||
transformElem = (Element)
|
||||
((javax.xml.crypto.dom.DOMStructure)parent).getNode();
|
||||
ownerDoc = DOMUtils.getOwnerDocument(transformElem);
|
||||
}
|
||||
|
||||
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
if (context != null && !(context instanceof DOMCryptoContext)) {
|
||||
throw new ClassCastException
|
||||
("context must be of type DOMCryptoContext");
|
||||
}
|
||||
if (parent == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
throw new ClassCastException("parent must be of type DOMStructure");
|
||||
}
|
||||
transformElem = (Element)
|
||||
((javax.xml.crypto.dom.DOMStructure)parent).getNode();
|
||||
ownerDoc = DOMUtils.getOwnerDocument(transformElem);
|
||||
}
|
||||
|
||||
public Data canonicalize(Data data, XMLCryptoContext xc)
|
||||
throws TransformException
|
||||
{
|
||||
return canonicalize(data, xc, null);
|
||||
}
|
||||
|
||||
public Data canonicalize(Data data, XMLCryptoContext xc, OutputStream os)
|
||||
throws TransformException
|
||||
{
|
||||
if (apacheCanonicalizer == null) {
|
||||
try {
|
||||
apacheCanonicalizer = Canonicalizer.getInstance(getAlgorithm());
|
||||
boolean secVal = Utils.secureValidation(xc);
|
||||
apacheCanonicalizer.setSecureValidation(secVal);
|
||||
LOG.debug("Created canonicalizer for algorithm: {}", getAlgorithm());
|
||||
} catch (InvalidCanonicalizerException ice) {
|
||||
throw new TransformException
|
||||
("Couldn't find Canonicalizer for: " + getAlgorithm() +
|
||||
": " + ice.getMessage(), ice);
|
||||
}
|
||||
}
|
||||
|
||||
if (os != null) {
|
||||
apacheCanonicalizer.setWriter(os);
|
||||
} else {
|
||||
apacheCanonicalizer.setWriter(new ByteArrayOutputStream());
|
||||
}
|
||||
|
||||
try {
|
||||
Set<Node> nodeSet = null;
|
||||
if (data instanceof ApacheData) {
|
||||
XMLSignatureInput in =
|
||||
((ApacheData)data).getXMLSignatureInput();
|
||||
if (in.isElement()) {
|
||||
if (inclusiveNamespaces != null) {
|
||||
return new OctetStreamData(new ByteArrayInputStream
|
||||
(apacheCanonicalizer.canonicalizeSubtree
|
||||
(in.getSubNode(), inclusiveNamespaces)));
|
||||
} else {
|
||||
return new OctetStreamData(new ByteArrayInputStream
|
||||
(apacheCanonicalizer.canonicalizeSubtree
|
||||
(in.getSubNode())));
|
||||
}
|
||||
} else if (in.isNodeSet()) {
|
||||
nodeSet = in.getNodeSet();
|
||||
} else {
|
||||
return new OctetStreamData(new ByteArrayInputStream(
|
||||
apacheCanonicalizer.canonicalize(
|
||||
Utils.readBytesFromStream(in.getOctetStream()))));
|
||||
}
|
||||
} else if (data instanceof DOMSubTreeData) {
|
||||
DOMSubTreeData subTree = (DOMSubTreeData)data;
|
||||
if (inclusiveNamespaces != null) {
|
||||
return new OctetStreamData(new ByteArrayInputStream
|
||||
(apacheCanonicalizer.canonicalizeSubtree
|
||||
(subTree.getRoot(), inclusiveNamespaces)));
|
||||
} else {
|
||||
return new OctetStreamData(new ByteArrayInputStream
|
||||
(apacheCanonicalizer.canonicalizeSubtree
|
||||
(subTree.getRoot())));
|
||||
}
|
||||
} else if (data instanceof NodeSetData) {
|
||||
NodeSetData nsd = (NodeSetData)data;
|
||||
// convert Iterator to Set
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Node> ns = Utils.toNodeSet(nsd.iterator());
|
||||
nodeSet = ns;
|
||||
LOG.debug("Canonicalizing {} nodes", nodeSet.size());
|
||||
} else {
|
||||
return new OctetStreamData(new ByteArrayInputStream(
|
||||
apacheCanonicalizer.canonicalize(
|
||||
Utils.readBytesFromStream(
|
||||
((OctetStreamData)data).getOctetStream()))));
|
||||
}
|
||||
if (inclusiveNamespaces != null) {
|
||||
return new OctetStreamData(new ByteArrayInputStream(
|
||||
apacheCanonicalizer.canonicalizeXPathNodeSet
|
||||
(nodeSet, inclusiveNamespaces)));
|
||||
} else {
|
||||
return new OctetStreamData(new ByteArrayInputStream(
|
||||
apacheCanonicalizer.canonicalizeXPathNodeSet(nodeSet)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new TransformException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
|
||||
throws TransformException
|
||||
{
|
||||
if (data == null) {
|
||||
throw new NullPointerException("data must not be null");
|
||||
}
|
||||
if (os == null) {
|
||||
throw new NullPointerException("output stream must not be null");
|
||||
}
|
||||
|
||||
if (ownerDoc == null) {
|
||||
throw new TransformException("transform must be marshalled");
|
||||
}
|
||||
|
||||
if (apacheTransform == null) {
|
||||
try {
|
||||
apacheTransform =
|
||||
new Transform(ownerDoc, getAlgorithm(), transformElem.getChildNodes());
|
||||
apacheTransform.setElement(transformElem, xc.getBaseURI());
|
||||
boolean secVal = Utils.secureValidation(xc);
|
||||
apacheTransform.setSecureValidation(secVal);
|
||||
LOG.debug("Created transform for algorithm: {}", getAlgorithm());
|
||||
} catch (Exception ex) {
|
||||
throw new TransformException
|
||||
("Couldn't find Transform for: " + getAlgorithm(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
XMLSignatureInput in;
|
||||
if (data instanceof ApacheData) {
|
||||
LOG.debug("ApacheData = true");
|
||||
in = ((ApacheData)data).getXMLSignatureInput();
|
||||
} else if (data instanceof NodeSetData) {
|
||||
LOG.debug("isNodeSet() = true");
|
||||
if (data instanceof DOMSubTreeData) {
|
||||
DOMSubTreeData subTree = (DOMSubTreeData)data;
|
||||
in = new XMLSignatureInput(subTree.getRoot());
|
||||
in.setExcludeComments(subTree.excludeComments());
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Node> nodeSet =
|
||||
Utils.toNodeSet(((NodeSetData)data).iterator());
|
||||
in = new XMLSignatureInput(nodeSet);
|
||||
}
|
||||
} else {
|
||||
LOG.debug("isNodeSet() = false");
|
||||
try {
|
||||
in = new XMLSignatureInput
|
||||
(((OctetStreamData)data).getOctetStream());
|
||||
} catch (Exception ex) {
|
||||
throw new TransformException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
boolean secVal = Utils.secureValidation(xc);
|
||||
in.setSecureValidation(secVal);
|
||||
|
||||
try {
|
||||
in = apacheTransform.performTransform(in, os);
|
||||
if (!in.isNodeSet() && !in.isElement()) {
|
||||
return null;
|
||||
}
|
||||
if (in.isOctetStream()) {
|
||||
return new ApacheOctetStreamData(in);
|
||||
} else {
|
||||
return new ApacheNodeSetData(in);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new TransformException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean isFeatureSupported(String feature) {
|
||||
if (feature == null) {
|
||||
throw new NullPointerException();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/ApacheData.java
Normal file
44
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/ApacheData.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: ApacheData.java 1788465 2017-03-24 15:10:51Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.Data;
|
||||
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
||||
|
||||
/**
|
||||
* XMLSignatureInput Data wrapper.
|
||||
*
|
||||
*/
|
||||
public interface ApacheData extends Data {
|
||||
|
||||
/**
|
||||
* Returns the XMLSignatureInput.
|
||||
*/
|
||||
XMLSignatureInput getXMLSignatureInput();
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: ApacheNodeSetData.java 1496478 2013-06-25 14:01:16Z mullan $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.xml.crypto.NodeSetData;
|
||||
import org.w3c.dom.Node;
|
||||
import com.sun.org.apache.xml.internal.security.signature.NodeFilter;
|
||||
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
||||
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
|
||||
|
||||
public class ApacheNodeSetData implements ApacheData, NodeSetData {
|
||||
|
||||
private XMLSignatureInput xi;
|
||||
|
||||
public ApacheNodeSetData(XMLSignatureInput xi) {
|
||||
this.xi = xi;
|
||||
}
|
||||
|
||||
public Iterator<Node> iterator() {
|
||||
// If nodefilters are set, must execute them first to create node-set
|
||||
if (xi.getNodeFilters() != null && !xi.getNodeFilters().isEmpty()) {
|
||||
return Collections.unmodifiableSet
|
||||
(getNodeSet(xi.getNodeFilters())).iterator();
|
||||
}
|
||||
try {
|
||||
return Collections.unmodifiableSet(xi.getNodeSet()).iterator();
|
||||
} catch (Exception e) {
|
||||
// should not occur
|
||||
throw new RuntimeException
|
||||
("unrecoverable error retrieving nodeset", e);
|
||||
}
|
||||
}
|
||||
|
||||
public XMLSignatureInput getXMLSignatureInput() {
|
||||
return xi;
|
||||
}
|
||||
|
||||
private Set<Node> getNodeSet(List<NodeFilter> nodeFilters) {
|
||||
if (xi.isNeedsToBeExpanded()) {
|
||||
XMLUtils.circumventBug2650
|
||||
(XMLUtils.getOwnerDocument(xi.getSubNode()));
|
||||
}
|
||||
|
||||
Set<Node> inputSet = new LinkedHashSet<Node>();
|
||||
XMLUtils.getSet(xi.getSubNode(), inputSet,
|
||||
null, !xi.isExcludeComments());
|
||||
Set<Node> nodeSet = new LinkedHashSet<Node>();
|
||||
for (Node currentNode : inputSet) {
|
||||
Iterator<NodeFilter> it = nodeFilters.iterator();
|
||||
boolean skipNode = false;
|
||||
while (it.hasNext() && !skipNode) {
|
||||
NodeFilter nf = it.next();
|
||||
if (nf.isNodeInclude(currentNode) != 1) {
|
||||
skipNode = true;
|
||||
}
|
||||
}
|
||||
if (!skipNode) {
|
||||
nodeSet.add(currentNode);
|
||||
}
|
||||
}
|
||||
return nodeSet;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: ApacheOctetStreamData.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.xml.crypto.OctetStreamData;
|
||||
import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
|
||||
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
||||
|
||||
public class ApacheOctetStreamData extends OctetStreamData
|
||||
implements ApacheData {
|
||||
|
||||
private XMLSignatureInput xi;
|
||||
|
||||
public ApacheOctetStreamData(XMLSignatureInput xi)
|
||||
throws CanonicalizationException, IOException
|
||||
{
|
||||
super(xi.getOctetStream(), xi.getSourceURI(), xi.getMIMEType());
|
||||
this.xi = xi;
|
||||
}
|
||||
|
||||
public XMLSignatureInput getXMLSignatureInput() {
|
||||
return xi;
|
||||
}
|
||||
}
|
||||
212
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/ApacheTransform.java
Normal file
212
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/ApacheTransform.java
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: ApacheTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Set;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
||||
import com.sun.org.apache.xml.internal.security.transforms.Transform;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dom.DOMCryptoContext;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
|
||||
/**
|
||||
* This is a wrapper/glue class which invokes the Apache XML-Security
|
||||
* Transform.
|
||||
*
|
||||
*/
|
||||
public abstract class ApacheTransform extends TransformService {
|
||||
|
||||
static {
|
||||
com.sun.org.apache.xml.internal.security.Init.init();
|
||||
}
|
||||
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(ApacheTransform.class);
|
||||
private Transform apacheTransform;
|
||||
protected Document ownerDoc;
|
||||
protected Element transformElem;
|
||||
protected TransformParameterSpec params;
|
||||
|
||||
@Override
|
||||
public final AlgorithmParameterSpec getParameterSpec() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void init(XMLStructure parent, XMLCryptoContext context)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (context != null && !(context instanceof DOMCryptoContext)) {
|
||||
throw new ClassCastException
|
||||
("context must be of type DOMCryptoContext");
|
||||
}
|
||||
if (parent == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
throw new ClassCastException("parent must be of type DOMStructure");
|
||||
}
|
||||
transformElem = (Element)
|
||||
((javax.xml.crypto.dom.DOMStructure) parent).getNode();
|
||||
ownerDoc = DOMUtils.getOwnerDocument(transformElem);
|
||||
}
|
||||
|
||||
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
if (context != null && !(context instanceof DOMCryptoContext)) {
|
||||
throw new ClassCastException
|
||||
("context must be of type DOMCryptoContext");
|
||||
}
|
||||
if (parent == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
throw new ClassCastException("parent must be of type DOMStructure");
|
||||
}
|
||||
transformElem = (Element)
|
||||
((javax.xml.crypto.dom.DOMStructure) parent).getNode();
|
||||
ownerDoc = DOMUtils.getOwnerDocument(transformElem);
|
||||
}
|
||||
|
||||
public Data transform(Data data, XMLCryptoContext xc)
|
||||
throws TransformException
|
||||
{
|
||||
if (data == null) {
|
||||
throw new NullPointerException("data must not be null");
|
||||
}
|
||||
return transformIt(data, xc, null);
|
||||
}
|
||||
|
||||
public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
|
||||
throws TransformException
|
||||
{
|
||||
if (data == null) {
|
||||
throw new NullPointerException("data must not be null");
|
||||
}
|
||||
if (os == null) {
|
||||
throw new NullPointerException("output stream must not be null");
|
||||
}
|
||||
return transformIt(data, xc, os);
|
||||
}
|
||||
|
||||
private Data transformIt(Data data, XMLCryptoContext xc, OutputStream os)
|
||||
throws TransformException
|
||||
{
|
||||
if (ownerDoc == null) {
|
||||
throw new TransformException("transform must be marshalled");
|
||||
}
|
||||
|
||||
if (apacheTransform == null) {
|
||||
try {
|
||||
apacheTransform =
|
||||
new Transform(ownerDoc, getAlgorithm(), transformElem.getChildNodes());
|
||||
apacheTransform.setElement(transformElem, xc.getBaseURI());
|
||||
boolean secVal = Utils.secureValidation(xc);
|
||||
apacheTransform.setSecureValidation(secVal);
|
||||
LOG.debug("Created transform for algorithm: {}", getAlgorithm());
|
||||
} catch (Exception ex) {
|
||||
throw new TransformException("Couldn't find Transform for: " +
|
||||
getAlgorithm(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (Utils.secureValidation(xc)) {
|
||||
String algorithm = getAlgorithm();
|
||||
if (Policy.restrictAlg(algorithm)) {
|
||||
throw new TransformException(
|
||||
"Transform " + algorithm + " is forbidden when secure validation is enabled"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
XMLSignatureInput in;
|
||||
if (data instanceof ApacheData) {
|
||||
LOG.debug("ApacheData = true");
|
||||
in = ((ApacheData)data).getXMLSignatureInput();
|
||||
} else if (data instanceof NodeSetData) {
|
||||
LOG.debug("isNodeSet() = true");
|
||||
if (data instanceof DOMSubTreeData) {
|
||||
LOG.debug("DOMSubTreeData = true");
|
||||
DOMSubTreeData subTree = (DOMSubTreeData)data;
|
||||
in = new XMLSignatureInput(subTree.getRoot());
|
||||
in.setExcludeComments(subTree.excludeComments());
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Node> nodeSet =
|
||||
Utils.toNodeSet(((NodeSetData)data).iterator());
|
||||
in = new XMLSignatureInput(nodeSet);
|
||||
}
|
||||
} else {
|
||||
LOG.debug("isNodeSet() = false");
|
||||
try {
|
||||
in = new XMLSignatureInput
|
||||
(((OctetStreamData)data).getOctetStream());
|
||||
} catch (Exception ex) {
|
||||
throw new TransformException(ex);
|
||||
}
|
||||
}
|
||||
boolean secVal = Utils.secureValidation(xc);
|
||||
in.setSecureValidation(secVal);
|
||||
|
||||
try {
|
||||
if (os != null) {
|
||||
in = apacheTransform.performTransform(in, os);
|
||||
if (!in.isNodeSet() && !in.isElement()) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
in = apacheTransform.performTransform(in);
|
||||
}
|
||||
if (in.isOctetStream()) {
|
||||
return new ApacheOctetStreamData(in);
|
||||
} else {
|
||||
return new ApacheNodeSetData(in);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new TransformException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean isFeatureSupported(String feature) {
|
||||
if (feature == null) {
|
||||
throw new NullPointerException();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMBase64Transform.java 1788465 2017-03-24 15:10:51Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of Base64 Encoding Transform.
|
||||
* (Uses Apache XML-Sec Transform implementation)
|
||||
*
|
||||
*/
|
||||
public final class DOMBase64Transform extends ApacheTransform {
|
||||
|
||||
@Override
|
||||
public void init(TransformParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
if (params != null) {
|
||||
throw new InvalidAlgorithmParameterException("params must be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
|
||||
import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of CanonicalizationMethod for Canonical XML 1.1
|
||||
* (with or without comments). Uses Apache XML-Sec Canonicalizer.
|
||||
*
|
||||
*/
|
||||
public final class DOMCanonicalXMLC14N11Method extends ApacheCanonicalizer {
|
||||
|
||||
public static final String C14N_11 = "http://www.w3.org/2006/12/xml-c14n11";
|
||||
public static final String C14N_11_WITH_COMMENTS
|
||||
= "http://www.w3.org/2006/12/xml-c14n11#WithComments";
|
||||
|
||||
public void init(TransformParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
if (params != null) {
|
||||
throw new InvalidAlgorithmParameterException("no parameters " +
|
||||
"should be specified for Canonical XML 1.1 algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
public Data transform(Data data, XMLCryptoContext xc)
|
||||
throws TransformException {
|
||||
|
||||
// ignore comments if dereferencing same-document URI that requires
|
||||
// you to omit comments, even if the Transform says otherwise -
|
||||
// this is to be compliant with section 4.3.3.3 of W3C Rec.
|
||||
if (data instanceof DOMSubTreeData) {
|
||||
DOMSubTreeData subTree = (DOMSubTreeData) data;
|
||||
if (subTree.excludeComments()) {
|
||||
try {
|
||||
apacheCanonicalizer = Canonicalizer.getInstance(C14N_11);
|
||||
boolean secVal = Utils.secureValidation(xc);
|
||||
apacheCanonicalizer.setSecureValidation(secVal);
|
||||
} catch (InvalidCanonicalizerException ice) {
|
||||
throw new TransformException
|
||||
("Couldn't find Canonicalizer for: " +
|
||||
C14N_11 + ": " + ice.getMessage(), ice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return canonicalize(data, xc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMCanonicalXMLC14NMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
|
||||
import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of CanonicalizationMethod for Canonical XML
|
||||
* (with or without comments). Uses Apache XML-Sec Canonicalizer.
|
||||
*
|
||||
*/
|
||||
public final class DOMCanonicalXMLC14NMethod extends ApacheCanonicalizer {
|
||||
|
||||
public void init(TransformParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
if (params != null) {
|
||||
throw new InvalidAlgorithmParameterException("no parameters " +
|
||||
"should be specified for Canonical XML C14N algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
public Data transform(Data data, XMLCryptoContext xc)
|
||||
throws TransformException {
|
||||
|
||||
// ignore comments if dereferencing same-document URI that requires
|
||||
// you to omit comments, even if the Transform says otherwise -
|
||||
// this is to be compliant with section 4.3.3.3 of W3C Rec.
|
||||
if (data instanceof DOMSubTreeData) {
|
||||
DOMSubTreeData subTree = (DOMSubTreeData) data;
|
||||
if (subTree.excludeComments()) {
|
||||
try {
|
||||
apacheCanonicalizer = Canonicalizer.getInstance
|
||||
(CanonicalizationMethod.INCLUSIVE);
|
||||
boolean secVal = Utils.secureValidation(xc);
|
||||
apacheCanonicalizer.setSecureValidation(secVal);
|
||||
} catch (InvalidCanonicalizerException ice) {
|
||||
throw new TransformException
|
||||
("Couldn't find Canonicalizer for: " +
|
||||
CanonicalizationMethod.INCLUSIVE + ": " +
|
||||
ice.getMessage(), ice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return canonicalize(data, xc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMCanonicalizationMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.Provider;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
|
||||
/**
|
||||
* DOM-based abstract implementation of CanonicalizationMethod.
|
||||
*
|
||||
*/
|
||||
public class DOMCanonicalizationMethod extends DOMTransform
|
||||
implements CanonicalizationMethod {
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMCanonicalizationMethod}.
|
||||
*
|
||||
* @param spi TransformService
|
||||
*/
|
||||
public DOMCanonicalizationMethod(TransformService spi)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
super(spi);
|
||||
if (!(spi instanceof ApacheCanonicalizer) && !isC14Nalg(spi.getAlgorithm())) {
|
||||
throw new InvalidAlgorithmParameterException("Illegal CanonicalizationMethod");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMCanonicalizationMethod} from an element. It unmarshals any
|
||||
* algorithm-specific input parameters.
|
||||
*
|
||||
* @param cmElem a CanonicalizationMethod element
|
||||
*/
|
||||
public DOMCanonicalizationMethod(Element cmElem, XMLCryptoContext context,
|
||||
Provider provider)
|
||||
throws MarshalException
|
||||
{
|
||||
super(cmElem, context, provider);
|
||||
if (!(spi instanceof ApacheCanonicalizer) && !isC14Nalg(spi.getAlgorithm())) {
|
||||
throw new MarshalException("Illegal CanonicalizationMethod");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Canonicalizes the specified data using the underlying canonicalization
|
||||
* algorithm. This is a convenience method that is equivalent to invoking
|
||||
* the {@link #transform transform} method.
|
||||
*
|
||||
* @param data the data to be canonicalized
|
||||
* @param xc the {@code XMLCryptoContext} containing
|
||||
* additional context (may be {@code null} if not applicable)
|
||||
* @return the canonicalized data
|
||||
* @throws NullPointerException if {@code data} is {@code null}
|
||||
* @throws TransformException if an unexpected error occurs while
|
||||
* canonicalizing the data
|
||||
*/
|
||||
public Data canonicalize(Data data, XMLCryptoContext xc)
|
||||
throws TransformException
|
||||
{
|
||||
return transform(data, xc);
|
||||
}
|
||||
|
||||
public Data canonicalize(Data data, XMLCryptoContext xc, OutputStream os)
|
||||
throws TransformException
|
||||
{
|
||||
return transform(data, xc, os);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof CanonicalizationMethod)) {
|
||||
return false;
|
||||
}
|
||||
CanonicalizationMethod ocm = (CanonicalizationMethod)o;
|
||||
|
||||
return getAlgorithm().equals(ocm.getAlgorithm()) &&
|
||||
DOMUtils.paramsEqual(getParameterSpec(), ocm.getParameterSpec());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + getAlgorithm().hashCode();
|
||||
AlgorithmParameterSpec spec = getParameterSpec();
|
||||
if (spec != null) {
|
||||
result = 31 * result + spec.hashCode();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isC14Nalg(String alg) {
|
||||
return isInclusiveC14Nalg(alg) || isExclusiveC14Nalg(alg) || isC14N11alg(alg);
|
||||
}
|
||||
|
||||
private static boolean isInclusiveC14Nalg(String alg) {
|
||||
return alg.equals(CanonicalizationMethod.INCLUSIVE)
|
||||
|| alg.equals(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS);
|
||||
}
|
||||
|
||||
private static boolean isExclusiveC14Nalg(String alg) {
|
||||
return alg.equals(CanonicalizationMethod.EXCLUSIVE)
|
||||
|| alg.equals(CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS);
|
||||
}
|
||||
|
||||
private static boolean isC14N11alg(String alg) {
|
||||
return alg.equals(DOMCanonicalXMLC14N11Method.C14N_11)
|
||||
|| alg.equals(DOMCanonicalXMLC14N11Method.C14N_11_WITH_COMMENTS);
|
||||
}
|
||||
}
|
||||
105
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java
Normal file
105
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. 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} simple type
|
||||
* as defined in the W3C specification for XML-Signature Syntax and Processing.
|
||||
* The XML Schema Definition is defined as:
|
||||
*
|
||||
* <pre>{@code
|
||||
* <simpleType name="CryptoBinary">
|
||||
* <restriction base = "base64Binary">
|
||||
* </restriction>
|
||||
* </simpleType>
|
||||
* }</pre>
|
||||
*
|
||||
* @author Sean Mullan
|
||||
*/
|
||||
public final class DOMCryptoBinary extends DOMStructure {
|
||||
|
||||
private final BigInteger bigNum;
|
||||
private final String value;
|
||||
|
||||
/**
|
||||
* Create a {@code DOMCryptoBinary} instance from the specified
|
||||
* {@code BigInteger}
|
||||
*
|
||||
* @param bigNum the arbitrary-length integer
|
||||
* @throws NullPointerException if {@code bigNum} is {@code null}
|
||||
*/
|
||||
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} 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} that this object contains.
|
||||
*
|
||||
* @return the {@code BigInteger} 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));
|
||||
}
|
||||
}
|
||||
328
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java
Normal file
328
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMDigestMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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 DOMStructure
|
||||
implements DigestMethod {
|
||||
|
||||
static final String SHA224 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#sha224"; // see RFC 4051
|
||||
static final String SHA384 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#sha384"; // see RFC 4051
|
||||
|
||||
private DigestMethodParameterSpec params;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMDigestMethod}.
|
||||
*
|
||||
* @param params the algorithm-specific params (may be {@code null})
|
||||
* @throws InvalidAlgorithmParameterException if the parameters are not
|
||||
* appropriate for this digest method
|
||||
*/
|
||||
DOMDigestMethod(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (params != null && !(params instanceof DigestMethodParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("params must be of type DigestMethodParameterSpec");
|
||||
}
|
||||
checkParams((DigestMethodParameterSpec)params);
|
||||
this.params = (DigestMethodParameterSpec)params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMDigestMethod} from an element. This constructor
|
||||
* invokes the abstract {@link #unmarshalParams unmarshalParams} method to
|
||||
* unmarshal any algorithm-specific input parameters.
|
||||
*
|
||||
* @param dmElem a DigestMethod element
|
||||
*/
|
||||
DOMDigestMethod(Element dmElem) throws MarshalException {
|
||||
Element paramsElem = DOMUtils.getFirstChildElement(dmElem);
|
||||
if (paramsElem != null) {
|
||||
params = unmarshalParams(paramsElem);
|
||||
}
|
||||
try {
|
||||
checkParams(params);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new MarshalException(iape);
|
||||
}
|
||||
}
|
||||
|
||||
static DigestMethod unmarshal(Element dmElem) throws MarshalException {
|
||||
String alg = DOMUtils.getAttributeValue(dmElem, "Algorithm");
|
||||
if (alg.equals(DigestMethod.SHA1)) {
|
||||
return new SHA1(dmElem);
|
||||
} else if (alg.equals(SHA224)) {
|
||||
return new SHA224(dmElem);
|
||||
} else if (alg.equals(DigestMethod.SHA256)) {
|
||||
return new SHA256(dmElem);
|
||||
} else if (alg.equals(SHA384)) {
|
||||
return new SHA384(dmElem);
|
||||
} else if (alg.equals(DigestMethod.SHA512)) {
|
||||
return new SHA512(dmElem);
|
||||
} else if (alg.equals(DigestMethod.RIPEMD160)) {
|
||||
return new RIPEMD160(dmElem);
|
||||
} else {
|
||||
throw new MarshalException("unsupported DigestMethod algorithm: " +
|
||||
alg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified parameters are valid for this algorithm. By
|
||||
* default, this method throws an exception if parameters are specified
|
||||
* since most DigestMethod algorithms do not have parameters. Subclasses
|
||||
* should override it if they have parameters.
|
||||
*
|
||||
* @param params the algorithm-specific params (may be {@code null})
|
||||
* @throws InvalidAlgorithmParameterException if the parameters are not
|
||||
* appropriate for this digest method
|
||||
*/
|
||||
void checkParams(DigestMethodParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (params != null) {
|
||||
throw new InvalidAlgorithmParameterException("no parameters " +
|
||||
"should be specified for the " + getMessageDigestAlgorithm() +
|
||||
" DigestMethod algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
public final AlgorithmParameterSpec getParameterSpec() {
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshals {@code DigestMethodParameterSpec} from the specified
|
||||
* {@code Element}. By default, this method throws an exception since
|
||||
* most DigestMethod algorithms do not have parameters. Subclasses should
|
||||
* override it if they have parameters.
|
||||
*
|
||||
* @param paramsElem the {@code Element} holding the input params
|
||||
* @return the algorithm-specific {@code DigestMethodParameterSpec}
|
||||
* @throws MarshalException if the parameters cannot be unmarshalled
|
||||
*/
|
||||
DigestMethodParameterSpec unmarshalParams(Element paramsElem)
|
||||
throws MarshalException
|
||||
{
|
||||
throw new MarshalException("no parameters should " +
|
||||
"be specified for the " +
|
||||
getMessageDigestAlgorithm() +
|
||||
" DigestMethod algorithm");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method invokes the abstract {@link #marshalParams marshalParams}
|
||||
* method to marshal any algorithm-specific parameters.
|
||||
*/
|
||||
@Override
|
||||
public void marshal(Node parent, String prefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
|
||||
Element dmElem = DOMUtils.createElement(ownerDoc, "DigestMethod",
|
||||
XMLSignature.XMLNS, prefix);
|
||||
DOMUtils.setAttribute(dmElem, "Algorithm", getAlgorithm());
|
||||
|
||||
if (params != null) {
|
||||
marshalParams(dmElem, prefix);
|
||||
}
|
||||
|
||||
parent.appendChild(dmElem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof DigestMethod)) {
|
||||
return false;
|
||||
}
|
||||
DigestMethod odm = (DigestMethod)o;
|
||||
|
||||
boolean paramsEqual = params == null ? odm.getParameterSpec() == null :
|
||||
params.equals(odm.getParameterSpec());
|
||||
|
||||
return getAlgorithm().equals(odm.getAlgorithm()) && paramsEqual;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (params != null) {
|
||||
result = 31 * result + params.hashCode();
|
||||
}
|
||||
result = 31 * result + getAlgorithm().hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshals the algorithm-specific parameters to an Element and
|
||||
* appends it to the specified parent element. By default, this method
|
||||
* throws an exception since most DigestMethod algorithms do not have
|
||||
* parameters. Subclasses should override it if they have parameters.
|
||||
*
|
||||
* @param parent the parent element to append the parameters to
|
||||
* @param the namespace prefix to use
|
||||
* @throws MarshalException if the parameters cannot be marshalled
|
||||
*/
|
||||
void marshalParams(Element parent, String prefix)
|
||||
throws MarshalException
|
||||
{
|
||||
throw new MarshalException("no parameters should " +
|
||||
"be specified for the " +
|
||||
getMessageDigestAlgorithm() +
|
||||
" DigestMethod algorithm");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MessageDigest standard algorithm name.
|
||||
*/
|
||||
abstract String getMessageDigestAlgorithm();
|
||||
|
||||
static final class SHA1 extends DOMDigestMethod {
|
||||
SHA1(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA1(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return DigestMethod.SHA1;
|
||||
}
|
||||
String getMessageDigestAlgorithm() {
|
||||
return "SHA-1";
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA224 extends DOMDigestMethod {
|
||||
SHA224(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA224(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return SHA224;
|
||||
}
|
||||
@Override
|
||||
String getMessageDigestAlgorithm() {
|
||||
return "SHA-224";
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA256 extends DOMDigestMethod {
|
||||
SHA256(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA256(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return DigestMethod.SHA256;
|
||||
}
|
||||
String getMessageDigestAlgorithm() {
|
||||
return "SHA-256";
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA384 extends DOMDigestMethod {
|
||||
SHA384(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA384(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return SHA384;
|
||||
}
|
||||
String getMessageDigestAlgorithm() {
|
||||
return "SHA-384";
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA512 extends DOMDigestMethod {
|
||||
SHA512(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA512(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return DigestMethod.SHA512;
|
||||
}
|
||||
String getMessageDigestAlgorithm() {
|
||||
return "SHA-512";
|
||||
}
|
||||
}
|
||||
|
||||
static final class RIPEMD160 extends DOMDigestMethod {
|
||||
RIPEMD160(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
RIPEMD160(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return DigestMethod.RIPEMD160;
|
||||
}
|
||||
@Override
|
||||
String getMessageDigestAlgorithm() {
|
||||
return "RIPEMD160";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMEnvelopedTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of Enveloped Signature Transform.
|
||||
* (Uses Apache XML-Sec Transform implementation)
|
||||
*
|
||||
*/
|
||||
public final class DOMEnvelopedTransform extends ApacheTransform {
|
||||
|
||||
public void init(TransformParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
if (params != null) {
|
||||
throw new InvalidAlgorithmParameterException("params must be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
169
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java
Normal file
169
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMExcC14NMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
|
||||
import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.*;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
|
||||
import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of CanonicalizationMethod for Exclusive
|
||||
* Canonical XML algorithm (with or without comments).
|
||||
* Uses Apache XML-Sec Canonicalizer.
|
||||
*
|
||||
*/
|
||||
public final class DOMExcC14NMethod extends ApacheCanonicalizer {
|
||||
|
||||
public void init(TransformParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (params != null) {
|
||||
if (!(params instanceof ExcC14NParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("params must be of type ExcC14NParameterSpec");
|
||||
}
|
||||
this.params = (C14NMethodParameterSpec)params;
|
||||
}
|
||||
}
|
||||
|
||||
public void init(XMLStructure parent, XMLCryptoContext context)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
super.init(parent, context);
|
||||
Element paramsElem = DOMUtils.getFirstChildElement(transformElem);
|
||||
if (paramsElem == null) {
|
||||
this.params = null;
|
||||
this.inclusiveNamespaces = null;
|
||||
return;
|
||||
}
|
||||
unmarshalParams(paramsElem);
|
||||
}
|
||||
|
||||
private void unmarshalParams(Element paramsElem) {
|
||||
String prefixListAttr = paramsElem.getAttributeNS(null, "PrefixList");
|
||||
this.inclusiveNamespaces = prefixListAttr;
|
||||
int begin = 0;
|
||||
int end = prefixListAttr.indexOf(' ');
|
||||
List<String> prefixList = new ArrayList<>();
|
||||
while (end != -1) {
|
||||
prefixList.add(prefixListAttr.substring(begin, end));
|
||||
begin = end + 1;
|
||||
end = prefixListAttr.indexOf(' ', begin);
|
||||
}
|
||||
if (begin <= prefixListAttr.length()) {
|
||||
prefixList.add(prefixListAttr.substring(begin));
|
||||
}
|
||||
this.params = new ExcC14NParameterSpec(prefixList);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> getParameterSpecPrefixList(ExcC14NParameterSpec paramSpec) {
|
||||
return paramSpec.getPrefixList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
super.marshalParams(parent, context);
|
||||
AlgorithmParameterSpec spec = getParameterSpec();
|
||||
if (spec == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
StringBuffer prefixListAttr = new StringBuffer("");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> prefixList = getParameterSpecPrefixList(params);
|
||||
for (int i = 0, size = prefixList.size(); i < size; i++) {
|
||||
prefixListAttr.append(prefixList.get(i));
|
||||
if (i < size - 1) {
|
||||
prefixListAttr.append(" ");
|
||||
}
|
||||
}
|
||||
DOMUtils.setAttribute(eElem, "PrefixList", prefixListAttr.toString());
|
||||
this.inclusiveNamespaces = prefixListAttr.toString();
|
||||
transformElem.appendChild(eElem);
|
||||
}
|
||||
|
||||
public String getParamsNSURI() {
|
||||
return CanonicalizationMethod.EXCLUSIVE;
|
||||
}
|
||||
|
||||
public Data transform(Data data, XMLCryptoContext xc)
|
||||
throws TransformException
|
||||
{
|
||||
// ignore comments if dereferencing same-document URI that require
|
||||
// you to omit comments, even if the Transform says otherwise -
|
||||
// this is to be compliant with section 4.3.3.3 of W3C Rec.
|
||||
if (data instanceof DOMSubTreeData) {
|
||||
DOMSubTreeData subTree = (DOMSubTreeData)data;
|
||||
if (subTree.excludeComments()) {
|
||||
try {
|
||||
apacheCanonicalizer = Canonicalizer.getInstance
|
||||
(CanonicalizationMethod.EXCLUSIVE);
|
||||
boolean secVal = Utils.secureValidation(xc);
|
||||
apacheCanonicalizer.setSecureValidation(secVal);
|
||||
} catch (InvalidCanonicalizerException ice) {
|
||||
throw new TransformException
|
||||
("Couldn't find Canonicalizer for: " +
|
||||
CanonicalizationMethod.EXCLUSIVE + ": " +
|
||||
ice.getMessage(), ice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return canonicalize(data, xc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMHMACSignatureMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.spec.HMACParameterSpec;
|
||||
import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
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;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of HMAC SignatureMethod.
|
||||
*
|
||||
*/
|
||||
public abstract class DOMHMACSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMHMACSignatureMethod.class);
|
||||
|
||||
// see RFC 4051 for these algorithm definitions
|
||||
static final String HMAC_SHA224 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha224";
|
||||
static final String HMAC_SHA256 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha256";
|
||||
static final String HMAC_SHA384 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha384";
|
||||
static final String HMAC_SHA512 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha512";
|
||||
static final String HMAC_RIPEMD160 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160";
|
||||
|
||||
private Mac hmac;
|
||||
private int outputLength;
|
||||
private boolean outputLengthSet;
|
||||
private SignatureMethodParameterSpec params;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMHMACSignatureMethod} with the specified params
|
||||
*
|
||||
* @param params algorithm-specific parameters (may be {@code null})
|
||||
* @throws InvalidAlgorithmParameterException if params are inappropriate
|
||||
*/
|
||||
DOMHMACSignatureMethod(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
checkParams((SignatureMethodParameterSpec)params);
|
||||
this.params = (SignatureMethodParameterSpec)params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMHMACSignatureMethod} from an element.
|
||||
*
|
||||
* @param smElem a SignatureMethod element
|
||||
*/
|
||||
DOMHMACSignatureMethod(Element smElem) throws MarshalException {
|
||||
Element paramsElem = DOMUtils.getFirstChildElement(smElem);
|
||||
if (paramsElem != null) {
|
||||
params = unmarshalParams(paramsElem);
|
||||
}
|
||||
try {
|
||||
checkParams(params);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new MarshalException(iape);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void checkParams(SignatureMethodParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (params != null) {
|
||||
if (!(params instanceof HMACParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("params must be of type HMACParameterSpec");
|
||||
}
|
||||
outputLength = ((HMACParameterSpec)params).getOutputLength();
|
||||
outputLengthSet = true;
|
||||
LOG.debug("Setting outputLength from HMACParameterSpec to: {}", outputLength);
|
||||
}
|
||||
}
|
||||
|
||||
public final AlgorithmParameterSpec getParameterSpec() {
|
||||
return params;
|
||||
}
|
||||
|
||||
SignatureMethodParameterSpec unmarshalParams(Element paramsElem)
|
||||
throws MarshalException
|
||||
{
|
||||
outputLength = Integer.parseInt(paramsElem.getFirstChild().getNodeValue());
|
||||
outputLengthSet = true;
|
||||
LOG.debug("unmarshalled outputLength: {}", outputLength);
|
||||
return new HMACParameterSpec(outputLength);
|
||||
}
|
||||
|
||||
void marshalParams(Element parent, String prefix)
|
||||
throws MarshalException
|
||||
{
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
Element hmacElem = DOMUtils.createElement(ownerDoc, "HMACOutputLength",
|
||||
XMLSignature.XMLNS, prefix);
|
||||
hmacElem.appendChild(ownerDoc.createTextNode
|
||||
(String.valueOf(outputLength)));
|
||||
|
||||
parent.appendChild(hmacElem);
|
||||
}
|
||||
|
||||
boolean verify(Key key, SignedInfo si, byte[] sig,
|
||||
XMLValidateContext context)
|
||||
throws InvalidKeyException, SignatureException, XMLSignatureException
|
||||
{
|
||||
if (key == null || si == null || sig == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (!(key instanceof SecretKey)) {
|
||||
throw new InvalidKeyException("key must be SecretKey");
|
||||
}
|
||||
if (hmac == null) {
|
||||
try {
|
||||
hmac = Mac.getInstance(getJCAAlgorithm());
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new XMLSignatureException(nsae);
|
||||
}
|
||||
}
|
||||
if (outputLengthSet && outputLength < getDigestLength()) {
|
||||
throw new XMLSignatureException
|
||||
("HMACOutputLength must not be less than " + getDigestLength());
|
||||
}
|
||||
hmac.init(key);
|
||||
((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
|
||||
byte[] result = hmac.doFinal();
|
||||
|
||||
return MessageDigest.isEqual(sig, result);
|
||||
}
|
||||
|
||||
byte[] sign(Key key, SignedInfo si, XMLSignContext context)
|
||||
throws InvalidKeyException, XMLSignatureException
|
||||
{
|
||||
if (key == null || si == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (!(key instanceof SecretKey)) {
|
||||
throw new InvalidKeyException("key must be SecretKey");
|
||||
}
|
||||
if (hmac == null) {
|
||||
try {
|
||||
hmac = Mac.getInstance(getJCAAlgorithm());
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new XMLSignatureException(nsae);
|
||||
}
|
||||
}
|
||||
if (outputLengthSet && outputLength < getDigestLength()) {
|
||||
throw new XMLSignatureException
|
||||
("HMACOutputLength must not be less than " + getDigestLength());
|
||||
}
|
||||
hmac.init(key);
|
||||
((DOMSignedInfo)si).canonicalize(context, new MacOutputStream(hmac));
|
||||
return hmac.doFinal();
|
||||
}
|
||||
|
||||
boolean paramsEqual(AlgorithmParameterSpec spec) {
|
||||
if (getParameterSpec() == spec) {
|
||||
return true;
|
||||
}
|
||||
if (!(spec instanceof HMACParameterSpec)) {
|
||||
return false;
|
||||
}
|
||||
HMACParameterSpec ospec = (HMACParameterSpec)spec;
|
||||
|
||||
return outputLength == ospec.getOutputLength();
|
||||
}
|
||||
|
||||
Type getAlgorithmType() {
|
||||
return Type.HMAC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the output length of the hash/digest.
|
||||
*/
|
||||
abstract int getDigestLength();
|
||||
|
||||
static final class SHA1 extends DOMHMACSignatureMethod {
|
||||
SHA1(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA1(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return SignatureMethod.HMAC_SHA1;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "HmacSHA1";
|
||||
}
|
||||
int getDigestLength() {
|
||||
return 160;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA224 extends DOMHMACSignatureMethod {
|
||||
SHA224(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA224(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return HMAC_SHA224;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "HmacSHA224";
|
||||
}
|
||||
@Override
|
||||
int getDigestLength() {
|
||||
return 224;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA256 extends DOMHMACSignatureMethod {
|
||||
SHA256(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA256(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return HMAC_SHA256;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "HmacSHA256";
|
||||
}
|
||||
int getDigestLength() {
|
||||
return 256;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA384 extends DOMHMACSignatureMethod {
|
||||
SHA384(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA384(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return HMAC_SHA384;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "HmacSHA384";
|
||||
}
|
||||
int getDigestLength() {
|
||||
return 384;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA512 extends DOMHMACSignatureMethod {
|
||||
SHA512(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA512(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return HMAC_SHA512;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "HmacSHA512";
|
||||
}
|
||||
int getDigestLength() {
|
||||
return 512;
|
||||
}
|
||||
}
|
||||
|
||||
static final class RIPEMD160 extends DOMHMACSignatureMethod {
|
||||
RIPEMD160(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
RIPEMD160(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return HMAC_RIPEMD160;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "HMACRIPEMD160";
|
||||
}
|
||||
@Override
|
||||
int getDigestLength() {
|
||||
return 160;
|
||||
}
|
||||
}
|
||||
}
|
||||
250
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java
Normal file
250
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMKeyInfo.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.security.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
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;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of KeyInfo.
|
||||
*
|
||||
*/
|
||||
public final class DOMKeyInfo extends DOMStructure implements KeyInfo {
|
||||
|
||||
private final String id;
|
||||
private final List<XMLStructure> keyInfoTypes;
|
||||
|
||||
/**
|
||||
* A utility function to suppress casting warnings.
|
||||
* @param ki
|
||||
* @return the content of a KeyInfo Object
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<XMLStructure> getContent(KeyInfo ki) {
|
||||
return ki.getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMKeyInfo}.
|
||||
*
|
||||
* @param content a list of one or more {@link XMLStructure}s representing
|
||||
* key information types. The list is defensively copied to protect
|
||||
* against subsequent modification.
|
||||
* @param id an ID attribute
|
||||
* @throws NullPointerException if {@code content} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code content} is empty
|
||||
* @throws ClassCastException if {@code content} contains any entries
|
||||
* that are not of type {@link XMLStructure}
|
||||
*/
|
||||
public DOMKeyInfo(List<? extends XMLStructure> content, String id) {
|
||||
if (content == null) {
|
||||
throw new NullPointerException("content cannot be null");
|
||||
}
|
||||
this.keyInfoTypes =
|
||||
Collections.unmodifiableList(new ArrayList<>(content));
|
||||
if (this.keyInfoTypes.isEmpty()) {
|
||||
throw new IllegalArgumentException("content cannot be empty");
|
||||
}
|
||||
for (int i = 0, size = this.keyInfoTypes.size(); i < size; i++) {
|
||||
if (!(this.keyInfoTypes.get(i) instanceof XMLStructure)) {
|
||||
throw new ClassCastException
|
||||
("content["+i+"] is not a valid KeyInfo type");
|
||||
}
|
||||
}
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMKeyInfo} from XML.
|
||||
*
|
||||
* @param kiElem KeyInfo element
|
||||
*/
|
||||
public DOMKeyInfo(Element kiElem, XMLCryptoContext context,
|
||||
Provider provider)
|
||||
throws MarshalException
|
||||
{
|
||||
// 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<>();
|
||||
Node firstChild = kiElem.getFirstChild();
|
||||
if (firstChild == null) {
|
||||
throw new MarshalException("KeyInfo must contain at least one type");
|
||||
}
|
||||
while (firstChild != null) {
|
||||
if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element childElem = (Element)firstChild;
|
||||
String localName = childElem.getLocalName();
|
||||
String namespace = childElem.getNamespaceURI();
|
||||
if ("X509Data".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
content.add(new DOMX509Data(childElem));
|
||||
} else if ("KeyName".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
content.add(new DOMKeyName(childElem));
|
||||
} else if ("KeyValue".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
content.add(DOMKeyValue.unmarshal(childElem));
|
||||
} else if ("RetrievalMethod".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
content.add(new DOMRetrievalMethod(childElem,
|
||||
context, provider));
|
||||
} else if ("PGPData".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
content.add(new DOMPGPData(childElem));
|
||||
} else { //may be MgmtData, SPKIData or element from other namespace
|
||||
content.add(new javax.xml.crypto.dom.DOMStructure(childElem));
|
||||
}
|
||||
}
|
||||
firstChild = firstChild.getNextSibling();
|
||||
}
|
||||
keyInfoTypes = Collections.unmodifiableList(content);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<XMLStructure> getContent() {
|
||||
return keyInfoTypes;
|
||||
}
|
||||
|
||||
public void marshal(XMLStructure parent, XMLCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
if (parent == null) {
|
||||
throw new NullPointerException("parent is null");
|
||||
}
|
||||
if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
throw new ClassCastException("parent must be of type DOMStructure");
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
marshal(pNode, kiElem, nextSibling, dsPrefix, (DOMCryptoContext)context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix,
|
||||
DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
marshal(parent, null, dsPrefix, context);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private void marshal(Node parent, Element kiElem, Node nextSibling,
|
||||
String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
// create and append KeyInfoType elements
|
||||
for (XMLStructure kiType : keyInfoTypes) {
|
||||
if (kiType instanceof DOMStructure) {
|
||||
((DOMStructure)kiType).marshal(kiElem, dsPrefix, context);
|
||||
} else {
|
||||
DOMUtils.appendChild(kiElem,
|
||||
((javax.xml.crypto.dom.DOMStructure)kiType).getNode());
|
||||
}
|
||||
}
|
||||
|
||||
// append id attribute
|
||||
DOMUtils.setAttributeID(kiElem, "Id", id);
|
||||
|
||||
parent.insertBefore(kiElem, nextSibling);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof KeyInfo)) {
|
||||
return false;
|
||||
}
|
||||
KeyInfo oki = (KeyInfo)o;
|
||||
|
||||
boolean idsEqual = id == null ? oki.getId() == null
|
||||
: id.equals(oki.getId());
|
||||
|
||||
return keyInfoTypes.equals(oki.getContent()) && idsEqual;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (id != null) {
|
||||
result = 31 * result + id.hashCode();
|
||||
}
|
||||
result = 31 * result + keyInfoTypes.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
189
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java
Normal file
189
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMKeyInfoFactory.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.List;
|
||||
|
||||
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.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;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of KeyInfoFactory.
|
||||
*
|
||||
*/
|
||||
public final class DOMKeyInfoFactory extends KeyInfoFactory {
|
||||
|
||||
public DOMKeyInfoFactory() { }
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public KeyInfo newKeyInfo(List content) {
|
||||
return newKeyInfo(content, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public KeyInfo newKeyInfo(List content, String id) {
|
||||
return new DOMKeyInfo(content, id);
|
||||
}
|
||||
|
||||
public KeyName newKeyName(String name) {
|
||||
return new DOMKeyName(name);
|
||||
}
|
||||
|
||||
public KeyValue newKeyValue(PublicKey key) throws KeyException {
|
||||
String algorithm = key.getAlgorithm();
|
||||
if ("DSA".equals(algorithm)) {
|
||||
return new DOMKeyValue.DSA((DSAPublicKey) key);
|
||||
} else if ("RSA".equals(algorithm)) {
|
||||
return new DOMKeyValue.RSA((RSAPublicKey) key);
|
||||
} else if ("EC".equals(algorithm)) {
|
||||
return new DOMKeyValue.EC((ECPublicKey) key);
|
||||
} else {
|
||||
throw new KeyException("unsupported key algorithm: " + algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
public PGPData newPGPData(byte[] keyId) {
|
||||
return newPGPData(keyId, null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public PGPData newPGPData(byte[] keyId, byte[] keyPacket, List other) {
|
||||
return new DOMPGPData(keyId, keyPacket, other);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public PGPData newPGPData(byte[] keyPacket, List other) {
|
||||
return new DOMPGPData(keyPacket, other);
|
||||
}
|
||||
|
||||
public RetrievalMethod newRetrievalMethod(String uri) {
|
||||
return newRetrievalMethod(uri, null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public RetrievalMethod newRetrievalMethod(String uri, String type,
|
||||
List transforms) {
|
||||
if (uri == null) {
|
||||
throw new NullPointerException("uri must not be null");
|
||||
}
|
||||
return new DOMRetrievalMethod(uri, type, transforms);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
public X509Data newX509Data(List content) {
|
||||
return new DOMX509Data(content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509IssuerSerial newX509IssuerSerial(String issuerName,
|
||||
BigInteger serialNumber) {
|
||||
return new DOMX509IssuerSerial(issuerName, serialNumber);
|
||||
}
|
||||
|
||||
public boolean isFeatureSupported(String feature) {
|
||||
if (feature == null) {
|
||||
throw new NullPointerException();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public URIDereferencer getURIDereferencer() {
|
||||
return DOMURIDereferencer.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyInfo unmarshalKeyInfo(XMLStructure xmlStructure)
|
||||
throws MarshalException {
|
||||
if (xmlStructure == null) {
|
||||
throw new NullPointerException("xmlStructure cannot be null");
|
||||
}
|
||||
if (!(xmlStructure instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
throw new ClassCastException("xmlStructure must be of type DOMStructure");
|
||||
}
|
||||
Node node =
|
||||
((javax.xml.crypto.dom.DOMStructure) xmlStructure).getNode();
|
||||
node.normalize();
|
||||
|
||||
Element element = null;
|
||||
if (node.getNodeType() == Node.DOCUMENT_NODE) {
|
||||
element = ((Document) node).getDocumentElement();
|
||||
} else if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
element = (Element) node;
|
||||
} else {
|
||||
throw new MarshalException
|
||||
("xmlStructure does not contain a proper Node");
|
||||
}
|
||||
|
||||
// check tag
|
||||
String tag = element.getLocalName();
|
||||
String namespace = element.getNamespaceURI();
|
||||
if (tag == null || namespace == null) {
|
||||
throw new MarshalException("Document implementation must " +
|
||||
"support DOM Level 2 and be namespace aware");
|
||||
}
|
||||
if ("KeyInfo".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
try {
|
||||
return new DOMKeyInfo(element, new UnmarshalContext(), getProvider());
|
||||
} catch (MarshalException me) {
|
||||
throw me;
|
||||
} catch (Exception e) {
|
||||
throw new MarshalException(e);
|
||||
}
|
||||
} else {
|
||||
throw new MarshalException("Invalid KeyInfo tag: " + namespace + ":" + tag);
|
||||
}
|
||||
}
|
||||
|
||||
private static class UnmarshalContext extends DOMCryptoContext {
|
||||
UnmarshalContext() {}
|
||||
}
|
||||
|
||||
}
|
||||
105
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMKeyName.java
Normal file
105
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMKeyName.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMKeyName.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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 DOMStructure implements KeyName {
|
||||
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMKeyName}.
|
||||
*
|
||||
* @param name the name of the key identifier
|
||||
* @throws NullPointerException if {@code name} is null
|
||||
*/
|
||||
public DOMKeyName(String name) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException("name cannot be null");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMKeyName} from a KeyName element.
|
||||
*
|
||||
* @param knElem a KeyName element
|
||||
*/
|
||||
public DOMKeyName(Element knElem) {
|
||||
name = knElem.getFirstChild().getNodeValue();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof KeyName)) {
|
||||
return false;
|
||||
}
|
||||
KeyName okn = (KeyName)obj;
|
||||
return name.equals(okn.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + name.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
625
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java
Normal file
625
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java
Normal file
@@ -0,0 +1,625 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMKeyValue.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.DSAPublicKeySpec;
|
||||
import java.security.spec.ECField;
|
||||
import java.security.spec.ECFieldFp;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.security.spec.ECPoint;
|
||||
import java.security.spec.ECPublicKeySpec;
|
||||
import java.security.spec.EllipticCurve;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.dom.DOMCryptoContext;
|
||||
import javax.xml.crypto.dsig.XMLSignature;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyValue;
|
||||
|
||||
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 DOMStructure implements KeyValue {
|
||||
|
||||
private static final String XMLDSIG_11_XMLNS
|
||||
= "http://www.w3.org/2009/xmldsig11#";
|
||||
private final K publicKey;
|
||||
|
||||
public DOMKeyValue(K key) throws KeyException {
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key cannot be null");
|
||||
}
|
||||
this.publicKey = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMKeyValue} from an element.
|
||||
*
|
||||
* @param kvtElem a KeyValue child element
|
||||
*/
|
||||
public DOMKeyValue(Element kvtElem) throws MarshalException {
|
||||
this.publicKey = unmarshalKeyValue(kvtElem);
|
||||
}
|
||||
|
||||
static KeyValue unmarshal(Element kvElem) throws MarshalException {
|
||||
Element kvtElem = DOMUtils.getFirstChildElement(kvElem);
|
||||
if (kvtElem == null) {
|
||||
throw new MarshalException("KeyValue must contain at least one type");
|
||||
}
|
||||
|
||||
String namespace = kvtElem.getNamespaceURI();
|
||||
if (kvtElem.getLocalName().equals("DSAKeyValue") && XMLSignature.XMLNS.equals(namespace)) {
|
||||
return new DSA(kvtElem);
|
||||
} else if (kvtElem.getLocalName().equals("RSAKeyValue") && XMLSignature.XMLNS.equals(namespace)) {
|
||||
return new RSA(kvtElem);
|
||||
} else if (kvtElem.getLocalName().equals("ECKeyValue") && XMLDSIG_11_XMLNS.equals(namespace)) {
|
||||
return new EC(kvtElem);
|
||||
} else {
|
||||
return new Unknown(kvtElem);
|
||||
}
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey() throws KeyException {
|
||||
if (publicKey == null) {
|
||||
throw new KeyException("can't convert KeyValue to PublicKey");
|
||||
} else {
|
||||
return publicKey;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
|
||||
// create KeyValue element
|
||||
Element kvElem = DOMUtils.createElement(ownerDoc, "KeyValue",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
marshalPublicKey(kvElem, ownerDoc, dsPrefix, context);
|
||||
|
||||
parent.appendChild(kvElem);
|
||||
}
|
||||
|
||||
abstract void marshalPublicKey(Node parent, Document doc, String dsPrefix,
|
||||
DOMCryptoContext context) throws MarshalException;
|
||||
|
||||
abstract K unmarshalKeyValue(Element kvtElem)
|
||||
throws MarshalException;
|
||||
|
||||
private static PublicKey generatePublicKey(KeyFactory kf, KeySpec keyspec) {
|
||||
try {
|
||||
return kf.generatePublic(keyspec);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
//@@@ should dump exception to LOG
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof KeyValue)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
KeyValue kv = (KeyValue)obj;
|
||||
if (publicKey == null ) {
|
||||
if (kv.getPublicKey() != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!publicKey.equals(kv.getPublicKey())) {
|
||||
return false;
|
||||
}
|
||||
} catch (KeyException ke) {
|
||||
// no practical way to determine if the keys are equal
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static BigInteger decode(Element elem) throws MarshalException {
|
||||
try {
|
||||
String base64str = elem.getFirstChild().getNodeValue();
|
||||
return new BigInteger(1, XMLUtils.decode(base64str));
|
||||
} catch (Exception ex) {
|
||||
throw new MarshalException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (publicKey != null) {
|
||||
result = 31 * result + publicKey.hashCode();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
RSAPublicKey unmarshalKeyValue(Element kvtElem)
|
||||
throws MarshalException
|
||||
{
|
||||
if (rsakf == null) {
|
||||
try {
|
||||
rsakf = KeyFactory.getInstance("RSA");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException
|
||||
("unable to create RSA KeyFactory: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
Element modulusElem = DOMUtils.getFirstChildElement(kvtElem,
|
||||
"Modulus",
|
||||
XMLSignature.XMLNS);
|
||||
BigInteger modulus = decode(modulusElem);
|
||||
Element exponentElem = DOMUtils.getNextSiblingElement(modulusElem,
|
||||
"Exponent",
|
||||
XMLSignature.XMLNS);
|
||||
BigInteger exponent = decode(exponentElem);
|
||||
RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent);
|
||||
return (RSAPublicKey) generatePublicKey(rsakf, spec);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
super(elem);
|
||||
}
|
||||
|
||||
@Override
|
||||
void marshalPublicKey(Node parent, Document doc, String dsPrefix,
|
||||
DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
Element dsaElem = DOMUtils.createElement(doc, "DSAKeyValue",
|
||||
XMLSignature.XMLNS,
|
||||
dsPrefix);
|
||||
// parameters J, Seed & PgenCounter are not included
|
||||
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
|
||||
DSAPublicKey unmarshalKeyValue(Element kvtElem)
|
||||
throws MarshalException
|
||||
{
|
||||
if (dsakf == null) {
|
||||
try {
|
||||
dsakf = KeyFactory.getInstance("DSA");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException
|
||||
("unable to create DSA KeyFactory: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
Element curElem = DOMUtils.getFirstChildElement(kvtElem);
|
||||
if (curElem == null) {
|
||||
throw new MarshalException("KeyValue must contain at least one type");
|
||||
}
|
||||
// check for P and Q
|
||||
BigInteger p = null;
|
||||
BigInteger q = null;
|
||||
if (curElem.getLocalName().equals("P") && XMLSignature.XMLNS.equals(curElem.getNamespaceURI())) {
|
||||
p = decode(curElem);
|
||||
curElem = DOMUtils.getNextSiblingElement(curElem, "Q", XMLSignature.XMLNS);
|
||||
q = decode(curElem);
|
||||
curElem = DOMUtils.getNextSiblingElement(curElem);
|
||||
}
|
||||
BigInteger g = null;
|
||||
if (curElem != null
|
||||
&& curElem.getLocalName().equals("G") && XMLSignature.XMLNS.equals(curElem.getNamespaceURI())) {
|
||||
g = decode(curElem);
|
||||
curElem = DOMUtils.getNextSiblingElement(curElem, "Y", XMLSignature.XMLNS);
|
||||
}
|
||||
BigInteger y = null;
|
||||
if (curElem != null) {
|
||||
y = decode(curElem);
|
||||
curElem = DOMUtils.getNextSiblingElement(curElem);
|
||||
}
|
||||
//if (curElem != null && curElem.getLocalName().equals("J")) {
|
||||
//j = new DOMCryptoBinary(curElem.getFirstChild());
|
||||
// curElem = DOMUtils.getNextSiblingElement(curElem);
|
||||
//}
|
||||
//@@@ do we care about j, pgenCounter or seed?
|
||||
DSAPublicKeySpec spec = new DSAPublicKeySpec(y, p, q, g);
|
||||
return (DSAPublicKey) generatePublicKey(dsakf, spec);
|
||||
}
|
||||
}
|
||||
|
||||
static final class EC extends DOMKeyValue<ECPublicKey> {
|
||||
// ECKeyValue CryptoBinaries
|
||||
private byte[] ecPublicKey;
|
||||
private KeyFactory eckf;
|
||||
private ECParameterSpec ecParams;
|
||||
|
||||
/* Supported curve, secp256r1 */
|
||||
private static final Curve SECP256R1 = initializeCurve(
|
||||
"secp256r1 [NIST P-256, X9.62 prime256v1]",
|
||||
"1.2.840.10045.3.1.7",
|
||||
"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
|
||||
"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
|
||||
"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
|
||||
"4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
|
||||
"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
|
||||
1
|
||||
);
|
||||
|
||||
/* Supported curve secp384r1 */
|
||||
private static final Curve SECP384R1 = initializeCurve(
|
||||
"secp384r1 [NIST P-384]",
|
||||
"1.3.132.0.34",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
|
||||
"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
|
||||
"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
|
||||
"3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
|
||||
1
|
||||
);
|
||||
|
||||
/* Supported curve secp521r1 */
|
||||
private static final Curve SECP521R1 = initializeCurve(
|
||||
"secp521r1 [NIST P-521]",
|
||||
"1.3.132.0.35",
|
||||
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
|
||||
"0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
|
||||
"00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
|
||||
"011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
|
||||
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
|
||||
1
|
||||
);
|
||||
|
||||
private static Curve initializeCurve(String name, String oid,
|
||||
String sfield, String a, String b,
|
||||
String x, String y, String n, int h) {
|
||||
BigInteger p = bigInt(sfield);
|
||||
ECField field = new ECFieldFp(p);
|
||||
EllipticCurve curve = new EllipticCurve(field, bigInt(a),
|
||||
bigInt(b));
|
||||
ECPoint g = new ECPoint(bigInt(x), bigInt(y));
|
||||
return new Curve(name, oid, curve, g, bigInt(n), h);
|
||||
}
|
||||
|
||||
EC(ECPublicKey ecKey) throws KeyException {
|
||||
super(ecKey);
|
||||
ECPoint ecPoint = ecKey.getW();
|
||||
ecParams = ecKey.getParams();
|
||||
ecPublicKey = encodePoint(ecPoint, ecParams.getCurve());
|
||||
}
|
||||
|
||||
EC(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
|
||||
private static ECPoint decodePoint(byte[] data, EllipticCurve curve)
|
||||
throws IOException {
|
||||
if (data.length == 0 || data[0] != 4) {
|
||||
throw new IOException("Only uncompressed point format " +
|
||||
"supported");
|
||||
}
|
||||
// Per ANSI X9.62, an encoded point is a 1 byte type followed by
|
||||
// ceiling(LOG base 2 field-size / 8) bytes of x and the same of y.
|
||||
int n = (data.length - 1) / 2;
|
||||
if (n != (curve.getField().getFieldSize() + 7) >> 3) {
|
||||
throw new IOException("Point does not match field size");
|
||||
}
|
||||
|
||||
byte[] xb = Arrays.copyOfRange(data, 1, 1 + n);
|
||||
byte[] yb = Arrays.copyOfRange(data, n + 1, n + 1 + n);
|
||||
|
||||
return new ECPoint(new BigInteger(1, xb), new BigInteger(1, yb));
|
||||
}
|
||||
|
||||
private static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
|
||||
// get field size in bytes (rounding up)
|
||||
int n = (curve.getField().getFieldSize() + 7) >> 3;
|
||||
byte[] xb = trimZeroes(point.getAffineX().toByteArray());
|
||||
byte[] yb = trimZeroes(point.getAffineY().toByteArray());
|
||||
if (xb.length > n || yb.length > n) {
|
||||
throw new RuntimeException("Point coordinates do not " +
|
||||
"match field size");
|
||||
}
|
||||
byte[] b = new byte[1 + (n << 1)];
|
||||
b[0] = 4; // uncompressed
|
||||
System.arraycopy(xb, 0, b, n - xb.length + 1, xb.length);
|
||||
System.arraycopy(yb, 0, b, b.length - yb.length, yb.length);
|
||||
return b;
|
||||
}
|
||||
|
||||
private static byte[] trimZeroes(byte[] b) {
|
||||
int i = 0;
|
||||
while (i < b.length - 1 && b[i] == 0) {
|
||||
i++;
|
||||
}
|
||||
if (i == 0) {
|
||||
return b;
|
||||
}
|
||||
return Arrays.copyOfRange(b, i, b.length);
|
||||
}
|
||||
|
||||
private static String getCurveOid(ECParameterSpec params) {
|
||||
// Check that the params represent one of the supported
|
||||
// curves. If there is a match, return the object identifier
|
||||
// of the curve.
|
||||
Curve match;
|
||||
if (matchCurve(params, SECP256R1)) {
|
||||
match = SECP256R1;
|
||||
} else if (matchCurve(params, SECP384R1)) {
|
||||
match = SECP384R1;
|
||||
} else if (matchCurve(params, SECP521R1)) {
|
||||
match = SECP521R1;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return match.getObjectId();
|
||||
}
|
||||
|
||||
private static boolean matchCurve(ECParameterSpec params, Curve curve) {
|
||||
int fieldSize = params.getCurve().getField().getFieldSize();
|
||||
if (curve.getCurve().getField().getFieldSize() == fieldSize
|
||||
&& curve.getCurve().equals(params.getCurve())
|
||||
&& curve.getGenerator().equals(params.getGenerator())
|
||||
&& curve.getOrder().equals(params.getOrder())
|
||||
&& curve.getCofactor() == params.getCofactor()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void marshalPublicKey(Node parent, Document doc, String dsPrefix,
|
||||
DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
String prefix = DOMUtils.getNSPrefix(context, 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");
|
||||
}
|
||||
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
|
||||
ECPublicKey unmarshalKeyValue(Element kvtElem)
|
||||
throws MarshalException
|
||||
{
|
||||
if (eckf == null) {
|
||||
try {
|
||||
eckf = KeyFactory.getInstance("EC");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException
|
||||
("unable to create EC KeyFactory: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
ECParameterSpec ecParams = null;
|
||||
Element curElem = DOMUtils.getFirstChildElement(kvtElem);
|
||||
if (curElem == null) {
|
||||
throw new MarshalException("KeyValue must contain at least one type");
|
||||
}
|
||||
|
||||
if (curElem.getLocalName().equals("ECParameters")
|
||||
&& XMLDSIG_11_XMLNS.equals(curElem.getNamespaceURI())) {
|
||||
throw new UnsupportedOperationException
|
||||
("ECParameters not supported");
|
||||
} else if (curElem.getLocalName().equals("NamedCurve")
|
||||
&& XMLDSIG_11_XMLNS.equals(curElem.getNamespaceURI())) {
|
||||
String uri = DOMUtils.getAttributeValue(curElem, "URI");
|
||||
// strip off "urn:oid"
|
||||
if (uri.startsWith("urn:oid:")) {
|
||||
String oid = uri.substring("urn:oid:".length());
|
||||
ecParams = getECParameterSpec(oid);
|
||||
if (ecParams == null) {
|
||||
throw new MarshalException("Invalid curve OID");
|
||||
}
|
||||
} else {
|
||||
throw new MarshalException("Invalid NamedCurve URI");
|
||||
}
|
||||
} else {
|
||||
throw new MarshalException("Invalid ECKeyValue");
|
||||
}
|
||||
curElem = DOMUtils.getNextSiblingElement(curElem, "PublicKey", XMLDSIG_11_XMLNS);
|
||||
ECPoint ecPoint = null;
|
||||
|
||||
try {
|
||||
String content = XMLUtils.getFullTextChildrenFromNode(curElem);
|
||||
ecPoint = decodePoint(XMLUtils.decode(content),
|
||||
ecParams.getCurve());
|
||||
} catch (IOException ioe) {
|
||||
throw new MarshalException("Invalid EC Point", ioe);
|
||||
}
|
||||
|
||||
ECPublicKeySpec spec = new ECPublicKeySpec(ecPoint, ecParams);
|
||||
return (ECPublicKey) generatePublicKey(eckf, spec);
|
||||
}
|
||||
|
||||
private static ECParameterSpec getECParameterSpec(String oid) {
|
||||
if (oid.equals(SECP256R1.getObjectId())) {
|
||||
return SECP256R1;
|
||||
} else if (oid.equals(SECP384R1.getObjectId())) {
|
||||
return SECP384R1;
|
||||
} else if (oid.equals(SECP521R1.getObjectId())) {
|
||||
return SECP521R1;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static final class Curve extends ECParameterSpec {
|
||||
private final String name;
|
||||
private final String oid;
|
||||
|
||||
Curve(String name, String oid, EllipticCurve curve,
|
||||
ECPoint g, BigInteger n, int h) {
|
||||
super(curve, g, n, h);
|
||||
this.name = name;
|
||||
this.oid = oid;
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private String getObjectId() {
|
||||
return oid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static BigInteger bigInt(String s) {
|
||||
return new BigInteger(s, 16);
|
||||
}
|
||||
|
||||
static final class Unknown extends DOMKeyValue<PublicKey> {
|
||||
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(Node parent, Document doc, String dsPrefix,
|
||||
DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
parent.appendChild(externalPublicKey.getNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
178
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMManifest.java
Normal file
178
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMManifest.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMManifest.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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 DOMStructure implements Manifest {
|
||||
|
||||
private final List<Reference> references;
|
||||
private final String id;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMManifest} containing the specified
|
||||
* list of {@link Reference}s and optional id.
|
||||
*
|
||||
* @param references a list of one or more {@code Reference}s. The list
|
||||
* is defensively copied to protect against subsequent modification.
|
||||
* @param id the id (may be {@code null}
|
||||
* @throws NullPointerException if {@code references} is
|
||||
* {@code null}
|
||||
* @throws IllegalArgumentException if {@code references} is empty
|
||||
* @throws ClassCastException if {@code references} contains any
|
||||
* entries that are not of type {@link Reference}
|
||||
*/
|
||||
public DOMManifest(List<? extends Reference> references, String id) {
|
||||
if (references == null) {
|
||||
throw new NullPointerException("references cannot be null");
|
||||
}
|
||||
this.references =
|
||||
Collections.unmodifiableList(new ArrayList<>(references));
|
||||
if (this.references.isEmpty()) {
|
||||
throw new IllegalArgumentException("list of references must " +
|
||||
"contain at least one entry");
|
||||
}
|
||||
for (int i = 0, size = this.references.size(); i < size; i++) {
|
||||
if (!(this.references.get(i) instanceof Reference)) {
|
||||
throw new ClassCastException
|
||||
("references["+i+"] is not a valid type");
|
||||
}
|
||||
}
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMManifest} from an element.
|
||||
*
|
||||
* @param manElem a Manifest element
|
||||
*/
|
||||
public DOMManifest(Element manElem, XMLCryptoContext context,
|
||||
Provider provider)
|
||||
throws MarshalException
|
||||
{
|
||||
this.id = DOMUtils.getIdAttributeValue(manElem, "Id");
|
||||
|
||||
boolean secVal = Utils.secureValidation(context);
|
||||
|
||||
Element refElem = DOMUtils.getFirstChildElement(manElem, "Reference", XMLSignature.XMLNS);
|
||||
List<Reference> refs = new ArrayList<>();
|
||||
refs.add(new DOMReference(refElem, context, provider));
|
||||
|
||||
refElem = DOMUtils.getNextSiblingElement(refElem);
|
||||
while (refElem != null) {
|
||||
String localName = refElem.getLocalName();
|
||||
String namespace = refElem.getNamespaceURI();
|
||||
if (!"Reference".equals(localName) || !XMLSignature.XMLNS.equals(namespace)) {
|
||||
throw new MarshalException("Invalid element name: " +
|
||||
namespace + ":" + localName + ", expected Reference");
|
||||
}
|
||||
refs.add(new DOMReference(refElem, context, provider));
|
||||
if (secVal && Policy.restrictNumReferences(refs.size())) {
|
||||
String error = "A maxiumum of " + Policy.maxReferences()
|
||||
+ " references per Manifest are allowed when"
|
||||
+ " secure validation is enabled";
|
||||
throw new MarshalException(error);
|
||||
}
|
||||
refElem = DOMUtils.getNextSiblingElement(refElem);
|
||||
}
|
||||
this.references = Collections.unmodifiableList(refs);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Reference> getManifestReferences(Manifest mf) {
|
||||
return mf.getReferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Reference> getReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
@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
|
||||
for (Reference ref : references) {
|
||||
((DOMReference)ref).marshal(manElem, dsPrefix, context);
|
||||
}
|
||||
parent.appendChild(manElem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Manifest)) {
|
||||
return false;
|
||||
}
|
||||
Manifest oman = (Manifest)o;
|
||||
|
||||
boolean idsEqual = id == null ? oman.getId() == null
|
||||
: id.equals(oman.getId());
|
||||
|
||||
return idsEqual && references.equals(oman.getReferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (id != null) {
|
||||
result = 31 * result + id.hashCode();
|
||||
}
|
||||
result = 31 * result + references.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
261
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMPGPData.java
Normal file
261
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMPGPData.java
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMPGPData.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of PGPData.
|
||||
*
|
||||
*/
|
||||
public final class DOMPGPData extends DOMStructure implements PGPData {
|
||||
|
||||
private final byte[] keyId;
|
||||
private final byte[] keyPacket;
|
||||
private final List<XMLStructure> externalElements;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMPGPData} containing the specified key packet.
|
||||
* and optional list of external elements.
|
||||
*
|
||||
* @param keyPacket a PGP Key Material Packet as defined in section 5.5 of
|
||||
* <a href="https://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>. The
|
||||
* array is cloned to prevent subsequent modification.
|
||||
* @param other a list of {@link XMLStructure}s representing elements from
|
||||
* an external namespace. The list is defensively copied to prevent
|
||||
* subsequent modification. May be {@code null} or empty.
|
||||
* @throws NullPointerException if {@code keyPacket} is
|
||||
* {@code null}
|
||||
* @throws IllegalArgumentException if the key packet is not in the
|
||||
* correct format
|
||||
* @throws ClassCastException if {@code other} contains any
|
||||
* entries that are not of type {@link XMLStructure}
|
||||
*/
|
||||
public DOMPGPData(byte[] keyPacket, List<? extends XMLStructure> other) {
|
||||
if (keyPacket == null) {
|
||||
throw new NullPointerException("keyPacket cannot be null");
|
||||
}
|
||||
if (other == null || other.isEmpty()) {
|
||||
this.externalElements = Collections.emptyList();
|
||||
} else {
|
||||
this.externalElements =
|
||||
Collections.unmodifiableList(new ArrayList<>(other));
|
||||
for (int i = 0, size = this.externalElements.size(); i < size; i++) {
|
||||
if (!(this.externalElements.get(i) instanceof XMLStructure)) {
|
||||
throw new ClassCastException
|
||||
("other["+i+"] is not a valid PGPData type");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.keyPacket = (byte[])keyPacket.clone();
|
||||
checkKeyPacket(keyPacket);
|
||||
this.keyId = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMPGPData} containing the specified key id and
|
||||
* optional key packet and list of external elements.
|
||||
*
|
||||
* @param keyId a PGP public key id as defined in section 11.2 of
|
||||
* <a href="https://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>. The
|
||||
* array is cloned to prevent subsequent modification.
|
||||
* @param keyPacket a PGP Key Material Packet as defined in section 5.5 of
|
||||
* <a href="https://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a> (may
|
||||
* be {@code null}). The array is cloned to prevent subsequent
|
||||
* modification.
|
||||
* @param other a list of {@link XMLStructure}s representing elements from
|
||||
* an external namespace. The list is defensively copied to prevent
|
||||
* subsequent modification. May be {@code null} or empty.
|
||||
* @throws NullPointerException if {@code keyId} is {@code null}
|
||||
* @throws IllegalArgumentException if the key id or packet is not in the
|
||||
* correct format
|
||||
* @throws ClassCastException if {@code other} contains any
|
||||
* entries that are not of type {@link XMLStructure}
|
||||
*/
|
||||
public DOMPGPData(byte[] keyId, byte[] keyPacket,
|
||||
List<? extends XMLStructure> other)
|
||||
{
|
||||
if (keyId == null) {
|
||||
throw new NullPointerException("keyId cannot be null");
|
||||
}
|
||||
// key ids must be 8 bytes
|
||||
if (keyId.length != 8) {
|
||||
throw new IllegalArgumentException("keyId must be 8 bytes long");
|
||||
}
|
||||
if (other == null || other.isEmpty()) {
|
||||
this.externalElements = Collections.emptyList();
|
||||
} else {
|
||||
this.externalElements =
|
||||
Collections.unmodifiableList(new ArrayList<>(other));
|
||||
for (int i = 0, size = this.externalElements.size(); i < size; i++) {
|
||||
if (!(this.externalElements.get(i) instanceof XMLStructure)) {
|
||||
throw new ClassCastException
|
||||
("other["+i+"] is not a valid PGPData type");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.keyId = (byte[])keyId.clone();
|
||||
this.keyPacket = keyPacket == null ? null
|
||||
: (byte[])keyPacket.clone();
|
||||
if (keyPacket != null) {
|
||||
checkKeyPacket(keyPacket);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMPGPData} from an element.
|
||||
*
|
||||
* @param pdElem a PGPData element
|
||||
*/
|
||||
public DOMPGPData(Element pdElem) throws MarshalException {
|
||||
// get all children nodes
|
||||
byte[] pgpKeyId = null;
|
||||
byte[] pgpKeyPacket = null;
|
||||
|
||||
List<XMLStructure> other = new ArrayList<>();
|
||||
Node firstChild = pdElem.getFirstChild();
|
||||
while (firstChild != null) {
|
||||
if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element childElem = (Element)firstChild;
|
||||
String localName = childElem.getLocalName();
|
||||
String namespace = childElem.getNamespaceURI();
|
||||
if ("PGPKeyID".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
String content = XMLUtils.getFullTextChildrenFromNode(childElem);
|
||||
pgpKeyId = XMLUtils.decode(content);
|
||||
} else if ("PGPKeyPacket".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
String content = XMLUtils.getFullTextChildrenFromNode(childElem);
|
||||
pgpKeyPacket = XMLUtils.decode(content);
|
||||
} else {
|
||||
other.add
|
||||
(new javax.xml.crypto.dom.DOMStructure(childElem));
|
||||
}
|
||||
}
|
||||
firstChild = firstChild.getNextSibling();
|
||||
}
|
||||
this.keyId = pgpKeyId;
|
||||
this.keyPacket = pgpKeyPacket;
|
||||
this.externalElements = Collections.unmodifiableList(other);
|
||||
}
|
||||
|
||||
public byte[] getKeyId() {
|
||||
return keyId == null ? null : keyId.clone();
|
||||
}
|
||||
|
||||
public byte[] getKeyPacket() {
|
||||
return keyPacket == null ? null : keyPacket.clone();
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* This method only checks if the packet contains a valid tag. The
|
||||
* contents of the packet should be checked by the application.
|
||||
*/
|
||||
private void checkKeyPacket(byte[] keyPacket) {
|
||||
// length must be at least 3 (one byte for tag, one byte for length,
|
||||
// and minimally one byte of content
|
||||
if (keyPacket.length < 3) {
|
||||
throw new IllegalArgumentException("keypacket must be at least " +
|
||||
"3 bytes long");
|
||||
}
|
||||
|
||||
int tag = keyPacket[0];
|
||||
// first bit must be set
|
||||
if ((tag & 128) != 128) {
|
||||
throw new IllegalArgumentException("keypacket tag is invalid: " +
|
||||
"bit 7 is not set");
|
||||
}
|
||||
// make sure using new format
|
||||
if ((tag & 64) != 64) {
|
||||
throw new IllegalArgumentException("old keypacket tag format is " +
|
||||
"unsupported");
|
||||
}
|
||||
|
||||
// tag value must be 6, 14, 5 or 7
|
||||
if ((tag & 6) != 6 && (tag & 14) != 14 &&
|
||||
(tag & 5) != 5 && (tag & 7) != 7) {
|
||||
throw new IllegalArgumentException("keypacket tag is invalid: " +
|
||||
"must be 6, 14, 5, or 7");
|
||||
}
|
||||
}
|
||||
}
|
||||
656
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMReference.java
Normal file
656
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMReference.java
Normal file
@@ -0,0 +1,656 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* ===========================================================================
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2003 All Rights Reserved.
|
||||
*
|
||||
* ===========================================================================
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMReference.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of Reference.
|
||||
*
|
||||
*/
|
||||
public final class DOMReference extends DOMStructure
|
||||
implements Reference, DOMURIReference {
|
||||
|
||||
/**
|
||||
* The maximum number of transforms per reference, if secure validation is enabled.
|
||||
*/
|
||||
public static final int MAXIMUM_TRANSFORM_COUNT = 5;
|
||||
|
||||
/**
|
||||
* Look up useC14N11 system property. If true, an explicit C14N11 transform
|
||||
* will be added if necessary when generating the signature. See section
|
||||
* 3.1.1 of http://www.w3.org/2007/xmlsec/Drafts/xmldsig-core/ for more info.
|
||||
*
|
||||
* If true, overrides the same property if set in the XMLSignContext.
|
||||
*/
|
||||
private static boolean useC14N11 =
|
||||
AccessController.doPrivileged((PrivilegedAction<Boolean>)
|
||||
() -> Boolean.getBoolean("com.sun.org.apache.xml.internal.security.useC14N11"));
|
||||
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMReference.class);
|
||||
|
||||
private final DigestMethod digestMethod;
|
||||
private final String id;
|
||||
private final List<Transform> transforms;
|
||||
private List<Transform> allTransforms;
|
||||
private final Data appliedTransformData;
|
||||
private Attr here;
|
||||
private final String uri;
|
||||
private final String type;
|
||||
private byte[] digestValue;
|
||||
private byte[] calcDigestValue;
|
||||
private Element refElem;
|
||||
private boolean digested = false;
|
||||
private boolean validated = false;
|
||||
private boolean validationStatus;
|
||||
private Data derefData;
|
||||
private InputStream dis;
|
||||
private MessageDigest md;
|
||||
private Provider provider;
|
||||
|
||||
/**
|
||||
* Creates a {@code Reference} from the specified parameters.
|
||||
*
|
||||
* @param uri the URI (may be null)
|
||||
* @param type the type (may be null)
|
||||
* @param dm the digest method
|
||||
* @param transforms a list of {@link Transform}s. The list
|
||||
* is defensively copied to protect against subsequent modification.
|
||||
* May be {@code null} or empty.
|
||||
* @param id the reference ID (may be {@code null})
|
||||
* @throws NullPointerException if {@code dm} is {@code null}
|
||||
* @throws ClassCastException if any of the {@code transforms} are
|
||||
* not of type {@code Transform}
|
||||
*/
|
||||
public DOMReference(String uri, String type, DigestMethod dm,
|
||||
List<? extends Transform> transforms, String id,
|
||||
Provider provider)
|
||||
{
|
||||
this(uri, type, dm, null, null, transforms, id, null, provider);
|
||||
}
|
||||
|
||||
public DOMReference(String uri, String type, DigestMethod dm,
|
||||
List<? extends Transform> appliedTransforms,
|
||||
Data result, List<? extends Transform> transforms,
|
||||
String id, Provider provider)
|
||||
{
|
||||
this(uri, type, dm, appliedTransforms,
|
||||
result, transforms, id, null, provider);
|
||||
}
|
||||
|
||||
public DOMReference(String uri, String type, DigestMethod dm,
|
||||
List<? extends Transform> appliedTransforms,
|
||||
Data result, List<? extends Transform> transforms,
|
||||
String id, byte[] digestValue, Provider provider)
|
||||
{
|
||||
if (dm == null) {
|
||||
throw new NullPointerException("DigestMethod must be non-null");
|
||||
}
|
||||
if (appliedTransforms == null) {
|
||||
this.allTransforms = new ArrayList<>();
|
||||
} else {
|
||||
this.allTransforms = new ArrayList<>(appliedTransforms);
|
||||
for (int i = 0, size = this.allTransforms.size(); i < size; i++) {
|
||||
if (!(this.allTransforms.get(i) instanceof Transform)) {
|
||||
throw new ClassCastException
|
||||
("appliedTransforms["+i+"] is not a valid type");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (transforms == null) {
|
||||
this.transforms = Collections.emptyList();
|
||||
} else {
|
||||
this.transforms = new ArrayList<>(transforms);
|
||||
for (int i = 0, size = this.transforms.size(); i < size; i++) {
|
||||
if (!(this.transforms.get(i) instanceof Transform)) {
|
||||
throw new ClassCastException
|
||||
("transforms["+i+"] is not a valid type");
|
||||
}
|
||||
}
|
||||
this.allTransforms.addAll(this.transforms);
|
||||
}
|
||||
this.digestMethod = dm;
|
||||
this.uri = uri;
|
||||
if (uri != null && !uri.equals("")) {
|
||||
try {
|
||||
new URI(uri);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
if (digestValue != null) {
|
||||
this.digestValue = (byte[])digestValue.clone();
|
||||
this.digested = true;
|
||||
}
|
||||
this.appliedTransformData = result;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMReference} from an element.
|
||||
*
|
||||
* @param refElem a Reference element
|
||||
*/
|
||||
public DOMReference(Element refElem, XMLCryptoContext context,
|
||||
Provider provider)
|
||||
throws MarshalException
|
||||
{
|
||||
boolean secVal = Utils.secureValidation(context);
|
||||
|
||||
// unmarshal Transforms, if specified
|
||||
Element nextSibling = DOMUtils.getFirstChildElement(refElem);
|
||||
List<Transform> newTransforms = new ArrayList<>(MAXIMUM_TRANSFORM_COUNT);
|
||||
if (nextSibling.getLocalName().equals("Transforms")
|
||||
&& XMLSignature.XMLNS.equals(nextSibling.getNamespaceURI())) {
|
||||
Element transformElem = DOMUtils.getFirstChildElement(nextSibling,
|
||||
"Transform",
|
||||
XMLSignature.XMLNS);
|
||||
newTransforms.add(new DOMTransform(transformElem, context, provider));
|
||||
transformElem = DOMUtils.getNextSiblingElement(transformElem);
|
||||
while (transformElem != null) {
|
||||
String localName = transformElem.getLocalName();
|
||||
String namespace = transformElem.getNamespaceURI();
|
||||
if (!"Transform".equals(localName) || !XMLSignature.XMLNS.equals(namespace)) {
|
||||
throw new MarshalException(
|
||||
"Invalid element name: " + localName +
|
||||
", expected Transform");
|
||||
}
|
||||
newTransforms.add
|
||||
(new DOMTransform(transformElem, context, provider));
|
||||
if (secVal && Policy.restrictNumTransforms(newTransforms.size())) {
|
||||
String error = "A maximum of " + Policy.maxTransforms()
|
||||
+ " transforms per Reference are allowed when"
|
||||
+ " secure validation is enabled";
|
||||
throw new MarshalException(error);
|
||||
}
|
||||
transformElem = DOMUtils.getNextSiblingElement(transformElem);
|
||||
}
|
||||
nextSibling = DOMUtils.getNextSiblingElement(nextSibling);
|
||||
}
|
||||
if (!nextSibling.getLocalName().equals("DigestMethod")
|
||||
&& XMLSignature.XMLNS.equals(nextSibling.getNamespaceURI())) {
|
||||
throw new MarshalException("Invalid element name: " +
|
||||
nextSibling.getLocalName() +
|
||||
", expected DigestMethod");
|
||||
}
|
||||
|
||||
// unmarshal DigestMethod
|
||||
Element dmElem = nextSibling;
|
||||
this.digestMethod = DOMDigestMethod.unmarshal(dmElem);
|
||||
String digestMethodAlgorithm = this.digestMethod.getAlgorithm();
|
||||
if (secVal && Policy.restrictAlg(digestMethodAlgorithm)) {
|
||||
throw new MarshalException(
|
||||
"It is forbidden to use algorithm " + digestMethodAlgorithm +
|
||||
" when secure validation is enabled"
|
||||
);
|
||||
}
|
||||
|
||||
// unmarshal DigestValue
|
||||
Element dvElem = DOMUtils.getNextSiblingElement(dmElem, "DigestValue", XMLSignature.XMLNS);
|
||||
String content = XMLUtils.getFullTextChildrenFromNode(dvElem);
|
||||
this.digestValue = XMLUtils.decode(content);
|
||||
|
||||
// check for extra elements
|
||||
if (DOMUtils.getNextSiblingElement(dvElem) != null) {
|
||||
throw new MarshalException(
|
||||
"Unexpected element after DigestValue element");
|
||||
}
|
||||
|
||||
// unmarshal attributes
|
||||
this.uri = DOMUtils.getAttributeValue(refElem, "URI");
|
||||
|
||||
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");
|
||||
this.refElem = refElem;
|
||||
this.transforms = newTransforms;
|
||||
this.allTransforms = transforms;
|
||||
this.appliedTransformData = null;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public DigestMethod getDigestMethod() {
|
||||
return digestMethod;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getURI() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<Transform> getTransforms() {
|
||||
return Collections.unmodifiableList(allTransforms);
|
||||
}
|
||||
|
||||
public byte[] getDigestValue() {
|
||||
return digestValue == null ? null : digestValue.clone();
|
||||
}
|
||||
|
||||
public byte[] getCalculatedDigestValue() {
|
||||
return calcDigestValue == null ? null
|
||||
: calcDigestValue.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
LOG.debug("Marshalling Reference");
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
|
||||
refElem = DOMUtils.createElement(ownerDoc, "Reference",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
|
||||
// set attributes
|
||||
DOMUtils.setAttributeID(refElem, "Id", id);
|
||||
DOMUtils.setAttribute(refElem, "URI", uri);
|
||||
DOMUtils.setAttribute(refElem, "Type", type);
|
||||
|
||||
// create and append Transforms element
|
||||
if (!allTransforms.isEmpty()) {
|
||||
Element transformsElem = DOMUtils.createElement(ownerDoc,
|
||||
"Transforms",
|
||||
XMLSignature.XMLNS,
|
||||
dsPrefix);
|
||||
refElem.appendChild(transformsElem);
|
||||
for (Transform transform : allTransforms) {
|
||||
((DOMStructure)transform).marshal(transformsElem,
|
||||
dsPrefix, context);
|
||||
}
|
||||
}
|
||||
|
||||
// create and append DigestMethod element
|
||||
((DOMDigestMethod)digestMethod).marshal(refElem, dsPrefix, context);
|
||||
|
||||
// create and append DigestValue element
|
||||
LOG.debug("Adding digestValueElem");
|
||||
Element digestValueElem = DOMUtils.createElement(ownerDoc,
|
||||
"DigestValue",
|
||||
XMLSignature.XMLNS,
|
||||
dsPrefix);
|
||||
if (digestValue != null) {
|
||||
digestValueElem.appendChild
|
||||
(ownerDoc.createTextNode(XMLUtils.encodeToString(digestValue)));
|
||||
}
|
||||
refElem.appendChild(digestValueElem);
|
||||
|
||||
parent.appendChild(refElem);
|
||||
here = refElem.getAttributeNodeNS(null, "URI");
|
||||
}
|
||||
|
||||
public void digest(XMLSignContext signContext)
|
||||
throws XMLSignatureException
|
||||
{
|
||||
Data data = null;
|
||||
if (appliedTransformData == null) {
|
||||
data = dereference(signContext);
|
||||
} else {
|
||||
data = appliedTransformData;
|
||||
}
|
||||
digestValue = transform(data, signContext);
|
||||
|
||||
// insert digestValue into DigestValue element
|
||||
String encodedDV = XMLUtils.encodeToString(digestValue);
|
||||
LOG.debug("Reference object uri = {}", uri);
|
||||
Element digestElem = DOMUtils.getLastChildElement(refElem);
|
||||
if (digestElem == null) {
|
||||
throw new XMLSignatureException("DigestValue element expected");
|
||||
}
|
||||
DOMUtils.removeAllChildren(digestElem);
|
||||
digestElem.appendChild
|
||||
(refElem.getOwnerDocument().createTextNode(encodedDV));
|
||||
|
||||
digested = true;
|
||||
LOG.debug("Reference digesting completed");
|
||||
}
|
||||
|
||||
public boolean validate(XMLValidateContext validateContext)
|
||||
throws XMLSignatureException
|
||||
{
|
||||
if (validateContext == null) {
|
||||
throw new NullPointerException("validateContext cannot be null");
|
||||
}
|
||||
if (validated) {
|
||||
return validationStatus;
|
||||
}
|
||||
Data data = dereference(validateContext);
|
||||
calcDigestValue = transform(data, validateContext);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Expected digest: " + XMLUtils.encodeToString(digestValue));
|
||||
LOG.debug("Actual digest: " + XMLUtils.encodeToString(calcDigestValue));
|
||||
}
|
||||
|
||||
validationStatus = Arrays.equals(digestValue, calcDigestValue);
|
||||
validated = true;
|
||||
return validationStatus;
|
||||
}
|
||||
|
||||
public Data getDereferencedData() {
|
||||
return derefData;
|
||||
}
|
||||
|
||||
public InputStream getDigestInputStream() {
|
||||
return dis;
|
||||
}
|
||||
|
||||
private Data dereference(XMLCryptoContext context)
|
||||
throws XMLSignatureException
|
||||
{
|
||||
Data data = null;
|
||||
|
||||
// use user-specified URIDereferencer if specified; otherwise use deflt
|
||||
URIDereferencer deref = context.getURIDereferencer();
|
||||
if (deref == null) {
|
||||
deref = DOMURIDereferencer.INSTANCE;
|
||||
}
|
||||
try {
|
||||
data = deref.dereference(this, context);
|
||||
LOG.debug("URIDereferencer class name: {}", deref.getClass().getName());
|
||||
LOG.debug("Data class name: {}", data.getClass().getName());
|
||||
} catch (URIReferenceException ure) {
|
||||
throw new XMLSignatureException(ure);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private byte[] transform(Data dereferencedData,
|
||||
XMLCryptoContext context)
|
||||
throws XMLSignatureException
|
||||
{
|
||||
if (md == null) {
|
||||
try {
|
||||
md = MessageDigest.getInstance
|
||||
(((DOMDigestMethod)digestMethod).getMessageDigestAlgorithm());
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new XMLSignatureException(nsae);
|
||||
}
|
||||
}
|
||||
md.reset();
|
||||
DigesterOutputStream dos;
|
||||
Boolean cache = (Boolean)
|
||||
context.getProperty("javax.xml.crypto.dsig.cacheReference");
|
||||
if (cache != null && cache) {
|
||||
this.derefData = copyDerefData(dereferencedData);
|
||||
dos = new DigesterOutputStream(md, true);
|
||||
} else {
|
||||
dos = new DigesterOutputStream(md);
|
||||
}
|
||||
Data data = dereferencedData;
|
||||
try (OutputStream os = new UnsyncBufferedOutputStream(dos)) {
|
||||
for (int i = 0, size = transforms.size(); i < size; i++) {
|
||||
DOMTransform transform = (DOMTransform)transforms.get(i);
|
||||
if (i < size - 1) {
|
||||
data = transform.transform(data, context);
|
||||
} else {
|
||||
data = transform.transform(data, context, os);
|
||||
}
|
||||
}
|
||||
|
||||
if (data != null) {
|
||||
XMLSignatureInput xi;
|
||||
// explicitly use C14N 1.1 when generating signature
|
||||
// first check system property, then context property
|
||||
boolean c14n11 = useC14N11;
|
||||
String c14nalg = CanonicalizationMethod.INCLUSIVE;
|
||||
if (context instanceof XMLSignContext) {
|
||||
if (!c14n11) {
|
||||
Boolean prop = (Boolean)context.getProperty
|
||||
("com.sun.org.apache.xml.internal.security.useC14N11");
|
||||
c14n11 = prop != null && prop;
|
||||
if (c14n11) {
|
||||
c14nalg = "http://www.w3.org/2006/12/xml-c14n11";
|
||||
}
|
||||
} else {
|
||||
c14nalg = "http://www.w3.org/2006/12/xml-c14n11";
|
||||
}
|
||||
}
|
||||
if (data instanceof ApacheData) {
|
||||
xi = ((ApacheData)data).getXMLSignatureInput();
|
||||
} else if (data instanceof OctetStreamData) {
|
||||
xi = new XMLSignatureInput
|
||||
(((OctetStreamData)data).getOctetStream());
|
||||
} else if (data instanceof NodeSetData) {
|
||||
TransformService spi = null;
|
||||
if (provider == null) {
|
||||
spi = TransformService.getInstance(c14nalg, "DOM");
|
||||
} else {
|
||||
try {
|
||||
spi = TransformService.getInstance(c14nalg, "DOM", provider);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
spi = TransformService.getInstance(c14nalg, "DOM");
|
||||
}
|
||||
}
|
||||
data = spi.transform(data, context);
|
||||
xi = new XMLSignatureInput
|
||||
(((OctetStreamData)data).getOctetStream());
|
||||
} else {
|
||||
throw new XMLSignatureException("unrecognized Data type");
|
||||
}
|
||||
|
||||
boolean secVal = Utils.secureValidation(context);
|
||||
try {
|
||||
xi.setSecureValidation(secVal);
|
||||
if (context instanceof XMLSignContext && c14n11
|
||||
&& !xi.isOctetStream() && !xi.isOutputStreamSet()) {
|
||||
TransformService spi = null;
|
||||
if (provider == null) {
|
||||
spi = TransformService.getInstance(c14nalg, "DOM");
|
||||
} else {
|
||||
try {
|
||||
spi = TransformService.getInstance(c14nalg, "DOM", provider);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
spi = TransformService.getInstance(c14nalg, "DOM");
|
||||
}
|
||||
}
|
||||
|
||||
DOMTransform t = new DOMTransform(spi);
|
||||
Element transformsElem = null;
|
||||
String dsPrefix = DOMUtils.getSignaturePrefix(context);
|
||||
if (allTransforms.isEmpty()) {
|
||||
transformsElem = DOMUtils.createElement(
|
||||
refElem.getOwnerDocument(),
|
||||
"Transforms", XMLSignature.XMLNS, dsPrefix);
|
||||
refElem.insertBefore(transformsElem,
|
||||
DOMUtils.getFirstChildElement(refElem));
|
||||
} else {
|
||||
transformsElem = DOMUtils.getFirstChildElement(refElem);
|
||||
}
|
||||
t.marshal(transformsElem, dsPrefix,
|
||||
(DOMCryptoContext) context);
|
||||
allTransforms.add(t);
|
||||
xi.updateOutputStream(os, true);
|
||||
} else {
|
||||
xi.updateOutputStream(os);
|
||||
}
|
||||
} finally {
|
||||
if(xi.getOctetStreamReal() != null) {
|
||||
xi.getOctetStreamReal().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
os.flush();
|
||||
if (cache != null && cache) {
|
||||
this.dis = dos.getInputStream();
|
||||
}
|
||||
return dos.getDigestValue();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new XMLSignatureException(e);
|
||||
} catch (TransformException e) {
|
||||
throw new XMLSignatureException(e);
|
||||
} catch (MarshalException e) {
|
||||
throw new XMLSignatureException(e);
|
||||
} catch (IOException e) {
|
||||
throw new XMLSignatureException(e);
|
||||
} catch (com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException e) {
|
||||
throw new XMLSignatureException(e);
|
||||
} finally {
|
||||
if (dos != null) {
|
||||
try {
|
||||
dos.close();
|
||||
} catch (IOException e) {
|
||||
throw new XMLSignatureException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Node getHere() {
|
||||
return here;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Reference)) {
|
||||
return false;
|
||||
}
|
||||
Reference oref = (Reference)o;
|
||||
|
||||
boolean idsEqual = id == null ? oref.getId() == null
|
||||
: id.equals(oref.getId());
|
||||
boolean urisEqual = uri == null ? oref.getURI() == null
|
||||
: uri.equals(oref.getURI());
|
||||
boolean typesEqual = type == null ? oref.getType() == null
|
||||
: type.equals(oref.getType());
|
||||
boolean digestValuesEqual =
|
||||
Arrays.equals(digestValue, oref.getDigestValue());
|
||||
|
||||
return digestMethod.equals(oref.getDigestMethod()) && idsEqual &&
|
||||
urisEqual && typesEqual &&
|
||||
allTransforms.equals(oref.getTransforms()) && digestValuesEqual;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (id != null) {
|
||||
result = 31 * result + id.hashCode();
|
||||
}
|
||||
if (uri != null) {
|
||||
result = 31 * result + uri.hashCode();
|
||||
}
|
||||
if (type != null) {
|
||||
result = 31 * result + type.hashCode();
|
||||
}
|
||||
if (digestValue != null) {
|
||||
result = 31 * result + Arrays.hashCode(digestValue);
|
||||
}
|
||||
result = 31 * result + digestMethod.hashCode();
|
||||
result = 31 * result + allTransforms.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean isDigested() {
|
||||
return digested;
|
||||
}
|
||||
|
||||
private static Data copyDerefData(Data dereferencedData) {
|
||||
if (dereferencedData instanceof ApacheData) {
|
||||
// need to make a copy of the Data
|
||||
ApacheData ad = (ApacheData)dereferencedData;
|
||||
XMLSignatureInput xsi = ad.getXMLSignatureInput();
|
||||
if (xsi.isNodeSet()) {
|
||||
try {
|
||||
final Set<Node> s = xsi.getNodeSet();
|
||||
return new NodeSetData() {
|
||||
public Iterator<Node> iterator() { return s.iterator(); }
|
||||
};
|
||||
} catch (Exception e) {
|
||||
// LOG a warning
|
||||
LOG.warn("cannot cache dereferenced data: " + e);
|
||||
return null;
|
||||
}
|
||||
} else if (xsi.isElement()) {
|
||||
return new DOMSubTreeData
|
||||
(xsi.getSubNode(), xsi.isExcludeComments());
|
||||
} else if (xsi.isOctetStream() || xsi.isByteArray()) {
|
||||
try {
|
||||
return new OctetStreamData
|
||||
(xsi.getOctetStream(), xsi.getSourceURI(),
|
||||
xsi.getMIMEType());
|
||||
} catch (IOException ioe) {
|
||||
// LOG a warning
|
||||
LOG.warn("cannot cache dereferenced data: " + ioe);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dereferencedData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* ===========================================================================
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2003 All Rights Reserved.
|
||||
*
|
||||
* ===========================================================================
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMRetrievalMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.crypto.Data;
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.NodeSetData;
|
||||
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;
|
||||
import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of RetrievalMethod.
|
||||
*
|
||||
*/
|
||||
public final class DOMRetrievalMethod extends DOMStructure
|
||||
implements RetrievalMethod, DOMURIReference {
|
||||
|
||||
private final List<Transform> transforms;
|
||||
private String uri;
|
||||
private String type;
|
||||
private Attr here;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMRetrievalMethod} containing the specified
|
||||
* URIReference and List of Transforms.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param type the type
|
||||
* @param transforms a list of {@link Transform}s. The list is defensively
|
||||
* copied to prevent subsequent modification. May be {@code null}
|
||||
* or empty.
|
||||
* @throws IllegalArgumentException if the format of {@code uri} is
|
||||
* invalid, as specified by Reference's URI attribute in the W3C
|
||||
* specification for XML-Signature Syntax and Processing
|
||||
* @throws NullPointerException if {@code uriReference}
|
||||
* is {@code null}
|
||||
* @throws ClassCastException if {@code transforms} contains any
|
||||
* entries that are not of type {@link Transform}
|
||||
*/
|
||||
public DOMRetrievalMethod(String uri, String type,
|
||||
List<? extends Transform> transforms)
|
||||
{
|
||||
if (uri == null) {
|
||||
throw new NullPointerException("uri cannot be null");
|
||||
}
|
||||
if (transforms == null || transforms.isEmpty()) {
|
||||
this.transforms = Collections.emptyList();
|
||||
} else {
|
||||
this.transforms = Collections.unmodifiableList(
|
||||
new ArrayList<>(transforms));
|
||||
for (int i = 0, size = this.transforms.size(); i < size; i++) {
|
||||
if (!(this.transforms.get(i) instanceof Transform)) {
|
||||
throw new ClassCastException
|
||||
("transforms["+i+"] is not a valid type");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.uri = uri;
|
||||
if (!uri.equals("")) {
|
||||
try {
|
||||
new URI(uri);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMRetrievalMethod} from an element.
|
||||
*
|
||||
* @param rmElem a RetrievalMethod element
|
||||
*/
|
||||
public DOMRetrievalMethod(Element rmElem, XMLCryptoContext context,
|
||||
Provider provider)
|
||||
throws MarshalException
|
||||
{
|
||||
// get URI and Type attributes
|
||||
uri = DOMUtils.getAttributeValue(rmElem, "URI");
|
||||
type = DOMUtils.getAttributeValue(rmElem, "Type");
|
||||
|
||||
// get here node
|
||||
here = rmElem.getAttributeNodeNS(null, "URI");
|
||||
|
||||
boolean secVal = Utils.secureValidation(context);
|
||||
|
||||
// get Transforms, if specified
|
||||
List<Transform> newTransforms = new ArrayList<>();
|
||||
Element transformsElem = DOMUtils.getFirstChildElement(rmElem);
|
||||
|
||||
if (transformsElem != null) {
|
||||
String localName = transformsElem.getLocalName();
|
||||
String namespace = transformsElem.getNamespaceURI();
|
||||
if (!"Transforms".equals(localName) || !XMLSignature.XMLNS.equals(namespace)) {
|
||||
throw new MarshalException("Invalid element name: " +
|
||||
namespace + ":" + localName + ", expected Transforms");
|
||||
}
|
||||
Element transformElem =
|
||||
DOMUtils.getFirstChildElement(transformsElem, "Transform", XMLSignature.XMLNS);
|
||||
while (transformElem != null) {
|
||||
String name = transformElem.getLocalName();
|
||||
namespace = transformElem.getNamespaceURI();
|
||||
if (!"Transform".equals(name) || !XMLSignature.XMLNS.equals(namespace)) {
|
||||
throw new MarshalException("Invalid element name: " +
|
||||
name + ", expected Transform");
|
||||
}
|
||||
newTransforms.add
|
||||
(new DOMTransform(transformElem, context, provider));
|
||||
if (secVal && Policy.restrictNumTransforms(newTransforms.size())) {
|
||||
String error = "A maximum of " + Policy.maxTransforms()
|
||||
+ " transforms per Reference are allowed when"
|
||||
+ " secure validation is enabled";
|
||||
throw new MarshalException(error);
|
||||
}
|
||||
transformElem = DOMUtils.getNextSiblingElement(transformElem);
|
||||
}
|
||||
}
|
||||
if (newTransforms.isEmpty()) {
|
||||
this.transforms = Collections.emptyList();
|
||||
} else {
|
||||
this.transforms = Collections.unmodifiableList(newTransforms);
|
||||
}
|
||||
}
|
||||
|
||||
public String getURI() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<Transform> getTransforms() {
|
||||
return transforms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
Element rmElem = DOMUtils.createElement(ownerDoc, "RetrievalMethod",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
|
||||
// add URI and Type attributes
|
||||
DOMUtils.setAttribute(rmElem, "URI", uri);
|
||||
DOMUtils.setAttribute(rmElem, "Type", type);
|
||||
|
||||
// add Transforms elements
|
||||
if (!transforms.isEmpty()) {
|
||||
Element transformsElem = DOMUtils.createElement(ownerDoc,
|
||||
"Transforms",
|
||||
XMLSignature.XMLNS,
|
||||
dsPrefix);
|
||||
rmElem.appendChild(transformsElem);
|
||||
for (Transform transform : transforms) {
|
||||
((DOMTransform)transform).marshal(transformsElem,
|
||||
dsPrefix, context);
|
||||
}
|
||||
}
|
||||
|
||||
parent.appendChild(rmElem);
|
||||
|
||||
// save here node
|
||||
here = rmElem.getAttributeNodeNS(null, "URI");
|
||||
}
|
||||
|
||||
public Node getHere() {
|
||||
return here;
|
||||
}
|
||||
|
||||
public Data dereference(XMLCryptoContext context)
|
||||
throws URIReferenceException
|
||||
{
|
||||
if (context == null) {
|
||||
throw new NullPointerException("context cannot be null");
|
||||
}
|
||||
|
||||
/*
|
||||
* If URIDereferencer is specified in context; use it, otherwise use
|
||||
* built-in.
|
||||
*/
|
||||
URIDereferencer deref = context.getURIDereferencer();
|
||||
if (deref == null) {
|
||||
deref = DOMURIDereferencer.INSTANCE;
|
||||
}
|
||||
|
||||
Data data = deref.dereference(this, context);
|
||||
|
||||
// pass dereferenced data through Transforms
|
||||
try {
|
||||
for (Transform transform : transforms) {
|
||||
data = ((DOMTransform)transform).transform(data, context);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new URIReferenceException(e);
|
||||
}
|
||||
|
||||
// guard against RetrievalMethod loops
|
||||
if (data instanceof NodeSetData && Utils.secureValidation(context)
|
||||
&& Policy.restrictRetrievalMethodLoops()) {
|
||||
NodeSetData nsd = (NodeSetData)data;
|
||||
Iterator<?> i = nsd.iterator();
|
||||
if (i.hasNext()) {
|
||||
Node root = (Node)i.next();
|
||||
if ("RetrievalMethod".equals(root.getLocalName())) {
|
||||
throw new URIReferenceException(
|
||||
"It is forbidden to have one RetrievalMethod point " +
|
||||
"to another when secure validation is enabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public XMLStructure dereferenceAsXMLStructure(XMLCryptoContext context)
|
||||
throws URIReferenceException
|
||||
{
|
||||
DocumentBuilder db = null;
|
||||
boolean secVal = Utils.secureValidation(context);
|
||||
ApacheData data = (ApacheData)dereference(context);
|
||||
try (InputStream is = new ByteArrayInputStream(data.getXMLSignatureInput().getBytes())) {
|
||||
db = XMLUtils.createDocumentBuilder(false, secVal);
|
||||
Document doc = db.parse(is);
|
||||
Element kiElem = doc.getDocumentElement();
|
||||
if (kiElem.getLocalName().equals("X509Data")
|
||||
&& XMLSignature.XMLNS.equals(kiElem.getNamespaceURI())) {
|
||||
return new DOMX509Data(kiElem);
|
||||
} else {
|
||||
return null; // unsupported
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new URIReferenceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof RetrievalMethod)) {
|
||||
return false;
|
||||
}
|
||||
RetrievalMethod orm = (RetrievalMethod)obj;
|
||||
|
||||
boolean typesEqual = type == null ? orm.getType() == null
|
||||
: type.equals(orm.getType());
|
||||
|
||||
return uri.equals(orm.getURI()) &&
|
||||
transforms.equals(orm.getTransforms()) && typesEqual;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (type != null) {
|
||||
result = 31 * result + type.hashCode();
|
||||
}
|
||||
result = 31 * result + uri.hashCode();
|
||||
result = 31 * result + transforms.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,825 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMSignatureMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.DSAKey;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
import java.security.spec.PSSParameterSpec;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA;
|
||||
import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
|
||||
import org.jcp.xml.dsig.internal.SignerOutputStream;
|
||||
import sun.security.util.KeyUtil;
|
||||
|
||||
/**
|
||||
* DOM-based abstract implementation of SignatureMethod.
|
||||
*
|
||||
*/
|
||||
public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMSignatureMethod.class);
|
||||
|
||||
private SignatureMethodParameterSpec params;
|
||||
private Signature signature;
|
||||
|
||||
// see RFC 4051 for these algorithm definitions
|
||||
static final String RSA_SHA224 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha224";
|
||||
static final String RSA_SHA256 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
|
||||
static final String RSA_SHA384 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha384";
|
||||
static final String RSA_SHA512 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512";
|
||||
static final String RSA_RIPEMD160 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160";
|
||||
static final String ECDSA_SHA1 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1";
|
||||
static final String ECDSA_SHA224 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224";
|
||||
static final String ECDSA_SHA256 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
|
||||
static final String ECDSA_SHA384 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384";
|
||||
static final String ECDSA_SHA512 =
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512";
|
||||
static final String DSA_SHA256 =
|
||||
"http://www.w3.org/2009/xmldsig11#dsa-sha256";
|
||||
|
||||
// see RFC 6931 for these algorithm definitions
|
||||
static final String ECDSA_RIPEMD160 =
|
||||
"http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160";
|
||||
static final String RSA_SHA1_MGF1 =
|
||||
"http://www.w3.org/2007/05/xmldsig-more#sha1-rsa-MGF1";
|
||||
static final String RSA_SHA224_MGF1 =
|
||||
"http://www.w3.org/2007/05/xmldsig-more#sha224-rsa-MGF1";
|
||||
static final String RSA_SHA256_MGF1 =
|
||||
"http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1";
|
||||
static final String RSA_SHA384_MGF1 =
|
||||
"http://www.w3.org/2007/05/xmldsig-more#sha384-rsa-MGF1";
|
||||
static final String RSA_SHA512_MGF1 =
|
||||
"http://www.w3.org/2007/05/xmldsig-more#sha512-rsa-MGF1";
|
||||
static final String RSA_RIPEMD160_MGF1 =
|
||||
"http://www.w3.org/2007/05/xmldsig-more#ripemd160-rsa-MGF1";
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMSignatureMethod}.
|
||||
*
|
||||
* @param params the algorithm-specific params (may be {@code null})
|
||||
* @throws InvalidAlgorithmParameterException if the parameters are not
|
||||
* appropriate for this signature method
|
||||
*/
|
||||
DOMSignatureMethod(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (params != null &&
|
||||
!(params instanceof SignatureMethodParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("params must be of type SignatureMethodParameterSpec");
|
||||
}
|
||||
checkParams((SignatureMethodParameterSpec)params);
|
||||
this.params = (SignatureMethodParameterSpec)params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMSignatureMethod} from an element. This ctor
|
||||
* invokes the {@link #unmarshalParams unmarshalParams} method to
|
||||
* unmarshal any algorithm-specific input parameters.
|
||||
*
|
||||
* @param smElem a SignatureMethod element
|
||||
*/
|
||||
DOMSignatureMethod(Element smElem) throws MarshalException {
|
||||
Element paramsElem = DOMUtils.getFirstChildElement(smElem);
|
||||
if (paramsElem != null) {
|
||||
params = unmarshalParams(paramsElem);
|
||||
}
|
||||
try {
|
||||
checkParams(params);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new MarshalException(iape);
|
||||
}
|
||||
}
|
||||
|
||||
static SignatureMethod unmarshal(Element smElem) throws MarshalException {
|
||||
String alg = DOMUtils.getAttributeValue(smElem, "Algorithm");
|
||||
if (alg.equals(SignatureMethod.RSA_SHA1)) {
|
||||
return new SHA1withRSA(smElem);
|
||||
} else if (alg.equals(RSA_SHA224)) {
|
||||
return new SHA224withRSA(smElem);
|
||||
} else if (alg.equals(RSA_SHA256)) {
|
||||
return new SHA256withRSA(smElem);
|
||||
} else if (alg.equals(RSA_SHA384)) {
|
||||
return new SHA384withRSA(smElem);
|
||||
} else if (alg.equals(RSA_SHA512)) {
|
||||
return new SHA512withRSA(smElem);
|
||||
} else if (alg.equals(RSA_RIPEMD160)) {
|
||||
return new RIPEMD160withRSA(smElem);
|
||||
} else if (alg.equals(RSA_SHA1_MGF1)) {
|
||||
return new SHA1withRSAandMGF1(smElem);
|
||||
} else if (alg.equals(RSA_SHA224_MGF1)) {
|
||||
return new SHA224withRSAandMGF1(smElem);
|
||||
} else if (alg.equals(RSA_SHA256_MGF1)) {
|
||||
return new SHA256withRSAandMGF1(smElem);
|
||||
} else if (alg.equals(RSA_SHA384_MGF1)) {
|
||||
return new SHA384withRSAandMGF1(smElem);
|
||||
} else if (alg.equals(RSA_SHA512_MGF1)) {
|
||||
return new SHA512withRSAandMGF1(smElem);
|
||||
} else if (alg.equals(RSA_RIPEMD160_MGF1)) {
|
||||
return new RIPEMD160withRSAandMGF1(smElem);
|
||||
} else if (alg.equals(SignatureMethod.DSA_SHA1)) {
|
||||
return new SHA1withDSA(smElem);
|
||||
} else if (alg.equals(DSA_SHA256)) {
|
||||
return new SHA256withDSA(smElem);
|
||||
} else if (alg.equals(ECDSA_SHA1)) {
|
||||
return new SHA1withECDSA(smElem);
|
||||
} else if (alg.equals(ECDSA_SHA224)) {
|
||||
return new SHA224withECDSA(smElem);
|
||||
} else if (alg.equals(ECDSA_SHA256)) {
|
||||
return new SHA256withECDSA(smElem);
|
||||
} else if (alg.equals(ECDSA_SHA384)) {
|
||||
return new SHA384withECDSA(smElem);
|
||||
} else if (alg.equals(ECDSA_SHA512)) {
|
||||
return new SHA512withECDSA(smElem);
|
||||
} else if (alg.equals(ECDSA_RIPEMD160)) {
|
||||
return new RIPEMD160withECDSA(smElem);
|
||||
} else if (alg.equals(SignatureMethod.HMAC_SHA1)) {
|
||||
return new DOMHMACSignatureMethod.SHA1(smElem);
|
||||
} else if (alg.equals(DOMHMACSignatureMethod.HMAC_SHA224)) {
|
||||
return new DOMHMACSignatureMethod.SHA224(smElem);
|
||||
} else if (alg.equals(DOMHMACSignatureMethod.HMAC_SHA256)) {
|
||||
return new DOMHMACSignatureMethod.SHA256(smElem);
|
||||
} else if (alg.equals(DOMHMACSignatureMethod.HMAC_SHA384)) {
|
||||
return new DOMHMACSignatureMethod.SHA384(smElem);
|
||||
} else if (alg.equals(DOMHMACSignatureMethod.HMAC_SHA512)) {
|
||||
return new DOMHMACSignatureMethod.SHA512(smElem);
|
||||
} else if (alg.equals(DOMHMACSignatureMethod.HMAC_RIPEMD160)) {
|
||||
return new DOMHMACSignatureMethod.RIPEMD160(smElem);
|
||||
} else {
|
||||
throw new MarshalException
|
||||
("unsupported SignatureMethod algorithm: " + alg);
|
||||
}
|
||||
}
|
||||
|
||||
public final AlgorithmParameterSpec getParameterSpec() {
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of Signature from the specified Provider.
|
||||
* The algorithm is specified by the {@code getJCAAlgorithm()} method.
|
||||
*
|
||||
* @param p the Provider to use
|
||||
* @return an instance of Signature implementing the algorithm
|
||||
* specified by {@code getJCAAlgorithm()}
|
||||
* @throws NoSuchAlgorithmException if the Provider does not support the
|
||||
* signature algorithm
|
||||
*/
|
||||
Signature getSignature(Provider p)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (p == null)
|
||||
? Signature.getInstance(getJCAAlgorithm())
|
||||
: Signature.getInstance(getJCAAlgorithm(), p);
|
||||
}
|
||||
|
||||
boolean verify(Key key, SignedInfo si, byte[] sig,
|
||||
XMLValidateContext context)
|
||||
throws InvalidKeyException, SignatureException, XMLSignatureException
|
||||
{
|
||||
if (key == null || si == null || sig == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (!(key instanceof PublicKey)) {
|
||||
throw new InvalidKeyException("key must be PublicKey");
|
||||
}
|
||||
checkKeySize(context, key);
|
||||
if (signature == null) {
|
||||
Provider p = (Provider) context.getProperty
|
||||
("org.jcp.xml.dsig.internal.dom.SignatureProvider");
|
||||
try {
|
||||
signature = getSignature(p);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new XMLSignatureException(nsae);
|
||||
}
|
||||
}
|
||||
signature.initVerify((PublicKey)key);
|
||||
LOG.debug("Signature provider: {}", signature.getProvider());
|
||||
LOG.debug("Verifying with key: {}", key);
|
||||
LOG.debug("JCA Algorithm: {}", getJCAAlgorithm());
|
||||
LOG.debug("Signature Bytes length: {}", sig.length);
|
||||
|
||||
try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
|
||||
((DOMSignedInfo)si).canonicalize(context, outputStream);
|
||||
Type type = getAlgorithmType();
|
||||
if (type == Type.DSA) {
|
||||
int size = ((DSAKey)key).getParams().getQ().bitLength();
|
||||
return signature.verify(JavaUtils.convertDsaXMLDSIGtoASN1(sig,
|
||||
size/8));
|
||||
} else if (type == Type.ECDSA) {
|
||||
return signature.verify(SignatureECDSA.convertXMLDSIGtoASN1(sig));
|
||||
} else {
|
||||
return signature.verify(sig);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
throw new XMLSignatureException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If secure validation mode is enabled, checks that the key size is
|
||||
* restricted.
|
||||
*
|
||||
* @param context the context
|
||||
* @param key the key to check
|
||||
* @throws XMLSignatureException if the key size is restricted
|
||||
*/
|
||||
private static void checkKeySize(XMLCryptoContext context, Key key)
|
||||
throws XMLSignatureException {
|
||||
if (Utils.secureValidation(context)) {
|
||||
int size = KeyUtil.getKeySize(key);
|
||||
if (size == -1) {
|
||||
// key size cannot be determined, so we cannot check against
|
||||
// restrictions. Note that a DSA key w/o params will be
|
||||
// rejected later if the certificate chain is validated.
|
||||
LOG.debug("Size for " +
|
||||
key.getAlgorithm() + " key cannot be determined");
|
||||
return;
|
||||
}
|
||||
if (Policy.restrictKey(key.getAlgorithm(), size)) {
|
||||
throw new XMLSignatureException(key.getAlgorithm() +
|
||||
" keys less than " +
|
||||
Policy.minKeySize(key.getAlgorithm()) + " bits are" +
|
||||
" forbidden when secure validation is enabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte[] sign(Key key, SignedInfo si, XMLSignContext context)
|
||||
throws InvalidKeyException, XMLSignatureException
|
||||
{
|
||||
if (key == null || si == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (!(key instanceof PrivateKey)) {
|
||||
throw new InvalidKeyException("key must be PrivateKey");
|
||||
}
|
||||
checkKeySize(context, key);
|
||||
if (signature == null) {
|
||||
Provider p = (Provider)context.getProperty
|
||||
("org.jcp.xml.dsig.internal.dom.SignatureProvider");
|
||||
try {
|
||||
signature = getSignature(p);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new XMLSignatureException(nsae);
|
||||
}
|
||||
}
|
||||
signature.initSign((PrivateKey)key);
|
||||
LOG.debug("Signature provider: {}", signature.getProvider());
|
||||
LOG.debug("JCA Algorithm: {}", getJCAAlgorithm());
|
||||
|
||||
try (SignerOutputStream outputStream = new SignerOutputStream(signature)) {
|
||||
((DOMSignedInfo)si).canonicalize(context, outputStream);
|
||||
Type type = getAlgorithmType();
|
||||
if (type == Type.DSA) {
|
||||
int size = ((DSAKey)key).getParams().getQ().bitLength();
|
||||
return JavaUtils.convertDsaASN1toXMLDSIG(signature.sign(),
|
||||
size/8);
|
||||
} else if (type == Type.ECDSA) {
|
||||
return SignatureECDSA.convertASN1toXMLDSIG(signature.sign());
|
||||
} else {
|
||||
return signature.sign();
|
||||
}
|
||||
} catch (SignatureException se) {
|
||||
throw new XMLSignatureException(se);
|
||||
} catch (IOException ioe) {
|
||||
throw new XMLSignatureException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
abstract static class AbstractRSAPSSSignatureMethod
|
||||
extends DOMSignatureMethod {
|
||||
|
||||
AbstractRSAPSSSignatureMethod(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
|
||||
AbstractRSAPSSSignatureMethod(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
|
||||
abstract public PSSParameterSpec getPSSParameterSpec();
|
||||
|
||||
@Override
|
||||
Signature getSignature(Provider p)
|
||||
throws NoSuchAlgorithmException {
|
||||
try {
|
||||
Signature s = (p == null)
|
||||
? Signature.getInstance("RSASSA-PSS")
|
||||
: Signature.getInstance("RSASSA-PSS", p);
|
||||
try {
|
||||
s.setParameter(getPSSParameterSpec());
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
throw new NoSuchAlgorithmException("Should not happen", e);
|
||||
}
|
||||
return s;
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
return (p == null)
|
||||
? Signature.getInstance(getJCAAlgorithm())
|
||||
: Signature.getInstance(getJCAAlgorithm(), p);
|
||||
}
|
||||
}
|
||||
}
|
||||
static final class SHA1withRSA extends DOMSignatureMethod {
|
||||
SHA1withRSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA1withRSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return SignatureMethod.RSA_SHA1;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA1withRSA";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA224withRSA extends DOMSignatureMethod {
|
||||
SHA224withRSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA224withRSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return RSA_SHA224;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA224withRSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA256withRSA extends DOMSignatureMethod {
|
||||
SHA256withRSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA256withRSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return RSA_SHA256;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA256withRSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA384withRSA extends DOMSignatureMethod {
|
||||
SHA384withRSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA384withRSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return RSA_SHA384;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA384withRSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA512withRSA extends DOMSignatureMethod {
|
||||
SHA512withRSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA512withRSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return RSA_SHA512;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA512withRSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class RIPEMD160withRSA extends DOMSignatureMethod {
|
||||
RIPEMD160withRSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
RIPEMD160withRSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return RSA_RIPEMD160;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "RIPEMD160withRSA";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA1withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
|
||||
|
||||
private static PSSParameterSpec spec
|
||||
= new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1,
|
||||
20, PSSParameterSpec.TRAILER_FIELD_BC);
|
||||
|
||||
SHA1withRSAandMGF1(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA1withRSAandMGF1(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return RSA_SHA1_MGF1;
|
||||
}
|
||||
@Override
|
||||
public PSSParameterSpec getPSSParameterSpec() {
|
||||
return spec;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA1withRSAandMGF1";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA224withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
|
||||
|
||||
private static PSSParameterSpec spec
|
||||
= new PSSParameterSpec("SHA-224", "MGF1", MGF1ParameterSpec.SHA224,
|
||||
28, PSSParameterSpec.TRAILER_FIELD_BC);
|
||||
|
||||
SHA224withRSAandMGF1(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA224withRSAandMGF1(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return RSA_SHA224_MGF1;
|
||||
}
|
||||
@Override
|
||||
public PSSParameterSpec getPSSParameterSpec() {
|
||||
return spec;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA224withRSAandMGF1";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA256withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
|
||||
|
||||
private static PSSParameterSpec spec
|
||||
= new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,
|
||||
32, PSSParameterSpec.TRAILER_FIELD_BC);
|
||||
|
||||
SHA256withRSAandMGF1(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA256withRSAandMGF1(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return RSA_SHA256_MGF1;
|
||||
}
|
||||
@Override
|
||||
public PSSParameterSpec getPSSParameterSpec() {
|
||||
return spec;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA256withRSAandMGF1";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA384withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
|
||||
|
||||
private static PSSParameterSpec spec
|
||||
= new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384,
|
||||
48, PSSParameterSpec.TRAILER_FIELD_BC);
|
||||
|
||||
SHA384withRSAandMGF1(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA384withRSAandMGF1(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return RSA_SHA384_MGF1;
|
||||
}
|
||||
@Override
|
||||
public PSSParameterSpec getPSSParameterSpec() {
|
||||
return spec;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA384withRSAandMGF1";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA512withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
|
||||
|
||||
private static PSSParameterSpec spec
|
||||
= new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512,
|
||||
64, PSSParameterSpec.TRAILER_FIELD_BC);
|
||||
|
||||
SHA512withRSAandMGF1(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA512withRSAandMGF1(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return RSA_SHA512_MGF1;
|
||||
}
|
||||
@Override
|
||||
public PSSParameterSpec getPSSParameterSpec() {
|
||||
return spec;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA512withRSAandMGF1";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class RIPEMD160withRSAandMGF1 extends DOMSignatureMethod {
|
||||
RIPEMD160withRSAandMGF1(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
RIPEMD160withRSAandMGF1(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return RSA_RIPEMD160_MGF1;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "RIPEMD160withRSAandMGF1";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.RSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA1withDSA extends DOMSignatureMethod {
|
||||
SHA1withDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA1withDSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return SignatureMethod.DSA_SHA1;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA1withDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.DSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA256withDSA extends DOMSignatureMethod {
|
||||
SHA256withDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA256withDSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return DSA_SHA256;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA256withDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.DSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA1withECDSA extends DOMSignatureMethod {
|
||||
SHA1withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA1withECDSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return ECDSA_SHA1;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA1withECDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.ECDSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA224withECDSA extends DOMSignatureMethod {
|
||||
SHA224withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA224withECDSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return ECDSA_SHA224;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA224withECDSA";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.ECDSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA256withECDSA extends DOMSignatureMethod {
|
||||
SHA256withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA256withECDSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return ECDSA_SHA256;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA256withECDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.ECDSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA384withECDSA extends DOMSignatureMethod {
|
||||
SHA384withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA384withECDSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return ECDSA_SHA384;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA384withECDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.ECDSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA512withECDSA extends DOMSignatureMethod {
|
||||
SHA512withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
SHA512withECDSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
public String getAlgorithm() {
|
||||
return ECDSA_SHA512;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA512withECDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
return Type.ECDSA;
|
||||
}
|
||||
}
|
||||
|
||||
static final class RIPEMD160withECDSA extends DOMSignatureMethod {
|
||||
RIPEMD160withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
}
|
||||
RIPEMD160withECDSA(Element dmElem) throws MarshalException {
|
||||
super(dmElem);
|
||||
}
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return ECDSA_RIPEMD160;
|
||||
}
|
||||
@Override
|
||||
String getJCAAlgorithm() {
|
||||
return "RIPEMD160withECDSA";
|
||||
}
|
||||
@Override
|
||||
Type getAlgorithmType() {
|
||||
return Type.ECDSA;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMSignatureProperties.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of SignatureProperties.
|
||||
*
|
||||
*/
|
||||
public final class DOMSignatureProperties extends DOMStructure
|
||||
implements SignatureProperties {
|
||||
|
||||
private final String id;
|
||||
private final List<SignatureProperty> properties;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMSignatureProperties} from the specified
|
||||
* parameters.
|
||||
*
|
||||
* @param properties a list of one or more {@link SignatureProperty}s. The
|
||||
* list is defensively copied to protect against subsequent modification.
|
||||
* @param id the Id (may be {@code null})
|
||||
* @throws ClassCastException if {@code properties} contains any
|
||||
* entries that are not of type {@link SignatureProperty}
|
||||
* @throws IllegalArgumentException if {@code properties} is empty
|
||||
* @throws NullPointerException if {@code properties}
|
||||
*/
|
||||
public DOMSignatureProperties(List<? extends SignatureProperty> properties,
|
||||
String id)
|
||||
{
|
||||
if (properties == null) {
|
||||
throw new NullPointerException("properties cannot be null");
|
||||
} else if (properties.isEmpty()) {
|
||||
throw new IllegalArgumentException("properties cannot be empty");
|
||||
} else {
|
||||
this.properties = Collections.unmodifiableList(
|
||||
new ArrayList<>(properties));
|
||||
for (int i = 0, size = this.properties.size(); i < size; i++) {
|
||||
if (!(this.properties.get(i) instanceof SignatureProperty)) {
|
||||
throw new ClassCastException
|
||||
("properties["+i+"] is not a valid type");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMSignatureProperties} from an element.
|
||||
*
|
||||
* @param propsElem a SignatureProperties element
|
||||
* @throws MarshalException if a marshalling error occurs
|
||||
*/
|
||||
public DOMSignatureProperties(Element propsElem)
|
||||
throws MarshalException
|
||||
{
|
||||
// unmarshal attributes
|
||||
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();
|
||||
while (firstChild != null) {
|
||||
if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
|
||||
String name = firstChild.getLocalName();
|
||||
String namespace = firstChild.getNamespaceURI();
|
||||
if (!"SignatureProperty".equals(name) || !XMLSignature.XMLNS.equals(namespace)) {
|
||||
throw new MarshalException("Invalid element name: " + namespace + ":" + name +
|
||||
", expected SignatureProperty");
|
||||
}
|
||||
newProperties.add(new DOMSignatureProperty((Element)firstChild));
|
||||
}
|
||||
firstChild = firstChild.getNextSibling();
|
||||
}
|
||||
if (newProperties.isEmpty()) {
|
||||
throw new MarshalException("properties cannot be empty");
|
||||
} else {
|
||||
this.properties = Collections.unmodifiableList(newProperties);
|
||||
}
|
||||
}
|
||||
|
||||
public List<SignatureProperty> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
Element propsElem = DOMUtils.createElement(ownerDoc,
|
||||
"SignatureProperties",
|
||||
XMLSignature.XMLNS,
|
||||
dsPrefix);
|
||||
|
||||
// set attributes
|
||||
DOMUtils.setAttributeID(propsElem, "Id", id);
|
||||
|
||||
// create and append any properties
|
||||
for (SignatureProperty property : properties) {
|
||||
((DOMSignatureProperty)property).marshal(propsElem, dsPrefix,
|
||||
context);
|
||||
}
|
||||
|
||||
parent.appendChild(propsElem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof SignatureProperties)) {
|
||||
return false;
|
||||
}
|
||||
SignatureProperties osp = (SignatureProperties)o;
|
||||
|
||||
boolean idsEqual = id == null ? osp.getId() == null
|
||||
: id.equals(osp.getId());
|
||||
|
||||
return properties.equals(osp.getProperties()) && idsEqual;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (id != null) {
|
||||
result = 31 * result + id.hashCode();
|
||||
}
|
||||
result = 31 * result + properties.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMSignatureProperty.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of SignatureProperty.
|
||||
*
|
||||
*/
|
||||
public final class DOMSignatureProperty extends DOMStructure
|
||||
implements SignatureProperty {
|
||||
|
||||
private final String id;
|
||||
private final String target;
|
||||
private final List<XMLStructure> content;
|
||||
|
||||
/**
|
||||
* Creates a {@code SignatureProperty} from the specified parameters.
|
||||
*
|
||||
* @param content a list of one or more {@link XMLStructure}s. The list
|
||||
* is defensively copied to protect against subsequent modification.
|
||||
* @param target the target URI
|
||||
* @param id the Id (may be {@code null})
|
||||
* @throws ClassCastException if {@code content} contains any
|
||||
* entries that are not of type {@link XMLStructure}
|
||||
* @throws IllegalArgumentException if {@code content} is empty
|
||||
* @throws NullPointerException if {@code content} or
|
||||
* {@code target} is {@code null}
|
||||
*/
|
||||
public DOMSignatureProperty(List<? extends XMLStructure> content,
|
||||
String target, String id)
|
||||
{
|
||||
if (target == null) {
|
||||
throw new NullPointerException("target cannot be null");
|
||||
} else if (content == null) {
|
||||
throw new NullPointerException("content cannot be null");
|
||||
} else if (content.isEmpty()) {
|
||||
throw new IllegalArgumentException("content cannot be empty");
|
||||
} else {
|
||||
this.content = Collections.unmodifiableList(
|
||||
new ArrayList<>(content));
|
||||
for (int i = 0, size = this.content.size(); i < size; i++) {
|
||||
if (!(this.content.get(i) instanceof XMLStructure)) {
|
||||
throw new ClassCastException
|
||||
("content["+i+"] is not a valid type");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.target = target;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMSignatureProperty} from an element.
|
||||
*
|
||||
* @param propElem a SignatureProperty element
|
||||
*/
|
||||
public DOMSignatureProperty(Element propElem)
|
||||
throws MarshalException
|
||||
{
|
||||
// unmarshal attributes
|
||||
target = DOMUtils.getAttributeValue(propElem, "Target");
|
||||
if (target == null) {
|
||||
throw new MarshalException("target cannot be null");
|
||||
}
|
||||
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();
|
||||
while (firstChild != null) {
|
||||
newContent.add(new javax.xml.crypto.dom.DOMStructure(firstChild));
|
||||
firstChild = firstChild.getNextSibling();
|
||||
}
|
||||
if (newContent.isEmpty()) {
|
||||
throw new MarshalException("content cannot be empty");
|
||||
} else {
|
||||
this.content = Collections.unmodifiableList(newContent);
|
||||
}
|
||||
}
|
||||
|
||||
public List<XMLStructure> getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
Element propElem = DOMUtils.createElement(ownerDoc, "SignatureProperty",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
|
||||
// set attributes
|
||||
DOMUtils.setAttributeID(propElem, "Id", id);
|
||||
DOMUtils.setAttribute(propElem, "Target", target);
|
||||
|
||||
// create and append any elements and mixed content
|
||||
for (XMLStructure property : content) {
|
||||
DOMUtils.appendChild(propElem,
|
||||
((javax.xml.crypto.dom.DOMStructure)property).getNode());
|
||||
}
|
||||
|
||||
parent.appendChild(propElem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof SignatureProperty)) {
|
||||
return false;
|
||||
}
|
||||
SignatureProperty osp = (SignatureProperty)o;
|
||||
|
||||
boolean idsEqual = id == null ? osp.getId() == null
|
||||
: id.equals(osp.getId());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<XMLStructure> ospContent = osp.getContent();
|
||||
return equalsContent(ospContent) &&
|
||||
target.equals(osp.getTarget()) && idsEqual;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (id != null) {
|
||||
result = 31 * result + id.hashCode();
|
||||
}
|
||||
result = 31 * result + target.hashCode();
|
||||
result = 31 * result + content.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean equalsContent(List<XMLStructure> otherContent) {
|
||||
int osize = otherContent.size();
|
||||
if (content.size() != osize) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < osize; i++) {
|
||||
XMLStructure oxs = otherContent.get(i);
|
||||
XMLStructure xs = content.get(i);
|
||||
if (oxs instanceof javax.xml.crypto.dom.DOMStructure) {
|
||||
if (!(xs instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
return false;
|
||||
}
|
||||
Node onode = ((javax.xml.crypto.dom.DOMStructure)oxs).getNode();
|
||||
Node node = ((javax.xml.crypto.dom.DOMStructure)xs).getNode();
|
||||
if (!DOMUtils.nodesEqual(node, onode)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!(xs.equals(oxs))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
303
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java
Normal file
303
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMSignedInfo.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
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.
|
||||
*
|
||||
*/
|
||||
public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
|
||||
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMSignedInfo.class);
|
||||
|
||||
private List<Reference> references;
|
||||
private CanonicalizationMethod canonicalizationMethod;
|
||||
private SignatureMethod signatureMethod;
|
||||
private String id;
|
||||
private Document ownerDoc;
|
||||
private Element localSiElem;
|
||||
private InputStream canonData;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMSignedInfo} from the specified parameters. Use
|
||||
* this constructor when the {@code Id} is not specified.
|
||||
*
|
||||
* @param cm the canonicalization method
|
||||
* @param sm the signature method
|
||||
* @param references the list of references. The list is copied.
|
||||
* @throws NullPointerException if
|
||||
* {@code cm}, {@code sm}, or {@code references} is
|
||||
* {@code null}
|
||||
* @throws IllegalArgumentException if {@code references} is empty
|
||||
* @throws ClassCastException if any of the references are not of
|
||||
* type {@code Reference}
|
||||
*/
|
||||
public DOMSignedInfo(CanonicalizationMethod cm, SignatureMethod sm,
|
||||
List<? extends Reference> references) {
|
||||
if (cm == null || sm == null || references == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.canonicalizationMethod = cm;
|
||||
this.signatureMethod = sm;
|
||||
this.references = Collections.unmodifiableList(
|
||||
new ArrayList<>(references));
|
||||
if (this.references.isEmpty()) {
|
||||
throw new IllegalArgumentException("list of references must " +
|
||||
"contain at least one entry");
|
||||
}
|
||||
for (int i = 0, size = this.references.size(); i < size; i++) {
|
||||
Object obj = this.references.get(i);
|
||||
if (!(obj instanceof Reference)) {
|
||||
throw new ClassCastException("list of references contains " +
|
||||
"an illegal type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMSignedInfo} from the specified parameters.
|
||||
*
|
||||
* @param cm the canonicalization method
|
||||
* @param sm the signature method
|
||||
* @param references the list of references. The list is copied.
|
||||
* @param id an optional identifer that will allow this
|
||||
* {@code SignedInfo} to be referenced by other signatures and
|
||||
* objects
|
||||
* @throws NullPointerException if {@code cm}, {@code sm},
|
||||
* or {@code references} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code references} is empty
|
||||
* @throws ClassCastException if any of the references are not of
|
||||
* type {@code Reference}
|
||||
*/
|
||||
public DOMSignedInfo(CanonicalizationMethod cm, SignatureMethod sm,
|
||||
List<? extends Reference> references, String id) {
|
||||
this(cm, sm, references);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMSignedInfo} from an element.
|
||||
*
|
||||
* @param siElem a SignedInfo element
|
||||
*/
|
||||
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");
|
||||
|
||||
// unmarshal CanonicalizationMethod
|
||||
Element cmElem = DOMUtils.getFirstChildElement(siElem,
|
||||
"CanonicalizationMethod",
|
||||
XMLSignature.XMLNS);
|
||||
canonicalizationMethod = new DOMCanonicalizationMethod(cmElem, context,
|
||||
provider);
|
||||
|
||||
// unmarshal SignatureMethod
|
||||
Element smElem = DOMUtils.getNextSiblingElement(cmElem,
|
||||
"SignatureMethod",
|
||||
XMLSignature.XMLNS);
|
||||
signatureMethod = DOMSignatureMethod.unmarshal(smElem);
|
||||
|
||||
boolean secVal = Utils.secureValidation(context);
|
||||
|
||||
String signatureMethodAlgorithm = signatureMethod.getAlgorithm();
|
||||
if (secVal && Policy.restrictAlg(signatureMethodAlgorithm)) {
|
||||
throw new MarshalException(
|
||||
"It is forbidden to use algorithm " + signatureMethodAlgorithm +
|
||||
" when secure validation is enabled"
|
||||
);
|
||||
}
|
||||
|
||||
// unmarshal References
|
||||
ArrayList<Reference> refList = new ArrayList<>(5);
|
||||
Element refElem = DOMUtils.getNextSiblingElement(smElem, "Reference", XMLSignature.XMLNS);
|
||||
refList.add(new DOMReference(refElem, context, provider));
|
||||
|
||||
refElem = DOMUtils.getNextSiblingElement(refElem);
|
||||
while (refElem != null) {
|
||||
String name = refElem.getLocalName();
|
||||
String namespace = refElem.getNamespaceURI();
|
||||
if (!"Reference".equals(name) || !XMLSignature.XMLNS.equals(namespace)) {
|
||||
throw new MarshalException("Invalid element name: " +
|
||||
namespace + ":" + name + ", expected Reference");
|
||||
}
|
||||
refList.add(new DOMReference(refElem, context, provider));
|
||||
if (secVal && Policy.restrictNumReferences(refList.size())) {
|
||||
String error = "A maxiumum of " + Policy.maxReferences()
|
||||
+ " references per Manifest are allowed when"
|
||||
+ " secure validation is enabled";
|
||||
throw new MarshalException(error);
|
||||
}
|
||||
refElem = DOMUtils.getNextSiblingElement(refElem);
|
||||
}
|
||||
references = Collections.unmodifiableList(refList);
|
||||
}
|
||||
|
||||
public CanonicalizationMethod getCanonicalizationMethod() {
|
||||
return canonicalizationMethod;
|
||||
}
|
||||
|
||||
public SignatureMethod getSignatureMethod() {
|
||||
return signatureMethod;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<Reference> getReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
public InputStream getCanonicalizedData() {
|
||||
return canonData;
|
||||
}
|
||||
|
||||
public void canonicalize(XMLCryptoContext context, ByteArrayOutputStream bos)
|
||||
throws XMLSignatureException {
|
||||
if (context == null) {
|
||||
throw new NullPointerException("context cannot be null");
|
||||
}
|
||||
|
||||
DOMSubTreeData subTree = new DOMSubTreeData(localSiElem, true);
|
||||
try (OutputStream os = new UnsyncBufferedOutputStream(bos)) {
|
||||
((DOMCanonicalizationMethod)
|
||||
canonicalizationMethod).canonicalize(subTree, context, os);
|
||||
|
||||
os.flush();
|
||||
|
||||
byte[] signedInfoBytes = bos.toByteArray();
|
||||
|
||||
// this whole block should only be done if LOGging is enabled
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Canonicalized SignedInfo:");
|
||||
StringBuilder sb = new StringBuilder(signedInfoBytes.length);
|
||||
for (int i = 0; i < signedInfoBytes.length; i++) {
|
||||
sb.append((char)signedInfoBytes[i]);
|
||||
}
|
||||
LOG.debug(sb.toString());
|
||||
LOG.debug("Data to be signed/verified:" + XMLUtils.encodeToString(signedInfoBytes));
|
||||
}
|
||||
|
||||
this.canonData = new ByteArrayInputStream(signedInfoBytes);
|
||||
} catch (TransformException te) {
|
||||
throw new XMLSignatureException(te);
|
||||
} catch (IOException e) {
|
||||
LOG.debug(e.getMessage(), e);
|
||||
// Impossible
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
Element siElem = DOMUtils.createElement(ownerDoc, "SignedInfo",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
|
||||
// create and append CanonicalizationMethod element
|
||||
DOMCanonicalizationMethod dcm =
|
||||
(DOMCanonicalizationMethod)canonicalizationMethod;
|
||||
dcm.marshal(siElem, dsPrefix, context);
|
||||
|
||||
// create and append SignatureMethod element
|
||||
((DOMStructure)signatureMethod).marshal(siElem, dsPrefix, context);
|
||||
|
||||
// create and append Reference elements
|
||||
for (Reference reference : references) {
|
||||
((DOMReference)reference).marshal(siElem, dsPrefix, context);
|
||||
}
|
||||
|
||||
// append Id attribute
|
||||
DOMUtils.setAttributeID(siElem, "Id", id);
|
||||
|
||||
parent.appendChild(siElem);
|
||||
localSiElem = siElem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof SignedInfo)) {
|
||||
return false;
|
||||
}
|
||||
SignedInfo osi = (SignedInfo)o;
|
||||
|
||||
boolean idEqual = id == null ? osi.getId() == null
|
||||
: id.equals(osi.getId());
|
||||
|
||||
return canonicalizationMethod.equals(osi.getCanonicalizationMethod())
|
||||
&& signatureMethod.equals(osi.getSignatureMethod()) &&
|
||||
references.equals(osi.getReferences()) && idEqual;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Reference> getSignedInfoReferences(SignedInfo si) {
|
||||
return si.getReferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (id != null) {
|
||||
result = 31 * result + id.hashCode();
|
||||
}
|
||||
result = 31 * result + canonicalizationMethod.hashCode();
|
||||
result = 31 * result + signatureMethod.hashCode();
|
||||
result = 31 * result + references.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
52
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMStructure.java
Normal file
52
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMStructure.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMStructure.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.MarshalException;
|
||||
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 implements XMLStructure {
|
||||
|
||||
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;
|
||||
}
|
||||
182
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java
Normal file
182
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.NodeSetData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* This is a subtype of NodeSetData that represents a dereferenced
|
||||
* same-document URI as the root of a subdocument. The main reason is
|
||||
* for efficiency and performance, as some transforms can operate
|
||||
* directly on the subdocument and there is no need to convert it
|
||||
* first to an XPath node-set.
|
||||
*/
|
||||
public class DOMSubTreeData implements NodeSetData {
|
||||
|
||||
private boolean excludeComments;
|
||||
private Node root;
|
||||
|
||||
public DOMSubTreeData(Node root, boolean excludeComments) {
|
||||
this.root = root;
|
||||
this.excludeComments = excludeComments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Node> iterator() {
|
||||
return new DelayedNodeIterator(root, excludeComments);
|
||||
}
|
||||
|
||||
public Node getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public boolean excludeComments() {
|
||||
return excludeComments;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an Iterator that contains a backing node-set that is
|
||||
* not populated until the caller first attempts to advance the iterator.
|
||||
*/
|
||||
static class DelayedNodeIterator implements Iterator<Node> {
|
||||
private Node root;
|
||||
private List<Node> nodeSet;
|
||||
private ListIterator<Node> li;
|
||||
private boolean withComments;
|
||||
|
||||
DelayedNodeIterator(Node root, boolean excludeComments) {
|
||||
this.root = root;
|
||||
this.withComments = !excludeComments;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
if (nodeSet == null) {
|
||||
nodeSet = dereferenceSameDocumentURI(root);
|
||||
li = nodeSet.listIterator();
|
||||
}
|
||||
return li.hasNext();
|
||||
}
|
||||
|
||||
public Node next() {
|
||||
if (nodeSet == null) {
|
||||
nodeSet = dereferenceSameDocumentURI(root);
|
||||
li = nodeSet.listIterator();
|
||||
}
|
||||
if (li.hasNext()) {
|
||||
return li.next();
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dereferences a same-document URI fragment.
|
||||
*
|
||||
* @param node the node (document or element) referenced by the
|
||||
* URI fragment. If null, returns an empty set.
|
||||
* @return a set of nodes (minus any comment nodes)
|
||||
*/
|
||||
private List<Node> dereferenceSameDocumentURI(Node node) {
|
||||
List<Node> nodes = new ArrayList<>();
|
||||
if (node != null) {
|
||||
nodeSetMinusCommentNodes(node, nodes, null);
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively traverses the subtree, and returns an XPath-equivalent
|
||||
* node-set of all nodes traversed, excluding any comment nodes,
|
||||
* if specified.
|
||||
*
|
||||
* @param node the node to traverse
|
||||
* @param nodeSet the set of nodes traversed so far
|
||||
* @param the previous sibling node
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
private void nodeSetMinusCommentNodes(Node node, List<Node> nodeSet,
|
||||
Node prevSibling)
|
||||
{
|
||||
switch (node.getNodeType()) {
|
||||
case Node.ELEMENT_NODE :
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
if (attrs != null) {
|
||||
for (int i = 0, len = attrs.getLength(); i < len; i++) {
|
||||
nodeSet.add(attrs.item(i));
|
||||
}
|
||||
}
|
||||
nodeSet.add(node);
|
||||
Node pSibling = null;
|
||||
for (Node child = node.getFirstChild(); child != null;
|
||||
child = child.getNextSibling()) {
|
||||
nodeSetMinusCommentNodes(child, nodeSet, pSibling);
|
||||
pSibling = child;
|
||||
}
|
||||
break;
|
||||
case Node.DOCUMENT_NODE :
|
||||
pSibling = null;
|
||||
for (Node child = node.getFirstChild(); child != null;
|
||||
child = child.getNextSibling()) {
|
||||
nodeSetMinusCommentNodes(child, nodeSet, pSibling);
|
||||
pSibling = child;
|
||||
}
|
||||
break;
|
||||
case Node.TEXT_NODE :
|
||||
case Node.CDATA_SECTION_NODE:
|
||||
// emulate XPath which only returns the first node in
|
||||
// contiguous text/cdata nodes
|
||||
if (prevSibling != null &&
|
||||
(prevSibling.getNodeType() == Node.TEXT_NODE ||
|
||||
prevSibling.getNodeType() == Node.CDATA_SECTION_NODE)) {
|
||||
return;
|
||||
}
|
||||
nodeSet.add(node);
|
||||
break;
|
||||
case Node.PROCESSING_INSTRUCTION_NODE :
|
||||
nodeSet.add(node);
|
||||
break;
|
||||
case Node.COMMENT_NODE:
|
||||
if (withComments) {
|
||||
nodeSet.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
227
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMTransform.java
Normal file
227
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMTransform.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
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;
|
||||
|
||||
/**
|
||||
* DOM-based abstract implementation of Transform.
|
||||
*
|
||||
*/
|
||||
public class DOMTransform extends DOMStructure implements Transform {
|
||||
|
||||
protected TransformService spi;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMTransform}.
|
||||
*
|
||||
* @param spi the TransformService
|
||||
*/
|
||||
public DOMTransform(TransformService spi) {
|
||||
this.spi = spi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMTransform} from an element. It unmarshals any
|
||||
* algorithm-specific input parameters.
|
||||
*
|
||||
* @param transElem a Transform element
|
||||
*/
|
||||
public DOMTransform(Element transElem, XMLCryptoContext context,
|
||||
Provider provider)
|
||||
throws MarshalException
|
||||
{
|
||||
String algorithm = DOMUtils.getAttributeValue(transElem, "Algorithm");
|
||||
|
||||
if (provider == null) {
|
||||
try {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
} catch (NoSuchAlgorithmException e1) {
|
||||
throw new MarshalException(e1);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
spi = TransformService.getInstance(algorithm, "DOM", provider);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
try {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
} catch (NoSuchAlgorithmException e2) {
|
||||
throw new MarshalException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
spi.init(new javax.xml.crypto.dom.DOMStructure(transElem), context);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new MarshalException(iape);
|
||||
}
|
||||
}
|
||||
|
||||
public final AlgorithmParameterSpec getParameterSpec() {
|
||||
return spi.getParameterSpec();
|
||||
}
|
||||
|
||||
public final String getAlgorithm() {
|
||||
return spi.getAlgorithm();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method marshals any algorithm-specific parameters.
|
||||
*/
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
|
||||
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());
|
||||
|
||||
spi.marshalParams(new javax.xml.crypto.dom.DOMStructure(transformElem),
|
||||
context);
|
||||
|
||||
parent.appendChild(transformElem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the specified data using the underlying transform algorithm.
|
||||
*
|
||||
* @param data the data to be transformed
|
||||
* @param xc the {@code XMLCryptoContext} containing
|
||||
* additional context (may be {@code null} if not applicable)
|
||||
* @return the transformed data
|
||||
* @throws NullPointerException if {@code data} is {@code null}
|
||||
* @throws XMLSignatureException if an unexpected error occurs while
|
||||
* executing the transform
|
||||
*/
|
||||
public Data transform(Data data, XMLCryptoContext xc)
|
||||
throws TransformException
|
||||
{
|
||||
return spi.transform(data, xc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the specified data using the underlying transform algorithm.
|
||||
*
|
||||
* @param data the data to be transformed
|
||||
* @param xc the {@code XMLCryptoContext} containing
|
||||
* additional context (may be {@code null} if not applicable)
|
||||
* @param os the {@code OutputStream} that should be used to write
|
||||
* the transformed data to
|
||||
* @return the transformed data
|
||||
* @throws NullPointerException if {@code data} is {@code null}
|
||||
* @throws XMLSignatureException if an unexpected error occurs while
|
||||
* executing the transform
|
||||
*/
|
||||
public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
|
||||
throws TransformException
|
||||
{
|
||||
return spi.transform(data, xc, os);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Transform)) {
|
||||
return false;
|
||||
}
|
||||
Transform otransform = (Transform)o;
|
||||
|
||||
return getAlgorithm().equals(otransform.getAlgorithm()) &&
|
||||
DOMUtils.paramsEqual(getParameterSpec(),
|
||||
otransform.getParameterSpec());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + getAlgorithm().hashCode();
|
||||
AlgorithmParameterSpec spec = getParameterSpec();
|
||||
if (spec != null) {
|
||||
result = 31 * result + spec.hashCode();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the specified data using the underlying transform algorithm.
|
||||
* This method invokes the {@link #marshal marshal} method and passes it
|
||||
* the specified {@code DOMSignContext} before transforming the data.
|
||||
*
|
||||
* @param data the data to be transformed
|
||||
* @param sc the {@code XMLCryptoContext} containing
|
||||
* additional context (may be {@code null} if not applicable)
|
||||
* @param context the marshalling context
|
||||
* @return the transformed data
|
||||
* @throws MarshalException if an exception occurs while marshalling
|
||||
* @throws NullPointerException if {@code data} or {@code context}
|
||||
* is {@code null}
|
||||
* @throws XMLSignatureException if an unexpected error occurs while
|
||||
* executing the transform
|
||||
*/
|
||||
Data transform(Data data, XMLCryptoContext xc, DOMSignContext context)
|
||||
throws MarshalException, TransformException
|
||||
{
|
||||
marshal(context.getParent(),
|
||||
DOMUtils.getSignaturePrefix(context), context);
|
||||
return transform(data, xc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMURIDereferencer.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.Init;
|
||||
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
|
||||
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;
|
||||
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dom.*;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of URIDereferencer.
|
||||
*
|
||||
*/
|
||||
public final class DOMURIDereferencer implements URIDereferencer {
|
||||
|
||||
static final URIDereferencer INSTANCE = new DOMURIDereferencer();
|
||||
|
||||
private DOMURIDereferencer() {
|
||||
// need to call com.sun.org.apache.xml.internal.security.Init.init()
|
||||
// before calling any apache security code
|
||||
Init.init();
|
||||
}
|
||||
|
||||
public Data dereference(URIReference uriRef, XMLCryptoContext context)
|
||||
throws URIReferenceException {
|
||||
|
||||
if (uriRef == null) {
|
||||
throw new NullPointerException("uriRef cannot be null");
|
||||
}
|
||||
if (context == null) {
|
||||
throw new NullPointerException("context cannot be null");
|
||||
}
|
||||
|
||||
DOMURIReference domRef = (DOMURIReference) uriRef;
|
||||
Attr uriAttr = (Attr) domRef.getHere();
|
||||
String uri = uriRef.getURI();
|
||||
DOMCryptoContext dcc = (DOMCryptoContext) context;
|
||||
String baseURI = context.getBaseURI();
|
||||
|
||||
boolean secVal = Utils.secureValidation(context);
|
||||
|
||||
if (secVal) {
|
||||
try {
|
||||
if (Policy.restrictReferenceUriScheme(uri)) {
|
||||
throw new URIReferenceException(
|
||||
"URI " + uri + " is forbidden when secure validation is enabled");
|
||||
}
|
||||
|
||||
if (uri != null && !uri.isEmpty() && uri.charAt(0) != '#' && URI.create(uri).getScheme() == null) {
|
||||
// beseURI will be used to dereference a relative uri
|
||||
try {
|
||||
if (Policy.restrictReferenceUriScheme(baseURI)) {
|
||||
throw new URIReferenceException(
|
||||
"Base URI " + baseURI + " is forbidden when secure validation is enabled");
|
||||
}
|
||||
} catch (IllegalArgumentException e) { // thrown by Policy.restrictReferenceUriScheme
|
||||
throw new URIReferenceException("Invalid base URI " + baseURI);
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException e) { // thrown by Policy.restrictReferenceUriScheme or URI.create
|
||||
throw new URIReferenceException("Invalid URI " + uri);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if same-document URI and already registered on the context
|
||||
if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') {
|
||||
String id = uri.substring(1);
|
||||
|
||||
if (id.startsWith("xpointer(id(")) {
|
||||
int i1 = id.indexOf('\'');
|
||||
int i2 = id.indexOf('\'', i1+1);
|
||||
id = id.substring(i1+1, i2);
|
||||
}
|
||||
|
||||
// check if element is registered by Id
|
||||
Node referencedElem = uriAttr.getOwnerDocument().getElementById(id);
|
||||
if (referencedElem == null) {
|
||||
// see if element is registered in DOMCryptoContext
|
||||
referencedElem = dcc.getElementById(id);
|
||||
}
|
||||
if (referencedElem != null) {
|
||||
if (secVal && Policy.restrictDuplicateIds()) {
|
||||
Element start = referencedElem.getOwnerDocument().getDocumentElement();
|
||||
if (!XMLUtils.protectAgainstWrappingAttack(start, (Element)referencedElem, id)) {
|
||||
String error = "Multiple Elements with the same ID "
|
||||
+ id + " detected when secure validation"
|
||||
+ " is enabled";
|
||||
throw new URIReferenceException(error);
|
||||
}
|
||||
}
|
||||
|
||||
XMLSignatureInput result = new XMLSignatureInput(referencedElem);
|
||||
result.setSecureValidation(secVal);
|
||||
if (!uri.substring(1).startsWith("xpointer(id(")) {
|
||||
result.setExcludeComments(true);
|
||||
}
|
||||
|
||||
result.setMIMEType("text/xml");
|
||||
if (baseURI != null && baseURI.length() > 0) {
|
||||
result.setSourceURI(baseURI.concat(uriAttr.getNodeValue()));
|
||||
} else {
|
||||
result.setSourceURI(uriAttr.getNodeValue());
|
||||
}
|
||||
return new ApacheNodeSetData(result);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
ResourceResolver apacheResolver =
|
||||
ResourceResolver.getInstance(uriAttr, baseURI, secVal);
|
||||
XMLSignatureInput in = apacheResolver.resolve(uriAttr, baseURI, secVal);
|
||||
if (in.isOctetStream()) {
|
||||
return new ApacheOctetStreamData(in);
|
||||
} else {
|
||||
return new ApacheNodeSetData(in);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new URIReferenceException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
520
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMUtils.java
Normal file
520
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMUtils.java
Normal file
@@ -0,0 +1,520 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMUtils.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.util.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.spec.*;
|
||||
|
||||
/**
|
||||
* Useful static DOM utility methods.
|
||||
*
|
||||
*/
|
||||
public final class DOMUtils {
|
||||
|
||||
// class cannot be instantiated
|
||||
private DOMUtils() {}
|
||||
|
||||
/**
|
||||
* Returns the owner document of the specified node.
|
||||
*
|
||||
* @param node the node
|
||||
* @return the owner document
|
||||
*/
|
||||
public static Document getOwnerDocument(Node node) {
|
||||
if (node.getNodeType() == Node.DOCUMENT_NODE) {
|
||||
return (Document)node;
|
||||
} else {
|
||||
return node.getOwnerDocument();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a QName string from a prefix and local name.
|
||||
*
|
||||
* @param prefix The prefix, if any. Can be either null or empty.
|
||||
* @param localName The local name.
|
||||
*
|
||||
* @return The string for the qName, for example, "xsd:element".
|
||||
*/
|
||||
public static String getQNameString(String prefix, String localName) {
|
||||
String qName = prefix == null || prefix.length() == 0
|
||||
? localName : prefix + ":" + localName;
|
||||
|
||||
return qName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an element in the specified namespace, with the specified tag
|
||||
* and namespace prefix.
|
||||
*
|
||||
* @param doc the owner document
|
||||
* @param tag the tag
|
||||
* @param nsURI the namespace URI
|
||||
* @param prefix the namespace prefix
|
||||
* @return the newly created element
|
||||
*/
|
||||
public static Element createElement(Document doc, String tag,
|
||||
String nsURI, String prefix)
|
||||
{
|
||||
String qName = prefix == null || prefix.length() == 0
|
||||
? tag : prefix + ":" + tag;
|
||||
return doc.createElementNS(nsURI, qName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element's attribute (using DOM level 2) with the
|
||||
* specified value and namespace prefix.
|
||||
*
|
||||
* @param elem the element to set the attribute on
|
||||
* @param name the name of the attribute
|
||||
* @param value the attribute value. If null, no attribute is set.
|
||||
*/
|
||||
public static void setAttribute(Element elem, String name, String value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
elem.setAttributeNS(null, name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element's attribute (using DOM level 2) with the
|
||||
* specified value and namespace prefix AND registers the ID value with
|
||||
* the specified element. This is for resolving same-document
|
||||
* ID references.
|
||||
*
|
||||
* @param elem the element to set the attribute on
|
||||
* @param name the name of the attribute
|
||||
* @param value the attribute value. If null, no attribute is set.
|
||||
*/
|
||||
public static void setAttributeID(Element elem, String name, String value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
elem.setAttributeNS(null, name, value);
|
||||
elem.setIdAttributeNS(null, name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first child element of the specified node, or null if there
|
||||
* is no such element.
|
||||
*
|
||||
* @param node the node
|
||||
* @return the first child element of the specified node, or null if there
|
||||
* is no such element
|
||||
* @throws NullPointerException if {@code node == null}
|
||||
*/
|
||||
public static Element getFirstChildElement(Node node) {
|
||||
Node child = node.getFirstChild();
|
||||
while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
|
||||
child = child.getNextSibling();
|
||||
}
|
||||
return (Element)child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first child element of the specified node and checks that
|
||||
* the local name is equal to {@code localName}.
|
||||
*
|
||||
* @param node the node
|
||||
* @return the first child element of the specified node
|
||||
* @throws NullPointerException if {@code node == null}
|
||||
* @throws MarshalException if no such element or the local name is not
|
||||
* equal to {@code localName}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Element getFirstChildElement(Node node, String localName)
|
||||
throws MarshalException
|
||||
{
|
||||
return verifyElement(getFirstChildElement(node), localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first child element of the specified node and checks that
|
||||
* the local name is equal to {@code localName} and the namespace is equal to
|
||||
* {@code namespaceURI}
|
||||
*
|
||||
* @param node the node
|
||||
* @return the first child element of the specified node
|
||||
* @throws NullPointerException if {@code node == null}
|
||||
* @throws MarshalException if no such element or the local name is not
|
||||
* equal to {@code localName}
|
||||
*/
|
||||
public static Element getFirstChildElement(Node node, String localName, String namespaceURI)
|
||||
throws MarshalException
|
||||
{
|
||||
return verifyElement(getFirstChildElement(node), localName, namespaceURI);
|
||||
}
|
||||
|
||||
private static Element verifyElement(Element elem, String localName)
|
||||
throws MarshalException
|
||||
{
|
||||
if (elem == null) {
|
||||
throw new MarshalException("Missing " + localName + " element");
|
||||
}
|
||||
String name = elem.getLocalName();
|
||||
if (!name.equals(localName)) {
|
||||
throw new MarshalException("Invalid element name: " +
|
||||
name + ", expected " + localName);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
private static Element verifyElement(Element elem, String localName, String namespaceURI)
|
||||
throws MarshalException
|
||||
{
|
||||
if (elem == null) {
|
||||
throw new MarshalException("Missing " + localName + " element");
|
||||
}
|
||||
String name = elem.getLocalName();
|
||||
String namespace = elem.getNamespaceURI();
|
||||
if (!name.equals(localName) || namespace == null && namespaceURI != null
|
||||
|| namespace != null && !namespace.equals(namespaceURI)) {
|
||||
throw new MarshalException("Invalid element name: " +
|
||||
namespace + ":" + name + ", expected " + namespaceURI + ":" + localName);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last child element of the specified node, or null if there
|
||||
* is no such element.
|
||||
*
|
||||
* @param node the node
|
||||
* @return the last child element of the specified node, or null if there
|
||||
* is no such element
|
||||
* @throws NullPointerException if {@code node == null}
|
||||
*/
|
||||
public static Element getLastChildElement(Node node) {
|
||||
Node child = node.getLastChild();
|
||||
while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
|
||||
child = child.getPreviousSibling();
|
||||
}
|
||||
return (Element)child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next sibling element of the specified node, or null if there
|
||||
* is no such element.
|
||||
*
|
||||
* @param node the node
|
||||
* @return the next sibling element of the specified node, or null if there
|
||||
* is no such element
|
||||
* @throws NullPointerException if {@code node == null}
|
||||
*/
|
||||
public static Element getNextSiblingElement(Node node) {
|
||||
Node sibling = node.getNextSibling();
|
||||
while (sibling != null && sibling.getNodeType() != Node.ELEMENT_NODE) {
|
||||
sibling = sibling.getNextSibling();
|
||||
}
|
||||
return (Element)sibling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next sibling element of the specified node and checks that
|
||||
* the local name is equal to {@code localName}.
|
||||
*
|
||||
* @param node the node
|
||||
* @return the next sibling element of the specified node
|
||||
* @throws NullPointerException if {@code node == null}
|
||||
* @throws MarshalException if no such element or the local name is not
|
||||
* equal to {@code localName}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Element getNextSiblingElement(Node node, String localName)
|
||||
throws MarshalException
|
||||
{
|
||||
return verifyElement(getNextSiblingElement(node), localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next sibling element of the specified node and checks that
|
||||
* the local name is equal to {@code localName} and the namespace is equal to
|
||||
* {@code namespaceURI}
|
||||
*
|
||||
* @param node the node
|
||||
* @return the next sibling element of the specified node
|
||||
* @throws NullPointerException if {@code node == null}
|
||||
* @throws MarshalException if no such element or the local name is not
|
||||
* equal to {@code localName}
|
||||
*/
|
||||
public static Element getNextSiblingElement(Node node, String localName, String namespaceURI)
|
||||
throws MarshalException
|
||||
{
|
||||
return verifyElement(getNextSiblingElement(node), localName, namespaceURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attribute value for the attribute with the specified name.
|
||||
* Returns null if there is no such attribute, or
|
||||
* the empty string if the attribute value is empty.
|
||||
*
|
||||
* <p>This works around a limitation of the DOM
|
||||
* {@code Element.getAttributeNode} method, which does not distinguish
|
||||
* between an unspecified attribute and an attribute with a value of
|
||||
* "" (it returns "" for both cases).
|
||||
*
|
||||
* @param elem the element containing the attribute
|
||||
* @param name the name of the attribute
|
||||
* @return the attribute value (may be null if unspecified)
|
||||
*/
|
||||
public static String getAttributeValue(Element elem, String name) {
|
||||
Attr attr = elem.getAttributeNodeNS(null, name);
|
||||
return (attr == null) ? null : attr.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attribute value for the attribute with the specified name.
|
||||
* Returns null if there is no such attribute, or
|
||||
* the empty string if the attribute value is empty.
|
||||
*
|
||||
* <p>This works around a limitation of the DOM
|
||||
* {@code Element.getAttributeNode} method, which does not distinguish
|
||||
* between an unspecified attribute and an attribute with a value of
|
||||
* "" (it returns "" for both cases).
|
||||
*
|
||||
* @param elem the element containing the attribute
|
||||
* @param name the name of the attribute
|
||||
* @return the attribute value (may be null if unspecified)
|
||||
*/
|
||||
public static <N> String getIdAttributeValue(Element elem, String name) {
|
||||
Attr attr = elem.getAttributeNodeNS(null, name);
|
||||
if (attr != null && !attr.isId()) {
|
||||
elem.setIdAttributeNode(attr, true);
|
||||
}
|
||||
return (attr == null) ? null : attr.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Set of {@code Node}s, backed by the specified
|
||||
* {@code NodeList}.
|
||||
*
|
||||
* @param nl the NodeList
|
||||
* @return a Set of Nodes
|
||||
*/
|
||||
public static Set<Node> nodeSet(NodeList nl) {
|
||||
return new NodeSet(nl);
|
||||
}
|
||||
|
||||
static class NodeSet extends AbstractSet<Node> {
|
||||
private NodeList nl;
|
||||
public NodeSet(NodeList nl) {
|
||||
this.nl = nl;
|
||||
}
|
||||
|
||||
public int size() { return nl.getLength(); }
|
||||
public Iterator<Node> iterator() {
|
||||
return new Iterator<Node>() {
|
||||
private int index;
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public Node next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return nl.item(index++);
|
||||
}
|
||||
public boolean hasNext() {
|
||||
return index < nl.getLength();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the prefix associated with the specified namespace URI
|
||||
*
|
||||
* @param context contains the namespace map
|
||||
* @param nsURI the namespace URI
|
||||
* @return the prefix associated with the specified namespace URI, or
|
||||
* null if not set
|
||||
*/
|
||||
public static String getNSPrefix(XMLCryptoContext context, String nsURI) {
|
||||
if (context != null) {
|
||||
return context.getNamespacePrefix
|
||||
(nsURI, context.getDefaultNamespacePrefix());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the prefix associated with the XML Signature namespace URI
|
||||
*
|
||||
* @param context contains the namespace map
|
||||
* @return the prefix associated with the specified namespace URI, or
|
||||
* null if not set
|
||||
*/
|
||||
public static String getSignaturePrefix(XMLCryptoContext context) {
|
||||
return getNSPrefix(context, XMLSignature.XMLNS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all children nodes from the specified node.
|
||||
*
|
||||
* @param node the parent node whose children are to be removed
|
||||
*/
|
||||
public static void removeAllChildren(Node node) {
|
||||
Node firstChild = node.getFirstChild();
|
||||
while (firstChild != null) {
|
||||
Node nodeToRemove = firstChild;
|
||||
firstChild = firstChild.getNextSibling();
|
||||
node.removeChild(nodeToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares 2 nodes for equality. Implementation is not complete.
|
||||
*/
|
||||
public static boolean nodesEqual(Node thisNode, Node otherNode) {
|
||||
if (thisNode == otherNode) {
|
||||
return true;
|
||||
}
|
||||
if (thisNode.getNodeType() != otherNode.getNodeType()) {
|
||||
return false;
|
||||
}
|
||||
// FIXME - test content, etc
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if child element has same owner document before
|
||||
* appending to the parent, and imports it to the parent's document
|
||||
* if necessary.
|
||||
*/
|
||||
public static void appendChild(Node parent, Node child) {
|
||||
Document ownerDoc = getOwnerDocument(parent);
|
||||
if (child.getOwnerDocument() != ownerDoc) {
|
||||
parent.appendChild(ownerDoc.importNode(child, true));
|
||||
} else {
|
||||
parent.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean paramsEqual(AlgorithmParameterSpec spec1,
|
||||
AlgorithmParameterSpec spec2) {
|
||||
if (spec1 == spec2) {
|
||||
return true;
|
||||
}
|
||||
if (spec1 instanceof XPathFilter2ParameterSpec &&
|
||||
spec2 instanceof XPathFilter2ParameterSpec) {
|
||||
return paramsEqual((XPathFilter2ParameterSpec)spec1,
|
||||
(XPathFilter2ParameterSpec)spec2);
|
||||
}
|
||||
if (spec1 instanceof ExcC14NParameterSpec &&
|
||||
spec2 instanceof ExcC14NParameterSpec) {
|
||||
return paramsEqual((ExcC14NParameterSpec) spec1,
|
||||
(ExcC14NParameterSpec)spec2);
|
||||
}
|
||||
if (spec1 instanceof XPathFilterParameterSpec &&
|
||||
spec2 instanceof XPathFilterParameterSpec) {
|
||||
return paramsEqual((XPathFilterParameterSpec)spec1,
|
||||
(XPathFilterParameterSpec)spec2);
|
||||
}
|
||||
if (spec1 instanceof XSLTTransformParameterSpec &&
|
||||
spec2 instanceof XSLTTransformParameterSpec) {
|
||||
return paramsEqual((XSLTTransformParameterSpec)spec1,
|
||||
(XSLTTransformParameterSpec)spec2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean paramsEqual(XPathFilter2ParameterSpec spec1,
|
||||
XPathFilter2ParameterSpec spec2)
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
List<XPathType> types = spec1.getXPathList();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<XPathType> otypes = spec2.getXPathList();
|
||||
int size = types.size();
|
||||
if (size != otypes.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
XPathType type = types.get(i);
|
||||
XPathType otype = otypes.get(i);
|
||||
if (!type.getExpression().equals(otype.getExpression()) ||
|
||||
!type.getNamespaceMap().equals(otype.getNamespaceMap()) ||
|
||||
type.getFilter() != otype.getFilter()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean paramsEqual(ExcC14NParameterSpec spec1,
|
||||
ExcC14NParameterSpec spec2)
|
||||
{
|
||||
return spec1.getPrefixList().equals(spec2.getPrefixList());
|
||||
}
|
||||
|
||||
private static boolean paramsEqual(XPathFilterParameterSpec spec1,
|
||||
XPathFilterParameterSpec spec2)
|
||||
{
|
||||
return spec1.getXPath().equals(spec2.getXPath()) &&
|
||||
spec1.getNamespaceMap().equals(spec2.getNamespaceMap());
|
||||
}
|
||||
|
||||
private static boolean paramsEqual(XSLTTransformParameterSpec spec1,
|
||||
XSLTTransformParameterSpec spec2)
|
||||
{
|
||||
|
||||
XMLStructure ostylesheet = spec2.getStylesheet();
|
||||
if (!(ostylesheet instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
return false;
|
||||
}
|
||||
Node ostylesheetElem =
|
||||
((javax.xml.crypto.dom.DOMStructure) ostylesheet).getNode();
|
||||
XMLStructure stylesheet = spec1.getStylesheet();
|
||||
Node stylesheetElem =
|
||||
((javax.xml.crypto.dom.DOMStructure) stylesheet).getNode();
|
||||
return nodesEqual(stylesheetElem, ostylesheetElem);
|
||||
}
|
||||
|
||||
public static boolean isNamespace(Node node)
|
||||
{
|
||||
final short nodeType = node.getNodeType();
|
||||
if (nodeType == Node.ATTRIBUTE_NODE) {
|
||||
final String namespaceURI = node.getNamespaceURI();
|
||||
return XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
295
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMX509Data.java
Normal file
295
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMX509Data.java
Normal file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMX509Data.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.cert.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.XMLStructure;
|
||||
import javax.xml.crypto.dom.DOMCryptoContext;
|
||||
import javax.xml.crypto.dsig.XMLSignature;
|
||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
||||
import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of X509Data.
|
||||
*
|
||||
*/
|
||||
//@@@ check for illegal combinations of data violating MUSTs in W3c spec
|
||||
public final class DOMX509Data extends DOMStructure implements X509Data {
|
||||
|
||||
private final List<Object> content;
|
||||
private CertificateFactory cf;
|
||||
|
||||
/**
|
||||
* Creates a DOMX509Data.
|
||||
*
|
||||
* @param content a list of one or more X.509 data types. Valid types are
|
||||
* {@link String} (subject names), {@code byte[]} (subject key ids),
|
||||
* {@link java.security.cert.X509Certificate}, {@link X509CRL},
|
||||
* or {@link javax.xml.dsig.XMLStructure}
|
||||
* objects or elements from an external namespace). The list is
|
||||
* defensively copied to protect against subsequent modification.
|
||||
* @throws NullPointerException if {@code content} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code content} is empty
|
||||
* @throws ClassCastException if {@code content} contains any entries
|
||||
* that are not of one of the valid types mentioned above
|
||||
*/
|
||||
public DOMX509Data(List<?> content) {
|
||||
if (content == null) {
|
||||
throw new NullPointerException("content cannot be null");
|
||||
}
|
||||
List<Object> contentCopy = new ArrayList<>(content);
|
||||
if (contentCopy.isEmpty()) {
|
||||
throw new IllegalArgumentException("content cannot be empty");
|
||||
}
|
||||
for (int i = 0, size = contentCopy.size(); i < size; i++) {
|
||||
Object x509Type = contentCopy.get(i);
|
||||
if (x509Type instanceof String) {
|
||||
new X500Principal((String)x509Type);
|
||||
} else if (!(x509Type instanceof byte[]) &&
|
||||
!(x509Type instanceof X509Certificate) &&
|
||||
!(x509Type instanceof X509CRL) &&
|
||||
!(x509Type instanceof XMLStructure)) {
|
||||
throw new ClassCastException
|
||||
("content["+i+"] is not a valid X509Data type");
|
||||
}
|
||||
}
|
||||
this.content = Collections.unmodifiableList(contentCopy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMX509Data} from an element.
|
||||
*
|
||||
* @param xdElem an X509Data element
|
||||
* @throws MarshalException if there is an error while unmarshalling
|
||||
*/
|
||||
public DOMX509Data(Element xdElem) throws MarshalException {
|
||||
// get all children nodes
|
||||
List<Object> newContent = new ArrayList<>();
|
||||
Node firstChild = xdElem.getFirstChild();
|
||||
while (firstChild != null) {
|
||||
if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element childElem = (Element)firstChild;
|
||||
String localName = childElem.getLocalName();
|
||||
String namespace = childElem.getNamespaceURI();
|
||||
if ("X509Certificate".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
newContent.add(unmarshalX509Certificate(childElem));
|
||||
} else if ("X509IssuerSerial".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
newContent.add(new DOMX509IssuerSerial(childElem));
|
||||
} else if ("X509SubjectName".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
newContent.add(childElem.getFirstChild().getNodeValue());
|
||||
} else if ("X509SKI".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
String content = XMLUtils.getFullTextChildrenFromNode(childElem);
|
||||
newContent.add(XMLUtils.decode(content));
|
||||
} else if ("X509CRL".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
newContent.add(unmarshalX509CRL(childElem));
|
||||
} else {
|
||||
newContent.add(new javax.xml.crypto.dom.DOMStructure(childElem));
|
||||
}
|
||||
}
|
||||
firstChild = firstChild.getNextSibling();
|
||||
}
|
||||
this.content = Collections.unmodifiableList(newContent);
|
||||
}
|
||||
|
||||
public List<Object> getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
Element xdElem = DOMUtils.createElement(ownerDoc, "X509Data",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
|
||||
// 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((X509Certificate)object,xdElem,ownerDoc,dsPrefix);
|
||||
} else if (object instanceof XMLStructure) {
|
||||
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((byte[])object, xdElem, ownerDoc, dsPrefix);
|
||||
} else if (object instanceof String) {
|
||||
marshalSubjectName((String)object, xdElem, ownerDoc,dsPrefix);
|
||||
} else if (object instanceof X509CRL) {
|
||||
marshalCRL((X509CRL)object, xdElem, ownerDoc, dsPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
parent.appendChild(xdElem);
|
||||
}
|
||||
|
||||
private void marshalSKI(byte[] skid, Node parent, Document doc,
|
||||
String dsPrefix)
|
||||
{
|
||||
Element skidElem = DOMUtils.createElement(doc, "X509SKI",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
skidElem.appendChild(doc.createTextNode(XMLUtils.encodeToString(skid)));
|
||||
parent.appendChild(skidElem);
|
||||
}
|
||||
|
||||
private void marshalSubjectName(String name, Node parent, Document doc,
|
||||
String dsPrefix)
|
||||
{
|
||||
Element snElem = DOMUtils.createElement(doc, "X509SubjectName",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
snElem.appendChild(doc.createTextNode(name));
|
||||
parent.appendChild(snElem);
|
||||
}
|
||||
|
||||
private void marshalCert(X509Certificate cert, Node parent, Document doc,
|
||||
String dsPrefix)
|
||||
throws MarshalException
|
||||
{
|
||||
Element certElem = DOMUtils.createElement(doc, "X509Certificate",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
try {
|
||||
certElem.appendChild(doc.createTextNode
|
||||
(XMLUtils.encodeToString(cert.getEncoded())));
|
||||
} catch (CertificateEncodingException e) {
|
||||
throw new MarshalException("Error encoding X509Certificate", e);
|
||||
}
|
||||
parent.appendChild(certElem);
|
||||
}
|
||||
|
||||
private void marshalCRL(X509CRL crl, Node parent, Document doc,
|
||||
String dsPrefix)
|
||||
throws MarshalException
|
||||
{
|
||||
Element crlElem = DOMUtils.createElement(doc, "X509CRL",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
try {
|
||||
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)
|
||||
throws MarshalException
|
||||
{
|
||||
try (ByteArrayInputStream bs = unmarshalBase64Binary(elem)) {
|
||||
return (X509Certificate)cf.generateCertificate(bs);
|
||||
} catch (CertificateException e) {
|
||||
throw new MarshalException("Cannot create X509Certificate", e);
|
||||
} catch (IOException e) {
|
||||
throw new MarshalException("Error closing stream", e);
|
||||
}
|
||||
}
|
||||
|
||||
private X509CRL unmarshalX509CRL(Element elem) throws MarshalException {
|
||||
try (ByteArrayInputStream bs = unmarshalBase64Binary(elem)) {
|
||||
return (X509CRL)cf.generateCRL(bs);
|
||||
} catch (CRLException e) {
|
||||
throw new MarshalException("Cannot create X509CRL", e);
|
||||
} catch (IOException e) {
|
||||
throw new MarshalException("Error closing stream", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ByteArrayInputStream unmarshalBase64Binary(Element elem)
|
||||
throws MarshalException {
|
||||
try {
|
||||
if (cf == null) {
|
||||
cf = CertificateFactory.getInstance("X.509");
|
||||
}
|
||||
String content = XMLUtils.getFullTextChildrenFromNode(elem);
|
||||
return new ByteArrayInputStream(XMLUtils.decode(content));
|
||||
} catch (CertificateException e) {
|
||||
throw new MarshalException("Cannot create CertificateFactory", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof X509Data)) {
|
||||
return false;
|
||||
}
|
||||
X509Data oxd = (X509Data)o;
|
||||
|
||||
@SuppressWarnings("unchecked") List<Object> ocontent = oxd.getContent();
|
||||
int size = content.size();
|
||||
if (size != ocontent.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
Object x = content.get(i);
|
||||
Object ox = ocontent.get(i);
|
||||
if (x instanceof byte[]) {
|
||||
if (!(ox instanceof byte[]) ||
|
||||
!Arrays.equals((byte[])x, (byte[])ox)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!(x.equals(ox))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + content.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMX509IssuerSerial.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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 DOMStructure
|
||||
implements X509IssuerSerial {
|
||||
|
||||
private final String issuerName;
|
||||
private final BigInteger serialNumber;
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMX509IssuerSerial} containing the specified
|
||||
* issuer distinguished name/serial number pair.
|
||||
*
|
||||
* @param issuerName the X.509 issuer distinguished name in RFC 2253
|
||||
* String format
|
||||
* @param serialNumber the serial number
|
||||
* @throws IllegalArgumentException if the format of {@code issuerName}
|
||||
* is not RFC 2253 compliant
|
||||
* @throws NullPointerException if {@code issuerName} or
|
||||
* {@code serialNumber} is {@code null}
|
||||
*/
|
||||
public DOMX509IssuerSerial(String issuerName, BigInteger serialNumber) {
|
||||
if (issuerName == null) {
|
||||
throw new NullPointerException("issuerName cannot be null");
|
||||
}
|
||||
if (serialNumber == null) {
|
||||
throw new NullPointerException("serialNumber cannot be null");
|
||||
}
|
||||
// check that issuer distinguished name conforms to RFC 2253
|
||||
new X500Principal(issuerName);
|
||||
this.issuerName = issuerName;
|
||||
this.serialNumber = serialNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMX509IssuerSerial} from an element.
|
||||
*
|
||||
* @param isElem an X509IssuerSerial element
|
||||
*/
|
||||
public DOMX509IssuerSerial(Element isElem) throws MarshalException {
|
||||
Element iNElem = DOMUtils.getFirstChildElement(isElem,
|
||||
"X509IssuerName",
|
||||
XMLSignature.XMLNS);
|
||||
Element sNElem = DOMUtils.getNextSiblingElement(iNElem,
|
||||
"X509SerialNumber",
|
||||
XMLSignature.XMLNS);
|
||||
issuerName = iNElem.getFirstChild().getNodeValue();
|
||||
serialNumber = new BigInteger(sNElem.getFirstChild().getNodeValue());
|
||||
}
|
||||
|
||||
public String getIssuerName() {
|
||||
return issuerName;
|
||||
}
|
||||
|
||||
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) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof X509IssuerSerial)) {
|
||||
return false;
|
||||
}
|
||||
X509IssuerSerial ois = (X509IssuerSerial)obj;
|
||||
return issuerName.equals(ois.getIssuerName()) &&
|
||||
serialNumber.equals(ois.getSerialNumber());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + issuerName.hashCode();
|
||||
result = 31 * result + serialNumber.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
264
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java
Normal file
264
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMXMLObject.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of 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.
|
||||
*
|
||||
* @param content a list of {@link XMLStructure}s. The list
|
||||
* is defensively copied to protect against subsequent modification.
|
||||
* May be {@code null} or empty.
|
||||
* @param id the Id (may be {@code null})
|
||||
* @param mimeType the mime type (may be {@code null})
|
||||
* @param encoding the encoding (may be {@code null})
|
||||
* @throws ClassCastException if {@code content} contains any
|
||||
* entries that are not of type {@link XMLStructure}
|
||||
*/
|
||||
public DOMXMLObject(List<? extends XMLStructure> content, String id,
|
||||
String mimeType, String encoding)
|
||||
{
|
||||
if (content == null || content.isEmpty()) {
|
||||
this.content = Collections.emptyList();
|
||||
} else {
|
||||
this.content = Collections.unmodifiableList(
|
||||
new ArrayList<>(content));
|
||||
for (int i = 0, size = this.content.size(); i < size; i++) {
|
||||
if (!(this.content.get(i) instanceof XMLStructure)) {
|
||||
throw new ClassCastException
|
||||
("content["+i+"] is not a valid type");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.id = id;
|
||||
this.mimeType = mimeType;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code XMLObject} from an element.
|
||||
*
|
||||
* @param objElem an Object element
|
||||
* @throws MarshalException if there is an error when unmarshalling
|
||||
*/
|
||||
public DOMXMLObject(Element objElem, XMLCryptoContext context,
|
||||
Provider provider)
|
||||
throws MarshalException
|
||||
{
|
||||
// unmarshal attributes
|
||||
this.encoding = DOMUtils.getAttributeValue(objElem, "Encoding");
|
||||
|
||||
Attr attr = objElem.getAttributeNodeNS(null, "Id");
|
||||
if (attr != null) {
|
||||
this.id = attr.getValue();
|
||||
objElem.setIdAttributeNode(attr, true);
|
||||
} else {
|
||||
this.id = null;
|
||||
}
|
||||
this.mimeType = DOMUtils.getAttributeValue(objElem, "MimeType");
|
||||
|
||||
List<XMLStructure> newContent = new ArrayList<>();
|
||||
Node firstChild = objElem.getFirstChild();
|
||||
while (firstChild != null) {
|
||||
if (firstChild.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element childElem = (Element)firstChild;
|
||||
String tag = childElem.getLocalName();
|
||||
String namespace = childElem.getNamespaceURI();
|
||||
if ("Manifest".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
newContent.add(new DOMManifest(childElem, context, provider));
|
||||
} else if ("SignatureProperties".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
newContent.add(new DOMSignatureProperties(childElem));
|
||||
} else if ("X509Data".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
newContent.add(new DOMX509Data(childElem));
|
||||
} else {
|
||||
//@@@FIXME: check for other dsig structures
|
||||
newContent.add(new javax.xml.crypto.dom.DOMStructure(firstChild));
|
||||
}
|
||||
} else {
|
||||
newContent.add(new javax.xml.crypto.dom.DOMStructure(firstChild));
|
||||
}
|
||||
firstChild = firstChild.getNextSibling();
|
||||
}
|
||||
|
||||
// Here we capture namespace declarations, so that when they're marshalled back
|
||||
// out, we can make copies of them. Note that attributes are NOT captured.
|
||||
NamedNodeMap nnm = objElem.getAttributes();
|
||||
for (int idx = 0 ; idx < nnm.getLength() ; idx++) {
|
||||
Node nsDecl = nnm.item(idx);
|
||||
if (DOMUtils.isNamespace(nsDecl)) {
|
||||
newContent.add(new javax.xml.crypto.dom.DOMStructure(nsDecl));
|
||||
}
|
||||
}
|
||||
|
||||
if (newContent.isEmpty()) {
|
||||
this.content = Collections.emptyList();
|
||||
} else {
|
||||
this.content = Collections.unmodifiableList(newContent);
|
||||
}
|
||||
this.objectElem = objElem;
|
||||
}
|
||||
|
||||
public List<XMLStructure> getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException {
|
||||
Document ownerDoc = DOMUtils.getOwnerDocument(parent);
|
||||
|
||||
Element objElem = objectElem != null ? objectElem : null;
|
||||
if (objElem == null) {
|
||||
objElem = DOMUtils.createElement(ownerDoc, "Object",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent.appendChild(objElem);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof XMLObject)) {
|
||||
return false;
|
||||
}
|
||||
XMLObject oxo = (XMLObject)o;
|
||||
|
||||
boolean idsEqual = id == null ? oxo.getId() == null
|
||||
: id.equals(oxo.getId());
|
||||
boolean encodingsEqual =
|
||||
encoding == null ? oxo.getEncoding() == null
|
||||
: encoding.equals(oxo.getEncoding());
|
||||
boolean mimeTypesEqual =
|
||||
mimeType == null ? oxo.getMimeType() == null
|
||||
: mimeType.equals(oxo.getMimeType());
|
||||
|
||||
return idsEqual && encodingsEqual && mimeTypesEqual &&
|
||||
equalsContent(oxo.getContent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (id != null) {
|
||||
result = 31 * result + id.hashCode();
|
||||
}
|
||||
if (encoding != null) {
|
||||
result = 31 * result + encoding.hashCode();
|
||||
}
|
||||
if (mimeType != null) {
|
||||
result = 31 * result + mimeType.hashCode();
|
||||
}
|
||||
result = 31 * result + content.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean equalsContent(List<XMLStructure> otherContent) {
|
||||
if (content.size() != otherContent.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0, osize = otherContent.size(); i < osize; i++) {
|
||||
XMLStructure oxs = otherContent.get(i);
|
||||
XMLStructure xs = content.get(i);
|
||||
if (oxs instanceof javax.xml.crypto.dom.DOMStructure) {
|
||||
if (!(xs instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
return false;
|
||||
}
|
||||
Node onode = ((javax.xml.crypto.dom.DOMStructure)oxs).getNode();
|
||||
Node node = ((javax.xml.crypto.dom.DOMStructure)xs).getNode();
|
||||
if (!DOMUtils.nodesEqual(node, onode)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!(xs.equals(oxs))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
634
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java
Normal file
634
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java
Normal file
@@ -0,0 +1,634 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* ===========================================================================
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2003 All Rights Reserved.
|
||||
*
|
||||
* ===========================================================================
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMXMLSignature.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.Provider;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
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;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of XMLSignature.
|
||||
*
|
||||
*/
|
||||
public final class DOMXMLSignature extends DOMStructure
|
||||
implements XMLSignature {
|
||||
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMXMLSignature.class);
|
||||
private String id;
|
||||
private SignatureValue sv;
|
||||
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;
|
||||
private Map<String, XMLStructure> signatureIdMap;
|
||||
|
||||
static {
|
||||
com.sun.org.apache.xml.internal.security.Init.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMXMLSignature} from the specified components.
|
||||
*
|
||||
* @param si the {@code SignedInfo}
|
||||
* @param ki the {@code KeyInfo}, or {@code null} if not specified
|
||||
* @param objs a list of {@code XMLObject}s or {@code null}
|
||||
* if not specified. The list is copied to protect against subsequent
|
||||
* modification.
|
||||
* @param id an optional id (specify {@code null} to omit)
|
||||
* @param signatureValueId an optional id (specify {@code null} to
|
||||
* omit)
|
||||
* @throws NullPointerException if {@code si} is {@code null}
|
||||
*/
|
||||
public DOMXMLSignature(SignedInfo si, KeyInfo ki,
|
||||
List<? extends XMLObject> objs,
|
||||
String id, String signatureValueId)
|
||||
{
|
||||
if (si == null) {
|
||||
throw new NullPointerException("signedInfo cannot be null");
|
||||
}
|
||||
this.si = si;
|
||||
this.id = id;
|
||||
this.sv = new DOMSignatureValue(signatureValueId);
|
||||
if (objs == null) {
|
||||
this.objects = Collections.emptyList();
|
||||
} else {
|
||||
this.objects =
|
||||
Collections.unmodifiableList(new ArrayList<>(objs));
|
||||
for (int i = 0, size = this.objects.size(); i < size; i++) {
|
||||
if (!(this.objects.get(i) instanceof XMLObject)) {
|
||||
throw new ClassCastException
|
||||
("objs["+i+"] is not an XMLObject");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.ki = ki;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code DOMXMLSignature} from XML.
|
||||
*
|
||||
* @param sigElem Signature element
|
||||
* @throws MarshalException if XMLSignature cannot be unmarshalled
|
||||
*/
|
||||
public DOMXMLSignature(Element sigElem, XMLCryptoContext context,
|
||||
Provider provider)
|
||||
throws MarshalException
|
||||
{
|
||||
localSigElem = sigElem;
|
||||
ownerDoc = localSigElem.getOwnerDocument();
|
||||
|
||||
// get Id attribute, if specified
|
||||
id = DOMUtils.getAttributeValue(localSigElem, "Id");
|
||||
// unmarshal SignedInfo
|
||||
Element siElem = DOMUtils.getFirstChildElement(localSigElem,
|
||||
"SignedInfo",
|
||||
XMLSignature.XMLNS);
|
||||
si = new DOMSignedInfo(siElem, context, provider);
|
||||
|
||||
// unmarshal SignatureValue
|
||||
Element sigValElem = DOMUtils.getNextSiblingElement(siElem,
|
||||
"SignatureValue",
|
||||
XMLSignature.XMLNS);
|
||||
sv = new DOMSignatureValue(sigValElem);
|
||||
|
||||
// unmarshal KeyInfo, if specified
|
||||
Element nextSibling = DOMUtils.getNextSiblingElement(sigValElem);
|
||||
if (nextSibling != null && nextSibling.getLocalName().equals("KeyInfo")
|
||||
&& XMLSignature.XMLNS.equals(nextSibling.getNamespaceURI())) {
|
||||
ki = new DOMKeyInfo(nextSibling, context, provider);
|
||||
nextSibling = DOMUtils.getNextSiblingElement(nextSibling);
|
||||
}
|
||||
|
||||
// unmarshal Objects, if specified
|
||||
if (nextSibling == null) {
|
||||
objects = Collections.emptyList();
|
||||
} else {
|
||||
List<XMLObject> tempObjects = new ArrayList<>();
|
||||
while (nextSibling != null) {
|
||||
String name = nextSibling.getLocalName();
|
||||
String namespace = nextSibling.getNamespaceURI();
|
||||
if (!"Object".equals(name) || !XMLSignature.XMLNS.equals(namespace)) {
|
||||
throw new MarshalException("Invalid element name: " + namespace + ":" + name +
|
||||
", expected KeyInfo or Object");
|
||||
}
|
||||
tempObjects.add(new DOMXMLObject(nextSibling,
|
||||
context, provider));
|
||||
nextSibling = DOMUtils.getNextSiblingElement(nextSibling);
|
||||
}
|
||||
objects = Collections.unmodifiableList(tempObjects);
|
||||
}
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public KeyInfo getKeyInfo() {
|
||||
return ki;
|
||||
}
|
||||
|
||||
public SignedInfo getSignedInfo() {
|
||||
return si;
|
||||
}
|
||||
|
||||
public List<XMLObject> getObjects() {
|
||||
return objects;
|
||||
}
|
||||
|
||||
public SignatureValue getSignatureValue() {
|
||||
return sv;
|
||||
}
|
||||
|
||||
public KeySelectorResult getKeySelectorResult() {
|
||||
return ksr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// create and append SignedInfo element
|
||||
((DOMSignedInfo)si).marshal(sigElem, dsPrefix, context);
|
||||
|
||||
// create and append SignatureValue element
|
||||
((DOMSignatureValue)sv).marshal(sigElem, dsPrefix, context);
|
||||
|
||||
// create and append KeyInfo element if necessary
|
||||
if (ki != null) {
|
||||
((DOMKeyInfo)ki).marshal(sigElem, null, dsPrefix, context);
|
||||
}
|
||||
|
||||
// create and append Object elements if necessary
|
||||
for (int i = 0, size = objects.size(); i < size; i++) {
|
||||
((DOMXMLObject)objects.get(i)).marshal(sigElem, dsPrefix, context);
|
||||
}
|
||||
|
||||
// append Id attribute
|
||||
DOMUtils.setAttributeID(sigElem, "Id", id);
|
||||
|
||||
parent.insertBefore(sigElem, nextSibling);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(XMLValidateContext vc)
|
||||
throws XMLSignatureException
|
||||
{
|
||||
if (vc == null) {
|
||||
throw new NullPointerException("validateContext is null");
|
||||
}
|
||||
|
||||
if (!(vc instanceof DOMValidateContext)) {
|
||||
throw new ClassCastException
|
||||
("validateContext must be of type DOMValidateContext");
|
||||
}
|
||||
|
||||
if (validated) {
|
||||
return validationStatus;
|
||||
}
|
||||
|
||||
// validate the signature
|
||||
boolean sigValidity = sv.validate(vc);
|
||||
if (!sigValidity) {
|
||||
validationStatus = false;
|
||||
validated = true;
|
||||
return validationStatus;
|
||||
}
|
||||
|
||||
// validate all References
|
||||
@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);
|
||||
boolean refValid = ref.validate(vc);
|
||||
LOG.debug("Reference [{}] is valid: {}", ref.getURI(), refValid);
|
||||
validateRefs &= refValid;
|
||||
}
|
||||
if (!validateRefs) {
|
||||
LOG.debug("Couldn't validate the References");
|
||||
validationStatus = false;
|
||||
validated = true;
|
||||
return validationStatus;
|
||||
}
|
||||
|
||||
// validate Manifests, if property set
|
||||
boolean validateMans = true;
|
||||
if (Boolean.TRUE.equals(vc.getProperty
|
||||
("org.jcp.xml.dsig.validateManifests")))
|
||||
{
|
||||
for (int i=0, size=objects.size(); validateMans && i < size; i++) {
|
||||
XMLObject xo = objects.get(i);
|
||||
@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;
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Reference> manRefs = man.getReferences();
|
||||
int rsize = manRefs.size();
|
||||
for (int k = 0; validateMans && k < rsize; k++) {
|
||||
Reference ref = manRefs.get(k);
|
||||
boolean refValid = ref.validate(vc);
|
||||
LOG.debug(
|
||||
"Manifest ref [{}] is valid: {}", ref.getURI(), refValid
|
||||
);
|
||||
validateMans &= refValid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
validationStatus = validateMans;
|
||||
validated = true;
|
||||
return validationStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sign(XMLSignContext signContext)
|
||||
throws MarshalException, XMLSignatureException
|
||||
{
|
||||
if (signContext == null) {
|
||||
throw new NullPointerException("signContext cannot be null");
|
||||
}
|
||||
DOMSignContext context = (DOMSignContext)signContext;
|
||||
marshal(context.getParent(), context.getNextSibling(),
|
||||
DOMUtils.getSignaturePrefix(context), context);
|
||||
|
||||
// generate references and signature value
|
||||
List<Reference> allReferences = new ArrayList<>();
|
||||
|
||||
// traverse the Signature and register all objects with IDs that
|
||||
// may contain References
|
||||
signatureIdMap = new HashMap<>();
|
||||
signatureIdMap.put(id, this);
|
||||
signatureIdMap.put(si.getId(), 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);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<XMLStructure> content = obj.getContent();
|
||||
for (XMLStructure xs : content) {
|
||||
if (xs instanceof Manifest) {
|
||||
Manifest man = (Manifest)xs;
|
||||
signatureIdMap.put(man.getId(), man);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Reference> manRefs = man.getReferences();
|
||||
for (Reference ref : manRefs) {
|
||||
allReferences.add(ref);
|
||||
signatureIdMap.put(ref.getId(), ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// always add SignedInfo references after Manifest references so
|
||||
// that Manifest reference are digested first
|
||||
allReferences.addAll(refs);
|
||||
|
||||
// generate/digest each reference
|
||||
for (Reference ref : allReferences) {
|
||||
digestReference((DOMReference)ref, signContext);
|
||||
}
|
||||
|
||||
// do final sweep to digest any references that were skipped or missed
|
||||
for (Reference ref : allReferences) {
|
||||
if (((DOMReference)ref).isDigested()) {
|
||||
continue;
|
||||
}
|
||||
((DOMReference)ref).digest(signContext);
|
||||
}
|
||||
|
||||
Key signingKey = null;
|
||||
try {
|
||||
KeySelectorResult keySelectorResult = signContext.getKeySelector().select(ki,
|
||||
KeySelector.Purpose.SIGN,
|
||||
si.getSignatureMethod(),
|
||||
signContext);
|
||||
signingKey = keySelectorResult.getKey();
|
||||
if (signingKey == null) {
|
||||
throw new XMLSignatureException("the keySelector did not " +
|
||||
"find a signing key");
|
||||
}
|
||||
ksr = keySelectorResult;
|
||||
} catch (KeySelectorException kse) {
|
||||
throw new XMLSignatureException("cannot find signing key", kse);
|
||||
}
|
||||
|
||||
// calculate signature value
|
||||
try {
|
||||
byte[] val = ((AbstractDOMSignatureMethod)
|
||||
si.getSignatureMethod()).sign(signingKey, si, signContext);
|
||||
((DOMSignatureValue)sv).setValue(val);
|
||||
} catch (InvalidKeyException ike) {
|
||||
throw new XMLSignatureException(ike);
|
||||
}
|
||||
|
||||
this.localSigElem = sigElem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof XMLSignature)) {
|
||||
return false;
|
||||
}
|
||||
XMLSignature osig = (XMLSignature)o;
|
||||
|
||||
boolean idEqual =
|
||||
id == null ? osig.getId() == null : id.equals(osig.getId());
|
||||
boolean keyInfoEqual =
|
||||
ki == null ? osig.getKeyInfo() == null
|
||||
: ki.equals(osig.getKeyInfo());
|
||||
|
||||
return idEqual && keyInfoEqual &&
|
||||
sv.equals(osig.getSignatureValue()) &&
|
||||
si.equals(osig.getSignedInfo()) &&
|
||||
objects.equals(osig.getObjects());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (id != null) {
|
||||
result = 31 * result + id.hashCode();
|
||||
}
|
||||
if (ki != null) {
|
||||
result = 31 * result + ki.hashCode();
|
||||
}
|
||||
result = 31 * result + sv.hashCode();
|
||||
result = 31 * result + si.hashCode();
|
||||
result = 31 * result + objects.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void digestReference(DOMReference ref, XMLSignContext signContext)
|
||||
throws XMLSignatureException
|
||||
{
|
||||
if (ref.isDigested()) {
|
||||
return;
|
||||
}
|
||||
// check dependencies
|
||||
String uri = ref.getURI();
|
||||
if (Utils.sameDocumentURI(uri)) {
|
||||
String parsedId = Utils.parseIdFromSameDocumentURI(uri);
|
||||
if (parsedId != null && signatureIdMap.containsKey(parsedId)) {
|
||||
XMLStructure xs = signatureIdMap.get(parsedId);
|
||||
if (xs instanceof DOMReference) {
|
||||
digestReference((DOMReference)xs, signContext);
|
||||
} else if (xs instanceof Manifest) {
|
||||
Manifest man = (Manifest)xs;
|
||||
List<Reference> manRefs = DOMManifest.getManifestReferences(man);
|
||||
for (int i = 0, size = manRefs.size(); i < size; i++) {
|
||||
digestReference((DOMReference)manRefs.get(i),
|
||||
signContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if uri="" and there are XPath Transforms, there may be
|
||||
// reference dependencies in the XPath Transform - so be on
|
||||
// the safe side, and skip and do at end in the final sweep
|
||||
if (uri.length() == 0) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Transform> transforms = ref.getTransforms();
|
||||
for (Transform transform : transforms) {
|
||||
String transformAlg = transform.getAlgorithm();
|
||||
if (transformAlg.equals(Transform.XPATH) ||
|
||||
transformAlg.equals(Transform.XPATH2)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ref.digest(signContext);
|
||||
}
|
||||
|
||||
public class DOMSignatureValue extends DOMStructure
|
||||
implements SignatureValue
|
||||
{
|
||||
private String id;
|
||||
private byte[] value;
|
||||
private String valueBase64;
|
||||
private Element sigValueElem;
|
||||
private boolean validated = false;
|
||||
private boolean validationStatus;
|
||||
|
||||
DOMSignatureValue(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
DOMSignatureValue(Element sigValueElem)
|
||||
throws MarshalException
|
||||
{
|
||||
// base64 decode signatureValue
|
||||
String content = XMLUtils.getFullTextChildrenFromNode(sigValueElem);
|
||||
value = XMLUtils.decode(content);
|
||||
|
||||
Attr attr = sigValueElem.getAttributeNodeNS(null, "Id");
|
||||
if (attr != null) {
|
||||
id = attr.getValue();
|
||||
sigValueElem.setIdAttributeNode(attr, true);
|
||||
} else {
|
||||
id = null;
|
||||
}
|
||||
this.sigValueElem = sigValueElem;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte[] getValue() {
|
||||
return (value == null) ? null : (byte[])value.clone();
|
||||
}
|
||||
|
||||
public String getEncodedValue() {
|
||||
return valueBase64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(XMLValidateContext validateContext)
|
||||
throws XMLSignatureException
|
||||
{
|
||||
if (validateContext == null) {
|
||||
throw new NullPointerException("context cannot be null");
|
||||
}
|
||||
|
||||
if (validated) {
|
||||
return validationStatus;
|
||||
}
|
||||
|
||||
// get validating key
|
||||
SignatureMethod sm = si.getSignatureMethod();
|
||||
Key validationKey = null;
|
||||
KeySelectorResult ksResult = null;
|
||||
try {
|
||||
KeySelector keySelector = validateContext.getKeySelector();
|
||||
if (keySelector != null) {
|
||||
ksResult = keySelector.select
|
||||
(ki, KeySelector.Purpose.VERIFY, sm, validateContext);
|
||||
if (ksResult != null) {
|
||||
validationKey = ksResult.getKey();
|
||||
}
|
||||
}
|
||||
if (validationKey == null) {
|
||||
throw new XMLSignatureException("the keyselector did not " +
|
||||
"find a validation key");
|
||||
}
|
||||
} catch (KeySelectorException kse) {
|
||||
throw new XMLSignatureException("cannot find validation " +
|
||||
"key", kse);
|
||||
}
|
||||
|
||||
// canonicalize SignedInfo and verify signature
|
||||
try {
|
||||
validationStatus = ((AbstractDOMSignatureMethod)sm).verify
|
||||
(validationKey, si, value, validateContext);
|
||||
} catch (Exception e) {
|
||||
throw new XMLSignatureException(e);
|
||||
}
|
||||
|
||||
validated = true;
|
||||
ksr = ksResult;
|
||||
return validationStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof SignatureValue)) {
|
||||
return false;
|
||||
}
|
||||
SignatureValue osv = (SignatureValue)o;
|
||||
|
||||
boolean idEqual =
|
||||
id == null ? osv.getId() == null : id.equals(osv.getId());
|
||||
|
||||
//XXX compare signature values?
|
||||
return idEqual;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (id != null) {
|
||||
result = 31 * result + id.hashCode();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void marshal(Node parent, String dsPrefix,
|
||||
DOMCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
// create SignatureValue element
|
||||
sigValueElem = DOMUtils.createElement(ownerDoc, "SignatureValue",
|
||||
XMLSignature.XMLNS, dsPrefix);
|
||||
if (valueBase64 != null) {
|
||||
sigValueElem.appendChild(ownerDoc.createTextNode(valueBase64));
|
||||
}
|
||||
|
||||
// append Id attribute, if specified
|
||||
DOMUtils.setAttributeID(sigValueElem, "Id", id);
|
||||
parent.appendChild(sigValueElem);
|
||||
}
|
||||
|
||||
void setValue(byte[] value) {
|
||||
this.value = value;
|
||||
valueBase64 = XMLUtils.encodeToString(value);
|
||||
sigValueElem.appendChild(ownerDoc.createTextNode(valueBase64));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMXMLSignatureFactory.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
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.dom.DOMValidateContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.*;
|
||||
import javax.xml.crypto.dsig.spec.*;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of XMLSignatureFactory.
|
||||
*
|
||||
*/
|
||||
public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*/
|
||||
public DOMXMLSignatureFactory() {}
|
||||
|
||||
public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki) {
|
||||
return new DOMXMLSignature(si, ki, null, null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki,
|
||||
List objects, String id, String signatureValueId) {
|
||||
return new DOMXMLSignature(si, ki, objects, id, signatureValueId);
|
||||
}
|
||||
|
||||
public Reference newReference(String uri, DigestMethod dm) {
|
||||
return newReference(uri, dm, null, null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Reference newReference(String uri, DigestMethod dm, List transforms,
|
||||
String type, String id) {
|
||||
return new DOMReference(uri, type, dm, transforms, id, getProvider());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Reference newReference(String uri, DigestMethod dm,
|
||||
List appliedTransforms, Data result, List transforms, String type,
|
||||
String id) {
|
||||
if (appliedTransforms == null) {
|
||||
throw new NullPointerException("appliedTransforms cannot be null");
|
||||
}
|
||||
if (appliedTransforms.isEmpty()) {
|
||||
throw new NullPointerException("appliedTransforms cannot be empty");
|
||||
}
|
||||
if (result == null) {
|
||||
throw new NullPointerException("result cannot be null");
|
||||
}
|
||||
return new DOMReference
|
||||
(uri, type, dm, appliedTransforms, result, transforms, id, getProvider());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Reference newReference(String uri, DigestMethod dm, List transforms,
|
||||
String type, String id, byte[] digestValue) {
|
||||
if (digestValue == null) {
|
||||
throw new NullPointerException("digestValue cannot be null");
|
||||
}
|
||||
return new DOMReference
|
||||
(uri, type, dm, null, null, transforms, id, digestValue, getProvider());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
public SignedInfo newSignedInfo(CanonicalizationMethod cm,
|
||||
SignatureMethod sm, List references) {
|
||||
return newSignedInfo(cm, sm, references, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public SignedInfo newSignedInfo(CanonicalizationMethod cm,
|
||||
SignatureMethod sm, List references, String id) {
|
||||
return new DOMSignedInfo(cm, sm, references, id);
|
||||
}
|
||||
|
||||
// Object factory methods
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public XMLObject newXMLObject(List content, String id, String mimeType,
|
||||
String encoding) {
|
||||
return new DOMXMLObject(content, id, mimeType, encoding);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
public Manifest newManifest(List references) {
|
||||
return newManifest(references, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Manifest newManifest(List references, String id) {
|
||||
return new DOMManifest(references, id);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public SignatureProperties newSignatureProperties(List props, String id) {
|
||||
return new DOMSignatureProperties(props, id);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public SignatureProperty newSignatureProperty
|
||||
(List info, String target, String id) {
|
||||
return new DOMSignatureProperty(info, target, id);
|
||||
}
|
||||
|
||||
public XMLSignature unmarshalXMLSignature(XMLValidateContext context)
|
||||
throws MarshalException {
|
||||
|
||||
if (context == null) {
|
||||
throw new NullPointerException("context cannot be null");
|
||||
}
|
||||
return unmarshal(((DOMValidateContext) context).getNode(), context);
|
||||
}
|
||||
|
||||
public XMLSignature unmarshalXMLSignature(XMLStructure xmlStructure)
|
||||
throws MarshalException {
|
||||
|
||||
if (xmlStructure == null) {
|
||||
throw new NullPointerException("xmlStructure cannot be null");
|
||||
}
|
||||
if (!(xmlStructure instanceof javax.xml.crypto.dom.DOMStructure)) {
|
||||
throw new ClassCastException("xmlStructure must be of type DOMStructure");
|
||||
}
|
||||
return unmarshal
|
||||
(((javax.xml.crypto.dom.DOMStructure) xmlStructure).getNode(),
|
||||
new UnmarshalContext());
|
||||
}
|
||||
|
||||
private static class UnmarshalContext extends DOMCryptoContext {
|
||||
UnmarshalContext() {}
|
||||
}
|
||||
|
||||
private XMLSignature unmarshal(Node node, XMLCryptoContext context)
|
||||
throws MarshalException {
|
||||
|
||||
node.normalize();
|
||||
|
||||
Element element = null;
|
||||
if (node.getNodeType() == Node.DOCUMENT_NODE) {
|
||||
element = ((Document) node).getDocumentElement();
|
||||
} else if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
element = (Element) node;
|
||||
} else {
|
||||
throw new MarshalException
|
||||
("Signature element is not a proper Node");
|
||||
}
|
||||
|
||||
// check tag
|
||||
String tag = element.getLocalName();
|
||||
String namespace = element.getNamespaceURI();
|
||||
if (tag == null || namespace == null) {
|
||||
throw new MarshalException("Document implementation must " +
|
||||
"support DOM Level 2 and be namespace aware");
|
||||
}
|
||||
if ("Signature".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
|
||||
try {
|
||||
return new DOMXMLSignature(element, context, getProvider());
|
||||
} catch (MarshalException me) {
|
||||
throw me;
|
||||
} catch (Exception e) {
|
||||
throw new MarshalException(e);
|
||||
}
|
||||
} else {
|
||||
throw new MarshalException("Invalid Signature tag: " + namespace + ":" + tag);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFeatureSupported(String feature) {
|
||||
if (feature == null) {
|
||||
throw new NullPointerException();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public DigestMethod newDigestMethod(String algorithm,
|
||||
DigestMethodParameterSpec params) throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException {
|
||||
if (algorithm == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (algorithm.equals(DigestMethod.SHA1)) {
|
||||
return new DOMDigestMethod.SHA1(params);
|
||||
} else if (algorithm.equals(DOMDigestMethod.SHA224)) {
|
||||
return new DOMDigestMethod.SHA224(params);
|
||||
} else if (algorithm.equals(DigestMethod.SHA256)) {
|
||||
return new DOMDigestMethod.SHA256(params);
|
||||
} else if (algorithm.equals(DOMDigestMethod.SHA384)) {
|
||||
return new DOMDigestMethod.SHA384(params);
|
||||
} else if (algorithm.equals(DigestMethod.SHA512)) {
|
||||
return new DOMDigestMethod.SHA512(params);
|
||||
} else if (algorithm.equals(DigestMethod.RIPEMD160)) {
|
||||
return new DOMDigestMethod.RIPEMD160(params);
|
||||
} else {
|
||||
throw new NoSuchAlgorithmException("unsupported algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
public SignatureMethod newSignatureMethod(String algorithm,
|
||||
SignatureMethodParameterSpec params) throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException {
|
||||
if (algorithm == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (algorithm.equals(SignatureMethod.RSA_SHA1)) {
|
||||
return new DOMSignatureMethod.SHA1withRSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA224)) {
|
||||
return new DOMSignatureMethod.SHA224withRSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA256)) {
|
||||
return new DOMSignatureMethod.SHA256withRSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA384)) {
|
||||
return new DOMSignatureMethod.SHA384withRSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512)) {
|
||||
return new DOMSignatureMethod.SHA512withRSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160)) {
|
||||
return new DOMSignatureMethod.RIPEMD160withRSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA1_MGF1)) {
|
||||
return new DOMSignatureMethod.SHA1withRSAandMGF1(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA224_MGF1)) {
|
||||
return new DOMSignatureMethod.SHA224withRSAandMGF1(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA256_MGF1)) {
|
||||
return new DOMSignatureMethod.SHA256withRSAandMGF1(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA384_MGF1)) {
|
||||
return new DOMSignatureMethod.SHA384withRSAandMGF1(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512_MGF1)) {
|
||||
return new DOMSignatureMethod.SHA512withRSAandMGF1(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160_MGF1)) {
|
||||
return new DOMSignatureMethod.RIPEMD160withRSAandMGF1(params);
|
||||
} else if (algorithm.equals(SignatureMethod.DSA_SHA1)) {
|
||||
return new DOMSignatureMethod.SHA1withDSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.DSA_SHA256)) {
|
||||
return new DOMSignatureMethod.SHA256withDSA(params);
|
||||
} else if (algorithm.equals(SignatureMethod.HMAC_SHA1)) {
|
||||
return new DOMHMACSignatureMethod.SHA1(params);
|
||||
} else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA224)) {
|
||||
return new DOMHMACSignatureMethod.SHA224(params);
|
||||
} else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA256)) {
|
||||
return new DOMHMACSignatureMethod.SHA256(params);
|
||||
} else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA384)) {
|
||||
return new DOMHMACSignatureMethod.SHA384(params);
|
||||
} else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA512)) {
|
||||
return new DOMHMACSignatureMethod.SHA512(params);
|
||||
} else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_RIPEMD160)) {
|
||||
return new DOMHMACSignatureMethod.RIPEMD160(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA1)) {
|
||||
return new DOMSignatureMethod.SHA1withECDSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA224)) {
|
||||
return new DOMSignatureMethod.SHA224withECDSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA256)) {
|
||||
return new DOMSignatureMethod.SHA256withECDSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA384)) {
|
||||
return new DOMSignatureMethod.SHA384withECDSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA512)) {
|
||||
return new DOMSignatureMethod.SHA512withECDSA(params);
|
||||
} else if (algorithm.equals(DOMSignatureMethod.ECDSA_RIPEMD160)) {
|
||||
return new DOMSignatureMethod.RIPEMD160withECDSA(params);
|
||||
}else {
|
||||
throw new NoSuchAlgorithmException("unsupported algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
public Transform newTransform(String algorithm,
|
||||
TransformParameterSpec params) throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException {
|
||||
|
||||
TransformService spi;
|
||||
if (getProvider() == null) {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
} else {
|
||||
try {
|
||||
spi = TransformService.getInstance(algorithm, "DOM", getProvider());
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
}
|
||||
}
|
||||
|
||||
spi.init(params);
|
||||
return new DOMTransform(spi);
|
||||
}
|
||||
|
||||
public Transform newTransform(String algorithm,
|
||||
XMLStructure params) throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException {
|
||||
TransformService spi;
|
||||
if (getProvider() == null) {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
} else {
|
||||
try {
|
||||
spi = TransformService.getInstance(algorithm, "DOM", getProvider());
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
}
|
||||
}
|
||||
|
||||
if (params == null) {
|
||||
spi.init(null);
|
||||
} else {
|
||||
spi.init(params, null);
|
||||
}
|
||||
return new DOMTransform(spi);
|
||||
}
|
||||
|
||||
public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
|
||||
C14NMethodParameterSpec params) throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException {
|
||||
TransformService spi;
|
||||
if (getProvider() == null) {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
} else {
|
||||
try {
|
||||
spi = TransformService.getInstance(algorithm, "DOM", getProvider());
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
}
|
||||
}
|
||||
|
||||
spi.init(params);
|
||||
return new DOMCanonicalizationMethod(spi);
|
||||
}
|
||||
|
||||
public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
|
||||
XMLStructure params) throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException {
|
||||
TransformService spi;
|
||||
if (getProvider() == null) {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
} else {
|
||||
try {
|
||||
spi = TransformService.getInstance(algorithm, "DOM", getProvider());
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
spi = TransformService.getInstance(algorithm, "DOM");
|
||||
}
|
||||
}
|
||||
if (params == null) {
|
||||
spi.init(null);
|
||||
} else {
|
||||
spi.init(params, null);
|
||||
}
|
||||
|
||||
return new DOMCanonicalizationMethod(spi);
|
||||
}
|
||||
|
||||
public URIDereferencer getURIDereferencer() {
|
||||
return DOMURIDereferencer.INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* ===========================================================================
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2003 All Rights Reserved.
|
||||
*
|
||||
* ===========================================================================
|
||||
*/
|
||||
/*
|
||||
* Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMXPathFilter2Transform.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
import javax.xml.crypto.dsig.spec.XPathType;
|
||||
import javax.xml.crypto.dsig.spec.XPathFilter2ParameterSpec;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of XPath Filter 2.0 Transform.
|
||||
* (Uses Apache XML-Sec Transform implementation)
|
||||
*
|
||||
*/
|
||||
public final class DOMXPathFilter2Transform extends ApacheTransform {
|
||||
|
||||
public void init(TransformParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (params == null) {
|
||||
throw new InvalidAlgorithmParameterException("params are required");
|
||||
} else if (!(params instanceof XPathFilter2ParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("params must be of type XPathFilter2ParameterSpec");
|
||||
}
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public void init(XMLStructure parent, XMLCryptoContext context)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
super.init(parent, context);
|
||||
try {
|
||||
unmarshalParams(DOMUtils.getFirstChildElement(transformElem));
|
||||
} catch (MarshalException me) {
|
||||
throw new InvalidAlgorithmParameterException(me);
|
||||
}
|
||||
}
|
||||
|
||||
private void unmarshalParams(Element curXPathElem) throws MarshalException
|
||||
{
|
||||
List<XPathType> list = new ArrayList<>();
|
||||
Element currentElement = curXPathElem;
|
||||
while (currentElement != null) {
|
||||
String xPath = currentElement.getFirstChild().getNodeValue();
|
||||
String filterVal = DOMUtils.getAttributeValue(currentElement,
|
||||
"Filter");
|
||||
if (filterVal == null) {
|
||||
throw new MarshalException("filter cannot be null");
|
||||
}
|
||||
XPathType.Filter filter = null;
|
||||
if ("intersect".equals(filterVal)) {
|
||||
filter = XPathType.Filter.INTERSECT;
|
||||
} else if ("subtract".equals(filterVal)) {
|
||||
filter = XPathType.Filter.SUBTRACT;
|
||||
} else if ("union".equals(filterVal)) {
|
||||
filter = XPathType.Filter.UNION;
|
||||
} else {
|
||||
throw new MarshalException("Unknown XPathType filter type" +
|
||||
filterVal);
|
||||
}
|
||||
NamedNodeMap attributes = currentElement.getAttributes();
|
||||
if (attributes != null) {
|
||||
int length = attributes.getLength();
|
||||
Map<String, String> namespaceMap =
|
||||
new HashMap<>(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
Attr attr = (Attr)attributes.item(i);
|
||||
String prefix = attr.getPrefix();
|
||||
if (prefix != null && "xmlns".equals(prefix)) {
|
||||
namespaceMap.put(attr.getLocalName(), attr.getValue());
|
||||
}
|
||||
}
|
||||
list.add(new XPathType(xPath, filter, namespaceMap));
|
||||
} else {
|
||||
list.add(new XPathType(xPath, filter));
|
||||
}
|
||||
|
||||
currentElement = DOMUtils.getNextSiblingElement(currentElement);
|
||||
}
|
||||
this.params = new XPathFilter2ParameterSpec(list);
|
||||
}
|
||||
|
||||
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
super.marshalParams(parent, context);
|
||||
XPathFilter2ParameterSpec xp =
|
||||
(XPathFilter2ParameterSpec)getParameterSpec();
|
||||
String prefix = DOMUtils.getNSPrefix(context, Transform.XPATH2);
|
||||
String qname = prefix == null || prefix.length() == 0
|
||||
? "xmlns" : "xmlns:" + prefix;
|
||||
@SuppressWarnings("unchecked")
|
||||
List<XPathType> xpathList = xp.getXPathList();
|
||||
for (XPathType xpathType : xpathList) {
|
||||
Element elem = DOMUtils.createElement(ownerDoc, "XPath",
|
||||
Transform.XPATH2, prefix);
|
||||
elem.appendChild
|
||||
(ownerDoc.createTextNode(xpathType.getExpression()));
|
||||
DOMUtils.setAttribute(elem, "Filter",
|
||||
xpathType.getFilter().toString());
|
||||
elem.setAttributeNS("http://www.w3.org/2000/xmlns/", qname,
|
||||
Transform.XPATH2);
|
||||
|
||||
// add namespace attributes, if necessary
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Map.Entry<String, String>> entries =
|
||||
xpathType.getNamespaceMap().entrySet();
|
||||
for (Map.Entry<String, String> entry : entries) {
|
||||
elem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" +
|
||||
entry.getKey(),
|
||||
entry.getValue());
|
||||
}
|
||||
|
||||
transformElem.appendChild(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
113
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java
Normal file
113
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMXPathTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.*;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of XPath Filtering Transform.
|
||||
* (Uses Apache XML-Sec Transform implementation)
|
||||
*
|
||||
*/
|
||||
public final class DOMXPathTransform extends ApacheTransform {
|
||||
|
||||
@Override
|
||||
public void init(TransformParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
if (params == null) {
|
||||
throw new InvalidAlgorithmParameterException("params are required");
|
||||
} else if (!(params instanceof XPathFilterParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("params must be of type XPathFilterParameterSpec");
|
||||
}
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public void init(XMLStructure parent, XMLCryptoContext context)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
super.init(parent, context);
|
||||
unmarshalParams(DOMUtils.getFirstChildElement(transformElem));
|
||||
}
|
||||
|
||||
private void unmarshalParams(Element paramsElem) {
|
||||
String xPath = paramsElem.getFirstChild().getNodeValue();
|
||||
// create a Map of namespace prefixes
|
||||
NamedNodeMap attributes = paramsElem.getAttributes();
|
||||
if (attributes != null) {
|
||||
int length = attributes.getLength();
|
||||
Map<String, String> namespaceMap =
|
||||
new HashMap<>(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
Attr attr = (Attr)attributes.item(i);
|
||||
String prefix = attr.getPrefix();
|
||||
if (prefix != null && "xmlns".equals(prefix)) {
|
||||
namespaceMap.put(attr.getLocalName(), attr.getValue());
|
||||
}
|
||||
}
|
||||
this.params = new XPathFilterParameterSpec(xPath, namespaceMap);
|
||||
} else {
|
||||
this.params = new XPathFilterParameterSpec(xPath);
|
||||
}
|
||||
}
|
||||
|
||||
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
|
||||
throws MarshalException
|
||||
{
|
||||
super.marshalParams(parent, context);
|
||||
XPathFilterParameterSpec xp =
|
||||
(XPathFilterParameterSpec)getParameterSpec();
|
||||
Element xpathElem = DOMUtils.createElement(ownerDoc, "XPath",
|
||||
XMLSignature.XMLNS, DOMUtils.getSignaturePrefix(context));
|
||||
xpathElem.appendChild(ownerDoc.createTextNode(xp.getXPath()));
|
||||
|
||||
// add namespace attributes, if necessary
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Map.Entry<String, String>> entries =
|
||||
xp.getNamespaceMap().entrySet();
|
||||
for (Map.Entry<String, String> entry : entries) {
|
||||
xpathElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" +
|
||||
entry.getKey(),
|
||||
entry.getValue());
|
||||
}
|
||||
|
||||
transformElem.appendChild(xpathElem);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: DOMXSLTTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
import javax.xml.crypto.dsig.spec.XSLTTransformParameterSpec;
|
||||
|
||||
/**
|
||||
* DOM-based implementation of XSLT Transform.
|
||||
* (Uses Apache XML-Sec Transform implementation)
|
||||
*
|
||||
*/
|
||||
public final class DOMXSLTTransform extends ApacheTransform {
|
||||
|
||||
@Override
|
||||
public void init(TransformParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
if (params == null) {
|
||||
throw new InvalidAlgorithmParameterException("params are required");
|
||||
}
|
||||
if (!(params instanceof XSLTTransformParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException("unrecognized params");
|
||||
}
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public void init(XMLStructure parent, XMLCryptoContext context)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
|
||||
super.init(parent, context);
|
||||
unmarshalParams(DOMUtils.getFirstChildElement(transformElem));
|
||||
}
|
||||
|
||||
private void unmarshalParams(Element sheet) {
|
||||
this.params = new XSLTTransformParameterSpec
|
||||
(new javax.xml.crypto.dom.DOMStructure(sheet));
|
||||
}
|
||||
|
||||
public void marshalParams(XMLStructure parent, XMLCryptoContext context)
|
||||
throws MarshalException {
|
||||
super.marshalParams(parent, context);
|
||||
XSLTTransformParameterSpec xp =
|
||||
(XSLTTransformParameterSpec) getParameterSpec();
|
||||
Node xsltElem =
|
||||
((javax.xml.crypto.dom.DOMStructure) xp.getStylesheet()).getNode();
|
||||
DOMUtils.appendChild(transformElem, xsltElem);
|
||||
}
|
||||
}
|
||||
196
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/Policy.java
Normal file
196
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/Policy.java
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.Security;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The secure validation policy as specified by the
|
||||
* jdk.xml.dsig.secureValidationPolicy security property.
|
||||
*/
|
||||
public final class Policy {
|
||||
|
||||
// all restrictions are initialized to be unconstrained
|
||||
private static Set<URI> disallowedAlgs = new HashSet<>();
|
||||
private static int maxTrans = Integer.MAX_VALUE;
|
||||
private static int maxRefs = Integer.MAX_VALUE;
|
||||
private static Set<String> disallowedRefUriSchemes = new HashSet<>();
|
||||
private static Map<String, Integer> minKeyMap = new HashMap<>();
|
||||
private static boolean noDuplicateIds = false;
|
||||
private static boolean noRMLoops = false;
|
||||
|
||||
static {
|
||||
try {
|
||||
initialize();
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException(
|
||||
"Cannot initialize the secure validation policy", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Policy() {}
|
||||
|
||||
private static void initialize() {
|
||||
String prop =
|
||||
AccessController.doPrivileged((PrivilegedAction<String>) () ->
|
||||
Security.getProperty("jdk.xml.dsig.secureValidationPolicy"));
|
||||
if (prop == null || prop.isEmpty()) {
|
||||
// no policy specified, so don't enforce any restrictions
|
||||
return;
|
||||
}
|
||||
String[] entries = prop.split(",");
|
||||
for (String entry : entries) {
|
||||
String[] tokens = entry.split("\\s");
|
||||
String type = tokens[0];
|
||||
switch(type) {
|
||||
case "disallowAlg":
|
||||
if (tokens.length != 2) {
|
||||
error(entry);
|
||||
}
|
||||
disallowedAlgs.add(URI.create(tokens[1]));
|
||||
break;
|
||||
case "maxTransforms":
|
||||
if (tokens.length != 2) {
|
||||
error(entry);
|
||||
}
|
||||
maxTrans = Integer.parseUnsignedInt(tokens[1]);
|
||||
break;
|
||||
case "maxReferences":
|
||||
if (tokens.length != 2) {
|
||||
error(entry);
|
||||
}
|
||||
maxRefs = Integer.parseUnsignedInt(tokens[1]);
|
||||
break;
|
||||
case "disallowReferenceUriSchemes":
|
||||
if (tokens.length == 1) {
|
||||
error(entry);
|
||||
}
|
||||
for (int i = 1; i < tokens.length; i++) {
|
||||
String scheme = tokens[i];
|
||||
disallowedRefUriSchemes.add(
|
||||
scheme.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
break;
|
||||
case "minKeySize":
|
||||
if (tokens.length != 3) {
|
||||
error(entry);
|
||||
}
|
||||
minKeyMap.put(tokens[1],
|
||||
Integer.parseUnsignedInt(tokens[2]));
|
||||
break;
|
||||
case "noDuplicateIds":
|
||||
if (tokens.length != 1) {
|
||||
error(entry);
|
||||
}
|
||||
noDuplicateIds = true;
|
||||
break;
|
||||
case "noRetrievalMethodLoops":
|
||||
if (tokens.length != 1) {
|
||||
error(entry);
|
||||
}
|
||||
noRMLoops = true;
|
||||
break;
|
||||
default:
|
||||
error(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean restrictAlg(String alg) {
|
||||
try {
|
||||
URI uri = new URI(alg);
|
||||
return disallowedAlgs.contains(uri);
|
||||
} catch (URISyntaxException use) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean restrictNumTransforms(int numTrans) {
|
||||
return (numTrans > maxTrans);
|
||||
}
|
||||
|
||||
public static boolean restrictNumReferences(int numRefs) {
|
||||
return (numRefs > maxRefs);
|
||||
}
|
||||
|
||||
public static boolean restrictReferenceUriScheme(String uri) {
|
||||
if (uri != null) {
|
||||
String scheme = java.net.URI.create(uri).getScheme();
|
||||
if (scheme != null) {
|
||||
return disallowedRefUriSchemes.contains(
|
||||
scheme.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean restrictKey(String type, int size) {
|
||||
return (size < minKeyMap.getOrDefault(type, 0));
|
||||
}
|
||||
|
||||
public static boolean restrictDuplicateIds() {
|
||||
return noDuplicateIds;
|
||||
}
|
||||
|
||||
public static boolean restrictRetrievalMethodLoops() {
|
||||
return noRMLoops;
|
||||
}
|
||||
|
||||
public static Set<URI> disabledAlgs() {
|
||||
return Collections.<URI>unmodifiableSet(disallowedAlgs);
|
||||
}
|
||||
|
||||
public static int maxTransforms() {
|
||||
return maxTrans;
|
||||
}
|
||||
|
||||
public static int maxReferences() {
|
||||
return maxRefs;
|
||||
}
|
||||
|
||||
public static Set<String> disabledReferenceUriSchemes() {
|
||||
return Collections.<String>unmodifiableSet(disallowedRefUriSchemes);
|
||||
}
|
||||
|
||||
public static int minKeySize(String type) {
|
||||
return minKeyMap.getOrDefault(type, 0);
|
||||
}
|
||||
|
||||
private static void error(String entry) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid jdk.xml.dsig.secureValidationPolicy entry: " + entry);
|
||||
}
|
||||
}
|
||||
123
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/Utils.java
Normal file
123
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/Utils.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: Utils.java 1788465 2017-03-24 15:10:51Z coheigea $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import javax.xml.crypto.XMLCryptoContext;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Miscellaneous static utility methods for use in JSR 105 RI.
|
||||
*
|
||||
*/
|
||||
public final class Utils {
|
||||
|
||||
private Utils() {}
|
||||
|
||||
public static byte[] readBytesFromStream(InputStream is)
|
||||
throws IOException
|
||||
{
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
byte[] buf = new byte[1024];
|
||||
while (true) {
|
||||
int read = is.read(buf);
|
||||
if (read == -1) { // EOF
|
||||
break;
|
||||
}
|
||||
baos.write(buf, 0, read);
|
||||
if (read < 1024) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an Iterator to a Set of Nodes, according to the XPath
|
||||
* Data Model.
|
||||
*
|
||||
* @param i the Iterator
|
||||
* @return the Set of Nodes
|
||||
*/
|
||||
static Set<Node> toNodeSet(Iterator<Node> i) {
|
||||
Set<Node> nodeSet = new HashSet<>();
|
||||
while (i.hasNext()) {
|
||||
Node n = i.next();
|
||||
nodeSet.add(n);
|
||||
// insert attributes nodes to comply with XPath
|
||||
if (n.getNodeType() == Node.ELEMENT_NODE) {
|
||||
NamedNodeMap nnm = n.getAttributes();
|
||||
for (int j = 0, length = nnm.getLength(); j < length; j++) {
|
||||
nodeSet.add(nnm.item(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID from a same-document URI (ex: "#id")
|
||||
*/
|
||||
public static String parseIdFromSameDocumentURI(String uri) {
|
||||
if (uri.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
String id = uri.substring(1);
|
||||
if (id != null && id.startsWith("xpointer(id(")) {
|
||||
int i1 = id.indexOf('\'');
|
||||
int i2 = id.indexOf('\'', i1+1);
|
||||
id = id.substring(i1+1, i2);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if uri is a same-document URI, false otherwise.
|
||||
*/
|
||||
public static boolean sameDocumentURI(String uri) {
|
||||
return uri != null && (uri.length() == 0 || uri.charAt(0) == '#');
|
||||
}
|
||||
|
||||
static boolean secureValidation(XMLCryptoContext xc) {
|
||||
if (xc == null) {
|
||||
return false;
|
||||
}
|
||||
return getBoolean(xc, "org.jcp.xml.dsig.secureValidation");
|
||||
}
|
||||
|
||||
private static boolean getBoolean(XMLCryptoContext xc, String name) {
|
||||
Boolean value = (Boolean)xc.getProperty(name);
|
||||
return value != null && value.booleanValue();
|
||||
}
|
||||
}
|
||||
161
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java
Normal file
161
jdkSrc/jdk8/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* ===========================================================================
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2003 All Rights Reserved.
|
||||
*
|
||||
* ===========================================================================
|
||||
*/
|
||||
/*
|
||||
* Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* $Id: XMLDSigRI.java 1833618 2018-06-15 17:36:20Z mullan $
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
import java.util.*;
|
||||
import java.security.*;
|
||||
|
||||
import javax.xml.crypto.dsig.*;
|
||||
|
||||
/**
|
||||
* The XMLDSig RI Provider.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines the XMLDSigRI provider.
|
||||
*/
|
||||
|
||||
public final class XMLDSigRI extends Provider {
|
||||
|
||||
static final long serialVersionUID = -5049765099299494554L;
|
||||
|
||||
private static final String INFO = "XMLDSig " +
|
||||
"(DOM XMLSignatureFactory; DOM KeyInfoFactory; " +
|
||||
"C14N 1.0, C14N 1.1, Exclusive C14N, Base64, Enveloped, XPath, " +
|
||||
"XPath2, XSLT TransformServices)";
|
||||
|
||||
public XMLDSigRI() {
|
||||
/* We are the XMLDSig provider */
|
||||
super("XMLDSig", 1.8d, INFO);
|
||||
|
||||
final Map<Object, Object> map = new HashMap<Object, Object>();
|
||||
map.put("XMLSignatureFactory.DOM",
|
||||
"org.jcp.xml.dsig.internal.dom.DOMXMLSignatureFactory");
|
||||
map.put("KeyInfoFactory.DOM",
|
||||
"org.jcp.xml.dsig.internal.dom.DOMKeyInfoFactory");
|
||||
|
||||
|
||||
// Inclusive C14N
|
||||
map.put("TransformService." + CanonicalizationMethod.INCLUSIVE,
|
||||
"org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14NMethod");
|
||||
map.put("Alg.Alias.TransformService.INCLUSIVE",
|
||||
CanonicalizationMethod.INCLUSIVE);
|
||||
map.put("TransformService." + CanonicalizationMethod.INCLUSIVE +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// InclusiveWithComments C14N
|
||||
map.put("TransformService." +
|
||||
CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
|
||||
"org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14NMethod");
|
||||
map.put("Alg.Alias.TransformService.INCLUSIVE_WITH_COMMENTS",
|
||||
CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS);
|
||||
map.put("TransformService." +
|
||||
CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// Inclusive C14N 1.1
|
||||
map.put("TransformService.http://www.w3.org/2006/12/xml-c14n11",
|
||||
"org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14N11Method");
|
||||
map.put("TransformService.http://www.w3.org/2006/12/xml-c14n11" +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// InclusiveWithComments C14N 1.1
|
||||
map.put("TransformService.http://www.w3.org/2006/12/xml-c14n11#WithComments",
|
||||
"org.jcp.xml.dsig.internal.dom.DOMCanonicalXMLC14N11Method");
|
||||
map.put("TransformService.http://www.w3.org/2006/12/xml-c14n11#WithComments" +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// Exclusive C14N
|
||||
map.put("TransformService." + CanonicalizationMethod.EXCLUSIVE,
|
||||
"org.jcp.xml.dsig.internal.dom.DOMExcC14NMethod");
|
||||
map.put("Alg.Alias.TransformService.EXCLUSIVE",
|
||||
CanonicalizationMethod.EXCLUSIVE);
|
||||
map.put("TransformService." + CanonicalizationMethod.EXCLUSIVE +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// ExclusiveWithComments C14N
|
||||
map.put("TransformService." +
|
||||
CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
|
||||
"org.jcp.xml.dsig.internal.dom.DOMExcC14NMethod");
|
||||
map.put("Alg.Alias.TransformService.EXCLUSIVE_WITH_COMMENTS",
|
||||
CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS);
|
||||
map.put("TransformService." +
|
||||
CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// Base64 Transform
|
||||
map.put("TransformService." + Transform.BASE64,
|
||||
"org.jcp.xml.dsig.internal.dom.DOMBase64Transform");
|
||||
map.put("Alg.Alias.TransformService.BASE64", Transform.BASE64);
|
||||
map.put("TransformService." + Transform.BASE64 +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// Enveloped Transform
|
||||
map.put("TransformService." + Transform.ENVELOPED,
|
||||
"org.jcp.xml.dsig.internal.dom.DOMEnvelopedTransform");
|
||||
map.put("Alg.Alias.TransformService.ENVELOPED", Transform.ENVELOPED);
|
||||
map.put("TransformService." + Transform.ENVELOPED +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// XPath2 Transform
|
||||
map.put("TransformService." + Transform.XPATH2,
|
||||
"org.jcp.xml.dsig.internal.dom.DOMXPathFilter2Transform");
|
||||
map.put("Alg.Alias.TransformService.XPATH2", Transform.XPATH2);
|
||||
map.put("TransformService." + Transform.XPATH2 +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// XPath Transform
|
||||
map.put("TransformService." + Transform.XPATH,
|
||||
"org.jcp.xml.dsig.internal.dom.DOMXPathTransform");
|
||||
map.put("Alg.Alias.TransformService.XPATH", Transform.XPATH);
|
||||
map.put("TransformService." + Transform.XPATH +
|
||||
" MechanismType", "DOM");
|
||||
|
||||
// XSLT Transform
|
||||
map.put("TransformService." + Transform.XSLT,
|
||||
"org.jcp.xml.dsig.internal.dom.DOMXSLTTransform");
|
||||
map.put("Alg.Alias.TransformService.XSLT", Transform.XSLT);
|
||||
map.put("TransformService." + Transform.XSLT + " MechanismType", "DOM");
|
||||
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
putAll(map);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user