[OOM-CERT-SERVICE] Refactor CertService API code 95/122595/2
authorPiotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com>
Tue, 13 Jul 2021 13:41:57 +0000 (15:41 +0200)
committerPiotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com>
Tue, 13 Jul 2021 14:08:38 +0000 (14:08 +0000)
- move conversion StringBase64 to PrivateKey to separate class
- move protection algorithm classes to separate package
- adjust modifiers and test to above changes

Issue-ID: OOM-2753
Signed-off-by: Piotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com>
Change-Id: Ifafa38162acfcd59d5177dbc478a6209e97a18e3

18 files changed:
certService/src/main/java/org/onap/oom/certservice/certification/CertificationProvider.java
certService/src/main/java/org/onap/oom/certservice/certification/conversion/CsrModelFactory.java
certService/src/main/java/org/onap/oom/certservice/certification/conversion/OldCertificateModelFactory.java
certService/src/main/java/org/onap/oom/certservice/certification/conversion/StringBase64ToPrivateKeyConverter.java [new file with mode: 0644]
certService/src/main/java/org/onap/oom/certservice/certification/model/CsrModel.java
certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java
certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpUtil.java
certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CreateCertRequest.java
certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/protections/PasswordBasedProtection.java [moved from certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/PasswordBasedProtection.java with 95% similarity]
certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/protections/PkiMessageProtection.java [moved from certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/PkiMessageProtection.java with 92% similarity]
certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/protections/SignatureProtection.java [moved from certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/SignatureProtection.java with 92% similarity]
certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpCertificationValidator.java
certService/src/test/java/org/onap/oom/certservice/certification/conversion/CsrModelFactoryTest.java
certService/src/test/java/org/onap/oom/certservice/certification/conversion/StringBase64ToPrivateKeyConverterTest.java [new file with mode: 0644]
certService/src/test/java/org/onap/oom/certservice/certification/model/CsrModelTest.java
certService/src/test/java/org/onap/oom/certservice/cmpv2client/impl/protections/PasswordBasedProtectionTest.java [moved from certService/src/test/java/org/onap/oom/certservice/cmpv2client/impl/PasswordBasedProtectionTest.java with 96% similarity]
certService/src/test/java/org/onap/oom/certservice/cmpv2client/impl/protections/PkiTestUtils.java [moved from certService/src/test/java/org/onap/oom/certservice/cmpv2client/impl/PkiTestUtils.java with 98% similarity]
certService/src/test/java/org/onap/oom/certservice/cmpv2client/impl/protections/SignatureProtectionTest.java [moved from certService/src/test/java/org/onap/oom/certservice/cmpv2client/impl/SignatureProtectionTest.java with 91% similarity]

index 94e778e..f7fe2c6 100644 (file)
@@ -70,7 +70,7 @@ public class CertificationProvider {
         return getCertificationResponseModel(certificates);
     }
 
-    private static List<String> convertFromX509CertificateListToPemList(List<X509Certificate> certificates) {
+    private List<String> convertFromX509CertificateListToPemList(List<X509Certificate> certificates) {
         return certificates.stream().map(CertificationProvider::convertFromX509CertificateToPem).filter(cert -> !cert.isEmpty())
                 .collect(Collectors.toList());
     }
index e4ee4c1..6f80f79 100644 (file)
 package org.onap.oom.certservice.certification.conversion;
 
 import org.bouncycastle.pkcs.PKCS10CertificationRequest;
-import org.bouncycastle.util.io.pem.PemObject;
 import org.onap.oom.certservice.certification.exception.CsrDecryptionException;
 import org.onap.oom.certservice.certification.exception.DecryptionException;
-import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
 import org.onap.oom.certservice.certification.model.CsrModel;
 import org.springframework.stereotype.Service;
 
+import java.security.PrivateKey;
+
 
 @Service
 public class CsrModelFactory {
@@ -36,23 +36,14 @@ public class CsrModelFactory {
             = new PemObjectFactory();
     private final Pkcs10CertificationRequestFactory certificationRequestFactory
             = new Pkcs10CertificationRequestFactory();
-
+    private final StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter
+            = new StringBase64ToPrivateKeyConverter();
 
     public CsrModel createCsrModel(StringBase64 csr, StringBase64 privateKey)
             throws DecryptionException {
         PKCS10CertificationRequest decodedCsr = decodeCsr(csr);
-        PemObject decodedPrivateKey = decodePrivateKey(privateKey);
-        return new CsrModel.CsrModelBuilder(decodedCsr, decodedPrivateKey).build();
-    }
-
-    private PemObject decodePrivateKey(StringBase64 privateKey)
-            throws KeyDecryptionException {
-
-        return privateKey.asString()
-                .flatMap(pemObjectFactory::createPemObject)
-                .orElseThrow(
-                        () -> new KeyDecryptionException("Incorrect Key, decryption failed")
-                );
+        PrivateKey javaPrivateKey = stringBase64ToPrivateKeyConverter.convert(privateKey);
+        return new CsrModel.CsrModelBuilder(decodedCsr, javaPrivateKey).build();
     }
 
     private PKCS10CertificationRequest decodeCsr(StringBase64 csr)
index f5c199f..fba5259 100644 (file)
 
 package org.onap.oom.certservice.certification.conversion;
 
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.asn1.x509.Certificate;
 import org.bouncycastle.asn1.x509.GeneralName;
 import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
-import org.bouncycastle.util.io.pem.PemObject;
 import org.onap.oom.certservice.certification.X509CertificateParser;
 import org.onap.oom.certservice.certification.exception.CertificateDecryptionException;
 import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
@@ -41,13 +32,19 @@ import org.onap.oom.certservice.certification.model.OldCertificateModel;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+
 @Service
 public class OldCertificateModelFactory {
 
     private static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n";
     private static final String END_CERTIFICATE = "-----END CERTIFICATE-----\n";
-    private static final PemObjectFactory PEM_OBJECT_FACTORY = new PemObjectFactory();
 
+    private final StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter
+            = new StringBase64ToPrivateKeyConverter();
     private final PemStringToCertificateConverter pemStringToCertificateConverter;
     private final X509CertificateParser x509CertificateParser;
 
@@ -68,14 +65,13 @@ public class OldCertificateModelFactory {
             final X500Name subjectData = x509CertificateParser.getSubject(x509Certificate);
             final GeneralName[] sans = x509CertificateParser.getSans(x509Certificate);
             final Certificate certificate = new JcaX509CertificateHolder(x509Certificate).toASN1Structure();
-            final PrivateKey oldPrivateKey = getOldPrivateKeyObject(encodedOldPrivateKey);
+            final PrivateKey oldPrivateKey = stringBase64ToPrivateKeyConverter.convert(new StringBase64(encodedOldPrivateKey));
             return new OldCertificateModel(certificate, subjectData, sans, oldPrivateKey);
         } catch (StringToCertificateConversionException e) {
             throw new CertificateDecryptionException("Cannot convert certificate", e);
-
         } catch (CertificateParsingException e) {
             throw new CertificateDecryptionException("Cannot read Subject Alternative Names from certificate");
-        } catch (NoSuchAlgorithmException | KeyDecryptionException | CertificateEncodingException | InvalidKeySpecException e) {
+        } catch (KeyDecryptionException | CertificateEncodingException e) {
             throw new CertificateDecryptionException("Cannot convert certificate or key", e);
         }
     }
@@ -91,17 +87,4 @@ public class OldCertificateModelFactory {
         return !(certificateChain.contains(BEGIN_CERTIFICATE) && certificateChain.contains(END_CERTIFICATE));
     }
 
-    private PrivateKey getOldPrivateKeyObject(String encodedOldPrivateKey)
-        throws KeyDecryptionException, InvalidKeySpecException, NoSuchAlgorithmException {
-
-        StringBase64 stringBase64 = new StringBase64(encodedOldPrivateKey);
-        PemObject pemObject = stringBase64.asString()
-            .flatMap(PEM_OBJECT_FACTORY::createPemObject)
-            .orElseThrow(
-                () -> new KeyDecryptionException("Incorrect Key, decryption failed")
-            );
-        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemObject.getContent());
-        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
-        return keyFactory.generatePrivate(keySpec);
-    }
 }
diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/conversion/StringBase64ToPrivateKeyConverter.java b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/StringBase64ToPrivateKeyConverter.java
new file mode 100644 (file)
index 0000000..1ea752b
--- /dev/null
@@ -0,0 +1,55 @@
+/*-
+ * ============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.certification.conversion;
+
+import org.bouncycastle.util.io.pem.PemObject;
+import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
+
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+public class StringBase64ToPrivateKeyConverter {
+
+    private final PemObjectFactory pemObjectFactory = new PemObjectFactory();
+
+    public PrivateKey convert(StringBase64 privateKey) throws KeyDecryptionException {
+        PemObject decodedPrivateKey = createDecodedPrivateKey(privateKey);
+        try {
+            KeyFactory factory = KeyFactory.getInstance("RSA");
+            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedPrivateKey.getContent());
+            return factory.generatePrivate(keySpec);
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+            throw new KeyDecryptionException("Converting Private Key failed", e.getCause());
+        }
+    }
+
+    private PemObject createDecodedPrivateKey(StringBase64 privateKey) throws KeyDecryptionException {
+        return privateKey.asString()
+                .flatMap(pemObjectFactory::createPemObject)
+                .orElseThrow(
+                        () -> new KeyDecryptionException("Incorrect Key, decryption failed")
+                );
+    }
+
+}
index 9675583..cd88ff1 100644 (file)
 
 package org.onap.oom.certservice.certification.model;
 
-import java.io.IOException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Arrays;
-import java.util.stream.Collectors;
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.asn1.x509.Extension;
 import org.bouncycastle.asn1.x509.Extensions;
@@ -41,6 +31,16 @@ import org.onap.oom.certservice.certification.exception.CsrDecryptionException;
 import org.onap.oom.certservice.certification.exception.DecryptionException;
 import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
 
+import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
 
 public class CsrModel {
 
@@ -95,19 +95,18 @@ public class CsrModel {
     public static class CsrModelBuilder {
         private final PKCS10CertificationRequest csr;
 
-        private final PemObject privateKey;
+        private final PrivateKey privateKey;
 
         public CsrModel build() throws DecryptionException {
 
             X500Name subjectData = getSubjectData();
-            PrivateKey javaPrivateKey = convertingPemPrivateKeyToJavaSecurityPrivateKey(getPrivateKey());
             PublicKey javaPublicKey = convertingPemPublicKeyToJavaSecurityPublicKey(getPublicKey());
             GeneralName[] sans = getSansData();
 
-            return new CsrModel(csr, subjectData, javaPrivateKey, javaPublicKey, sans);
+            return new CsrModel(csr, subjectData, privateKey, javaPublicKey, sans);
         }
 
-        public CsrModelBuilder(PKCS10CertificationRequest csr, PemObject privateKey) {
+        public CsrModelBuilder(PKCS10CertificationRequest csr, PrivateKey privateKey) {
             this.csr = csr;
             this.privateKey = privateKey;
         }
@@ -120,10 +119,6 @@ public class CsrModel {
             }
         }
 
-        private PemObject getPrivateKey() {
-            return privateKey;
-        }
-
         private X500Name getSubjectData() {
             return csr.getSubject();
         }
@@ -144,17 +139,6 @@ public class CsrModel {
             return csr.getAttributes().length == 0;
         }
 
-        private PrivateKey convertingPemPrivateKeyToJavaSecurityPrivateKey(PemObject privateKey)
-            throws KeyDecryptionException {
-            try {
-                KeyFactory factory = KeyFactory.getInstance("RSA");
-                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey.getContent());
-                return factory.generatePrivate(keySpec);
-            } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
-                throw new KeyDecryptionException("Converting Private Key failed", e.getCause());
-            }
-        }
-
         private PublicKey convertingPemPublicKeyToJavaSecurityPublicKey(PemObject publicKey)
             throws KeyDecryptionException {
             try {
index bbca91b..5829165 100644 (file)
 
 package org.onap.oom.certservice.cmpv2client.impl;
 
-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;
-
-import java.io.IOException;
-import java.security.KeyPair;
-import java.security.Security;
-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;
@@ -48,11 +35,28 @@ import org.onap.oom.certservice.certification.model.CsrModel;
 import org.onap.oom.certservice.certification.model.OldCertificateModel;
 import org.onap.oom.certservice.cmpv2client.api.CmpClient;
 import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException;
+import org.onap.oom.certservice.cmpv2client.impl.protections.PasswordBasedProtection;
+import org.onap.oom.certservice.cmpv2client.impl.protections.PkiMessageProtection;
+import org.onap.oom.certservice.cmpv2client.impl.protections.SignatureProtection;
 import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel;
 import org.onap.oom.certservice.cmpv2client.validation.CmpCertificationValidator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import java.security.KeyPair;
+import java.security.Security;
+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 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;
+
 /**
  * Implementation of the CmpClient Interface conforming to RFC4210 (Certificate Management Protocol
  * (CMP)) and RFC4211 (Certificate Request Message Format (CRMF)) standards.
index 8912e88..a05a5b7 100644 (file)
 
 package org.onap.oom.certservice.cmpv2client.impl;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.SecureRandom;
-import java.util.Date;
-import java.util.Objects;
-
 import org.bouncycastle.asn1.ASN1Encodable;
 import org.bouncycastle.asn1.ASN1EncodableVector;
 import org.bouncycastle.asn1.ASN1GeneralizedTime;
@@ -46,6 +40,12 @@ import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Date;
+import java.util.Objects;
+
 public final class CmpUtil {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(CmpUtil.class);
@@ -83,7 +83,7 @@ public final class CmpUtil {
      *
      * @return bytes containing a random number string representing a nonce
      */
-    static byte[] createRandomBytes() {
+    public static byte[] createRandomBytes() {
         LOGGER.info("Generating random array of bytes");
         byte[] randomBytes = new byte[RANDOM_BYTE_LENGTH];
         SECURE_RANDOM.nextBytes(randomBytes);
@@ -96,7 +96,7 @@ public final class CmpUtil {
      *
      * @return bytes containing a random number string representing a nonce
      */
-    static int createRandomInt(int range) {
+    public static int createRandomInt(int range) {
         LOGGER.info("Generating random integer");
         return SECURE_RANDOM.nextInt(range) + RANDOM_SEED;
     }
@@ -108,7 +108,7 @@ public final class CmpUtil {
      * @param body   Body of PKIMessage containing specific information for message
      * @return bytes representing the PKIHeader and PKIBody thats to be protected
      */
-    static byte[] generateProtectedBytes(PKIHeader header, PKIBody body) throws CmpClientException {
+    public static byte[] generateProtectedBytes(PKIHeader header, PKIBody body) throws CmpClientException {
         LOGGER.info("Generating array of bytes representing PkiHeader and PkiBody");
         byte[] res;
         ASN1EncodableVector vector = new ASN1EncodableVector();
index c328304..c7ed8b7 100644 (file)
 
 package org.onap.oom.certservice.cmpv2client.impl;
 
-import static org.onap.oom.certservice.cmpv2client.impl.CmpUtil.createRandomInt;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpUtil.generatePkiHeader;
-
-import java.security.KeyPair;
-import java.util.Date;
-
 import org.bouncycastle.asn1.ASN1Integer;
 import org.bouncycastle.asn1.DERBitString;
 import org.bouncycastle.asn1.cmp.CMPCertificate;
@@ -44,6 +38,13 @@ import org.bouncycastle.asn1.x509.GeneralName;
 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
 import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
 import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException;
+import org.onap.oom.certservice.cmpv2client.impl.protections.PkiMessageProtection;
+
+import java.security.KeyPair;
+import java.util.Date;
+
+import static org.onap.oom.certservice.cmpv2client.impl.CmpUtil.createRandomInt;
+import static org.onap.oom.certservice.cmpv2client.impl.CmpUtil.generatePkiHeader;
 
 /**
  * Implementation of the CmpClient Interface conforming to RFC4210 (Certificate Management Protocol
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
 
 import org.bouncycastle.asn1.ASN1Integer;
 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -54,12 +54,12 @@ public class PasswordBasedProtection extends PkiMessageProtection {
 
     private final String initAuthPassword;
 
-    PasswordBasedProtection(String initAuthPassword) {
+    public PasswordBasedProtection(String initAuthPassword) {
         this.initAuthPassword = initAuthPassword;
     }
 
     @Override
-    AlgorithmIdentifier getAlgorithmIdentifier() {
+    public AlgorithmIdentifier getAlgorithmIdentifier() {
         ASN1Integer iteration = new ASN1Integer(ITERATIONS);
         DEROctetString derSalt = new DEROctetString(SALT);
 
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
 
 import org.bouncycastle.asn1.DERBitString;
 import org.bouncycastle.asn1.cmp.PKIBody;
@@ -45,7 +45,7 @@ public abstract class PkiMessageProtection {
      *
      * @return bytes representing protection wrapped into DERBitString object.
      */
-    DERBitString generatePkiMessageProtection(PKIHeader pkiHeader, PKIBody pkiBody) throws CmpClientException {
+    public DERBitString generatePkiMessageProtection(PKIHeader pkiHeader, PKIBody pkiBody) throws CmpClientException {
         try {
             byte[] protectedBytes = generateProtectedBytes(pkiHeader, pkiBody);
             byte[] protectionBytes = generateProtectionBytes(protectedBytes);
@@ -60,17 +60,17 @@ public abstract class PkiMessageProtection {
     }
 
     /**
-     * Takes encoded bytes of PKIMessage (PKIHeader and PKIBody) and generates protection bytes.
+     * Returns Algorithm Identifier for protection of PKIMessage.
      *
-     * @return bytes representing protection.
+     * @return Algorithm Identifier.
      */
-    abstract byte[] generateProtectionBytes(byte[] protectedBytes) throws GeneralSecurityException;
+    public abstract AlgorithmIdentifier getAlgorithmIdentifier();
 
     /**
-     * Returns Algorithm Identifier for protection of PKIMessage.
+     * Takes encoded bytes of PKIMessage (PKIHeader and PKIBody) and generates protection bytes.
      *
-     * @return Algorithm Identifier.
+     * @return bytes representing protection.
      */
-    abstract AlgorithmIdentifier getAlgorithmIdentifier();
+    abstract byte[] generateProtectionBytes(byte[] protectedBytes) throws GeneralSecurityException;
 
 }
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
 
 
 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -40,12 +40,12 @@ public class SignatureProtection extends PkiMessageProtection {
 
     private final PrivateKey oldPrivateKey;
 
-    SignatureProtection(PrivateKey privateKey) {
+    public SignatureProtection(PrivateKey privateKey) {
         this.oldPrivateKey = privateKey;
     }
 
     @Override
-    AlgorithmIdentifier getAlgorithmIdentifier() {
+    public AlgorithmIdentifier getAlgorithmIdentifier() {
         return SHA256_RSA_ALGORITHM;
     }
 
index 40a2a1d..b9a04a4 100644 (file)
 
 package org.onap.oom.certservice.cmpv2client.validation;
 
-import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.checkImplicitConfirm;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifyPasswordBasedProtection;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifySignature;
 
-import java.security.PublicKey;
-import java.util.Date;
-import java.util.Objects;
-import java.util.Optional;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.cmp.CertResponse;
@@ -46,13 +39,22 @@ import org.onap.oom.certservice.cmpv2client.impl.PkiStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.security.PublicKey;
+import java.util.Date;
+import java.util.Objects;
+import java.util.Optional;
+
+import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.checkImplicitConfirm;
+import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifyPasswordBasedProtection;
+import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifySignature;
+
 public class CmpCertificationValidator {
     private static final String DEFAULT_CA_NAME = "Certification Authority";
     private static final String DEFAULT_PROFILE = CaMode.RA.getProfile();
     private static final ASN1ObjectIdentifier PASSWORD_BASED_MAC = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13");
     private static final Logger LOG = LoggerFactory.getLogger(CmpCertificationValidator.class);
 
-    public static void validate(
+    public void validate(
         final CsrModel csrModel,
         final Cmpv2Server server,
         final CloseableHttpClient httpClient,
index 2662486..54508e4 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * Cert Service
  * ================================================================================
- * Copyright (C) 2020 Nokia. All rights reserved.
+ * Copyright (C) 2020-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.certification.conversion;
 
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.onap.oom.certservice.certification.TestData.TEST_CSR;
-import static org.onap.oom.certservice.certification.TestData.TEST_PK;
-import static org.onap.oom.certservice.certification.TestData.TEST_WRONG_CSR;
-import static org.onap.oom.certservice.certification.TestData.TEST_WRONG_PEM;
-
 import org.bouncycastle.util.encoders.Base64;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -36,6 +29,13 @@ import org.onap.oom.certservice.certification.exception.DecryptionException;
 import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
 import org.onap.oom.certservice.certification.model.CsrModel;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.onap.oom.certservice.certification.TestData.TEST_CSR;
+import static org.onap.oom.certservice.certification.TestData.TEST_PK;
+import static org.onap.oom.certservice.certification.TestData.TEST_WRONG_CSR;
+import static org.onap.oom.certservice.certification.TestData.TEST_WRONG_PEM;
+
 
 class CsrModelFactoryTest {
 
@@ -58,7 +58,6 @@ class CsrModelFactoryTest {
 
         assertTrue(decryptedCsr.toString()
             .contains(TestData.EXPECTED_CERT_SUBJECT));
-        System.out.println(decryptedCsr.toString());
         assertTrue(decryptedCsr.toString()
             .contains(TestData.EXPECTED_CERT_SANS));
     }
diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/conversion/StringBase64ToPrivateKeyConverterTest.java b/certService/src/test/java/org/onap/oom/certservice/certification/conversion/StringBase64ToPrivateKeyConverterTest.java
new file mode 100644 (file)
index 0000000..7a722b2
--- /dev/null
@@ -0,0 +1,89 @@
+/*-
+ * ============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.certification.conversion;
+
+import org.bouncycastle.util.encoders.Base64;
+import org.junit.jupiter.api.Test;
+import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
+
+import java.security.PrivateKey;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.onap.oom.certservice.certification.TestData.TEST_PEM;
+import static org.onap.oom.certservice.certification.TestData.TEST_PK;
+
+class StringBase64ToPrivateKeyConverterTest {
+
+    private static final String RSA = "RSA";
+    public static final String PKCS_8 = "PKCS#8";
+
+    @Test
+    void shouldUseProperAlgorithmWhenConverting() throws KeyDecryptionException {
+        // Given
+        StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter = new StringBase64ToPrivateKeyConverter();
+        String encodedPK = new String(Base64.encode(TEST_PK.getBytes()));
+        // When
+        PrivateKey privateKey = stringBase64ToPrivateKeyConverter.convert(new StringBase64(encodedPK));
+        // Then
+        assertEquals(RSA, privateKey.getAlgorithm());
+    }
+
+    @Test
+    void shouldUsePkcs8FormatWhenConverting() throws KeyDecryptionException {
+        // Given
+        StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter = new StringBase64ToPrivateKeyConverter();
+        String encodedPK = new String(Base64.encode(TEST_PK.getBytes()));
+        // When
+        PrivateKey privateKey = stringBase64ToPrivateKeyConverter.convert(new StringBase64(encodedPK));
+        // Then
+        assertEquals(PKCS_8, privateKey.getFormat());
+    }
+
+    @Test
+    void shouldCorrectlyConvertWhenPrivateKeyPemIsProper() throws KeyDecryptionException {
+        // Given
+        StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter = new StringBase64ToPrivateKeyConverter();
+        String encodedPK = new String(Base64.encode(TEST_PK.getBytes()));
+        // When
+        PrivateKey privateKey = stringBase64ToPrivateKeyConverter.convert(new StringBase64(encodedPK));
+        // Then
+        assertNotNull(privateKey.getEncoded());
+    }
+
+    @Test
+    void shouldThrowExceptionWhenPrivateKeyPemIsNotProperPrivateKey() {
+        // Given
+        StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter = new StringBase64ToPrivateKeyConverter();
+        StringBase64 privateKey = new StringBase64(TEST_PEM);
+        // When
+        Exception exception = assertThrows(
+                KeyDecryptionException.class, () -> stringBase64ToPrivateKeyConverter.convert(privateKey));
+
+        String expectedMessage = "Incorrect Key, decryption failed";
+        String actualMessage = exception.getMessage();
+        // Then
+        assertTrue(actualMessage.contains(expectedMessage));
+    }
+
+}
index 72837e5..c3bd4d7 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * PROJECT
  * ================================================================================
- * Copyright (C) 2020 Nokia. All rights reserved.
+ * Copyright (C) 2020-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.certification.model;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
 import org.bouncycastle.pkcs.PKCS10CertificationRequest;
 import org.bouncycastle.util.io.pem.PemObject;
 import org.junit.jupiter.api.Test;
-import org.onap.oom.certservice.certification.conversion.Pkcs10CertificationRequestFactory;
-import org.onap.oom.certservice.certification.conversion.PemObjectFactory;
 import org.onap.oom.certservice.certification.TestData;
+import org.onap.oom.certservice.certification.conversion.PemObjectFactory;
+import org.onap.oom.certservice.certification.conversion.Pkcs10CertificationRequestFactory;
 import org.onap.oom.certservice.certification.exception.CsrDecryptionException;
 import org.onap.oom.certservice.certification.exception.DecryptionException;
 import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
 
 import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -57,7 +62,7 @@ class CsrModelTest {
     @Test
     void shouldByConstructedAndReturnProperFields() throws DecryptionException, IOException {
         // Given
-        PemObject testPrivateKey = getPemPrivateKey();
+        PrivateKey testPrivateKey = getPemPrivateKey();
         PemObject testPublicKey = generateTestPublicKey();
         PKCS10CertificationRequest testCsr = generateTestCertificationRequest();
 
@@ -70,7 +75,7 @@ class CsrModelTest {
         assertThat(csrModel.getCsr())
             .isEqualTo(testCsr);
         assertThat(csrModel.getPrivateKey().getEncoded())
-            .contains(testPrivateKey.getContent());
+            .isEqualTo(testPrivateKey.getEncoded());
         assertThat(csrModel.getPublicKey().getEncoded())
             .contains(testPublicKey.getContent());
         assertThat(sansList)
@@ -84,7 +89,7 @@ class CsrModelTest {
     @Test
     void shouldThrowExceptionWhenPublicKeyIsNotCorrect() throws DecryptionException, IOException {
         // Given
-        PemObject testPrivateKey = getPemPrivateKey();
+        PrivateKey testPrivateKey = getPemPrivateKey();
         PKCS10CertificationRequest testCsr = mock(PKCS10CertificationRequest.class);
         SubjectPublicKeyInfo wrongKryInfo = mock(SubjectPublicKeyInfo.class);
         when(testCsr.getSubjectPublicKeyInfo())
@@ -105,34 +110,10 @@ class CsrModelTest {
         assertTrue(actualMessage.contains(expectedMessage));
     }
 
-    @Test
-    void shouldThrowExceptionWhenPrivateKeyPemIsNotProperPrivateKey() throws KeyDecryptionException, IOException {
-        // Given
-        PemObject testPrivateKey = getPemWrongKey();
-        PKCS10CertificationRequest testCsr = mock(PKCS10CertificationRequest.class);
-        SubjectPublicKeyInfo wrongKryInfo = mock(SubjectPublicKeyInfo.class);
-        when(testCsr.getSubjectPublicKeyInfo())
-            .thenReturn(wrongKryInfo);
-        when(wrongKryInfo.getEncoded())
-            .thenThrow(new IOException());
-
-        // When
-        Exception exception = assertThrows(
-            KeyDecryptionException.class,
-            () -> new CsrModel.CsrModelBuilder(testCsr, testPrivateKey).build()
-        );
-
-        String expectedMessage = "Converting Private Key failed";
-        String actualMessage = exception.getMessage();
-
-        // Then
-        assertTrue(actualMessage.contains(expectedMessage));
-    }
-
     @Test
     void shouldThrowExceptionWhenPublicKeyPemIsNotProperPublicKey() throws KeyDecryptionException, IOException {
         // Given
-        PemObject testPrivateKey = getPemPrivateKey();
+        PrivateKey testPrivateKey = getPemPrivateKey();
         PemObject testPublicKey = getPemWrongKey();
         PKCS10CertificationRequest testCsr = mock(PKCS10CertificationRequest.class);
         SubjectPublicKeyInfo wrongKryInfo = mock(SubjectPublicKeyInfo.class);
@@ -154,11 +135,12 @@ class CsrModelTest {
         assertTrue(actualMessage.contains(expectedMessage));
     }
 
-    private PemObject getPemPrivateKey() throws KeyDecryptionException {
+    private PrivateKey getPemPrivateKey() throws KeyDecryptionException {
         PemObjectFactory pemObjectFactory = new PemObjectFactory();
-        return pemObjectFactory.createPemObject(TEST_PK).orElseThrow(
-            () -> new KeyDecryptionException("Private key decoding fail")
+        PemObject pemObject = pemObjectFactory.createPemObject(TEST_PK).orElseThrow(
+                () -> new KeyDecryptionException("Private key decoding fail")
         );
+        return convertToPrivateKey(pemObject);
     }
 
     private PemObject getPemWrongKey() throws KeyDecryptionException {
@@ -172,7 +154,7 @@ class CsrModelTest {
         PemObject testPrivateKey = pemObjectFactory.createPemObject(TEST_PK).orElseThrow(
             () -> new DecryptionException("Incorrect Private Key, decryption failed")
         );
-        return new CsrModel.CsrModelBuilder(testCsr, testPrivateKey).build();
+        return new CsrModel.CsrModelBuilder(testCsr, convertToPrivateKey(testPrivateKey)).build();
     }
 
     private PemObject generateTestPublicKey() throws DecryptionException, IOException {
@@ -189,4 +171,15 @@ class CsrModelTest {
             );
     }
 
+    private PrivateKey convertToPrivateKey(PemObject privateKey)
+            throws KeyDecryptionException {
+        try {
+            KeyFactory factory = KeyFactory.getInstance("RSA");
+            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey.getContent());
+            return factory.generatePrivate(keySpec);
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+            throw new KeyDecryptionException("Converting Private Key failed", e.getCause());
+        }
+    }
+
 }
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
 
 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.DERBitString;
@@ -44,8 +44,8 @@ import java.security.Security;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getProtectedPkiMessage;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getTestPkiHeader;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getProtectedPkiMessage;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getTestPkiHeader;
 
 class PasswordBasedProtectionTest {
 
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
 
 import org.bouncycastle.asn1.DERBitString;
 import org.bouncycastle.asn1.DERGeneralizedTime;
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
 
 import org.bouncycastle.asn1.DERBitString;
 import org.bouncycastle.asn1.cmp.PKIBody;
@@ -42,9 +42,9 @@ import java.security.Security;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getProtectedPkiMessage;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getTestPkiBody;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getTestPkiHeader;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getProtectedPkiMessage;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getTestPkiBody;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getTestPkiHeader;
 
 class SignatureProtectionTest {