33 #define WOLFSSL_OPTIONS_IGNORE_SYS 37 #include <cyassl/version.h> 38 #if defined(HAVE_CYASSL_OPTIONS_H) && (LIBCYASSL_VERSION_HEX > 0x03004008) 39 #if defined(CYASSL_API) || defined(WOLFSSL_API) 42 #error "CyaSSL API was included before the CyaSSL build options." 44 #include <cyassl/options.h> 55 #ifdef HAVE_WOLFSSL_USEALPN 63 #ifndef WOLFSSL_ALLOW_SSLV3 64 #if (LIBCYASSL_VERSION_HEX < 0x03006006) || \ 65 defined(HAVE_WOLFSSLV3_CLIENT_METHOD) 66 #define WOLFSSL_ALLOW_SSLV3 72 #ifndef HAVE_SUPPORTED_CURVES 73 #if defined(HAVE_CYASSL_CTX_USESUPPORTEDCURVE) || \ 74 defined(HAVE_WOLFSSL_CTX_USESUPPORTEDCURVE) 75 #define HAVE_SUPPORTED_CURVES 94 #include <cyassl/openssl/ssl.h> 95 #include <cyassl/ssl.h> 96 #ifdef HAVE_CYASSL_ERROR_SSL_H 97 #include <cyassl/error-ssl.h> 99 #include <cyassl/error.h> 101 #include <cyassl/ctaocrypt/random.h> 102 #include <cyassl/ctaocrypt/sha256.h> 110 #if LIBCYASSL_VERSION_HEX < 0x02007002 111 #define CYASSL_MAX_ERROR_SZ 80 118 #ifndef KEEP_PEER_CERT 119 #if defined(HAVE_CYASSL_GET_PEER_CERTIFICATE) || \ 120 defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \ 121 (defined(OPENSSL_EXTRA) && !defined(NO_CERTS)) 122 #define KEEP_PEER_CERT 126 struct ssl_backend_data {
131 #define BACKEND connssl->backend 137 static int do_file_type(
const char *type)
139 if(!type || !type[0])
140 return SSL_FILETYPE_PEM;
142 return SSL_FILETYPE_PEM;
144 return SSL_FILETYPE_ASN1;
156 char error_buffer[CYASSL_MAX_ERROR_SZ];
160 SSL_METHOD* req_method = NULL;
164 #define use_sni(x) sni = (x) 166 #define use_sni(x) Curl_nop_stmt 173 failf(data,
"CyaSSL does not support to set maximum SSL/TLS version");
181 #if LIBCYASSL_VERSION_HEX >= 0x03003000 185 infof(data,
"CyaSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, " 186 "TLS 1.0 is used exclusively\n");
196 req_method = TLSv1_1_client_method();
200 req_method = TLSv1_2_client_method();
204 failf(data,
"CyaSSL: TLS 1.3 is not yet supported");
207 #ifdef WOLFSSL_ALLOW_SSLV3 211 failf(data,
"CyaSSL does not support SSLv3");
216 failf(data,
"CyaSSL does not support SSLv2");
219 failf(data,
"Unrecognized parameter passed via CURLOPT_SSLVERSION");
224 failf(data,
"SSL: couldn't create a method!");
233 failf(data,
"SSL: couldn't create a context!");
240 #if LIBCYASSL_VERSION_HEX > 0x03004006 248 if((wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1) != 1) &&
249 (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_1) != 1) &&
250 (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_2) != 1)) {
251 failf(data,
"SSL: couldn't set the minimum protocol version");
261 failf(data,
"failed setting cipher list: %s", ciphers);
264 infof(data,
"Cipher selection: %s\n", ciphers);
267 #ifndef NO_FILESYSTEM 275 failf(data,
"error setting certificate verify locations:\n" 276 " CAfile: %s\n CApath: %s",
286 infof(data,
"error setting certificate verify locations," 287 " continuing anyway:\n");
292 infof(data,
"successfully set certificate verify locations:\n");
309 failf(data,
"unable to use client certificate (no key or wrong pass" 317 failf(data,
"unable to set private key");
334 struct in_addr addr4;
336 struct in6_addr addr6;
340 size_t hostname_len = strlen(hostname);
341 if((hostname_len < USHRT_MAX) &&
346 (CyaSSL_CTX_UseSNI(BACKEND->ctx, CYASSL_SNI_HOST_NAME, hostname,
347 (
unsigned short)hostname_len) != 1)) {
348 infof(data,
"WARNING: failed to configure server name indication (SNI) " 354 #ifdef HAVE_SUPPORTED_CURVES 359 CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x17);
360 CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x19);
361 CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x18);
370 failf(data,
"error signaled by ssl ctx callback");
376 failf(data,
"SSL: Certificates couldn't be loaded because CyaSSL was built" 377 " with \"no filesystem\". Either disable peer verification" 378 " (insecure) or if you are building an application with libcurl you" 379 " can load certificates via CURLOPT_SSL_CTX_FUNCTION.");
387 BACKEND->handle =
SSL_new(BACKEND->ctx);
388 if(!BACKEND->handle) {
389 failf(data,
"SSL: couldn't create a context (handle)!");
403 strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID
",");
404 infof(data,
"ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
411 if(wolfSSL_UseALPN(BACKEND->handle, protocols,
412 (
unsigned)strlen(protocols),
413 WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) {
414 failf(data,
"SSL: failed setting ALPN protocols");
422 void *ssl_sessionid = NULL;
424 Curl_ssl_sessionid_lock(conn);
425 if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
428 Curl_ssl_sessionid_unlock(conn);
429 failf(data,
"SSL: SSL_set_session failed: %s",
435 infof(data,
"SSL re-using session ID\n");
437 Curl_ssl_sessionid_unlock(conn);
441 if(!
SSL_set_fd(BACKEND->handle, (
int)sockfd)) {
442 failf(data,
"SSL: SSL_set_fd failed");
466 conn->
recv[sockindex] = cyassl_recv;
467 conn->
send[sockindex] = cyassl_send;
471 ret = CyaSSL_check_domain_name(BACKEND->handle, hostname);
472 if(ret == SSL_FAILURE)
478 char error_buffer[CYASSL_MAX_ERROR_SZ];
481 if(SSL_ERROR_WANT_READ == detail) {
485 else if(SSL_ERROR_WANT_WRITE == detail) {
492 else if(DOMAIN_NAME_MISMATCH == detail) {
494 failf(data,
"\tsubject alt name(s) or common name do not match \"%s\"\n",
505 "\tsubject alt name(s) or common name do not match \"%s\"\n",
511 "\tsubject alt name(s) and/or common name do not match \"%s\"\n",
517 #if LIBCYASSL_VERSION_HEX >= 0x02007000 518 else if(ASN_NO_SIGNER_E == detail) {
520 failf(data,
"\tCA signer not available for verification\n");
526 infof(data,
"CA signer not available for verification, " 527 "continuing anyway\n");
532 failf(data,
"SSL_connect failed with error %d: %s", detail,
539 #ifdef KEEP_PEER_CERT 541 const char *x509_der;
543 curl_X509certificate x509_parsed;
544 curl_asn1Element *pubkey;
549 failf(data,
"SSL: failed retrieving server certificate");
553 x509_der = (
const char *)CyaSSL_X509_get_der(x509, &x509_der_len);
555 failf(data,
"SSL: failed retrieving ASN.1 server certificate");
559 memset(&x509_parsed, 0,
sizeof x509_parsed);
560 if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
563 pubkey = &x509_parsed.subjectPublicKeyInfo;
564 if(!pubkey->header || pubkey->end <= pubkey->header) {
565 failf(data,
"SSL: failed retrieving public key from server certificate");
569 result = Curl_pin_peer_pubkey(data,
571 (
const unsigned char *)pubkey->header,
572 (
size_t)(pubkey->end - pubkey->header));
574 failf(data,
"SSL: public key does not match pinned public key!");
578 failf(data,
"Library lacks pinning support built-in");
586 char *protocol = NULL;
587 unsigned short protocol_len = 0;
589 rc = wolfSSL_ALPN_GetProtocol(BACKEND->handle, &protocol, &protocol_len);
591 if(rc == SSL_SUCCESS) {
592 infof(data,
"ALPN, server accepted to use %.*s\n", protocol_len,
600 protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN &&
601 !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID,
602 NGHTTP2_PROTO_VERSION_ID_LEN))
606 infof(data,
"ALPN, unrecognized protocol %.*s\n", protocol_len,
609 else if(rc == SSL_ALPN_NOT_FOUND)
610 infof(data,
"ALPN, server did not agree to a protocol\n");
612 failf(data,
"ALPN, failure getting protocol, error %d", rc);
619 #if (LIBCYASSL_VERSION_HEX >= 0x03009010) 620 infof(data,
"SSL connection using %s / %s\n",
621 wolfSSL_get_version(BACKEND->handle),
622 wolfSSL_get_cipher_name(BACKEND->handle));
624 infof(data,
"SSL connected\n");
643 SSL_SESSION *our_ssl_sessionid;
644 void *old_ssl_sessionid = NULL;
648 Curl_ssl_sessionid_lock(conn);
649 incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
652 if(old_ssl_sessionid != our_ssl_sessionid) {
653 infof(data,
"old SSL session ID is stale, removing\n");
654 Curl_ssl_delsessionid(conn, old_ssl_sessionid);
660 result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
663 Curl_ssl_sessionid_unlock(conn);
664 failf(data,
"failed to store ssl session");
668 Curl_ssl_sessionid_unlock(conn);
684 char error_buffer[CYASSL_MAX_ERROR_SZ];
685 int memlen = (len > (
size_t)INT_MAX) ? INT_MAX : (int)len;
686 int rc =
SSL_write(BACKEND->handle, mem, memlen);
692 case SSL_ERROR_WANT_READ:
693 case SSL_ERROR_WANT_WRITE:
698 failf(conn->
data,
"SSL write: %s, errno %d",
708 static void Curl_cyassl_close(
struct connectdata *conn,
int sockindex)
712 if(BACKEND->handle) {
715 BACKEND->handle = NULL;
730 char error_buffer[CYASSL_MAX_ERROR_SZ];
731 int buffsize = (buffersize > (
size_t)INT_MAX) ? INT_MAX : (int)buffersize;
732 int nread =
SSL_read(BACKEND->handle, buf, buffsize);
738 case SSL_ERROR_ZERO_RETURN:
740 case SSL_ERROR_WANT_READ:
741 case SSL_ERROR_WANT_WRITE:
746 failf(conn->
data,
"SSL read: %s, errno %d",
757 static void Curl_cyassl_session_free(
void *
ptr)
764 static size_t Curl_cyassl_version(
char *
buffer,
size_t size)
766 #if LIBCYASSL_VERSION_HEX >= 0x03006000 767 return snprintf(buffer, size,
"wolfSSL/%s", wolfSSL_lib_version());
768 #elif defined(WOLFSSL_VERSION) 769 return snprintf(buffer, size,
"wolfSSL/%s", WOLFSSL_VERSION);
770 #elif defined(CYASSL_VERSION) 771 return snprintf(buffer, size,
"CyaSSL/%s", CYASSL_VERSION);
773 return snprintf(buffer, size,
"CyaSSL/%s",
"<1.8.8");
778 static int Curl_cyassl_init(
void)
780 return (CyaSSL_Init() == SSL_SUCCESS);
784 static bool Curl_cyassl_data_pending(
const struct connectdata* conn,
799 static int Curl_cyassl_shutdown(
struct connectdata *conn,
int sockindex)
804 if(BACKEND->handle) {
806 BACKEND->handle = NULL;
837 failf(data,
"SSL connection timeout");
841 result = cyassl_connect_step1(conn, sockindex);
855 failf(data,
"SSL connection timeout");
869 nonblocking?0:timeout_ms);
882 failf(data,
"SSL connection timeout");
896 result = cyassl_connect_step2(conn, sockindex);
897 if(result || (nonblocking &&
905 result = cyassl_connect_step3(conn, sockindex);
912 conn->
recv[sockindex] = cyassl_recv;
913 conn->
send[sockindex] = cyassl_send;
927 int sockindex,
bool *done)
929 return cyassl_connect_common(conn, sockindex,
TRUE, done);
938 result = cyassl_connect_common(conn, sockindex,
FALSE, &done);
948 unsigned char *entropy,
size_t length)
954 if(length > UINT_MAX)
956 if(RNG_GenerateBlock(&rng, entropy, (
unsigned)length))
961 static void Curl_cyassl_sha256sum(
const unsigned char *tmp,
963 unsigned char *sha256sum ,
968 InitSha256(&SHA256pw);
969 Sha256Update(&SHA256pw, tmp, (word32)tmplen);
970 Sha256Final(&SHA256pw, sha256sum);
977 return BACKEND->handle;
980 const struct Curl_ssl Curl_ssl_cyassl = {
985 #ifdef KEEP_PEER_CERT 993 sizeof(
struct ssl_backend_data),
999 Curl_cyassl_shutdown,
1000 Curl_cyassl_data_pending,
1003 Curl_cyassl_connect,
1004 Curl_cyassl_connect_nonblocking,
1005 Curl_cyassl_get_internals,
1008 Curl_cyassl_session_free,
1014 Curl_cyassl_sha256sum
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
static const struct Curl_handler *const protocols[]
#define SSL_CTX_use_PrivateKey_file
#define SSL_CTX_set_cipher_list
#define SSL_get_peer_certificate
#define strcasecompare(a, b)
#define SSL_CTX_load_verify_locations
UNITTEST_START int result
struct ssl_config_data ssl
struct proxy_info http_proxy
ssl_connection_state state
#define SSL_CTX_use_certificate_file
int Curl_none_check_cxn(struct connectdata *conn)
#define ALPN_HTTP_1_1_LENGTH
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
curl_easy_setopt expects a curl_off_t argument for this option curl_easy_setopt expects a curl_write_callback argument for this option curl_easy_setopt expects a curl_ioctl_callback argument for this option curl_easy_setopt expects a curl_opensocket_callback argument for this option curl_easy_setopt expects a curl_debug_callback argument for this option curl_easy_setopt expects a curl_conv_callback argument for this option curl_easy_setopt expects a private data pointer as argument for this option curl_easy_setopt expects a FILE *argument for this option curl_easy_setopt expects a struct curl_httppost *argument for this option curl_easy_setopt expects a struct curl_slist *argument for this option curl_easy_getinfo expects a pointer to char *for this info curl_easy_getinfo expects a pointer to double for this info curl_easy_getinfo expects a pointer to struct curl_tlssessioninfo *for this info curl_easy_getinfo expects a pointer to curl_socket_t for this info size_t
bool Curl_none_false_start(void)
bool Curl_none_cert_status_request(void)
#define TLSv1_client_method
void Curl_none_cleanup(void)
#define SSL_CTX_set_verify
curl_ssl_ctx_callback fsslctx
ssize_t( Curl_send)(struct connectdata *conn, int sockindex, const void *buf, size_t len, CURLcode *err)
int Curl_inet_pton(int af, const char *src, void *dst)
CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, unsigned char *md5sum, size_t md5len)
int Curl_socket_check(curl_socket_t readfd0, curl_socket_t readfd1, curl_socket_t writefd, time_t timeout_ms)
CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine)
struct curl_slist * Curl_none_engines_list(struct Curl_easy *data)
#define CURL_HTTP_VERSION_2
#define SSLv23_client_method
CURLcode Curl_none_set_engine_default(struct Curl_easy *data)
void Curl_none_close_all(struct Curl_easy *data)
#define SSLv3_client_method