From 3635fc5c8d8409d1c5e0f521469a6aaca4d19ffe Mon Sep 17 00:00:00 2001 From: Instrumental Date: Thu, 29 Mar 2018 09:58:42 -0500 Subject: Local CA to use Keystores Issue-ID: AAF-204 Change-Id: I59491ffa26d5ea117a98470f38f090900b9e1b4e Signed-off-by: Instrumental --- auth/auth-certman/.gitignore | 4 + .../main/java/org/onap/aaf/auth/cm/ca/LocalCA.java | 124 ++++++++++++++++----- .../onap/aaf/auth/cm/ca/X509ChainWithIssuer.java | 15 +++ 3 files changed, 113 insertions(+), 30 deletions(-) create mode 100644 auth/auth-certman/.gitignore (limited to 'auth/auth-certman') diff --git a/auth/auth-certman/.gitignore b/auth/auth-certman/.gitignore new file mode 100644 index 00000000..6028f0a5 --- /dev/null +++ b/auth/auth-certman/.gitignore @@ -0,0 +1,4 @@ +/.classpath +/.settings/ +/target/ +/.project diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/LocalCA.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/LocalCA.java index b6a2a0a9..70f67940 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/LocalCA.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/LocalCA.java @@ -21,13 +21,22 @@ package org.onap.aaf.auth.cm.ca; import java.io.File; +import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.KeyStore.Entry; +import java.security.KeyStore.PrivateKeyEntry; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.Provider; import java.security.SecureRandom; +import java.security.UnrecoverableEntryException; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.Date; @@ -68,7 +77,7 @@ public class LocalCA extends CA { KeyPurposeId.id_kp_serverAuth, // WebServer KeyPurposeId.id_kp_clientAuth};// WebClient - private final RSAPrivateKey caKey; + private final PrivateKey caKey; private final X500Name issuer; private final SecureRandom random = new SecureRandom(); private byte[] serialish; @@ -82,38 +91,93 @@ public class LocalCA extends CA { } // Read in the Private Key - File f = new File(params[0][0]); // key - if(f.exists()) { - caKey = (RSAPrivateKey)Factory.toPrivateKey(NullTrans.singleton(),f); - } else { - throw new CertException("Private Key, " + f.getPath() + ", does not exist"); - } + String configured; + File f = new File(params[0][0]); + if(f.exists() && f.isFile()) { + String fileName = f.getName(); + if(fileName.endsWith(".key")) { + caKey = Factory.toPrivateKey(NullTrans.singleton(),f); + List frs = new ArrayList(params.length-1); + try { + String dir = access.getProperty(CM_PUBLIC_DIR, ""); + if(!"".equals(dir) && !dir.endsWith("/")) { + dir = dir + '/'; + } - String dir = access.getProperty(CM_PUBLIC_DIR, ""); - if(!"".equals(dir) && !dir.endsWith("/")) { - dir = dir + '/'; - } - List frs = new ArrayList(params.length-1); - try { - String path; - for(int i=1; i; enc:>"); + } + try { + Provider p; + KeyStore keyStore; + if(fileName.endsWith(".pkcs11")) { + String ksType; + p = Factory.getSecurityProvider(ksType="PKCS11",params); + keyStore = KeyStore.getInstance(ksType,p); + } else if(fileName.endsWith(".jks")) { + keyStore = KeyStore.getInstance("JKS"); + } else if(fileName.endsWith(".p12") || fileName.endsWith(".pkcs12")) { + keyStore = KeyStore.getInstance("PKCS12"); + } else { + throw new CertException("Unknown Keystore type from filename " + fileName); + } + + FileInputStream fis = new FileInputStream(f); + KeyStore.ProtectionParameter keyPass; + + try { + String pass = access.decrypt(params[0][2]/*encrypted passcode*/, true); + if(pass==null) { + throw new CertException("Passcode for " + fileName + " cannot be decrypted."); + } + char[] ksPass = pass.toCharArray(); + //Assuming Key Pass is same as Keystore Pass + keyPass = new KeyStore.PasswordProtection(ksPass); + + keyStore.load(fis,ksPass); + } finally { + fis.close(); + } + Entry entry = keyStore.getEntry(params[0][1]/*alias*/, keyPass); + if(entry==null) { + throw new CertException("There is no Keystore entry with name '" + params[0][1] +'\''); + } + PrivateKeyEntry privateKeyEntry = (PrivateKeyEntry)entry; + caKey = privateKeyEntry.getPrivateKey(); + + x509cwi = new X509ChainWithIssuer(privateKeyEntry.getCertificateChain()); + configured = "keystore \"" + fileName + "\", alias " + params[0][1]; + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableEntryException e) { + throw new CertException("Exception opening Keystore " + fileName, e); } } + } else { + throw new CertException("Private Key, " + f.getPath() + ", does not exist"); + } + + X500NameBuilder xnb = new X500NameBuilder(); + for(RDN rnd : RDN.parse(',', x509cwi.getIssuerDN())) { + xnb.addRDN(rnd.aoi,rnd.value); } + issuer = xnb.build(); + access.printf(Level.INIT, "LocalCA is configured with %s. The Issuer DN is %s.", + configured, issuer.toString()); } /* (non-Javadoc) diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/X509ChainWithIssuer.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/X509ChainWithIssuer.java index e0a85676..6f3062bb 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/X509ChainWithIssuer.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/X509ChainWithIssuer.java @@ -67,6 +67,21 @@ public class X509ChainWithIssuer extends X509andChain { } } + public X509ChainWithIssuer(Certificate[] certs) throws IOException, CertException { + X509Certificate x509; + for(Certificate c : certs) { + x509=(X509Certificate)c; + Principal subject = x509.getSubjectDN(); + if(subject!=null) { + if(cert==null) { // first in Trust Chain + issuerDN= subject.toString(); + } + addTrustChainEntry(x509); + cert=x509; // adding each time makes sure last one is signer. + } + } + } + public String getIssuerDN() { return issuerDN; } -- cgit 1.2.3-korg