diff options
11 files changed, 189 insertions, 91 deletions
@@ -2,6 +2,7 @@ target/ !**/src/main/** !**/src/test/** **/var +certServiceClient/certs_volume ### STS ### .apt_generated diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java index 184d724a..f768dabb 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java @@ -51,12 +51,12 @@ class CSRMetaBuilder { CSRMeta build(CsrModel csrModel, Cmpv2Server server) { CSRMeta csrMeta = createCsrMeta(csrModel); addSans(csrModel, csrMeta); - csrMeta.keyPair(new KeyPair(csrModel.getPublicKey(), csrModel.getPrivateKey())); - csrMeta.password(server.getAuthentication().getIak()); + csrMeta.setKeyPair(new KeyPair(csrModel.getPublicKey(), csrModel.getPrivateKey())); + csrMeta.setPassword(server.getAuthentication().getIak()); csrMeta.setIssuerName(server.getIssuerDN()); - csrMeta.caUrl(server.getUrl()); + csrMeta.setCaUrl(server.getUrl()); csrMeta.setName(csrModel.getSubjectData()); - csrMeta.senderKid(server.getAuthentication().getRv()); + csrMeta.setSenderKid(server.getAuthentication().getRv()); return csrMeta; } @@ -66,7 +66,7 @@ class CSRMetaBuilder { } private void addSans(CsrModel csrModel, CSRMeta csrMeta) { - csrModel.getSans().forEach(csrMeta::san); + csrModel.getSans().forEach(csrMeta::addSan); } private String convertRDNToString(org.bouncycastle.asn1.x500.RDN rdn) { diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CSRMeta.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CSRMeta.java index aa9748f9..470a070f 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CSRMeta.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/CSRMeta.java @@ -1,4 +1,4 @@ -/** +/* * ============LICENSE_START==================================================== * org.onap.aaf * =========================================================================== @@ -23,7 +23,6 @@ package org.onap.aaf.certservice.cmpv2client.external; import java.security.KeyPair; -import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.x500.X500Name; @@ -41,7 +40,7 @@ public class CSRMeta { private String issuerCn; private String issuerEmail; private String password; - private String CaUrl; + private String caUrl; private List<RDN> rdns; private ArrayList<String> sanList = new ArrayList<>(); private KeyPair keyPair; @@ -54,27 +53,27 @@ public class CSRMeta { this.rdns = rdns; } - public X500Name x500Name() { + public X500Name getX500Name() { if (name == null) { - X500NameBuilder xnb = new X500NameBuilder(); - xnb.addRDN(BCStyle.CN, cn); - xnb.addRDN(BCStyle.E, email); + X500NameBuilder nameBuilder = new X500NameBuilder(); + nameBuilder.addRDN(BCStyle.CN, cn); + nameBuilder.addRDN(BCStyle.E, email); if (mechID != null) { if (environment == null) { - xnb.addRDN(BCStyle.OU, mechID); + nameBuilder.addRDN(BCStyle.OU, mechID); } else { - xnb.addRDN(BCStyle.OU, mechID + ':' + environment); + nameBuilder.addRDN(BCStyle.OU, mechID + ':' + environment); } } for (RDN rdn : rdns) { - xnb.addRDN(rdn.getAoi(), rdn.getValue()); + nameBuilder.addRDN(rdn.getAoi(), rdn.getValue()); } - name = xnb.build(); + name = nameBuilder.build(); } return name; } - public X500Name issuerx500Name() { + public X500Name getIssuerX500Name() { if (issuerName == null) { X500NameBuilder xnb = new X500NameBuilder(); xnb.addRDN(BCStyle.CN, issuerCn); @@ -86,125 +85,114 @@ public class CSRMeta { return issuerName; } - public CSRMeta san(String v) { + public void addSan(String v) { sanList.add(v); - return this; } - public List<String> sans() { + public List<String> getSans() { return sanList; } - public KeyPair keypair() { + public KeyPair getKeyPairOrGenerateIfNull() { if (keyPair == null) { keyPair = Factory.generateKeyPair(); } return keyPair; } - public KeyPair keyPair() { + public KeyPair getKeyPair() { return keyPair; } - public void keyPair(KeyPair keyPair) { + public void setKeyPair(KeyPair keyPair) { this.keyPair = keyPair; } - /** @return the cn */ - public String cn() { + public String getCn() { return cn; } - /** @param cn the cn to set */ - public void cn(String cn) { + public void setCn(String cn) { this.cn = cn; } - /** Environment of Service MechID is good for */ - public void environment(String env) { + public void setEnvironment(String env) { environment = env; } - /** @return */ - public String environment() { + public String getEnvironment() { return environment; } - /** @return the mechID */ - public String mechID() { + public String getMechID() { return mechID; } - /** @param mechID the mechID to set */ - public void mechID(String mechID) { + public void setMechID(String mechID) { this.mechID = mechID; } - /** @return the email */ - public String email() { + public String getEmail() { return email; } - /** @param email the email to set */ - public void email(String email) { + public void setEmail(String email) { this.email = email; } - /** @return the challenge */ - public String challenge() { + public String getChallenge() { return challenge; } - /** @param challenge the challenge to set */ - public void challenge(String challenge) { + public void setChallenge(String challenge) { this.challenge = challenge; } - public void password(String password) { + public void setPassword(String password) { this.password = password; } - public String password() { + public String getPassword() { return password; } - public void certificate(Certificate certificate) { + public void setCertificate(Certificate certificate) { this.certificate = certificate; } - public Certificate certificate() { + public Certificate getCertificate() { return certificate; } - public void issuerCn(String issuerCn) { + public void setIssuerCn(String issuerCn) { this.issuerCn = issuerCn; } - public String caUrl() { - return CaUrl; + public String getCaUrl() { + return caUrl; } - public void caUrl(String caUrl) { - CaUrl = caUrl; + public void setCaUrl(String caUrl) { + this.caUrl = caUrl; } - public String senderKid() { + public String getSenderKid() { return senderKid; } - public void senderKid(String senderKid) { + public void setSenderKid(String senderKid) { this.senderKid = senderKid; } - public String issuerCn() { + public String getIssuerCn() { return issuerCn; } - public String issuerEmail() { + public String getIssuerEmail() { return issuerEmail; } - public void issuerEmail(String issuerEmail) { + public void setIssuerEmail(String issuerEmail) { this.issuerEmail = issuerEmail; } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java index 29bd671d..e77e8b0f 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/impl/CmpClientImpl.java @@ -81,14 +81,14 @@ public class CmpClientImpl implements CmpClient { final CreateCertRequest certRequest = CmpMessageBuilder.of(CreateCertRequest::new) - .with(CreateCertRequest::setIssuerDn, csrMeta.issuerx500Name()) - .with(CreateCertRequest::setSubjectDn, csrMeta.x500Name()) - .with(CreateCertRequest::setSansList, csrMeta.sans()) - .with(CreateCertRequest::setSubjectKeyPair, csrMeta.keyPair()) + .with(CreateCertRequest::setIssuerDn, csrMeta.getIssuerX500Name()) + .with(CreateCertRequest::setSubjectDn, csrMeta.getX500Name()) + .with(CreateCertRequest::setSansList, csrMeta.getSans()) + .with(CreateCertRequest::setSubjectKeyPair, csrMeta.getKeyPair()) .with(CreateCertRequest::setNotBefore, notBefore) .with(CreateCertRequest::setNotAfter, notAfter) - .with(CreateCertRequest::setInitAuthPassword, csrMeta.password()) - .with(CreateCertRequest::setSenderKid, csrMeta.senderKid()) + .with(CreateCertRequest::setInitAuthPassword, csrMeta.getPassword()) + .with(CreateCertRequest::setSenderKid, csrMeta.getSenderKid()) .build(); final PKIMessage pkiMessage = certRequest.generateCertReq(); @@ -212,12 +212,12 @@ public class CmpClientImpl implements CmpClient { "Validate before creating Certificate Request for CA :{} in Mode {} ", caName, caProfile); CmpUtil.notNull(csrMeta, "CSRMeta Instance"); - CmpUtil.notNull(csrMeta.x500Name(), "Subject DN"); - CmpUtil.notNull(csrMeta.issuerx500Name(), "Issuer DN"); - CmpUtil.notNull(csrMeta.password(), "IAK/RV Password"); + CmpUtil.notNull(csrMeta.getX500Name(), "Subject DN"); + CmpUtil.notNull(csrMeta.getIssuerX500Name(), "Issuer DN"); + CmpUtil.notNull(csrMeta.getPassword(), "IAK/RV Password"); CmpUtil.notNull(cert, "Certificate Signing Request (CSR)"); - CmpUtil.notNull(csrMeta.caUrl(), "External CA URL"); - CmpUtil.notNull(csrMeta.keypair(), "Subject KeyPair"); + CmpUtil.notNull(csrMeta.getCaUrl(), "External CA URL"); + CmpUtil.notNull(csrMeta.getKeyPairOrGenerateIfNull(), "Subject KeyPair"); CmpUtil.notNull(httpClient, "Closeable Http Client"); if (notBefore != null && notAfter != null && notBefore.compareTo(notAfter) > 0) { @@ -228,12 +228,12 @@ public class CmpClientImpl implements CmpClient { private List<List<X509Certificate>> retrieveCertificates( String caName, CSRMeta csrMeta, PKIMessage pkiMessage, Cmpv2HttpClient cmpv2HttpClient) throws CmpClientException { - final byte[] respBytes = cmpv2HttpClient.postRequest(pkiMessage, csrMeta.caUrl(), caName); + final byte[] respBytes = cmpv2HttpClient.postRequest(pkiMessage, csrMeta.getCaUrl(), caName); try { final PKIMessage respPkiMessage = PKIMessage.getInstance(respBytes); LOG.info("Received response from Server"); checkIfCmpResponseContainsError(respPkiMessage); - checkCmpResponse(respPkiMessage, csrMeta.keypair().getPublic(), csrMeta.password()); + checkCmpResponse(respPkiMessage, csrMeta.getKeyPairOrGenerateIfNull().getPublic(), csrMeta.getPassword()); return checkCmpCertRepMessage(respPkiMessage); } catch (IllegalArgumentException iae) { CmpClientException cmpClientException = diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilderTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilderTest.java index d3f8cc65..adb89b31 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilderTest.java +++ b/certService/src/test/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilderTest.java @@ -72,14 +72,14 @@ public class CSRMetaBuilderTest { CSRMeta createdCSRMeta = csrMetaBuilder.build(testCsrModel, testServer); // Then - assertThat(createdCSRMeta.password()).isEqualTo(testServer.getAuthentication().getIak()); - assertThat(createdCSRMeta.senderKid()).isEqualTo(testServer.getAuthentication().getRv()); - assertThat(createdCSRMeta.caUrl()).isEqualTo(testServer.getUrl()); - assertThat(createdCSRMeta.sans()).containsAll(testSans); - assertThat(createdCSRMeta.keyPair().getPrivate()).isEqualTo(mockPrivateKey); - assertThat(createdCSRMeta.keyPair().getPublic()).isEqualTo(mockPublicKey); - assertThat(createdCSRMeta.x500Name()).isEqualTo(TEST_SUBJECT_DATA); - assertThat(createdCSRMeta.issuerx500Name()).isEqualTo(TEST_SUBJECT_DATA); + assertThat(createdCSRMeta.getPassword()).isEqualTo(testServer.getAuthentication().getIak()); + assertThat(createdCSRMeta.getSenderKid()).isEqualTo(testServer.getAuthentication().getRv()); + assertThat(createdCSRMeta.getCaUrl()).isEqualTo(testServer.getUrl()); + assertThat(createdCSRMeta.getSans()).containsAll(testSans); + assertThat(createdCSRMeta.getKeyPair().getPrivate()).isEqualTo(mockPrivateKey); + assertThat(createdCSRMeta.getKeyPair().getPublic()).isEqualTo(mockPublicKey); + assertThat(createdCSRMeta.getX500Name()).isEqualTo(TEST_SUBJECT_DATA); + assertThat(createdCSRMeta.getIssuerX500Name()).isEqualTo(TEST_SUBJECT_DATA); } private Cmpv2Server createTestServer() { diff --git a/certService/src/test/java/org/onap/aaf/certservice/cmpv2Client/Cmpv2ClientTest.java b/certService/src/test/java/org/onap/aaf/certservice/cmpv2Client/Cmpv2ClientTest.java index 713a2d00..a2f3050f 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/cmpv2Client/Cmpv2ClientTest.java +++ b/certService/src/test/java/org/onap/aaf/certservice/cmpv2Client/Cmpv2ClientTest.java @@ -89,7 +89,7 @@ class Cmpv2ClientTest { KeyPairGenerator keyGenerator; keyGenerator = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME); keyGenerator.initialize(2048); - keyPair = LoadKeyPair(); + keyPair = loadKeyPair(); rdns = new ArrayList<>(); try { rdns.add(new RDN("O=CommonCompany")); @@ -99,7 +99,7 @@ class Cmpv2ClientTest { initMocks(this); } - public KeyPair LoadKeyPair() + public KeyPair loadKeyPair() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { @@ -307,16 +307,15 @@ class Cmpv2ClientTest { Date notBefore, Date notAfter) { csrMeta = new CSRMeta(rdns); - csrMeta.cn(cn); - csrMeta.san(san); - csrMeta.password(password); - csrMeta.email(email); - csrMeta.issuerCn(issuerCn); + csrMeta.setCn(cn); + csrMeta.addSan(san); + csrMeta.setPassword(password); + csrMeta.setEmail(email); + csrMeta.setIssuerCn(issuerCn); when(kpg.generateKeyPair()).thenReturn(keyPair); - csrMeta.keypair(); - csrMeta.caUrl(externalCaUrl); - csrMeta.senderKid(senderKid); - + csrMeta.getKeyPairOrGenerateIfNull(); + csrMeta.setCaUrl(externalCaUrl); + csrMeta.setSenderKid(senderKid); this.notBefore = notBefore; this.notAfter = notAfter; } diff --git a/certServiceClient/client_docker.env b/certServiceClient/client_docker.env new file mode 100644 index 00000000..f2697173 --- /dev/null +++ b/certServiceClient/client_docker.env @@ -0,0 +1,14 @@ +#Client envs +REQUEST_URL=http://certservice:8080/v1/certificate/ +REQUEST_TIMEOUT=1000 +OUTPUT_PATH=/var/certs +CA_NAME=RA +#Csr config envs +COMMON_NAME=onap.org +ORGANIZATION=Linux-Foundation +ORGANIZATION_UNIT=ONAP +LOCATION=San-Francisco +STATE=California +COUNTRY=US +SANS=example.org + diff --git a/certServiceClient/docker-compose.yml b/certServiceClient/docker-compose.yml new file mode 100644 index 00000000..b0c65be9 --- /dev/null +++ b/certServiceClient/docker-compose.yml @@ -0,0 +1,59 @@ +version: "2.1" + +services: + ejbca: + image: primekey/ejbca-ce:6.15.2.5 + hostname: cahostname + container_name: aafcert-ejbca + ports: + - "80:8080" + - "443:8443" + volumes: + - ../certService/src/main/resources/scripts/:/opt/primekey/scripts + command: bash -c " + ./scripts/ejbca-configuration.sh & + /opt/primekey/bin/start.sh + " + healthcheck: + test: ["CMD-SHELL", "curl -kI https://localhost:8443/ejbca/publicweb/healthcheck/ejbcahealth"] + interval: 20s + timeout: 3s + retries: 9 + networks: + - certservice + + certservice: + image: onap/org.onap.aaf.certservice.aaf-certservice-api:latest + volumes: + - ../certService/helm/aaf-cert-service/resources/cmpServers.json:/etc/onap/aaf/certservice/cmpServers.json + container_name: aafcert-service + ports: + - "8080:8080" + depends_on: + ejbca: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8080/actuator/health"] + interval: 10s + timeout: 3s + retries: 9 + networks: + - certservice + + certservice-client: + image: onap/org.onap.aaf.certservice.aaf-certservice-client:latest + container_name: aafcert-client + env_file: + - ./client_docker.env + user: root #Run as root to avoid volume permission issues + volumes: + - ./certs_volume/:/var/certs + depends_on: + certservice: + condition: service_healthy + networks: + - certservice + +networks: + certservice: + driver: bridge diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/model/ClientConfiguration.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/model/ClientConfiguration.java index 58d3f6b1..d1c1c685 100644 --- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/model/ClientConfiguration.java +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/model/ClientConfiguration.java @@ -23,7 +23,7 @@ package org.onap.aaf.certservice.client.configuration.model; public class ClientConfiguration implements ConfigurationModel { private static final Integer DEFAULT_TIMEOUT_MS = 30000; - private static final String DEFAULT_REQUEST_URL = "http://cert-service:8080/v1/certificate/"; + private static final String DEFAULT_REQUEST_URL = "http://aaf-cert-service-service:8080/v1/certificate/"; private String urlToCertService; private Integer requestTimeout; diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java index 8f4fe6a3..36b3b1a4 100644 --- a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java @@ -38,4 +38,40 @@ class EnvValidationUtilsTest { public void shouldRejectInvalidPath(String path){ assertFalse(EnvValidationUtils.isPathValid(path)); } + + @ParameterizedTest + @ValueSource(strings = {"PL", "DE", "PT", "US"}) + public void shouldAcceptValidCountryCode(String countryCode){ + assertTrue(EnvValidationUtils.isCountryValid(countryCode)); + } + + @ParameterizedTest + @ValueSource(strings = {"1P", "PLP", "P#", "&*"}) + public void shouldRejectInvalidCountryCode(String countryCode){ + assertFalse(EnvValidationUtils.isCountryValid(countryCode)); + } + + @ParameterizedTest + @ValueSource(strings = {"caname", "caname1", "123caName", "ca1name"}) + public void shouldAcceptValidAlphanumeric(String caName){ + assertTrue(EnvValidationUtils.isAlphaNumeric(caName)); + } + + @ParameterizedTest + @ValueSource(strings = {"44caname$", "#caname1", "1c_aname", "ca1-name"}) + public void shouldRejectInvalidAlphanumeric(String caName){ + assertFalse(EnvValidationUtils.isAlphaNumeric(caName)); + } + + @ParameterizedTest + @ValueSource(strings = {"example.com", "www.example.com"}) + public void shouldAcceptValidCommonName(String commonName){ + assertTrue(EnvValidationUtils.isCommonNameValid(commonName)); + } + + @ParameterizedTest + @ValueSource(strings = {"https://example.com", "http://example.com", "example.com:8080", "0.0.0.0", "@#$%.com"}) + public void shouldRejectInvalidCommonName(String commonName){ + assertFalse(EnvValidationUtils.isCommonNameValid(commonName)); + } }
\ No newline at end of file diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/ClientConfigurationFactoryTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/ClientConfigurationFactoryTest.java index 2c875c24..c936ef52 100644 --- a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/ClientConfigurationFactoryTest.java +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/ClientConfigurationFactoryTest.java @@ -39,6 +39,7 @@ public class ClientConfigurationFactoryTest { private final String TIME_OUT_VALID = "30000"; private final String OUTPUT_PATH_VALID = "/opt/app/osaaf"; private final String URL_TO_CERT_SERVICE_VALID = "http://cert-service:8080/v1/certificate/"; + private final String URL_TO_CERT_SERVICE_DEFAULT = "http://aaf-cert-service-service:8080/v1/certificate/"; private final String CA_NAME_INVALID = "caaaftest2#$"; private final String OUTPUT_PATH_INVALID = "/opt//app/osaaf"; @@ -75,7 +76,7 @@ public class ClientConfigurationFactoryTest { assertThat(configuration.getCaName()).isEqualTo(CA_NAME_VALID); assertThat(configuration.getRequestTimeout()).isEqualTo(Integer.valueOf(TIME_OUT_VALID)); assertThat(configuration.getCertsOutputPath()).isEqualTo(OUTPUT_PATH_VALID); - assertThat(configuration.getUrlToCertService()).isEqualTo(URL_TO_CERT_SERVICE_VALID); + assertThat(configuration.getUrlToCertService()).isEqualTo(URL_TO_CERT_SERVICE_DEFAULT); } @Test |