[gnutls-devel] [sr #108634] Getter functions for gnutls_certificate_credentials_t
armin at arbur.net
Mon Sep 8 15:59:56 CEST 2014
On Mon, 2014-09-08 at 11:23 +0200, Nikos Mavrogiannopoulos wrote:
> On Sun, Sep 7, 2014 at 10:04 PM, Armin Burgmeier
> <INVALID.NOREPLY at gnu.org> wrote:
> > Follow-up Comment #3, sr #108634 (project gnutls):
> >> I have misread you message. Which function has that limitation and would
> > you suggest to address that issue?
> > All the certificate verification functions I think. The limitation is in the
> > internal function "verify_crt" in x509/verify.c. If, for example, the verify
> > result is GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE or
> > GNUTLS_CERT_SIGNER_NOT_FOUND, then the certificate is not checked for other
> > problems, such as whether it is expired. Other errors, such as
> > GNUTLS_CERT_SIGNATURE_FAILURE, do not stop the procedure and certificate
> > checking continues.
> Indeed, if the constraints fail it would not proceed to the
> verification itself. I don't know if that's useful to proceed. If you
> could make a description of your use-case it may help to figure out
> whether some changes should be done.
My use-case is the following. I'm verifying the certificate of a peer.
If the certificate validates, I want to just go on with the connection.
However, if the signer of the certificate is not in my trust list, I
want to present a dialog to the user asking whether the certificate
should be trusted, for example if it is a self-signed certificate.
However, if the certificate is invalid beyond the signer not trusted
error (signature failure, or expired), then I want to reject the
connection without any user interaction.
At the moment I am achieving this by verifying the certificate twice:
Once "normally", and if that returns GNUTLS_CERT_SIGNER_NOT_FOUND, then
I am verifying it again but this time I add the certificate's issuer (as
sent by the peer) in the trust list artificially, so that the signer is
always found and the certificate is checked for other flaws.
In the end this is a bit like SSH-like trust-on-first-use... I
understand there is actually a API in gnutls for something very similar,
but from what I have seen this is on top of the "issuer trusted" check,
and not replacing it.
> >> That as I understand would be possible by a function that enumerates all
> > certificates in a trust list. Is that correct?
> > In addition I would need to get the trust list from the
> > gnutls_certificate_credentials_t structure, I think. It would also be nice to
> > obtain the private key (gnutls_x509_privkey_t) and certificate(s)
> > (gnutls_x509_crt_t) from that structure, not only the trust list.
> That would be indeed useful. The certificate_credentials_t
> functionality typically wraps over the functionality of trusted_list,
> so that would be ok.
> The data should be extracted from a trust list/credentials however in
> a way that don't assume much about the internal structure of it, in
> order to allow a revamp without affecting the API.
> A way for example to export the trusted CAs from the trusted list
> would be using an iterator similarly to
Okay, this sounds reasonable.
> >From the certificate_credentials_t structure you could export the
> private key as a gnutls_privkey_t (and assume that this will be the
> format used internally by gnutls), but for the certificates, you only
> have gnutls_pubkey_t and a datum with the DER data held internally. I
> don't know if that would suffice.
> > What I would like to do is to only keep the gnutls_certificate_credentials_t
> > structure, and when I need to show the common name in the user interface, I
> > would get the certificate from the gnutls_certificate_credentials_t, and then
> > get the name from the certificate. Then I would only end up with the private
> > key and certificate once in my program's memory.
> That would be tricky as gnutls doesn't hold internally a
> gnutls_x509_crt_t. You could of course add functionality to get the
> DER encoding of the certificate from the credentials, decode it and
> get an x509_crt_t, but that you can already do with
> gnutls_certificate_get_ours(). I'm not sure I have a good suggestion
> for that case.
For my case, just exporting the DER-encoded data would be fine.
Basically just like gnutls_certificate_get_ours(), but with a
gnutls_certificate_credentials_t instead of a gnutls_session_t.
In terms of API flexibility however, it might make sense to construct a
new gnutls_x509_crt_t and return that, i.e. doing the DER-decoding
inside gnutls, and documenting that the caller should
gnutls_x509_crt_free() the result. In this case, the API would always
return a newly constructed gnutls_x509_crt_t, but it is independent of
the actual storage in the credentials structure, as long as what is
stored can be converted to a gnutls_x509_crt_t.
What do you think?
More information about the Gnutls-devel