From 06f7465cebf967f6c1ffd9970b05158c00aa5ff1 Mon Sep 17 00:00:00 2001 From: Bartosz Gardziejewski Date: Thu, 13 Feb 2020 14:55:21 +0100 Subject: Improve exception flow Issue-ID: AAF-995 Signed-off-by: Bartosz Gardziejewski Change-Id: I4d690fbe27364bc50b97ab42e64e610566d93ca0 --- .../aaf/certservice/api/CertificationService.java | 40 ++++-------- .../certservice/certification/CsrModelFactory.java | 42 ++++++++---- .../PKCS10CertificationRequestFactory.java | 38 +++++++++++ .../certification/PemObjectFactory.java | 9 ++- .../CertificationExceptionController.java | 56 ++++++++++++++++ .../exceptions/CsrDecryptionException.java | 3 + .../exceptions/DecryptionException.java | 3 + .../exceptions/KeyDecryptionException.java | 30 +++++++++ .../exceptions/PemDecryptionException.java | 28 -------- .../certservice/api/CertificationServiceTest.java | 42 ++++++------ .../certification/CsrModelFactoryTest.java | 24 ++++++- .../certification/PemObjectFactoryTest.java | 18 ++++-- .../aaf/certservice/certification/TestUtils.java | 6 +- .../CertificationExceptionControllerTest.java | 74 ++++++++++++++++++++++ .../certification/model/CsrModelTest.java | 40 ++++++++---- 15 files changed, 330 insertions(+), 123 deletions(-) create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/PKCS10CertificationRequestFactory.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/CertificationExceptionController.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/KeyDecryptionException.java delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/PemDecryptionException.java create mode 100644 certService/src/test/java/org/onap/aaf/certservice/certification/exception/CertificationExceptionControllerTest.java (limited to 'certService') diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/CertificationService.java b/certService/src/main/java/org/onap/aaf/certservice/api/CertificationService.java index 75fc0f52..d1a4a17a 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/CertificationService.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/CertificationService.java @@ -24,11 +24,9 @@ import com.google.gson.Gson; import org.onap.aaf.certservice.certification.CertificationModelFactory; import org.onap.aaf.certservice.certification.CsrModelFactory; import org.onap.aaf.certservice.certification.CsrModelFactory.StringBase64; -import org.onap.aaf.certservice.certification.exceptions.CsrDecryptionException; -import org.onap.aaf.certservice.certification.exceptions.PemDecryptionException; +import org.onap.aaf.certservice.certification.exceptions.DecryptionException; import org.onap.aaf.certservice.certification.model.CertificationModel; import org.onap.aaf.certservice.certification.model.CsrModel; -import org.onap.aaf.certservice.certification.model.ErrorResponseModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -68,35 +66,19 @@ public class CertificationService { @PathVariable String caName, @RequestHeader("CSR") String encodedCsr, @RequestHeader("PK") String encodedPrivateKey - ) { + ) throws DecryptionException { + caName = caName.replaceAll("[\n|\r|\t]", "_"); LOGGER.info("Received certificate signing request for CA named: {}", caName); + CsrModel csrModel = csrModelFactory.createCsrModel( + new StringBase64(encodedCsr), + new StringBase64(encodedPrivateKey) + ); + LOGGER.debug("Received CSR meta data: \n{}", csrModel); + CertificationModel certificationModel = certificationModelFactory + .createCertificationModel(csrModel,caName); + return new ResponseEntity<>(new Gson().toJson(certificationModel), HttpStatus.OK); - try { - CsrModel csrModel = csrModelFactory.createCsrModel( - new StringBase64(encodedCsr), - new StringBase64(encodedPrivateKey) - ); - LOGGER.debug("Received CSR meta data: \n{}", csrModel); - CertificationModel certificationModel = certificationModelFactory - .createCertificationModel(csrModel,caName); - return new ResponseEntity<>( - new Gson().toJson(certificationModel), - HttpStatus.OK); - } catch (CsrDecryptionException e) { - LOGGER.error("Exception occurred during decoding certificate sign request:", e); - return getErrorResponseEntity("Wrong certificate signing request (CSR) format"); - } catch (PemDecryptionException e) { - LOGGER.error("Exception occurred during decoding key:", e); - return getErrorResponseEntity("Wrong key (PK) format"); - } - } - - private ResponseEntity getErrorResponseEntity(String errorMessage) { - ErrorResponseModel errorResponse = new ErrorResponseModel(errorMessage); - return new ResponseEntity<>( - new Gson().toJson(errorResponse), - HttpStatus.BAD_REQUEST); } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/CsrModelFactory.java b/certService/src/main/java/org/onap/aaf/certservice/certification/CsrModelFactory.java index c1262e1e..6794bd6b 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/CsrModelFactory.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/CsrModelFactory.java @@ -20,13 +20,13 @@ package org.onap.aaf.certservice.certification; -import java.io.IOException; import java.util.Base64; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.util.io.pem.PemObject; import org.onap.aaf.certservice.certification.exceptions.CsrDecryptionException; -import org.onap.aaf.certservice.certification.exceptions.PemDecryptionException; +import org.onap.aaf.certservice.certification.exceptions.DecryptionException; +import org.onap.aaf.certservice.certification.exceptions.KeyDecryptionException; import org.onap.aaf.certservice.certification.model.CsrModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,22 +37,35 @@ import org.springframework.stereotype.Service; public class CsrModelFactory { private static final Logger LOGGER = LoggerFactory.getLogger(CsrModelFactory.class); - private final PemObjectFactory pemObjectFactory = new PemObjectFactory(); + private final PemObjectFactory pemObjectFactory + = new PemObjectFactory(); + private final PKCS10CertificationRequestFactory certificationRequestFactory + = new PKCS10CertificationRequestFactory(); + public CsrModel createCsrModel(StringBase64 csr, StringBase64 privateKey) - throws CsrDecryptionException, PemDecryptionException { + throws DecryptionException { LOGGER.debug("Decoded CSR: \n{}", csr); + PKCS10CertificationRequest decodedCsr = decodeCsr(csr); + PemObject decodedPrivateKey = decodePrivateKey(privateKey); + return new CsrModel(decodedCsr, decodedPrivateKey); + } - try { - PemObject pemObject = pemObjectFactory.createPemObject(csr.asString()); - PKCS10CertificationRequest decodedCsr = new PKCS10CertificationRequest( - pemObject.getContent() - ); - PemObject decodedPrivateKey = pemObjectFactory.createPemObject(privateKey.asString()); - return new CsrModel(decodedCsr, decodedPrivateKey); - } catch (IOException e) { - throw new CsrDecryptionException("Incorrect CSR, decryption failed", e); - } + private PemObject decodePrivateKey(StringBase64 privateKey) + throws KeyDecryptionException { + return pemObjectFactory.createPemObject(privateKey.asString()).orElseThrow( + () -> new KeyDecryptionException("Incorrect Key, decryption failed") + ); + } + + private PKCS10CertificationRequest decodeCsr(StringBase64 csr) + throws CsrDecryptionException { + return pemObjectFactory.createPemObject(csr.asString()) + .flatMap( + certificationRequestFactory::createKCS10CertificationRequest + ).orElseThrow( + () -> new CsrDecryptionException("Incorrect CSR, decryption failed") + ); } public static class StringBase64 { @@ -67,6 +80,7 @@ public class CsrModelFactory { return new String(decoder.decode(value)); } } + } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/PKCS10CertificationRequestFactory.java b/certService/src/main/java/org/onap/aaf/certservice/certification/PKCS10CertificationRequestFactory.java new file mode 100644 index 00000000..8f89de2f --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/PKCS10CertificationRequestFactory.java @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.certification; + +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.util.io.pem.PemObject; + +import java.io.IOException; +import java.util.Optional; + +public class PKCS10CertificationRequestFactory { + + public Optional createKCS10CertificationRequest(PemObject pemObject) { + try { + return Optional.of(new PKCS10CertificationRequest(pemObject.getContent())); + } catch (IOException e) { + return Optional.empty(); + } + } +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/PemObjectFactory.java b/certService/src/main/java/org/onap/aaf/certservice/certification/PemObjectFactory.java index 61ea0aaf..514101b9 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/PemObjectFactory.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/PemObjectFactory.java @@ -22,22 +22,21 @@ package org.onap.aaf.certservice.certification; import java.io.IOException; import java.io.StringReader; +import java.util.Optional; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; -import org.onap.aaf.certservice.certification.exceptions.PemDecryptionException; - public class PemObjectFactory { - public PemObject createPemObject(String pem) throws PemDecryptionException { + public Optional createPemObject(String pem) { try (StringReader stringReader = new StringReader(pem); PemReader pemReader = new PemReader(stringReader)) { - return pemReader.readPemObject(); + return Optional.ofNullable(pemReader.readPemObject()); } catch (IOException e) { - throw new PemDecryptionException("Unable to create PEM", e); + return Optional.empty(); } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/CertificationExceptionController.java b/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/CertificationExceptionController.java new file mode 100644 index 00000000..7d2c43ed --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/CertificationExceptionController.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.certification.exceptions; + +import com.google.gson.Gson; +import org.onap.aaf.certservice.certification.model.ErrorResponseModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class CertificationExceptionController { + + private static final Logger LOGGER = LoggerFactory.getLogger(CertificationExceptionController.class); + + @ExceptionHandler(value = CsrDecryptionException.class) + public ResponseEntity handle(CsrDecryptionException exception) { + LOGGER.error("Exception occurred during decoding certificate sign request:", exception); + return getErrorResponseEntity("Wrong certificate signing request (CSR) format"); + } + + @ExceptionHandler(value = KeyDecryptionException.class) + public ResponseEntity handle(KeyDecryptionException exception) { + LOGGER.error("Exception occurred during decoding key:", exception); + return getErrorResponseEntity("Wrong key (PK) format"); + } + + private ResponseEntity getErrorResponseEntity(String errorMessage) { + ErrorResponseModel errorResponse = new ErrorResponseModel(errorMessage); + return new ResponseEntity<>( + new Gson().toJson(errorResponse), + HttpStatus.BAD_REQUEST + ); + } +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/CsrDecryptionException.java b/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/CsrDecryptionException.java index 2f3f3659..929fbdb6 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/CsrDecryptionException.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/CsrDecryptionException.java @@ -24,4 +24,7 @@ public class CsrDecryptionException extends DecryptionException { public CsrDecryptionException(String message, Throwable cause) { super(message, cause); } + public CsrDecryptionException(String message) { + super(message); + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/DecryptionException.java b/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/DecryptionException.java index 67249cd5..8f5f48e6 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/DecryptionException.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/DecryptionException.java @@ -24,4 +24,7 @@ public class DecryptionException extends Exception { public DecryptionException(String message, Throwable cause) { super(message, cause); } + public DecryptionException(String message) { + super(message); + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/KeyDecryptionException.java b/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/KeyDecryptionException.java new file mode 100644 index 00000000..15d53935 --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/KeyDecryptionException.java @@ -0,0 +1,30 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.certification.exceptions; + +public class KeyDecryptionException extends DecryptionException { + public KeyDecryptionException(String message, Throwable cause) { + super(message, cause); + } + public KeyDecryptionException(String message) { + super(message); + } +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/PemDecryptionException.java b/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/PemDecryptionException.java deleted file mode 100644 index 564660e5..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/exceptions/PemDecryptionException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PROJECT - * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.aaf.certservice.certification.exceptions; - -public class PemDecryptionException extends DecryptionException { - public PemDecryptionException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/certService/src/test/java/org/onap/aaf/certservice/api/CertificationServiceTest.java b/certService/src/test/java/org/onap/aaf/certservice/api/CertificationServiceTest.java index 8ee88db5..0bb99d9f 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/api/CertificationServiceTest.java +++ b/certService/src/test/java/org/onap/aaf/certservice/api/CertificationServiceTest.java @@ -30,7 +30,7 @@ import org.onap.aaf.certservice.certification.CsrModelFactory; import org.onap.aaf.certservice.certification.CsrModelFactory.StringBase64; import org.onap.aaf.certservice.certification.exceptions.CsrDecryptionException; import org.onap.aaf.certservice.certification.exceptions.DecryptionException; -import org.onap.aaf.certservice.certification.exceptions.PemDecryptionException; +import org.onap.aaf.certservice.certification.exceptions.KeyDecryptionException; import org.onap.aaf.certservice.certification.model.CertificationModel; import org.onap.aaf.certservice.certification.model.CsrModel; import org.springframework.http.HttpStatus; @@ -41,7 +41,7 @@ import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -93,43 +93,41 @@ class CertificationServiceTest { } @Test - void shouldReturnBadRequestWhenCreatingCsrModelFails() throws DecryptionException { + void shouldThrowCsrDecryptionExceptionWhenCreatingCsrModelFails() throws DecryptionException { // given + String expectedMessage = "Incorrect CSR, decryption failed"; when(csrModelFactory.createCsrModel(any(StringBase64.class), any(StringBase64.class))) - .thenThrow(new CsrDecryptionException("CSR creation fail",new IOException())); + .thenThrow(new CsrDecryptionException(expectedMessage,new IOException())); // when - ResponseEntity testResponse = - certificationService.signCertificate("TestCa", "encryptedCSR", "encryptedPK"); + Exception exception = assertThrows( + CsrDecryptionException.class, () -> certificationService. + signCertificate("TestCa", "encryptedCSR", "encryptedPK") + ); - String expectedMessage = "Wrong certificate signing request (CSR) format"; + String actualMessage = exception.getMessage(); // then - assertEquals(HttpStatus.BAD_REQUEST, testResponse.getStatusCode()); - assertTrue( - testResponse.toString().contains(expectedMessage) - ); - + assertEquals(expectedMessage, actualMessage); } @Test - void shouldReturnBadRequestWhenCreatingPemModelFails() throws DecryptionException { + void shouldThrowPemDecryptionExceptionWhenCreatingPemModelFails() throws DecryptionException { // given + String expectedMessage = "Incorrect PEM, decryption failed"; when(csrModelFactory.createCsrModel(any(StringBase64.class), any(StringBase64.class))) - .thenThrow(new PemDecryptionException("PEM creation fail",new IOException())); + .thenThrow(new KeyDecryptionException(expectedMessage,new IOException())); // when - ResponseEntity testResponse = - certificationService.signCertificate("TestCa", "encryptedCSR", "encryptedPK"); + Exception exception = assertThrows( + KeyDecryptionException.class, () -> certificationService. + signCertificate("TestCa", "encryptedCSR", "encryptedPK") + ); - String expectedMessage = "Wrong key (PK) format"; + String actualMessage = exception.getMessage(); // then - assertEquals(HttpStatus.BAD_REQUEST, testResponse.getStatusCode()); - assertTrue( - testResponse.toString().contains(expectedMessage) - ); - + assertEquals(expectedMessage, actualMessage); } } diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/CsrModelFactoryTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/CsrModelFactoryTest.java index 065c7a0e..77594ed7 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/certification/CsrModelFactoryTest.java +++ b/certService/src/test/java/org/onap/aaf/certservice/certification/CsrModelFactoryTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test; import org.onap.aaf.certservice.certification.CsrModelFactory.StringBase64; import org.onap.aaf.certservice.certification.exceptions.CsrDecryptionException; import org.onap.aaf.certservice.certification.exceptions.DecryptionException; +import org.onap.aaf.certservice.certification.exceptions.KeyDecryptionException; import org.onap.aaf.certservice.certification.model.CsrModel; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -33,6 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.onap.aaf.certservice.certification.TestData.TEST_CSR; import static org.onap.aaf.certservice.certification.TestData.TEST_PK; import static org.onap.aaf.certservice.certification.TestData.TEST_WRONG_CSR; +import static org.onap.aaf.certservice.certification.TestData.TEST_WRONG_PEM; class CsrModelFactoryTest { @@ -66,9 +68,8 @@ class CsrModelFactoryTest { ); } - @Test - void shouldThrowCsrDecryptionExceptionWhenCsrAreIncorrect() { + void shouldThrowCsrDecryptionExceptionWhenCsrIsIncorrect() { // given String encoderPK = new String(Base64.encode(TEST_PK.getBytes())); String wrongCsr = new String(Base64.encode(TEST_WRONG_CSR.getBytes())); @@ -86,4 +87,23 @@ class CsrModelFactoryTest { assertTrue(actualMessage.contains(expectedMessage)); } + @Test + void shouldThrowKeyDecryptionExceptionWhenKeyIsIncorrect() { + // given + String encoderPK = new String(Base64.encode(TEST_WRONG_PEM.getBytes())); + String wrongCsr = new String(Base64.encode(TEST_CSR.getBytes())); + + // when + Exception exception = assertThrows( + KeyDecryptionException.class, () -> csrModelFactory + .createCsrModel(new StringBase64(wrongCsr), new StringBase64(encoderPK)) + ); + + String expectedMessage = "Incorrect Key, decryption failed"; + String actualMessage = exception.getMessage(); + + // then + assertTrue(actualMessage.contains(expectedMessage)); + } + } diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/PemObjectFactoryTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/PemObjectFactoryTest.java index 479c375b..0b70475c 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/certification/PemObjectFactoryTest.java +++ b/certService/src/test/java/org/onap/aaf/certservice/certification/PemObjectFactoryTest.java @@ -23,8 +23,8 @@ package org.onap.aaf.certservice.certification; import org.bouncycastle.util.io.pem.PemObject; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.onap.aaf.certservice.certification.exceptions.CsrDecryptionException; -import org.onap.aaf.certservice.certification.exceptions.PemDecryptionException; +import org.onap.aaf.certservice.certification.exceptions.DecryptionException; +import org.onap.aaf.certservice.certification.exceptions.KeyDecryptionException; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -45,9 +45,11 @@ class PemObjectFactoryTest { } @Test - void shouldTransformStringInToPemObjectAndBackToString() throws PemDecryptionException { + void shouldTransformStringInToPemObjectAndBackToString() throws DecryptionException { // when - PemObject pemObject = pemObjectFactory.createPemObject(TEST_PEM); + PemObject pemObject = pemObjectFactory.createPemObject(TEST_PEM).orElseThrow( + () -> new DecryptionException("Pem decryption failed") + ); String parsedPemObject = pemObjectToString(pemObject); // then @@ -56,12 +58,16 @@ class PemObjectFactoryTest { @Test void shouldThrowExceptionWhenParsingPemFailed() { + // given + String expectedMessage = "Unable to create PEM"; + // when Exception exception = assertThrows( - PemDecryptionException.class, () -> pemObjectFactory.createPemObject(TEST_WRONG_PEM) + DecryptionException.class, () -> pemObjectFactory.createPemObject(TEST_WRONG_PEM).orElseThrow( + () -> new DecryptionException(expectedMessage) + ) ); - String expectedMessage = "Unable to create PEM"; String actualMessage = exception.getMessage(); // then diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/TestUtils.java b/certService/src/test/java/org/onap/aaf/certservice/certification/TestUtils.java index c2824c80..39554417 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/certification/TestUtils.java +++ b/certService/src/test/java/org/onap/aaf/certservice/certification/TestUtils.java @@ -22,7 +22,7 @@ package org.onap.aaf.certservice.certification; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; -import org.onap.aaf.certservice.certification.exceptions.PemDecryptionException; +import org.onap.aaf.certservice.certification.exceptions.KeyDecryptionException; import java.io.IOException; import java.io.StringWriter; @@ -33,7 +33,7 @@ public final class TestUtils { private TestUtils() { } - public static String pemObjectToString(PemObject pemObject) throws PemDecryptionException { + public static String pemObjectToString(PemObject pemObject) throws KeyDecryptionException { try (StringWriter output = new StringWriter()) { PemWriter pemWriter = new PemWriter(output); pemWriter.writeObject(pemObject); @@ -41,7 +41,7 @@ public final class TestUtils { return output.getBuffer().toString(); } catch (IOException e) { - throw new PemDecryptionException("Writing PAM Object to string failed", e); + throw new KeyDecryptionException("Writing PAM Object to string failed", e); } } } diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/exception/CertificationExceptionControllerTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/exception/CertificationExceptionControllerTest.java new file mode 100644 index 00000000..58e59f45 --- /dev/null +++ b/certService/src/test/java/org/onap/aaf/certservice/certification/exception/CertificationExceptionControllerTest.java @@ -0,0 +1,74 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.certification.exception; + +import com.google.gson.Gson; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.aaf.certservice.certification.exceptions.CertificationExceptionController; +import org.onap.aaf.certservice.certification.exceptions.CsrDecryptionException; +import org.onap.aaf.certservice.certification.exceptions.KeyDecryptionException; +import org.onap.aaf.certservice.certification.model.ErrorResponseModel; +import org.springframework.http.ResponseEntity; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class CertificationExceptionControllerTest { + + private CertificationExceptionController certificationExceptionController; + + @BeforeEach + void setUp() { + certificationExceptionController = + new CertificationExceptionController(); + } + + @Test + void shouldReturnResponseEntityWithAppropriateErrorMessageWhenGivenCsrDecryptionException() { + // given + String expectedMessage = "Wrong certificate signing request (CSR) format"; + CsrDecryptionException csrDecryptionException = new CsrDecryptionException("test csr exception"); + + // when + ResponseEntity responseEntity = certificationExceptionController.handle(csrDecryptionException); + + ErrorResponseModel response = new Gson().fromJson(responseEntity.getBody(), ErrorResponseModel.class); + + // then + assertEquals(expectedMessage, response.getErrorMessage()); + } + + @Test + void shouldReturnResponseEntityWithAppropriateErrorMessageWhenGivenKeyDecryptionException() { + // given + String expectedMessage = "Wrong key (PK) format"; + KeyDecryptionException csrDecryptionException = new KeyDecryptionException("test pk exception"); + + // when + ResponseEntity responseEntity = certificationExceptionController.handle(csrDecryptionException); + + ErrorResponseModel response = new Gson().fromJson(responseEntity.getBody(), ErrorResponseModel.class); + + // then + assertEquals(expectedMessage, response.getErrorMessage()); + } + +} diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/model/CsrModelTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/model/CsrModelTest.java index 9d748150..7df785d2 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/certification/model/CsrModelTest.java +++ b/certService/src/test/java/org/onap/aaf/certservice/certification/model/CsrModelTest.java @@ -24,10 +24,11 @@ import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.util.io.pem.PemObject; import org.junit.jupiter.api.Test; +import org.onap.aaf.certservice.certification.PKCS10CertificationRequestFactory; import org.onap.aaf.certservice.certification.PemObjectFactory; import org.onap.aaf.certservice.certification.exceptions.CsrDecryptionException; import org.onap.aaf.certservice.certification.exceptions.DecryptionException; -import org.onap.aaf.certservice.certification.exceptions.PemDecryptionException; +import org.onap.aaf.certservice.certification.exceptions.KeyDecryptionException; import java.io.IOException; @@ -44,7 +45,10 @@ import static org.onap.aaf.certservice.certification.TestUtils.pemObjectToString class CsrModelTest { - + private final PKCS10CertificationRequestFactory certificationRequestFactory + = new PKCS10CertificationRequestFactory(); + private final PemObjectFactory pemObjectFactory + = new PemObjectFactory(); @Test void shouldByConstructedAndReturnProperFields() throws DecryptionException, IOException { // given @@ -70,7 +74,7 @@ class CsrModelTest { } @Test - void shouldThrowExceptionWhenKeyIsNotCorrect() throws PemDecryptionException ,IOException { + void shouldThrowExceptionWhenPublicKeyIsNotCorrect() throws KeyDecryptionException, IOException { // given PemObjectFactory pemObjectFactory = new PemObjectFactory(); PKCS10CertificationRequest testCsr = mock(PKCS10CertificationRequest.class); @@ -79,7 +83,9 @@ class CsrModelTest { .thenReturn(wrongKryInfo); when(wrongKryInfo.getEncoded()) .thenThrow(new IOException()); - PemObject testPrivateKey = pemObjectFactory.createPemObject(TEST_PK); + PemObject testPrivateKey = pemObjectFactory.createPemObject(TEST_PK).orElseThrow( + () -> new KeyDecryptionException("Private key decoding fail") + ); CsrModel csrModel = new CsrModel(testCsr, testPrivateKey); // when @@ -95,20 +101,26 @@ class CsrModelTest { assertTrue(actualMessage.contains(expectedMessage)); } - private CsrModel generateTestCsrModel() throws PemDecryptionException, IOException { - PemObjectFactory pemObjectFactory = new PemObjectFactory(); - PKCS10CertificationRequest testCsr = new PKCS10CertificationRequest( - pemObjectFactory.createPemObject(TEST_CSR).getContent() + private CsrModel generateTestCsrModel() throws DecryptionException { + PemObject testPrivateKey = pemObjectFactory.createPemObject(TEST_PK).orElseThrow( + () -> new DecryptionException("Incorrect Private Key, decryption failed") ); - PemObject testPrivateKey = pemObjectFactory.createPemObject(TEST_PK); + PKCS10CertificationRequest testCsr = generateTestCertificationRequest(); return new CsrModel(testCsr, testPrivateKey); } - private PemObject generateTestPublicKey() throws PemDecryptionException, IOException { - PemObjectFactory pemObjectFactory = new PemObjectFactory(); - PKCS10CertificationRequest testCsr = new PKCS10CertificationRequest( - pemObjectFactory.createPemObject(TEST_CSR).getContent() - ); + private PemObject generateTestPublicKey() throws DecryptionException, IOException { + PKCS10CertificationRequest testCsr = generateTestCertificationRequest(); return new PemObject("PUBLIC KEY", testCsr.getSubjectPublicKeyInfo().getEncoded()); } + + private PKCS10CertificationRequest generateTestCertificationRequest() throws DecryptionException { + return pemObjectFactory.createPemObject(TEST_CSR) + .flatMap( + certificationRequestFactory::createKCS10CertificationRequest + ).orElseThrow( + () -> new DecryptionException("Incorrect CSR, decryption failed") + ); + } + } -- cgit 1.2.3-korg