From 26ef1a575d819de4e1dae9f9044b1ab715f41b13 Mon Sep 17 00:00:00 2001 From: Jan Malkiewicz Date: Tue, 19 Jan 2021 08:16:19 +0100 Subject: [CMPV2] Fix NPE & enhance error messages Fix NPE. Include error messages returned by CMP server in API response. Issue-ID: OOM-2657 Signed-off-by: Jan Malkiewicz Change-Id: I6ec46b14ba04b5be10de5994236efd8fc14c5d2e --- certService/pom.xml | 4 +- .../api/advice/CertificationExceptionAdvice.java | 35 ++++-- .../cmpv2client/exceptions/CmpServerException.java | 28 +++++ .../cmpv2client/impl/CmpClientImpl.java | 36 ++++-- .../cmpv2client/impl/CmpResponseHelper.java | 132 ++++++++++----------- .../certservice/cmpv2client/impl/PkiStatus.java | 37 ++++++ .../advice/CertificationExceptionAdviceTest.java | 27 ++++- .../certservice/cmpv2client/Cmpv2ClientTest.java | 3 +- certServiceClient/pom.xml | 4 +- certServiceK8sExternalProvider/pom.xml | 2 +- certServicePostProcessor/pom.xml | 4 +- docs/sections/change-log.rst | 41 +++++++ pom.xml | 2 +- version.properties | 2 +- 14 files changed, 254 insertions(+), 103 deletions(-) create mode 100644 certService/src/main/java/org/onap/oom/certservice/cmpv2client/exceptions/CmpServerException.java create mode 100644 certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/PkiStatus.java diff --git a/certService/pom.xml b/certService/pom.xml index fa5ca41f..3c9efcaa 100644 --- a/certService/pom.xml +++ b/certService/pom.xml @@ -18,10 +18,10 @@ org.onap.oom.platform.cert-service oom-certservice - 2.3.2-SNAPSHOT + 2.3.3-SNAPSHOT oom-certservice-api - 2.3.2-SNAPSHOT + 2.3.3-SNAPSHOT oom-certservice-api OOM Certification Service Api jar diff --git a/certService/src/main/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdvice.java b/certService/src/main/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdvice.java index 5fb9d2ad..1c6c3a0a 100644 --- a/certService/src/main/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdvice.java +++ b/certService/src/main/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdvice.java @@ -3,6 +3,7 @@ * PROJECT * ================================================================================ * Copyright (C) 2020 Nokia. All rights reserved. + * Copyright (C) 2021 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. @@ -27,6 +28,7 @@ import org.onap.oom.certservice.certification.exception.CsrDecryptionException; import org.onap.oom.certservice.certification.exception.ErrorResponseModel; import org.onap.oom.certservice.certification.exception.KeyDecryptionException; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; +import org.onap.oom.certservice.cmpv2client.exceptions.CmpServerException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -43,8 +45,8 @@ public final class CertificationExceptionAdvice { public ResponseEntity handle(CsrDecryptionException exception) { LOGGER.error("Exception occurred during decoding certificate sign request:", exception); return getErrorResponseEntity( - "Wrong certificate signing request (CSR) format", - HttpStatus.BAD_REQUEST + "Wrong certificate signing request (CSR) format", + HttpStatus.BAD_REQUEST ); } @@ -52,8 +54,8 @@ public final class CertificationExceptionAdvice { public ResponseEntity handle(KeyDecryptionException exception) { LOGGER.error("Exception occurred during decoding key:", exception); return getErrorResponseEntity( - "Wrong key (PK) format", - HttpStatus.BAD_REQUEST + "Wrong key (PK) format", + HttpStatus.BAD_REQUEST ); } @@ -61,8 +63,8 @@ public final class CertificationExceptionAdvice { public ResponseEntity handle(Cmpv2ServerNotFoundException exception) { LOGGER.error("Exception occurred selecting CMPv2 server:", exception); return getErrorResponseEntity( - "Certification authority not found for given CAName", - HttpStatus.NOT_FOUND + "Certification authority not found for given CAName", + HttpStatus.NOT_FOUND ); } @@ -75,8 +77,17 @@ public final class CertificationExceptionAdvice { public ResponseEntity handle(CmpClientException exception) { LOGGER.error("Exception occurred calling cmp client:", exception); return getErrorResponseEntity( - "Exception occurred during call to cmp client", - HttpStatus.INTERNAL_SERVER_ERROR + "Exception occurred during call to cmp client: " + exception.getMessage(), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + + @ExceptionHandler(value = CmpServerException.class) + public ResponseEntity handle(CmpServerException exception) { + LOGGER.error("CMPv2 server returned following error: {} ", exception.getMessage(), exception); + return getErrorResponseEntity( + "CMPv2 server returned following error: " + exception.getMessage(), + HttpStatus.INTERNAL_SERVER_ERROR ); } @@ -84,16 +95,16 @@ public final class CertificationExceptionAdvice { public ResponseEntity handle(Cmpv2ClientAdapterException exception) { LOGGER.error("Exception occurred parsing cmp client response:", exception); return getErrorResponseEntity( - "Exception occurred parsing cmp client response", - HttpStatus.INTERNAL_SERVER_ERROR + "Exception occurred parsing cmp client response: " + exception.getMessage(), + HttpStatus.INTERNAL_SERVER_ERROR ); } private ResponseEntity getErrorResponseEntity(String errorMessage, HttpStatus status) { ErrorResponseModel errorResponse = new ErrorResponseModel(errorMessage); return new ResponseEntity<>( - errorResponse, - status + errorResponse, + status ); } diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/exceptions/CmpServerException.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/exceptions/CmpServerException.java new file mode 100644 index 00000000..48eceb7d --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/exceptions/CmpServerException.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nokia. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.certservice.cmpv2client.exceptions; + +public class CmpServerException extends RuntimeException { + + public CmpServerException(String message) { + super(message); + } +} diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java index 6ff274c5..a673869d 100644 --- a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java @@ -2,6 +2,8 @@ * ============LICENSE_START======================================================= * Copyright (C) 2020 Nordix Foundation. * ================================================================================ + * Modification copyright 2021 Nokia + * ================================================================================ * 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 @@ -20,9 +22,6 @@ package org.onap.oom.certservice.cmpv2client.impl; -import java.security.KeyPair; -import java.security.PublicKey; - import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.checkIfCmpResponseContainsError; import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.getCertFromByteArray; import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore; @@ -31,13 +30,14 @@ import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHel import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifySignature; import java.io.IOException; +import java.security.KeyPair; +import java.security.PublicKey; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Date; 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; @@ -49,8 +49,9 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.onap.oom.certservice.certification.configuration.model.CaMode; import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server; import org.onap.oom.certservice.certification.model.CsrModel; -import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; import org.onap.oom.certservice.cmpv2client.api.CmpClient; +import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; +import org.onap.oom.certservice.cmpv2client.exceptions.CmpServerException; import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -150,9 +151,9 @@ public class CmpClientImpl implements CmpClient { if (Objects.nonNull(pkiBody) && pkiBody.getContent() instanceof CertRepMessage) { final CertRepMessage certRepMessage = (CertRepMessage) pkiBody.getContent(); if (Objects.nonNull(certRepMessage)) { - final CertResponse certResponse = - getCertificateResponseContainingNewCertificate(certRepMessage); try { + CertResponse certResponse = getCertificateResponseContainingNewCertificate(certRepMessage); + checkServerResponse(certResponse); return verifyReturnCertChainAndTrustStore(respPkiMessage, certRepMessage, certResponse); } catch (IOException | CertificateParsingException ex) { CmpClientException cmpClientException = @@ -168,6 +169,27 @@ public class CmpClientImpl implements CmpClient { return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList()); } + private void checkServerResponse(CertResponse certResponse) { + if (certResponse.getStatus() != null && certResponse.getStatus().getStatus() != null) { + logServerResponse(certResponse); + if (certResponse.getStatus().getStatus().intValue() == PkiStatus.REJECTED.getCode()) { + String serverMessage = certResponse.getStatus().getStatusString().getStringAt(0).getString(); + throw new CmpServerException(Optional.ofNullable(serverMessage).orElse("N/A")); + } + } + } + + private void logServerResponse(CertResponse certResponse) { + LOG.info("Response status code: {}", certResponse.getStatus().getStatus().toString()); + if (certResponse.getStatus().getStatusString() != null) { + String serverMessage = certResponse.getStatus().getStatusString().getStringAt(0).getString(); + LOG.warn("Response status text: {}", serverMessage); + } + if (certResponse.getStatus().getFailInfo() != null) { + LOG.warn("Response fail info: {}", certResponse.getStatus().getFailInfo().toString()); + } + } + private Cmpv2CertificationModel verifyReturnCertChainAndTrustStore( PKIMessage respPkiMessage, CertRepMessage certRepMessage, CertResponse certResponse) throws CertificateParsingException, CmpClientException, IOException { diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpResponseHelper.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpResponseHelper.java index db508603..1b900987 100644 --- a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpResponseHelper.java +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpResponseHelper.java @@ -2,6 +2,8 @@ * ============LICENSE_START======================================================= * Copyright (C) 2020 Nordix Foundation. * ================================================================================ + * Modification copyright 2021 Nokia + * ================================================================================ * 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 @@ -45,7 +47,6 @@ import java.util.List; import java.util.Map; 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,7 +55,7 @@ import org.bouncycastle.asn1.cmp.PKIMessage; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; -import org.onap.oom.certservice.cmpv2client.exceptions.PkiErrorException; +import org.onap.oom.certservice.cmpv2client.exceptions.CmpServerException; import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,18 +67,14 @@ public final class CmpResponseHelper { private CmpResponseHelper() { } - static void checkIfCmpResponseContainsError(PKIMessage respPkiMessage) - throws CmpClientException { + static void checkIfCmpResponseContainsError(PKIMessage respPkiMessage) { + LOG.info("Response type: {} ", respPkiMessage.getBody().getType()); 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; + (ErrorMsgContent) respPkiMessage.getBody().getContent(); + String text = errorMsgContent.getPKIStatusInfo().getStatusString().getStringAt(0).getString(); + LOG.error("Error in the PkiMessage response: {} ", text); + throw new CmpServerException(Optional.ofNullable(text).orElse("N/A")); } } @@ -94,16 +91,16 @@ public final class CmpResponseHelper { * @throws CmpClientException thrown if error occurs during the verification of the certChain */ static Cmpv2CertificationModel verifyAndReturnCertChainAndTrustSTore( - PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCertificate) - throws CertificateParsingException, IOException, CmpClientException { + PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCertificate) + throws CertificateParsingException, IOException, CmpClientException { Map certificates = mapAllCertificates(respPkiMessage, certRepMessage); return extractCertificationModel(certificates, leafCertificate); } private static Map mapAllCertificates( - PKIMessage respPkiMessage, CertRepMessage certRepMessage + PKIMessage respPkiMessage, CertRepMessage certRepMessage ) - throws IOException, CertificateParsingException, CmpClientException { + throws IOException, CertificateParsingException, CmpClientException { Map certificates = new HashMap<>(); @@ -117,16 +114,16 @@ public final class CmpResponseHelper { } private static Map mapCertificates( - CMPCertificate[] cmpCertificates) - throws CertificateParsingException, CmpClientException, IOException { + CMPCertificate[] cmpCertificates) + throws CertificateParsingException, CmpClientException, IOException { Map certificates = new HashMap<>(); if (cmpCertificates != null) { for (CMPCertificate certificate : cmpCertificates) { getCertFromByteArray(certificate.getEncoded(), X509Certificate.class) - .ifPresent(x509Certificate -> - certificates.put(extractSubjectDn(x509Certificate), x509Certificate) - ); + .ifPresent(x509Certificate -> + certificates.put(extractSubjectDn(x509Certificate), x509Certificate) + ); } } @@ -134,9 +131,9 @@ public final class CmpResponseHelper { } private static Cmpv2CertificationModel extractCertificationModel( - Map certificates, X509Certificate leafCertificate + Map certificates, X509Certificate leafCertificate ) - throws CmpClientException { + throws CmpClientException { List certificateChain = new ArrayList<>(); X509Certificate previousCertificateInChain; X509Certificate nextCertificateInChain = leafCertificate; @@ -170,75 +167,74 @@ public final class CmpResponseHelper { * 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 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 + * @param pkixCertPathCheckers optional PKIXCertPathChecker implementations to use during cert path validation * @throws CmpClientException if certificate could not be validated */ private static void verify( - X509Certificate certificate, - X509Certificate caCertChain, - Date date, - PKIXCertPathChecker... pkixCertPathCheckers) - throws CmpClientException { + 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); + 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); + 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); + 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); + 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.", + 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; } } private static void verifyCertificates( - X509Certificate certificate, - X509Certificate caCertChain, - Date date, - PKIXCertPathChecker[] pkixCertPathCheckers) - throws CertificateException, NoSuchProviderException, InvalidAlgorithmParameterException, - NoSuchAlgorithmException, CertPathValidatorException { + X509Certificate certificate, + X509Certificate caCertChain, + Date date, + PKIXCertPathChecker[] pkixCertPathCheckers) + throws CertificateException, NoSuchProviderException, InvalidAlgorithmParameterException, + NoSuchAlgorithmException, CertPathValidatorException { if (caCertChain == null) { final String noRootCaCertificateMessage = "Server response does not contain proper root CA certificate"; throw new CertificateException(noRootCaCertificateMessage); } LOG.debug( - "Verifying certificate {} as part of cert chain with certificate {}", - certificate.getSubjectDN().getName(), - caCertChain.getSubjectDN().getName()); + "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); + CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, params); if (LOG.isDebugEnabled()) { LOG.debug("Certificate verify result:{} ", result); @@ -246,8 +242,8 @@ public final class CmpResponseHelper { } private static PKIXParameters getPkixParameters( - X509Certificate caCertChain, Date date, PKIXCertPathChecker[] pkixCertPathCheckers) - throws InvalidAlgorithmParameterException { + 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) { @@ -259,22 +255,21 @@ public final class CmpResponseHelper { } private static CertPath getCertPath(X509Certificate certificate) - throws CertificateException, NoSuchProviderException { + throws CertificateException, NoSuchProviderException { ArrayList certlist = new ArrayList<>(); certlist.add(certificate); return CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME) - .generateCertPath(certlist); + .generateCertPath(certlist); } /** * 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. + * @param provider Security provider that should be used to create certificates, default BC is null is passed. * @return CertificateFactory for creating certificate */ private static CertificateFactory getCertificateFactory(final String provider) - throws CmpClientException { + throws CmpClientException { LOG.debug("Creating certificate Factory to generate certificate using provider {}", provider); final String prov; prov = Objects.requireNonNullElse(provider, BouncyCastleProvider.PROVIDER_NAME); @@ -293,19 +288,20 @@ public final class 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. + * @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. */ static Optional getCertFromByteArray( - byte[] cert, Class returnType) throws CertificateParsingException, CmpClientException { + byte[] cert, Class returnType) throws CertificateParsingException, CmpClientException { LOG.debug("Retrieving certificate of type {} from byte array.", returnType); String prov = BouncyCastleProvider.PROVIDER_NAME; if (returnType.equals(X509Certificate.class)) { return parseX509Certificate(prov, cert); } else { - LOG.debug("Certificate of type {} was skipped, because type of certificate is not 'X509Certificate'.", returnType); + LOG.debug("Certificate of type {} was skipped, because type of certificate is not 'X509Certificate'.", + returnType); return Optional.empty(); } } @@ -317,11 +313,11 @@ public final class CmpResponseHelper { * @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. + * @throws CertificateParsingException if the byte array wasn't valid, or contained a certificate other than an X509 + * Certificate. */ private static Optional parseX509Certificate(String provider, byte[] cert) - throws CertificateParsingException, CmpClientException { + throws CertificateParsingException, CmpClientException { LOG.debug("Parsing X509Certificate from bytes with provider {}", provider); final CertificateFactory cf = getCertificateFactory(provider); X509Certificate result; diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/PkiStatus.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/PkiStatus.java new file mode 100644 index 00000000..3792e8c8 --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/PkiStatus.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nokia. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.certservice.cmpv2client.impl; + +public enum PkiStatus { + + REJECTED(2); + + private int code; + + PkiStatus(int code) { + this.code = code; + } + + public int getCode() { + return code; + } +} + diff --git a/certService/src/test/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdviceTest.java b/certService/src/test/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdviceTest.java index 081a01a0..9e6a6ced 100644 --- a/certService/src/test/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdviceTest.java +++ b/certService/src/test/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdviceTest.java @@ -3,6 +3,7 @@ * PROJECT * ================================================================================ * Copyright (C) 2020 Nokia. All rights reserved. + * Copyright (C) 2021 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. @@ -20,7 +21,10 @@ package org.onap.oom.certservice.api.advice; -import com.google.gson.Gson; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.onap.oom.certservice.certification.exception.Cmpv2ClientAdapterException; @@ -29,12 +33,10 @@ import org.onap.oom.certservice.certification.exception.CsrDecryptionException; import org.onap.oom.certservice.certification.exception.ErrorResponseModel; import org.onap.oom.certservice.certification.exception.KeyDecryptionException; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; +import org.onap.oom.certservice.cmpv2client.exceptions.CmpServerException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - class CertificationExceptionAdviceTest { private CertificationExceptionAdvice certificationExceptionAdvice; @@ -98,7 +100,7 @@ class CertificationExceptionAdviceTest { // Then assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); - assertEquals(expectedMessage, response.getBody().getErrorMessage()); + assertTrue(response.getBody().getErrorMessage().startsWith(expectedMessage)); } @Test @@ -112,7 +114,7 @@ class CertificationExceptionAdviceTest { // Then assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); - assertEquals(expectedMessage, response.getBody().getErrorMessage()); + assertTrue(response.getBody().getErrorMessage().startsWith(expectedMessage)); } @Test @@ -131,4 +133,17 @@ class CertificationExceptionAdviceTest { assertEquals(expectedMessage, exception.getMessage()); } + @Test + void shouldReturnResponseEntityWithCmpErrorMessage() { + // Given + String expectedMessage = "CMPv2 server returned following error: EJBCA fault"; + CmpServerException exception = new CmpServerException("EJBCA fault"); + + // When + ResponseEntity response = certificationExceptionAdvice.handle(exception); + + // Then + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertTrue(response.getBody().getErrorMessage().startsWith(expectedMessage)); + } } diff --git a/certService/src/test/java/org/onap/oom/certservice/cmpv2client/Cmpv2ClientTest.java b/certService/src/test/java/org/onap/oom/certservice/cmpv2client/Cmpv2ClientTest.java index b09025b2..df9699ae 100644 --- a/certService/src/test/java/org/onap/oom/certservice/cmpv2client/Cmpv2ClientTest.java +++ b/certService/src/test/java/org/onap/oom/certservice/cmpv2client/Cmpv2ClientTest.java @@ -62,6 +62,7 @@ import org.onap.oom.certservice.certification.configuration.model.Authentication import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server; import org.onap.oom.certservice.certification.model.CsrModel; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; +import org.onap.oom.certservice.cmpv2client.exceptions.CmpServerException; import org.onap.oom.certservice.cmpv2client.impl.CmpClientImpl; import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel; @@ -230,7 +231,7 @@ class Cmpv2ClientTest { // then Assertions.assertThrows( - CmpClientException.class, + CmpServerException.class, () -> cmpClient.createCertificate(csrModel, server, notBefore, notAfter)); } diff --git a/certServiceClient/pom.xml b/certServiceClient/pom.xml index 799d9aac..d330d82e 100644 --- a/certServiceClient/pom.xml +++ b/certServiceClient/pom.xml @@ -18,12 +18,12 @@ oom-certservice org.onap.oom.platform.cert-service - 2.3.2-SNAPSHOT + 2.3.3-SNAPSHOT 4.0.0 oom-certservice-client - 2.3.2-SNAPSHOT + 2.3.3-SNAPSHOT oom-certservice-client OOM Certification Service Api Client jar diff --git a/certServiceK8sExternalProvider/pom.xml b/certServiceK8sExternalProvider/pom.xml index c6454f65..4e7f6898 100644 --- a/certServiceK8sExternalProvider/pom.xml +++ b/certServiceK8sExternalProvider/pom.xml @@ -5,7 +5,7 @@ oom-certservice org.onap.oom.platform.cert-service - 2.3.2-SNAPSHOT + 2.3.3-SNAPSHOT 4.0.0 diff --git a/certServicePostProcessor/pom.xml b/certServicePostProcessor/pom.xml index 346c6adf..6fa10de6 100644 --- a/certServicePostProcessor/pom.xml +++ b/certServicePostProcessor/pom.xml @@ -5,12 +5,12 @@ oom-certservice org.onap.oom.platform.cert-service - 2.3.2-SNAPSHOT + 2.3.3-SNAPSHOT 4.0.0 oom-certservice-post-processor - 2.3.2-SNAPSHOT + 2.3.3-SNAPSHOT oom-certservice-post-processor An application which conducts certificate post-processing like: merging truststores, copying keystores. jar diff --git a/docs/sections/change-log.rst b/docs/sections/change-log.rst index 9d422592..c2047808 100644 --- a/docs/sections/change-log.rst +++ b/docs/sections/change-log.rst @@ -14,6 +14,47 @@ Honolulu ============== +Version: 2.3.3 +-------------- + +:Release Date: 2021-01-19 + +**New Features** + + N/A + +**Bug Fixes** + + Enhance CertServiceAPI response (include CMP server error messages). + +**Known Issues** + + N/A + +**Security Notes** + + N/A + +*Fixed Security Issues* + + N/A + +*Known Security Issues* + + N/A + +*Known Vulnerabilities in Used Modules* + + N/A + +**Upgrade Notes** + +**Deprecation Notes** + +**Other** + +============== + Version: 2.3.2 -------------- diff --git a/pom.xml b/pom.xml index 85b278f9..36690f83 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ org.onap.oom.platform.cert-service oom-certservice - 2.3.2-SNAPSHOT + 2.3.3-SNAPSHOT oom-certservice OOM Certification Service pom diff --git a/version.properties b/version.properties index 29a89d0c..c5515fc9 100644 --- a/version.properties +++ b/version.properties @@ -1,6 +1,6 @@ major=2 minor=3 -patch=2 +patch=3 base_version=${major}.${minor}.${patch} release_version=${base_version} snapshot_version=${base_version}-SNAPSHOT -- cgit 1.2.3-korg