1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2010, 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.
41 #ifdef HAVE_SYS_SOCKET_H
42 #include <sys/socket.h>
47 #include "formdata.h" /* for the boundary function */
48 #include "url.h" /* for the ssl config check function */
49 #include "inet_pton.h"
57 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
58 #include <curl/mprintf.h>
63 #include <openssl/rand.h>
64 #include <openssl/x509v3.h>
65 #include <openssl/dsa.h>
66 #include <openssl/dh.h>
72 #include "curl_memory.h"
73 #include "easyif.h" /* for Curl_convert_from_utf8 prototype */
75 /* The last #include file should be: */
78 #if OPENSSL_VERSION_NUMBER >= 0x0090581fL
79 #define HAVE_SSL_GET1_SESSION 1
81 #undef HAVE_SSL_GET1_SESSION
84 #if OPENSSL_VERSION_NUMBER >= 0x00904100L
85 #define HAVE_USERDATA_IN_PWD_CALLBACK 1
87 #undef HAVE_USERDATA_IN_PWD_CALLBACK
90 #if OPENSSL_VERSION_NUMBER >= 0x00907001L
91 /* ENGINE_load_private_key() takes four arguments */
92 #define HAVE_ENGINE_LOAD_FOUR_ARGS
93 #include <openssl/ui.h>
95 /* ENGINE_load_private_key() takes three arguments */
96 #undef HAVE_ENGINE_LOAD_FOUR_ARGS
99 #if (OPENSSL_VERSION_NUMBER >= 0x00903001L) && defined(HAVE_OPENSSL_PKCS12_H)
100 /* OpenSSL has PKCS 12 support */
101 #define HAVE_PKCS12_SUPPORT
103 /* OpenSSL/SSLEay does not have PKCS12 support */
104 #undef HAVE_PKCS12_SUPPORT
107 #if OPENSSL_VERSION_NUMBER >= 0x00906001L
108 #define HAVE_ERR_ERROR_STRING_N 1
111 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
112 #define SSL_METHOD_QUAL const
114 #define SSL_METHOD_QUAL
117 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
118 /* 0.9.6 didn't have X509_STORE_set_flags() */
119 #define HAVE_X509_STORE_SET_FLAGS 1
121 #define X509_STORE_set_flags(x,y)
125 * Number of bytes to read from the random number seed file. This must be
126 * a finite value (because some entropy "files" like /dev/urandom have
127 * an infinite length), but must be large enough to provide enough
128 * entopy to properly seed OpenSSL's PRNG.
130 #define RAND_LOAD_LENGTH 1024
132 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
133 static char global_passwd[64];
136 static int passwd_callback(char *buf, int num, int verify
137 #ifdef HAVE_USERDATA_IN_PWD_CALLBACK
138 /* This was introduced in 0.9.4, we can set this
139 using SSL_CTX_set_default_passwd_cb_userdata()
141 , void *global_passwd
146 fprintf(stderr, "%s\n", buf);
148 if(num > (int)strlen((char *)global_passwd)) {
149 strcpy(buf, global_passwd);
150 return (int)strlen(buf);
157 * rand_enough() is a function that returns TRUE if we have seeded the random
158 * engine properly. We use some preprocessor magic to provide a seed_enough()
159 * macro to use, just to prevent a compiler warning on this function if we
160 * pass in an argument that is never used.
163 #ifdef HAVE_RAND_STATUS
164 #define seed_enough(x) rand_enough()
165 static bool rand_enough(void)
167 return (bool)(0 != RAND_status());
170 #define seed_enough(x) rand_enough(x)
171 static bool rand_enough(int nread)
173 /* this is a very silly decision to make */
174 return (bool)(nread > 500);
178 static int ossl_seed(struct SessionHandle *data)
180 char *buf = data->state.buffer; /* point to the big buffer */
183 /* Q: should we add support for a random file name as a libcurl option?
184 A: Yes, it is here */
187 /* if RANDOM_FILE isn't defined, we only perform this if an option tells
189 if(data->set.ssl.random_file)
190 #define RANDOM_FILE "" /* doesn't matter won't be used */
193 /* let the option override the define */
194 nread += RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
195 data->set.str[STRING_SSL_RANDOM_FILE]:
198 if(seed_enough(nread))
202 #if defined(HAVE_RAND_EGD)
203 /* only available in OpenSSL 0.9.5 and later */
204 /* EGD_SOCKET is set at configure time or not at all */
206 /* If we don't have the define set, we only do this if the egd-option
208 if(data->set.str[STRING_SSL_EGDSOCKET])
209 #define EGD_SOCKET "" /* doesn't matter won't be used */
212 /* If there's an option and a define, the option overrides the
214 int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
215 data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
218 if(seed_enough(nread))
224 /* If we get here, it means we need to seed the PRNG using a "silly"
226 #ifdef HAVE_RAND_SCREEN
227 /* if RAND_screen() is present, it was called during global init */
228 nread = 100; /* just a value */
234 /* Changed call to RAND_seed to use the underlying RAND_add implementation
235 * directly. Do this in a loop, with the amount of additional entropy
236 * being dependent upon the algorithm used by Curl_FormBoundary(): N bytes
237 * of a 7-bit ascii set. -- Richard Gorton, March 11 2003.
241 area = Curl_FormBoundary();
243 return 3; /* out of memory */
245 len = (int)strlen(area);
246 RAND_add(area, len, (len >> 1));
248 free(area); /* now remove the random junk */
249 } while(!RAND_status());
253 /* generates a default path for the random seed file */
254 buf[0]=0; /* blank it first */
255 RAND_file_name(buf, BUFSIZE);
257 /* we got a file name to try */
258 nread += RAND_load_file(buf, RAND_LOAD_LENGTH);
259 if(seed_enough(nread))
263 infof(data, "libcurl is now using a weak random seed!\n");
267 int Curl_ossl_seed(struct SessionHandle *data)
269 /* we have the "SSL is seeded" boolean static to prevent multiple
270 time-consuming seedings in vain */
271 static bool ssl_seeded = FALSE;
273 if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
274 data->set.str[STRING_SSL_EGDSOCKET]) {
282 #ifndef SSL_FILETYPE_ENGINE
283 #define SSL_FILETYPE_ENGINE 42
285 #ifndef SSL_FILETYPE_PKCS12
286 #define SSL_FILETYPE_PKCS12 43
288 static int do_file_type(const char *type)
290 if(!type || !type[0])
291 return SSL_FILETYPE_PEM;
292 if(Curl_raw_equal(type, "PEM"))
293 return SSL_FILETYPE_PEM;
294 if(Curl_raw_equal(type, "DER"))
295 return SSL_FILETYPE_ASN1;
296 if(Curl_raw_equal(type, "ENG"))
297 return SSL_FILETYPE_ENGINE;
298 if(Curl_raw_equal(type, "P12"))
299 return SSL_FILETYPE_PKCS12;
304 int cert_stuff(struct connectdata *conn,
307 const char *cert_type,
309 const char *key_type)
311 struct SessionHandle *data = conn->data;
313 int file_type = do_file_type(cert_type);
315 if(cert_file != NULL || file_type == SSL_FILETYPE_ENGINE) {
320 if(data->set.str[STRING_KEY_PASSWD]) {
321 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
323 * If password has been given, we store that in the global
324 * area (*shudder*) for a while:
326 size_t len = strlen(data->set.key_passwd);
327 if(len < sizeof(global_passwd))
328 memcpy(global_passwd, data->set.key_passwd, len+1);
331 * We set the password in the callback userdata
333 SSL_CTX_set_default_passwd_cb_userdata(ctx,
334 data->set.str[STRING_KEY_PASSWD]);
336 /* Set passwd callback: */
337 SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
341 #define SSL_CLIENT_CERT_ERR \
342 "unable to use client certificate (no key found or wrong pass phrase?)"
345 case SSL_FILETYPE_PEM:
346 /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
347 if(SSL_CTX_use_certificate_chain_file(ctx,
349 failf(data, SSL_CLIENT_CERT_ERR);
354 case SSL_FILETYPE_ASN1:
355 /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
356 we use the case above for PEM so this can only be performed with
358 if(SSL_CTX_use_certificate_file(ctx,
361 failf(data, SSL_CLIENT_CERT_ERR);
365 case SSL_FILETYPE_ENGINE:
366 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
368 if(data->state.engine) {
369 const char *cmd_name = "LOAD_CERT_CTRL";
375 params.cert_id = cert_file;
378 /* Does the engine supports LOAD_CERT_CTRL ? */
379 if (!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
380 0, (void *)cmd_name, NULL)) {
381 failf(data, "ssl engine does not support loading certificates");
385 /* Load the certificate from the engine */
386 if (!ENGINE_ctrl_cmd(data->state.engine, cmd_name,
387 0, ¶ms, NULL, 1)) {
388 failf(data, "ssl engine cannot load client cert with id"
389 " '%s' [%s]", cert_file,
390 ERR_error_string(ERR_get_error(), NULL));
395 failf(data, "ssl engine didn't initialized the certificate "
400 if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
401 failf(data, "unable to set client certificate");
402 X509_free(params.cert);
405 X509_free(params.cert); /* we don't need the handle any more... */
408 failf(data, "crypto engine not set, can't load certificate");
414 failf(data, "file type ENG for certificate not implemented");
418 case SSL_FILETYPE_PKCS12:
420 #ifdef HAVE_PKCS12_SUPPORT
424 STACK_OF(X509) *ca = NULL;
427 f = fopen(cert_file,"rb");
429 failf(data, "could not open PKCS12 file '%s'", cert_file);
432 p12 = d2i_PKCS12_fp(f, NULL);
436 failf(data, "error reading PKCS12 file '%s'", cert_file );
442 if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509,
445 "could not parse PKCS12 file, check password, OpenSSL error %s",
446 ERR_error_string(ERR_get_error(), NULL) );
453 if(SSL_CTX_use_certificate(ctx, x509) != 1) {
454 failf(data, SSL_CLIENT_CERT_ERR);
460 if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
461 failf(data, "unable to use private key from PKCS12 file '%s'",
468 if (!SSL_CTX_check_private_key (ctx)) {
469 failf(data, "private key from PKCS12 file '%s' "
470 "does not match certificate in same file", cert_file);
475 /* Set Certificate Verification chain */
476 if (ca && sk_X509_num(ca)) {
477 for (i = 0; i < sk_X509_num(ca); i++) {
478 if (!SSL_CTX_add_extra_chain_cert(ctx,sk_X509_value(ca, i))) {
479 failf(data, "cannot add certificate to certificate chain");
484 if (!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i))) {
485 failf(data, "cannot add certificate to client CA list");
498 failf(data, "file type P12 for certificate not supported");
503 failf(data, "not supported file type '%s' for certificate", cert_type);
507 file_type = do_file_type(key_type);
510 case SSL_FILETYPE_PEM:
514 /* cert & key can only be in PEM case in the same file */
516 case SSL_FILETYPE_ASN1:
517 if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
518 failf(data, "unable to set private key file: '%s' type %s",
519 key_file, key_type?key_type:"PEM");
523 case SSL_FILETYPE_ENGINE:
524 #ifdef HAVE_OPENSSL_ENGINE_H
525 { /* XXXX still needs some work */
526 EVP_PKEY *priv_key = NULL;
527 if(data->state.engine) {
528 #ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
529 UI_METHOD *ui_method = UI_OpenSSL();
531 /* the typecast below was added to please mingw32 */
532 priv_key = (EVP_PKEY *)
533 ENGINE_load_private_key(data->state.engine,key_file,
534 #ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
537 data->set.str[STRING_KEY_PASSWD]);
539 failf(data, "failed to load private key from crypto engine");
542 if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
543 failf(data, "unable to set private key");
544 EVP_PKEY_free(priv_key);
547 EVP_PKEY_free(priv_key); /* we don't need the handle any more... */
550 failf(data, "crypto engine not set, can't load private key");
556 failf(data, "file type ENG for private key not supported");
559 case SSL_FILETYPE_PKCS12:
561 failf(data, "file type P12 for private key not supported");
566 failf(data, "not supported file type for private key");
572 failf(data,"unable to create an SSL structure");
576 x509=SSL_get_certificate(ssl);
578 /* This version was provided by Evan Jordan and is supposed to not
579 leak memory as the previous version: */
581 EVP_PKEY *pktmp = X509_get_pubkey(x509);
582 EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));
583 EVP_PKEY_free(pktmp);
588 /* If we are using DSA, we can copy the parameters from
592 /* Now we know that a key and cert have been set against
594 if(!SSL_CTX_check_private_key(ctx)) {
595 failf(data, "Private key does not match the certificate public key");
598 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
600 memset(global_passwd, 0, sizeof(global_passwd));
606 /* returns non-zero on failure */
607 static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
610 return X509_NAME_oneline(a, buf, size);
612 BIO *bio_out = BIO_new(BIO_s_mem());
617 return 1; /* alloc failed! */
619 rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC);
620 BIO_get_mem_ptr(bio_out, &biomem);
622 if((size_t)biomem->length < size)
623 size = biomem->length;
625 size--; /* don't overwrite the buffer end */
627 memcpy(buf, biomem->data, size);
637 int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
642 err_cert=X509_STORE_CTX_get_current_cert(ctx);
643 (void)x509_name_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
647 /* Return error string for last OpenSSL error
649 static char *SSL_strerror(unsigned long error, char *buf, size_t size)
651 #ifdef HAVE_ERR_ERROR_STRING_N
652 /* OpenSSL 0.9.6 and later has a function named
653 ERRO_error_string_n() that takes the size of the buffer as a
655 ERR_error_string_n(error, buf, size);
658 ERR_error_string(error, buf);
663 #endif /* USE_SSLEAY */
669 * @retval 0 error initializing SSL
670 * @retval 1 SSL initialized successfully
672 int Curl_ossl_init(void)
674 #ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
675 ENGINE_load_builtin_engines();
678 /* Lets get nice error messages */
679 SSL_load_error_strings();
681 /* Init the global ciphers and digests */
682 if(!SSLeay_add_ssl_algorithms())
685 OpenSSL_add_all_algorithms();
687 #ifdef HAVE_RAND_SCREEN
688 /* This one gets a random value by reading the currently shown screen.
689 RAND_screen() is not thread-safe according to OpenSSL devs - although not
690 mentioned in documentation. */
697 #endif /* USE_SSLEAY */
702 void Curl_ossl_cleanup(void)
704 /* Free the SSL error strings */
707 /* EVP_cleanup() removes all ciphers and digests from the table. */
710 #ifdef HAVE_ENGINE_CLEANUP
714 #ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
715 /* this function was not present in 0.9.6b, but was added sometimes
717 CRYPTO_cleanup_all_ex_data();
722 * This function uses SSL_peek to determine connection status.
725 * 1 means the connection is still in place
726 * 0 means the connection has been closed
727 * -1 means the connection status is unknown
729 int Curl_ossl_check_cxn(struct connectdata *conn)
734 rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1);
736 return 1; /* connection still in place */
739 return 0; /* connection has been closed */
741 return -1; /* connection status unknown */
744 /* Selects an OpenSSL crypto engine
746 CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
748 #if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
751 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
752 e = ENGINE_by_id(engine);
754 /* avoid memory leak */
755 for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
756 const char *e_id = ENGINE_get_id(e);
757 if(!strcmp(engine, e_id))
763 failf(data, "SSL Engine '%s' not found", engine);
764 return CURLE_SSL_ENGINE_NOTFOUND;
767 if(data->state.engine) {
768 ENGINE_finish(data->state.engine);
769 ENGINE_free(data->state.engine);
770 data->state.engine = NULL;
772 if(!ENGINE_init(e)) {
776 failf(data, "Failed to initialise SSL Engine '%s':\n%s",
777 engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf)));
778 return CURLE_SSL_ENGINE_INITFAILED;
780 data->state.engine = e;
784 failf(data, "SSL Engine not supported");
785 return CURLE_SSL_ENGINE_NOTFOUND;
789 /* Sets engine as default for all SSL operations
791 CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
793 #ifdef HAVE_OPENSSL_ENGINE_H
794 if(data->state.engine) {
795 if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
796 infof(data,"set default crypto engine '%s'\n", ENGINE_get_id(data->state.engine));
799 failf(data, "set default crypto engine '%s' failed", ENGINE_get_id(data->state.engine));
800 return CURLE_SSL_ENGINE_SETFAILED;
809 /* Return list of OpenSSL crypto engine names.
811 struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
813 struct curl_slist *list = NULL;
814 #if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
815 struct curl_slist *beg = NULL;
818 for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
819 list = curl_slist_append(list, ENGINE_get_id(e));
821 curl_slist_free_all(beg);
824 else if(beg == NULL) {
835 * This function is called when an SSL connection is closed.
837 void Curl_ossl_close(struct connectdata *conn, int sockindex)
839 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
841 if(connssl->handle) {
842 (void)SSL_shutdown(connssl->handle);
843 SSL_set_connect_state(connssl->handle);
845 SSL_free (connssl->handle);
846 connssl->handle = NULL;
849 SSL_CTX_free (connssl->ctx);
855 * This function is called to shut down the SSL layer but keep the
856 * socket open (CCC - Clear Command Channel)
858 int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
861 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
862 struct SessionHandle *data = conn->data;
863 char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
864 to be at least 120 bytes long. */
865 unsigned long sslerror;
871 /* This has only been tested on the proftpd server, and the mod_tls code
872 sends a close notify alert without waiting for a close notify alert in
873 response. Thus we wait for a close notify alert from the server, but
874 we do not send one. Let's hope other servers do the same... */
876 if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
877 (void)SSL_shutdown(connssl->handle);
879 if(connssl->handle) {
880 buffsize = (int)sizeof(buf);
882 int what = Curl_socket_ready(conn->sock[sockindex],
883 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
885 /* Something to read, let's do it and hope that it is the close
886 notify alert from the server */
887 nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
889 err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
892 case SSL_ERROR_NONE: /* this is not an error */
893 case SSL_ERROR_ZERO_RETURN: /* no more data */
894 /* This is the expected response. There was no data but only
895 the close notify alert */
898 case SSL_ERROR_WANT_READ:
899 /* there's data pending, re-invoke SSL_read() */
900 infof(data, "SSL_ERROR_WANT_READ\n");
902 case SSL_ERROR_WANT_WRITE:
903 /* SSL wants a write. Really odd. Let's bail out. */
904 infof(data, "SSL_ERROR_WANT_WRITE\n");
908 /* openssl/ssl.h says "look at error stack/return value/errno" */
909 sslerror = ERR_get_error();
910 failf(conn->data, "SSL read: %s, errno %d",
911 ERR_error_string(sslerror, buf),
919 failf(data, "SSL shutdown timeout");
923 /* anything that gets here is fatally bad */
924 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
928 } /* while()-loop for the select() */
930 if(data->set.verbose) {
931 #ifdef HAVE_SSL_GET_SHUTDOWN
932 switch(SSL_get_shutdown(connssl->handle)) {
933 case SSL_SENT_SHUTDOWN:
934 infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
936 case SSL_RECEIVED_SHUTDOWN:
937 infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
939 case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
940 infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
941 "SSL_RECEIVED__SHUTDOWN\n");
947 SSL_free (connssl->handle);
948 connssl->handle = NULL;
953 void Curl_ossl_session_free(void *ptr)
956 SSL_SESSION_free(ptr);
960 * This function is called when the 'data' struct is going away. Close
961 * down everything and free all resources!
963 int Curl_ossl_close_all(struct SessionHandle *data)
966 ERR_remove_state() frees the error queue associated with
967 thread pid. If pid == 0, the current thread will have its
970 Since error queue data structures are allocated
971 automatically for new threads, they must be freed when
972 threads are terminated in oder to avoid memory leaks.
976 #ifdef HAVE_OPENSSL_ENGINE_H
977 if(data->state.engine) {
978 ENGINE_finish(data->state.engine);
979 ENGINE_free(data->state.engine);
980 data->state.engine = NULL;
988 static int asn1_output(const ASN1_UTCTIME *tm,
992 const char *asn1_string;
995 int year=0,month=0,day=0,hour=0,minute=0,second=0;
998 asn1_string=(const char *)tm->data;
1002 if(asn1_string[i-1] == 'Z')
1004 for (i=0; i<10; i++)
1005 if((asn1_string[i] > '9') || (asn1_string[i] < '0'))
1008 year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0');
1012 month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0');
1013 if((month > 12) || (month < 1))
1016 day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0');
1017 hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0');
1018 minute= (asn1_string[8]-'0')*10+(asn1_string[9]-'0');
1020 if((asn1_string[10] >= '0') && (asn1_string[10] <= '9') &&
1021 (asn1_string[11] >= '0') && (asn1_string[11] <= '9'))
1022 second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0');
1024 snprintf(buf, sizeofbuf,
1025 "%04d-%02d-%02d %02d:%02d:%02d %s",
1026 year+1900, month, day, hour, minute, second, (gmt?"GMT":""));
1031 /* ====================================================== */
1034 * Match a hostname against a wildcard pattern.
1036 * "foo.host.com" matches "*.host.com".
1038 * We are a bit more liberal than RFC2818 describes in that we
1039 * accept multiple "*" in pattern (similar to what some other browsers do).
1041 * "abc.def.domain.com" should strickly not match "*.domain.com", but we
1042 * don't consider "." to be important in CERT checking.
1044 #define HOST_NOMATCH 0
1045 #define HOST_MATCH 1
1047 static int hostmatch(const char *hostname, const char *pattern)
1050 char c = *pattern++;
1053 return (*hostname ? HOST_NOMATCH : HOST_MATCH);
1057 if(c == '\0') /* "*\0" matches anything remaining */
1061 /* The only recursive function in libcurl! */
1062 if(hostmatch(hostname++,pattern) == HOST_MATCH)
1068 if(Curl_raw_toupper(c) != Curl_raw_toupper(*hostname++))
1071 return HOST_NOMATCH;
1075 cert_hostcheck(const char *match_pattern, const char *hostname)
1077 if(!match_pattern || !*match_pattern ||
1078 !hostname || !*hostname) /* sanity check */
1081 if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
1084 if(hostmatch(hostname,match_pattern) == HOST_MATCH)
1089 /* Quote from RFC2818 section 3.1 "Server Identity"
1091 If a subjectAltName extension of type dNSName is present, that MUST
1092 be used as the identity. Otherwise, the (most specific) Common Name
1093 field in the Subject field of the certificate MUST be used. Although
1094 the use of the Common Name is existing practice, it is deprecated and
1095 Certification Authorities are encouraged to use the dNSName instead.
1097 Matching is performed using the matching rules specified by
1098 [RFC2459]. If more than one identity of a given type is present in
1099 the certificate (e.g., more than one dNSName name, a match in any one
1100 of the set is considered acceptable.) Names may contain the wildcard
1101 character * which is considered to match any single domain name
1102 component or component fragment. E.g., *.a.com matches foo.a.com but
1103 not bar.foo.a.com. f*.com matches foo.com but not bar.com.
1105 In some cases, the URI is specified as an IP address rather than a
1106 hostname. In this case, the iPAddress subjectAltName must be present
1107 in the certificate and must exactly match the IP in the URI.
1110 static CURLcode verifyhost(struct connectdata *conn,
1113 int matched = -1; /* -1 is no alternative match yet, 1 means match and 0
1115 int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
1117 struct SessionHandle *data = conn->data;
1118 STACK_OF(GENERAL_NAME) *altnames;
1120 struct in6_addr addr;
1122 struct in_addr addr;
1124 CURLcode res = CURLE_OK;
1127 if(conn->bits.ipv6_ip &&
1128 Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
1130 addrlen = sizeof(struct in6_addr);
1134 if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
1136 addrlen = sizeof(struct in_addr);
1139 /* get a "list" of alternative names */
1140 altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
1146 /* get amount of alternatives, RFC2459 claims there MUST be at least
1147 one, but we don't depend on it... */
1148 numalts = sk_GENERAL_NAME_num(altnames);
1150 /* loop through all alternatives while none has matched */
1151 for (i=0; (i<numalts) && (matched != 1); i++) {
1152 /* get a handle to alternative name number i */
1153 const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
1155 /* only check alternatives of the same type the target is */
1156 if(check->type == target) {
1157 /* get data and length */
1158 const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
1159 size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
1162 case GEN_DNS: /* name/pattern comparison */
1163 /* The OpenSSL man page explicitly says: "In general it cannot be
1164 assumed that the data returned by ASN1_STRING_data() is null
1165 terminated or does not contain embedded nulls." But also that
1166 "The actual format of the data will depend on the actual string
1167 type itself: for example for and IA5String the data will be ASCII"
1169 Gisle researched the OpenSSL sources:
1170 "I checked the 0.9.6 and 0.9.8 sources before my patch and
1171 it always 0-terminates an IA5String."
1173 if((altlen == strlen(altptr)) &&
1174 /* if this isn't true, there was an embedded zero in the name
1175 string and we cannot match it. */
1176 cert_hostcheck(altptr, conn->host.name))
1182 case GEN_IPADD: /* IP address comparison */
1183 /* compare alternative IP address if the data chunk is the same size
1184 our server IP address is */
1185 if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
1193 GENERAL_NAMES_free(altnames);
1197 /* an alternative name matched the server hostname */
1198 infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
1199 else if(matched == 0) {
1200 /* an alternative name field existed, but didn't match and then
1202 infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
1203 res = CURLE_PEER_FAILED_VERIFICATION;
1206 /* we have to look to the last occurence of a commonName in the
1207 distinguished one to get the most significant one. */
1210 /* The following is done because of a bug in 0.9.6b */
1212 unsigned char *nulstr = (unsigned char *)"";
1213 unsigned char *peer_CN = nulstr;
1215 X509_NAME *name = X509_get_subject_name(server_cert) ;
1217 while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i))>=0)
1220 /* we have the name entry and we will now convert this to a string
1221 that we can use for comparison. Doing this we support BMPstring,
1225 ASN1_STRING *tmp = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
1227 /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
1228 is already UTF-8 encoded. We check for this case and copy the raw
1229 string manually to avoid the problem. This code can be made
1230 conditional in the future when OpenSSL has been fixed. Work-around
1231 brought by Alexis S. L. Carvalho. */
1233 if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
1234 j = ASN1_STRING_length(tmp);
1236 peer_CN = OPENSSL_malloc(j+1);
1238 memcpy(peer_CN, ASN1_STRING_data(tmp), j);
1243 else /* not a UTF8 name */
1244 j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
1246 if(peer_CN && ((int)strlen((char *)peer_CN) != j)) {
1247 /* there was a terminating zero before the end of string, this
1248 cannot match and we return failure! */
1249 failf(data, "SSL: illegal cert name field");
1250 res = CURLE_PEER_FAILED_VERIFICATION;
1255 if(peer_CN == nulstr)
1257 #ifdef CURL_DOES_CONVERSIONS
1259 /* convert peer_CN from UTF8 */
1261 rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
1262 /* Curl_convert_from_utf8 calls failf if unsuccessful */
1263 if(rc != CURLE_OK) {
1264 OPENSSL_free(peer_CN);
1268 #endif /* CURL_DOES_CONVERSIONS */
1271 /* error already detected, pass through */
1275 "SSL: unable to obtain common name from peer certificate");
1276 res = CURLE_PEER_FAILED_VERIFICATION;
1278 else if(!cert_hostcheck((const char *)peer_CN, conn->host.name)) {
1279 if(data->set.ssl.verifyhost > 1) {
1280 failf(data, "SSL: certificate subject name '%s' does not match "
1281 "target host name '%s'", peer_CN, conn->host.dispname);
1282 res = CURLE_PEER_FAILED_VERIFICATION;
1285 infof(data, "\t common name: %s (does not match '%s')\n",
1286 peer_CN, conn->host.dispname);
1289 infof(data, "\t common name: %s (matched)\n", peer_CN);
1292 OPENSSL_free(peer_CN);
1296 #endif /* USE_SSLEAY */
1298 /* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
1299 and thus this cannot be done there. */
1300 #ifdef SSL_CTRL_SET_MSG_CALLBACK
1302 static const char *ssl_msg_type(int ssl_ver, int msg)
1304 if(ssl_ver == SSL2_VERSION_MAJOR) {
1308 case SSL2_MT_CLIENT_HELLO:
1309 return "Client hello";
1310 case SSL2_MT_CLIENT_MASTER_KEY:
1311 return "Client key";
1312 case SSL2_MT_CLIENT_FINISHED:
1313 return "Client finished";
1314 case SSL2_MT_SERVER_HELLO:
1315 return "Server hello";
1316 case SSL2_MT_SERVER_VERIFY:
1317 return "Server verify";
1318 case SSL2_MT_SERVER_FINISHED:
1319 return "Server finished";
1320 case SSL2_MT_REQUEST_CERTIFICATE:
1321 return "Request CERT";
1322 case SSL2_MT_CLIENT_CERTIFICATE:
1323 return "Client CERT";
1326 else if(ssl_ver == SSL3_VERSION_MAJOR) {
1328 case SSL3_MT_HELLO_REQUEST:
1329 return "Hello request";
1330 case SSL3_MT_CLIENT_HELLO:
1331 return "Client hello";
1332 case SSL3_MT_SERVER_HELLO:
1333 return "Server hello";
1334 case SSL3_MT_CERTIFICATE:
1336 case SSL3_MT_SERVER_KEY_EXCHANGE:
1337 return "Server key exchange";
1338 case SSL3_MT_CLIENT_KEY_EXCHANGE:
1339 return "Client key exchange";
1340 case SSL3_MT_CERTIFICATE_REQUEST:
1341 return "Request CERT";
1342 case SSL3_MT_SERVER_DONE:
1343 return "Server finished";
1344 case SSL3_MT_CERTIFICATE_VERIFY:
1345 return "CERT verify";
1346 case SSL3_MT_FINISHED:
1353 static const char *tls_rt_type(int type)
1356 type == SSL3_RT_CHANGE_CIPHER_SPEC ? "TLS change cipher, " :
1357 type == SSL3_RT_ALERT ? "TLS alert, " :
1358 type == SSL3_RT_HANDSHAKE ? "TLS handshake, " :
1359 type == SSL3_RT_APPLICATION_DATA ? "TLS app data, " :
1365 * Our callback from the SSL/TLS layers.
1367 static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
1368 const void *buf, size_t len, const SSL *ssl,
1369 struct connectdata *conn)
1371 struct SessionHandle *data;
1372 const char *msg_name, *tls_rt_name;
1374 int ver, msg_type, txt_len;
1376 if(!conn || !conn->data || !conn->data->set.fdebug ||
1377 (direction != 0 && direction != 1))
1382 ver = (ssl_ver == SSL2_VERSION_MAJOR ? '2' :
1383 ssl_ver == SSL3_VERSION_MAJOR ? '3' : '?');
1385 /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
1386 * always pass-up content-type as 0. But the interesting message-type
1389 if(ssl_ver == SSL3_VERSION_MAJOR && content_type != 0)
1390 tls_rt_name = tls_rt_type(content_type);
1394 msg_type = *(char*)buf;
1395 msg_name = ssl_msg_type(ssl_ver, msg_type);
1397 txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n",
1398 ver, tls_rt_name, msg_name, msg_type);
1399 Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
1401 Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
1402 CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
1408 /* ====================================================== */
1410 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1411 # define use_sni(x) sni = (x)
1413 # define use_sni(x) do { } while (0)
1417 ossl_connect_step1(struct connectdata *conn,
1420 CURLcode retcode = CURLE_OK;
1422 struct SessionHandle *data = conn->data;
1423 SSL_METHOD_QUAL SSL_METHOD *req_method=NULL;
1424 void *ssl_sessionid=NULL;
1425 X509_LOOKUP *lookup=NULL;
1426 curl_socket_t sockfd = conn->sock[sockindex];
1427 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1428 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1431 struct in6_addr addr;
1433 struct in_addr addr;
1437 DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
1439 /* Make funny stuff to get random input */
1440 Curl_ossl_seed(data);
1442 /* check to see if we've been told to use an explicit SSL/TLS version */
1443 switch(data->set.ssl.version) {
1445 case CURL_SSLVERSION_DEFAULT:
1446 /* we try to figure out version */
1447 req_method = SSLv23_client_method();
1450 case CURL_SSLVERSION_TLSv1:
1451 req_method = TLSv1_client_method();
1454 case CURL_SSLVERSION_SSLv2:
1455 req_method = SSLv2_client_method();
1458 case CURL_SSLVERSION_SSLv3:
1459 req_method = SSLv3_client_method();
1465 SSL_CTX_free(connssl->ctx);
1466 connssl->ctx = SSL_CTX_new(req_method);
1469 failf(data, "SSL: couldn't create a context!");
1470 return CURLE_OUT_OF_MEMORY;
1473 #ifdef SSL_CTRL_SET_MSG_CALLBACK
1474 if(data->set.fdebug && data->set.verbose) {
1475 /* the SSL trace callback is only used for verbose logging so we only
1476 inform about failures of setting it */
1477 if(!SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
1478 (void (*)(void))ssl_tls_trace)) {
1479 infof(data, "SSL: couldn't set callback!\n");
1481 else if(!SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0,
1483 infof(data, "SSL: couldn't set callback argument!\n");
1488 /* OpenSSL contains code to work-around lots of bugs and flaws in various
1489 SSL-implementations. SSL_CTX_set_options() is used to enabled those
1490 work-arounds. The man page for this option states that SSL_OP_ALL enables
1491 all the work-arounds and that "It is usually safe to use SSL_OP_ALL to
1492 enable the bug workaround options if compatibility with somewhat broken
1493 implementations is desired."
1495 The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to
1496 disable "rfc4507bis session ticket support". rfc4507bis was later turned
1497 into the proper RFC5077 it seems: http://tools.ietf.org/html/rfc5077
1499 The enabled extension concerns the session management. I wonder how often
1500 libcurl stops a connection and then resumes a TLS session. also, sending
1501 the session data is some overhead. .I suggest that you just use your
1502 proposed patch (which explicitly disables TICKET).
1504 If someone writes an application with libcurl and openssl who wants to
1505 enable the feature, one can do this in the SSL callback.
1508 #ifdef SSL_OP_NO_TICKET
1509 /* expect older openssl releases to not have this define so only use it if
1511 #define CURL_CTX_OPTIONS SSL_OP_ALL|SSL_OP_NO_TICKET
1513 #define CURL_CTX_OPTIONS SSL_OP_ALL
1516 SSL_CTX_set_options(connssl->ctx, CURL_CTX_OPTIONS);
1518 /* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
1519 if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
1520 SSL_CTX_set_options(connssl->ctx, SSL_OP_NO_SSLv2);
1524 * Not sure it's needed to tell SSL_connect() that socket is
1525 * non-blocking. It doesn't seem to care, but just return with
1528 if(data->state.used_interface == Curl_if_multi)
1529 SSL_CTX_ctrl(connssl->ctx, BIO_C_SET_NBIO, 1, NULL);
1532 if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) {
1533 if(!cert_stuff(conn,
1535 data->set.str[STRING_CERT],
1536 data->set.str[STRING_CERT_TYPE],
1537 data->set.str[STRING_KEY],
1538 data->set.str[STRING_KEY_TYPE])) {
1539 /* failf() is already done in cert_stuff() */
1540 return CURLE_SSL_CERTPROBLEM;
1544 if(data->set.str[STRING_SSL_CIPHER_LIST]) {
1545 if(!SSL_CTX_set_cipher_list(connssl->ctx,
1546 data->set.str[STRING_SSL_CIPHER_LIST])) {
1547 failf(data, "failed setting cipher list");
1548 return CURLE_SSL_CIPHER;
1552 if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) {
1553 /* tell SSL where to find CA certificates that are used to verify
1554 the servers certificate. */
1555 if(!SSL_CTX_load_verify_locations(connssl->ctx,
1556 data->set.str[STRING_SSL_CAFILE],
1557 data->set.str[STRING_SSL_CAPATH])) {
1558 if(data->set.ssl.verifypeer) {
1559 /* Fail if we insist on successfully verifying the server. */
1560 failf(data,"error setting certificate verify locations:\n"
1561 " CAfile: %s\n CApath: %s\n",
1562 data->set.str[STRING_SSL_CAFILE]?
1563 data->set.str[STRING_SSL_CAFILE]: "none",
1564 data->set.str[STRING_SSL_CAPATH]?
1565 data->set.str[STRING_SSL_CAPATH] : "none");
1566 return CURLE_SSL_CACERT_BADFILE;
1569 /* Just continue with a warning if no strict certificate verification
1571 infof(data, "error setting certificate verify locations,"
1572 " continuing anyway:\n");
1576 /* Everything is fine. */
1577 infof(data, "successfully set certificate verify locations:\n");
1582 data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
1584 data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
1588 if (data->set.str[STRING_SSL_CRLFILE]) {
1589 /* tell SSL where to find CRL file that is used to check certificate
1591 lookup=X509_STORE_add_lookup(connssl->ctx->cert_store,X509_LOOKUP_file());
1593 (!X509_load_crl_file(lookup,data->set.str[STRING_SSL_CRLFILE],
1594 X509_FILETYPE_PEM)) ) {
1595 failf(data,"error loading CRL file :\n"
1597 data->set.str[STRING_SSL_CRLFILE]?
1598 data->set.str[STRING_SSL_CRLFILE]: "none");
1599 return CURLE_SSL_CRL_BADFILE;
1602 /* Everything is fine. */
1603 infof(data, "successfully load CRL file:\n");
1604 X509_STORE_set_flags(connssl->ctx->cert_store,
1605 X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1608 " CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
1609 data->set.str[STRING_SSL_CRLFILE]: "none");
1612 /* SSL always tries to verify the peer, this only says whether it should
1613 * fail to connect if the verification fails, or if it should continue
1614 * anyway. In the latter case the result of the verification is checked with
1615 * SSL_get_verify_result() below. */
1616 SSL_CTX_set_verify(connssl->ctx,
1617 data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
1618 cert_verify_callback);
1620 /* give application a chance to interfere with SSL set up. */
1621 if(data->set.ssl.fsslctx) {
1622 retcode = (*data->set.ssl.fsslctx)(data, connssl->ctx,
1623 data->set.ssl.fsslctxp);
1625 failf(data,"error signaled by ssl ctx callback");
1630 /* Lets make an SSL structure */
1632 SSL_free(connssl->handle);
1633 connssl->handle = SSL_new(connssl->ctx);
1634 if(!connssl->handle) {
1635 failf(data, "SSL: couldn't create a context (handle)!");
1636 return CURLE_OUT_OF_MEMORY;
1638 SSL_set_connect_state(connssl->handle);
1640 connssl->server_cert = 0x0;
1642 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1643 if ((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
1645 (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
1648 !SSL_set_tlsext_host_name(connssl->handle, conn->host.name))
1649 infof(data, "WARNING: failed to configure server name indication (SNI) "
1653 /* Check if there's a cached ID we can/should use here! */
1654 if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
1655 /* we got a session id, use it! */
1656 if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
1657 failf(data, "SSL: SSL_set_session failed: %s",
1658 ERR_error_string(ERR_get_error(),NULL));
1659 return CURLE_SSL_CONNECT_ERROR;
1661 /* Informational message */
1662 infof (data, "SSL re-using session ID\n");
1665 /* pass the raw socket into the SSL layers */
1666 if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
1667 failf(data, "SSL: SSL_set_fd failed: %s",
1668 ERR_error_string(ERR_get_error(),NULL));
1669 return CURLE_SSL_CONNECT_ERROR;
1672 connssl->connecting_state = ssl_connect_2;
1677 ossl_connect_step2(struct connectdata *conn, int sockindex)
1679 struct SessionHandle *data = conn->data;
1681 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1683 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1684 || ssl_connect_2_reading == connssl->connecting_state
1685 || ssl_connect_2_writing == connssl->connecting_state);
1687 err = SSL_connect(connssl->handle);
1690 0 is "not successful but was shut down controlled"
1691 <0 is "handshake was not successful, because a fatal error occurred" */
1693 int detail = SSL_get_error(connssl->handle, err);
1695 if(SSL_ERROR_WANT_READ == detail) {
1696 connssl->connecting_state = ssl_connect_2_reading;
1699 else if(SSL_ERROR_WANT_WRITE == detail) {
1700 connssl->connecting_state = ssl_connect_2_writing;
1704 /* untreated error */
1705 unsigned long errdetail;
1706 char error_buffer[256]; /* OpenSSL documents that this must be at least
1709 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 cert_problem = "SSL certificate problem, verify that the CA cert is"
1733 rc = CURLE_SSL_CACERT;
1736 rc = CURLE_SSL_CONNECT_ERROR;
1740 /* detail is already set to the SSL error above */
1742 /* If we e.g. use SSLv2 request-method and the server doesn't like us
1743 * (RST connection etc.), OpenSSL gives no explanation whatsoever and
1744 * the SO_ERROR is also lost.
1746 if(CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
1747 failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
1748 conn->host.name, conn->port);
1751 /* Could be a CERT problem */
1753 SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
1754 failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
1759 /* we have been connected fine, we're not waiting for anything else. */
1760 connssl->connecting_state = ssl_connect_3;
1762 /* Informational message */
1763 infof (data, "SSL connection using %s\n",
1764 SSL_get_cipher(connssl->handle));
1770 static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
1774 if((ilen = (int)len) < 0)
1775 return 1; /* buffer too big */
1777 i = i2t_ASN1_OBJECT(buf, ilen, a);
1780 return 1; /* buffer too small */
1785 static CURLcode push_certinfo_len(struct SessionHandle *data,
1791 struct curl_certinfo *ci = &data->info.certs;
1793 struct curl_slist *nl;
1794 CURLcode res = CURLE_OK;
1795 size_t labellen = strlen(label);
1796 size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
1798 output = malloc(outlen);
1800 return CURLE_OUT_OF_MEMORY;
1802 /* sprintf the label and colon */
1803 snprintf(output, outlen, "%s:", label);
1805 /* memcpy the value (it might not be zero terminated) */
1806 memcpy(&output[labellen+1], value, valuelen);
1808 /* zero terminate the output */
1809 output[labellen + 1 + valuelen] = 0;
1811 /* TODO: we should rather introduce an internal API that can do the
1812 equivalent of curl_slist_append but doesn't strdup() the given data as
1813 like in this place the extra malloc/free is totally pointless */
1814 nl = curl_slist_append(ci->certinfo[certnum], output);
1816 curl_slist_free_all(ci->certinfo[certnum]);
1817 res = CURLE_OUT_OF_MEMORY;
1820 ci->certinfo[certnum] = nl;
1827 /* this is a convenience function for push_certinfo_len that takes a zero
1829 static CURLcode push_certinfo(struct SessionHandle *data,
1834 size_t valuelen = strlen(value);
1836 return push_certinfo_len(data, certnum, label, value, valuelen);
1839 static void pubkey_show(struct SessionHandle *data,
1847 size_t left = sizeof(buffer);
1852 snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
1854 for(i=0; i< len; i++) {
1855 snprintf(ptr, left, "%02x:", raw[i]);
1859 infof(data, " %s: %s\n", namebuf, buffer);
1860 push_certinfo(data, num, namebuf, buffer);
1863 #define print_pubkey_BN(_type, _name, _num) \
1865 if (pubkey->pkey._type->_name != NULL) { \
1866 int len = BN_num_bytes(pubkey->pkey._type->_name); \
1867 if(len < (int)sizeof(buf)) { \
1868 BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)buf); \
1870 pubkey_show(data, _num, #_type, #_name, (unsigned char*)buf, len); \
1875 static int X509V3_ext(struct SessionHandle *data,
1877 STACK_OF(X509_EXTENSION) *exts)
1882 if(sk_X509_EXTENSION_num(exts) <= 0)
1883 /* no extensions, bail out */
1886 for (i=0; i<sk_X509_EXTENSION_num(exts); i++) {
1888 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
1893 BIO *bio_out = BIO_new(BIO_s_mem());
1898 obj = X509_EXTENSION_get_object(ext);
1900 asn1_object_dump(obj, namebuf, sizeof(namebuf));
1902 infof(data, "%s: %s\n", namebuf,
1903 X509_EXTENSION_get_critical(ext)?"(critical)":"");
1905 if(!X509V3_EXT_print(bio_out, ext, 0, 0))
1906 M_ASN1_OCTET_STRING_print(bio_out, ext->value);
1908 BIO_get_mem_ptr(bio_out, &biomem);
1910 /* biomem->length bytes at biomem->data, this little loop here is only
1911 done for the infof() call, we send the "raw" data to the certinfo
1913 for(j=0; j<(size_t)biomem->length; j++) {
1915 if(biomem->data[j] == '\n') {
1917 j++; /* skip the newline */
1919 while((biomem->data[j] == ' ') && (j<(size_t)biomem->length))
1921 if(j<(size_t)biomem->length)
1922 ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep, biomem->data[j]);
1924 infof(data, " %s\n", buf);
1926 push_certinfo(data, certnum, namebuf, buf);
1931 return 0; /* all is fine */
1935 static void X509_signature(struct SessionHandle *data,
1942 for (i=0; i<sig->length; i++)
1943 ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%02x:", sig->data[i]);
1945 infof(data, " Signature: %s\n", buf);
1946 push_certinfo(data, numcert, "Signature", buf);
1949 static void dumpcert(struct SessionHandle *data, X509 *x, int numcert)
1951 BIO *bio_out = BIO_new(BIO_s_mem());
1954 /* this outputs the cert in this 64 column wide style with newlines and
1955 -----BEGIN CERTIFICATE----- texts and more */
1956 PEM_write_bio_X509(bio_out, x);
1958 BIO_get_mem_ptr(bio_out, &biomem);
1960 infof(data, "%s\n", biomem->data);
1962 push_certinfo_len(data, numcert, "Cert", biomem->data, biomem->length);
1969 static int init_certinfo(struct SessionHandle *data,
1972 struct curl_certinfo *ci = &data->info.certs;
1973 struct curl_slist **table;
1975 Curl_ssl_free_certinfo(data);
1977 ci->num_of_certs = num;
1978 table = calloc((size_t)num, sizeof(struct curl_slist *));
1982 ci->certinfo = table;
1986 static CURLcode get_cert_chain(struct connectdata *conn,
1987 struct ssl_connect_data *connssl)
1993 struct SessionHandle *data = conn->data;
1996 sk = SSL_get_peer_cert_chain(connssl->handle);
1999 return CURLE_OUT_OF_MEMORY;
2001 numcerts = sk_X509_num(sk);
2003 if(init_certinfo(data, numcerts))
2004 return CURLE_OUT_OF_MEMORY;
2006 infof(data, "--- Certificate chain\n");
2007 for (i=0; i<numcerts; i++) {
2010 ASN1_TIME *certdate;
2012 /* get the certs in "importance order" */
2014 X509 *x = sk_X509_value(sk, numcerts - i - 1);
2016 X509 *x = sk_X509_value(sk, i);
2020 EVP_PKEY *pubkey=NULL;
2024 (void)x509_name_oneline(X509_get_subject_name(x), buf, sizeof(buf));
2025 infof(data, "%2d Subject: %s\n",i,buf);
2026 push_certinfo(data, i, "Subject", buf);
2028 (void)x509_name_oneline(X509_get_issuer_name(x), buf, sizeof(buf));
2029 infof(data, " Issuer: %s\n",buf);
2030 push_certinfo(data, i, "Issuer", buf);
2032 value = X509_get_version(x);
2033 infof(data, " Version: %lu (0x%lx)\n", value+1, value);
2034 snprintf(buf, sizeof(buf), "%lx", value);
2035 push_certinfo(data, i, "Version", buf); /* hex */
2037 num=X509_get_serialNumber(x);
2038 if (num->length <= 4) {
2039 value = ASN1_INTEGER_get(num);
2040 infof(data," Serial Number: %ld (0x%lx)\n", value, value);
2041 snprintf(buf, sizeof(buf), "%lx", value);
2047 if(num->type == V_ASN1_NEG_INTEGER)
2050 for (j=0; j<num->length; j++) {
2051 /* TODO: length restrictions */
2052 snprintf(ptr, 3, "%02x%c",num->data[j],
2053 ((j+1 == num->length)?'\n':':'));
2057 infof(data," Serial Number: %s\n", buf);
2062 push_certinfo(data, i, "Serial Number", buf); /* hex */
2064 cinf = x->cert_info;
2066 j = asn1_object_dump(cinf->signature->algorithm, buf, sizeof(buf));
2068 infof(data, " Signature Algorithm: %s\n", buf);
2069 push_certinfo(data, i, "Signature Algorithm", buf);
2072 certdate = X509_get_notBefore(x);
2073 asn1_output(certdate, buf, sizeof(buf));
2074 infof(data, " Start date: %s\n", buf);
2075 push_certinfo(data, i, "Start date", buf);
2077 certdate = X509_get_notAfter(x);
2078 asn1_output(certdate, buf, sizeof(buf));
2079 infof(data, " Expire date: %s\n", buf);
2080 push_certinfo(data, i, "Expire date", buf);
2082 j = asn1_object_dump(cinf->key->algor->algorithm, buf, sizeof(buf));
2084 infof(data, " Public Key Algorithm: %s\n", buf);
2085 push_certinfo(data, i, "Public Key Algorithm", buf);
2088 pubkey = X509_get_pubkey(x);
2090 infof(data, " Unable to load public key\n");
2092 switch(pubkey->type) {
2094 infof(data, " RSA Public Key (%d bits)\n",
2095 BN_num_bits(pubkey->pkey.rsa->n));
2096 snprintf(buf, sizeof(buf), "%d", BN_num_bits(pubkey->pkey.rsa->n));
2097 push_certinfo(data, i, "RSA Public Key", buf);
2099 print_pubkey_BN(rsa, n, i);
2100 print_pubkey_BN(rsa, e, i);
2101 print_pubkey_BN(rsa, d, i);
2102 print_pubkey_BN(rsa, p, i);
2103 print_pubkey_BN(rsa, q, i);
2104 print_pubkey_BN(rsa, dmp1, i);
2105 print_pubkey_BN(rsa, dmq1, i);
2106 print_pubkey_BN(rsa, iqmp, i);
2109 print_pubkey_BN(dsa, p, i);
2110 print_pubkey_BN(dsa, q, i);
2111 print_pubkey_BN(dsa, g, i);
2112 print_pubkey_BN(dsa, priv_key, i);
2113 print_pubkey_BN(dsa, pub_key, i);
2116 print_pubkey_BN(dh, p, i);
2117 print_pubkey_BN(dh, g, i);
2118 print_pubkey_BN(dh, priv_key, i);
2119 print_pubkey_BN(dh, pub_key, i);
2122 case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
2127 EVP_PKEY_free(pubkey);
2130 X509V3_ext(data, i, cinf->extensions);
2132 X509_signature(data, i, x->signature);
2134 dumpcert(data, x, i);
2141 * Get the server cert, verify it and show it etc, only call failf() if the
2142 * 'strict' argument is TRUE as otherwise all this is for informational
2145 * We check certificates to authenticate the server; otherwise we risk
2146 * man-in-the-middle attack.
2148 static CURLcode servercert(struct connectdata *conn,
2149 struct ssl_connect_data *connssl,
2152 CURLcode retcode = CURLE_OK;
2155 ASN1_TIME *certdate;
2156 struct SessionHandle *data = conn->data;
2161 if(data->set.ssl.certinfo)
2162 /* we've been asked to gather certificate info! */
2163 (void)get_cert_chain(conn, connssl);
2165 data->set.ssl.certverifyresult = !X509_V_OK;
2167 connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
2168 if(!connssl->server_cert) {
2170 failf(data, "SSL: couldn't get peer certificate!");
2171 return CURLE_PEER_FAILED_VERIFICATION;
2173 infof (data, "Server certificate:\n");
2175 rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
2176 buffer, sizeof(buffer));
2179 failf(data, "SSL: couldn't get X509-subject!");
2180 X509_free(connssl->server_cert);
2181 connssl->server_cert = NULL;
2182 return CURLE_SSL_CONNECT_ERROR;
2184 infof(data, "\t subject: %s\n", buffer);
2186 certdate = X509_get_notBefore(connssl->server_cert);
2187 asn1_output(certdate, buffer, sizeof(buffer));
2188 infof(data, "\t start date: %s\n", buffer);
2190 certdate = X509_get_notAfter(connssl->server_cert);
2191 asn1_output(certdate, buffer, sizeof(buffer));
2192 infof(data, "\t expire date: %s\n", buffer);
2194 if(data->set.ssl.verifyhost) {
2195 retcode = verifyhost(conn, connssl->server_cert);
2197 X509_free(connssl->server_cert);
2198 connssl->server_cert = NULL;
2203 rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert),
2204 buffer, sizeof(buffer));
2207 failf(data, "SSL: couldn't get X509-issuer name!");
2208 retcode = CURLE_SSL_CONNECT_ERROR;
2211 infof(data, "\t issuer: %s\n", buffer);
2213 /* We could do all sorts of certificate verification stuff here before
2214 deallocating the certificate. */
2216 /* e.g. match issuer name with provided issuer certificate */
2217 if (data->set.str[STRING_SSL_ISSUERCERT]) {
2218 if (! (fp=fopen(data->set.str[STRING_SSL_ISSUERCERT],"r"))) {
2220 failf(data, "SSL: Unable to open issuer cert (%s)\n",
2221 data->set.str[STRING_SSL_ISSUERCERT]);
2222 X509_free(connssl->server_cert);
2223 connssl->server_cert = NULL;
2224 return CURLE_SSL_ISSUER_ERROR;
2226 issuer = PEM_read_X509(fp,NULL,ZERO_NULL,NULL);
2229 failf(data, "SSL: Unable to read issuer cert (%s)\n",
2230 data->set.str[STRING_SSL_ISSUERCERT]);
2231 X509_free(connssl->server_cert);
2234 return CURLE_SSL_ISSUER_ERROR;
2237 if (X509_check_issued(issuer,connssl->server_cert) != X509_V_OK) {
2239 failf(data, "SSL: Certificate issuer check failed (%s)\n",
2240 data->set.str[STRING_SSL_ISSUERCERT]);
2241 X509_free(connssl->server_cert);
2243 connssl->server_cert = NULL;
2244 return CURLE_SSL_ISSUER_ERROR;
2246 infof(data, "\t SSL certificate issuer check ok (%s)\n",
2247 data->set.str[STRING_SSL_ISSUERCERT]);
2251 lerr = data->set.ssl.certverifyresult=
2252 SSL_get_verify_result(connssl->handle);
2253 if(data->set.ssl.certverifyresult != X509_V_OK) {
2254 if(data->set.ssl.verifypeer) {
2255 /* We probably never reach this, because SSL_connect() will fail
2256 and we return earlier if verifypeer is set? */
2258 failf(data, "SSL certificate verify result: %s (%ld)",
2259 X509_verify_cert_error_string(lerr), lerr);
2260 retcode = CURLE_PEER_FAILED_VERIFICATION;
2263 infof(data, "\t SSL certificate verify result: %s (%ld),"
2264 " continuing anyway.\n",
2265 X509_verify_cert_error_string(lerr), lerr);
2268 infof(data, "\t SSL certificate verify ok.\n");
2271 X509_free(connssl->server_cert);
2272 connssl->server_cert = NULL;
2273 connssl->connecting_state = ssl_connect_done;
2280 ossl_connect_step3(struct connectdata *conn,
2283 CURLcode retcode = CURLE_OK;
2284 void *old_ssl_sessionid=NULL;
2285 struct SessionHandle *data = conn->data;
2286 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2288 SSL_SESSION *our_ssl_sessionid;
2290 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
2292 #ifdef HAVE_SSL_GET1_SESSION
2293 our_ssl_sessionid = SSL_get1_session(connssl->handle);
2295 /* SSL_get1_session() will increment the reference
2296 count and the session will stay in memory until explicitly freed with
2297 SSL_SESSION_free(3), regardless of its state.
2298 This function was introduced in openssl 0.9.5a. */
2300 our_ssl_sessionid = SSL_get_session(connssl->handle);
2302 /* if SSL_get1_session() is unavailable, use SSL_get_session().
2303 This is an inferior option because the session can be flushed
2304 at any time by openssl. It is included only so curl compiles
2305 under versions of openssl < 0.9.5a.
2307 WARNING: How curl behaves if it's session is flushed is
2312 incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
2314 if (old_ssl_sessionid != our_ssl_sessionid) {
2315 infof(data, "old SSL session ID is stale, removing\n");
2316 Curl_ssl_delsessionid(conn, old_ssl_sessionid);
2321 retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
2322 0 /* unknown size */);
2324 failf(data, "failed to store ssl session");
2328 #ifdef HAVE_SSL_GET1_SESSION
2330 /* Session was incache, so refcount already incremented earlier.
2331 * Avoid further increments with each SSL_get1_session() call.
2332 * This does not free the session as refcount remains > 0
2334 SSL_SESSION_free(our_ssl_sessionid);
2339 * We check certificates to authenticate the server; otherwise we risk
2340 * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to
2341 * verify the peer ignore faults and failures from the server cert
2345 if(!data->set.ssl.verifypeer)
2346 (void)servercert(conn, connssl, FALSE);
2348 retcode = servercert(conn, connssl, TRUE);
2350 if(CURLE_OK == retcode)
2351 connssl->connecting_state = ssl_connect_done;
2355 static Curl_recv ossl_recv;
2356 static Curl_send ossl_send;
2359 ossl_connect_common(struct connectdata *conn,
2365 struct SessionHandle *data = conn->data;
2366 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2367 curl_socket_t sockfd = conn->sock[sockindex];
2371 if(ssl_connect_1==connssl->connecting_state) {
2372 /* Find out how much more time we're allowed */
2373 timeout_ms = Curl_timeleft(conn, NULL, TRUE);
2375 if(timeout_ms < 0) {
2376 /* no need to continue if time already is up */
2377 failf(data, "SSL connection timeout");
2378 return CURLE_OPERATION_TIMEDOUT;
2380 retcode = ossl_connect_step1(conn, sockindex);
2385 while(ssl_connect_2 == connssl->connecting_state ||
2386 ssl_connect_2_reading == connssl->connecting_state ||
2387 ssl_connect_2_writing == connssl->connecting_state) {
2389 /* check allowed time left */
2390 timeout_ms = Curl_timeleft(conn, NULL, TRUE);
2392 if(timeout_ms < 0) {
2393 /* no need to continue if time already is up */
2394 failf(data, "SSL connection timeout");
2395 return CURLE_OPERATION_TIMEDOUT;
2398 /* if ssl is expecting something, check if it's available. */
2399 if(connssl->connecting_state == ssl_connect_2_reading
2400 || connssl->connecting_state == ssl_connect_2_writing) {
2402 curl_socket_t writefd = ssl_connect_2_writing==
2403 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2404 curl_socket_t readfd = ssl_connect_2_reading==
2405 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2407 what = Curl_socket_ready(readfd, writefd,
2408 nonblocking?0:(int)timeout_ms);
2411 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2412 return CURLE_SSL_CONNECT_ERROR;
2414 else if(0 == what) {
2421 failf(data, "SSL connection timeout");
2422 return CURLE_OPERATION_TIMEDOUT;
2425 /* socket is readable or writable */
2428 /* Run transaction, and return to the caller if it failed or if
2429 * this connection is part of a multi handle and this loop would
2430 * execute again. This permits the owner of a multi handle to
2431 * abort a connection attempt before step2 has completed while
2432 * ensuring that a client using select() or epoll() will always
2433 * have a valid fdset to wait on.
2435 retcode = ossl_connect_step2(conn, sockindex);
2436 if(retcode || (data->state.used_interface == Curl_if_multi &&
2437 (ssl_connect_2 == connssl->connecting_state ||
2438 ssl_connect_2_reading == connssl->connecting_state ||
2439 ssl_connect_2_writing == connssl->connecting_state)))
2442 } /* repeat step2 until all transactions are done. */
2445 if(ssl_connect_3==connssl->connecting_state) {
2446 retcode = ossl_connect_step3(conn, sockindex);
2451 if(ssl_connect_done==connssl->connecting_state) {
2452 connssl->state = ssl_connection_complete;
2453 conn->recv[sockindex] = ossl_recv;
2454 conn->send[sockindex] = ossl_send;
2460 /* Reset our connect state machine */
2461 connssl->connecting_state = ssl_connect_1;
2467 Curl_ossl_connect_nonblocking(struct connectdata *conn,
2471 return ossl_connect_common(conn, sockindex, TRUE, done);
2475 Curl_ossl_connect(struct connectdata *conn,
2481 retcode = ossl_connect_common(conn, sockindex, FALSE, &done);
2490 bool Curl_ossl_data_pending(const struct connectdata *conn,
2493 if(conn->ssl[connindex].handle)
2495 return (bool)(0 != SSL_pending(conn->ssl[connindex].handle));
2500 static ssize_t ossl_send(struct connectdata *conn,
2506 /* SSL_write() is said to return 'int' while write() and send() returns
2509 char error_buffer[120]; /* OpenSSL documents that this must be at least 120
2511 unsigned long sslerror;
2515 memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
2516 rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
2519 err = SSL_get_error(conn->ssl[sockindex].handle, rc);
2522 case SSL_ERROR_WANT_READ:
2523 case SSL_ERROR_WANT_WRITE:
2524 /* The operation did not complete; the same TLS/SSL I/O function
2525 should be called again later. This is basicly an EWOULDBLOCK
2527 *curlcode = CURLE_AGAIN;
2529 case SSL_ERROR_SYSCALL:
2530 failf(conn->data, "SSL_write() returned SYSCALL, errno = %d",
2532 *curlcode = CURLE_SEND_ERROR;
2535 /* A failure in the SSL library occurred, usually a protocol error.
2536 The OpenSSL error queue contains more information on the error. */
2537 sslerror = ERR_get_error();
2538 failf(conn->data, "SSL_write() error: %s",
2539 ERR_error_string(sslerror, error_buffer));
2540 *curlcode = CURLE_SEND_ERROR;
2544 failf(conn->data, "SSL_write() return error %d", err);
2545 *curlcode = CURLE_SEND_ERROR;
2548 return (ssize_t)rc; /* number of bytes */
2551 static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
2552 int num, /* socketindex */
2553 char *buf, /* store read data here */
2554 size_t buffersize, /* max amount to read */
2557 char error_buffer[120]; /* OpenSSL documents that this must be at
2558 least 120 bytes long. */
2559 unsigned long sslerror;
2563 buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
2564 nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize);
2566 /* failed SSL_read */
2567 int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
2570 case SSL_ERROR_NONE: /* this is not an error */
2571 case SSL_ERROR_ZERO_RETURN: /* no more data */
2573 case SSL_ERROR_WANT_READ:
2574 case SSL_ERROR_WANT_WRITE:
2575 /* there's data pending, re-invoke SSL_read() */
2576 *curlcode = CURLE_AGAIN;
2579 /* openssl/ssl.h says "look at error stack/return value/errno" */
2580 sslerror = ERR_get_error();
2581 failf(conn->data, "SSL read: %s, errno %d",
2582 ERR_error_string(sslerror, error_buffer),
2584 *curlcode = CURLE_RECV_ERROR;
2591 size_t Curl_ossl_version(char *buffer, size_t size)
2593 #ifdef YASSL_VERSION
2594 /* yassl provides an OpenSSL API compatiblity layer so it looks identical
2595 to OpenSSL in all other aspects */
2596 return snprintf(buffer, size, "yassl/%s", YASSL_VERSION);
2597 #else /* YASSL_VERSION */
2599 #if(SSLEAY_VERSION_NUMBER >= 0x905000)
2602 unsigned long ssleay_value;
2604 ssleay_value=SSLeay();
2605 if(ssleay_value < 0x906000) {
2606 ssleay_value=SSLEAY_VERSION_NUMBER;
2610 if(ssleay_value&0xff0) {
2611 sub[0]=(char)(((ssleay_value>>4)&0xff) + 'a' -1);
2617 return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx%s",
2618 (ssleay_value>>28)&0xf,
2619 (ssleay_value>>20)&0xff,
2620 (ssleay_value>>12)&0xff,
2624 #else /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
2626 #if(SSLEAY_VERSION_NUMBER >= 0x900000)
2627 return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx",
2628 (SSLEAY_VERSION_NUMBER>>28)&0xff,
2629 (SSLEAY_VERSION_NUMBER>>20)&0xff,
2630 (SSLEAY_VERSION_NUMBER>>12)&0xf);
2632 #else /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
2636 if(SSLEAY_VERSION_NUMBER&0x0f) {
2637 sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
2642 return snprintf(buffer, size, "SSL/%x.%x.%x%s",
2643 (SSLEAY_VERSION_NUMBER>>12)&0xff,
2644 (SSLEAY_VERSION_NUMBER>>8)&0xf,
2645 (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
2647 #endif /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
2648 #endif /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
2650 #endif /* YASSL_VERSION */
2652 #endif /* USE_SSLEAY */