import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.onap.oom.certservice.certification.CertificationResponseModelFactory;
-import org.onap.oom.certservice.certification.exception.CertificateDecryptionException;
import org.onap.oom.certservice.certification.exception.DecryptionException;
import org.onap.oom.certservice.certification.exception.ErrorResponseModel;
import org.onap.oom.certservice.certification.model.CertificateUpdateModel;
content = @Content(schema = @Schema(implementation = ErrorResponseModel.class)))
})
@Operation(
- summary = "sign certificate",
- description = "Web endpoint for requesting certificate signing. Used by system components to gain certificate signed by CA.",
+ summary = "initialize certificate",
+ description = "Web endpoint for requesting certificate initialization. Used by system components to gain certificate signed by CA.",
tags = {"CertificationService"})
public ResponseEntity<CertificationResponseModel> signCertificate(
@Parameter(description = "Name of certification authority that will sign CSR.")
@PathVariable String caName,
- @Parameter(description = "Certificate signing request in form of PEM object encoded in Base64 (with header and footer).")
+ @Parameter(description = "Certificate initialization request in form of PEM object encoded in Base64 (with header and footer).")
@RequestHeader("CSR") String encodedCsr,
@Parameter(description = "Private key in form of PEM object encoded in Base64 (with header and footer).")
@RequestHeader("PK") String encodedPrivateKey
) throws DecryptionException, CmpClientException {
caName = replaceWhiteSpaceChars(caName);
- LOGGER.info("Received certificate signing request for CA named: {}", caName);
+ LOGGER.info("Received certificate initialization request for CA named: {}", caName);
CertificationResponseModel certificationResponseModel = certificationResponseModelFactory
.provideCertificationModelFromInitialRequest(encodedCsr, encodedPrivateKey, caName);
return new ResponseEntity<>(certificationResponseModel, HttpStatus.OK);
@RequestHeader("PK") String encodedPrivateKey,
@RequestHeader("OLD_CERT") String encodedOldCert,
@RequestHeader("OLD_PK") String encodedOldPrivateKey
- ) throws DecryptionException, CmpClientException, CertificateDecryptionException {
+ ) throws DecryptionException, CmpClientException {
caName = replaceWhiteSpaceChars(caName);
LOGGER.info("Received certificate update request for CA named: {}", caName);
CertificateUpdateModel certificateUpdateModel = new CertificateUpdateModel.CertificateUpdateModelBuilder()
return getCertificationResponseModel(certificates);
}
- private static List<String> convertFromX509CertificateListToPemList(List<X509Certificate> certificates) {
+ private List<String> convertFromX509CertificateListToPemList(List<X509Certificate> certificates) {
return certificates.stream().map(CertificationProvider::convertFromX509CertificateToPem).filter(cert -> !cert.isEmpty())
.collect(Collectors.toList());
}
* ============LICENSE_START=======================================================
* Cert Service
* ================================================================================
- * Copyright (C) 2020 Nokia. All rights reserved.
+ * Copyright (C) 2020-2021 Nokia. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.onap.oom.certservice.certification.conversion.CsrModelFactory;
import org.onap.oom.certservice.certification.conversion.OldCertificateModelFactory;
import org.onap.oom.certservice.certification.conversion.StringBase64;
-import org.onap.oom.certservice.certification.exception.CertificateDecryptionException;
import org.onap.oom.certservice.certification.exception.DecryptionException;
import org.onap.oom.certservice.certification.model.CertificateUpdateModel;
import org.onap.oom.certservice.certification.model.CertificationResponseModel;
Cmpv2Server cmpv2Server = cmpv2ServerProvider.getCmpv2Server(caName);
LOGGER.debug("Found server for given CA name: \n{}", cmpv2Server);
- LOGGER.info("Sending sign request for certification model for CA named: {}, and certificate signing request:\n{}",
+ LOGGER.info("Sending initialization request for certification model for CA named: {}, and certificate signing request:\n{}",
caName, csrModel);
return certificationProvider.executeInitializationRequest(csrModel, cmpv2Server);
}
public CertificationResponseModel provideCertificationModelFromUpdateRequest(CertificateUpdateModel certificateUpdateModel)
- throws DecryptionException, CmpClientException, CertificateDecryptionException {
- LOGGER.info("CSR: " + certificateUpdateModel.getEncodedCsr() +
- ", old cert: " + certificateUpdateModel.getEncodedOldCert() +
- ", CA: " + certificateUpdateModel.getCaName());
+ throws DecryptionException, CmpClientException {
+ LOGGER.debug("CSR: {}, old cert: {}, CA: {}", certificateUpdateModel.getEncodedCsr(),
+ certificateUpdateModel.getEncodedOldCert(), certificateUpdateModel.getCaName());
final CsrModel csrModel = csrModelFactory.createCsrModel(
new StringBase64(certificateUpdateModel.getEncodedCsr()),
new StringBase64(certificateUpdateModel.getEncodedPrivateKey())
+++ /dev/null
-/*
- * ============LICENSE_START=======================================================
- * PROJECT
- * ================================================================================
- * Copyright (C) 2020 Nokia. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.oom.certservice.certification.configuration.model;
-
-public enum CaMode {
- RA("RA"), CLIENT("Client");
-
- private String profile;
-
- CaMode(String profile) {
- this.profile = profile;
- }
-
- public String getProfile() {
- return profile;
- }
-}
/*
* ============LICENSE_START=======================================================
- * PROJECT
+ * Cert Service
* ================================================================================
- * Copyright (C) 2020 Nokia. All rights reserved.
+ * Copyright (C) 2020-2021 Nokia. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.bouncycastle.asn1.x500.X500Name;
import org.hibernate.validator.constraints.Length;
import org.onap.oom.certservice.certification.configuration.validation.constraints.Cmpv2Url;
+@JsonIgnoreProperties(ignoreUnknown = true)
public class Cmpv2Server {
private static final int MAX_CA_NAME_LENGTH = 128;
@Valid
private Authentication authentication;
@NotNull
- private CaMode caMode;
- @NotNull
@Length(min = 1, max = MAX_CA_NAME_LENGTH)
private String caName;
@NotNull
this.authentication = authentication;
}
- public CaMode getCaMode() {
- return caMode;
- }
-
- public void setCaMode(CaMode caMode) {
- this.caMode = caMode;
- }
-
public String getCaName() {
return caName;
}
public String toString() {
return "Cmpv2Server{"
+ "authentication=" + authentication
- + ", caMode=" + caMode
+ ", caName='" + caName + '\''
+ ", issuerDN='" + issuerDN + '\''
+ ", url='" + url + '\''
+ '}';
}
-
}
package org.onap.oom.certservice.certification.conversion;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
-import org.bouncycastle.util.io.pem.PemObject;
import org.onap.oom.certservice.certification.exception.CsrDecryptionException;
import org.onap.oom.certservice.certification.exception.DecryptionException;
-import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
import org.onap.oom.certservice.certification.model.CsrModel;
import org.springframework.stereotype.Service;
+import java.security.PrivateKey;
+
@Service
public class CsrModelFactory {
= new PemObjectFactory();
private final Pkcs10CertificationRequestFactory certificationRequestFactory
= new Pkcs10CertificationRequestFactory();
-
+ private final StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter
+ = new StringBase64ToPrivateKeyConverter();
public CsrModel createCsrModel(StringBase64 csr, StringBase64 privateKey)
throws DecryptionException {
PKCS10CertificationRequest decodedCsr = decodeCsr(csr);
- PemObject decodedPrivateKey = decodePrivateKey(privateKey);
- return new CsrModel.CsrModelBuilder(decodedCsr, decodedPrivateKey).build();
- }
-
- private PemObject decodePrivateKey(StringBase64 privateKey)
- throws KeyDecryptionException {
-
- return privateKey.asString()
- .flatMap(pemObjectFactory::createPemObject)
- .orElseThrow(
- () -> new KeyDecryptionException("Incorrect Key, decryption failed")
- );
+ PrivateKey javaPrivateKey = stringBase64ToPrivateKeyConverter.convert(privateKey);
+ return new CsrModel.CsrModelBuilder(decodedCsr, javaPrivateKey).build();
}
private PKCS10CertificationRequest decodeCsr(StringBase64 csr)
package org.onap.oom.certservice.certification.conversion;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
-import org.bouncycastle.util.io.pem.PemObject;
import org.onap.oom.certservice.certification.X509CertificateParser;
import org.onap.oom.certservice.certification.exception.CertificateDecryptionException;
import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+
@Service
public class OldCertificateModelFactory {
private static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n";
private static final String END_CERTIFICATE = "-----END CERTIFICATE-----\n";
- private static final PemObjectFactory PEM_OBJECT_FACTORY = new PemObjectFactory();
+ private final StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter
+ = new StringBase64ToPrivateKeyConverter();
private final PemStringToCertificateConverter pemStringToCertificateConverter;
private final X509CertificateParser x509CertificateParser;
final X500Name subjectData = x509CertificateParser.getSubject(x509Certificate);
final GeneralName[] sans = x509CertificateParser.getSans(x509Certificate);
final Certificate certificate = new JcaX509CertificateHolder(x509Certificate).toASN1Structure();
- final PrivateKey oldPrivateKey = getOldPrivateKeyObject(encodedOldPrivateKey);
+ final PrivateKey oldPrivateKey = stringBase64ToPrivateKeyConverter.convert(new StringBase64(encodedOldPrivateKey));
return new OldCertificateModel(certificate, subjectData, sans, oldPrivateKey);
} catch (StringToCertificateConversionException e) {
throw new CertificateDecryptionException("Cannot convert certificate", e);
-
} catch (CertificateParsingException e) {
throw new CertificateDecryptionException("Cannot read Subject Alternative Names from certificate");
- } catch (NoSuchAlgorithmException | KeyDecryptionException | CertificateEncodingException | InvalidKeySpecException e) {
+ } catch (KeyDecryptionException | CertificateEncodingException e) {
throw new CertificateDecryptionException("Cannot convert certificate or key", e);
}
}
return !(certificateChain.contains(BEGIN_CERTIFICATE) && certificateChain.contains(END_CERTIFICATE));
}
- private PrivateKey getOldPrivateKeyObject(String encodedOldPrivateKey)
- throws KeyDecryptionException, InvalidKeySpecException, NoSuchAlgorithmException {
-
- StringBase64 stringBase64 = new StringBase64(encodedOldPrivateKey);
- PemObject pemObject = stringBase64.asString()
- .flatMap(PEM_OBJECT_FACTORY::createPemObject)
- .orElseThrow(
- () -> new KeyDecryptionException("Incorrect Key, decryption failed")
- );
- PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemObject.getContent());
- KeyFactory keyFactory = KeyFactory.getInstance("RSA");
- return keyFactory.generatePrivate(keySpec);
- }
}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nokia.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.oom.certservice.certification.conversion;
+
+import org.bouncycastle.util.io.pem.PemObject;
+import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
+
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+public class StringBase64ToPrivateKeyConverter {
+
+ private final PemObjectFactory pemObjectFactory = new PemObjectFactory();
+
+ public PrivateKey convert(StringBase64 privateKey) throws KeyDecryptionException {
+ PemObject decodedPrivateKey = createDecodedPrivateKey(privateKey);
+ try {
+ KeyFactory factory = KeyFactory.getInstance("RSA");
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedPrivateKey.getContent());
+ return factory.generatePrivate(keySpec);
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ throw new KeyDecryptionException("Converting Private Key failed", e.getCause());
+ }
+ }
+
+ private PemObject createDecodedPrivateKey(StringBase64 privateKey) throws KeyDecryptionException {
+ return privateKey.asString()
+ .flatMap(pemObjectFactory::createPemObject)
+ .orElseThrow(
+ () -> new KeyDecryptionException("Incorrect Key, decryption failed")
+ );
+ }
+
+}
package org.onap.oom.certservice.certification.exception;
-public class CertificateDecryptionException extends Exception {
+public class CertificateDecryptionException extends DecryptionException {
public CertificateDecryptionException(String message, Throwable cause) {
super(message, cause);
package org.onap.oom.certservice.certification.model;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.GeneralName;
-
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.GeneralName;
public class CertificateData {
}
@Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- CertificateData that = (CertificateData) o;
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ CertificateData that = (CertificateData) obj;
return Objects.equals(subject, that.subject) && Objects.equals(sortedSans, that.sortedSans);
}
private final String caName;
private CertificateUpdateModel(String encodedCsr, String encodedPrivateKey, String encodedOldCert,
- String encodedOldPrivateKey, String caName) {
+ String encodedOldPrivateKey, String caName) {
this.encodedCsr = encodedCsr;
this.encodedPrivateKey = encodedPrivateKey;
this.encodedOldCert = encodedOldCert;
}
@Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- CertificateUpdateModel that = (CertificateUpdateModel) o;
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ CertificateUpdateModel that = (CertificateUpdateModel) obj;
return Objects.equals(encodedCsr, that.encodedCsr)
- && Objects.equals(encodedPrivateKey, that.encodedPrivateKey)
- && Objects.equals(encodedOldCert, that.encodedOldCert)
- && Objects.equals(encodedOldPrivateKey, that.encodedOldPrivateKey)
- && Objects.equals(caName, that.caName);
+ && Objects.equals(encodedPrivateKey, that.encodedPrivateKey)
+ && Objects.equals(encodedOldCert, that.encodedOldCert)
+ && Objects.equals(encodedOldPrivateKey, that.encodedOldPrivateKey)
+ && Objects.equals(caName, that.caName);
}
@Override
}
public CertificateUpdateModel build() {
- return new CertificateUpdateModel(encodedCsr, encodedPrivateKey, encodedOldCert, encodedOldPrivateKey, caName);
+ return new CertificateUpdateModel(encodedCsr, encodedPrivateKey, encodedOldCert, encodedOldPrivateKey,
+ caName);
}
}
}
package org.onap.oom.certservice.certification.model;
-import java.io.IOException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Arrays;
-import java.util.stream.Collectors;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
import org.onap.oom.certservice.certification.exception.DecryptionException;
import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
+import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
public class CsrModel {
public static class CsrModelBuilder {
private final PKCS10CertificationRequest csr;
- private final PemObject privateKey;
+ private final PrivateKey privateKey;
public CsrModel build() throws DecryptionException {
X500Name subjectData = getSubjectData();
- PrivateKey javaPrivateKey = convertingPemPrivateKeyToJavaSecurityPrivateKey(getPrivateKey());
PublicKey javaPublicKey = convertingPemPublicKeyToJavaSecurityPublicKey(getPublicKey());
GeneralName[] sans = getSansData();
- return new CsrModel(csr, subjectData, javaPrivateKey, javaPublicKey, sans);
+ return new CsrModel(csr, subjectData, privateKey, javaPublicKey, sans);
}
- public CsrModelBuilder(PKCS10CertificationRequest csr, PemObject privateKey) {
+ public CsrModelBuilder(PKCS10CertificationRequest csr, PrivateKey privateKey) {
this.csr = csr;
this.privateKey = privateKey;
}
}
}
- private PemObject getPrivateKey() {
- return privateKey;
- }
-
private X500Name getSubjectData() {
return csr.getSubject();
}
return csr.getAttributes().length == 0;
}
- private PrivateKey convertingPemPrivateKeyToJavaSecurityPrivateKey(PemObject privateKey)
- throws KeyDecryptionException {
- try {
- KeyFactory factory = KeyFactory.getInstance("RSA");
- PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey.getContent());
- return factory.generatePrivate(keySpec);
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
- throw new KeyDecryptionException("Converting Private Key failed", e.getCause());
- }
- }
-
private PublicKey convertingPemPublicKeyToJavaSecurityPublicKey(PemObject publicKey)
throws KeyDecryptionException {
try {
package org.onap.oom.certservice.cmpv2client.impl;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.checkIfCmpResponseContainsError;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.getCertFromByteArray;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore;
-
-import java.io.IOException;
-import java.security.KeyPair;
-import java.security.Security;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Objects;
-import java.util.Optional;
import org.apache.http.impl.client.CloseableHttpClient;
import org.bouncycastle.asn1.cmp.CMPCertificate;
import org.bouncycastle.asn1.cmp.CertRepMessage;
import org.onap.oom.certservice.certification.model.OldCertificateModel;
import org.onap.oom.certservice.cmpv2client.api.CmpClient;
import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException;
+import org.onap.oom.certservice.cmpv2client.impl.protections.PasswordBasedProtection;
+import org.onap.oom.certservice.cmpv2client.impl.protections.PkiMessageProtection;
+import org.onap.oom.certservice.cmpv2client.impl.protections.SignatureProtection;
import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel;
import org.onap.oom.certservice.cmpv2client.validation.CmpCertificationValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.security.KeyPair;
+import java.security.Security;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Objects;
+import java.util.Optional;
+
+import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.checkIfCmpResponseContainsError;
+import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.getCertFromByteArray;
+import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore;
+
/**
* Implementation of the CmpClient Interface conforming to RFC4210 (Certificate Management Protocol
* (CMP)) and RFC4211 (Certificate Request Message Format (CRMF)) standards.
final CreateCertRequest certRequest =
getCmpMessageBuilderWithCommonRequestValues(csrModel, cmpv2Server)
.with(CreateCertRequest::setCmpRequestType, PKIBody.TYPE_KEY_UPDATE_REQ)
- .with(CreateCertRequest::setExtraCerts, getCMPCertificate(oldCertificateModel.getOldCertificate()))
+ .with(CreateCertRequest::setExtraCerts, getCmpCertificate(oldCertificateModel.getOldCertificate()))
.with(CreateCertRequest::setProtection, pkiMessageProtection)
.build();
return new SignatureProtection(oldCertificateModel.getOldPrivateKey());
}
- private CMPCertificate[] getCMPCertificate(Certificate oldCertificate) {
+ private CMPCertificate[] getCmpCertificate(Certificate oldCertificate) {
CMPCertificate cert = new CMPCertificate(oldCertificate);
return new CMPCertificate[]{cert};
}
*/
public static OptionalValidity generateOptionalValidity(
final Date notBefore, final Date notAfter) {
- LOG.info("Generating Optional Validity from Date objects");
+ LOG.debug("Generating Optional Validity from Date objects");
ASN1EncodableVector optionalValidityV = new ASN1EncodableVector();
if (notBefore != null) {
Time nb = new Time(notBefore);
*/
public static Extensions generateExtension(final GeneralName[] sansArray)
throws CmpClientException {
- LOG.info("Generating Extensions from Subject Alternative Names");
+ LOG.debug("Generating Extensions from Subject Alternative Names");
final ExtensionsGenerator extGenerator = new ExtensionsGenerator();
try {
extGenerator.addExtension(Extension.keyUsage, CRITICAL_FALSE, getKeyUsage());
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation.
- * ================================================================================
- * Modification copyright 2021 Nokia
+ * 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.
public final class CmpResponseHelper {
private static final Logger LOG = LoggerFactory.getLogger(CmpResponseHelper.class);
+ private static final Map<Integer, String> RESPONSE_TYPE_TO_STRING = Map.of(
+ PKIBody.TYPE_INIT_REP, "INIT_REP",
+ PKIBody.TYPE_CERT_REP, "CERT_REP",
+ PKIBody.TYPE_KEY_UPDATE_REP, "KEY_UPDATE_REP");
private CmpResponseHelper() {
}
static void checkIfCmpResponseContainsError(PKIMessage respPkiMessage) {
- LOG.info("Response type: {} ", respPkiMessage.getBody().getType());
- if (respPkiMessage.getBody().getType() == PKIBody.TYPE_ERROR) {
+ final int responseType = respPkiMessage.getBody().getType();
+ final String responseTypeName = RESPONSE_TYPE_TO_STRING.getOrDefault(responseType, Integer.toString(responseType));
+ LOG.info("Response type is: {} ", responseTypeName);
+
+ if (responseType == PKIBody.TYPE_ERROR) {
final ErrorMsgContent errorMsgContent =
(ErrorMsgContent) respPkiMessage.getBody().getContent();
String text = errorMsgContent.getPKIStatusInfo().getStatusString().getStringAt(0).getString();
package org.onap.oom.certservice.cmpv2client.impl;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.SecureRandom;
-import java.util.Date;
-import java.util.Objects;
-
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Date;
+import java.util.Objects;
+
public final class CmpUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(CmpUtil.class);
*
* @return bytes containing a random number string representing a nonce
*/
- static byte[] createRandomBytes() {
- LOGGER.info("Generating random array of bytes");
+ public static byte[] createRandomBytes() {
+ LOGGER.debug("Generating random array of bytes");
byte[] randomBytes = new byte[RANDOM_BYTE_LENGTH];
SECURE_RANDOM.nextBytes(randomBytes);
return randomBytes;
*
* @return bytes containing a random number string representing a nonce
*/
- static int createRandomInt(int range) {
- LOGGER.info("Generating random integer");
+ public static int createRandomInt(int range) {
+ LOGGER.debug("Generating random integer");
return SECURE_RANDOM.nextInt(range) + RANDOM_SEED;
}
* @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");
+ public static byte[] generateProtectedBytes(PKIHeader header, PKIBody body) throws CmpClientException {
+ LOGGER.debug("Generating array of bytes representing PkiHeader and PkiBody");
byte[] res;
ASN1EncodableVector vector = new ASN1EncodableVector();
vector.add(header);
*/
static PKIHeader generatePkiHeader(
X500Name subjectDn, X500Name issuerDn, AlgorithmIdentifier protectionAlg, String senderKid) {
- LOGGER.info("Generating a Pki Header Builder");
+ LOGGER.debug("Generating a Pki Header Builder");
PKIHeaderBuilder pkiHeaderBuilder =
new PKIHeaderBuilder(
PKIHeader.CMP_2000, new GeneralName(subjectDn), new GeneralName(issuerDn));
package org.onap.oom.certservice.cmpv2client.impl;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpUtil.createRandomInt;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpUtil.generatePkiHeader;
-
-import java.security.KeyPair;
-import java.util.Date;
-
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.cmp.CMPCertificate;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException;
+import org.onap.oom.certservice.cmpv2client.impl.protections.PkiMessageProtection;
+
+import java.security.KeyPair;
+import java.util.Date;
+
+import static org.onap.oom.certservice.cmpv2client.impl.CmpUtil.createRandomInt;
+import static org.onap.oom.certservice.cmpv2client.impl.CmpUtil.generatePkiHeader;
/**
* Implementation of the CmpClient Interface conforming to RFC4210 (Certificate Management Protocol
* ============LICENSE_END=========================================================
*/
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
private final String initAuthPassword;
- PasswordBasedProtection(String initAuthPassword) {
+ public PasswordBasedProtection(String initAuthPassword) {
this.initAuthPassword = initAuthPassword;
}
@Override
- AlgorithmIdentifier getAlgorithmIdentifier() {
+ public AlgorithmIdentifier getAlgorithmIdentifier() {
ASN1Integer iteration = new ASN1Integer(ITERATIONS);
DEROctetString derSalt = new DEROctetString(SALT);
* ============LICENSE_END=========================================================
*/
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.cmp.PKIBody;
*
* @return bytes representing protection wrapped into DERBitString object.
*/
- DERBitString generatePkiMessageProtection(PKIHeader pkiHeader, PKIBody pkiBody) throws CmpClientException {
+ public DERBitString generatePkiMessageProtection(PKIHeader pkiHeader, PKIBody pkiBody) throws CmpClientException {
try {
byte[] protectedBytes = generateProtectedBytes(pkiHeader, pkiBody);
byte[] protectionBytes = generateProtectionBytes(protectedBytes);
}
/**
- * Takes encoded bytes of PKIMessage (PKIHeader and PKIBody) and generates protection bytes.
+ * Returns Algorithm Identifier for protection of PKIMessage.
*
- * @return bytes representing protection.
+ * @return Algorithm Identifier.
*/
- abstract byte[] generateProtectionBytes(byte[] protectedBytes) throws GeneralSecurityException;
+ public abstract AlgorithmIdentifier getAlgorithmIdentifier();
/**
- * Returns Algorithm Identifier for protection of PKIMessage.
+ * Takes encoded bytes of PKIMessage (PKIHeader and PKIBody) and generates protection bytes.
*
- * @return Algorithm Identifier.
+ * @return bytes representing protection.
*/
- abstract AlgorithmIdentifier getAlgorithmIdentifier();
+ abstract byte[] generateProtectionBytes(byte[] protectedBytes) throws GeneralSecurityException;
}
* ============LICENSE_END=========================================================
*/
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
private final PrivateKey oldPrivateKey;
- SignatureProtection(PrivateKey privateKey) {
+ public SignatureProtection(PrivateKey privateKey) {
this.oldPrivateKey = privateKey;
}
@Override
- AlgorithmIdentifier getAlgorithmIdentifier() {
+ public AlgorithmIdentifier getAlgorithmIdentifier() {
return SHA256_RSA_ALGORITHM;
}
/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Nordix Foundation.
- * ================================================================================
- * Modification copyright 2021 Nokia
+ * 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.
package org.onap.oom.certservice.cmpv2client.validation;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.checkImplicitConfirm;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifyPasswordBasedProtection;
-import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifySignature;
-import java.security.PublicKey;
-import java.util.Date;
-import java.util.Objects;
-import java.util.Optional;
import org.apache.http.impl.client.CloseableHttpClient;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.cmp.CertResponse;
import org.bouncycastle.asn1.cmp.PKIHeader;
import org.bouncycastle.asn1.cmp.PKIMessage;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.onap.oom.certservice.certification.configuration.model.CaMode;
import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server;
import org.onap.oom.certservice.certification.model.CsrModel;
import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.security.PublicKey;
+import java.util.Date;
+import java.util.Objects;
+import java.util.Optional;
+
+import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.checkImplicitConfirm;
+import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifyPasswordBasedProtection;
+import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifySignature;
+
public class CmpCertificationValidator {
private static final String DEFAULT_CA_NAME = "Certification Authority";
- private static final String DEFAULT_PROFILE = CaMode.RA.getProfile();
private static final ASN1ObjectIdentifier PASSWORD_BASED_MAC = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13");
private static final Logger LOG = LoggerFactory.getLogger(CmpCertificationValidator.class);
- public static void validate(
+ public void validate(
final CsrModel csrModel,
final Cmpv2Server server,
final CloseableHttpClient httpClient,
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);
+ "Validate before creating Certificate Request for CA: {}", caName);
CmpUtil.notNull(csrModel, "CsrModel Instance");
CmpUtil.notNull(csrModel.getSubjectData(), "Subject DN");
if (notBefore != null && notAfter != null && notBefore.compareTo(notAfter) > 0) {
throw new IllegalArgumentException("Before Date is set after the After Date");
}
+ LOG.info("Validation completed successfully.");
}
public void checkCmpResponse(final PKIMessage respPkiMessage, final PublicKey publicKey, final String initAuthPassword)
}
private void logServerResponse(CertResponse certResponse) {
- if (LOG.isInfoEnabled()) {
- LOG.info("Response status code: {}", certResponse.getStatus().getStatus());
- }
+ 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);
@Test
void shouldUpdateEndpointReturnDataAboutCsrBaseOnEncodedParameters()
- throws DecryptionException, CmpClientException, CertificateDecryptionException {
+ throws DecryptionException, CmpClientException {
// Given
CertificationResponseModel testCertificationResponseModel = new CertificationResponseModel(
Arrays.asList("ENTITY_CERT", "INTERMEDIATE_CERT"),
@Test
void shouldThrowCertificateDecryptionExceptionWhenCreatingPemModelFails()
- throws DecryptionException, CertificateDecryptionException, CmpClientException {
+ throws DecryptionException, CmpClientException {
// Given
String expectedMessage = "Incorrect certificate, decryption failed";
when(certificationResponseModelFactory.provideCertificationModelFromUpdateRequest(TEST_CERTIFICATE_UPDATE_MODEL))
// When
when(
cmpClient.executeKeyUpdateRequest(any(CsrModel.class), any(Cmpv2Server.class), any(OldCertificateModel.class))
- ).thenReturn(getCMPv2CertificationModel());
+ ).thenReturn(getCmpv2CertificationModel());
CertificationResponseModel certificationModel = certificationProvider
.executeKeyUpdateRequest(csrModel, server, oldCertificateModel);
when(
cmpClient.executeInitializationRequest(any(CsrModel.class), any(Cmpv2Server.class))
- ).thenReturn(getCMPv2CertificationModel());
+ ).thenReturn(getCmpv2CertificationModel());
CertificationResponseModel certificationModel = certificationProvider
.executeInitializationRequest(csrModel, server);
return string.replace("\n", "").replace("\r", "");
}
- private Cmpv2CertificationModel getCMPv2CertificationModel() throws IOException, CertificateException {
+ private Cmpv2CertificationModel getCmpv2CertificationModel() throws IOException, CertificateException {
List<X509Certificate> certificateChain = getX509CertificateFromPem(TEST_CMPv2_KEYSTORE);
List<X509Certificate> trustedCertificates = getX509CertificateFromPem(TEST_CMPv2_TRUSTSTORE);
return new Cmpv2CertificationModel(certificateChain, trustedCertificates);
@Test
void shouldPerformKurWhenCsrAndOldCertDataMatch()
- throws CertificateDecryptionException, DecryptionException, CmpClientException {
+ throws DecryptionException, CmpClientException {
// Given
CsrModel csrModel = mockCsrFactoryModelCreation();
Cmpv2Server testServer = mockCmpv2ProviderServerSelection();
@Test
void shouldThrowCmpClientExceptionWhenUpdateRequestFailed()
- throws DecryptionException, CmpClientException, CertificateDecryptionException {
+ throws DecryptionException, CmpClientException {
// Given
String expectedMessage = "Exception occurred while send request to CMPv2 Server";
@Test
void shouldPerformCrWhenCsrAndOldCertDataDontMatch()
- throws CertificateDecryptionException, DecryptionException, CmpClientException {
+ throws DecryptionException, CmpClientException {
// Given
CsrModel csrModel = mockCsrFactoryModelCreation();
Cmpv2Server testServer = mockCmpv2ProviderServerSelection();
public static final String EXPECTED_CERT_SUBJECT = "C=US,ST=California,L=San-Francisco,O=Linux-Foundation,OU=ONAP,CN=onap.org";
public static final String EXPECTED_CERT_SANS =
- "SANs: [onap@onap.org, localhost, onap.org, test.onap.org, onap://cluster.local/, " + LOCALHOST_IP_IN_HEX +"]";
+ "SANs: [onap@onap.org, localhost, onap.org, test.onap.org, onap://cluster.local/, " + LOCALHOST_IP_IN_HEX + "]";
public static final String TEST_CSR = "-----BEGIN CERTIFICATE REQUEST-----\n"
/*
* ============LICENSE_START=======================================================
- * PROJECT
+ * Cert Service
* ================================================================================
* Copyright (C) 2020-2021 Nokia. All rights reserved.
* ================================================================================
"CA_NAME", "TEST",
"URL", "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
"ISSUER_DN", "CN=ManagementCA",
- "CA_MODE", "CLIENT",
"IAK", "xxx",
"RV", "yyy"
);
"CA_NAME", "TEST2",
"URL", "http://127.0.0.1/ejbca/publicweb/cmp/cmpRA",
"ISSUER_DN", "CN=ManagementCA2",
- "CA_MODE", "RA",
"IAK", "xxx",
"RV", "yyy"
);
assertThat(cmpv2Server.getCaName()).isEqualTo(expected.get("CA_NAME"));
assertThat(cmpv2Server.getUrl()).isEqualTo(expected.get("URL"));
assertThat(cmpv2Server.getIssuerDN()).hasToString(expected.get("ISSUER_DN"));
- assertThat(cmpv2Server.getCaMode().name()).isEqualTo(expected.get("CA_MODE"));
assertThat(cmpv2Server.getAuthentication().getIak()).isEqualTo(expected.get("IAK"));
assertThat(cmpv2Server.getAuthentication().getRv()).isEqualTo(expected.get("RV"));
}
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.onap.oom.certservice.certification.configuration.model.Authentication;
-import org.onap.oom.certservice.certification.configuration.model.CaMode;
import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server;
@ExtendWith(MockitoExtension.class)
testAuthentication1.setIak("testIak");
testAuthentication1.setRv("testRv");
testServer1.setAuthentication(testAuthentication1);
- testServer1.setCaMode(CaMode.RA);
Cmpv2Server testServer2 = new Cmpv2Server();
testServer2.setCaName("TEST_CA2");
testAuthentication2.setIak("test2Iak");
testAuthentication2.setRv("test2Rv");
testServer2.setAuthentication(testAuthentication2);
- testServer2.setCaMode(CaMode.CLIENT);
return List.of(testServer1, testServer2);
}
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.onap.oom.certservice.certification.configuration.model.Authentication;
-import org.onap.oom.certservice.certification.configuration.model.CaMode;
import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server;
import org.onap.oom.certservice.certification.exception.Cmpv2ServerNotFoundException;
testAuthentication.setIak("testIak");
testAuthentication.setRv("testRv");
testServer.setAuthentication(testAuthentication);
- testServer.setCaMode(CaMode.RA);
return testServer;
}
/*
* ============LICENSE_START=======================================================
- * PROJECT
+ * Cert Service
* ================================================================================
- * Copyright (C) 2020 Nokia. All rights reserved.
+ * Copyright (C) 2020-2021 Nokia. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.junit.jupiter.api.extension.ExtendWith;
import org.onap.oom.certservice.CertServiceApplication;
import org.onap.oom.certservice.certification.configuration.model.Authentication;
-import org.onap.oom.certservice.certification.configuration.model.CaMode;
import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
assertExceptionIsThrown();
}
- @Test
- void shouldThrowExceptionWhenCaModeIsNull() {
- // Given
- server.setCaMode(null);
-
- // Then
- assertExceptionIsThrown();
- }
-
@Test
void shouldThrowExceptionWhenUrlIsNull() {
// Given
private void setServerConfiguration() {
server = new Cmpv2Server();
- server.setCaMode(CaMode.CLIENT);
server.setCaName("TEST");
server.setIssuerDN(new X500Name("CN=ManagementCA"));
server.setUrl("http://127.0.0.1/ejbca/publicweb/cmp/cmp");
authentication.setIak("testIAK");
}
-}
\ No newline at end of file
+}
* ============LICENSE_START=======================================================
* Cert Service
* ================================================================================
- * Copyright (C) 2020 Nokia. All rights reserved.
+ * Copyright (C) 2020-2021 Nokia. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.onap.oom.certservice.certification.conversion;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.onap.oom.certservice.certification.TestData.TEST_CSR;
-import static org.onap.oom.certservice.certification.TestData.TEST_PK;
-import static org.onap.oom.certservice.certification.TestData.TEST_WRONG_CSR;
-import static org.onap.oom.certservice.certification.TestData.TEST_WRONG_PEM;
-
import org.bouncycastle.util.encoders.Base64;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
import org.onap.oom.certservice.certification.model.CsrModel;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.onap.oom.certservice.certification.TestData.TEST_CSR;
+import static org.onap.oom.certservice.certification.TestData.TEST_PK;
+import static org.onap.oom.certservice.certification.TestData.TEST_WRONG_CSR;
+import static org.onap.oom.certservice.certification.TestData.TEST_WRONG_PEM;
+
class CsrModelFactoryTest {
assertTrue(decryptedCsr.toString()
.contains(TestData.EXPECTED_CERT_SUBJECT));
- System.out.println(decryptedCsr.toString());
assertTrue(decryptedCsr.toString()
.contains(TestData.EXPECTED_CERT_SANS));
}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nokia.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.oom.certservice.certification.conversion;
+
+import org.bouncycastle.util.encoders.Base64;
+import org.junit.jupiter.api.Test;
+import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
+
+import java.security.PrivateKey;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.onap.oom.certservice.certification.TestData.TEST_PEM;
+import static org.onap.oom.certservice.certification.TestData.TEST_PK;
+
+class StringBase64ToPrivateKeyConverterTest {
+
+ private static final String RSA = "RSA";
+ public static final String PKCS_8 = "PKCS#8";
+
+ @Test
+ void shouldUseProperAlgorithmWhenConverting() throws KeyDecryptionException {
+ // Given
+ StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter = new StringBase64ToPrivateKeyConverter();
+ String encodedPK = new String(Base64.encode(TEST_PK.getBytes()));
+ // When
+ PrivateKey privateKey = stringBase64ToPrivateKeyConverter.convert(new StringBase64(encodedPK));
+ // Then
+ assertEquals(RSA, privateKey.getAlgorithm());
+ }
+
+ @Test
+ void shouldUsePkcs8FormatWhenConverting() throws KeyDecryptionException {
+ // Given
+ StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter = new StringBase64ToPrivateKeyConverter();
+ String encodedPK = new String(Base64.encode(TEST_PK.getBytes()));
+ // When
+ PrivateKey privateKey = stringBase64ToPrivateKeyConverter.convert(new StringBase64(encodedPK));
+ // Then
+ assertEquals(PKCS_8, privateKey.getFormat());
+ }
+
+ @Test
+ void shouldCorrectlyConvertWhenPrivateKeyPemIsProper() throws KeyDecryptionException {
+ // Given
+ StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter = new StringBase64ToPrivateKeyConverter();
+ String encodedPK = new String(Base64.encode(TEST_PK.getBytes()));
+ // When
+ PrivateKey privateKey = stringBase64ToPrivateKeyConverter.convert(new StringBase64(encodedPK));
+ // Then
+ assertNotNull(privateKey.getEncoded());
+ }
+
+ @Test
+ void shouldThrowExceptionWhenPrivateKeyPemIsNotProperPrivateKey() {
+ // Given
+ StringBase64ToPrivateKeyConverter stringBase64ToPrivateKeyConverter = new StringBase64ToPrivateKeyConverter();
+ StringBase64 privateKey = new StringBase64(TEST_PEM);
+ // When
+ Exception exception = assertThrows(
+ KeyDecryptionException.class, () -> stringBase64ToPrivateKeyConverter.convert(privateKey));
+
+ String expectedMessage = "Incorrect Key, decryption failed";
+ String actualMessage = exception.getMessage();
+ // Then
+ assertTrue(actualMessage.contains(expectedMessage));
+ }
+
+}
* ============LICENSE_START=======================================================
* PROJECT
* ================================================================================
- * Copyright (C) 2020 Nokia. All rights reserved.
+ * Copyright (C) 2020-2021 Nokia. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.onap.oom.certservice.certification.model;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.util.io.pem.PemObject;
import org.junit.jupiter.api.Test;
-import org.onap.oom.certservice.certification.conversion.Pkcs10CertificationRequestFactory;
-import org.onap.oom.certservice.certification.conversion.PemObjectFactory;
import org.onap.oom.certservice.certification.TestData;
+import org.onap.oom.certservice.certification.conversion.PemObjectFactory;
+import org.onap.oom.certservice.certification.conversion.Pkcs10CertificationRequestFactory;
import org.onap.oom.certservice.certification.exception.CsrDecryptionException;
import org.onap.oom.certservice.certification.exception.DecryptionException;
import org.onap.oom.certservice.certification.exception.KeyDecryptionException;
import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@Test
void shouldByConstructedAndReturnProperFields() throws DecryptionException, IOException {
// Given
- PemObject testPrivateKey = getPemPrivateKey();
+ PrivateKey testPrivateKey = getPemPrivateKey();
PemObject testPublicKey = generateTestPublicKey();
PKCS10CertificationRequest testCsr = generateTestCertificationRequest();
assertThat(csrModel.getCsr())
.isEqualTo(testCsr);
assertThat(csrModel.getPrivateKey().getEncoded())
- .contains(testPrivateKey.getContent());
+ .isEqualTo(testPrivateKey.getEncoded());
assertThat(csrModel.getPublicKey().getEncoded())
.contains(testPublicKey.getContent());
assertThat(sansList)
@Test
void shouldThrowExceptionWhenPublicKeyIsNotCorrect() throws DecryptionException, IOException {
// Given
- PemObject testPrivateKey = getPemPrivateKey();
+ PrivateKey testPrivateKey = getPemPrivateKey();
PKCS10CertificationRequest testCsr = mock(PKCS10CertificationRequest.class);
SubjectPublicKeyInfo wrongKryInfo = mock(SubjectPublicKeyInfo.class);
when(testCsr.getSubjectPublicKeyInfo())
assertTrue(actualMessage.contains(expectedMessage));
}
- @Test
- void shouldThrowExceptionWhenPrivateKeyPemIsNotProperPrivateKey() throws KeyDecryptionException, IOException {
- // Given
- PemObject testPrivateKey = getPemWrongKey();
- PKCS10CertificationRequest testCsr = mock(PKCS10CertificationRequest.class);
- SubjectPublicKeyInfo wrongKryInfo = mock(SubjectPublicKeyInfo.class);
- when(testCsr.getSubjectPublicKeyInfo())
- .thenReturn(wrongKryInfo);
- when(wrongKryInfo.getEncoded())
- .thenThrow(new IOException());
-
- // When
- Exception exception = assertThrows(
- KeyDecryptionException.class,
- () -> new CsrModel.CsrModelBuilder(testCsr, testPrivateKey).build()
- );
-
- String expectedMessage = "Converting Private Key failed";
- String actualMessage = exception.getMessage();
-
- // Then
- assertTrue(actualMessage.contains(expectedMessage));
- }
-
@Test
void shouldThrowExceptionWhenPublicKeyPemIsNotProperPublicKey() throws KeyDecryptionException, IOException {
// Given
- PemObject testPrivateKey = getPemPrivateKey();
+ PrivateKey testPrivateKey = getPemPrivateKey();
PemObject testPublicKey = getPemWrongKey();
PKCS10CertificationRequest testCsr = mock(PKCS10CertificationRequest.class);
SubjectPublicKeyInfo wrongKryInfo = mock(SubjectPublicKeyInfo.class);
assertTrue(actualMessage.contains(expectedMessage));
}
- private PemObject getPemPrivateKey() throws KeyDecryptionException {
+ private PrivateKey getPemPrivateKey() throws KeyDecryptionException {
PemObjectFactory pemObjectFactory = new PemObjectFactory();
- return pemObjectFactory.createPemObject(TEST_PK).orElseThrow(
- () -> new KeyDecryptionException("Private key decoding fail")
+ PemObject pemObject = pemObjectFactory.createPemObject(TEST_PK).orElseThrow(
+ () -> new KeyDecryptionException("Private key decoding fail")
);
+ return convertToPrivateKey(pemObject);
}
private PemObject getPemWrongKey() throws KeyDecryptionException {
PemObject testPrivateKey = pemObjectFactory.createPemObject(TEST_PK).orElseThrow(
() -> new DecryptionException("Incorrect Private Key, decryption failed")
);
- return new CsrModel.CsrModelBuilder(testCsr, testPrivateKey).build();
+ return new CsrModel.CsrModelBuilder(testCsr, convertToPrivateKey(testPrivateKey)).build();
}
private PemObject generateTestPublicKey() throws DecryptionException, IOException {
);
}
+ private PrivateKey convertToPrivateKey(PemObject privateKey)
+ throws KeyDecryptionException {
+ try {
+ KeyFactory factory = KeyFactory.getInstance("RSA");
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey.getContent());
+ return factory.generatePrivate(keySpec);
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ throw new KeyDecryptionException("Converting Private Key failed", e.getCause());
+ }
+ }
+
}
private static final OldCertificateModelFactory factory =
new OldCertificateModelFactory(new PemStringToCertificateConverter(), new X509CertificateParser());
- static final OldCertificateModel createCorrectOldCertificateModel() throws CertificateDecryptionException {
+ static OldCertificateModel createCorrectOldCertificateModel() throws CertificateDecryptionException {
return createOldCertificateModel(TEST_ENCODED_OLD_CERT, TEST_ENCODED_OLD_PRIVATE_KEY);
}
- static final OldCertificateModel createOldCertificateModelWithWrongCert() throws CertificateDecryptionException {
+ static OldCertificateModel createOldCertificateModelWithWrongCert() throws CertificateDecryptionException {
return createOldCertificateModel(WRONG_OLD_CERT, TEST_ENCODED_OLD_PRIVATE_KEY);
}
- static final OldCertificateModel createOldCertificateModelWithWrongPrivateKey() throws CertificateDecryptionException {
+ static OldCertificateModel createOldCertificateModelWithWrongPrivateKey() throws CertificateDecryptionException {
return createOldCertificateModel(TEST_ENCODED_OLD_CERT, WRONG_OLD_PRIVATE_KEY);
}
- static final OldCertificateModel createOldCertificateModelWithPrivateKeyInPKCS1() throws CertificateDecryptionException {
+ static OldCertificateModel createOldCertificateModelWithPrivateKeyInPkcs1() throws CertificateDecryptionException {
return createOldCertificateModel(TEST_ENCODED_OLD_CERT, TEST_ENCODED_PRIVATE_KEY_IN_PKCS1);
}
- static final OldCertificateModel createOldCertificateModelWithPrivateKeyInPKCS8() throws CertificateDecryptionException {
+ static OldCertificateModel createOldCertificateModelWithPrivateKeyInPkcs8() throws CertificateDecryptionException {
return createOldCertificateModel(TEST_ENCODED_OLD_CERT, TEST_ENCODED_PRIVATE_KEY_IN_PKCS8);
}
- private static final OldCertificateModel createOldCertificateModel(String certificate, String privateKey) throws CertificateDecryptionException {
+ private static OldCertificateModel createOldCertificateModel(String certificate, String privateKey) throws CertificateDecryptionException {
StringBase64 base64EncodedCertificate = new StringBase64(certificate);
return factory.createCertificateModel(base64EncodedCertificate, privateKey);
}
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
-import static org.onap.oom.certservice.cmpv2client.ClientTestData.createOldCertificateModelWithPrivateKeyInPKCS1;
-import static org.onap.oom.certservice.cmpv2client.ClientTestData.createOldCertificateModelWithPrivateKeyInPKCS8;
+import static org.onap.oom.certservice.cmpv2client.ClientTestData.createOldCertificateModelWithPrivateKeyInPkcs1;
+import static org.onap.oom.certservice.cmpv2client.ClientTestData.createOldCertificateModelWithPrivateKeyInPkcs8;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
private static KeyPair keyPair;
- private final static Decoder BASE64_DECODER = Base64.getDecoder();
+ private static final Decoder BASE64_DECODER = Base64.getDecoder();
@BeforeEach
void setUp()
@Test
- void shouldThrowCMPClientExceptionWhenCannotParseOldCertificate() {
+ void shouldThrowCmpClientExceptionWhenCannotParseOldCertificate() {
setCsrModelAndServerTestDefaultValues();
CmpClientImpl cmpClient = new CmpClientImpl(httpClient);
try (
BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(
- preparePKIMessageWithoutProtectionAlgorithm().getEncoded()
+ preparePkiMessageWithoutProtectionAlgorithm().getEncoded()
))) {
byte[] ba = IOUtils.toByteArray(bis);
server.setIssuerDN(dn);
}
- private PKIMessage preparePKIMessageWithoutProtectionAlgorithm() {
+ private PKIMessage preparePkiMessageWithoutProtectionAlgorithm() {
CertTemplateBuilder certTemplateBuilder = new CertTemplateBuilder();
X500Name issuerDN = getTestIssuerDN();
private static Stream<Arguments> getTestUpdateModelWithSupportedPrivateKeys()
throws CertificateDecryptionException {
return Stream.of(
- Arguments.of(createOldCertificateModelWithPrivateKeyInPKCS1()),
- Arguments.of(createOldCertificateModelWithPrivateKeyInPKCS8())
+ Arguments.of(createOldCertificateModelWithPrivateKeyInPkcs1()),
+ Arguments.of(createOldCertificateModelWithPrivateKeyInPkcs8())
);
}
* ============LICENSE_END=========================================================
*/
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERBitString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getProtectedPkiMessage;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getTestPkiHeader;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getProtectedPkiMessage;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getTestPkiHeader;
class PasswordBasedProtectionTest {
* ============LICENSE_END=========================================================
*/
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERGeneralizedTime;
* ============LICENSE_END=========================================================
*/
-package org.onap.oom.certservice.cmpv2client.impl;
+package org.onap.oom.certservice.cmpv2client.impl.protections;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.cmp.PKIBody;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getProtectedPkiMessage;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getTestPkiBody;
-import static org.onap.oom.certservice.cmpv2client.impl.PkiTestUtils.getTestPkiHeader;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getProtectedPkiMessage;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getTestPkiBody;
+import static org.onap.oom.certservice.cmpv2client.impl.protections.PkiTestUtils.getTestPkiHeader;
class SignatureProtectionTest {
"caName": "TEST",
"url": "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
"issuerDN": "CN=ManagementCA",
- "caMode": "CLIENT",
"authentication": {
"iak": "xxx",
"rv": "yyy"
"caName": "TEST2",
"url": "http://127.0.0.1/ejbca/publicweb/cmp/cmpRA",
"issuerDN": "CN=ManagementCA2",
- "caMode": "RA",
"authentication": {
"iak": "xxx",
"rv": "yyy"
}
}
]
-}
\ No newline at end of file
+}
{
"caName": " ",
"url": "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
- "issuerDN": "CN=ManagementCA",
- "caMode": "CLIENT"
+ "issuerDN": "CN=ManagementCA"
},
{
"caName": "TEST2",
"url": "http://127.0.0.1/ejbca/publicweb/cmp/cmpRA",
- "caMode": "RA",
"authentication": {
"iak": "xxx",
"rv": "yyy"
}
}
]
-}
\ No newline at end of file
+}
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
- name: _sample_cert_name_
+ name: cert-test
namespace: onap
spec:
# The secret name to store the signed certificate
- secretName: _sample_secret_name_
+ secretName: cert-test-secret-name
# Common Name
commonName: certissuer.onap.org
subject:
issuerRef:
group: certmanager.onap.org
kind: CMPv2Issuer
- name: cmpv2-issuer
+ name: cmpv2-issuer-onap
"caName": "Client",
"url": "http://oomcert-ejbca:8080/ejbca/publicweb/cmp/cmp",
"issuerDN": "O=EJBCA Container Quickstart,CN=ManagementCA,UID=12345",
- "caMode": "CLIENT",
"authentication": {
"iak": "mypassword",
"rv": "mypassword"
"caName": "RA",
"url": "http://oomcert-ejbca:8080/ejbca/publicweb/cmp/cmpRA",
"issuerDN": "O=EJBCA Container Quickstart,CN=ManagementCA,UID=12345",
- "caMode": "RA",
"authentication": {
"iak": "mypassword",
"rv": "mypassword"
**New Features**
- N/A
+ Add certificate update use case (support for CMPv2 messages: Key Update Request and Certification Request).
**Bug Fixes**
**Upgrade Notes**
+ caMode is removed from cmpServers.json configuration file.
+
**Deprecation Notes**
CertService client is not supported since Istanbul release.
"caName": "Client",
"url": "http://oomcert-ejbca:8080/ejbca/publicweb/cmp/cmp",
"issuerDN": "CN=ManagementCA",
- "caMode": "CLIENT",
"authentication": {
"iak": "mypassword",
"rv": "mypassword"
"caName": "RA",
"url": "http://oomcert-ejbca:8080/ejbca/publicweb/cmp/cmpRA",
"issuerDN": "CN=ManagementCA",
- "caMode": "RA",
"authentication": {
"iak": "mypassword",
"rv": "mypassword"
- *caName* - name of the external CA server. It's used to match *CA_NAME* sent by CertService client in order to match proper configuration.
- *url* - URL to CMPv2 server
- *issuerDN* - Distinguished Name of the CA that will sign the certificate
- - *caMode* - Issuer mode. Allowed values are *CLIENT* and *RA*
- *authentication*
- *iak* - Initial authentication key, used to authenticate request in CMPv2 server
+---------------------+---------------------------------------------------------------------------------------------------------------------------------+
| Name | Value |
+=====================+=================================================================================================================================+
-| Request URL | http://ejbca:8080/ejbca/publicweb/cmp/cmpRA |
+| Request URL | http://ejbca:8080/ejbca/publicweb/cmp/cmpRA |
+---------------------+---------------------------------------------------------------------------------------------------------------------------------+
| Response Type | PKI Response |
+---------------------+---------------------------------------------------------------------------------------------------------------------------------+