Update AAF Version 1.0.0
[aaf/authz.git] / authz-certman / src / main / java / com / att / authz / cm / cert / BCFactory.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package com.att.authz.cm.cert;\r
24 \r
25 import java.io.File;\r
26 import java.io.FileReader;\r
27 import java.io.IOException;\r
28 import java.lang.reflect.Field;\r
29 import java.security.InvalidKeyException;\r
30 import java.security.NoSuchAlgorithmException;\r
31 import java.security.PrivateKey;\r
32 import java.security.SignatureException;\r
33 import java.util.List;\r
34 \r
35 import org.bouncycastle.asn1.ASN1Object;\r
36 import org.bouncycastle.operator.ContentSigner;\r
37 import org.bouncycastle.operator.OperatorCreationException;\r
38 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;\r
39 import org.bouncycastle.pkcs.PKCS10CertificationRequest;\r
40 \r
41 import com.att.authz.cm.ca.CA;\r
42 import com.att.authz.cm.validation.Validator;\r
43 import com.att.cadi.Symm;\r
44 import com.att.cadi.cm.CertException;\r
45 import com.att.cadi.cm.Factory;\r
46 import com.att.inno.env.Env;\r
47 import com.att.inno.env.TimeTaken;\r
48 import com.att.inno.env.Trans;\r
49 \r
50 \r
51 /**\r
52  * Additional Factory mechanisms for CSRs, and BouncyCastle.  The main Factory\r
53  * utilizes only Java abstractions, and is useful in Client code.\r
54  * \r
55 \r
56  *\r
57  */\r
58 public class BCFactory extends Factory {\r
59         private static final JcaContentSignerBuilder jcsb;\r
60 \r
61 \r
62         static {\r
63                 // Bouncy\r
64                 jcsb = new JcaContentSignerBuilder(Factory.SIG_ALGO);\r
65         }\r
66         \r
67         public static ContentSigner contentSigner(PrivateKey pk) throws OperatorCreationException {\r
68                 return jcsb.build(pk);\r
69         }\r
70         \r
71         public static String toString(Trans trans, PKCS10CertificationRequest csr) throws IOException, CertException {\r
72                 TimeTaken tt = trans.start("CSR to String", Env.SUB);\r
73                 try {\r
74                         if(csr==null) {\r
75                                 throw new CertException("x509 Certificate Request not built");\r
76                         }\r
77                         return textBuilder("CERTIFICATE REQUEST",csr.getEncoded());\r
78                 }finally {\r
79                         tt.done();\r
80                 }\r
81         }\r
82 \r
83         public static PKCS10CertificationRequest toCSR(Trans trans, File file) throws IOException {\r
84                 TimeTaken tt = trans.start("Reconstitute CSR", Env.SUB);\r
85                 try {\r
86                         FileReader fr = new FileReader(file);\r
87                         return new PKCS10CertificationRequest(decode(strip(fr)));\r
88                 } finally {\r
89                         tt.done();\r
90                 }\r
91         }\r
92 \r
93         public static byte[] sign(Trans trans, ASN1Object toSign, PrivateKey pk) throws IOException, InvalidKeyException, SignatureException, NoSuchAlgorithmException {\r
94                 TimeTaken tt = trans.start("Encode Security Object", Env.SUB);\r
95                 try {\r
96                         return sign(trans,toSign.getEncoded(),pk);\r
97                 } finally {\r
98                         tt.done();\r
99                 }\r
100         }\r
101 \r
102         public static CSRMeta createCSRMeta(CA ca,final String args[]) throws IllegalArgumentException, IllegalAccessException, CertException {\r
103                 CSRMeta csr = new CSRMeta();\r
104                 ca.stdFields().set(csr);\r
105                 //TODO should we checkDigest?\r
106 //              digest = ca.messageDigest();\r
107 \r
108                 Field[] fld = CSRMeta.class.getDeclaredFields();\r
109                 for(int i=0;i+1<args.length;++i) {\r
110                         if(args[i].charAt(0)=='-') {\r
111                                 for(int j=0;j<fld.length;++j) {\r
112                                         if(fld[j].getType().equals(String.class) && args[i].substring(1).equals(fld[j].getName())) {\r
113                                                 fld[j].set(csr,args[++i]);\r
114                                                 break;\r
115                                         }\r
116                                 }\r
117                         }\r
118                 }\r
119                 String errs = validate(csr);\r
120                 if(errs!=null) {\r
121                         throw new CertException(errs);\r
122                 }\r
123                 return csr;\r
124         }\r
125         \r
126         \r
127         public static CSRMeta createCSRMeta(CA ca, String mechid, String sponsorEmail, List<String> fqdns) throws CertException {\r
128                 CSRMeta csr = new CSRMeta();\r
129                 boolean first = true;\r
130                 // Set CN (and SAN)\r
131                 for(String fqdn : fqdns) {\r
132                         if(first) {\r
133                                 first = false;\r
134                                 csr.cn(fqdn);\r
135                         } else {\r
136                                 csr.san(fqdn);\r
137                         }\r
138                 }\r
139                 \r
140                 csr.challenge(new String(Symm.randomGen(24)));\r
141                 ca.stdFields().set(csr);\r
142                 csr.mechID(mechid);\r
143                 csr.email(sponsorEmail);\r
144                 String errs = validate(csr);\r
145                 if(errs!=null) {\r
146                         throw new CertException(errs);\r
147                 }\r
148                 return csr;\r
149         }\r
150 \r
151         private static String validate(CSRMeta csr) {\r
152                 Validator v = new Validator();\r
153                 if(v.nullOrBlank("cn", csr.cn())\r
154                         .nullOrBlank("mechID", csr.mechID())\r
155                         .nullOrBlank("email", csr.email())\r
156                         .nullOrBlank("o",csr.o())\r
157                         .nullOrBlank("l",csr.l())\r
158                         .nullOrBlank("st",csr.st())\r
159                         .nullOrBlank("c",csr.c())\r
160                         .err()) {\r
161                         return v.errs();\r
162                 } else {\r
163                         return null;\r
164                 }\r
165         }\r
166         \r
167 \r
168 }\r