Fix checkstyle warnings
[oom/platform/cert-service.git] / certServiceClient / src / main / java / org / onap / aaf / certservice / client / certification / CsrFactory.java
1 /*============LICENSE_START=======================================================
2  * aaf-certservice-client
3  * ================================================================================
4  * Copyright (C) 2020 Nokia. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  * ============LICENSE_END=========================================================
18  */
19
20 package org.onap.aaf.certservice.client.certification;
21
22 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
23 import org.bouncycastle.asn1.x509.Extension;
24 import org.bouncycastle.asn1.x509.Extensions;
25 import org.bouncycastle.asn1.x509.ExtensionsGenerator;
26 import org.bouncycastle.asn1.x509.GeneralName;
27 import org.bouncycastle.asn1.x509.GeneralNames;
28 import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
29 import org.bouncycastle.operator.ContentSigner;
30 import org.bouncycastle.operator.OperatorCreationException;
31 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
32 import org.bouncycastle.pkcs.PKCS10CertificationRequest;
33 import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
34 import org.onap.aaf.certservice.client.certification.exception.CsrGenerationException;
35 import org.onap.aaf.certservice.client.configuration.model.CsrConfiguration;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 import javax.security.auth.x500.X500Principal;
40 import java.io.IOException;
41 import java.io.StringWriter;
42 import java.security.KeyPair;
43 import java.util.Optional;
44
45 import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.COMMON_NAME;
46 import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.COUNTRY;
47 import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.LOCATION;
48 import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.ORGANIZATION;
49 import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.ORGANIZATION_UNIT;
50 import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.SIGN_ALGORITHM;
51 import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.STATE;
52
53
54 public class CsrFactory {
55
56     private static final Logger LOGGER = LoggerFactory.getLogger(CsrFactory.class);
57     private static final String SANS_DELIMITER = ":";
58     private final CsrConfiguration configuration;
59
60
61     public CsrFactory(CsrConfiguration configuration) {
62         this.configuration = configuration;
63     }
64
65
66     public String createCsrInPem(KeyPair keyPair) throws CsrGenerationException {
67         LOGGER.info("Creation of CSR has been started with following parameters: {}", configuration.toString());
68         String csrParameters = getMandatoryParameters().append(getOptionalParameters()).toString();
69         X500Principal subject = new X500Principal(csrParameters);
70         PKCS10CertificationRequest request = createPkcs10Csr(subject, keyPair);
71
72         LOGGER.info("Creation of CSR has been completed successfully");
73         return convertPkcs10CsrToPem(request);
74     }
75
76     private StringBuilder getMandatoryParameters() {
77         return new StringBuilder(String.format("%s=%s, %s=%s, %s=%s, %s=%s",
78                 COMMON_NAME, configuration.getCommonName(),
79                 COUNTRY, configuration.getCountry(),
80                 STATE, configuration.getState(),
81                 ORGANIZATION, configuration.getOrganization()));
82     }
83
84     private String getOptionalParameters() {
85         StringBuilder optionalParameters = new StringBuilder();
86         Optional.ofNullable(configuration.getOrganizationUnit())
87                 .filter(CsrFactory::isParameterPresent)
88                 .map(unit -> optionalParameters.append(String.format(", %s=%s", ORGANIZATION_UNIT, unit)));
89         Optional.ofNullable(configuration.getLocation())
90                 .filter(CsrFactory::isParameterPresent)
91                 .map(location -> optionalParameters.append(String.format(", %s=%s", LOCATION, location)));
92         return optionalParameters.toString();
93     }
94
95     private PKCS10CertificationRequest createPkcs10Csr(X500Principal subject, KeyPair keyPair) throws CsrGenerationException {
96         JcaPKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic());
97
98         if (isParameterPresent(configuration.getSans())) {
99             builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, generateSansExtension());
100         }
101
102         return builder.build(getContentSigner(keyPair));
103     }
104
105     private ContentSigner getContentSigner(KeyPair keyPair) throws CsrGenerationException {
106         ContentSigner contentSigner;
107         try {
108             contentSigner = new JcaContentSignerBuilder(SIGN_ALGORITHM).build(keyPair.getPrivate());
109         } catch (OperatorCreationException e) {
110             LOGGER.error("Creation of PKCS10Csr failed, exception message: {}", e.getMessage());
111             throw new CsrGenerationException(e);
112
113         }
114         return contentSigner;
115     }
116
117     private String convertPkcs10CsrToPem(PKCS10CertificationRequest request) throws CsrGenerationException {
118         final StringWriter stringWriter = new StringWriter();
119         try (JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) {
120             LOGGER.info("Conversion of CSR to PEM has been started");
121             pemWriter.writeObject(request);
122         } catch (IOException e) {
123             LOGGER.error("Conversion to PEM failed, exception message: {}", e.getMessage());
124             throw new CsrGenerationException(e);
125         }
126         return stringWriter.toString();
127     }
128
129     private Extensions generateSansExtension() throws CsrGenerationException {
130         ExtensionsGenerator generator = new ExtensionsGenerator();
131         try {
132             generator.addExtension(Extension.subjectAlternativeName, false, createGeneralNames());
133         } catch (IOException e) {
134             LOGGER.error("Generation of SANs parameter failed, exception message: {}", e.getMessage());
135             throw new CsrGenerationException(e);
136         }
137         return generator.generate();
138     }
139
140     private GeneralNames createGeneralNames() {
141         String[] sansTable = this.configuration.getSans().split(SANS_DELIMITER);
142         int length = sansTable.length;
143         GeneralName[] generalNames = new GeneralName[length];
144         for (int i = 0; i < length; i++) {
145             generalNames[i] = new GeneralName(GeneralName.dNSName, sansTable[i]);
146         }
147         return new GeneralNames(generalNames);
148     }
149
150     private static Boolean isParameterPresent(String parameter) {
151         return parameter != null && !"".equals(parameter);
152     }
153 }