[OOM-CERT-SERVICE] Refactor CmpResponseValidationHelper 98/122598/2
authorPiotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com>
Tue, 13 Jul 2021 14:06:35 +0000 (16:06 +0200)
committerPiotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com>
Thu, 15 Jul 2021 11:26:23 +0000 (11:26 +0000)
- move to validation package
- adjust methods modifiers
- remove duplicated code (getProtectedBytes)

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

certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpCertificationValidator.java
certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpResponseValidationHelper.java [moved from certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpResponseValidationHelper.java with 81% similarity]

index c5d6f3e..93c6047 100644 (file)
@@ -43,9 +43,9 @@ 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;
+import static org.onap.oom.certservice.cmpv2client.validation.CmpResponseValidationHelper.checkImplicitConfirm;
+import static org.onap.oom.certservice.cmpv2client.validation.CmpResponseValidationHelper.verifyPasswordBasedProtection;
+import static org.onap.oom.certservice.cmpv2client.validation.CmpResponseValidationHelper.verifySignature;
 
 public class CmpCertificationValidator {
     private static final String DEFAULT_CA_NAME = "Certification Authority";
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2020 Nordix Foundation.
+ *  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.
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.validation;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
 import java.security.InvalidKeyException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -35,22 +34,18 @@ import javax.crypto.Mac;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
 
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1EncodableVector;
 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.DERBitString;
-import org.bouncycastle.asn1.DEROutputStream;
-import org.bouncycastle.asn1.DERSequence;
 import org.bouncycastle.asn1.cmp.CMPObjectIdentifiers;
 import org.bouncycastle.asn1.cmp.InfoTypeAndValue;
 import org.bouncycastle.asn1.cmp.PBMParameter;
-import org.bouncycastle.asn1.cmp.PKIBody;
 import org.bouncycastle.asn1.cmp.PKIHeader;
 import org.bouncycastle.asn1.cmp.PKIMessage;
 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException;
+import org.onap.oom.certservice.cmpv2client.impl.CmpUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -61,41 +56,6 @@ public final class CmpResponseValidationHelper {
     private CmpResponseValidationHelper() {
     }
 
-    /**
-     * Create a base key to use for verifying the PasswordBasedMac on a PKIMessage
-     *
-     * @param pbmParamSeq      parameters recieved in PKIMessage used with password
-     * @param initAuthPassword password used to decrypt the basekey
-     * @return bytes representing the basekey
-     * @throws CmpClientException thrown if algorithem exceptions occur for the message digest
-     */
-    public static byte[] getBaseKeyFromPbmParameters(
-            PBMParameter pbmParamSeq, String initAuthPassword) throws CmpClientException {
-        final int iterationCount = pbmParamSeq.getIterationCount().getPositiveValue().intValue();
-        LOG.info("Iteration count is: {}", iterationCount);
-        final AlgorithmIdentifier owfAlg = pbmParamSeq.getOwf();
-        LOG.info("One Way Function type is: {}", owfAlg.getAlgorithm().getId());
-        final byte[] salt = pbmParamSeq.getSalt().getOctets();
-        final byte[] raSecret = initAuthPassword != null ? initAuthPassword.getBytes() : new byte[0];
-        byte[] basekey = new byte[raSecret.length + salt.length];
-        System.arraycopy(raSecret, 0, basekey, 0, raSecret.length);
-        System.arraycopy(salt, 0, basekey, raSecret.length, salt.length);
-        try {
-            final MessageDigest messageDigest =
-                    MessageDigest.getInstance(
-                            owfAlg.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME);
-            for (int i = 0; i < iterationCount; i++) {
-                basekey = messageDigest.digest(basekey);
-                messageDigest.reset();
-            }
-        } catch (NoSuchAlgorithmException | NoSuchProviderException ex) {
-            LOG.error("ProtectionBytes don't match passwordBasedProtection, authentication failed");
-            throw new CmpClientException(
-                    "ProtectionBytes don't match passwordBasedProtection, authentication failed", ex);
-        }
-        return basekey;
-    }
-
     /**
      * Verifies the signature of the response message using our public key
      *
@@ -103,7 +63,7 @@ public final class CmpResponseValidationHelper {
      * @param pk             public key used to verify signature.
      * @throws CmpClientException
      */
-    public static void verifySignature(PKIMessage respPkiMessage, PublicKey pk)
+    static void verifySignature(PKIMessage respPkiMessage, PublicKey pk)
             throws CmpClientException {
         final byte[] protBytes = getProtectedBytes(respPkiMessage);
         final DERBitString derBitString = respPkiMessage.getProtection();
@@ -126,45 +86,6 @@ public final class CmpResponseValidationHelper {
         }
     }
 
-    /**
-     * Converts the header and the body of a PKIMessage to an ASN1Encodable and returns the as a byte
-     * array
-     *
-     * @param msg PKIMessage to get protected bytes from
-     * @return the PKIMessage's header and body in byte array
-     */
-    public static byte[] getProtectedBytes(PKIMessage msg) throws CmpClientException {
-        return getProtectedBytes(msg.getHeader(), msg.getBody());
-    }
-
-    /**
-     * Converts the header and the body of a PKIMessage to an ASN1Encodable and returns the as a byte
-     * array
-     *
-     * @param header PKIHeader to be converted
-     * @param body   PKIMessage to be converted
-     * @return the PKIMessage's header and body in byte array
-     */
-    public static byte[] getProtectedBytes(PKIHeader header, PKIBody body) throws CmpClientException {
-        byte[] res;
-        ASN1EncodableVector encodableVector = new ASN1EncodableVector();
-        encodableVector.add(header);
-        encodableVector.add(body);
-        ASN1Encodable protectedPart = new DERSequence(encodableVector);
-        try {
-            ByteArrayOutputStream bao = new ByteArrayOutputStream();
-            DEROutputStream out = new DEROutputStream(bao);
-            out.writeObject(protectedPart);
-            res = bao.toByteArray();
-        } catch (IOException ioe) {
-            CmpClientException cmpClientException =
-                    new CmpClientException("Error occured while getting protected bytes", ioe);
-            LOG.error("Error occured while getting protected bytes", ioe);
-            throw cmpClientException;
-        }
-        return res;
-    }
-
     /**
      * verify the password based protection within the response message
      *
@@ -173,7 +94,7 @@ public final class CmpResponseValidationHelper {
      * @param protectionAlgo   protection algorithm we can use to decrypt protection
      * @throws CmpClientException
      */
-    public static void verifyPasswordBasedProtection(
+    static void verifyPasswordBasedProtection(
             PKIMessage respPkiMessage, String initAuthPassword, AlgorithmIdentifier protectionAlgo)
             throws CmpClientException {
         final byte[] protectedBytes = getProtectedBytes(respPkiMessage);
@@ -198,7 +119,7 @@ public final class CmpResponseValidationHelper {
         }
     }
 
-    public static void checkImplicitConfirm(PKIHeader header) {
+    static void checkImplicitConfirm(PKIHeader header) {
         InfoTypeAndValue[] infos = header.getGeneralInfo();
         if (Objects.nonNull(infos)) {
             if (CMPObjectIdentifiers.it_implicitConfirm.equals(getImplicitConfirm(infos))) {
@@ -211,7 +132,42 @@ public final class CmpResponseValidationHelper {
         }
     }
 
-    public static ASN1ObjectIdentifier getImplicitConfirm(InfoTypeAndValue[] info) {
+    /**
+     * Create a base key to use for verifying the PasswordBasedMac on a PKIMessage
+     *
+     * @param pbmParamSeq      parameters recieved in PKIMessage used with password
+     * @param initAuthPassword password used to decrypt the basekey
+     * @return bytes representing the basekey
+     * @throws CmpClientException thrown if algorithem exceptions occur for the message digest
+     */
+    private static byte[] getBaseKeyFromPbmParameters(
+            PBMParameter pbmParamSeq, String initAuthPassword) throws CmpClientException {
+        final int iterationCount = pbmParamSeq.getIterationCount().getPositiveValue().intValue();
+        LOG.info("Iteration count is: {}", iterationCount);
+        final AlgorithmIdentifier owfAlg = pbmParamSeq.getOwf();
+        LOG.info("One Way Function type is: {}", owfAlg.getAlgorithm().getId());
+        final byte[] salt = pbmParamSeq.getSalt().getOctets();
+        final byte[] raSecret = initAuthPassword != null ? initAuthPassword.getBytes() : new byte[0];
+        byte[] basekey = new byte[raSecret.length + salt.length];
+        System.arraycopy(raSecret, 0, basekey, 0, raSecret.length);
+        System.arraycopy(salt, 0, basekey, raSecret.length, salt.length);
+        try {
+            final MessageDigest messageDigest =
+                    MessageDigest.getInstance(
+                            owfAlg.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME);
+            for (int i = 0; i < iterationCount; i++) {
+                basekey = messageDigest.digest(basekey);
+                messageDigest.reset();
+            }
+        } catch (NoSuchAlgorithmException | NoSuchProviderException ex) {
+            LOG.error("ProtectionBytes don't match passwordBasedProtection, authentication failed");
+            throw new CmpClientException(
+                    "ProtectionBytes don't match passwordBasedProtection, authentication failed", ex);
+        }
+        return basekey;
+    }
+
+    private static ASN1ObjectIdentifier getImplicitConfirm(InfoTypeAndValue[] info) {
         return info[0].getInfoType();
     }
 
@@ -226,7 +182,7 @@ public final class CmpResponseValidationHelper {
      * @throws NoSuchProviderException  Possibly thrown trying to get mac instance
      * @throws InvalidKeyException      Possibly thrown trying to initialize mac using secretkey
      */
-    public static Mac getMac(byte[] protectedBytes, PBMParameter pbmParamSeq, byte[] basekey)
+    private static Mac getMac(byte[] protectedBytes, PBMParameter pbmParamSeq, byte[] basekey)
             throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
         final AlgorithmIdentifier macAlg = pbmParamSeq.getMac();
         LOG.info("Mac type is: {}", macAlg.getAlgorithm().getId());
@@ -238,4 +194,15 @@ public final class CmpResponseValidationHelper {
         mac.update(protectedBytes, 0, protectedBytes.length);
         return mac;
     }
+
+    /**
+     * Converts the header and the body of a PKIMessage to an ASN1Encodable and returns the as a byte
+     * array
+     *
+     * @param msg PKIMessage to get protected bytes from
+     * @return the PKIMessage's header and body in byte array
+     */
+    private static byte[] getProtectedBytes(PKIMessage msg) throws CmpClientException {
+        return CmpUtil.generateProtectedBytes(msg.getHeader(), msg.getBody());
+    }
 }