diff options
Diffstat (limited to 'certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java')
-rw-r--r-- | certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java | 226 |
1 files changed, 50 insertions, 176 deletions
diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java index 549cf6b9..bbca91b6 100644 --- a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java @@ -25,45 +25,31 @@ 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 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.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStreamReader; import java.security.KeyPair; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; +import java.security.Security; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; import java.util.Collections; import java.util.Date; import java.util.Objects; import java.util.Optional; -import org.apache.commons.codec.binary.Base64; import org.apache.http.impl.client.CloseableHttpClient; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; 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.bouncycastle.asn1.x509.Certificate; -import org.bouncycastle.util.io.pem.PemReader; -import org.onap.oom.certservice.certification.configuration.model.CaMode; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server; -import org.onap.oom.certservice.certification.exception.KeyDecryptionException; -import org.onap.oom.certservice.certification.model.CertificateUpdateModel; 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.exceptions.CmpServerException; import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel; +import org.onap.oom.certservice.cmpv2client.validation.CmpCertificationValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,55 +61,56 @@ 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(); - private static final ASN1ObjectIdentifier PASSWORD_BASED_MAC = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13"); + private final CmpCertificationValidator validator; public CmpClientImpl(CloseableHttpClient httpClient) { this.httpClient = httpClient; + this.validator = new CmpCertificationValidator(); + } + + static { + Security.addProvider(new BouncyCastleProvider()); } @Override - public Cmpv2CertificationModel createCertificate( + public Cmpv2CertificationModel executeInitializationRequest( CsrModel csrModel, Cmpv2Server server, Date notBefore, Date notAfter) throws CmpClientException { - validate(csrModel, server, httpClient, notBefore, notAfter); + validator.validate(csrModel, server, httpClient, notBefore, notAfter); final CreateCertRequest certRequest = getIakRvRequest(csrModel, server, notBefore, notAfter, PKIBody.TYPE_INIT_REQ); return executeCmpRequest(csrModel, server, certRequest); } @Override - public Cmpv2CertificationModel createCertificate(CsrModel csrModel, Cmpv2Server server) + public Cmpv2CertificationModel executeInitializationRequest(CsrModel csrModel, Cmpv2Server server) throws CmpClientException { - return createCertificate(csrModel, server, null, null); + return executeInitializationRequest(csrModel, server, null, null); } @Override - public Cmpv2CertificationModel updateCertificate(CsrModel csrModel, Cmpv2Server cmpv2Server, - CertificateUpdateModel certificateUpdateModel) throws CmpClientException { - validate(csrModel, cmpv2Server, httpClient, null, null); + public Cmpv2CertificationModel executeKeyUpdateRequest(CsrModel csrModel, Cmpv2Server cmpv2Server, + OldCertificateModel oldCertificateModel) throws CmpClientException { + validator.validate(csrModel, cmpv2Server, httpClient, null, null); - final PkiMessageProtection pkiMessageProtection = getSignatureProtection(certificateUpdateModel); + final PkiMessageProtection pkiMessageProtection = getSignatureProtection(oldCertificateModel); final CreateCertRequest certRequest = getCmpMessageBuilderWithCommonRequestValues(csrModel, cmpv2Server) .with(CreateCertRequest::setCmpRequestType, PKIBody.TYPE_KEY_UPDATE_REQ) - .with(CreateCertRequest::setExtraCerts, getCMPCertificateFromPem(certificateUpdateModel.getEncodedOldCert())) + .with(CreateCertRequest::setExtraCerts, getCMPCertificate(oldCertificateModel.getOldCertificate())) .with(CreateCertRequest::setProtection, pkiMessageProtection) .build(); return executeCmpRequest(csrModel, cmpv2Server, certRequest); - } @Override - public Cmpv2CertificationModel certificationRequest(CsrModel csrModel, Cmpv2Server cmpv2Server) throws CmpClientException { + public Cmpv2CertificationModel executeCertificationRequest(CsrModel csrModel, Cmpv2Server cmpv2Server) throws CmpClientException { - validate(csrModel, cmpv2Server, httpClient, null, null); + validator.validate(csrModel, cmpv2Server, httpClient, null, null); final CreateCertRequest certRequest = getIakRvRequest(csrModel, cmpv2Server, null, null, PKIBody.TYPE_CERT_REQ); return executeCmpRequest(csrModel, cmpv2Server, certRequest); } @@ -163,86 +150,48 @@ public class CmpClientImpl implements CmpClient { .with(CreateCertRequest::setSubjectKeyPair, keyPair); } - private SignatureProtection getSignatureProtection(CertificateUpdateModel certificateUpdateModel) - throws CmpClientException { - try { - PrivateKey oldPrivateKey = certificateUpdateModel.getOldPrivateKeyObject(); - return new SignatureProtection(oldPrivateKey); - } catch (NoSuchAlgorithmException | KeyDecryptionException | InvalidKeySpecException e) { - throw new CmpClientException("Cannot parse old private key ", e); - } - + private SignatureProtection getSignatureProtection(OldCertificateModel oldCertificateModel) { + return new SignatureProtection(oldCertificateModel.getOldPrivateKey()); } - private CMPCertificate[] getCMPCertificateFromPem(String encodedCertPem) throws CmpClientException { - try { - Certificate certificate = Certificate.getInstance( - new PemReader( - new InputStreamReader( - new ByteArrayInputStream( - Base64.decodeBase64(encodedCertPem)))) - .readPemObject().getContent()); - CMPCertificate cert = new CMPCertificate(certificate); + private CMPCertificate[] getCMPCertificate(Certificate oldCertificate) { + CMPCertificate cert = new CMPCertificate(oldCertificate); return new CMPCertificate[]{cert}; - } catch (IOException | NullPointerException e ) { - throw new CmpClientException("Cannot parse old certificate", e); - } - } - - 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); - if (isPasswordBasedMacAlgorithm(protectionAlgo)) { - LOG.info("CMP response is protected by Password Base Mac Algorithm. Attempt to verify protection"); - verifyPasswordBasedMacProtection(respPkiMessage, initAuthPassword, header, protectionAlgo); - } } - private boolean isPasswordBasedMacAlgorithm(AlgorithmIdentifier protectionAlgo) throws CmpClientException { - if (Objects.isNull(protectionAlgo)) { - LOG.error("CMP response does not contain Protection Algorithm field"); - throw new CmpClientException("CMP response does not contain Protection Algorithm field"); - } - return PASSWORD_BASED_MAC.equals(protectionAlgo.getAlgorithm()); - } - - private void verifySignatureWithPublicKey(PKIMessage respPkiMessage, PublicKey publicKey) + private Cmpv2CertificationModel retrieveCertificates( + CsrModel csrModel, Cmpv2Server server, PKIMessage pkiMessage, Cmpv2HttpClient cmpv2HttpClient) 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"); + 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); + validator.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; } } - private void verifyPasswordBasedMacProtection(PKIMessage respPkiMessage, String initAuthPassword, - PKIHeader header, AlgorithmIdentifier protectionAlgo) - throws CmpClientException { - LOG.debug("Verifying PasswordBased Protection of the Response."); - verifyPasswordBasedProtection(respPkiMessage, initAuthPassword, protectionAlgo); - checkImplicitConfirm(header); - } - private Cmpv2CertificationModel checkCmpCertRepMessage(final PKIMessage respPkiMessage) - throws CmpClientException { + 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)) { try { CertResponse certResponse = getCertificateResponseContainingNewCertificate(certRepMessage); - checkServerResponse(certResponse); + validator.checkServerResponse(certResponse); return verifyReturnCertChainAndTrustStore(respPkiMessage, certRepMessage, certResponse); } catch (IOException | CertificateParsingException ex) { CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while retrieving Certificates from response", ex); + new CmpClientException( + "Exception occurred while retrieving Certificates from response", ex); LOG.error("Exception occurred while retrieving Certificates from response", ex); throw cmpClientException; } @@ -253,98 +202,23 @@ public class CmpClientImpl implements CmpClient { return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList()); } - private void checkServerResponse(CertResponse certResponse) { - if (certResponse.getStatus() != null && certResponse.getStatus().getStatus() != null) { - logServerResponse(certResponse); - if (certResponse.getStatus().getStatus().intValue() == PkiStatus.REJECTED.getCode()) { - String serverMessage = certResponse.getStatus().getStatusString().getStringAt(0).getString(); - throw new CmpServerException(Optional.ofNullable(serverMessage).orElse("N/A")); - } - } - } - - private void logServerResponse(CertResponse certResponse) { - if (LOG.isInfoEnabled()) { - LOG.info("Response status code: {}", certResponse.getStatus().getStatus()); - } - if (certResponse.getStatus().getStatusString() != null) { - String serverMessage = certResponse.getStatus().getStatusString().getStringAt(0).getString(); - LOG.warn("Response status text: {}", serverMessage); - } - if (LOG.isWarnEnabled() && certResponse.getStatus().getFailInfo() != null) { - LOG.warn("Response fail info: {}", certResponse.getStatus().getFailInfo()); - } - } - private Cmpv2CertificationModel verifyReturnCertChainAndTrustStore( - PKIMessage respPkiMessage, CertRepMessage certRepMessage, CertResponse certResponse) - throws CertificateParsingException, CmpClientException, IOException { + 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(); + certResponse.getCertifiedKeyPair().getCertOrEncCert().getCertificate(); final Optional<X509Certificate> leafCertificate = - getCertFromByteArray(cmpCertificate.getEncoded(), X509Certificate.class); + getCertFromByteArray(cmpCertificate.getEncoded(), X509Certificate.class); if (leafCertificate.isPresent()) { return verifyAndReturnCertChainAndTrustSTore( - respPkiMessage, certRepMessage, leafCertificate.get()); + respPkiMessage, certRepMessage, leafCertificate.get()); } return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList()); } private CertResponse getCertificateResponseContainingNewCertificate( - CertRepMessage certRepMessage) { + 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; - } - } } |