Merge "Update README"
authorBogumil Zebek <bogumil.zebek@nokia.com>
Fri, 27 Mar 2020 11:06:47 +0000 (11:06 +0000)
committerGerrit Code Review <gerrit@onap.org>
Fri, 27 Mar 2020 11:06:47 +0000 (11:06 +0000)
12 files changed:
certService/src/main/java/org/onap/aaf/certservice/certification/CertificationProvider.java
certService/src/main/java/org/onap/aaf/certservice/cmpv2client/api/CmpClient.java
certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java
certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelper.java
certService/src/main/java/org/onap/aaf/certservice/cmpv2client/model/Cmpv2CertificationModel.java [new file with mode: 0644]
certService/src/test/java/org/onap/aaf/certservice/certification/CertificationProviderTest.java
certService/src/test/java/org/onap/aaf/certservice/cmpv2client/Cmpv2ClientTest.java
certService/src/test/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelperTest.java [new file with mode: 0644]
docs/sections/architecture.rst
docs/sections/offeredapis.rst
docs/sections/resources/OpenAPI.yaml [moved from docs/sections/openapi.yaml with 100% similarity]
docs/sections/resources/certservice_high_level.jpg [moved from docs/sections/img/certservice_high_level.jpg with 100% similarity]

index 4435aa7..2478cc5 100644 (file)
@@ -28,6 +28,7 @@ import org.onap.aaf.certservice.certification.model.CertificationModel;
 import org.onap.aaf.certservice.certification.model.CsrModel;
 import org.onap.aaf.certservice.cmpv2client.api.CmpClient;
 import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException;
+import org.onap.aaf.certservice.cmpv2client.model.Cmpv2CertificationModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -53,9 +54,9 @@ public class CertificationProvider {
 
     public CertificationModel signCsr(CsrModel csrModel, Cmpv2Server server)
             throws CmpClientException {
-        List<List<X509Certificate>> certificates = cmpClient.createCertificate(csrModel, server);
-        return new CertificationModel(convertFromX509CertificateListToPemList(certificates.get(0)),
-                convertFromX509CertificateListToPemList(certificates.get(1)));
+        Cmpv2CertificationModel certificates = cmpClient.createCertificate(csrModel, server);
+        return new CertificationModel(convertFromX509CertificateListToPemList(certificates.getCertificateChain()),
+                convertFromX509CertificateListToPemList(certificates.getTrustedCertificates()));
     }
 
     private static List<String> convertFromX509CertificateListToPemList(List<X509Certificate> certificates) {
index 6ff1bf6..cccb744 100644 (file)
 
 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.certification.configuration.model.Cmpv2Server;
 import org.onap.aaf.certservice.certification.model.CsrModel;
 import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException;
+import org.onap.aaf.certservice.cmpv2client.model.Cmpv2CertificationModel;
 
 /**
  * This class represent CmpV2Client Interface for obtaining X.509 Digital Certificates in a Public
@@ -47,10 +46,10 @@ public interface CmpClient {
    *                  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.
+   * @return model for certification containing certificate chain and trusted certificates
    * @throws CmpClientException if client error occurs.
    */
-  List<List<X509Certificate>> createCertificate(
+  Cmpv2CertificationModel createCertificate(
       CsrModel csrModel,
       Cmpv2Server server,
       Date notBefore,
@@ -65,10 +64,10 @@ public interface CmpClient {
    *
    * @param csrModel  Certificate Signing Request Model. Must not be {@code null}.
    * @param server    CMPv2 server. Must not be {@code null}.
-   * @return {@link X509Certificate} The newly created Certificate.
+   * @return model for certification containing certificate chain and trusted certificates
    * @throws CmpClientException if client error occurs.
    */
-  List<List<X509Certificate>> createCertificate(
+  Cmpv2CertificationModel createCertificate(
       CsrModel csrModel,
       Cmpv2Server server)
       throws CmpClientException;
index 28731f2..8799113 100644 (file)
@@ -24,7 +24,7 @@ import java.security.KeyPair;
 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.getCertFromByteArray;
 import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore;
 import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseValidationHelper.checkImplicitConfirm;
 import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifyPasswordBasedProtection;
@@ -33,10 +33,8 @@ import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseValidationHel
 import java.io.IOException;
 import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
-import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 
@@ -53,6 +51,7 @@ import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
 import org.onap.aaf.certservice.certification.model.CsrModel;
 import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException;
 import org.onap.aaf.certservice.cmpv2client.api.CmpClient;
+import org.onap.aaf.certservice.cmpv2client.model.Cmpv2CertificationModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -73,7 +72,7 @@ public class CmpClientImpl implements CmpClient {
     }
 
     @Override
-    public List<List<X509Certificate>> createCertificate(
+    public Cmpv2CertificationModel createCertificate(
             CsrModel csrModel,
             Cmpv2Server server,
             Date notBefore,
@@ -101,7 +100,7 @@ public class CmpClientImpl implements CmpClient {
     }
 
     @Override
-    public List<List<X509Certificate>> createCertificate(CsrModel csrModel, Cmpv2Server server)
+    public Cmpv2CertificationModel createCertificate(CsrModel csrModel, Cmpv2Server server)
             throws CmpClientException {
         return createCertificate(csrModel, server, null, null);
     }
@@ -145,7 +144,7 @@ public class CmpClientImpl implements CmpClient {
         }
     }
 
-    private List<List<X509Certificate>> checkCmpCertRepMessage(final PKIMessage respPkiMessage)
+    private Cmpv2CertificationModel checkCmpCertRepMessage(final PKIMessage respPkiMessage)
             throws CmpClientException {
         final PKIBody pkiBody = respPkiMessage.getBody();
         if (Objects.nonNull(pkiBody) && pkiBody.getContent() instanceof CertRepMessage) {
@@ -163,25 +162,25 @@ public class CmpClientImpl implements CmpClient {
                     throw cmpClientException;
                 }
             } else {
-                return new ArrayList<>(Collections.emptyList());
+                return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList());
             }
         }
-        return new ArrayList<>(Collections.emptyList());
+        return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList());
     }
 
-    private List<List<X509Certificate>> verifyReturnCertChainAndTrustStore(
+    private Cmpv2CertificationModel 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<X509Certificate> leafCertificate =
-                getCertfromByteArray(cmpCertificate.getEncoded(), X509Certificate.class);
+                getCertFromByteArray(cmpCertificate.getEncoded(), X509Certificate.class);
         if (leafCertificate.isPresent()) {
             return verifyAndReturnCertChainAndTrustSTore(
                     respPkiMessage, certRepMessage, leafCertificate.get());
         }
-        return Collections.emptyList();
+        return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList());
     }
 
     private CertResponse getCertificateResponseContainingNewCertificate(
@@ -192,8 +191,8 @@ public class CmpClientImpl implements CmpClient {
     /**
      * Validate inputs for Certificate Creation.
      *
-     * @param csrModel        Certificate Signing Request model. Must not be {@code null}.
-     * @param server          CMPv2 Server. Must not be {@code null}.
+     * @param csrModel Certificate Signing Request model. Must not be {@code null}.
+     * @param server   CMPv2 Server. Must not be {@code null}.
      * @throws IllegalArgumentException if Before Date is set after the After Date.
      */
     private static void validate(
@@ -222,7 +221,7 @@ public class CmpClientImpl implements CmpClient {
         }
     }
 
-    private List<List<X509Certificate>> retrieveCertificates(
+    private Cmpv2CertificationModel retrieveCertificates(
             CsrModel csrModel, Cmpv2Server server, PKIMessage pkiMessage, Cmpv2HttpClient cmpv2HttpClient)
             throws CmpClientException {
         final byte[] respBytes = cmpv2HttpClient.postRequest(pkiMessage, server.getUrl(), server.getCaName());
index b2a7b29..3cb0b0c 100644 (file)
@@ -40,7 +40,9 @@ import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 
@@ -49,9 +51,11 @@ import org.bouncycastle.asn1.cmp.CertRepMessage;
 import org.bouncycastle.asn1.cmp.ErrorMsgContent;
 import org.bouncycastle.asn1.cmp.PKIBody;
 import org.bouncycastle.asn1.cmp.PKIMessage;
+import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException;
 import org.onap.aaf.certservice.cmpv2client.exceptions.PkiErrorException;
+import org.onap.aaf.certservice.cmpv2client.model.Cmpv2CertificationModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,7 +66,7 @@ public final class CmpResponseHelper {
     private CmpResponseHelper() {
     }
 
-    public static void checkIfCmpResponseContainsError(PKIMessage respPkiMessage)
+    static void checkIfCmpResponseContainsError(PKIMessage respPkiMessage)
             throws CmpClientException {
         if (respPkiMessage.getBody().getType() == PKIBody.TYPE_ERROR) {
             final ErrorMsgContent errorMsgContent =
@@ -77,54 +81,91 @@ 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.
-     * @throws CertificateParsingException if the byte array does not contain a proper certificate.
+     * 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 model for certification containing certificate chain and trusted certificates
+     * @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 <T extends Certificate> Optional<X509Certificate> getCertfromByteArray(
-            byte[] cert, Class<T> returnType) throws CertificateParsingException, CmpClientException {
-        LOG.debug("Retrieving certificate of type {} from byte array.", returnType);
-        return getCertfromByteArray(cert, BouncyCastleProvider.PROVIDER_NAME, returnType);
+    static Cmpv2CertificationModel verifyAndReturnCertChainAndTrustSTore(
+            PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCertificate)
+            throws CertificateParsingException, IOException, CmpClientException {
+        Map<X500Name, X509Certificate> certificates = mapAllCertificates(respPkiMessage, certRepMessage);
+        return extractCertificationModel(certificates, leafCertificate);
     }
 
-    /**
-     * @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 <T extends Certificate> Optional<X509Certificate> getCertfromByteArray(
-            byte[] cert, String provider, Class<T> returnType)
-            throws CertificateParsingException, CmpClientException {
-        String prov = provider;
-        if (provider == null) {
-            prov = BouncyCastleProvider.PROVIDER_NAME;
-        }
+    private static Map<X500Name, X509Certificate> mapAllCertificates(
+            PKIMessage respPkiMessage, CertRepMessage certRepMessage
+    )
+            throws IOException, CertificateParsingException, CmpClientException {
 
-        if (returnType.equals(X509Certificate.class)) {
-            return parseX509Certificate(prov, cert);
+        Map<X500Name, X509Certificate> certificates = new HashMap<>();
+
+        CMPCertificate[] extraCerts = respPkiMessage.getExtraCerts();
+        certificates.putAll(mapCertificates(extraCerts));
+
+        CMPCertificate[] caPubsCerts = certRepMessage.getCaPubs();
+        certificates.putAll(mapCertificates(caPubsCerts));
+
+        return certificates;
+    }
+
+    private static Map<X500Name, X509Certificate> mapCertificates(
+            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)
+                        );
+            }
         }
-        return Optional.empty();
+
+        return certificates;
     }
 
-    /**
-     * 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<X509Certificate> caCertChain) throws CmpClientException {
-        int iterator = 1;
-        while (iterator < caCertChain.size()) {
-            verify(caCertChain.get(iterator - 1), caCertChain.get(iterator), null);
-            iterator += 1;
+    private static Cmpv2CertificationModel extractCertificationModel(
+            Map<X500Name, X509Certificate> certificates, X509Certificate leafCertificate
+    )
+            throws CmpClientException {
+        List<X509Certificate> certificateChain = new ArrayList<>();
+        X509Certificate previousCertificateInChain;
+        X509Certificate nextCertificateInChain = leafCertificate;
+        do {
+            certificateChain.add(nextCertificateInChain);
+            certificates.remove(extractSubjectDn(nextCertificateInChain));
+            previousCertificateInChain = nextCertificateInChain;
+            nextCertificateInChain = certificates.get(extractIssuerDn(nextCertificateInChain));
+            verify(previousCertificateInChain, nextCertificateInChain, null);
         }
+        while (!isSelfSign(nextCertificateInChain));
+        List<X509Certificate> trustedCertificates = new ArrayList<>(certificates.values());
+
+        return new Cmpv2CertificationModel(certificateChain, trustedCertificates);
+    }
+
+    private static boolean isSelfSign(X509Certificate certificate) {
+        return extractIssuerDn(certificate).equals(extractSubjectDn(certificate));
+    }
+
+    private static X500Name extractIssuerDn(X509Certificate x509Certificate) {
+        return X500Name.getInstance(x509Certificate.getIssuerDN());
+    }
+
+    private static X500Name extractSubjectDn(X509Certificate x509Certificate) {
+        return X500Name.getInstance(x509Certificate.getSubjectDN());
     }
 
+
     /**
      * Check the certificate with CA certificate.
      *
@@ -136,7 +177,7 @@ public final class CmpResponseHelper {
      *                             path validation
      * @throws CmpClientException if certificate could not be validated
      */
-    public static void verify(
+    private static void verify(
             X509Certificate certificate,
             X509Certificate caCertChain,
             Date date,
@@ -179,13 +220,17 @@ public final class CmpResponseHelper {
         }
     }
 
-    public static void verifyCertificates(
+    private static void verifyCertificates(
             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(),
@@ -200,7 +245,7 @@ public final class CmpResponseHelper {
         }
     }
 
-    public static PKIXParameters getPkixParameters(
+    private static PKIXParameters getPkixParameters(
             X509Certificate caCertChain, Date date, PKIXCertPathChecker[] pkixCertPathCheckers)
             throws InvalidAlgorithmParameterException {
         TrustAnchor anchor = new TrustAnchor(caCertChain, null);
@@ -213,7 +258,7 @@ public final class CmpResponseHelper {
         return params;
     }
 
-    public static CertPath getCertPath(X509Certificate certificate)
+    private static CertPath getCertPath(X509Certificate certificate)
             throws CertificateException, NoSuchProviderException {
         ArrayList<X509Certificate> certlist = new ArrayList<>();
         certlist.add(certificate);
@@ -221,34 +266,6 @@ public final class CmpResponseHelper {
                 .generateCertPath(certlist);
     }
 
-    /**
-     * 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<X509Certificate> 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.
      *
@@ -256,7 +273,7 @@ public final class CmpResponseHelper {
      *                 null is passed.
      * @return CertificateFactory for creating certificate
      */
-    public static CertificateFactory getCertificateFactory(final String provider)
+    private static CertificateFactory getCertificateFactory(final String provider)
             throws CmpClientException {
         LOG.debug("Creating certificate Factory to generate certificate using provider {}", provider);
         final String prov;
@@ -275,99 +292,44 @@ public final class CmpResponseHelper {
     }
 
     /**
-     * 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
+     * @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 List<List<X509Certificate>> verifyAndReturnCertChainAndTrustSTore(
-            PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCertificate)
-            throws CertificateParsingException, IOException, CmpClientException {
-        List<X509Certificate> certChain =
-                addExtraCertsToChain(respPkiMessage, certRepMessage, leafCertificate);
-        List<String> certNames = getNamesOfCerts(certChain);
-        LOG.debug("Verifying the following certificates in the cert chain: {}", certNames);
-        verify(certChain);
-        ArrayList<X509Certificate> trustStore = new ArrayList<>();
-        final int rootCaIndex = certChain.size() - 1;
-        trustStore.add(certChain.get(rootCaIndex));
-        certChain.remove(rootCaIndex);
-        List<List<X509Certificate>> listOfArray = new ArrayList<>();
-        listOfArray.add(certChain);
-        listOfArray.add(trustStore);
-        return listOfArray;
-    }
+    static <T extends Certificate> Optional<X509Certificate> getCertFromByteArray(
+            byte[] cert, Class<T> returnType) throws CertificateParsingException, CmpClientException {
+        LOG.debug("Retrieving certificate of type {} from byte array.", returnType);
+        String prov = BouncyCastleProvider.PROVIDER_NAME;
 
-    public static List<String> getNamesOfCerts(List<X509Certificate> certChain) {
-        List<String> certNames = new ArrayList<>();
-        certChain.forEach(cert -> certNames.add(cert.getSubjectDN().getName()));
-        return certNames;
+        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);
+            return Optional.empty();
+        }
     }
 
+
     /**
-     * checks whether PKIMessage contains extracerts to create certchain, if not creates from caPubs
+     * Parse a X509Certificate from an array of bytes
      *
-     * @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
+     * @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 List<X509Certificate> addExtraCertsToChain(
-            PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCert)
-            throws CertificateParsingException, IOException, CmpClientException {
-        List<X509Certificate> certChain = new ArrayList<>();
-        certChain.add(leafCert);
-        if (respPkiMessage.getExtraCerts() != null) {
-            final CMPCertificate[] extraCerts = respPkiMessage.getExtraCerts();
-            for (CMPCertificate cmpCert : extraCerts) {
-                Optional<X509Certificate> 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<X509Certificate> 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();
-    }
-
-    public static List<X509Certificate> ifCertPresent(
-            List<X509Certificate> certChain,
-            Optional<X509Certificate> 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 Optional<X509Certificate> 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));
+            return Optional.ofNullable(result);
+        } catch (CertificateException ce) {
+            throw new CertificateParsingException("Could not parse byte array as X509Certificate ", ce);
         }
     }
-
-    private static CMPCertificate getRootCa(CertRepMessage certRepMessage) {
-        return certRepMessage.getCaPubs()[0];
-    }
 }
diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/model/Cmpv2CertificationModel.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/model/Cmpv2CertificationModel.java
new file mode 100644 (file)
index 0000000..5d48b97
--- /dev/null
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.cmpv2client.model;
+
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.List;
+
+public class Cmpv2CertificationModel {
+
+    private final List<X509Certificate> certificateChain;
+    private final List<X509Certificate> trustedCertificates;
+
+    public Cmpv2CertificationModel(List<X509Certificate> certificateChain, List<X509Certificate> trustedCertificates) {
+        this.certificateChain = certificateChain;
+        this.trustedCertificates = trustedCertificates;
+    }
+
+    public List<X509Certificate> getCertificateChain() {
+        return Collections.unmodifiableList(certificateChain);
+    }
+
+    public List<X509Certificate> getTrustedCertificates() {
+        return Collections.unmodifiableList(trustedCertificates);
+    }
+}
index cf3c723..a590c5e 100644 (file)
@@ -31,6 +31,7 @@ import org.onap.aaf.certservice.certification.model.CertificationModel;
 import org.onap.aaf.certservice.certification.model.CsrModel;
 import org.onap.aaf.certservice.cmpv2client.api.CmpClient;
 import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException;
+import org.onap.aaf.certservice.cmpv2client.model.Cmpv2CertificationModel;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -38,9 +39,7 @@ import java.nio.charset.StandardCharsets;
 import java.security.NoSuchProviderException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -115,14 +114,15 @@ class CertificationProviderTest {
         assertThat(exception.getMessage()).isEqualTo(expectedErrorMessage);
     }
 
-    private List<List<X509Certificate>> createCorrectClientResponse()
+    private Cmpv2CertificationModel createCorrectClientResponse()
             throws CertificateException, NoSuchProviderException {
         InputStream certificateChain = getClass().getClassLoader().getResourceAsStream("certificateChain.first");
         InputStream trustedCertificate = getClass().getClassLoader().getResourceAsStream("trustedCertificates.first");
         X509Certificate x509Certificate = new CertificateFactoryProvider().generateCertificate(certificateChain);
         X509Certificate x509TrustedCertificate =
                 new CertificateFactoryProvider().generateCertificate(trustedCertificate);
-        return Arrays.asList(Collections.singletonList(x509Certificate),
+        return new Cmpv2CertificationModel(
+                Collections.singletonList(x509Certificate),
                 Collections.singletonList(x509TrustedCertificate));
     }
 
index 06eeecc..05bda54 100644 (file)
@@ -62,6 +62,7 @@ import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
 import org.onap.aaf.certservice.certification.model.CsrModel;
 import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException;
 import org.onap.aaf.certservice.cmpv2client.impl.CmpClientImpl;
+import org.onap.aaf.certservice.cmpv2client.model.Cmpv2CertificationModel;
 
 class Cmpv2ClientTest {
 
@@ -152,7 +153,7 @@ class Cmpv2ClientTest {
         }
         CmpClientImpl cmpClient = spy(new CmpClientImpl(httpClient));
         // when
-        List<List<X509Certificate>> cmpClientResult =
+        Cmpv2CertificationModel cmpClientResult =
                 cmpClient.createCertificate(csrModel, server, notBefore, notAfter);
         // then
         assertNotNull(cmpClientResult);
diff --git a/certService/src/test/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelperTest.java b/certService/src/test/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelperTest.java
new file mode 100644 (file)
index 0000000..c41d636
--- /dev/null
@@ -0,0 +1,609 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.cmpv2client.impl;
+
+import org.bouncycastle.asn1.cmp.CMPCertificate;
+import org.bouncycastle.asn1.cmp.CertRepMessage;
+import org.bouncycastle.asn1.cmp.PKIMessage;
+import org.bouncycastle.util.io.pem.PemObject;
+import org.bouncycastle.util.io.pem.PemReader;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException;
+import org.onap.aaf.certservice.cmpv2client.model.Cmpv2CertificationModel;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class CmpResponseHelperTest {
+
+
+    private static final String EXPECTED_ERROR_MESSAGE = "Something was wrong with the supplied certificate";
+
+    private static final String TEST_1LAYER_ENTITY_CERT = ""
+            + "-----BEGIN CERTIFICATE-----\n"
+            + "MIIEqDCCAxCgAwIBAgIUFioEkVJsxfZGGDMEyCA8Rin3uhQwDQYJKoZIhvcNAQEL\n"
+            + "BQAwYTEjMCEGCgmSJomT8ixkAQEME2MtMDM1ZDk4NTAwYzhiN2JiMjIxFTATBgNV\n"
+            + "BAMMDE1hbmFnZW1lbnRDQTEjMCEGA1UECgwaRUpCQ0EgQ29udGFpbmVyIFF1aWNr\n"
+            + "c3RhcnQwHhcNMjAwMzI0MTEzNTU0WhcNMjIwMzI0MTEzNTU0WjCBljEgMB4GCSqG\n"
+            + "SIb3DQEJARYRQ29tbW9uTmFtZUBjbi5jb20xDjAMBgNVBAMMBUNsMTIzMQ0wCwYD\n"
+            + "VQQLDARPTkFQMRkwFwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMRYwFAYDVQQHDA1T\n"
+            + "YW4tRnJhbmNpc2NvMRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzCC\n"
+            + "ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL94FcmRn/g9Y9ZrEL+jKiud\n"
+            + "xzDdtVLoF0ijZOGG0rnzyimzzwOjd8LA0jiZlYtpoDef95bbMeZJMKzE3bA8EMFp\n"
+            + "hynqUHs/KdsLBV+o3J6EzlpYHrwypX7kOriw9o4dmPAxvJHXTu3HC2SejJjHHArk\n"
+            + "FyahEJ03ypvCJx3iPvGXkLI9tZetobiVXslBJd5t0hQj+JQxzAlTwS0fV+xMowFT\n"
+            + "css2IlGXfQgd88cdhXBVOE0//qln1ko3G3KeH58iIWLqh9KG660SCeoTCop7bO1N\n"
+            + "abVrcXlgdE06hAvzTj3FoBxqO5KEWDPo2Dr11qRdq8bLP2T0EbTzAw4DPUwE+H8C\n"
+            + "AwEAAaOBoTCBnjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFDPaBc+EX/hCLe5c\n"
+            + "d+oZIxcQZ1tHMB8GA1UdEQQYMBaCBUNsMTIzgg10ZXN0Lm9uYXAub3JnMB0GA1Ud\n"
+            + "JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDAdBgNVHQ4EFgQU4dP1HuV9O+sHInl+\n"
+            + "WuvdDJ63lp8wDgYDVR0PAQH/BAQDAgXgMA0GCSqGSIb3DQEBCwUAA4IBgQBWTF8C\n"
+            + "sH0ir4bj7rTlJMf5o7apkXFeQ/c7+zXnSLCfXqwM6ad0EDh3FixfTC8IpW5CaENt\n"
+            + "zTR7IGJr06ccwLgsigR7FxJKnEkxJiBxzkE3zFOEel3KAnV2b7KvOP7cJAzsCdcS\n"
+            + "iZU475XHOw4Ox3k8fHzhTJJa0Tzw5EjQ3GO99HTiUClGrjJuYDLfen1q7IQSNuTY\n"
+            + "FzxJZjyqzi34pkKeCNSPRj8Z8Q5aZiWqlmzSJmZRT83xzzeW/pQ1JwvIrWwrbEjR\n"
+            + "FPXBlUa1n2HztkDgeBQfRyMAj5ixFV+s1Jj+cEYl3pjbugnuHfgBdSJokXFGBo6N\n"
+            + "8PTd1CnMGWcWiMyhbTwNm2UiSr5KhQbjABjiUzDp4C7jFhIzmu/4/tm2uA+y0xPN\n"
+            + "342uEZC0ZSZmpCIbQMhPaBNjSHeHj8NaLHjnt5jppLkMxScayRqMvSW07eNew2+k\n"
+            + "VYJD6z6gfy4y+Y5MSLfvddq1JdPDU86TFprtD1ydcUBS5tduYQG2+1bLgpE="
+            + "\n-----END CERTIFICATE-----\n";
+
+    private static final String TEST_1LAYER_CA_CERT = ""
+            + "-----BEGIN CERTIFICATE-----\n"
+            + "MIIEszCCAxugAwIBAgIUEhkh+zJtXZN3K3kzQYcbp2smyIkwDQYJKoZIhvcNAQEL\n"
+            + "BQAwYTEjMCEGCgmSJomT8ixkAQEME2MtMDM1ZDk4NTAwYzhiN2JiMjIxFTATBgNV\n"
+            + "BAMMDE1hbmFnZW1lbnRDQTEjMCEGA1UECgwaRUpCQ0EgQ29udGFpbmVyIFF1aWNr\n"
+            + "c3RhcnQwHhcNMjAwMzI0MTAyODQyWhcNMzAwMzI0MTAyODQyWjBhMSMwIQYKCZIm\n"
+            + "iZPyLGQBAQwTYy0wMzVkOTg1MDBjOGI3YmIyMjEVMBMGA1UEAwwMTWFuYWdlbWVu\n"
+            + "dENBMSMwIQYDVQQKDBpFSkJDQSBDb250YWluZXIgUXVpY2tzdGFydDCCAaIwDQYJ\n"
+            + "KoZIhvcNAQEBBQADggGPADCCAYoCggGBAJyKZyKIRyW6cbga/I1YFJGCEEgs9JVU\n"
+            + "sV7MD5/yF4SIkJlZqFjJ9kfw8D5thg68zAx2vEWIpNTMroqb1eptIn/XsFoyM//6\n"
+            + "HzKrY3UUYWHx9sQMDZPenTL8LTRx+4szSen7rzrozH2pJat7kfX4EODEtQ6q7RQ2\n"
+            + "hmXoo7heeSgiHoeHsPGZixPGzcB27WBaY00Z/sP/n+f0CFaE04MKLw8WeQmq/RkC\n"
+            + "pj628+eBK0lGtEmUcT7z4CBy4x3hbhn9XHOb0+RlDk7rqFbsc09vHoZK2BfQ/r6e\n"
+            + "HguZjBQ5Ebqf6PiLF3HqkSW73toIdIy/olvQ2dLbOEyI4OnlObc+8xs/1AC7l9xX\n"
+            + "FkXY+NBv24KG1C2POXx14+ufHhWY0k2nIRUUlkUIJ7WGMWbuiNUXc1wSE1VrmY/c\n"
+            + "iXlhsJERqFc6bL/STlhOGuwmkdAD1/K8WS+o/QmIIX6cXlOR0U9bHMbD40F9fur6\n"
+            + "PV8wSKcQQNd0VHRLhmFwo4kkhZpDpuUp4QIDAQABo2MwYTAPBgNVHRMBAf8EBTAD\n"
+            + "AQH/MB8GA1UdIwQYMBaAFDPaBc+EX/hCLe5cd+oZIxcQZ1tHMB0GA1UdDgQWBBQz\n"
+            + "2gXPhF/4Qi3uXHfqGSMXEGdbRzAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL\n"
+            + "BQADggGBAFGsyu5nWycdk8iva+uY98QnPQe/M6uaUGUis0vGn9UYxoz5ddtpF3Z+\n"
+            + "MsHgbS51BH9iRYn4ZkQoRoukIjt1iO86d6sgpUS5AStCXsylL4DwAY5G/K5i/Qw5\n"
+            + "x0lP/tRYwqh2tUhmnx1xZLOWbRFZ63A0YHdguj3CqaXQ/cxafYZe0zcNhX3iH3gf\n"
+            + "5kHH8E682RT0x4ibb1JtPioQ48+pweyfMlOJkJ7WmZEfiVQitQSSNOnw1hRORiUz\n"
+            + "oFb0MlYHqe/9lIb9nmzD8QQ9q0H8J6RBCFsntx/Z6oUM8GHr80zAvNjqFfR14lOo\n"
+            + "jp05w2mr7wxIHFpM6h1HGY1QaeGp6W/fi+N7+gSL3nu1LzXVCYNCTcGkBDeasovB\n"
+            + "ma70KHGO4ZyRcEMKFCxxE8y4GZnw/EhMhDDevXAVsHEzr6XsBCJkC8e2l3iW5IKH\n"
+            + "4N/f/k06d4kS5pL290dJ450zx/mBxYGJm+pPHZfDszqVeKn1m1ZhGT80150OePGQ\n"
+            + "Cc2ir84HwQ=="
+            + "\n-----END CERTIFICATE-----\n";
+
+    private static final String TEST_2LAYER_ENTITY_CERT = ""
+            + "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDjDCCAnSgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlVT\n"
+            + "MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw\n"
+            + "FwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQD\n"
+            + "DBVpbnRlcm1lZGlhdGUub25hcC5vcmcwHhcNMjAwMjEyMDk1MTI2WhcNMjIxMTA4\n"
+            + "MDk1MTI2WjB7MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG\n"
+            + "A1UEBwwNU2FuLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjEN\n"
+            + "MAsGA1UECwwET05BUDEVMBMGA1UEAwwMdmlkLm9uYXAub3JnMIIBIjANBgkqhkiG\n"
+            + "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+GIRzJzUOh0gtc+wzFJEdTnn+q5F10L0Yhr\n"
+            + "G1xKdjPieHIFGsoiXwcuCU8arNSqlz7ocx62KQRkcA8y6edlOAsYtdOEJvqEI9vc\n"
+            + "eyTB/HYsbzw3URPGch4AmibrQkKU9QvGwouHtHn4R2Ft2Y0tfEqv9hxj9v4njq4A\n"
+            + "EiDLAFLl5FmVyCZu/MtKngSgu1smcaFKTYySPMxytgJZexoa/ALZyyE0gRhsvwHm\n"
+            + "NLGCPt1bmE/PEGZybsCqliyTO0S56ncD55The7+D/UDS4kE1Wg0svlWon/YsE6QW\n"
+            + "B3oeJDX7Kr8ebDTIAErevIAD7Sm4ee5se2zxYrsYlj0MzHZtvwIDAQABoxAwDjAM\n"
+            + "BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvQ1pTvjON6vSlcJRKSY4r\n"
+            + "8q7L4/9ZaVXWJAjzEYJtPIqsgGiPWz0vGfgklowU6tZxp9zRZFXfMil+mPQSe+yo\n"
+            + "ULrZSQ/z48YHPueE/BNO/nT4aaVBEhPLR5aVwC7uQVX8H+m1V1UGT8lk9vdI9rej\n"
+            + "CI9l524sLCpdE4dFXiWK2XHEZ0Vfylk221u3IYEogVVA+UMX7BFPSsOnI2vtYK/i\n"
+            + "lwZtlri8LtTusNe4oiTkYyq+RSyDhtAswg8ANgvfHolhCHoLFj6w1IkG88UCmbwN\n"
+            + "d7BoGMy06y5MJxyXEZG0vR7eNeLey0TIh+rAszAFPsIQvrOHW+HuA+WLQAj1mhnm\n"
+            + "-----END CERTIFICATE-----";
+
+    private static final String TEST_2LAYER_INTERMEDIATE_CERT = ""
+            + "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDqTCCApGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNVBAYTAlVT\n"
+            + "MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw\n"
+            + "FwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMREwDwYDVQQD\n"
+            + "DAhvbmFwLm9yZzEeMBwGCSqGSIb3DQEJARYPdGVzdGVyQG9uYXAub3JnMB4XDTIw\n"
+            + "MDIxMjA5NDAxMloXDTIyMTEwODA5NDAxMlowgYQxCzAJBgNVBAYTAlVTMRMwEQYD\n"
+            + "VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkwFwYDVQQK\n"
+            + "DBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQDDBVpbnRl\n"
+            + "cm1lZGlhdGUub25hcC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n"
+            + "AQC1oOYMZ6G+2DGDAizYnzdCNiogivlht1s4oqgem7fM1XFPxD2p31ATIibOdqr/\n"
+            + "gv1qemO9Q4r1xn6w1Ufq7T1K7PjnMzdSeTqZefurE2JM/HHx2QvW4TjMlz2ILgaD\n"
+            + "L1LN60kmMQSOi5VxKJpsrCQxbOsxhvefd212gny5AZMcjJe23kUd9OxUrtvpdLEv\n"
+            + "wI3vFEvT7oRUnEUg/XNz7qeg33vf1C39yMR+6O4s6oevgsEebVKjb+yOoS6zzGtz\n"
+            + "72wZjm07C54ZlO+4Uy+QAlMjRiU3mgWkKbkOy+4CvwehjhpTikdBs2DX39ZLGHhn\n"
+            + "L/0a2NYtGulp9XEqmTvRoI+PAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI\n"
+            + "hvcNAQELBQADggEBADcitdJ6YswiV8jAD9GK0gf3+zqcGegt4kt+79JXlXYbb1sY\n"
+            + "q3o6prcB7nSUoClgF2xUPCslFGpM0Er9FCSFElQM/ru0l/KVmJS6kSpwEHvsYIH3\n"
+            + "q5anta+Pyk8JSQWAAw+qrind0uBQMnhR8Tn13tgV+Kjvg/xlH/nZIEdN5YtLB1cA\n"
+            + "beVsZRyRfVL9DeZU8s/MZ5wC3kgcEp5A4m5lg7HyBxBdqhzFcDr6xiy6OGqW8Yep\n"
+            + "xrwfc8Fw8a/lOv4U+tBeGNKPQDYaL9hh+oM+qMkNXsHXDqdJsuEGJtU4i3Wcwzoc\n"
+            + "XGN5NWV//4bP+NFmwgcn7AYCdRvz04A8GU/0Cwg=\n"
+            + "-----END CERTIFICATE-----";
+
+    private static final String TEST_2LAYER_CA_CERT = ""
+            + "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDtzCCAp8CFAwqQddh4/iyGfP8UZ3dpXlxfAN8MA0GCSqGSIb3DQEBCwUAMIGX\n"
+            + "MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu\n"
+            + "LUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwE\n"
+            + "T05BUDERMA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBv\n"
+            + "bmFwLm9yZzAeFw0yMDAyMTIwOTM0MjdaFw0yMTAyMTEwOTM0MjdaMIGXMQswCQYD\n"
+            + "VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuLUZyYW5j\n"
+            + "aXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwET05BUDER\n"
+            + "MA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBvbmFwLm9y\n"
+            + "ZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCFrnO7/eT6V+7XkPPd\n"
+            + "eiL/6xXreuegvit/1/jTVjG+3AOVcmTn2WXwXXRcQLvkWQfJVPoltsY8E3FqFRti\n"
+            + "797XjY6cdQJFVDyzNU0+Fb4vJL9FK5wSvnS6EFjBEn3JvXRlENorDCs/mfjkjJoa\n"
+            + "Dl74gXQEJYcg4nsTeNIj7cm3Q7VK3mZt1t7LSJJ+czxv69UJDuNJpmQ/2WOKyLZA\n"
+            + "gTtBJ+Hyol45/OLsrqwq1dAn9ZRWIFPvRt/XQYH9bI/6MtqSreRVUrdYCiTe/XpP\n"
+            + "B/OM6NEi2+p5QLi3Yi70CEbqP3HqUVbkzF+r7bwIb6M5/HxfqzLmGwLvD+6rYnUn\n"
+            + "Bm8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAhXoO65DXth2X/zFRNsCNpLwmDy7r\n"
+            + "PxT9ZAIZAzSxx3/aCYiuTrKP1JnqjkO+F2IbikrI4n6sKO49SKnRf9SWTFhd+5dX\n"
+            + "vxq5y7MaqxHAY9J7+Qzq33+COVFQnaF7ddel2NbyUVb2b9ZINNsaZkkPXui6DtQ7\n"
+            + "/Fb/1tmAGWd3hMp75G2thBSzs816JMKKa9WD+4VGATEs6OSll4sv2fOZEn+0mAD3\n"
+            + "9q9c+WtLGIudOwcHwzPb2njtNntQSCK/tVOqbY+vzhMY3JW+p9oSrLDSdGC+pAKK\n"
+            + "m/wB+2VPIYcsPMtIhHC4tgoSaiCqjXYptaOh4b8ye8CPBUCpX/AYYkN0Ow==\n"
+            + "-----END CERTIFICATE-----";
+
+
+    @BeforeAll
+    static void setUpSecurity() {
+        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+    }
+
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertInCaPubsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        PKIMessage respPkiMessage = mockExtraCerts(null);
+
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_1LAYER_CA_CERT);
+        CMPCertificate[] cmpCertificates = {caCmpCertificate};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_1LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityCertificate(certs, TEST_1LAYER_ENTITY_CERT);
+
+        assertThatRootCaAndTrustedCaAreInSecondList(certs, caCmpCertificate);
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertInExtraCertsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_1LAYER_CA_CERT);
+        CMPCertificate[] extraCmpCertificates = {caCmpCertificate};
+        PKIMessage respPkiMessage = mockExtraCerts(extraCmpCertificates);
+
+        CertRepMessage certRepMessage = mockCaPubs(null);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_1LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityCertificate(certs, TEST_1LAYER_ENTITY_CERT);
+
+        assertThatRootCaAndTrustedCaAreInSecondList(certs, caCmpCertificate);
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertInExtraCertsAndExtraTrustAnchorInCaPubsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_1LAYER_CA_CERT);
+        CMPCertificate[] extraCmpCertificates = {caCmpCertificate};
+        PKIMessage respPkiMessage = mockExtraCerts(extraCmpCertificates);
+
+        CMPCertificate extraTrustAnchor = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate[] cmpCertificates = {extraTrustAnchor};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_1LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityCertificate(certs, TEST_1LAYER_ENTITY_CERT);
+
+        assertThatRootCaAndTrustedCaAreInSecondList(
+                certs,
+                caCmpCertificate, extraTrustAnchor
+        );
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertInExtraCertsAndExtraTrustAnchorInExtraCertsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        CMPCertificate trustedCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_1LAYER_CA_CERT);
+        CMPCertificate[] extraCmpCertificates = {caCmpCertificate, trustedCmpCertificate};
+        PKIMessage respPkiMessage = mockExtraCerts(extraCmpCertificates);
+
+        CertRepMessage certRepMessage = mockCaPubs(null);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_1LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityCertificate(certs, TEST_1LAYER_ENTITY_CERT);
+
+        assertThatRootCaAndTrustedCaAreInSecondList(
+                certs,
+                caCmpCertificate, trustedCmpCertificate
+        );
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertAndIntermediateCertInExtraCertsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate intermediateCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_INTERMEDIATE_CERT);
+        CMPCertificate[] extraCmpCertificates = {caCmpCertificate, intermediateCmpCertificate};
+        PKIMessage respPkiMessage = mockExtraCerts(extraCmpCertificates);
+
+        CertRepMessage certRepMessage = mockCaPubs(null);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_2LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityAndIntermediateCertificate(certs, TEST_2LAYER_ENTITY_CERT, TEST_2LAYER_INTERMEDIATE_CERT);
+
+        assertThatRootCaAndTrustedCaAreInSecondList(
+                certs,
+                caCmpCertificate
+        );
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertAndIntermediateCertInCmpCertificatesAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        PKIMessage respPkiMessage = mockExtraCerts(null);
+
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate intermediateCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_INTERMEDIATE_CERT);
+        CMPCertificate[] cmpCertificates = {caCmpCertificate, intermediateCmpCertificate};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_2LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityAndIntermediateCertificate(certs, TEST_2LAYER_ENTITY_CERT, TEST_2LAYER_INTERMEDIATE_CERT);
+
+        assertThatRootCaAndTrustedCaAreInSecondList(
+                certs,
+                caCmpCertificate
+        );
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertInCaPubsAndIntermediateCertInExtraCertsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        CMPCertificate intermediateCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_INTERMEDIATE_CERT);
+        CMPCertificate[] extraCmpCertificates = {intermediateCmpCertificate};
+        PKIMessage respPkiMessage = mockExtraCerts(extraCmpCertificates);
+
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate[] cmpCertificates = {caCmpCertificate};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_2LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityAndIntermediateCertificate(certs, TEST_2LAYER_ENTITY_CERT, TEST_2LAYER_INTERMEDIATE_CERT);
+
+        assertThatRootCaAndTrustedCaAreInSecondList(
+                certs,
+                caCmpCertificate
+        );
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertInCaPubsAndExtraCertsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_1LAYER_CA_CERT);
+        CMPCertificate[] extraCmpCertificates = {caCmpCertificate};
+        PKIMessage respPkiMessage = mockExtraCerts(extraCmpCertificates);
+        CMPCertificate[] cmpCertificates = {mockCmpCertificateFromPem(TEST_1LAYER_CA_CERT)};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_1LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityCertificate(certs, TEST_1LAYER_ENTITY_CERT);
+        assertThatRootCaAndTrustedCaAreInSecondList(certs, mockCmpCertificateFromPem(TEST_1LAYER_CA_CERT));
+
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertAndIntermediateCertInExtraCertsAndIntermediateCertInCaPubsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate intermediateCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_INTERMEDIATE_CERT);
+        CMPCertificate[] extraCmpCertificates = {caCmpCertificate, intermediateCmpCertificate};
+        PKIMessage respPkiMessage = mockExtraCerts(extraCmpCertificates);
+        CMPCertificate[] cmpCertificates = {intermediateCmpCertificate};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_2LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityAndIntermediateCertificate(certs, TEST_2LAYER_ENTITY_CERT, TEST_2LAYER_INTERMEDIATE_CERT);
+        assertThatRootCaAndTrustedCaAreInSecondList(
+                certs,
+                caCmpCertificate
+        );
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertAndExtraTrustAnchorInCaPubsAndIntermediateCertInExtraCertsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        CMPCertificate intermediateCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_INTERMEDIATE_CERT);
+        CMPCertificate[] extraCmpCertificates = {intermediateCmpCertificate};
+        PKIMessage respPkiMessage = mockExtraCerts(extraCmpCertificates);
+
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate extraTrustAnchor = mockCmpCertificateFromPem(TEST_1LAYER_CA_CERT);
+        CMPCertificate[] cmpCertificates = {caCmpCertificate, extraTrustAnchor};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_2LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityAndIntermediateCertificate(certs, TEST_2LAYER_ENTITY_CERT, TEST_2LAYER_INTERMEDIATE_CERT);
+
+        assertThatRootCaAndTrustedCaAreInSecondList(
+                certs,
+                caCmpCertificate, extraTrustAnchor
+        );
+    }
+
+    @Test
+    void returnListOfCertificationWhenGivenCaCertAndFirstExtraTrustAnchorInCaPubsAndIntermediateCertAndSecondExtraTrustAnchorInExtraCertsAndEntityCertInLeafCertificate()
+            throws CertificateException, CmpClientException, IOException, NoSuchProviderException {
+        //  given
+        CMPCertificate intermediateCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_INTERMEDIATE_CERT);
+        CMPCertificate extraTrustAnchor01 = mockCmpCertificateFromPem(TEST_1LAYER_ENTITY_CERT);
+        CMPCertificate[] extraCmpCertificates = {intermediateCmpCertificate, extraTrustAnchor01};
+        PKIMessage respPkiMessage = mockExtraCerts(extraCmpCertificates);
+
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate extraTrustAnchor02 = mockCmpCertificateFromPem(TEST_1LAYER_CA_CERT);
+        CMPCertificate[] cmpCertificates = {caCmpCertificate, extraTrustAnchor02};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_2LAYER_ENTITY_CERT);
+
+        //  when
+        Cmpv2CertificationModel certs = CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                respPkiMessage, certRepMessage, leafCertificate);
+
+        // then
+        assertThatChainContainsEntityAndIntermediateCertificate(certs, TEST_2LAYER_ENTITY_CERT, TEST_2LAYER_INTERMEDIATE_CERT);
+
+        assertThatRootCaAndTrustedCaAreInSecondList(
+                certs,
+                caCmpCertificate, extraTrustAnchor01, extraTrustAnchor02
+        );
+    }
+
+    @Test
+    void throwsExceptionWhenNoCaCertForEntityCertIsGivenAndOnlyExtraTrustAnchorIsReturned()
+            throws CertificateException, IOException, NoSuchProviderException {
+        //  given
+
+        PKIMessage respPkiMessage = mockExtraCerts(null);
+
+        CMPCertificate trustedCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate[] cmpCertificates = {trustedCmpCertificate};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_1LAYER_ENTITY_CERT);
+
+        //  when
+        Exception exception = assertThrows(
+                CmpClientException.class,
+                () -> CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                        respPkiMessage, certRepMessage, leafCertificate
+                )
+        );
+
+        String actualMessage = exception.getMessage();
+
+        // then
+        assertThat(actualMessage).isEqualTo(EXPECTED_ERROR_MESSAGE);
+    }
+
+    @Test
+    void throwsExceptionWhenBothExtraCertsAndCaPubsAreEmpty()
+            throws CertificateException, IOException, NoSuchProviderException {
+        //  given
+
+        PKIMessage respPkiMessage = mockExtraCerts(null);
+        CertRepMessage certRepMessage = mockCaPubs(null);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_1LAYER_ENTITY_CERT);
+
+        //  when
+        Exception exception = assertThrows(
+                CmpClientException.class,
+                () -> CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                        respPkiMessage, certRepMessage, leafCertificate
+                )
+        );
+
+        String actualMessage = exception.getMessage();
+
+        // then
+        assertThat(actualMessage).isEqualTo(EXPECTED_ERROR_MESSAGE);
+    }
+
+    @Test
+    void throwsExceptionWhenNoIntermediateCertForEntityCertIsGiven()
+            throws CertificateException, IOException, NoSuchProviderException {
+        //  given
+
+        PKIMessage respPkiMessage = mockExtraCerts(null);
+
+        CMPCertificate caCmpCertificate = mockCmpCertificateFromPem(TEST_2LAYER_CA_CERT);
+        CMPCertificate[] cmpCertificates = {caCmpCertificate};
+        CertRepMessage certRepMessage = mockCaPubs(cmpCertificates);
+
+        X509Certificate leafCertificate = getX509CertificateFromPem(TEST_2LAYER_ENTITY_CERT);
+
+        //  when
+        Exception exception = assertThrows(
+                CmpClientException.class,
+                () -> CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore(
+                        respPkiMessage, certRepMessage, leafCertificate
+                )
+        );
+
+        String actualMessage = exception.getMessage();
+
+        // then
+        assertThat(actualMessage).isEqualTo(EXPECTED_ERROR_MESSAGE);
+    }
+
+
+    private void assertThatRootCaAndTrustedCaAreInSecondList(
+            Cmpv2CertificationModel certs, CMPCertificate... rootAndTrustedCerts
+    ) throws IOException {
+        assertThat(certs.getTrustedCertificates().size()).isEqualTo(rootAndTrustedCerts.length);
+        for (CMPCertificate certificate : rootAndTrustedCerts) {
+            assertThat(certs.getTrustedCertificates())
+                    .extracting(Certificate::getEncoded)
+                    .contains(certificate.getEncoded());
+        }
+    }
+
+    private void assertThatChainContainsEntityCertificate(
+            Cmpv2CertificationModel certs, String entityCertificate
+    ) throws CertificateEncodingException, IOException {
+        assertThat(certs.getCertificateChain().size()).isEqualTo(1);
+        assertThat(certs.getCertificateChain().get(0).getEncoded()).isEqualTo(createPemObject(entityCertificate).getContent());
+    }
+
+    private void assertThatChainContainsEntityAndIntermediateCertificate(
+            Cmpv2CertificationModel certs, String entityCertificate, String intermediateCertificate
+    ) throws CertificateEncodingException, IOException {
+        assertThat(certs.getCertificateChain().size()).isEqualTo(2);
+        assertThat(certs.getCertificateChain().get(0).getEncoded()).isEqualTo(createPemObject(entityCertificate).getContent());
+        assertThat(certs.getCertificateChain().get(1).getEncoded()).isEqualTo(createPemObject(intermediateCertificate).getContent());
+    }
+
+    private X509Certificate getX509CertificateFromPem(String pem) throws CertificateException, NoSuchProviderException, IOException {
+        return (X509Certificate)
+                CertificateFactory.getInstance("X.509", "BC").generateCertificate(
+                        new ByteArrayInputStream(createPemObject(pem).getContent())
+                );
+    }
+
+    private PKIMessage mockExtraCerts(CMPCertificate[] cmpCertificates) {
+        PKIMessage respPkiMessage = mock(PKIMessage.class);
+        when(respPkiMessage.getExtraCerts()).thenReturn(cmpCertificates);
+        return respPkiMessage;
+    }
+
+    private CertRepMessage mockCaPubs(CMPCertificate[] cmpCertificates) {
+        CertRepMessage certRepMessage = mock(CertRepMessage.class);
+        when(certRepMessage.getCaPubs()).thenReturn(cmpCertificates);
+        return certRepMessage;
+    }
+
+    private CMPCertificate mockCmpCertificateFromPem(String pem) throws IOException {
+        return mockCmpCertificate(createPemObject(pem).getContent());
+    }
+
+    private CMPCertificate mockCmpCertificate(byte[] encodedCertificate) throws IOException {
+        CMPCertificate cmpCertificate01 = mock(CMPCertificate.class);
+        when(cmpCertificate01.getEncoded()).thenReturn(encodedCertificate);
+        return cmpCertificate01;
+    }
+
+    private PemObject createPemObject(String pem) throws IOException {
+        try (StringReader stringReader = new StringReader(pem);
+             PemReader pemReader = new PemReader(stringReader)) {
+            return pemReader.readPemObject();
+        }
+    }
+}
index 654208d..9b1b481 100644 (file)
@@ -12,7 +12,7 @@ End component is an ONAP component (e.g. DCAE collector or controller) which req
 to protect external traffic and uses CertService's client to get it.
 CertService's client communicates with CertService via REST API over HTTPS, while CertService with CMPv2 server via CMP over HTTP.
 
-.. image:: img/certservice_high_level.jpg
+.. image:: resources/certservice_high_level.jpg
    :width: 855px
    :height: 178px
    :alt: Interaction between components
index fe5807a..31e53bc 100644 (file)
@@ -8,4 +8,4 @@ Offered APIs
 AAF Cert Service Api
 --------------------
 
-.. openapi:: ../../certService/OpenAPI.yaml
+.. openapi:: resources/OpenAPI.yaml