void print_cert_info (gnutls_session_t session, const char *hostname, int insecure) { if (gnutls_certificate_client_get_request_status (session) != 0) printf ("- Server has requested a certificate.\n"); printf ("- Certificate type: "); switch (gnutls_certificate_type_get (session)) { case GNUTLS_CRT_UNKNOWN: printf ("Unknown\n"); if (!insecure) exit (1); break; case GNUTLS_CRT_X509: printf ("X.509\n"); print_x509_info (session, hostname, insecure); break; #ifdef ENABLE_OPENPGP case GNUTLS_CRT_OPENPGP: printf ("OpenPGP\n"); print_openpgp_info (session, hostname, insecure); break; #endif } }
/* sanity-checking wrapper for gnutls_certificate_verify_peers */ static gnutls_certificate_status tls_verify_peers (gnutls_session tlsstate) { int verify_ret; unsigned int status; verify_ret = gnutls_certificate_verify_peers2 (tlsstate, &status); if (!verify_ret) return status; if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) { mutt_error (_("Unable to get certificate from peer")); mutt_sleep (2); return 0; } if (verify_ret < 0) { mutt_error (_("Certificate verification error (%s)"), gnutls_strerror (status)); mutt_sleep (2); return 0; } /* We only support X.509 certificates (not OpenPGP) at the moment */ if (gnutls_certificate_type_get (tlsstate) != GNUTLS_CRT_X509) { mutt_error (_("Certificate is not X.509")); mutt_sleep (2); return 0; } return status; }
unsigned char * get_ssl_connection_cipher(struct socket *socket) { ssl_t *ssl = socket->ssl; struct string str; if (!init_string(&str)) return NULL; #ifdef USE_OPENSSL add_format_to_string(&str, "%ld-bit %s %s", SSL_get_cipher_bits(ssl, NULL), SSL_get_cipher_version(ssl), SSL_get_cipher_name(ssl)); #elif defined(CONFIG_GNUTLS) /* XXX: How to get other relevant parameters? */ add_format_to_string(&str, "%s - %s - %s - %s - %s (compr: %s)", gnutls_protocol_get_name(gnutls_protocol_get_version(*ssl)), gnutls_kx_get_name(gnutls_kx_get(*ssl)), gnutls_cipher_get_name(gnutls_cipher_get(*ssl)), gnutls_mac_get_name(gnutls_mac_get(*ssl)), gnutls_certificate_type_get_name(gnutls_certificate_type_get(*ssl)), gnutls_compression_get_name(gnutls_compression_get(*ssl))); #endif return str.source; }
/** * gnutls_certificate_verify_peers3: * @session: is a gnutls session * @hostname: is the expected name of the peer; may be %NULL * @status: is the output of the verification * * This function will verify the peer's certificate and store the * status in the @status variable as a bitwise or'd gnutls_certificate_status_t * values or zero if the certificate is trusted. Note that value in @status * is set only when the return value of this function is success (i.e, failure * to trust a certificate does not imply a negative return value). * * If the @hostname provided is non-NULL then this function will compare * the hostname in the certificate against the given. If they do not match * the %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set. * * If available the OCSP Certificate Status extension will be * utilized by this function. * * To avoid denial of service attacks some * default upper limits regarding the certificate key size and chain * size are set. To override them use gnutls_certificate_set_verify_limits(). * * Returns: a negative error code on error and %GNUTLS_E_SUCCESS (0) on success. * * Since: 3.1.4 **/ int gnutls_certificate_verify_peers3 (gnutls_session_t session, const char* hostname, unsigned int *status) { cert_auth_info_t info; CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST); info = _gnutls_get_auth_info (session); if (info == NULL) { return GNUTLS_E_NO_CERTIFICATE_FOUND; } if (info->raw_certificate_list == NULL || info->ncerts == 0) return GNUTLS_E_NO_CERTIFICATE_FOUND; switch (gnutls_certificate_type_get (session)) { case GNUTLS_CRT_X509: return _gnutls_x509_cert_verify_peers (session, hostname, status); #ifdef ENABLE_OPENPGP case GNUTLS_CRT_OPENPGP: return _gnutls_openpgp_crt_verify_peers (session, hostname, status); #endif default: return GNUTLS_E_INVALID_REQUEST; } }
/** * gnutls_certificate_activation_time_peers: * @session: is a gnutls session * * This function will return the peer's certificate activation time. * This is the creation time for openpgp keys. * * Returns: (time_t)-1 on error. * * Deprecated: gnutls_certificate_verify_peers2() now verifies activation times. **/ time_t gnutls_certificate_activation_time_peers (gnutls_session_t session) { cert_auth_info_t info; CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST); info = _gnutls_get_auth_info (session); if (info == NULL) { return (time_t) - 1; } if (info->raw_certificate_list == NULL || info->ncerts == 0) { gnutls_assert (); return (time_t) - 1; } switch (gnutls_certificate_type_get (session)) { case GNUTLS_CRT_X509: return _gnutls_x509_get_raw_crt_activation_time (&info->raw_certificate_list [0]); #ifdef ENABLE_OPENPGP case GNUTLS_CRT_OPENPGP: return _gnutls_openpgp_get_raw_key_creation_time (&info->raw_certificate_list [0]); #endif default: return (time_t) - 1; } }
int verify_certificate (gnutls_session session, char* CN) { unsigned int cert_list_size; const gnutls_datum *cert_list; int ret; char dn[MAX_DN_LEN]; size_t dn_len = MAX_DN_LEN; gnutls_x509_crt cert; ret = gnutls_certificate_verify_peers(session); if (ret < 0) { quorum_debug(LOG_DEBUG,"gnutls_certificate_verify_peers2 returns error"); return -1; } if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { quorum_debug(LOG_DEBUG,"The certificate is not a x.509 cert"); return -1; } if (gnutls_x509_crt_init (&cert) < 0) { quorum_debug(LOG_DEBUG,"error in gnutls_x509_crt_init"); return -1; } cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list == NULL) { quorum_debug(LOG_DEBUG,"No certificate was found!"); return -1; } if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) { quorum_debug(LOG_DEBUG,"error parsing certificate"); return -1; } if (gnutls_x509_crt_get_expiration_time (cert) < time (0)) { quorum_debug(LOG_DEBUG,"The certificate has expired"); return -1; } if (gnutls_x509_crt_get_activation_time (cert) > time (0)) { quorum_debug(LOG_DEBUG,"The certificate is not yet activated"); return -1; } memset(dn, 0, MAX_DN_LEN); gnutls_x509_crt_get_dn(cert, dn, &dn_len); strncpy(CN, strstr(dn, "CN=")+3, MAX_DN_LEN); CN[MAX_DN_LEN-1]= '\0'; quorum_debug(LOG_DEBUG,"The certificate cn:%s",CN); gnutls_x509_crt_deinit (cert); return 0; }
static void tls_print_session_info(const host_addr_t addr, uint16 port, gnutls_session session, bool incoming) { const char *proto, *cert, *kx, *ciph, *mac, *comp; g_return_if_fail(session); proto = gnutls_protocol_get_name(gnutls_protocol_get_version(session)); cert = gnutls_certificate_type_get_name( gnutls_certificate_type_get(session)); kx = gnutls_kx_get_name(gnutls_kx_get(session)); comp = gnutls_compression_get_name(gnutls_compression_get(session)); ciph = gnutls_cipher_get_name(gnutls_cipher_get(session)); mac = gnutls_mac_get_name(gnutls_mac_get (session)); g_debug( "TLS session info (%s):\n" " Host: %s\n" " Protocol: %s\n" " Certificate: %s\n" " Key Exchange: %s\n" " Cipher: %s\n" " MAC: %s\n" " Compression: %s", incoming ? "incoming" : "outgoing", host_addr_port_to_string(addr, port), NULL_STRING(proto), NULL_STRING(cert), NULL_STRING(kx), NULL_STRING(ciph), NULL_STRING(mac), NULL_STRING(comp) ); }
int rb_get_ssl_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN], int method) { gnutls_x509_crt_t cert; gnutls_digest_algorithm_t algo; unsigned int cert_list_size; const gnutls_datum_t *cert_list; uint8_t digest[RB_SSL_CERTFP_LEN * 2]; size_t digest_size; int len; if (gnutls_certificate_type_get(SSL_P(F)) != GNUTLS_CRT_X509) return 0; if (gnutls_x509_crt_init(&cert) < 0) return 0; cert_list_size = 0; cert_list = gnutls_certificate_get_peers(SSL_P(F), &cert_list_size); if (cert_list == NULL) { gnutls_x509_crt_deinit(cert); return 0; } if (gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) { gnutls_x509_crt_deinit(cert); return 0; } switch(method) { case RB_SSL_CERTFP_METH_SHA1: algo = GNUTLS_DIG_SHA1; len = RB_SSL_CERTFP_LEN_SHA1; break; case RB_SSL_CERTFP_METH_SHA256: algo = GNUTLS_DIG_SHA256; len = RB_SSL_CERTFP_LEN_SHA256; break; case RB_SSL_CERTFP_METH_SHA512: algo = GNUTLS_DIG_SHA512; len = RB_SSL_CERTFP_LEN_SHA512; break; default: return 0; } if (gnutls_x509_crt_get_fingerprint(cert, algo, digest, &digest_size) < 0) { gnutls_x509_crt_deinit(cert); return 0; } memcpy(certfp, digest, len); gnutls_x509_crt_deinit(cert); return len; }
static int mailstream_gnutls_client_cert_cb(gnutls_session session, const gnutls_datum *req_ca_rdn, int nreqs, const gnutls_pk_algorithm *sign_algos, int sign_algos_length, gnutls_retr2_st *st) #endif { struct mailstream_ssl_context * ssl_context = (struct mailstream_ssl_context *)gnutls_session_get_ptr(session); gnutls_certificate_type type = gnutls_certificate_type_get(session); st->ncerts = 0; if (ssl_context == NULL) return 0; if (type == GNUTLS_CRT_X509 && ssl_context->client_x509 && ssl_context->client_pkey) { st->ncerts = 1; #if GNUTLS_VERSION_NUMBER <= 0x020c00 st->type = type; #else st->cert_type = type; st->key_type = GNUTLS_PRIVKEY_X509; #endif st->cert.x509 = &(ssl_context->client_x509); st->key.x509 = ssl_context->client_pkey; st->deinit_all = 0; } return 0; }
static int verify_certificate_callback (gnutls_session_t session) { if (trust_override) return 0; // This verification function uses the trusted CAs in the credentials // structure. So you must have installed one or more CA certificates. unsigned int status = 0; #if GNUTLS_VERSION_NUMBER >= 0x030104 int ret = gnutls_certificate_verify_peers3 (session, NULL, &status); #else int ret = gnutls_certificate_verify_peers2 (session, &status); #endif if (ret < 0) return GNUTLS_E_CERTIFICATE_ERROR; #if GNUTLS_VERSION_NUMBER >= 0x030105 gnutls_certificate_type_t type = gnutls_certificate_type_get (session); gnutls_datum_t out; ret = gnutls_certificate_verification_status_print (status, type, &out, 0); if (ret < 0) return GNUTLS_E_CERTIFICATE_ERROR; gnutls_free (out.data); #endif if (status != 0) return GNUTLS_E_CERTIFICATE_ERROR; // Continue handshake. return 0; }
void print_cert_info(gnutls_session_t session, int verbose, int print_cert) { int flag; if (verbose) flag = GNUTLS_CRT_PRINT_FULL; else flag = GNUTLS_CRT_PRINT_COMPACT; if (gnutls_certificate_client_get_request_status(session) != 0) printf("- Server has requested a certificate.\n"); switch (gnutls_certificate_type_get(session)) { case GNUTLS_CRT_X509: print_x509_info(session, flag, print_cert); break; #ifdef ENABLE_OPENPGP case GNUTLS_CRT_OPENPGP: print_openpgp_info(session, flag, print_cert); break; #endif default: printf("Unknown type\n"); break; } }
static int verify_certificate_callback( gnutls_session_t session ) { unsigned int status; const gnutls_datum_t *cert_list; unsigned int cert_list_size; int gnutlsret; int verifyret = 0; gnutls_x509_crt_t cert; const char *hostname; hostname = gnutls_session_get_ptr( session ); gnutlsret = gnutls_certificate_verify_peers2( session, &status ); if( gnutlsret < 0 ) return VERIFY_CERT_ERROR; if( status & GNUTLS_CERT_INVALID ) verifyret |= VERIFY_CERT_INVALID; if( status & GNUTLS_CERT_REVOKED ) verifyret |= VERIFY_CERT_REVOKED; if( status & GNUTLS_CERT_SIGNER_NOT_FOUND ) verifyret |= VERIFY_CERT_SIGNER_NOT_FOUND; if( status & GNUTLS_CERT_SIGNER_NOT_CA ) verifyret |= VERIFY_CERT_SIGNER_NOT_CA; if( status & GNUTLS_CERT_INSECURE_ALGORITHM ) verifyret |= VERIFY_CERT_INSECURE_ALGORITHM; #ifdef GNUTLS_CERT_NOT_ACTIVATED /* Amusingly, the GnuTLS function used above didn't check for expiry until GnuTLS 2.8 or so. (See CVE-2009-1417) */ if( status & GNUTLS_CERT_NOT_ACTIVATED ) verifyret |= VERIFY_CERT_NOT_ACTIVATED; if( status & GNUTLS_CERT_EXPIRED ) verifyret |= VERIFY_CERT_EXPIRED; #endif if( gnutls_certificate_type_get( session ) != GNUTLS_CRT_X509 || gnutls_x509_crt_init( &cert ) < 0 ) return VERIFY_CERT_ERROR; cert_list = gnutls_certificate_get_peers( session, &cert_list_size ); if( cert_list == NULL || gnutls_x509_crt_import( cert, &cert_list[0], GNUTLS_X509_FMT_DER ) < 0 ) return VERIFY_CERT_ERROR; if( !gnutls_x509_crt_check_hostname( cert, hostname ) ) { verifyret |= VERIFY_CERT_INVALID; verifyret |= VERIFY_CERT_WRONG_HOSTNAME; } gnutls_x509_crt_deinit( cert ); return verifyret; }
static int cert_callback (gnutls_session_t session, const gnutls_datum_t * req_ca_rdn, int nreqs, const gnutls_pk_algorithm_t * sign_algos, int sign_algos_length, gnutls_retr_st * st) { char issuer_dn[256]; int i, ret; size_t len; gnutls_certificate_type_t type; /* Print the server's trusted CAs */ if (nreqs > 0) printf ("- Server's trusted authorities:\n"); else printf ("- Server did not send us any trusted authorities names.\n"); /* print the names (if any) */ for (i = 0; i < nreqs; i++) { len = sizeof (issuer_dn); ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len); if (ret >= 0) { printf (" [%d]: ", i); printf ("%s\n", issuer_dn); } } /* Select a certificate and return it. * The certificate must be of any of the "sign algorithms" * supported by the server. */ type = gnutls_certificate_type_get (session); if (type == GNUTLS_CRT_X509) { st->type = type; st->ncerts = 1; st->cert.x509 = &crt; st->key.x509 = key; st->deinit_all = 0; } else { return -1; } return 0; }
int verify_certificate (gnutls_session session) { unsigned int cert_list_size; const gnutls_datum *cert_list; int ret; gnutls_x509_crt cert; ret = gnutls_certificate_verify_peers (session); if (ret < 0) { printf("gnutls_certificate_verify_peers2 returns error.\n"); return -1; } if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { printf("The certificate is not a x.509 cert\n"); return -1; } if (gnutls_x509_crt_init (&cert) < 0) { printf("error in gnutls_x509_crt_init\n"); return -1; } cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list == NULL) { printf("No certificate was found!\n"); return -1; } if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) { printf("error parsing certificate\n"); return -1; } if (gnutls_x509_crt_get_expiration_time (cert) < time (0)) { printf("The certificate has expired\n"); return -1; } if (gnutls_x509_crt_get_activation_time (cert) > time (0)) { printf("The certificate is not yet activated\n"); return -1; } gnutls_x509_crt_deinit (cert); return 0; }
/* This function will log some details of the given session. */ static void logtlsinfo (gnutls_session_t session) { gnutls_credentials_type_t cred; const char *protocol = gnutls_protocol_get_name (gnutls_protocol_get_version (session)); gnutls_kx_algorithm_t kx = gnutls_kx_get (session); const char *keyexchange = gnutls_kx_get_name (kx); const char *certtype = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session)); const char *cipher = gnutls_cipher_get_name (gnutls_cipher_get (session)); const char *mac = gnutls_mac_get_name (gnutls_mac_get (session)); const char *compression = gnutls_compression_get_name (gnutls_compression_get (session)); int resumedp = gnutls_session_is_resumed (session); /* This message can arguably belong to LOG_AUTH. */ syslog (LOG_INFO, "TLS handshake negotiated protocol `%s', " "key exchange `%s', certficate type `%s', cipher `%s', " "mac `%s', compression `%s', %s", protocol ? protocol : "N/A", keyexchange ? keyexchange : "N/A", certtype ? certtype : "N/A", cipher ? cipher : "N/A", mac ? mac : "N/A", compression ? compression : "N/A", resumedp ? "resumed session" : "session not resumed"); cred = gnutls_auth_get_type (session); switch (cred) { case GNUTLS_CRD_ANON: syslog (LOG_INFO | LOG_DAEMON, "TLS anonymous authentication with %d bit Diffie-Hellman", gnutls_dh_get_prime_bits (session)); break; case GNUTLS_CRD_CERTIFICATE: if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) syslog (LOG_INFO | LOG_DAEMON, "TLS certificate authentication with %d bits " "ephemeral Diffie-Hellman", gnutls_dh_get_prime_bits (session)); logcertinfo (session); break; case GNUTLS_CRD_SRP: case GNUTLS_CRD_PSK: case GNUTLS_CRD_IA: default: syslog (LOG_ERR | LOG_DAEMON, "Unknown TLS authentication (%d)", cred); break; } }
static void print_cert_vrfy (gnutls_session_t session) { int rc; unsigned int status; rc = gnutls_certificate_verify_peers2 (session, &status); if (rc < 0) { printf ("- Could not verify certificate (err: %s)\n", gnutls_strerror (rc)); return; } if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) { printf ("- Peer did not send any certificate.\n"); return; } if (gnutls_certificate_type_get (session) == GNUTLS_CRT_X509) { if (status & GNUTLS_CERT_REVOKED) printf ("- Peer's certificate chain revoked\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 (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"); } }
SSL_CIPHER * SSL_get_current_cipher (SSL * ssl) { if (!ssl) return NULL; ssl->ciphersuite.version = gnutls_protocol_get_version (ssl->gnutls_state); ssl->ciphersuite.cipher = gnutls_cipher_get (ssl->gnutls_state); ssl->ciphersuite.kx = gnutls_kx_get (ssl->gnutls_state); ssl->ciphersuite.mac = gnutls_mac_get (ssl->gnutls_state); ssl->ciphersuite.compression = gnutls_compression_get (ssl->gnutls_state); ssl->ciphersuite.cert = gnutls_certificate_type_get (ssl->gnutls_state); return &(ssl->ciphersuite); }
static GList * ssl_gnutls_get_peer_certificates(PurpleSslConnection * gsc) { PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc); PurpleCertificate *prvcrt = NULL; /* List of Certificate instances to return */ GList * peer_certs = NULL; /* List of raw certificates as given by GnuTLS */ const gnutls_datum_t *cert_list; unsigned int cert_list_size = 0; unsigned int i; /* This should never, ever happen. */ g_return_val_if_fail( gnutls_certificate_type_get (gnutls_data->session) == GNUTLS_CRT_X509, NULL); /* Get the certificate list from GnuTLS */ /* TODO: I am _pretty sure_ this doesn't block or do other exciting things */ cert_list = gnutls_certificate_get_peers(gnutls_data->session, &cert_list_size); /* Convert each certificate to a Certificate and append it to the list */ for (i = 0; i < cert_list_size; i++) { PurpleCertificate * newcrt = x509_import_from_datum(cert_list[i], GNUTLS_X509_FMT_DER); /* Append is somewhat inefficient on linked lists, but is easy to read. If someone complains, I'll change it. TODO: Is anyone complaining? (Maybe elb?) */ /* only append if previous cert was actually signed by this one. * Thanks Microsoft. */ if ((prvcrt == NULL) || x509_certificate_signed_by(prvcrt, newcrt)) { peer_certs = g_list_append(peer_certs, newcrt); prvcrt = newcrt; } else { x509_destroy_certificate(newcrt); purple_debug_error("gnutls", "Dropping further peer certificates " "because the chain is broken!\n"); break; } } /* cert_list doesn't need free()-ing */ return peer_certs; }
int TLSSocket::verify(VerifyResult& result) { const char* hostname = (const char*) gnutls_session_get_ptr (session); unsigned int status; int ret = gnutls_certificate_verify_peers2 (session, &status); if (ret < 0) { return -1; } result.distrusted = (status & GNUTLS_CERT_INVALID); result.unknownIssuer = (status & GNUTLS_CERT_SIGNER_NOT_FOUND); result.revoked = (status & GNUTLS_CERT_REVOKED); result.expired = (status & GNUTLS_CERT_EXPIRED); result.inactive = (status & GNUTLS_CERT_NOT_ACTIVATED); result.invalidCert = false; if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { result.invalidCert = true; return -1; } gnutls_x509_crt_t cert; if (gnutls_x509_crt_init (&cert) < 0) { return -1; } const gnutls_datum_t *cert_list; unsigned int cert_list_size; cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list == NULL) { result.invalidCert = true; gnutls_x509_crt_deinit (cert); return -1; } if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0){ result.invalidCert = true; gnutls_x509_crt_deinit (cert); return -1; } result.hostnameMismatch = !gnutls_x509_crt_check_hostname (cert, hostname); gnutls_x509_crt_deinit (cert); return 0; }
/** * Internally used gnutls callback function that gets called during handshake. */ static int internal_cert_callback(gnutls_session_t session, const gnutls_datum_t * req_ca_rdn, int nreqs, const gnutls_pk_algorithm_t * sign_algos, int sign_algos_length, gnutls_retr_st * st) { int res = -1; gnutls_certificate_type_t type = gnutls_certificate_type_get(session); if (type == GNUTLS_CRT_X509) { ssl_data_t ssl_data = (ssl_data_t)gnutls_session_get_ptr(session); if (ssl_data && ssl_data->host_privkey && ssl_data->host_cert) { debug_info("Passing certificate"); st->type = type; st->ncerts = 1; st->cert.x509 = &ssl_data->host_cert; st->key.x509 = ssl_data->host_privkey; st->deinit_all = 0; res = 0; } } return res; }
static int verify_cert_authorized(gnutls_session_t session) { unsigned status; gnutls_certificate_type_t type; gnutls_datum_t out; int r; r = gnutls_certificate_verify_peers2(session, &status); if (r < 0) return log_error_errno(r, "gnutls_certificate_verify_peers2 failed: %m"); type = gnutls_certificate_type_get(session); r = gnutls_certificate_verification_status_print(status, type, &out, 0); if (r < 0) return log_error_errno(r, "gnutls_certificate_verification_status_print failed: %m"); log_info("Certificate status: %s", out.data); return status == 0 ? 0 : -EPERM; }
void print_cert_info_compact(gnutls_session_t session) { if (gnutls_certificate_client_get_request_status(session) != 0) printf("- Server has requested a certificate.\n"); switch (gnutls_certificate_type_get(session)) { case GNUTLS_CRT_X509: print_x509_info_compact(session); break; #ifdef ENABLE_OPENPGP case GNUTLS_CRT_OPENPGP: print_openpgp_info_compact(session); break; #endif default: printf("Unknown type\n"); break; } }
/* Callback invoked when the SSL server requests a client certificate. */ static int provide_client_cert(gnutls_session session, const gnutls_datum *req_ca_rdn, int nreqs, const gnutls_pk_algorithm *sign_algos, int sign_algos_length, gnutls_retr_st *st) { ne_session *sess = gnutls_session_get_ptr(session); if (!sess) { return -1; } if (!sess->client_cert && sess->ssl_provide_fn) { /* The dname array cannot be converted without better dname * support from GNUTLS. */ sess->ssl_provide_fn(sess->ssl_provide_ud, sess, NULL, 0); } NE_DEBUG(NE_DBG_SSL, "In client cert provider callback.\n"); if (sess->client_cert) { gnutls_certificate_type type = gnutls_certificate_type_get(session); if (type == GNUTLS_CRT_X509) { NE_DEBUG(NE_DBG_SSL, "Supplying client certificate.\n"); st->type = type; st->ncerts = 1; st->cert.x509 = &sess->client_cert->cert.subject; st->key.x509 = sess->client_cert->pkey; /* tell GNU TLS not to deallocate the certs. */ st->deinit_all = 0; } else { return -1; } } else { NE_DEBUG(NE_DBG_SSL, "No client certificate supplied.\n"); } return 0; }
test_code_t test_openpgp1 (gnutls_session_t session) { int ret; sprintf (prio_str, INIT_STR ALL_CIPHERS ":" ALL_COMP ":+CTYPE-OPENPGP:%s:" ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); _gnutls_priority_set_direct (session, prio_str); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); ret = do_handshake (session); if (ret == TEST_FAILED) return ret; if (gnutls_certificate_type_get (session) == GNUTLS_CRT_OPENPGP) return TEST_SUCCEED; return TEST_FAILED; }
test_code_t test_openpgp1 (gnutls_session session) { int ret; ADD_ALL_CIPHERS (session); ADD_ALL_COMP (session); ADD_CERTTYPE (session, GNUTLS_CRT_OPENPGP); ADD_ALL_PROTOCOLS (session); ADD_ALL_MACS (session); ADD_ALL_KX (session); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); ret = do_handshake (session); if (ret == TEST_FAILED) return ret; if (gnutls_certificate_type_get (session) == GNUTLS_CRT_OPENPGP) return TEST_SUCCEED; return TEST_FAILED; }
int rb_get_ssl_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN]) { gnutls_x509_crt_t cert; unsigned int cert_list_size; const gnutls_datum_t *cert_list; uint8_t digest[RB_SSL_CERTFP_LEN * 2]; size_t digest_size; if (gnutls_certificate_type_get(SSL_P(F)) != GNUTLS_CRT_X509) return 0; if (gnutls_x509_crt_init(&cert) < 0) return 0; cert_list_size = 0; cert_list = gnutls_certificate_get_peers(SSL_P(F), &cert_list_size); if (cert_list == NULL) { gnutls_x509_crt_deinit(cert); return 0; } if (gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) { gnutls_x509_crt_deinit(cert); return 0; } if (gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, digest, &digest_size) < 0) { gnutls_x509_crt_deinit(cert); return 0; } memcpy(certfp, digest, RB_SSL_CERTFP_LEN); gnutls_x509_crt_deinit(cert); return 1; }
/* This function will verify the peer's certificate, and check * if the hostname matches, as well as the activation, expiration dates. */ extern int verify_certificate_callback (gnutls_session_t session) { unsigned int status; int ret, type; const char *hostname; gnutls_datum_t out; /* read hostname */ hostname = gnutls_session_get_ptr (session); /* This verification function uses the trusted CAs in the credentials * structure. So you must have installed one or more CA certificates. */ ret = gnutls_certificate_verify_peers3 (session, hostname, &status); if (ret < 0) { printf ("Error\n"); return GNUTLS_E_CERTIFICATE_ERROR; } type = gnutls_certificate_type_get (session); 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); if (status != 0) /* Certificate is not trusted */ return GNUTLS_E_CERTIFICATE_ERROR; /* notify gnutls to continue handshake normally */ return 0; }
static int get_x509_dname (int soc, char *x509_dname, size_t x509_dname_size) { gnutls_session_t session; gnutls_x509_crt_t cert; unsigned int cert_list_size = 0; const gnutls_datum_t *cert_list; int ret; session = ovas_get_tlssession_from_connection (soc); if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { log_write ("Certificate is not an X.509 certificate."); return -1; } cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list_size == 0) return -1; gnutls_x509_crt_init (&cert); if ((ret = gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER)) < 0) { log_write ("certificate decoding error: %s\n", gnutls_strerror (ret)); gnutls_x509_crt_deinit (cert); return -1; } if ((ret = gnutls_x509_crt_get_dn (cert, x509_dname, &x509_dname_size)) < 0) { log_write ("couldn't get subject from certificate: %s\n", gnutls_strerror (ret)); gnutls_x509_crt_deinit (cert); return -1; } gnutls_x509_crt_deinit (cert); return 0; }
static int _verify_certificate_callback (gnutls_session_t session) { unsigned int status; const gnutls_datum_t *cert_list; unsigned int cert_list_size; int ret; gnutls_x509_crt_t cert; ret = gnutls_certificate_verify_peers2 (session, &status); if (ret < 0) return GNUTLS_E_CERTIFICATE_ERROR; if (status & GNUTLS_CERT_INVALID || status & GNUTLS_CERT_SIGNER_NOT_FOUND || status & GNUTLS_CERT_REVOKED || status & GNUTLS_CERT_EXPIRED || status & GNUTLS_CERT_NOT_ACTIVATED) return GNUTLS_E_CERTIFICATE_ERROR; if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) return GNUTLS_E_CERTIFICATE_ERROR; if (gnutls_x509_crt_init (&cert) < 0) return GNUTLS_E_CERTIFICATE_ERROR; cert_list = gnutls_certificate_get_peers (session, &cert_list_size); if (cert_list == NULL) return GNUTLS_E_CERTIFICATE_ERROR; if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) return GNUTLS_E_CERTIFICATE_ERROR; gnutls_x509_crt_deinit (cert); return 0; }
/* returns false (0) if not verified, or true (1) otherwise */ int 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); if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) { printf("- Peer did not send any certificate.\n"); return 0; } if (rc < 0) { printf("- Could not verify certificate (err: %s)\n", gnutls_strerror(rc)); return 0; } type = gnutls_certificate_type_get(session); rc = gnutls_certificate_verification_status_print(status, type, &out, 0); if (rc < 0) { printf("- Could not print verification flags (err: %s)\n", gnutls_strerror(rc)); return 0; } printf("- Status: %s\n", out.data); gnutls_free(out.data); if (status) return 0; return 1; }