From c85a8965e876fde2089582a6468eb02ce18bafd5 Mon Sep 17 00:00:00 2001 From: Bartosz Gardziejewski Date: Wed, 18 Mar 2020 09:38:27 +0100 Subject: Resolve all checkstyle warnings Issue-ID: AAF-1107 Signed-off-by: Bartosz Gardziejewski Change-Id: I28cfc2b82f1a4800a984e30f59ff36fe90bebb38 --- .../aaf/certservice/CertServiceApplication.java | 2 +- .../certservice/api/CertificationController.java | 13 +- .../aaf/certservice/api/ReadinessController.java | 4 +- .../certservice/api/ReloadConfigController.java | 4 +- .../api/advice/CertificationExceptionAdvice.java | 4 +- .../api/advice/ReloadConfigExceptionAdvice.java | 2 +- .../api/configuration/OpenApiConfig.java | 2 +- .../certification/CertificationData.java | 3 +- .../certservice/certification/CsrModelFactory.java | 28 +- .../PKCS10CertificationRequestFactory.java | 45 -- .../Pkcs10CertificationRequestFactory.java | 45 ++ .../certification/adapter/CSRMetaBuilder.java | 90 ---- .../certification/adapter/Cmpv2ClientAdapter.java | 24 +- .../certification/adapter/CsrMetaBuilder.java | 90 ++++ .../adapter/RSAContentSignerBuilder.java | 45 -- .../adapter/RsaContentSignerBuilder.java | 46 ++ .../configuration/CmpClientConfig.java | 7 +- .../configuration/CmpServersConfigLoader.java | 2 +- .../configuration/model/Authentication.java | 14 +- .../certification/configuration/model/CaMode.java | 2 +- .../configuration/model/Cmpv2Server.java | 23 +- .../validation/constraints/Cmpv2URL.java | 39 -- .../validation/constraints/Cmpv2URLValidator.java | 55 -- .../validation/constraints/Cmpv2Url.java | 41 ++ .../validation/constraints/Cmpv2UrlValidator.java | 55 ++ .../violations/PortNumberViolation.java | 2 +- .../violations/RequestTypeViolation.java | 4 +- .../constraints/violations/URLServerViolation.java | 25 - .../constraints/violations/UrlServerViolation.java | 25 + .../exception/CsrDecryptionException.java | 1 + .../exception/DecryptionException.java | 3 + .../exception/KeyDecryptionException.java | 1 + .../aaf/certservice/cmpv2client/api/CmpClient.java | 99 ++-- .../cmpv2client/exceptions/CmpClientException.java | 36 +- .../cmpv2client/exceptions/PkiErrorException.java | 32 +- .../certservice/cmpv2client/external/CSRMeta.java | 206 -------- .../certservice/cmpv2client/external/CsrMeta.java | 208 ++++++++ .../certservice/cmpv2client/external/Factory.java | 18 +- .../aaf/certservice/cmpv2client/external/RDN.java | 156 ------ .../aaf/certservice/cmpv2client/external/Rdn.java | 157 ++++++ .../cmpv2client/impl/CmpClientImpl.java | 360 ++++++------- .../cmpv2client/impl/CmpMessageBuilder.java | 54 +- .../cmpv2client/impl/CmpMessageHelper.java | 330 ++++++------ .../cmpv2client/impl/CmpResponseHelper.java | 574 +++++++++++---------- .../impl/CmpResponseValidationHelper.java | 335 ++++++------ .../aaf/certservice/cmpv2client/impl/CmpUtil.java | 186 +++---- .../cmpv2client/impl/Cmpv2HttpClient.java | 81 +-- .../cmpv2client/impl/CreateCertRequest.java | 169 +++--- 48 files changed, 1903 insertions(+), 1844 deletions(-) delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/PKCS10CertificationRequestFactory.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/Pkcs10CertificationRequestFactory.java delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CsrMetaBuilder.java delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/adapter/RSAContentSignerBuilder.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/adapter/RsaContentSignerBuilder.java delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URL.java delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URLValidator.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2Url.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2UrlValidator.java delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/URLServerViolation.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/UrlServerViolation.java delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CSRMeta.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CsrMeta.java delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/RDN.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Rdn.java (limited to 'certService/src/main/java') diff --git a/certService/src/main/java/org/onap/aaf/certservice/CertServiceApplication.java b/certService/src/main/java/org/onap/aaf/certservice/CertServiceApplication.java index 087cf259..11478965 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/CertServiceApplication.java +++ b/certService/src/main/java/org/onap/aaf/certservice/CertServiceApplication.java @@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.PropertySource; @SpringBootApplication -@PropertySource(value={"classpath:application.properties"}) +@PropertySource(value = {"classpath:application.properties"}) public class CertServiceApplication { // We are excluding this line in Sonar due to fact that diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java b/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java index fe941f58..74f64061 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java @@ -60,9 +60,8 @@ public class CertificationController { /** * Request for signing certificate by given CA. * - * - * @param caName the name of Certification Authority that will sign root certificate - * @param encodedCsr Certificate Sign Request encoded in Base64 form + * @param caName the name of Certification Authority that will sign root certificate + * @param encodedCsr Certificate Sign Request encoded in Base64 form * @param encodedPrivateKey Private key for CSR, needed for PoP, encoded in Base64 form * @return JSON containing trusted certificates and certificate chain */ @@ -79,13 +78,13 @@ public class CertificationController { @Operation( summary = "sign certificate", description = "Web endpoint for requesting certificate signing. Used by system components to gain certificate signed by CA.", - tags = { "CertificationService" }) + tags = {"CertificationService"}) public ResponseEntity signCertificate( - @Parameter(description="Name of certification authority that will sign CSR.") + @Parameter(description = "Name of certification authority that will sign CSR.") @PathVariable String caName, - @Parameter(description="Certificate signing request in form of PEM object encoded in Base64 (with header and footer).") + @Parameter(description = "Certificate signing request in form of PEM object encoded in Base64 (with header and footer).") @RequestHeader("CSR") String encodedCsr, - @Parameter(description="Private key in form of PEM object encoded in Base64 (with header and footer).") + @Parameter(description = "Private key in form of PEM object encoded in Base64 (with header and footer).") @RequestHeader("PK") String encodedPrivateKey ) throws DecryptionException, CmpClientException, Cmpv2ClientAdapterException { caName = caName.replaceAll("[\n|\r|\t]", "_"); diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/ReadinessController.java b/certService/src/main/java/org/onap/aaf/certservice/api/ReadinessController.java index 288957ca..f900edf9 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/ReadinessController.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/ReadinessController.java @@ -33,7 +33,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController @Tag(name = "CertificationService") -public class ReadinessController { +public final class ReadinessController { private final CmpServersConfig cmpServersConfig; @@ -50,7 +50,7 @@ public class ReadinessController { @Operation( summary = "check is container is ready", description = "Web endpoint for checking if service is ready to be used.", - tags = { "CertificationService" }) + tags = {"CertificationService"}) public ResponseEntity checkReady() { if (cmpServersConfig.isReady()) { return new ResponseEntity<>(HttpStatus.OK); diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java b/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java index c52cf4f2..e812ce0d 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java @@ -37,7 +37,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController @Tag(name = "CertificationService") -public class ReloadConfigController { +public final class ReloadConfigController { private final CmpServersConfig cmpServersConfig; @@ -55,7 +55,7 @@ public class ReloadConfigController { @Operation( summary = "reload service configuration from file", description = "Web endpoint for performing configuration reload. Used to reload configuration file from file.", - tags = { "CertificationService" }) + tags = {"CertificationService"}) public ResponseEntity reloadConfiguration() throws CmpServersConfigLoadingException { cmpServersConfig.reloadConfiguration(); return new ResponseEntity<>(HttpStatus.OK); diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/advice/CertificationExceptionAdvice.java b/certService/src/main/java/org/onap/aaf/certservice/api/advice/CertificationExceptionAdvice.java index f75e93c9..a40fea8f 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/advice/CertificationExceptionAdvice.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/advice/CertificationExceptionAdvice.java @@ -35,7 +35,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice(assignableTypes = CertificationController.class) -public class CertificationExceptionAdvice { +public final class CertificationExceptionAdvice { private static final Logger LOGGER = LoggerFactory.getLogger(CertificationExceptionAdvice.class); @@ -92,7 +92,7 @@ public class CertificationExceptionAdvice { private ResponseEntity getErrorResponseEntity(String errorMessage, HttpStatus status) { ErrorResponseModel errorResponse = new ErrorResponseModel(errorMessage); return new ResponseEntity<>( - errorResponse, + errorResponse, status ); } diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdvice.java b/certService/src/main/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdvice.java index bf83ece2..4a4073ff 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdvice.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdvice.java @@ -30,7 +30,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice(assignableTypes = ReloadConfigController.class) -public class ReloadConfigExceptionAdvice { +public final class ReloadConfigExceptionAdvice { private static final Logger LOGGER = LoggerFactory.getLogger(ReloadConfigExceptionAdvice.class); diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/configuration/OpenApiConfig.java b/certService/src/main/java/org/onap/aaf/certservice/api/configuration/OpenApiConfig.java index 18327048..503b2818 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/configuration/OpenApiConfig.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/configuration/OpenApiConfig.java @@ -30,7 +30,7 @@ import org.springframework.context.annotation.Configuration; public class OpenApiConfig { @Bean - public OpenAPI customOpenAPI() { + public OpenAPI customOpenApi() { return new OpenAPI() .components(new Components()) .info( diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/CertificationData.java b/certService/src/main/java/org/onap/aaf/certservice/certification/CertificationData.java index a347762e..bce72977 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/CertificationData.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/CertificationData.java @@ -23,7 +23,8 @@ package org.onap.aaf.certservice.certification; final class CertificationData { - private CertificationData() {} + private CertificationData() { + } private static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n"; private static final String END_CERTIFICATE = "-----END CERTIFICATE-----"; diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/CsrModelFactory.java b/certService/src/main/java/org/onap/aaf/certservice/certification/CsrModelFactory.java index 501ed6d0..b4f94b93 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/CsrModelFactory.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/CsrModelFactory.java @@ -40,8 +40,8 @@ public class CsrModelFactory { private final PemObjectFactory pemObjectFactory = new PemObjectFactory(); - private final PKCS10CertificationRequestFactory certificationRequestFactory - = new PKCS10CertificationRequestFactory(); + private final Pkcs10CertificationRequestFactory certificationRequestFactory + = new Pkcs10CertificationRequestFactory(); public CsrModel createCsrModel(StringBase64 csr, StringBase64 privateKey) @@ -57,15 +57,15 @@ public class CsrModelFactory { return privateKey.asString() .flatMap(pemObjectFactory::createPemObject) .orElseThrow( - () -> new KeyDecryptionException("Incorrect Key, decryption failed") - ); + () -> new KeyDecryptionException("Incorrect Key, decryption failed") + ); } private PKCS10CertificationRequest decodeCsr(StringBase64 csr) throws CsrDecryptionException { return csr.asString() .flatMap(pemObjectFactory::createPemObject) - .flatMap(certificationRequestFactory::createKCS10CertificationRequest) + .flatMap(certificationRequestFactory::createPkcs10CertificationRequest) .orElseThrow( () -> new CsrDecryptionException("Incorrect CSR, decryption failed") ); @@ -84,20 +84,28 @@ public class CsrModelFactory { try { String decodedString = new String(decoder.decode(value)); return Optional.of(decodedString); - } catch(RuntimeException e) { + } catch (RuntimeException e) { LOGGER.error("Exception occurred during decoding:", e); return Optional.empty(); } } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - StringBase64 that = (StringBase64) o; + public boolean equals(Object otherObject) { + if (this == otherObject) { + return true; + } + if (otherObject == null || getClass() != otherObject.getClass()) { + return false; + } + StringBase64 that = (StringBase64) otherObject; return Objects.equals(value, that.value); } + @Override + public int hashCode() { + return value.hashCode(); + } } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/PKCS10CertificationRequestFactory.java b/certService/src/main/java/org/onap/aaf/certservice/certification/PKCS10CertificationRequestFactory.java deleted file mode 100644 index b255b7c2..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/PKCS10CertificationRequestFactory.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PROJECT - * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aaf.certservice.certification; - -import org.bouncycastle.pkcs.PKCS10CertificationRequest; -import org.bouncycastle.util.encoders.DecoderException; -import org.bouncycastle.util.io.pem.PemObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.Optional; - -public class PKCS10CertificationRequestFactory { - - private static final Logger LOGGER = LoggerFactory.getLogger(PKCS10CertificationRequestFactory.class); - - public Optional createKCS10CertificationRequest(PemObject pemObject) { - try { - LOGGER.debug("Creating certification request from pem object"); - return Optional.of(new PKCS10CertificationRequest(pemObject.getContent())); - } catch (DecoderException | IOException e) { - LOGGER.error("Exception occurred during creation of certification request:", e); - return Optional.empty(); - } - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/Pkcs10CertificationRequestFactory.java b/certService/src/main/java/org/onap/aaf/certservice/certification/Pkcs10CertificationRequestFactory.java new file mode 100644 index 00000000..1b00a815 --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/Pkcs10CertificationRequestFactory.java @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.certification; + +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.util.encoders.DecoderException; +import org.bouncycastle.util.io.pem.PemObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Optional; + +public class Pkcs10CertificationRequestFactory { + + private static final Logger LOGGER = LoggerFactory.getLogger(Pkcs10CertificationRequestFactory.class); + + public Optional createPkcs10CertificationRequest(PemObject pemObject) { + try { + LOGGER.debug("Creating certification request from pem object"); + return Optional.of(new PKCS10CertificationRequest(pemObject.getContent())); + } catch (DecoderException | IOException e) { + LOGGER.error("Exception occurred during creation of certification request:", e); + return Optional.empty(); + } + } +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java deleted file mode 100644 index 1959d638..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Cert Service - * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aaf.certservice.certification.adapter; - -import java.security.KeyPair; -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.bouncycastle.asn1.x500.AttributeTypeAndValue; -import org.bouncycastle.asn1.x500.style.BCStyle; -import org.bouncycastle.asn1.x500.style.IETFUtils; -import org.bouncycastle.cert.CertException; -import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server; -import org.onap.aaf.certservice.certification.model.CsrModel; -import org.onap.aaf.certservice.cmpv2client.external.CSRMeta; -import org.onap.aaf.certservice.cmpv2client.external.RDN; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -class CSRMetaBuilder { - - private static final Logger LOGGER = LoggerFactory.getLogger(CSRMetaBuilder.class); - - /** - * Creates CSRMeta from CsrModel and Cmpv2Server - * - * @param csrModel Certificate Signing Request from Service external API - * @param server Cmp Server configuration from cmpServers.json - * @return AAF native model for CSR metadata - */ - CSRMeta build(CsrModel csrModel, Cmpv2Server server) { - CSRMeta csrMeta = createCsrMeta(csrModel); - addSans(csrModel, csrMeta); - csrMeta.setKeyPair(new KeyPair(csrModel.getPublicKey(), csrModel.getPrivateKey())); - csrMeta.setPassword(server.getAuthentication().getIak()); - csrMeta.setIssuerName(server.getIssuerDN()); - csrMeta.setCaUrl(server.getUrl()); - csrMeta.setName(csrModel.getSubjectData()); - csrMeta.setSenderKid(server.getAuthentication().getRv()); - return csrMeta; - } - - private CSRMeta createCsrMeta(CsrModel csrModel) { - return new CSRMeta((Arrays.stream(csrModel.getSubjectData().getRDNs()).map(this::convertFromBcRDN) - .filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList()))); - } - - private void addSans(CsrModel csrModel, CSRMeta csrMeta) { - csrModel.getSans().forEach(csrMeta::addSan); - } - - private Optional convertFromBcRDN(org.bouncycastle.asn1.x500.RDN rdn) { - RDN result = null; - try { - result = convertRDN(rdn); - } catch (CertException e) { - LOGGER.error("Exception occurred during convert of RDN", e); - } - return Optional.ofNullable(result); - } - - private RDN convertRDN(org.bouncycastle.asn1.x500.RDN rdn) throws CertException { - AttributeTypeAndValue rdnData = rdn.getFirst(); - String tag = BCStyle.INSTANCE.oidToDisplayName(rdnData.getType()); - String value = IETFUtils.valueToString(rdnData.getValue()); - return new RDN(tag, value); - } - -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/Cmpv2ClientAdapter.java b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/Cmpv2ClientAdapter.java index be39f1f3..c9e61b02 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/Cmpv2ClientAdapter.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/Cmpv2ClientAdapter.java @@ -54,15 +54,15 @@ public class Cmpv2ClientAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(Cmpv2ClientAdapter.class); private final CmpClient cmpClient; - private final CSRMetaBuilder csrMetaBuilder; - private final RSAContentSignerBuilder rsaContentSignerBuilder; + private final CsrMetaBuilder csrMetaBuilder; + private final RsaContentSignerBuilder rsaContentSignerBuilder; private final X509CertificateBuilder x509CertificateBuilder; private final CertificateFactoryProvider certificateFactoryProvider; @Autowired - public Cmpv2ClientAdapter(CmpClient cmpClient, CSRMetaBuilder csrMetaBuilder, - RSAContentSignerBuilder rsaContentSignerBuilder, X509CertificateBuilder x509CertificateBuilder, - CertificateFactoryProvider certificateFactoryProvider) { + public Cmpv2ClientAdapter(CmpClient cmpClient, CsrMetaBuilder csrMetaBuilder, + RsaContentSignerBuilder rsaContentSignerBuilder, X509CertificateBuilder x509CertificateBuilder, + CertificateFactoryProvider certificateFactoryProvider) { this.cmpClient = cmpClient; this.csrMetaBuilder = csrMetaBuilder; this.rsaContentSignerBuilder = rsaContentSignerBuilder; @@ -83,12 +83,12 @@ public class Cmpv2ClientAdapter { throws CmpClientException, Cmpv2ClientAdapterException { List> certificates = cmpClient.createCertificate(server.getCaName(), server.getCaMode().getProfile(), csrMetaBuilder.build(csrModel, server), - convertCSRToX509Certificate(csrModel.getCsr(), csrModel.getPrivateKey())); - return new CertificationModel(convertFromX509CertificateListToPEMList(certificates.get(0)), - convertFromX509CertificateListToPEMList(certificates.get(1))); + convertCsrToX509Certificate(csrModel.getCsr(), csrModel.getPrivateKey())); + return new CertificationModel(convertFromX509CertificateListToPemList(certificates.get(0)), + convertFromX509CertificateListToPemList(certificates.get(1))); } - private String convertFromX509CertificateToPEM(X509Certificate certificate) { + private String convertFromX509CertificateToPem(X509Certificate certificate) { StringWriter sw = new StringWriter(); try (PemWriter pw = new PemWriter(sw)) { PemObjectGenerator gen = new JcaMiscPEMGenerator(certificate); @@ -99,7 +99,7 @@ public class Cmpv2ClientAdapter { return sw.toString(); } - private X509Certificate convertCSRToX509Certificate(PKCS10CertificationRequest csr, PrivateKey privateKey) + private X509Certificate convertCsrToX509Certificate(PKCS10CertificationRequest csr, PrivateKey privateKey) throws Cmpv2ClientAdapterException { try { X509v3CertificateBuilder certificateGenerator = x509CertificateBuilder.build(csr); @@ -112,8 +112,8 @@ public class Cmpv2ClientAdapter { } } - private List convertFromX509CertificateListToPEMList(List certificates) { - return certificates.stream().map(this::convertFromX509CertificateToPEM).filter(cert -> !cert.isEmpty()) + private List convertFromX509CertificateListToPemList(List certificates) { + return certificates.stream().map(this::convertFromX509CertificateToPem).filter(cert -> !cert.isEmpty()) .collect(Collectors.toList()); } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CsrMetaBuilder.java b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CsrMetaBuilder.java new file mode 100644 index 00000000..cf35efa1 --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CsrMetaBuilder.java @@ -0,0 +1,90 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.certification.adapter; + +import java.security.KeyPair; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.bouncycastle.asn1.x500.AttributeTypeAndValue; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.asn1.x500.style.IETFUtils; +import org.bouncycastle.cert.CertException; +import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server; +import org.onap.aaf.certservice.certification.model.CsrModel; +import org.onap.aaf.certservice.cmpv2client.external.CsrMeta; +import org.onap.aaf.certservice.cmpv2client.external.Rdn; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +class CsrMetaBuilder { + + private static final Logger LOGGER = LoggerFactory.getLogger(CsrMetaBuilder.class); + + /** + * Creates CSRMeta from CsrModel and Cmpv2Server + * + * @param csrModel Certificate Signing Request from Service external API + * @param server Cmp Server configuration from cmpServers.json + * @return AAF native model for CSR metadata + */ + CsrMeta build(CsrModel csrModel, Cmpv2Server server) { + CsrMeta csrMeta = createCsrMeta(csrModel); + addSans(csrModel, csrMeta); + csrMeta.setKeyPair(new KeyPair(csrModel.getPublicKey(), csrModel.getPrivateKey())); + csrMeta.setPassword(server.getAuthentication().getIak()); + csrMeta.setIssuerName(server.getIssuerDN()); + csrMeta.setCaUrl(server.getUrl()); + csrMeta.setName(csrModel.getSubjectData()); + csrMeta.setSenderKid(server.getAuthentication().getRv()); + return csrMeta; + } + + private CsrMeta createCsrMeta(CsrModel csrModel) { + return new CsrMeta((Arrays.stream(csrModel.getSubjectData().getRDNs()).map(this::convertFromBcRdn) + .filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList()))); + } + + private void addSans(CsrModel csrModel, CsrMeta csrMeta) { + csrModel.getSans().forEach(csrMeta::addSan); + } + + private Optional convertFromBcRdn(org.bouncycastle.asn1.x500.RDN rdn) { + Rdn result = null; + try { + result = convertRdn(rdn); + } catch (CertException e) { + LOGGER.error("Exception occurred during convert of RDN", e); + } + return Optional.ofNullable(result); + } + + private Rdn convertRdn(org.bouncycastle.asn1.x500.RDN rdn) throws CertException { + AttributeTypeAndValue rdnData = rdn.getFirst(); + String tag = BCStyle.INSTANCE.oidToDisplayName(rdnData.getType()); + String value = IETFUtils.valueToString(rdnData.getValue()); + return new Rdn(tag, value); + } + +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/RSAContentSignerBuilder.java b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/RSAContentSignerBuilder.java deleted file mode 100644 index 266c22e2..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/RSAContentSignerBuilder.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Cert Service - * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aaf.certservice.certification.adapter; - -import java.io.IOException; -import java.security.PrivateKey; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.crypto.util.PrivateKeyFactory; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; -import org.bouncycastle.pkcs.PKCS10CertificationRequest; -import org.springframework.stereotype.Component; - -@Component -public class RSAContentSignerBuilder { - - ContentSigner build(PKCS10CertificationRequest csr, PrivateKey privateKey) - throws IOException, OperatorCreationException { - AlgorithmIdentifier sigAlgId = csr.getSignatureAlgorithm(); - AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); - - return new BcRSAContentSignerBuilder(sigAlgId, digAlgId) - .build(PrivateKeyFactory.createKey(privateKey.getEncoded())); - } - -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/RsaContentSignerBuilder.java b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/RsaContentSignerBuilder.java new file mode 100644 index 00000000..bda89235 --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/RsaContentSignerBuilder.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.certification.adapter; + +import java.io.IOException; +import java.security.PrivateKey; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.crypto.util.PrivateKeyFactory; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.springframework.stereotype.Component; + +@Component +public class RsaContentSignerBuilder { + + ContentSigner build(PKCS10CertificationRequest csr, PrivateKey privateKey) + throws IOException, OperatorCreationException { + AlgorithmIdentifier sigAlgId = csr.getSignatureAlgorithm(); + AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); + + return new BcRSAContentSignerBuilder(sigAlgId, digAlgId) + .build(PrivateKeyFactory.createKey(privateKey.getEncoded())); + } + +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpClientConfig.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpClientConfig.java index 21b873e6..329098ac 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpClientConfig.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpClientConfig.java @@ -17,6 +17,7 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.onap.aaf.certservice.certification.configuration; import org.apache.http.impl.client.CloseableHttpClient; @@ -31,18 +32,18 @@ import org.springframework.web.context.annotation.RequestScope; public class CmpClientConfig { @Bean - CmpClient cmpClient(CloseableHttpClient closeableHttpClient){ + CmpClient cmpClient(CloseableHttpClient closeableHttpClient) { return new CmpClientImpl(closeableHttpClient); } @Bean @RequestScope - CloseableHttpClient closeableHttpClient(HttpClientBuilder httpClientBuilder){ + CloseableHttpClient closeableHttpClient(HttpClientBuilder httpClientBuilder) { return httpClientBuilder.build(); } @Bean - HttpClientBuilder httpClientBuilder(){ + HttpClientBuilder httpClientBuilder() { return HttpClientBuilder.create(); } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java index 1072d630..696ae564 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java @@ -40,7 +40,7 @@ class CmpServersConfigLoader { private final Cmpv2ServerConfigurationValidator validator; @Autowired - public CmpServersConfigLoader(Cmpv2ServerConfigurationValidator validator) { + CmpServersConfigLoader(Cmpv2ServerConfigurationValidator validator) { this.validator = validator; } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Authentication.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Authentication.java index 3785cf8e..e4c15518 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Authentication.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Authentication.java @@ -25,11 +25,13 @@ import org.hibernate.validator.constraints.Length; public class Authentication { + private static final int MAX_IAK_RV_LENGTH = 256; + @NotNull - @Length(min = 1, max = 256) + @Length(min = 1, max = MAX_IAK_RV_LENGTH) private String iak; @NotNull - @Length(min = 1, max = 256) + @Length(min = 1, max = MAX_IAK_RV_LENGTH) private String rv; public String getIak() { @@ -50,9 +52,9 @@ public class Authentication { @Override public String toString() { - return "Authentication{" + - " iak=*****" + - ", rv=*****" + - '}'; + return "Authentication{" + + " iak=*****" + + ", rv=*****" + + '}'; } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/CaMode.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/CaMode.java index 2186b6ff..374feb3b 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/CaMode.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/CaMode.java @@ -29,7 +29,7 @@ public enum CaMode { this.profile = profile; } - public String getProfile(){ + public String getProfile() { return profile; } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Cmpv2Server.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Cmpv2Server.java index 20b83b82..51d91966 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Cmpv2Server.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Cmpv2Server.java @@ -22,23 +22,26 @@ package org.onap.aaf.certservice.certification.configuration.model; import javax.validation.Valid; import javax.validation.constraints.NotNull; + import org.bouncycastle.asn1.x500.X500Name; import org.hibernate.validator.constraints.Length; -import org.onap.aaf.certservice.certification.configuration.validation.constraints.Cmpv2URL; +import org.onap.aaf.certservice.certification.configuration.validation.constraints.Cmpv2Url; public class Cmpv2Server { + private static final int MAX_CA_NAME_LENGTH = 128; + @NotNull @Valid private Authentication authentication; @NotNull private CaMode caMode; @NotNull - @Length(min = 1, max = 128) + @Length(min = 1, max = MAX_CA_NAME_LENGTH) private String caName; @NotNull private X500Name issuerDN; - @Cmpv2URL + @Cmpv2Url private String url; public Authentication getAuthentication() { @@ -83,13 +86,13 @@ public class Cmpv2Server { @Override public String toString() { - return "Cmpv2Server{" + - "authentication=" + authentication + - ", caMode=" + caMode + - ", caName='" + caName + '\'' + - ", issuerDN='" + issuerDN + '\'' + - ", url='" + url + '\'' + - '}'; + return "Cmpv2Server{" + + "authentication=" + authentication + + ", caMode=" + caMode + + ", caName='" + caName + '\'' + + ", issuerDN='" + issuerDN + '\'' + + ", url='" + url + '\'' + + '}'; } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URL.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URL.java deleted file mode 100644 index 7c942548..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URL.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PROJECT - * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aaf.certservice.certification.configuration.validation.constraints; - -import javax.validation.Constraint; -import javax.validation.Payload; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.ANNOTATION_TYPE; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -@Target( { FIELD, ANNOTATION_TYPE }) -@Retention(RUNTIME) -@Constraint(validatedBy = Cmpv2URLValidator.class) -public @interface Cmpv2URL { - String message() default "Server URL is invalid."; - Class[] groups() default {}; - Class[] payload() default {}; -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URLValidator.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URLValidator.java deleted file mode 100644 index b3224c45..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URLValidator.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PROJECT - * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - - -package org.onap.aaf.certservice.certification.configuration.validation.constraints; - -import org.onap.aaf.certservice.certification.configuration.validation.constraints.violations.PortNumberViolation; -import org.onap.aaf.certservice.certification.configuration.validation.constraints.violations.RequestTypeViolation; -import org.onap.aaf.certservice.certification.configuration.validation.constraints.violations.URLServerViolation; - -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -class Cmpv2URLValidator implements ConstraintValidator { - - private final List violations; - - public Cmpv2URLValidator() { - this.violations = Arrays.asList( - new PortNumberViolation(), - new RequestTypeViolation() - ); - } - - @Override - public boolean isValid(String url, ConstraintValidatorContext context) { - AtomicBoolean isValid = new AtomicBoolean(true); - violations.forEach(violation -> { - if (!violation.validate(url)) { - isValid.set(false); - } - }); - return isValid.get(); - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2Url.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2Url.java new file mode 100644 index 00000000..a5450a25 --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2Url.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.certification.configuration.validation.constraints; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Target({FIELD, ANNOTATION_TYPE}) +@Retention(RUNTIME) +@Constraint(validatedBy = Cmpv2UrlValidator.class) +public @interface Cmpv2Url { + String message() default "Server URL is invalid."; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2UrlValidator.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2UrlValidator.java new file mode 100644 index 00000000..7ce3bb6c --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2UrlValidator.java @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + + +package org.onap.aaf.certservice.certification.configuration.validation.constraints; + +import org.onap.aaf.certservice.certification.configuration.validation.constraints.violations.PortNumberViolation; +import org.onap.aaf.certservice.certification.configuration.validation.constraints.violations.RequestTypeViolation; +import org.onap.aaf.certservice.certification.configuration.validation.constraints.violations.UrlServerViolation; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +class Cmpv2UrlValidator implements ConstraintValidator { + + private final List violations; + + Cmpv2UrlValidator() { + this.violations = Arrays.asList( + new PortNumberViolation(), + new RequestTypeViolation() + ); + } + + @Override + public boolean isValid(String url, ConstraintValidatorContext context) { + AtomicBoolean isValid = new AtomicBoolean(true); + violations.forEach(violation -> { + if (!violation.validate(url)) { + isValid.set(false); + } + }); + return isValid.get(); + } +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/PortNumberViolation.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/PortNumberViolation.java index acde0417..96f30149 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/PortNumberViolation.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/PortNumberViolation.java @@ -23,7 +23,7 @@ package org.onap.aaf.certservice.certification.configuration.validation.constrai import java.net.MalformedURLException; import java.net.URL; -public class PortNumberViolation implements URLServerViolation { +public class PortNumberViolation implements UrlServerViolation { private static final int MIN_PORT = 1; private static final int MAX_PORT = 65535; diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/RequestTypeViolation.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/RequestTypeViolation.java index 7fbbdf34..67a5c3c4 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/RequestTypeViolation.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/RequestTypeViolation.java @@ -27,9 +27,9 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; -public class RequestTypeViolation implements URLServerViolation { +public class RequestTypeViolation implements UrlServerViolation { - private final static List VALID_REQUESTS = Collections.singletonList("http"); + private static final List VALID_REQUESTS = Collections.singletonList("http"); @Override public boolean validate(String serverUrl) { diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/URLServerViolation.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/URLServerViolation.java deleted file mode 100644 index e5a110d2..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/URLServerViolation.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PROJECT - * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aaf.certservice.certification.configuration.validation.constraints.violations; - -public interface URLServerViolation { - boolean validate(String url); -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/UrlServerViolation.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/UrlServerViolation.java new file mode 100644 index 00000000..5452beb4 --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/UrlServerViolation.java @@ -0,0 +1,25 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.certification.configuration.validation.constraints.violations; + +public interface UrlServerViolation { + boolean validate(String url); +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/exception/CsrDecryptionException.java b/certService/src/main/java/org/onap/aaf/certservice/certification/exception/CsrDecryptionException.java index 0bb46258..ed434e07 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/exception/CsrDecryptionException.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/exception/CsrDecryptionException.java @@ -24,6 +24,7 @@ public class CsrDecryptionException extends DecryptionException { public CsrDecryptionException(String message, Throwable cause) { super(message, cause); } + public CsrDecryptionException(String message) { super(message); } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/exception/DecryptionException.java b/certService/src/main/java/org/onap/aaf/certservice/certification/exception/DecryptionException.java index ee0fb202..6d8f7073 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/exception/DecryptionException.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/exception/DecryptionException.java @@ -21,10 +21,13 @@ package org.onap.aaf.certservice.certification.exception; public class DecryptionException extends Exception { + public DecryptionException(String message, Throwable cause) { super(message, cause); } + public DecryptionException(String message) { super(message); } + } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/exception/KeyDecryptionException.java b/certService/src/main/java/org/onap/aaf/certservice/certification/exception/KeyDecryptionException.java index 7970c393..d4814d6a 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/exception/KeyDecryptionException.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/exception/KeyDecryptionException.java @@ -24,6 +24,7 @@ public class KeyDecryptionException extends DecryptionException { public KeyDecryptionException(String message, Throwable cause) { super(message, cause); } + public KeyDecryptionException(String message) { super(message); } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/api/CmpClient.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/api/CmpClient.java index 150f15d5..8f9d20bd 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/api/CmpClient.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/api/CmpClient.java @@ -23,8 +23,9 @@ package org.onap.aaf.certservice.cmpv2client.api; import java.security.cert.X509Certificate; import java.util.Date; import java.util.List; + import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException; -import org.onap.aaf.certservice.cmpv2client.external.CSRMeta; +import org.onap.aaf.certservice.cmpv2client.external.CsrMeta; /** * This class represent CmpV2Client Interface for obtaining X.509 Digital Certificates in a Public @@ -33,53 +34,53 @@ import org.onap.aaf.certservice.cmpv2client.external.CSRMeta; */ public interface CmpClient { - /** - * Requests for a External Root CA Certificate to be created for the passed public keyPair wrapped - * in a CSRMeta with common details, accepts self-signed certificate. Basic Authentication using - * IAK/RV, Verification of the signature (proof-of-possession) on the request is performed and an - * Exception thrown if verification fails or issue encountered in fetching certificate from CA. - * - * @param caName Information about the External Root Certificate Authority (CA) performing the - * event CA Name. Could be {@code null}. - * @param profile Profile on CA server Client/RA Mode configuration on Server. Could be {@code - * null}. - * @param csrMeta Certificate Signing Request Meta Data. Must not be {@code null}. - * @param csr Certificate Signing Request {.cer} file. Must not be {@code null}. - * @param notBefore An optional validity to set in the created certificate, Certificate not valid - * before this date. - * @param notAfter An optional validity to set in the created certificate, Certificate not valid - * after this date. - * @return {@link X509Certificate} The newly created Certificate. - * @throws CmpClientException if client error occurs. - */ - List> createCertificate( - String caName, - String profile, - CSRMeta csrMeta, - X509Certificate csr, - Date notBefore, - Date notAfter) - throws CmpClientException; + /** + * Requests for a External Root CA Certificate to be created for the passed public keyPair wrapped + * in a CSRMeta with common details, accepts self-signed certificate. Basic Authentication using + * IAK/RV, Verification of the signature (proof-of-possession) on the request is performed and an + * Exception thrown if verification fails or issue encountered in fetching certificate from CA. + * + * @param caName Information about the External Root Certificate Authority (CA) performing the + * event CA Name. Could be {@code null}. + * @param profile Profile on CA server Client/RA Mode configuration on Server. Could be {@code + * null}. + * @param csrMeta Certificate Signing Request Meta Data. Must not be {@code null}. + * @param csr Certificate Signing Request {.cer} file. Must not be {@code null}. + * @param notBefore An optional validity to set in the created certificate, Certificate not valid + * before this date. + * @param notAfter An optional validity to set in the created certificate, Certificate not valid + * after this date. + * @return {@link X509Certificate} The newly created Certificate. + * @throws CmpClientException if client error occurs. + */ + List> createCertificate( + String caName, + String profile, + CsrMeta csrMeta, + X509Certificate csr, + Date notBefore, + Date notAfter) + throws CmpClientException; - /** - * Requests for a External Root CA Certificate to be created for the passed public keyPair wrapped - * in a CSRMeta with common details, accepts self-signed certificate. Basic Authentication using - * IAK/RV, Verification of the signature (proof-of-possession) on the request is performed and an - * Exception thrown if verification fails or issue encountered in fetching certificate from CA. - * - * @param caName Information about the External Root Certificate Authority (CA) performing the - * event CA Name. Could be {@code null}. - * @param profile Profile on CA server Client/RA Mode configuration on Server. Could be {@code - * null}. - * @param csrMeta Certificate Signing Request Meta Data. Must not be {@code null}. - * @param csr Certificate Signing Request {.cer} file. Must not be {@code null}. - * @return {@link X509Certificate} The newly created Certificate. - * @throws CmpClientException if client error occurs. - */ - List> createCertificate( - String caName, - String profile, - CSRMeta csrMeta, - X509Certificate csr) - throws CmpClientException; + /** + * Requests for a External Root CA Certificate to be created for the passed public keyPair wrapped + * in a CSRMeta with common details, accepts self-signed certificate. Basic Authentication using + * IAK/RV, Verification of the signature (proof-of-possession) on the request is performed and an + * Exception thrown if verification fails or issue encountered in fetching certificate from CA. + * + * @param caName Information about the External Root Certificate Authority (CA) performing the + * event CA Name. Could be {@code null}. + * @param profile Profile on CA server Client/RA Mode configuration on Server. Could be {@code + * null}. + * @param csrMeta Certificate Signing Request Meta Data. Must not be {@code null}. + * @param csr Certificate Signing Request {.cer} file. Must not be {@code null}. + * @return {@link X509Certificate} The newly created Certificate. + * @throws CmpClientException if client error occurs. + */ + List> createCertificate( + String caName, + String profile, + CsrMeta csrMeta, + X509Certificate csr) + throws CmpClientException; } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/exceptions/CmpClientException.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/exceptions/CmpClientException.java index 06bdfd80..2a04306a 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/exceptions/CmpClientException.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/exceptions/CmpClientException.java @@ -20,23 +20,31 @@ package org.onap.aaf.certservice.cmpv2client.exceptions; -/** The CmpClientException wraps all exceptions occur internally to Cmpv2Client Api code. */ +/** + * The CmpClientException wraps all exceptions occur internally to Cmpv2Client Api code. + */ public class CmpClientException extends Exception { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - /** Creates a new instance with detail message. */ - public CmpClientException(String message) { - super(message); - } + /** + * Creates a new instance with detail message. + */ + public CmpClientException(String message) { + super(message); + } - /** Creates a new instance with detail Throwable cause. */ - public CmpClientException(Throwable cause) { - super(cause); - } + /** + * Creates a new instance with detail Throwable cause. + */ + public CmpClientException(Throwable cause) { + super(cause); + } - /** Creates a new instance with detail message and Throwable cause. */ - public CmpClientException(String message, Throwable cause) { - super(message, cause); - } + /** + * Creates a new instance with detail message and Throwable cause. + */ + public CmpClientException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/exceptions/PkiErrorException.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/exceptions/PkiErrorException.java index 9e6b9286..62411fbd 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/exceptions/PkiErrorException.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/exceptions/PkiErrorException.java @@ -22,20 +22,26 @@ package org.onap.aaf.certservice.cmpv2client.exceptions; public class PkiErrorException extends Exception { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - /** Creates a new instance with detail message. */ - public PkiErrorException(String message) { - super(message); - } + /** + * Creates a new instance with detail message. + */ + public PkiErrorException(String message) { + super(message); + } - /** Creates a new instance with detail Throwable cause. */ - public PkiErrorException(Throwable cause) { - super(cause); - } + /** + * Creates a new instance with detail Throwable cause. + */ + public PkiErrorException(Throwable cause) { + super(cause); + } - /** Creates a new instance with detail message and Throwable cause. */ - public PkiErrorException(String message, Throwable cause) { - super(message, cause); - } + /** + * Creates a new instance with detail message and Throwable cause. + */ + public PkiErrorException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CSRMeta.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CSRMeta.java deleted file mode 100644 index 470a070f..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CSRMeta.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * ============LICENSE_START==================================================== - * org.onap.aaf - * =========================================================================== - * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. - * - * Modifications Copyright (C) 2019 IBM. - * =========================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END==================================================== - * - */ -package org.onap.aaf.certservice.cmpv2client.external; - -import java.security.KeyPair; -import java.util.ArrayList; -import java.util.List; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x500.X500NameBuilder; -import org.bouncycastle.asn1.x500.style.BCStyle; -import org.bouncycastle.asn1.x509.Certificate; - -public class CSRMeta { - - private String cn; - private String mechID; - private String environment; - private String email; - private String challenge; - private String issuerCn; - private String issuerEmail; - private String password; - private String caUrl; - private List rdns; - private ArrayList sanList = new ArrayList<>(); - private KeyPair keyPair; - private X500Name name; - private X500Name issuerName; - private Certificate certificate; - private String senderKid; - - public CSRMeta(List rdns) { - this.rdns = rdns; - } - - public X500Name getX500Name() { - if (name == null) { - X500NameBuilder nameBuilder = new X500NameBuilder(); - nameBuilder.addRDN(BCStyle.CN, cn); - nameBuilder.addRDN(BCStyle.E, email); - if (mechID != null) { - if (environment == null) { - nameBuilder.addRDN(BCStyle.OU, mechID); - } else { - nameBuilder.addRDN(BCStyle.OU, mechID + ':' + environment); - } - } - for (RDN rdn : rdns) { - nameBuilder.addRDN(rdn.getAoi(), rdn.getValue()); - } - name = nameBuilder.build(); - } - return name; - } - - public X500Name getIssuerX500Name() { - if (issuerName == null) { - X500NameBuilder xnb = new X500NameBuilder(); - xnb.addRDN(BCStyle.CN, issuerCn); - if (issuerEmail != null) { - xnb.addRDN(BCStyle.E, issuerEmail); - } - issuerName = xnb.build(); - } - return issuerName; - } - - public void addSan(String v) { - sanList.add(v); - } - - public List getSans() { - return sanList; - } - - public KeyPair getKeyPairOrGenerateIfNull() { - if (keyPair == null) { - keyPair = Factory.generateKeyPair(); - } - return keyPair; - } - - public KeyPair getKeyPair() { - return keyPair; - } - - public void setKeyPair(KeyPair keyPair) { - this.keyPair = keyPair; - } - - public String getCn() { - return cn; - } - - public void setCn(String cn) { - this.cn = cn; - } - - public void setEnvironment(String env) { - environment = env; - } - - public String getEnvironment() { - return environment; - } - - public String getMechID() { - return mechID; - } - - public void setMechID(String mechID) { - this.mechID = mechID; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getChallenge() { - return challenge; - } - - public void setChallenge(String challenge) { - this.challenge = challenge; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getPassword() { - return password; - } - - public void setCertificate(Certificate certificate) { - this.certificate = certificate; - } - - public Certificate getCertificate() { - return certificate; - } - - public void setIssuerCn(String issuerCn) { - this.issuerCn = issuerCn; - } - - public String getCaUrl() { - return caUrl; - } - - public void setCaUrl(String caUrl) { - this.caUrl = caUrl; - } - - public String getSenderKid() { - return senderKid; - } - - public void setSenderKid(String senderKid) { - this.senderKid = senderKid; - } - - public String getIssuerCn() { - return issuerCn; - } - - public String getIssuerEmail() { - return issuerEmail; - } - - public void setIssuerEmail(String issuerEmail) { - this.issuerEmail = issuerEmail; - } - - public void setIssuerName(X500Name issuerName) { - this.issuerName = issuerName; - } - - public void setName(X500Name name) { - this.name = name; - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CsrMeta.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CsrMeta.java new file mode 100644 index 00000000..4c4e784c --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CsrMeta.java @@ -0,0 +1,208 @@ +/* + * ============LICENSE_START==================================================== + * org.onap.aaf + * =========================================================================== + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * + * Modifications Copyright (C) 2019 IBM. + * =========================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END==================================================== + * + */ + +package org.onap.aaf.certservice.cmpv2client.external; + +import java.security.KeyPair; +import java.util.ArrayList; +import java.util.List; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.X500NameBuilder; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.asn1.x509.Certificate; + +public class CsrMeta { + + private String cn; + private String mechID; + private String environment; + private String email; + private String challenge; + private String issuerCn; + private String issuerEmail; + private String password; + private String caUrl; + private List rdns; + private ArrayList sanList = new ArrayList<>(); + private KeyPair keyPair; + private X500Name name; + private X500Name issuerName; + private Certificate certificate; + private String senderKid; + + public CsrMeta(List rdns) { + this.rdns = rdns; + } + + public X500Name getX500Name() { + if (name == null) { + X500NameBuilder nameBuilder = new X500NameBuilder(); + nameBuilder.addRDN(BCStyle.CN, cn); + nameBuilder.addRDN(BCStyle.E, email); + if (mechID != null) { + if (environment == null) { + nameBuilder.addRDN(BCStyle.OU, mechID); + } else { + nameBuilder.addRDN(BCStyle.OU, mechID + ':' + environment); + } + } + for (Rdn rdn : rdns) { + nameBuilder.addRDN(rdn.getAoi(), rdn.getValue()); + } + name = nameBuilder.build(); + } + return name; + } + + public X500Name getIssuerX500Name() { + if (issuerName == null) { + X500NameBuilder xnb = new X500NameBuilder(); + xnb.addRDN(BCStyle.CN, issuerCn); + if (issuerEmail != null) { + xnb.addRDN(BCStyle.E, issuerEmail); + } + issuerName = xnb.build(); + } + return issuerName; + } + + public void addSan(String san) { + sanList.add(san); + } + + public List getSans() { + return sanList; + } + + public KeyPair getKeyPairOrGenerateIfNull() { + if (keyPair == null) { + keyPair = Factory.generateKeyPair(); + } + return keyPair; + } + + public KeyPair getKeyPair() { + return keyPair; + } + + public void setKeyPair(KeyPair keyPair) { + this.keyPair = keyPair; + } + + public String getCn() { + return cn; + } + + public void setCn(String cn) { + this.cn = cn; + } + + public void setEnvironment(String env) { + environment = env; + } + + public String getEnvironment() { + return environment; + } + + public String getMechID() { + return mechID; + } + + public void setMechID(String mechID) { + this.mechID = mechID; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getChallenge() { + return challenge; + } + + public void setChallenge(String challenge) { + this.challenge = challenge; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } + + public void setCertificate(Certificate certificate) { + this.certificate = certificate; + } + + public Certificate getCertificate() { + return certificate; + } + + public void setIssuerCn(String issuerCn) { + this.issuerCn = issuerCn; + } + + public String getCaUrl() { + return caUrl; + } + + public void setCaUrl(String caUrl) { + this.caUrl = caUrl; + } + + public String getSenderKid() { + return senderKid; + } + + public void setSenderKid(String senderKid) { + this.senderKid = senderKid; + } + + public String getIssuerCn() { + return issuerCn; + } + + public String getIssuerEmail() { + return issuerEmail; + } + + public void setIssuerEmail(String issuerEmail) { + this.issuerEmail = issuerEmail; + } + + public void setIssuerName(X500Name issuerName) { + this.issuerName = issuerName; + } + + public void setName(X500Name name) { + this.name = name; + } +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Factory.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Factory.java index e570f9ab..9e95ab2f 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Factory.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Factory.java @@ -20,6 +20,7 @@ * ============LICENSE_END==================================================== * */ + package org.onap.aaf.certservice.cmpv2client.external; import org.slf4j.Logger; @@ -30,30 +31,31 @@ import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; -public class Factory { +public final class Factory { private static final Logger LOGGER = LoggerFactory.getLogger(Factory.class); - private static final KeyPairGenerator keygen; - private static final SecureRandom random; + private static final KeyPairGenerator KEY_PAIR_GENERATOR; + private static final SecureRandom SECURE_RANDOM; private static final String KEY_ALGORITHM = "RSA"; private static final int KEY_LENGTH = 2048; static { - random = new SecureRandom(); + SECURE_RANDOM = new SecureRandom(); KeyPairGenerator tempKeygen; try { tempKeygen = KeyPairGenerator.getInstance(KEY_ALGORITHM); - tempKeygen.initialize(KEY_LENGTH, random); + tempKeygen.initialize(KEY_LENGTH, SECURE_RANDOM); } catch (NoSuchAlgorithmException e) { tempKeygen = null; LOGGER.error("Given KEY_ALGORITHM is invalid.", e); } - keygen = tempKeygen; + KEY_PAIR_GENERATOR = tempKeygen; } - private Factory() { } + private Factory() { + } public static KeyPair generateKeyPair() { - return keygen.generateKeyPair(); + return KEY_PAIR_GENERATOR.generateKeyPair(); } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/RDN.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/RDN.java deleted file mode 100644 index 229fd76b..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/RDN.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * ============LICENSE_START==================================================== - * org.onap.aaf - * =========================================================================== - * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. - * - * Modifications Copyright (C) 2019 IBM. - * =========================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END==================================================== - * - */ -package org.onap.aaf.certservice.cmpv2client.external; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.x500.style.BCStyle; -import org.bouncycastle.cert.CertException; - -public class RDN { - - private String tag; - private String value; - private ASN1ObjectIdentifier aoi; - - public String getValue() { - return value; - } - - public ASN1ObjectIdentifier getAoi() { - return aoi; - } - - public RDN(final String tag, final String value) throws CertException { - this.tag = tag; - this.value = value; - this.aoi = getAoi(tag); - } - - public RDN(final String tagValue) throws CertException { - List tv = parseRDN("=", tagValue); - this.tag = tv.get(0); - this.value = tv.get(1); - this.aoi = getAoi(this.tag); - } - - /** - * Splits RDN as string by given delimiter, then trims every part. - * - * @param splitBy Delimiter which splits value - * @param value Value to be splitted - * @return List of splitted and trimmed strings - */ - public static List parseRDN(String splitBy, String value) { - String[] splitted = value.split(splitBy); - return Arrays.stream(splitted) - .map(String::trim) - .collect(Collectors.toList()); - } - /** - * Parse various forms of DNs into appropriate RDNs, which have the ASN1ObjectIdentifier - * - * @param delim - * @param dnString - * @return - * @throws CertException - */ - - public static List parse(final char delim, final String dnString) throws CertException { - List lrnd = new ArrayList<>(); - StringBuilder sb = new StringBuilder(); - boolean inQuotes = false; - for (int i = 0; i < dnString.length(); ++i) { - char c = dnString.charAt(i); - if (inQuotes) { - if ('"' == c) { - inQuotes = false; - } else { - sb.append(dnString.charAt(i)); - } - } else { - if ('"' == c) { - inQuotes = true; - } else if (delim == c) { - if (sb.length() > 0) { - lrnd.add(new RDN(sb.toString())); - sb.setLength(0); - } - } else { - sb.append(dnString.charAt(i)); - } - } - } - if (sb.indexOf("=") > 0) { - lrnd.add(new RDN(sb.toString())); - } - return lrnd; - } - - @Override - public String toString() { - return tag + '=' + value; - } - - ASN1ObjectIdentifier getAoi(String tag) throws CertException { - switch (tag.toLowerCase()) { - case "cn": - return BCStyle.CN; - case "c": - return BCStyle.C; - case "st": - return BCStyle.ST; - case "l": - return BCStyle.L; - case "o": - return BCStyle.O; - case "ou": - return BCStyle.OU; - case "dc": - return BCStyle.DC; - case "gn": - return BCStyle.GIVENNAME; - case "sn": - return BCStyle.SN; - case "email": - case "e": - case "emailaddress": - return BCStyle.EmailAddress; - case "initials": - return BCStyle.INITIALS; - case "pseudonym": - return BCStyle.PSEUDONYM; - case "generationqualifier": - return BCStyle.GENERATION; - case "serialnumber": - return BCStyle.SERIALNUMBER; - default: - throw new CertException( - "Unknown ASN1ObjectIdentifier for tag " + tag); - } - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Rdn.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Rdn.java new file mode 100644 index 00000000..25017b8a --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Rdn.java @@ -0,0 +1,157 @@ +/* + * ============LICENSE_START==================================================== + * org.onap.aaf + * =========================================================================== + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * + * Modifications Copyright (C) 2019 IBM. + * =========================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END==================================================== + * + */ + +package org.onap.aaf.certservice.cmpv2client.external; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.cert.CertException; + +public class Rdn { + + private String tag; + private String value; + private ASN1ObjectIdentifier aoi; + + public String getValue() { + return value; + } + + public Rdn(final String tag, final String value) throws CertException { + this.tag = tag; + this.value = value; + this.aoi = getAoi(tag); + } + + public Rdn(final String tagValue) throws CertException { + List tv = parseRdn("=", tagValue); + this.tag = tv.get(0); + this.value = tv.get(1); + this.aoi = getAoi(this.tag); + } + + /** + * Splits RDN as string by given delimiter, then trims every part. + * + * @param splitBy Delimiter which splits value + * @param value Value to be splitted + * @return List of splitted and trimmed strings + */ + static List parseRdn(String splitBy, String value) { + String[] splitted = value.split(splitBy); + return Arrays.stream(splitted) + .map(String::trim) + .collect(Collectors.toList()); + } + /** + * Parse various forms of DNs into appropriate RDNs, which have the ASN1ObjectIdentifier + * + * @param delim + * @param dnString + * @return + * @throws CertException + */ + + public static List parse(final char delim, final String dnString) throws CertException { + List lrnd = new ArrayList<>(); + StringBuilder sb = new StringBuilder(); + boolean inQuotes = false; + for (int i = 0; i < dnString.length(); ++i) { + char currentCharacter = dnString.charAt(i); + if (inQuotes) { + if ('"' == currentCharacter) { + inQuotes = false; + } else { + sb.append(dnString.charAt(i)); + } + } else { + if ('"' == currentCharacter) { + inQuotes = true; + } else if (delim == currentCharacter) { + if (sb.length() > 0) { + lrnd.add(new Rdn(sb.toString())); + sb.setLength(0); + } + } else { + sb.append(dnString.charAt(i)); + } + } + } + if (sb.indexOf("=") > 0) { + lrnd.add(new Rdn(sb.toString())); + } + return lrnd; + } + + @Override + public String toString() { + return tag + '=' + value; + } + + ASN1ObjectIdentifier getAoi() { + return aoi; + } + + ASN1ObjectIdentifier getAoi(String tag) throws CertException { + switch (tag.toLowerCase()) { + case "cn": + return BCStyle.CN; + case "c": + return BCStyle.C; + case "st": + return BCStyle.ST; + case "l": + return BCStyle.L; + case "o": + return BCStyle.O; + case "ou": + return BCStyle.OU; + case "dc": + return BCStyle.DC; + case "gn": + return BCStyle.GIVENNAME; + case "sn": + return BCStyle.SN; + case "email": + case "e": + case "emailaddress": + return BCStyle.EmailAddress; + case "initials": + return BCStyle.INITIALS; + case "pseudonym": + return BCStyle.PSEUDONYM; + case "generationqualifier": + return BCStyle.GENERATION; + case "serialnumber": + return BCStyle.SERIALNUMBER; + default: + throw new CertException( + "Unknown ASN1ObjectIdentifier for tag " + tag); + } + } +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java index e77e8b0f..39a0877c 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java @@ -21,6 +21,7 @@ package org.onap.aaf.certservice.cmpv2client.impl; import java.security.PublicKey; + import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseHelper.checkIfCmpResponseContainsError; import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseHelper.getCertfromByteArray; import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore; @@ -37,6 +38,7 @@ import java.util.Date; import java.util.List; import java.util.Objects; import java.util.Optional; + import org.apache.http.impl.client.CloseableHttpClient; import org.bouncycastle.asn1.cmp.CMPCertificate; import org.bouncycastle.asn1.cmp.CertRepMessage; @@ -47,7 +49,7 @@ import org.bouncycastle.asn1.cmp.PKIMessage; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException; import org.onap.aaf.certservice.cmpv2client.api.CmpClient; -import org.onap.aaf.certservice.cmpv2client.external.CSRMeta; +import org.onap.aaf.certservice.cmpv2client.external.CsrMeta; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,190 +59,190 @@ import org.slf4j.LoggerFactory; */ public class CmpClientImpl implements CmpClient { - private static final Logger LOG = LoggerFactory.getLogger(CmpClientImpl.class); - private final CloseableHttpClient httpClient; - - private static final String DEFAULT_PROFILE = "RA"; - private static final String DEFAULT_CA_NAME = "Certification Authority"; - - public CmpClientImpl(CloseableHttpClient httpClient) { - this.httpClient = httpClient; - } - - @Override - public List> createCertificate( - String caName, - String profile, - CSRMeta csrMeta, - X509Certificate cert, - Date notBefore, - Date notAfter) - throws CmpClientException { - // Validate inputs for Certificate Request - validate(csrMeta, cert, caName, profile, httpClient, notBefore, notAfter); - - final CreateCertRequest certRequest = - CmpMessageBuilder.of(CreateCertRequest::new) - .with(CreateCertRequest::setIssuerDn, csrMeta.getIssuerX500Name()) - .with(CreateCertRequest::setSubjectDn, csrMeta.getX500Name()) - .with(CreateCertRequest::setSansList, csrMeta.getSans()) - .with(CreateCertRequest::setSubjectKeyPair, csrMeta.getKeyPair()) - .with(CreateCertRequest::setNotBefore, notBefore) - .with(CreateCertRequest::setNotAfter, notAfter) - .with(CreateCertRequest::setInitAuthPassword, csrMeta.getPassword()) - .with(CreateCertRequest::setSenderKid, csrMeta.getSenderKid()) - .build(); - - final PKIMessage pkiMessage = certRequest.generateCertReq(); - Cmpv2HttpClient cmpv2HttpClient = new Cmpv2HttpClient(httpClient); - return retrieveCertificates(caName, csrMeta, pkiMessage, cmpv2HttpClient); - } - - @Override - public List> createCertificate( - String caName, String profile, CSRMeta csrMeta, X509Certificate csr) - throws CmpClientException { - return createCertificate(caName, profile, csrMeta, csr, null, null); - } - - private void checkCmpResponse( - final PKIMessage respPkiMessage, final PublicKey publicKey, final String initAuthPassword) - throws CmpClientException { - final PKIHeader header = respPkiMessage.getHeader(); - final AlgorithmIdentifier protectionAlgo = header.getProtectionAlg(); - verifySignatureWithPublicKey(respPkiMessage, publicKey); - verifyProtectionWithProtectionAlgo(respPkiMessage, initAuthPassword, header, protectionAlgo); - } - - private void verifySignatureWithPublicKey(PKIMessage respPkiMessage, PublicKey publicKey) - throws CmpClientException { - if (Objects.nonNull(publicKey)) { - LOG.debug("Verifying signature of the response."); - verifySignature(respPkiMessage, publicKey); - } else { - LOG.error("Public Key is not available, therefore cannot verify signature"); - throw new CmpClientException( - "Public Key is not available, therefore cannot verify signature"); + private static final Logger LOG = LoggerFactory.getLogger(CmpClientImpl.class); + private final CloseableHttpClient httpClient; + + private static final String DEFAULT_PROFILE = "RA"; + private static final String DEFAULT_CA_NAME = "Certification Authority"; + + public CmpClientImpl(CloseableHttpClient httpClient) { + this.httpClient = httpClient; } - } - - private void verifyProtectionWithProtectionAlgo( - PKIMessage respPkiMessage, - String initAuthPassword, - PKIHeader header, - AlgorithmIdentifier protectionAlgo) - throws CmpClientException { - if (Objects.nonNull(protectionAlgo)) { - LOG.debug("Verifying PasswordBased Protection of the Response."); - verifyPasswordBasedProtection(respPkiMessage, initAuthPassword, protectionAlgo); - checkImplicitConfirm(header); - } else { - LOG.error( - "Protection Algorithm is not available when expecting PBE protected response containing protection algorithm"); - throw new CmpClientException( - "Protection Algorithm is not available when expecting PBE protected response containing protection algorithm"); + + @Override + public List> createCertificate( + String caName, + String profile, + CsrMeta csrMeta, + X509Certificate cert, + Date notBefore, + Date notAfter) + throws CmpClientException { + // Validate inputs for Certificate Request + validate(csrMeta, cert, caName, profile, httpClient, notBefore, notAfter); + + final CreateCertRequest certRequest = + CmpMessageBuilder.of(CreateCertRequest::new) + .with(CreateCertRequest::setIssuerDn, csrMeta.getIssuerX500Name()) + .with(CreateCertRequest::setSubjectDn, csrMeta.getX500Name()) + .with(CreateCertRequest::setSansList, csrMeta.getSans()) + .with(CreateCertRequest::setSubjectKeyPair, csrMeta.getKeyPair()) + .with(CreateCertRequest::setNotBefore, notBefore) + .with(CreateCertRequest::setNotAfter, notAfter) + .with(CreateCertRequest::setInitAuthPassword, csrMeta.getPassword()) + .with(CreateCertRequest::setSenderKid, csrMeta.getSenderKid()) + .build(); + + final PKIMessage pkiMessage = certRequest.generateCertReq(); + Cmpv2HttpClient cmpv2HttpClient = new Cmpv2HttpClient(httpClient); + return retrieveCertificates(caName, csrMeta, pkiMessage, cmpv2HttpClient); } - } - - private List> checkCmpCertRepMessage(final PKIMessage respPkiMessage) - throws CmpClientException { - final PKIBody pkiBody = respPkiMessage.getBody(); - if (Objects.nonNull(pkiBody) && pkiBody.getContent() instanceof CertRepMessage) { - final CertRepMessage certRepMessage = (CertRepMessage) pkiBody.getContent(); - if (Objects.nonNull(certRepMessage)) { - final CertResponse certResponse = - getCertificateResponseContainingNewCertificate(certRepMessage); - try { - return verifyReturnCertChainAndTrustStore(respPkiMessage, certRepMessage, certResponse); - } catch (IOException | CertificateParsingException ex) { - CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while retrieving Certificates from response", ex); - LOG.error("Exception occurred while retrieving Certificates from response", ex); - throw cmpClientException; + + @Override + public List> createCertificate( + String caName, String profile, CsrMeta csrMeta, X509Certificate csr) + throws CmpClientException { + return createCertificate(caName, profile, csrMeta, csr, null, null); + } + + private void checkCmpResponse( + final PKIMessage respPkiMessage, final PublicKey publicKey, final String initAuthPassword) + throws CmpClientException { + final PKIHeader header = respPkiMessage.getHeader(); + final AlgorithmIdentifier protectionAlgo = header.getProtectionAlg(); + verifySignatureWithPublicKey(respPkiMessage, publicKey); + verifyProtectionWithProtectionAlgo(respPkiMessage, initAuthPassword, header, protectionAlgo); + } + + private void verifySignatureWithPublicKey(PKIMessage respPkiMessage, PublicKey publicKey) + throws CmpClientException { + if (Objects.nonNull(publicKey)) { + LOG.debug("Verifying signature of the response."); + verifySignature(respPkiMessage, publicKey); + } else { + LOG.error("Public Key is not available, therefore cannot verify signature"); + throw new CmpClientException( + "Public Key is not available, therefore cannot verify signature"); + } + } + + private void verifyProtectionWithProtectionAlgo( + PKIMessage respPkiMessage, + String initAuthPassword, + PKIHeader header, + AlgorithmIdentifier protectionAlgo) + throws CmpClientException { + if (Objects.nonNull(protectionAlgo)) { + LOG.debug("Verifying PasswordBased Protection of the Response."); + verifyPasswordBasedProtection(respPkiMessage, initAuthPassword, protectionAlgo); + checkImplicitConfirm(header); + } else { + LOG.error( + "Protection Algorithm is not available when expecting PBE protected response containing protection algorithm"); + throw new CmpClientException( + "Protection Algorithm is not available when expecting PBE protected response containing protection algorithm"); + } + } + + private List> checkCmpCertRepMessage(final PKIMessage respPkiMessage) + throws CmpClientException { + final PKIBody pkiBody = respPkiMessage.getBody(); + if (Objects.nonNull(pkiBody) && pkiBody.getContent() instanceof CertRepMessage) { + final CertRepMessage certRepMessage = (CertRepMessage) pkiBody.getContent(); + if (Objects.nonNull(certRepMessage)) { + final CertResponse certResponse = + getCertificateResponseContainingNewCertificate(certRepMessage); + try { + return verifyReturnCertChainAndTrustStore(respPkiMessage, certRepMessage, certResponse); + } catch (IOException | CertificateParsingException ex) { + CmpClientException cmpClientException = + new CmpClientException( + "Exception occurred while retrieving Certificates from response", ex); + LOG.error("Exception occurred while retrieving Certificates from response", ex); + throw cmpClientException; + } + } else { + return new ArrayList<>(Collections.emptyList()); + } } - } else { return new ArrayList<>(Collections.emptyList()); - } } - return new ArrayList<>(Collections.emptyList()); - } - - private List> verifyReturnCertChainAndTrustStore( - PKIMessage respPkiMessage, CertRepMessage certRepMessage, CertResponse certResponse) - throws CertificateParsingException, CmpClientException, IOException { - LOG.info("Verifying certificates returned as part of CertResponse."); - final CMPCertificate cmpCertificate = - certResponse.getCertifiedKeyPair().getCertOrEncCert().getCertificate(); - final Optional leafCertificate = - getCertfromByteArray(cmpCertificate.getEncoded(), X509Certificate.class); - if (leafCertificate.isPresent()) { - return verifyAndReturnCertChainAndTrustSTore( - respPkiMessage, certRepMessage, leafCertificate.get()); + + private List> verifyReturnCertChainAndTrustStore( + PKIMessage respPkiMessage, CertRepMessage certRepMessage, CertResponse certResponse) + throws CertificateParsingException, CmpClientException, IOException { + LOG.info("Verifying certificates returned as part of CertResponse."); + final CMPCertificate cmpCertificate = + certResponse.getCertifiedKeyPair().getCertOrEncCert().getCertificate(); + final Optional leafCertificate = + getCertfromByteArray(cmpCertificate.getEncoded(), X509Certificate.class); + if (leafCertificate.isPresent()) { + return verifyAndReturnCertChainAndTrustSTore( + respPkiMessage, certRepMessage, leafCertificate.get()); + } + return Collections.emptyList(); } - return Collections.emptyList(); - } - - private CertResponse getCertificateResponseContainingNewCertificate( - CertRepMessage certRepMessage) { - return certRepMessage.getResponse()[0]; - } - - /** - * Validate inputs for Certificate Creation. - * - * @param csrMeta CSRMeta Object containing variables for creating a Certificate Request. - * @param cert Certificate object needed to validate response from CA server. - * @param incomingCaName Date specifying certificate is not valid before this date. - * @param incomingProfile Date specifying certificate is not valid after this date. - * @throws IllegalArgumentException if Before Date is set after the After Date. - */ - private void validate( - final CSRMeta csrMeta, - final X509Certificate cert, - final String incomingCaName, - final String incomingProfile, - final CloseableHttpClient httpClient, - final Date notBefore, - final Date notAfter) { - - String caName; - String caProfile; - caName = CmpUtil.isNullOrEmpty(incomingCaName) ? incomingCaName : DEFAULT_CA_NAME; - caProfile = CmpUtil.isNullOrEmpty(incomingProfile) ? incomingProfile : DEFAULT_PROFILE; - LOG.info( - "Validate before creating Certificate Request for CA :{} in Mode {} ", caName, caProfile); - - CmpUtil.notNull(csrMeta, "CSRMeta Instance"); - CmpUtil.notNull(csrMeta.getX500Name(), "Subject DN"); - CmpUtil.notNull(csrMeta.getIssuerX500Name(), "Issuer DN"); - CmpUtil.notNull(csrMeta.getPassword(), "IAK/RV Password"); - CmpUtil.notNull(cert, "Certificate Signing Request (CSR)"); - CmpUtil.notNull(csrMeta.getCaUrl(), "External CA URL"); - CmpUtil.notNull(csrMeta.getKeyPairOrGenerateIfNull(), "Subject KeyPair"); - CmpUtil.notNull(httpClient, "Closeable Http Client"); - - if (notBefore != null && notAfter != null && notBefore.compareTo(notAfter) > 0) { - throw new IllegalArgumentException("Before Date is set after the After Date"); + + private CertResponse getCertificateResponseContainingNewCertificate( + CertRepMessage certRepMessage) { + return certRepMessage.getResponse()[0]; } - } - - private List> retrieveCertificates( - String caName, CSRMeta csrMeta, PKIMessage pkiMessage, Cmpv2HttpClient cmpv2HttpClient) - throws CmpClientException { - final byte[] respBytes = cmpv2HttpClient.postRequest(pkiMessage, csrMeta.getCaUrl(), caName); - try { - final PKIMessage respPkiMessage = PKIMessage.getInstance(respBytes); - LOG.info("Received response from Server"); - checkIfCmpResponseContainsError(respPkiMessage); - checkCmpResponse(respPkiMessage, csrMeta.getKeyPairOrGenerateIfNull().getPublic(), csrMeta.getPassword()); - return checkCmpCertRepMessage(respPkiMessage); - } catch (IllegalArgumentException iae) { - CmpClientException cmpClientException = - new CmpClientException( - "Error encountered while processing response from CA server ", iae); - LOG.error("Error encountered while processing response from CA server ", iae); - throw cmpClientException; + + /** + * Validate inputs for Certificate Creation. + * + * @param csrMeta CSRMeta Object containing variables for creating a Certificate Request. + * @param cert Certificate object needed to validate response from CA server. + * @param incomingCaName Date specifying certificate is not valid before this date. + * @param incomingProfile Date specifying certificate is not valid after this date. + * @throws IllegalArgumentException if Before Date is set after the After Date. + */ + private void validate( + final CsrMeta csrMeta, + final X509Certificate cert, + final String incomingCaName, + final String incomingProfile, + final CloseableHttpClient httpClient, + final Date notBefore, + final Date notAfter) { + + String caName; + String caProfile; + caName = CmpUtil.isNullOrEmpty(incomingCaName) ? incomingCaName : DEFAULT_CA_NAME; + caProfile = CmpUtil.isNullOrEmpty(incomingProfile) ? incomingProfile : DEFAULT_PROFILE; + LOG.info( + "Validate before creating Certificate Request for CA :{} in Mode {} ", caName, caProfile); + + CmpUtil.notNull(csrMeta, "CSRMeta Instance"); + CmpUtil.notNull(csrMeta.getX500Name(), "Subject DN"); + CmpUtil.notNull(csrMeta.getIssuerX500Name(), "Issuer DN"); + CmpUtil.notNull(csrMeta.getPassword(), "IAK/RV Password"); + CmpUtil.notNull(cert, "Certificate Signing Request (CSR)"); + CmpUtil.notNull(csrMeta.getCaUrl(), "External CA URL"); + CmpUtil.notNull(csrMeta.getKeyPairOrGenerateIfNull(), "Subject KeyPair"); + CmpUtil.notNull(httpClient, "Closeable Http Client"); + + if (notBefore != null && notAfter != null && notBefore.compareTo(notAfter) > 0) { + throw new IllegalArgumentException("Before Date is set after the After Date"); + } + } + + private List> retrieveCertificates( + String caName, CsrMeta csrMeta, PKIMessage pkiMessage, Cmpv2HttpClient cmpv2HttpClient) + throws CmpClientException { + final byte[] respBytes = cmpv2HttpClient.postRequest(pkiMessage, csrMeta.getCaUrl(), caName); + try { + final PKIMessage respPkiMessage = PKIMessage.getInstance(respBytes); + LOG.info("Received response from Server"); + checkIfCmpResponseContainsError(respPkiMessage); + checkCmpResponse(respPkiMessage, csrMeta.getKeyPairOrGenerateIfNull().getPublic(), csrMeta.getPassword()); + return checkCmpCertRepMessage(respPkiMessage); + } catch (IllegalArgumentException iae) { + CmpClientException cmpClientException = + new CmpClientException( + "Error encountered while processing response from CA server ", iae); + LOG.error("Error encountered while processing response from CA server ", iae); + throw cmpClientException; + } } - } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageBuilder.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageBuilder.java index 2ab9b2cf..1f370f93 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageBuilder.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageBuilder.java @@ -26,30 +26,32 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; -/** Generic Builder Class for creating CMP Message. */ -public class CmpMessageBuilder { - - private final Supplier instantiator; - private final List> instanceModifiers = new ArrayList<>(); - - public CmpMessageBuilder(Supplier instantiator) { - this.instantiator = instantiator; - } - - public static CmpMessageBuilder of(Supplier instantiator) { - return new CmpMessageBuilder<>(instantiator); - } - - public CmpMessageBuilder with(BiConsumer consumer, U value) { - Consumer c = instance -> consumer.accept(instance, value); - instanceModifiers.add(c); - return this; - } - - public T build() { - T value = instantiator.get(); - instanceModifiers.forEach(modifier -> modifier.accept(value)); - instanceModifiers.clear(); - return value; - } +/** + * Generic Builder Class for creating CMP Message. + */ +public final class CmpMessageBuilder { + + private final Supplier instantiator; + private final List> instanceModifiers = new ArrayList<>(); + + public CmpMessageBuilder(Supplier instantiator) { + this.instantiator = instantiator; + } + + public static CmpMessageBuilder of(Supplier instantiator) { + return new CmpMessageBuilder<>(instantiator); + } + + public CmpMessageBuilder with(BiConsumer consumer, U value) { + Consumer valueConsumer = instance -> consumer.accept(instance, value); + instanceModifiers.add(valueConsumer); + return this; + } + + public T build() { + T value = instantiator.get(); + instanceModifiers.forEach(modifier -> modifier.accept(value)); + instanceModifiers.clear(); + return value; + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageHelper.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageHelper.java index 48b2336f..6fcc5f14 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageHelper.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageHelper.java @@ -37,6 +37,7 @@ import java.util.List; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; + import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; @@ -69,176 +70,177 @@ import org.slf4j.LoggerFactory; public final class CmpMessageHelper { - private static final Logger LOG = LoggerFactory.getLogger(CmpMessageHelper.class); - private static final AlgorithmIdentifier OWF_ALGORITHM = - new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.3.14.3.2.26")); - private static final AlgorithmIdentifier MAC_ALGORITHM = - new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.2.9")); - private static final ASN1ObjectIdentifier PASSWORD_BASED_MAC = - new ASN1ObjectIdentifier("1.2.840.113533.7.66.13"); - - private CmpMessageHelper() {} - - /** - * Creates an Optional Validity, which is used to specify how long the returned cert should be - * valid for. - * - * @param notBefore Date specifying certificate is not valid before this date. - * @param notAfter Date specifying certificate is not valid after this date. - * @return {@link OptionalValidity} that can be set for certificate on external CA. - */ - public static OptionalValidity generateOptionalValidity( - final Date notBefore, final Date notAfter) { - LOG.info("Generating Optional Validity from Date objects"); - ASN1EncodableVector optionalValidityV = new ASN1EncodableVector(); - if (notBefore != null) { - Time nb = new Time(notBefore); - optionalValidityV.add(new DERTaggedObject(true, 0, nb)); + private static final Logger LOG = LoggerFactory.getLogger(CmpMessageHelper.class); + private static final AlgorithmIdentifier OWF_ALGORITHM = + new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.3.14.3.2.26")); + private static final AlgorithmIdentifier MAC_ALGORITHM = + new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.2.9")); + private static final ASN1ObjectIdentifier PASSWORD_BASED_MAC = + new ASN1ObjectIdentifier("1.2.840.113533.7.66.13"); + + private CmpMessageHelper() { } - if (notAfter != null) { - Time na = new Time(notAfter); - optionalValidityV.add(new DERTaggedObject(true, 1, na)); + + /** + * Creates an Optional Validity, which is used to specify how long the returned cert should be + * valid for. + * + * @param notBefore Date specifying certificate is not valid before this date. + * @param notAfter Date specifying certificate is not valid after this date. + * @return {@link OptionalValidity} that can be set for certificate on external CA. + */ + public static OptionalValidity generateOptionalValidity( + final Date notBefore, final Date notAfter) { + LOG.info("Generating Optional Validity from Date objects"); + ASN1EncodableVector optionalValidityV = new ASN1EncodableVector(); + if (notBefore != null) { + Time nb = new Time(notBefore); + optionalValidityV.add(new DERTaggedObject(true, 0, nb)); + } + if (notAfter != null) { + Time na = new Time(notAfter); + optionalValidityV.add(new DERTaggedObject(true, 1, na)); + } + return OptionalValidity.getInstance(new DERSequence(optionalValidityV)); } - return OptionalValidity.getInstance(new DERSequence(optionalValidityV)); - } - - /** - * Create Extensions from Subject Alternative Names. - * - * @return {@link Extensions}. - */ - public static Extensions generateExtension(final List sansList) - throws CmpClientException { - LOG.info("Generating Extensions from Subject Alternative Names"); - final ExtensionsGenerator extGenerator = new ExtensionsGenerator(); - final GeneralName[] sansGeneralNames = getGeneralNames(sansList); - // KeyUsage - try { - final KeyUsage keyUsage = - new KeyUsage( - KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.nonRepudiation); - extGenerator.addExtension(Extension.keyUsage, false, new DERBitString(keyUsage)); - extGenerator.addExtension( - Extension.subjectAlternativeName, false, new GeneralNames(sansGeneralNames)); - } catch (IOException ioe) { - CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while creating extensions for PKIMessage", ioe); - LOG.error("Exception occurred while creating extensions for PKIMessage"); - throw cmpClientException; + + /** + * Create Extensions from Subject Alternative Names. + * + * @return {@link Extensions}. + */ + public static Extensions generateExtension(final List sansList) + throws CmpClientException { + LOG.info("Generating Extensions from Subject Alternative Names"); + final ExtensionsGenerator extGenerator = new ExtensionsGenerator(); + final GeneralName[] sansGeneralNames = getGeneralNames(sansList); + // KeyUsage + try { + final KeyUsage keyUsage = + new KeyUsage( + KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.nonRepudiation); + extGenerator.addExtension(Extension.keyUsage, false, new DERBitString(keyUsage)); + extGenerator.addExtension( + Extension.subjectAlternativeName, false, new GeneralNames(sansGeneralNames)); + } catch (IOException ioe) { + CmpClientException cmpClientException = + new CmpClientException( + "Exception occurred while creating extensions for PKIMessage", ioe); + LOG.error("Exception occurred while creating extensions for PKIMessage"); + throw cmpClientException; + } + return extGenerator.generate(); } - return extGenerator.generate(); - } - public static GeneralName[] getGeneralNames(List sansList) { - final List nameList = new ArrayList<>(); - for (String san : sansList) { - nameList.add(new GeneralName(GeneralName.dNSName, san)); + public static GeneralName[] getGeneralNames(List sansList) { + final List nameList = new ArrayList<>(); + for (String san : sansList) { + nameList.add(new GeneralName(GeneralName.dNSName, san)); + } + final GeneralName[] sansGeneralNames = new GeneralName[nameList.size()]; + nameList.toArray(sansGeneralNames); + return sansGeneralNames; } - final GeneralName[] sansGeneralNames = new GeneralName[nameList.size()]; - nameList.toArray(sansGeneralNames); - return sansGeneralNames; - } - - /** - * Method generates Proof-of-Possession (POP) of Private Key. To allow a CA/RA to properly - * validity binding between an End Entity and a Key Pair, the PKI Operations specified here make - * it possible for an End Entity to prove that it has possession of the Private Key corresponding - * to the Public Key for which a Certificate is requested. - * - * @param certRequest Certificate request that requires proof of possession - * @param keypair keypair associated with the subject sending the certificate request - * @return {@link ProofOfPossession}. - * @throws CmpClientException A general-purpose Cmp client exception. - */ - public static ProofOfPossession generateProofOfPossession( - final CertRequest certRequest, final KeyPair keypair) throws CmpClientException { - ProofOfPossession proofOfPossession; - try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { - final DEROutputStream derOutputStream = new DEROutputStream(byteArrayOutputStream); - derOutputStream.writeObject(certRequest); - - byte[] popoProtectionBytes = byteArrayOutputStream.toByteArray(); - final String sigalg = PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(); - final Signature signature = Signature.getInstance(sigalg, BouncyCastleProvider.PROVIDER_NAME); - signature.initSign(keypair.getPrivate()); - signature.update(popoProtectionBytes); - DERBitString bs = new DERBitString(signature.sign()); - - proofOfPossession = - new ProofOfPossession( - new POPOSigningKey( - null, new AlgorithmIdentifier(new ASN1ObjectIdentifier(sigalg)), bs)); - } catch (IOException - | NoSuchProviderException - | NoSuchAlgorithmException - | InvalidKeyException - | SignatureException ex) { - CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while creating proof of possession for PKIMessage", ex); - LOG.error("Exception occurred while creating proof of possession for PKIMessage"); - throw cmpClientException; + + /** + * Method generates Proof-of-Possession (POP) of Private Key. To allow a CA/RA to properly + * validity binding between an End Entity and a Key Pair, the PKI Operations specified here make + * it possible for an End Entity to prove that it has possession of the Private Key corresponding + * to the Public Key for which a Certificate is requested. + * + * @param certRequest Certificate request that requires proof of possession + * @param keypair keypair associated with the subject sending the certificate request + * @return {@link ProofOfPossession}. + * @throws CmpClientException A general-purpose Cmp client exception. + */ + public static ProofOfPossession generateProofOfPossession( + final CertRequest certRequest, final KeyPair keypair) throws CmpClientException { + ProofOfPossession proofOfPossession; + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + final DEROutputStream derOutputStream = new DEROutputStream(byteArrayOutputStream); + derOutputStream.writeObject(certRequest); + + byte[] popoProtectionBytes = byteArrayOutputStream.toByteArray(); + final String sigalg = PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(); + final Signature signature = Signature.getInstance(sigalg, BouncyCastleProvider.PROVIDER_NAME); + signature.initSign(keypair.getPrivate()); + signature.update(popoProtectionBytes); + DERBitString bs = new DERBitString(signature.sign()); + + proofOfPossession = + new ProofOfPossession( + new POPOSigningKey( + null, new AlgorithmIdentifier(new ASN1ObjectIdentifier(sigalg)), bs)); + } catch (IOException + | NoSuchProviderException + | NoSuchAlgorithmException + | InvalidKeyException + | SignatureException ex) { + CmpClientException cmpClientException = + new CmpClientException( + "Exception occurred while creating proof of possession for PKIMessage", ex); + LOG.error("Exception occurred while creating proof of possession for PKIMessage"); + throw cmpClientException; + } + return proofOfPossession; } - return proofOfPossession; - } - - /** - * Generic code to create Algorithm Identifier for protection of PKIMessage. - * - * @return Algorithm Identifier - */ - public static AlgorithmIdentifier protectionAlgoIdentifier(int iterations, byte[] salt) { - ASN1Integer iteration = new ASN1Integer(iterations); - DEROctetString derSalt = new DEROctetString(salt); - - PBMParameter pp = new PBMParameter(derSalt, OWF_ALGORITHM, iteration, MAC_ALGORITHM); - return new AlgorithmIdentifier(PASSWORD_BASED_MAC, pp); - } - - /** - * Adds protection to the PKIMessage via a specified protection algorithm. - * - * @param password password used to authenticate PkiMessage with external CA - * @param pkiHeader Header of PKIMessage containing generic details for any PKIMessage - * @param pkiBody Body of PKIMessage containing specific details for certificate request - * @return Protected Pki Message - * @throws CmpClientException Wraps several exceptions into one general-purpose exception. - */ - public static PKIMessage protectPkiMessage( - PKIHeader pkiHeader, PKIBody pkiBody, String password, int iterations, byte[] salt) - throws CmpClientException { - - byte[] raSecret = password.getBytes(); - byte[] basekey = new byte[raSecret.length + salt.length]; - System.arraycopy(raSecret, 0, basekey, 0, raSecret.length); - System.arraycopy(salt, 0, basekey, raSecret.length, salt.length); - byte[] out; - try { - MessageDigest dig = - MessageDigest.getInstance( - OWF_ALGORITHM.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME); - for (int i = 0; i < iterations; i++) { - basekey = dig.digest(basekey); - dig.reset(); - } - byte[] protectedBytes = generateProtectedBytes(pkiHeader, pkiBody); - Mac mac = - Mac.getInstance(MAC_ALGORITHM.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME); - SecretKey key = new SecretKeySpec(basekey, MAC_ALGORITHM.getAlgorithm().getId()); - mac.init(key); - mac.reset(); - mac.update(protectedBytes, 0, protectedBytes.length); - out = mac.doFinal(); - } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException ex) { - CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while generating proof of possession for PKIMessage", ex); - LOG.error("Exception occured while generating the proof of possession for PKIMessage"); - throw cmpClientException; + + /** + * Generic code to create Algorithm Identifier for protection of PKIMessage. + * + * @return Algorithm Identifier + */ + public static AlgorithmIdentifier protectionAlgoIdentifier(int iterations, byte[] salt) { + ASN1Integer iteration = new ASN1Integer(iterations); + DEROctetString derSalt = new DEROctetString(salt); + + PBMParameter pp = new PBMParameter(derSalt, OWF_ALGORITHM, iteration, MAC_ALGORITHM); + return new AlgorithmIdentifier(PASSWORD_BASED_MAC, pp); } - DERBitString bs = new DERBitString(out); - return new PKIMessage(pkiHeader, pkiBody, bs); - } + /** + * Adds protection to the PKIMessage via a specified protection algorithm. + * + * @param password password used to authenticate PkiMessage with external CA + * @param pkiHeader Header of PKIMessage containing generic details for any PKIMessage + * @param pkiBody Body of PKIMessage containing specific details for certificate request + * @return Protected Pki Message + * @throws CmpClientException Wraps several exceptions into one general-purpose exception. + */ + public static PKIMessage protectPkiMessage( + PKIHeader pkiHeader, PKIBody pkiBody, String password, int iterations, byte[] salt) + throws CmpClientException { + + byte[] raSecret = password.getBytes(); + byte[] basekey = new byte[raSecret.length + salt.length]; + System.arraycopy(raSecret, 0, basekey, 0, raSecret.length); + System.arraycopy(salt, 0, basekey, raSecret.length, salt.length); + byte[] out; + try { + MessageDigest dig = + MessageDigest.getInstance( + OWF_ALGORITHM.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME); + for (int i = 0; i < iterations; i++) { + basekey = dig.digest(basekey); + dig.reset(); + } + byte[] protectedBytes = generateProtectedBytes(pkiHeader, pkiBody); + Mac mac = + Mac.getInstance(MAC_ALGORITHM.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME); + SecretKey key = new SecretKeySpec(basekey, MAC_ALGORITHM.getAlgorithm().getId()); + mac.init(key); + mac.reset(); + mac.update(protectedBytes, 0, protectedBytes.length); + out = mac.doFinal(); + } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException ex) { + CmpClientException cmpClientException = + new CmpClientException( + "Exception occurred while generating proof of possession for PKIMessage", ex); + LOG.error("Exception occured while generating the proof of possession for PKIMessage"); + throw cmpClientException; + } + DERBitString bs = new DERBitString(out); + + return new PKIMessage(pkiHeader, pkiBody, bs); + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelper.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelper.java index 60d91c5f..b2a7b29e 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelper.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelper.java @@ -43,6 +43,7 @@ import java.util.Date; import java.util.List; import java.util.Objects; import java.util.Optional; + import org.bouncycastle.asn1.cmp.CMPCertificate; import org.bouncycastle.asn1.cmp.CertRepMessage; import org.bouncycastle.asn1.cmp.ErrorMsgContent; @@ -54,318 +55,319 @@ import org.onap.aaf.certservice.cmpv2client.exceptions.PkiErrorException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class CmpResponseHelper { - - private static final Logger LOG = LoggerFactory.getLogger(CmpResponseHelper.class); +public final class CmpResponseHelper { - private CmpResponseHelper() {} + private static final Logger LOG = LoggerFactory.getLogger(CmpResponseHelper.class); - public static void checkIfCmpResponseContainsError(PKIMessage respPkiMessage) - throws CmpClientException { - if (respPkiMessage.getBody().getType() == PKIBody.TYPE_ERROR) { - final ErrorMsgContent errorMsgContent = - (ErrorMsgContent) respPkiMessage.getBody().getContent(); - PkiErrorException pkiErrorException = - new PkiErrorException( - errorMsgContent.getPKIStatusInfo().getStatusString().getStringAt(0).getString()); - CmpClientException cmpClientException = - new CmpClientException("Error in the PkiMessage response", pkiErrorException); - LOG.error("Error in the PkiMessage response: {} ", pkiErrorException.getMessage()); - throw cmpClientException; + private CmpResponseHelper() { } - } - - /** - * @param cert byte array that contains certificate - * @param returnType the type of Certificate to be returned, for example X509Certificate.class. - * Certificate.class can be used if certificate type is unknown. - * @throws CertificateParsingException if the byte array does not contain a proper certificate. - */ - public static Optional getCertfromByteArray( - byte[] cert, Class returnType) throws CertificateParsingException, CmpClientException { - LOG.debug("Retrieving certificate of type {} from byte array.", returnType); - return getCertfromByteArray(cert, BouncyCastleProvider.PROVIDER_NAME, returnType); - } - /** - * @param cert byte array that contains certificate - * @param provider provider used to generate certificate from bytes - * @param returnType the type of Certificate to be returned, for example X509Certificate.class. - * Certificate.class can be used if certificate type is unknown. - * @throws CertificateParsingException if the byte array does not contain a proper certificate. - */ - public static Optional getCertfromByteArray( - byte[] cert, String provider, Class returnType) - throws CertificateParsingException, CmpClientException { - String prov = provider; - if (provider == null) { - prov = BouncyCastleProvider.PROVIDER_NAME; + public static void checkIfCmpResponseContainsError(PKIMessage respPkiMessage) + throws CmpClientException { + if (respPkiMessage.getBody().getType() == PKIBody.TYPE_ERROR) { + final ErrorMsgContent errorMsgContent = + (ErrorMsgContent) respPkiMessage.getBody().getContent(); + PkiErrorException pkiErrorException = + new PkiErrorException( + errorMsgContent.getPKIStatusInfo().getStatusString().getStringAt(0).getString()); + CmpClientException cmpClientException = + new CmpClientException("Error in the PkiMessage response", pkiErrorException); + LOG.error("Error in the PkiMessage response: {} ", pkiErrorException.getMessage()); + throw cmpClientException; + } } - if (returnType.equals(X509Certificate.class)) { - return parseX509Certificate(prov, cert); + /** + * @param cert byte array that contains certificate + * @param returnType the type of Certificate to be returned, for example X509Certificate.class. + * Certificate.class can be used if certificate type is unknown. + * @throws CertificateParsingException if the byte array does not contain a proper certificate. + */ + public static Optional getCertfromByteArray( + byte[] cert, Class returnType) throws CertificateParsingException, CmpClientException { + LOG.debug("Retrieving certificate of type {} from byte array.", returnType); + return getCertfromByteArray(cert, BouncyCastleProvider.PROVIDER_NAME, returnType); } - return Optional.empty(); - } - /** - * Check the certificate with CA certificate. - * - * @param caCertChain Collection of X509Certificates. May not be null, an empty list or a - * Collection with null entries. - * @throws CmpClientException if verification failed - */ - public static void verify(List caCertChain) throws CmpClientException { - int iterator = 1; - while (iterator < caCertChain.size()) { - verify(caCertChain.get(iterator - 1), caCertChain.get(iterator), null); - iterator += 1; + /** + * @param cert byte array that contains certificate + * @param provider provider used to generate certificate from bytes + * @param returnType the type of Certificate to be returned, for example X509Certificate.class. + * Certificate.class can be used if certificate type is unknown. + * @throws CertificateParsingException if the byte array does not contain a proper certificate. + */ + public static Optional getCertfromByteArray( + byte[] cert, String provider, Class returnType) + throws CertificateParsingException, CmpClientException { + String prov = provider; + if (provider == null) { + prov = BouncyCastleProvider.PROVIDER_NAME; + } + + if (returnType.equals(X509Certificate.class)) { + return parseX509Certificate(prov, cert); + } + return Optional.empty(); } - } - /** - * Check the certificate with CA certificate. - * - * @param certificate X.509 certificate to verify. May not be null. - * @param caCertChain Collection of X509Certificates. May not be null, an empty list or a - * Collection with null entries. - * @param date Date to verify at, or null to use current time. - * @param pkixCertPathCheckers optional PKIXCertPathChecker implementations to use during cert - * path validation - * @throws CmpClientException if certificate could not be validated - */ - public static void verify( - X509Certificate certificate, - X509Certificate caCertChain, - Date date, - PKIXCertPathChecker... pkixCertPathCheckers) - throws CmpClientException { - try { - verifyCertificates(certificate, caCertChain, date, pkixCertPathCheckers); - } catch (CertPathValidatorException cpve) { - CmpClientException cmpClientException = - new CmpClientException( - "Invalid certificate or certificate not issued by specified CA: ", cpve); - LOG.error("Invalid certificate or certificate not issued by specified CA: ", cpve); - throw cmpClientException; - } catch (CertificateException ce) { - CmpClientException cmpClientException = - new CmpClientException("Something was wrong with the supplied certificate", ce); - LOG.error("Something was wrong with the supplied certificate", ce); - throw cmpClientException; - } catch (NoSuchProviderException nspe) { - CmpClientException cmpClientException = - new CmpClientException("BouncyCastle provider not found.", nspe); - LOG.error("BouncyCastle provider not found.", nspe); - throw cmpClientException; - } catch (NoSuchAlgorithmException nsae) { - CmpClientException cmpClientException = - new CmpClientException("Algorithm PKIX was not found.", nsae); - LOG.error("Algorithm PKIX was not found.", nsae); - throw cmpClientException; - } catch (InvalidAlgorithmParameterException iape) { - CmpClientException cmpClientException = - new CmpClientException( - "Either ca certificate chain was empty," - + " or the certificate was on an inappropriate type for a PKIX path checker.", - iape); - LOG.error( - "Either ca certificate chain was empty, " - + "or the certificate was on an inappropriate type for a PKIX path checker.", - iape); - throw cmpClientException; + /** + * Check the certificate with CA certificate. + * + * @param caCertChain Collection of X509Certificates. May not be null, an empty list or a + * Collection with null entries. + * @throws CmpClientException if verification failed + */ + public static void verify(List caCertChain) throws CmpClientException { + int iterator = 1; + while (iterator < caCertChain.size()) { + verify(caCertChain.get(iterator - 1), caCertChain.get(iterator), null); + iterator += 1; + } } - } - public static void verifyCertificates( - X509Certificate certificate, - X509Certificate caCertChain, - Date date, - PKIXCertPathChecker[] pkixCertPathCheckers) - throws CertificateException, NoSuchProviderException, InvalidAlgorithmParameterException, - NoSuchAlgorithmException, CertPathValidatorException { - LOG.debug( - "Verifying certificate {} as part of cert chain with certificate {}", - certificate.getSubjectDN().getName(), - caCertChain.getSubjectDN().getName()); - CertPath cp = getCertPath(certificate); - PKIXParameters params = getPkixParameters(caCertChain, date, pkixCertPathCheckers); - CertPathValidator cpv = - CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); - PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, params); - if (LOG.isDebugEnabled()) { - LOG.debug("Certificate verify result:{} ", result); + /** + * Check the certificate with CA certificate. + * + * @param certificate X.509 certificate to verify. May not be null. + * @param caCertChain Collection of X509Certificates. May not be null, an empty list or a + * Collection with null entries. + * @param date Date to verify at, or null to use current time. + * @param pkixCertPathCheckers optional PKIXCertPathChecker implementations to use during cert + * path validation + * @throws CmpClientException if certificate could not be validated + */ + public static void verify( + X509Certificate certificate, + X509Certificate caCertChain, + Date date, + PKIXCertPathChecker... pkixCertPathCheckers) + throws CmpClientException { + try { + verifyCertificates(certificate, caCertChain, date, pkixCertPathCheckers); + } catch (CertPathValidatorException cpve) { + CmpClientException cmpClientException = + new CmpClientException( + "Invalid certificate or certificate not issued by specified CA: ", cpve); + LOG.error("Invalid certificate or certificate not issued by specified CA: ", cpve); + throw cmpClientException; + } catch (CertificateException ce) { + CmpClientException cmpClientException = + new CmpClientException("Something was wrong with the supplied certificate", ce); + LOG.error("Something was wrong with the supplied certificate", ce); + throw cmpClientException; + } catch (NoSuchProviderException nspe) { + CmpClientException cmpClientException = + new CmpClientException("BouncyCastle provider not found.", nspe); + LOG.error("BouncyCastle provider not found.", nspe); + throw cmpClientException; + } catch (NoSuchAlgorithmException nsae) { + CmpClientException cmpClientException = + new CmpClientException("Algorithm PKIX was not found.", nsae); + LOG.error("Algorithm PKIX was not found.", nsae); + throw cmpClientException; + } catch (InvalidAlgorithmParameterException iape) { + CmpClientException cmpClientException = + new CmpClientException( + "Either ca certificate chain was empty," + + " or the certificate was on an inappropriate type for a PKIX path checker.", + iape); + LOG.error( + "Either ca certificate chain was empty, " + + "or the certificate was on an inappropriate type for a PKIX path checker.", + iape); + throw cmpClientException; + } } - } - public static PKIXParameters getPkixParameters( - X509Certificate caCertChain, Date date, PKIXCertPathChecker[] pkixCertPathCheckers) - throws InvalidAlgorithmParameterException { - TrustAnchor anchor = new TrustAnchor(caCertChain, null); - PKIXParameters params = new PKIXParameters(Collections.singleton(anchor)); - for (final PKIXCertPathChecker pkixCertPathChecker : pkixCertPathCheckers) { - params.addCertPathChecker(pkixCertPathChecker); + public static void verifyCertificates( + X509Certificate certificate, + X509Certificate caCertChain, + Date date, + PKIXCertPathChecker[] pkixCertPathCheckers) + throws CertificateException, NoSuchProviderException, InvalidAlgorithmParameterException, + NoSuchAlgorithmException, CertPathValidatorException { + LOG.debug( + "Verifying certificate {} as part of cert chain with certificate {}", + certificate.getSubjectDN().getName(), + caCertChain.getSubjectDN().getName()); + CertPath cp = getCertPath(certificate); + PKIXParameters params = getPkixParameters(caCertChain, date, pkixCertPathCheckers); + CertPathValidator cpv = + CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); + PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, params); + if (LOG.isDebugEnabled()) { + LOG.debug("Certificate verify result:{} ", result); + } } - params.setRevocationEnabled(false); - params.setDate(date); - return params; - } - public static CertPath getCertPath(X509Certificate certificate) - throws CertificateException, NoSuchProviderException { - ArrayList certlist = new ArrayList<>(); - certlist.add(certificate); - return CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME) - .generateCertPath(certlist); - } + public static PKIXParameters getPkixParameters( + X509Certificate caCertChain, Date date, PKIXCertPathChecker[] pkixCertPathCheckers) + throws InvalidAlgorithmParameterException { + TrustAnchor anchor = new TrustAnchor(caCertChain, null); + PKIXParameters params = new PKIXParameters(Collections.singleton(anchor)); + for (final PKIXCertPathChecker pkixCertPathChecker : pkixCertPathCheckers) { + params.addCertPathChecker(pkixCertPathChecker); + } + params.setRevocationEnabled(false); + params.setDate(date); + return params; + } - /** - * Parse a X509Certificate from an array of bytes - * - * @param provider a provider name - * @param cert a byte array containing an encoded certificate - * @return a decoded X509Certificate - * @throws CertificateParsingException if the byte array wasn't valid, or contained a certificate - * other than an X509 Certificate. - */ - public static Optional parseX509Certificate(String provider, byte[] cert) - throws CertificateParsingException, CmpClientException { - LOG.debug("Parsing X509Certificate from bytes with provider {}", provider); - final CertificateFactory cf = getCertificateFactory(provider); - X509Certificate result; - try { - result = - (X509Certificate) - Objects.requireNonNull(cf).generateCertificate(new ByteArrayInputStream(cert)); - } catch (CertificateException ce) { - throw new CertificateParsingException("Could not parse byte array as X509Certificate ", ce); + public static CertPath getCertPath(X509Certificate certificate) + throws CertificateException, NoSuchProviderException { + ArrayList certlist = new ArrayList<>(); + certlist.add(certificate); + return CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME) + .generateCertPath(certlist); } - if (result != null) { - return Optional.of(result); - } else { - throw new CertificateParsingException("Could not parse byte array as X509Certificate."); + + /** + * Parse a X509Certificate from an array of bytes + * + * @param provider a provider name + * @param cert a byte array containing an encoded certificate + * @return a decoded X509Certificate + * @throws CertificateParsingException if the byte array wasn't valid, or contained a certificate + * other than an X509 Certificate. + */ + public static Optional parseX509Certificate(String provider, byte[] cert) + throws CertificateParsingException, CmpClientException { + LOG.debug("Parsing X509Certificate from bytes with provider {}", provider); + final CertificateFactory cf = getCertificateFactory(provider); + X509Certificate result; + try { + result = + (X509Certificate) + Objects.requireNonNull(cf).generateCertificate(new ByteArrayInputStream(cert)); + } catch (CertificateException ce) { + throw new CertificateParsingException("Could not parse byte array as X509Certificate ", ce); + } + if (result != null) { + return Optional.of(result); + } else { + throw new CertificateParsingException("Could not parse byte array as X509Certificate."); + } } - } - /** - * Returns a CertificateFactory that can be used to create certificates from byte arrays and such. - * - * @param provider Security provider that should be used to create certificates, default BC is - * null is passed. - * @return CertificateFactory for creating certificate - */ - public static CertificateFactory getCertificateFactory(final String provider) - throws CmpClientException { - LOG.debug("Creating certificate Factory to generate certificate using provider {}", provider); - final String prov; - prov = Objects.requireNonNullElse(provider, BouncyCastleProvider.PROVIDER_NAME); - try { - return CertificateFactory.getInstance("X.509", prov); - } catch (NoSuchProviderException nspe) { - CmpClientException cmpClientException = new CmpClientException("NoSuchProvider: ", nspe); - LOG.error("NoSuchProvider: ", nspe); - throw cmpClientException; - } catch (CertificateException ce) { - CmpClientException cmpClientException = new CmpClientException("CertificateException: ", ce); - LOG.error("CertificateException: ", ce); - throw cmpClientException; + /** + * Returns a CertificateFactory that can be used to create certificates from byte arrays and such. + * + * @param provider Security provider that should be used to create certificates, default BC is + * null is passed. + * @return CertificateFactory for creating certificate + */ + public static CertificateFactory getCertificateFactory(final String provider) + throws CmpClientException { + LOG.debug("Creating certificate Factory to generate certificate using provider {}", provider); + final String prov; + prov = Objects.requireNonNullElse(provider, BouncyCastleProvider.PROVIDER_NAME); + try { + return CertificateFactory.getInstance("X.509", prov); + } catch (NoSuchProviderException nspe) { + CmpClientException cmpClientException = new CmpClientException("NoSuchProvider: ", nspe); + LOG.error("NoSuchProvider: ", nspe); + throw cmpClientException; + } catch (CertificateException ce) { + CmpClientException cmpClientException = new CmpClientException("CertificateException: ", ce); + LOG.error("CertificateException: ", ce); + throw cmpClientException; + } } - } - /** - * puts together certChain and Trust store and verifies the certChain - * - * @param respPkiMessage PKIMessage that may contain extra certs used for certchain - * @param certRepMessage CertRepMessage that should contain rootCA for certchain - * @param leafCertificate certificate returned from our original Cert Request - * @return list of two lists, CertChain and TrustStore - * @throws CertificateParsingException thrown if error occurs while parsing certificate - * @throws IOException thrown if IOException occurs while parsing certificate - * @throws CmpClientException thrown if error occurs during the verification of the certChain - */ - public static List> verifyAndReturnCertChainAndTrustSTore( - PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCertificate) - throws CertificateParsingException, IOException, CmpClientException { - List certChain = - addExtraCertsToChain(respPkiMessage, certRepMessage, leafCertificate); - List certNames = getNamesOfCerts(certChain); - LOG.debug("Verifying the following certificates in the cert chain: {}", certNames); - verify(certChain); - ArrayList trustStore = new ArrayList<>(); - final int rootCaIndex = certChain.size() - 1; - trustStore.add(certChain.get(rootCaIndex)); - certChain.remove(rootCaIndex); - List> listOfArray = new ArrayList<>(); - listOfArray.add(certChain); - listOfArray.add(trustStore); - return listOfArray; - } + /** + * puts together certChain and Trust store and verifies the certChain + * + * @param respPkiMessage PKIMessage that may contain extra certs used for certchain + * @param certRepMessage CertRepMessage that should contain rootCA for certchain + * @param leafCertificate certificate returned from our original Cert Request + * @return list of two lists, CertChain and TrustStore + * @throws CertificateParsingException thrown if error occurs while parsing certificate + * @throws IOException thrown if IOException occurs while parsing certificate + * @throws CmpClientException thrown if error occurs during the verification of the certChain + */ + public static List> verifyAndReturnCertChainAndTrustSTore( + PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCertificate) + throws CertificateParsingException, IOException, CmpClientException { + List certChain = + addExtraCertsToChain(respPkiMessage, certRepMessage, leafCertificate); + List certNames = getNamesOfCerts(certChain); + LOG.debug("Verifying the following certificates in the cert chain: {}", certNames); + verify(certChain); + ArrayList trustStore = new ArrayList<>(); + final int rootCaIndex = certChain.size() - 1; + trustStore.add(certChain.get(rootCaIndex)); + certChain.remove(rootCaIndex); + List> listOfArray = new ArrayList<>(); + listOfArray.add(certChain); + listOfArray.add(trustStore); + return listOfArray; + } - public static List getNamesOfCerts(List certChain) { - List certNames = new ArrayList<>(); - certChain.forEach(cert -> certNames.add(cert.getSubjectDN().getName())); - return certNames; - } + public static List getNamesOfCerts(List certChain) { + List certNames = new ArrayList<>(); + certChain.forEach(cert -> certNames.add(cert.getSubjectDN().getName())); + return certNames; + } - /** - * checks whether PKIMessage contains extracerts to create certchain, if not creates from caPubs - * - * @param respPkiMessage PKIMessage that may contain extra certs used for certchain - * @param certRepMessage CertRepMessage that should contain rootCA for certchain - * @param leafCert certificate at top of certChain. - * @throws CertificateParsingException thrown if error occurs while parsing certificate - * @throws IOException thrown if IOException occurs while parsing certificate - * @throws CmpClientException thrown if there are errors creating CertificateFactory - */ - public static List addExtraCertsToChain( - PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCert) - throws CertificateParsingException, IOException, CmpClientException { - List certChain = new ArrayList<>(); - certChain.add(leafCert); - if (respPkiMessage.getExtraCerts() != null) { - final CMPCertificate[] extraCerts = respPkiMessage.getExtraCerts(); - for (CMPCertificate cmpCert : extraCerts) { - Optional cert = - getCertfromByteArray(cmpCert.getEncoded(), X509Certificate.class); - certChain = - ifCertPresent( - certChain, - cert, - "Adding certificate from extra certs {} to cert chain", - "Couldn't add certificate from extra certs, certificate wasn't an X509Certificate"); - return certChain; - } - } else { - final CMPCertificate respCmpCaCert = getRootCa(certRepMessage); - Optional cert = - getCertfromByteArray(respCmpCaCert.getEncoded(), X509Certificate.class); - certChain = - ifCertPresent( - certChain, - cert, - "Adding certificate from CaPubs {} to TrustStore", - "Couldn't add certificate from CaPubs, certificate wasn't an X509Certificate"); - return certChain; + /** + * checks whether PKIMessage contains extracerts to create certchain, if not creates from caPubs + * + * @param respPkiMessage PKIMessage that may contain extra certs used for certchain + * @param certRepMessage CertRepMessage that should contain rootCA for certchain + * @param leafCert certificate at top of certChain. + * @throws CertificateParsingException thrown if error occurs while parsing certificate + * @throws IOException thrown if IOException occurs while parsing certificate + * @throws CmpClientException thrown if there are errors creating CertificateFactory + */ + public static List addExtraCertsToChain( + PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCert) + throws CertificateParsingException, IOException, CmpClientException { + List certChain = new ArrayList<>(); + certChain.add(leafCert); + if (respPkiMessage.getExtraCerts() != null) { + final CMPCertificate[] extraCerts = respPkiMessage.getExtraCerts(); + for (CMPCertificate cmpCert : extraCerts) { + Optional cert = + getCertfromByteArray(cmpCert.getEncoded(), X509Certificate.class); + certChain = + ifCertPresent( + certChain, + cert, + "Adding certificate from extra certs {} to cert chain", + "Couldn't add certificate from extra certs, certificate wasn't an X509Certificate"); + return certChain; + } + } else { + final CMPCertificate respCmpCaCert = getRootCa(certRepMessage); + Optional cert = + getCertfromByteArray(respCmpCaCert.getEncoded(), X509Certificate.class); + certChain = + ifCertPresent( + certChain, + cert, + "Adding certificate from CaPubs {} to TrustStore", + "Couldn't add certificate from CaPubs, certificate wasn't an X509Certificate"); + return certChain; + } + return Collections.emptyList(); } - return Collections.emptyList(); - } - public static List ifCertPresent( - List certChain, - Optional cert, - String certPresentString, - String certUnavailableString) { - if (cert.isPresent()) { - LOG.debug(certPresentString, cert.get().getSubjectDN().getName()); - certChain.add(cert.get()); - return certChain; - } else { - LOG.debug(certUnavailableString); - return certChain; + public static List ifCertPresent( + List certChain, + Optional cert, + String certPresentString, + String certUnavailableString) { + if (cert.isPresent()) { + LOG.debug(certPresentString, cert.get().getSubjectDN().getName()); + certChain.add(cert.get()); + return certChain; + } else { + LOG.debug(certUnavailableString); + return certChain; + } } - } - private static CMPCertificate getRootCa(CertRepMessage certRepMessage) { - return certRepMessage.getCaPubs()[0]; - } + private static CMPCertificate getRootCa(CertRepMessage certRepMessage) { + return certRepMessage.getCaPubs()[0]; + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseValidationHelper.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseValidationHelper.java index 8191c69d..4b9f2cd1 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseValidationHelper.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseValidationHelper.java @@ -34,6 +34,7 @@ import java.util.Objects; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; + import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; @@ -55,184 +56,186 @@ import org.slf4j.LoggerFactory; public final class CmpResponseValidationHelper { - private static final Logger LOG = LoggerFactory.getLogger(CmpResponseValidationHelper.class); + private static final Logger LOG = LoggerFactory.getLogger(CmpResponseValidationHelper.class); + + private CmpResponseValidationHelper() { + } - private CmpResponseValidationHelper() {} + /** + * Create a base key to use for verifying the PasswordBasedMac on a PKIMessage + * + * @param pbmParamSeq parameters recieved in PKIMessage used with password + * @param initAuthPassword password used to decrypt the basekey + * @return bytes representing the basekey + * @throws CmpClientException thrown if algorithem exceptions occur for the message digest + */ + public static byte[] getBaseKeyFromPbmParameters( + PBMParameter pbmParamSeq, String initAuthPassword) throws CmpClientException { + final int iterationCount = pbmParamSeq.getIterationCount().getPositiveValue().intValue(); + LOG.info("Iteration count is: {}", iterationCount); + final AlgorithmIdentifier owfAlg = pbmParamSeq.getOwf(); + LOG.info("One Way Function type is: {}", owfAlg.getAlgorithm().getId()); + final byte[] salt = pbmParamSeq.getSalt().getOctets(); + final byte[] raSecret = initAuthPassword != null ? initAuthPassword.getBytes() : new byte[0]; + byte[] basekey = new byte[raSecret.length + salt.length]; + System.arraycopy(raSecret, 0, basekey, 0, raSecret.length); + System.arraycopy(salt, 0, basekey, raSecret.length, salt.length); + try { + final MessageDigest messageDigest = + MessageDigest.getInstance( + owfAlg.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME); + for (int i = 0; i < iterationCount; i++) { + basekey = messageDigest.digest(basekey); + messageDigest.reset(); + } + } catch (NoSuchAlgorithmException | NoSuchProviderException ex) { + LOG.error("ProtectionBytes don't match passwordBasedProtection, authentication failed"); + throw new CmpClientException( + "ProtectionBytes don't match passwordBasedProtection, authentication failed", ex); + } + return basekey; + } - /** - * Create a base key to use for verifying the PasswordBasedMac on a PKIMessage - * - * @param pbmParamSeq parameters recieved in PKIMessage used with password - * @param initAuthPassword password used to decrypt the basekey - * @return bytes representing the basekey - * @throws CmpClientException thrown if algorithem exceptions occur for the message digest - */ - public static byte[] getBaseKeyFromPbmParameters( - PBMParameter pbmParamSeq, String initAuthPassword) throws CmpClientException { - final int iterationCount = pbmParamSeq.getIterationCount().getPositiveValue().intValue(); - LOG.info("Iteration count is: {}", iterationCount); - final AlgorithmIdentifier owfAlg = pbmParamSeq.getOwf(); - LOG.info("One Way Function type is: {}", owfAlg.getAlgorithm().getId()); - final byte[] salt = pbmParamSeq.getSalt().getOctets(); - final byte[] raSecret = initAuthPassword != null ? initAuthPassword.getBytes() : new byte[0]; - byte[] basekey = new byte[raSecret.length + salt.length]; - System.arraycopy(raSecret, 0, basekey, 0, raSecret.length); - System.arraycopy(salt, 0, basekey, raSecret.length, salt.length); - try { - final MessageDigest messageDigest = - MessageDigest.getInstance( - owfAlg.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME); - for (int i = 0; i < iterationCount; i++) { - basekey = messageDigest.digest(basekey); - messageDigest.reset(); - } - } catch (NoSuchAlgorithmException | NoSuchProviderException ex) { - LOG.error("ProtectionBytes don't match passwordBasedProtection, authentication failed"); - throw new CmpClientException( - "ProtectionBytes don't match passwordBasedProtection, authentication failed", ex); + /** + * Verifies the signature of the response message using our public key + * + * @param respPkiMessage PKIMessage we wish to verify signature for + * @param pk public key used to verify signature. + * @throws CmpClientException + */ + public static void verifySignature(PKIMessage respPkiMessage, PublicKey pk) + throws CmpClientException { + final byte[] protBytes = getProtectedBytes(respPkiMessage); + final DERBitString derBitString = respPkiMessage.getProtection(); + try { + final Signature signature = + Signature.getInstance( + PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), + BouncyCastleProvider.PROVIDER_NAME); + signature.initVerify(pk); + signature.update(protBytes); + signature.verify(derBitString.getBytes()); + } catch (NoSuchAlgorithmException + | NoSuchProviderException + | InvalidKeyException + | SignatureException e) { + CmpClientException clientException = + new CmpClientException("Signature Verification failed", e); + LOG.error("Signature Verification failed", e); + throw clientException; + } } - return basekey; - } - /** - * Verifies the signature of the response message using our public key - * - * @param respPkiMessage PKIMessage we wish to verify signature for - * @param pk public key used to verify signature. - * @throws CmpClientException - */ - public static void verifySignature(PKIMessage respPkiMessage, PublicKey pk) - throws CmpClientException { - final byte[] protBytes = getProtectedBytes(respPkiMessage); - final DERBitString derBitString = respPkiMessage.getProtection(); - try { - final Signature signature = - Signature.getInstance( - PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), - BouncyCastleProvider.PROVIDER_NAME); - signature.initVerify(pk); - signature.update(protBytes); - signature.verify(derBitString.getBytes()); - } catch (NoSuchAlgorithmException - | NoSuchProviderException - | InvalidKeyException - | SignatureException e) { - CmpClientException clientException = - new CmpClientException("Signature Verification failed", e); - LOG.error("Signature Verification failed", e); - throw clientException; + /** + * Converts the header and the body of a PKIMessage to an ASN1Encodable and returns the as a byte + * array + * + * @param msg PKIMessage to get protected bytes from + * @return the PKIMessage's header and body in byte array + */ + public static byte[] getProtectedBytes(PKIMessage msg) throws CmpClientException { + return getProtectedBytes(msg.getHeader(), msg.getBody()); } - } - /** - * Converts the header and the body of a PKIMessage to an ASN1Encodable and returns the as a byte - * array - * - * @param msg PKIMessage to get protected bytes from - * @return the PKIMessage's header and body in byte array - */ - public static byte[] getProtectedBytes(PKIMessage msg) throws CmpClientException { - return getProtectedBytes(msg.getHeader(), msg.getBody()); - } - /** - * Converts the header and the body of a PKIMessage to an ASN1Encodable and returns the as a byte - * array - * - * @param header PKIHeader to be converted - * @param body PKIMessage to be converted - * @return the PKIMessage's header and body in byte array - */ - public static byte[] getProtectedBytes(PKIHeader header, PKIBody body) throws CmpClientException { - byte[] res; - ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(header); - v.add(body); - ASN1Encodable protectedPart = new DERSequence(v); - try { - ByteArrayOutputStream bao = new ByteArrayOutputStream(); - DEROutputStream out = new DEROutputStream(bao); - out.writeObject(protectedPart); - res = bao.toByteArray(); - } catch (IOException ioe) { - CmpClientException cmpClientException = - new CmpClientException("Error occured while getting protected bytes", ioe); - LOG.error("Error occured while getting protected bytes", ioe); - throw cmpClientException; + /** + * Converts the header and the body of a PKIMessage to an ASN1Encodable and returns the as a byte + * array + * + * @param header PKIHeader to be converted + * @param body PKIMessage to be converted + * @return the PKIMessage's header and body in byte array + */ + public static byte[] getProtectedBytes(PKIHeader header, PKIBody body) throws CmpClientException { + byte[] res; + ASN1EncodableVector encodableVector = new ASN1EncodableVector(); + encodableVector.add(header); + encodableVector.add(body); + ASN1Encodable protectedPart = new DERSequence(encodableVector); + try { + ByteArrayOutputStream bao = new ByteArrayOutputStream(); + DEROutputStream out = new DEROutputStream(bao); + out.writeObject(protectedPart); + res = bao.toByteArray(); + } catch (IOException ioe) { + CmpClientException cmpClientException = + new CmpClientException("Error occured while getting protected bytes", ioe); + LOG.error("Error occured while getting protected bytes", ioe); + throw cmpClientException; + } + return res; } - return res; - } - /** - * verify the password based protection within the response message - * - * @param respPkiMessage PKIMessage we want to verify password based protection for - * @param initAuthPassword password used to decrypt protection - * @param protectionAlgo protection algorithm we can use to decrypt protection - * @throws CmpClientException - */ - public static void verifyPasswordBasedProtection( - PKIMessage respPkiMessage, String initAuthPassword, AlgorithmIdentifier protectionAlgo) - throws CmpClientException { - final byte[] protectedBytes = getProtectedBytes(respPkiMessage); - final PBMParameter pbmParamSeq = PBMParameter.getInstance(protectionAlgo.getParameters()); - if (Objects.nonNull(pbmParamSeq)) { - try { - byte[] basekey = getBaseKeyFromPbmParameters(pbmParamSeq, initAuthPassword); - final Mac mac = getMac(protectedBytes, pbmParamSeq, basekey); - final byte[] outBytes = mac.doFinal(); - final byte[] protectionBytes = respPkiMessage.getProtection().getBytes(); - if (!Arrays.equals(outBytes, protectionBytes)) { - LOG.error("protectionBytes don't match passwordBasedProtection, authentication failed"); - throw new CmpClientException( - "protectionBytes don't match passwordBasedProtection, authentication failed"); + /** + * verify the password based protection within the response message + * + * @param respPkiMessage PKIMessage we want to verify password based protection for + * @param initAuthPassword password used to decrypt protection + * @param protectionAlgo protection algorithm we can use to decrypt protection + * @throws CmpClientException + */ + public static void verifyPasswordBasedProtection( + PKIMessage respPkiMessage, String initAuthPassword, AlgorithmIdentifier protectionAlgo) + throws CmpClientException { + final byte[] protectedBytes = getProtectedBytes(respPkiMessage); + final PBMParameter pbmParamSeq = PBMParameter.getInstance(protectionAlgo.getParameters()); + if (Objects.nonNull(pbmParamSeq)) { + try { + byte[] basekey = getBaseKeyFromPbmParameters(pbmParamSeq, initAuthPassword); + final Mac mac = getMac(protectedBytes, pbmParamSeq, basekey); + final byte[] outBytes = mac.doFinal(); + final byte[] protectionBytes = respPkiMessage.getProtection().getBytes(); + if (!Arrays.equals(outBytes, protectionBytes)) { + LOG.error("protectionBytes don't match passwordBasedProtection, authentication failed"); + throw new CmpClientException( + "protectionBytes don't match passwordBasedProtection, authentication failed"); + } + } catch (NoSuchProviderException | NoSuchAlgorithmException | InvalidKeyException ex) { + CmpClientException cmpClientException = + new CmpClientException("Error while validating CMP response ", ex); + LOG.error("Error while validating CMP response ", ex); + throw cmpClientException; + } } - } catch (NoSuchProviderException | NoSuchAlgorithmException | InvalidKeyException ex) { - CmpClientException cmpClientException = - new CmpClientException("Error while validating CMP response ", ex); - LOG.error("Error while validating CMP response ", ex); - throw cmpClientException; - } } - } - public static void checkImplicitConfirm(PKIHeader header) { - InfoTypeAndValue[] infos = header.getGeneralInfo(); - if (Objects.nonNull(infos)) { - if (CMPObjectIdentifiers.it_implicitConfirm.equals(getImplicitConfirm(infos))) { - LOG.info("Implicit Confirm on certificate from server."); - } else { - LOG.debug("No Implicit confirm in Response"); - } - } else { - LOG.debug("No general Info in header of response, cannot verify implicit confirm"); + public static void checkImplicitConfirm(PKIHeader header) { + InfoTypeAndValue[] infos = header.getGeneralInfo(); + if (Objects.nonNull(infos)) { + if (CMPObjectIdentifiers.it_implicitConfirm.equals(getImplicitConfirm(infos))) { + LOG.info("Implicit Confirm on certificate from server."); + } else { + LOG.debug("No Implicit confirm in Response"); + } + } else { + LOG.debug("No general Info in header of response, cannot verify implicit confirm"); + } } - } - public static ASN1ObjectIdentifier getImplicitConfirm(InfoTypeAndValue[] info) { - return info[0].getInfoType(); - } + public static ASN1ObjectIdentifier getImplicitConfirm(InfoTypeAndValue[] info) { + return info[0].getInfoType(); + } - /** - * Get cryptographical Mac we can use to decrypt our PKIMessage - * - * @param protectedBytes Protected bytes representing the PKIMessage - * @param pbmParamSeq Parameters used to decrypt PKIMessage, including mac algorithm used - * @param basekey Key used alongside mac Oid to create secret key for decrypting PKIMessage - * @return Mac that's ready to return decrypted bytes - * @throws NoSuchAlgorithmException Possibly thrown trying to get mac instance - * @throws NoSuchProviderException Possibly thrown trying to get mac instance - * @throws InvalidKeyException Possibly thrown trying to initialize mac using secretkey - */ - public static Mac getMac(byte[] protectedBytes, PBMParameter pbmParamSeq, byte[] basekey) - throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { - final AlgorithmIdentifier macAlg = pbmParamSeq.getMac(); - LOG.info("Mac type is: {}", macAlg.getAlgorithm().getId()); - final String macOid = macAlg.getAlgorithm().getId(); - final Mac mac = Mac.getInstance(macOid, BouncyCastleProvider.PROVIDER_NAME); - final SecretKey key = new SecretKeySpec(basekey, macOid); - mac.init(key); - mac.reset(); - mac.update(protectedBytes, 0, protectedBytes.length); - return mac; - } + /** + * Get cryptographical Mac we can use to decrypt our PKIMessage + * + * @param protectedBytes Protected bytes representing the PKIMessage + * @param pbmParamSeq Parameters used to decrypt PKIMessage, including mac algorithm used + * @param basekey Key used alongside mac Oid to create secret key for decrypting PKIMessage + * @return Mac that's ready to return decrypted bytes + * @throws NoSuchAlgorithmException Possibly thrown trying to get mac instance + * @throws NoSuchProviderException Possibly thrown trying to get mac instance + * @throws InvalidKeyException Possibly thrown trying to initialize mac using secretkey + */ + public static Mac getMac(byte[] protectedBytes, PBMParameter pbmParamSeq, byte[] basekey) + throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { + final AlgorithmIdentifier macAlg = pbmParamSeq.getMac(); + LOG.info("Mac type is: {}", macAlg.getAlgorithm().getId()); + final String macOid = macAlg.getAlgorithm().getId(); + final Mac mac = Mac.getInstance(macOid, BouncyCastleProvider.PROVIDER_NAME); + final SecretKey key = new SecretKeySpec(basekey, macOid); + mac.init(key); + mac.reset(); + mac.update(protectedBytes, 0, protectedBytes.length); + return mac; + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpUtil.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpUtil.java index 1bda4ac1..ced0fed0 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpUtil.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpUtil.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.security.SecureRandom; import java.util.Date; import java.util.Objects; + import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1GeneralizedTime; @@ -45,105 +46,108 @@ import org.slf4j.LoggerFactory; public final class CmpUtil { - private static final Logger LOGGER = LoggerFactory.getLogger(CmpUtil.class); - private static final SecureRandom secureRandom = new SecureRandom(); + private static final Logger LOGGER = LoggerFactory.getLogger(CmpUtil.class); + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + public static final int RANDOM_BYTE_LENGTH = 16; + public static final int RANDOM_SEED = 1000; - private CmpUtil() {} + private CmpUtil() { + } - /** - * Validates specified object reference is not null. - * - * @param argument T - the type of the reference. - * @param message message - detail message to be used in the event that a NullPointerException is - * thrown. - * @return The Object if not null - */ - public static T notNull(T argument, String message) { - return Objects.requireNonNull(argument, message + " must not be null"); - } + /** + * Validates specified object reference is not null. + * + * @param argument T - the type of the reference. + * @param message message - detail message to be used in the event that a NullPointerException is + * thrown. + * @return The Object if not null + */ + public static T notNull(T argument, String message) { + return Objects.requireNonNull(argument, message + " must not be null"); + } - /** - * Validates String object reference is not null and not empty. - * - * @param stringArg String Object that need to be validated. - * @return boolean - */ - public static boolean isNullOrEmpty(String stringArg) { - return (stringArg != null && !stringArg.trim().isEmpty()); - } + /** + * Validates String object reference is not null and not empty. + * + * @param stringArg String Object that need to be validated. + * @return boolean + */ + public static boolean isNullOrEmpty(String stringArg) { + return (stringArg != null && !stringArg.trim().isEmpty()); + } - /** - * Creates a random number than can be used for sendernonce, transactionId and salts. - * - * @return bytes containing a random number string representing a nonce - */ - static byte[] createRandomBytes() { - LOGGER.info("Generating random array of bytes"); - byte[] randomBytes = new byte[16]; - secureRandom.nextBytes(randomBytes); - return randomBytes; - } + /** + * Creates a random number than can be used for sendernonce, transactionId and salts. + * + * @return bytes containing a random number string representing a nonce + */ + static byte[] createRandomBytes() { + LOGGER.info("Generating random array of bytes"); + byte[] randomBytes = new byte[RANDOM_BYTE_LENGTH]; + SECURE_RANDOM.nextBytes(randomBytes); + return randomBytes; + } - /** - * Creates a random integer than can be used to represent a transactionId or determine the number - * iterations in a protection algorithm. - * - * @return bytes containing a random number string representing a nonce - */ - static int createRandomInt(int range) { - LOGGER.info("Generating random integer"); - return secureRandom.nextInt(range) + 1000; - } + /** + * Creates a random integer than can be used to represent a transactionId or determine the number + * iterations in a protection algorithm. + * + * @return bytes containing a random number string representing a nonce + */ + static int createRandomInt(int range) { + LOGGER.info("Generating random integer"); + return SECURE_RANDOM.nextInt(range) + RANDOM_SEED; + } - /** - * Generates protected bytes of a combined PKIHeader and PKIBody. - * - * @param header Header of PKIMessage containing common parameters - * @param body Body of PKIMessage containing specific information for message - * @return bytes representing the PKIHeader and PKIBody thats to be protected - */ - static byte[] generateProtectedBytes(PKIHeader header, PKIBody body) throws CmpClientException { - LOGGER.info("Generating array of bytes representing PkiHeader and PkiBody"); - byte[] res; - ASN1EncodableVector vector = new ASN1EncodableVector(); - vector.add(header); - vector.add(body); - ASN1Encodable protectedPart = new DERSequence(vector); - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - DEROutputStream out = new DEROutputStream(baos); - out.writeObject(protectedPart); - res = baos.toByteArray(); - } catch (IOException ioe) { - CmpClientException cmpClientException = - new CmpClientException("IOException occurred while creating protectedBytes", ioe); - LOGGER.error("IOException occurred while creating protectedBytes"); - throw cmpClientException; + /** + * Generates protected bytes of a combined PKIHeader and PKIBody. + * + * @param header Header of PKIMessage containing common parameters + * @param body Body of PKIMessage containing specific information for message + * @return bytes representing the PKIHeader and PKIBody thats to be protected + */ + static byte[] generateProtectedBytes(PKIHeader header, PKIBody body) throws CmpClientException { + LOGGER.info("Generating array of bytes representing PkiHeader and PkiBody"); + byte[] res; + ASN1EncodableVector vector = new ASN1EncodableVector(); + vector.add(header); + vector.add(body); + ASN1Encodable protectedPart = new DERSequence(vector); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + DEROutputStream out = new DEROutputStream(baos); + out.writeObject(protectedPart); + res = baos.toByteArray(); + } catch (IOException ioe) { + CmpClientException cmpClientException = + new CmpClientException("IOException occurred while creating protectedBytes", ioe); + LOGGER.error("IOException occurred while creating protectedBytes"); + throw cmpClientException; + } + return res; } - return res; - } - /** - * Generates a PKIHeader Builder object. - * - * @param subjectDn distinguished name of Subject - * @param issuerDn distinguished name of external CA - * @param protectionAlg protection Algorithm used to protect PKIMessage - * @return PKIHeaderBuilder - */ - static PKIHeader generatePkiHeader( - X500Name subjectDn, X500Name issuerDn, AlgorithmIdentifier protectionAlg, String senderKid) { - LOGGER.info("Generating a Pki Header Builder"); - PKIHeaderBuilder pkiHeaderBuilder = - new PKIHeaderBuilder( - PKIHeader.CMP_2000, new GeneralName(subjectDn), new GeneralName(issuerDn)); + /** + * Generates a PKIHeader Builder object. + * + * @param subjectDn distinguished name of Subject + * @param issuerDn distinguished name of external CA + * @param protectionAlg protection Algorithm used to protect PKIMessage + * @return PKIHeaderBuilder + */ + static PKIHeader generatePkiHeader( + X500Name subjectDn, X500Name issuerDn, AlgorithmIdentifier protectionAlg, String senderKid) { + LOGGER.info("Generating a Pki Header Builder"); + PKIHeaderBuilder pkiHeaderBuilder = + new PKIHeaderBuilder( + PKIHeader.CMP_2000, new GeneralName(subjectDn), new GeneralName(issuerDn)); - pkiHeaderBuilder.setMessageTime(new ASN1GeneralizedTime(new Date())); - pkiHeaderBuilder.setSenderNonce(new DEROctetString(createRandomBytes())); - pkiHeaderBuilder.setTransactionID(new DEROctetString(createRandomBytes())); - pkiHeaderBuilder.setProtectionAlg(protectionAlg); - pkiHeaderBuilder.setGeneralInfo(new InfoTypeAndValue(CMPObjectIdentifiers.it_implicitConfirm)); - pkiHeaderBuilder.setSenderKID(new DEROctetString(senderKid.getBytes())); + pkiHeaderBuilder.setMessageTime(new ASN1GeneralizedTime(new Date())); + pkiHeaderBuilder.setSenderNonce(new DEROctetString(createRandomBytes())); + pkiHeaderBuilder.setTransactionID(new DEROctetString(createRandomBytes())); + pkiHeaderBuilder.setProtectionAlg(protectionAlg); + pkiHeaderBuilder.setGeneralInfo(new InfoTypeAndValue(CMPObjectIdentifiers.it_implicitConfirm)); + pkiHeaderBuilder.setSenderKID(new DEROctetString(senderKid.getBytes())); - return pkiHeaderBuilder.build(); - } + return pkiHeaderBuilder.build(); + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/Cmpv2HttpClient.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/Cmpv2HttpClient.java index 682e410d..68c743d2 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/Cmpv2HttpClient.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/Cmpv2HttpClient.java @@ -22,6 +22,7 @@ package org.onap.aaf.certservice.cmpv2client.impl; import java.io.ByteArrayOutputStream; import java.io.IOException; + import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; @@ -33,50 +34,50 @@ import org.slf4j.LoggerFactory; class Cmpv2HttpClient { - private static final Logger LOG = LoggerFactory.getLogger(Cmpv2HttpClient.class); + private static final Logger LOG = LoggerFactory.getLogger(Cmpv2HttpClient.class); - private static final String CONTENT_TYPE = "Content-type"; - private static final String CMP_REQUEST_MIMETYPE = "application/pkixcmp"; - private final CloseableHttpClient httpClient; + private static final String CONTENT_TYPE = "Content-type"; + private static final String CMP_REQUEST_MIMETYPE = "application/pkixcmp"; + private final CloseableHttpClient httpClient; - /** - * constructor for Cmpv2HttpClient - * - * @param httpClient CloseableHttpClient used for sending/recieve request. - */ - public Cmpv2HttpClient(CloseableHttpClient httpClient) { - this.httpClient = httpClient; - } + /** + * constructor for Cmpv2HttpClient + * + * @param httpClient CloseableHttpClient used for sending/recieve request. + */ + Cmpv2HttpClient(CloseableHttpClient httpClient) { + this.httpClient = httpClient; + } - /** - * Send Post Request to Server - * - * @param pkiMessage PKIMessage to send to server - * @param urlString url for the server we're sending request - * @param caName name of CA server - * @return PKIMessage received from CMPServer - * @throws CmpClientException thrown if problems with connecting or parsing response to server - */ - public byte[] postRequest( - final PKIMessage pkiMessage, final String urlString, final String caName) - throws CmpClientException { - try (final ByteArrayOutputStream byteArrOutputStream = new ByteArrayOutputStream()) { - final HttpPost postRequest = new HttpPost(urlString); - final byte[] requestBytes = pkiMessage.getEncoded(); + /** + * Send Post Request to Server + * + * @param pkiMessage PKIMessage to send to server + * @param urlString url for the server we're sending request + * @param caName name of CA server + * @return PKIMessage received from CMPServer + * @throws CmpClientException thrown if problems with connecting or parsing response to server + */ + public byte[] postRequest( + final PKIMessage pkiMessage, final String urlString, final String caName) + throws CmpClientException { + try (ByteArrayOutputStream byteArrOutputStream = new ByteArrayOutputStream()) { + final HttpPost postRequest = new HttpPost(urlString); + final byte[] requestBytes = pkiMessage.getEncoded(); - postRequest.setEntity(new ByteArrayEntity(requestBytes)); - postRequest.setHeader(CONTENT_TYPE, CMP_REQUEST_MIMETYPE); + postRequest.setEntity(new ByteArrayEntity(requestBytes)); + postRequest.setHeader(CONTENT_TYPE, CMP_REQUEST_MIMETYPE); - try (CloseableHttpResponse response = httpClient.execute(postRequest)) { - response.getEntity().writeTo(byteArrOutputStream); - } - return byteArrOutputStream.toByteArray(); - } catch (IOException ioe) { - CmpClientException cmpClientException = - new CmpClientException( - String.format("IOException error while trying to connect CA %s", caName), ioe); - LOG.error("IOException error {}, while trying to connect CA {}", ioe.getMessage(), caName); - throw cmpClientException; + try (CloseableHttpResponse response = httpClient.execute(postRequest)) { + response.getEntity().writeTo(byteArrOutputStream); + } + return byteArrOutputStream.toByteArray(); + } catch (IOException ioe) { + CmpClientException cmpClientException = + new CmpClientException( + String.format("IOException error while trying to connect CA %s", caName), ioe); + LOG.error("IOException error {}, while trying to connect CA {}", ioe.getMessage(), caName); + throw cmpClientException; + } } - } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CreateCertRequest.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CreateCertRequest.java index b185c92a..687c47d1 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CreateCertRequest.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CreateCertRequest.java @@ -27,6 +27,7 @@ import static org.onap.aaf.certservice.cmpv2client.impl.CmpUtil.generatePkiHeade import java.security.KeyPair; import java.util.Date; import java.util.List; + import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.cmp.PKIHeader; @@ -48,88 +49,88 @@ import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException; */ class CreateCertRequest { - private X500Name issuerDn; - private X500Name subjectDn; - private List sansList; - private KeyPair subjectKeyPair; - private Date notBefore; - private Date notAfter; - private String initAuthPassword; - private String senderKid; - - private static final int ITERATIONS = createRandomInt(5000); - private static final byte[] SALT = createRandomBytes(); - private final int certReqId = createRandomInt(Integer.MAX_VALUE); - - public void setIssuerDn(X500Name issuerDn) { - this.issuerDn = issuerDn; - } - - public void setSubjectDn(X500Name subjectDn) { - this.subjectDn = subjectDn; - } - - public void setSansList(List sansList) { - this.sansList = sansList; - } - - public void setSubjectKeyPair(KeyPair subjectKeyPair) { - this.subjectKeyPair = subjectKeyPair; - } - - public void setNotBefore(Date notBefore) { - this.notBefore = notBefore; - } - - public void setNotAfter(Date notAfter) { - this.notAfter = notAfter; - } - - public void setInitAuthPassword(String initAuthPassword) { - this.initAuthPassword = initAuthPassword; - } - - public void setSenderKid(String senderKid) { - this.senderKid = senderKid; - } - - /** - * Method to create {@link PKIMessage} from {@link CertRequest},{@link ProofOfPossession}, {@link - * CertReqMsg}, {@link CertReqMessages}, {@link PKIHeader} and {@link PKIBody}. - * - * @return {@link PKIMessage} - */ - public PKIMessage generateCertReq() throws CmpClientException { - final CertTemplateBuilder certTemplateBuilder = - new CertTemplateBuilder() - .setIssuer(issuerDn) - .setSubject(subjectDn) - .setExtensions(CmpMessageHelper.generateExtension(sansList)) - .setValidity(CmpMessageHelper.generateOptionalValidity(notBefore, notAfter)) - .setPublicKey( - SubjectPublicKeyInfo.getInstance(subjectKeyPair.getPublic().getEncoded())); - - final CertRequest certRequest = new CertRequest(certReqId, certTemplateBuilder.build(), null); - final ProofOfPossession proofOfPossession = - CmpMessageHelper.generateProofOfPossession(certRequest, subjectKeyPair); - - final AttributeTypeAndValue[] attrTypeVal = { - new AttributeTypeAndValue( - CRMFObjectIdentifiers.id_regCtrl_regToken, new DERUTF8String(initAuthPassword)) - }; - - final CertReqMsg certReqMsg = new CertReqMsg(certRequest, proofOfPossession, attrTypeVal); - final CertReqMessages certReqMessages = new CertReqMessages(certReqMsg); - - final PKIHeader pkiHeader = - generatePkiHeader( - subjectDn, - issuerDn, - CmpMessageHelper.protectionAlgoIdentifier(ITERATIONS, SALT), - senderKid); - final PKIBody pkiBody = new PKIBody(PKIBody.TYPE_INIT_REQ, certReqMessages); - - return CmpMessageHelper.protectPkiMessage( - pkiHeader, pkiBody, initAuthPassword, ITERATIONS, SALT); - } + private X500Name issuerDn; + private X500Name subjectDn; + private List sansList; + private KeyPair subjectKeyPair; + private Date notBefore; + private Date notAfter; + private String initAuthPassword; + private String senderKid; + + private static final int ITERATIONS = createRandomInt(5000); + private static final byte[] SALT = createRandomBytes(); + private final int certReqId = createRandomInt(Integer.MAX_VALUE); + + public void setIssuerDn(X500Name issuerDn) { + this.issuerDn = issuerDn; + } + + public void setSubjectDn(X500Name subjectDn) { + this.subjectDn = subjectDn; + } + + public void setSansList(List sansList) { + this.sansList = sansList; + } + + public void setSubjectKeyPair(KeyPair subjectKeyPair) { + this.subjectKeyPair = subjectKeyPair; + } + + public void setNotBefore(Date notBefore) { + this.notBefore = notBefore; + } + + public void setNotAfter(Date notAfter) { + this.notAfter = notAfter; + } + + public void setInitAuthPassword(String initAuthPassword) { + this.initAuthPassword = initAuthPassword; + } + + public void setSenderKid(String senderKid) { + this.senderKid = senderKid; + } + + /** + * Method to create {@link PKIMessage} from {@link CertRequest},{@link ProofOfPossession}, {@link + * CertReqMsg}, {@link CertReqMessages}, {@link PKIHeader} and {@link PKIBody}. + * + * @return {@link PKIMessage} + */ + public PKIMessage generateCertReq() throws CmpClientException { + final CertTemplateBuilder certTemplateBuilder = + new CertTemplateBuilder() + .setIssuer(issuerDn) + .setSubject(subjectDn) + .setExtensions(CmpMessageHelper.generateExtension(sansList)) + .setValidity(CmpMessageHelper.generateOptionalValidity(notBefore, notAfter)) + .setPublicKey( + SubjectPublicKeyInfo.getInstance(subjectKeyPair.getPublic().getEncoded())); + + final CertRequest certRequest = new CertRequest(certReqId, certTemplateBuilder.build(), null); + final ProofOfPossession proofOfPossession = + CmpMessageHelper.generateProofOfPossession(certRequest, subjectKeyPair); + + final AttributeTypeAndValue[] attrTypeVal = { + new AttributeTypeAndValue( + CRMFObjectIdentifiers.id_regCtrl_regToken, new DERUTF8String(initAuthPassword)) + }; + + final CertReqMsg certReqMsg = new CertReqMsg(certRequest, proofOfPossession, attrTypeVal); + final CertReqMessages certReqMessages = new CertReqMessages(certReqMsg); + + final PKIHeader pkiHeader = + generatePkiHeader( + subjectDn, + issuerDn, + CmpMessageHelper.protectionAlgoIdentifier(ITERATIONS, SALT), + senderKid); + final PKIBody pkiBody = new PKIBody(PKIBody.TYPE_INIT_REQ, certReqMessages); + + return CmpMessageHelper.protectPkiMessage( + pkiHeader, pkiBody, initAuthPassword, ITERATIONS, SALT); + } } -- cgit 1.2.3-korg