[CMPV2] Fix NPE & enhance error messages 61/116961/5
authorJan Malkiewicz <jan.malkiewicz@nokia.com>
Tue, 19 Jan 2021 07:16:19 +0000 (08:16 +0100)
committerJan Malkiewicz <jan.malkiewicz@nokia.com>
Tue, 19 Jan 2021 14:26:01 +0000 (15:26 +0100)
Fix NPE.
Include error messages returned by CMP server in API response.

Issue-ID: OOM-2657
Signed-off-by: Jan Malkiewicz <jan.malkiewicz@nokia.com>
Change-Id: I6ec46b14ba04b5be10de5994236efd8fc14c5d2e

14 files changed:
certService/pom.xml
certService/src/main/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdvice.java
certService/src/main/java/org/onap/oom/certservice/cmpv2client/exceptions/CmpServerException.java [new file with mode: 0644]
certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java
certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpResponseHelper.java
certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/PkiStatus.java [new file with mode: 0644]
certService/src/test/java/org/onap/oom/certservice/api/advice/CertificationExceptionAdviceTest.java
certService/src/test/java/org/onap/oom/certservice/cmpv2client/Cmpv2ClientTest.java
certServiceClient/pom.xml
certServiceK8sExternalProvider/pom.xml
certServicePostProcessor/pom.xml
docs/sections/change-log.rst
pom.xml
version.properties

index fa5ca41..3c9efca 100644 (file)
     <parent>
         <groupId>org.onap.oom.platform.cert-service</groupId>
         <artifactId>oom-certservice</artifactId>
-        <version>2.3.2-SNAPSHOT</version>
+        <version>2.3.3-SNAPSHOT</version>
     </parent>
     <artifactId>oom-certservice-api</artifactId>
-    <version>2.3.2-SNAPSHOT</version>
+    <version>2.3.3-SNAPSHOT</version>
     <name>oom-certservice-api</name>
     <description>OOM Certification Service Api</description>
     <packaging>jar</packaging>
index 5fb9d2a..1c6c3a0 100644 (file)
@@ -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<ErrorResponseModel> 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<ErrorResponseModel> 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<ErrorResponseModel> 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<ErrorResponseModel> 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<ErrorResponseModel> 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<ErrorResponseModel> 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<ErrorResponseModel> 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 (file)
index 0000000..48eceb7
--- /dev/null
@@ -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);
+    }
+}
index 6ff274c..a673869 100644 (file)
@@ -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 {
index db50860..1b90098 100644 (file)
@@ -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<X500Name, X509Certificate> certificates = mapAllCertificates(respPkiMessage, certRepMessage);
         return extractCertificationModel(certificates, leafCertificate);
     }
 
     private static Map<X500Name, X509Certificate> mapAllCertificates(
-            PKIMessage respPkiMessage, CertRepMessage certRepMessage
+        PKIMessage respPkiMessage, CertRepMessage certRepMessage
     )
-            throws IOException, CertificateParsingException, CmpClientException {
+        throws IOException, CertificateParsingException, CmpClientException {
 
         Map<X500Name, X509Certificate> certificates = new HashMap<>();
 
@@ -117,16 +114,16 @@ public final class CmpResponseHelper {
     }
 
     private static Map<X500Name, X509Certificate> mapCertificates(
-            CMPCertificate[] cmpCertificates)
-            throws CertificateParsingException, CmpClientException, IOException {
+        CMPCertificate[] cmpCertificates)
+        throws CertificateParsingException, CmpClientException, IOException {
 
         Map<X500Name, X509Certificate> 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<X500Name, X509Certificate> certificates, X509Certificate leafCertificate
+        Map<X500Name, X509Certificate> certificates, X509Certificate leafCertificate
     )
-            throws CmpClientException {
+        throws CmpClientException {
         List<X509Certificate> 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<X509Certificate> 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 <T extends Certificate> Optional<X509Certificate> getCertFromByteArray(
-            byte[] cert, Class<T> returnType) throws CertificateParsingException, CmpClientException {
+        byte[] cert, Class<T> 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<X509Certificate> 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 (file)
index 0000000..3792e8c
--- /dev/null
@@ -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;
+    }
+}
+
index 081a01a..9e6a6ce 100644 (file)
@@ -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.
 
 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<ErrorResponseModel> response = certificationExceptionAdvice.handle(exception);
+
+        // Then
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
+        assertTrue(response.getBody().getErrorMessage().startsWith(expectedMessage));
+    }
 }
index b09025b..df9699a 100644 (file)
@@ -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));
     }
 
index 799d9aa..d330d82 100644 (file)
     <parent>
         <artifactId>oom-certservice</artifactId>
         <groupId>org.onap.oom.platform.cert-service</groupId>
-        <version>2.3.2-SNAPSHOT</version>
+        <version>2.3.3-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
     <artifactId>oom-certservice-client</artifactId>
-    <version>2.3.2-SNAPSHOT</version>
+    <version>2.3.3-SNAPSHOT</version>
     <name>oom-certservice-client</name>
     <description>OOM Certification Service Api Client</description>
     <packaging>jar</packaging>
index c6454f6..4e7f689 100644 (file)
@@ -5,7 +5,7 @@
   <parent>
     <artifactId>oom-certservice</artifactId>
     <groupId>org.onap.oom.platform.cert-service</groupId>
-    <version>2.3.2-SNAPSHOT</version>
+    <version>2.3.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
index 346c6ad..6fa10de 100644 (file)
@@ -5,12 +5,12 @@
     <parent>
         <artifactId>oom-certservice</artifactId>
         <groupId>org.onap.oom.platform.cert-service</groupId>
-        <version>2.3.2-SNAPSHOT</version>
+        <version>2.3.3-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
     <artifactId>oom-certservice-post-processor</artifactId>
-    <version>2.3.2-SNAPSHOT</version>
+    <version>2.3.3-SNAPSHOT</version>
     <name>oom-certservice-post-processor</name>
     <description>An application which conducts certificate post-processing like: merging truststores, copying keystores.</description>
     <packaging>jar</packaging>
index 9d42259..c204780 100644 (file)
@@ -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 85b278f..36690f8 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     </parent>
     <groupId>org.onap.oom.platform.cert-service</groupId>
     <artifactId>oom-certservice</artifactId>
-    <version>2.3.2-SNAPSHOT</version>
+    <version>2.3.3-SNAPSHOT</version>
     <name>oom-certservice</name>
     <description>OOM Certification Service</description>
     <packaging>pom</packaging>
index 29a89d0..c5515fc 100644 (file)
@@ -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