X-Git-Url: https://gerrit.onap.org/r/gitweb?p=aaf%2Fauthz.git;a=blobdiff_plain;f=auth%2Fauth-certman%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fauth%2Fcm%2Fca%2FLocalCA.java;h=f7de90ea06bb2f1e464140bab113f577c92c61b5;hp=cd8886dac31ec7b1967a94150531e01acac643bb;hb=be1edcb6830745015f5de72e820f40f36dd571ad;hpb=c36423577d5b8501af78cc2f8a7db1e43eacdf0d 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 cd8886da..f7de90ea 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 @@ -7,9 +7,9 @@ * 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. @@ -39,6 +39,7 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; @@ -64,191 +65,207 @@ import org.onap.aaf.auth.cm.cert.RDN; import org.onap.aaf.auth.env.NullTrans; import org.onap.aaf.cadi.Access; import org.onap.aaf.cadi.Access.Level; -import org.onap.aaf.cadi.cm.CertException; -import org.onap.aaf.cadi.cm.Factory; +import org.onap.aaf.cadi.configure.CertException; +import org.onap.aaf.cadi.configure.Factory; import org.onap.aaf.misc.env.Env; import org.onap.aaf.misc.env.TimeTaken; import org.onap.aaf.misc.env.Trans; public class LocalCA extends CA { + private final static BigInteger ONE = new BigInteger("1"); + // Extensions + private static final KeyPurposeId[] ASN_WebUsage = new KeyPurposeId[] { + KeyPurposeId.id_kp_serverAuth, // WebServer + KeyPurposeId.id_kp_clientAuth // WebClient + }; + + private final PrivateKey caKey; + private final X500Name issuer; + private BigInteger serial; + private final X509ChainWithIssuer x509cwi; // "Cert" is CACert + + + public LocalCA(Access access, final String name, final String env, final String[][] params) throws IOException, CertException { + super(access, name, env); + + serial = new BigInteger(64,new SecureRandom()); + + if (params.length<1 || params[0].length<2) { + throw new IOException("LocalCA expects cm_ca.=org.onap.aaf.auth.cm.ca.LocalCA,[;]+"); + } + + // Read in the Private Key + 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 path; + for (int i=1; i; enc:>"); + } + try { + Provider p; + KeyStore keyStore; + FileInputStream fis = null; + if (fileName.endsWith(".pkcs11")) { + String ksType="PKCS11"; + p = Factory.getSecurityProvider(ksType,params); + keyStore = KeyStore.getInstance(ksType,p); + } else if (fileName.endsWith(".jks")) { + keyStore = KeyStore.getInstance("JKS"); + fis = new FileInputStream(f); + } else if (fileName.endsWith(".p12") || fileName.endsWith(".pkcs12")) { + keyStore = KeyStore.getInstance("PKCS12"); + fis = new FileInputStream(f); + } else { + throw new CertException("Unknown Keystore type from filename " + fileName); + } - // Extensions - private static final KeyPurposeId[] ASN_WebUsage = new KeyPurposeId[] { - KeyPurposeId.id_kp_serverAuth, // WebServer - KeyPurposeId.id_kp_clientAuth};// WebClient - - private final PrivateKey caKey; - private final X500Name issuer; - private final SecureRandom random = new SecureRandom(); - private byte[] serialish; - private final X509ChainWithIssuer x509cwi; // "Cert" is CACert - - public LocalCA(Access access, final String name, final String env, final String[][] params) throws IOException, CertException { - super(access, name, env); - serialish = new byte[24]; - if(params.length<1 || params[0].length<2) { - throw new IOException("LocalCA expects cm_ca.=org.onap.aaf.auth.cm.ca.LocalCA,[;]+"); - } - - // Read in the Private Key - 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 path; - for(int i=1; i; enc:>"); - } - try { - Provider p; - KeyStore keyStore; - FileInputStream fis = null; - 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"); - fis = new FileInputStream(f); - } else if(fileName.endsWith(".p12") || fileName.endsWith(".pkcs12")) { - keyStore = KeyStore.getInstance("PKCS12"); - fis = new FileInputStream(f); - } else { - throw new CertException("Unknown Keystore type from filename " + fileName); - } - - 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 { - if (fis != null) - fis.close(); - } - Entry entry; - if(fileName.endsWith(".pkcs11")) { - entry = keyStore.getEntry(params[0][1]/*alias*/, null); - } else { - 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) - * @see org.onap.aaf.auth.cm.service.CA#sign(org.bouncycastle.pkcs.PKCS10CertificationRequest) - */ - @Override - public X509andChain sign(Trans trans, CSRMeta csrmeta) throws IOException, CertException { - GregorianCalendar gc = new GregorianCalendar(); - Date start = gc.getTime(); - gc.add(GregorianCalendar.MONTH, 2); - Date end = gc.getTime(); - X509Certificate x509; - TimeTaken tt = trans.start("Create/Sign Cert",Env.SUB); - try { - BigInteger bi; - synchronized(serialish) { - random.nextBytes(serialish); - bi = new BigInteger(serialish); - } - - RSAPublicKey rpk = (RSAPublicKey)csrmeta.keypair(trans).getPublic(); - X509v3CertificateBuilder xcb = new X509v3CertificateBuilder( - issuer, - bi, // replace with Serialnumber scheme - start, - end, - csrmeta.x500Name(), - SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(new RSAKeyParameters(false,rpk.getModulus(),rpk.getPublicExponent())) -// new SubjectPublicKeyInfo(ASN1Sequence.getInstance(caCert.getPublicKey().getEncoded())) - ); - List lsan = new ArrayList(); - for(String s : csrmeta.sans()) { - lsan.add(new GeneralName(GeneralName.dNSName,s)); - } - GeneralName[] sans = new GeneralName[lsan.size()]; - lsan.toArray(sans); - - JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); - xcb.addExtension(Extension.basicConstraints, - false, new BasicConstraints(false)) - .addExtension(Extension.keyUsage, - true, new KeyUsage(KeyUsage.digitalSignature - | KeyUsage.keyEncipherment)) - .addExtension(Extension.extendedKeyUsage, - true, new ExtendedKeyUsage(ASN_WebUsage)) + KeyStore.ProtectionParameter keyPass; + try { + String pass = access.decrypt(params[0][2]/*encrypted passcode*/, true); + if (pass==null || pass.isEmpty()) { + 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 { + if (fis != null) { + fis.close(); + } + } + Entry entry; + if (fileName.endsWith(".pkcs11")) { + entry = keyStore.getEntry(params[0][1]/*alias*/, null); + } else { + 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(); + List rp = RDN.parse(',', x509cwi.getIssuerDN()); + Collections.reverse(rp); + for (RDN rnd : rp) { + 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) + * @see org.onap.aaf.auth.cm.service.CA#sign(org.bouncycastle.pkcs.PKCS10CertificationRequest) + */ + @Override + public X509andChain sign(Trans trans, CSRMeta csrmeta) throws IOException, CertException { + GregorianCalendar gc = new GregorianCalendar(); + Date start = gc.getTime(); + gc.add(GregorianCalendar.MONTH, 12); + Date end = gc.getTime(); + X509Certificate x509; + TimeTaken tt = trans.start("Create/Sign Cert",Env.SUB); + try { + BigInteger bi; + + synchronized(ONE) { + bi = serial; + serial = serial.add(ONE); + } + + RSAPublicKey rpk = (RSAPublicKey)csrmeta.keypair(trans).getPublic(); + X509v3CertificateBuilder xcb = new X509v3CertificateBuilder( + issuer, + bi, // replace with Serialnumber scheme + start, + end, + csrmeta.x500Name(), + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(new RSAKeyParameters(false,rpk.getModulus(),rpk.getPublicExponent())) +// new SubjectPublicKeyInfo(ASN1Sequence.getInstance(caCert.getPublicKey().getEncoded())) + ); + List lsan = new ArrayList<>(); + // Email + lsan.add(new GeneralName(GeneralName.rfc822Name,csrmeta.email())); + for (String s : csrmeta.sans()) { + if(IPV4_PATTERN.matcher(s).matches() || IPV6_PATTERN.matcher(s).matches()) { + lsan.add(new GeneralName(GeneralName.iPAddress,s)); + } else { + lsan.add(new GeneralName(GeneralName.dNSName,s)); + } + } + GeneralName[] sans = new GeneralName[lsan.size()]; + lsan.toArray(sans); + + JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); + xcb.addExtension(Extension.basicConstraints, + false, new BasicConstraints(false + )) + .addExtension(Extension.keyUsage, + true, new KeyUsage(KeyUsage.digitalSignature + | KeyUsage.keyEncipherment + | KeyUsage.nonRepudiation)) + .addExtension(Extension.extendedKeyUsage, + true, new ExtendedKeyUsage(ASN_WebUsage)) .addExtension(Extension.authorityKeyIdentifier, - false, extUtils.createAuthorityKeyIdentifier(x509cwi.cert)) - .addExtension(Extension.subjectKeyIdentifier, - false, extUtils.createSubjectKeyIdentifier(x509cwi.cert.getPublicKey())) - .addExtension(Extension.subjectAlternativeName, - false, new GeneralNames(sans)) - ; - - x509 = new JcaX509CertificateConverter().getCertificate( - xcb.build(BCFactory.contentSigner(caKey))); - } catch (GeneralSecurityException|OperatorCreationException e) { - throw new CertException(e); - } finally { - tt.done(); - } - - return new X509ChainWithIssuer(x509cwi,x509); - } + false, extUtils.createAuthorityKeyIdentifier(x509cwi.cert)) + .addExtension(Extension.subjectKeyIdentifier, + false, extUtils.createSubjectKeyIdentifier(rpk)) + .addExtension(Extension.subjectAlternativeName, + false, new GeneralNames(sans)) +// .addExtension(MiscObjectIdentifiers.netscape, true, new NetscapeCertType( +// NetscapeCertType.sslClient|NetscapeCertType.sslClient)) + ; + + x509 = new JcaX509CertificateConverter().getCertificate( + xcb.build(BCFactory.contentSigner(caKey))); + } catch (GeneralSecurityException|OperatorCreationException e) { + throw new CertException(e); + } finally { + tt.done(); + } + + return new X509andChain(x509,x509cwi.trustChain); + } }