Started to add support for RSA raw encrypted keys.
authorwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Mon, 8 Dec 2003 22:49:32 +0000 (22:49 +0000)
committerwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Mon, 8 Dec 2003 22:49:32 +0000 (22:49 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@809 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

data/credentials13.xml [new file with mode: 0644]
src/edu/internet2/middleware/shibboleth/common/Credentials.java
tests/edu/internet2/middleware/shibboleth/common/CredentialsTests.java

diff --git a/data/credentials13.xml b/data/credentials13.xml
new file mode 100644 (file)
index 0000000..5af500d
--- /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.pemcrt</Path>
+               </Certificate>
+               <Key format="PEM" password="test123">
+                       <Path>/conf/test.pkcs1.enc.pemkey</Path>
+               </Key>
+       </FileResolver>
+</Credentials>
\ No newline at end of file
index 0587bdf..56c25b1 100644 (file)
@@ -502,6 +502,12 @@ class FileCredentialResolver implements CredentialResolver {
                                                "-----END PRIVATE KEY-----"));
 
                        } else if (str.matches("^.*-----BEGIN RSA PRIVATE KEY-----.*$")) {
+                               String nextStr = in.readLine();
+                               if (nextStr != null && nextStr.matches("^.*Proc-Type: 4,ENCRYPTED.*$")) {
+                                       log.debug("Key appears to be encrypted RSA in raw format.");
+                                       return getRSARawEncryptedPemKey(inputBytes.toByteArray());
+                               }
+                               
                                in.close();
                                log.debug("Key appears to be RSA in raw format.");
                                return getRSARawDerKey(
@@ -509,6 +515,7 @@ class FileCredentialResolver implements CredentialResolver {
                                                inputBytes.toByteArray(),
                                                "-----BEGIN RSA PRIVATE KEY-----",
                                                "-----END RSA PRIVATE KEY-----"));
+                                               
                        } else if (str.matches("^.*-----BEGIN DSA PRIVATE KEY-----.*$")) {
                                in.close();
                                log.debug("Key appears to be DSA in raw format.");
@@ -517,7 +524,7 @@ class FileCredentialResolver implements CredentialResolver {
                                                inputBytes.toByteArray(),
                                                "-----BEGIN DSA PRIVATE KEY-----",
                                                "-----END DSA PRIVATE KEY-----"));
-                                               
+
                        } else if (str.matches("^.*-----BEGIN ENCRYPTED PRIVATE KEY-----.*$")) {
                                in.close();
                                log.debug("Key appears to be in encrypted PKCS8 format.");
@@ -525,7 +532,8 @@ class FileCredentialResolver implements CredentialResolver {
                                        singleDerFromPEM(
                                                inputBytes.toByteArray(),
                                                "-----BEGIN ENCRYPTED PRIVATE KEY-----",
-                                               "-----END ENCRYPTED PRIVATE KEY-----"), password.toCharArray());
+                                               "-----END ENCRYPTED PRIVATE KEY-----"),
+                                       password.toCharArray());
                        }
                }
                in.close();
@@ -626,6 +634,86 @@ class FileCredentialResolver implements CredentialResolver {
                }
 
        }
+       private PrivateKey getRSARawEncryptedPemKey(byte[] bytes) throws CredentialFactoryException {
+
+               try {
+
+                       String algorithm = null;
+                       String algParams = null;
+
+                       BufferedReader in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes)));
+                       String str;
+                       boolean insideBase64 = false;
+                       StringBuffer base64Key = null;
+                       while ((str = in.readLine()) != null) {
+
+                               if (insideBase64) {
+                                       if (str.matches("^.*Proc-Type: 4,ENCRYPTED.*$")) {
+                                               continue;
+                                       }
+
+                                       if (str.matches("^.*DEK-Info:.*$")) {
+                                               String[] components = str.split(":\\s");
+                                               if (components.length != 2) {
+                                                       log.error("Encrypted key did not contain DEK-Info specification.");
+                                                       throw new CredentialFactoryException("Unable to load private key.");
+                                               }
+                                               String[] cryptData = components[1].split(",");
+                                               if (cryptData.length != 2
+                                                       || cryptData[0] == null
+                                                       || cryptData[0].equals("")
+                                                       || cryptData[1] == null
+                                                       || cryptData[1].equals("")) {
+                                                       log.error("Encrypted key did not contain a proper DEK-Info specification.");
+                                                       throw new CredentialFactoryException("Unable to load private key.");
+                                               }
+                                               algorithm = cryptData[0];
+                                               algParams = cryptData[1];
+                                               continue;
+                                       }
+                                       if (str.equals("")) {
+                                               continue;
+                                       }
+
+                                       if (str.matches("^.*-----END RSA PRIVATE KEY-----.*$")) {
+                                               break;
+                                       }
+                                       {
+                                               base64Key.append(str);
+                                       }
+                               } else if (str.matches("^.*-----BEGIN RSA PRIVATE KEY-----.*$")) {
+                                       insideBase64 = true;
+                                       base64Key = new StringBuffer();
+                               }
+                       }
+                       in.close();
+                       if (base64Key == null || base64Key.length() == 0) {
+                               log.error("Could not find Base 64 encoded entity.");
+                               throw new IOException("Could not find Base 64 encoded entity.");
+                       }
+
+                       try {
+                               BASE64Decoder decoder = new BASE64Decoder();
+                               byte[] encryptedBytes = decoder.decodeBuffer(base64Key.toString());
+                               
+                               //TODO This needs to come from the file
+                               Cipher cipher = Cipher.getInstance("DESede");
+                               //cipher.in
+
+                               return null;
+
+                       } catch (IOException ioe) {
+                               log.error("Could not decode Base 64: " + ioe);
+                               throw new IOException("Could not decode Base 64.");
+                       }
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       //TODO change these errors
+                       log.error("Could not load resource from specified location: " + e);
+                       throw new CredentialFactoryException("Could not load resource from specified location.");
+               }
+       }
 
        private PrivateKey getDSARawDerKey(byte[] bytes) throws CredentialFactoryException {
 
index 4bc2cd6..4928a5d 100644 (file)
@@ -494,5 +494,36 @@ public class CredentialsTests extends TestCase {
                        fail("Failed to load credentials: " + e);
                }
        }
+       
+       public void testKeyStoreX509_PEM_Encrypted_RSA_Key() {
+
+               try {
+                       InputStream inStream = new FileInputStream("data/credentials13.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=shib2.internet2.edu, OU=Unknown, O=Unknown, ST=Unknown, C=Unknown");
+                       assertEquals(
+                               "Unexpected certificate chain length.",
+                               new Integer(credential.getX509CertificateChain().length),
+                               new Integer(3));
+                       assertEquals(
+                               "Unexpected X509 certificate found.",
+                               credential.getX509CertificateChain()[2].getSubjectDN().getName(),
+                               "CN=HEPKI Master CA -- 20020701A, OU=Division of Information Technology, O=University of Wisconsin, L=Madison, ST=Wisconsin, C=US");
+               } catch (Exception e) {
+                       fail("Failed to load credentials: " + e);
+               }
+       }
 
 }