/* Very simple TLS client, to test TLS 1.3 connections */ #define MAXHOSTNAME 256 #define MAXPORTNAME 128 #define MAXMSG 1024 /* Default port */ #define PORT "https" #include #include #include #include #include #include #include #include /* https://gnutls.org/manual/gnutls.html */ int main(argc, argv) int argc; char **argv; { gnutls_session_t *session = malloc(sizeof(gnutls_session_t)); int tls_result; int last_alert; int cert_status; gnutls_datum_t *cert_out; int cert_type; int result; char *hostname = malloc(MAXHOSTNAME); char *portname = malloc(MAXPORTNAME); int sockfd; struct addrinfo hints, *res; gnutls_certificate_credentials_t xcred; if (argc <= 1 || argc>= 4) { fprintf(stderr, "Usage: %s server-name [server-port]\n", argv[0]); exit(1); } strcpy(hostname, argv[1]); if (argc == 3) { strcpy(portname, argv[2]); } else { strcpy(portname, PORT); } tls_result = gnutls_certificate_allocate_credentials(&xcred); if (tls_result != GNUTLS_E_SUCCESS) { fprintf(stderr, "Cannot allocate credentials: %s\n", gnutls_strerror(tls_result)); exit(1); } tls_result = gnutls_certificate_set_x509_system_trust(xcred); if (tls_result < 0) { fprintf(stderr, "Cannot load credentials: %s\n", gnutls_strerror(tls_result)); exit(1); } tls_result = gnutls_init(session, GNUTLS_CLIENT); if (tls_result != GNUTLS_E_SUCCESS) { fprintf(stderr, "Cannot create a new TLS session: %s\n", gnutls_strerror(tls_result)); exit(1); } tls_result = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE, xcred); /* Mandatory * or * "no * cipher * suites * found" */ if (tls_result != GNUTLS_E_SUCCESS) { fprintf(stderr, "Cannot set credentials: %s\n", gnutls_strerror(tls_result)); exit(1); } tls_result = gnutls_priority_set_direct(*session, "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0", NULL); if (tls_result != GNUTLS_E_SUCCESS) { fprintf(stderr, "Cannot set priorities: %s\n", gnutls_strerror(tls_result)); exit(1); } gnutls_session_set_verify_cert(*session, hostname, 0); tls_result = gnutls_server_name_set(*session, GNUTLS_NAME_DNS, hostname, strlen(hostname)); if (tls_result != GNUTLS_E_SUCCESS) { fprintf(stderr, "Cannot set Server Name Indication: %s\n", gnutls_strerror(tls_result)); exit(1); } memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; /* v4 or v6, I don't care */ hints.ai_socktype = SOCK_STREAM; result = getaddrinfo(hostname, portname, &hints, &res); if (result != 0) { fprintf(stderr, "Cannot resolve name '%s : %s' (wrong name or wrong port): %d\n", hostname, portname, result); exit(1); } sockfd = socket(res->ai_family, res->ai_socktype, 0); if (sockfd == -1) { fprintf(stderr, "Cannot create socket\n"); exit(1); } result = connect(sockfd, res->ai_addr, res->ai_addrlen); if (result != 0) { fprintf(stderr, "Cannot connect to %s: %d\n", hostname, errno); exit(1); } gnutls_transport_set_int(*session, sockfd); tls_result = gnutls_handshake(*session); if (tls_result != GNUTLS_E_SUCCESS) { fprintf(stderr, "Cannot start the TLS session to %s: ", hostname); if (tls_result == GNUTLS_E_FATAL_ALERT_RECEIVED) { last_alert = gnutls_alert_get(*session); fprintf(stderr, "Received alert '%d': %s.\n", last_alert, gnutls_alert_get_name(last_alert)); } else if (tls_result == GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR) { cert_status = gnutls_session_get_verify_cert_status(*session); cert_out = malloc(sizeof(gnutls_datum_t)); cert_out->size = 0; cert_out->data = malloc(MAXMSG); cert_out->data[0] = '0円'; cert_type = gnutls_certificate_type_get(*session); tls_result = gnutls_certificate_verification_status_print(cert_status, cert_type, cert_out, 0); if (tls_result != GNUTLS_E_SUCCESS) { fprintf(stderr, "Error in printing the certificate check status\n"); exit(1); } fprintf(stderr, "%s\n", cert_out->data); } else { fprintf(stderr, "%s\n", gnutls_strerror(tls_result)); } exit(1); } fprintf (stderr, "TLS connection using \"%s %s\"\n", gnutls_protocol_get_name(gnutls_protocol_get_version(*session)), gnutls_cipher_get_name(gnutls_cipher_get(*session))); }

AltStyle によって変換されたページ (->オリジナル) /