[vlc-commits] gnutls: support SSH-style first use certificate authentication
Rémi Denis-Courmont
git at videolan.org
Sun Sep 30 15:45:16 CEST 2012
vlc | branch: master | Rémi Denis-Courmont <remi at 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);
More information about the vlc-commits
mailing list