vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Fri Aug 22 23:32:48 2014 +0300| [f283e2537366f47ba8ccea582763ea086290164f] | committer: Rémi Denis-Courmont
gnutls: simplify certificate verification > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f283e2537366f47ba8ccea582763ea086290164f --- modules/misc/gnutls.c | 75 +++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 55 deletions(-) diff --git a/modules/misc/gnutls.c b/modules/misc/gnutls.c index c67c5f5..5a1bf3b 100644 --- a/modules/misc/gnutls.c +++ b/modules/misc/gnutls.c @@ -333,22 +333,6 @@ static int gnutls_CertSearch (vlc_tls_t *obj, const char *host, } -static struct -{ - unsigned flag; - const char msg[29]; -} cert_errs[] = -{ - { GNUTLS_CERT_INVALID, "Certificate not verified" }, - { GNUTLS_CERT_REVOKED, "Certificate revoked" }, - { GNUTLS_CERT_SIGNER_NOT_FOUND, "Signer not found" }, - { GNUTLS_CERT_SIGNER_NOT_CA, "Signer not a CA" }, - { GNUTLS_CERT_INSECURE_ALGORITHM, "Signature algorithm insecure" }, - { GNUTLS_CERT_NOT_ACTIVATED, "Certificate not activated" }, - { GNUTLS_CERT_EXPIRED, "Certificate expired" }, -}; - - static int gnutls_HandshakeAndValidate (vlc_tls_t *session, const char *host, const char *service) { @@ -361,29 +345,37 @@ static int gnutls_HandshakeAndValidate (vlc_tls_t *session, const char *host, /* certificates chain verification */ unsigned status; - val = gnutls_certificate_verify_peers2 (sys->session, &status); + val = gnutls_certificate_verify_peers3 (sys->session, host, &status); if (val) { msg_Err (session, "Certificate verification error: %s", gnutls_strerror (val)); return -1; } - if (status) + + if (status == 0) + return 0; /* good certificate */ + + gnutls_datum_t datum; + + if (gnutls_certificate_verification_status_print(status, + gnutls_certificate_type_get (sys->session), &datum, 0) == 0) { - msg_Err (session, "Certificate verification failure (0x%04X)", status); - for (size_t i = 0; i < sizeof (cert_errs) / sizeof (cert_errs[0]); i++) - if (status & cert_errs[i].flag) - msg_Err (session, " * %s", cert_errs[i].msg); - if (status & ~(GNUTLS_CERT_INVALID|GNUTLS_CERT_SIGNER_NOT_FOUND)) - return -1; + msg_Err (session, "Certificate verification failure: %s", datum.data); + gnutls_free (datum.data); } - if (host == NULL) - return status ? -1 : 0; + status &= ~GNUTLS_CERT_INVALID; /* always set / catch-all error */ + status &= ~GNUTLS_CERT_SIGNER_NOT_FOUND; /* unknown CA */ + status &= ~GNUTLS_CERT_UNEXPECTED_OWNER; /* mismatched hostname */ + + if (status != 0 || host == NULL) + return -1; /* really bad certificate */ - /* certificate (host)name verification */ + /* manual verification */ const gnutls_datum_t *data; unsigned count; + data = gnutls_certificate_get_peers (sys->session, &count); if (data == NULL || count == 0) { @@ -392,34 +384,7 @@ static int gnutls_HandshakeAndValidate (vlc_tls_t *session, const char *host, } msg_Dbg (session, "%u certificate(s) in the list", count); - if (status && gnutls_CertSearch (session, host, service, data)) - return -1; - - gnutls_x509_crt_t cert; - val = gnutls_x509_crt_init (&cert); - if (val) - { - msg_Err (session, "X.509 fatal error: %s", gnutls_strerror (val)); - return -1; - } - - val = gnutls_x509_crt_import (cert, data, GNUTLS_X509_FMT_DER); - if (val) - { - msg_Err (session, "Certificate import error: %s", - gnutls_strerror (val)); - goto error; - } - - val = !gnutls_x509_crt_check_hostname (cert, host); - if (val) - { - msg_Err (session, "Certificate does not match \"%s\"", host); - val = gnutls_CertSearch (session, host, service, data); - } -error: - gnutls_x509_crt_deinit (cert); - return val; + return gnutls_CertSearch (session, host, service, data); } static int _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
