[gnutls-devel] [sr #108634] Getter functions for gnutls_certificate_credentials_t

Armin Burgmeier armin at arbur.net
Wed Sep 10 17:15:39 CEST 2014


On Wed, 2014-09-10 at 10:34 +0200, Nikos Mavrogiannopoulos wrote:
> On Mon, Sep 8, 2014 at 3:59 PM, Armin Burgmeier <armin at arbur.net> wrote:
> 
> >> 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.
> 
> Ok, so I understand you would prefer to get as many as possible flags
> from the verification process.
> However, I'm not really sure that you add any value from that
> additional check. In the end an attacker would simply need to put an
> arbitrary end-user certificate in the chain and you'll revert to trust
> on first use just the same.

I agree. If I understand correctly, however, SSH is in exactly the same
situation.

The value from the additional check is that I don't have to bug my users
with an extra dialog when the server has a certificate that is issued by
a trusted CA. Only when that is not the case I resort to
trust-on-first-use. Then yes, an attacker could present an arbitrary
certificate; but if the user has connected to the server before already
it will detect that the certificate is different from the previous
connection attempt.

The whole situation is obviously not bullet-proof; I'm basically aiming
for a compromise between security and convenience -- don't want to force
people to get a CA-issued certificate to use the application but still
provide as much security as possible.

> > 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.
> 
> It's up to you how to use that API. It can be used with PKIX
> authentication or entirely separate.
> 
> >> > 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?
> 
> It seems ok, although there will be a discrepancy. The
> gnutls_privkey_t will not be released by the user, while the
> x509_crt_t should be released.

We could instead return a copy of the gnutls_privkey_t, so that it has
to be released as well by the user. This would then again give some
flexibility in case the key storage inside the credentials structure
changes at some point in the future.

>  Maybe for consistency it would make
> sense to generate it on the fly, cache in the structure, and
> deinitialize it when whole structure gets deinitialized. Such an API
> should allow flexibility on the exporting type of the certificate as
> well, since openpgp or raw public keys should be able to be exported
> as well (even if that functionality is not implemented initially).

In that case, the keys and certificates would then be stored twice in
memory again (once they have been queried via the new API). That idea is
not very appealing to me, but maybe it's just a matter of taste...
either way should work for what I would need the new API for.

What I don't understand is, how would returning a new
certificate/private key not allow openpgp or raw keys to be exported?

Cheers,
Armin




More information about the Gnutls-devel mailing list