From 92ec2f3a119d6253da3c8aebefe3b0b9829f7645 Mon Sep 17 00:00:00 2001 From: Remigiusz Janeczek Date: Wed, 30 Jun 2021 12:44:29 +0200 Subject: [OOM-CERT-SERVICE] Add logic for KUR/CR detection Issue-ID: OOM-2753 Signed-off-by: Remigiusz Janeczek Change-Id: I571ad3914a870dde83929cb6121c2c63a5df3ae4 --- .../certservice/api/CertificationController.java | 7 +- .../certification/CertificationModelFactory.java | 37 +++++++++-- .../certservice/certification/CsrModelFactory.java | 47 +------------ .../PemStringToCertificateConverter.java | 50 ++++++++++++++ .../certservice/certification/StringBase64.java | 65 ++++++++++++++++++ .../certification/UpdateRequestTypeDetector.java | 33 ++++++++++ .../certification/X509CertificateModelFactory.java | 77 ++++++++++++++++++++++ .../certification/X509CertificateParser.java | 53 +++++++++++++++ .../exception/CertificateDecryptionException.java | 33 ++++++++++ .../StringToCertificateConversionException.java | 33 ++++++++++ .../certification/model/CertificateData.java | 69 +++++++++++++++++++ .../certservice/certification/model/CsrModel.java | 24 +++---- .../certification/model/X509CertificateModel.java | 53 +++++++++++++++ 13 files changed, 514 insertions(+), 67 deletions(-) create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/PemStringToCertificateConverter.java create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/StringBase64.java create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/UpdateRequestTypeDetector.java create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateModelFactory.java create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateParser.java create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/exception/CertificateDecryptionException.java create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/exception/StringToCertificateConversionException.java create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/model/CertificateData.java create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/model/X509CertificateModel.java (limited to 'certService/src/main') diff --git a/certService/src/main/java/org/onap/oom/certservice/api/CertificationController.java b/certService/src/main/java/org/onap/oom/certservice/api/CertificationController.java index a0972d59..d21b1eb5 100644 --- a/certService/src/main/java/org/onap/oom/certservice/api/CertificationController.java +++ b/certService/src/main/java/org/onap/oom/certservice/api/CertificationController.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * PROJECT + * Cert Service * ================================================================================ * Copyright (C) 2020-2021 Nokia. All rights reserved. * ================================================================================ @@ -27,10 +27,11 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import org.onap.oom.certservice.certification.model.CertificateUpdateModel; import org.onap.oom.certservice.certification.CertificationModelFactory; +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; import org.onap.oom.certservice.certification.model.CertificationModel; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; import org.slf4j.Logger; @@ -111,7 +112,7 @@ public class CertificationController { @RequestHeader("PK") String encodedPrivateKey, @RequestHeader("OLD_CERT") String encodedOldCert, @RequestHeader("OLD_PK") String encodedOldPrivateKey - ) { + ) throws DecryptionException, CertificateDecryptionException { caName = replaceWhiteSpaceChars(caName); LOGGER.info("Received certificate update request for CA named: {}", caName); CertificateUpdateModel certificateUpdateModel = new CertificateUpdateModel.CertificateUpdateModelBuilder() diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/CertificationModelFactory.java b/certService/src/main/java/org/onap/oom/certservice/certification/CertificationModelFactory.java index 94332f2d..d5d9d9b8 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/CertificationModelFactory.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/CertificationModelFactory.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * PROJECT + * Cert Service * ================================================================================ * Copyright (C) 2020 Nokia. All rights reserved. * ================================================================================ @@ -22,10 +22,12 @@ package org.onap.oom.certservice.certification; import org.onap.oom.certservice.certification.configuration.Cmpv2ServerProvider; import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server; +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.CertificationModel; import org.onap.oom.certservice.certification.model.CsrModel; +import org.onap.oom.certservice.certification.model.X509CertificateModel; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,23 +42,28 @@ public class CertificationModelFactory { private final CsrModelFactory csrModelFactory; private final Cmpv2ServerProvider cmpv2ServerProvider; private final CertificationProvider certificationProvider; + private final X509CertificateModelFactory x509CertificateModelFactory; + private final UpdateRequestTypeDetector updateRequestTypeDetector; @Autowired CertificationModelFactory( CsrModelFactory csrModelFactory, Cmpv2ServerProvider cmpv2ServerProvider, - CertificationProvider certificationProvider - ) { + CertificationProvider certificationProvider, + X509CertificateModelFactory x509CertificateModelFactory, + UpdateRequestTypeDetector updateRequestTypeDetector) { this.cmpv2ServerProvider = cmpv2ServerProvider; this.csrModelFactory = csrModelFactory; this.certificationProvider = certificationProvider; + this.x509CertificateModelFactory = x509CertificateModelFactory; + this.updateRequestTypeDetector = updateRequestTypeDetector; } public CertificationModel createCertificationModel(String encodedCsr, String encodedPrivateKey, String caName) throws DecryptionException, CmpClientException { CsrModel csrModel = csrModelFactory.createCsrModel( - new CsrModelFactory.StringBase64(encodedCsr), - new CsrModelFactory.StringBase64(encodedPrivateKey) + new StringBase64(encodedCsr), + new StringBase64(encodedPrivateKey) ); LOGGER.debug("Received CSR meta data: \n{}", csrModel); @@ -68,10 +75,26 @@ public class CertificationModelFactory { return certificationProvider.signCsr(csrModel, cmpv2Server); } - public CertificationModel createCertificationModel(CertificateUpdateModel certificateUpdateModel) { + public CertificationModel createCertificationModel(CertificateUpdateModel certificateUpdateModel) + throws DecryptionException, CertificateDecryptionException { LOGGER.info("CSR: " + certificateUpdateModel.getEncodedCsr() + ", old cert: " + certificateUpdateModel.getEncodedOldCert() + ", CA: " + certificateUpdateModel.getCaName()); - throw new UnsupportedOperationException("TODO: it will be delivered in the next MR"); + final CsrModel csrModel = csrModelFactory.createCsrModel( + new StringBase64(certificateUpdateModel.getEncodedCsr()), + new StringBase64(certificateUpdateModel.getEncodedPrivateKey()) + ); + final X509CertificateModel certificateModel = x509CertificateModelFactory.createCertificateModel( + new StringBase64(certificateUpdateModel.getEncodedOldCert())); + + if (updateRequestTypeDetector.isKur(csrModel.getCertificateData(), certificateModel.getCertificateData())) { + LOGGER.info( + "Certificate Signing Request and Old Certificate have the same parameters. Preparing Key Update Request"); + throw new UnsupportedOperationException("TODO: implement KUR in separate MR"); + } else { + LOGGER.info( + "Certificate Signing Request and Old Certificate have different parameters. Preparing Certification Request"); + throw new UnsupportedOperationException("TODO: implement CR in separate MR"); + } } } diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/CsrModelFactory.java b/certService/src/main/java/org/onap/oom/certservice/certification/CsrModelFactory.java index 758427f6..789773d6 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/CsrModelFactory.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/CsrModelFactory.java @@ -1,8 +1,8 @@ /* * ============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. @@ -20,18 +20,12 @@ package org.onap.oom.certservice.certification; -import java.util.Base64; -import java.util.Objects; -import java.util.Optional; - 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.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -71,43 +65,6 @@ public class CsrModelFactory { ); } - public static class StringBase64 { - private final String value; - private final Base64.Decoder decoder = Base64.getDecoder(); - private static final Logger LOGGER = LoggerFactory.getLogger(StringBase64.class); - - public StringBase64(String value) { - this.value = value; - } - - public Optional asString() { - try { - String decodedString = new String(decoder.decode(value)); - return Optional.of(decodedString); - } catch (RuntimeException e) { - LOGGER.error("Exception occurred during decoding:", e); - return Optional.empty(); - } - } - - @Override - public boolean equals(Object otherObject) { - if (this == otherObject) { - return true; - } - if (otherObject == null || getClass() != otherObject.getClass()) { - return false; - } - StringBase64 that = (StringBase64) otherObject; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return value.hashCode(); - } - } - } diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/PemStringToCertificateConverter.java b/certService/src/main/java/org/onap/oom/certservice/certification/PemStringToCertificateConverter.java new file mode 100644 index 00000000..7126cd4a --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/PemStringToCertificateConverter.java @@ -0,0 +1,50 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 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. + * 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; + +import java.io.IOException; +import java.io.StringReader; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Optional; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMParser; +import org.onap.oom.certservice.certification.exception.StringToCertificateConversionException; +import org.springframework.stereotype.Service; + +@Service +public class PemStringToCertificateConverter { + + public X509Certificate convert(String certificatePemString) throws StringToCertificateConversionException { + try (PEMParser pemParser = new PEMParser(new StringReader(certificatePemString))) { + X509CertificateHolder certHolder = Optional.ofNullable((X509CertificateHolder) pemParser.readObject()) + .orElseThrow( + () -> new StringToCertificateConversionException("The certificate could not be converted correctly.")); + return new JcaX509CertificateConverter() + .setProvider(new BouncyCastleProvider()) + .getCertificate(certHolder); + } catch (IOException | CertificateException e) { + throw new StringToCertificateConversionException("Exception occurred during certificate conversion.", e); + } + } +} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/StringBase64.java b/certService/src/main/java/org/onap/oom/certservice/certification/StringBase64.java new file mode 100644 index 00000000..9929e52c --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/StringBase64.java @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * 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. + * 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; + +import java.util.Base64; +import java.util.Objects; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StringBase64 { + + private final String value; + private final Base64.Decoder decoder = Base64.getDecoder(); + private static final Logger LOGGER = LoggerFactory.getLogger(StringBase64.class); + + public StringBase64(String value) { + this.value = value; + } + + public Optional asString() { + try { + String decodedString = new String(decoder.decode(value)); + return Optional.of(decodedString); + } catch (RuntimeException e) { + LOGGER.error("Exception occurred during decoding:", e); + return Optional.empty(); + } + } + + @Override + public boolean equals(Object otherObject) { + if (this == otherObject) { + return true; + } + if (otherObject == null || getClass() != otherObject.getClass()) { + return false; + } + StringBase64 that = (StringBase64) otherObject; + return Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } +} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/UpdateRequestTypeDetector.java b/certService/src/main/java/org/onap/oom/certservice/certification/UpdateRequestTypeDetector.java new file mode 100644 index 00000000..bef2fd5f --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/UpdateRequestTypeDetector.java @@ -0,0 +1,33 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 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. + * 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; + +import org.onap.oom.certservice.certification.model.CertificateData; +import org.springframework.stereotype.Service; + +@Service +public class UpdateRequestTypeDetector { + + public boolean isKur(CertificateData certificateData1, CertificateData certificateData2) { + return certificateData1.equals(certificateData2); + } + +} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateModelFactory.java b/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateModelFactory.java new file mode 100644 index 00000000..17367ce7 --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateModelFactory.java @@ -0,0 +1,77 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 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. + * 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; + +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.GeneralName; +import org.onap.oom.certservice.certification.exception.CertificateDecryptionException; +import org.onap.oom.certservice.certification.exception.StringToCertificateConversionException; +import org.onap.oom.certservice.certification.model.X509CertificateModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class X509CertificateModelFactory { + + private static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n"; + private static final String END_CERTIFICATE = "-----END CERTIFICATE-----\n"; + + private final PemStringToCertificateConverter pemStringToCertificateConverter; + private final X509CertificateParser x509CertificateParser; + + @Autowired + public X509CertificateModelFactory(PemStringToCertificateConverter pemStringToCertificateConverter, + X509CertificateParser x509CertificateParser) { + this.pemStringToCertificateConverter = pemStringToCertificateConverter; + this.x509CertificateParser = x509CertificateParser; + } + + public X509CertificateModel createCertificateModel(StringBase64 base64EncodedCertificate) + throws CertificateDecryptionException { + final String certificateString = base64EncodedCertificate.asString() + .map(this::getFirstCertificateFromCertificateChain) + .orElseThrow(() -> new CertificateDecryptionException("Incorrect certificate, decryption failed")); + try { + final X509Certificate certificate = pemStringToCertificateConverter.convert(certificateString); + final X500Name subjectData = x509CertificateParser.getSubject(certificate); + final GeneralName[] sans = x509CertificateParser.getSans(certificate); + return new X509CertificateModel(certificate, subjectData, sans); + } catch (StringToCertificateConversionException e) { + throw new CertificateDecryptionException("Cannot convert certificate", e); + + } catch (CertificateParsingException e) { + throw new CertificateDecryptionException("Cannot read Subject Alternative Names from certificate"); + } + } + + private String getFirstCertificateFromCertificateChain(String certificateChain) { + if (doesNotContainCertificates(certificateChain)) { + return null; + } + return certificateChain.split(END_CERTIFICATE)[0] + END_CERTIFICATE; + } + + private boolean doesNotContainCertificates(String certificateChain) { + return !(certificateChain.contains(BEGIN_CERTIFICATE) && certificateChain.contains(END_CERTIFICATE)); + } +} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateParser.java b/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateParser.java new file mode 100644 index 00000000..67b12796 --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateParser.java @@ -0,0 +1,53 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 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. + * 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; + +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.security.auth.x500.X500Principal; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.GeneralName; +import org.springframework.stereotype.Service; + +@Service +public class X509CertificateParser { + + public X500Name getSubject(X509Certificate certificate) { + final X500Principal subjectX500Principal = certificate.getSubjectX500Principal(); + return new X500Name(subjectX500Principal.getName()); + } + + public GeneralName[] getSans(X509Certificate certificate) throws CertificateParsingException { + final Collection> sans = certificate.getSubjectAlternativeNames(); + if (sans == null) { + return new GeneralName[0]; + } + final ArrayList generalNames = new ArrayList<>(); + for (List san : sans) { + GeneralName sanGn = new GeneralName((Integer) san.get(0), san.get(1).toString()); + generalNames.add(sanGn); + } + return generalNames.toArray(new GeneralName[0]); + } +} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/exception/CertificateDecryptionException.java b/certService/src/main/java/org/onap/oom/certservice/certification/exception/CertificateDecryptionException.java new file mode 100644 index 00000000..16fdb44b --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/exception/CertificateDecryptionException.java @@ -0,0 +1,33 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 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. + * 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.exception; + +public class CertificateDecryptionException extends Exception { + + public CertificateDecryptionException(String message, Throwable cause) { + super(message, cause); + } + + public CertificateDecryptionException(String message) { + super(message); + } + +} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/exception/StringToCertificateConversionException.java b/certService/src/main/java/org/onap/oom/certservice/certification/exception/StringToCertificateConversionException.java new file mode 100644 index 00000000..087172d7 --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/exception/StringToCertificateConversionException.java @@ -0,0 +1,33 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 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. + * 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.exception; + +public class StringToCertificateConversionException extends Exception { + + public StringToCertificateConversionException(String message, Throwable cause) { + super(message, cause); + } + + public StringToCertificateConversionException(String message) { + super(message); + } + +} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificateData.java b/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificateData.java new file mode 100644 index 00000000..3a00c915 --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificateData.java @@ -0,0 +1,69 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 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. + * 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.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; + +public class CertificateData { + + private final X500Name subject; + private final List sortedSans; + + public CertificateData(X500Name subject, GeneralName[] sans) { + this.subject = subject; + this.sortedSans = sans != null ? getSortedSansList(sans) : Collections.emptyList(); + } + + public X500Name getSubject() { + return subject; + } + + public GeneralName[] getSortedSans() { + return sortedSans.toArray(new GeneralName[0]); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CertificateData that = (CertificateData) o; + return Objects.equals(subject, that.subject) && Objects.equals(sortedSans, that.sortedSans); + } + + @Override + public int hashCode() { + return Objects.hash(subject, sortedSans); + } + + private List getSortedSansList(GeneralName[] sans) { + return Arrays.stream(sans).sorted(Comparator.comparing(GeneralName::toString)) + .collect(Collectors.toUnmodifiableList()); + } + +} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/model/CsrModel.java b/certService/src/main/java/org/onap/oom/certservice/certification/model/CsrModel.java index 03d1a9d2..96755832 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/model/CsrModel.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/model/CsrModel.java @@ -1,8 +1,8 @@ /* * ============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. @@ -29,7 +29,6 @@ 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; @@ -38,7 +37,6 @@ import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; 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; @@ -47,18 +45,16 @@ import org.onap.oom.certservice.certification.exception.KeyDecryptionException; public class CsrModel { private final PKCS10CertificationRequest csr; - private final X500Name subjectData; private final PrivateKey privateKey; private final PublicKey publicKey; - private final GeneralName[] sans; + private final CertificateData certificateData; public CsrModel(PKCS10CertificationRequest csr, X500Name subjectData, PrivateKey privateKey, PublicKey publicKey, GeneralName[] sans) { this.csr = csr; - this.subjectData = subjectData; this.privateKey = privateKey; this.publicKey = publicKey; - this.sans = sans; + this.certificateData = new CertificateData(subjectData, sans); } public PKCS10CertificationRequest getCsr() { @@ -66,7 +62,7 @@ public class CsrModel { } public X500Name getSubjectData() { - return subjectData; + return certificateData.getSubject(); } public PrivateKey getPrivateKey() { @@ -78,16 +74,20 @@ public class CsrModel { } public GeneralName[] getSans() { - return sans; + return certificateData.getSortedSans(); + } + + public CertificateData getCertificateData() { + return certificateData; } @Override public String toString() { - return "CSR: { Subject: { " + subjectData + " }, SANs: [" + getSansInReadableFormat() + "] }"; + return "CSR: { Subject: { " + certificateData.getSubject() + " }, SANs: [" + getSansInReadableFormat() + "] }"; } private String getSansInReadableFormat() { - return Arrays.stream(this.sans) + return Arrays.stream(this.certificateData.getSortedSans()) .map(generalName -> generalName.getName().toString()) .collect(Collectors.joining(", ")); } diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/model/X509CertificateModel.java b/certService/src/main/java/org/onap/oom/certservice/certification/model/X509CertificateModel.java new file mode 100644 index 00000000..f45fb7d3 --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/model/X509CertificateModel.java @@ -0,0 +1,53 @@ +/* + * ============LICENSE_START======================================================= + * Cert Service + * ================================================================================ + * Copyright (C) 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. + * 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.model; + +import java.security.cert.X509Certificate; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.GeneralName; + +public class X509CertificateModel { + + private final X509Certificate certificate; + private final CertificateData certificateData; + + public X509CertificateModel(X509Certificate certificate, X500Name subjectData, + GeneralName[] sans) { + this.certificate = certificate; + this.certificateData = new CertificateData(subjectData, sans); + } + + public X509Certificate getCertificate() { + return certificate; + } + + public X500Name getSubjectData() { + return certificateData.getSubject(); + } + + public GeneralName[] getSans() { + return certificateData.getSortedSans(); + } + + public CertificateData getCertificateData() { + return certificateData; + } +} -- cgit 1.2.3-korg