From 56b2c3a4d002c1fc7e486fb49bd8c318f0cd5682 Mon Sep 17 00:00:00 2001 From: Piotr Marcinkiewicz Date: Thu, 24 Jun 2021 10:48:28 +0200 Subject: [PATCH] [OOM-CERT-SERVICE] Add update endpoint - Add endpoint with old cert and old PK parameters for KUR/CR requests Issue-ID: OOM-2753 Signed-off-by: Piotr Marcinkiewicz Change-Id: I094ce1a39a11bbb94f94e0b13ca7ff71eb99dd30 --- .../certservice/api/CertificationController.java | 38 ++++++- .../certification/CertificationModelFactory.java | 7 ++ .../model/CertificateUpdateModel.java | 116 +++++++++++++++++++++ .../api/CertificationControllerTest.java | 41 ++++++-- 4 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 certService/src/main/java/org/onap/oom/certservice/certification/model/CertificateUpdateModel.java 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 fd35ec8e..a0972d59 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 @@ -27,6 +27,7 @@ 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.DecryptionException; import org.onap.oom.certservice.certification.exception.ErrorResponseModel; @@ -86,11 +87,46 @@ public class CertificationController { @Parameter(description = "Private key in form of PEM object encoded in Base64 (with header and footer).") @RequestHeader("PK") String encodedPrivateKey ) throws DecryptionException, CmpClientException { - caName = caName.replaceAll("[\n\r\t]", "_"); + caName = replaceWhiteSpaceChars(caName); LOGGER.info("Received certificate signing request for CA named: {}", caName); CertificationModel certificationModel = certificationModelFactory .createCertificationModel(encodedCsr, encodedPrivateKey, caName); return new ResponseEntity<>(certificationModel, HttpStatus.OK); } + /** + * Request for updating certificate by given CA. + * + * @param caName the name of Certification Authority that will sign root certificate + * @param encodedCsr Certificate Sign Request encoded in Base64 form + * @param encodedPrivateKey Private key for CSR, needed for PoP, encoded in Base64 form + * @param encodedOldCert Certificate (signed by Certification Authority) that should be renewed + * @param encodedOldPrivateKey Old private key corresponding with old certificate + * @return JSON containing trusted certificates and certificate chain + */ + @GetMapping(value = "v1/certificate-update/{caName}", produces = "application/json") + public ResponseEntity updateCertificate( + @PathVariable String caName, + @RequestHeader("CSR") String encodedCsr, + @RequestHeader("PK") String encodedPrivateKey, + @RequestHeader("OLD_CERT") String encodedOldCert, + @RequestHeader("OLD_PK") String encodedOldPrivateKey + ) { + caName = replaceWhiteSpaceChars(caName); + LOGGER.info("Received certificate update request for CA named: {}", caName); + CertificateUpdateModel certificateUpdateModel = new CertificateUpdateModel.CertificateUpdateModelBuilder() + .setEncodedCsr(encodedCsr) + .setEncodedPrivateKey(encodedPrivateKey) + .setEncodedOldCert(encodedOldCert) + .setEncodedOldPrivateKey(encodedOldPrivateKey) + .setCaName(caName) + .build(); + CertificationModel certificationModel = certificationModelFactory + .createCertificationModel(certificateUpdateModel); + return new ResponseEntity<>(certificationModel, HttpStatus.OK); + } + + private String replaceWhiteSpaceChars(String text) { + return text.replaceAll("[\n\r\t]", "_"); + } } 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 23440ac5..94332f2d 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 @@ -23,6 +23,7 @@ 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.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.cmpv2client.exceptions.CmpClientException; @@ -67,4 +68,10 @@ public class CertificationModelFactory { return certificationProvider.signCsr(csrModel, cmpv2Server); } + public CertificationModel createCertificationModel(CertificateUpdateModel certificateUpdateModel) { + LOGGER.info("CSR: " + certificateUpdateModel.getEncodedCsr() + + ", old cert: " + certificateUpdateModel.getEncodedOldCert() + + ", CA: " + certificateUpdateModel.getCaName()); + throw new UnsupportedOperationException("TODO: it will be delivered in the next MR"); + } } diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificateUpdateModel.java b/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificateUpdateModel.java new file mode 100644 index 00000000..699ffe71 --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificateUpdateModel.java @@ -0,0 +1,116 @@ +/*- + * ============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.model; + +import java.util.Objects; + +public final class CertificateUpdateModel { + + private final String encodedCsr; + private final String encodedPrivateKey; + private final String encodedOldCert; + private final String encodedOldPrivateKey; + private final String caName; + + private CertificateUpdateModel(String encodedCsr, String encodedPrivateKey, String encodedOldCert, + String encodedOldPrivateKey, String caName) { + this.encodedCsr = encodedCsr; + this.encodedPrivateKey = encodedPrivateKey; + this.encodedOldCert = encodedOldCert; + this.encodedOldPrivateKey = encodedOldPrivateKey; + this.caName = caName; + } + + public String getEncodedCsr() { + return encodedCsr; + } + + public String getEncodedPrivateKey() { + return encodedPrivateKey; + } + + public String getEncodedOldCert() { + return encodedOldCert; + } + + public String getEncodedOldPrivateKey() { + return encodedOldPrivateKey; + } + + public String getCaName() { + return caName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CertificateUpdateModel that = (CertificateUpdateModel) o; + 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); + } + + @Override + public int hashCode() { + return Objects.hash(encodedCsr, encodedPrivateKey, encodedOldCert, encodedOldPrivateKey, caName); + } + + public static class CertificateUpdateModelBuilder { + + private String encodedCsr; + private String encodedPrivateKey; + private String encodedOldCert; + private String encodedOldPrivateKey; + private String caName; + + public CertificateUpdateModelBuilder setEncodedCsr(String encodedCsr) { + this.encodedCsr = encodedCsr; + return this; + } + + public CertificateUpdateModelBuilder setEncodedPrivateKey(String encodedPrivateKey) { + this.encodedPrivateKey = encodedPrivateKey; + return this; + } + + public CertificateUpdateModelBuilder setEncodedOldCert(String encodedOldCert) { + this.encodedOldCert = encodedOldCert; + return this; + } + + public CertificateUpdateModelBuilder setEncodedOldPrivateKey(String encodedOldPrivateKey) { + this.encodedOldPrivateKey = encodedOldPrivateKey; + return this; + } + + public CertificateUpdateModelBuilder setCaName(String caName) { + this.caName = caName; + return this; + } + + public CertificateUpdateModel build() { + return new CertificateUpdateModel(encodedCsr, encodedPrivateKey, encodedOldCert, encodedOldPrivateKey, caName); + } + } +} diff --git a/certService/src/test/java/org/onap/oom/certservice/api/CertificationControllerTest.java b/certService/src/test/java/org/onap/oom/certservice/api/CertificationControllerTest.java index abd950e8..0bf37901 100644 --- a/certService/src/test/java/org/onap/oom/certservice/api/CertificationControllerTest.java +++ b/certService/src/test/java/org/onap/oom/certservice/api/CertificationControllerTest.java @@ -2,7 +2,7 @@ * ============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. @@ -32,8 +32,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.onap.oom.certservice.certification.model.CertificateUpdateModel; import org.onap.oom.certservice.certification.CertificationModelFactory; -import org.onap.oom.certservice.certification.exception.Cmpv2ClientAdapterException; import org.onap.oom.certservice.certification.exception.Cmpv2ServerNotFoundException; import org.onap.oom.certservice.certification.exception.CsrDecryptionException; import org.onap.oom.certservice.certification.exception.DecryptionException; @@ -52,6 +52,8 @@ class CertificationControllerTest { private static final String TEST_WRONG_ENCODED_CSR = "wrongEncodedCSR"; private static final String TEST_WRONG_ENCODED_PK = "wrongEncodedPK"; private static final String TEST_WRONG_CA_NAME = "wrongTestCa"; + private static final String TEST_ENCODED_OLD_PK = "encodedOldPK"; + private static final String TEST_ENCODED_OLD_CERT = "encodedOldCert"; private CertificationController certificationController; @@ -65,7 +67,7 @@ class CertificationControllerTest { @Test void shouldReturnDataAboutCsrBaseOnEncodedParameters() - throws DecryptionException, CmpClientException, Cmpv2ClientAdapterException { + throws DecryptionException, CmpClientException { // Given CertificationModel testCertificationModel = new CertificationModel( Arrays.asList("ENTITY_CERT", "INTERMEDIATE_CERT"), @@ -87,7 +89,7 @@ class CertificationControllerTest { @Test void shouldThrowCsrDecryptionExceptionWhenCreatingCsrModelFails() - throws DecryptionException, CmpClientException, Cmpv2ClientAdapterException { + throws DecryptionException, CmpClientException { // Given String expectedMessage = "Incorrect CSR, decryption failed"; when(certificationModelFactory.createCertificationModel(TEST_WRONG_ENCODED_CSR, TEST_ENCODED_PK, TEST_CA_NAME)) @@ -107,7 +109,7 @@ class CertificationControllerTest { @Test void shouldThrowPemDecryptionExceptionWhenCreatingPemModelFails() - throws DecryptionException, CmpClientException, Cmpv2ClientAdapterException { + throws DecryptionException, CmpClientException { // Given String expectedMessage = "Incorrect PEM, decryption failed"; when(certificationModelFactory.createCertificationModel(TEST_ENCODED_CSR, TEST_WRONG_ENCODED_PK, TEST_CA_NAME)) @@ -127,7 +129,7 @@ class CertificationControllerTest { @Test void shouldThrowCmpv2ServerNotFoundWhenGivenWrongCaName() - throws DecryptionException, CmpClientException, Cmpv2ClientAdapterException { + throws DecryptionException, CmpClientException { // Given String expectedMessage = "No server found for given CA name"; when(certificationModelFactory.createCertificationModel(TEST_ENCODED_CSR, TEST_ENCODED_PK, TEST_WRONG_CA_NAME)) @@ -144,4 +146,31 @@ class CertificationControllerTest { // Then assertEquals(expectedMessage, actualMessage); } + + @Test + void shouldUpdateEndpointReturnDataAboutCsrBaseOnEncodedParameters() { + // Given + CertificationModel testCertificationModel = new CertificationModel( + Arrays.asList("ENTITY_CERT", "INTERMEDIATE_CERT"), + Arrays.asList("CA_CERT", "EXTRA_CA_CERT") + ); + CertificateUpdateModel certificateUpdateModel = new CertificateUpdateModel.CertificateUpdateModelBuilder() + .setEncodedCsr(TEST_ENCODED_CSR) + .setEncodedPrivateKey(TEST_ENCODED_PK) + .setEncodedOldCert(TEST_ENCODED_OLD_CERT) + .setEncodedOldPrivateKey(TEST_ENCODED_OLD_PK) + .setCaName(TEST_CA_NAME) + .build(); + when(certificationModelFactory.createCertificationModel(certificateUpdateModel)).thenReturn(testCertificationModel); + + // When + ResponseEntity responseCertificationModel = + certificationController.updateCertificate(TEST_CA_NAME, TEST_ENCODED_CSR, + TEST_ENCODED_PK, TEST_ENCODED_OLD_CERT, TEST_ENCODED_OLD_PK); + + // Then + assertEquals(HttpStatus.OK, responseCertificationModel.getStatusCode()); + assertThat(responseCertificationModel.getBody()).isEqualToComparingFieldByField(testCertificationModel); + } + } -- 2.16.6