Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Utilities / cmcurl / ssluse.c
blob02354357a30b7b8208e2c2b3f4228d9a9897a41e
1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2007, 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 * $Id: ssluse.c,v 1.2 2007/03/15 19:22:13 andy Exp $
22 ***************************************************************************/
25 * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code
26 * but sslgen.c should ever call or use these functions.
30 * The original SSLeay-using code for curl was written by Linas Vepstas and
31 * Sampo Kellomaki 1998.
34 #include "setup.h"
36 #include <string.h>
37 #include <stdlib.h>
38 #include <ctype.h>
39 #ifdef HAVE_SYS_TYPES_H
40 #include <sys/types.h>
41 #endif
42 #ifdef HAVE_SYS_SOCKET_H
43 #include <sys/socket.h>
44 #endif
46 #include "urldata.h"
47 #include "sendf.h"
48 #include "formdata.h" /* for the boundary function */
49 #include "url.h" /* for the ssl config check function */
50 #include "inet_pton.h"
51 #include "ssluse.h"
52 #include "connect.h" /* Curl_sockerrno() proto */
53 #include "strequal.h"
54 #include "select.h"
55 #include "sslgen.h"
57 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
58 #include <curl/mprintf.h>
60 #ifdef USE_SSLEAY
62 #ifdef USE_OPENSSL
63 #include <openssl/rand.h>
64 #include <openssl/x509v3.h>
65 #else
66 #include <rand.h>
67 #include <x509v3.h>
68 #endif
70 #include "memory.h"
71 #include "easyif.h" /* for Curl_convert_from_utf8 prototype */
73 /* The last #include file should be: */
74 #include "memdebug.h"
76 #ifndef min
77 #define min(a, b) ((a) < (b) ? (a) : (b))
78 #endif
80 #if OPENSSL_VERSION_NUMBER >= 0x0090581fL
81 #define HAVE_SSL_GET1_SESSION 1
82 #else
83 #undef HAVE_SSL_GET1_SESSION
84 #endif
86 #if OPENSSL_VERSION_NUMBER >= 0x00904100L
87 #define HAVE_USERDATA_IN_PWD_CALLBACK 1
88 #else
89 #undef HAVE_USERDATA_IN_PWD_CALLBACK
90 #endif
92 #if OPENSSL_VERSION_NUMBER >= 0x00907001L
93 /* ENGINE_load_private_key() takes four arguments */
94 #define HAVE_ENGINE_LOAD_FOUR_ARGS
95 #else
96 /* ENGINE_load_private_key() takes three arguments */
97 #undef HAVE_ENGINE_LOAD_FOUR_ARGS
98 #endif
100 #if (OPENSSL_VERSION_NUMBER >= 0x00903001L) && defined(HAVE_OPENSSL_PKCS12_H)
101 /* OpenSSL has PKCS 12 support */
102 #define HAVE_PKCS12_SUPPORT
103 #else
104 /* OpenSSL/SSLEay does not have PKCS12 support */
105 #undef HAVE_PKCS12_SUPPORT
106 #endif
108 #if OPENSSL_VERSION_NUMBER >= 0x00906001L
109 #define HAVE_ERR_ERROR_STRING_N 1
110 #endif
112 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
113 #define SSL_METHOD_QUAL const
114 #else
115 #define SSL_METHOD_QUAL
116 #endif
119 * Number of bytes to read from the random number seed file. This must be
120 * a finite value (because some entropy "files" like /dev/urandom have
121 * an infinite length), but must be large enough to provide enough
122 * entopy to properly seed OpenSSL's PRNG.
124 #define RAND_LOAD_LENGTH 1024
126 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
127 static char global_passwd[64];
128 #endif
130 static int passwd_callback(char *buf, int num, int verify
131 #if HAVE_USERDATA_IN_PWD_CALLBACK
132 /* This was introduced in 0.9.4, we can set this
133 using SSL_CTX_set_default_passwd_cb_userdata()
135 , void *global_passwd
136 #endif
139 if(verify)
140 fprintf(stderr, "%s\n", buf);
141 else {
142 if(num > (int)strlen((char *)global_passwd)) {
143 strcpy(buf, global_passwd);
144 return (int)strlen(buf);
147 return 0;
151 * rand_enough() is a function that returns TRUE if we have seeded the random
152 * engine properly. We use some preprocessor magic to provide a seed_enough()
153 * macro to use, just to prevent a compiler warning on this function if we
154 * pass in an argument that is never used.
157 #ifdef HAVE_RAND_STATUS
158 #define seed_enough(x) rand_enough()
159 static bool rand_enough(void)
161 return (bool)(0 != RAND_status());
163 #else
164 #define seed_enough(x) rand_enough(x)
165 static bool rand_enough(int nread)
167 /* this is a very silly decision to make */
168 return (bool)(nread > 500);
170 #endif
172 static int ossl_seed(struct SessionHandle *data)
174 char *buf = data->state.buffer; /* point to the big buffer */
175 int nread=0;
177 /* Q: should we add support for a random file name as a libcurl option?
178 A: Yes, it is here */
180 #ifndef RANDOM_FILE
181 /* if RANDOM_FILE isn't defined, we only perform this if an option tells
182 us to! */
183 if(data->set.ssl.random_file)
184 #define RANDOM_FILE "" /* doesn't matter won't be used */
185 #endif
187 /* let the option override the define */
188 nread += RAND_load_file((data->set.ssl.random_file?
189 data->set.ssl.random_file:RANDOM_FILE),
190 RAND_LOAD_LENGTH);
191 if(seed_enough(nread))
192 return nread;
195 #if defined(HAVE_RAND_EGD)
196 /* only available in OpenSSL 0.9.5 and later */
197 /* EGD_SOCKET is set at configure time or not at all */
198 #ifndef EGD_SOCKET
199 /* If we don't have the define set, we only do this if the egd-option
200 is set */
201 if(data->set.ssl.egdsocket)
202 #define EGD_SOCKET "" /* doesn't matter won't be used */
203 #endif
205 /* If there's an option and a define, the option overrides the
206 define */
207 int ret = RAND_egd(data->set.ssl.egdsocket?
208 data->set.ssl.egdsocket:EGD_SOCKET);
209 if(-1 != ret) {
210 nread += ret;
211 if(seed_enough(nread))
212 return nread;
215 #endif
217 /* If we get here, it means we need to seed the PRNG using a "silly"
218 approach! */
219 #ifdef HAVE_RAND_SCREEN
220 /* This one gets a random value by reading the currently shown screen */
221 RAND_screen();
222 nread = 100; /* just a value */
223 #else
225 int len;
226 char *area;
228 /* Changed call to RAND_seed to use the underlying RAND_add implementation
229 * directly. Do this in a loop, with the amount of additional entropy
230 * being dependent upon the algorithm used by Curl_FormBoundary(): N bytes
231 * of a 7-bit ascii set. -- Richard Gorton, March 11 2003.
234 do {
235 area = Curl_FormBoundary();
236 if(!area)
237 return 3; /* out of memory */
239 len = (int)strlen(area);
240 RAND_add(area, len, (len >> 1));
242 free(area); /* now remove the random junk */
243 } while (!RAND_status());
245 #endif
247 /* generates a default path for the random seed file */
248 buf[0]=0; /* blank it first */
249 RAND_file_name(buf, BUFSIZE);
250 if(buf[0]) {
251 /* we got a file name to try */
252 nread += RAND_load_file(buf, RAND_LOAD_LENGTH);
253 if(seed_enough(nread))
254 return nread;
257 infof(data, "libcurl is now using a weak random seed!\n");
258 return nread;
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.ssl.random_file || data->set.ssl.egdsocket) {
268 ossl_seed(data);
269 ssl_seeded = TRUE;
271 return 0;
275 #ifndef SSL_FILETYPE_ENGINE
276 #define SSL_FILETYPE_ENGINE 42
277 #endif
278 #ifndef SSL_FILETYPE_PKCS12
279 #define SSL_FILETYPE_PKCS12 43
280 #endif
281 static int do_file_type(const char *type)
283 if(!type || !type[0])
284 return SSL_FILETYPE_PEM;
285 if(curl_strequal(type, "PEM"))
286 return SSL_FILETYPE_PEM;
287 if(curl_strequal(type, "DER"))
288 return SSL_FILETYPE_ASN1;
289 if(curl_strequal(type, "ENG"))
290 return SSL_FILETYPE_ENGINE;
291 if(curl_strequal(type, "P12"))
292 return SSL_FILETYPE_PKCS12;
293 return -1;
296 static
297 int cert_stuff(struct connectdata *conn,
298 SSL_CTX* ctx,
299 char *cert_file,
300 const char *cert_type,
301 char *key_file,
302 const char *key_type)
304 struct SessionHandle *data = conn->data;
305 int file_type;
307 if(cert_file != NULL) {
308 SSL *ssl;
309 X509 *x509;
310 int cert_done = 0;
312 if(data->set.key_passwd) {
313 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
315 * If password has been given, we store that in the global
316 * area (*shudder*) for a while:
318 size_t len = strlen(data->set.key_passwd);
319 if(len < sizeof(global_passwd))
320 memcpy(global_passwd, data->set.key_passwd, len+1);
321 #else
323 * We set the password in the callback userdata
325 SSL_CTX_set_default_passwd_cb_userdata(ctx,
326 data->set.key_passwd);
327 #endif
328 /* Set passwd callback: */
329 SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
332 file_type = do_file_type(cert_type);
334 #define SSL_CLIENT_CERT_ERR \
335 "unable to use client certificate (no key found or wrong pass phrase?)"
337 switch(file_type) {
338 case SSL_FILETYPE_PEM:
339 /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
340 if(SSL_CTX_use_certificate_chain_file(ctx,
341 cert_file) != 1) {
342 failf(data, SSL_CLIENT_CERT_ERR);
343 return 0;
345 break;
347 case SSL_FILETYPE_ASN1:
348 /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
349 we use the case above for PEM so this can only be performed with
350 ASN1 files. */
351 if(SSL_CTX_use_certificate_file(ctx,
352 cert_file,
353 file_type) != 1) {
354 failf(data, SSL_CLIENT_CERT_ERR);
355 return 0;
357 break;
358 case SSL_FILETYPE_ENGINE:
359 failf(data, "file type ENG for certificate not implemented");
360 return 0;
362 case SSL_FILETYPE_PKCS12:
364 #ifdef HAVE_PKCS12_SUPPORT
365 FILE *f;
366 PKCS12 *p12;
367 EVP_PKEY *pri;
369 f = fopen(cert_file,"rb");
370 if (!f) {
371 failf(data, "could not open PKCS12 file '%s'", cert_file);
372 return 0;
374 p12 = d2i_PKCS12_fp(f, NULL);
375 fclose(f);
377 PKCS12_PBE_add();
379 if (!PKCS12_parse(p12, data->set.key_passwd, &pri, &x509, NULL)) {
380 failf(data,
381 "could not parse PKCS12 file, check password, OpenSSL error %s",
382 ERR_error_string(ERR_get_error(), NULL) );
383 return 0;
386 PKCS12_free(p12);
388 if(SSL_CTX_use_certificate(ctx, x509) != 1) {
389 failf(data, SSL_CLIENT_CERT_ERR);
390 EVP_PKEY_free(pri);
391 X509_free(x509);
392 return 0;
395 if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
396 failf(data, "unable to use private key from PKCS12 file '%s'",
397 cert_file);
398 EVP_PKEY_free(pri);
399 X509_free(x509);
400 return 0;
403 EVP_PKEY_free(pri);
404 X509_free(x509);
405 cert_done = 1;
406 break;
407 #else
408 failf(data, "file type P12 for certificate not supported");
409 return 0;
410 #endif
412 default:
413 failf(data, "not supported file type '%s' for certificate", cert_type);
414 return 0;
417 file_type = do_file_type(key_type);
419 switch(file_type) {
420 case SSL_FILETYPE_PEM:
421 if(cert_done)
422 break;
423 if(key_file == NULL)
424 /* cert & key can only be in PEM case in the same file */
425 key_file=cert_file;
426 case SSL_FILETYPE_ASN1:
427 if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
428 failf(data, "unable to set private key file: '%s' type %s\n",
429 key_file, key_type?key_type:"PEM");
430 return 0;
432 break;
433 case SSL_FILETYPE_ENGINE:
434 #ifdef HAVE_OPENSSL_ENGINE_H
435 { /* XXXX still needs some work */
436 EVP_PKEY *priv_key = NULL;
437 if(conn && conn->data && conn->data->state.engine) {
438 #ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
439 UI_METHOD *ui_method = UI_OpenSSL();
440 #endif
441 if(!key_file || !key_file[0]) {
442 failf(data, "no key set to load from crypto engine\n");
443 return 0;
445 /* the typecast below was added to please mingw32 */
446 priv_key = (EVP_PKEY *)
447 ENGINE_load_private_key(conn->data->state.engine,key_file,
448 #ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
449 ui_method,
450 #endif
451 data->set.key_passwd);
452 if(!priv_key) {
453 failf(data, "failed to load private key from crypto engine\n");
454 return 0;
456 if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
457 failf(data, "unable to set private key\n");
458 EVP_PKEY_free(priv_key);
459 return 0;
461 EVP_PKEY_free(priv_key); /* we don't need the handle any more... */
463 else {
464 failf(data, "crypto engine not set, can't load private key\n");
465 return 0;
468 break;
469 #else
470 failf(data, "file type ENG for private key not supported\n");
471 return 0;
472 #endif
473 case SSL_FILETYPE_PKCS12:
474 if(!cert_done) {
475 failf(data, "file type P12 for private key not supported\n");
476 return 0;
478 break;
479 default:
480 failf(data, "not supported file type for private key\n");
481 return 0;
484 ssl=SSL_new(ctx);
485 if (NULL == ssl) {
486 failf(data,"unable to create an SSL structure\n");
487 return 0;
490 x509=SSL_get_certificate(ssl);
492 /* This version was provided by Evan Jordan and is supposed to not
493 leak memory as the previous version: */
494 if(x509 != NULL) {
495 EVP_PKEY *pktmp = X509_get_pubkey(x509);
496 EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));
497 EVP_PKEY_free(pktmp);
500 SSL_free(ssl);
502 /* If we are using DSA, we can copy the parameters from
503 * the private key */
506 /* Now we know that a key and cert have been set against
507 * the SSL context */
508 if(!SSL_CTX_check_private_key(ctx)) {
509 failf(data, "Private key does not match the certificate public key");
510 return(0);
512 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
513 /* erase it now */
514 memset(global_passwd, 0, sizeof(global_passwd));
515 #endif
517 return(1);
520 static
521 int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
523 X509 *err_cert;
524 char buf[256];
526 err_cert=X509_STORE_CTX_get_current_cert(ctx);
527 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
528 return ok;
531 /* Return error string for last OpenSSL error
533 static char *SSL_strerror(unsigned long error, char *buf, size_t size)
535 #ifdef HAVE_ERR_ERROR_STRING_N
536 /* OpenSSL 0.9.6 and later has a function named
537 ERRO_error_string_n() that takes the size of the buffer as a
538 third argument */
539 ERR_error_string_n(error, buf, size);
540 #else
541 (void) size;
542 ERR_error_string(error, buf);
543 #endif
544 return (buf);
547 #endif /* USE_SSLEAY */
549 #ifdef USE_SSLEAY
551 * Global SSL init
553 * @retval 0 error initializing SSL
554 * @retval 1 SSL initialized successfully
556 int Curl_ossl_init(void)
558 #ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
559 ENGINE_load_builtin_engines();
560 #endif
562 /* Lets get nice error messages */
563 SSL_load_error_strings();
565 /* Setup all the global SSL stuff */
566 if (!SSLeay_add_ssl_algorithms())
567 return 0;
569 return 1;
572 #endif /* USE_SSLEAY */
574 #ifdef USE_SSLEAY
576 /* Global cleanup */
577 void Curl_ossl_cleanup(void)
579 /* Free the SSL error strings */
580 ERR_free_strings();
582 /* EVP_cleanup() removes all ciphers and digests from the
583 table. */
584 EVP_cleanup();
586 #ifdef HAVE_ENGINE_cleanup
587 ENGINE_cleanup();
588 #endif
590 #ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
591 /* this function was not present in 0.9.6b, but was added sometimes
592 later */
593 CRYPTO_cleanup_all_ex_data();
594 #endif
598 * This function uses SSL_peek to determine connection status.
600 * Return codes:
601 * 1 means the connection is still in place
602 * 0 means the connection has been closed
603 * -1 means the connection status is unknown
605 int Curl_ossl_check_cxn(struct connectdata *conn)
607 int rc;
608 char buf;
610 rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1);
611 if (rc > 0)
612 return 1; /* connection still in place */
614 if (rc == 0)
615 return 0; /* connection has been closed */
617 return -1; /* connection status unknown */
620 #endif /* USE_SSLEAY */
622 /* Selects an OpenSSL crypto engine
624 CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
626 #if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
627 ENGINE *e = ENGINE_by_id(engine);
629 if (!e) {
630 failf(data, "SSL Engine '%s' not found", engine);
631 return (CURLE_SSL_ENGINE_NOTFOUND);
634 if (data->state.engine) {
635 ENGINE_finish(data->state.engine);
636 ENGINE_free(data->state.engine);
637 data->state.engine = NULL;
639 if (!ENGINE_init(e)) {
640 char buf[256];
642 ENGINE_free(e);
643 failf(data, "Failed to initialise SSL Engine '%s':\n%s",
644 engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf)));
645 return (CURLE_SSL_ENGINE_INITFAILED);
647 data->state.engine = e;
648 return (CURLE_OK);
649 #else
650 (void)engine;
651 failf(data, "SSL Engine not supported");
652 return (CURLE_SSL_ENGINE_NOTFOUND);
653 #endif
656 #ifdef USE_SSLEAY
657 /* Sets engine as default for all SSL operations
659 CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
661 #ifdef HAVE_OPENSSL_ENGINE_H
662 if (data->state.engine) {
663 if (ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
664 infof(data,"set default crypto engine '%s'\n", ENGINE_get_id(data->state.engine));
666 else {
667 failf(data, "set default crypto engine '%s' failed", ENGINE_get_id(data->state.engine));
668 return CURLE_SSL_ENGINE_SETFAILED;
671 #else
672 (void) data;
673 #endif
674 return CURLE_OK;
676 #endif /* USE_SSLEAY */
678 /* Return list of OpenSSL crypto engine names.
680 struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
682 struct curl_slist *list = NULL;
683 #if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
684 ENGINE *e;
686 for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
687 list = curl_slist_append(list, ENGINE_get_id(e));
688 #endif
689 (void) data;
690 return (list);
694 #ifdef USE_SSLEAY
697 * This function is called when an SSL connection is closed.
699 void Curl_ossl_close(struct connectdata *conn)
701 int i;
703 ERR_remove_state() frees the error queue associated with
704 thread pid. If pid == 0, the current thread will have its
705 error queue removed.
707 Since error queue data structures are allocated
708 automatically for new threads, they must be freed when
709 threads are terminated in oder to avoid memory leaks.
711 ERR_remove_state(0);
713 for(i=0; i<2; i++) {
714 struct ssl_connect_data *connssl = &conn->ssl[i];
716 if(connssl->handle) {
717 (void)SSL_shutdown(connssl->handle);
718 SSL_set_connect_state(connssl->handle);
720 SSL_free (connssl->handle);
721 connssl->handle = NULL;
723 if(connssl->ctx) {
724 SSL_CTX_free (connssl->ctx);
725 connssl->ctx = NULL;
727 connssl->use = FALSE; /* get back to ordinary socket usage */
732 * This function is called to shut down the SSL layer but keep the
733 * socket open (CCC - Clear Command Channel)
735 int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
737 int retval = 0;
738 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
739 struct SessionHandle *data = conn->data;
740 char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
741 to be at least 120 bytes long. */
742 unsigned long sslerror;
743 ssize_t nread;
744 int err;
745 int done = 0;
747 /* This has only been tested on the proftpd server, and the mod_tls code
748 sends a close notify alert without waiting for a close notify alert in
749 response. Thus we wait for a close notify alert from the server, but
750 we do not send one. Let's hope other servers do the same... */
752 if(connssl->handle) {
753 while(!done) {
754 int what = Curl_select(conn->sock[sockindex],
755 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
756 if(what > 0) {
757 /* Something to read, let's do it and hope that it is the close
758 notify alert from the server */
759 nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
760 sizeof(buf));
761 err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
763 switch(err) {
764 case SSL_ERROR_NONE: /* this is not an error */
765 case SSL_ERROR_ZERO_RETURN: /* no more data */
766 /* This is the expected response. There was no data but only
767 the close notify alert */
768 done = 1;
769 break;
770 case SSL_ERROR_WANT_READ:
771 /* there's data pending, re-invoke SSL_read() */
772 infof(data, "SSL_ERROR_WANT_READ\n");
773 break;
774 case SSL_ERROR_WANT_WRITE:
775 /* SSL wants a write. Really odd. Let's bail out. */
776 infof(data, "SSL_ERROR_WANT_WRITE\n");
777 done = 1;
778 break;
779 default:
780 /* openssl/ssl.h says "look at error stack/return value/errno" */
781 sslerror = ERR_get_error();
782 failf(conn->data, "SSL read: %s, errno %d",
783 ERR_error_string(sslerror, buf),
784 Curl_sockerrno() );
785 done = 1;
786 break;
789 else if(0 == what) {
790 /* timeout */
791 failf(data, "SSL shutdown timeout");
792 done = 1;
793 break;
795 else {
796 /* anything that gets here is fatally bad */
797 failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
798 retval = -1;
799 done = 1;
801 } /* while()-loop for the select() */
803 if(data->set.verbose) {
804 switch(SSL_get_shutdown(connssl->handle)) {
805 case SSL_SENT_SHUTDOWN:
806 infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
807 break;
808 case SSL_RECEIVED_SHUTDOWN:
809 infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
810 break;
811 case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
812 infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
813 "SSL_RECEIVED__SHUTDOWN\n");
814 break;
818 connssl->use = FALSE; /* get back to ordinary socket usage */
820 SSL_free (connssl->handle);
821 connssl->handle = NULL;
823 return retval;
826 void Curl_ossl_session_free(void *ptr)
828 /* free the ID */
829 SSL_SESSION_free(ptr);
833 * This function is called when the 'data' struct is going away. Close
834 * down everything and free all resources!
836 int Curl_ossl_close_all(struct SessionHandle *data)
838 #ifdef HAVE_OPENSSL_ENGINE_H
839 if(data->state.engine) {
840 ENGINE_finish(data->state.engine);
841 ENGINE_free(data->state.engine);
842 data->state.engine = NULL;
844 #else
845 (void)data;
846 #endif
847 return 0;
850 static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,
851 const char *prefix,
852 ASN1_UTCTIME *tm)
854 char *asn1_string;
855 int gmt=FALSE;
856 int i;
857 int year=0,month=0,day=0,hour=0,minute=0,second=0;
858 struct SessionHandle *data = conn->data;
860 if(!data->set.verbose)
861 return 0;
863 i=tm->length;
864 asn1_string=(char *)tm->data;
866 if(i < 10)
867 return 1;
868 if(asn1_string[i-1] == 'Z')
869 gmt=TRUE;
870 for (i=0; i<10; i++)
871 if((asn1_string[i] > '9') || (asn1_string[i] < '0'))
872 return 2;
874 year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0');
875 if(year < 50)
876 year+=100;
878 month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0');
879 if((month > 12) || (month < 1))
880 return 3;
882 day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0');
883 hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0');
884 minute= (asn1_string[8]-'0')*10+(asn1_string[9]-'0');
886 if((asn1_string[10] >= '0') && (asn1_string[10] <= '9') &&
887 (asn1_string[11] >= '0') && (asn1_string[11] <= '9'))
888 second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0');
890 infof(data,
891 "%s%04d-%02d-%02d %02d:%02d:%02d %s\n",
892 prefix, year+1900, month, day, hour, minute, second, (gmt?"GMT":""));
894 return 0;
897 #endif
899 /* ====================================================== */
900 #ifdef USE_SSLEAY
903 * Match a hostname against a wildcard pattern.
904 * E.g.
905 * "foo.host.com" matches "*.host.com".
907 * We are a bit more liberal than RFC2818 describes in that we
908 * accept multiple "*" in pattern (similar to what some other browsers do).
909 * E.g.
910 * "abc.def.domain.com" should strickly not match "*.domain.com", but we
911 * don't consider "." to be important in CERT checking.
913 #define HOST_NOMATCH 0
914 #define HOST_MATCH 1
916 static int hostmatch(const char *hostname, const char *pattern)
918 while (1) {
919 int c = *pattern++;
921 if (c == '\0')
922 return (*hostname ? HOST_NOMATCH : HOST_MATCH);
924 if (c == '*') {
925 c = *pattern;
926 if (c == '\0') /* "*\0" matches anything remaining */
927 return HOST_MATCH;
929 while (*hostname) {
930 /* The only recursive function in libcurl! */
931 if (hostmatch(hostname++,pattern) == HOST_MATCH)
932 return HOST_MATCH;
934 break;
937 if (toupper(c) != toupper(*hostname++))
938 break;
940 return HOST_NOMATCH;
943 static int
944 cert_hostcheck(const char *match_pattern, const char *hostname)
946 if (!match_pattern || !*match_pattern ||
947 !hostname || !*hostname) /* sanity check */
948 return 0;
950 if(curl_strequal(hostname,match_pattern)) /* trivial case */
951 return 1;
953 if (hostmatch(hostname,match_pattern) == HOST_MATCH)
954 return 1;
955 return 0;
958 /* Quote from RFC2818 section 3.1 "Server Identity"
960 If a subjectAltName extension of type dNSName is present, that MUST
961 be used as the identity. Otherwise, the (most specific) Common Name
962 field in the Subject field of the certificate MUST be used. Although
963 the use of the Common Name is existing practice, it is deprecated and
964 Certification Authorities are encouraged to use the dNSName instead.
966 Matching is performed using the matching rules specified by
967 [RFC2459]. If more than one identity of a given type is present in
968 the certificate (e.g., more than one dNSName name, a match in any one
969 of the set is considered acceptable.) Names may contain the wildcard
970 character * which is considered to match any single domain name
971 component or component fragment. E.g., *.a.com matches foo.a.com but
972 not bar.foo.a.com. f*.com matches foo.com but not bar.com.
974 In some cases, the URI is specified as an IP address rather than a
975 hostname. In this case, the iPAddress subjectAltName must be present
976 in the certificate and must exactly match the IP in the URI.
979 static CURLcode verifyhost(struct connectdata *conn,
980 X509 *server_cert)
982 bool matched = FALSE; /* no alternative match yet */
983 int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
984 int addrlen = 0;
985 struct SessionHandle *data = conn->data;
986 STACK_OF(GENERAL_NAME) *altnames;
987 #ifdef ENABLE_IPV6
988 struct in6_addr addr;
989 #else
990 struct in_addr addr;
991 #endif
992 CURLcode res = CURLE_OK;
994 #ifdef ENABLE_IPV6
995 if(conn->bits.ipv6_ip &&
996 Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
997 target = GEN_IPADD;
998 addrlen = sizeof(struct in6_addr);
1000 else
1001 #endif
1002 if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
1003 target = GEN_IPADD;
1004 addrlen = sizeof(struct in_addr);
1007 /* get a "list" of alternative names */
1008 altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
1010 if(altnames) {
1011 int numalts;
1012 int i;
1014 /* get amount of alternatives, RFC2459 claims there MUST be at least
1015 one, but we don't depend on it... */
1016 numalts = sk_GENERAL_NAME_num(altnames);
1018 /* loop through all alternatives while none has matched */
1019 for (i=0; (i<numalts) && !matched; i++) {
1020 /* get a handle to alternative name number i */
1021 const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
1023 /* only check alternatives of the same type the target is */
1024 if(check->type == target) {
1025 /* get data and length */
1026 const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
1027 int altlen;
1029 switch(target) {
1030 case GEN_DNS: /* name/pattern comparison */
1031 /* The OpenSSL man page explicitly says: "In general it cannot be
1032 assumed that the data returned by ASN1_STRING_data() is null
1033 terminated or does not contain embedded nulls." But also that
1034 "The actual format of the data will depend on the actual string
1035 type itself: for example for and IA5String the data will be ASCII"
1037 Gisle researched the OpenSSL sources:
1038 "I checked the 0.9.6 and 0.9.8 sources before my patch and
1039 it always 0-terminates an IA5String."
1041 if (cert_hostcheck(altptr, conn->host.name))
1042 matched = TRUE;
1043 break;
1045 case GEN_IPADD: /* IP address comparison */
1046 /* compare alternative IP address if the data chunk is the same size
1047 our server IP address is */
1048 altlen = ASN1_STRING_length(check->d.ia5);
1049 if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
1050 matched = TRUE;
1051 break;
1055 GENERAL_NAMES_free(altnames);
1058 if(matched)
1059 /* an alternative name matched the server hostname */
1060 infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
1061 else {
1062 /* we have to look to the last occurence of a commonName in the
1063 distinguished one to get the most significant one. */
1064 int j,i=-1 ;
1066 /* The following is done because of a bug in 0.9.6b */
1068 unsigned char *nulstr = (unsigned char *)"";
1069 unsigned char *peer_CN = nulstr;
1071 X509_NAME *name = X509_get_subject_name(server_cert) ;
1072 if (name)
1073 while ((j=X509_NAME_get_index_by_NID(name,NID_commonName,i))>=0)
1074 i=j;
1076 /* we have the name entry and we will now convert this to a string
1077 that we can use for comparison. Doing this we support BMPstring,
1078 UTF8 etc. */
1080 if (i>=0) {
1081 ASN1_STRING *tmp = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
1083 /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
1084 is already UTF-8 encoded. We check for this case and copy the raw
1085 string manually to avoid the problem. This code can be made
1086 conditional in the future when OpenSSL has been fixed. Work-around
1087 brought by Alexis S. L. Carvalho. */
1088 if (tmp && ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
1089 j = ASN1_STRING_length(tmp);
1090 if (j >= 0) {
1091 peer_CN = OPENSSL_malloc(j+1);
1092 if (peer_CN) {
1093 memcpy(peer_CN, ASN1_STRING_data(tmp), j);
1094 peer_CN[j] = '\0';
1098 else /* not a UTF8 name */
1099 j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
1102 if (peer_CN == nulstr)
1103 peer_CN = NULL;
1104 #ifdef CURL_DOES_CONVERSIONS
1105 else {
1106 /* convert peer_CN from UTF8 */
1107 size_t rc;
1108 rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
1109 /* Curl_convert_from_utf8 calls failf if unsuccessful */
1110 if (rc != CURLE_OK) {
1111 return(rc);
1114 #endif /* CURL_DOES_CONVERSIONS */
1116 if (!peer_CN) {
1117 if(data->set.ssl.verifyhost > 1) {
1118 failf(data,
1119 "SSL: unable to obtain common name from peer certificate");
1120 return CURLE_SSL_PEER_CERTIFICATE;
1122 else {
1123 /* Consider verifyhost == 1 as an "OK" for a missing CN field, but we
1124 output a note about the situation */
1125 infof(data, "\t common name: WARNING couldn't obtain\n");
1128 else if(!cert_hostcheck((const char *)peer_CN, conn->host.name)) {
1129 if(data->set.ssl.verifyhost > 1) {
1130 failf(data, "SSL: certificate subject name '%s' does not match "
1131 "target host name '%s'", peer_CN, conn->host.dispname);
1132 res = CURLE_SSL_PEER_CERTIFICATE;
1134 else
1135 infof(data, "\t common name: %s (does not match '%s')\n",
1136 peer_CN, conn->host.dispname);
1138 else {
1139 infof(data, "\t common name: %s (matched)\n", peer_CN);
1141 if(peer_CN)
1142 OPENSSL_free(peer_CN);
1144 return res;
1146 #endif
1148 /* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
1149 and thus this cannot be done there. */
1150 #ifdef SSL_CTRL_SET_MSG_CALLBACK
1152 static const char *ssl_msg_type(int ssl_ver, int msg)
1154 if (ssl_ver == SSL2_VERSION_MAJOR) {
1155 switch (msg) {
1156 case SSL2_MT_ERROR:
1157 return "Error";
1158 case SSL2_MT_CLIENT_HELLO:
1159 return "Client hello";
1160 case SSL2_MT_CLIENT_MASTER_KEY:
1161 return "Client key";
1162 case SSL2_MT_CLIENT_FINISHED:
1163 return "Client finished";
1164 case SSL2_MT_SERVER_HELLO:
1165 return "Server hello";
1166 case SSL2_MT_SERVER_VERIFY:
1167 return "Server verify";
1168 case SSL2_MT_SERVER_FINISHED:
1169 return "Server finished";
1170 case SSL2_MT_REQUEST_CERTIFICATE:
1171 return "Request CERT";
1172 case SSL2_MT_CLIENT_CERTIFICATE:
1173 return "Client CERT";
1176 else if (ssl_ver == SSL3_VERSION_MAJOR) {
1177 switch (msg) {
1178 case SSL3_MT_HELLO_REQUEST:
1179 return "Hello request";
1180 case SSL3_MT_CLIENT_HELLO:
1181 return "Client hello";
1182 case SSL3_MT_SERVER_HELLO:
1183 return "Server hello";
1184 case SSL3_MT_CERTIFICATE:
1185 return "CERT";
1186 case SSL3_MT_SERVER_KEY_EXCHANGE:
1187 return "Server key exchange";
1188 case SSL3_MT_CLIENT_KEY_EXCHANGE:
1189 return "Client key exchange";
1190 case SSL3_MT_CERTIFICATE_REQUEST:
1191 return "Request CERT";
1192 case SSL3_MT_SERVER_DONE:
1193 return "Server finished";
1194 case SSL3_MT_CERTIFICATE_VERIFY:
1195 return "CERT verify";
1196 case SSL3_MT_FINISHED:
1197 return "Finished";
1200 return "Unknown";
1203 static const char *tls_rt_type(int type)
1205 return (
1206 type == SSL3_RT_CHANGE_CIPHER_SPEC ? "TLS change cipher, " :
1207 type == SSL3_RT_ALERT ? "TLS alert, " :
1208 type == SSL3_RT_HANDSHAKE ? "TLS handshake, " :
1209 type == SSL3_RT_APPLICATION_DATA ? "TLS app data, " :
1210 "TLS Unknown, ");
1215 * Our callback from the SSL/TLS layers.
1217 static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
1218 const void *buf, size_t len, const SSL *ssl,
1219 struct connectdata *conn)
1221 struct SessionHandle *data;
1222 const char *msg_name, *tls_rt_name;
1223 char ssl_buf[1024];
1224 int ver, msg_type, txt_len;
1226 if (!conn || !conn->data || !conn->data->set.fdebug ||
1227 (direction != 0 && direction != 1))
1228 return;
1230 data = conn->data;
1231 ssl_ver >>= 8;
1232 ver = (ssl_ver == SSL2_VERSION_MAJOR ? '2' :
1233 ssl_ver == SSL3_VERSION_MAJOR ? '3' : '?');
1235 /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
1236 * always pass-up content-type as 0. But the interesting message-type
1237 * is at 'buf[0]'.
1239 if (ssl_ver == SSL3_VERSION_MAJOR && content_type != 0)
1240 tls_rt_name = tls_rt_type(content_type);
1241 else
1242 tls_rt_name = "";
1244 msg_type = *(char*)buf;
1245 msg_name = ssl_msg_type(ssl_ver, msg_type);
1247 txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n",
1248 ver, tls_rt_name, msg_name, msg_type);
1249 Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
1251 Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
1252 CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
1253 (void) ssl;
1255 #endif
1257 #ifdef USE_SSLEAY
1258 /* ====================================================== */
1260 static CURLcode
1261 Curl_ossl_connect_step1(struct connectdata *conn,
1262 int sockindex)
1264 CURLcode retcode = CURLE_OK;
1266 struct SessionHandle *data = conn->data;
1267 SSL_METHOD_QUAL SSL_METHOD *req_method=NULL;
1268 void *ssl_sessionid=NULL;
1269 curl_socket_t sockfd = conn->sock[sockindex];
1270 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1272 curlassert(ssl_connect_1 == connssl->connecting_state);
1274 /* Make funny stuff to get random input */
1275 Curl_ossl_seed(data);
1277 /* check to see if we've been told to use an explicit SSL/TLS version */
1278 switch(data->set.ssl.version) {
1279 default:
1280 case CURL_SSLVERSION_DEFAULT:
1281 /* we try to figure out version */
1282 req_method = SSLv23_client_method();
1283 break;
1284 case CURL_SSLVERSION_TLSv1:
1285 req_method = TLSv1_client_method();
1286 break;
1287 case CURL_SSLVERSION_SSLv2:
1288 req_method = SSLv2_client_method();
1289 break;
1290 case CURL_SSLVERSION_SSLv3:
1291 req_method = SSLv3_client_method();
1292 break;
1295 if (connssl->ctx)
1296 SSL_CTX_free(connssl->ctx);
1297 connssl->ctx = SSL_CTX_new(req_method);
1299 if(!connssl->ctx) {
1300 failf(data, "SSL: couldn't create a context!");
1301 return CURLE_OUT_OF_MEMORY;
1304 #ifdef SSL_CTRL_SET_MSG_CALLBACK
1305 if (data->set.fdebug && data->set.verbose) {
1306 /* the SSL trace callback is only used for verbose logging so we only
1307 inform about failures of setting it */
1308 if (!SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
1309 (void (*)(void))ssl_tls_trace)) {
1310 infof(data, "SSL: couldn't set callback!\n");
1312 else if (!SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0,
1313 conn)) {
1314 infof(data, "SSL: couldn't set callback argument!\n");
1317 #endif
1319 /* OpenSSL contains code to work-around lots of bugs and flaws in various
1320 SSL-implementations. SSL_CTX_set_options() is used to enabled those
1321 work-arounds. The man page for this option states that SSL_OP_ALL enables
1322 all the work-arounds and that "It is usually safe to use SSL_OP_ALL to
1323 enable the bug workaround options if compatibility with somewhat broken
1324 implementations is desired."
1327 SSL_CTX_set_options(connssl->ctx, SSL_OP_ALL);
1329 #if 0
1331 * Not sure it's needed to tell SSL_connect() that socket is
1332 * non-blocking. It doesn't seem to care, but just return with
1333 * SSL_ERROR_WANT_x.
1335 if (data->state.used_interface == Curl_if_multi)
1336 SSL_CTX_ctrl(connssl->ctx, BIO_C_SET_NBIO, 1, NULL);
1337 #endif
1339 if(data->set.cert) {
1340 if(!cert_stuff(conn,
1341 connssl->ctx,
1342 data->set.cert,
1343 data->set.cert_type,
1344 data->set.key,
1345 data->set.key_type)) {
1346 /* failf() is already done in cert_stuff() */
1347 return CURLE_SSL_CERTPROBLEM;
1351 if(data->set.ssl.cipher_list) {
1352 if(!SSL_CTX_set_cipher_list(connssl->ctx,
1353 data->set.ssl.cipher_list)) {
1354 failf(data, "failed setting cipher list");
1355 return CURLE_SSL_CIPHER;
1359 if (data->set.ssl.CAfile || data->set.ssl.CApath) {
1360 /* tell SSL where to find CA certificates that are used to verify
1361 the servers certificate. */
1362 if (!SSL_CTX_load_verify_locations(connssl->ctx, data->set.ssl.CAfile,
1363 data->set.ssl.CApath)) {
1364 if (data->set.ssl.verifypeer) {
1365 /* Fail if we insist on successfully verifying the server. */
1366 failf(data,"error setting certificate verify locations:\n"
1367 " CAfile: %s\n CApath: %s\n",
1368 data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
1369 data->set.ssl.CApath ? data->set.ssl.CApath : "none");
1370 return CURLE_SSL_CACERT_BADFILE;
1372 else {
1373 /* Just continue with a warning if no strict certificate verification
1374 is required. */
1375 infof(data, "error setting certificate verify locations,"
1376 " continuing anyway:\n");
1379 else {
1380 /* Everything is fine. */
1381 infof(data, "successfully set certificate verify locations:\n");
1383 infof(data,
1384 " CAfile: %s\n"
1385 " CApath: %s\n",
1386 data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
1387 data->set.ssl.CApath ? data->set.ssl.CApath : "none");
1389 /* SSL always tries to verify the peer, this only says whether it should
1390 * fail to connect if the verification fails, or if it should continue
1391 * anyway. In the latter case the result of the verification is checked with
1392 * SSL_get_verify_result() below. */
1393 SSL_CTX_set_verify(connssl->ctx,
1394 data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
1395 cert_verify_callback);
1397 /* give application a chance to interfere with SSL set up. */
1398 if(data->set.ssl.fsslctx) {
1399 retcode = (*data->set.ssl.fsslctx)(data, connssl->ctx,
1400 data->set.ssl.fsslctxp);
1401 if(retcode) {
1402 failf(data,"error signaled by ssl ctx callback");
1403 return retcode;
1407 /* Lets make an SSL structure */
1408 if (connssl->handle)
1409 SSL_free(connssl->handle);
1410 connssl->handle = SSL_new(connssl->ctx);
1411 if (!connssl->handle) {
1412 failf(data, "SSL: couldn't create a context (handle)!");
1413 return CURLE_OUT_OF_MEMORY;
1415 SSL_set_connect_state(connssl->handle);
1417 connssl->server_cert = 0x0;
1419 /* Check if there's a cached ID we can/should use here! */
1420 if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
1421 /* we got a session id, use it! */
1422 if (!SSL_set_session(connssl->handle, ssl_sessionid)) {
1423 failf(data, "SSL: SSL_set_session failed: %s",
1424 ERR_error_string(ERR_get_error(),NULL));
1425 return CURLE_SSL_CONNECT_ERROR;
1427 /* Informational message */
1428 infof (data, "SSL re-using session ID\n");
1431 /* pass the raw socket into the SSL layers */
1432 if (!SSL_set_fd(connssl->handle, sockfd)) {
1433 failf(data, "SSL: SSL_set_fd failed: %s",
1434 ERR_error_string(ERR_get_error(),NULL));
1435 return CURLE_SSL_CONNECT_ERROR;
1438 connssl->connecting_state = ssl_connect_2;
1439 return CURLE_OK;
1442 static CURLcode
1443 Curl_ossl_connect_step2(struct connectdata *conn,
1444 int sockindex, long *timeout_ms)
1446 struct SessionHandle *data = conn->data;
1447 int err;
1448 long has_passed;
1449 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1451 curlassert(ssl_connect_2 == connssl->connecting_state
1452 || ssl_connect_2_reading == connssl->connecting_state
1453 || ssl_connect_2_writing == connssl->connecting_state);
1455 /* Find out if any timeout is set. If not, use 300 seconds.
1456 Otherwise, figure out the most strict timeout of the two possible one
1457 and then how much time that has elapsed to know how much time we
1458 allow for the connect call */
1459 if(data->set.timeout && data->set.connecttimeout) {
1460 /* get the most strict timeout of the ones converted to milliseconds */
1461 if(data->set.timeout<data->set.connecttimeout)
1462 *timeout_ms = data->set.timeout*1000;
1463 else
1464 *timeout_ms = data->set.connecttimeout*1000;
1466 else if(data->set.timeout)
1467 *timeout_ms = data->set.timeout*1000;
1468 else if(data->set.connecttimeout)
1469 *timeout_ms = data->set.connecttimeout*1000;
1470 else
1471 /* no particular time-out has been set */
1472 *timeout_ms= DEFAULT_CONNECT_TIMEOUT;
1474 /* Evaluate in milliseconds how much time that has passed */
1475 has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
1477 /* subtract the passed time */
1478 *timeout_ms -= has_passed;
1480 if(*timeout_ms < 0) {
1481 /* a precaution, no need to continue if time already is up */
1482 failf(data, "SSL connection timeout");
1483 return CURLE_OPERATION_TIMEOUTED;
1486 err = SSL_connect(connssl->handle);
1488 /* 1 is fine
1489 0 is "not successful but was shut down controlled"
1490 <0 is "handshake was not successful, because a fatal error occurred" */
1491 if(1 != err) {
1492 int detail = SSL_get_error(connssl->handle, err);
1494 if(SSL_ERROR_WANT_READ == detail) {
1495 connssl->connecting_state = ssl_connect_2_reading;
1496 return CURLE_OK;
1498 else if(SSL_ERROR_WANT_WRITE == detail) {
1499 connssl->connecting_state = ssl_connect_2_writing;
1500 return CURLE_OK;
1502 else {
1503 /* untreated error */
1504 unsigned long errdetail;
1505 char error_buffer[256]; /* OpenSSL documents that this must be at least
1506 256 bytes long. */
1507 CURLcode rc;
1508 const char *cert_problem = NULL;
1510 connssl->connecting_state = ssl_connect_2; /* the connection failed,
1511 we're not waiting for
1512 anything else. */
1514 errdetail = ERR_get_error(); /* Gets the earliest error code from the
1515 thread's error queue and removes the
1516 entry. */
1518 switch(errdetail) {
1519 case 0x1407E086:
1520 /* 1407E086:
1521 SSL routines:
1522 SSL2_SET_CERTIFICATE:
1523 certificate verify failed */
1524 /* fall-through */
1525 case 0x14090086:
1526 /* 14090086:
1527 SSL routines:
1528 SSL3_GET_SERVER_CERTIFICATE:
1529 certificate verify failed */
1530 cert_problem = "SSL certificate problem, verify that the CA cert is"
1531 " OK. Details:\n";
1532 rc = CURLE_SSL_CACERT;
1533 break;
1534 default:
1535 rc = CURLE_SSL_CONNECT_ERROR;
1536 break;
1539 /* detail is already set to the SSL error above */
1541 /* If we e.g. use SSLv2 request-method and the server doesn't like us
1542 * (RST connection etc.), OpenSSL gives no explanation whatsoever and
1543 * the SO_ERROR is also lost.
1545 if (CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
1546 failf(data, "Unknown SSL protocol error in connection to %s:%d ",
1547 conn->host.name, conn->port);
1548 return rc;
1550 /* Could be a CERT problem */
1552 SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
1553 failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
1554 return rc;
1557 else {
1558 /* we have been connected fine, we're not waiting for anything else. */
1559 connssl->connecting_state = ssl_connect_3;
1561 /* Informational message */
1562 infof (data, "SSL connection using %s\n",
1563 SSL_get_cipher(connssl->handle));
1565 return CURLE_OK;
1569 static CURLcode
1570 Curl_ossl_connect_step3(struct connectdata *conn,
1571 int sockindex)
1573 CURLcode retcode = CURLE_OK;
1574 char * str;
1575 long lerr;
1576 ASN1_TIME *certdate;
1577 void *ssl_sessionid=NULL;
1578 struct SessionHandle *data = conn->data;
1579 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1581 curlassert(ssl_connect_3 == connssl->connecting_state);
1583 if(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
1584 /* Since this is not a cached session ID, then we want to stach this one
1585 in the cache! */
1586 SSL_SESSION *our_ssl_sessionid;
1587 #ifdef HAVE_SSL_GET1_SESSION
1588 our_ssl_sessionid = SSL_get1_session(connssl->handle);
1590 /* SSL_get1_session() will increment the reference
1591 count and the session will stay in memory until explicitly freed with
1592 SSL_SESSION_free(3), regardless of its state.
1593 This function was introduced in openssl 0.9.5a. */
1594 #else
1595 our_ssl_sessionid = SSL_get_session(connssl->handle);
1597 /* if SSL_get1_session() is unavailable, use SSL_get_session().
1598 This is an inferior option because the session can be flushed
1599 at any time by openssl. It is included only so curl compiles
1600 under versions of openssl < 0.9.5a.
1602 WARNING: How curl behaves if it's session is flushed is
1603 untested.
1605 #endif
1606 retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
1607 0 /* unknown size */);
1608 if(retcode) {
1609 failf(data, "failed to store ssl session");
1610 return retcode;
1615 /* Get server's certificate (note: beware of dynamic allocation) - opt */
1616 /* major serious hack alert -- we should check certificates
1617 * to authenticate the server; otherwise we risk man-in-the-middle
1618 * attack
1621 connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
1622 if(!connssl->server_cert) {
1623 failf(data, "SSL: couldn't get peer certificate!");
1624 return CURLE_SSL_PEER_CERTIFICATE;
1626 infof (data, "Server certificate:\n");
1628 str = X509_NAME_oneline(X509_get_subject_name(connssl->server_cert),
1629 NULL, 0);
1630 if(!str) {
1631 failf(data, "SSL: couldn't get X509-subject!");
1632 X509_free(connssl->server_cert);
1633 connssl->server_cert = NULL;
1634 return CURLE_SSL_CONNECT_ERROR;
1636 infof(data, "\t subject: %s\n", str);
1637 CRYPTO_free(str);
1639 certdate = X509_get_notBefore(connssl->server_cert);
1640 Curl_ASN1_UTCTIME_output(conn, "\t start date: ", certdate);
1642 certdate = X509_get_notAfter(connssl->server_cert);
1643 Curl_ASN1_UTCTIME_output(conn, "\t expire date: ", certdate);
1645 if(data->set.ssl.verifyhost) {
1646 retcode = verifyhost(conn, connssl->server_cert);
1647 if(retcode) {
1648 X509_free(connssl->server_cert);
1649 connssl->server_cert = NULL;
1650 return retcode;
1654 str = X509_NAME_oneline(X509_get_issuer_name(connssl->server_cert),
1655 NULL, 0);
1656 if(!str) {
1657 failf(data, "SSL: couldn't get X509-issuer name!");
1658 retcode = CURLE_SSL_CONNECT_ERROR;
1660 else {
1661 infof(data, "\t issuer: %s\n", str);
1662 CRYPTO_free(str);
1664 /* We could do all sorts of certificate verification stuff here before
1665 deallocating the certificate. */
1667 lerr = data->set.ssl.certverifyresult=
1668 SSL_get_verify_result(connssl->handle);
1669 if(data->set.ssl.certverifyresult != X509_V_OK) {
1670 if(data->set.ssl.verifypeer) {
1671 /* We probably never reach this, because SSL_connect() will fail
1672 and we return earlyer if verifypeer is set? */
1673 failf(data, "SSL certificate verify result: %s (%ld)",
1674 X509_verify_cert_error_string(lerr), lerr);
1675 retcode = CURLE_SSL_PEER_CERTIFICATE;
1677 else
1678 infof(data, "SSL certificate verify result: %s (%ld),"
1679 " continuing anyway.\n",
1680 X509_verify_cert_error_string(lerr), lerr);
1682 else
1683 infof(data, "SSL certificate verify ok.\n");
1686 X509_free(connssl->server_cert);
1687 connssl->server_cert = NULL;
1688 connssl->connecting_state = ssl_connect_done;
1689 return retcode;
1692 static CURLcode
1693 Curl_ossl_connect_common(struct connectdata *conn,
1694 int sockindex,
1695 bool nonblocking,
1696 bool *done)
1698 CURLcode retcode;
1699 struct SessionHandle *data = conn->data;
1700 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1701 curl_socket_t sockfd = conn->sock[sockindex];
1702 long timeout_ms;
1704 if (ssl_connect_1==connssl->connecting_state) {
1705 retcode = Curl_ossl_connect_step1(conn, sockindex);
1706 if (retcode)
1707 return retcode;
1710 timeout_ms = 0;
1711 while (ssl_connect_2 == connssl->connecting_state ||
1712 ssl_connect_2_reading == connssl->connecting_state ||
1713 ssl_connect_2_writing == connssl->connecting_state) {
1715 /* if ssl is expecting something, check if it's available. */
1716 if (connssl->connecting_state == ssl_connect_2_reading
1717 || connssl->connecting_state == ssl_connect_2_writing) {
1719 int writefd = ssl_connect_2_writing==
1720 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1721 int readfd = ssl_connect_2_reading==
1722 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1724 while(1) {
1725 int what = Curl_select(readfd, writefd, nonblocking?0:(int)timeout_ms);
1726 if(what > 0)
1727 /* readable or writable, go loop in the outer loop */
1728 break;
1729 else if(0 == what) {
1730 if (nonblocking) {
1731 *done = FALSE;
1732 return CURLE_OK;
1734 else {
1735 /* timeout */
1736 failf(data, "SSL connection timeout");
1737 return CURLE_OPERATION_TIMEDOUT;
1740 else {
1741 /* anything that gets here is fatally bad */
1742 failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
1743 return CURLE_SSL_CONNECT_ERROR;
1745 } /* while()-loop for the select() */
1748 /* get the timeout from step2 to avoid computing it twice. */
1749 retcode = Curl_ossl_connect_step2(conn, sockindex, &timeout_ms);
1750 if (retcode)
1751 return retcode;
1753 } /* repeat step2 until all transactions are done. */
1756 if (ssl_connect_3==connssl->connecting_state) {
1757 retcode = Curl_ossl_connect_step3(conn, sockindex);
1758 if (retcode)
1759 return retcode;
1762 if (ssl_connect_done==connssl->connecting_state) {
1763 *done = TRUE;
1765 else {
1766 *done = FALSE;
1769 /* Reset our connect state machine */
1770 connssl->connecting_state = ssl_connect_1;
1772 return CURLE_OK;
1775 CURLcode
1776 Curl_ossl_connect_nonblocking(struct connectdata *conn,
1777 int sockindex,
1778 bool *done)
1780 return Curl_ossl_connect_common(conn, sockindex, TRUE, done);
1783 CURLcode
1784 Curl_ossl_connect(struct connectdata *conn,
1785 int sockindex)
1787 CURLcode retcode;
1788 bool done = FALSE;
1790 retcode = Curl_ossl_connect_common(conn, sockindex, FALSE, &done);
1791 if (retcode)
1792 return retcode;
1794 curlassert(done);
1796 return CURLE_OK;
1799 /* return number of sent (non-SSL) bytes */
1800 ssize_t Curl_ossl_send(struct connectdata *conn,
1801 int sockindex,
1802 void *mem,
1803 size_t len)
1805 /* SSL_write() is said to return 'int' while write() and send() returns
1806 'size_t' */
1807 int err;
1808 char error_buffer[120]; /* OpenSSL documents that this must be at least 120
1809 bytes long. */
1810 unsigned long sslerror;
1811 int rc = SSL_write(conn->ssl[sockindex].handle, mem, (int)len);
1813 if(rc < 0) {
1814 err = SSL_get_error(conn->ssl[sockindex].handle, rc);
1816 switch(err) {
1817 case SSL_ERROR_WANT_READ:
1818 case SSL_ERROR_WANT_WRITE:
1819 /* The operation did not complete; the same TLS/SSL I/O function
1820 should be called again later. This is basicly an EWOULDBLOCK
1821 equivalent. */
1822 return 0;
1823 case SSL_ERROR_SYSCALL:
1824 failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
1825 Curl_sockerrno());
1826 return -1;
1827 case SSL_ERROR_SSL:
1828 /* A failure in the SSL library occurred, usually a protocol error.
1829 The OpenSSL error queue contains more information on the error. */
1830 sslerror = ERR_get_error();
1831 failf(conn->data, "SSL_write() error: %s\n",
1832 ERR_error_string(sslerror, error_buffer));
1833 return -1;
1835 /* a true error */
1836 failf(conn->data, "SSL_write() return error %d\n", err);
1837 return -1;
1839 return (ssize_t)rc; /* number of bytes */
1843 * If the read would block we return -1 and set 'wouldblock' to TRUE.
1844 * Otherwise we return the amount of data read. Other errors should return -1
1845 * and set 'wouldblock' to FALSE.
1847 ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
1848 int num, /* socketindex */
1849 char *buf, /* store read data here */
1850 size_t buffersize, /* max amount to read */
1851 bool *wouldblock)
1853 char error_buffer[120]; /* OpenSSL documents that this must be at
1854 least 120 bytes long. */
1855 unsigned long sslerror;
1856 ssize_t nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf,
1857 (int)buffersize);
1858 *wouldblock = FALSE;
1859 if(nread < 0) {
1860 /* failed SSL_read */
1861 int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
1863 switch(err) {
1864 case SSL_ERROR_NONE: /* this is not an error */
1865 case SSL_ERROR_ZERO_RETURN: /* no more data */
1866 break;
1867 case SSL_ERROR_WANT_READ:
1868 case SSL_ERROR_WANT_WRITE:
1869 /* there's data pending, re-invoke SSL_read() */
1870 *wouldblock = TRUE;
1871 return -1; /* basically EWOULDBLOCK */
1872 default:
1873 /* openssl/ssl.h says "look at error stack/return value/errno" */
1874 sslerror = ERR_get_error();
1875 failf(conn->data, "SSL read: %s, errno %d",
1876 ERR_error_string(sslerror, error_buffer),
1877 Curl_sockerrno() );
1878 return -1;
1881 return nread;
1884 size_t Curl_ossl_version(char *buffer, size_t size)
1886 #ifdef YASSL_VERSION
1887 /* yassl provides an OpenSSL API compatiblity layer so it looks identical
1888 to OpenSSL in all other aspects */
1889 return snprintf(buffer, size, " yassl/%s", YASSL_VERSION);
1890 #else /* YASSL_VERSION */
1892 #if (SSLEAY_VERSION_NUMBER >= 0x905000)
1894 char sub[2];
1895 unsigned long ssleay_value;
1896 sub[1]='\0';
1897 ssleay_value=SSLeay();
1898 if(ssleay_value < 0x906000) {
1899 ssleay_value=SSLEAY_VERSION_NUMBER;
1900 sub[0]='\0';
1902 else {
1903 if(ssleay_value&0xff0) {
1904 sub[0]=(char)(((ssleay_value>>4)&0xff) + 'a' -1);
1906 else
1907 sub[0]='\0';
1910 return snprintf(buffer, size, " OpenSSL/%lx.%lx.%lx%s",
1911 (ssleay_value>>28)&0xf,
1912 (ssleay_value>>20)&0xff,
1913 (ssleay_value>>12)&0xff,
1914 sub);
1917 #else /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
1919 #if (SSLEAY_VERSION_NUMBER >= 0x900000)
1920 return snprintf(buffer, size, " OpenSSL/%lx.%lx.%lx",
1921 (SSLEAY_VERSION_NUMBER>>28)&0xff,
1922 (SSLEAY_VERSION_NUMBER>>20)&0xff,
1923 (SSLEAY_VERSION_NUMBER>>12)&0xf);
1925 #else /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
1927 char sub[2];
1928 sub[1]='\0';
1929 if(SSLEAY_VERSION_NUMBER&0x0f) {
1930 sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
1932 else
1933 sub[0]='\0';
1935 return snprintf(buffer, size, " SSL/%x.%x.%x%s",
1936 (SSLEAY_VERSION_NUMBER>>12)&0xff,
1937 (SSLEAY_VERSION_NUMBER>>8)&0xf,
1938 (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
1940 #endif /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
1941 #endif /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
1943 #endif /* YASSL_VERSION */
1945 #endif /* USE_SSLEAY */