Skip to content

Conversation

@arturobernalg
Copy link
Member

This implementation adds decoding for Subject Alternative Names in X.509 certificates, including:

  • DNS names handled as plain text.
  • IP addresses decoded from binary (IPv4 and IPv6 supported).
  • Fallback to hexadecimal encoding for non-standard or unknown types.

result.add(new SubjectName((String) o, type));
} else if (o instanceof byte[]) {
// TODO ASN.1 DER encoded form
final byte[] bytes = (byte[]) o;
Copy link
Member

Choose a reason for hiding this comment

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

@arturobernalg We have got to be super careful here as this method has security implications. It is better to be too strict and too lax here. I trust you know what you are doing.

Copy link
Member Author

Choose a reason for hiding this comment

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

@arturobernalg We have got to be super careful here as this method has security implications. It is better to be too strict and too lax here. I trust you know what you are doing.

@ok2c I've ensured strict validation in the updated method: DNS names now reject unexpected byte[], IP addresses only allow 4 or 16 bytes with exceptions for invalid lengths, and unrecognized types log warnings while falling back.

throw new IllegalArgumentException("Invalid byte length for IP address: " + bytes.length);
}
} else if (type == SubjectName.DNS) {
throw new IllegalArgumentException("Unexpected byte[] for DNS SAN type");
Copy link
Member

Choose a reason for hiding this comment

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

@arturobernalg IllegalArgumentException looks really wrong here. Can we just ignore those bits that we are not able to properly recognize and handle?

if (LOG.isWarnEnabled()) {
LOG.warn("Unrecognized SAN type: {}, data: {}", type, TextUtils.toHexString(bytes));
}
decodedValue = TextUtils.toHexString(bytes); // Fallback to hex string
Copy link
Member

Choose a reason for hiding this comment

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

@arturobernalg I would not do that. Before you know there will be so called security professionals with all sorts of hand-crafted certificates, claiming vulnerabilities in our code and demanding we issue CVE with them as a finder.

Copy link
Member Author

Choose a reason for hiding this comment

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

@ok2c please take another look

Supports DNS names as plain text, IPv4 and IPv6 addresses in binary form, and falls back to hex encoding for unknown types.
@arturobernalg arturobernalg merged commit ed9594a into apache:master Jan 20, 2025
10 checks passed
@leonardehrenfried
Copy link

Has this change made into 5.4.3?

I upgrade to that version yesterday and I'm seeing the following exception which seems related:

Caused by: javax.net.ssl.SSLPeerUnverifiedException: Certificate for <s3.amazonaws.com> doesn't match any of the subject alternative names: [s3.amazonaws.com, *.s3.amazonaws.com, *.s3.dualstack.us-east-1.amazonaws.com, s3.dualstack.us-east-1.amazonaws.com, *.s3.us-east-1.amazonaws.com, s3.us-east-1.amazonaws.com, *.s3-control.us-east-1.amazonaws.com, s3-control.us-east-1.amazonaws.com, *.s3-control.dualstack.us-east-1.amazonaws.com, s3-control.dualstack.us-east-1.amazonaws.com, *.s3-accesspoint.us-east-1.amazonaws.com, *.s3-accesspoint.dualstack.us-east-1.amazonaws.com, *.s3-deprecated.us-east-1.amazonaws.com, s3-deprecated.us-east-1.amazonaws.com, s3-external-1.amazonaws.com, *.s3-external-1.amazonaws.com, s3-external-2.amazonaws.com, *.s3-external-2.amazonaws.com]
	at org.apache.hc.client5.http.ssl.DefaultHostnameVerifier.matchDNSName(DefaultHostnameVerifier.java:172)
	at org.apache.hc.client5.http.ssl.DefaultHostnameVerifier.verify(DefaultHostnameVerifier.java:130)
	at org.apache.hc.client5.http.ssl.AbstractClientTlsStrategy.verifySession(AbstractClientTlsStrategy.java:316)
	at org.apache.hc.client5.http.ssl.AbstractClientTlsStrategy.verifySession(AbstractClientTlsStrategy.java:194)
	at org.apache.hc.client5.http.ssl.AbstractClientTlsStrategy.executeHandshake(AbstractClientTlsStrategy.java:253)
	at org.apache.hc.client5.http.ssl.AbstractClientTlsStrategy.upgrade(AbstractClientTlsStrategy.java:210)
	at org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy.upgrade(DefaultClientTlsStrategy.java:48)
	at org.apache.hc.client5.http.impl.io.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:231)
	at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:490)
	at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:164)
	at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:174)
	at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:144)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:192)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:150)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:113)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:183)
	at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:245)
	at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:188)
	at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:162)
	at org.opentripplanner.framework.io.OtpHttpClient.executeAndMapWithResponseHandler(OtpHttpClient.java:302)
	... 14 common frames omitted

When I downgrade to 5.4.2 the request succeeds.

The URL that fails is the following: https://s3.amazonaws.com/kcm-alerts-realtime-prod/vehiclepositions.pb

@arturobernalg
Copy link
Member Author

Has this change made into 5.4.3?

I upgrade to that version yesterday and I'm seeing the following exception which seems related:

Caused by: javax.net.ssl.SSLPeerUnverifiedException: Certificate for <s3.amazonaws.com> doesn't match any of the subject alternative names: [s3.amazonaws.com, *.s3.amazonaws.com, *.s3.dualstack.us-east-1.amazonaws.com, s3.dualstack.us-east-1.amazonaws.com, *.s3.us-east-1.amazonaws.com, s3.us-east-1.amazonaws.com, *.s3-control.us-east-1.amazonaws.com, s3-control.us-east-1.amazonaws.com, *.s3-control.dualstack.us-east-1.amazonaws.com, s3-control.dualstack.us-east-1.amazonaws.com, *.s3-accesspoint.us-east-1.amazonaws.com, *.s3-accesspoint.dualstack.us-east-1.amazonaws.com, *.s3-deprecated.us-east-1.amazonaws.com, s3-deprecated.us-east-1.amazonaws.com, s3-external-1.amazonaws.com, *.s3-external-1.amazonaws.com, s3-external-2.amazonaws.com, *.s3-external-2.amazonaws.com]
	at org.apache.hc.client5.http.ssl.DefaultHostnameVerifier.matchDNSName(DefaultHostnameVerifier.java:172)
	at org.apache.hc.client5.http.ssl.DefaultHostnameVerifier.verify(DefaultHostnameVerifier.java:130)
	at org.apache.hc.client5.http.ssl.AbstractClientTlsStrategy.verifySession(AbstractClientTlsStrategy.java:316)
	at org.apache.hc.client5.http.ssl.AbstractClientTlsStrategy.verifySession(AbstractClientTlsStrategy.java:194)
	at org.apache.hc.client5.http.ssl.AbstractClientTlsStrategy.executeHandshake(AbstractClientTlsStrategy.java:253)
	at org.apache.hc.client5.http.ssl.AbstractClientTlsStrategy.upgrade(AbstractClientTlsStrategy.java:210)
	at org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy.upgrade(DefaultClientTlsStrategy.java:48)
	at org.apache.hc.client5.http.impl.io.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:231)
	at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:490)
	at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:164)
	at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:174)
	at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:144)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:192)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:150)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:113)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
	at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:183)
	at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:245)
	at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:188)
	at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:162)
	at org.opentripplanner.framework.io.OtpHttpClient.executeAndMapWithResponseHandler(OtpHttpClient.java:302)
	... 14 common frames omitted

When I downgrade to 5.4.2 the request succeeds.

The URL that fails is the following: https://s3.amazonaws.com/kcm-alerts-realtime-prod/vehiclepositions.pb

This failure isn't caused by SAN parsing. The old code ignored byte[] SANs entirely, including iPAddress (type 7), which per RFC 5280 must be stored as an OCTET STRING in network byte order.

@ok2c
Copy link
Member

ok2c commented Mar 28, 2025

@leonardehrenfried This PR is completely unrelated to your problem. The cause of it is a regression introduced by #566.

Feel free to raise a JIRA for the regression https://issues.apache.org/jira/browse/HTTPCLIENT

@leonardehrenfried
Copy link

Thanks for looking into it. I will create a Jira user and a ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants