diff options
author | baniewsk <pawel.baniewski@nokia.com> | 2020-07-29 16:01:27 +0200 |
---|---|---|
committer | Pawel <pawel.kasperkiewicz@nokia.com> | 2020-08-05 14:18:54 +0200 |
commit | b8c4e6867d6b26652f4382e93665c220769cdc9f (patch) | |
tree | bb60a44b012731e3ee6fdffe2466f5ed7d6b5c7b /certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl | |
parent | fc31c9e47b3e08f8914dcd1f0c5b6d18aa625567 (diff) |
Removing AAF references from Cert-Service in OOM repo.
Certificates regenerated
External files (from legacy AAF) removed
Still left:
* Sonar link,
* Link to documentation,
* Names of K8s resources in RTD documentation,
* Link to CSITs
Issue-ID: OOM-2526
Signed-off-by: Pawel Baniewski <pawel.baniewski@nokia.com>
Change-Id: I675f7485160b9b8e46e9ea573550e62ed28ca607
Diffstat (limited to 'certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl')
8 files changed, 0 insertions, 1485 deletions
diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java deleted file mode 100644 index 87991132..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java +++ /dev/null @@ -1,242 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. - * ================================================================================ - * 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 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.verifyAndReturnCertChainAndTrustSTore; -import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseValidationHelper.checkImplicitConfirm; -import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifyPasswordBasedProtection; -import static org.onap.aaf.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifySignature; - -import java.io.IOException; -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; -import org.bouncycastle.asn1.cmp.CertResponse; -import org.bouncycastle.asn1.cmp.PKIBody; -import org.bouncycastle.asn1.cmp.PKIHeader; -import org.bouncycastle.asn1.cmp.PKIMessage; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.onap.aaf.certservice.certification.configuration.model.CaMode; -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; - -/** - * Implementation of the CmpClient Interface conforming to RFC4210 (Certificate Management Protocol - * (CMP)) and RFC4211 (Certificate Request Message Format (CRMF)) standards. - */ -public class CmpClientImpl implements CmpClient { - - private static final Logger LOG = LoggerFactory.getLogger(CmpClientImpl.class); - private final CloseableHttpClient httpClient; - - private static final String DEFAULT_CA_NAME = "Certification Authority"; - private static final String DEFAULT_PROFILE = CaMode.RA.getProfile(); - - public CmpClientImpl(CloseableHttpClient httpClient) { - this.httpClient = httpClient; - } - - @Override - public Cmpv2CertificationModel createCertificate( - CsrModel csrModel, - Cmpv2Server server, - Date notBefore, - Date notAfter) - throws CmpClientException { - - validate(csrModel, server, httpClient, notBefore, notAfter); - KeyPair keyPair = new KeyPair(csrModel.getPublicKey(), csrModel.getPrivateKey()); - - final CreateCertRequest certRequest = - CmpMessageBuilder.of(CreateCertRequest::new) - .with(CreateCertRequest::setIssuerDn, server.getIssuerDN()) - .with(CreateCertRequest::setSubjectDn, csrModel.getSubjectData()) - .with(CreateCertRequest::setSansList, csrModel.getSans()) - .with(CreateCertRequest::setSubjectKeyPair, keyPair) - .with(CreateCertRequest::setNotBefore, notBefore) - .with(CreateCertRequest::setNotAfter, notAfter) - .with(CreateCertRequest::setInitAuthPassword, server.getAuthentication().getIak()) - .with(CreateCertRequest::setSenderKid, server.getAuthentication().getRv()) - .build(); - - final PKIMessage pkiMessage = certRequest.generateCertReq(); - Cmpv2HttpClient cmpv2HttpClient = new Cmpv2HttpClient(httpClient); - return retrieveCertificates(csrModel, server, pkiMessage, cmpv2HttpClient); - } - - @Override - public Cmpv2CertificationModel createCertificate(CsrModel csrModel, Cmpv2Server server) - throws CmpClientException { - return createCertificate(csrModel, server, null, null); - } - - private void checkCmpResponse( - final PKIMessage respPkiMessage, final PublicKey publicKey, final String initAuthPassword) - throws CmpClientException { - final PKIHeader header = respPkiMessage.getHeader(); - final AlgorithmIdentifier protectionAlgo = header.getProtectionAlg(); - verifySignatureWithPublicKey(respPkiMessage, publicKey); - verifyProtectionWithProtectionAlgo(respPkiMessage, initAuthPassword, header, protectionAlgo); - } - - private void verifySignatureWithPublicKey(PKIMessage respPkiMessage, PublicKey publicKey) - throws CmpClientException { - if (Objects.nonNull(publicKey)) { - LOG.debug("Verifying signature of the response."); - verifySignature(respPkiMessage, publicKey); - } else { - LOG.error("Public Key is not available, therefore cannot verify signature"); - throw new CmpClientException( - "Public Key is not available, therefore cannot verify signature"); - } - } - - private void verifyProtectionWithProtectionAlgo( - PKIMessage respPkiMessage, - String initAuthPassword, - PKIHeader header, - AlgorithmIdentifier protectionAlgo) - throws CmpClientException { - if (Objects.nonNull(protectionAlgo)) { - LOG.debug("Verifying PasswordBased Protection of the Response."); - verifyPasswordBasedProtection(respPkiMessage, initAuthPassword, protectionAlgo); - checkImplicitConfirm(header); - } else { - LOG.error( - "Protection Algorithm is not available when expecting PBE protected response containing protection algorithm"); - throw new CmpClientException( - "Protection Algorithm is not available when expecting PBE protected response containing protection algorithm"); - } - } - - private Cmpv2CertificationModel checkCmpCertRepMessage(final PKIMessage respPkiMessage) - throws CmpClientException { - final PKIBody pkiBody = respPkiMessage.getBody(); - if (Objects.nonNull(pkiBody) && pkiBody.getContent() instanceof CertRepMessage) { - final CertRepMessage certRepMessage = (CertRepMessage) pkiBody.getContent(); - if (Objects.nonNull(certRepMessage)) { - final CertResponse certResponse = - getCertificateResponseContainingNewCertificate(certRepMessage); - try { - return verifyReturnCertChainAndTrustStore(respPkiMessage, certRepMessage, certResponse); - } catch (IOException | CertificateParsingException ex) { - CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while retrieving Certificates from response", ex); - LOG.error("Exception occurred while retrieving Certificates from response", ex); - throw cmpClientException; - } - } else { - return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList()); - } - } - return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList()); - } - - 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); - if (leafCertificate.isPresent()) { - return verifyAndReturnCertChainAndTrustSTore( - respPkiMessage, certRepMessage, leafCertificate.get()); - } - return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList()); - } - - private CertResponse getCertificateResponseContainingNewCertificate( - CertRepMessage certRepMessage) { - return certRepMessage.getResponse()[0]; - } - - /** - * 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}. - * @throws IllegalArgumentException if Before Date is set after the After Date. - */ - private static void validate( - final CsrModel csrModel, - final Cmpv2Server server, - final CloseableHttpClient httpClient, - final Date notBefore, - final Date notAfter) { - - String caName = CmpUtil.isNullOrEmpty(server.getCaName()) ? server.getCaName() : DEFAULT_CA_NAME; - String profile = server.getCaMode() != null ? server.getCaMode().getProfile() : DEFAULT_PROFILE; - LOG.info( - "Validate before creating Certificate Request for CA :{} in Mode {} ", caName, profile); - - CmpUtil.notNull(csrModel, "CsrModel Instance"); - CmpUtil.notNull(csrModel.getSubjectData(), "Subject DN"); - CmpUtil.notNull(csrModel.getPrivateKey(), "Subject private key"); - CmpUtil.notNull(csrModel.getPublicKey(), "Subject public key"); - CmpUtil.notNull(server.getIssuerDN(), "Issuer DN"); - CmpUtil.notNull(server.getUrl(), "External CA URL"); - CmpUtil.notNull(server.getAuthentication().getIak(), "IAK/RV Password"); - CmpUtil.notNull(httpClient, "Closeable Http Client"); - - if (notBefore != null && notAfter != null && notBefore.compareTo(notAfter) > 0) { - throw new IllegalArgumentException("Before Date is set after the After Date"); - } - } - - private Cmpv2CertificationModel retrieveCertificates( - CsrModel csrModel, Cmpv2Server server, PKIMessage pkiMessage, Cmpv2HttpClient cmpv2HttpClient) - throws CmpClientException { - final byte[] respBytes = cmpv2HttpClient.postRequest(pkiMessage, server.getUrl(), server.getCaName()); - try { - final PKIMessage respPkiMessage = PKIMessage.getInstance(respBytes); - LOG.info("Received response from Server"); - checkIfCmpResponseContainsError(respPkiMessage); - checkCmpResponse(respPkiMessage, csrModel.getPublicKey(), server.getAuthentication().getIak()); - return checkCmpCertRepMessage(respPkiMessage); - } catch (IllegalArgumentException iae) { - CmpClientException cmpClientException = - new CmpClientException( - "Error encountered while processing response from CA server ", iae); - LOG.error("Error encountered while processing response from CA server ", iae); - throw cmpClientException; - } - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageBuilder.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageBuilder.java deleted file mode 100644 index 1f370f93..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageBuilder.java +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. - * ================================================================================ - * 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 java.util.ArrayList; -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Supplier; - -/** - * Generic Builder Class for creating CMP Message. - */ -public final class CmpMessageBuilder<T> { - - private final Supplier<T> instantiator; - private final List<Consumer<T>> instanceModifiers = new ArrayList<>(); - - public CmpMessageBuilder(Supplier<T> instantiator) { - this.instantiator = instantiator; - } - - public static <T> CmpMessageBuilder<T> of(Supplier<T> instantiator) { - return new CmpMessageBuilder<>(instantiator); - } - - public <U> CmpMessageBuilder<T> with(BiConsumer<T, U> consumer, U value) { - Consumer<T> valueConsumer = instance -> consumer.accept(instance, value); - instanceModifiers.add(valueConsumer); - return this; - } - - public T build() { - T value = instantiator.get(); - instanceModifiers.forEach(modifier -> modifier.accept(value)); - instanceModifiers.clear(); - return value; - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageHelper.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageHelper.java deleted file mode 100644 index 6fcc5f14..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpMessageHelper.java +++ /dev/null @@ -1,246 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. - * ================================================================================ - * 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 static org.onap.aaf.certservice.cmpv2client.impl.CmpUtil.generateProtectedBytes; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.KeyPair; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.Signature; -import java.security.SignatureException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.DEROutputStream; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.DERTaggedObject; -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.crmf.CertRequest; -import org.bouncycastle.asn1.crmf.OptionalValidity; -import org.bouncycastle.asn1.crmf.POPOSigningKey; -import org.bouncycastle.asn1.crmf.ProofOfPossession; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.Extensions; -import org.bouncycastle.asn1.x509.ExtensionsGenerator; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.asn1.x509.KeyUsage; -import org.bouncycastle.asn1.x509.Time; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class CmpMessageHelper { - - private static final Logger LOG = LoggerFactory.getLogger(CmpMessageHelper.class); - private static final AlgorithmIdentifier OWF_ALGORITHM = - new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.3.14.3.2.26")); - private static final AlgorithmIdentifier MAC_ALGORITHM = - new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.2.9")); - private static final ASN1ObjectIdentifier PASSWORD_BASED_MAC = - new ASN1ObjectIdentifier("1.2.840.113533.7.66.13"); - - private CmpMessageHelper() { - } - - /** - * Creates an Optional Validity, which is used to specify how long the returned cert should be - * valid for. - * - * @param notBefore Date specifying certificate is not valid before this date. - * @param notAfter Date specifying certificate is not valid after this date. - * @return {@link OptionalValidity} that can be set for certificate on external CA. - */ - public static OptionalValidity generateOptionalValidity( - final Date notBefore, final Date notAfter) { - LOG.info("Generating Optional Validity from Date objects"); - ASN1EncodableVector optionalValidityV = new ASN1EncodableVector(); - if (notBefore != null) { - Time nb = new Time(notBefore); - optionalValidityV.add(new DERTaggedObject(true, 0, nb)); - } - if (notAfter != null) { - Time na = new Time(notAfter); - optionalValidityV.add(new DERTaggedObject(true, 1, na)); - } - return OptionalValidity.getInstance(new DERSequence(optionalValidityV)); - } - - /** - * Create Extensions from Subject Alternative Names. - * - * @return {@link Extensions}. - */ - public static Extensions generateExtension(final List<String> sansList) - throws CmpClientException { - LOG.info("Generating Extensions from Subject Alternative Names"); - final ExtensionsGenerator extGenerator = new ExtensionsGenerator(); - final GeneralName[] sansGeneralNames = getGeneralNames(sansList); - // KeyUsage - try { - final KeyUsage keyUsage = - new KeyUsage( - KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.nonRepudiation); - extGenerator.addExtension(Extension.keyUsage, false, new DERBitString(keyUsage)); - extGenerator.addExtension( - Extension.subjectAlternativeName, false, new GeneralNames(sansGeneralNames)); - } catch (IOException ioe) { - CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while creating extensions for PKIMessage", ioe); - LOG.error("Exception occurred while creating extensions for PKIMessage"); - throw cmpClientException; - } - return extGenerator.generate(); - } - - public static GeneralName[] getGeneralNames(List<String> sansList) { - final List<GeneralName> nameList = new ArrayList<>(); - for (String san : sansList) { - nameList.add(new GeneralName(GeneralName.dNSName, san)); - } - final GeneralName[] sansGeneralNames = new GeneralName[nameList.size()]; - nameList.toArray(sansGeneralNames); - return sansGeneralNames; - } - - /** - * Method generates Proof-of-Possession (POP) of Private Key. To allow a CA/RA to properly - * validity binding between an End Entity and a Key Pair, the PKI Operations specified here make - * it possible for an End Entity to prove that it has possession of the Private Key corresponding - * to the Public Key for which a Certificate is requested. - * - * @param certRequest Certificate request that requires proof of possession - * @param keypair keypair associated with the subject sending the certificate request - * @return {@link ProofOfPossession}. - * @throws CmpClientException A general-purpose Cmp client exception. - */ - public static ProofOfPossession generateProofOfPossession( - final CertRequest certRequest, final KeyPair keypair) throws CmpClientException { - ProofOfPossession proofOfPossession; - try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { - final DEROutputStream derOutputStream = new DEROutputStream(byteArrayOutputStream); - derOutputStream.writeObject(certRequest); - - byte[] popoProtectionBytes = byteArrayOutputStream.toByteArray(); - final String sigalg = PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(); - final Signature signature = Signature.getInstance(sigalg, BouncyCastleProvider.PROVIDER_NAME); - signature.initSign(keypair.getPrivate()); - signature.update(popoProtectionBytes); - DERBitString bs = new DERBitString(signature.sign()); - - proofOfPossession = - new ProofOfPossession( - new POPOSigningKey( - null, new AlgorithmIdentifier(new ASN1ObjectIdentifier(sigalg)), bs)); - } catch (IOException - | NoSuchProviderException - | NoSuchAlgorithmException - | InvalidKeyException - | SignatureException ex) { - CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while creating proof of possession for PKIMessage", ex); - LOG.error("Exception occurred while creating proof of possession for PKIMessage"); - throw cmpClientException; - } - return proofOfPossession; - } - - /** - * Generic code to create Algorithm Identifier for protection of PKIMessage. - * - * @return Algorithm Identifier - */ - public static AlgorithmIdentifier protectionAlgoIdentifier(int iterations, byte[] salt) { - ASN1Integer iteration = new ASN1Integer(iterations); - DEROctetString derSalt = new DEROctetString(salt); - - PBMParameter pp = new PBMParameter(derSalt, OWF_ALGORITHM, iteration, MAC_ALGORITHM); - return new AlgorithmIdentifier(PASSWORD_BASED_MAC, pp); - } - - /** - * Adds protection to the PKIMessage via a specified protection algorithm. - * - * @param password password used to authenticate PkiMessage with external CA - * @param pkiHeader Header of PKIMessage containing generic details for any PKIMessage - * @param pkiBody Body of PKIMessage containing specific details for certificate request - * @return Protected Pki Message - * @throws CmpClientException Wraps several exceptions into one general-purpose exception. - */ - public static PKIMessage protectPkiMessage( - PKIHeader pkiHeader, PKIBody pkiBody, String password, int iterations, byte[] salt) - throws CmpClientException { - - byte[] raSecret = password.getBytes(); - 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); - byte[] out; - try { - MessageDigest dig = - MessageDigest.getInstance( - OWF_ALGORITHM.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME); - for (int i = 0; i < iterations; i++) { - basekey = dig.digest(basekey); - dig.reset(); - } - byte[] protectedBytes = generateProtectedBytes(pkiHeader, pkiBody); - Mac mac = - Mac.getInstance(MAC_ALGORITHM.getAlgorithm().getId(), BouncyCastleProvider.PROVIDER_NAME); - SecretKey key = new SecretKeySpec(basekey, MAC_ALGORITHM.getAlgorithm().getId()); - mac.init(key); - mac.reset(); - mac.update(protectedBytes, 0, protectedBytes.length); - out = mac.doFinal(); - } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException ex) { - CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while generating proof of possession for PKIMessage", ex); - LOG.error("Exception occured while generating the proof of possession for PKIMessage"); - throw cmpClientException; - } - DERBitString bs = new DERBitString(out); - - return new PKIMessage(pkiHeader, pkiBody, bs); - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelper.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelper.java deleted file mode 100644 index 3cb0b0c5..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseHelper.java +++ /dev/null @@ -1,335 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. - * ================================================================================ - * 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 java.io.ByteArrayInputStream; -import java.io.IOException; -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.cert.CertPath; -import java.security.cert.CertPathValidator; -import java.security.cert.CertPathValidatorException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.CertificateParsingException; -import java.security.cert.PKIXCertPathChecker; -import java.security.cert.PKIXCertPathValidatorResult; -import java.security.cert.PKIXParameters; -import java.security.cert.TrustAnchor; -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; - -import org.bouncycastle.asn1.cmp.CMPCertificate; -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; - -public final class CmpResponseHelper { - - private static final Logger LOG = LoggerFactory.getLogger(CmpResponseHelper.class); - - private CmpResponseHelper() { - } - - static void checkIfCmpResponseContainsError(PKIMessage respPkiMessage) - throws CmpClientException { - if (respPkiMessage.getBody().getType() == PKIBody.TYPE_ERROR) { - final ErrorMsgContent errorMsgContent = - (ErrorMsgContent) respPkiMessage.getBody().getContent(); - PkiErrorException pkiErrorException = - new PkiErrorException( - errorMsgContent.getPKIStatusInfo().getStatusString().getStringAt(0).getString()); - CmpClientException cmpClientException = - new CmpClientException("Error in the PkiMessage response", pkiErrorException); - LOG.error("Error in the PkiMessage response: {} ", pkiErrorException.getMessage()); - throw cmpClientException; - } - } - - - /** - * 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 - */ - static Cmpv2CertificationModel verifyAndReturnCertChainAndTrustSTore( - PKIMessage respPkiMessage, CertRepMessage certRepMessage, X509Certificate leafCertificate) - throws CertificateParsingException, IOException, CmpClientException { - Map<X500Name, X509Certificate> certificates = mapAllCertificates(respPkiMessage, certRepMessage); - return extractCertificationModel(certificates, leafCertificate); - } - - private static Map<X500Name, X509Certificate> mapAllCertificates( - PKIMessage respPkiMessage, CertRepMessage certRepMessage - ) - throws IOException, CertificateParsingException, CmpClientException { - - 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 certificates; - } - - 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. - * - * @param certificate X.509 certificate to verify. May not be null. - * @param caCertChain Collection of X509Certificates. May not be null, an empty list or a - * Collection with null entries. - * @param date Date to verify at, or null to use current time. - * @param pkixCertPathCheckers optional PKIXCertPathChecker implementations to use during cert - * path validation - * @throws CmpClientException if certificate could not be validated - */ - private static void verify( - X509Certificate certificate, - X509Certificate caCertChain, - Date date, - PKIXCertPathChecker... pkixCertPathCheckers) - throws CmpClientException { - try { - verifyCertificates(certificate, caCertChain, date, pkixCertPathCheckers); - } catch (CertPathValidatorException cpve) { - CmpClientException cmpClientException = - new CmpClientException( - "Invalid certificate or certificate not issued by specified CA: ", cpve); - LOG.error("Invalid certificate or certificate not issued by specified CA: ", cpve); - throw cmpClientException; - } catch (CertificateException ce) { - CmpClientException cmpClientException = - new CmpClientException("Something was wrong with the supplied certificate", ce); - LOG.error("Something was wrong with the supplied certificate", ce); - throw cmpClientException; - } catch (NoSuchProviderException nspe) { - CmpClientException cmpClientException = - new CmpClientException("BouncyCastle provider not found.", nspe); - LOG.error("BouncyCastle provider not found.", nspe); - throw cmpClientException; - } catch (NoSuchAlgorithmException nsae) { - CmpClientException cmpClientException = - new CmpClientException("Algorithm PKIX was not found.", nsae); - LOG.error("Algorithm PKIX was not found.", nsae); - throw cmpClientException; - } catch (InvalidAlgorithmParameterException iape) { - CmpClientException cmpClientException = - new CmpClientException( - "Either ca certificate chain was empty," - + " or the certificate was on an inappropriate type for a PKIX path checker.", - iape); - LOG.error( - "Either ca certificate chain was empty, " - + "or the certificate was on an inappropriate type for a PKIX path checker.", - iape); - throw cmpClientException; - } - } - - 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(), - caCertChain.getSubjectDN().getName()); - CertPath cp = getCertPath(certificate); - PKIXParameters params = getPkixParameters(caCertChain, date, pkixCertPathCheckers); - CertPathValidator cpv = - CertPathValidator.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME); - PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, params); - if (LOG.isDebugEnabled()) { - LOG.debug("Certificate verify result:{} ", result); - } - } - - private static PKIXParameters getPkixParameters( - X509Certificate caCertChain, Date date, PKIXCertPathChecker[] pkixCertPathCheckers) - throws InvalidAlgorithmParameterException { - TrustAnchor anchor = new TrustAnchor(caCertChain, null); - PKIXParameters params = new PKIXParameters(Collections.singleton(anchor)); - for (final PKIXCertPathChecker pkixCertPathChecker : pkixCertPathCheckers) { - params.addCertPathChecker(pkixCertPathChecker); - } - params.setRevocationEnabled(false); - params.setDate(date); - return params; - } - - private static CertPath getCertPath(X509Certificate certificate) - throws CertificateException, NoSuchProviderException { - ArrayList<X509Certificate> certlist = new ArrayList<>(); - certlist.add(certificate); - return CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME) - .generateCertPath(certlist); - } - - /** - * Returns a CertificateFactory that can be used to create certificates from byte arrays and such. - * - * @param provider Security provider that should be used to create certificates, default BC is - * null is passed. - * @return CertificateFactory for creating certificate - */ - private static CertificateFactory getCertificateFactory(final String provider) - throws CmpClientException { - LOG.debug("Creating certificate Factory to generate certificate using provider {}", provider); - final String prov; - prov = Objects.requireNonNullElse(provider, BouncyCastleProvider.PROVIDER_NAME); - try { - return CertificateFactory.getInstance("X.509", prov); - } catch (NoSuchProviderException nspe) { - CmpClientException cmpClientException = new CmpClientException("NoSuchProvider: ", nspe); - LOG.error("NoSuchProvider: ", nspe); - throw cmpClientException; - } catch (CertificateException ce) { - CmpClientException cmpClientException = new CmpClientException("CertificateException: ", ce); - LOG.error("CertificateException: ", ce); - throw cmpClientException; - } - } - - /** - * @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. - */ - 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; - - 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(); - } - } - - - /** - * 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. - */ - 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); - } - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseValidationHelper.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseValidationHelper.java deleted file mode 100644 index 4b9f2cd1..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpResponseValidationHelper.java +++ /dev/null @@ -1,241 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. - * ================================================================================ - * 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 java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PublicKey; -import java.security.Signature; -import java.security.SignatureException; -import java.util.Arrays; -import java.util.Objects; -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.aaf.certservice.cmpv2client.exceptions.CmpClientException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class CmpResponseValidationHelper { - - private static final Logger LOG = LoggerFactory.getLogger(CmpResponseValidationHelper.class); - - 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 - * - * @param respPkiMessage PKIMessage we wish to verify signature for - * @param pk public key used to verify signature. - * @throws CmpClientException - */ - public static void verifySignature(PKIMessage respPkiMessage, PublicKey pk) - throws CmpClientException { - final byte[] protBytes = getProtectedBytes(respPkiMessage); - final DERBitString derBitString = respPkiMessage.getProtection(); - try { - final Signature signature = - Signature.getInstance( - PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), - BouncyCastleProvider.PROVIDER_NAME); - signature.initVerify(pk); - signature.update(protBytes); - signature.verify(derBitString.getBytes()); - } catch (NoSuchAlgorithmException - | NoSuchProviderException - | InvalidKeyException - | SignatureException e) { - CmpClientException clientException = - new CmpClientException("Signature Verification failed", e); - LOG.error("Signature Verification failed", e); - throw clientException; - } - } - - /** - * 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 - * - * @param respPkiMessage PKIMessage we want to verify password based protection for - * @param initAuthPassword password used to decrypt protection - * @param protectionAlgo protection algorithm we can use to decrypt protection - * @throws CmpClientException - */ - public static void verifyPasswordBasedProtection( - PKIMessage respPkiMessage, String initAuthPassword, AlgorithmIdentifier protectionAlgo) - throws CmpClientException { - final byte[] protectedBytes = getProtectedBytes(respPkiMessage); - final PBMParameter pbmParamSeq = PBMParameter.getInstance(protectionAlgo.getParameters()); - if (Objects.nonNull(pbmParamSeq)) { - try { - byte[] basekey = getBaseKeyFromPbmParameters(pbmParamSeq, initAuthPassword); - final Mac mac = getMac(protectedBytes, pbmParamSeq, basekey); - final byte[] outBytes = mac.doFinal(); - final byte[] protectionBytes = respPkiMessage.getProtection().getBytes(); - if (!Arrays.equals(outBytes, protectionBytes)) { - LOG.error("protectionBytes don't match passwordBasedProtection, authentication failed"); - throw new CmpClientException( - "protectionBytes don't match passwordBasedProtection, authentication failed"); - } - } catch (NoSuchProviderException | NoSuchAlgorithmException | InvalidKeyException ex) { - CmpClientException cmpClientException = - new CmpClientException("Error while validating CMP response ", ex); - LOG.error("Error while validating CMP response ", ex); - throw cmpClientException; - } - } - } - - public static void checkImplicitConfirm(PKIHeader header) { - InfoTypeAndValue[] infos = header.getGeneralInfo(); - if (Objects.nonNull(infos)) { - if (CMPObjectIdentifiers.it_implicitConfirm.equals(getImplicitConfirm(infos))) { - LOG.info("Implicit Confirm on certificate from server."); - } else { - LOG.debug("No Implicit confirm in Response"); - } - } else { - LOG.debug("No general Info in header of response, cannot verify implicit confirm"); - } - } - - public static ASN1ObjectIdentifier getImplicitConfirm(InfoTypeAndValue[] info) { - return info[0].getInfoType(); - } - - /** - * Get cryptographical Mac we can use to decrypt our PKIMessage - * - * @param protectedBytes Protected bytes representing the PKIMessage - * @param pbmParamSeq Parameters used to decrypt PKIMessage, including mac algorithm used - * @param basekey Key used alongside mac Oid to create secret key for decrypting PKIMessage - * @return Mac that's ready to return decrypted bytes - * @throws NoSuchAlgorithmException Possibly thrown trying to get mac instance - * @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) - throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException { - final AlgorithmIdentifier macAlg = pbmParamSeq.getMac(); - LOG.info("Mac type is: {}", macAlg.getAlgorithm().getId()); - final String macOid = macAlg.getAlgorithm().getId(); - final Mac mac = Mac.getInstance(macOid, BouncyCastleProvider.PROVIDER_NAME); - final SecretKey key = new SecretKeySpec(basekey, macOid); - mac.init(key); - mac.reset(); - mac.update(protectedBytes, 0, protectedBytes.length); - return mac; - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpUtil.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpUtil.java deleted file mode 100644 index ced0fed0..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpUtil.java +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. - * ================================================================================ - * 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 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; -import org.bouncycastle.asn1.DEROctetString; -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.PKIBody; -import org.bouncycastle.asn1.cmp.PKIHeader; -import org.bouncycastle.asn1.cmp.PKIHeaderBuilder; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x509.GeneralName; -import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class CmpUtil { - - private static final Logger LOGGER = LoggerFactory.getLogger(CmpUtil.class); - private static final SecureRandom SECURE_RANDOM = new SecureRandom(); - public static final int RANDOM_BYTE_LENGTH = 16; - public static final int RANDOM_SEED = 1000; - - private CmpUtil() { - } - - /** - * Validates specified object reference is not null. - * - * @param argument T - the type of the reference. - * @param message message - detail message to be used in the event that a NullPointerException is - * thrown. - * @return The Object if not null - */ - public static <T> T notNull(T argument, String message) { - return Objects.requireNonNull(argument, message + " must not be null"); - } - - /** - * Validates String object reference is not null and not empty. - * - * @param stringArg String Object that need to be validated. - * @return boolean - */ - public static boolean isNullOrEmpty(String stringArg) { - return (stringArg != null && !stringArg.trim().isEmpty()); - } - - /** - * Creates a random number than can be used for sendernonce, transactionId and salts. - * - * @return bytes containing a random number string representing a nonce - */ - static byte[] createRandomBytes() { - LOGGER.info("Generating random array of bytes"); - byte[] randomBytes = new byte[RANDOM_BYTE_LENGTH]; - SECURE_RANDOM.nextBytes(randomBytes); - return randomBytes; - } - - /** - * Creates a random integer than can be used to represent a transactionId or determine the number - * iterations in a protection algorithm. - * - * @return bytes containing a random number string representing a nonce - */ - static int createRandomInt(int range) { - LOGGER.info("Generating random integer"); - return SECURE_RANDOM.nextInt(range) + RANDOM_SEED; - } - - /** - * Generates protected bytes of a combined PKIHeader and PKIBody. - * - * @param header Header of PKIMessage containing common parameters - * @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 { - LOGGER.info("Generating array of bytes representing PkiHeader and PkiBody"); - byte[] res; - ASN1EncodableVector vector = new ASN1EncodableVector(); - vector.add(header); - vector.add(body); - ASN1Encodable protectedPart = new DERSequence(vector); - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - DEROutputStream out = new DEROutputStream(baos); - out.writeObject(protectedPart); - res = baos.toByteArray(); - } catch (IOException ioe) { - CmpClientException cmpClientException = - new CmpClientException("IOException occurred while creating protectedBytes", ioe); - LOGGER.error("IOException occurred while creating protectedBytes"); - throw cmpClientException; - } - return res; - } - - /** - * Generates a PKIHeader Builder object. - * - * @param subjectDn distinguished name of Subject - * @param issuerDn distinguished name of external CA - * @param protectionAlg protection Algorithm used to protect PKIMessage - * @return PKIHeaderBuilder - */ - static PKIHeader generatePkiHeader( - X500Name subjectDn, X500Name issuerDn, AlgorithmIdentifier protectionAlg, String senderKid) { - LOGGER.info("Generating a Pki Header Builder"); - PKIHeaderBuilder pkiHeaderBuilder = - new PKIHeaderBuilder( - PKIHeader.CMP_2000, new GeneralName(subjectDn), new GeneralName(issuerDn)); - - pkiHeaderBuilder.setMessageTime(new ASN1GeneralizedTime(new Date())); - pkiHeaderBuilder.setSenderNonce(new DEROctetString(createRandomBytes())); - pkiHeaderBuilder.setTransactionID(new DEROctetString(createRandomBytes())); - pkiHeaderBuilder.setProtectionAlg(protectionAlg); - pkiHeaderBuilder.setGeneralInfo(new InfoTypeAndValue(CMPObjectIdentifiers.it_implicitConfirm)); - pkiHeaderBuilder.setSenderKID(new DEROctetString(senderKid.getBytes())); - - return pkiHeaderBuilder.build(); - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/Cmpv2HttpClient.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/Cmpv2HttpClient.java deleted file mode 100644 index 68c743d2..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/Cmpv2HttpClient.java +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. - * ================================================================================ - * 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 java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ByteArrayEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.bouncycastle.asn1.cmp.PKIMessage; -import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class Cmpv2HttpClient { - - private static final Logger LOG = LoggerFactory.getLogger(Cmpv2HttpClient.class); - - private static final String CONTENT_TYPE = "Content-type"; - private static final String CMP_REQUEST_MIMETYPE = "application/pkixcmp"; - private final CloseableHttpClient httpClient; - - /** - * constructor for Cmpv2HttpClient - * - * @param httpClient CloseableHttpClient used for sending/recieve request. - */ - Cmpv2HttpClient(CloseableHttpClient httpClient) { - this.httpClient = httpClient; - } - - /** - * Send Post Request to Server - * - * @param pkiMessage PKIMessage to send to server - * @param urlString url for the server we're sending request - * @param caName name of CA server - * @return PKIMessage received from CMPServer - * @throws CmpClientException thrown if problems with connecting or parsing response to server - */ - public byte[] postRequest( - final PKIMessage pkiMessage, final String urlString, final String caName) - throws CmpClientException { - try (ByteArrayOutputStream byteArrOutputStream = new ByteArrayOutputStream()) { - final HttpPost postRequest = new HttpPost(urlString); - final byte[] requestBytes = pkiMessage.getEncoded(); - - postRequest.setEntity(new ByteArrayEntity(requestBytes)); - postRequest.setHeader(CONTENT_TYPE, CMP_REQUEST_MIMETYPE); - - try (CloseableHttpResponse response = httpClient.execute(postRequest)) { - response.getEntity().writeTo(byteArrOutputStream); - } - return byteArrOutputStream.toByteArray(); - } catch (IOException ioe) { - CmpClientException cmpClientException = - new CmpClientException( - String.format("IOException error while trying to connect CA %s", caName), ioe); - LOG.error("IOException error {}, while trying to connect CA {}", ioe.getMessage(), caName); - throw cmpClientException; - } - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CreateCertRequest.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CreateCertRequest.java deleted file mode 100644 index 74380d84..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CreateCertRequest.java +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation. - * ================================================================================ - * 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 static org.onap.aaf.certservice.cmpv2client.impl.CmpUtil.createRandomBytes; -import static org.onap.aaf.certservice.cmpv2client.impl.CmpUtil.createRandomInt; -import static org.onap.aaf.certservice.cmpv2client.impl.CmpUtil.generatePkiHeader; - -import java.security.KeyPair; -import java.util.Date; -import java.util.List; - -import org.bouncycastle.asn1.cmp.PKIBody; -import org.bouncycastle.asn1.cmp.PKIHeader; -import org.bouncycastle.asn1.cmp.PKIMessage; -import org.bouncycastle.asn1.crmf.CertReqMessages; -import org.bouncycastle.asn1.crmf.CertReqMsg; -import org.bouncycastle.asn1.crmf.CertRequest; -import org.bouncycastle.asn1.crmf.CertTemplateBuilder; -import org.bouncycastle.asn1.crmf.ProofOfPossession; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException; - -/** - * Implementation of the CmpClient Interface conforming to RFC4210 (Certificate Management Protocol - * (CMP)) and RFC4211 (Certificate Request Message Format (CRMF)) standards. - */ -class CreateCertRequest { - - private X500Name issuerDn; - private X500Name subjectDn; - private List<String> sansList; - private KeyPair subjectKeyPair; - private Date notBefore; - private Date notAfter; - private String initAuthPassword; - private String senderKid; - - private static final int ITERATIONS = createRandomInt(5000); - private static final byte[] SALT = createRandomBytes(); - private final int certReqId = createRandomInt(Integer.MAX_VALUE); - - public void setIssuerDn(X500Name issuerDn) { - this.issuerDn = issuerDn; - } - - public void setSubjectDn(X500Name subjectDn) { - this.subjectDn = subjectDn; - } - - public void setSansList(List<String> sansList) { - this.sansList = sansList; - } - - public void setSubjectKeyPair(KeyPair subjectKeyPair) { - this.subjectKeyPair = subjectKeyPair; - } - - public void setNotBefore(Date notBefore) { - this.notBefore = notBefore; - } - - public void setNotAfter(Date notAfter) { - this.notAfter = notAfter; - } - - public void setInitAuthPassword(String initAuthPassword) { - this.initAuthPassword = initAuthPassword; - } - - public void setSenderKid(String senderKid) { - this.senderKid = senderKid; - } - - /** - * Method to create {@link PKIMessage} from {@link CertRequest},{@link ProofOfPossession}, {@link - * CertReqMsg}, {@link CertReqMessages}, {@link PKIHeader} and {@link PKIBody}. - * - * @return {@link PKIMessage} - */ - public PKIMessage generateCertReq() throws CmpClientException { - final CertTemplateBuilder certTemplateBuilder = - new CertTemplateBuilder() - .setIssuer(issuerDn) - .setSubject(subjectDn) - .setExtensions(CmpMessageHelper.generateExtension(sansList)) - .setValidity(CmpMessageHelper.generateOptionalValidity(notBefore, notAfter)) - .setPublicKey( - SubjectPublicKeyInfo.getInstance(subjectKeyPair.getPublic().getEncoded())); - - final CertRequest certRequest = new CertRequest(certReqId, certTemplateBuilder.build(), null); - final ProofOfPossession proofOfPossession = - CmpMessageHelper.generateProofOfPossession(certRequest, subjectKeyPair); - - final CertReqMsg certReqMsg = new CertReqMsg(certRequest, proofOfPossession, null); - final CertReqMessages certReqMessages = new CertReqMessages(certReqMsg); - - final PKIHeader pkiHeader = - generatePkiHeader( - subjectDn, - issuerDn, - CmpMessageHelper.protectionAlgoIdentifier(ITERATIONS, SALT), - senderKid); - final PKIBody pkiBody = new PKIBody(PKIBody.TYPE_INIT_REQ, certReqMessages); - - return CmpMessageHelper.protectPkiMessage( - pkiHeader, pkiBody, initAuthPassword, ITERATIONS, SALT); - } -} |