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 --- .../api/CertificationControllerTest.java | 45 ++++-- .../CertificationModelFactoryTest.java | 166 ++++++++++++++------- .../certification/CsrModelFactoryTest.java | 4 +- .../PemStringToCertificateConverterTest.java | 90 +++++++++++ .../oom/certservice/certification/TestData.java | 4 +- .../oom/certservice/certification/TestUtils.java | 4 +- .../UpdateRequestTypeDetectorTest.java | 120 +++++++++++++++ .../X509CertificateModelFactoryTest.java | 166 +++++++++++++++++++++ .../certification/X509CertificateParserTest.java | 84 +++++++++++ .../certification/model/CertificateDataTest.java | 117 +++++++++++++++ 10 files changed, 732 insertions(+), 68 deletions(-) create mode 100644 certService/src/test/java/org/onap/oom/certservice/certification/PemStringToCertificateConverterTest.java create mode 100644 certService/src/test/java/org/onap/oom/certservice/certification/UpdateRequestTypeDetectorTest.java create mode 100644 certService/src/test/java/org/onap/oom/certservice/certification/X509CertificateModelFactoryTest.java create mode 100644 certService/src/test/java/org/onap/oom/certservice/certification/X509CertificateParserTest.java create mode 100644 certService/src/test/java/org/onap/oom/certservice/certification/model/CertificateDataTest.java (limited to 'certService/src/test/java/org/onap') 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 0bf37901..f1d5baaf 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * PROJECT + * Cert Service * ================================================================================ * Copyright (C) 2020-2021 Nokia. All rights reserved. * ================================================================================ @@ -32,12 +32,15 @@ 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.exception.CertificateDecryptionException; +import org.onap.oom.certservice.certification.exception.StringToCertificateConversionException; import org.onap.oom.certservice.certification.model.CertificateUpdateModel; import org.onap.oom.certservice.certification.CertificationModelFactory; import org.onap.oom.certservice.certification.exception.Cmpv2ServerNotFoundException; 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.CertificateUpdateModel.CertificateUpdateModelBuilder; import org.onap.oom.certservice.certification.model.CertificationModel; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; import org.springframework.http.HttpStatus; @@ -54,6 +57,13 @@ class CertificationControllerTest { 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 static final CertificateUpdateModel TEST_CERTIFICATE_UPDATE_MODEL = new CertificateUpdateModelBuilder() + .setEncodedCsr(TEST_ENCODED_CSR) + .setEncodedPrivateKey(TEST_ENCODED_PK) + .setEncodedOldCert(TEST_ENCODED_OLD_CERT) + .setEncodedOldPrivateKey(TEST_ENCODED_OLD_PK) + .setCaName(TEST_CA_NAME) + .build(); private CertificationController certificationController; @@ -148,20 +158,14 @@ class CertificationControllerTest { } @Test - void shouldUpdateEndpointReturnDataAboutCsrBaseOnEncodedParameters() { + void shouldUpdateEndpointReturnDataAboutCsrBaseOnEncodedParameters() + throws DecryptionException, CertificateDecryptionException { // 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(certificationModelFactory.createCertificationModel(TEST_CERTIFICATE_UPDATE_MODEL)).thenReturn(testCertificationModel); // When ResponseEntity responseCertificationModel = @@ -173,4 +177,25 @@ class CertificationControllerTest { assertThat(responseCertificationModel.getBody()).isEqualToComparingFieldByField(testCertificationModel); } + @Test + void shouldThrowCertificateDecryptionExceptionWhenCreatingPemModelFails() + throws DecryptionException, CertificateDecryptionException { + // Given + String expectedMessage = "Incorrect certificate, decryption failed"; + when(certificationModelFactory.createCertificationModel(TEST_CERTIFICATE_UPDATE_MODEL)) + .thenThrow(new CertificateDecryptionException(expectedMessage)); + + // When + Exception exception = assertThrows( + CertificateDecryptionException.class, () -> + certificationController.updateCertificate(TEST_CA_NAME, TEST_ENCODED_CSR, + TEST_ENCODED_PK, TEST_ENCODED_OLD_CERT, TEST_ENCODED_OLD_PK) + ); + + String actualMessage = exception.getMessage(); + + // Then + assertEquals(expectedMessage, actualMessage); + } + } diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/CertificationModelFactoryTest.java b/certService/src/test/java/org/onap/oom/certservice/certification/CertificationModelFactoryTest.java index 705ae004..c898b687 100644 --- a/certService/src/test/java/org/onap/oom/certservice/certification/CertificationModelFactoryTest.java +++ b/certService/src/test/java/org/onap/oom/certservice/certification/CertificationModelFactoryTest.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * PROJECT + * Cert Service * ================================================================================ * Copyright (C) 2020-2021 Nokia. All rights reserved. * ================================================================================ @@ -20,6 +20,25 @@ package org.onap.oom.certservice.certification; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.onap.oom.certservice.certification.CertificationData.CA_CERT; +import static org.onap.oom.certservice.certification.CertificationData.ENTITY_CERT; +import static org.onap.oom.certservice.certification.CertificationData.EXTRA_CA_CERT; +import static org.onap.oom.certservice.certification.CertificationData.INTERMEDIATE_CERT; +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 java.util.Arrays; +import java.util.Base64; +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -27,33 +46,18 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; 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.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; +import org.onap.oom.certservice.certification.model.CertificateUpdateModel; +import org.onap.oom.certservice.certification.model.CertificateUpdateModel.CertificateUpdateModelBuilder; 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 java.util.Arrays; -import java.util.Base64; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.onap.oom.certservice.certification.CertificationData.CA_CERT; -import static org.onap.oom.certservice.certification.CertificationData.ENTITY_CERT; -import static org.onap.oom.certservice.certification.CertificationData.INTERMEDIATE_CERT; -import static org.onap.oom.certservice.certification.CertificationData.EXTRA_CA_CERT; -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; - @ExtendWith(MockitoExtension.class) class CertificationModelFactoryTest { @@ -62,6 +66,18 @@ class CertificationModelFactoryTest { private static final String ENCODED_PK = getEncodedString(TEST_PK); private static final String ENCODED_WRONG_CSR = getEncodedString(TEST_WRONG_CSR); private static final String ENCODED_WRONG_PK = getEncodedString(TEST_WRONG_PEM); + private static final String TEST_CA_NAME = "TestCa"; + private static final String TEST_ENCODED_CSR = "encodedCSR"; + private static final String TEST_ENCODED_PK = "encodedPK"; + private static final String TEST_ENCODED_OLD_PK = "encodedOldPK"; + private static final String TEST_ENCODED_OLD_CERT = "encodedOldCert"; + private static final CertificateUpdateModel TEST_CERTIFICATE_UPDATE_MODEL = new CertificateUpdateModelBuilder() + .setEncodedCsr(TEST_ENCODED_CSR) + .setEncodedPrivateKey(TEST_ENCODED_PK) + .setEncodedOldCert(TEST_ENCODED_OLD_CERT) + .setEncodedOldPrivateKey(TEST_ENCODED_OLD_PK) + .setCaName(TEST_CA_NAME) + .build(); private CertificationModelFactory certificationModelFactory; @@ -71,7 +87,10 @@ class CertificationModelFactoryTest { private CsrModelFactory csrModelFactory; @Mock private CertificationProvider certificationProvider; - + @Mock + private X509CertificateModelFactory x509CertificateModelFactory; + @Mock + private UpdateRequestTypeDetector updateRequestTypeDetector; private static String getEncodedString(String testCsr) { return Base64.getEncoder().encodeToString(testCsr.getBytes()); @@ -80,12 +99,13 @@ class CertificationModelFactoryTest { @BeforeEach void setUp() { certificationModelFactory = - new CertificationModelFactory(csrModelFactory, cmpv2ServerProvider, certificationProvider); + new CertificationModelFactory(csrModelFactory, cmpv2ServerProvider, certificationProvider, + x509CertificateModelFactory, updateRequestTypeDetector); } @Test void shouldCreateProperCertificationModelWhenGivenProperCsrModelAndCaName() - throws CmpClientException, DecryptionException, Cmpv2ClientAdapterException { + throws CmpClientException, DecryptionException, Cmpv2ClientAdapterException { // Given CsrModel csrModel = mockCsrFactoryModelCreation(); @@ -94,7 +114,7 @@ class CertificationModelFactoryTest { // When CertificationModel certificationModel = - certificationModelFactory.createCertificationModel(ENCODED_CSR, ENCODED_PK, TEST_CA); + certificationModelFactory.createCertificationModel(ENCODED_CSR, ENCODED_PK, TEST_CA); // Then assertEquals(2, certificationModel.getCertificateChain().size()); @@ -105,22 +125,22 @@ class CertificationModelFactoryTest { @Test void shouldThrowDecryptionExceptionWhenGivenWrongEncodedCsr() - throws DecryptionException { + throws DecryptionException { // Given String expectedMessage = "Incorrect CSR, decryption failed"; when( - csrModelFactory.createCsrModel( - new CsrModelFactory.StringBase64(ENCODED_WRONG_CSR), - new CsrModelFactory.StringBase64(ENCODED_WRONG_PK) - ) + csrModelFactory.createCsrModel( + new StringBase64(ENCODED_WRONG_CSR), + new StringBase64(ENCODED_WRONG_PK) + ) ).thenThrow( - new CsrDecryptionException(expectedMessage) + new CsrDecryptionException(expectedMessage) ); // When Exception exception = assertThrows( - DecryptionException.class, () -> - certificationModelFactory.createCertificationModel(ENCODED_WRONG_CSR, ENCODED_WRONG_PK, TEST_CA) + DecryptionException.class, () -> + certificationModelFactory.createCertificationModel(ENCODED_WRONG_CSR, ENCODED_WRONG_PK, TEST_CA) ); // Then @@ -129,20 +149,20 @@ class CertificationModelFactoryTest { @Test void shouldThrowCmpv2ServerNotFoundExceptionWhenGivenWrongCaName() - throws DecryptionException { + throws DecryptionException { // Given String expectedMessage = "CA not found"; mockCsrFactoryModelCreation(); when( - cmpv2ServerProvider.getCmpv2Server(TEST_CA) + cmpv2ServerProvider.getCmpv2Server(TEST_CA) ).thenThrow( - new Cmpv2ServerNotFoundException(expectedMessage) + new Cmpv2ServerNotFoundException(expectedMessage) ); // When Exception exception = assertThrows( - Cmpv2ServerNotFoundException.class, () -> - certificationModelFactory.createCertificationModel(ENCODED_CSR, ENCODED_PK, TEST_CA) + Cmpv2ServerNotFoundException.class, () -> + certificationModelFactory.createCertificationModel(ENCODED_CSR, ENCODED_PK, TEST_CA) ); // Then @@ -151,56 +171,98 @@ class CertificationModelFactoryTest { @Test void shouldThrowCmpClientExceptionWhenSigningCsrFailed() - throws DecryptionException, CmpClientException, Cmpv2ClientAdapterException { + throws DecryptionException, CmpClientException, Cmpv2ClientAdapterException { // Given String expectedMessage = "failed to sign certificate"; CsrModel csrModel = mockCsrFactoryModelCreation(); Cmpv2Server testServer = mockCmpv2ProviderServerSelection(); when( - certificationProvider.signCsr(csrModel, testServer) + certificationProvider.signCsr(csrModel, testServer) ).thenThrow( - new CmpClientException(expectedMessage) + new CmpClientException(expectedMessage) ); // When Exception exception = assertThrows( - CmpClientException.class, () -> - certificationModelFactory.createCertificationModel(ENCODED_CSR, ENCODED_PK, TEST_CA) + CmpClientException.class, () -> + certificationModelFactory.createCertificationModel(ENCODED_CSR, ENCODED_PK, TEST_CA) ); // Then assertTrue(exception.getMessage().contains(expectedMessage)); } + @Test + void shouldPerformKurWhenCsrAndOldCertDataMatch() throws CertificateDecryptionException, DecryptionException { + //given + mockCsrFactoryModelCreation(); + mockCertificateFactoryModelCreation(); + when(updateRequestTypeDetector.isKur(any(), any())).thenReturn(true); + //when, then + Exception exception = assertThrows( + UnsupportedOperationException.class, () -> + certificationModelFactory.createCertificationModel(TEST_CERTIFICATE_UPDATE_MODEL) + ); + assertEquals(exception.getMessage(), "TODO: implement KUR in separate MR"); + } + + @Test + void shouldPerformCrWhenCsrAndOldCertDataMatch() throws CertificateDecryptionException, DecryptionException { + //given + mockCsrFactoryModelCreation(); + mockCertificateFactoryModelCreation(); + when(updateRequestTypeDetector.isKur(any(), any())).thenReturn(false); + //when, then + Exception exception = assertThrows( + UnsupportedOperationException.class, () -> + certificationModelFactory.createCertificationModel(TEST_CERTIFICATE_UPDATE_MODEL) + ); + assertEquals(exception.getMessage(), "TODO: implement CR in separate MR"); + } + + @Test + void shouldThrowCertificateDecryptionExceptionWhenOldCertificateInvalid() + throws CertificateDecryptionException { + //given + when(x509CertificateModelFactory.createCertificateModel(any())) + .thenThrow(new CertificateDecryptionException("Incorrect certificate, decryption failed")); + //when, then + assertThrows( + CertificateDecryptionException.class, () -> + certificationModelFactory.createCertificationModel(TEST_CERTIFICATE_UPDATE_MODEL) + ); + } private void mockCertificateProviderCertificateSigning(CsrModel csrModel, Cmpv2Server testServer) - throws CmpClientException, Cmpv2ClientAdapterException { + throws CmpClientException, Cmpv2ClientAdapterException { CertificationModel expectedCertificationModel = getCertificationModel(); when( - certificationProvider.signCsr(csrModel, testServer) + certificationProvider.signCsr(csrModel, testServer) ).thenReturn(expectedCertificationModel); } private Cmpv2Server mockCmpv2ProviderServerSelection() { Cmpv2Server testServer = getCmpv2Server(); when( - cmpv2ServerProvider.getCmpv2Server(TEST_CA) + cmpv2ServerProvider.getCmpv2Server(TEST_CA) ).thenReturn(testServer); return testServer; } private CsrModel mockCsrFactoryModelCreation() - throws DecryptionException { + throws DecryptionException { CsrModel csrModel = getCsrModel(); - when( - csrModelFactory.createCsrModel( - new CsrModelFactory.StringBase64(ENCODED_CSR), - new CsrModelFactory.StringBase64(ENCODED_PK) - ) - ).thenReturn(csrModel); + when(csrModelFactory.createCsrModel(any(), any())).thenReturn(csrModel); return csrModel; } + private X509CertificateModel mockCertificateFactoryModelCreation() + throws CertificateDecryptionException { + final X509CertificateModel certificateModel = mock(X509CertificateModel.class); + when(x509CertificateModelFactory.createCertificateModel(any())).thenReturn(certificateModel); + return certificateModel; + } + private Cmpv2Server getCmpv2Server() { return new Cmpv2Server(); } diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/CsrModelFactoryTest.java b/certService/src/test/java/org/onap/oom/certservice/certification/CsrModelFactoryTest.java index 88cc6fb8..eb6a0550 100644 --- a/certService/src/test/java/org/onap/oom/certservice/certification/CsrModelFactoryTest.java +++ b/certService/src/test/java/org/onap/oom/certservice/certification/CsrModelFactoryTest.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * PROJECT + * Cert Service * ================================================================================ * Copyright (C) 2020 Nokia. All rights reserved. * ================================================================================ @@ -23,7 +23,6 @@ package org.onap.oom.certservice.certification; import org.bouncycastle.util.encoders.Base64; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.onap.oom.certservice.certification.CsrModelFactory.StringBase64; import org.onap.oom.certservice.certification.exception.CsrDecryptionException; import org.onap.oom.certservice.certification.exception.DecryptionException; import org.onap.oom.certservice.certification.exception.KeyDecryptionException; @@ -58,6 +57,7 @@ class CsrModelFactoryTest { assertTrue(decryptedCsr.toString() .contains(TestData.EXPECTED_CERT_SUBJECT)); + System.out.println(decryptedCsr.toString()); assertTrue(decryptedCsr.toString() .contains(TestData.EXPECTED_CERT_SANS)); } diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/PemStringToCertificateConverterTest.java b/certService/src/test/java/org/onap/oom/certservice/certification/PemStringToCertificateConverterTest.java new file mode 100644 index 00000000..ecdb1a2e --- /dev/null +++ b/certService/src/test/java/org/onap/oom/certservice/certification/PemStringToCertificateConverterTest.java @@ -0,0 +1,90 @@ +/* + * ============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 static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.Serializable; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.List; +import org.bouncycastle.asn1.x509.GeneralName; +import org.junit.jupiter.api.Test; +import org.onap.oom.certservice.certification.exception.StringToCertificateConversionException; + +class PemStringToCertificateConverterTest { + + private static final String CERTIFICATE_PEM_STRING = + "-----BEGIN CERTIFICATE-----\n" + + "MIIEizCCAvOgAwIBAgIUGEp2GZ6Y8nzDA9CKl5nURI7CUN8wDQYJKoZIhvcNAQEL\n" + + "BQAwYTEjMCEGCgmSJomT8ixkAQEME2MtMGpiZnE4cWExZm8wd2ttbnkxFTATBgNV\n" + + "BAMMDE1hbmFnZW1lbnRDQTEjMCEGA1UECgwaRUpCQ0EgQ29udGFpbmVyIFF1aWNr\n" + + "c3RhcnQwHhcNMjEwNjI5MDY1MDI1WhcNMjMwNjI5MDY1MDI0WjB3MREwDwYDVQQD\n" + + "DAhvbmFwLm9yZzEZMBcGA1UECwwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECgwE\n" + + "T05BUDEWMBQGA1UEBwwNU2FuLUZyYW5jaXNjbzETMBEGA1UECAwKQ2FsaWZvcm5p\n" + + "YTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDB\n" + + "zvbyrrEiaoBj8kma2QmC+VLmmtWFWyAJgSrYA4kxuyrjQCW4JyFGvmzbYoUFFLOF\n" + + "hfq18VjTs0cbTysX8cFSfkV2EKGERBaZnZRQso6SIJNGa3xMe5FHjREy34Np04IH\n" + + "jSQ42eIBgcNiIada4jgEnIQQYQJSPQtHkfOMC6O+3RpT/eHtvo5urR16MFY1K6so\n" + + "nWYitI5TpEKRozav6zqU/otHgn5jRLryj0IZy0ijlBfSKTxrFfZr3KoMDudVEfUM\n" + + "tsqER3poc1gFkqmCRK38BPNiY7v5KATRB+fWN+P75mw43drx9rImp+JtpOUsDK8r\n" + + "IBd8o4afNvr/WrygBB8rAgMBAAGjgaQwgaEwDAYDVR0TAQH/BAIwADAfBgNVHSME\n" + + "GDAWgBR9M1qUnQM0CpHUz34F5sVUUcIDtjAYBgNVHREEETAPgg10ZXN0Lm9uYXAu\n" + + "b3JnMCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwEwHQYD\n" + + "VR0OBBYEFAfqcU6xGi8jzjlRuKQBtqRcXi+uMA4GA1UdDwEB/wQEAwIF4DANBgkq\n" + + "hkiG9w0BAQsFAAOCAYEAAdw77q7shKtS8lDGcJ/Y8dEjjNSlRtU14EMC59kmKeft\n" + + "Ri7d0oCQXtdRCut3ymizLVqQkmX6SrGshpWUsNzTdITjQ6JB2KOaiIWIF60NSleW\n" + + "0vLm36EmY1ErK+zKe7tvGWZhTNVzBXtnq+AMfJc41u2uelkx0LNczsX9aCajLH1v\n" + + "4z4XsUnm9qiXpnEm632emuJyj6Nt0JWVuNTJTPRnqVZf6KKR83v8JuV0EefWd5WV\n" + + "cFspL0H3MKJV7uf7hfllnIcRtzXa5pctBCboFShVkRNaAMPpJf0DBLQxm7dAWj5A\n" + + "hG1rwmTmzM6NpwGHW/I1SFMmtQiF0PACz1Un6nDW/Rf1iHEoGf8YBLP332LJSDug\n" + + "RKn0cM3QTcyUEzCZxSwKJ2ngC9eG9C2d3YhB6Zxtl+gUIa3AwwPbqr7YR9QkD2Eo\n" + + "d4LqEH9znyBfi7k2YCwP6rtfSi6ClybXe8eBcuMES4TAQfFK6FVf58tGQIx06I0O\n" + + "34nemZwkLoOBzZkepaQv\n" + + "-----END CERTIFICATE-----\n"; + + private static final List EXPECTED_SUBJECT_ALTERNATIVE_NAME = List + .of(GeneralName.dNSName, "test.onap.org"); + + private static final String EXPECTED_SUBJECT = "CN=onap.org,OU=Linux-Foundation,O=ONAP,L=San-Francisco,ST=California,C=US"; + + private final PemStringToCertificateConverter converter = new PemStringToCertificateConverter(); + + @Test + void shouldConvertStringToCertificate() throws CertificateParsingException, StringToCertificateConversionException { + //given, when + X509Certificate certificate = converter.convert(CERTIFICATE_PEM_STRING); + //then + assertThat(certificate).isNotNull(); + assertThat(certificate.getSubjectDN()) + .hasToString(EXPECTED_SUBJECT); + assertThat(certificate.getSubjectAlternativeNames()) + .containsExactly(EXPECTED_SUBJECT_ALTERNATIVE_NAME); + } + + @Test + void shouldThrowExceptionWhenCertificateStringInvalid() { + assertThatThrownBy(() -> converter.convert("")) + .isInstanceOf(StringToCertificateConversionException.class); + } + +} diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/TestData.java b/certService/src/test/java/org/onap/oom/certservice/certification/TestData.java index 1c883f8e..92b239f1 100644 --- a/certService/src/test/java/org/onap/oom/certservice/certification/TestData.java +++ b/certService/src/test/java/org/onap/oom/certservice/certification/TestData.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. @@ -29,7 +29,7 @@ public final class TestData { 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: [localhost, onap.org, test.onap.org, onap@onap.org, " + LOCALHOST_IP_IN_HEX + ", onap://cluster.local/]"; + "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" diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/TestUtils.java b/certService/src/test/java/org/onap/oom/certservice/certification/TestUtils.java index 7c69bd52..0dceda19 100644 --- a/certService/src/test/java/org/onap/oom/certservice/certification/TestUtils.java +++ b/certService/src/test/java/org/onap/oom/certservice/certification/TestUtils.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * PROJECT + * Cert Service * ================================================================================ * Copyright (C) 2020 Nokia. All rights reserved. * ================================================================================ @@ -56,6 +56,6 @@ public final class TestUtils { String encoderCsr = new String(Base64.encode(TEST_CSR.getBytes())); String encoderPK = new String(Base64.encode(TEST_PK.getBytes())); return csrModelFactory - .createCsrModel(new CsrModelFactory.StringBase64(encoderCsr), new CsrModelFactory.StringBase64(encoderPK)); + .createCsrModel(new StringBase64(encoderCsr), new StringBase64(encoderPK)); } } diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/UpdateRequestTypeDetectorTest.java b/certService/src/test/java/org/onap/oom/certservice/certification/UpdateRequestTypeDetectorTest.java new file mode 100644 index 00000000..ee078534 --- /dev/null +++ b/certService/src/test/java/org/onap/oom/certservice/certification/UpdateRequestTypeDetectorTest.java @@ -0,0 +1,120 @@ +/* + * ============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 static org.assertj.core.api.Assertions.assertThat; + +import java.util.stream.Stream; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.GeneralName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.onap.oom.certservice.certification.model.CertificateData; + +class UpdateRequestTypeDetectorTest { + + private static final String SUBJECT = "CN=onap.org,OU=Linux-Foundation,O=ONAP,L=San-Francisco,ST=California,C=US"; + private static final String SUBJECT_CHANGED_ORDER = "ST=California,C=US,OU=Linux-Foundation,CN=onap.org,O=ONAP,L=San-Francisco"; + private static final String OTHER_SUBJECT = "CN=onap1.org,OU=Linux-Foundation,O=ONAP,L=San-Francisco,ST=California,C=US"; + private static final String DNS_NAME = "test.onap.org"; + private static final String OTHER_DNS_NAME = "test1.onap.org"; + + private final UpdateRequestTypeDetector updateRequestTypeDetector = new UpdateRequestTypeDetector(); + + private static Stream equalSubjectParameters() { + return Stream.of( + Arguments.of(SUBJECT, SUBJECT), + Arguments.of(SUBJECT_CHANGED_ORDER, SUBJECT_CHANGED_ORDER), + Arguments.of(SUBJECT, SUBJECT_CHANGED_ORDER), + Arguments.of(SUBJECT_CHANGED_ORDER, SUBJECT) + ); + } + + private static Stream notEqualSubjectParameters() { + return Stream.of( + Arguments.of(SUBJECT, OTHER_SUBJECT), + Arguments.of(OTHER_SUBJECT, SUBJECT), + Arguments.of(SUBJECT_CHANGED_ORDER, OTHER_SUBJECT), + Arguments.of(OTHER_SUBJECT, SUBJECT_CHANGED_ORDER) + ); + } + + @ParameterizedTest + @MethodSource("equalSubjectParameters") + void shouldBeKurWhenSameSubjectData(String subject1, String subject2) { + //given + final CertificateData certificateData1 = new CertificateData(new X500Name(subject1), null); + final CertificateData certificateData2 = new CertificateData(new X500Name(subject2), null); + //when, then + assertThat(updateRequestTypeDetector.isKur(certificateData1, certificateData2)).isTrue(); + } + + @ParameterizedTest + @MethodSource("notEqualSubjectParameters") + void shouldNotBeKurDifferentSubjectData(String subject1, String subject2) { + //given + final CertificateData certificateData1 = new CertificateData(new X500Name(subject1), null); + final CertificateData certificateData2 = new CertificateData(new X500Name(subject2), null); + //when, then + assertThat(updateRequestTypeDetector.isKur(certificateData1, certificateData2)).isFalse(); + } + + @Test + void shouldBeKurWhenEqualSans() { + //given + final GeneralName[] sans1 = new GeneralName[]{new GeneralName(GeneralName.dNSName, DNS_NAME)}; + final GeneralName[] sans2 = new GeneralName[]{new GeneralName(GeneralName.dNSName, DNS_NAME)}; + final CertificateData certificateData1 = new CertificateData(new X500Name(SUBJECT), sans1); + final CertificateData certificateData2 = new CertificateData(new X500Name(SUBJECT), sans2); + //when, then + assertThat(updateRequestTypeDetector.isKur(certificateData1, certificateData2)).isTrue(); + } + + @Test + void shouldNotBeKurWhenNotEqualSans() { + //given + final GeneralName[] sans1 = new GeneralName[]{new GeneralName(GeneralName.dNSName, DNS_NAME)}; + final GeneralName[] sans2 = new GeneralName[]{new GeneralName(GeneralName.dNSName, OTHER_DNS_NAME)}; + final CertificateData certificateData1 = new CertificateData(new X500Name(SUBJECT), sans1); + final CertificateData certificateData2 = new CertificateData(new X500Name(SUBJECT), sans2); + //when, then + assertThat(updateRequestTypeDetector.isKur(certificateData1, certificateData2)).isFalse(); + } + + @Test + void shouldBeKurWhenEqualSansIgnoringOrder() { + //given + GeneralName[] sans1 = new GeneralName[]{ + new GeneralName(GeneralName.dNSName, DNS_NAME), + new GeneralName(GeneralName.dNSName, OTHER_DNS_NAME) + }; + GeneralName[] sans2 = new GeneralName[]{ + new GeneralName(GeneralName.dNSName, OTHER_DNS_NAME), + new GeneralName(GeneralName.dNSName, DNS_NAME) + }; + final CertificateData certificateData1 = new CertificateData(new X500Name(SUBJECT), sans1); + final CertificateData certificateData2 = new CertificateData(new X500Name(SUBJECT), sans2); + //when, then + assertThat(updateRequestTypeDetector.isKur(certificateData1, certificateData2)).isTrue(); + } +} diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/X509CertificateModelFactoryTest.java b/certService/src/test/java/org/onap/oom/certservice/certification/X509CertificateModelFactoryTest.java new file mode 100644 index 00000000..bad4887b --- /dev/null +++ b/certService/src/test/java/org/onap/oom/certservice/certification/X509CertificateModelFactoryTest.java @@ -0,0 +1,166 @@ +/* + * ============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 static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.GeneralName; +import org.junit.jupiter.api.Test; +import org.onap.oom.certservice.certification.exception.CertificateDecryptionException; +import org.onap.oom.certservice.certification.model.X509CertificateModel; + +class X509CertificateModelFactoryTest { + + private static final String ENCODED_CERTIFICATE_STRING = + "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVpekNDQXZPZ0F3SUJBZ0lVR0VwMkdaNlk4" + + "bnpEQTlDS2w1blVSSTdDVU44d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lURWpNQ0VHQ2dtU0pvbVQ4" + + "aXhrQVFFTUUyTXRNR3BpWm5FNGNXRXhabTh3ZDJ0dGJua3hGVEFUQmdOVgpCQU1NREUxaGJtRm5a" + + "VzFsYm5SRFFURWpNQ0VHQTFVRUNnd2FSVXBDUTBFZ1EyOXVkR0ZwYm1WeUlGRjFhV05yCmMzUmhj" + + "blF3SGhjTk1qRXdOakk1TURZMU1ESTFXaGNOTWpNd05qSTVNRFkxTURJMFdqQjNNUkV3RHdZRFZR" + + "UUQKREFodmJtRndMbTl5WnpFWk1CY0dBMVVFQ3d3UVRHbHVkWGd0Um05MWJtUmhkR2x2YmpFTk1B" + + "c0dBMVVFQ2d3RQpUMDVCVURFV01CUUdBMVVFQnd3TlUyRnVMVVp5WVc1amFYTmpiekVUTUJFR0Ex" + + "VUVDQXdLUTJGc2FXWnZjbTVwCllURUxNQWtHQTFVRUJoTUNWVk13Z2dFaU1BMEdDU3FHU0liM0RR" + + "RUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRREIKenZieXJyRWlhb0JqOGttYTJRbUMrVkxtbXRXRld5" + + "QUpnU3JZQTRreHV5cmpRQ1c0SnlGR3ZtemJZb1VGRkxPRgpoZnExOFZqVHMwY2JUeXNYOGNGU2Zr" + + "VjJFS0dFUkJhWm5aUlFzbzZTSUpOR2EzeE1lNUZIalJFeTM0TnAwNElICmpTUTQyZUlCZ2NOaUlh" + + "ZGE0amdFbklRUVlRSlNQUXRIa2ZPTUM2TyszUnBUL2VIdHZvNXVyUjE2TUZZMUs2c28KbldZaXRJ" + + "NVRwRUtSb3phdjZ6cVUvb3RIZ241alJMcnlqMElaeTBpamxCZlNLVHhyRmZacjNLb01EdWRWRWZV" + + "TQp0c3FFUjNwb2MxZ0ZrcW1DUkszOEJQTmlZN3Y1S0FUUkIrZldOK1A3NW13NDNkcng5ckltcCtK" + + "dHBPVXNESzhyCklCZDhvNGFmTnZyL1dyeWdCQjhyQWdNQkFBR2pnYVF3Z2FFd0RBWURWUjBUQVFI" + + "L0JBSXdBREFmQmdOVkhTTUUKR0RBV2dCUjlNMXFVblFNMENwSFV6MzRGNXNWVVVjSUR0akFZQmdO" + + "VkhSRUVFVEFQZ2cxMFpYTjBMbTl1WVhBdQpiM0puTUNjR0ExVWRKUVFnTUI0R0NDc0dBUVVGQndN" + + "Q0JnZ3JCZ0VGQlFjREJBWUlLd1lCQlFVSEF3RXdIUVlEClZSME9CQllFRkFmcWNVNnhHaThqemps" + + "UnVLUUJ0cVJjWGkrdU1BNEdBMVVkRHdFQi93UUVBd0lGNERBTkJna3EKaGtpRzl3MEJBUXNGQUFP" + + "Q0FZRUFBZHc3N3E3c2hLdFM4bERHY0ovWThkRWpqTlNsUnRVMTRFTUM1OWttS2VmdApSaTdkMG9D" + + "UVh0ZFJDdXQzeW1pekxWcVFrbVg2U3JHc2hwV1VzTnpUZElUalE2SkIyS09haUlXSUY2ME5TbGVX" + + "CjB2TG0zNkVtWTFFcksrektlN3R2R1daaFROVnpCWHRucStBTWZKYzQxdTJ1ZWxreDBMTmN6c1g5" + + "YUNhakxIMXYKNHo0WHNVbm05cWlYcG5FbTYzMmVtdUp5ajZOdDBKV1Z1TlRKVFBSbnFWWmY2S0tS" + + "ODN2OEp1VjBFZWZXZDVXVgpjRnNwTDBIM01LSlY3dWY3aGZsbG5JY1J0elhhNXBjdEJDYm9GU2hW" + + "a1JOYUFNUHBKZjBEQkxReG03ZEFXajVBCmhHMXJ3bVRtek02TnB3R0hXL0kxU0ZNbXRRaUYwUEFD" + + "ejFVbjZuRFcvUmYxaUhFb0dmOFlCTFAzMzJMSlNEdWcKUktuMGNNM1FUY3lVRXpDWnhTd0tKMm5n" + + "QzllRzlDMmQzWWhCNlp4dGwrZ1VJYTNBd3dQYnFyN1lSOVFrRDJFbwpkNExxRUg5em55QmZpN2sy" + + "WUN3UDZydGZTaTZDbHliWGU4ZUJjdU1FUzRUQVFmRks2RlZmNTh0R1FJeDA2STBPCjM0bmVtWndr" + + "TG9PQnpaa2VwYVF2Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"; + + private static final String ENCODED_CERTIFICATE_CHAIN_STRING = + "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVpekNDQXZPZ0F3SUJBZ0lVR0VwMkdaNlk4" + + "bnpEQTlDS2w1blVSSTdDVU44d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lURWpNQ0VHQ2dtU0pvbVQ4" + + "aXhrQVFFTUUyTXRNR3BpWm5FNGNXRXhabTh3ZDJ0dGJua3hGVEFUQmdOVgpCQU1NREUxaGJtRm5a" + + "VzFsYm5SRFFURWpNQ0VHQTFVRUNnd2FSVXBDUTBFZ1EyOXVkR0ZwYm1WeUlGRjFhV05yCmMzUmhj" + + "blF3SGhjTk1qRXdOakk1TURZMU1ESTFXaGNOTWpNd05qSTVNRFkxTURJMFdqQjNNUkV3RHdZRFZR" + + "UUQKREFodmJtRndMbTl5WnpFWk1CY0dBMVVFQ3d3UVRHbHVkWGd0Um05MWJtUmhkR2x2YmpFTk1B" + + "c0dBMVVFQ2d3RQpUMDVCVURFV01CUUdBMVVFQnd3TlUyRnVMVVp5WVc1amFYTmpiekVUTUJFR0Ex" + + "VUVDQXdLUTJGc2FXWnZjbTVwCllURUxNQWtHQTFVRUJoTUNWVk13Z2dFaU1BMEdDU3FHU0liM0RR" + + "RUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRREIKenZieXJyRWlhb0JqOGttYTJRbUMrVkxtbXRXRld5" + + "QUpnU3JZQTRreHV5cmpRQ1c0SnlGR3ZtemJZb1VGRkxPRgpoZnExOFZqVHMwY2JUeXNYOGNGU2Zr" + + "VjJFS0dFUkJhWm5aUlFzbzZTSUpOR2EzeE1lNUZIalJFeTM0TnAwNElICmpTUTQyZUlCZ2NOaUlh" + + "ZGE0amdFbklRUVlRSlNQUXRIa2ZPTUM2TyszUnBUL2VIdHZvNXVyUjE2TUZZMUs2c28KbldZaXRJ" + + "NVRwRUtSb3phdjZ6cVUvb3RIZ241alJMcnlqMElaeTBpamxCZlNLVHhyRmZacjNLb01EdWRWRWZV" + + "TQp0c3FFUjNwb2MxZ0ZrcW1DUkszOEJQTmlZN3Y1S0FUUkIrZldOK1A3NW13NDNkcng5ckltcCtK" + + "dHBPVXNESzhyCklCZDhvNGFmTnZyL1dyeWdCQjhyQWdNQkFBR2pnYVF3Z2FFd0RBWURWUjBUQVFI" + + "L0JBSXdBREFmQmdOVkhTTUUKR0RBV2dCUjlNMXFVblFNMENwSFV6MzRGNXNWVVVjSUR0akFZQmdO" + + "VkhSRUVFVEFQZ2cxMFpYTjBMbTl1WVhBdQpiM0puTUNjR0ExVWRKUVFnTUI0R0NDc0dBUVVGQndN" + + "Q0JnZ3JCZ0VGQlFjREJBWUlLd1lCQlFVSEF3RXdIUVlEClZSME9CQllFRkFmcWNVNnhHaThqemps" + + "UnVLUUJ0cVJjWGkrdU1BNEdBMVVkRHdFQi93UUVBd0lGNERBTkJna3EKaGtpRzl3MEJBUXNGQUFP" + + "Q0FZRUFBZHc3N3E3c2hLdFM4bERHY0ovWThkRWpqTlNsUnRVMTRFTUM1OWttS2VmdApSaTdkMG9D" + + "UVh0ZFJDdXQzeW1pekxWcVFrbVg2U3JHc2hwV1VzTnpUZElUalE2SkIyS09haUlXSUY2ME5TbGVX" + + "CjB2TG0zNkVtWTFFcksrektlN3R2R1daaFROVnpCWHRucStBTWZKYzQxdTJ1ZWxreDBMTmN6c1g5" + + "YUNhakxIMXYKNHo0WHNVbm05cWlYcG5FbTYzMmVtdUp5ajZOdDBKV1Z1TlRKVFBSbnFWWmY2S0tS" + + "ODN2OEp1VjBFZWZXZDVXVgpjRnNwTDBIM01LSlY3dWY3aGZsbG5JY1J0elhhNXBjdEJDYm9GU2hW" + + "a1JOYUFNUHBKZjBEQkxReG03ZEFXajVBCmhHMXJ3bVRtek02TnB3R0hXL0kxU0ZNbXRRaUYwUEFD" + + "ejFVbjZuRFcvUmYxaUhFb0dmOFlCTFAzMzJMSlNEdWcKUktuMGNNM1FUY3lVRXpDWnhTd0tKMm5n" + + "QzllRzlDMmQzWWhCNlp4dGwrZ1VJYTNBd3dQYnFyN1lSOVFrRDJFbwpkNExxRUg5em55QmZpN2sy" + + "WUN3UDZydGZTaTZDbHliWGU4ZUJjdU1FUzRUQVFmRks2RlZmNTh0R1FJeDA2STBPCjM0bmVtWndr" + + "TG9PQnpaa2VwYVF2Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJ" + + "Q0FURS0tLS0tCk1JSUVzekNDQXh1Z0F3SUJBZ0lVTk1lYzl0ZlJEU3FPQlJGaTFkWDd2RCsyVG9z" + + "d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lURWpNQ0VHQ2dtU0pvbVQ4aXhrQVFFTUUyTXRNR3BpWm5F" + + "NGNXRXhabTh3ZDJ0dGJua3hGVEFUQmdOVgpCQU1NREUxaGJtRm5aVzFsYm5SRFFURWpNQ0VHQTFV" + + "RUNnd2FSVXBDUTBFZ1EyOXVkR0ZwYm1WeUlGRjFhV05yCmMzUmhjblF3SGhjTk1qRXdOakk1TURZ" + + "ME9UQTFXaGNOTXpFd05qSTVNRFkwT1RBMFdqQmhNU013SVFZS0NaSW0KaVpQeUxHUUJBUXdUWXkw" + + "d2FtSm1jVGh4WVRGbWJ6QjNhMjF1ZVRFVk1CTUdBMVVFQXd3TVRXRnVZV2RsYldWdQpkRU5CTVNN" + + "d0lRWURWUVFLREJwRlNrSkRRU0JEYjI1MFlXbHVaWElnVVhWcFkydHpkR0Z5ZERDQ0FhSXdEUVlK" + + "CktvWklodmNOQVFFQkJRQURnZ0dQQURDQ0FZb0NnZ0dCQUtvRjduSzQzUDBaRi9tWUVCbU5GWENw" + + "MmZma2srcFoKS1hCdFRFY1UwZVZmQU5WMzRFNHZEcnFSc0k0U3RFdmt5NGxiWW1PUEx5SnVabnRk" + + "c1dyUC9rbi9kUENHWEEzQQovUE44WmNrUENBQVlwa0JuOFNsMVdxaW1UeTA3TStPM0UxOER0TnBO" + + "Sy9RNWVkWW0rRnFXU3BVWHY5NEMzbjZVCmVXKytWaWNlWWc0ZUFDMVBka01LZGV3VEdnWGYzK1lI" + + "Q1dySW9JeWozcDNCOUp4RDdXVVUzTEZ3UkdHWnljVU0KYnRla2FUZXhodDZ1N2JMeld0Ylg1ZHhw" + + "bTBuR1dZa05KVm1mN0pJOHErMGpZdUNDcXdjYXpTNHIyeko5K1BqVwoyclZ0TkdUdVE0RmQyMm1r" + + "c1RMK0FRbktJaW9jNEJadVcwTkM0emNPZ2Ztc2dRdnBsR2s1ZGlmY0RZeHU5c3hkClFGampMKzJ1" + + "UURaK0RMTWlkYXNHRGxEb3FSQXBnV0lnajFxZllOMVNNbXJFZkdKWjFud05WcTlmemswV2VHNEgK" + + "WmVBYjlnU3BxSk9LNlp6d0F0TTV5NlFxOXo4RC84U2hjS2JiN01waExiSnVGVFRyL1lWaE1QRVZE" + + "SHA5RGZMbApYbzhGbkJCRVplUE9FYmdPZk5XbzlhTkg4RlczcHc1Znd3SURBUUFCbzJNd1lUQVBC" + + "Z05WSFJNQkFmOEVCVEFECkFRSC9NQjhHQTFVZEl3UVlNQmFBRkgweldwU2RBelFLa2RUUGZnWG14" + + "VlJSd2dPMk1CMEdBMVVkRGdRV0JCUjkKTTFxVW5RTTBDcEhVejM0RjVzVlVVY0lEdGpBT0JnTlZI" + + "UThCQWY4RUJBTUNBWVl3RFFZSktvWklodmNOQVFFTApCUUFEZ2dHQkFLZUFSdHBweExodThZbms5" + + "RHJFWUFmZHVwb0pESWU0K0RHYlVyQ212LzlIcVozRWxSaHpYWWdqClJCSlgzSjR1eHdNcEZQZFdO" + + "Qk9nMWdzV2FQYkdYSGg4K1U0Y29HLzVjVm5abmYzRG1PelliVW5pYXU4eTFnclAKaWNyNTZLdDcr" + + "Q2tRMFIrWWxUdXBGM3M5WjlIZW5UaHA3YmQ5N3hZNXBFK2l3cG1hNjNmcHJhSFVBb01qQXZEYQpU" + + "S3ZRUDRZS3pJY1ZuamtEdzlqUUxyNGNxYTdaeU1EUVlNTTd5YUJZNkx0bDYxbU9xQ2l4Q2JMWStL" + + "MmlMV0lNCnRoT2grV3R0cXZRejFPc2x4VkV1cWZtak4zMHBhUy9xSWY4MjhLZHp4UEN6S0RnTVVP" + + "ZjdvTEZUa0JCcGVoWVkKYVd5SUFNd2hEa1grRXYzRXg4ZnRzRmJSUUdWOWMvcDJPUXd2TEdTOXdB" + + "cVUyM1pEckhaTTFla0J5RE5FZUVpUgpTSGRWOEtNSTJuQ0J0NlhUeFhTejkwME5EV0l4aXJET0Rp" + + "WmU5SGJJUm5hWlIzMEEyVCtTeElxYUpsNXZVQzYyCnlLbjNicnFUM1UyMlNlbmVpZ2w3bW81bWhL" + + "bE8wdHErc2lJK1Y0T3lORkhadnJHQUNaUTNxYUFUZlozYlN3RVcKYkg1QjRlbHRodz09Ci0tLS0t" + + "RU5EIENFUlRJRklDQVRFLS0tLS0K"; + + private static final String SUBJECT = "CN=onap.org,OU=Linux-Foundation,O=ONAP,L=San-Francisco,ST=California,C=US"; + private static final GeneralName GENERAL_NAME = new GeneralName(GeneralName.dNSName, "test.onap.org"); + + private final X509CertificateModelFactory factory = + new X509CertificateModelFactory(new PemStringToCertificateConverter(), new X509CertificateParser()); + + @Test + void shouldCorrectlyParseX509CertificateFromCertificate() + throws CertificateDecryptionException { + //given + StringBase64 base64EncodedCertificate = new StringBase64(ENCODED_CERTIFICATE_STRING); + //when + final X509CertificateModel certificateModel = factory.createCertificateModel(base64EncodedCertificate); + //then + assertThat(certificateModel.getCertificate()).isNotNull(); + assertThat(certificateModel.getSubjectData()).isEqualTo(new X500Name(SUBJECT)); + assertThat(certificateModel.getSans()).containsExactly(GENERAL_NAME); + } + + @Test + void shouldCorrectlyParseX509CertificateFromCertificateChain() + throws CertificateDecryptionException { + //given + StringBase64 base64EncodedCertificate = new StringBase64(ENCODED_CERTIFICATE_CHAIN_STRING); + //when + final X509CertificateModel certificateModel = factory.createCertificateModel(base64EncodedCertificate); + //then + assertThat(certificateModel.getCertificate()).isNotNull(); + assertThat(certificateModel.getSubjectData()).isEqualTo(new X500Name(SUBJECT)); + assertThat(certificateModel.getSans()).containsExactly(GENERAL_NAME); + } + + @Test + void shouldThrowExceptionWhenCertificateChainHasNoCertificates() { + //given + StringBase64 base64EncodedCertificate = new StringBase64(""); + //when, then + assertThatThrownBy(() -> factory.createCertificateModel(base64EncodedCertificate)) + .isInstanceOf(CertificateDecryptionException.class); + } +} diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/X509CertificateParserTest.java b/certService/src/test/java/org/onap/oom/certservice/certification/X509CertificateParserTest.java new file mode 100644 index 00000000..4629234e --- /dev/null +++ b/certService/src/test/java/org/onap/oom/certservice/certification/X509CertificateParserTest.java @@ -0,0 +1,84 @@ +/* + * ============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 static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.List; +import javax.security.auth.x500.X500Principal; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.GeneralName; +import org.junit.jupiter.api.Test; + +class X509CertificateParserTest { + + private static final String SUBJECT = "CN=onap.org,OU=Linux-Foundation,O=ONAP,L=San-Francisco,ST=California,C=US"; + + private final X509CertificateParser parser = new X509CertificateParser(); + + @Test + void getSubject_shouldReturnCorrectSubject() { + //given + X509Certificate certificate = mock(X509Certificate.class); + when(certificate.getSubjectX500Principal()) + .thenReturn(new X500Principal(SUBJECT)); + //when + final X500Name subject = parser.getSubject(certificate); + //then + assertThat(subject).isEqualTo(new X500Name(SUBJECT)); + } + + @Test + void getSans_shouldReturnCorrectSansArray() throws CertificateParsingException { + //given + X509Certificate certificate = mock(X509Certificate.class); + when(certificate.getSubjectAlternativeNames()) + .thenReturn(List.of( + List.of(GeneralName.dNSName, "test.onap.org"), + List.of(GeneralName.dNSName, "test2.onap.org"), + List.of(GeneralName.iPAddress, "127.0.0.1") + )); + //when + final GeneralName[] sans = parser.getSans(certificate); + //then + assertThat(sans).containsExactlyInAnyOrder( + new GeneralName(GeneralName.dNSName, "test.onap.org"), + new GeneralName(GeneralName.dNSName, "test2.onap.org"), + new GeneralName(GeneralName.iPAddress, "127.0.0.1") + ); + } + + @Test + void getSans_shouldReturnEmptyArrayWhenNoSans() throws CertificateParsingException { + //given + X509Certificate certificate = mock(X509Certificate.class); + when(certificate.getSubjectAlternativeNames()).thenReturn(null); + //when + final GeneralName[] sans = parser.getSans(certificate); + //then + assertThat(sans).isEmpty(); + } + +} diff --git a/certService/src/test/java/org/onap/oom/certservice/certification/model/CertificateDataTest.java b/certService/src/test/java/org/onap/oom/certservice/certification/model/CertificateDataTest.java new file mode 100644 index 00000000..e32ade8d --- /dev/null +++ b/certService/src/test/java/org/onap/oom/certservice/certification/model/CertificateDataTest.java @@ -0,0 +1,117 @@ +/* + * ============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 static org.assertj.core.api.Assertions.assertThat; + +import java.util.stream.Stream; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.GeneralName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class CertificateDataTest { + + private static final String SUBJECT = "CN=onap.org,OU=Linux-Foundation,O=ONAP,L=San-Francisco,ST=California,C=US"; + private static final String SUBJECT_CHANGED_ORDER = "ST=California,C=US,OU=Linux-Foundation,CN=onap.org,O=ONAP,L=San-Francisco"; + private static final String OTHER_SUBJECT = "CN=onap1.org,OU=Linux-Foundation,O=ONAP,L=San-Francisco,ST=California,C=US"; + private static final String DNS_NAME = "test.onap.org"; + private static final String OTHER_DNS_NAME = "test1.onap.org"; + + private static Stream equalSubjectParameters() { + return Stream.of( + Arguments.of(SUBJECT, SUBJECT), + Arguments.of(SUBJECT_CHANGED_ORDER, SUBJECT_CHANGED_ORDER), + Arguments.of(SUBJECT, SUBJECT_CHANGED_ORDER), + Arguments.of(SUBJECT_CHANGED_ORDER, SUBJECT) + ); + } + + private static Stream notEqualSubjectParameters() { + return Stream.of( + Arguments.of(SUBJECT, OTHER_SUBJECT), + Arguments.of(OTHER_SUBJECT, SUBJECT), + Arguments.of(SUBJECT_CHANGED_ORDER, OTHER_SUBJECT), + Arguments.of(OTHER_SUBJECT, SUBJECT_CHANGED_ORDER) + ); + } + + @ParameterizedTest + @MethodSource("equalSubjectParameters") + void shouldAcceptSameSubjectData(String subject1, String subject2) { + //given + final CertificateData certificateData1 = new CertificateData(new X500Name(subject1), null); + final CertificateData certificateData2 = new CertificateData(new X500Name(subject2), null); + //when, then + assertThat(certificateData1).isEqualTo(certificateData2); + } + + @ParameterizedTest + @MethodSource("notEqualSubjectParameters") + void shouldRejectDifferentSubjectData(String subject1, String subject2) { + //given + final CertificateData certificateData1 = new CertificateData(new X500Name(subject1), null); + final CertificateData certificateData2 = new CertificateData(new X500Name(subject2), null); + //when, then + assertThat(certificateData1).isNotEqualTo(certificateData2); + } + + @Test + void shouldAcceptEqualSans() { + //given + final GeneralName[] sans1 = new GeneralName[]{new GeneralName(GeneralName.dNSName, DNS_NAME)}; + final GeneralName[] sans2 = new GeneralName[]{new GeneralName(GeneralName.dNSName, DNS_NAME)}; + final CertificateData certificateData1 = new CertificateData(new X500Name(SUBJECT), sans1); + final CertificateData certificateData2 = new CertificateData(new X500Name(SUBJECT), sans2); + //when, then + assertThat(certificateData1).isEqualTo(certificateData2); + } + + @Test + void shouldRejectNotEqualSans() { + //given + final GeneralName[] sans1 = new GeneralName[]{new GeneralName(GeneralName.dNSName, DNS_NAME)}; + final GeneralName[] sans2 = new GeneralName[]{new GeneralName(GeneralName.dNSName, OTHER_DNS_NAME)}; + final CertificateData certificateData1 = new CertificateData(new X500Name(SUBJECT), sans1); + final CertificateData certificateData2 = new CertificateData(new X500Name(SUBJECT), sans2); + //when, then + assertThat(certificateData1).isNotEqualTo(certificateData2); + } + + @Test + void shouldAcceptEqualSansIgnoringOrder() { + //given + GeneralName[] sans1 = new GeneralName[]{ + new GeneralName(GeneralName.dNSName, DNS_NAME), + new GeneralName(GeneralName.dNSName, OTHER_DNS_NAME) + }; + GeneralName[] sans2 = new GeneralName[]{ + new GeneralName(GeneralName.dNSName, OTHER_DNS_NAME), + new GeneralName(GeneralName.dNSName, DNS_NAME) + }; + final CertificateData certificateData1 = new CertificateData(new X500Name(SUBJECT), sans1); + final CertificateData certificateData2 = new CertificateData(new X500Name(SUBJECT), sans2); + //when, then + assertThat(certificateData1).isEqualTo(certificateData2); + } +} -- cgit 1.2.3-korg