From 2e1ca9b2576a54de010b359326cfa699e21486c9 Mon Sep 17 00:00:00 2001 From: Henry Avetisyan Date: Tue, 7 Jan 2025 10:59:43 -0800 Subject: [PATCH] Provide interface to allow customization of SPIFFE URI format Signed-off-by: Henry Avetisyan --- .../server/spiffe/SpiffeUriManager.java | 89 +++++++++++++++++++ .../server/spiffe/SpiffeUriValidator.java | 45 ++++++++++ .../server/spiffe/impl/SpiffeUriBasic.java | 52 +++++++++++ .../spiffe/impl/SpiffeUriTrustDomain.java | 61 +++++++++++++ .../server/spiffe/SpiffeUriManagerTest.java | 87 ++++++++++++++++++ .../server/spiffe/SpiffeUriValidatorTest.java | 53 +++++++++++ .../spiffe/impl/SpiffeUriBasicTest.java | 47 ++++++++++ .../spiffe/impl/SpiffeUriTrustDomainTest.java | 58 ++++++++++++ .../impl/KubernetesPodResolverUtilTest.java | 25 +++--- servers/zts/conf/zts.properties | 11 +++ .../java/com/yahoo/athenz/zts/ZTSConsts.java | 1 - .../java/com/yahoo/athenz/zts/ZTSImpl.java | 16 ++-- .../athenz/zts/cert/X509CertRequest.java | 11 ++- .../athenz/zts/cert/X509RoleCertRequest.java | 24 ++--- .../zts/cert/X509ServiceCertRequest.java | 30 ++----- .../com/yahoo/athenz/zts/ZTSImplTest.java | 30 +++---- .../athenz/zts/cert/X509CertRequestTest.java | 85 +++++++++--------- .../zts/cert/X509RoleCertRequestTest.java | 35 ++++---- .../zts/cert/X509ServiceCertRequestTest.java | 41 +++++---- 19 files changed, 641 insertions(+), 160 deletions(-) create mode 100644 libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriManager.java create mode 100644 libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriValidator.java create mode 100644 libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriBasic.java create mode 100644 libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriTrustDomain.java create mode 100644 libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriManagerTest.java create mode 100644 libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriValidatorTest.java create mode 100644 libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriBasicTest.java create mode 100644 libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriTrustDomainTest.java diff --git a/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriManager.java b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriManager.java new file mode 100644 index 00000000000..1ab8fdffaa5 --- /dev/null +++ b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriManager.java @@ -0,0 +1,89 @@ +/* + * + * * Copyright The Athenz Authors + * * + * * 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. + * + */ + +package com.yahoo.athenz.common.server.spiffe; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class SpiffeUriManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(SpiffeUriManager.class); + + public static final String ZTS_PROP_SPIFFE_URI_VALIDATOR_CLASSES = "athenz.zts.spiffe_uri_validator_classes"; + public static final String ZTS_DEFAULT_SPIFFE_URI_VALIDATOR_CLASSES = "com.yahoo.athenz.common.server.spiffe.impl.SpiffeUriTrustDomain,com.yahoo.athenz.common.server.spiffe.impl.SpiffeUriBasic"; + + private final List validators; + + public SpiffeUriManager() { + + final String validatorClasses = System.getProperty(ZTS_PROP_SPIFFE_URI_VALIDATOR_CLASSES, + ZTS_DEFAULT_SPIFFE_URI_VALIDATOR_CLASSES); + + validators = new ArrayList<>(); + String[] validatorClassList = validatorClasses.split(","); + for (String validatorClass : validatorClassList) { + SpiffeUriValidator validator = getValidator(validatorClass.trim()); + if (validator == null) { + throw new IllegalArgumentException("Invalid spiffe uri validator: " + validatorClass); + } + validators.add(validator); + } + } + + SpiffeUriValidator getValidator(String className) { + + LOGGER.debug("Loading spiffe uri validator {}...", className); + + SpiffeUriValidator validator; + try { + validator = (SpiffeUriValidator) Class.forName(className).getDeclaredConstructor().newInstance(); + } catch (Exception ex) { + LOGGER.error("Invalid validator class: {}", className, ex); + return null; + } + return validator; + } + + public boolean validateServiceCertUri(final String spiffeUri, final String domainName, final String serviceName, + final String namespace) { + + for (SpiffeUriValidator validator : validators) { + if (validator.validateServiceCertUri(spiffeUri, domainName, serviceName, namespace)) { + return true; + } + } + LOGGER.error("unable to validate service spiffe uri: {}, domainName: {}, serviceName: {}, namespace: {}", + spiffeUri, domainName, serviceName, namespace); + return false; + } + + public boolean validateRoleCertUri(final String spiffeUri, final String domainName, final String roleName) { + for (SpiffeUriValidator validator : validators) { + if (validator.validateRoleCertUri(spiffeUri, domainName, roleName)) { + return true; + } + } + LOGGER.error("unable to validate role spiffe uri: {}, domainName: {}, roleName: {}", + spiffeUri, domainName, roleName); + return false; + } +} diff --git a/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriValidator.java b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriValidator.java new file mode 100644 index 00000000000..9512a530345 --- /dev/null +++ b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriValidator.java @@ -0,0 +1,45 @@ +/* + * + * * Copyright The Athenz Authors + * * + * * 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. + * + */ + +package com.yahoo.athenz.common.server.spiffe; + +/** + * An interface that allows system administrators to validate SPIFFE URIs + * based on their own requirements. + */ +public interface SpiffeUriValidator { + + /** + * Validate the SPIFFE URI for service identity certificates based on the system requirements. + * @param spiffeUri the SPIFFE URI to be validated (e.g. spiffe://athenz.domain/sa/service) + * @param domainName the domain name of the service + * @param serviceName the service name + * @param namespace the namespace of the service (typically a Kubernetes namespace) + * @return true if the SPIFFE URI is valid, false otherwise + */ + boolean validateServiceCertUri(final String spiffeUri, final String domainName, final String serviceName, final String namespace); + + /** + * Validate the SPIFFE URI for rike certificates based on the system requirements. + * @param spiffeUri the SPIFFE URI to be validated (e.g. spiffe://athenz.domain/ra/writers) + * @param domainName the domain name of the service + * @param roleName the role name + * @return true if the SPIFFE URI is valid, false otherwise + */ + boolean validateRoleCertUri(final String spiffeUri, final String domainName, final String roleName); +} diff --git a/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriBasic.java b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriBasic.java new file mode 100644 index 00000000000..7ec1ba18dc4 --- /dev/null +++ b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriBasic.java @@ -0,0 +1,52 @@ +/* + * + * * Copyright The Athenz Authors + * * + * * 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. + * + */ + +package com.yahoo.athenz.common.server.spiffe.impl; + +import com.yahoo.athenz.common.server.spiffe.SpiffeUriValidator; + +/** + * Basic implementation of SpiffeUriValidator interface. This class validates the SPIFFE URI + * with the following formats: + * Service Cert URI: spiffe:///sa/ + * Example: spiffe://athenz/sa/api + * Role Cert URI: spiffe:///ra/ + * Example: spiffe://athenz/ra/readers + */ +public class SpiffeUriBasic implements SpiffeUriValidator { + + /** + * Supported Service Cert URI: spiffe:///sa/ + * Example: spiffe://athenz/sa/api + */ + @Override + public boolean validateServiceCertUri(String spiffeUri, String domainName, String serviceName, String namespace) { + final String reqUri = String.format("spiffe://%s/sa/%s", domainName, serviceName); + return reqUri.equalsIgnoreCase(spiffeUri); + } + + /** + * Supported Role Cert URI: spiffe:///ra/ + * Example: spiffe://athenz/ra/readers + */ + @Override + public boolean validateRoleCertUri(String spiffeUri, String domainName, String roleName) { + final String reqUri = String.format("spiffe://%s/ra/%s", domainName, roleName); + return reqUri.equalsIgnoreCase(spiffeUri); + } +} diff --git a/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriTrustDomain.java b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriTrustDomain.java new file mode 100644 index 00000000000..c992603ff3f --- /dev/null +++ b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriTrustDomain.java @@ -0,0 +1,61 @@ +/* + * + * * Copyright The Athenz Authors + * * + * * 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. + * + */ + +package com.yahoo.athenz.common.server.spiffe.impl; + +import com.yahoo.athenz.common.server.spiffe.SpiffeUriValidator; +import org.eclipse.jetty.util.StringUtil; + +/** + * Trust Domain implementation of SpiffeUriValidator interface. This class validates the SPIFFE URI + * with the following formats: + * Service Cert URI: spiffe:///ns//sa/. + * Example: spiffe://athenz.io/ns/prod/sa/athenz.api + * Role Cert URI: spiffe:///ns//ra/ + * Example: spiffe://athenz.io/ns/athenz/ra/readers + */ +public class SpiffeUriTrustDomain implements SpiffeUriValidator { + + private static final String SPIFFE_DEFAULT_NAMESPACE = "default"; + + private static final String SPIFFE_PROP_TRUST_DOMAIN = "athenz.zts.spiffe_trust_domain"; + private static final String SPIFFE_TRUST_DOMAIN = System.getProperty(SPIFFE_PROP_TRUST_DOMAIN, "athenz.io"); + + /** + * Service Cert URI: spiffe:///ns//sa/. + * Example: spiffe://athenz.io/ns/prod/sa/athenz.api + */ + @Override + public boolean validateServiceCertUri(String spiffeUri, String domainName, String serviceName, String namespace) { + final String ns = StringUtil.isEmpty(namespace) ? SPIFFE_DEFAULT_NAMESPACE : namespace; + final String reqUri = String.format("spiffe://%s/ns/%s/sa/%s.%s", SPIFFE_TRUST_DOMAIN, + ns, domainName, serviceName); + return reqUri.equalsIgnoreCase(spiffeUri); + } + + /** + * Role Cert URI: spiffe:///ns//ra/ + * Example: spiffe://athenz.io/ns/athenz/ra/readers + */ + @Override + public boolean validateRoleCertUri(String spiffeUri, String domainName, String roleName) { + final String reqUri = String.format("spiffe://%s/ns/%s/ra/%s", SPIFFE_TRUST_DOMAIN, + domainName, roleName); + return reqUri.equalsIgnoreCase(spiffeUri); + } +} diff --git a/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriManagerTest.java b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriManagerTest.java new file mode 100644 index 00000000000..8b2197eeb5e --- /dev/null +++ b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriManagerTest.java @@ -0,0 +1,87 @@ +/* + * Copyright The Athenz Authors + * + * 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. + */ + +package com.yahoo.athenz.common.server.spiffe; + +import com.yahoo.athenz.common.server.spiffe.impl.SpiffeUriTrustDomain; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class SpiffeUriManagerTest { + + @BeforeClass + public void setup() { + System.setProperty("athenz.zts.spiffe_trust_domain", "spiffe.athenz.io"); + } + + @Test + public void testValidateServiceCertUriDefaultClasses() { + + System.clearProperty("athenz.zts.spiffe_uri_validator_classes"); + SpiffeUriManager manager = new SpiffeUriManager(); + + assertTrue(manager.validateServiceCertUri("spiffe://athenz/sa/api", "athenz", "api", null)); + assertTrue(manager.validateServiceCertUri("spiffe://athenz/sa/api", "athenz", "api", "default")); + + assertFalse(manager.validateServiceCertUri("spiffe://athenz/sa/api", "athenz.prod", "api", "default")); + assertFalse(manager.validateServiceCertUri("spiffe://athenz/sa/api", "athenz", "backend", "default")); + + assertTrue(manager.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/default/sa/athenz.api", "athenz", "api", null)); + assertTrue(manager.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/default/sa/athenz.api", "athenz", "api", "default")); + assertTrue(manager.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/prod/sa/athenz.api", "athenz", "api", "prod")); + + assertFalse(manager.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/default/sa/athenz.api", "athenz", "api", "prod")); + assertFalse(manager.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/default/sa/athenz.backend", "athenz", "api", "default")); + assertFalse(manager.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/prod/sa/athenz.api", "athenz.prod", "api", "prod")); + + assertFalse(manager.validateServiceCertUri("spiffe://athenz.io/ns/prod/sa/athenz.api", "athenz", "api", "prod")); + } + + @Test + public void testValidateRoleCertUriDefaultClasses() { + + System.clearProperty("athenz.zts.spiffe_uri_validator_classes"); + SpiffeUriManager manager = new SpiffeUriManager(); + + assertTrue(manager.validateRoleCertUri("spiffe://athenz/ra/readers", "athenz", "readers")); + assertTrue(manager.validateRoleCertUri("spiffe://athenz/ra/writers", "athenz", "writers")); + + assertFalse(manager.validateRoleCertUri("spiffe://athenz/ra/readers", "athenz.prod", "readers")); + assertFalse(manager.validateRoleCertUri("spiffe://athenz/ra/readers", "athenz", "writers")); + + assertTrue(manager.validateRoleCertUri("spiffe://spiffe.athenz.io/ns/athenz/ra/readers", "athenz", "readers")); + + assertFalse(manager.validateRoleCertUri("spiffe://spiffe.athenz.io/ns/athenz/ra/readers", "athenz", "writers")); + assertFalse(manager.validateRoleCertUri("spiffe://spiffe.athenz.io/ns/athenz/ra/readers", "athenz.prod", "readers")); + + assertFalse(manager.validateRoleCertUri("spiffe://athenz.io/ns/athenz/ra/readers", "athenz", "readers")); + } + + @Test + public void testValidateInvalidClass() { + + System.setProperty("athenz.zts.spiffe_uri_validator_classes", "com.yahoo.athenz.common.server.spiffe.impl.InvalidClass"); + try { + new SpiffeUriManager(); + fail(); + } catch (IllegalArgumentException ex) { + assertTrue(ex.getMessage().contains("Invalid spiffe uri validator: com.yahoo.athenz.common.server.spiffe.impl.InvalidClass")); + } + System.clearProperty("athenz.zts.spiffe_uri_validator_classes"); + } +} diff --git a/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriValidatorTest.java b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriValidatorTest.java new file mode 100644 index 00000000000..be98dbb77b2 --- /dev/null +++ b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/SpiffeUriValidatorTest.java @@ -0,0 +1,53 @@ +/* + * Copyright The Athenz Authors + * + * 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. + */ + +package com.yahoo.athenz.common.server.spiffe; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +public class SpiffeUriValidatorTest { + + @Test + public void testValidate() { + + final String trustDomain = "athenz.io"; + + SpiffeUriValidator validator = new SpiffeUriValidator() { + @Override + public boolean validateServiceCertUri(String spiffeUri, String domainName, String serviceName, String namespace) { + final String expectedUri = String.format("spiffe://%s/ns/%s/sa/%s.%s", trustDomain, namespace, + domainName, serviceName); + return spiffeUri.equals(expectedUri); + } + + @Override + public boolean validateRoleCertUri(String spiffeUri, String domainName, String roleName) { + final String expectedUri = String.format("spiffe://%s/ns/%s/ra/%s", trustDomain, + domainName, roleName); + return spiffeUri.equals(expectedUri); + } + }; + + assertTrue(validator.validateServiceCertUri("spiffe://athenz.io/ns/prod/sa/athenz.api", "athenz", "api", "prod")); + assertFalse(validator.validateServiceCertUri("spiffe://athenz.io/ns/prod/sa/athenz.api", "athenz", "api", "dev")); + + assertTrue(validator.validateRoleCertUri("spiffe://athenz.io/ns/athenz/ra/readers", "athenz", "readers")); + assertFalse(validator.validateRoleCertUri("spiffe://athenz.io/ns/athenz/ra/readers", "athenz", "writers")); + } +} diff --git a/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriBasicTest.java b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriBasicTest.java new file mode 100644 index 00000000000..198c9106229 --- /dev/null +++ b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriBasicTest.java @@ -0,0 +1,47 @@ +/* + * Copyright The Athenz Authors + * + * 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. + */ + +package com.yahoo.athenz.common.server.spiffe.impl; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +public class SpiffeUriBasicTest { + + @Test + public void testValidateServiceCertUri() { + SpiffeUriBasic validator = new SpiffeUriBasic(); + + assertTrue(validator.validateServiceCertUri("spiffe://athenz/sa/api", "athenz", "api", null)); + assertTrue(validator.validateServiceCertUri("spiffe://athenz/sa/api", "athenz", "api", "default")); + + assertFalse(validator.validateServiceCertUri("spiffe://athenz/sa/api", "athenz.prod", "api", "default")); + assertFalse(validator.validateServiceCertUri("spiffe://athenz/sa/api", "athenz", "backend", "default")); + } + + @Test + public void testValidateRoleCertUri() { + SpiffeUriBasic validator = new SpiffeUriBasic(); + + assertTrue(validator.validateRoleCertUri("spiffe://athenz/ra/readers", "athenz", "readers")); + assertTrue(validator.validateRoleCertUri("spiffe://athenz/ra/writers", "athenz", "writers")); + + assertFalse(validator.validateRoleCertUri("spiffe://athenz/ra/readers", "athenz.prod", "readers")); + assertFalse(validator.validateRoleCertUri("spiffe://athenz/ra/readers", "athenz", "writers")); + } +} diff --git a/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriTrustDomainTest.java b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriTrustDomainTest.java new file mode 100644 index 00000000000..1d4b5af2ae5 --- /dev/null +++ b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/spiffe/impl/SpiffeUriTrustDomainTest.java @@ -0,0 +1,58 @@ +/* + * Copyright The Athenz Authors + * + * 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. + */ + +package com.yahoo.athenz.common.server.spiffe.impl; + +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +public class SpiffeUriTrustDomainTest { + + @BeforeClass + public void setup() { + System.setProperty("athenz.zts.spiffe_trust_domain", "spiffe.athenz.io"); + } + + @Test + public void testValidateServiceCertUri() { + + SpiffeUriTrustDomain validator = new SpiffeUriTrustDomain(); + assertTrue(validator.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/default/sa/athenz.api", "athenz", "api", null)); + assertTrue(validator.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/default/sa/athenz.api", "athenz", "api", "default")); + assertTrue(validator.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/prod/sa/athenz.api", "athenz", "api", "prod")); + + assertFalse(validator.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/default/sa/athenz.api", "athenz", "api", "prod")); + assertFalse(validator.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/default/sa/athenz.backend", "athenz", "api", "default")); + assertFalse(validator.validateServiceCertUri("spiffe://spiffe.athenz.io/ns/prod/sa/athenz.api", "athenz.prod", "api", "prod")); + + assertFalse(validator.validateServiceCertUri("spiffe://athenz.io/ns/prod/sa/athenz.api", "athenz", "api", "prod")); + } + + @Test + public void testValidateRoleCertUri() { + + SpiffeUriTrustDomain validator = new SpiffeUriTrustDomain(); + assertTrue(validator.validateRoleCertUri("spiffe://spiffe.athenz.io/ns/athenz/ra/readers", "athenz", "readers")); + + assertFalse(validator.validateRoleCertUri("spiffe://spiffe.athenz.io/ns/athenz/ra/readers", "athenz", "writers")); + assertFalse(validator.validateRoleCertUri("spiffe://spiffe.athenz.io/ns/athenz/ra/readers", "athenz.prod", "readers")); + + assertFalse(validator.validateRoleCertUri("spiffe://athenz.io/ns/athenz/ra/readers", "athenz", "readers")); + } +} diff --git a/libs/java/server_k8s_common/src/test/java/io/athenz/server/k8s/common/impl/KubernetesPodResolverUtilTest.java b/libs/java/server_k8s_common/src/test/java/io/athenz/server/k8s/common/impl/KubernetesPodResolverUtilTest.java index 3ca48c54347..03abcc08719 100644 --- a/libs/java/server_k8s_common/src/test/java/io/athenz/server/k8s/common/impl/KubernetesPodResolverUtilTest.java +++ b/libs/java/server_k8s_common/src/test/java/io/athenz/server/k8s/common/impl/KubernetesPodResolverUtilTest.java @@ -43,24 +43,16 @@ public void testGetPodSiblings() throws UnknownHostException { @Test public void testGetPodSiblingsEmptyServiceNameException() { String serviceName = ""; - Exception ex = null; try { KubernetesPodResolverUtil.getSiblingPodIPs(serviceName); - } catch (IllegalArgumentException | UnknownHostException e) { - ex = e; - } - if (ex == null) { Assert.fail("expected IllegalArgumentException not thrown"); + } catch (IllegalArgumentException | UnknownHostException ignored) { } - Exception nullEx = null; try { KubernetesPodResolverUtil.getSiblingPodIPs(null); - } catch (IllegalArgumentException | UnknownHostException e) { - nullEx = e; - } - if (nullEx == null) { Assert.fail("expected IllegalArgumentException not thrown"); + } catch (IllegalArgumentException | UnknownHostException ignored) { } } @@ -69,15 +61,18 @@ public void testGetPodSiblingsInvalidHostnameException() { String serviceName = "foo"; MockedStatic inetAddressMock = Mockito.mockStatic(InetAddress.class); inetAddressMock.when(() -> InetAddress.getAllByName(serviceName)).thenThrow(UnknownHostException.class); - Exception ex = null; try { KubernetesPodResolverUtil.getSiblingPodIPs(serviceName); - } catch (IllegalArgumentException | UnknownHostException e) { - ex = e; - } - if (ex == null) { Assert.fail("expected UnknownHostException not thrown"); + } catch (IllegalArgumentException | UnknownHostException ignored) { } inetAddressMock.close(); } + + @Test + public void testConstructor() { + // test to get code coverage to 100% + KubernetesPodResolverUtil util = new KubernetesPodResolverUtil(); + Assert.assertNotNull(util); + } } diff --git a/servers/zts/conf/zts.properties b/servers/zts/conf/zts.properties index 7ca45f937e8..85934efb89c 100644 --- a/servers/zts/conf/zts.properties +++ b/servers/zts/conf/zts.properties @@ -810,3 +810,14 @@ athenz.zts.k8s_provider_distribution_validator_factory_class=com.yahoo.athenz.in # as duration * timeunit, and the CertRecordCleaner will run at this defined interval. #athenz.zts.cert_record_cleaner_duration=1 #athenz.zts.cert_record_cleaner_timeunit=day + +# This property specifies a comma separated list of Spiffe URI validator classes. +# The class must implement the com.yahoo.athenz.common.server.spiffe interface from +# the athenz-server-common package. The server will use the classes in the order +# they are specified in the list. By default, the server uses both SpiffeUriTrustDomain +# and SpiffeUriBasic classes. +#athenz.zts.spiffe_uri_validator_classes=com.yahoo.athenz.common.server.spiffe.impl.SpiffeUriTrustDomain,com.yahoo.athenz.common.server.spiffe.impl.SpiffeUriBasic + +# This property specifies the Spiffe trust domain that the server will use to validate +# the Spiffe URI in the request if SpiffeUriTrustDomain validator is enabled. +#athenz.zts.spiffe_trust_domain=athenz.io diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSConsts.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSConsts.java index 4dbe4934dc7..5ccaea68ead 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSConsts.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSConsts.java @@ -55,7 +55,6 @@ public final class ZTSConsts { public static final String ZTS_PROP_READ_ONLY_MODE = "athenz.zts.read_only_mode"; public static final String ZTS_PROP_HEALTH_CHECK_PATH = "athenz.zts.health_check_path"; public static final String ZTS_PROP_SERVER_REGION = "athenz.zts.server_region"; - public static final String ZTS_PROP_SPIFFE_TRUST_DOMAIN = "athenz.zts.spiffe_trust_domain"; public static final String ZTS_PROP_AWS_CREDS_CACHE_TIMEOUT = "athenz.zts.aws_creds_cache_timeout"; public static final String ZTS_PROP_AWS_CREDS_INVALID_CACHE_TIMEOUT = "athenz.zts.aws_creds_invalid_cache_timeout"; diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSImpl.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSImpl.java index d4cb010dd96..93083a3ceb8 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSImpl.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSImpl.java @@ -45,6 +45,7 @@ import com.yahoo.athenz.common.server.rest.Http; import com.yahoo.athenz.common.server.rest.Http.AuthorityList; import com.yahoo.athenz.common.server.ServerResourceException; +import com.yahoo.athenz.common.server.spiffe.SpiffeUriManager; import com.yahoo.athenz.common.server.ssh.SSHCertRecord; import com.yahoo.athenz.common.server.status.StatusCheckException; import com.yahoo.athenz.common.server.status.StatusChecker; @@ -183,6 +184,7 @@ public class ZTSImpl implements KeyStore, ZTSHandler { private final Object updateJWKMutex = new Object(); protected ExternalCredentialsManager externalCredentialsManager; protected DynamicConfigInteger serviceCertDefaultExpiryMins; + protected SpiffeUriManager spiffeUriManager; private static final String TYPE_DOMAIN_NAME = "DomainName"; private static final String TYPE_SIMPLE_NAME = "SimpleName"; @@ -386,6 +388,10 @@ public ZTSImpl(CloudStore implCloudStore, DataStore implDataStore) { // initialize our external credentials providers externalCredentialsManager = new ExternalCredentialsManager(authorizer); + + // load spiffe uri validators + + spiffeUriManager = new SpiffeUriManager(); } void loadJsonMapper() { @@ -2875,7 +2881,7 @@ public RoleToken postRoleCertificateRequest(ResourceContext ctx, String domainNa X509RoleCertRequest certReq; try { - certReq = new X509RoleCertRequest(req.getCsr()); + certReq = new X509RoleCertRequest(req.getCsr(), spiffeUriManager); } catch (CryptoException ex) { throw requestError("Unable to parse PKCS10 CSR: " + ex.getMessage(), caller, domainName, principalDomain); @@ -3224,7 +3230,7 @@ public RoleCertificate postRoleCertificateRequestExt(ResourceContext ctx, RoleCe X509RoleCertRequest certReq; try { - certReq = new X509RoleCertRequest(req.getCsr()); + certReq = new X509RoleCertRequest(req.getCsr(), spiffeUriManager); } catch (CryptoException ex) { throw requestError("Unable to parse PKCS10 CSR: " + ex.getMessage(), caller, principalDomain, principalDomain); @@ -3769,7 +3775,7 @@ public Response postInstanceRegisterInformation(ResourceContext ctx, InstanceReg X509ServiceCertRequest certReq; try { - certReq = new X509ServiceCertRequest(info.getCsr()); + certReq = new X509ServiceCertRequest(info.getCsr(), spiffeUriManager); } catch (CryptoException ex) { throw requestError("unable to parse PKCS10 CSR: " + ex.getMessage(), caller, domain, principalDomain); @@ -4307,7 +4313,7 @@ InstanceIdentity processProviderX509RefreshRequest(ResourceContext ctx, DomainDa final String principalDomain = principal.getDomain(); X509ServiceCertRequest certReq; try { - certReq = new X509ServiceCertRequest(info.getCsr()); + certReq = new X509ServiceCertRequest(info.getCsr(), spiffeUriManager); } catch (CryptoException ex) { throw requestError("unable to parse PKCS10 CSR", caller, domain, principalDomain); } @@ -4823,7 +4829,7 @@ public Identity postInstanceRefreshRequest(ResourceContext ctx, String domain, X509ServiceCertRequest x509CertReq; try { - x509CertReq = new X509ServiceCertRequest(req.getCsr()); + x509CertReq = new X509ServiceCertRequest(req.getCsr(), spiffeUriManager); } catch (CryptoException ex) { throw requestError("Unable to parse PKCS10 certificate request", caller, domain, principalDomain); diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509CertRequest.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509CertRequest.java index 8f3dabfa03b..506a6334d08 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509CertRequest.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509CertRequest.java @@ -23,6 +23,7 @@ import java.util.regex.Pattern; import com.yahoo.athenz.common.server.dns.HostnameResolver; +import com.yahoo.athenz.common.server.spiffe.SpiffeUriManager; import com.yahoo.athenz.common.utils.X509CertUtils; import com.yahoo.athenz.zts.CertType; import com.yahoo.athenz.zts.ZTSConsts; @@ -39,9 +40,6 @@ public class X509CertRequest { private static final Logger LOGGER = LoggerFactory.getLogger(X509CertRequest.class); private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+"); - protected static final String SPIFFE_NAMESPACE_AGENT = "ns"; - protected static final String SPIFFE_TRUST_DOMAIN = System.getProperty(ZTSConsts.ZTS_PROP_SPIFFE_TRUST_DOMAIN, "athenz.io"); - protected PKCS10CertificationRequest certReq; protected String instanceId; protected String uriHostname; @@ -53,8 +51,9 @@ public class X509CertRequest { protected List providerDnsNames; protected List ipAddresses; protected List uris; + protected SpiffeUriManager spiffeUriManager; - public X509CertRequest(String csr) throws CryptoException { + public X509CertRequest(String csr, SpiffeUriManager spiffeUriManager) throws CryptoException { certReq = Crypto.getPKCS10CertRequest(csr); if (certReq == null) { @@ -106,6 +105,10 @@ public X509CertRequest(String csr) throws CryptoException { if (instanceId == null) { instanceId = X509CertUtils.extractRequestInstanceIdFromDnsNames(dnsNames); } + + // save the spiffe uri manager object + + this.spiffeUriManager = spiffeUriManager; } public PKCS10CertificationRequest getCertReq() { diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509RoleCertRequest.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509RoleCertRequest.java index e171ca28bfd..d89881e95a1 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509RoleCertRequest.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509RoleCertRequest.java @@ -18,6 +18,7 @@ import com.yahoo.athenz.auth.AuthorityConsts; import com.yahoo.athenz.auth.util.Crypto; import com.yahoo.athenz.auth.util.CryptoException; +import com.yahoo.athenz.common.server.spiffe.SpiffeUriManager; import com.yahoo.athenz.common.utils.X509CertUtils; import com.yahoo.athenz.zts.ZTSConsts; import com.yahoo.athenz.zts.utils.ZTSUtils; @@ -32,17 +33,15 @@ public class X509RoleCertRequest extends X509CertRequest { private static final Logger LOGGER = LoggerFactory.getLogger(X509RoleCertRequest.class); - private static final String SPIFFE_ROLE_AGENT = "ra"; - protected String reqRoleName; protected String reqRoleDomain; protected String rolePrincipal; - public X509RoleCertRequest(String csr) throws CryptoException { + public X509RoleCertRequest(String csr, SpiffeUriManager spiffeUriManager) throws CryptoException { // parse the csr request - super(csr); + super(csr, spiffeUriManager); // make sure the CN is a valid role name @@ -230,26 +229,13 @@ public boolean validateIPAddress(X509Certificate cert, final String ip) { public boolean validateSpiffeURI(final String domainName, final String roleName) { - // the expected format are: - // spiffe:///ra/ - // e.g. spiffe://sports/ra/hockey-writers - // spiffe:///ns//ra/ - // e.g. spiffe://athenz.io/ns/sports/ra/hockey-writers + // validate the spiffe uri according to our configured validators if (spiffeUri == null) { return true; } - final String reqUri1 = "spiffe://" + domainName + "/" + SPIFFE_ROLE_AGENT + "/" + roleName; - final String reqUri2 = "spiffe://" + SPIFFE_TRUST_DOMAIN + "/" + SPIFFE_NAMESPACE_AGENT + "/" + - domainName + "/" + SPIFFE_ROLE_AGENT + "/" + roleName; - boolean uriVerified = reqUri1.equalsIgnoreCase(spiffeUri) || reqUri2.equalsIgnoreCase(spiffeUri); - - if (!uriVerified) { - LOGGER.error("validateSpiffeURI: spiffe uri mismatch: {}/{}/{}", spiffeUri, reqUri1, reqUri2); - } - - return uriVerified; + return spiffeUriManager.validateRoleCertUri(spiffeUri, domainName, roleName); } } diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509ServiceCertRequest.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509ServiceCertRequest.java index 61737a4889f..353b9594158 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509ServiceCertRequest.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509ServiceCertRequest.java @@ -19,20 +19,14 @@ import java.util.Set; import com.yahoo.athenz.auth.util.CryptoException; import com.yahoo.athenz.common.server.dns.HostnameResolver; +import com.yahoo.athenz.common.server.spiffe.SpiffeUriManager; import com.yahoo.athenz.zts.cache.DataCache; import org.eclipse.jetty.util.StringUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class X509ServiceCertRequest extends X509CertRequest { - private static final Logger LOGGER = LoggerFactory.getLogger(X509ServiceCertRequest.class); - - public static final String SPIFFE_SERVICE_AGENT = "sa"; - public static final String SPIFFE_DEFAULT_NAMESPACE = "default"; - - public X509ServiceCertRequest(String csr) throws CryptoException { - super(csr); + public X509ServiceCertRequest(String csr, SpiffeUriManager spiffeUriManager) throws CryptoException { + super(csr, spiffeUriManager); } public boolean validate(final String domainName, final String serviceName, final String provider, @@ -91,26 +85,12 @@ public boolean validate(final String domainName, final String serviceName, final public boolean validateSpiffeURI(final String domainName, final String serviceName, final String namespace) { - // the expected format are: - // spiffe:///sa/ - // e.g. spiffe://sports/sa/api - // spiffe:///ns//sa/ - // e.g. spiffe://athenz.io/ns/default/sa/sports.api + // validate the spiffe uri according to our configured validators if (spiffeUri == null) { return true; } - final String ns = StringUtil.isEmpty(namespace) ? SPIFFE_DEFAULT_NAMESPACE : namespace; - final String reqUri1 = "spiffe://" + domainName + "/" + SPIFFE_SERVICE_AGENT + "/" + serviceName; - final String reqUri2 = "spiffe://" + SPIFFE_TRUST_DOMAIN + "/" + SPIFFE_NAMESPACE_AGENT + "/" + - ns + "/" + SPIFFE_SERVICE_AGENT + "/" + domainName + "." + serviceName; - boolean uriVerified = reqUri1.equalsIgnoreCase(spiffeUri) || reqUri2.equalsIgnoreCase(spiffeUri); - - if (!uriVerified) { - LOGGER.error("validateSpiffeURI: spiffe uri mismatch: {}/{}/{}", spiffeUri, reqUri1, reqUri2); - } - - return uriVerified; + return spiffeUriManager.validateServiceCertUri(spiffeUri, domainName, serviceName, namespace); } } diff --git a/servers/zts/src/test/java/com/yahoo/athenz/zts/ZTSImplTest.java b/servers/zts/src/test/java/com/yahoo/athenz/zts/ZTSImplTest.java index b6d715789ef..e23ef12ea09 100644 --- a/servers/zts/src/test/java/com/yahoo/athenz/zts/ZTSImplTest.java +++ b/servers/zts/src/test/java/com/yahoo/athenz/zts/ZTSImplTest.java @@ -4218,7 +4218,7 @@ public void testValidateRoleCertificateRequestMismatchEmail() throws IOException Path path = Paths.get("src/test/resources/valid_email.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, zts.spiffeUriManager); zts.validCertSubjectOrgValues = null; assertFalse(zts.validateRoleCertificateRequest(certReq, "sports.standings", @@ -4231,7 +4231,7 @@ public void testValidateRoleCertificateRequestNoEmail() throws IOException { Path path = Paths.get("src/test/resources/valid_noemail.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, zts.spiffeUriManager); zts.validCertSubjectOrgValues = null; assertFalse(zts.validateRoleCertificateRequest(certReq, "no-email", null, @@ -4244,7 +4244,7 @@ public void testValidateRoleCertificateRequestInvalidOField() throws IOException Path path = Paths.get("src/test/resources/valid_email.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, zts.spiffeUriManager); Set validOValues = new HashSet<>(); validOValues.add("InvalidCompany"); @@ -4259,7 +4259,7 @@ public void testValidateRoleCertificateRequest() throws IOException { Path path = Paths.get("src/test/resources/valid_email.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, zts.spiffeUriManager); zts.validCertSubjectOrgValues = null; assertTrue(zts.validateRoleCertificateRequest(certReq, "sports.scores", @@ -4285,7 +4285,7 @@ public void testValidateRoleCertificateRequestOU() throws IOException { zts.validCertSubjectOrgUnitValues = ouValues; zts.verifyCertSubjectOU = true; - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, zts.spiffeUriManager); assertFalse(zts.validateRoleCertificateRequest(certReq, "sports.scores", null, null, "10.0.0.1")); ouValues.add("Testing Domain"); @@ -4301,7 +4301,7 @@ public void testValidateRoleCertificateRequestWithUriHostname() throws IOExcepti String pem = new String(Files.readAllBytes(path)); X509Certificate cert = Crypto.loadX509Certificate(pem); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, zts.spiffeUriManager); // if the CSR has hostname, but the cert doesn't have hostname, it should result in false assertFalse(zts.validateRoleCertificateRequest(certReq, "athenz.examples.httpd", @@ -4316,7 +4316,7 @@ public void testValidateRoleCertificateRequestWithUriHostname() throws IOExcepti path = Paths.get("src/test/resources/athenz.examples.role-uri-instanceid-hostname.csr"); csr = new String(Files.readAllBytes(path)); - certReq = new X509RoleCertRequest(csr); + certReq = new X509RoleCertRequest(csr, zts.spiffeUriManager); // if CSR has hostname+instanceid, and cert has only hostname, it should result in false assertFalse(zts.validateRoleCertificateRequest(certReq, "athenz.examples.httpd", @@ -4382,7 +4382,7 @@ public void testValidateRoleCertificateRequestOUWithCert() throws IOException { pem = new String(Files.readAllBytes(path)); X509Certificate invalidCert = Crypto.loadX509Certificate(pem); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, zts.spiffeUriManager); zts.validCertSubjectOrgValues = null; @@ -4408,7 +4408,7 @@ public void testValidateRoleCertificateRequestMismatchIP() throws IOException { String pem = new String(Files.readAllBytes(path)); X509Certificate cert = Crypto.loadX509Certificate(pem); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, zts.spiffeUriManager); // disable IP validation and we should get success @@ -4440,7 +4440,7 @@ public void testProcessRoleCertificateRequestFailedValidation() { RoleCertificateRequest req = new RoleCertificateRequest(); - X509RoleCertRequest certReq = new X509RoleCertRequest(ROLE_CERT_CORETECH_REQUEST); + X509RoleCertRequest certReq = new X509RoleCertRequest(ROLE_CERT_CORETECH_REQUEST, zts.spiffeUriManager); Set origUnitValues = zts.validCertSubjectOrgUnitValues; boolean verifyCertSubjectOU = zts.verifyCertSubjectOU; @@ -9065,7 +9065,7 @@ public void testValidateServiceX509RefreshRequest() throws IOException { Path path = Paths.get("src/test/resources/valid_provider_refresh.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, ztsImpl.spiffeUriManager); assertNotNull(certReq); path = Paths.get("src/test/resources/valid_provider_refresh.pem"); @@ -9092,7 +9092,7 @@ public void testValidateServiceX509RefreshRequestMismatchPublicKeys() throws IOE Path path = Paths.get("src/test/resources/valid_provider_refresh.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, ztsImpl.spiffeUriManager); assertNotNull(certReq); certReq.setNormCsrPublicKey("mismatch-public-key"); @@ -9120,7 +9120,7 @@ public void testValidateServiceX509RefreshRequestNotAllowedIP() throws IOExcepti Path path = Paths.get("src/test/resources/valid_provider_refresh.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, ztsImpl.spiffeUriManager); assertNotNull(certReq); path = Paths.get("src/test/resources/valid_provider_refresh.pem"); @@ -9149,7 +9149,7 @@ public void testValidateServiceX509RefreshRequestMismatchDns() throws IOExceptio Path path = Paths.get("src/test/resources/athenz.mismatch.dns.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, ztsImpl.spiffeUriManager); assertNotNull(certReq); path = Paths.get("src/test/resources/athenz.instanceid.pem"); @@ -14606,7 +14606,7 @@ public void testGenerateInstanceConfirmObjectWithCtxCert() throws IOException { path = Paths.get("src/test/resources/athenz.instanceid.csr"); String certCsr = new String(Files.readAllBytes(path)); - X509CertRequest certRequest = new X509ServiceCertRequest(certCsr); + X509CertRequest certRequest = new X509ServiceCertRequest(certCsr, zts.spiffeUriManager); InstanceConfirmation confirmation = ztsImpl.newInstanceConfirmationForRegister(context, "secureboot.provider", diff --git a/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509CertRequestTest.java b/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509CertRequestTest.java index 2357fa2a3eb..9d425abd4ee 100644 --- a/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509CertRequestTest.java +++ b/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509CertRequestTest.java @@ -25,6 +25,7 @@ import static org.testng.Assert.*; import com.yahoo.athenz.common.server.dns.HostnameResolver; +import com.yahoo.athenz.common.server.spiffe.SpiffeUriManager; import com.yahoo.athenz.zts.CertType; import com.yahoo.athenz.zts.cache.DataCache; import com.yahoo.athenz.zts.cert.impl.TestHostnameResolver; @@ -37,13 +38,15 @@ public class X509CertRequestTest { + final SpiffeUriManager spiffeUriManager = new SpiffeUriManager(); + @Test public void testConstructorValidCsr() throws IOException { Path path = Paths.get("src/test/resources/valid_email.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); } @@ -52,7 +55,7 @@ public void testConstructorInvalidCsr() { X509CertRequest certReq = null; try { - certReq = new X509CertRequest("csr"); + certReq = new X509CertRequest("csr", spiffeUriManager); fail(); } catch (CryptoException ignored) { } @@ -63,14 +66,14 @@ public void testConstructorInvalidCsr() { public void testConstructorValidUriHostname() throws IOException { Path path = Paths.get("src/test/resources/athenz.examples.uri-instanceid-hostname.csr"); - X509CertRequest certReq = new X509CertRequest(new String(Files.readAllBytes(path))); + X509CertRequest certReq = new X509CertRequest(new String(Files.readAllBytes(path)), spiffeUriManager); assertNotNull(certReq); assertEquals(certReq.getUriHostname(), "abc.athenz.com"); path = Paths.get("src/test/resources/athenz.examples.uri-hostname-only.csr"); - certReq = new X509CertRequest(new String(Files.readAllBytes(path))); + certReq = new X509CertRequest(new String(Files.readAllBytes(path)), spiffeUriManager); assertNotNull(certReq); assertEquals(certReq.getUriHostname(), "abc.athenz.com"); } @@ -80,7 +83,7 @@ public void testParseCertRequestIPs() throws IOException { Path path = Paths.get("src/test/resources/multiple_ips.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); List values = certReq.getDnsNames(); @@ -99,7 +102,7 @@ public void testParseCertRequestInvalid() throws IOException { Path path = Paths.get("src/test/resources/invalid_dns.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); } @@ -108,7 +111,7 @@ public void testValidateCommonName() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertTrue(certReq.validateCommonName("athenz.production")); @@ -123,7 +126,7 @@ public void testValidateUriHostname() throws IOException { Path path = Paths.get("src/test/resources/athenz.examples.uri-instanceid-hostname.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertTrue(certReq.validateUriHostname("abc.athenz.com")); @@ -136,7 +139,7 @@ public void testValidateUriHostname() throws IOException { path = Paths.get("src/test/resources/athenz.examples.uri-hostname-empty.csr"); csr = new String(Files.readAllBytes(path)); - certReq = new X509CertRequest(csr); + certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertTrue(certReq.validateUriHostname("abc.athenz.com")); } @@ -146,7 +149,7 @@ public void testInstanceId() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertEquals(certReq.getInstanceId(), "1001"); @@ -158,7 +161,7 @@ public void testValidateDnsNamesWithCert() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); path = Paths.get("src/test/resources/athenz.instanceid.pem"); @@ -174,7 +177,7 @@ public void testValidateDnsNamesWithValues() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); List providerDnsSuffixList = new ArrayList<>(); @@ -233,7 +236,7 @@ public void testValidateDnsNamesWithCnameValues() throws IOException { String csr = new String(Files.readAllBytes(path)); String service = "athenz.production"; - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); DataCache athenzSysDomainCache = Mockito.mock(DataCache.class); @@ -276,7 +279,7 @@ public void testValidateDnsNamesWithCnameValuesWithSameSuffix() throws IOExcepti String csr = new String(Files.readAllBytes(path)); String service = "athenz.production"; - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); DataCache athenzSysDomainCache = Mockito.mock(DataCache.class); @@ -310,7 +313,7 @@ public void testValidateDnsNamesWithMultipleDomainValues() throws IOException { Path path = Paths.get("src/test/resources/multi_dns_domain.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); List providerDnsSuffixList = new ArrayList<>(); @@ -383,7 +386,7 @@ public void testValidateUri() throws IOException { Path path = Paths.get("src/test/resources/multi_dns_domain.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); List providerDnsSuffixList = new ArrayList<>(); @@ -414,7 +417,7 @@ public void testValidateDnsNamesHostnameNullLists() throws IOException { Path path = Paths.get("src/test/resources/multi_dns_domain.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); List providerDnsSuffixList = new ArrayList<>(); @@ -444,7 +447,7 @@ public void testValidateDnsNamesHostnameNotAllowed() throws IOException { Path path = Paths.get("src/test/resources/multi_dns_domain.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); List providerDnsSuffixList = new ArrayList<>(); @@ -501,7 +504,7 @@ public void testValidateProviderDnsNamesList() throws IOException { Path path = Paths.get("src/test/resources/multi_dns_domain.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); // now add the hostname to the list @@ -534,7 +537,7 @@ public void testValidateProviderDnsNamesListWithWildcard() throws IOException { Path path = Paths.get("src/test/resources/multi_dns_domain_wildcard.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); // now add the hostname to the list @@ -565,7 +568,7 @@ public void testValidateProviderDnsNamesListWithWildcardMismatch() throws IOExce Path path = Paths.get("src/test/resources/multi_dns_domain_wildcard_mismatch.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); // now add the hostname to the list @@ -598,7 +601,7 @@ public void testValidateDnsNamesNoValues() throws IOException { Path path = Paths.get("src/test/resources/valid_cn_only.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); DataCache athenzSysDomainCache = Mockito.mock(DataCache.class); @@ -616,7 +619,7 @@ public void testValidateDnsNamesMismatchSize() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); path = Paths.get("src/test/resources/valid_cn_x509.cert"); @@ -632,7 +635,7 @@ public void testValidateDnsNamesMismatchValues() throws IOException { Path path = Paths.get("src/test/resources/athenz.mismatch.dns.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); path = Paths.get("src/test/resources/athenz.instanceid.pem"); @@ -648,7 +651,7 @@ public void testValidatePublicKeysCert() throws IOException { Path path = Paths.get("src/test/resources/valid_provider_refresh.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); path = Paths.get("src/test/resources/valid_provider_refresh.pem"); @@ -664,7 +667,7 @@ public void testValidatePublicKeysCertFailure() throws IOException { Path path = Paths.get("src/test/resources/valid_provider_refresh.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); X509Certificate cert = Mockito.mock(X509Certificate.class); @@ -679,7 +682,7 @@ public void testValidatePublicKeysCertCSRFailure() throws IOException { Path path = Paths.get("src/test/resources/valid_provider_refresh.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); PKCS10CertificationRequest req = Mockito.mock(PKCS10CertificationRequest.class); @@ -699,7 +702,7 @@ public void testValidatePublicKeysCertMismatch() throws IOException { Path path = Paths.get("src/test/resources/athenz.mismatch.dns.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); path = Paths.get("src/test/resources/athenz.instanceid.pem"); @@ -715,7 +718,7 @@ public void testValidatePublicKeysNull() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertFalse(certReq.validatePublicKeys((String) null)); @@ -727,7 +730,7 @@ public void testValidatePublicKeysFailure() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); PKCS10CertificationRequest req = Mockito.mock(PKCS10CertificationRequest.class); @@ -742,7 +745,7 @@ public void testValidatePublicKeysString() throws IOException { Path path = Paths.get("src/test/resources/valid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); final String ztsPublicKey = "-----BEGIN PUBLIC KEY-----\n" + "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKrvfvBgXWqWAorw5hYJu3dpOJe0gp3n\n" @@ -757,7 +760,7 @@ public void testValidateCertReqPublicKey() throws IOException { Path path = Paths.get("src/test/resources/valid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); final String ztsPublicKey = "-----BEGIN PUBLIC KEY-----\n" @@ -773,7 +776,7 @@ public void testValidateCertReqPublicKeyMismatch() throws IOException { Path path = Paths.get("src/test/resources/valid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); final String ztsPublicKey = "-----BEGIN PUBLIC KEY-----\n" @@ -789,7 +792,7 @@ public void testValidateCertReqPublicKeyWhitespace() throws IOException { Path path = Paths.get("src/test/resources/valid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); final String ztsPublicKey1 = " -----BEGIN PUBLIC KEY-----\n" @@ -812,7 +815,7 @@ public void testValidateCertCNFailure() throws IOException { String csr = new String(Files.readAllBytes(path)); try { - new X509CertRequest(csr); + new X509CertRequest(csr, spiffeUriManager); fail(); } catch (CryptoException ex) { assertTrue(ex.getMessage().contains("Subject contains multiple values")); @@ -827,7 +830,7 @@ public void testValidateOUFieldCheck() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); testValidateOUFieldCheck(certReq); @@ -838,7 +841,7 @@ public void testValidateOUFieldCheck() throws IOException { path = Paths.get("src/test/resources/athenz.instanceid.restricted.csr"); csr = new String(Files.readAllBytes(path)); - certReq = new X509CertRequest(csr); + certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); testValidateOUFieldCheck(certReq); @@ -878,7 +881,7 @@ public void testValidateOUFieldCheckMissingOU() throws IOException { Path path = Paths.get("src/test/resources/athenz.single_ip.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); HashSet validOrgUnits = new HashSet<>(); @@ -899,7 +902,7 @@ public void testValidateOUFieldCheckInvalidOU() throws IOException { Path path = Paths.get("src/test/resources/athenz.multiple_ou.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertFalse(certReq.validateSubjectOUField("Athenz", null, null)); @@ -912,7 +915,7 @@ public void testExtractInstanceIdURI() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.uri.csr"); String csr = new String(Files.readAllBytes(path)); - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertEquals(certReq.getInstanceId(), "id-001"); @@ -925,7 +928,7 @@ public void testValidateInstanceCnames() throws IOException { String csr = new String(Files.readAllBytes(path)); String service = "athenz.api"; - X509CertRequest certReq = new X509CertRequest(csr); + X509CertRequest certReq = new X509CertRequest(csr, spiffeUriManager); assertNotNull(certReq); // cnames null and empty is always true diff --git a/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509RoleCertRequestTest.java b/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509RoleCertRequestTest.java index 5189e84bb89..6c0f676551d 100644 --- a/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509RoleCertRequestTest.java +++ b/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509RoleCertRequestTest.java @@ -16,6 +16,7 @@ package com.yahoo.athenz.zts.cert; import com.yahoo.athenz.auth.util.Crypto; +import com.yahoo.athenz.common.server.spiffe.SpiffeUriManager; import org.testng.annotations.Test; import java.io.IOException; @@ -29,12 +30,14 @@ public class X509RoleCertRequestTest { + final SpiffeUriManager spiffeUriManager = new SpiffeUriManager(); + @Test public void testX509RoleCertRequest() throws IOException { Path path = Paths.get("src/test/resources/spiffe_role.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertEquals(certReq.getReqRoleDomain(), "coretech"); @@ -55,7 +58,7 @@ public void testValidateSpiffeRoleCert() throws IOException { Path path = Paths.get("src/test/resources/spiffe_role.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); Set orgValues = new HashSet<>(); orgValues.add("Athenz"); @@ -69,7 +72,7 @@ public void testValidateRoleIPAddressNoIPs() throws IOException { Path path = Paths.get("src/test/resources/spiffe_role.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertTrue(certReq.validateIPAddress(null, "10.10.11.12")); } @@ -79,7 +82,7 @@ public void testValidateRoleIPAddressNoCert() throws IOException { Path path = Paths.get("src/test/resources/role_single_ip.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertTrue(certReq.validateIPAddress(null, "10.11.12.13")); assertFalse(certReq.validateIPAddress(null, "10.10.11.12")); } @@ -94,7 +97,7 @@ public void testValidateRoleIPAddressCertNoIPs() throws IOException { String pem = new String(Files.readAllBytes(path)); X509Certificate cert = Crypto.loadX509Certificate(pem); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertTrue(certReq.validateIPAddress(cert, "10.11.12.13")); assertFalse(certReq.validateIPAddress(cert, "10.10.11.12")); } @@ -113,7 +116,7 @@ public void testValidateRoleIPAddressCertIPs() throws IOException { pem = new String(Files.readAllBytes(path)); X509Certificate cert2 = Crypto.loadX509Certificate(pem); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertTrue(certReq.validateIPAddress(cert1, "10.11.12.13")); assertTrue(certReq.validateIPAddress(cert2, "10.11.12.13")); } @@ -132,7 +135,7 @@ public void testValidateRoleIPAddressCertMultipleIPs() throws IOException { pem = new String(Files.readAllBytes(path)); X509Certificate cert2 = Crypto.loadX509Certificate(pem); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertFalse(certReq.validateIPAddress(cert1, "10.11.12.13")); assertTrue(certReq.validateIPAddress(cert2, "10.11.12.13")); } @@ -143,7 +146,7 @@ public void testValidateMissingProxyUserUri() throws IOException { Path path = Paths.get("src/test/resources/spiffe_role.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); Set orgValues = new HashSet<>(); orgValues.add("Athenz"); @@ -157,7 +160,7 @@ public void testValidateNoProxyUserUri() throws IOException { Path path = Paths.get("src/test/resources/role_single_ip.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); Set orgValues = new HashSet<>(); orgValues.add("Athenz"); @@ -171,7 +174,7 @@ public void testValidateMultipleProxyUserUri() throws IOException { Path path = Paths.get("src/test/resources/multiple_proxy_role.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); Set orgValues = new HashSet<>(); orgValues.add("Athenz"); @@ -185,7 +188,7 @@ public void testValidateProxyUserUri() throws IOException { Path path = Paths.get("src/test/resources/proxy_role.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); Set orgValues = new HashSet<>(); orgValues.add("Athenz"); @@ -203,7 +206,7 @@ public void testRoleCertValidatePrincipalURINoEmail() throws IOException { Path path = Paths.get("src/test/resources/athenz_role_principal_uri.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertTrue(certReq.validate("athenz.production", null, null)); assertFalse(certReq.validate("athenz.api", null, null)); } @@ -214,7 +217,7 @@ public void testRoleCertValidatePrincipalURIWithEmail() throws IOException { Path path = Paths.get("src/test/resources/athenz_role_principal_uri_email.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertTrue(certReq.validate("athenz.production", null, null)); assertFalse(certReq.validate("athenz.api", null, null)); } @@ -225,7 +228,7 @@ public void testRoleCertValidatePrincipalURIWithEmailMismatch() throws IOExcepti Path path = Paths.get("src/test/resources/athenz_role_principal_uri_email_mismatch.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertFalse(certReq.validate("athenz.production", null, null)); assertFalse(certReq.validate("athenz.api", null, null)); } @@ -236,7 +239,7 @@ public void testValidateSpiffeURIWithoutTrustDomain() throws IOException { Path path = Paths.get("src/test/resources/spiffe_role.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertTrue(certReq.validateSpiffeURI("coretech", "api")); assertFalse(certReq.validateSpiffeURI("coretech", "backend")); } @@ -247,7 +250,7 @@ public void testValidateSpiffeURIWithTrustDomain() throws IOException { Path path = Paths.get("src/test/resources/spiffe_role_trust_domain.csr"); String csr = new String(Files.readAllBytes(path)); - X509RoleCertRequest certReq = new X509RoleCertRequest(csr); + X509RoleCertRequest certReq = new X509RoleCertRequest(csr, spiffeUriManager); assertTrue(certReq.validateSpiffeURI("coretech", "api")); assertFalse(certReq.validateSpiffeURI("coretech", "backend")); } diff --git a/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509ServiceCertRequestTest.java b/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509ServiceCertRequestTest.java index 508f2d0c58d..149ab9461e9 100644 --- a/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509ServiceCertRequestTest.java +++ b/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509ServiceCertRequestTest.java @@ -17,6 +17,7 @@ import com.yahoo.athenz.auth.util.Crypto; import com.yahoo.athenz.auth.util.CryptoException; +import com.yahoo.athenz.common.server.spiffe.SpiffeUriManager; import com.yahoo.athenz.zts.cache.DataCache; import org.mockito.Mockito; import org.testng.annotations.DataProvider; @@ -33,13 +34,15 @@ public class X509ServiceCertRequestTest { + final SpiffeUriManager spiffeUriManager = new SpiffeUriManager(); + @Test public void testValidateInvalidDnsNames() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); StringBuilder errorMsg = new StringBuilder(256); @@ -53,7 +56,7 @@ public void testValidateInvalidInstanceId() throws IOException { Path path = Paths.get("src/test/resources/valid_email.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); StringBuilder errorMsg = new StringBuilder(256); @@ -72,7 +75,7 @@ public void testValidateInstanceIdMismatch() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); path = Paths.get("src/test/resources/athenz.instanceid.pem"); @@ -89,7 +92,7 @@ public void testValidateCnMismatch() throws IOException { Path path = Paths.get("src/test/resources/athenz.mismatch.cn.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); StringBuilder errorMsg = new StringBuilder(256); @@ -109,7 +112,7 @@ public void testValidateDnsSuffixMismatch() throws IOException { Path path = Paths.get("src/test/resources/athenz.mismatch.dns.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); StringBuilder errorMsg = new StringBuilder(256); @@ -129,7 +132,7 @@ public void testValidateOFieldCheck() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); StringBuilder errorMsg = new StringBuilder(256); @@ -156,7 +159,7 @@ public void testValidateOFieldCheckNoValue() throws IOException { Path path = Paths.get("src/test/resources/valid_cn_only.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); HashSet validOrgs = new HashSet<>(); @@ -171,7 +174,7 @@ public void testValidateOFieldCheckMultipleValue() throws IOException { Path path = Paths.get("src/test/resources/multiple_org.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); HashSet validOrgs = new HashSet<>(); @@ -186,7 +189,7 @@ public void testValidate() throws IOException { Path path = Paths.get("src/test/resources/athenz.instanceid.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); StringBuilder errorMsg = new StringBuilder(256); @@ -225,7 +228,7 @@ public void testValidateSpiffeUri(final String csrPath, boolean expectedResult) Path path = Paths.get(csrPath); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); StringBuilder errorMsg = new StringBuilder(256); @@ -247,7 +250,7 @@ public void testValidateIPAddressMultipleIPs() throws IOException { Path path = Paths.get("src/test/resources/multiple_ips.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertFalse(certReq.validateIPAddress("10.11.12.14")); @@ -259,7 +262,7 @@ public void testValidateIPAddressNoIPs() throws IOException { Path path = Paths.get("src/test/resources/valid.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertTrue(certReq.validateIPAddress("10.11.12.14")); @@ -271,7 +274,7 @@ public void testValidateIPAddressMismatchIPs() throws IOException { Path path = Paths.get("src/test/resources/athenz.single_ip.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertFalse(certReq.validateIPAddress("10.11.12.14")); @@ -283,7 +286,7 @@ public void testValidateIPAddress() throws IOException { Path path = Paths.get("src/test/resources/athenz.single_ip.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertTrue(certReq.validateIPAddress("10.11.12.13")); @@ -295,7 +298,7 @@ public void testValidateUriHostname() throws IOException { Path path = Paths.get("src/test/resources/athenz.examples.uri-instanceid-hostname.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); assertTrue(certReq.validateUriHostname("abc.athenz.com")); @@ -313,7 +316,7 @@ public void testValidateWithUriHostname() throws IOException { Path path = Paths.get("src/test/resources/athenz.examples.uri-instanceid-hostname.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertNotNull(certReq); StringBuilder errorMsg = new StringBuilder(256); @@ -344,7 +347,7 @@ public void testValidateSpiffeURIWithoutURI() throws IOException { Path path = Paths.get("src/test/resources/valid.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertTrue(certReq.validateSpiffeURI("domain", "api", null)); assertTrue(certReq.validateSpiffeURI("domain", "api", "default")); } @@ -355,7 +358,7 @@ public void testValidateSpiffeURIWithNamespace() throws IOException { Path path = Paths.get("src/test/resources/spiffe-namespace.csr"); String csr = new String(Files.readAllBytes(path)); - X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr); + X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr, spiffeUriManager); assertTrue(certReq.validateSpiffeURI("athenz", "production", "default")); assertFalse(certReq.validateSpiffeURI("athenz", "production", "test")); @@ -372,7 +375,7 @@ public void testValidateSpiffeURIMultipleValues() throws IOException { String csr = new String(Files.readAllBytes(path)); try { - new X509ServiceCertRequest(csr); + new X509ServiceCertRequest(csr, spiffeUriManager); fail(); } catch (CryptoException ex) { assertTrue(ex.getMessage().contains("Invalid SPIFFE URI present"));