vlc | branch: master | Rémi Denis-Courmont <r...@remlab.net> | Sun Sep 30 16:32:08 2012 +0300| [dd782427396b32a74aaa5e2d27c3cce1bbf3f1bd] | committer: Rémi Denis-Courmont
gnutls: support SSH-style first use certificate authentication If a certificate does not validate, the user will be given the option to accept it manually. GnuTLS will then store the certificate in its known hosts database. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=dd782427396b32a74aaa5e2d27c3cce1bbf3f1bd --- modules/misc/gnutls.c | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/modules/misc/gnutls.c b/modules/misc/gnutls.c index 56124cb..7ca5063 100644 --- a/modules/misc/gnutls.c +++ b/modules/misc/gnutls.c @@ -247,9 +247,29 @@ static int gnutls_ContinueHandshake (vlc_tls_t *session, const char *host, * @return 0 on success, -1 on failure. */ static int gnutls_CertSearch (vlc_tls_t *obj, const char *host, + const char *service, const gnutls_datum_t *restrict datum) { assert (host != NULL); + /* Look up mismatching certificate in store */ + int val = gnutls_verify_stored_pubkey (NULL, NULL, host, service, + GNUTLS_CRT_X509, datum, 0); + switch (val) + { + case 0: + msg_Dbg (obj, "certificate key match for %s", host); + return 0; + case GNUTLS_E_NO_CERTIFICATE_FOUND: + msg_Dbg (obj, "no known certificates for %s", host); + break; + case GNUTLS_E_CERTIFICATE_KEY_MISMATCH: + msg_Dbg (obj, "certificate keys mismatch for %s", host); + break; + default: + msg_Err (obj, "certificate key match error for %s: %s", host, + gnutls_strerror (val)); + return -1; + } if (dialog_Question (obj, N_("Insecure site"), N_("You attempted to reach %s, but security certificate presented by " @@ -273,14 +293,25 @@ static int gnutls_CertSearch (vlc_tls_t *obj, const char *host, } gnutls_x509_crt_deinit (cert); - int val = dialog_Question (obj, N_("Insecure site"), + val = dialog_Question (obj, N_("Insecure site"), N_("This is the certificate presented by %s:\n%s\n\n" "If in doubt, abort now.\n"), - N_("Abort"), N_("Proceed anyway"), NULL, - host, desc.data); + N_("Abort"), N_("Accept 24 hours"), + N_("Accept permanently"), host, desc.data); gnutls_free (desc.data); - return (val == 2) ? 0 : -1; + time_t expiry = 0; + switch (val) + { + case 2: + time (&expiry); + expiry += 24 * 60 * 60; + case 3: + gnutls_store_pubkey (NULL, NULL, host, service, GNUTLS_CRT_X509, + datum, expiry, 0); + return 0; + } + return -1; } @@ -361,7 +392,7 @@ static int gnutls_HandshakeAndValidate (vlc_tls_t *session, const char *host, if (val || host == NULL) return val; - if (status && gnutls_CertSearch (session, host, data)) + if (status && gnutls_CertSearch (session, host, service, data)) return -1; gnutls_x509_crt_t cert; @@ -384,7 +415,7 @@ static int gnutls_HandshakeAndValidate (vlc_tls_t *session, const char *host, if (val) { msg_Err (session, "Certificate does not match \"%s\"", host); - val = gnutls_CertSearch (session, host, data); + val = gnutls_CertSearch (session, host, service, data); } error: gnutls_x509_crt_init (&cert); _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org http://mailman.videolan.org/listinfo/vlc-commits