04ba0b896cc2e18d328eab0a3f199344e0bf66c5
[aaf/authz.git] / auth / auth-certman / src / main / java / org / onap / aaf / auth / cm / cert / CSRMeta.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  *
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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====================================================
21  *
22  */
23 package org.onap.aaf.auth.cm.cert;
24
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;
35
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;
57
58 public class CSRMeta {
59     private String cn;
60     private String mechID;
61     private String environment;
62     private String email;
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();
69
70     public CSRMeta(List<RDN> rdns) {
71         this.rdns = rdns;
72     }
73
74     public X500Name x500Name() {
75         if (name==null) {
76             X500NameBuilder xnb = new X500NameBuilder();
77             xnb.addRDN(BCStyle.CN,cn);
78             xnb.addRDN(BCStyle.E,email);
79             if (mechID!=null) {
80                 if (environment==null) {
81                     xnb.addRDN(BCStyle.OU,mechID);
82                 } else {
83                     xnb.addRDN(BCStyle.OU,mechID+':'+environment);
84                 }
85             }
86             for (RDN rdn : rdns) {
87                 xnb.addRDN(rdn.aoi,rdn.value);
88             }
89             name = xnb.build();
90         }
91         return name;
92     }
93
94
95     public PKCS10CertificationRequest  generateCSR(Trans trans) throws IOException, CertException {
96         PKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder(x500Name(),keypair(trans).getPublic());
97         if (challenge!=null) {
98             DERPrintableString password = new DERPrintableString(challenge);
99             builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_challengePassword, password);
100         }
101
102         int plus = email==null?0:1;
103         if (!sanList.isEmpty()) {
104             GeneralName[] gna = new GeneralName[sanList.size()+plus];
105             int i=-1;
106             for (String s : sanList) {
107                 gna[++i]=new GeneralName(GeneralName.dNSName,s);
108             }
109             gna[++i]=new GeneralName(GeneralName.rfc822Name,email);
110
111             builder.addAttribute(
112                     PKCSObjectIdentifiers.pkcs_9_at_extensionRequest,
113                     new Extensions(new Extension[] {
114                             new Extension(Extension.subjectAlternativeName,false,new GeneralNames(gna).getEncoded())
115                     })
116             );
117         }
118
119         try {
120             return builder.build(BCFactory.contentSigner(keypair(trans).getPrivate()));
121         } catch (OperatorCreationException e) {
122             throw new CertException(e);
123         }
124     }
125
126     @SuppressWarnings("deprecation")
127     public static void dump(PKCS10CertificationRequest csr) {
128          Attribute[] certAttributes = csr.getAttributes();
129          for (Attribute attribute : certAttributes) {
130              if (!attribute.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) {
131                      continue;
132                  }
133
134                  Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0));
135                  GeneralNames gns = GeneralNames.fromExtensions(extensions,Extension.subjectAlternativeName);
136                  GeneralName[] names = gns.getNames();
137                  for (int k=0; k < names.length; k++) {
138                          String title = "";
139                          if (names[k].getTagNo() == GeneralName.dNSName) {
140                                  title = "dNSName";
141                          } else if (names[k].getTagNo() == GeneralName.iPAddress) {
142                                  title = "iPAddress";
143                                  // Deprecated, but I don't see anything better to use.
144                                  names[k].toASN1Object();
145                          } else if (names[k].getTagNo() == GeneralName.otherName) {
146                                  title = "otherName";
147                          } else if (names[k].getTagNo() == GeneralName.rfc822Name) {
148                                  title = "email";
149                          }
150
151                          System.out.println(title + ": "+ names[k].getName());
152                  }
153          }
154     }
155
156     public X509Certificate initialConversationCert(Trans trans) throws CertificateException, OperatorCreationException {
157         GregorianCalendar gc = new GregorianCalendar();
158         Date start = gc.getTime();
159         gc.add(GregorianCalendar.DAY_OF_MONTH,2);
160         Date end = gc.getTime();
161         @SuppressWarnings("deprecation")
162         X509v3CertificateBuilder xcb = new X509v3CertificateBuilder(
163                 x500Name(),
164                 new BigInteger(12,random), // replace with Serialnumber scheme
165                 start,
166                 end,
167                 x500Name(),
168                 new SubjectPublicKeyInfo(ASN1Sequence.getInstance(keypair(trans).getPublic().getEncoded()))
169                 );
170         return new JcaX509CertificateConverter().getCertificate(
171                 xcb.build(BCFactory.contentSigner(keypair(trans).getPrivate())));
172     }
173
174     public CSRMeta san(String v) {
175         sanList.add(v);
176         return this;
177     }
178
179     public List<String> sans() {
180         return sanList;
181     }
182
183
184     public KeyPair keypair(Trans trans) {
185         if (keyPair == null) {
186             keyPair = Factory.generateKeyPair(trans);
187         }
188         return keyPair;
189     }
190
191     /**
192      * @return the cn
193      */
194     public String cn() {
195         return cn;
196     }
197
198
199     /**
200      * @param cn the cn to set
201      */
202     public void cn(String cn) {
203         this.cn = cn;
204     }
205
206     /**
207      * Environment of Service MechID is good for
208      */
209     public void environment(String env) {
210         environment = env;
211     }
212
213     /**
214      *
215      * @return
216      */
217     public String environment() {
218         return environment;
219     }
220
221     /**
222      * @return the mechID
223      */
224     public String mechID() {
225         return mechID;
226     }
227
228
229     /**
230      * @param mechID the mechID to set
231      */
232     public void mechID(String mechID) {
233         this.mechID = mechID;
234     }
235
236
237     /**
238      * @return the email
239      */
240     public String email() {
241         return email;
242     }
243
244
245     /**
246      * @param email the email to set
247      */
248     public void email(String email) {
249         this.email = email;
250     }
251
252     /**
253      * @return the challenge
254      */
255     public String challenge() {
256         return challenge;
257     }
258
259
260     /**
261      * @param challenge the challenge to set
262      */
263     public void challenge(String challenge) {
264         this.challenge = challenge;
265     }
266
267 }