2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
7 * Modifications Copyright (C) 2019 IBM.
8 * ===========================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END====================================================
23 package org.onap.aaf.auth.cm.cert;
25 import java.io.IOException;
26 import java.math.BigInteger;
27 import java.security.KeyPair;
28 import java.security.SecureRandom;
29 import java.security.cert.CertificateException;
30 import java.security.cert.X509Certificate;
31 import java.util.ArrayList;
32 import java.util.Date;
33 import java.util.GregorianCalendar;
34 import java.util.List;
36 import org.bouncycastle.asn1.ASN1Sequence;
37 import org.bouncycastle.asn1.DERPrintableString;
38 import org.bouncycastle.asn1.pkcs.Attribute;
39 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
40 import org.bouncycastle.asn1.x500.X500Name;
41 import org.bouncycastle.asn1.x500.X500NameBuilder;
42 import org.bouncycastle.asn1.x500.style.BCStyle;
43 import org.bouncycastle.asn1.x509.Extension;
44 import org.bouncycastle.asn1.x509.Extensions;
45 import org.bouncycastle.asn1.x509.GeneralName;
46 import org.bouncycastle.asn1.x509.GeneralNames;
47 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
48 import org.bouncycastle.cert.X509v3CertificateBuilder;
49 import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
50 import org.bouncycastle.operator.OperatorCreationException;
51 import org.bouncycastle.pkcs.PKCS10CertificationRequest;
52 import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
53 import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
54 import org.onap.aaf.cadi.configure.CertException;
55 import org.onap.aaf.cadi.configure.Factory;
56 import org.onap.aaf.misc.env.Trans;
58 public class CSRMeta {
60 private String mechID;
61 private String environment;
63 private String challenge;
64 private List<RDN> rdns;
65 private ArrayList<String> sanList = new ArrayList<>();
66 private KeyPair keyPair;
67 private X500Name name = null;
68 private SecureRandom random = new SecureRandom();
70 public CSRMeta(List<RDN> rdns) {
74 public X500Name x500Name() {
76 X500NameBuilder xnb = new X500NameBuilder();
77 xnb.addRDN(BCStyle.CN,cn);
78 // Add as Subject Alternate Name, email
79 // xnb.addRDN(BCStyle.E,email);
81 if (environment==null) {
82 xnb.addRDN(BCStyle.OU,mechID);
84 xnb.addRDN(BCStyle.OU,mechID+':'+environment);
87 for (RDN rdn : rdns) {
88 xnb.addRDN(rdn.aoi,rdn.value);
96 public PKCS10CertificationRequest generateCSR(Trans trans) throws IOException, CertException {
97 PKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder(x500Name(),keypair(trans).getPublic());
98 if (challenge!=null) {
99 DERPrintableString password = new DERPrintableString(challenge);
100 builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_challengePassword, password);
103 int plus = email==null?0:1;
104 if (!sanList.isEmpty()) {
105 GeneralName[] gna = new GeneralName[sanList.size()+plus];
107 for (String s : sanList) {
108 gna[++i]=new GeneralName(GeneralName.dNSName,s);
110 gna[++i]=new GeneralName(GeneralName.rfc822Name,email);
112 builder.addAttribute(
113 PKCSObjectIdentifiers.pkcs_9_at_extensionRequest,
114 new Extensions(new Extension[] {
115 new Extension(Extension.subjectAlternativeName,false,new GeneralNames(gna).getEncoded())
121 return builder.build(BCFactory.contentSigner(keypair(trans).getPrivate()));
122 } catch (OperatorCreationException e) {
123 throw new CertException(e);
127 @SuppressWarnings("deprecation")
128 public static void dump(PKCS10CertificationRequest csr) {
129 Attribute[] certAttributes = csr.getAttributes();
130 for (Attribute attribute : certAttributes) {
131 if (!attribute.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) {
135 Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0));
136 GeneralNames gns = GeneralNames.fromExtensions(extensions,Extension.subjectAlternativeName);
137 GeneralName[] names = gns.getNames();
138 for (int k=0; k < names.length; k++) {
140 if (names[k].getTagNo() == GeneralName.dNSName) {
142 } else if (names[k].getTagNo() == GeneralName.iPAddress) {
144 // Deprecated, but I don't see anything better to use.
145 names[k].toASN1Object();
146 } else if (names[k].getTagNo() == GeneralName.otherName) {
148 } else if (names[k].getTagNo() == GeneralName.rfc822Name) {
152 System.out.println(title + ": "+ names[k].getName());
157 public X509Certificate initialConversationCert(Trans trans) throws CertificateException, OperatorCreationException {
158 GregorianCalendar gc = new GregorianCalendar();
159 Date start = gc.getTime();
160 gc.add(GregorianCalendar.DAY_OF_MONTH,2);
161 Date end = gc.getTime();
162 @SuppressWarnings("deprecation")
163 X509v3CertificateBuilder xcb = new X509v3CertificateBuilder(
165 new BigInteger(12,random), // replace with Serialnumber scheme
169 new SubjectPublicKeyInfo(ASN1Sequence.getInstance(keypair(trans).getPublic().getEncoded()))
171 return new JcaX509CertificateConverter().getCertificate(
172 xcb.build(BCFactory.contentSigner(keypair(trans).getPrivate())));
175 public CSRMeta san(String v) {
180 public List<String> sans() {
185 public KeyPair keypair(Trans trans) {
186 if (keyPair == null) {
187 keyPair = Factory.generateKeyPair(trans);
201 * @param cn the cn to set
203 public void cn(String cn) {
208 * Environment of Service MechID is good for
210 public void environment(String env) {
218 public String environment() {
225 public String mechID() {
231 * @param mechID the mechID to set
233 public void mechID(String mechID) {
234 this.mechID = mechID;
241 public String email() {
247 * @param email the email to set
249 public void email(String email) {
254 * @return the challenge
256 public String challenge() {
262 * @param challenge the challenge to set
264 public void challenge(String challenge) {
265 this.challenge = challenge;