From c59231cda5282632bbfcf34e0e62c24bfa645fff Mon Sep 17 00:00:00 2001 From: Piotr Marcinkiewicz Date: Tue, 13 Jul 2021 16:06:35 +0200 Subject: [PATCH] [OOM-CERT-SERVICE] Refactor CmpResponseValidationHelper - move to validation package - adjust methods modifiers - remove duplicated code (getProtectedBytes) Issue-ID: OOM-2753 Signed-off-by: Piotr Marcinkiewicz Change-Id: I2dd977ac136e2d1f99338f2c92b36b19651426df --- .../validation/CmpCertificationValidator.java | 6 +- .../CmpResponseValidationHelper.java | 141 ++++++++------------- 2 files changed, 57 insertions(+), 90 deletions(-) rename certService/src/main/java/org/onap/oom/certservice/cmpv2client/{impl => validation}/CmpResponseValidationHelper.java (81%) diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpCertificationValidator.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpCertificationValidator.java index c5d6f3e8..93c60474 100644 --- a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpCertificationValidator.java +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpCertificationValidator.java @@ -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"; diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpResponseValidationHelper.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpResponseValidationHelper.java similarity index 81% rename from certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpResponseValidationHelper.java rename to certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpResponseValidationHelper.java index c699b110..90044b66 100644 --- a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpResponseValidationHelper.java +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpResponseValidationHelper.java @@ -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. @@ -18,10 +19,8 @@ * ============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()); + } } -- 2.16.6