uschar * tls_cert_signature_algorithm(void * cert, uschar * mod) { gnutls_sign_algorithm_t algo = gnutls_x509_crt_get_signature_algorithm((gnutls_x509_crt_t)cert); return algo < 0 ? NULL : string_copy(gnutls_sign_get_name(algo)); }
/* Parses the Signature Algorithm structure and stores data into * session->security_parameters.extensions. */ int _gnutls_sign_algorithm_parse_data(gnutls_session_t session, const uint8_t * data, size_t data_size) { unsigned int sig, i; sig_ext_st *priv; extension_priv_data_t epriv; if (data_size % 2 != 0) return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); priv = gnutls_calloc(1, sizeof(*priv)); if (priv == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } for (i = 0; i < data_size; i += 2) { sign_algorithm_st aid; aid.hash_algorithm = data[i]; aid.sign_algorithm = data[i + 1]; sig = _gnutls_tls_aid_to_sign(&aid); _gnutls_handshake_log ("EXT[%p]: rcvd signature algo (%d.%d) %s\n", session, aid.hash_algorithm, aid.sign_algorithm, gnutls_sign_get_name(sig)); if (sig != GNUTLS_SIGN_UNKNOWN) { priv->sign_algorithms[priv-> sign_algorithms_size++] = sig; if (priv->sign_algorithms_size == MAX_SIGNATURE_ALGORITHMS) break; } } epriv = priv; _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS, epriv); return 0; }
/* generates a SignatureAndHashAlgorithm structure with length as prefix * by using the setup priorities. */ int _gnutls_sign_algorithm_write_params(gnutls_session_t session, uint8_t * data, size_t max_data_size) { uint8_t *p = data, *len_p; unsigned int len, i, j; const sign_algorithm_st *aid; if (max_data_size < (session->internals.priorities.sign_algo.algorithms * 2) + 2) { gnutls_assert(); return GNUTLS_E_SHORT_MEMORY_BUFFER; } len = 0; len_p = p; p += 2; for (i = j = 0; j < session->internals.priorities.sign_algo.algorithms; i += 2, j++) { aid = _gnutls_sign_to_tls_aid(session->internals. priorities.sign_algo. priority[j]); if (aid == NULL) continue; _gnutls_handshake_log ("EXT[%p]: sent signature algo (%d.%d) %s\n", session, aid->hash_algorithm, aid->sign_algorithm, gnutls_sign_get_name(session->internals.priorities. sign_algo.priority[j])); *p = aid->hash_algorithm; p++; *p = aid->sign_algorithm; p++; len += 2; } _gnutls_write_uint16(len, len_p); return len + 2; }
static void main_texinfo (void) { { 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 ("@heading Ciphersuites\n"); printf ("@multitable @columnfractions .60 .20 .20\n"); printf("@headitem Ciphersuite name @tab TLS ID @tab Since\n"); for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, &version)); i++) { printf ("@item %s\n@tab 0x%02X 0x%02X\n@tab %s\n", escape_texi_string(name, buffer, sizeof(buffer)), (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); } printf ("@end multitable\n"); } { const gnutls_certificate_type_t *p = gnutls_certificate_type_list (); printf ("\n\n@heading Certificate types\n"); printf ("@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_certificate_type_get_name (*p)); } printf ("@end table\n"); } { const gnutls_protocol_t *p = gnutls_protocol_list (); printf ("\n@heading Protocols\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_protocol_get_name (*p)); } printf ("@end table\n"); } { const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); printf ("\n@heading Ciphers\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_cipher_get_name (*p)); } printf ("@end table\n"); } { const gnutls_mac_algorithm_t *p = gnutls_mac_list (); printf ("\n@heading MAC algorithms\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_mac_get_name (*p)); } printf ("@end table\n"); } { const gnutls_kx_algorithm_t *p = gnutls_kx_list (); printf ("\n@heading Key exchange methods\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_kx_get_name (*p)); } printf ("@end table\n"); } { const gnutls_pk_algorithm_t *p = gnutls_pk_list (); printf ("\n@heading Public key algorithms\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_pk_get_name (*p)); } printf ("@end table\n"); } { const gnutls_sign_algorithm_t *p = gnutls_sign_list (); printf ("\n@heading Public key signature algorithms\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_sign_get_name (*p)); } printf ("@end table\n"); } { const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list (); printf ("\n@heading Elliptic curves\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_ecc_curve_get_name (*p)); } printf ("@end table\n"); } { const gnutls_compression_method_t *p = gnutls_compression_list (); printf ("\n@heading Compression methods\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_compression_get_name (*p)); } printf ("@end table\n"); } }
int print_info(gnutls_session_t session, int verbose, int print_cert) { const char *tmp; gnutls_credentials_type_t cred; gnutls_kx_algorithm_t kx; unsigned char session_id[33]; size_t session_id_size = sizeof(session_id); gnutls_srtp_profile_t srtp_profile; gnutls_datum_t p; char *desc; int rc; desc = gnutls_session_get_desc(session); printf("- Description: %s\n", desc); gnutls_free(desc); /* print session ID */ gnutls_session_get_id(session, session_id, &session_id_size); printf("- Session ID: %s\n", raw_to_string(session_id, session_id_size)); /* print the key exchange's algorithm name */ kx = gnutls_kx_get(session); cred = gnutls_auth_get_type(session); switch (cred) { #ifdef ENABLE_ANON case GNUTLS_CRD_ANON: if (kx == GNUTLS_KX_ANON_ECDH) print_ecdh_info(session, "Anonymous "); else print_dh_info(session, "Anonymous ", verbose); break; #endif #ifdef ENABLE_SRP case GNUTLS_CRD_SRP: /* This should be only called in server * side. */ if (gnutls_srp_server_get_username(session) != NULL) printf("- SRP authentication. Connected as '%s'\n", gnutls_srp_server_get_username(session)); break; #endif #ifdef ENABLE_PSK case GNUTLS_CRD_PSK: /* This returns NULL in server side. */ if (gnutls_psk_client_get_hint(session) != NULL) printf("- PSK authentication. PSK hint '%s'\n", gnutls_psk_client_get_hint(session)); /* This returns NULL in client side. */ if (gnutls_psk_server_get_username(session) != NULL) printf("- PSK authentication. Connected as '%s'\n", gnutls_psk_server_get_username(session)); if (kx == GNUTLS_KX_DHE_PSK) print_dh_info(session, "Ephemeral ", verbose); if (kx == GNUTLS_KX_ECDHE_PSK) print_ecdh_info(session, "Ephemeral "); break; #endif case GNUTLS_CRD_IA: printf("- TLS/IA authentication\n"); break; case GNUTLS_CRD_CERTIFICATE: { char dns[256]; size_t dns_size = sizeof(dns); unsigned int type; /* This fails in client side */ if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0) { printf("- Given server name[%d]: %s\n", type, dns); } } if (print_cert) print_cert_info(session, verbose, print_cert); if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) print_dh_info(session, "Ephemeral ", verbose); else if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA) print_ecdh_info(session, "Ephemeral "); } tmp = SU(gnutls_protocol_get_name (gnutls_protocol_get_version(session))); printf("- Version: %s\n", tmp); tmp = SU(gnutls_kx_get_name(kx)); printf("- Key Exchange: %s\n", tmp); if (gnutls_sign_algorithm_get(session) != GNUTLS_SIGN_UNKNOWN) { tmp = SU(gnutls_sign_get_name (gnutls_sign_algorithm_get(session))); printf("- Server Signature: %s\n", tmp); } if (gnutls_sign_algorithm_get_client(session) != GNUTLS_SIGN_UNKNOWN) { tmp = SU(gnutls_sign_get_name (gnutls_sign_algorithm_get_client(session))); printf("- Client Signature: %s\n", tmp); } tmp = SU(gnutls_cipher_get_name(gnutls_cipher_get(session))); printf("- Cipher: %s\n", tmp); tmp = SU(gnutls_mac_get_name(gnutls_mac_get(session))); printf("- MAC: %s\n", tmp); tmp = SU(gnutls_compression_get_name (gnutls_compression_get(session))); printf("- Compression: %s\n", tmp); #ifdef ENABLE_DTLS_SRTP rc = gnutls_srtp_get_selected_profile(session, &srtp_profile); if (rc == 0) printf("- SRTP profile: %s\n", gnutls_srtp_get_profile_name(srtp_profile)); #endif #ifdef ENABLE_ALPN rc = gnutls_alpn_get_selected_protocol(session, &p); if (rc == 0) printf("- Application protocol: %.*s\n", p.size, p.data); #endif if (verbose) { gnutls_datum_t cb; rc = gnutls_session_channel_binding(session, GNUTLS_CB_TLS_UNIQUE, &cb); if (rc) fprintf(stderr, "Channel binding error: %s\n", gnutls_strerror(rc)); else { size_t i; printf("- Channel binding 'tls-unique': "); for (i = 0; i < cb.size; i++) printf("%02x", cb.data[i]); printf("\n"); } } /* Warning: Do not print anything more here. The 'Compression:' output MUST be the last non-verbose output. This is used by Emacs starttls.el code. */ fflush(stdout); return 0; }
static void print_pkcs7_info(gnutls_pkcs7_signature_info_st * info, gnutls_buffer_st * str, gnutls_certificate_print_formats_t format) { unsigned i; char *oid; gnutls_datum_t data; char prefix[128]; char s[42]; size_t max; int ret; if (info->issuer_dn.size > 0) print_dn(str, "\tSigner's issuer DN", &info->issuer_dn); print_raw(str, "\tSigner's serial", &info->signer_serial); print_raw(str, "\tSigner's issuer key ID", &info->issuer_keyid); if (info->signing_time != -1) { struct tm t; if (gmtime_r(&info->signing_time, &t) == NULL) { addf(str, "error: gmtime_r (%ld)\n", (unsigned long)info->signing_time); } else { max = sizeof(s); if (strftime(s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0) { addf(str, "error: strftime (%ld)\n", (unsigned long)info->signing_time); } else { addf(str, "\tSigning time: %s\n", s); } } } addf(str, "\tSignature Algorithm: %s\n", gnutls_sign_get_name(info->algo)); if (format == GNUTLS_CRT_PRINT_FULL) { if (info->signed_attrs) { for (i = 0;; i++) { ret = gnutls_pkcs7_get_attr(info->signed_attrs, i, &oid, &data, 0); if (ret < 0) break; if (i == 0) addf(str, "\tSigned Attributes:\n"); snprintf(prefix, sizeof(prefix), "\t\t%s", oid); print_raw(str, prefix, &data); gnutls_free(data.data); } } if (info->unsigned_attrs) { for (i = 0;; i++) { ret = gnutls_pkcs7_get_attr(info->unsigned_attrs, i, &oid, &data, 0); if (ret < 0) break; if (i == 0) addf(str, "\tUnsigned Attributes:\n"); snprintf(prefix, sizeof(prefix), "\t\t%s", oid); print_raw(str, prefix, &data); gnutls_free(data.data); } } } adds(str, "\n"); }
int main (void) { { 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 ("Available cipher suites:\n"); printf ("@multitable @columnfractions .60 .20 .20\n"); for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, &version)); i++) { printf ("@item %s\n@tab 0x%02x 0x%02x\n@tab %s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); } printf ("@end multitable\n"); } { const gnutls_certificate_type_t *p = gnutls_certificate_type_list (); printf ("\n\nAvailable certificate types:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_certificate_type_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_protocol_t *p = gnutls_protocol_list (); printf ("\nAvailable protocols:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_protocol_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); printf ("\nAvailable ciphers:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_cipher_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_mac_algorithm_t *p = gnutls_mac_list (); printf ("\nAvailable MAC algorithms:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_mac_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_kx_algorithm_t *p = gnutls_kx_list (); printf ("\nAvailable key exchange methods:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_kx_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_pk_algorithm_t *p = gnutls_pk_list (); printf ("\nAvailable public key algorithms:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_pk_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_sign_algorithm_t *p = gnutls_sign_list (); printf ("\nAvailable public key signature algorithms:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_sign_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_compression_method_t *p = gnutls_compression_list (); printf ("\nAvailable compression methods:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_compression_get_name (*p)); } printf ("@end itemize\n"); } }
void dtls_try_with_key_mtu(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx, gnutls_sign_algorithm_t server_sign_algo, gnutls_sign_algorithm_t client_sign_algo, const gnutls_datum_t *serv_cert, const gnutls_datum_t *serv_key, const gnutls_datum_t *client_cert, const gnutls_datum_t *client_key, unsigned cert_flags, unsigned smtu) { int ret; char buffer[256]; /* Server stuff. */ gnutls_certificate_credentials_t serverx509cred; gnutls_anon_server_credentials_t s_anoncred; gnutls_dh_params_t dh_params; const gnutls_datum_t p3 = { (unsigned char *) pkcs3, strlen(pkcs3) }; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t clientx509cred; gnutls_anon_client_credentials_t c_anoncred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN, version; /* General init. */ gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(6); reset_buffers(); /* Init server */ gnutls_anon_allocate_server_credentials(&s_anoncred); gnutls_certificate_allocate_credentials(&serverx509cred); ret = gnutls_certificate_set_x509_key_mem(serverx509cred, serv_cert, serv_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("Could not set key/cert: %s\n", gnutls_strerror(ret)); } gnutls_dh_params_init(&dh_params); gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_dh_params(serverx509cred, dh_params); gnutls_anon_set_server_dh_params(s_anoncred, dh_params); assert(gnutls_init(&server, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK)>=0); assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred)>=0); assert(gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred)>=0); assert(gnutls_priority_set_direct(server, "NORMAL:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519", NULL)>=0); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_pull_timeout_function(server, server_pull_timeout_func); gnutls_transport_set_ptr(server, server); if (smtu) gnutls_dtls_set_mtu (server, smtu); /* Init client */ ret = gnutls_certificate_allocate_credentials(&clientx509cred); if (ret < 0) exit(1); if (cert_flags == USE_CERT) { ret = gnutls_certificate_set_x509_key_mem(clientx509cred, client_cert, client_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("Could not set key/cert: %s\n", gnutls_strerror(ret)); } gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE); } else if (cert_flags == ASK_CERT) { gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); } #if 0 ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); #endif ret = gnutls_init(&client, GNUTLS_CLIENT|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK); if (ret < 0) exit(1); assert(gnutls_anon_allocate_client_credentials(&c_anoncred)>=0); assert(gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred)>=0); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_pull_timeout_function(client, client_pull_timeout_func); gnutls_transport_set_ptr(client, client); if (smtu) gnutls_dtls_set_mtu (client, smtu); ret = gnutls_priority_set_direct(client, client_prio, NULL); if (ret < 0) { exit(1); } success("negotiating %s\n", name); HANDSHAKE_DTLS(client, server); if (gnutls_kx_get(client) != client_kx) { fail("%s: got unexpected key exchange algorithm: %s (expected %s)\n", name, gnutls_kx_get_name(gnutls_kx_get(client)), gnutls_kx_get_name(client_kx)); exit(1); } /* test signature algorithm match */ version = gnutls_protocol_get_version(client); if (version >= GNUTLS_DTLS1_2) { ret = gnutls_sign_algorithm_get(server); if (ret != (int)server_sign_algo) { fail("%s: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get_client(server); if (ret != (int)client_sign_algo) { fail("%s: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get(client); if (ret != (int)server_sign_algo) { fail("%s: cl: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get_client(client); if (ret != (int)client_sign_algo) { fail("%s: cl: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } } gnutls_record_send(server, MSG, strlen(MSG)); ret = gnutls_record_recv(client, buffer, sizeof(buffer)); if (ret == 0) { fail("client: Peer has closed the TLS connection\n"); exit(1); } else if (ret < 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); exit(1); } if (ret != strlen(MSG) || memcmp(MSG, buffer, ret) != 0) { fail("client: Error in data received. Expected %d, got %d\n", (int)strlen(MSG), ret); exit(1); } gnutls_bye(client, GNUTLS_SHUT_RDWR); gnutls_bye(server, GNUTLS_SHUT_RDWR); gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); gnutls_anon_free_server_credentials(s_anoncred); gnutls_anon_free_client_credentials(c_anoncred); gnutls_dh_params_deinit(dh_params); }
void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx, gnutls_sign_algorithm_t server_sign_algo, gnutls_sign_algorithm_t client_sign_algo, const gnutls_datum_t *serv_cert, const gnutls_datum_t *serv_key, const gnutls_datum_t *client_cert, const gnutls_datum_t *client_key, unsigned cert_flags, unsigned exp_group, gnutls_certificate_type_t server_ctype, gnutls_certificate_type_t client_ctype) { int ret; char buffer[256]; /* Server stuff. */ gnutls_certificate_credentials_t server_cred; gnutls_anon_server_credentials_t s_anoncred; gnutls_dh_params_t dh_params; const gnutls_datum_t p3 = { (unsigned char *) pkcs3, strlen(pkcs3) }; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t client_cred; gnutls_anon_client_credentials_t c_anoncred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN, version; const char *err; /* General init. */ gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(6); reset_buffers(); /* Init server */ assert(gnutls_anon_allocate_server_credentials(&s_anoncred)>=0); assert(gnutls_certificate_allocate_credentials(&server_cred)>=0); // Set server crt creds based on ctype switch (server_ctype) { case GNUTLS_CRT_X509: ret = gnutls_certificate_set_x509_key_mem(server_cred, serv_cert, serv_key, GNUTLS_X509_FMT_PEM); break; case GNUTLS_CRT_RAWPK: ret = gnutls_certificate_set_rawpk_key_mem(server_cred, serv_cert, serv_key, GNUTLS_X509_FMT_PEM, NULL, 0, NULL, 0, 0); break; default: ret = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } if (ret < 0) { fail("Could not set key/cert: %s\n", gnutls_strerror(ret)); } gnutls_dh_params_init(&dh_params); gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_dh_params(server_cred, dh_params); gnutls_anon_set_server_dh_params(s_anoncred, dh_params); assert(gnutls_init(&server, GNUTLS_SERVER | GNUTLS_ENABLE_RAWPK)>=0); assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, server_cred)>=0); assert(gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred)>=0); if (server_priority) assert(gnutls_priority_set_direct(server, server_priority, NULL) >= 0); else assert(gnutls_priority_set_direct(server, "NORMAL:+VERS-SSL3.0:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519:+CTYPE-ALL", NULL)>=0); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); /* Init client */ ret = gnutls_certificate_allocate_credentials(&client_cred); if (ret < 0) exit(1); if (cert_flags == USE_CERT) { // Set client crt creds based on ctype switch (client_ctype) { case GNUTLS_CRT_X509: gnutls_certificate_set_x509_key_mem(client_cred, client_cert, client_key, GNUTLS_X509_FMT_PEM); break; case GNUTLS_CRT_RAWPK: gnutls_certificate_set_rawpk_key_mem(client_cred, client_cert, client_key, GNUTLS_X509_FMT_PEM, NULL, 0, NULL, 0, 0); break; default: fail("Illegal client certificate type given\n"); } gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE); } else if (cert_flags == ASK_CERT) { gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); } #if 0 ret = gnutls_certificate_set_x509_trust_mem(client_cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); #endif ret = gnutls_init(&client, GNUTLS_CLIENT | GNUTLS_ENABLE_RAWPK); if (ret < 0) exit(1); assert(gnutls_anon_allocate_client_credentials(&c_anoncred)>=0); assert(gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred)>=0); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, client_cred); if (ret < 0) exit(1); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); ret = gnutls_priority_set_direct(client, client_prio, &err); if (ret < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) fprintf(stderr, "Error in %s\n", err); exit(1); } success("negotiating %s\n", name); HANDSHAKE(client, server); if (gnutls_kx_get(client) != client_kx) { fail("%s: got unexpected key exchange algorithm: %s (expected %s)\n", name, gnutls_kx_get_name(gnutls_kx_get(client)), gnutls_kx_get_name(client_kx)); exit(1); } /* test signature algorithm match */ version = gnutls_protocol_get_version(client); if (version >= GNUTLS_TLS1_2) { ret = gnutls_sign_algorithm_get(server); if (ret != (int)server_sign_algo) { fail("%s: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get_client(server); if (ret != (int)client_sign_algo) { fail("%s: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get(client); if (ret != (int)server_sign_algo) { fail("%s: cl: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get_client(client); if (ret != (int)client_sign_algo) { fail("%s: cl: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } } if (exp_group != 0) { ret = gnutls_group_get(server); if (ret != (int)exp_group) { fail("%s: got unexpected server group: %d/%s\n", name, ret, gnutls_group_get_name(ret)); } ret = gnutls_group_get(client); if (ret != (int)exp_group) { fail("%s: got unexpected client group: %d/%s\n", name, ret, gnutls_group_get_name(ret)); } } gnutls_record_send(server, MSG, strlen(MSG)); ret = gnutls_record_recv(client, buffer, sizeof(buffer)); if (ret == 0) { fail("client: Peer has closed the TLS connection\n"); exit(1); } else if (ret < 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); exit(1); } if (ret != strlen(MSG) || memcmp(MSG, buffer, ret) != 0) { fail("client: Error in data received. Expected %d, got %d\n", (int)strlen(MSG), ret); exit(1); } gnutls_bye(client, GNUTLS_SHUT_RDWR); gnutls_bye(server, GNUTLS_SHUT_RDWR); gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(server_cred); gnutls_certificate_free_credentials(client_cred); gnutls_anon_free_server_credentials(s_anoncred); gnutls_anon_free_client_credentials(c_anoncred); gnutls_dh_params_deinit(dh_params); }