-
We have discovered that trust list initialization is a massive performance bottleneck when loading websites: https://bugs.webkit.org/show_bug.cgi?id=251336 https://gitlab.com/gnutls/gnutls/-/issues/1528 At first, I thought there was not much we can do about this, because the gnutls_certificate_credentials_t object takes ownership of the gnutls_x509_trust_list object that we pass to it, meaning we definitely need to create a new trust list each time we create a new credentials object. But I eventually realized that we can safely cache and reuse the gnutls_certificate_credentials_t instead. With this, we now only need to populate the trust list twice per connection. We need to do it twice because we cannot share the priv->trust_list that we use in g_tls_database_gnutls_verify_chain() with the one that is given to the credentials object, since, again, the credentials object takes ownership. We could alternatively always create priv->credentials when initializing the database and instead create priv->trust_list lazily only when the first first verify_chain() operation is requested, which would get us down to one initialization in the usual case. (Normally, the application will never call g_tls_database_gnutls_verify_chain(), because GTlsConnectionGnutls will never do this, because it defers certificate verification to the GTlsDatabase only when it is not a GTlsDatabaseGnutls). But I think it's slightly easier to read this way. Twice isn't so bad. We can always change it in the future if desired, but it would have the disadvantage that the GTlsDatabaseGnutls's private data would no longer be read-only after initialization, which doesn't seem worth it. That rule makes it easier to reason about correctness. Part-of: <!249>
We have discovered that trust list initialization is a massive performance bottleneck when loading websites: https://bugs.webkit.org/show_bug.cgi?id=251336 https://gitlab.com/gnutls/gnutls/-/issues/1528 At first, I thought there was not much we can do about this, because the gnutls_certificate_credentials_t object takes ownership of the gnutls_x509_trust_list object that we pass to it, meaning we definitely need to create a new trust list each time we create a new credentials object. But I eventually realized that we can safely cache and reuse the gnutls_certificate_credentials_t instead. With this, we now only need to populate the trust list twice per connection. We need to do it twice because we cannot share the priv->trust_list that we use in g_tls_database_gnutls_verify_chain() with the one that is given to the credentials object, since, again, the credentials object takes ownership. We could alternatively always create priv->credentials when initializing the database and instead create priv->trust_list lazily only when the first first verify_chain() operation is requested, which would get us down to one initialization in the usual case. (Normally, the application will never call g_tls_database_gnutls_verify_chain(), because GTlsConnectionGnutls will never do this, because it defers certificate verification to the GTlsDatabase only when it is not a GTlsDatabaseGnutls). But I think it's slightly easier to read this way. Twice isn't so bad. We can always change it in the future if desired, but it would have the disadvantage that the GTlsDatabaseGnutls's private data would no longer be read-only after initialization, which doesn't seem worth it. That rule makes it easier to reason about correctness. Part-of: <!249>
Loading