blob: a70d52012d0faab482c67f261aaf73d2fa7c8733 [file] [log] [blame]
/*
* Copyright 2001-2008 The Apache Software Foundation.
*
* Licensed 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.apache.juddi.v3.tck;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class TckSigningUtil {
private static XMLSignatureFactory initXMLSigFactory() {
XMLSignatureFactory fac = XMLSignatureFactory.getInstance();
return fac;
}
private static Reference initReference(XMLSignatureFactory fac) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
List transformers = new ArrayList();
transformers.add(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null));
Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null), transformers, null, null);
return ref;
}
private static SignedInfo initSignedInfo(XMLSignatureFactory fac) throws Exception {
Reference ref = initReference(fac);
SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null), fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null), Collections.singletonList(ref));
return si;
}
public static boolean verifySignature(Element element, PublicKey validatingKey) {
XMLSignatureFactory fac = initXMLSigFactory();
NodeList nl = element.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
throw new RuntimeException("Cannot find Signature element");
}
DOMValidateContext valContext = new DOMValidateContext(validatingKey, nl.item(0));
try {
valContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
boolean coreValidity = signature.validate(valContext);
// Check core validation status.
if (coreValidity == false) {
System.err.println("Signature failed core validation");
boolean sv = signature.getSignatureValue().validate(valContext);
System.out.println("signature validation status: " + sv);
// Check the validation status of each Reference.
@SuppressWarnings("unchecked")
Iterator<Reference> i = signature.getSignedInfo().getReferences().iterator();
System.out.println("---------------------------------------------");
for (int j = 0; i.hasNext(); j++) {
Reference ref = (Reference) i.next();
boolean refValid = ref.validate(valContext);
System.out.println("ref[" + j + "] validity status: " + refValid);
System.out.println("Ref type: " + ref.getType() + ", URI: " + ref.getURI());
for (Object xform : ref.getTransforms()) {
System.out.println("Transform: " + xform);
}
String calcDigValStr = digestToString(ref.getCalculatedDigestValue());
String expectedDigValStr = digestToString(ref.getDigestValue());
System.out.println(" Calc Digest: " + calcDigValStr);
System.out.println("Expected Digest: " + expectedDigValStr);
InputStream is = ref.getDigestInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
is.close();
System.out.println("---------------------------------------------");
}
} else {
System.out.println("Signature passed core validation");
}
return coreValidity;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String digestToString(byte[] digest) {
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
}
public static void signDOM(Node node, PrivateKey privateKey, Certificate origCert) {
XMLSignatureFactory fac = initXMLSigFactory();
X509Certificate cert = (X509Certificate) origCert;
// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif = fac.getKeyInfoFactory();
List<Object> x509Content = new ArrayList<Object>();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature's parent element.
DOMSignContext dsc = new DOMSignContext(privateKey, node);
dsc.putNamespacePrefix("http://www.w3.org/2000/09/xmldsig#", "ns2");
// Create the XMLSignature, but don't sign it yet.
try {
SignedInfo si = initSignedInfo(fac);
XMLSignature signature = fac.newXMLSignature(si, ki);
// Marshal, generate, and sign the enveloped signature.
signature.sign(dsc);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void serializeNode(Node node, String filename) {
try {
TransformerFactory transFactory = TransformerFactory.newInstance();
transFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
transFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
Transformer transformer = transFactory.newTransformer();
DOMSource domSrc = new DOMSource(node);
FileOutputStream fos = new FileOutputStream(filename);
StreamResult streamResult = new StreamResult(fos);
transformer.transform(domSrc, streamResult);
fos.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}