Added support to the file credential resolver for DSA native keys in PEM and DER...
authorwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 4 Dec 2003 21:35:41 +0000 (21:35 +0000)
committerwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 4 Dec 2003 21:35:41 +0000 (21:35 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@801 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

data/credentials8.xml [new file with mode: 0644]
data/credentials9.xml [new file with mode: 0644]
src/edu/internet2/middleware/shibboleth/common/Credentials.java
tests/conf/test.dsa.derkey [new file with mode: 0644]
tests/conf/test.dsa.pemcrt [new file with mode: 0644]
tests/conf/test.dsa.pemkey [new file with mode: 0644]
tests/edu/internet2/middleware/shibboleth/common/CredentialsTests.java

diff --git a/data/credentials8.xml b/data/credentials8.xml
new file mode 100644 (file)
index 0000000..151a310
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Credentials xmlns="urn:mace:shibboleth:credentials:1.0" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="urn:mace:shibboleth:credentials:1.0 credentials.xsd">
+       
+       <FileResolver Id="test">
+               <Certificate format="PEM">
+                       <Path>/conf/test.dsa.pemcrt</Path>
+               </Certificate>
+               <Key format="DER">
+                       <Path>/conf/test.dsa.derkey</Path>
+               </Key>
+       </FileResolver>
+</Credentials>
\ No newline at end of file
diff --git a/data/credentials9.xml b/data/credentials9.xml
new file mode 100644 (file)
index 0000000..8b1f48b
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Credentials xmlns="urn:mace:shibboleth:credentials:1.0" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="urn:mace:shibboleth:credentials:1.0 credentials.xsd">
+       
+       <FileResolver Id="test">
+               <Certificate format="PEM">
+                       <Path>/conf/test.dsa.pemcrt</Path>
+               </Certificate>
+               <Key format="PEM">
+                       <Path>/conf/test.dsa.pemkey</Path>
+               </Key>
+       </FileResolver>
+</Credentials>
\ No newline at end of file
index 67e1335..26facd7 100644 (file)
@@ -55,6 +55,7 @@ import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.security.spec.DSAPrivateKeySpec;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.RSAPrivateCrtKeySpec;
 import java.util.ArrayList;
@@ -331,12 +332,19 @@ class FileCredentialResolver implements CredentialResolver {
                        }
                } while (i > -1);
 
+               //TODO switch to examining the DER, so we don't get failure messages
                try {
                        return getRSAPkcs8DerKey(inputBytes.toByteArray());
 
                } catch (CredentialFactoryException e) {
-                       log.debug("Unable to load private key as PKCS8, attempting raw RSA.");
-                       return getRSARawDERKey(inputBytes.toByteArray());
+                       try {
+                               log.debug("Unable to load private key as PKCS8, attempting raw RSA.");
+                               return getRSARawDERKey(inputBytes.toByteArray());
+
+                       } catch (CredentialFactoryException e2) {
+                               log.debug("Unable to load private key as raw RSA, attempting raw DSA.");
+                               return getDSARawDERKey(inputBytes.toByteArray());
+                       }
                }
 
        }
@@ -375,8 +383,11 @@ class FileCredentialResolver implements CredentialResolver {
                                                "-----END RSA PRIVATE KEY-----"));
                        } else if (str.matches("^.*-----BEGIN DSA PRIVATE KEY-----.*$")) {
                                in.close();
-                               log.error("No Support for DSA PEM keys.");
-                               throw new CredentialFactoryException("Failed to initialize Credential Resolver.");
+                               return getDSARawDERKey(
+                                       singleDerFromPEM(
+                                               inputBytes.toByteArray(),
+                                               "-----BEGIN DSA PRIVATE KEY-----",
+                                               "-----END DSA PRIVATE KEY-----"));
                        }
                }
                in.close();
@@ -457,7 +468,60 @@ class FileCredentialResolver implements CredentialResolver {
                        return keyFactory.generatePrivate(keySpec);
 
                } catch (IOException e) {
-                       log.error("Invalid DER encoding: " + e);
+                       log.error("Invalid DER encoding for RSA key: " + e);
+                       throw new CredentialFactoryException("Unable to load private key.");
+               } catch (GeneralSecurityException e) {
+                       log.error("Unable to marshall private key: " + e);
+                       throw new CredentialFactoryException("Unable to load private key.");
+               }
+
+       }
+
+       private PrivateKey getDSARawDERKey(byte[] bytes) throws CredentialFactoryException {
+
+               try {
+                       DerValue root = new DerValue(bytes);
+                       if (root.tag != DerValue.tag_Sequence) {
+                               log.error("Unexpected data type.  Unable to load data as an DSA key.");
+                               throw new CredentialFactoryException("Unable to load private key.");
+                       }
+
+                       DerValue[] childValues = new DerValue[6];
+                       childValues[0] = root.data.getDerValue();
+                       childValues[1] = root.data.getDerValue();
+                       childValues[2] = root.data.getDerValue();
+                       childValues[3] = root.data.getDerValue();
+                       childValues[4] = root.data.getDerValue();
+                       childValues[5] = root.data.getDerValue();
+
+                       if (root.data.available() != 0) {
+                               log.error("Data overflow.  Unable to load data as an DSA key.");
+                               throw new CredentialFactoryException("Unable to load private key.");
+                       }
+
+                       if (childValues[0].tag != DerValue.tag_Integer
+                               || childValues[1].tag != DerValue.tag_Integer
+                               || childValues[2].tag != DerValue.tag_Integer
+                               || childValues[3].tag != DerValue.tag_Integer
+                               || childValues[4].tag != DerValue.tag_Integer
+                               || childValues[5].tag != DerValue.tag_Integer) {
+                               log.error("Unexpected data type.  Unable to load data as an DSA key.");
+                               throw new CredentialFactoryException("Unable to load private key.");
+                       }
+
+                       DSAPrivateKeySpec keySpec =
+                               new DSAPrivateKeySpec(
+                                       childValues[5].getBigInteger(),
+                                       childValues[1].getBigInteger(),
+                                       childValues[2].getBigInteger(),
+                                       childValues[3].getBigInteger());
+
+                       KeyFactory keyFactory = KeyFactory.getInstance("DSA");
+
+                       return keyFactory.generatePrivate(keySpec);
+
+               } catch (IOException e) {
+                       log.error("Invalid DER encoding for DSA key: " + e);
                        throw new CredentialFactoryException("Unable to load private key.");
                } catch (GeneralSecurityException e) {
                        log.error("Unable to marshall private key: " + e);
@@ -468,7 +532,7 @@ class FileCredentialResolver implements CredentialResolver {
 
        private PrivateKey getPkcs8PemKey(byte[] bytes) throws CredentialFactoryException {
 
-               //Needs to work for DSA as well
+               //TODO Needs to work for DSA as well
                return getRSAPkcs8DerKey(bytes);
        }
 
diff --git a/tests/conf/test.dsa.derkey b/tests/conf/test.dsa.derkey
new file mode 100644 (file)
index 0000000..fc6abe6
Binary files /dev/null and b/tests/conf/test.dsa.derkey differ
diff --git a/tests/conf/test.dsa.pemcrt b/tests/conf/test.dsa.pemcrt
new file mode 100644 (file)
index 0000000..e9670a0
--- /dev/null
@@ -0,0 +1,119 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 0 (0x0)
+        Signature Algorithm: dsaWithSHA1
+        Issuer: C=US, ST=NY, L=New York, O=Columbia University, OU=ACIS, CN=test.columbia.edu
+        Validity
+            Not Before: Dec  4 21:17:48 2003 GMT
+            Not After : Apr 21 21:17:48 2031 GMT
+        Subject: C=US, ST=NY, L=New York, O=Columbia University, OU=ACIS, CN=test.columbia.edu
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    28:90:8d:3e:b8:8d:87:74:1b:f7:b0:b2:66:7b:d4:
+                    55:d1:b4:4d:30:53:85:3b:05:93:ef:a9:9d:68:26:
+                    fe:60:d0:44:cf:d2:cf:39:58:d5:cb:3b:28:b3:15:
+                    cb:c2:fd:28:c4:8d:d2:19:ab:36:8a:73:5d:32:10:
+                    96:fd:5a:9c:4b:17:23:55:56:c5:70:32:d2:44:f9:
+                    63:e0:10:19:f7:02:da:40:e8:05:b0:fc:ed:ba:f2:
+                    fc:37:4d:72:2c:af:fc:12:ce:4e:e1:6c:25:68:7f:
+                    5b:47:13:5d:da:75:4f:22:74:cf:c3:27:0a:0b:ba:
+                    2d:d4:1f:24:3f:10:db:0a:a5:c6:c8:34:93:fa:b0:
+                    ed:3a:8d:ce:39:3e:8e:c2:ae:9d:76:2c:9a:d4:49:
+                    53:a9:e6:a8:ea:c3:91:ba:ab:7d:2d:ea:7c:59:9a:
+                    ad:5d:9b:c2:44:2e:95:05:89:52:cb:ba:4e:9e:60:
+                    ba:a9:0b:ec:f0:bd:ac:c5:f5:b8:08:e0:68:b3:35:
+                    c3:62:e3:8f:3e:88:ed:dd:2e:2d:53:d0:52:57:38:
+                    2d:5c:ff:d9:a2:5c:8f:dc:52:98:95:c2:09:0f:61:
+                    5b:95:79:0f:c9:c1:c2:b3:e1:fc:b1:7d:a3:95:10:
+                    e0:61:a6:55:9f:79:e1:ca:8f:48:85:42:6f:9b:18:
+                    d8
+                P:   
+                    00:de:f6:ce:e5:2b:8f:09:02:ef:37:5f:56:7d:a5:
+                    7b:66:b3:fb:8d:92:1d:5c:83:73:da:72:82:30:46:
+                    17:05:3f:a9:79:65:63:de:bd:ef:6f:88:35:59:3f:
+                    11:ee:19:93:af:f6:5b:0e:e4:e9:bf:c2:23:a6:55:
+                    c6:f0:9a:df:c1:81:57:db:ae:df:89:a6:4d:a6:f3:
+                    14:16:a6:07:0e:30:83:3f:53:a3:89:6c:bf:55:50:
+                    5d:db:0c:50:72:10:47:82:8e:91:9a:5c:66:03:a9:
+                    2a:3c:68:24:08:50:f5:cb:bc:3a:78:b1:e1:a0:04:
+                    a5:dd:88:9e:f1:0e:4f:f4:98:76:9b:55:de:78:50:
+                    50:7f:2a:e8:aa:4d:b0:82:24:a5:38:a0:7e:e6:95:
+                    9e:4d:b5:54:c4:46:d7:75:a9:1f:63:7d:e0:8b:99:
+                    a3:b6:fa:80:da:73:7b:73:ab:d5:6a:ce:2b:a2:18:
+                    04:d0:ec:01:3b:cf:be:50:98:62:b0:ca:6d:25:a6:
+                    3f:89:89:59:2d:e2:81:60:34:4f:57:a1:7f:ab:7b:
+                    6b:70:26:86:c6:a2:e4:78:3d:9e:4a:95:a8:98:d4:
+                    13:85:e2:b2:19:17:bd:69:bb:b8:14:a5:54:11:3c:
+                    89:33:84:d3:4b:bb:93:29:76:e4:f7:93:1a:42:ce:
+                    54:ef
+                Q:   
+                    00:ac:b7:12:00:0b:8f:20:0c:2a:e8:45:f1:ae:a4:
+                    7b:61:56:14:1e:31
+                G:   
+                    00:89:c2:61:a1:fd:fe:59:43:44:05:9e:1f:71:d4:
+                    59:e2:5c:84:27:01:9e:99:99:cd:32:b3:92:f4:e8:
+                    b4:13:01:9a:a3:7b:26:2b:4e:31:4c:ec:19:cd:c8:
+                    04:60:2c:45:f7:b1:86:d5:e8:d6:d4:84:f6:4e:2f:
+                    8a:83:a7:aa:14:fb:91:5a:64:28:40:6b:20:1e:75:
+                    34:68:95:ff:2d:1f:78:99:ba:d6:0c:3d:6b:de:7c:
+                    33:b0:43:08:b2:38:9f:58:03:a7:6f:cc:6a:10:50:
+                    01:b5:a8:44:ce:b8:53:cc:fa:3e:be:79:ac:b4:6f:
+                    11:6f:55:50:36:5f:48:5e:ad:90:76:99:4c:08:13:
+                    d7:db:6a:ea:df:37:e0:ab:6f:4b:e1:15:0a:ba:a1:
+                    7d:6e:08:ee:df:5d:b0:10:1b:87:1d:ba:db:af:ce:
+                    b7:65:05:f0:65:39:5b:17:b3:8e:b9:8b:41:c5:76:
+                    e5:8a:de:ef:fb:8e:a7:44:93:11:b5:6a:7f:0c:e2:
+                    7b:34:e5:f1:5a:cf:4b:e3:5f:27:7d:f2:d0:66:3e:
+                    92:a4:a2:59:c1:07:e7:08:44:0f:79:b6:51:b9:1b:
+                    13:ca:50:d2:b5:73:35:15:a2:53:3d:88:a6:a4:3c:
+                    13:a8:b1:a4:f2:36:03:2b:78:e9:e7:fe:30:fe:ba:
+                    fc:71
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                A2:47:7E:C0:91:D9:4B:92:04:50:E1:93:70:D3:89:67:DE:CA:5F:42
+            X509v3 Authority Key Identifier: 
+                keyid:A2:47:7E:C0:91:D9:4B:92:04:50:E1:93:70:D3:89:67:DE:CA:5F:42
+                DirName:/C=US/ST=NY/L=New York/O=Columbia University/OU=ACIS/CN=test.columbia.edu
+                serial:00
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: dsaWithSHA1
+        30:2d:02:14:4c:6e:fa:2b:f4:47:84:d9:61:ba:51:a0:4c:87:
+        e6:02:6c:62:b1:7a:02:15:00:a8:2b:40:fd:5a:a1:9c:8a:36:
+        99:2f:4d:76:9d:6f:84:c1:83:51:9f
+-----BEGIN CERTIFICATE-----
+MIIFeTCCBTigAwIBAgIBADAJBgcqhkjOOAQDMHYxCzAJBgNVBAYTAlVTMQswCQYD
+VQQIEwJOWTERMA8GA1UEBxMITmV3IFlvcmsxHDAaBgNVBAoTE0NvbHVtYmlhIFVu
+aXZlcnNpdHkxDTALBgNVBAsTBEFDSVMxGjAYBgNVBAMTEXRlc3QuY29sdW1iaWEu
+ZWR1MB4XDTAzMTIwNDIxMTc0OFoXDTMxMDQyMTIxMTc0OFowdjELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAk5ZMREwDwYDVQQHEwhOZXcgWW9yazEcMBoGA1UEChMTQ29s
+dW1iaWEgVW5pdmVyc2l0eTENMAsGA1UECxMEQUNJUzEaMBgGA1UEAxMRdGVzdC5j
+b2x1bWJpYS5lZHUwggM7MIICLgYHKoZIzjgEATCCAiECggEBAN72zuUrjwkC7zdf
+Vn2le2az+42SHVyDc9pygjBGFwU/qXllY96972+INVk/Ee4Zk6/2Ww7k6b/CI6ZV
+xvCa38GBV9uu34mmTabzFBamBw4wgz9To4lsv1VQXdsMUHIQR4KOkZpcZgOpKjxo
+JAhQ9cu8Onix4aAEpd2InvEOT/SYdptV3nhQUH8q6KpNsIIkpTigfuaVnk21VMRG
+13WpH2N94IuZo7b6gNpze3Or1WrOK6IYBNDsATvPvlCYYrDKbSWmP4mJWS3igWA0
+T1ehf6t7a3Amhsai5Hg9nkqVqJjUE4XishkXvWm7uBSlVBE8iTOE00u7kyl25PeT
+GkLOVO8CFQCstxIAC48gDCroRfGupHthVhQeMQKCAQEAicJhof3+WUNEBZ4fcdRZ
+4lyEJwGemZnNMrOS9Oi0EwGao3smK04xTOwZzcgEYCxF97GG1ejW1IT2Ti+Kg6eq
+FPuRWmQoQGsgHnU0aJX/LR94mbrWDD1r3nwzsEMIsjifWAOnb8xqEFABtahEzrhT
+zPo+vnmstG8Rb1VQNl9IXq2QdplMCBPX22rq3zfgq29L4RUKuqF9bgju312wEBuH
+Hbrbr863ZQXwZTlbF7OOuYtBxXblit7v+46nRJMRtWp/DOJ7NOXxWs9L418nffLQ
+Zj6SpKJZwQfnCEQPebZRuRsTylDStXM1FaJTPYimpDwTqLGk8jYDK3jp5/4w/rr8
+cQOCAQUAAoIBACiQjT64jYd0G/ewsmZ71FXRtE0wU4U7BZPvqZ1oJv5g0ETP0s85
+WNXLOyizFcvC/SjEjdIZqzaKc10yEJb9WpxLFyNVVsVwMtJE+WPgEBn3AtpA6AWw
+/O268vw3TXIsr/wSzk7hbCVof1tHE13adU8idM/DJwoLui3UHyQ/ENsKpcbINJP6
+sO06jc45Po7Crp12LJrUSVOp5qjqw5G6q30t6nxZmq1dm8JELpUFiVLLuk6eYLqp
+C+zwvazF9bgI4GizNcNi448+iO3dLi1T0FJXOC1c/9miXI/cUpiVwgkPYVuVeQ/J
+wcKz4fyxfaOVEOBhplWfeeHKj0iFQm+bGNijgdMwgdAwHQYDVR0OBBYEFKJHfsCR
+2UuSBFDhk3DTiWfeyl9CMIGgBgNVHSMEgZgwgZWAFKJHfsCR2UuSBFDhk3DTiWfe
+yl9CoXqkeDB2MQswCQYDVQQGEwJVUzELMAkGA1UECBMCTlkxETAPBgNVBAcTCE5l
+dyBZb3JrMRwwGgYDVQQKExNDb2x1bWJpYSBVbml2ZXJzaXR5MQ0wCwYDVQQLEwRB
+Q0lTMRowGAYDVQQDExF0ZXN0LmNvbHVtYmlhLmVkdYIBADAMBgNVHRMEBTADAQH/
+MAkGByqGSM44BAMDMAAwLQIUTG76K/RHhNlhulGgTIfmAmxisXoCFQCoK0D9WqGc
+ijaZL012nW+EwYNRnw==
+-----END CERTIFICATE-----
diff --git a/tests/conf/test.dsa.pemkey b/tests/conf/test.dsa.pemkey
new file mode 100644 (file)
index 0000000..761a915
--- /dev/null
@@ -0,0 +1,20 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIDPwIBAAKCAQEA3vbO5SuPCQLvN19WfaV7ZrP7jZIdXINz2nKCMEYXBT+peWVj
+3r3vb4g1WT8R7hmTr/ZbDuTpv8IjplXG8JrfwYFX267fiaZNpvMUFqYHDjCDP1Oj
+iWy/VVBd2wxQchBHgo6RmlxmA6kqPGgkCFD1y7w6eLHhoASl3Yie8Q5P9Jh2m1Xe
+eFBQfyroqk2wgiSlOKB+5pWeTbVUxEbXdakfY33gi5mjtvqA2nN7c6vVas4rohgE
+0OwBO8++UJhisMptJaY/iYlZLeKBYDRPV6F/q3trcCaGxqLkeD2eSpWomNQTheKy
+GRe9abu4FKVUETyJM4TTS7uTKXbk95MaQs5U7wIVAKy3EgALjyAMKuhF8a6ke2FW
+FB4xAoIBAQCJwmGh/f5ZQ0QFnh9x1FniXIQnAZ6Zmc0ys5L06LQTAZqjeyYrTjFM
+7BnNyARgLEX3sYbV6NbUhPZOL4qDp6oU+5FaZChAayAedTRolf8tH3iZutYMPWve
+fDOwQwiyOJ9YA6dvzGoQUAG1qETOuFPM+j6+eay0bxFvVVA2X0herZB2mUwIE9fb
+aurfN+Crb0vhFQq6oX1uCO7fXbAQG4cdutuvzrdlBfBlOVsXs465i0HFduWK3u/7
+jqdEkxG1an8M4ns05fFaz0vjXyd98tBmPpKkolnBB+cIRA95tlG5GxPKUNK1czUV
+olM9iKakPBOosaTyNgMreOnn/jD+uvxxAoIBACiQjT64jYd0G/ewsmZ71FXRtE0w
+U4U7BZPvqZ1oJv5g0ETP0s85WNXLOyizFcvC/SjEjdIZqzaKc10yEJb9WpxLFyNV
+VsVwMtJE+WPgEBn3AtpA6AWw/O268vw3TXIsr/wSzk7hbCVof1tHE13adU8idM/D
+JwoLui3UHyQ/ENsKpcbINJP6sO06jc45Po7Crp12LJrUSVOp5qjqw5G6q30t6nxZ
+mq1dm8JELpUFiVLLuk6eYLqpC+zwvazF9bgI4GizNcNi448+iO3dLi1T0FJXOC1c
+/9miXI/cUpiVwgkPYVuVeQ/JwcKz4fyxfaOVEOBhplWfeeHKj0iFQm+bGNgCFQCp
+svfWZegZLGjUod/nLgp8kokgjA==
+-----END DSA PRIVATE KEY-----
index ef83cc7..d06dccf 100644 (file)
@@ -352,4 +352,58 @@ public class CredentialsTests extends TestCase {
                }
        }
 
+       public void testKeyStoreX509_DER_DSA_Key() {
+
+               try {
+                       InputStream inStream = new FileInputStream("data/credentials8.xml");
+                       parser.parse(new InputSource(inStream));
+                       Credentials credentials = new Credentials(parser.getDocument().getDocumentElement());
+
+                       assertTrue("Credential could not be found.", credentials.containsCredential("test"));
+                       Credential credential = credentials.getCredential("test");
+
+                       assertTrue(
+                               "Credential was loaded with an incorrect type.",
+                               credential.getCredentialType() == Credential.X509);
+                       assertNotNull("Private key was not loaded correctly.", credential.getPrivateKey());
+                       assertEquals(
+                               "Unexpected X509 certificate found.",
+                               credential.getX509Certificate().getSubjectDN().getName(),
+                               "CN=test.columbia.edu, OU=ACIS, O=Columbia University, L=New York, ST=NY, C=US");
+                       assertEquals(
+                               "Unexpected certificate chain length.",
+                               new Integer(credential.getX509CertificateChain().length),
+                               new Integer(1));
+               } catch (Exception e) {
+                       fail("Failed to load credentials: " + e);
+               }
+       }
+       
+       public void testKeyStoreX509_PEM_DSA_Key() {
+
+               try {
+                       InputStream inStream = new FileInputStream("data/credentials9.xml");
+                       parser.parse(new InputSource(inStream));
+                       Credentials credentials = new Credentials(parser.getDocument().getDocumentElement());
+
+                       assertTrue("Credential could not be found.", credentials.containsCredential("test"));
+                       Credential credential = credentials.getCredential("test");
+
+                       assertTrue(
+                               "Credential was loaded with an incorrect type.",
+                               credential.getCredentialType() == Credential.X509);
+                       assertNotNull("Private key was not loaded correctly.", credential.getPrivateKey());
+                       assertEquals(
+                               "Unexpected X509 certificate found.",
+                               credential.getX509Certificate().getSubjectDN().getName(),
+                               "CN=test.columbia.edu, OU=ACIS, O=Columbia University, L=New York, ST=NY, C=US");
+                       assertEquals(
+                               "Unexpected certificate chain length.",
+                               new Integer(credential.getX509CertificateChain().length),
+                               new Integer(1));
+               } catch (Exception e) {
+                       fail("Failed to load credentials: " + e);
+               }
+       }
+
 }