Skip to content

Commit fb8946f

Browse files
authored
make cluster name in spiffe uri optional (AthenZ#589)
1 parent cacd550 commit fb8946f

File tree

5 files changed

+126
-13
lines changed

5 files changed

+126
-13
lines changed

servers/zts/src/main/java/com/yahoo/athenz/zts/cert/X509CertRequest.java

+27-13
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,12 @@ public boolean validateIPAddress(final String ip) {
309309
boolean validateSpiffeURI(final String domain, final String name, final String value) {
310310

311311
// the expected default format is
312-
// spiffe://<provider-cluster>/ns/<athenz-domain>/sa/<athenz-service>
313-
// spiffe://<provider-cluster>/ns/<athenz-domain>/ra/<athenz-role>
312+
// spiffe://[<provider-cluster>/ns/]<athenz-domain>/sa/<athenz-service>
313+
// spiffe://[<provider-cluster>/ns/]<athenz-domain>/ra/<athenz-role>
314+
//
314315
// so we'll be validating that our request has:
315-
// spiffe://<provider-cluster>/ns/<domain>/<name>/<value>
316+
// spiffe://<provider-cluster>/ns/<domain>/<name>/<value> or
317+
// spiffe://<domain>/<name>/<value> or
316318

317319
// first extract the URI list from the request
318320

@@ -337,25 +339,37 @@ boolean validateSpiffeURI(final String domain, final String name, final String v
337339
return false;
338340
}
339341

340-
if (uri.getScheme() == null || uri.getPath() == null) {
342+
final String uriScheme = uri.getScheme();
343+
final String uriPath = uri.getPath();
344+
final String uriHost = uri.getHost();
345+
346+
if (uriScheme == null || uriPath == null || uriHost == null) {
341347
LOGGER.error("validateSpiffeURI: invalid uri {}", spiffeUri);
342348
return false;
343349
}
344350

345-
if (!uri.getScheme().equalsIgnoreCase("spiffe")) {
346-
LOGGER.error("validateSpiffeURI: invalid uri scheme: {} in {}",
347-
uri.getScheme(), spiffeUri);
351+
if (!uriScheme.equalsIgnoreCase("spiffe")) {
352+
LOGGER.error("validateSpiffeURI: invalid uri scheme: {}", spiffeUri);
348353
return false;
349354
}
350355

351-
final String path = "/ns/" + domain + "/" + name + "/" + value;
352-
if (!uri.getPath().equalsIgnoreCase(path)) {
353-
LOGGER.error("validateSpiffeURI: invalid uri path: {} vs {}",
354-
path, uri.getPath());
355-
return false;
356+
// let's check to see if our path starts with our
357+
// namespace ns field and thus which format we're using
358+
359+
boolean uriVerified = false;
360+
if (uriPath.startsWith("/ns/")) {
361+
final String path = "/ns/" + domain + "/" + name + "/" + value;
362+
uriVerified = uriPath.equalsIgnoreCase(path);
363+
} else {
364+
final String path = "/" + name + "/" + value;
365+
uriVerified = uriHost.equalsIgnoreCase(domain) && uriPath.equalsIgnoreCase(path);
356366
}
357367

358-
return true;
368+
if (!uriVerified) {
369+
LOGGER.error("validateSpiffeURI: invalid uri path/host: {}", spiffeUri);
370+
}
371+
372+
return uriVerified;
359373
}
360374

361375
public void setNormCsrPublicKey(String normCsrPublicKey) {

servers/zts/src/test/java/com/yahoo/athenz/zts/cert/X509CertRequestTest.java

+63
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,69 @@ public void testValidateSpiffeServiceCertMismatch() throws IOException {
625625
"1001", validOrgs, null, errorMsg));
626626
}
627627

628+
@Test
629+
public void testValidateSpiffeServiceCertShortValid() throws IOException {
630+
631+
Path path = Paths.get("src/test/resources/spiffe_short_service.csr");
632+
String csr = new String(Files.readAllBytes(path));
633+
634+
X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr);
635+
assertNotNull(certReq);
636+
637+
Authorizer authorizer = Mockito.mock(Authorizer.class);
638+
Principal provider = Mockito.mock(Principal.class);
639+
Mockito.when(authorizer.access("launch", "sys.auth:dns.ostk.athenz.cloud", provider, null))
640+
.thenReturn(true);
641+
642+
StringBuilder errorMsg = new StringBuilder(256);
643+
HashSet<String> validOrgs = new HashSet<>();
644+
validOrgs.add("Athenz");
645+
assertTrue(certReq.validate(provider, "athenz", "production",
646+
"1001", validOrgs, null, errorMsg));
647+
}
648+
649+
@Test
650+
public void testValidateSpiffeServiceCertShortMismatchDomain() throws IOException {
651+
652+
Path path = Paths.get("src/test/resources/spiffe_service_short_mismatch_domain.csr");
653+
String csr = new String(Files.readAllBytes(path));
654+
655+
X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr);
656+
assertNotNull(certReq);
657+
658+
Authorizer authorizer = Mockito.mock(Authorizer.class);
659+
Principal provider = Mockito.mock(Principal.class);
660+
Mockito.when(authorizer.access("launch", "sys.auth:dns.ostk.athenz.cloud", provider, null))
661+
.thenReturn(true);
662+
663+
StringBuilder errorMsg = new StringBuilder(256);
664+
HashSet<String> validOrgs = new HashSet<>();
665+
validOrgs.add("Athenz");
666+
assertFalse(certReq.validate(provider, "athenz", "production",
667+
"1001", validOrgs, null, errorMsg));
668+
}
669+
670+
@Test
671+
public void testValidateSpiffeServiceCertShortMismatchService() throws IOException {
672+
673+
Path path = Paths.get("src/test/resources/spiffe_service_short_mismatch_service.csr");
674+
String csr = new String(Files.readAllBytes(path));
675+
676+
X509ServiceCertRequest certReq = new X509ServiceCertRequest(csr);
677+
assertNotNull(certReq);
678+
679+
Authorizer authorizer = Mockito.mock(Authorizer.class);
680+
Principal provider = Mockito.mock(Principal.class);
681+
Mockito.when(authorizer.access("launch", "sys.auth:dns.ostk.athenz.cloud", provider, null))
682+
.thenReturn(true);
683+
684+
StringBuilder errorMsg = new StringBuilder(256);
685+
HashSet<String> validOrgs = new HashSet<>();
686+
validOrgs.add("Athenz");
687+
assertFalse(certReq.validate(provider, "athenz", "production",
688+
"1001", validOrgs, null, errorMsg));
689+
}
690+
628691
@Test
629692
public void testValidateSpiffeInvalidScheme() throws IOException {
630693

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIIBuDCCAWICAQAwYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ8wDQYDVQQK
3+
EwZBdGhlbnoxFzAVBgNVBAsTDlRlc3RpbmcgRG9tYWluMRowGAYDVQQDExFhdGhl
4+
bnoucHJvZHVjdGlvbjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDCvtASJL3f3dsk
5+
ZDxuJ5sXRr5PLFX3Q272cgO72gG2IusvoL8I6oL8WGy0ZMCYAOC6fqGaeT8BXvXS
6+
YmRieKSZAgMBAAGggZwwgZkGCSqGSIb3DQEJDjGBizCBiDCBhQYDVR0RBH4wfIIj
7+
cHJvZHVjdGlvbi5hdGhlbnoub3N0ay5hdGhlbnouY2xvdWSCKDEwMDEuaW5zdGFu
8+
Y2VpZC5hdGhlbnoub3N0ay5hdGhlbnouY2xvdWSHBAoLDA2HBAoLDA6GH3NwaWZm
9+
ZTovL2NvcmV0ZWNoL3NhL3Byb2R1Y3Rpb24wDQYJKoZIhvcNAQELBQADQQCR5uq8
10+
yEQJsGXu6Y8jj//kBNSyFTVceWzZ5MqYm80X9+E7R4B7FU3mdYJX1/ghHn8574Pi
11+
bJA43fVYwnpboAhB
12+
-----END CERTIFICATE REQUEST-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIIBrTCCAVcCAQAwYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ8wDQYDVQQK
3+
EwZBdGhlbnoxFzAVBgNVBAsTDlRlc3RpbmcgRG9tYWluMRowGAYDVQQDExFhdGhl
4+
bnoucHJvZHVjdGlvbjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDFnIrCLPQaIUt1
5+
SeTXxFhu8ULxuPbklABGx7s5ypQa3Rdcs4dNpFB2PAygU7NhsSWKUDfD9SJIF460
6+
ohUzziQrAgMBAAGggZEwgY4GCSqGSIb3DQEJDjGBgDB+MHwGA1UdEQR1MHOCI3By
7+
b2R1Y3Rpb24uYXRoZW56Lm9zdGsuYXRoZW56LmNsb3VkgigxMDAxLmluc3RhbmNl
8+
aWQuYXRoZW56Lm9zdGsuYXRoZW56LmNsb3VkhwQKCwwNhwQKCwwOhhZzcGlmZmU6
9+
Ly9hdGhlbnovc2EvYXBpMA0GCSqGSIb3DQEBCwUAA0EApXOYXJ9MVlxdXI/n94SC
10+
S9eGMfpdMtrh6SoEJTa/KWNYp7pK9xo8j5FSP6QiddjLZnuz8rxrgqkEPyv+ENyz
11+
nA==
12+
-----END CERTIFICATE REQUEST-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIIBtjCCAWACAQAwYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ8wDQYDVQQK
3+
EwZBdGhlbnoxFzAVBgNVBAsTDlRlc3RpbmcgRG9tYWluMRowGAYDVQQDExFhdGhl
4+
bnoucHJvZHVjdGlvbjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3gXNrQpZl3j1s
5+
n/n05BJO+JZQN56cty8WHpmWVNna3EJhGT+C1OSC4mJgO4Bz1UR8w6y0FUxJ6Ge6
6+
Ep6vQJtjAgMBAAGggZowgZcGCSqGSIb3DQEJDjGBiTCBhjCBgwYDVR0RBHwweoIj
7+
cHJvZHVjdGlvbi5hdGhlbnoub3N0ay5hdGhlbnouY2xvdWSCKDEwMDEuaW5zdGFu
8+
Y2VpZC5hdGhlbnoub3N0ay5hdGhlbnouY2xvdWSHBAoLDA2HBAoLDA6GHXNwaWZm
9+
ZTovL2F0aGVuei9zYS9wcm9kdWN0aW9uMA0GCSqGSIb3DQEBCwUAA0EAThxUa0Ca
10+
1ufMIR2LoDHvdZWYzOyU6w3SL6OnV8BfRS8/gn2j3/uM66CS3QDlpo67sNsnBFYY
11+
T39E03gcW/b4fA==
12+
-----END CERTIFICATE REQUEST-----

0 commit comments

Comments
 (0)