Daiki might have some ideas about how to approach this. I think that we considered this when we first landed this code, but deferred adding any callbacks until it was clear what the right answer was. As you say, you get the callback, but you might not if the request is rejected.
On Tue, Jul 7, 2020 at 3:56 AM Alex Scheel <asch...@redhat.com> wrote: > > 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 -- dev-tech-crypto mailing list dev-tech-crypto@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-crypto