blautenb 2003/11/15 00:51:08
Modified: src_unitTests/org/apache/xml/security/test/encryption
BaltimoreEncTest.java
Log:
Implement interop tests for all basic merlin-five key-unwraps
Revision Changes Path
1.7 +299 -58
xml-security/src_unitTests/org/apache/xml/security/test/encryption/BaltimoreEncTest.java
Index: BaltimoreEncTest.java
===================================================================
RCS file:
/home/cvs/xml-security/src_unitTests/org/apache/xml/security/test/encryption/BaltimoreEncTest.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- BaltimoreEncTest.java 14 Nov 2003 21:05:41 -0000 1.6
+++ BaltimoreEncTest.java 15 Nov 2003 08:51:08 -0000 1.7
@@ -60,8 +60,13 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
import java.security.Key;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
@@ -73,12 +78,15 @@
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import junit.framework.Assert;
import org.apache.xml.security.encryption.EncryptedData;
import org.apache.xml.security.encryption.EncryptedKey;
import org.apache.xml.security.encryption.XMLCipher;
-import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.keys.content.x509.XMLX509Certificate;
import org.apache.xml.security.keys.content.KeyName;
+import org.apache.xml.security.keys.content.X509Data;
+import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.utils.XMLUtils;
import org.apache.xml.serialize.DOMSerializer;
import org.apache.xml.serialize.Method;
@@ -102,24 +110,12 @@
bad-encrypt-content-aes128-cbc-kw-aes192.xml
decryption-transform-except.xml
decryption-transform.xml
-dh0.p8
-dh1.p8
-dsa.p8
-encrypt-content-aes128-cbc-kw-aes192.xml
encrypt-content-aes192-cbc-dh-sha512.xml
-encrypt-content-aes256-cbc-prop.xml
-encrypt-content-tripledes-cbc.xml
-encrypt-data-aes128-cbc.xml
-encrypt-data-aes192-cbc-kw-aes256.xml
-encrypt-data-aes256-cbc-kw-tripledes.xml
encrypt-data-tripledes-cbc-rsa-oaep-mgf1p-sha256.xml
-encrypt-data-tripledes-cbc-rsa-oaep-mgf1p.xml
-encrypt-element-aes128-cbc-rsa-1_5.xml
encrypt-element-aes192-cbc-ref.xml
encrypt-element-aes256-cbc-carried-kw-aes256.xml
encrypt-element-aes256-cbc-kw-aes256-dh-ripemd160.xml
encrypt-element-aes256-cbc-retrieved-kw-aes256.xml
-encrypt-element-tripledes-cbc-kw-aes128.xml
encsig-hmac-sha256-dh.xml
encsig-hmac-sha256-kw-tripledes-dh.xml
encsig-hmac-sha256-rsa-1_5.xml
@@ -133,11 +129,14 @@
public class BaltimoreEncTest extends TestCase {
private static String cardNumber;
+ private static String rsaCertSerialNumber;
+ private static String testDecryptString;
private static int nodeCount = 0;
- private static final byte[] bobBytes =
- "abcdefghijklmnopqrstuvwx".getBytes();
- private static final byte[] jebBytes =
- "abcdefghijklmnopqrstuvwx".getBytes();
+ private static byte[] bobBytes;
+ private static byte[] jebBytes;
+ private static byte[] jobBytes;
+ private static byte[] jedBytes;
+ private static PrivateKey rsaKey;
/** [EMAIL PROTECTED] org.apache.commons.logging} logging facility */
static org.apache.commons.logging.Log log =
@@ -188,9 +187,40 @@
cardNumber = retrieveCCNumber(doc);
+ // Test decrypt
+ testDecryptString = new String("top secret message\n");
+
// Count the nodes in the document as a secondary test
nodeCount = countNodes(doc);
+ // Create the keys
+ bobBytes =
+ "abcdefghijklmnopqrstuvwx".getBytes("ASCII");
+ jebBytes =
+ "abcdefghijklmnopqrstuvwx".getBytes("ASCII");
+ jobBytes =
+ "abcdefghijklmnop".getBytes("ASCII");
+ jedBytes =
+ "abcdefghijklmnopqrstuvwxyz012345".getBytes("ASCII");
+
+ // Certificate information
+ rsaCertSerialNumber = new String("1014918766910");
+
+ // rsaKey
+ FileInputStream infile =
+ new
FileInputStream("data/ie/baltimore/merlin-examples/merlin-xmlenc-five/rsa.p8");
+ byte[] pkcs8Bytes = new byte[10240];
+ int inputSz = infile.read(pkcs8Bytes);
+ infile.close();
+
+ PKCS8EncodedKeySpec pkcs8Spec =
+ new PKCS8EncodedKeySpec(pkcs8Bytes);
+
+ // Create a key factory
+ KeyFactory keyFactory =
+ KeyFactory.getInstance("RSA");
+ rsaKey = keyFactory.generatePrivate(pkcs8Spec);
+
// Initialise the library and get out of here
org.apache.xml.security.Init.init();
@@ -242,6 +272,16 @@
}
/**
+ * Check a decrypt of data was OK
+ */
+
+ private void checkDecryptedData(byte [] data) throws Exception {
+
+ String input = new String(data, "ASCII");
+ Assert.assertEquals(testDecryptString, input);
+ }
+
+ /**
* Method test_five_content_3des_cbc
*
* Check the merlin-enc-five element content test for 3DES
@@ -258,9 +298,25 @@
}
/**
- * Method test_five_content_3des_cbc
+ * Method test_five_content_aes256_cbc
*
- * Check the merlin-enc-five element content test for 3DES
+ * Check the merlin-enc-five element content test for AES256
+ *
+ */
+
+ public void test_five_content_aes256_cbc() throws Exception {
+
+ String filename =
"data/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-content-aes256-cbc-prop.xml";
+
+ Document dd = decryptElement(filename);
+ checkDecryptedDoc(dd);
+ }
+
+ /**
+ * Method test_five_content_aes128_cbc_kw_aes192
+ *
+ * Check the merlin-enc-five element content test for AES128 with
+ * AES 192 key wrap
*
*/
@@ -269,19 +325,106 @@
String filename =
"data/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-content-aes128-cbc-kw-aes192.xml";
Document dd = decryptElement(filename);
+ checkDecryptedDoc(dd);
- String cc = retrieveCCNumber(dd);
+ }
- // Compare the retrieved number to the stored number
+ /**
+ * Method test_five_content_3des_cbc_kw_aes128
+ *
+ * Check the merlin-enc-five element content test for 3DES with
+ * AES 128 key wrap
+ *
+ */
- assertTrue(cc, ((cc != null) && (cc.equals(cardNumber))));
-
- // Test my numbers
+ public void test_five_content_3des_cbc_kw_aes128() throws Exception {
- int myNodeCount = countNodes(dd);
+ String filename =
"data/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-element-tripledes-cbc-kw-aes128.xml";
- assertTrue("Node count mismatches",
- ((myNodeCount > 0) && myNodeCount ==
nodeCount));
+ Document dd = decryptElement(filename);
+ checkDecryptedDoc(dd);
+
+ }
+
+ /**
+ * Method test_five_content_aes128_cbc_kw_rsa_15
+ *
+ * Check the merlin-enc-five element content test for AES128 with
+ * RSA key wrap (PKCS 1.5 padding)
+ *
+ */
+
+ public void test_five_content_aes128_cbc_rsa_15() throws Exception {
+
+ String filename =
"data/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-element-aes128-cbc-rsa-1_5.xml";
+
+ Document dd = decryptElement(filename);
+ checkDecryptedDoc(dd);
+
+ }
+
+ /**
+ * Method test_five_data_aes128_cbc
+ *
+ * Check the merlin-enc-five element data test for AES128 with no
+ * key wrap
+ *
+ */
+
+ public void test_five_data_aes128_cbc() throws Exception {
+
+ String filename =
"data/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-data-aes128-cbc.xml";
+
+ byte[] decrypt = decryptData(filename);
+ checkDecryptedData(decrypt);
+ }
+
+ /**
+ * Method test_five_data_aes256_cbc_3des
+ *
+ * Check the merlin-enc-five element data test for AES256 with 3DES
+ * key wrap
+ *
+ */
+
+ public void test_five_data_aes256_cbc_3des() throws Exception {
+
+ String filename =
"data/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-data-aes256-cbc-kw-tripledes.xml";
+
+ byte[] decrypt = decryptData(filename);
+ checkDecryptedData(decrypt);
+ }
+
+ /**
+ * Method test_five_data_aes192_cbc_aes256
+ *
+ * Check the merlin-enc-five element data test for AES192 with AES256
+ * key wrap
+ *
+ */
+
+ public void test_five_data_aes192_cbc_aes256() throws Exception {
+
+ String filename =
"data/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-data-aes192-cbc-kw-aes256.xml";
+
+ byte[] decrypt = decryptData(filename);
+ checkDecryptedData(decrypt);
+ }
+
+ /**
+ * Method test_five_data_3des_cbc_rsa_oaep
+ *
+ * Check the merlin-enc-five element data test for 3DES with
+ * RSA key wrap (OAEP and no parameters)
+ *
+ */
+
+ public void test_five_data_3des_cbc_rsa_oaep() throws Exception {
+
+ String filename =
"data/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-data-tripledes-cbc-rsa-oaep-mgf1p.xml";
+
+ byte[] decrypt = decryptData(filename);
+ checkDecryptedData(decrypt);
}
/**
@@ -291,8 +434,6 @@
* decrypt it and return the resulting document
*
* @param filename File to decrypt from
- * @param encType String representing the encryption type
- * @param key Key to use for decryption
*/
public Document decryptElement (String filename)
@@ -325,39 +466,59 @@
ee = (Element)
doc.getElementsByTagName("EncryptedData").item(0);
cipher.init(XMLCipher.DECRYPT_MODE, null);
EncryptedData encryptedData = cipher.loadEncryptedData(doc, ee);
- KeyInfo ki = encryptedData.getKeyInfo();
- Key key = null;
- Key kek = null;
+ Key key = findKey(encryptedData);
+ cipher.init(XMLCipher.DECRYPT_MODE, key);
+ Document dd = cipher.doFinal(doc, ee);
+
+ return dd;
+
+ }
+
+ /**
+ * Method decryptData
+ *
+ * Take a file, find an encrypted element decrypt it and return the
+ * resulting byte array
+ *
+ * @param filename File to decrypt from
+ */
+
+ public byte[] decryptData (String filename)
+ throws Exception {
+
+ XMLCipher cipher;
- if (ki != null) {
- KeyName keyName = ki.itemKeyName(0);
- if (keyName != null) {
- key = mapKeyName(keyName.getKeyName());
- }
- else {
- EncryptedKey encryptedKey =
ki.itemEncryptedKey(0);
- if (encryptedKey != null) {
- KeyInfo kiek =
encryptedKey.getKeyInfo();
- if (kiek != null) {
- KeyName kekKeyName =
kiek.itemKeyName(0);
- if (kekKeyName != null) {
- kek =
mapKeyName(kekKeyName.getKeyName());
- if (kek != null) {
-
cipher.setKEK(kek);
- key =
cipher.decryptKey(encryptedKey,
-
encryptedData.
-
getEncryptionMethod().
-
getAlgorithm());
- }
- }
- }
- }
- }
- }
+ // Parse the document in question
+
+ javax.xml.parsers.DocumentBuilderFactory dbf =
+ javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ dbf.setAttribute("http://xml.org/sax/features/namespaces",
Boolean.TRUE);
+ File f = new File(filename);
+
+ DocumentBuilder db = dbf.newDocumentBuilder();
+
+ Document doc = db.parse(new java.io.FileInputStream(f));
+
+ // Now we have the document, lets build the XMLCipher element
+
+ Element ee = null;
+
+ // Create the XMLCipher element
+
+ cipher = XMLCipher.getInstance();
+
+ // Need to pre-load the Encrypted Data so we can get the key
info
+
+ ee = (Element)
doc.getElementsByTagName("EncryptedData").item(0);
+ cipher.init(XMLCipher.DECRYPT_MODE, null);
+ EncryptedData encryptedData = cipher.loadEncryptedData(doc, ee);
+
+ Key key = findKey(encryptedData);
cipher.init(XMLCipher.DECRYPT_MODE, key);
- Document dd = cipher.doFinal(doc, ee);
+ byte[] dd = cipher.decryptToByteArray(ee);
return dd;
@@ -385,17 +546,97 @@
return key;
}
+ if (name.equals("job")) {
+
+ // Jeb is a AES-128 key
+ SecretKey key = new SecretKeySpec(jobBytes, "AES");
+ return key;
+ }
if (name.equals("jeb")) {
// Jeb is a AES-192 key
SecretKey key = new SecretKeySpec(jebBytes, "AES");
return key;
}
+ if (name.equals("jed")) {
+
+ // Jeb is a AES-256 key
+ SecretKey key = new SecretKeySpec(jedBytes, "AES");
+ return key;
+ }
return null;
}
+ /**
+ * Method findKey
+ *
+ * Given an encryptedData structure, return the key that will decrypt
+ * it
+ *
+ * @param encryptedData EncryptedData to get key for
+ */
+
+ public Key findKey(EncryptedData encryptedData) throws Exception {
+
+ KeyInfo ki = encryptedData.getKeyInfo();
+
+ Key key = null;
+ Key kek = null;
+
+ if (ki == null)
+ return null;
+
+
+ // First check for a known key name
+ KeyName keyName = ki.itemKeyName(0);
+ if (keyName != null) {
+ return (mapKeyName(keyName.getKeyName()));
+ }
+
+ // Decrypt any encryptedKey structures
+ EncryptedKey encryptedKey = ki.itemEncryptedKey(0);
+
+ if (encryptedKey == null)
+ return null;
+
+ KeyInfo kiek = encryptedKey.getKeyInfo();
+ if (kiek == null) {
+ return null;
+ }
+
+ KeyName kekKeyName = kiek.itemKeyName(0);
+ if (kekKeyName != null) {
+ kek = mapKeyName(kekKeyName.getKeyName());
+ }
+ else {
+
+ X509Data certData = kiek.itemX509Data(0);
+ XMLX509Certificate xcert = certData.itemCertificate(0);
+ X509Certificate cert = xcert.getX509Certificate();
+
+ if (cert != null) {
+
+ if
(cert.getSerialNumber().toString().equals(rsaCertSerialNumber)) {
+
+ kek = rsaKey;
+
+ }
+ }
+ }
+ if (kek != null) {
+ XMLCipher cipher = XMLCipher.getInstance();
+ cipher.init(XMLCipher.DECRYPT_MODE, null);
+ cipher.setKEK(kek);
+ key = cipher.decryptKey(encryptedKey,
+
encryptedData.
+
getEncryptionMethod().
+
getAlgorithm());
+ }
+
+ return key;
+ }
/**
* Method countNodes
*