[OOM CERT-SERVICE-API] Add support for URI, IP, E-mail in SANs
[oom/platform/cert-service.git] / certService / src / main / java / org / onap / oom / certservice / certification / model / CsrModel.java
1 /*
2  * ============LICENSE_START=======================================================
3  * PROJECT
4  * ================================================================================
5  * Copyright (C) 2020 Nokia. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.oom.certservice.certification.model;
22
23 import java.io.IOException;
24 import java.security.KeyFactory;
25 import java.security.NoSuchAlgorithmException;
26 import java.security.PrivateKey;
27 import java.security.PublicKey;
28 import java.security.spec.InvalidKeySpecException;
29 import java.security.spec.PKCS8EncodedKeySpec;
30 import java.security.spec.X509EncodedKeySpec;
31 import java.util.Arrays;
32
33 import java.util.stream.Collectors;
34 import org.bouncycastle.asn1.x500.X500Name;
35 import org.bouncycastle.asn1.x509.Extension;
36 import org.bouncycastle.asn1.x509.Extensions;
37 import org.bouncycastle.asn1.x509.GeneralName;
38 import org.bouncycastle.asn1.x509.GeneralNames;
39 import org.bouncycastle.pkcs.PKCS10CertificationRequest;
40 import org.bouncycastle.util.io.pem.PemObject;
41
42 import org.onap.oom.certservice.certification.exception.CsrDecryptionException;
43 import org.onap.oom.certservice.certification.exception.DecryptionException;
44 import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
45
46
47 public class CsrModel {
48
49     private final PKCS10CertificationRequest csr;
50     private final X500Name subjectData;
51     private final PrivateKey privateKey;
52     private final PublicKey publicKey;
53     private final GeneralName[] sans;
54
55     public CsrModel(PKCS10CertificationRequest csr, X500Name subjectData, PrivateKey privateKey, PublicKey publicKey,
56         GeneralName[] sans) {
57         this.csr = csr;
58         this.subjectData = subjectData;
59         this.privateKey = privateKey;
60         this.publicKey = publicKey;
61         this.sans = sans;
62     }
63
64     public PKCS10CertificationRequest getCsr() {
65         return csr;
66     }
67
68     public X500Name getSubjectData() {
69         return subjectData;
70     }
71
72     public PrivateKey getPrivateKey() {
73         return privateKey;
74     }
75
76     public PublicKey getPublicKey() {
77         return publicKey;
78     }
79
80     public GeneralName[] getSans() {
81         return sans;
82     }
83
84     @Override
85     public String toString() {
86         return "CSR: { Subject: { " + subjectData + " }, SANs: [" + getSansInReadableFormat() + "] }";
87     }
88
89     private String getSansInReadableFormat() {
90         return Arrays.stream(this.sans)
91             .map(generalName -> generalName.getName().toString())
92             .collect(Collectors.joining(", "));
93     }
94
95     public static class CsrModelBuilder {
96         private final PKCS10CertificationRequest csr;
97
98         private final PemObject privateKey;
99
100         public CsrModel build() throws DecryptionException {
101
102             X500Name subjectData = getSubjectData();
103             PrivateKey javaPrivateKey = convertingPemPrivateKeyToJavaSecurityPrivateKey(getPrivateKey());
104             PublicKey javaPublicKey = convertingPemPublicKeyToJavaSecurityPublicKey(getPublicKey());
105             GeneralName[] sans = getSansData();
106
107             return new CsrModel(csr, subjectData, javaPrivateKey, javaPublicKey, sans);
108         }
109
110         public CsrModelBuilder(PKCS10CertificationRequest csr, PemObject privateKey) {
111             this.csr = csr;
112             this.privateKey = privateKey;
113         }
114
115         private PemObject getPublicKey() throws CsrDecryptionException {
116             try {
117                 return new PemObject("PUBLIC KEY", csr.getSubjectPublicKeyInfo().getEncoded());
118             } catch (IOException e) {
119                 throw new CsrDecryptionException("Reading Public Key from CSR failed", e.getCause());
120             }
121         }
122
123         private PemObject getPrivateKey() {
124             return privateKey;
125         }
126
127         private X500Name getSubjectData() {
128             return csr.getSubject();
129         }
130
131         private GeneralName[] getSansData() {
132             if (!isAttrsEmpty() && !isAttrsValuesEmpty()) {
133                 Extensions extensions = Extensions.getInstance(csr.getAttributes()[0].getAttrValues().getObjectAt(0));
134                 return GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName).getNames();
135             }
136             return new GeneralName[0];
137         }
138
139         private boolean isAttrsValuesEmpty() {
140             return csr.getAttributes()[0].getAttrValues().size() == 0;
141         }
142
143         private boolean isAttrsEmpty() {
144             return csr.getAttributes().length == 0;
145         }
146
147         private PrivateKey convertingPemPrivateKeyToJavaSecurityPrivateKey(PemObject privateKey)
148             throws KeyDecryptionException {
149             try {
150                 KeyFactory factory = KeyFactory.getInstance("RSA");
151                 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey.getContent());
152                 return factory.generatePrivate(keySpec);
153             } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
154                 throw new KeyDecryptionException("Converting Private Key failed", e.getCause());
155             }
156         }
157         private PublicKey convertingPemPublicKeyToJavaSecurityPublicKey(PemObject publicKey)
158             throws KeyDecryptionException {
159             try {
160                 KeyFactory factory = KeyFactory.getInstance("RSA");
161                 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey.getContent());
162                 return factory.generatePublic(keySpec);
163             } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
164                 throw new KeyDecryptionException("Converting Public Key from CSR failed", e.getCause());
165             }
166         }
167
168     }
169 }