Contract of the javax.net.ssl.X509KeyManager.chooseClientAlias method

Thomas Fox thomas.fox at seitenbau.com
Wed Dec 30 09:56:20 UTC 2020


Thanks, Brad, for your answer.

I have looked at the source code and think I understand the TLS 1.0 code, but not the TLS 1.2 code
As my understanding of HTTPS is not firm, I put your answer in the observed context to make sure I understood correctly:

The client logs the following Certificate Request message (for TLS 1.2):
javax.net.ssl|FINE|01|main|2020-12-30 08:49:18.944 CET|Logger.java:765|Consuming CertificateRequest handshake message (
"CertificateRequest": {
  "certificate types": [rsa_sign, dss_sign, ecdsa_sign]
  "supported signature algorithms": [ecdsa_secp521r1_sha512, rsa_pkcs1_sha512, ecdsa_secp384r1_sha384, rsa_pkcs1_sha384, ecdsa_secp256r1_sha256, rsa_pkcs1_sha256, dsa_sha256, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
  "certificate authorities": [CN=localhost, O=Seitenbau GmbH, L=Konstanz, ST=BW, C=DE]
}
)

Then, later in the code, the method javax.net.ssl.X509KeyManager.chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) is called on the Client's key manager to return the certificate to authenticate with.
As I understand it, the client JDK should pass ["RSA", "DSA", "EC"] as parameter keyType to the key manager.
Passing just ["EC"] as parameter keyType to the key manager, as observed in openjdk 8u272 is then a bug, as I understand it?
(As an aside, if the keyMananger is programmed such that it ignores the passed keyTypes["EC"] and presents a RSA key anyway, a successful SSL connection is established)

Thanks for bearing with my questions, I just want to make sure I do not miss anything and that [1] can be confirmed as a bug.

    Thomas 

[1] https://github.com/AdoptOpenJDK/openjdk-support/issues/200

----- Ursprüngliche Mail -----
Von: "Bradford Wetmore" <bradford.wetmore at oracle.com>
An: "Thomas Fox" <thomas.fox at seitenbau.com>, "security-dev" <security-dev at openjdk.java.net>
Gesendet: Montag, 28. Dezember 2020 19:42:50
Betreff: Re: Contract of the javax.net.ssl.X509KeyManager.chooseClientAlias method

I haven't been following what OpenJDK has been doing recently, but IIRC, 
the original call includes all of the server's requested key types, 
copied directly from the CertificateRequest message.  See:

https://tools.ietf.org/rfcmarkup?doc=2246#section-7.4.4

Have a look at the current code:

https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java

See the T10CertificateRequestMessage(line 
182)/T10CertificateRequestConsumer(346) where the message is read off 
the wire, then is passed to chooseClientAlias(369) after checking for 
duplicates() and whether the algorithm is available.

It's similar but more involved for TLS12.

Brad




On 12/27/2020 1:54 AM, Thomas Fox wrote:
> Hello,
> 
> I have a question regarding the contract of the method javax.net.ssl.X509KeyManager.chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket). This method gets called by SSL code on a client when a SSL connection is opened to a server, the server requests client authentication and the client wants to choose which one of the available keys is used for the authentication.
> The question is whether the SSL code should pass all possible key types in the argument keyType, or should it pass only one (probably the favoured key type???) in the argument keyType?
> The javadoc of the argument says "keyType - the key algorithm type name(s), ordered with the most-preferred key type first.", which leaves a little room to interpretation (is it "all acceptable key algorithm type name(s)" or "a subset of all allowed key algorithm type name(s)"?).
> 
> Background is that the argument keyType passed by the SSL code is different between (A) openjdk 8u272 TLSv1.2 on the one hand and (B) openjdk 8u272 TLSv1.1, openjdk 8u265 TLSv1.1 and openjdk 8u265 TLSv1.2 on the other hand. In the former case (A), ["EC"] is passed as keyType, whereas in the latter case (B), ["RSA", "DSA", "EC"] is passed as key type, with no other changes except from JDK and TLS version. Note that in all cases, at least the key type "RSA" is acceptable as a key type.
> The question is if the behavior (A) is a bug (see [1]), because it does not contain the acceptable key type "RSA" (did not check whether DSA keys are also acceptable).
> 
> One implementation (Apache HttpClient 4.5.13 org.apache.http.conn.ssl.SSLContextBuilder.KeyManagerDelegate, [2]) uses the passed key types to find matching keys (it iterates over the passed key types and asks a delegate KeyManger for aliases for that key type). In case (1) this strategy fails if the keystore only contains a RSA key because RSA keys are never queried, although the RSA key can be used to authenticate to the server.
> If (A) were correct, how could the implementation guess that it can also return a RSA key?
> 
>      Thanks,
>          
>              Thomas Fox
> 
> [1] https://github.com/AdoptOpenJDK/openjdk-support/issues/200
> [2] https://hc.apache.org/httpcomponents-client-ga/httpclient/xref/org/apache/http/conn/ssl/SSLContextBuilder.html#L221
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5461 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20201230/a593580a/smime.p7s>


More information about the security-dev mailing list