blob: 66cc491556610d381e0cf8977581129cced80e9d [file] [log] [blame]
/*
* Copyright 2006 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.
*
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
*/
package javax.xml.crypto.test.dsig;
import java.io.*;
import java.security.Security;
import java.util.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import org.w3c.dom.Document;
import junit.framework.*;
/**
* Unit test for javax.xml.crypto.dsig.Reference
*
* @version $Id$
* @author Valerie Peng
*/
public class ReferenceTest extends TestCase {
private XMLSignatureFactory fac;
private KeyInfoFactory kifac;
private DigestMethod dmSHA1;
private String uri = "http://www.ietf.org/rfc/rfc3275.txt";
private static final String[] CRYPTO_ALGS = { "RSA", "DSA" };
private static final String[] SIG_ALGS = {
SignatureMethod.RSA_SHA1,
SignatureMethod.DSA_SHA1
};
static {
Security.insertProviderAt
(new org.jcp.xml.dsig.internal.dom.XMLDSigRI(), 1);
}
public ReferenceTest() {
super("ReferenceTest");
}
public ReferenceTest(String name) {
super(name);
}
public void setUp() throws Exception {
fac = XMLSignatureFactory.getInstance
("DOM", new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
kifac = KeyInfoFactory.getInstance
("DOM", new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
dmSHA1 = fac.newDigestMethod(DigestMethod.SHA1, null);
}
public void tearDown() {}
public void testConstructor() throws Exception {
Reference ref;
// test XMLSignatureFactory.newReference(String uri,
// DigestMethod dm) for generating Reference objects
ref = fac.newReference(null, dmSHA1);
assertNotNull(ref);
ref = fac.newReference(uri, dmSHA1);
assertNotNull(ref);
try {
ref = fac.newReference("illegal!@#$%" + uri, dmSHA1);
fail("Should throw a IAE for non-RFC2396-compliant uri");
} catch (IllegalArgumentException iae) {
} catch (Exception ex) {
fail("Should throw a IAE instead of " + ex +
" for non-RFC2396-compliant uri");
}
try {
ref = fac.newReference(uri, null);
fail("Should throw a NPE for null dm");
} catch (NullPointerException npe) {
} catch (Exception ex) {
fail("Should throw a NPE instead of " + ex + " for null dm");
}
// test XMLSignatureFactory.newReference(String uri,
// DigestMethod dm, List transforms, String type, String id)
// for generating Reference objects
try {
ref = fac.newReference(null, dmSHA1, null, null, null);
assertEquals(ref.getDigestMethod(), dmSHA1);
} catch(Exception ex) {
fail("Unexpected Exception: " + ex);
}
try {
ref = fac.newReference(null, null, null, null, null);
fail("Should throw a NPE for null dm");
} catch (NullPointerException npe) {
} catch(Exception ex) {
fail("Should throw a NPE instead of " + ex + " for null dm");
}
String id = "id";
String type = "type";
try {
ref = fac.newReference(uri, dmSHA1, null, type, id);
assertNotNull(ref.getDigestMethod());
assertEquals(uri, ref.getURI());
assertEquals(id, ref.getId());
assertEquals(type, ref.getType());
assertEquals(ref.getTransforms(), Collections.EMPTY_LIST);
} catch(Exception ex) {
fail("Unexpected Exception: " + ex);
}
List transforms = new Vector();
try {
// try empty transforms list
ref = fac.newReference(uri, dmSHA1, transforms,
type, id);
assertTrue(Arrays.equals(transforms.toArray(),
ref.getTransforms().toArray()));
} catch(Exception ex) {
fail("Unexpected Exception: " + ex);
}
transforms.add(new Object());
try {
// try a transforms list with an invalid object
ref = fac.newReference(uri, dmSHA1, transforms,
type, id);
} catch (ClassCastException cce) {
} catch (Exception ex) {
fail("Should throw a ClassCastException instead of " + ex);
}
// Test with various composition of Transform list
// 1. String only
transforms.clear();
transforms.add(Transform.BASE64);
try {
// try a transforms list with a String object
ref = fac.newReference(uri, dmSHA1, transforms,
type, id);
fail("Should throw a CCE for illegal transforms");
} catch (ClassCastException cce) {
} catch(Exception ex) {
fail("Should throw a CCE instead of " + ex +
" for illegal transforms");
}
// 2. Transform only
transforms.clear();
Transform c14nWithComments = fac.newTransform
(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
(TransformParameterSpec) null);
transforms.add(c14nWithComments);
try {
// try a transforms list with a Transform object
ref = fac.newReference(uri, dmSHA1, transforms, type, id);
assertTrue(Arrays.equals(transforms.toArray(),
ref.getTransforms().toArray()));
} catch (Exception ex) {
fail("Unexpected Exception: " + ex);
}
}
public void testisFeatureSupported() throws Exception {
Reference ref = fac.newReference(null, dmSHA1, null, null, null);
try {
ref.isFeatureSupported(null);
fail("Should raise a NPE for null feature");
} catch (NullPointerException npe) {}
assertTrue(!ref.isFeatureSupported("not supported"));
}
private void donottestvalidate() throws Exception {
Reference ref = null;
String type = "http://www.w3.org/2000/09/xmldsig#Object";
byte[] in = new byte[200];
Random rand = new Random();
// Test XMLSignContext
XMLSignContext signContext;
XMLValidateContext validateContext;
for (int i = 0; i < CRYPTO_ALGS.length; i++) {
rand.nextBytes(in);
TestUtils.SimpleURIDereferencer dereferrer =
new TestUtils.SimpleURIDereferencer(in);
Document doc = TestUtils.newDocument();
signContext = new
DOMSignContext(TestUtils.getPrivateKey(CRYPTO_ALGS[i]), doc);
signContext.setURIDereferencer(dereferrer);
signContext.setProperty("javax.xml.dsig.cacheReference",
Boolean.TRUE);
ref = fac.newReference(null, dmSHA1, null, type, null);
XMLSignature sig = fac.newXMLSignature(fac.newSignedInfo
(fac.newCanonicalizationMethod
(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SIG_ALGS[i], null),
Collections.singletonList(ref)),
kifac.newKeyInfo(Collections.singletonList
(kifac.newKeyValue(TestUtils.getPublicKey(CRYPTO_ALGS[i])))));
try {
sig.sign(signContext);
validateContext = new DOMValidateContext
(TestUtils.getPublicKey(CRYPTO_ALGS[i]),
doc.getDocumentElement());
validateContext.setURIDereferencer(dereferrer);
validateContext.setProperty("javax.xml.dsig.cacheReference",
Boolean.TRUE);
boolean result = sig.validate(validateContext);
assertTrue(result);
Iterator iter = sig.getSignedInfo().getReferences().iterator();
for (int j=0; iter.hasNext(); j++) {
Reference validated_ref = (Reference) iter.next();
byte[] dv = validated_ref.getDigestValue();
byte[] digestInput = readBytesFromStream
(validated_ref.getDigestInputStream());
boolean match = Arrays.equals(digestInput, in);
assertTrue(match);
boolean valid = validated_ref.validate(validateContext);
assertTrue(valid);
}
} catch (XMLSignatureException xse) {
fail("Unexpected Exception: " + xse);
}
}
}
private static byte[] readBytesFromStream(InputStream is)
throws IOException {
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();
}
}