diff options
Diffstat (limited to 'certService/src/main')
19 files changed, 314 insertions, 446 deletions
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 9f877788..8e2a378e 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,12 +27,12 @@ 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.CertificationModelFactory; +import org.onap.oom.certservice.certification.CertificationResponseModelFactory; import org.onap.oom.certservice.certification.exception.CertificateDecryptionException; import org.onap.oom.certservice.certification.exception.DecryptionException; import org.onap.oom.certservice.certification.exception.ErrorResponseModel; import org.onap.oom.certservice.certification.model.CertificateUpdateModel; -import org.onap.oom.certservice.certification.model.CertificationModel; +import org.onap.oom.certservice.certification.model.CertificationResponseModel; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,11 +51,11 @@ public class CertificationController { private static final Logger LOGGER = LoggerFactory.getLogger(CertificationController.class); - private final CertificationModelFactory certificationModelFactory; + private final CertificationResponseModelFactory certificationResponseModelFactory; @Autowired - CertificationController(CertificationModelFactory certificationModelFactory) { - this.certificationModelFactory = certificationModelFactory; + CertificationController(CertificationResponseModelFactory certificationResponseModelFactory) { + this.certificationResponseModelFactory = certificationResponseModelFactory; } /** @@ -80,7 +80,7 @@ public class CertificationController { summary = "sign certificate", description = "Web endpoint for requesting certificate signing. Used by system components to gain certificate signed by CA.", tags = {"CertificationService"}) - public ResponseEntity<CertificationModel> signCertificate( + public ResponseEntity<CertificationResponseModel> signCertificate( @Parameter(description = "Name of certification authority that will sign CSR.") @PathVariable String caName, @Parameter(description = "Certificate signing request in form of PEM object encoded in Base64 (with header and footer).") @@ -90,9 +90,9 @@ public class CertificationController { ) throws DecryptionException, CmpClientException { 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); + CertificationResponseModel certificationResponseModel = certificationResponseModelFactory + .provideCertificationModelFromInitialRequest(encodedCsr, encodedPrivateKey, caName); + return new ResponseEntity<>(certificationResponseModel, HttpStatus.OK); } /** @@ -106,7 +106,7 @@ public class CertificationController { * @return JSON containing trusted certificates and certificate chain */ @GetMapping(value = "v1/certificate-update/{caName}", produces = "application/json") - public ResponseEntity<CertificationModel> updateCertificate( + public ResponseEntity<CertificationResponseModel> updateCertificate( @PathVariable String caName, @RequestHeader("CSR") String encodedCsr, @RequestHeader("PK") String encodedPrivateKey, @@ -122,9 +122,9 @@ public class CertificationController { .setEncodedOldPrivateKey(encodedOldPrivateKey) .setCaName(caName) .build(); - CertificationModel certificationModel = certificationModelFactory - .createCertificationModel(certificateUpdateModel); - return new ResponseEntity<>(certificationModel, HttpStatus.OK); + CertificationResponseModel certificationResponseModel = certificationResponseModelFactory + .provideCertificationModelFromUpdateRequest(certificateUpdateModel); + return new ResponseEntity<>(certificationResponseModel, HttpStatus.OK); } private String replaceWhiteSpaceChars(String text) { diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/CertificateFactoryProvider.java b/certService/src/main/java/org/onap/oom/certservice/certification/CertificateFactoryProvider.java deleted file mode 100644 index 93fa4c21..00000000 --- a/certService/src/main/java/org/onap/oom/certservice/certification/CertificateFactoryProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Cert Service - * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.oom.certservice.certification; - -import java.io.InputStream; -import java.security.NoSuchProviderException; -import java.security.Security; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.springframework.stereotype.Component; - -@Component -public class CertificateFactoryProvider { - - static { - Security.addProvider(new BouncyCastleProvider()); - } - - X509Certificate generateCertificate(InputStream inStream) throws CertificateException, NoSuchProviderException { - return (X509Certificate) CertificateFactory.getInstance("X.509", "BC").generateCertificate(inStream); - } -} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/CertificationData.java b/certService/src/main/java/org/onap/oom/certservice/certification/CertificationData.java deleted file mode 100644 index 11e81807..00000000 --- a/certService/src/main/java/org/onap/oom/certservice/certification/CertificationData.java +++ /dev/null @@ -1,128 +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.oom.certservice.certification; - - -final class CertificationData { - - private CertificationData() { - } - - private static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n"; - private static final String END_CERTIFICATE = "-----END CERTIFICATE-----"; - - static final String EXTRA_CA_CERT = "" - + BEGIN_CERTIFICATE - + "MIIDvzCCAqcCFF5DejiyfoNfPiiMmBXulniBewBGMA0GCSqGSIb3DQEBCwUAMIGb\n" - + "MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu\n" - + "LUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwE\n" - + "T05BUDEVMBMGA1UEAwwMbmV3Lm9uYXAub3JnMR4wHAYJKoZIhvcNAQkBFg90ZXN0\n" - + "ZXJAb25hcC5vcmcwHhcNMjAwMjEyMDk1OTM3WhcNMjEwMjExMDk1OTM3WjCBmzEL\n" - + "MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbi1G\n" - + "cmFuY2lzY28xGTAXBgNVBAoMEExpbnV4LUZvdW5kYXRpb24xDTALBgNVBAsMBE9O\n" - + "QVAxFTATBgNVBAMMDG5ldy5vbmFwLm9yZzEeMBwGCSqGSIb3DQEJARYPdGVzdGVy\n" - + "QG9uYXAub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtF4FXeDV\n" - + "ng/inC/bTACmZnLC9IiC7PyG/vVbMxxN1bvQLRAwC/Hbl3i9zD68Vs/jPPr/SDr9\n" - + "2rgItdDdUY1V30Y3PT06F11XdEaRb+t++1NX0rDf1AqPaBZgnBmB86s1wbqHdJTr\n" - + "wEImDZ5xMPfP3fiWy/9Yw/U7iRMIi1/oI0lWuHJV0bn908shuJ6dvInpRCoDnoTX\n" - + "YP/FiDSZCFVewQcq4TigB7kRqZrDcPZWbSlqHklDMXRwbCxAiFSziuX6TBwru9Rn\n" - + "HhIeXVSgMU1ZSSopVbJGtQ4zSsU1nvTK5Bhc2UHGcAOZy1xTN5D9EEbTqh7l+Wtx\n" - + "y8ojkEXvFG8lVwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAE+bUphwHit78LK8sb\n" - + "OMjt4DiEu32KeSJOpYgPLeBeAIynaNsa7sQrpuxerGNTmQWIcw6olXI0J+OOwkik\n" - + "II7elrYtd5G1uALxXWdamNsaY0Du34moVL1YjexJ7qQ4oBUxg2tuY8NAQGDK+23I\n" - + "nCA+ZwzdTJo73TYS6sx64d/YLWkX4nHGUoMlF+xUH34csDyhpuTSzQhC2quB5N8z\n" - + "tSFdpe4z2jqx07qo2EBFxi03EQ8Q0ex6l421QM2gbs7cZQ66K0DkpPcF2+iHZnyx\n" - + "xq1lnlsWHklElF2bhyXTn3fPp5wtan00P8IolKx7CAWb92QjkW6M0RvTW/xuwIzh\n" - + "0rTO\n" - + END_CERTIFICATE; - - static final String CA_CERT = "" - + BEGIN_CERTIFICATE - + "MIIDtzCCAp8CFAwqQddh4/iyGfP8UZ3dpXlxfAN8MA0GCSqGSIb3DQEBCwUAMIGX\n" - + "MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu\n" - + "LUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwE\n" - + "T05BUDERMA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBv\n" - + "bmFwLm9yZzAeFw0yMDAyMTIwOTM0MjdaFw0yMTAyMTEwOTM0MjdaMIGXMQswCQYD\n" - + "VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuLUZyYW5j\n" - + "aXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwET05BUDER\n" - + "MA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBvbmFwLm9y\n" - + "ZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCFrnO7/eT6V+7XkPPd\n" - + "eiL/6xXreuegvit/1/jTVjG+3AOVcmTn2WXwXXRcQLvkWQfJVPoltsY8E3FqFRti\n" - + "797XjY6cdQJFVDyzNU0+Fb4vJL9FK5wSvnS6EFjBEn3JvXRlENorDCs/mfjkjJoa\n" - + "Dl74gXQEJYcg4nsTeNIj7cm3Q7VK3mZt1t7LSJJ+czxv69UJDuNJpmQ/2WOKyLZA\n" - + "gTtBJ+Hyol45/OLsrqwq1dAn9ZRWIFPvRt/XQYH9bI/6MtqSreRVUrdYCiTe/XpP\n" - + "B/OM6NEi2+p5QLi3Yi70CEbqP3HqUVbkzF+r7bwIb6M5/HxfqzLmGwLvD+6rYnUn\n" - + "Bm8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAhXoO65DXth2X/zFRNsCNpLwmDy7r\n" - + "PxT9ZAIZAzSxx3/aCYiuTrKP1JnqjkO+F2IbikrI4n6sKO49SKnRf9SWTFhd+5dX\n" - + "vxq5y7MaqxHAY9J7+Qzq33+COVFQnaF7ddel2NbyUVb2b9ZINNsaZkkPXui6DtQ7\n" - + "/Fb/1tmAGWd3hMp75G2thBSzs816JMKKa9WD+4VGATEs6OSll4sv2fOZEn+0mAD3\n" - + "9q9c+WtLGIudOwcHwzPb2njtNntQSCK/tVOqbY+vzhMY3JW+p9oSrLDSdGC+pAKK\n" - + "m/wB+2VPIYcsPMtIhHC4tgoSaiCqjXYptaOh4b8ye8CPBUCpX/AYYkN0Ow==\n" - + END_CERTIFICATE; - - static final String INTERMEDIATE_CERT = "" - + BEGIN_CERTIFICATE - + "MIIDqTCCApGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNVBAYTAlVT\n" - + "MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw\n" - + "FwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMREwDwYDVQQD\n" - + "DAhvbmFwLm9yZzEeMBwGCSqGSIb3DQEJARYPdGVzdGVyQG9uYXAub3JnMB4XDTIw\n" - + "MDIxMjA5NDAxMloXDTIyMTEwODA5NDAxMlowgYQxCzAJBgNVBAYTAlVTMRMwEQYD\n" - + "VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkwFwYDVQQK\n" - + "DBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQDDBVpbnRl\n" - + "cm1lZGlhdGUub25hcC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n" - + "AQC1oOYMZ6G+2DGDAizYnzdCNiogivlht1s4oqgem7fM1XFPxD2p31ATIibOdqr/\n" - + "gv1qemO9Q4r1xn6w1Ufq7T1K7PjnMzdSeTqZefurE2JM/HHx2QvW4TjMlz2ILgaD\n" - + "L1LN60kmMQSOi5VxKJpsrCQxbOsxhvefd212gny5AZMcjJe23kUd9OxUrtvpdLEv\n" - + "wI3vFEvT7oRUnEUg/XNz7qeg33vf1C39yMR+6O4s6oevgsEebVKjb+yOoS6zzGtz\n" - + "72wZjm07C54ZlO+4Uy+QAlMjRiU3mgWkKbkOy+4CvwehjhpTikdBs2DX39ZLGHhn\n" - + "L/0a2NYtGulp9XEqmTvRoI+PAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI\n" - + "hvcNAQELBQADggEBADcitdJ6YswiV8jAD9GK0gf3+zqcGegt4kt+79JXlXYbb1sY\n" - + "q3o6prcB7nSUoClgF2xUPCslFGpM0Er9FCSFElQM/ru0l/KVmJS6kSpwEHvsYIH3\n" - + "q5anta+Pyk8JSQWAAw+qrind0uBQMnhR8Tn13tgV+Kjvg/xlH/nZIEdN5YtLB1cA\n" - + "beVsZRyRfVL9DeZU8s/MZ5wC3kgcEp5A4m5lg7HyBxBdqhzFcDr6xiy6OGqW8Yep\n" - + "xrwfc8Fw8a/lOv4U+tBeGNKPQDYaL9hh+oM+qMkNXsHXDqdJsuEGJtU4i3Wcwzoc\n" - + "XGN5NWV//4bP+NFmwgcn7AYCdRvz04A8GU/0Cwg=\n" - + END_CERTIFICATE; - - static final String ENTITY_CERT = "" - + BEGIN_CERTIFICATE - + "MIIDjDCCAnSgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlVT\n" - + "MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw\n" - + "FwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQD\n" - + "DBVpbnRlcm1lZGlhdGUub25hcC5vcmcwHhcNMjAwMjEyMDk1MTI2WhcNMjIxMTA4\n" - + "MDk1MTI2WjB7MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG\n" - + "A1UEBwwNU2FuLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjEN\n" - + "MAsGA1UECwwET05BUDEVMBMGA1UEAwwMdmlkLm9uYXAub3JnMIIBIjANBgkqhkiG\n" - + "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+GIRzJzUOh0gtc+wzFJEdTnn+q5F10L0Yhr\n" - + "G1xKdjPieHIFGsoiXwcuCU8arNSqlz7ocx62KQRkcA8y6edlOAsYtdOEJvqEI9vc\n" - + "eyTB/HYsbzw3URPGch4AmibrQkKU9QvGwouHtHn4R2Ft2Y0tfEqv9hxj9v4njq4A\n" - + "EiDLAFLl5FmVyCZu/MtKngSgu1smcaFKTYySPMxytgJZexoa/ALZyyE0gRhsvwHm\n" - + "NLGCPt1bmE/PEGZybsCqliyTO0S56ncD55The7+D/UDS4kE1Wg0svlWon/YsE6QW\n" - + "B3oeJDX7Kr8ebDTIAErevIAD7Sm4ee5se2zxYrsYlj0MzHZtvwIDAQABoxAwDjAM\n" - + "BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvQ1pTvjON6vSlcJRKSY4r\n" - + "8q7L4/9ZaVXWJAjzEYJtPIqsgGiPWz0vGfgklowU6tZxp9zRZFXfMil+mPQSe+yo\n" - + "ULrZSQ/z48YHPueE/BNO/nT4aaVBEhPLR5aVwC7uQVX8H+m1V1UGT8lk9vdI9rej\n" - + "CI9l524sLCpdE4dFXiWK2XHEZ0Vfylk221u3IYEogVVA+UMX7BFPSsOnI2vtYK/i\n" - + "lwZtlri8LtTusNe4oiTkYyq+RSyDhtAswg8ANgvfHolhCHoLFj6w1IkG88UCmbwN\n" - + "d7BoGMy06y5MJxyXEZG0vR7eNeLey0TIh+rAszAFPsIQvrOHW+HuA+WLQAj1mhnm\n" - + END_CERTIFICATE; - -} diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/CertificationProvider.java b/certService/src/main/java/org/onap/oom/certservice/certification/CertificationProvider.java index 17e23e39..94e778e3 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/CertificationProvider.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/CertificationProvider.java @@ -24,9 +24,9 @@ import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator; import org.bouncycastle.util.io.pem.PemObjectGenerator; import org.bouncycastle.util.io.pem.PemWriter; import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server; -import org.onap.oom.certservice.certification.model.CertificateUpdateModel; -import org.onap.oom.certservice.certification.model.CertificationModel; +import org.onap.oom.certservice.certification.model.CertificationResponseModel; import org.onap.oom.certservice.certification.model.CsrModel; +import org.onap.oom.certservice.certification.model.OldCertificateModel; import org.onap.oom.certservice.cmpv2client.api.CmpClient; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel; @@ -53,24 +53,21 @@ public class CertificationProvider { this.cmpClient = cmpClient; } - public CertificationModel signCsr(CsrModel csrModel, Cmpv2Server server) + public CertificationResponseModel executeInitializationRequest(CsrModel csrModel, Cmpv2Server server) throws CmpClientException { - Cmpv2CertificationModel certificates = cmpClient.createCertificate(csrModel, server); - return new CertificationModel(convertFromX509CertificateListToPemList(certificates.getCertificateChain()), - convertFromX509CertificateListToPemList(certificates.getTrustedCertificates())); + Cmpv2CertificationModel certificates = cmpClient.executeInitializationRequest(csrModel, server); + return getCertificationResponseModel(certificates); } - public CertificationModel updateCertificate(CsrModel csrModel, Cmpv2Server cmpv2Server, - CertificateUpdateModel certificateUpdateModel) throws CmpClientException { - Cmpv2CertificationModel certificates = cmpClient.updateCertificate(csrModel, cmpv2Server, certificateUpdateModel); - return new CertificationModel(convertFromX509CertificateListToPemList(certificates.getCertificateChain()), - convertFromX509CertificateListToPemList(certificates.getTrustedCertificates())); + public CertificationResponseModel executeKeyUpdateRequest(CsrModel csrModel, Cmpv2Server cmpv2Server, + OldCertificateModel oldCertificateModel) throws CmpClientException { + Cmpv2CertificationModel certificates = cmpClient.executeKeyUpdateRequest(csrModel, cmpv2Server, oldCertificateModel); + return getCertificationResponseModel(certificates); } - public CertificationModel certificationRequest(CsrModel csrModel, Cmpv2Server cmpv2Server) throws CmpClientException { - Cmpv2CertificationModel certificates = cmpClient.certificationRequest(csrModel, cmpv2Server); - return new CertificationModel(convertFromX509CertificateListToPemList(certificates.getCertificateChain()), - convertFromX509CertificateListToPemList(certificates.getTrustedCertificates())); + public CertificationResponseModel executeCertificationRequest(CsrModel csrModel, Cmpv2Server cmpv2Server) throws CmpClientException { + Cmpv2CertificationModel certificates = cmpClient.executeCertificationRequest(csrModel, cmpv2Server); + return getCertificationResponseModel(certificates); } private static List<String> convertFromX509CertificateListToPemList(List<X509Certificate> certificates) { @@ -78,6 +75,12 @@ public class CertificationProvider { .collect(Collectors.toList()); } + private CertificationResponseModel getCertificationResponseModel(Cmpv2CertificationModel certificates) { + return new CertificationResponseModel( + convertFromX509CertificateListToPemList(certificates.getCertificateChain()), + convertFromX509CertificateListToPemList(certificates.getTrustedCertificates())); + } + private static String convertFromX509CertificateToPem(X509Certificate certificate) { StringWriter sw = new StringWriter(); try (PemWriter pw = new PemWriter(sw)) { diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/CertificationModelFactory.java b/certService/src/main/java/org/onap/oom/certservice/certification/CertificationResponseModelFactory.java index dddeb2d3..0e793bb0 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/CertificationModelFactory.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/CertificationResponseModelFactory.java @@ -22,12 +22,15 @@ 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.conversion.CsrModelFactory; +import org.onap.oom.certservice.certification.conversion.OldCertificateModelFactory; +import org.onap.oom.certservice.certification.conversion.StringBase64; import org.onap.oom.certservice.certification.exception.CertificateDecryptionException; import org.onap.oom.certservice.certification.exception.DecryptionException; import org.onap.oom.certservice.certification.model.CertificateUpdateModel; -import org.onap.oom.certservice.certification.model.CertificationModel; +import org.onap.oom.certservice.certification.model.CertificationResponseModel; import org.onap.oom.certservice.certification.model.CsrModel; -import org.onap.oom.certservice.certification.model.X509CertificateModel; +import org.onap.oom.certservice.certification.model.OldCertificateModel; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,31 +38,31 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service -public class CertificationModelFactory { +public class CertificationResponseModelFactory { - private static final Logger LOGGER = LoggerFactory.getLogger(CertificationModelFactory.class); + private static final Logger LOGGER = LoggerFactory.getLogger(CertificationResponseModelFactory.class); private final CsrModelFactory csrModelFactory; private final Cmpv2ServerProvider cmpv2ServerProvider; private final CertificationProvider certificationProvider; - private final X509CertificateModelFactory x509CertificateModelFactory; + private final OldCertificateModelFactory oldCertificateModelFactory; private final UpdateRequestTypeDetector updateRequestTypeDetector; @Autowired - CertificationModelFactory( + CertificationResponseModelFactory( CsrModelFactory csrModelFactory, Cmpv2ServerProvider cmpv2ServerProvider, CertificationProvider certificationProvider, - X509CertificateModelFactory x509CertificateModelFactory, + OldCertificateModelFactory oldCertificateModelFactory, UpdateRequestTypeDetector updateRequestTypeDetector) { this.cmpv2ServerProvider = cmpv2ServerProvider; this.csrModelFactory = csrModelFactory; this.certificationProvider = certificationProvider; - this.x509CertificateModelFactory = x509CertificateModelFactory; + this.oldCertificateModelFactory = oldCertificateModelFactory; this.updateRequestTypeDetector = updateRequestTypeDetector; } - public CertificationModel createCertificationModel(String encodedCsr, String encodedPrivateKey, String caName) + public CertificationResponseModel provideCertificationModelFromInitialRequest(String encodedCsr, String encodedPrivateKey, String caName) throws DecryptionException, CmpClientException { CsrModel csrModel = csrModelFactory.createCsrModel( new StringBase64(encodedCsr), @@ -72,10 +75,10 @@ public class CertificationModelFactory { LOGGER.info("Sending sign request for certification model for CA named: {}, and certificate signing request:\n{}", caName, csrModel); - return certificationProvider.signCsr(csrModel, cmpv2Server); + return certificationProvider.executeInitializationRequest(csrModel, cmpv2Server); } - public CertificationModel createCertificationModel(CertificateUpdateModel certificateUpdateModel) + public CertificationResponseModel provideCertificationModelFromUpdateRequest(CertificateUpdateModel certificateUpdateModel) throws DecryptionException, CmpClientException, CertificateDecryptionException { LOGGER.info("CSR: " + certificateUpdateModel.getEncodedCsr() + ", old cert: " + certificateUpdateModel.getEncodedOldCert() + @@ -84,8 +87,8 @@ public class CertificationModelFactory { new StringBase64(certificateUpdateModel.getEncodedCsr()), new StringBase64(certificateUpdateModel.getEncodedPrivateKey()) ); - final X509CertificateModel certificateModel = x509CertificateModelFactory.createCertificateModel( - new StringBase64(certificateUpdateModel.getEncodedOldCert())); + final OldCertificateModel certificateModel = oldCertificateModelFactory.createCertificateModel( + new StringBase64(certificateUpdateModel.getEncodedOldCert()), certificateUpdateModel.getEncodedOldPrivateKey()); Cmpv2Server cmpv2Server = cmpv2ServerProvider.getCmpv2Server(certificateUpdateModel.getCaName()); LOGGER.debug("Found server for given CA name: \n{}", cmpv2Server); @@ -95,11 +98,11 @@ public class CertificationModelFactory { if (updateRequestTypeDetector.isKur(csrModel.getCertificateData(), certificateModel.getCertificateData())) { LOGGER.info( "Certificate Signing Request and Old Certificate have the same parameters. Preparing Key Update Request"); - return certificationProvider.updateCertificate(csrModel, cmpv2Server, certificateUpdateModel); + return certificationProvider.executeKeyUpdateRequest(csrModel, cmpv2Server, certificateModel); } else { LOGGER.info( "Certificate Signing Request and Old Certificate have different parameters. Preparing Certification Request"); - return certificationProvider.certificationRequest(csrModel, cmpv2Server); + return certificationProvider.executeCertificationRequest(csrModel, cmpv2Server); } } } diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/CsrModelFactory.java b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/CsrModelFactory.java index 789773d6..e4ee4c10 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/CsrModelFactory.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/CsrModelFactory.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.certservice.certification; +package org.onap.oom.certservice.certification.conversion; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.util.io.pem.PemObject; diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateModelFactory.java b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/OldCertificateModelFactory.java index 17367ce7..f5c199f6 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateModelFactory.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/OldCertificateModelFactory.java @@ -18,49 +18,65 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.certservice.certification; +package org.onap.oom.certservice.certification.conversion; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; +import org.bouncycastle.util.io.pem.PemObject; +import org.onap.oom.certservice.certification.X509CertificateParser; import org.onap.oom.certservice.certification.exception.CertificateDecryptionException; +import org.onap.oom.certservice.certification.exception.KeyDecryptionException; import org.onap.oom.certservice.certification.exception.StringToCertificateConversionException; -import org.onap.oom.certservice.certification.model.X509CertificateModel; +import org.onap.oom.certservice.certification.model.OldCertificateModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service -public class X509CertificateModelFactory { +public class OldCertificateModelFactory { private static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n"; private static final String END_CERTIFICATE = "-----END CERTIFICATE-----\n"; + private static final PemObjectFactory PEM_OBJECT_FACTORY = new PemObjectFactory(); private final PemStringToCertificateConverter pemStringToCertificateConverter; private final X509CertificateParser x509CertificateParser; @Autowired - public X509CertificateModelFactory(PemStringToCertificateConverter pemStringToCertificateConverter, + public OldCertificateModelFactory(PemStringToCertificateConverter pemStringToCertificateConverter, X509CertificateParser x509CertificateParser) { this.pemStringToCertificateConverter = pemStringToCertificateConverter; this.x509CertificateParser = x509CertificateParser; } - public X509CertificateModel createCertificateModel(StringBase64 base64EncodedCertificate) + public OldCertificateModel createCertificateModel(StringBase64 base64EncodedCertificate, String encodedOldPrivateKey) throws CertificateDecryptionException { final String certificateString = base64EncodedCertificate.asString() .map(this::getFirstCertificateFromCertificateChain) .orElseThrow(() -> new CertificateDecryptionException("Incorrect certificate, decryption failed")); try { - final X509Certificate certificate = pemStringToCertificateConverter.convert(certificateString); - final X500Name subjectData = x509CertificateParser.getSubject(certificate); - final GeneralName[] sans = x509CertificateParser.getSans(certificate); - return new X509CertificateModel(certificate, subjectData, sans); + final X509Certificate x509Certificate = pemStringToCertificateConverter.convert(certificateString); + final X500Name subjectData = x509CertificateParser.getSubject(x509Certificate); + final GeneralName[] sans = x509CertificateParser.getSans(x509Certificate); + final Certificate certificate = new JcaX509CertificateHolder(x509Certificate).toASN1Structure(); + final PrivateKey oldPrivateKey = getOldPrivateKeyObject(encodedOldPrivateKey); + return new OldCertificateModel(certificate, subjectData, sans, oldPrivateKey); } catch (StringToCertificateConversionException e) { throw new CertificateDecryptionException("Cannot convert certificate", e); } catch (CertificateParsingException e) { throw new CertificateDecryptionException("Cannot read Subject Alternative Names from certificate"); + } catch (NoSuchAlgorithmException | KeyDecryptionException | CertificateEncodingException | InvalidKeySpecException e) { + throw new CertificateDecryptionException("Cannot convert certificate or key", e); } } @@ -74,4 +90,18 @@ public class X509CertificateModelFactory { private boolean doesNotContainCertificates(String certificateChain) { return !(certificateChain.contains(BEGIN_CERTIFICATE) && certificateChain.contains(END_CERTIFICATE)); } + + private PrivateKey getOldPrivateKeyObject(String encodedOldPrivateKey) + throws KeyDecryptionException, InvalidKeySpecException, NoSuchAlgorithmException { + + StringBase64 stringBase64 = new StringBase64(encodedOldPrivateKey); + PemObject pemObject = stringBase64.asString() + .flatMap(PEM_OBJECT_FACTORY::createPemObject) + .orElseThrow( + () -> new KeyDecryptionException("Incorrect Key, decryption failed") + ); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemObject.getContent()); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePrivate(keySpec); + } } diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/PemObjectFactory.java b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/PemObjectFactory.java index 24d32bdd..0bded4d3 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/PemObjectFactory.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/PemObjectFactory.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.certservice.certification; +package org.onap.oom.certservice.certification.conversion; import java.io.IOException; import java.io.StringReader; diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/PemStringToCertificateConverter.java b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/PemStringToCertificateConverter.java index 7126cd4a..99499939 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/PemStringToCertificateConverter.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/PemStringToCertificateConverter.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.certservice.certification; +package org.onap.oom.certservice.certification.conversion; import java.io.IOException; import java.io.StringReader; diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/Pkcs10CertificationRequestFactory.java b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/Pkcs10CertificationRequestFactory.java index c38eb0a1..2b9399d0 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/Pkcs10CertificationRequestFactory.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/Pkcs10CertificationRequestFactory.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.certservice.certification; +package org.onap.oom.certservice.certification.conversion; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.util.encoders.DecoderException; diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/RsaContentSignerBuilder.java b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/RsaContentSignerBuilder.java index 741b20ab..d869cef9 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/RsaContentSignerBuilder.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/RsaContentSignerBuilder.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.certservice.certification; +package org.onap.oom.certservice.certification.conversion; import java.io.IOException; import java.security.PrivateKey; diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/StringBase64.java b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/StringBase64.java index 9929e52c..4b4813ba 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/StringBase64.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/StringBase64.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.certservice.certification; +package org.onap.oom.certservice.certification.conversion; import java.util.Base64; import java.util.Objects; diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateBuilder.java b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/X509CertificateBuilder.java index 67aecb7c..88e77766 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/X509CertificateBuilder.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/conversion/X509CertificateBuilder.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.certservice.certification; +package org.onap.oom.certservice.certification.conversion; import java.io.IOException; import java.math.BigInteger; @@ -38,7 +38,7 @@ public class X509CertificateBuilder { private static final int SECURE_NEXT_BYTES = 16; private static final int VALID_PERIOD_IN_DAYS = 365; - X509v3CertificateBuilder build(PKCS10CertificationRequest csr) throws IOException { + public X509v3CertificateBuilder build(PKCS10CertificationRequest csr) throws IOException { return new X509v3CertificateBuilder(csr.getSubject(), createSerial(), Date.from(LocalDateTime.now().toInstant(ZoneOffset.UTC)), Date.from(LocalDateTime.now().plusDays(VALID_PERIOD_IN_DAYS).toInstant(ZoneOffset.UTC)), 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 index 9423af52..699ffe71 100644 --- 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 @@ -20,16 +20,7 @@ package org.onap.oom.certservice.certification.model; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; import java.util.Objects; -import org.bouncycastle.util.io.pem.PemObject; -import org.onap.oom.certservice.certification.PemObjectFactory; -import org.onap.oom.certservice.certification.StringBase64; -import org.onap.oom.certservice.certification.exception.KeyDecryptionException; public final class CertificateUpdateModel { @@ -38,7 +29,6 @@ public final class CertificateUpdateModel { private final String encodedOldCert; private final String encodedOldPrivateKey; private final String caName; - private static final PemObjectFactory PEM_OBJECT_FACTORY = new PemObjectFactory(); private CertificateUpdateModel(String encodedCsr, String encodedPrivateKey, String encodedOldCert, String encodedOldPrivateKey, String caName) { @@ -69,20 +59,6 @@ public final class CertificateUpdateModel { return caName; } - public PrivateKey getOldPrivateKeyObject() - throws KeyDecryptionException, InvalidKeySpecException, NoSuchAlgorithmException { - - StringBase64 stringBase64 = new StringBase64(encodedOldPrivateKey); - PemObject pemObject = stringBase64.asString() - .flatMap(PEM_OBJECT_FACTORY::createPemObject) - .orElseThrow( - () -> new KeyDecryptionException("Incorrect Key, decryption failed") - ); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemObject.getContent()); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - return keyFactory.generatePrivate(keySpec); - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificationModel.java b/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificationResponseModel.java index 08a09a75..27b9c917 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificationModel.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/model/CertificationResponseModel.java @@ -23,12 +23,12 @@ package org.onap.oom.certservice.certification.model; import java.util.Collections; import java.util.List; -public class CertificationModel { +public class CertificationResponseModel { private final List<String> certificateChain; private final List<String> trustedCertificates; - public CertificationModel(List<String> certificateChain, List<String> trustedCertificates) { + public CertificationResponseModel(List<String> certificateChain, List<String> trustedCertificates) { this.certificateChain = certificateChain; this.trustedCertificates = trustedCertificates; } diff --git a/certService/src/main/java/org/onap/oom/certservice/certification/model/X509CertificateModel.java b/certService/src/main/java/org/onap/oom/certservice/certification/model/OldCertificateModel.java index f45fb7d3..bd2d33a5 100644 --- a/certService/src/main/java/org/onap/oom/certservice/certification/model/X509CertificateModel.java +++ b/certService/src/main/java/org/onap/oom/certservice/certification/model/OldCertificateModel.java @@ -20,22 +20,28 @@ package org.onap.oom.certservice.certification.model; -import java.security.cert.X509Certificate; +import java.security.PrivateKey; import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.GeneralName; -public class X509CertificateModel { +public class OldCertificateModel { - private final X509Certificate certificate; private final CertificateData certificateData; - public X509CertificateModel(X509Certificate certificate, X500Name subjectData, - GeneralName[] sans) { - this.certificate = certificate; + private final Certificate certificate; + + private final PrivateKey oldPrivateKey; + + + public OldCertificateModel(Certificate certificate, X500Name subjectData, + GeneralName[] sans, PrivateKey oldPrivateKey) { this.certificateData = new CertificateData(subjectData, sans); + this.certificate = certificate; + this.oldPrivateKey = oldPrivateKey; } - public X509Certificate getCertificate() { + public Certificate getOldCertificate() { return certificate; } @@ -50,4 +56,8 @@ public class X509CertificateModel { public CertificateData getCertificateData() { return certificateData; } + + public PrivateKey getOldPrivateKey() { + return oldPrivateKey; + } } diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/api/CmpClient.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/api/CmpClient.java index 88c73c04..0d9fdeea 100644 --- a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/api/CmpClient.java +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/api/CmpClient.java @@ -24,8 +24,8 @@ package org.onap.oom.certservice.cmpv2client.api; import java.util.Date; import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server; -import org.onap.oom.certservice.certification.model.CertificateUpdateModel; import org.onap.oom.certservice.certification.model.CsrModel; +import org.onap.oom.certservice.certification.model.OldCertificateModel; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel; @@ -51,7 +51,7 @@ public interface CmpClient { * @return model for certification containing certificate chain and trusted certificates * @throws CmpClientException if client error occurs. */ - Cmpv2CertificationModel createCertificate( + Cmpv2CertificationModel executeInitializationRequest( CsrModel csrModel, Cmpv2Server server, Date notBefore, @@ -69,7 +69,7 @@ public interface CmpClient { * @return model for certification containing certificate chain and trusted certificates * @throws CmpClientException if client error occurs. */ - Cmpv2CertificationModel createCertificate( + Cmpv2CertificationModel executeInitializationRequest( CsrModel csrModel, Cmpv2Server server) throws CmpClientException; @@ -82,12 +82,12 @@ public interface CmpClient { * * @param csrModel Certificate Signing Request Model. Must not be {@code null}. * @param cmpv2Server CMPv2 server. Must not be {@code null}. - * @param certificateUpdateModel Model with key update parameters {@code null}. + * @param oldCertificateModel Model with key update parameters {@code null}. * @return model for certification containing certificate chain and trusted certificates * @throws CmpClientException if client error occurs. */ - Cmpv2CertificationModel updateCertificate(CsrModel csrModel, Cmpv2Server cmpv2Server, - CertificateUpdateModel certificateUpdateModel) throws CmpClientException; + Cmpv2CertificationModel executeKeyUpdateRequest(CsrModel csrModel, Cmpv2Server cmpv2Server, + OldCertificateModel oldCertificateModel) throws CmpClientException; /** * Requests for an additional External Root CA Certificate to be created for the passed keyPair wrapped @@ -100,5 +100,5 @@ public interface CmpClient { * @return model for certification containing certificate chain and trusted certificates * @throws CmpClientException if client error occurs. */ - Cmpv2CertificationModel certificationRequest(CsrModel csrModel, Cmpv2Server cmpv2Server) throws CmpClientException; + Cmpv2CertificationModel executeCertificationRequest(CsrModel csrModel, Cmpv2Server cmpv2Server) throws CmpClientException; } diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java index 549cf6b9..bbca91b6 100644 --- a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/impl/CmpClientImpl.java @@ -25,45 +25,31 @@ package org.onap.oom.certservice.cmpv2client.impl; import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.checkIfCmpResponseContainsError; import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.getCertFromByteArray; import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseHelper.verifyAndReturnCertChainAndTrustSTore; -import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.checkImplicitConfirm; -import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifyPasswordBasedProtection; -import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifySignature; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStreamReader; import java.security.KeyPair; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; +import java.security.Security; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; import java.util.Collections; import java.util.Date; import java.util.Objects; import java.util.Optional; -import org.apache.commons.codec.binary.Base64; import org.apache.http.impl.client.CloseableHttpClient; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cmp.CMPCertificate; import org.bouncycastle.asn1.cmp.CertRepMessage; import org.bouncycastle.asn1.cmp.CertResponse; import org.bouncycastle.asn1.cmp.PKIBody; -import org.bouncycastle.asn1.cmp.PKIHeader; import org.bouncycastle.asn1.cmp.PKIMessage; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Certificate; -import org.bouncycastle.util.io.pem.PemReader; -import org.onap.oom.certservice.certification.configuration.model.CaMode; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server; -import org.onap.oom.certservice.certification.exception.KeyDecryptionException; -import org.onap.oom.certservice.certification.model.CertificateUpdateModel; import org.onap.oom.certservice.certification.model.CsrModel; +import org.onap.oom.certservice.certification.model.OldCertificateModel; import org.onap.oom.certservice.cmpv2client.api.CmpClient; import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; -import org.onap.oom.certservice.cmpv2client.exceptions.CmpServerException; import org.onap.oom.certservice.cmpv2client.model.Cmpv2CertificationModel; +import org.onap.oom.certservice.cmpv2client.validation.CmpCertificationValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,55 +61,56 @@ public class CmpClientImpl implements CmpClient { private static final Logger LOG = LoggerFactory.getLogger(CmpClientImpl.class); private final CloseableHttpClient httpClient; - - private static final String DEFAULT_CA_NAME = "Certification Authority"; - private static final String DEFAULT_PROFILE = CaMode.RA.getProfile(); - private static final ASN1ObjectIdentifier PASSWORD_BASED_MAC = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13"); + private final CmpCertificationValidator validator; public CmpClientImpl(CloseableHttpClient httpClient) { this.httpClient = httpClient; + this.validator = new CmpCertificationValidator(); + } + + static { + Security.addProvider(new BouncyCastleProvider()); } @Override - public Cmpv2CertificationModel createCertificate( + public Cmpv2CertificationModel executeInitializationRequest( CsrModel csrModel, Cmpv2Server server, Date notBefore, Date notAfter) throws CmpClientException { - validate(csrModel, server, httpClient, notBefore, notAfter); + validator.validate(csrModel, server, httpClient, notBefore, notAfter); final CreateCertRequest certRequest = getIakRvRequest(csrModel, server, notBefore, notAfter, PKIBody.TYPE_INIT_REQ); return executeCmpRequest(csrModel, server, certRequest); } @Override - public Cmpv2CertificationModel createCertificate(CsrModel csrModel, Cmpv2Server server) + public Cmpv2CertificationModel executeInitializationRequest(CsrModel csrModel, Cmpv2Server server) throws CmpClientException { - return createCertificate(csrModel, server, null, null); + return executeInitializationRequest(csrModel, server, null, null); } @Override - public Cmpv2CertificationModel updateCertificate(CsrModel csrModel, Cmpv2Server cmpv2Server, - CertificateUpdateModel certificateUpdateModel) throws CmpClientException { - validate(csrModel, cmpv2Server, httpClient, null, null); + public Cmpv2CertificationModel executeKeyUpdateRequest(CsrModel csrModel, Cmpv2Server cmpv2Server, + OldCertificateModel oldCertificateModel) throws CmpClientException { + validator.validate(csrModel, cmpv2Server, httpClient, null, null); - final PkiMessageProtection pkiMessageProtection = getSignatureProtection(certificateUpdateModel); + final PkiMessageProtection pkiMessageProtection = getSignatureProtection(oldCertificateModel); final CreateCertRequest certRequest = getCmpMessageBuilderWithCommonRequestValues(csrModel, cmpv2Server) .with(CreateCertRequest::setCmpRequestType, PKIBody.TYPE_KEY_UPDATE_REQ) - .with(CreateCertRequest::setExtraCerts, getCMPCertificateFromPem(certificateUpdateModel.getEncodedOldCert())) + .with(CreateCertRequest::setExtraCerts, getCMPCertificate(oldCertificateModel.getOldCertificate())) .with(CreateCertRequest::setProtection, pkiMessageProtection) .build(); return executeCmpRequest(csrModel, cmpv2Server, certRequest); - } @Override - public Cmpv2CertificationModel certificationRequest(CsrModel csrModel, Cmpv2Server cmpv2Server) throws CmpClientException { + public Cmpv2CertificationModel executeCertificationRequest(CsrModel csrModel, Cmpv2Server cmpv2Server) throws CmpClientException { - validate(csrModel, cmpv2Server, httpClient, null, null); + validator.validate(csrModel, cmpv2Server, httpClient, null, null); final CreateCertRequest certRequest = getIakRvRequest(csrModel, cmpv2Server, null, null, PKIBody.TYPE_CERT_REQ); return executeCmpRequest(csrModel, cmpv2Server, certRequest); } @@ -163,86 +150,48 @@ public class CmpClientImpl implements CmpClient { .with(CreateCertRequest::setSubjectKeyPair, keyPair); } - private SignatureProtection getSignatureProtection(CertificateUpdateModel certificateUpdateModel) - throws CmpClientException { - try { - PrivateKey oldPrivateKey = certificateUpdateModel.getOldPrivateKeyObject(); - return new SignatureProtection(oldPrivateKey); - } catch (NoSuchAlgorithmException | KeyDecryptionException | InvalidKeySpecException e) { - throw new CmpClientException("Cannot parse old private key ", e); - } - + private SignatureProtection getSignatureProtection(OldCertificateModel oldCertificateModel) { + return new SignatureProtection(oldCertificateModel.getOldPrivateKey()); } - private CMPCertificate[] getCMPCertificateFromPem(String encodedCertPem) throws CmpClientException { - try { - Certificate certificate = Certificate.getInstance( - new PemReader( - new InputStreamReader( - new ByteArrayInputStream( - Base64.decodeBase64(encodedCertPem)))) - .readPemObject().getContent()); - CMPCertificate cert = new CMPCertificate(certificate); + private CMPCertificate[] getCMPCertificate(Certificate oldCertificate) { + CMPCertificate cert = new CMPCertificate(oldCertificate); return new CMPCertificate[]{cert}; - } catch (IOException | NullPointerException e ) { - throw new CmpClientException("Cannot parse old certificate", e); - } - } - - private void checkCmpResponse( - final PKIMessage respPkiMessage, final PublicKey publicKey, final String initAuthPassword) - throws CmpClientException { - final PKIHeader header = respPkiMessage.getHeader(); - final AlgorithmIdentifier protectionAlgo = header.getProtectionAlg(); - verifySignatureWithPublicKey(respPkiMessage, publicKey); - if (isPasswordBasedMacAlgorithm(protectionAlgo)) { - LOG.info("CMP response is protected by Password Base Mac Algorithm. Attempt to verify protection"); - verifyPasswordBasedMacProtection(respPkiMessage, initAuthPassword, header, protectionAlgo); - } } - private boolean isPasswordBasedMacAlgorithm(AlgorithmIdentifier protectionAlgo) throws CmpClientException { - if (Objects.isNull(protectionAlgo)) { - LOG.error("CMP response does not contain Protection Algorithm field"); - throw new CmpClientException("CMP response does not contain Protection Algorithm field"); - } - return PASSWORD_BASED_MAC.equals(protectionAlgo.getAlgorithm()); - } - - private void verifySignatureWithPublicKey(PKIMessage respPkiMessage, PublicKey publicKey) + private Cmpv2CertificationModel retrieveCertificates( + CsrModel csrModel, Cmpv2Server server, PKIMessage pkiMessage, Cmpv2HttpClient cmpv2HttpClient) throws CmpClientException { - if (Objects.nonNull(publicKey)) { - LOG.debug("Verifying signature of the response."); - verifySignature(respPkiMessage, publicKey); - } else { - LOG.error("Public Key is not available, therefore cannot verify signature"); - throw new CmpClientException( - "Public Key is not available, therefore cannot verify signature"); + final byte[] respBytes = cmpv2HttpClient.postRequest(pkiMessage, server.getUrl(), server.getCaName()); + try { + final PKIMessage respPkiMessage = PKIMessage.getInstance(respBytes); + LOG.info("Received response from Server"); + checkIfCmpResponseContainsError(respPkiMessage); + validator.checkCmpResponse(respPkiMessage, csrModel.getPublicKey(), server.getAuthentication().getIak()); + return checkCmpCertRepMessage(respPkiMessage); + } catch (IllegalArgumentException iae) { + CmpClientException cmpClientException = + new CmpClientException( + "Error encountered while processing response from CA server ", iae); + LOG.error("Error encountered while processing response from CA server ", iae); + throw cmpClientException; } } - private void verifyPasswordBasedMacProtection(PKIMessage respPkiMessage, String initAuthPassword, - PKIHeader header, AlgorithmIdentifier protectionAlgo) - throws CmpClientException { - LOG.debug("Verifying PasswordBased Protection of the Response."); - verifyPasswordBasedProtection(respPkiMessage, initAuthPassword, protectionAlgo); - checkImplicitConfirm(header); - } - private Cmpv2CertificationModel checkCmpCertRepMessage(final PKIMessage respPkiMessage) - throws CmpClientException { + throws CmpClientException { final PKIBody pkiBody = respPkiMessage.getBody(); if (Objects.nonNull(pkiBody) && pkiBody.getContent() instanceof CertRepMessage) { final CertRepMessage certRepMessage = (CertRepMessage) pkiBody.getContent(); if (Objects.nonNull(certRepMessage)) { try { CertResponse certResponse = getCertificateResponseContainingNewCertificate(certRepMessage); - checkServerResponse(certResponse); + validator.checkServerResponse(certResponse); return verifyReturnCertChainAndTrustStore(respPkiMessage, certRepMessage, certResponse); } catch (IOException | CertificateParsingException ex) { CmpClientException cmpClientException = - new CmpClientException( - "Exception occurred while retrieving Certificates from response", ex); + new CmpClientException( + "Exception occurred while retrieving Certificates from response", ex); LOG.error("Exception occurred while retrieving Certificates from response", ex); throw cmpClientException; } @@ -253,98 +202,23 @@ public class CmpClientImpl implements CmpClient { return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList()); } - private void checkServerResponse(CertResponse certResponse) { - if (certResponse.getStatus() != null && certResponse.getStatus().getStatus() != null) { - logServerResponse(certResponse); - if (certResponse.getStatus().getStatus().intValue() == PkiStatus.REJECTED.getCode()) { - String serverMessage = certResponse.getStatus().getStatusString().getStringAt(0).getString(); - throw new CmpServerException(Optional.ofNullable(serverMessage).orElse("N/A")); - } - } - } - - private void logServerResponse(CertResponse certResponse) { - if (LOG.isInfoEnabled()) { - LOG.info("Response status code: {}", certResponse.getStatus().getStatus()); - } - if (certResponse.getStatus().getStatusString() != null) { - String serverMessage = certResponse.getStatus().getStatusString().getStringAt(0).getString(); - LOG.warn("Response status text: {}", serverMessage); - } - if (LOG.isWarnEnabled() && certResponse.getStatus().getFailInfo() != null) { - LOG.warn("Response fail info: {}", certResponse.getStatus().getFailInfo()); - } - } - private Cmpv2CertificationModel verifyReturnCertChainAndTrustStore( - PKIMessage respPkiMessage, CertRepMessage certRepMessage, CertResponse certResponse) - throws CertificateParsingException, CmpClientException, IOException { + PKIMessage respPkiMessage, CertRepMessage certRepMessage, CertResponse certResponse) + throws CertificateParsingException, CmpClientException, IOException { LOG.info("Verifying certificates returned as part of CertResponse."); final CMPCertificate cmpCertificate = - certResponse.getCertifiedKeyPair().getCertOrEncCert().getCertificate(); + certResponse.getCertifiedKeyPair().getCertOrEncCert().getCertificate(); final Optional<X509Certificate> leafCertificate = - getCertFromByteArray(cmpCertificate.getEncoded(), X509Certificate.class); + getCertFromByteArray(cmpCertificate.getEncoded(), X509Certificate.class); if (leafCertificate.isPresent()) { return verifyAndReturnCertChainAndTrustSTore( - respPkiMessage, certRepMessage, leafCertificate.get()); + respPkiMessage, certRepMessage, leafCertificate.get()); } return new Cmpv2CertificationModel(Collections.emptyList(), Collections.emptyList()); } private CertResponse getCertificateResponseContainingNewCertificate( - CertRepMessage certRepMessage) { + CertRepMessage certRepMessage) { return certRepMessage.getResponse()[0]; } - - /** - * Validate inputs for Certificate Creation. - * - * @param csrModel Certificate Signing Request model. Must not be {@code null}. - * @param server CMPv2 Server. Must not be {@code null}. - * @throws IllegalArgumentException if Before Date is set after the After Date. - */ - private static void validate( - final CsrModel csrModel, - final Cmpv2Server server, - final CloseableHttpClient httpClient, - final Date notBefore, - final Date notAfter) { - - String caName = CmpUtil.isNullOrEmpty(server.getCaName()) ? server.getCaName() : DEFAULT_CA_NAME; - String profile = server.getCaMode() != null ? server.getCaMode().getProfile() : DEFAULT_PROFILE; - LOG.info( - "Validate before creating Certificate Request for CA :{} in Mode {} ", caName, profile); - - CmpUtil.notNull(csrModel, "CsrModel Instance"); - CmpUtil.notNull(csrModel.getSubjectData(), "Subject DN"); - CmpUtil.notNull(csrModel.getPrivateKey(), "Subject private key"); - CmpUtil.notNull(csrModel.getPublicKey(), "Subject public key"); - CmpUtil.notNull(server.getIssuerDN(), "Issuer DN"); - CmpUtil.notNull(server.getUrl(), "External CA URL"); - CmpUtil.notNull(server.getAuthentication().getIak(), "IAK/RV Password"); - CmpUtil.notNull(httpClient, "Closeable Http Client"); - - if (notBefore != null && notAfter != null && notBefore.compareTo(notAfter) > 0) { - throw new IllegalArgumentException("Before Date is set after the After Date"); - } - } - - private Cmpv2CertificationModel retrieveCertificates( - CsrModel csrModel, Cmpv2Server server, PKIMessage pkiMessage, Cmpv2HttpClient cmpv2HttpClient) - throws CmpClientException { - final byte[] respBytes = cmpv2HttpClient.postRequest(pkiMessage, server.getUrl(), server.getCaName()); - try { - final PKIMessage respPkiMessage = PKIMessage.getInstance(respBytes); - LOG.info("Received response from Server"); - checkIfCmpResponseContainsError(respPkiMessage); - checkCmpResponse(respPkiMessage, csrModel.getPublicKey(), server.getAuthentication().getIak()); - return checkCmpCertRepMessage(respPkiMessage); - } catch (IllegalArgumentException iae) { - CmpClientException cmpClientException = - new CmpClientException( - "Error encountered while processing response from CA server ", iae); - LOG.error("Error encountered while processing response from CA server ", iae); - throw cmpClientException; - } - } } diff --git a/certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpCertificationValidator.java b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpCertificationValidator.java new file mode 100644 index 00000000..40a2a1d9 --- /dev/null +++ b/certService/src/main/java/org/onap/oom/certservice/cmpv2client/validation/CmpCertificationValidator.java @@ -0,0 +1,142 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Modification copyright 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.cmpv2client.validation; + +import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.checkImplicitConfirm; +import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifyPasswordBasedProtection; +import static org.onap.oom.certservice.cmpv2client.impl.CmpResponseValidationHelper.verifySignature; + +import java.security.PublicKey; +import java.util.Date; +import java.util.Objects; +import java.util.Optional; +import org.apache.http.impl.client.CloseableHttpClient; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.cmp.CertResponse; +import org.bouncycastle.asn1.cmp.PKIHeader; +import org.bouncycastle.asn1.cmp.PKIMessage; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.onap.oom.certservice.certification.configuration.model.CaMode; +import org.onap.oom.certservice.certification.configuration.model.Cmpv2Server; +import org.onap.oom.certservice.certification.model.CsrModel; +import org.onap.oom.certservice.cmpv2client.exceptions.CmpClientException; +import org.onap.oom.certservice.cmpv2client.exceptions.CmpServerException; +import org.onap.oom.certservice.cmpv2client.impl.CmpUtil; +import org.onap.oom.certservice.cmpv2client.impl.PkiStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CmpCertificationValidator { + private static final String DEFAULT_CA_NAME = "Certification Authority"; + private static final String DEFAULT_PROFILE = CaMode.RA.getProfile(); + private static final ASN1ObjectIdentifier PASSWORD_BASED_MAC = new ASN1ObjectIdentifier("1.2.840.113533.7.66.13"); + private static final Logger LOG = LoggerFactory.getLogger(CmpCertificationValidator.class); + + public static void validate( + final CsrModel csrModel, + final Cmpv2Server server, + final CloseableHttpClient httpClient, + final Date notBefore, + final Date notAfter) { + + String caName = CmpUtil.isNullOrEmpty(server.getCaName()) ? server.getCaName() : DEFAULT_CA_NAME; + String profile = server.getCaMode() != null ? server.getCaMode().getProfile() : DEFAULT_PROFILE; + LOG.info( + "Validate before creating Certificate Request for CA :{} in Mode {} ", caName, profile); + + CmpUtil.notNull(csrModel, "CsrModel Instance"); + CmpUtil.notNull(csrModel.getSubjectData(), "Subject DN"); + CmpUtil.notNull(csrModel.getPrivateKey(), "Subject private key"); + CmpUtil.notNull(csrModel.getPublicKey(), "Subject public key"); + CmpUtil.notNull(server.getIssuerDN(), "Issuer DN"); + CmpUtil.notNull(server.getUrl(), "External CA URL"); + CmpUtil.notNull(server.getAuthentication().getIak(), "IAK/RV Password"); + CmpUtil.notNull(httpClient, "Closeable Http Client"); + + if (notBefore != null && notAfter != null && notBefore.compareTo(notAfter) > 0) { + throw new IllegalArgumentException("Before Date is set after the After Date"); + } + } + + public void checkCmpResponse(final PKIMessage respPkiMessage, final PublicKey publicKey, final String initAuthPassword) + throws CmpClientException { + final PKIHeader header = respPkiMessage.getHeader(); + final AlgorithmIdentifier protectionAlgo = header.getProtectionAlg(); + verifySignatureWithPublicKey(respPkiMessage, publicKey); + if (isPasswordBasedMacAlgorithm(protectionAlgo)) { + LOG.info("CMP response is protected by Password Base Mac Algorithm. Attempt to verify protection"); + verifyPasswordBasedMacProtection(respPkiMessage, initAuthPassword, header, protectionAlgo); + } + } + + public void checkServerResponse(CertResponse certResponse) { + if (certResponse.getStatus() != null && certResponse.getStatus().getStatus() != null) { + logServerResponse(certResponse); + if (certResponse.getStatus().getStatus().intValue() == PkiStatus.REJECTED.getCode()) { + String serverMessage = certResponse.getStatus().getStatusString().getStringAt(0).getString(); + throw new CmpServerException(Optional.ofNullable(serverMessage).orElse("N/A")); + } + } + } + + private boolean isPasswordBasedMacAlgorithm(AlgorithmIdentifier protectionAlgo) throws CmpClientException { + if (Objects.isNull(protectionAlgo)) { + LOG.error("CMP response does not contain Protection Algorithm field"); + throw new CmpClientException("CMP response does not contain Protection Algorithm field"); + } + return PASSWORD_BASED_MAC.equals(protectionAlgo.getAlgorithm()); + } + + private void verifySignatureWithPublicKey(PKIMessage respPkiMessage, PublicKey publicKey) + throws CmpClientException { + if (Objects.nonNull(publicKey)) { + LOG.debug("Verifying signature of the response."); + verifySignature(respPkiMessage, publicKey); + } else { + LOG.error("Public Key is not available, therefore cannot verify signature"); + throw new CmpClientException( + "Public Key is not available, therefore cannot verify signature"); + } + } + + private void verifyPasswordBasedMacProtection(PKIMessage respPkiMessage, String initAuthPassword, + PKIHeader header, AlgorithmIdentifier protectionAlgo) + throws CmpClientException { + LOG.debug("Verifying PasswordBased Protection of the Response."); + verifyPasswordBasedProtection(respPkiMessage, initAuthPassword, protectionAlgo); + checkImplicitConfirm(header); + } + + private void logServerResponse(CertResponse certResponse) { + if (LOG.isInfoEnabled()) { + LOG.info("Response status code: {}", certResponse.getStatus().getStatus()); + } + if (certResponse.getStatus().getStatusString() != null) { + String serverMessage = certResponse.getStatus().getStatusString().getStringAt(0).getString(); + LOG.warn("Response status text: {}", serverMessage); + } + if (LOG.isWarnEnabled() && certResponse.getStatus().getFailInfo() != null) { + LOG.warn("Response fail info: {}", certResponse.getStatus().getFailInfo()); + } + } +} |