diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-10-30 19:18:24 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-10-30 19:24:24 +0100 |
commit | 4ecbf335793e040c74e1e45dd51269c544bb7605 (patch) | |
tree | cfbd2ac36f7b6ffd5dcfb11f76dd64580b0e2e12 | |
parent | c8008cae74231ac83b08a2dc995415f2fea497fc (diff) | |
download | gnutls-4ecbf335793e040c74e1e45dd51269c544bb7605.tar.gz |
Added gnutls_certificate_verification_status_print().
This function simplifies printing the certificate verification status.
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | doc/examples/ex-client-x509.c | 24 | ||||
-rw-r--r-- | doc/examples/ex-verify-ssh.c | 36 | ||||
-rw-r--r-- | doc/examples/verify.c | 27 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 85 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 4 | ||||
-rw-r--r-- | lib/libgnutls.map | 1 | ||||
-rw-r--r-- | lib/x509/output.c | 6 | ||||
-rw-r--r-- | src/common.c | 49 |
9 files changed, 144 insertions, 89 deletions
@@ -22,6 +22,7 @@ gnutls_certificate_verify_peers3(). gnutls_session_get_id2: Added gnutls_certificate_update_verify_flags: Added gnutls_certificate_verify_peers3: Added +gnutls_certificate_verification_status_print: Added GNUTLS_CERT_REVOCATION_DATA_TOO_OLD: Added. GNUTLS_CERT_REVOCATION_DATA_INVALID: Added. diff --git a/doc/examples/ex-client-x509.c b/doc/examples/ex-client-x509.c index 3c90e952a1..6e38a15615 100644 --- a/doc/examples/ex-client-x509.c +++ b/doc/examples/ex-client-x509.c @@ -142,8 +142,9 @@ static int _verify_certificate_callback (gnutls_session_t session) { unsigned int status; - int ret; + int ret, type; const char *hostname; + gnutls_datum_t out; /* read hostname */ hostname = gnutls_session_get_ptr (session); @@ -158,23 +159,18 @@ _verify_certificate_callback (gnutls_session_t session) return GNUTLS_E_CERTIFICATE_ERROR; } - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - printf ("The certificate hasn't got a known issuer.\n"); + type = gnutls_certificate_type_get (session); - if (status & GNUTLS_CERT_REVOKED) - printf ("The certificate has been revoked.\n"); - - if (status & GNUTLS_CERT_EXPIRED) - printf ("The certificate has expired\n"); - - if (status & GNUTLS_CERT_NOT_ACTIVATED) - printf ("The certificate is not yet activated\n"); - - if (status & GNUTLS_CERT_INVALID) + ret = gnutls_certificate_verification_status_print( status, type, &out, 0); + if (ret < 0) { - printf ("The certificate is not trusted.\n"); + printf ("Error\n"); return GNUTLS_E_CERTIFICATE_ERROR; } + + printf ("%s", out.data); + + gnutls_free(out.data); /* notify gnutls to continue handshake normally */ return 0; diff --git a/doc/examples/ex-verify-ssh.c b/doc/examples/ex-verify-ssh.c index 28e09ac97e..9251b78b23 100644 --- a/doc/examples/ex-verify-ssh.c +++ b/doc/examples/ex-verify-ssh.c @@ -22,7 +22,8 @@ _ssh_verify_certificate_callback (gnutls_session_t session) unsigned int status; const gnutls_datum_t *cert_list; unsigned int cert_list_size; - int ret; + int ret, type; + gnutls_datum_t out; const char *hostname; /* read hostname */ @@ -37,22 +38,21 @@ _ssh_verify_certificate_callback (gnutls_session_t session) printf ("Error\n"); return GNUTLS_E_CERTIFICATE_ERROR; } + + type = gnutls_certificate_type_get (session); - if (status & GNUTLS_CERT_INVALID) - printf ("The certificate is not trusted.\n"); - - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - printf ("The certificate hasn't got a known issuer.\n"); - - if (status & GNUTLS_CERT_REVOKED) - printf ("The certificate has been revoked.\n"); - - if (status & GNUTLS_CERT_EXPIRED) - printf ("The certificate has expired\n"); - - if (status & GNUTLS_CERT_NOT_ACTIVATED) - printf ("The certificate is not yet activated\n"); + ret = gnutls_certificate_verification_status_print( status, type, &out, 0); + if (ret < 0) + { + printf ("Error\n"); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + printf ("%s", out.data); + + gnutls_free(out.data); + /* Do SSH verification */ cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list == NULL) { @@ -62,8 +62,7 @@ _ssh_verify_certificate_callback (gnutls_session_t session) /* service may be obtained alternatively using getservbyport() */ ret = gnutls_verify_stored_pubkey(NULL, NULL, hostname, "https", - gnutls_certificate_type_get (session), - &cert_list[0], 0); + type, &cert_list[0], 0); if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND) { printf("Host %s is not known.", hostname); @@ -99,8 +98,7 @@ _ssh_verify_certificate_callback (gnutls_session_t session) if (ret != 0) { ret = gnutls_store_pubkey(NULL, NULL, hostname, "https", - gnutls_certificate_type_get (session), - &cert_list[0], 0, 0); + type, &cert_list[0], 0, 0); if (ret < 0) printf("gnutls_store_pubkey: %s\n", gnutls_strerror(ret)); } diff --git a/doc/examples/verify.c b/doc/examples/verify.c index 10aed207bb..8fd593136c 100644 --- a/doc/examples/verify.c +++ b/doc/examples/verify.c @@ -13,8 +13,9 @@ int verify_certificate_callback (gnutls_session_t session) { unsigned int status; - int ret; + int ret, type; const char *hostname; + gnutls_datum_t out; /* read hostname */ hostname = gnutls_session_get_ptr (session); @@ -29,20 +30,18 @@ int verify_certificate_callback (gnutls_session_t session) return GNUTLS_E_CERTIFICATE_ERROR; } - if (status & GNUTLS_CERT_INVALID) - printf ("The certificate is not trusted.\n"); + type = gnutls_certificate_type_get (session); - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - printf ("The certificate hasn't got a known issuer.\n"); - - if (status & GNUTLS_CERT_REVOKED) - printf ("The certificate has been revoked.\n"); - - if (status & GNUTLS_CERT_EXPIRED) - printf ("The certificate has expired\n"); - - if (status & GNUTLS_CERT_NOT_ACTIVATED) - printf ("The certificate is not yet activated\n"); + ret = gnutls_certificate_verification_status_print( status, type, &out, 0); + if (ret < 0) + { + printf ("Error\n"); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + printf ("%s", out.data); + + gnutls_free(out.data); /* notify gnutls to continue handshake normally */ return 0; diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index ef1a3dcc0b..f803a65dd6 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -41,6 +41,8 @@ #ifdef ENABLE_OPENPGP #include "openpgp/gnutls_openpgp.h" #endif +#include "gettext.h" +#define _(String) dgettext (PACKAGE, String) /** * gnutls_certificate_free_keys: @@ -902,3 +904,86 @@ _gnutls_check_key_cert_match (gnutls_certificate_credentials_t res) return 0; } + +/** + * gnutls_certificate_verification_status_print: + * @status: The status flags to be printed + * @type: The certificate type + * @out: Newly allocated datum with (0) terminated string. + * @flags: should be zero + * + * This function will pretty print the status of a verification + * process -- eg. the one obtained by gnutls_certificate_verify_peers3(). + * + * The output @out needs to be deallocated using gnutls_free(). + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + **/ +int +gnutls_certificate_verification_status_print (unsigned int status, + gnutls_certificate_type_t type, + gnutls_datum_t * out, unsigned int flags) +{ + gnutls_buffer_st str; + int ret; + + _gnutls_buffer_init (&str); + + if (type == GNUTLS_CRT_X509) + { + if (status == 0) + _gnutls_buffer_append_str (&str, _("- Peer's certificate is trusted\n")); + else + { + if (status & GNUTLS_CERT_INVALID) + _gnutls_buffer_append_str (&str, _("- Peer's certificate is NOT trusted\n")); + + if (status & GNUTLS_CERT_REVOKED) + _gnutls_buffer_append_str (&str, _("- Peer's certificate chain revoked\n")); + + if (status & GNUTLS_CERT_REVOCATION_DATA_TOO_OLD) + _gnutls_buffer_append_str (&str, _("- The revocation data provided by the peer are too old\n")); + + if (status & GNUTLS_CERT_REVOCATION_DATA_INVALID) + _gnutls_buffer_append_str (&str, _("- The revocation data provided by the peer are invalid\n")); + + if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) + _gnutls_buffer_append_str (&str, _("- Peer's certificate issuer is unknown\n")); + + if (status & GNUTLS_CERT_SIGNER_NOT_CA) + _gnutls_buffer_append_str (&str, _("- Peer's certificate issuer is not a CA\n")); + } + } + else if (type == GNUTLS_CRT_OPENPGP) + { + if (status == 0) + _gnutls_buffer_append_str (&str, _("- Peer's key is valid\n")); + + if (status & GNUTLS_CERT_INVALID) + _gnutls_buffer_append_str (&str, _("- Peer's certificate is invalid\n")); + + if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) + _gnutls_buffer_append_str (&str, _("- Could not find a signer of the peer's certificate\n")); + + if (status & GNUTLS_CERT_REVOKED) + _gnutls_buffer_append_str (&str, _("- Peer's certificate is revoked\n")); + } + + if (status & GNUTLS_CERT_INSECURE_ALGORITHM) + _gnutls_buffer_append_str (&str, _("- Peer's certificate chain uses insecure algorithm\n")); + + if (status & GNUTLS_CERT_NOT_ACTIVATED) + _gnutls_buffer_append_str (&str, _("- Peer's certificate chain uses not yet valid certificate\n")); + + if (status & GNUTLS_CERT_EXPIRED) + _gnutls_buffer_append_str (&str, _("- Peer's certificate chain uses expired certificate\n")); + + if (status & GNUTLS_CERT_UNEXPECTED_OWNER) + _gnutls_buffer_append_str (&str, _("- The name in the certificate does not match the expected\n")); + + ret = _gnutls_buffer_to_datum( &str, out); + if (out->size > 0) out->size--; + + return ret; +} diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 8a48479965..98a86fb83e 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1705,6 +1705,10 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session); const char* hostname, unsigned int *status); + int gnutls_certificate_verification_status_print (unsigned int status, + gnutls_certificate_type_t type, + gnutls_datum_t * out, unsigned int flags); + int gnutls_pem_base64_encode (const char *msg, const gnutls_datum_t * data, char *result, size_t * result_size); int gnutls_pem_base64_decode (const char *header, diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 278524b988..e20597c737 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -860,6 +860,7 @@ GNUTLS_3_1_0 { gnutls_session_get_id2; gnutls_certificate_update_verify_flags; gnutls_certificate_verify_peers3; + gnutls_certificate_verification_status_print; } GNUTLS_3_0_0; GNUTLS_PRIVATE { diff --git a/lib/x509/output.c b/lib/x509/output.c index 1797b26419..ec1a6f271e 100644 --- a/lib/x509/output.c +++ b/lib/x509/output.c @@ -1711,7 +1711,7 @@ print_oneline (gnutls_buffer_st * str, gnutls_x509_crt_t cert) * %GNUTLS_CRT_PRINT_ONELINE format will generate one line with some * selected fields, which is useful for logging purposes. * - * The output @out needs to be deallocate using gnutls_free(). + * The output @out needs to be deallocated using gnutls_free(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. @@ -2086,7 +2086,7 @@ print_crl (gnutls_buffer_st * str, gnutls_x509_crl_t crl, int notsigned) * This function will pretty print a X.509 certificate revocation * list, suitable for display to a human. * - * The output @out needs to be deallocate using gnutls_free(). + * The output @out needs to be deallocated using gnutls_free(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. @@ -2400,7 +2400,7 @@ print_crq_other (gnutls_buffer_st * str, gnutls_x509_crq_t crq) * This function will pretty print a certificate request, suitable for * display to a human. * - * The output @out needs to be deallocate using gnutls_free(). + * The output @out needs to be deallocated using gnutls_free(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. diff --git a/src/common.c b/src/common.c index 4f3c9d895e..3e8932a5e8 100644 --- a/src/common.c +++ b/src/common.c @@ -314,6 +314,7 @@ cert_verify (gnutls_session_t session, const char* hostname) { int rc; unsigned int status = 0; + gnutls_datum_t out; int type; rc = gnutls_certificate_verify_peers3 (session, hostname, &status); @@ -331,48 +332,18 @@ cert_verify (gnutls_session_t session, const char* hostname) } type = gnutls_certificate_type_get (session); - if (type == GNUTLS_CRT_X509) - { - - if (status & GNUTLS_CERT_REVOKED) - printf ("- Peer's certificate chain revoked\n"); - if (status & GNUTLS_CERT_REVOCATION_DATA_TOO_OLD) - printf ("- The revocation data provided by the peer are too old\n"); - if (status & GNUTLS_CERT_REVOCATION_DATA_INVALID) - printf ("- The revocation data provided by the peer are invalid\n"); - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - printf ("- Peer's certificate issuer is unknown\n"); - if (status & GNUTLS_CERT_SIGNER_NOT_CA) - printf ("- Peer's certificate issuer is not a CA\n"); - if (status & GNUTLS_CERT_INSECURE_ALGORITHM) - printf - ("- Peer's certificate chain uses insecure algorithm\n"); - if (status & GNUTLS_CERT_NOT_ACTIVATED) - printf - ("- Peer's certificate chain uses not yet valid certificate\n"); - if (status & GNUTLS_CERT_EXPIRED) - printf - ("- Peer's certificate chain uses expired certificate\n"); - if (status & GNUTLS_CERT_INVALID) - printf ("- Peer's certificate is NOT trusted\n"); - else - printf ("- Peer's certificate is trusted\n"); - } - else if (type == GNUTLS_CRT_OPENPGP) - { - if (status & GNUTLS_CERT_INVALID) - printf ("- Peer's key is invalid\n"); - else - printf ("- Peer's key is valid\n"); - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - printf ("- Could not find a signer of the peer's key\n"); - } - else + rc = gnutls_certificate_verification_status_print( status, type, &out, 0); + if (rc < 0) { - fprintf(stderr, "Unknown certificate type\n"); - status |= GNUTLS_CERT_INVALID; + printf ("- Could not print verification flags (err: %s)\n", + gnutls_strerror (rc)); + return 0; } + printf ("%s", out.data); + + gnutls_free(out.data); + if (status) return 0; |