1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
24 * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code
25 * but sslgen.c should ever call or use these functions.
29 * The original SSLeay-using code for curl was written by Linas Vepstas and
30 * Sampo Kellomaki 1998.
33 #include "curl_setup.h"
41 #include "formdata.h" /* for the boundary function */
42 #include "url.h" /* for the ssl config check function */
43 #include "inet_pton.h"
51 #include "hostcheck.h"
53 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
54 #include <curl/mprintf.h>
59 #include <openssl/rand.h>
60 #include <openssl/x509v3.h>
61 #include <openssl/dsa.h>
62 #include <openssl/dh.h>
63 #include <openssl/err.h>
64 #include <openssl/md5.h>
72 #include "curl_memory.h"
73 #include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */
75 /* The last #include file should be: */
78 #ifndef OPENSSL_VERSION_NUMBER
79 #error "OPENSSL_VERSION_NUMBER not defined"
82 #if OPENSSL_VERSION_NUMBER >= 0x0090581fL
83 #define HAVE_SSL_GET1_SESSION 1
85 #undef HAVE_SSL_GET1_SESSION
88 #if OPENSSL_VERSION_NUMBER >= 0x00904100L
89 #define HAVE_USERDATA_IN_PWD_CALLBACK 1
91 #undef HAVE_USERDATA_IN_PWD_CALLBACK
94 #if OPENSSL_VERSION_NUMBER >= 0x00907001L
95 /* ENGINE_load_private_key() takes four arguments */
96 #define HAVE_ENGINE_LOAD_FOUR_ARGS
97 #include <openssl/ui.h>
99 /* ENGINE_load_private_key() takes three arguments */
100 #undef HAVE_ENGINE_LOAD_FOUR_ARGS
103 #if (OPENSSL_VERSION_NUMBER >= 0x00903001L) && defined(HAVE_OPENSSL_PKCS12_H)
104 /* OpenSSL has PKCS 12 support */
105 #define HAVE_PKCS12_SUPPORT
107 /* OpenSSL/SSLEay does not have PKCS12 support */
108 #undef HAVE_PKCS12_SUPPORT
111 #if OPENSSL_VERSION_NUMBER >= 0x00906001L
112 #define HAVE_ERR_ERROR_STRING_N 1
115 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
116 #define SSL_METHOD_QUAL const
118 #define SSL_METHOD_QUAL
121 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
122 /* 0.9.6 didn't have X509_STORE_set_flags() */
123 #define HAVE_X509_STORE_SET_FLAGS 1
125 #define X509_STORE_set_flags(x,y) Curl_nop_stmt
128 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
129 #define HAVE_ERR_REMOVE_THREAD_STATE 1
132 #ifndef HAVE_SSLV2_CLIENT_METHOD
133 #undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */
134 #define OPENSSL_NO_SSL2
138 * Number of bytes to read from the random number seed file. This must be
139 * a finite value (because some entropy "files" like /dev/urandom have
140 * an infinite length), but must be large enough to provide enough
141 * entopy to properly seed OpenSSL's PRNG.
143 #define RAND_LOAD_LENGTH 1024
145 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
146 static char global_passwd[64];
149 static int passwd_callback(char *buf, int num, int encrypting
150 #ifdef HAVE_USERDATA_IN_PWD_CALLBACK
151 /* This was introduced in 0.9.4, we can set this
152 using SSL_CTX_set_default_passwd_cb_userdata()
154 , void *global_passwd
158 DEBUGASSERT(0 == encrypting);
161 int klen = curlx_uztosi(strlen((char *)global_passwd));
163 memcpy(buf, global_passwd, klen+1);
171 * rand_enough() is a function that returns TRUE if we have seeded the random
172 * engine properly. We use some preprocessor magic to provide a seed_enough()
173 * macro to use, just to prevent a compiler warning on this function if we
174 * pass in an argument that is never used.
177 #ifdef HAVE_RAND_STATUS
178 #define seed_enough(x) rand_enough()
179 static bool rand_enough(void)
181 return (0 != RAND_status()) ? TRUE : FALSE;
184 #define seed_enough(x) rand_enough(x)
185 static bool rand_enough(int nread)
187 /* this is a very silly decision to make */
188 return (nread > 500) ? TRUE : FALSE;
192 static int ossl_seed(struct SessionHandle *data)
194 char *buf = data->state.buffer; /* point to the big buffer */
197 /* Q: should we add support for a random file name as a libcurl option?
198 A: Yes, it is here */
201 /* if RANDOM_FILE isn't defined, we only perform this if an option tells
203 if(data->set.ssl.random_file)
204 #define RANDOM_FILE "" /* doesn't matter won't be used */
207 /* let the option override the define */
208 nread += RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
209 data->set.str[STRING_SSL_RANDOM_FILE]:
212 if(seed_enough(nread))
216 #if defined(HAVE_RAND_EGD)
217 /* only available in OpenSSL 0.9.5 and later */
218 /* EGD_SOCKET is set at configure time or not at all */
220 /* If we don't have the define set, we only do this if the egd-option
222 if(data->set.str[STRING_SSL_EGDSOCKET])
223 #define EGD_SOCKET "" /* doesn't matter won't be used */
226 /* If there's an option and a define, the option overrides the
228 int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
229 data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
232 if(seed_enough(nread))
238 /* If we get here, it means we need to seed the PRNG using a "silly"
241 unsigned char randb[64];
242 int len = sizeof(randb);
243 RAND_bytes(randb, len);
244 RAND_add(randb, len, (len >> 1));
245 } while(!RAND_status());
247 /* generates a default path for the random seed file */
248 buf[0]=0; /* blank it first */
249 RAND_file_name(buf, BUFSIZE);
251 /* we got a file name to try */
252 nread += RAND_load_file(buf, RAND_LOAD_LENGTH);
253 if(seed_enough(nread))
257 infof(data, "libcurl is now using a weak random seed!\n");
261 int Curl_ossl_seed(struct SessionHandle *data)
263 /* we have the "SSL is seeded" boolean static to prevent multiple
264 time-consuming seedings in vain */
265 static bool ssl_seeded = FALSE;
267 if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
268 data->set.str[STRING_SSL_EGDSOCKET]) {
276 #ifndef SSL_FILETYPE_ENGINE
277 #define SSL_FILETYPE_ENGINE 42
279 #ifndef SSL_FILETYPE_PKCS12
280 #define SSL_FILETYPE_PKCS12 43
282 static int do_file_type(const char *type)
284 if(!type || !type[0])
285 return SSL_FILETYPE_PEM;
286 if(Curl_raw_equal(type, "PEM"))
287 return SSL_FILETYPE_PEM;
288 if(Curl_raw_equal(type, "DER"))
289 return SSL_FILETYPE_ASN1;
290 if(Curl_raw_equal(type, "ENG"))
291 return SSL_FILETYPE_ENGINE;
292 if(Curl_raw_equal(type, "P12"))
293 return SSL_FILETYPE_PKCS12;
298 int cert_stuff(struct connectdata *conn,
301 const char *cert_type,
303 const char *key_type)
305 struct SessionHandle *data = conn->data;
307 int file_type = do_file_type(cert_type);
309 if(cert_file != NULL || file_type == SSL_FILETYPE_ENGINE) {
314 if(data->set.str[STRING_KEY_PASSWD]) {
315 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
317 * If password has been given, we store that in the global
318 * area (*shudder*) for a while:
320 size_t len = strlen(data->set.str[STRING_KEY_PASSWD]);
321 if(len < sizeof(global_passwd))
322 memcpy(global_passwd, data->set.str[STRING_KEY_PASSWD], len+1);
324 global_passwd[0] = '\0';
327 * We set the password in the callback userdata
329 SSL_CTX_set_default_passwd_cb_userdata(ctx,
330 data->set.str[STRING_KEY_PASSWD]);
332 /* Set passwd callback: */
333 SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
337 #define SSL_CLIENT_CERT_ERR \
338 "unable to use client certificate (no key found or wrong pass phrase?)"
341 case SSL_FILETYPE_PEM:
342 /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
343 if(SSL_CTX_use_certificate_chain_file(ctx,
345 failf(data, SSL_CLIENT_CERT_ERR);
350 case SSL_FILETYPE_ASN1:
351 /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
352 we use the case above for PEM so this can only be performed with
354 if(SSL_CTX_use_certificate_file(ctx,
357 failf(data, SSL_CLIENT_CERT_ERR);
361 case SSL_FILETYPE_ENGINE:
362 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
364 if(data->state.engine) {
365 const char *cmd_name = "LOAD_CERT_CTRL";
371 params.cert_id = cert_file;
374 /* Does the engine supports LOAD_CERT_CTRL ? */
375 if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
376 0, (void *)cmd_name, NULL)) {
377 failf(data, "ssl engine does not support loading certificates");
381 /* Load the certificate from the engine */
382 if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name,
383 0, ¶ms, NULL, 1)) {
384 failf(data, "ssl engine cannot load client cert with id"
385 " '%s' [%s]", cert_file,
386 ERR_error_string(ERR_get_error(), NULL));
391 failf(data, "ssl engine didn't initialized the certificate "
396 if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
397 failf(data, "unable to set client certificate");
398 X509_free(params.cert);
401 X509_free(params.cert); /* we don't need the handle any more... */
404 failf(data, "crypto engine not set, can't load certificate");
410 failf(data, "file type ENG for certificate not implemented");
414 case SSL_FILETYPE_PKCS12:
416 #ifdef HAVE_PKCS12_SUPPORT
420 STACK_OF(X509) *ca = NULL;
423 f = fopen(cert_file,"rb");
425 failf(data, "could not open PKCS12 file '%s'", cert_file);
428 p12 = d2i_PKCS12_fp(f, NULL);
432 failf(data, "error reading PKCS12 file '%s'", cert_file );
438 if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509,
441 "could not parse PKCS12 file, check password, OpenSSL error %s",
442 ERR_error_string(ERR_get_error(), NULL) );
449 if(SSL_CTX_use_certificate(ctx, x509) != 1) {
450 failf(data, SSL_CLIENT_CERT_ERR);
454 if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
455 failf(data, "unable to use private key from PKCS12 file '%s'",
460 if(!SSL_CTX_check_private_key (ctx)) {
461 failf(data, "private key from PKCS12 file '%s' "
462 "does not match certificate in same file", cert_file);
465 /* Set Certificate Verification chain */
466 if(ca && sk_X509_num(ca)) {
467 for(i = 0; i < sk_X509_num(ca); i++) {
469 * Note that sk_X509_pop() is used below to make sure the cert is
470 * removed from the stack properly before getting passed to
471 * SSL_CTX_add_extra_chain_cert(). Previously we used
472 * sk_X509_value() instead, but then we'd clean it in the subsequent
473 * sk_X509_pop_free() call.
475 X509 *x = sk_X509_pop(ca);
476 if(!SSL_CTX_add_extra_chain_cert(ctx, x)) {
477 failf(data, "cannot add certificate to certificate chain");
480 /* SSL_CTX_add_client_CA() seems to work with either sk_* function,
481 * presumably because it duplicates what we pass to it.
483 if(!SSL_CTX_add_client_CA(ctx, x)) {
484 failf(data, "cannot add certificate to client CA list");
494 sk_X509_pop_free(ca, X509_free);
497 return 0; /* failure! */
499 failf(data, "file type P12 for certificate not supported");
504 failf(data, "not supported file type '%s' for certificate", cert_type);
508 file_type = do_file_type(key_type);
511 case SSL_FILETYPE_PEM:
515 /* cert & key can only be in PEM case in the same file */
517 case SSL_FILETYPE_ASN1:
518 if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
519 failf(data, "unable to set private key file: '%s' type %s",
520 key_file, key_type?key_type:"PEM");
524 case SSL_FILETYPE_ENGINE:
525 #ifdef HAVE_OPENSSL_ENGINE_H
526 { /* XXXX still needs some work */
527 EVP_PKEY *priv_key = NULL;
528 if(data->state.engine) {
529 #ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
530 UI_METHOD *ui_method = UI_OpenSSL();
532 /* the typecast below was added to please mingw32 */
533 priv_key = (EVP_PKEY *)
534 ENGINE_load_private_key(data->state.engine,key_file,
535 #ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
538 data->set.str[STRING_KEY_PASSWD]);
540 failf(data, "failed to load private key from crypto engine");
543 if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
544 failf(data, "unable to set private key");
545 EVP_PKEY_free(priv_key);
548 EVP_PKEY_free(priv_key); /* we don't need the handle any more... */
551 failf(data, "crypto engine not set, can't load private key");
557 failf(data, "file type ENG for private key not supported");
560 case SSL_FILETYPE_PKCS12:
562 failf(data, "file type P12 for private key not supported");
567 failf(data, "not supported file type for private key");
573 failf(data,"unable to create an SSL structure");
577 x509=SSL_get_certificate(ssl);
579 /* This version was provided by Evan Jordan and is supposed to not
580 leak memory as the previous version: */
582 EVP_PKEY *pktmp = X509_get_pubkey(x509);
583 EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));
584 EVP_PKEY_free(pktmp);
589 /* If we are using DSA, we can copy the parameters from
593 /* Now we know that a key and cert have been set against
595 if(!SSL_CTX_check_private_key(ctx)) {
596 failf(data, "Private key does not match the certificate public key");
599 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
601 memset(global_passwd, 0, sizeof(global_passwd));
607 /* returns non-zero on failure */
608 static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
611 return X509_NAME_oneline(a, buf, size);
613 BIO *bio_out = BIO_new(BIO_s_mem());
618 return 1; /* alloc failed! */
620 rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC);
621 BIO_get_mem_ptr(bio_out, &biomem);
623 if((size_t)biomem->length < size)
624 size = biomem->length;
626 size--; /* don't overwrite the buffer end */
628 memcpy(buf, biomem->data, size);
638 int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
643 err_cert=X509_STORE_CTX_get_current_cert(ctx);
644 (void)x509_name_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
648 /* Return error string for last OpenSSL error
650 static char *SSL_strerror(unsigned long error, char *buf, size_t size)
652 #ifdef HAVE_ERR_ERROR_STRING_N
653 /* OpenSSL 0.9.6 and later has a function named
654 ERRO_error_string_n() that takes the size of the buffer as a
656 ERR_error_string_n(error, buf, size);
659 ERR_error_string(error, buf);
664 #endif /* USE_SSLEAY */
670 * @retval 0 error initializing SSL
671 * @retval 1 SSL initialized successfully
673 int Curl_ossl_init(void)
675 #ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
676 ENGINE_load_builtin_engines();
679 /* Lets get nice error messages */
680 SSL_load_error_strings();
682 /* Init the global ciphers and digests */
683 if(!SSLeay_add_ssl_algorithms())
686 OpenSSL_add_all_algorithms();
691 #endif /* USE_SSLEAY */
696 void Curl_ossl_cleanup(void)
698 /* Free ciphers and digests lists */
701 #ifdef HAVE_ENGINE_CLEANUP
702 /* Free engine list */
706 #ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
707 /* Free OpenSSL ex_data table */
708 CRYPTO_cleanup_all_ex_data();
711 /* Free OpenSSL error strings */
714 /* Free thread local error state, destroying hash upon zero refcount */
715 #ifdef HAVE_ERR_REMOVE_THREAD_STATE
716 ERR_remove_thread_state(NULL);
723 * This function uses SSL_peek to determine connection status.
726 * 1 means the connection is still in place
727 * 0 means the connection has been closed
728 * -1 means the connection status is unknown
730 int Curl_ossl_check_cxn(struct connectdata *conn)
735 rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1);
737 return 1; /* connection still in place */
740 return 0; /* connection has been closed */
742 return -1; /* connection status unknown */
745 /* Selects an OpenSSL crypto engine
747 CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
749 #if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
752 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
753 e = ENGINE_by_id(engine);
755 /* avoid memory leak */
756 for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
757 const char *e_id = ENGINE_get_id(e);
758 if(!strcmp(engine, e_id))
764 failf(data, "SSL Engine '%s' not found", engine);
765 return CURLE_SSL_ENGINE_NOTFOUND;
768 if(data->state.engine) {
769 ENGINE_finish(data->state.engine);
770 ENGINE_free(data->state.engine);
771 data->state.engine = NULL;
773 if(!ENGINE_init(e)) {
777 failf(data, "Failed to initialise SSL Engine '%s':\n%s",
778 engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf)));
779 return CURLE_SSL_ENGINE_INITFAILED;
781 data->state.engine = e;
785 failf(data, "SSL Engine not supported");
786 return CURLE_SSL_ENGINE_NOTFOUND;
790 /* Sets engine as default for all SSL operations
792 CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
794 #ifdef HAVE_OPENSSL_ENGINE_H
795 if(data->state.engine) {
796 if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
797 infof(data,"set default crypto engine '%s'\n",
798 ENGINE_get_id(data->state.engine));
801 failf(data, "set default crypto engine '%s' failed",
802 ENGINE_get_id(data->state.engine));
803 return CURLE_SSL_ENGINE_SETFAILED;
812 /* Return list of OpenSSL crypto engine names.
814 struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
816 struct curl_slist *list = NULL;
817 #if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
818 struct curl_slist *beg;
821 for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
822 beg = curl_slist_append(list, ENGINE_get_id(e));
824 curl_slist_free_all(list);
836 * This function is called when an SSL connection is closed.
838 void Curl_ossl_close(struct connectdata *conn, int sockindex)
840 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
842 if(connssl->handle) {
843 (void)SSL_shutdown(connssl->handle);
844 SSL_set_connect_state(connssl->handle);
846 SSL_free (connssl->handle);
847 connssl->handle = NULL;
850 SSL_CTX_free (connssl->ctx);
856 * This function is called to shut down the SSL layer but keep the
857 * socket open (CCC - Clear Command Channel)
859 int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
862 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
863 struct SessionHandle *data = conn->data;
864 char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
865 to be at least 120 bytes long. */
866 unsigned long sslerror;
872 /* This has only been tested on the proftpd server, and the mod_tls code
873 sends a close notify alert without waiting for a close notify alert in
874 response. Thus we wait for a close notify alert from the server, but
875 we do not send one. Let's hope other servers do the same... */
877 if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
878 (void)SSL_shutdown(connssl->handle);
880 if(connssl->handle) {
881 buffsize = (int)sizeof(buf);
883 int what = Curl_socket_ready(conn->sock[sockindex],
884 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
888 /* Something to read, let's do it and hope that it is the close
889 notify alert from the server */
890 nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
892 err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
895 case SSL_ERROR_NONE: /* this is not an error */
896 case SSL_ERROR_ZERO_RETURN: /* no more data */
897 /* This is the expected response. There was no data but only
898 the close notify alert */
901 case SSL_ERROR_WANT_READ:
902 /* there's data pending, re-invoke SSL_read() */
903 infof(data, "SSL_ERROR_WANT_READ\n");
905 case SSL_ERROR_WANT_WRITE:
906 /* SSL wants a write. Really odd. Let's bail out. */
907 infof(data, "SSL_ERROR_WANT_WRITE\n");
911 /* openssl/ssl.h says "look at error stack/return value/errno" */
912 sslerror = ERR_get_error();
913 failf(conn->data, "SSL read: %s, errno %d",
914 ERR_error_string(sslerror, buf),
922 failf(data, "SSL shutdown timeout");
926 /* anything that gets here is fatally bad */
927 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
931 } /* while()-loop for the select() */
933 if(data->set.verbose) {
934 #ifdef HAVE_SSL_GET_SHUTDOWN
935 switch(SSL_get_shutdown(connssl->handle)) {
936 case SSL_SENT_SHUTDOWN:
937 infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
939 case SSL_RECEIVED_SHUTDOWN:
940 infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
942 case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
943 infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
944 "SSL_RECEIVED__SHUTDOWN\n");
950 SSL_free (connssl->handle);
951 connssl->handle = NULL;
956 void Curl_ossl_session_free(void *ptr)
959 SSL_SESSION_free(ptr);
963 * This function is called when the 'data' struct is going away. Close
964 * down everything and free all resources!
966 int Curl_ossl_close_all(struct SessionHandle *data)
968 #ifdef HAVE_OPENSSL_ENGINE_H
969 if(data->state.engine) {
970 ENGINE_finish(data->state.engine);
971 ENGINE_free(data->state.engine);
972 data->state.engine = NULL;
980 static int asn1_output(const ASN1_UTCTIME *tm,
984 const char *asn1_string;
987 int year=0,month=0,day=0,hour=0,minute=0,second=0;
990 asn1_string=(const char *)tm->data;
994 if(asn1_string[i-1] == 'Z')
997 if((asn1_string[i] > '9') || (asn1_string[i] < '0'))
1000 year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0');
1004 month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0');
1005 if((month > 12) || (month < 1))
1008 day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0');
1009 hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0');
1010 minute= (asn1_string[8]-'0')*10+(asn1_string[9]-'0');
1012 if((asn1_string[10] >= '0') && (asn1_string[10] <= '9') &&
1013 (asn1_string[11] >= '0') && (asn1_string[11] <= '9'))
1014 second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0');
1016 snprintf(buf, sizeofbuf,
1017 "%04d-%02d-%02d %02d:%02d:%02d %s",
1018 year+1900, month, day, hour, minute, second, (gmt?"GMT":""));
1023 /* ====================================================== */
1026 /* Quote from RFC2818 section 3.1 "Server Identity"
1028 If a subjectAltName extension of type dNSName is present, that MUST
1029 be used as the identity. Otherwise, the (most specific) Common Name
1030 field in the Subject field of the certificate MUST be used. Although
1031 the use of the Common Name is existing practice, it is deprecated and
1032 Certification Authorities are encouraged to use the dNSName instead.
1034 Matching is performed using the matching rules specified by
1035 [RFC2459]. If more than one identity of a given type is present in
1036 the certificate (e.g., more than one dNSName name, a match in any one
1037 of the set is considered acceptable.) Names may contain the wildcard
1038 character * which is considered to match any single domain name
1039 component or component fragment. E.g., *.a.com matches foo.a.com but
1040 not bar.foo.a.com. f*.com matches foo.com but not bar.com.
1042 In some cases, the URI is specified as an IP address rather than a
1043 hostname. In this case, the iPAddress subjectAltName must be present
1044 in the certificate and must exactly match the IP in the URI.
1047 static CURLcode verifyhost(struct connectdata *conn,
1050 int matched = -1; /* -1 is no alternative match yet, 1 means match and 0
1052 int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
1054 struct SessionHandle *data = conn->data;
1055 STACK_OF(GENERAL_NAME) *altnames;
1057 struct in6_addr addr;
1059 struct in_addr addr;
1061 CURLcode res = CURLE_OK;
1064 if(conn->bits.ipv6_ip &&
1065 Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
1067 addrlen = sizeof(struct in6_addr);
1071 if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
1073 addrlen = sizeof(struct in_addr);
1076 /* get a "list" of alternative names */
1077 altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
1083 /* get amount of alternatives, RFC2459 claims there MUST be at least
1084 one, but we don't depend on it... */
1085 numalts = sk_GENERAL_NAME_num(altnames);
1087 /* loop through all alternatives while none has matched */
1088 for(i=0; (i<numalts) && (matched != 1); i++) {
1089 /* get a handle to alternative name number i */
1090 const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
1092 /* only check alternatives of the same type the target is */
1093 if(check->type == target) {
1094 /* get data and length */
1095 const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
1096 size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
1099 case GEN_DNS: /* name/pattern comparison */
1100 /* The OpenSSL man page explicitly says: "In general it cannot be
1101 assumed that the data returned by ASN1_STRING_data() is null
1102 terminated or does not contain embedded nulls." But also that
1103 "The actual format of the data will depend on the actual string
1104 type itself: for example for and IA5String the data will be ASCII"
1106 Gisle researched the OpenSSL sources:
1107 "I checked the 0.9.6 and 0.9.8 sources before my patch and
1108 it always 0-terminates an IA5String."
1110 if((altlen == strlen(altptr)) &&
1111 /* if this isn't true, there was an embedded zero in the name
1112 string and we cannot match it. */
1113 Curl_cert_hostcheck(altptr, conn->host.name))
1119 case GEN_IPADD: /* IP address comparison */
1120 /* compare alternative IP address if the data chunk is the same size
1121 our server IP address is */
1122 if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
1130 GENERAL_NAMES_free(altnames);
1134 /* an alternative name matched the server hostname */
1135 infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
1136 else if(matched == 0) {
1137 /* an alternative name field existed, but didn't match and then
1139 infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
1140 res = CURLE_PEER_FAILED_VERIFICATION;
1143 /* we have to look to the last occurrence of a commonName in the
1144 distinguished one to get the most significant one. */
1147 /* The following is done because of a bug in 0.9.6b */
1149 unsigned char *nulstr = (unsigned char *)"";
1150 unsigned char *peer_CN = nulstr;
1152 X509_NAME *name = X509_get_subject_name(server_cert) ;
1154 while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i))>=0)
1157 /* we have the name entry and we will now convert this to a string
1158 that we can use for comparison. Doing this we support BMPstring,
1162 ASN1_STRING *tmp = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
1164 /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
1165 is already UTF-8 encoded. We check for this case and copy the raw
1166 string manually to avoid the problem. This code can be made
1167 conditional in the future when OpenSSL has been fixed. Work-around
1168 brought by Alexis S. L. Carvalho. */
1170 if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
1171 j = ASN1_STRING_length(tmp);
1173 peer_CN = OPENSSL_malloc(j+1);
1175 memcpy(peer_CN, ASN1_STRING_data(tmp), j);
1180 else /* not a UTF8 name */
1181 j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
1183 if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != j)) {
1184 /* there was a terminating zero before the end of string, this
1185 cannot match and we return failure! */
1186 failf(data, "SSL: illegal cert name field");
1187 res = CURLE_PEER_FAILED_VERIFICATION;
1192 if(peer_CN == nulstr)
1195 /* convert peer_CN from UTF8 */
1196 CURLcode rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
1197 /* Curl_convert_from_utf8 calls failf if unsuccessful */
1199 OPENSSL_free(peer_CN);
1205 /* error already detected, pass through */
1209 "SSL: unable to obtain common name from peer certificate");
1210 res = CURLE_PEER_FAILED_VERIFICATION;
1212 else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
1213 failf(data, "SSL: certificate subject name '%s' does not match "
1214 "target host name '%s'", peer_CN, conn->host.dispname);
1215 res = CURLE_PEER_FAILED_VERIFICATION;
1218 infof(data, "\t common name: %s (matched)\n", peer_CN);
1221 OPENSSL_free(peer_CN);
1225 #endif /* USE_SSLEAY */
1227 /* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
1228 and thus this cannot be done there. */
1229 #ifdef SSL_CTRL_SET_MSG_CALLBACK
1231 static const char *ssl_msg_type(int ssl_ver, int msg)
1233 if(ssl_ver == SSL2_VERSION_MAJOR) {
1237 case SSL2_MT_CLIENT_HELLO:
1238 return "Client hello";
1239 case SSL2_MT_CLIENT_MASTER_KEY:
1240 return "Client key";
1241 case SSL2_MT_CLIENT_FINISHED:
1242 return "Client finished";
1243 case SSL2_MT_SERVER_HELLO:
1244 return "Server hello";
1245 case SSL2_MT_SERVER_VERIFY:
1246 return "Server verify";
1247 case SSL2_MT_SERVER_FINISHED:
1248 return "Server finished";
1249 case SSL2_MT_REQUEST_CERTIFICATE:
1250 return "Request CERT";
1251 case SSL2_MT_CLIENT_CERTIFICATE:
1252 return "Client CERT";
1255 else if(ssl_ver == SSL3_VERSION_MAJOR) {
1257 case SSL3_MT_HELLO_REQUEST:
1258 return "Hello request";
1259 case SSL3_MT_CLIENT_HELLO:
1260 return "Client hello";
1261 case SSL3_MT_SERVER_HELLO:
1262 return "Server hello";
1263 case SSL3_MT_CERTIFICATE:
1265 case SSL3_MT_SERVER_KEY_EXCHANGE:
1266 return "Server key exchange";
1267 case SSL3_MT_CLIENT_KEY_EXCHANGE:
1268 return "Client key exchange";
1269 case SSL3_MT_CERTIFICATE_REQUEST:
1270 return "Request CERT";
1271 case SSL3_MT_SERVER_DONE:
1272 return "Server finished";
1273 case SSL3_MT_CERTIFICATE_VERIFY:
1274 return "CERT verify";
1275 case SSL3_MT_FINISHED:
1282 static const char *tls_rt_type(int type)
1285 type == SSL3_RT_CHANGE_CIPHER_SPEC ? "TLS change cipher, " :
1286 type == SSL3_RT_ALERT ? "TLS alert, " :
1287 type == SSL3_RT_HANDSHAKE ? "TLS handshake, " :
1288 type == SSL3_RT_APPLICATION_DATA ? "TLS app data, " :
1294 * Our callback from the SSL/TLS layers.
1296 static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
1297 const void *buf, size_t len, const SSL *ssl,
1298 struct connectdata *conn)
1300 struct SessionHandle *data;
1301 const char *msg_name, *tls_rt_name;
1303 int ver, msg_type, txt_len;
1305 if(!conn || !conn->data || !conn->data->set.fdebug ||
1306 (direction != 0 && direction != 1))
1311 ver = (ssl_ver == SSL2_VERSION_MAJOR ? '2' :
1312 ssl_ver == SSL3_VERSION_MAJOR ? '3' : '?');
1314 /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
1315 * always pass-up content-type as 0. But the interesting message-type
1318 if(ssl_ver == SSL3_VERSION_MAJOR && content_type != 0)
1319 tls_rt_name = tls_rt_type(content_type);
1323 msg_type = *(char*)buf;
1324 msg_name = ssl_msg_type(ssl_ver, msg_type);
1326 txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n",
1327 ver, tls_rt_name, msg_name, msg_type);
1328 Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
1330 Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
1331 CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
1337 /* ====================================================== */
1339 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1340 # define use_sni(x) sni = (x)
1342 # define use_sni(x) Curl_nop_stmt
1346 ossl_connect_step1(struct connectdata *conn,
1349 CURLcode retcode = CURLE_OK;
1351 struct SessionHandle *data = conn->data;
1352 SSL_METHOD_QUAL SSL_METHOD *req_method=NULL;
1353 void *ssl_sessionid=NULL;
1354 X509_LOOKUP *lookup=NULL;
1355 curl_socket_t sockfd = conn->sock[sockindex];
1356 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1358 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1361 struct in6_addr addr;
1363 struct in_addr addr;
1367 DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
1369 /* Make funny stuff to get random input */
1370 Curl_ossl_seed(data);
1372 /* check to see if we've been told to use an explicit SSL/TLS version */
1374 switch(data->set.ssl.version) {
1376 case CURL_SSLVERSION_DEFAULT:
1378 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
1379 infof(data, "Set version TLSv1 for SRP authorisation\n");
1380 req_method = TLSv1_client_method() ;
1384 /* we try to figure out version */
1385 req_method = SSLv23_client_method();
1388 case CURL_SSLVERSION_TLSv1:
1389 req_method = TLSv1_client_method();
1392 case CURL_SSLVERSION_SSLv2:
1393 #ifdef OPENSSL_NO_SSL2
1394 failf(data, "OpenSSL was built without SSLv2 support");
1395 return CURLE_NOT_BUILT_IN;
1398 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
1399 return CURLE_SSL_CONNECT_ERROR;
1401 req_method = SSLv2_client_method();
1405 case CURL_SSLVERSION_SSLv3:
1407 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
1408 return CURLE_SSL_CONNECT_ERROR;
1410 req_method = SSLv3_client_method();
1416 SSL_CTX_free(connssl->ctx);
1417 connssl->ctx = SSL_CTX_new(req_method);
1420 failf(data, "SSL: couldn't create a context: %s",
1421 ERR_error_string(ERR_peek_error(), NULL));
1422 return CURLE_OUT_OF_MEMORY;
1425 #ifdef SSL_MODE_RELEASE_BUFFERS
1426 SSL_CTX_set_mode(connssl->ctx, SSL_MODE_RELEASE_BUFFERS);
1429 #ifdef SSL_CTRL_SET_MSG_CALLBACK
1430 if(data->set.fdebug && data->set.verbose) {
1431 /* the SSL trace callback is only used for verbose logging so we only
1432 inform about failures of setting it */
1433 if(!SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
1434 (void (*)(void))ssl_tls_trace)) {
1435 infof(data, "SSL: couldn't set callback!\n");
1437 else if(!SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0,
1439 infof(data, "SSL: couldn't set callback argument!\n");
1444 /* OpenSSL contains code to work-around lots of bugs and flaws in various
1445 SSL-implementations. SSL_CTX_set_options() is used to enabled those
1446 work-arounds. The man page for this option states that SSL_OP_ALL enables
1447 all the work-arounds and that "It is usually safe to use SSL_OP_ALL to
1448 enable the bug workaround options if compatibility with somewhat broken
1449 implementations is desired."
1451 The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to
1452 disable "rfc4507bis session ticket support". rfc4507bis was later turned
1453 into the proper RFC5077 it seems: http://tools.ietf.org/html/rfc5077
1455 The enabled extension concerns the session management. I wonder how often
1456 libcurl stops a connection and then resumes a TLS session. also, sending
1457 the session data is some overhead. .I suggest that you just use your
1458 proposed patch (which explicitly disables TICKET).
1460 If someone writes an application with libcurl and openssl who wants to
1461 enable the feature, one can do this in the SSL callback.
1463 SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper
1464 interoperability with web server Netscape Enterprise Server 2.0.1 which
1465 was released back in 1996.
1467 Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has
1468 become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate
1469 CVE-2010-4180 when using previous OpenSSL versions we no longer enable
1470 this option regardless of OpenSSL version and SSL_OP_ALL definition.
1472 OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability
1473 (http://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to
1474 SSL_OP_ALL that _disables_ that work-around despite the fact that
1475 SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to
1476 keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit
1480 ctx_options = SSL_OP_ALL;
1482 #ifdef SSL_OP_NO_TICKET
1483 ctx_options |= SSL_OP_NO_TICKET;
1486 #ifdef SSL_OP_NO_COMPRESSION
1487 ctx_options |= SSL_OP_NO_COMPRESSION;
1490 #ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
1491 /* mitigate CVE-2010-4180 */
1492 ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
1495 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
1496 /* unless the user explicitly ask to allow the protocol vulnerability we
1497 use the work-around */
1498 if(!conn->data->set.ssl_enable_beast)
1499 ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
1502 /* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
1503 if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
1504 ctx_options |= SSL_OP_NO_SSLv2;
1506 SSL_CTX_set_options(connssl->ctx, ctx_options);
1508 if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) {
1509 if(!cert_stuff(conn,
1511 data->set.str[STRING_CERT],
1512 data->set.str[STRING_CERT_TYPE],
1513 data->set.str[STRING_KEY],
1514 data->set.str[STRING_KEY_TYPE])) {
1515 /* failf() is already done in cert_stuff() */
1516 return CURLE_SSL_CERTPROBLEM;
1520 if(data->set.str[STRING_SSL_CIPHER_LIST]) {
1521 if(!SSL_CTX_set_cipher_list(connssl->ctx,
1522 data->set.str[STRING_SSL_CIPHER_LIST])) {
1523 failf(data, "failed setting cipher list");
1524 return CURLE_SSL_CIPHER;
1529 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
1530 infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
1532 if(!SSL_CTX_set_srp_username(connssl->ctx, data->set.ssl.username)) {
1533 failf(data, "Unable to set SRP user name");
1534 return CURLE_BAD_FUNCTION_ARGUMENT;
1536 if(!SSL_CTX_set_srp_password(connssl->ctx,data->set.ssl.password)) {
1537 failf(data, "failed setting SRP password");
1538 return CURLE_BAD_FUNCTION_ARGUMENT;
1540 if(!data->set.str[STRING_SSL_CIPHER_LIST]) {
1541 infof(data, "Setting cipher list SRP\n");
1543 if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) {
1544 failf(data, "failed setting SRP cipher list");
1545 return CURLE_SSL_CIPHER;
1550 if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) {
1551 /* tell SSL where to find CA certificates that are used to verify
1552 the servers certificate. */
1553 if(!SSL_CTX_load_verify_locations(connssl->ctx,
1554 data->set.str[STRING_SSL_CAFILE],
1555 data->set.str[STRING_SSL_CAPATH])) {
1556 if(data->set.ssl.verifypeer) {
1557 /* Fail if we insist on successfully verifying the server. */
1558 failf(data,"error setting certificate verify locations:\n"
1559 " CAfile: %s\n CApath: %s",
1560 data->set.str[STRING_SSL_CAFILE]?
1561 data->set.str[STRING_SSL_CAFILE]: "none",
1562 data->set.str[STRING_SSL_CAPATH]?
1563 data->set.str[STRING_SSL_CAPATH] : "none");
1564 return CURLE_SSL_CACERT_BADFILE;
1567 /* Just continue with a warning if no strict certificate verification
1569 infof(data, "error setting certificate verify locations,"
1570 " continuing anyway:\n");
1574 /* Everything is fine. */
1575 infof(data, "successfully set certificate verify locations:\n");
1580 data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
1582 data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
1586 if(data->set.str[STRING_SSL_CRLFILE]) {
1587 /* tell SSL where to find CRL file that is used to check certificate
1589 lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx),
1590 X509_LOOKUP_file());
1592 (!X509_load_crl_file(lookup,data->set.str[STRING_SSL_CRLFILE],
1593 X509_FILETYPE_PEM)) ) {
1594 failf(data,"error loading CRL file: %s",
1595 data->set.str[STRING_SSL_CRLFILE]);
1596 return CURLE_SSL_CRL_BADFILE;
1599 /* Everything is fine. */
1600 infof(data, "successfully load CRL file:\n");
1601 X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
1602 X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1605 " CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
1606 data->set.str[STRING_SSL_CRLFILE]: "none");
1609 /* SSL always tries to verify the peer, this only says whether it should
1610 * fail to connect if the verification fails, or if it should continue
1611 * anyway. In the latter case the result of the verification is checked with
1612 * SSL_get_verify_result() below. */
1613 SSL_CTX_set_verify(connssl->ctx,
1614 data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
1615 cert_verify_callback);
1617 /* give application a chance to interfere with SSL set up. */
1618 if(data->set.ssl.fsslctx) {
1619 retcode = (*data->set.ssl.fsslctx)(data, connssl->ctx,
1620 data->set.ssl.fsslctxp);
1622 failf(data,"error signaled by ssl ctx callback");
1627 /* Lets make an SSL structure */
1629 SSL_free(connssl->handle);
1630 connssl->handle = SSL_new(connssl->ctx);
1631 if(!connssl->handle) {
1632 failf(data, "SSL: couldn't create a context (handle)!");
1633 return CURLE_OUT_OF_MEMORY;
1635 SSL_set_connect_state(connssl->handle);
1637 connssl->server_cert = 0x0;
1639 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1640 if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
1642 (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
1645 !SSL_set_tlsext_host_name(connssl->handle, conn->host.name))
1646 infof(data, "WARNING: failed to configure server name indication (SNI) "
1650 /* Check if there's a cached ID we can/should use here! */
1651 if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
1652 /* we got a session id, use it! */
1653 if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
1654 failf(data, "SSL: SSL_set_session failed: %s",
1655 ERR_error_string(ERR_get_error(),NULL));
1656 return CURLE_SSL_CONNECT_ERROR;
1658 /* Informational message */
1659 infof (data, "SSL re-using session ID\n");
1662 /* pass the raw socket into the SSL layers */
1663 if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
1664 failf(data, "SSL: SSL_set_fd failed: %s",
1665 ERR_error_string(ERR_get_error(),NULL));
1666 return CURLE_SSL_CONNECT_ERROR;
1669 connssl->connecting_state = ssl_connect_2;
1674 ossl_connect_step2(struct connectdata *conn, int sockindex)
1676 struct SessionHandle *data = conn->data;
1678 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1680 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1681 || ssl_connect_2_reading == connssl->connecting_state
1682 || ssl_connect_2_writing == connssl->connecting_state);
1686 err = SSL_connect(connssl->handle);
1689 0 is "not successful but was shut down controlled"
1690 <0 is "handshake was not successful, because a fatal error occurred" */
1692 int detail = SSL_get_error(connssl->handle, err);
1694 if(SSL_ERROR_WANT_READ == detail) {
1695 connssl->connecting_state = ssl_connect_2_reading;
1698 else if(SSL_ERROR_WANT_WRITE == detail) {
1699 connssl->connecting_state = ssl_connect_2_writing;
1703 /* untreated error */
1704 unsigned long errdetail;
1705 char error_buffer[256]; /* OpenSSL documents that this must be at least
1708 const char *cert_problem = NULL;
1711 connssl->connecting_state = ssl_connect_2; /* the connection failed,
1712 we're not waiting for
1715 errdetail = ERR_get_error(); /* Gets the earliest error code from the
1716 thread's error queue and removes the
1723 SSL2_SET_CERTIFICATE:
1724 certificate verify failed */
1729 SSL3_GET_SERVER_CERTIFICATE:
1730 certificate verify failed */
1731 rc = CURLE_SSL_CACERT;
1733 lerr = SSL_get_verify_result(connssl->handle);
1734 if(lerr != X509_V_OK) {
1735 snprintf(error_buffer, sizeof(error_buffer),
1736 "SSL certificate problem: %s",
1737 X509_verify_cert_error_string(lerr));
1740 cert_problem = "SSL certificate problem, verify that the CA cert is"
1745 rc = CURLE_SSL_CONNECT_ERROR;
1746 SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
1750 /* detail is already set to the SSL error above */
1752 /* If we e.g. use SSLv2 request-method and the server doesn't like us
1753 * (RST connection etc.), OpenSSL gives no explanation whatsoever and
1754 * the SO_ERROR is also lost.
1756 if(CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
1757 failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
1758 conn->host.name, conn->port);
1761 /* Could be a CERT problem */
1763 failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
1768 /* we have been connected fine, we're not waiting for anything else. */
1769 connssl->connecting_state = ssl_connect_3;
1771 /* Informational message */
1772 infof (data, "SSL connection using %s\n",
1773 SSL_get_cipher(connssl->handle));
1779 static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
1783 if((ilen = (int)len) < 0)
1784 return 1; /* buffer too big */
1786 i = i2t_ASN1_OBJECT(buf, ilen, a);
1789 return 1; /* buffer too small */
1794 static void pubkey_show(struct SessionHandle *data,
1807 buffer = malloc(left);
1810 snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
1811 for(i=0; i< len; i++) {
1812 snprintf(ptr, left, "%02x:", raw[i]);
1816 infof(data, " %s: %s\n", namebuf, buffer);
1817 Curl_ssl_push_certinfo(data, num, namebuf, buffer);
1822 #define print_pubkey_BN(_type, _name, _num) \
1824 if(pubkey->pkey._type->_name != NULL) { \
1825 int len = BN_num_bytes(pubkey->pkey._type->_name); \
1826 if(len < CERTBUFFERSIZE) { \
1827 BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)bufp); \
1829 pubkey_show(data, _num, #_type, #_name, (unsigned char*)bufp, len); \
1834 static int X509V3_ext(struct SessionHandle *data,
1836 STACK_OF(X509_EXTENSION) *exts)
1841 if(sk_X509_EXTENSION_num(exts) <= 0)
1842 /* no extensions, bail out */
1845 for(i=0; i<sk_X509_EXTENSION_num(exts); i++) {
1847 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
1852 BIO *bio_out = BIO_new(BIO_s_mem());
1857 obj = X509_EXTENSION_get_object(ext);
1859 asn1_object_dump(obj, namebuf, sizeof(namebuf));
1861 infof(data, "%s: %s\n", namebuf,
1862 X509_EXTENSION_get_critical(ext)?"(critical)":"");
1864 if(!X509V3_EXT_print(bio_out, ext, 0, 0))
1865 M_ASN1_OCTET_STRING_print(bio_out, ext->value);
1867 BIO_get_mem_ptr(bio_out, &biomem);
1869 /* biomem->length bytes at biomem->data, this little loop here is only
1870 done for the infof() call, we send the "raw" data to the certinfo
1872 for(j=0; j<(size_t)biomem->length; j++) {
1874 if(biomem->data[j] == '\n') {
1876 j++; /* skip the newline */
1878 while((biomem->data[j] == ' ') && (j<(size_t)biomem->length))
1880 if(j<(size_t)biomem->length)
1881 ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
1884 infof(data, " %s\n", buf);
1886 Curl_ssl_push_certinfo(data, certnum, namebuf, buf);
1891 return 0; /* all is fine */
1895 static void X509_signature(struct SessionHandle *data,
1902 for(i=0; i<sig->length; i++)
1903 ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%02x:", sig->data[i]);
1905 infof(data, " Signature: %s\n", buf);
1906 Curl_ssl_push_certinfo(data, numcert, "Signature", buf);
1909 static void dumpcert(struct SessionHandle *data, X509 *x, int numcert)
1911 BIO *bio_out = BIO_new(BIO_s_mem());
1914 /* this outputs the cert in this 64 column wide style with newlines and
1915 -----BEGIN CERTIFICATE----- texts and more */
1916 PEM_write_bio_X509(bio_out, x);
1918 BIO_get_mem_ptr(bio_out, &biomem);
1920 infof(data, "%s\n", biomem->data);
1922 Curl_ssl_push_certinfo_len(data, numcert,
1923 "Cert", biomem->data, biomem->length);
1930 * This size was previously 512 which has been reported "too small" without
1931 * any specifics, so it was enlarged to allow more data to get shown uncut.
1932 * The "perfect" size is yet to figure out.
1934 #define CERTBUFFERSIZE 8192
1936 static CURLcode get_cert_chain(struct connectdata *conn,
1937 struct ssl_connect_data *connssl)
1943 struct SessionHandle *data = conn->data;
1946 bufp = malloc(CERTBUFFERSIZE);
1948 return CURLE_OUT_OF_MEMORY;
1950 sk = SSL_get_peer_cert_chain(connssl->handle);
1953 return CURLE_OUT_OF_MEMORY;
1956 numcerts = sk_X509_num(sk);
1957 if(Curl_ssl_init_certinfo(data, numcerts)) {
1959 return CURLE_OUT_OF_MEMORY;
1962 infof(data, "--- Certificate chain\n");
1963 for(i=0; i<numcerts; i++) {
1966 ASN1_TIME *certdate;
1968 /* get the certs in "importance order" */
1970 X509 *x = sk_X509_value(sk, numcerts - i - 1);
1972 X509 *x = sk_X509_value(sk, i);
1976 EVP_PKEY *pubkey=NULL;
1980 (void)x509_name_oneline(X509_get_subject_name(x), bufp, CERTBUFFERSIZE);
1981 infof(data, "%2d Subject: %s\n", i, bufp);
1982 Curl_ssl_push_certinfo(data, i, "Subject", bufp);
1984 (void)x509_name_oneline(X509_get_issuer_name(x), bufp, CERTBUFFERSIZE);
1985 infof(data, " Issuer: %s\n", bufp);
1986 Curl_ssl_push_certinfo(data, i, "Issuer", bufp);
1988 value = X509_get_version(x);
1989 infof(data, " Version: %lu (0x%lx)\n", value+1, value);
1990 snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
1991 Curl_ssl_push_certinfo(data, i, "Version", bufp); /* hex */
1993 num=X509_get_serialNumber(x);
1994 if(num->length <= 4) {
1995 value = ASN1_INTEGER_get(num);
1996 infof(data," Serial Number: %ld (0x%lx)\n", value, value);
1997 snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
2000 int left = CERTBUFFERSIZE;
2004 if(num->type == V_ASN1_NEG_INTEGER)
2007 for(j=0; (j<num->length) && (left>=4); j++) {
2008 /* TODO: length restrictions */
2009 snprintf(ptr, 3, "%02x%c",num->data[j],
2010 ((j+1 == num->length)?'\n':':'));
2015 infof(data," Serial Number: %s\n", bufp);
2020 Curl_ssl_push_certinfo(data, i, "Serial Number", bufp); /* hex */
2022 cinf = x->cert_info;
2024 j = asn1_object_dump(cinf->signature->algorithm, bufp, CERTBUFFERSIZE);
2026 infof(data, " Signature Algorithm: %s\n", bufp);
2027 Curl_ssl_push_certinfo(data, i, "Signature Algorithm", bufp);
2030 certdate = X509_get_notBefore(x);
2031 asn1_output(certdate, bufp, CERTBUFFERSIZE);
2032 infof(data, " Start date: %s\n", bufp);
2033 Curl_ssl_push_certinfo(data, i, "Start date", bufp);
2035 certdate = X509_get_notAfter(x);
2036 asn1_output(certdate, bufp, CERTBUFFERSIZE);
2037 infof(data, " Expire date: %s\n", bufp);
2038 Curl_ssl_push_certinfo(data, i, "Expire date", bufp);
2040 j = asn1_object_dump(cinf->key->algor->algorithm, bufp, CERTBUFFERSIZE);
2042 infof(data, " Public Key Algorithm: %s\n", bufp);
2043 Curl_ssl_push_certinfo(data, i, "Public Key Algorithm", bufp);
2046 pubkey = X509_get_pubkey(x);
2048 infof(data, " Unable to load public key\n");
2050 switch(pubkey->type) {
2052 infof(data, " RSA Public Key (%d bits)\n",
2053 BN_num_bits(pubkey->pkey.rsa->n));
2054 snprintf(bufp, CERTBUFFERSIZE, "%d", BN_num_bits(pubkey->pkey.rsa->n));
2055 Curl_ssl_push_certinfo(data, i, "RSA Public Key", bufp);
2057 print_pubkey_BN(rsa, n, i);
2058 print_pubkey_BN(rsa, e, i);
2059 print_pubkey_BN(rsa, d, i);
2060 print_pubkey_BN(rsa, p, i);
2061 print_pubkey_BN(rsa, q, i);
2062 print_pubkey_BN(rsa, dmp1, i);
2063 print_pubkey_BN(rsa, dmq1, i);
2064 print_pubkey_BN(rsa, iqmp, i);
2067 print_pubkey_BN(dsa, p, i);
2068 print_pubkey_BN(dsa, q, i);
2069 print_pubkey_BN(dsa, g, i);
2070 print_pubkey_BN(dsa, priv_key, i);
2071 print_pubkey_BN(dsa, pub_key, i);
2074 print_pubkey_BN(dh, p, i);
2075 print_pubkey_BN(dh, g, i);
2076 print_pubkey_BN(dh, priv_key, i);
2077 print_pubkey_BN(dh, pub_key, i);
2080 case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
2085 EVP_PKEY_free(pubkey);
2088 X509V3_ext(data, i, cinf->extensions);
2090 X509_signature(data, i, x->signature);
2092 dumpcert(data, x, i);
2101 * Get the server cert, verify it and show it etc, only call failf() if the
2102 * 'strict' argument is TRUE as otherwise all this is for informational
2105 * We check certificates to authenticate the server; otherwise we risk
2106 * man-in-the-middle attack.
2108 static CURLcode servercert(struct connectdata *conn,
2109 struct ssl_connect_data *connssl,
2112 CURLcode retcode = CURLE_OK;
2115 ASN1_TIME *certdate;
2116 struct SessionHandle *data = conn->data;
2119 char *buffer = data->state.buffer;
2121 if(data->set.ssl.certinfo)
2122 /* we've been asked to gather certificate info! */
2123 (void)get_cert_chain(conn, connssl);
2125 data->set.ssl.certverifyresult = !X509_V_OK;
2127 connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
2128 if(!connssl->server_cert) {
2130 failf(data, "SSL: couldn't get peer certificate!");
2131 return CURLE_PEER_FAILED_VERIFICATION;
2133 infof (data, "Server certificate:\n");
2135 rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
2137 infof(data, "\t subject: %s\n", rc?"[NONE]":buffer);
2139 certdate = X509_get_notBefore(connssl->server_cert);
2140 asn1_output(certdate, buffer, BUFSIZE);
2141 infof(data, "\t start date: %s\n", buffer);
2143 certdate = X509_get_notAfter(connssl->server_cert);
2144 asn1_output(certdate, buffer, BUFSIZE);
2145 infof(data, "\t expire date: %s\n", buffer);
2147 if(data->set.ssl.verifyhost) {
2148 retcode = verifyhost(conn, connssl->server_cert);
2150 X509_free(connssl->server_cert);
2151 connssl->server_cert = NULL;
2156 rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert),
2160 failf(data, "SSL: couldn't get X509-issuer name!");
2161 retcode = CURLE_SSL_CONNECT_ERROR;
2164 infof(data, "\t issuer: %s\n", buffer);
2166 /* We could do all sorts of certificate verification stuff here before
2167 deallocating the certificate. */
2169 /* e.g. match issuer name with provided issuer certificate */
2170 if(data->set.str[STRING_SSL_ISSUERCERT]) {
2171 fp=fopen(data->set.str[STRING_SSL_ISSUERCERT],"r");
2174 failf(data, "SSL: Unable to open issuer cert (%s)",
2175 data->set.str[STRING_SSL_ISSUERCERT]);
2176 X509_free(connssl->server_cert);
2177 connssl->server_cert = NULL;
2178 return CURLE_SSL_ISSUER_ERROR;
2180 issuer = PEM_read_X509(fp,NULL,ZERO_NULL,NULL);
2183 failf(data, "SSL: Unable to read issuer cert (%s)",
2184 data->set.str[STRING_SSL_ISSUERCERT]);
2185 X509_free(connssl->server_cert);
2188 return CURLE_SSL_ISSUER_ERROR;
2191 if(X509_check_issued(issuer,connssl->server_cert) != X509_V_OK) {
2193 failf(data, "SSL: Certificate issuer check failed (%s)",
2194 data->set.str[STRING_SSL_ISSUERCERT]);
2195 X509_free(connssl->server_cert);
2197 connssl->server_cert = NULL;
2198 return CURLE_SSL_ISSUER_ERROR;
2200 infof(data, "\t SSL certificate issuer check ok (%s)\n",
2201 data->set.str[STRING_SSL_ISSUERCERT]);
2205 lerr = data->set.ssl.certverifyresult=
2206 SSL_get_verify_result(connssl->handle);
2207 if(data->set.ssl.certverifyresult != X509_V_OK) {
2208 if(data->set.ssl.verifypeer) {
2209 /* We probably never reach this, because SSL_connect() will fail
2210 and we return earlier if verifypeer is set? */
2212 failf(data, "SSL certificate verify result: %s (%ld)",
2213 X509_verify_cert_error_string(lerr), lerr);
2214 retcode = CURLE_PEER_FAILED_VERIFICATION;
2217 infof(data, "\t SSL certificate verify result: %s (%ld),"
2218 " continuing anyway.\n",
2219 X509_verify_cert_error_string(lerr), lerr);
2222 infof(data, "\t SSL certificate verify ok.\n");
2225 X509_free(connssl->server_cert);
2226 connssl->server_cert = NULL;
2227 connssl->connecting_state = ssl_connect_done;
2234 ossl_connect_step3(struct connectdata *conn,
2237 CURLcode retcode = CURLE_OK;
2238 void *old_ssl_sessionid=NULL;
2239 struct SessionHandle *data = conn->data;
2240 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2242 SSL_SESSION *our_ssl_sessionid;
2244 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
2246 #ifdef HAVE_SSL_GET1_SESSION
2247 our_ssl_sessionid = SSL_get1_session(connssl->handle);
2249 /* SSL_get1_session() will increment the reference
2250 count and the session will stay in memory until explicitly freed with
2251 SSL_SESSION_free(3), regardless of its state.
2252 This function was introduced in openssl 0.9.5a. */
2254 our_ssl_sessionid = SSL_get_session(connssl->handle);
2256 /* if SSL_get1_session() is unavailable, use SSL_get_session().
2257 This is an inferior option because the session can be flushed
2258 at any time by openssl. It is included only so curl compiles
2259 under versions of openssl < 0.9.5a.
2261 WARNING: How curl behaves if it's session is flushed is
2266 incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
2268 if(old_ssl_sessionid != our_ssl_sessionid) {
2269 infof(data, "old SSL session ID is stale, removing\n");
2270 Curl_ssl_delsessionid(conn, old_ssl_sessionid);
2275 retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
2276 0 /* unknown size */);
2278 failf(data, "failed to store ssl session");
2282 #ifdef HAVE_SSL_GET1_SESSION
2284 /* Session was incache, so refcount already incremented earlier.
2285 * Avoid further increments with each SSL_get1_session() call.
2286 * This does not free the session as refcount remains > 0
2288 SSL_SESSION_free(our_ssl_sessionid);
2293 * We check certificates to authenticate the server; otherwise we risk
2294 * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to
2295 * verify the peer ignore faults and failures from the server cert
2299 if(!data->set.ssl.verifypeer)
2300 (void)servercert(conn, connssl, FALSE);
2302 retcode = servercert(conn, connssl, TRUE);
2304 if(CURLE_OK == retcode)
2305 connssl->connecting_state = ssl_connect_done;
2309 static Curl_recv ossl_recv;
2310 static Curl_send ossl_send;
2313 ossl_connect_common(struct connectdata *conn,
2319 struct SessionHandle *data = conn->data;
2320 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2321 curl_socket_t sockfd = conn->sock[sockindex];
2325 /* check if the connection has already been established */
2326 if(ssl_connection_complete == connssl->state) {
2331 if(ssl_connect_1==connssl->connecting_state) {
2332 /* Find out how much more time we're allowed */
2333 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2335 if(timeout_ms < 0) {
2336 /* no need to continue if time already is up */
2337 failf(data, "SSL connection timeout");
2338 return CURLE_OPERATION_TIMEDOUT;
2340 retcode = ossl_connect_step1(conn, sockindex);
2345 while(ssl_connect_2 == connssl->connecting_state ||
2346 ssl_connect_2_reading == connssl->connecting_state ||
2347 ssl_connect_2_writing == connssl->connecting_state) {
2349 /* check allowed time left */
2350 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2352 if(timeout_ms < 0) {
2353 /* no need to continue if time already is up */
2354 failf(data, "SSL connection timeout");
2355 return CURLE_OPERATION_TIMEDOUT;
2358 /* if ssl is expecting something, check if it's available. */
2359 if(connssl->connecting_state == ssl_connect_2_reading
2360 || connssl->connecting_state == ssl_connect_2_writing) {
2362 curl_socket_t writefd = ssl_connect_2_writing==
2363 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2364 curl_socket_t readfd = ssl_connect_2_reading==
2365 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2367 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
2370 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2371 return CURLE_SSL_CONNECT_ERROR;
2373 else if(0 == what) {
2380 failf(data, "SSL connection timeout");
2381 return CURLE_OPERATION_TIMEDOUT;
2384 /* socket is readable or writable */
2387 /* Run transaction, and return to the caller if it failed or if this
2388 * connection is done nonblocking and this loop would execute again. This
2389 * permits the owner of a multi handle to abort a connection attempt
2390 * before step2 has completed while ensuring that a client using select()
2391 * or epoll() will always have a valid fdset to wait on.
2393 retcode = ossl_connect_step2(conn, sockindex);
2394 if(retcode || (nonblocking &&
2395 (ssl_connect_2 == connssl->connecting_state ||
2396 ssl_connect_2_reading == connssl->connecting_state ||
2397 ssl_connect_2_writing == connssl->connecting_state)))
2400 } /* repeat step2 until all transactions are done. */
2403 if(ssl_connect_3==connssl->connecting_state) {
2404 retcode = ossl_connect_step3(conn, sockindex);
2409 if(ssl_connect_done==connssl->connecting_state) {
2410 connssl->state = ssl_connection_complete;
2411 conn->recv[sockindex] = ossl_recv;
2412 conn->send[sockindex] = ossl_send;
2418 /* Reset our connect state machine */
2419 connssl->connecting_state = ssl_connect_1;
2425 Curl_ossl_connect_nonblocking(struct connectdata *conn,
2429 return ossl_connect_common(conn, sockindex, TRUE, done);
2433 Curl_ossl_connect(struct connectdata *conn,
2439 retcode = ossl_connect_common(conn, sockindex, FALSE, &done);
2448 bool Curl_ossl_data_pending(const struct connectdata *conn,
2451 if(conn->ssl[connindex].handle)
2453 return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
2458 static ssize_t ossl_send(struct connectdata *conn,
2464 /* SSL_write() is said to return 'int' while write() and send() returns
2467 char error_buffer[120]; /* OpenSSL documents that this must be at least 120
2469 unsigned long sslerror;
2475 memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
2476 rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
2479 err = SSL_get_error(conn->ssl[sockindex].handle, rc);
2482 case SSL_ERROR_WANT_READ:
2483 case SSL_ERROR_WANT_WRITE:
2484 /* The operation did not complete; the same TLS/SSL I/O function
2485 should be called again later. This is basically an EWOULDBLOCK
2487 *curlcode = CURLE_AGAIN;
2489 case SSL_ERROR_SYSCALL:
2490 failf(conn->data, "SSL_write() returned SYSCALL, errno = %d",
2492 *curlcode = CURLE_SEND_ERROR;
2495 /* A failure in the SSL library occurred, usually a protocol error.
2496 The OpenSSL error queue contains more information on the error. */
2497 sslerror = ERR_get_error();
2498 failf(conn->data, "SSL_write() error: %s",
2499 ERR_error_string(sslerror, error_buffer));
2500 *curlcode = CURLE_SEND_ERROR;
2504 failf(conn->data, "SSL_write() return error %d", err);
2505 *curlcode = CURLE_SEND_ERROR;
2508 return (ssize_t)rc; /* number of bytes */
2511 static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
2512 int num, /* socketindex */
2513 char *buf, /* store read data here */
2514 size_t buffersize, /* max amount to read */
2517 char error_buffer[120]; /* OpenSSL documents that this must be at
2518 least 120 bytes long. */
2519 unsigned long sslerror;
2525 buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
2526 nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize);
2528 /* failed SSL_read */
2529 int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
2532 case SSL_ERROR_NONE: /* this is not an error */
2533 case SSL_ERROR_ZERO_RETURN: /* no more data */
2535 case SSL_ERROR_WANT_READ:
2536 case SSL_ERROR_WANT_WRITE:
2537 /* there's data pending, re-invoke SSL_read() */
2538 *curlcode = CURLE_AGAIN;
2541 /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
2543 /* http://www.openssl.org/docs/crypto/ERR_get_error.html */
2544 sslerror = ERR_get_error();
2545 if((nread < 0) || sslerror) {
2546 /* If the return code was negative or there actually is an error in the
2548 failf(conn->data, "SSL read: %s, errno %d",
2549 ERR_error_string(sslerror, error_buffer),
2551 *curlcode = CURLE_RECV_ERROR;
2559 size_t Curl_ossl_version(char *buffer, size_t size)
2561 #ifdef YASSL_VERSION
2562 /* yassl provides an OpenSSL API compatibility layer so it looks identical
2563 to OpenSSL in all other aspects */
2564 return snprintf(buffer, size, "yassl/%s", YASSL_VERSION);
2565 #else /* YASSL_VERSION */
2567 #if(SSLEAY_VERSION_NUMBER >= 0x905000)
2570 unsigned long ssleay_value;
2572 ssleay_value=SSLeay();
2573 if(ssleay_value < 0x906000) {
2574 ssleay_value=SSLEAY_VERSION_NUMBER;
2578 if(ssleay_value&0xff0) {
2579 sub[0]=(char)(((ssleay_value>>4)&0xff) + 'a' -1);
2585 return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx%s",
2586 (ssleay_value>>28)&0xf,
2587 (ssleay_value>>20)&0xff,
2588 (ssleay_value>>12)&0xff,
2592 #else /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
2594 #if(SSLEAY_VERSION_NUMBER >= 0x900000)
2595 return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx",
2596 (SSLEAY_VERSION_NUMBER>>28)&0xff,
2597 (SSLEAY_VERSION_NUMBER>>20)&0xff,
2598 (SSLEAY_VERSION_NUMBER>>12)&0xf);
2600 #else /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
2604 if(SSLEAY_VERSION_NUMBER&0x0f) {
2605 sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
2610 return snprintf(buffer, size, "SSL/%x.%x.%x%s",
2611 (SSLEAY_VERSION_NUMBER>>12)&0xff,
2612 (SSLEAY_VERSION_NUMBER>>8)&0xf,
2613 (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
2615 #endif /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
2616 #endif /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
2618 #endif /* YASSL_VERSION */
2621 void Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy,
2624 Curl_ossl_seed(data); /* Initiate the seed if not already done */
2625 RAND_bytes(entropy, curlx_uztosi(length));
2628 void Curl_ossl_md5sum(unsigned char *tmp, /* input */
2630 unsigned char *md5sum /* output */,
2636 MD5_Update(&MD5pw, tmp, tmplen);
2637 MD5_Final(md5sum, &MD5pw);
2639 #endif /* USE_SSLEAY */