diff options
Diffstat (limited to 'auth/auth-certman')
19 files changed, 258 insertions, 215 deletions
diff --git a/auth/auth-certman/pom.xml b/auth/auth-certman/pom.xml index 10a3bb0b..f0dc08ff 100644 --- a/auth/auth-certman/pom.xml +++ b/auth/auth-certman/pom.xml @@ -17,7 +17,7 @@ <parent> <groupId>org.onap.aaf.authz</groupId> <artifactId>authparent</artifactId> - <version>2.1.0-SNAPSHOT</version> + <version>2.1.2-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/AAF_CM.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/AAF_CM.java index 5c5ab962..a9a9b4e5 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/AAF_CM.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/AAF_CM.java @@ -71,7 +71,7 @@ import com.datastax.driver.core.Cluster; public class AAF_CM extends AbsService<AuthzEnv, AuthzTrans> { private static final String USER_PERMS = "userPerms"; - private static final Map<String,CA> certAuths = new TreeMap<String,CA>(); + private static final Map<String,CA> certAuths = new TreeMap<>(); public Facade1_0 facade1_0; // this is the default Facade public Facade1_0 facade1_0_XML; // this is the XML Facade public Map<String, Dated> cacheUser; @@ -201,11 +201,12 @@ public class AAF_CM extends AbsService<AuthzEnv, AuthzTrans> { } @Override - public Filter[] filters() throws CadiException, LocatorException { + public Filter[] _filters(Object ... additionalTafLurs) throws CadiException, LocatorException { try { return new Filter[] { new AuthzTransFilter(env,aafCon(), - new AAFTrustChecker((Env)env)) + new AAFTrustChecker((Env)env), + additionalTafLurs) }; } catch (NumberFormatException e) { throw new CadiException("Invalid Property information", e); diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/CA.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/CA.java index c90dcccf..e840ef56 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/CA.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/CA.java @@ -36,7 +36,8 @@ import org.onap.aaf.auth.cm.cert.CSRMeta; import org.onap.aaf.auth.cm.cert.RDN; 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.config.Config; +import org.onap.aaf.cadi.configure.CertException; import org.onap.aaf.misc.env.Trans; import org.onap.aaf.misc.env.util.Split; @@ -50,15 +51,16 @@ public abstract class CA { private static final String CM_TRUST_CAS = "cm_trust_cas"; protected static final String CM_BACKUP_CAS = "cm_backup_cas"; - public static final Set<String> EMPTY = Collections.unmodifiableSet(new HashSet<String>()); + public static final Set<String> EMPTY = Collections.unmodifiableSet(new HashSet<>()); - private final String name,env; + private final String name; + private final String env; private MessageDigest messageDigest; private final String permType; - private Set<String> caIssuerDNs; private final ArrayList<String> idDomains; private String[] trustedCAs; + private String[] caIssuerDNs; private List<RDN> rdns; @@ -70,7 +72,7 @@ public abstract class CA { if(permType==null) { throw new CertException(CM_CA_PREFIX + name + ".perm_type" + MUST_EXIST_TO_CREATE_CSRS_FOR + caName); } - caIssuerDNs = new HashSet<String>(); + caIssuerDNs = Split.splitTrim(':', access.getProperty(Config.CADI_X509_ISSUERS, null)); String tag = CA.CM_CA_PREFIX+caName+CA.CM_CA_BASE_SUBJECT; @@ -79,13 +81,14 @@ public abstract class CA { throw new CertException(tag + MUST_EXIST_TO_CREATE_CSRS_FOR + caName); } access.log(Level.INFO, tag, "=",fields); - for(RDN rdn : rdns = RDN.parse('/',fields)) { + rdns = RDN.parse('/',fields); + for(RDN rdn : rdns) { if(rdn.aoi==BCStyle.EmailAddress) { // Cert Specs say Emails belong in Subject throw new CertException("email address is not allowed in " + CM_CA_BASE_SUBJECT); } } - idDomains = new ArrayList<String>(); + idDomains = new ArrayList<>(); StringBuilder sb = null; for(String s : Split.splitTrim(',', access.getProperty(CA.CM_CA_PREFIX+caName+".idDomains", ""))) { if(s.length()>0) { @@ -102,15 +105,20 @@ public abstract class CA { access.printf(Level.INIT, "CA '%s' supports Personal Certificates for %s", caName, sb); } - String data_dir = access.getProperty(CM_PUBLIC_DIR,null); - if(data_dir!=null) { - File data = new File(data_dir); + String dataDir = access.getProperty(CM_PUBLIC_DIR,null); + if(dataDir!=null) { + File data = new File(dataDir); byte[] bytes; if(data.exists()) { - String trust_cas = access.getProperty(CM_TRUST_CAS,null); - if(trust_cas!=null) { - for(String fname : Split.splitTrim(',', trust_cas)) { - File crt = new File(data,fname); + String trustCas = access.getProperty(CM_TRUST_CAS,null); + if(trustCas!=null) { + for(String fname : Split.splitTrim(',', trustCas)) { + File crt; + if(fname.contains("/")) { + crt = new File(fname); + } else { + crt = new File(data,fname); + } if(crt.exists()) { access.printf(Level.INIT, "Loading CA Cert from %s", crt.getAbsolutePath()); bytes = new byte[(int)crt.length()]; @@ -137,7 +145,19 @@ public abstract class CA { } protected void addCaIssuerDN(String issuerDN) { - caIssuerDNs.add(issuerDN); + boolean changed = true; + for(String id : caIssuerDNs) { + if(id.equals(issuerDN)) { + changed = false; + break; + } + } + if(changed) { + String[] newsa = new String[caIssuerDNs.length+1]; + newsa[0]=issuerDN; + System.arraycopy(caIssuerDNs, 0, newsa, 1, caIssuerDNs.length); + caIssuerDNs = newsa; + } } protected synchronized void addTrustedCA(final String crtString) { @@ -159,7 +179,7 @@ public abstract class CA { trustedCAs = temp; } - public Set<String> getCaIssuerDNs() { + public String[] getCaIssuerDNs() { return caIssuerDNs; } @@ -209,4 +229,5 @@ public abstract class CA { public CSRMeta newCSRMeta() { return new CSRMeta(rdns); } + } diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/JscepCA.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/JscepCA.java index 0d494acd..3f398381 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/JscepCA.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/JscepCA.java @@ -48,7 +48,7 @@ import org.onap.aaf.cadi.Access; import org.onap.aaf.cadi.LocatorException; import org.onap.aaf.cadi.Access.Level; import org.onap.aaf.cadi.Locator.Item; -import org.onap.aaf.cadi.cm.CertException; +import org.onap.aaf.cadi.configure.CertException; import org.onap.aaf.cadi.locator.HotPeerLocator; import org.onap.aaf.misc.env.Env; import org.onap.aaf.misc.env.TimeTaken; @@ -59,21 +59,21 @@ public class JscepCA extends CA { static final String CA_PREFIX = "http://"; static final String CA_POSTFIX="/certsrv/mscep_admin/mscep.dll"; - private final static String MS_PROFILE="1"; - private final static int MAX_RETRY=3; + private static final String MS_PROFILE="1"; + private static final int MAX_RETRY=3; public static final long INVALIDATE_TIME = 1000*60*10L; // 10 mins // package on purpose - private Map<String,X509ChainWithIssuer> mxcwi_s; - private Map<Client,X509ChainWithIssuer> mxcwi_c; + private Map<String,X509ChainWithIssuer> mxcwiS; + private Map<Client,X509ChainWithIssuer> mxcwiC; private JscepClientLocator clients; public JscepCA(final Access access, final String name, final String env, String [][] params) throws IOException, CertException, LocatorException { super(access, name, env); - mxcwi_s = new ConcurrentHashMap<String,X509ChainWithIssuer>(); - mxcwi_c = new ConcurrentHashMap<Client,X509ChainWithIssuer>(); + mxcwiS = new ConcurrentHashMap<>(); + mxcwiC = new ConcurrentHashMap<>(); if(params.length<2) { throw new CertException("No Trust Chain parameters are included"); @@ -110,7 +110,7 @@ public class JscepCA extends CA { dir = dir + '/'; } String path; - List<FileReader> frs = new ArrayList<FileReader>(params.length-1); + List<FileReader> frs = new ArrayList<>(params.length-1); try { for(int j=1; j<params[i].length; ++j) { // first 3 taken up, see above path = !params[i][j].contains("/")?dir+params[i][j]:params[i][j]; @@ -119,7 +119,7 @@ public class JscepCA extends CA { } X509ChainWithIssuer xcwi = new X509ChainWithIssuer(frs); addCaIssuerDN(xcwi.getIssuerDN()); - mxcwi_s.put(params[i][0],xcwi); + mxcwiS.put(params[i][0],xcwi); } finally { for(FileReader fr : frs) { if(fr!=null) { @@ -173,26 +173,16 @@ public class JscepCA extends CA { break; } } - X509ChainWithIssuer mxcwi = mxcwi_c.get(client); + X509ChainWithIssuer mxcwi = mxcwiC.get(client); return new X509ChainWithIssuer(mxcwi,x509); -// break; + } else if (er.isPending()) { trans.checkpoint("Polling, waiting on CA to complete"); Thread.sleep(3000); } else if (er.isFailure()) { -// switch(er.getFailInfo()) { -// case badMessageCheck: -// throw new ClientException("Received BadMessageCheck from Jscep"); -// case badAlg: -// case badCertId: -// case badRequest: -// case badTime: -// default: -// } throw new CertException(clients.info(item)+':'+er.getFailInfo().toString()); } } - //i=MAX_RETRY; } catch(LocatorException e) { trans.error().log(e); i=MAX_RETRY; @@ -246,7 +236,7 @@ public class JscepCA extends CA { } ); // Map URL to Client, because Client doesn't expose Connection - mxcwi_c.put(c,mxcwi_s.get(urlinfo)); + mxcwiC.put(c, mxcwiS.get(urlinfo)); return c; } catch (MalformedURLException e) { throw new LocatorException(e); @@ -260,7 +250,7 @@ public class JscepCA extends CA { @Override protected void _destroy(Client client) { - mxcwi_c.remove(client); + mxcwiC.remove(client); } 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..af2d2f6b 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 @@ -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,28 +65,33 @@ 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 - + KeyPurposeId.id_kp_clientAuth // WebClient + }; + private final PrivateKey caKey; private final X500Name issuer; private final SecureRandom random = new SecureRandom(); - private byte[] serialish; + 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); - serialish = new byte[24]; + + serial = new BigInteger(64,random); + if(params.length<1 || params[0].length<2) { throw new IOException("LocalCA expects cm_ca.<ca name>=org.onap.aaf.auth.cm.ca.LocalCA,<full path to key file>[;<Full Path to Trust Chain, ending with actual CA>]+"); } @@ -97,7 +103,7 @@ public class LocalCA extends CA { String fileName = f.getName(); if(fileName.endsWith(".key")) { caKey = Factory.toPrivateKey(NullTrans.singleton(),f); - List<FileReader> frs = new ArrayList<FileReader>(params.length-1); + List<FileReader> frs = new ArrayList<>(params.length-1); try { String dir = access.getProperty(CM_PUBLIC_DIR, ""); if(!"".equals(dir) && !dir.endsWith("/")) { @@ -128,8 +134,8 @@ public class LocalCA extends CA { KeyStore keyStore; FileInputStream fis = null; if(fileName.endsWith(".pkcs11")) { - String ksType; - p = Factory.getSecurityProvider(ksType="PKCS11",params); + String ksType="PKCS11"; + p = Factory.getSecurityProvider(ksType,params); keyStore = KeyStore.getInstance(ksType,p); } else if(fileName.endsWith(".jks")) { keyStore = KeyStore.getInstance("JKS"); @@ -180,7 +186,9 @@ public class LocalCA extends CA { } X500NameBuilder xnb = new X500NameBuilder(); - for(RDN rnd : RDN.parse(',', x509cwi.getIssuerDN())) { + List<RDN> rp = RDN.parse(',', x509cwi.getIssuerDN()); + Collections.reverse(rp); + for(RDN rnd : rp) { xnb.addRDN(rnd.aoi,rnd.value); } issuer = xnb.build(); @@ -201,9 +209,10 @@ public class LocalCA extends CA { TimeTaken tt = trans.start("Create/Sign Cert",Env.SUB); try { BigInteger bi; - synchronized(serialish) { - random.nextBytes(serialish); - bi = new BigInteger(serialish); + + synchronized(ONE) { + bi = serial; + serial = serial.add(ONE); } RSAPublicKey rpk = (RSAPublicKey)csrmeta.keypair(trans).getPublic(); @@ -216,7 +225,7 @@ public class LocalCA extends CA { SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(new RSAKeyParameters(false,rpk.getModulus(),rpk.getPublicExponent())) // new SubjectPublicKeyInfo(ASN1Sequence.getInstance(caCert.getPublicKey().getEncoded())) ); - List<GeneralName> lsan = new ArrayList<GeneralName>(); + List<GeneralName> lsan = new ArrayList<>(); for(String s : csrmeta.sans()) { lsan.add(new GeneralName(GeneralName.dNSName,s)); } @@ -225,20 +234,23 @@ public class LocalCA extends CA { JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); xcb.addExtension(Extension.basicConstraints, - false, new BasicConstraints(false)) + false, new BasicConstraints(false + )) .addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature - | KeyUsage.keyEncipherment)) + | 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())) + 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))); @@ -248,7 +260,7 @@ public class LocalCA extends CA { tt.done(); } - return new X509ChainWithIssuer(x509cwi,x509); + return new X509andChain(x509,x509cwi.trustChain); } } 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 6f3062bb..e31b9988 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 @@ -29,13 +29,14 @@ import java.security.cert.X509Certificate; import java.util.Collection; import java.util.List; -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; public class X509ChainWithIssuer extends X509andChain { private String issuerDN; + public X509Certificate caX509; - public X509ChainWithIssuer(X509ChainWithIssuer orig, X509Certificate x509) { + public X509ChainWithIssuer(X509ChainWithIssuer orig, X509Certificate x509) throws IOException, CertException { super(x509,orig.trustChain); issuerDN=orig.issuerDN; } @@ -45,39 +46,42 @@ public class X509ChainWithIssuer extends X509andChain { Collection<? extends Certificate> certs; X509Certificate x509; for(Reader rdr : rdrs) { - if(rdr!=null) { // cover for badly formed array - byte[] bytes = Factory.decode(rdr); - try { - certs = Factory.toX509Certificate(bytes); - } catch (CertificateException e) { - throw new CertException(e); + if(rdr==null) { // cover for badly formed array + continue; + } + + byte[] bytes = Factory.decode(rdr,null); + try { + certs = Factory.toX509Certificate(bytes); + } catch (CertificateException e) { + throw new CertException(e); + } + for(Certificate c : certs) { + x509=(X509Certificate)c; + Principal subject = x509.getSubjectDN(); + if(subject==null) { + continue; } - 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. - } + if(cert==null) { // first in Trust Chain + issuerDN = subject.toString(); + cert=x509; // adding each time makes sure last one is signer. } + addTrustChainEntry(x509); } } } public X509ChainWithIssuer(Certificate[] certs) throws IOException, CertException { X509Certificate x509; - for(Certificate c : certs) { - x509=(X509Certificate)c; + for(int i=certs.length-1; i>=0; --i) { + x509=(X509Certificate)certs[i]; 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. + if(i==0) { // last one is signer + cert=x509; + issuerDN= subject.toString(); + } } } } diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/X509andChain.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/X509andChain.java index 46a6393a..5141cc62 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/X509andChain.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/X509andChain.java @@ -25,8 +25,8 @@ import java.security.cert.X509Certificate; import java.util.List; import org.onap.aaf.auth.env.NullTrans; -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; /** @@ -45,14 +45,14 @@ public class X509andChain { trustChain = null; } - public X509andChain(X509Certificate cert, String[] trustChain) { + public X509andChain(X509Certificate cert, String[] tc) throws IOException, CertException { this.cert = cert; - this.trustChain = trustChain; + trustChain=tc; } - public X509andChain(X509Certificate cert, List<String> chain) { + public X509andChain(X509Certificate cert, List<String> chain) throws IOException, CertException { this.cert = cert; - trustChain = new String[chain.size()]; + trustChain = new String[chain.size()+1]; chain.toArray(trustChain); } @@ -67,6 +67,7 @@ public class X509andChain { trustChain=temp; } } + public X509Certificate getX509() { return cert; diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/BCFactory.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/BCFactory.java index 7f4590f3..70ddd438 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/BCFactory.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/BCFactory.java @@ -37,8 +37,8 @@ import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.onap.aaf.auth.cm.ca.CA; import org.onap.aaf.auth.cm.validation.CertmanValidator; import org.onap.aaf.cadi.Symm; -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; diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/CSRMeta.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/CSRMeta.java index 2541bea0..7d417d5f 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/CSRMeta.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/CSRMeta.java @@ -49,8 +49,8 @@ import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; -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.Trans; public class CSRMeta { @@ -60,17 +60,16 @@ public class CSRMeta { private String email; private String challenge; private List<RDN> rdns; - - public CSRMeta(List<RDN> rdns) { - this.rdns = rdns; - } - - private ArrayList<String> sanList = new ArrayList<String>(); + private ArrayList<String> sanList = new ArrayList<>(); private KeyPair keyPair; private X500Name name = null; private SecureRandom random = new SecureRandom(); - public X500Name x500Name() throws IOException { + public CSRMeta(List<RDN> rdns) { + this.rdns = rdns; + } + + public X500Name x500Name() { if(name==null) { X500NameBuilder xnb = new X500NameBuilder(); xnb.addRDN(BCStyle.CN,cn); @@ -99,7 +98,7 @@ public class CSRMeta { } int plus = email==null?0:1; - if(sanList.size()>0) { + if(!sanList.isEmpty()) { GeneralName[] gna = new GeneralName[sanList.size()+plus]; int i=-1; for(String s : sanList) { @@ -114,10 +113,7 @@ public class CSRMeta { }) ); } - - if(email!=null) { - - } + try { return builder.build(BCFactory.contentSigner(keypair(trans).getPrivate())); } catch (OperatorCreationException e) { @@ -129,27 +125,29 @@ public class CSRMeta { public static void dump(PKCS10CertificationRequest csr) { Attribute[] certAttributes = csr.getAttributes(); for (Attribute attribute : certAttributes) { - if (attribute.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) { - Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0)); - GeneralNames gns = GeneralNames.fromExtensions(extensions,Extension.subjectAlternativeName); - GeneralName[] names = gns.getNames(); - for(int k=0; k < names.length; k++) { - String title = ""; - if(names[k].getTagNo() == GeneralName.dNSName) { - title = "dNSName"; - } else if(names[k].getTagNo() == GeneralName.iPAddress) { - title = "iPAddress"; - // Deprecated, but I don't see anything better to use. - names[k].toASN1Object(); - } else if(names[k].getTagNo() == GeneralName.otherName) { - title = "otherName"; - } else if(names[k].getTagNo() == GeneralName.rfc822Name) { - title = "email"; - } + if (!attribute.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) { + continue; + } + + Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0)); + GeneralNames gns = GeneralNames.fromExtensions(extensions,Extension.subjectAlternativeName); + GeneralName[] names = gns.getNames(); + for(int k=0; k < names.length; k++) { + String title = ""; + if(names[k].getTagNo() == GeneralName.dNSName) { + title = "dNSName"; + } else if(names[k].getTagNo() == GeneralName.iPAddress) { + title = "iPAddress"; + // Deprecated, but I don't see anything better to use. + names[k].toASN1Object(); + } else if(names[k].getTagNo() == GeneralName.otherName) { + title = "otherName"; + } else if(names[k].getTagNo() == GeneralName.rfc822Name) { + title = "email"; + } - System.out.println(title + ": "+ names[k].getName()); - } - } + System.out.println(title + ": "+ names[k].getName()); + } } } diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/RDN.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/RDN.java index 5b55f1ca..b109ffcb 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/RDN.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/cert/RDN.java @@ -25,7 +25,7 @@ import java.util.List; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x500.style.BCStyle; -import org.onap.aaf.cadi.cm.CertException; +import org.onap.aaf.cadi.configure.CertException; import org.onap.aaf.cadi.util.Split; public class RDN { @@ -66,7 +66,7 @@ public class RDN { * @throws CertException */ public static List<RDN> parse(final char delim, final String dnString ) throws CertException { - List<RDN> lrnd = new ArrayList<RDN>(); + List<RDN> lrnd = new ArrayList<>(); StringBuilder sb = new StringBuilder(); boolean inQuotes = false; for(int i=0;i<dnString.length();++i) { diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/data/CertReq.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/data/CertReq.java index aa0b9c26..d960945c 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/data/CertReq.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/data/CertReq.java @@ -28,7 +28,7 @@ import javax.xml.datatype.XMLGregorianCalendar; import org.onap.aaf.auth.cm.ca.CA; import org.onap.aaf.auth.cm.cert.BCFactory; import org.onap.aaf.auth.cm.cert.CSRMeta; -import org.onap.aaf.cadi.cm.CertException; +import org.onap.aaf.cadi.configure.CertException; public class CertReq { // These cannot be null diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/data/CertResp.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/data/CertResp.java index 595025e7..970bfb85 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/data/CertResp.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/data/CertResp.java @@ -25,12 +25,11 @@ import java.io.IOException; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.cert.X509Certificate; -import java.util.Set; import org.onap.aaf.auth.cm.ca.CA; import org.onap.aaf.auth.cm.cert.CSRMeta; -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.Trans; public class CertResp { @@ -40,17 +39,15 @@ public class CertResp { private String privateKey, certString; private String[] trustChain; - private String[] trustCAs; private String[] notes; - public CertResp(Trans trans, CA ca, X509Certificate x509, CSRMeta csrMeta, String[] trustChain, String[] trustCAs, String[] notes) throws IOException, GeneralSecurityException, CertException { + public CertResp(Trans trans, CA ca, X509Certificate x509, CSRMeta csrMeta, String[] trustChain, String[] notes) throws IOException, GeneralSecurityException, CertException { keyPair = csrMeta.keypair(trans); privateKey = Factory.toString(trans, keyPair.getPrivate()); certString = Factory.toString(trans,x509); challenge=csrMeta.challenge(); this.ca = ca; this.trustChain = trustChain; - this.trustCAs = trustCAs; this.notes = notes; } @@ -76,7 +73,7 @@ public class CertResp { return notes; } - public Set<String> caIssuerDNs() { + public String[] caIssuerDNs() { return ca.getCaIssuerDNs(); } @@ -89,6 +86,6 @@ public class CertResp { } public String[] trustCAs() { - return trustCAs; + return ca.getTrustedCAs(); } } diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java index 0598ee60..794f63a6 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java @@ -58,8 +58,8 @@ import org.onap.aaf.auth.env.AuthzEnv; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.auth.layer.Result; import org.onap.aaf.cadi.aaf.AAFPermission; -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.APIException; import org.onap.aaf.misc.env.Data; import org.onap.aaf.misc.env.Env; @@ -365,7 +365,7 @@ public abstract class FacadeImpl<REQ,CERT,ARTIFACTS,ERROR> extends org.onap.aaf. jks.load(null, cap); // Get the Cert(s)... Might include Trust store - List<String> lcerts = new ArrayList<String>(); + List<String> lcerts = new ArrayList<>(); lcerts.add(cr.asCertString()); for(String s : trustChain) { lcerts.add(s); diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper1_0.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper1_0.java index 3d865d30..c06734f4 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper1_0.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper1_0.java @@ -31,8 +31,8 @@ import org.onap.aaf.auth.cm.data.CertReq; import org.onap.aaf.auth.cm.data.CertResp; import org.onap.aaf.auth.cm.validation.CertmanValidator; import org.onap.aaf.auth.dao.cass.ArtiDAO; -import org.onap.aaf.auth.dao.cass.CertDAO; import org.onap.aaf.auth.dao.cass.ArtiDAO.Data; +import org.onap.aaf.auth.dao.cass.CertDAO; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.auth.layer.Result; import org.onap.aaf.cadi.util.FQI; @@ -97,50 +97,59 @@ public class Mapper1_0 implements Mapper<BaseRequest,CertInfo,Artifacts,Error> { */ @Override public Result<CertInfo> toCert(AuthzTrans trans, Result<CertResp> in, boolean withTrustChain) throws IOException { - if(in.isOK()) { - CertResp cin = in.value; - CertInfo cout = newInstance(API.CERT); - cout.setPrivatekey(cin.privateString()); - String value; - if((value=cin.challenge())!=null) { - cout.setChallenge(value); - } - cout.getCerts().add(cin.asCertString()); - if(cin.trustChain()!=null) { - for(String c : cin.trustChain()) { - if(c!=null) { - cout.getCerts().add(c); - } + if(!in.isOK()) { + return Result.err(in); + } + + CertResp cin = in.value; + CertInfo cout = newInstance(API.CERT); + cout.setPrivatekey(cin.privateString()); + String value; + if((value=cin.challenge())!=null) { + cout.setChallenge(value); + } + // In Version 1, Cert is always first + cout.getCerts().add(cin.asCertString()); + // Follow with Trust Chain + if(cin.trustChain()!=null) { + for(String c : cin.trustChain()) { + if(c!=null) { + cout.getCerts().add(c); } } - // Adding all the Certs in one response is a mistake. Makes it very hard for Agent to setup - // Certs in keystore versus Truststore. Separate in Version 2_0 - if(cin.trustCAs()!=null) { - for(String c : cin.trustCAs()) { - if(c!=null) { + } + + // Adding all the Certs in one response is a mistake. Makes it very hard for Agent to setup + // Certs in keystore versus Truststore. Separate in Version 2_0 + if(cin.trustCAs()!=null) { + for(String c : cin.trustCAs()) { + if(c!=null) { + if(!cout.getCerts().contains(c)) { cout.getCerts().add(c); - } + } } } - if(cin.notes()!=null) { - boolean first = true; - StringBuilder sb = new StringBuilder(); - for(String n : cin.notes()) { - if(first) { - first = false; - } else { - sb.append('\n'); - } - sb.append(n); + } + if(cin.notes()!=null) { + boolean first = true; + StringBuilder sb = new StringBuilder(); + for(String n : cin.notes()) { + if(first) { + first = false; + } else { + sb.append('\n'); } - cout.setNotes(sb.toString()); + sb.append(n); } - cout.getCaIssuerDNs().addAll(cin.caIssuerDNs()); - cout.setEnv(cin.env()); - return Result.ok(cout); - } else { - return Result.err(in); + cout.setNotes(sb.toString()); + } + List<String> caIssuerDNs = cout.getCaIssuerDNs(); + for(String s : cin.caIssuerDNs()) { + caIssuerDNs.add(s); } + cout.setEnv(cin.env()); + return Result.ok(cout); + } @Override @@ -171,9 +180,10 @@ public class Mapper1_0 implements Mapper<BaseRequest,CertInfo,Artifacts,Error> { CertReq out = new CertReq(); CertmanValidator v = new CertmanValidator(); - v.isNull("CertRequest", req) - .nullOrBlank("MechID", out.mechid=in.getMechid()); - v.nullBlankMin("FQDNs", out.fqdns=in.getFqdns(),1); + out.mechid=in.getMechid(); + out.fqdns=in.getFqdns(); + v.isNull("CertRequest", req).nullOrBlank("MechID", out.mechid); + v.nullBlankMin("FQDNs", out.fqdns,1); if(v.err()) { return Result.err(Result.ERR_BadData, v.errs()); } @@ -206,7 +216,7 @@ public class Mapper1_0 implements Mapper<BaseRequest,CertInfo,Artifacts,Error> { */ @Override public List<ArtiDAO.Data> toArtifact(AuthzTrans trans, Artifacts artifacts) { - List<ArtiDAO.Data> ladd = new ArrayList<ArtiDAO.Data>(); + List<ArtiDAO.Data> ladd = new ArrayList<>(); for(Artifact arti : artifacts.getArtifact()) { ArtiDAO.Data data = new ArtiDAO.Data(); data.mechid = arti.getMechid(); @@ -226,10 +236,8 @@ public class Mapper1_0 implements Mapper<BaseRequest,CertInfo,Artifacts,Error> { // Derive Optional Data from Machine (Domain) if exists if(data.machine!=null) { - if(data.ca==null) { - if(data.machine.endsWith(".att.com")) { + if(data.ca==null && data.machine.endsWith(".att.com")) { data.ca = "aaf"; // default - } } if(data.ns==null ) { data.ns=FQI.reverseDomain(data.machine); diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper2_0.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper2_0.java index a5e831ed..23a0c543 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper2_0.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper2_0.java @@ -127,7 +127,12 @@ public class Mapper2_0 implements Mapper<BaseRequest,CertInfo,Artifacts,Error> { } cout.setNotes(sb.toString()); } - cout.getCaIssuerDNs().addAll(cin.caIssuerDNs()); + + List<String> caIssuerDNs = cout.getCaIssuerDNs(); + for(String s : cin.caIssuerDNs()) { + caIssuerDNs.add(s); + } + cout.setEnv(cin.env()); return Result.ok(cout); } else { @@ -200,7 +205,7 @@ public class Mapper2_0 implements Mapper<BaseRequest,CertInfo,Artifacts,Error> { */ @Override public List<ArtiDAO.Data> toArtifact(AuthzTrans trans, Artifacts artifacts) { - List<ArtiDAO.Data> ladd = new ArrayList<ArtiDAO.Data>(); + List<ArtiDAO.Data> ladd = new ArrayList<>(); for(Artifact arti : artifacts.getArtifact()) { ArtiDAO.Data data = new ArtiDAO.Data(); data.mechid = arti.getMechid(); diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java index 4ef5472a..dee788e4 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java @@ -59,7 +59,7 @@ import org.onap.aaf.auth.org.Organization.Identity; import org.onap.aaf.auth.org.OrganizationException; import org.onap.aaf.cadi.Hash; import org.onap.aaf.cadi.aaf.AAFPermission; -import org.onap.aaf.cadi.cm.Factory; +import org.onap.aaf.cadi.configure.Factory; import org.onap.aaf.cadi.util.FQI; import org.onap.aaf.misc.env.APIException; import org.onap.aaf.misc.env.util.Chrono; @@ -125,7 +125,7 @@ public class CMService { } List<String> notes = null; - List<String> fqdns = new ArrayList<String>(req.value.fqdns); + List<String> fqdns = new ArrayList<>(req.value.fqdns); String email = null; @@ -161,7 +161,7 @@ public class CMService { for(String cn : req.value.fqdns) { try { InetAddress[] ias = InetAddress.getAllByName(cn); - Set<String> potentialSanNames = new HashSet<String>(); + Set<String> potentialSanNames = new HashSet<>(); for(InetAddress ia1 : ias) { InetAddress ia2 = InetAddress.getByAddress(ia1.getAddress()); if(primary==null && ias.length==1 && trans.ip().equals(ia1.getHostAddress())) { @@ -261,7 +261,7 @@ public class CMService { // } // }, // new AAFPermission(ca.getPermType(), ca.getName(), SANS))) { -// if(notes==null) {notes = new ArrayList<String>();} +// if(notes==null) {notes = new ArrayList<>();} // notes.add("Warning: Subject Alternative Names only allowed by Permission: Get CSO Exception."); // return Result.err(Status.ERR_Denied, "%s must have a CSO Exception to work with SAN",trans.user()); // } @@ -317,7 +317,7 @@ public class CMService { crdd.type = CredDAO.CERT_SHA256_RSA; credDAO.create(trans, crdd); - CertResp cr = new CertResp(trans, ca, x509, csrMeta, x509ac.getTrustChain(), ca.getTrustedCAs(), compileNotes(notes)); + CertResp cr = new CertResp(trans, ca, x509, csrMeta, x509ac.getTrustChain(),compileNotes(notes)); return Result.ok(cr); } catch (Exception e) { trans.error().log(e); @@ -398,7 +398,7 @@ public class CMService { cdd.x509=Factory.toString(trans, x509); certDAO.create(trans, cdd); - CertResp cr = new CertResp(trans, ca, x509, csrMeta, x509ac.getTrustChain(), ca.getTrustedCAs(), compileNotes(null)); + CertResp cr = new CertResp(trans, ca, x509, csrMeta, x509ac.getTrustChain(), compileNotes(null)); return Result.ok(cr); } catch (Exception e) { trans.error().log(e); @@ -426,17 +426,24 @@ public class CMService { } // Policy 2: MechID must have valid Organization Owner - Identity ouser = muser.responsibleTo(); - if(ouser == null) { - return Result.err(Result.ERR_Denied,"%s is not a valid Sponsor for %s at %s", - trans.user(),add.mechid,trans.org().getName()); + Identity emailUser; + if(muser.isPerson()) { + emailUser = muser; + } else { + Identity ouser = muser.responsibleTo(); + if(ouser == null) { + return Result.err(Result.ERR_Denied,"%s is not a valid Sponsor for %s at %s", + trans.user(),add.mechid,trans.org().getName()); + } + + // Policy 3: Calling ID must be MechID Owner + if(!trans.user().equals(ouser.fullID())) { + return Result.err(Result.ERR_Denied,"%s is not the Sponsor for %s at %s", + trans.user(),add.mechid,trans.org().getName()); + } + emailUser = ouser; } - // Policy 3: Calling ID must be MechID Owner - if(!trans.user().equals(ouser.fullID())) { - return Result.err(Result.ERR_Denied,"%s is not the Sponsor for %s at %s", - trans.user(),add.mechid,trans.org().getName()); - } // Policy 4: Renewal Days are between 10 and 60 (constants, may be parameterized) if(add.renewDays<MIN_RENEWAL) { @@ -447,7 +454,7 @@ public class CMService { // Policy 5: If Notify is blank, set to Owner's Email if(add.notify==null || add.notify.length()==0) { - add.notify = "mailto:"+ouser.email(); + add.notify = "mailto:"+emailUser.email(); } // Policy 6: Only do Domain by Exception @@ -462,7 +469,7 @@ public class CMService { } // Set Sponsor from Golden Source - add.sponsor = ouser.fullID(); + add.sponsor = emailUser.fullID(); } catch (OrganizationException e) { diff --git a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/ca/JU_AppCA.java b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/ca/JU_AppCA.java index f6d5cab1..1ab0f4bd 100644 --- a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/ca/JU_AppCA.java +++ b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/ca/JU_AppCA.java @@ -52,10 +52,9 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; -import org.onap.aaf.auth.cm.ca.CA; import org.onap.aaf.auth.cm.cert.CSRMeta; import org.onap.aaf.auth.dao.cached.CachedCertDAO; -import org.onap.aaf.cadi.cm.CertException; +import org.onap.aaf.cadi.configure.CertException; import org.onap.aaf.misc.env.Trans; //TODO: Gabe [JUnit] Import does not exist @@ -243,7 +242,7 @@ public class JU_AppCA { } }; - X509andChain xac = new X509andChain(cert, new ArrayList<String>()); + X509andChain xac = new X509andChain(cert, new ArrayList<>()); when(localCA.sign(Mockito.any(Trans.class), Mockito.any(CSRMeta.class))).thenReturn(xac); certDAO = mock(CachedCertDAO.class, CALLS_REAL_METHODS); } diff --git a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/cert/JU_BCFactory.java b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/cert/JU_BCFactory.java index 856d09c2..337bc9ed 100644 --- a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/cert/JU_BCFactory.java +++ b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/cert/JU_BCFactory.java @@ -41,7 +41,7 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; -import org.onap.aaf.cadi.cm.CertException; +import org.onap.aaf.cadi.configure.CertException; import org.onap.aaf.misc.env.TimeTaken; import org.onap.aaf.misc.env.Trans; diff --git a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/test/CertmanTest.java b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/test/CertmanTest.java index 7d3f25ca..5ec96f25 100644 --- a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/test/CertmanTest.java +++ b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/test/CertmanTest.java @@ -41,8 +41,8 @@ import org.onap.aaf.cadi.Locator.Item; import org.onap.aaf.cadi.client.Future; import org.onap.aaf.cadi.client.Rcli; import org.onap.aaf.cadi.client.Retryable; -import org.onap.aaf.cadi.cm.Factory; import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.configure.Factory; import org.onap.aaf.cadi.http.HBasicAuthSS; import org.onap.aaf.cadi.http.HMangr; import org.onap.aaf.cadi.locator.DNSLocator; |