Skip to content
Open
24 changes: 24 additions & 0 deletions testing/src/main/resources/certs/bad_wildcard_dns_certificate.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIUCs5j4C2KXgCRVFa48kc5TYRS1JswDQYJKoZIhvcNAQEL
BQAwGTEXMBUGA1UEAwwOTXkgSW50ZXJuYWwgQ0EwHhcNMjUwOTA4MTI0NTQyWhcN
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to create any new certificate, we can work with
testing/src/main/resources/certs/server0.pem and server1.pem themselves. server0.pem is issued to *.test.google.com.au server1.pem is issued to the names
*.test.google.fr, waterzooi.test.google.be, *.test.youtube.com, IP Address:192.168.1.3

MjYwOTA4MTI0NTQyWjBlMQswCQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMx
EDAOBgNVBAcMB0NoaWNhZ28xFTATBgNVBAoMDEV4YW1wbGUsIENvLjEaMBgGA1UE
AwwRKi50ZXN0Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCqKnJzYfTFd/Rh+iYwuSlTDejDtSKE8OsByTdCSf5xjcesnCLASvEoCXmE
UdgRKU+lmW2vn9OCgoXAeGfbYjyEjb1AaZhL++qwLHbXAGcEqRdOquMMR1RORa1+
pjU/IZOOPJgwQxh1FzQE+oP3v1ZbelNF0crru9d4G2atV+iR9vRRuxCdy1Md+Yer
BJL05WWd5ujSa+82KKq2If4EZD4oLT8WjXKF6NIFZuCBHXtLGM9u0lsjR+L/6Ntz
cp0rpTsMeA8BIQTl3pC2+UCRwasDEz8p2jJ3AUCFxfj13rsTfWt80eg0p/oxsINN
PLUtLZ9hbgLyQwZdKWhMpHTq9qzTAgMBAAGjgeIwgd8wCwYDVR0PBAQDAgXgMBMG
A1UdJQQMMAoGCCsGAQUFBwMBMHsGA1UdEQR0MHKCCioqbHlmdC5jb22CCmx5ZnQq
Ki5jb22CCmx5KipmdC5jb22CCGx5ZnQuYyptgggqeWZ0LmMqbYIKKi5seWZ0LmNv
bYIHbCpmdC5jb4IIbHk/dC5jb22CCGxmKnQuY29tggkqbHlmdC5jb22HBMCoAQMw
HQYDVR0OBBYEFGaC9jswbSvwVM0mH4Fw8d4g43CEMB8GA1UdIwQYMBaAFB5bLRTe
Vki0qsiYFA8ugQdM9Aa4MA0GCSqGSIb3DQEBCwUAA4IBAQA4KAJD17VZqzS59mKw
k5mZAmQoY5LbTIusbUuHKvVMJig6bDFwbbeTwcSE492sZQQN/ZP0OlAQGBK/pxl9
ynrTlh95SqhLgWgVfh//EmVKbMq+tJKlixz7fTgpjMxka4iCzzQtyYUIy3XhrqKY
B8TBt4M2O52clG/xp/2zMvs4zkjXxuHVSHpMWQV4wGqb+/Rk5oPUCqklOfqQHQcf
3EqqVVArk0AzG0tHiXiQUNggioMZfL/pqsLqOsnSVKSCg5avy4sVXDoB5YHtBpx2
VL77nfG49WbSg5yGqrPAzIeAu6+ffhTt0XhegxvaV/F/ZnvSMSI59ntGYfsoEqtc
O8w2
-----END CERTIFICATE-----
25 changes: 25 additions & 0 deletions testing/src/main/resources/certs/wildcard_dns_certificate.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEIjCCAwqgAwIBAgIUCs5j4C2KXgCRVFa48kc5TYRS1JkwDQYJKoZIhvcNAQEL
BQAwGTEXMBUGA1UEAwwOTXkgSW50ZXJuYWwgQ0EwHhcNMjUwOTA4MTIzNTI4WhcN
MjYwOTA4MTIzNTI4WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMx
EDAOBgNVBAcMB0NoaWNhZ28xFTATBgNVBAoMDEV4YW1wbGUsIENvLjEaMBgGA1UE
AwwRKi50ZXN0Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCqKnJzYfTFd/Rh+iYwuSlTDejDtSKE8OsByTdCSf5xjcesnCLASvEoCXmE
UdgRKU+lmW2vn9OCgoXAeGfbYjyEjb1AaZhL++qwLHbXAGcEqRdOquMMR1RORa1+
pjU/IZOOPJgwQxh1FzQE+oP3v1ZbelNF0crru9d4G2atV+iR9vRRuxCdy1Md+Yer
BJL05WWd5ujSa+82KKq2If4EZD4oLT8WjXKF6NIFZuCBHXtLGM9u0lsjR+L/6Ntz
cp0rpTsMeA8BIQTl3pC2+UCRwasDEz8p2jJ3AUCFxfj13rsTfWt80eg0p/oxsINN
PLUtLZ9hbgLyQwZdKWhMpHTq9qzTAgMBAAGjggEUMIIBEDALBgNVHQ8EBAMCBeAw
EwYDVR0lBAwwCgYIKwYBBQUHAwEwgasGA1UdEQSBozCBoIIQKi50ZXN0Lmdvb2ds
ZS5mcoIYd2F0ZXJ6b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5j
b22CCmEubHlmdC5jb22CCmEuTFlGVC5jb22CCWx5ZnQqLmNvbYIJKmx5ZnQuY29t
gghseWYqLmNvbYIJbHlmdCouY29tgghsKmZ0LmNvbYILdCoubHlmdC5jb22HBMCo
AQMwHQYDVR0OBBYEFGaC9jswbSvwVM0mH4Fw8d4g43CEMB8GA1UdIwQYMBaAFB5b
LRTeVki0qsiYFA8ugQdM9Aa4MA0GCSqGSIb3DQEBCwUAA4IBAQC5bu34wiKkck4z
aejXjh2PtW6YyzJS2eIi2MbRtF27WA7okM6ZYpz/Xf7dYygSitfsVgUyciZkkkf9
I6Qi7M7cImBVpagB9w1HA6Fm30Flphgs+HhFdOB/VwDL1sU7YI4R88tPugnANeVq
cxxUbfkZvUxkbwnkgnA+ZoH6Orwjaz1I8I1mTJtZ6IotU42F2iwBBLv6r3xeiOq/
gwmnPwO8T002OT5m8GyXd6O7cWMRH/Ys0K/hNpLmYWQxa86F3oWJi8RGF/h3ORnz
w7AAWS0PahXx0tmsaZNTZGOwyTnRL7thiXJajdCwpWWsClfgwhhZaZgUrqKbx3/r
2wZpTadR
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ private static boolean verifyDnsNamePrefix(
if (Strings.isNullOrEmpty(sanToVerifyPrefix)) {
return false;
}
if ((ignoreCase
? sanToVerifyPrefix.toLowerCase(Locale.ROOT)
: sanToVerifyPrefix).contains("*")) {
return verifyDnsNameWildcard(altNameFromCert, sanToVerifyPrefix , ignoreCase);
}
return ignoreCase
? altNameFromCert.toLowerCase(Locale.ROOT).startsWith(
sanToVerifyPrefix.toLowerCase(Locale.ROOT))
Expand All @@ -125,6 +130,11 @@ private static boolean verifyDnsNameSuffix(
if (Strings.isNullOrEmpty(sanToVerifySuffix)) {
return false;
}
if ((ignoreCase
? sanToVerifySuffix.toLowerCase(Locale.ROOT)
: sanToVerifySuffix).contains("*")) {
return verifyDnsNameWildcard(altNameFromCert, sanToVerifySuffix , ignoreCase);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the envoy code here it is not doing wildcard matching for prefix, suffix, and contains and for safe regex it is compiling the pattern as regex. gRPC code is already doing the same for these 3 cases, so only for exact DNS match we need to have the changes for handling split patterns and *.

return ignoreCase
? altNameFromCert.toLowerCase(Locale.ROOT).endsWith(
sanToVerifySuffix.toLowerCase(Locale.ROOT))
Expand All @@ -136,6 +146,11 @@ private static boolean verifyDnsNameContains(
if (Strings.isNullOrEmpty(sanToVerifySubstring)) {
return false;
}
if ((ignoreCase
? sanToVerifySubstring.toLowerCase(Locale.ROOT)
: sanToVerifySubstring).contains("*")) {
return verifyDnsNameWildcard(altNameFromCert, sanToVerifySubstring , ignoreCase);
}
return ignoreCase
? altNameFromCert.toLowerCase(Locale.ROOT).contains(
sanToVerifySubstring.toLowerCase(Locale.ROOT))
Expand All @@ -147,6 +162,11 @@ private static boolean verifyDnsNameExact(
if (Strings.isNullOrEmpty(sanToVerifyExact)) {
return false;
}
if ((ignoreCase
? sanToVerifyExact.toLowerCase(Locale.ROOT)
: sanToVerifyExact).contains("*")) {
return verifyDnsNameWildcard(altNameFromCert, sanToVerifyExact , ignoreCase);
}
return ignoreCase
? sanToVerifyExact.equalsIgnoreCase(altNameFromCert)
: sanToVerifyExact.equals(altNameFromCert);
Expand Down Expand Up @@ -303,4 +323,38 @@ public X509Certificate[] getAcceptedIssuers() {
}
return delegate.getAcceptedIssuers();
}

public static boolean verifyDnsNameWildcard(
String altNameFromCert, String sanToVerify, boolean ignoreCase) {
if (Strings.isNullOrEmpty(altNameFromCert) || Strings.isNullOrEmpty(sanToVerify)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this check since the logic can already handle empty strings, and null won't be passed for sanToVerify here. altNameFromCert wont' be null.
Instead have the trivial check for "*" like Envoy does

return false;
}
String[] certLabels = (ignoreCase ? altNameFromCert.toLowerCase(Locale.ROOT) : altNameFromCert)
.split("\\.", -1);
String[] sanLabels = (ignoreCase ? sanToVerify.toLowerCase(Locale.ROOT) : sanToVerify)
.split("\\.", -1);
if (certLabels.length != sanLabels.length) {
return false;
}
if ((int) sanLabels[0].chars().filter(ch -> ch == '*').count() != 1
|| sanLabels[0].startsWith("xn--")) {
return false;
}
for (int i = 1; i < sanLabels.length; i++) {
if (!sanLabels[i].equals(certLabels[i])) {
return false;
}
}
return labelWildcardMatch(certLabels[0], sanLabels[0]);
}

private static boolean labelWildcardMatch(String certLabel, String sanLabel) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename certLabel to pattern and sanLabel to dnsLabel like in Envoy code, it is more clear that way.

int starIndex = sanLabel.indexOf('*');
String prefix = sanLabel.substring(0, starIndex);
String suffix = sanLabel.substring(starIndex + 1);
if (certLabel.length() < prefix.length() + suffix.length()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better said as certLabel.length() <= sanLabel.length() + 1 like in Envoy code. The +1 is for * that stands for 0 or more characters. Combine with below condition in the return statement

return false;
}
return certLabel.startsWith(prefix) && certLabel.endsWith(suffix);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public class CommonTlsContextTestsUtil {
public static final String BAD_SERVER_KEY_FILE = "badserver.key";
public static final String BAD_CLIENT_PEM_FILE = "badclient.pem";
public static final String BAD_CLIENT_KEY_FILE = "badclient.key";
public static final String WILDCARD_DNS_PEM_FILE = "wildcard_dns_certificate.pem";
public static final String BAD_WILDCARD_DNS_PEM_FILE = "bad_wildcard_dns_certificate.pem";

/** takes additional values and creates CombinedCertificateValidationContext as needed. */
private static CommonTlsContext buildCommonTlsContextWithAdditionalValues(
Expand Down
Loading