Greetings folks, With moz-bz#1561637 having landed upstream (and subsequently v3.52 being shipped downstream in Fedora), I've been testing JSS's SSLEngine with TLSv1.3 again.
One of the issues I've had is there's no good indicator for either key-exchange or post-handshake auth being started or completed by either party (client or server). SSLEngine (in Java) for those unaware has (roughly) the following semantics: - After beginHandshake() has been called, handshake status stays in NEED_WRAP, NEED_UNWRAP, or NEED_TASK until the handshake is complete. Then it moves to FINISHED and finally to NOT_HANDSHAKING. - beginHandshake() is called implicitly the first time from wrap() and unwrap(). - If certs are required after the initial handshake (such as via PHA in TLSv1.3 or a full re-handshake when available in TLSv1.2 and earlier), beginHandshake() semantics apply again. The last requirement is the "hard" one under TLSv1.3. I've set a SSL_HandshakeCallback() that informs me when the initial handshake is completed. This works fine for both client and server-initiated re-handshakes under TLSv1.2. However, this callback is never executed under TLSv1.3 (in part) because PHA and re-key requests aren't strictly a new handshake. So what I ask are: - Is there a reliable way to tell (as both a client and server) when PHA/rekey requests have started? - Is there a reliable way to tell (as both a client and server) when PHA/rekey requests have completed? - Is there a reliable way to tell (as both a client and server) when a handshake has been initiated by the other party (on TLS < 1.2)? I'm fine living without 1 and 3, but 2 is the more of an issue for me. I'd be happy to submit the code changes to trigger SSL_HandshakeCallback via TLSv1.3 PHA/re-key requests -- but I'm not sure if that'd technically conform to the function's documentation: > /* > ** Set the callback that gets called when a TLS handshake is complete. The > ** handshake callback is called after verifying the peer's Finished message > and > ** before processing incoming application data. > ** > ** For the initial handshake: If the handshake false started (see > ** SSL_ENABLE_FALSE_START), then application data may already have been sent > ** before the handshake callback is called. If we did not false start then the > ** callback will get called before any application data is sent. > */ > typedef void(PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd, > void *client_data); > SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd, > SSLHandshakeCallback cb, void > *client_data); It might be surprising behavior? But on the other hand, these two do kinda replace the (insecure) second handshake. Perhaps gating it behind an option flag would suffice though (SSL_HANDSHAKE_CALLBACK_FOR_PHA or some such)? When looking at the other SSL_SendCertificateRequest experimental API docs, it does say AuthCertificateComplete is called on the server side: > /* This function allows a server application to trigger > * re-authentication (TLS 1.3 only) after handshake. > * > * This function will cause a CertificateRequest message to be sent by > * a server. This can be called once at a time, and is not allowed > * until an answer is received. > * > * This function is not allowed for use with DTLS or when external > * PSK authentication has been negotiated. SECFailure is returned > * in both cases. > * > * The AuthCertificateCallback is called when the answer is received. > * If the answer is accepted by the server, the value returned by > * SSL_PeerCertificate() is replaced. If you need to remember all the > * certificates, you will need to call SSL_PeerCertificate() and save > * what you get before calling this. > * > * If the AuthCertificateCallback returns SECFailure, the connection > * is aborted. > */ > #define SSL_SendCertificateRequest(fd) \ > SSL_EXPERIMENTAL_API("SSL_SendCertificateRequest", \ > (PRFileDesc * _fd), \ > (fd)) But this doesn't help on the client side. Additionally, my situation with AuthCertificateCallback is... complicated (it is either not explicitly set to use the default NSS value, set to something with no knowledge of my SSLEngine, or something with knowledge of the SSLEngine) -- so I'm not sure I like that design. Thoughts? I feel like I might be missing something. - Alex -- dev-tech-crypto mailing list dev-tech-crypto@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-crypto