32 #include <axTLS/config.h> 33 #include <axTLS/ssl.h> 50 struct ssl_backend_data {
55 #define BACKEND connssl->backend 57 static CURLcode map_error_to_curl(
int axtls_err)
60 case SSL_ERROR_NOT_SUPPORTED:
61 case SSL_ERROR_INVALID_VERSION:
65 case SSL_ERROR_NO_CIPHER:
68 case SSL_ERROR_BAD_CERTIFICATE:
69 case SSL_ERROR_NO_CERT_DEFINED:
77 case SSL_X509_ERROR(X509_NOT_OK):
78 case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
79 case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
80 case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
81 case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
82 case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
83 case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
84 case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
85 case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
94 case SSL_ERROR_CONN_LOST:
95 case SSL_ERROR_SOCK_SETUP_FAILURE:
96 case SSL_ERROR_INVALID_HANDSHAKE:
97 case SSL_ERROR_INVALID_PROT_MSG:
98 case SSL_ERROR_INVALID_HMAC:
99 case SSL_ERROR_INVALID_SESSION:
100 case SSL_ERROR_INVALID_KEY:
101 case SSL_ERROR_FINISHED_INVALID:
102 case SSL_ERROR_NO_CLIENT_RENOG:
115 ssl_free(BACKEND->ssl);
118 if(BACKEND->ssl_ctx) {
119 ssl_ctx_free(BACKEND->ssl_ctx);
120 BACKEND->ssl_ctx = NULL;
135 int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
136 int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
137 int i, ssl_fcn_return;
142 uint32_t client_option = SSL_NO_DEFAULT_KEY |
143 SSL_SERVER_VERIFY_LATER |
144 SSL_CONNECT_IN_PARTS;
152 failf(data,
"axtls does not support CURL_SSLVERSION_MAX");
164 failf(data,
"axTLS only supports TLS 1.0 and 1.1, " 165 "and it cannot be specified which one to use");
170 client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
174 ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
175 if(ssl_ctx == NULL) {
176 failf(data,
"unable to create client SSL context");
180 BACKEND->ssl_ctx = ssl_ctx;
185 if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT,
187 infof(data,
"error reading ca cert file %s \n",
209 while(cert_types[i] != 0) {
210 ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
212 if(ssl_fcn_return == SSL_OK) {
213 infof(data,
"successfully read cert file %s \n",
220 if(cert_types[i] == 0) {
221 failf(data,
"%s is not x509 or pkcs12 format",
233 while(key_types[i] != 0) {
234 ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
236 if(ssl_fcn_return == SSL_OK) {
237 infof(data,
"successfully read key file %s \n",
244 if(key_types[i] == 0) {
245 failf(data,
"Failure: %s is not a supported key file",
258 const uint8_t *ssl_sessionid;
262 Curl_ssl_sessionid_lock(conn);
263 if(!Curl_ssl_getsessionid(conn, (
void **) &ssl_sessionid, &ssl_idsize,
266 infof(data,
"SSL re-using session ID\n");
267 ssl = ssl_client_new(ssl_ctx, conn->
sock[sockindex],
268 ssl_sessionid, (uint8_t)ssl_idsize, NULL);
270 Curl_ssl_sessionid_unlock(conn);
274 ssl = ssl_client_new(ssl_ctx, conn->
sock[sockindex], NULL, 0, NULL);
280 static void Curl_axtls_close(
struct connectdata *conn,
int sockindex)
284 infof(conn->
data,
" Curl_axtls_close\n");
293 free_ssl_structs(connssl);
304 SSL *ssl = BACKEND->ssl;
306 uint32_t dns_altname_index;
307 const char *dns_altname;
308 int8_t found_subject_alt_names = 0;
309 int8_t found_subject_alt_name_matching_conn = 0;
321 if(ssl_verify_cert(ssl) != SSL_OK) {
322 Curl_axtls_close(conn, sockindex);
323 failf(data,
"server cert verify failed");
328 infof(data,
"\t server certificate verification SKIPPED\n");
343 for(dns_altname_index = 0; ; dns_altname_index++) {
344 dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
345 if(dns_altname == NULL) {
348 found_subject_alt_names = 1;
350 infof(data,
"\tComparing subject alt name DNS with hostname: %s <-> %s\n",
351 dns_altname, hostname);
353 found_subject_alt_name_matching_conn = 1;
359 if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
362 Curl_axtls_close(conn, sockindex);
363 failf(data,
"\tsubjectAltName(s) do not match %s\n", dispname);
367 infof(data,
"\tsubjectAltName(s) do not match %s\n", dispname);
369 else if(found_subject_alt_names == 0) {
372 peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
373 if(peer_CN == NULL) {
375 Curl_axtls_close(conn, sockindex);
376 failf(data,
"unable to obtain common name from peer certificate");
380 infof(data,
"unable to obtain common name from peer certificate");
386 Curl_axtls_close(conn, sockindex);
387 failf(data,
"\tcommon name \"%s\" does not match \"%s\"\n",
392 infof(data,
"\tcommon name \"%s\" does not match \"%s\"\n",
400 conn->
recv[sockindex] = axtls_recv;
401 conn->
send[sockindex] = axtls_send;
405 const uint8_t *ssl_sessionid = ssl_get_session_id(ssl);
406 size_t ssl_idsize = ssl_get_session_id_size(ssl);
407 Curl_ssl_sessionid_lock(conn);
408 if(Curl_ssl_addsessionid(conn, (
void *) ssl_sessionid, ssl_idsize,
410 infof(data,
"failed to add session to cache\n");
411 Curl_ssl_sessionid_unlock(conn);
422 int sockindex,
bool *done)
433 conn_step = connect_prep(conn, sockindex);
435 Curl_axtls_close(conn, sockindex);
443 if(ssl_handshake_status(BACKEND->ssl) != SSL_OK) {
447 for(i = 0; i<5; i++) {
448 ssl_fcn_return = ssl_read(BACKEND->ssl, NULL);
449 if(ssl_fcn_return < 0) {
450 Curl_axtls_close(conn, sockindex);
451 ssl_display_error(ssl_fcn_return);
452 return map_error_to_curl(ssl_fcn_return);
457 infof(conn->
data,
"handshake completed successfully\n");
462 conn_step = connect_finish(conn, sockindex);
464 Curl_axtls_close(conn, sockindex);
490 CURLcode conn_step = connect_prep(conn, sockindex);
493 SSL *ssl = BACKEND->ssl;
497 Curl_axtls_close(conn, sockindex);
502 while(ssl_handshake_status(ssl) != SSL_OK) {
508 failf(data,
"SSL connection timeout");
512 ssl_fcn_return = ssl_read(ssl, NULL);
513 if(ssl_fcn_return < 0) {
514 Curl_axtls_close(conn, sockindex);
515 ssl_display_error(ssl_fcn_return);
516 return map_error_to_curl(ssl_fcn_return);
521 infof(conn->
data,
"handshake completed successfully\n");
523 conn_step = connect_finish(conn, sockindex);
525 Curl_axtls_close(conn, sockindex);
541 int rc = ssl_write(BACKEND->ssl, mem, (
int)len);
546 *err = map_error_to_curl(rc);
558 static int Curl_axtls_shutdown(
struct connectdata *conn,
int sockindex)
569 infof(conn->
data,
" Curl_axtls_shutdown\n");
588 nread = (
ssize_t)ssl_read(BACKEND->ssl, &buf);
591 failf(data,
"close notify alert not received during shutdown");
597 failf(data,
"SSL shutdown timeout");
605 free_ssl_structs(connssl);
624 ret = ssl_read(BACKEND->ssl, &read_buf);
629 (
size_t)ret > buffersize ? buffersize : (
size_t)ret);
631 else if(ret == SSL_OK) {
639 Curl_axtls_close(conn, num);
642 failf(conn->
data,
"axTLS recv error (%d)", ret);
643 *err = map_error_to_curl((
int) ret);
657 static int Curl_axtls_check_cxn(
struct connectdata *conn)
664 infof(conn->
data,
" Curl_axtls_check_cxn\n");
668 static void Curl_axtls_session_free(
void *
ptr)
676 static size_t Curl_axtls_version(
char *
buffer,
size_t size)
678 return snprintf(buffer, size,
"axTLS/%s", ssl_version());
682 unsigned char *entropy,
size_t length)
684 static bool ssl_seeded =
FALSE;
693 get_random((
int)length, entropy);
704 const struct Curl_ssl Curl_ssl_axtls = {
713 sizeof(
struct ssl_backend_data),
723 Curl_axtls_check_cxn,
729 Curl_axtls_connect_nonblocking,
730 Curl_axtls_get_internals,
733 Curl_axtls_session_free,
struct ssl_connect_data ssl[2]
ssize_t( Curl_recv)(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err)
#define SSL_CONN_CONFIG(var)
#define SSL_SET_OPTION(var)
ssl_connect_state connecting_state
UNITTEST_START char * ptr
bool Curl_none_data_pending(const struct connectdata *conn, int connindex)
struct proxy_info http_proxy
ssl_connection_state state
memcpy(filename, filename1, strlen(filename1))
int Curl_wait_ms(int timeout_ms)
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
bool Curl_none_false_start(void)
#define SOCKET_READABLE(x, z)
bool Curl_none_cert_status_request(void)
void Curl_none_cleanup(void)
ssize_t( Curl_send)(struct connectdata *conn, int sockindex, const void *buf, size_t len, CURLcode *err)
CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, unsigned char *md5sum, size_t md5len)
CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine)
int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
struct curl_slist * Curl_none_engines_list(struct Curl_easy *data)
CURLcode Curl_none_set_engine_default(struct Curl_easy *data)
void Curl_none_close_all(struct Curl_easy *data)