/* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2 */ static int _gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session, gnutls_pcert_st* cert, gnutls_privkey_t pkey, gnutls_datum_t * signature) { gnutls_datum_t dconcat; int ret; opaque concat[MAX_SIG_SIZE]; digest_hd_st td; gnutls_sign_algorithm_t sign_algo; gnutls_digest_algorithm_t hash_algo; digest_hd_st *handshake_td; sign_algo = _gnutls_session_get_sign_algo (session, cert); if (sign_algo == GNUTLS_SIGN_UNKNOWN) { gnutls_assert (); return GNUTLS_E_UNKNOWN_PK_ALGORITHM; } hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo); _gnutls_debug_log ("sign handshake cert vrfy: picked %s with %s\n", gnutls_sign_algorithm_get_name (sign_algo), gnutls_mac_get_name (hash_algo)); if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha1.algorithm) handshake_td = &session->internals.handshake_mac_handle.tls12.sha1; else if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha256.algorithm) handshake_td = &session->internals.handshake_mac_handle.tls12.sha256; else return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); /* too bad we only support SHA1 and SHA256 */ ret = _gnutls_hash_copy (&td, handshake_td); if (ret < 0) { gnutls_assert (); return ret; } _gnutls_hash_deinit (&td, concat); dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len (hash_algo); ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature); if (ret < 0) { gnutls_assert (); return ret; } return sign_algo; }
/* the same as _gnutls_handshake_sign_crt_vrfy except that it is made for TLS 1.2 */ static int _gnutls_handshake_sign_crt_vrfy12(gnutls_session_t session, gnutls_pcert_st * cert, gnutls_privkey_t pkey, gnutls_datum_t * signature) { gnutls_datum_t dconcat; int ret; uint8_t concat[MAX_SIG_SIZE]; gnutls_sign_algorithm_t sign_algo; const mac_entry_st *me; sign_algo = _gnutls_session_get_sign_algo(session, cert); if (sign_algo == GNUTLS_SIGN_UNKNOWN) { gnutls_assert(); return GNUTLS_E_UNKNOWN_PK_ALGORITHM; } gnutls_sign_algorithm_set_client(session, sign_algo); me = hash_to_entry(gnutls_sign_get_hash_algorithm(sign_algo)); _gnutls_debug_log("sign handshake cert vrfy: picked %s with %s\n", gnutls_sign_algorithm_get_name(sign_algo), _gnutls_mac_get_name(me)); ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)me->id, session->internals.handshake_hash_buffer. data, session->internals.handshake_hash_buffer. length, concat); if (ret < 0) return gnutls_assert_val(ret); dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len(me); ret = sign_tls_hash(session, me, cert, pkey, &dconcat, signature); if (ret < 0) { gnutls_assert(); return ret; } return sign_algo; }
void __certificate_properties_fill_cert_signature(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate) { int result; GtkTreeIter j; GtkTreeIter k; const gchar *name = NULL; result = gnutls_x509_crt_get_signature_algorithm(*certificate); name = gnutls_sign_algorithm_get_name(result); gtk_tree_store_append(store, &j, parent); gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Signature"), -1); gtk_tree_store_append(store, &k, &j); gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Algorithm"), CERTIFICATE_PROPERTIES_COL_VALUE, name, -1); gtk_tree_store_append(store, &k, &j); gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1); }
void doit (void) { if (debug) { printf ("GnuTLS header version %s.\n", GNUTLS_VERSION); printf ("GnuTLS library version %s.\n", gnutls_check_version (NULL)); } if (!gnutls_check_version (GNUTLS_VERSION)) fail ("gnutls_check_version ERROR\n"); { const gnutls_pk_algorithm_t *algs; size_t i; int pk; algs = gnutls_pk_list (); if (!algs) fail ("gnutls_pk_list return NULL\n"); for (i = 0; algs[i]; i++) { if (debug) printf ("pk_list[%d] = %d = %s = %d\n", (int) i, algs[i], gnutls_pk_algorithm_get_name (algs[i]), gnutls_pk_get_id (gnutls_pk_algorithm_get_name (algs[i]))); if (gnutls_pk_get_id (gnutls_pk_algorithm_get_name (algs[i])) != algs[i]) fail ("gnutls_pk id's doesn't match\n"); } pk = gnutls_pk_get_id ("foo"); if (pk != GNUTLS_PK_UNKNOWN) fail ("gnutls_pk unknown test failed (%d)\n", pk); if (debug) success ("gnutls_pk_list ok\n"); } { const gnutls_sign_algorithm_t *algs; size_t i; int pk; algs = gnutls_sign_list (); if (!algs) fail ("gnutls_sign_list return NULL\n"); for (i = 0; algs[i]; i++) { if (debug) printf ("sign_list[%d] = %d = %s = %d\n", (int) i, algs[i], gnutls_sign_algorithm_get_name (algs[i]), gnutls_sign_get_id (gnutls_sign_algorithm_get_name (algs[i]))); if (gnutls_sign_get_id (gnutls_sign_algorithm_get_name (algs[i])) != algs[i]) fail ("gnutls_sign id's doesn't match\n"); } pk = gnutls_sign_get_id ("foo"); if (pk != GNUTLS_PK_UNKNOWN) fail ("gnutls_sign unknown test failed (%d)\n", pk); if (debug) success ("gnutls_sign_list ok\n"); } }
void print_list (const char *priorities, int verbose) { size_t i; int ret; unsigned int idx; const char *name; const char *err; unsigned char id[2]; gnutls_kx_algorithm_t kx; gnutls_cipher_algorithm_t cipher; gnutls_mac_algorithm_t mac; gnutls_protocol_t version; gnutls_priority_t pcache; const unsigned int *list; if (priorities != NULL) { printf ("Cipher suites for %s\n", priorities); ret = gnutls_priority_init (&pcache, priorities, &err); if (ret < 0) { fprintf (stderr, "Syntax error at: %s\n", err); exit (1); } for (i = 0;; i++) { ret = gnutls_priority_get_cipher_suite_index (pcache, i, &idx); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) break; if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) continue; name = gnutls_cipher_suite_info (idx, id, NULL, NULL, NULL, &version); if (name != NULL) printf ("%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); } printf("\n"); { ret = gnutls_priority_certificate_type_list (pcache, &list); printf ("Certificate types: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("CTYPE-%s", gnutls_certificate_type_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } { ret = gnutls_priority_protocol_list (pcache, &list); printf ("Protocols: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("VERS-%s", gnutls_protocol_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } { ret = gnutls_priority_compression_list (pcache, &list); printf ("Compression: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("COMP-%s", gnutls_compression_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } { ret = gnutls_priority_ecc_curve_list (pcache, &list); printf ("Elliptic curves: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("CURVE-%s", gnutls_ecc_curve_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } { ret = gnutls_priority_sign_list (pcache, &list); printf ("PK-signatures: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("SIGN-%s", gnutls_sign_algorithm_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } return; } printf ("Cipher suites:\n"); for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, &version)); i++) { printf ("%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); if (verbose) printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n", gnutls_kx_get_name (kx), gnutls_cipher_get_name (cipher), gnutls_mac_get_name (mac)); } printf("\n"); { const gnutls_certificate_type_t *p = gnutls_certificate_type_list (); printf ("Certificate types: "); for (; *p; p++) { printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_protocol_t *p = gnutls_protocol_list (); printf ("Protocols: "); for (; *p; p++) { printf ("VERS-%s", gnutls_protocol_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); printf ("Ciphers: "); for (; *p; p++) { printf ("%s", gnutls_cipher_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_mac_algorithm_t *p = gnutls_mac_list (); printf ("MACs: "); for (; *p; p++) { printf ("%s", gnutls_mac_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_kx_algorithm_t *p = gnutls_kx_list (); printf ("Key exchange algorithms: "); for (; *p; p++) { printf ("%s", gnutls_kx_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_compression_method_t *p = gnutls_compression_list (); printf ("Compression: "); for (; *p; p++) { printf ("COMP-%s", gnutls_compression_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list (); printf ("Elliptic curves: "); for (; *p; p++) { printf ("CURVE-%s", gnutls_ecc_curve_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_pk_algorithm_t *p = gnutls_pk_list (); printf ("Public Key Systems: "); for (; *p; p++) { printf ("%s", gnutls_pk_algorithm_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_sign_algorithm_t *p = gnutls_sign_list (); printf ("PK-signatures: "); for (; *p; p++) { printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } }
static void print_resp(gnutls_buffer_st * str, gnutls_ocsp_resp_t resp, gnutls_ocsp_print_formats_t format) { int ret; unsigned indx; ret = gnutls_ocsp_resp_get_status(resp); if (ret < 0) { addf(str, "error: ocsp_resp_get_status: %s\n", gnutls_strerror(ret)); return; } adds(str, "\tResponse Status: "); switch (ret) { case GNUTLS_OCSP_RESP_SUCCESSFUL: adds(str, "Successful\n"); break; case GNUTLS_OCSP_RESP_MALFORMEDREQUEST: adds(str, "malformedRequest\n"); return; case GNUTLS_OCSP_RESP_INTERNALERROR: adds(str, "internalError\n"); return; case GNUTLS_OCSP_RESP_TRYLATER: adds(str, "tryLater\n"); return; case GNUTLS_OCSP_RESP_SIGREQUIRED: adds(str, "sigRequired\n"); return; case GNUTLS_OCSP_RESP_UNAUTHORIZED: adds(str, "unauthorized\n"); return; default: adds(str, "unknown\n"); return; } { gnutls_datum_t oid; ret = gnutls_ocsp_resp_get_response(resp, &oid, NULL); if (ret < 0) { addf(str, "error: get_response: %s\n", gnutls_strerror(ret)); return; } adds(str, "\tResponse Type: "); #define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1" if (oid.size == sizeof(OCSP_BASIC) && memcmp(oid.data, OCSP_BASIC, oid.size) == 0) { adds(str, "Basic OCSP Response\n"); gnutls_free(oid.data); } else { addf(str, "Unknown response type (%.*s)\n", oid.size, oid.data); gnutls_free(oid.data); return; } } /* Version. */ { int version = gnutls_ocsp_resp_get_version(resp); if (version < 0) addf(str, "error: get_version: %s\n", gnutls_strerror(version)); else addf(str, _("\tVersion: %d\n"), version); } /* responderID */ { gnutls_datum_t dn; ret = gnutls_ocsp_resp_get_responder(resp, &dn); if (ret < 0 || dn.data == NULL) { if (dn.data == 0) { ret = gnutls_ocsp_resp_get_responder_raw_id(resp, GNUTLS_OCSP_RESP_ID_KEY, &dn); if (ret >= 0) { addf(str, _("\tResponder Key ID: ")); _gnutls_buffer_hexprint(str, dn.data, dn.size); adds(str, "\n"); } gnutls_free(dn.data); } else { addf(str, "error: get_dn: %s\n", gnutls_strerror(ret)); } } else { if (dn.data != NULL) { addf(str, _("\tResponder ID: %.*s\n"), dn.size, dn.data); gnutls_free(dn.data); } } } { char s[42]; size_t max = sizeof(s); struct tm t; time_t tim = gnutls_ocsp_resp_get_produced(resp); if (tim == (time_t) - 1) addf(str, "error: ocsp_resp_get_produced\n"); else if (gmtime_r(&tim, &t) == NULL) addf(str, "error: gmtime_r (%ld)\n", (unsigned long) tim); else if (strftime(s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0) addf(str, "error: strftime (%ld)\n", (unsigned long) tim); else addf(str, _("\tProduced At: %s\n"), s); } addf(str, "\tResponses:\n"); for (indx = 0;; indx++) { gnutls_digest_algorithm_t digest; gnutls_datum_t in, ik, sn; unsigned int cert_status; time_t this_update; time_t next_update; time_t revocation_time; unsigned int revocation_reason; ret = gnutls_ocsp_resp_get_single(resp, indx, &digest, &in, &ik, &sn, &cert_status, &this_update, &next_update, &revocation_time, &revocation_reason); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) break; addf(str, "\t\tCertificate ID:\n"); if (ret != GNUTLS_E_SUCCESS) { addf(str, "error: get_singleresponse: %s\n", gnutls_strerror(ret)); continue; } addf(str, "\t\t\tHash Algorithm: %s\n", _gnutls_digest_get_name(hash_to_entry(digest))); adds(str, "\t\t\tIssuer Name Hash: "); _gnutls_buffer_hexprint(str, in.data, in.size); adds(str, "\n"); adds(str, "\t\t\tIssuer Key Hash: "); _gnutls_buffer_hexprint(str, ik.data, ik.size); adds(str, "\n"); adds(str, "\t\t\tSerial Number: "); _gnutls_buffer_hexprint(str, sn.data, sn.size); adds(str, "\n"); gnutls_free(in.data); gnutls_free(ik.data); gnutls_free(sn.data); { const char *p = NULL; switch (cert_status) { case GNUTLS_OCSP_CERT_GOOD: p = "good"; break; case GNUTLS_OCSP_CERT_REVOKED: p = "revoked"; break; case GNUTLS_OCSP_CERT_UNKNOWN: p = "unknown"; break; default: addf(str, "\t\tCertificate Status: unexpected value %d\n", cert_status); break; } if (p) addf(str, "\t\tCertificate Status: %s\n", p); } /* XXX revocation reason */ if (cert_status == GNUTLS_OCSP_CERT_REVOKED) { char s[42]; size_t max = sizeof(s); struct tm t; if (revocation_time == (time_t) - 1) addf(str, "error: revocation_time\n"); else if (gmtime_r(&revocation_time, &t) == NULL) addf(str, "error: gmtime_r (%ld)\n", (unsigned long) revocation_time); else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0) addf(str, "error: strftime (%ld)\n", (unsigned long) revocation_time); else addf(str, _("\t\tRevocation time: %s\n"), s); } { char s[42]; size_t max = sizeof(s); struct tm t; if (this_update == (time_t) - 1) addf(str, "error: this_update\n"); else if (gmtime_r(&this_update, &t) == NULL) addf(str, "error: gmtime_r (%ld)\n", (unsigned long) this_update); else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0) addf(str, "error: strftime (%ld)\n", (unsigned long) this_update); else addf(str, _("\t\tThis Update: %s\n"), s); } { char s[42]; size_t max = sizeof(s); struct tm t; if (next_update != (time_t) - 1) { if (gmtime_r(&next_update, &t) == NULL) addf(str, "error: gmtime_r (%ld)\n", (unsigned long) next_update); else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0) addf(str, "error: strftime (%ld)\n", (unsigned long) next_update); else addf(str, _("\t\tNext Update: %s\n"), s); } } /* XXX singleRequestExtensions */ } adds(str, "\tExtensions:\n"); for (indx = 0;; indx++) { gnutls_datum_t oid; unsigned int critical; gnutls_datum_t data; ret = gnutls_ocsp_resp_get_extension(resp, indx, &oid, &critical, &data); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) break; else if (ret != GNUTLS_E_SUCCESS) { addf(str, "error: get_extension: %s\n", gnutls_strerror(ret)); continue; } if (oid.size == sizeof(GNUTLS_OCSP_NONCE) && memcmp(oid.data, GNUTLS_OCSP_NONCE, oid.size) == 0) { gnutls_datum_t nonce; unsigned int ncrit; ret = gnutls_ocsp_resp_get_nonce(resp, &ncrit, &nonce); if (ret != GNUTLS_E_SUCCESS) { addf(str, "error: get_nonce: %s\n", gnutls_strerror(ret)); } else { addf(str, "\t\tNonce%s: ", ncrit ? " (critical)" : ""); _gnutls_buffer_hexprint(str, nonce.data, nonce.size); adds(str, "\n"); gnutls_free(nonce.data); } } else { addf(str, "\t\tUnknown extension %s (%s):\n", oid.data, critical ? "critical" : "not critical"); adds(str, _("\t\t\tASCII: ")); _gnutls_buffer_asciiprint(str, (char *) data.data, data.size); addf(str, "\n"); adds(str, _("\t\t\tHexdump: ")); _gnutls_buffer_hexprint(str, (char *) data.data, data.size); adds(str, "\n"); } gnutls_free(oid.data); gnutls_free(data.data); } /* Signature. */ if (format == GNUTLS_OCSP_PRINT_FULL) { gnutls_datum_t sig; ret = gnutls_ocsp_resp_get_signature_algorithm(resp); if (ret < 0) addf(str, "error: get_signature_algorithm: %s\n", gnutls_strerror(ret)); else { const char *name = gnutls_sign_algorithm_get_name(ret); if (name == NULL) name = _("unknown"); addf(str, _("\tSignature Algorithm: %s\n"), name); } if (ret != GNUTLS_SIGN_UNKNOWN && gnutls_sign_is_secure(ret) == 0) { adds(str, _("warning: signed using a broken signature " "algorithm that can be forged.\n")); } ret = gnutls_ocsp_resp_get_signature(resp, &sig); if (ret < 0) addf(str, "error: get_signature: %s\n", gnutls_strerror(ret)); else { adds(str, _("\tSignature:\n")); _gnutls_buffer_hexdump(str, sig.data, sig.size, "\t\t"); gnutls_free(sig.data); } } /* certs */ if (format == GNUTLS_OCSP_PRINT_FULL) { gnutls_x509_crt_t *certs; size_t ncerts, i; gnutls_datum_t out; ret = gnutls_ocsp_resp_get_certs(resp, &certs, &ncerts); if (ret < 0) addf(str, "error: get_certs: %s\n", gnutls_strerror(ret)); else { if (ncerts > 0) addf(str, "\tAdditional certificates:\n"); for (i = 0; i < ncerts; i++) { size_t s = 0; ret = gnutls_x509_crt_print(certs[i], GNUTLS_CRT_PRINT_FULL, &out); if (ret < 0) addf(str, "error: crt_print: %s\n", gnutls_strerror(ret)); else { addf(str, "%.*s", out.size, out.data); gnutls_free(out.data); } ret = gnutls_x509_crt_export(certs[i], GNUTLS_X509_FMT_PEM, NULL, &s); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) addf(str, "error: crt_export: %s\n", gnutls_strerror(ret)); else { out.data = gnutls_malloc(s); if (out.data == NULL) addf(str, "error: malloc: %s\n", gnutls_strerror (GNUTLS_E_MEMORY_ERROR)); else { ret = gnutls_x509_crt_export (certs[i], GNUTLS_X509_FMT_PEM, out.data, &s); if (ret < 0) addf(str, "error: crt_export: %s\n", gnutls_strerror (ret)); else { out.size = s; addf(str, "%.*s", out.size, out.data); } gnutls_free(out.data); } } gnutls_x509_crt_deinit(certs[i]); } gnutls_free(certs); } } }
bool CTlsSocket::ExtractCert(const void* in, CCertificate& out) { const gnutls_datum_t* datum = reinterpret_cast<const gnutls_datum_t*>(in); gnutls_x509_crt_t cert; if (gnutls_x509_crt_init(&cert)) { m_pOwner->LogMessage(::Error, _("Could not initialize structure for peer certificates, gnutls_x509_crt_init failed")); return false; } if (gnutls_x509_crt_import(cert, datum, GNUTLS_X509_FMT_DER)) { m_pOwner->LogMessage(::Error, _("Could not import peer certificates, gnutls_x509_crt_import failed")); gnutls_x509_crt_deinit(cert); return false; } wxDateTime expirationTime = gnutls_x509_crt_get_expiration_time(cert); wxDateTime activationTime = gnutls_x509_crt_get_activation_time(cert); // Get the serial number of the certificate unsigned char buffer[40]; size_t size = sizeof(buffer); int res = gnutls_x509_crt_get_serial(cert, buffer, &size); if( res != 0 ) { size = 0; } wxString serial = bin2hex(buffer, size); unsigned int pkBits; int pkAlgo = gnutls_x509_crt_get_pk_algorithm(cert, &pkBits); wxString pkAlgoName; if (pkAlgo >= 0) { const char* pAlgo = gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)pkAlgo); if (pAlgo) pkAlgoName = wxString(pAlgo, wxConvUTF8); } int signAlgo = gnutls_x509_crt_get_signature_algorithm(cert); wxString signAlgoName; if (signAlgo >= 0) { const char* pAlgo = gnutls_sign_algorithm_get_name((gnutls_sign_algorithm_t)signAlgo); if (pAlgo) signAlgoName = wxString(pAlgo, wxConvUTF8); } wxString subject, issuer; size = 0; res = gnutls_x509_crt_get_dn(cert, 0, &size); if (size) { char* dn = new char[size + 1]; dn[size] = 0; if (!(res = gnutls_x509_crt_get_dn(cert, dn, &size))) { dn[size] = 0; subject = wxString(dn, wxConvUTF8); } else LogError(res, _T("gnutls_x509_crt_get_dn")); delete [] dn; } else LogError(res, _T("gnutls_x509_crt_get_dn")); if (subject == _T("")) { m_pOwner->LogMessage(::Error, _("Could not get distinguished name of certificate subject, gnutls_x509_get_dn failed")); gnutls_x509_crt_deinit(cert); return false; } size = 0; res = gnutls_x509_crt_get_issuer_dn(cert, 0, &size); if (size) { char* dn = new char[++size + 1]; dn[size] = 0; if (!(res = gnutls_x509_crt_get_issuer_dn(cert, dn, &size))) { dn[size] = 0; issuer = wxString(dn, wxConvUTF8); } else LogError(res, _T("gnutls_x509_crt_get_issuer_dn")); delete [] dn; } else LogError(res, _T("gnutls_x509_crt_get_issuer_dn")); if (issuer == _T("")) { m_pOwner->LogMessage(::Error, _("Could not get distinguished name of certificate issuer, gnutls_x509_get_issuer_dn failed")); gnutls_x509_crt_deinit(cert); return false; } wxString fingerprint_md5; wxString fingerprint_sha1; unsigned char digest[100]; size = sizeof(digest) - 1; if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_MD5, digest, &size)) { digest[size] = 0; fingerprint_md5 = bin2hex(digest, size); } size = sizeof(digest) - 1; if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, digest, &size)) { digest[size] = 0; fingerprint_sha1 = bin2hex(digest, size); } gnutls_x509_crt_deinit(cert); out = CCertificate( datum->data, datum->size, activationTime, expirationTime, serial, pkAlgoName, pkBits, signAlgoName, fingerprint_md5, fingerprint_sha1, subject, issuer); return true; }
void print_list (int verbose) { { size_t i; const char *name; char id[2]; gnutls_kx_algorithm_t kx; gnutls_cipher_algorithm_t cipher; gnutls_mac_algorithm_t mac; gnutls_protocol_t version; printf ("Cipher suites:\n"); for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, &version)); i++) { printf ("%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); if (verbose) printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n", gnutls_kx_get_name (kx), gnutls_cipher_get_name (cipher), gnutls_mac_get_name (mac)); } } { const gnutls_certificate_type_t *p = gnutls_certificate_type_list (); printf ("Certificate types: "); for (; *p; p++) { printf ("%s", gnutls_certificate_type_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_protocol_t *p = gnutls_protocol_list (); printf ("Protocols: "); for (; *p; p++) { printf ("%s", gnutls_protocol_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); printf ("Ciphers: "); for (; *p; p++) { printf ("%s", gnutls_cipher_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_mac_algorithm_t *p = gnutls_mac_list (); printf ("MACs: "); for (; *p; p++) { printf ("%s", gnutls_mac_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_kx_algorithm_t *p = gnutls_kx_list (); printf ("Key exchange algorithms: "); for (; *p; p++) { printf ("%s", gnutls_kx_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_compression_method_t *p = gnutls_compression_list (); printf ("Compression: "); for (; *p; p++) { printf ("%s", gnutls_compression_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_pk_algorithm_t *p = gnutls_pk_list (); printf ("Public Key Systems: "); for (; *p; p++) { printf ("%s", gnutls_pk_algorithm_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_sign_algorithm_t *p = gnutls_sign_list (); printf ("PK-signatures: "); for (; *p; p++) { printf ("%s", gnutls_sign_algorithm_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } }
/* Generates a signature of all the random data and the parameters. * Used in DHE_* ciphersuites. */ int _gnutls_handshake_sign_data(gnutls_session_t session, gnutls_pcert_st * cert, gnutls_privkey_t pkey, gnutls_datum_t * params, gnutls_datum_t * signature, gnutls_sign_algorithm_t * sign_algo) { gnutls_datum_t dconcat; int ret; digest_hd_st td_sha; uint8_t concat[MAX_SIG_SIZE]; const version_entry_st *ver = get_version(session); const mac_entry_st *hash_algo; *sign_algo = _gnutls_session_get_sign_algo(session, cert); if (*sign_algo == GNUTLS_SIGN_UNKNOWN) { gnutls_assert(); return GNUTLS_E_UNKNOWN_PK_ALGORITHM; } gnutls_sign_algorithm_set_server(session, *sign_algo); hash_algo = hash_to_entry(gnutls_sign_get_hash_algorithm(*sign_algo)); if (hash_algo == NULL) return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM); _gnutls_handshake_log ("HSK[%p]: signing handshake data: using %s\n", session, gnutls_sign_algorithm_get_name(*sign_algo)); ret = _gnutls_hash_init(&td_sha, hash_algo); if (ret < 0) { gnutls_assert(); return ret; } _gnutls_hash(&td_sha, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_sha, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_sha, params->data, params->size); switch (gnutls_privkey_get_pk_algorithm(pkey, NULL)) { case GNUTLS_PK_RSA: if (!_gnutls_version_has_selectable_sighash(ver)) { digest_hd_st td_md5; ret = _gnutls_hash_init(&td_md5, hash_to_entry (GNUTLS_DIG_MD5)); if (ret < 0) { gnutls_assert(); return ret; } _gnutls_hash(&td_md5, session->security_parameters. client_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_md5, session->security_parameters. server_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_md5, params->data, params->size); _gnutls_hash_deinit(&td_md5, concat); _gnutls_hash_deinit(&td_sha, &concat[16]); dconcat.data = concat; dconcat.size = 36; } else { /* TLS 1.2 way */ _gnutls_hash_deinit(&td_sha, concat); dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len(hash_algo); } break; case GNUTLS_PK_DSA: case GNUTLS_PK_EC: _gnutls_hash_deinit(&td_sha, concat); if (!IS_SHA((gnutls_digest_algorithm_t)hash_algo->id)) { gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len(hash_algo); break; default: gnutls_assert(); _gnutls_hash_deinit(&td_sha, NULL); return GNUTLS_E_INTERNAL_ERROR; } ret = sign_tls_hash(session, hash_algo, cert, pkey, &dconcat, signature); if (ret < 0) { gnutls_assert(); } return ret; }
/* Verifies a TLS signature (like the one in the client certificate * verify message). */ int _gnutls_handshake_verify_crt_vrfy(gnutls_session_t session, gnutls_pcert_st * cert, gnutls_datum_t * signature, gnutls_sign_algorithm_t sign_algo) { int ret; uint8_t concat[MAX_SIG_SIZE]; digest_hd_st td_md5; digest_hd_st td_sha; gnutls_datum_t dconcat; const version_entry_st *ver = get_version(session); _gnutls_handshake_log("HSK[%p]: verify cert vrfy: using %s\n", session, gnutls_sign_algorithm_get_name(sign_algo)); if (unlikely(ver == NULL)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); if (_gnutls_version_has_selectable_sighash(ver)) return _gnutls_handshake_verify_crt_vrfy12(session, cert, signature, sign_algo); ret = _gnutls_hash_init(&td_md5, hash_to_entry(GNUTLS_DIG_MD5)); if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_hash_init(&td_sha, hash_to_entry(GNUTLS_DIG_SHA1)); if (ret < 0) { gnutls_assert(); _gnutls_hash_deinit(&td_md5, NULL); return GNUTLS_E_HASH_FAILED; } _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len); _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len); if (ver->id == GNUTLS_SSL3) { ret = _gnutls_generate_master(session, 1); if (ret < 0) { _gnutls_hash_deinit(&td_md5, NULL); _gnutls_hash_deinit(&td_sha, NULL); return gnutls_assert_val(ret); } ret = _gnutls_mac_deinit_ssl3_handshake(&td_md5, concat, session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) { _gnutls_hash_deinit(&td_sha, NULL); return gnutls_assert_val(ret); } ret = _gnutls_mac_deinit_ssl3_handshake(&td_sha, &concat[16], session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) { return gnutls_assert_val(ret); } } else { _gnutls_hash_deinit(&td_md5, concat); _gnutls_hash_deinit(&td_sha, &concat[16]); } dconcat.data = concat; dconcat.size = 20 + 16; /* md5+ sha */ ret = verify_tls_hash(session, ver, cert, &dconcat, signature, 16, GNUTLS_SIGN_UNKNOWN, gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL)); if (ret < 0) { gnutls_assert(); return ret; } return ret; }
/* Generates a signature of all the random data and the parameters. * Used in DHE_* ciphersuites. */ int _gnutls_handshake_verify_data(gnutls_session_t session, gnutls_pcert_st * cert, const gnutls_datum_t * params, gnutls_datum_t * signature, gnutls_sign_algorithm_t sign_algo) { gnutls_datum_t dconcat; int ret; digest_hd_st td_md5; digest_hd_st td_sha; uint8_t concat[MAX_SIG_SIZE]; const version_entry_st *ver = get_version(session); gnutls_digest_algorithm_t hash_algo; const mac_entry_st *me; if (_gnutls_version_has_selectable_sighash(ver)) { _gnutls_handshake_log ("HSK[%p]: verify handshake data: using %s\n", session, gnutls_sign_algorithm_get_name(sign_algo)); ret = _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver, sign_algo); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_session_sign_algo_enabled(session, sign_algo); if (ret < 0) return gnutls_assert_val(ret); hash_algo = gnutls_sign_get_hash_algorithm(sign_algo); me = hash_to_entry(hash_algo); } else { me = hash_to_entry(GNUTLS_DIG_MD5); ret = _gnutls_hash_init(&td_md5, me); if (ret < 0) { gnutls_assert(); return ret; } _gnutls_hash(&td_md5, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_md5, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_md5, params->data, params->size); me = hash_to_entry(GNUTLS_DIG_SHA1); } ret = _gnutls_hash_init(&td_sha, me); if (ret < 0) { gnutls_assert(); if (!_gnutls_version_has_selectable_sighash(ver)) _gnutls_hash_deinit(&td_md5, NULL); return ret; } _gnutls_hash(&td_sha, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_sha, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_sha, params->data, params->size); if (!_gnutls_version_has_selectable_sighash(ver)) { _gnutls_hash_deinit(&td_md5, concat); _gnutls_hash_deinit(&td_sha, &concat[16]); dconcat.data = concat; dconcat.size = 36; } else { _gnutls_hash_deinit(&td_sha, concat); dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len(me); } ret = verify_tls_hash(session, ver, cert, &dconcat, signature, dconcat.size - _gnutls_hash_get_algo_len(me), sign_algo, gnutls_sign_get_pk_algorithm(sign_algo)); if (ret < 0) { gnutls_assert(); return ret; } return ret; }
/* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2 */ static int _gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session, gnutls_cert * cert, gnutls_privkey * pkey, gnutls_datum_t * signature) { gnutls_datum_t dconcat; int ret; opaque concat[MAX_SIG_SIZE]; digest_hd_st td; gnutls_sign_algorithm_t sign_algo; gnutls_digest_algorithm_t hash_algo; digest_hd_st *handshake_td; handshake_td = &session->internals.handshake_mac_handle.tls12.sha1; hash_algo = handshake_td->algorithm; sign_algo = _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo); /* The idea here is to try signing with the one of the algorithms * that have been initiated at handshake (SHA1, SHA256). If they * are not requested by peer... tough luck */ ret = _gnutls_session_sign_algo_requested (session, sign_algo); if (sign_algo == GNUTLS_SIGN_UNKNOWN || ret < 0) { handshake_td = &session->internals.handshake_mac_handle.tls12.sha256; hash_algo = handshake_td->algorithm; sign_algo = _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo); if (sign_algo == GNUTLS_SIGN_UNKNOWN) { gnutls_assert (); return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM; } ret = _gnutls_session_sign_algo_requested (session, sign_algo); if (ret < 0) { gnutls_assert (); _gnutls_x509_log ("Server did not allow either '%s' or '%s' for signing\n", gnutls_mac_get_name (hash_algo), gnutls_mac_get_name (session->internals.handshake_mac_handle. tls12.sha1.algorithm)); return ret; } } _gnutls_x509_log ("sign handshake cert vrfy: picked %s with %s\n", gnutls_sign_algorithm_get_name (sign_algo), gnutls_mac_get_name (hash_algo)); ret = _gnutls_hash_copy (&td, handshake_td); if (ret < 0) { gnutls_assert (); return ret; } _gnutls_hash_deinit (&td, concat); dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len (hash_algo); ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature); if (ret < 0) { gnutls_assert (); return ret; } return sign_algo; }
/* Generates a signature of all the random data and the parameters. * Used in DHE_* ciphersuites. */ int _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_pcert_st* cert, gnutls_privkey_t pkey, gnutls_datum_t * params, gnutls_datum_t * signature, gnutls_sign_algorithm_t * sign_algo) { gnutls_datum_t dconcat; int ret; digest_hd_st td_sha; opaque concat[MAX_SIG_SIZE]; gnutls_protocol_t ver = gnutls_protocol_get_version (session); gnutls_digest_algorithm_t hash_algo; *sign_algo = _gnutls_session_get_sign_algo (session, cert); if (*sign_algo == GNUTLS_SIGN_UNKNOWN) { gnutls_assert (); return GNUTLS_E_UNKNOWN_PK_ALGORITHM; } hash_algo = _gnutls_sign_get_hash_algorithm (*sign_algo); _gnutls_handshake_log ("HSK[%p]: signing handshake data: using %s\n", session, gnutls_sign_algorithm_get_name (*sign_algo)); ret = _gnutls_hash_init (&td_sha, hash_algo); if (ret < 0) { gnutls_assert (); return ret; } _gnutls_hash (&td_sha, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); _gnutls_hash (&td_sha, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE); _gnutls_hash (&td_sha, params->data, params->size); switch (gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL)) { case GNUTLS_PK_RSA: if (!_gnutls_version_has_selectable_sighash (ver)) { digest_hd_st td_md5; ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5); if (ret < 0) { gnutls_assert (); return ret; } _gnutls_hash (&td_md5, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); _gnutls_hash (&td_md5, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE); _gnutls_hash (&td_md5, params->data, params->size); _gnutls_hash_deinit (&td_md5, concat); _gnutls_hash_deinit (&td_sha, &concat[16]); dconcat.data = concat; dconcat.size = 36; } else { /* TLS 1.2 way */ _gnutls_hash_deinit (&td_sha, concat); dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len (hash_algo); } break; case GNUTLS_PK_DSA: _gnutls_hash_deinit (&td_sha, concat); if ((hash_algo != GNUTLS_DIG_SHA1) && (hash_algo != GNUTLS_DIG_SHA224) && (hash_algo != GNUTLS_DIG_SHA256)) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len (hash_algo); break; default: gnutls_assert (); _gnutls_hash_deinit (&td_sha, NULL); return GNUTLS_E_INTERNAL_ERROR; } ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature); if (ret < 0) { gnutls_assert (); } return ret; }
/* Verifies a TLS signature (like the one in the client certificate * verify message). */ int _gnutls_handshake_verify_cert_vrfy (gnutls_session_t session, gnutls_pcert_st *cert, gnutls_datum_t * signature, gnutls_sign_algorithm_t sign_algo) { int ret; opaque concat[MAX_SIG_SIZE]; digest_hd_st td_md5; digest_hd_st td_sha; gnutls_datum_t dconcat; gnutls_protocol_t ver = gnutls_protocol_get_version (session); _gnutls_handshake_log ("HSK[%p]: verify cert vrfy: using %s\n", session, gnutls_sign_algorithm_get_name (sign_algo)); if (session->security_parameters.handshake_mac_handle_type == HANDSHAKE_MAC_TYPE_12) { return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature, sign_algo); } else if (session->security_parameters.handshake_mac_handle_type != HANDSHAKE_MAC_TYPE_10) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } ret = _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle.tls10.md5); if (ret < 0) { gnutls_assert (); return ret; } ret = _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle.tls10.sha); if (ret < 0) { gnutls_assert (); _gnutls_hash_deinit (&td_md5, NULL); return GNUTLS_E_HASH_FAILED; } if (ver == GNUTLS_SSL3) { ret = _gnutls_generate_master (session, 1); if (ret < 0) { _gnutls_hash_deinit (&td_md5, NULL); _gnutls_hash_deinit (&td_sha, NULL); return gnutls_assert_val(ret); } ret = _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat, session-> security_parameters.master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) { _gnutls_hash_deinit (&td_sha, NULL); return gnutls_assert_val(ret); } ret = _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16], session-> security_parameters.master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) { return gnutls_assert_val(ret); } } else { _gnutls_hash_deinit (&td_md5, concat); _gnutls_hash_deinit (&td_sha, &concat[16]); } dconcat.data = concat; dconcat.size = 20 + 16; /* md5+ sha */ ret = verify_tls_hash (ver, cert, &dconcat, signature, 16, gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL)); if (ret < 0) { gnutls_assert (); return ret; } return ret; }