GNOME Bugzilla – Bug 656343
gnutls tls backend shouldn't do handshake in mainloop
Last modified: 2012-07-18 21:49:01 UTC
The gnutls tls backend shouldn't do its handshake in the mainloop. There are several reasons for this: * The RSA/DSA operations related to X.509 can take a user detectable amount of time. This is especially true with large key sizes. * The crypto operations in the database can block since hardware could prompt the user for input. * We need to be able to block the handshake while we lookup (or prompt) the user for an appropriate client certificate. See bug #637257
(In reply to comment #0) > * The RSA/DSA operations related to X.509 can take a user detectable > amount of time. This is especially true with large key sizes. How long are we talking? Like, should we handshake in a separate thread even when doing a synchronous handshake? (Since the GCancellable would not be functional during the cryptographic operations.) This is going to end up looking a little bit like GThreadedResolver; create an operation, send it to another thread via a thread pool, and either synchronously or asynchronously wait for it to either finish or be cancelled. A few additional complications: (1) if the request is cancelled while it's blocked, you can't just abandon the work thread like we do in the resolver, because that thread may try to modify/write-to/read-from the gnutls_session, so you still need to wait for that thread to exit before you can safely work with the session from the original thread. (2) the handshake operatoin may need to emit signals or call callbacks, which will need to happen in the calling thread, not the work thread, and if the operation is cancelled while interaction is occurring, we need to fully cancel the interaction operation before allowing the main operation to complete. The theorized future NSS TLS provider will need to do the same things, so it would be nice if this was implemented generically, not inside the gnutls provider.
(In reply to comment #1) > (In reply to comment #0) > > * The RSA/DSA operations related to X.509 can take a user detectable > > amount of time. This is especially true with large key sizes. > > How long are we talking? Easily a second or more when a) using large key sizes, b) on a slow cpu, c) using smart cards. A 16384 bit RSA key sign takes 1.4 seconds on my Core2. My smart card takes a second or two to initialize, and then noticeable amount of time to sign with a 1024 bit key. > Like, should we handshake in a separate thread even > when doing a synchronous handshake? (Since the GCancellable would not be > functional during the cryptographic operations.) I guess we could. How important is it that GCancellable cancels immediately for the synchronous use case? > A few additional complications: (1) if the request is cancelled while it's > blocked, you can't just abandon the work thread like we do in the resolver, > because that thread may try to modify/write-to/read-from the gnutls_session, so > you still need to wait for that thread to exit before you can safely work with > the session from the original thread. Which is why I don't think it's possible for us to fire the 'cancelled' signal immediately in the main thread. I think that cancellation of one a handshake will take time (whether asynchronous or synchronous). And its likely that the session will be modified in some way by the underlying crypto library. > (2) the handshake operatoin may need to > emit signals or call callbacks, which will need to happen in the calling > thread, not the work thread, and if the operation is cancelled while > interaction is occurring, we need to fully cancel the interaction operation > before allowing the main operation to complete. Right. I guess we should probably modify GTlsInteraction's ask_password method so that it can be cancelled. Discussion -> bug #656443 > The theorized future NSS TLS provider will need to do the same things, so it > would be nice if this was implemented generically, not inside the gnutls > provider. Yes, would be nice. It may be easier to implement it generically inside glib-networking, rather than generically inside of glib.
(In reply to comment #2) > (In reply to comment #1) > > The theorized future NSS TLS provider will need to do the same things, so it > > would be nice if this was implemented generically, not inside the gnutls > > provider. > > Yes, would be nice. It may be easier to implement it generically inside > glib-networking, rather than generically inside of glib. About half of this stuff is solved by this code: Bug 657567
fixed in master; we now always do the gnutls_handshake() call in another thread, although the accept-certificate and notify::peer-certificate signals still happen back in the original calling thread.