1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
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.
13 *
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.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23/*
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.
26 */
27
28/*
29 * The original SSLeay-using code for curl was written by Linas Vepstas and
30 * Sampo Kellomaki 1998.
31 */
32
33#include "curl_setup.h"
34
35#ifdef HAVE_LIMITS_H
36#include <limits.h>
37#endif
38
39#include "urldata.h"
40#include "sendf.h"
41#include "formdata.h" /* for the boundary function */
42#include "url.h" /* for the ssl config check function */
43#include "inet_pton.h"
44#include "ssluse.h"
45#include "connect.h"
46#include "strequal.h"
47#include "select.h"
48#include "sslgen.h"
49#include "rawstr.h"
50#include "hostcheck.h"
51
52#define _MPRINTF_REPLACE /* use the internal *printf() functions */
53#include <curl/mprintf.h>
54
55#ifdef USE_SSLEAY
56
57#ifdef USE_OPENSSL
58#include <openssl/rand.h>
59#include <openssl/x509v3.h>
60#include <openssl/dsa.h>
61#include <openssl/dh.h>
62#include <openssl/err.h>
63#include <openssl/md5.h>
64#else
65#include <rand.h>
66#include <x509v3.h>
67#include <md5.h>
68#endif
69
70#include "warnless.h"
71#include "curl_memory.h"
72#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */
73
74/* The last #include file should be: */
75#include "memdebug.h"
76
77#ifndef OPENSSL_VERSION_NUMBER
78#error "OPENSSL_VERSION_NUMBER not defined"
79#endif
80
81#if OPENSSL_VERSION_NUMBER >= 0x0090581fL
82#define HAVE_SSL_GET1_SESSION 1
83#else
84#undef HAVE_SSL_GET1_SESSION
85#endif
86
87#if OPENSSL_VERSION_NUMBER >= 0x00904100L
88#define HAVE_USERDATA_IN_PWD_CALLBACK 1
89#else
90#undef HAVE_USERDATA_IN_PWD_CALLBACK
91#endif
92
93#if OPENSSL_VERSION_NUMBER >= 0x00907001L
94/* ENGINE_load_private_key() takes four arguments */
95#define HAVE_ENGINE_LOAD_FOUR_ARGS
96#include <openssl/ui.h>
97#else
98/* ENGINE_load_private_key() takes three arguments */
99#undef HAVE_ENGINE_LOAD_FOUR_ARGS
100#endif
101
102#if (OPENSSL_VERSION_NUMBER >= 0x00903001L) && defined(HAVE_OPENSSL_PKCS12_H)
103/* OpenSSL has PKCS 12 support */
104#define HAVE_PKCS12_SUPPORT
105#else
106/* OpenSSL/SSLEay does not have PKCS12 support */
107#undef HAVE_PKCS12_SUPPORT
108#endif
109
110#if OPENSSL_VERSION_NUMBER >= 0x00906001L
111#define HAVE_ERR_ERROR_STRING_N 1
112#endif
113
114#if OPENSSL_VERSION_NUMBER >= 0x00909000L
115#define SSL_METHOD_QUAL const
116#else
117#define SSL_METHOD_QUAL
118#endif
119
120#if OPENSSL_VERSION_NUMBER >= 0x00907000L
121/* 0.9.6 didn't have X509_STORE_set_flags() */
122#define HAVE_X509_STORE_SET_FLAGS 1
123#else
124#define X509_STORE_set_flags(x,y) Curl_nop_stmt
125#endif
126
127#if OPENSSL_VERSION_NUMBER >= 0x10000000L
128#define HAVE_ERR_REMOVE_THREAD_STATE 1
129#endif
130
131#ifndef HAVE_SSLV2_CLIENT_METHOD
132#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */
133#define OPENSSL_NO_SSL2
134#endif
135
136/*
137 * Number of bytes to read from the random number seed file. This must be
138 * a finite value (because some entropy "files" like /dev/urandom have
139 * an infinite length), but must be large enough to provide enough
140 * entopy to properly seed OpenSSL's PRNG.
141 */
142#define RAND_LOAD_LENGTH 1024
143
144#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
145static char global_passwd[64];
146#endif
147
148static int passwd_callback(char *buf, int num, int encrypting
149#ifdef HAVE_USERDATA_IN_PWD_CALLBACK
150                           /* This was introduced in 0.9.4, we can set this
151                              using SSL_CTX_set_default_passwd_cb_userdata()
152                              */
153                           , void *global_passwd
154#endif
155                           )
156{
157  DEBUGASSERT(0 == encrypting);
158
159  if(!encrypting) {
160    int klen = curlx_uztosi(strlen((char *)global_passwd));
161    if(num > klen) {
162      memcpy(buf, global_passwd, klen+1);
163      return klen;
164    }
165  }
166  return 0;
167}
168
169/*
170 * rand_enough() is a function that returns TRUE if we have seeded the random
171 * engine properly. We use some preprocessor magic to provide a seed_enough()
172 * macro to use, just to prevent a compiler warning on this function if we
173 * pass in an argument that is never used.
174 */
175
176#ifdef HAVE_RAND_STATUS
177#define seed_enough(x) rand_enough()
178static bool rand_enough(void)
179{
180  return (0 != RAND_status()) ? TRUE : FALSE;
181}
182#else
183#define seed_enough(x) rand_enough(x)
184static bool rand_enough(int nread)
185{
186  /* this is a very silly decision to make */
187  return (nread > 500) ? TRUE : FALSE;
188}
189#endif
190
191static int ossl_seed(struct SessionHandle *data)
192{
193  char *buf = data->state.buffer; /* point to the big buffer */
194  int nread=0;
195
196  /* Q: should we add support for a random file name as a libcurl option?
197     A: Yes, it is here */
198
199#ifndef RANDOM_FILE
200  /* if RANDOM_FILE isn't defined, we only perform this if an option tells
201     us to! */
202  if(data->set.ssl.random_file)
203#define RANDOM_FILE "" /* doesn't matter won't be used */
204#endif
205  {
206    /* let the option override the define */
207    nread += RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
208                             data->set.str[STRING_SSL_RANDOM_FILE]:
209                             RANDOM_FILE),
210                            RAND_LOAD_LENGTH);
211    if(seed_enough(nread))
212      return nread;
213  }
214
215#if defined(HAVE_RAND_EGD)
216  /* only available in OpenSSL 0.9.5 and later */
217  /* EGD_SOCKET is set at configure time or not at all */
218#ifndef EGD_SOCKET
219  /* If we don't have the define set, we only do this if the egd-option
220     is set */
221  if(data->set.str[STRING_SSL_EGDSOCKET])
222#define EGD_SOCKET "" /* doesn't matter won't be used */
223#endif
224  {
225    /* If there's an option and a define, the option overrides the
226       define */
227    int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
228                       data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
229    if(-1 != ret) {
230      nread += ret;
231      if(seed_enough(nread))
232        return nread;
233    }
234  }
235#endif
236
237  /* If we get here, it means we need to seed the PRNG using a "silly"
238     approach! */
239  do {
240    unsigned char randb[64];
241    int len = sizeof(randb);
242    RAND_bytes(randb, len);
243    RAND_add(randb, len, (len >> 1));
244  } while(!RAND_status());
245
246  /* generates a default path for the random seed file */
247  buf[0]=0; /* blank it first */
248  RAND_file_name(buf, BUFSIZE);
249  if(buf[0]) {
250    /* we got a file name to try */
251    nread += RAND_load_file(buf, RAND_LOAD_LENGTH);
252    if(seed_enough(nread))
253      return nread;
254  }
255
256  infof(data, "libcurl is now using a weak random seed!\n");
257  return nread;
258}
259
260int Curl_ossl_seed(struct SessionHandle *data)
261{
262  /* we have the "SSL is seeded" boolean static to prevent multiple
263     time-consuming seedings in vain */
264  static bool ssl_seeded = FALSE;
265
266  if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
267     data->set.str[STRING_SSL_EGDSOCKET]) {
268    ossl_seed(data);
269    ssl_seeded = TRUE;
270  }
271  return 0;
272}
273
274
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
281static int do_file_type(const char *type)
282{
283  if(!type || !type[0])
284    return SSL_FILETYPE_PEM;
285  if(Curl_raw_equal(type, "PEM"))
286    return SSL_FILETYPE_PEM;
287  if(Curl_raw_equal(type, "DER"))
288    return SSL_FILETYPE_ASN1;
289  if(Curl_raw_equal(type, "ENG"))
290    return SSL_FILETYPE_ENGINE;
291  if(Curl_raw_equal(type, "P12"))
292    return SSL_FILETYPE_PKCS12;
293  return -1;
294}
295
296static
297int 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)
303{
304  struct SessionHandle *data = conn->data;
305
306  int file_type = do_file_type(cert_type);
307
308  if(cert_file != NULL || file_type == SSL_FILETYPE_ENGINE) {
309    SSL *ssl;
310    X509 *x509;
311    int cert_done = 0;
312
313    if(data->set.str[STRING_KEY_PASSWD]) {
314#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
315      /*
316       * If password has been given, we store that in the global
317       * area (*shudder*) for a while:
318       */
319      size_t len = strlen(data->set.str[STRING_KEY_PASSWD]);
320      if(len < sizeof(global_passwd))
321        memcpy(global_passwd, data->set.str[STRING_KEY_PASSWD], len+1);
322      else
323        global_passwd[0] = '\0';
324#else
325      /*
326       * We set the password in the callback userdata
327       */
328      SSL_CTX_set_default_passwd_cb_userdata(ctx,
329                                             data->set.str[STRING_KEY_PASSWD]);
330#endif
331      /* Set passwd callback: */
332      SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
333    }
334
335
336#define SSL_CLIENT_CERT_ERR \
337    "unable to use client certificate (no key found or wrong pass phrase?)"
338
339    switch(file_type) {
340    case SSL_FILETYPE_PEM:
341      /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
342      if(SSL_CTX_use_certificate_chain_file(ctx,
343                                            cert_file) != 1) {
344        failf(data, SSL_CLIENT_CERT_ERR);
345        return 0;
346      }
347      break;
348
349    case SSL_FILETYPE_ASN1:
350      /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
351         we use the case above for PEM so this can only be performed with
352         ASN1 files. */
353      if(SSL_CTX_use_certificate_file(ctx,
354                                      cert_file,
355                                      file_type) != 1) {
356        failf(data, SSL_CLIENT_CERT_ERR);
357        return 0;
358      }
359      break;
360    case SSL_FILETYPE_ENGINE:
361#if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
362      {
363        if(data->state.engine) {
364          const char *cmd_name = "LOAD_CERT_CTRL";
365          struct {
366            const char *cert_id;
367            X509 *cert;
368          } params;
369
370          params.cert_id = cert_file;
371          params.cert = NULL;
372
373          /* Does the engine supports LOAD_CERT_CTRL ? */
374          if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
375                          0, (void *)cmd_name, NULL)) {
376            failf(data, "ssl engine does not support loading certificates");
377            return 0;
378          }
379
380          /* Load the certificate from the engine */
381          if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name,
382                              0, &params, NULL, 1)) {
383            failf(data, "ssl engine cannot load client cert with id"
384                  " '%s' [%s]", cert_file,
385                  ERR_error_string(ERR_get_error(), NULL));
386            return 0;
387          }
388
389          if(!params.cert) {
390            failf(data, "ssl engine didn't initialized the certificate "
391                  "properly.");
392            return 0;
393          }
394
395          if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
396            failf(data, "unable to set client certificate");
397            X509_free(params.cert);
398            return 0;
399          }
400          X509_free(params.cert); /* we don't need the handle any more... */
401        }
402        else {
403          failf(data, "crypto engine not set, can't load certificate");
404          return 0;
405        }
406      }
407      break;
408#else
409      failf(data, "file type ENG for certificate not implemented");
410      return 0;
411#endif
412
413    case SSL_FILETYPE_PKCS12:
414    {
415#ifdef HAVE_PKCS12_SUPPORT
416      FILE *f;
417      PKCS12 *p12;
418      EVP_PKEY *pri;
419      STACK_OF(X509) *ca = NULL;
420      int i;
421
422      f = fopen(cert_file,"rb");
423      if(!f) {
424        failf(data, "could not open PKCS12 file '%s'", cert_file);
425        return 0;
426      }
427      p12 = d2i_PKCS12_fp(f, NULL);
428      fclose(f);
429
430      if(!p12) {
431        failf(data, "error reading PKCS12 file '%s'", cert_file );
432        return 0;
433      }
434
435      PKCS12_PBE_add();
436
437      if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509,
438                        &ca)) {
439        failf(data,
440              "could not parse PKCS12 file, check password, OpenSSL error %s",
441              ERR_error_string(ERR_get_error(), NULL) );
442        PKCS12_free(p12);
443        return 0;
444      }
445
446      PKCS12_free(p12);
447
448      if(SSL_CTX_use_certificate(ctx, x509) != 1) {
449        failf(data, SSL_CLIENT_CERT_ERR);
450        EVP_PKEY_free(pri);
451        X509_free(x509);
452        sk_X509_pop_free(ca, X509_free);
453        return 0;
454      }
455
456      if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
457        failf(data, "unable to use private key from PKCS12 file '%s'",
458              cert_file);
459        EVP_PKEY_free(pri);
460        X509_free(x509);
461        sk_X509_pop_free(ca, X509_free);
462        return 0;
463      }
464
465      if(!SSL_CTX_check_private_key (ctx)) {
466        failf(data, "private key from PKCS12 file '%s' "
467              "does not match certificate in same file", cert_file);
468        EVP_PKEY_free(pri);
469        X509_free(x509);
470        sk_X509_pop_free(ca, X509_free);
471        return 0;
472      }
473      /* Set Certificate Verification chain */
474      if(ca && sk_X509_num(ca)) {
475        for(i = 0; i < sk_X509_num(ca); i++) {
476          if(!SSL_CTX_add_extra_chain_cert(ctx,sk_X509_value(ca, i))) {
477            failf(data, "cannot add certificate to certificate chain");
478            EVP_PKEY_free(pri);
479            X509_free(x509);
480            sk_X509_pop_free(ca, X509_free);
481            return 0;
482          }
483          if(!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i))) {
484            failf(data, "cannot add certificate to client CA list");
485            EVP_PKEY_free(pri);
486            X509_free(x509);
487            sk_X509_pop_free(ca, X509_free);
488            return 0;
489          }
490        }
491      }
492
493      EVP_PKEY_free(pri);
494      X509_free(x509);
495      sk_X509_pop_free(ca, X509_free);
496      cert_done = 1;
497      break;
498#else
499      failf(data, "file type P12 for certificate not supported");
500      return 0;
501#endif
502    }
503    default:
504      failf(data, "not supported file type '%s' for certificate", cert_type);
505      return 0;
506    }
507
508    file_type = do_file_type(key_type);
509
510    switch(file_type) {
511    case SSL_FILETYPE_PEM:
512      if(cert_done)
513        break;
514      if(key_file == NULL)
515        /* cert & key can only be in PEM case in the same file */
516        key_file=cert_file;
517    case SSL_FILETYPE_ASN1:
518      if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
519        failf(data, "unable to set private key file: '%s' type %s",
520              key_file, key_type?key_type:"PEM");
521        return 0;
522      }
523      break;
524    case SSL_FILETYPE_ENGINE:
525#ifdef HAVE_OPENSSL_ENGINE_H
526      {                         /* XXXX still needs some work */
527        EVP_PKEY *priv_key = NULL;
528        if(data->state.engine) {
529#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
530          UI_METHOD *ui_method = UI_OpenSSL();
531#endif
532          /* the typecast below was added to please mingw32 */
533          priv_key = (EVP_PKEY *)
534            ENGINE_load_private_key(data->state.engine,key_file,
535#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
536                                    ui_method,
537#endif
538                                    data->set.str[STRING_KEY_PASSWD]);
539          if(!priv_key) {
540            failf(data, "failed to load private key from crypto engine");
541            return 0;
542          }
543          if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
544            failf(data, "unable to set private key");
545            EVP_PKEY_free(priv_key);
546            return 0;
547          }
548          EVP_PKEY_free(priv_key);  /* we don't need the handle any more... */
549        }
550        else {
551          failf(data, "crypto engine not set, can't load private key");
552          return 0;
553        }
554      }
555      break;
556#else
557      failf(data, "file type ENG for private key not supported");
558      return 0;
559#endif
560    case SSL_FILETYPE_PKCS12:
561      if(!cert_done) {
562        failf(data, "file type P12 for private key not supported");
563        return 0;
564      }
565      break;
566    default:
567      failf(data, "not supported file type for private key");
568      return 0;
569    }
570
571    ssl=SSL_new(ctx);
572    if(NULL == ssl) {
573      failf(data,"unable to create an SSL structure");
574      return 0;
575    }
576
577    x509=SSL_get_certificate(ssl);
578
579    /* This version was provided by Evan Jordan and is supposed to not
580       leak memory as the previous version: */
581    if(x509 != NULL) {
582      EVP_PKEY *pktmp = X509_get_pubkey(x509);
583      EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));
584      EVP_PKEY_free(pktmp);
585    }
586
587    SSL_free(ssl);
588
589    /* If we are using DSA, we can copy the parameters from
590     * the private key */
591
592
593    /* Now we know that a key and cert have been set against
594     * the SSL context */
595    if(!SSL_CTX_check_private_key(ctx)) {
596      failf(data, "Private key does not match the certificate public key");
597      return 0;
598    }
599#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
600    /* erase it now */
601    memset(global_passwd, 0, sizeof(global_passwd));
602#endif
603  }
604  return 1;
605}
606
607/* returns non-zero on failure */
608static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
609{
610#if 0
611  return X509_NAME_oneline(a, buf, size);
612#else
613  BIO *bio_out = BIO_new(BIO_s_mem());
614  BUF_MEM *biomem;
615  int rc;
616
617  if(!bio_out)
618    return 1; /* alloc failed! */
619
620  rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC);
621  BIO_get_mem_ptr(bio_out, &biomem);
622
623  if((size_t)biomem->length < size)
624    size = biomem->length;
625  else
626    size--; /* don't overwrite the buffer end */
627
628  memcpy(buf, biomem->data, size);
629  buf[size]=0;
630
631  BIO_free(bio_out);
632
633  return !rc;
634#endif
635}
636
637static
638int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
639{
640  X509 *err_cert;
641  char buf[256];
642
643  err_cert=X509_STORE_CTX_get_current_cert(ctx);
644  (void)x509_name_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
645  return ok;
646}
647
648/* Return error string for last OpenSSL error
649 */
650static char *SSL_strerror(unsigned long error, char *buf, size_t size)
651{
652#ifdef HAVE_ERR_ERROR_STRING_N
653  /* OpenSSL 0.9.6 and later has a function named
654     ERRO_error_string_n() that takes the size of the buffer as a
655     third argument */
656  ERR_error_string_n(error, buf, size);
657#else
658  (void) size;
659  ERR_error_string(error, buf);
660#endif
661  return buf;
662}
663
664#endif /* USE_SSLEAY */
665
666#ifdef USE_SSLEAY
667/**
668 * Global SSL init
669 *
670 * @retval 0 error initializing SSL
671 * @retval 1 SSL initialized successfully
672 */
673int Curl_ossl_init(void)
674{
675#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
676  ENGINE_load_builtin_engines();
677#endif
678
679  /* Lets get nice error messages */
680  SSL_load_error_strings();
681
682  /* Init the global ciphers and digests */
683  if(!SSLeay_add_ssl_algorithms())
684    return 0;
685
686  OpenSSL_add_all_algorithms();
687
688  return 1;
689}
690
691#endif /* USE_SSLEAY */
692
693#ifdef USE_SSLEAY
694
695/* Global cleanup */
696void Curl_ossl_cleanup(void)
697{
698  /* Free ciphers and digests lists */
699  EVP_cleanup();
700
701#ifdef HAVE_ENGINE_CLEANUP
702  /* Free engine list */
703  ENGINE_cleanup();
704#endif
705
706#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
707  /* Free OpenSSL ex_data table */
708  CRYPTO_cleanup_all_ex_data();
709#endif
710
711  /* Free OpenSSL error strings */
712  ERR_free_strings();
713
714  /* Free thread local error state, destroying hash upon zero refcount */
715#ifdef HAVE_ERR_REMOVE_THREAD_STATE
716  ERR_remove_thread_state(NULL);
717#else
718  ERR_remove_state(0);
719#endif
720}
721
722/*
723 * This function uses SSL_peek to determine connection status.
724 *
725 * Return codes:
726 *     1 means the connection is still in place
727 *     0 means the connection has been closed
728 *    -1 means the connection status is unknown
729 */
730int Curl_ossl_check_cxn(struct connectdata *conn)
731{
732  int rc;
733  char buf;
734
735  rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1);
736  if(rc > 0)
737    return 1; /* connection still in place */
738
739  if(rc == 0)
740    return 0; /* connection has been closed */
741
742  return -1; /* connection status unknown */
743}
744
745/* Selects an OpenSSL crypto engine
746 */
747CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
748{
749#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
750  ENGINE *e;
751
752#if OPENSSL_VERSION_NUMBER >= 0x00909000L
753  e = ENGINE_by_id(engine);
754#else
755  /* avoid memory leak */
756  for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
757    const char *e_id = ENGINE_get_id(e);
758    if(!strcmp(engine, e_id))
759      break;
760  }
761#endif
762
763  if(!e) {
764    failf(data, "SSL Engine '%s' not found", engine);
765    return CURLE_SSL_ENGINE_NOTFOUND;
766  }
767
768  if(data->state.engine) {
769    ENGINE_finish(data->state.engine);
770    ENGINE_free(data->state.engine);
771    data->state.engine = NULL;
772  }
773  if(!ENGINE_init(e)) {
774    char buf[256];
775
776    ENGINE_free(e);
777    failf(data, "Failed to initialise SSL Engine '%s':\n%s",
778          engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf)));
779    return CURLE_SSL_ENGINE_INITFAILED;
780  }
781  data->state.engine = e;
782  return CURLE_OK;
783#else
784  (void)engine;
785  failf(data, "SSL Engine not supported");
786  return CURLE_SSL_ENGINE_NOTFOUND;
787#endif
788}
789
790/* Sets engine as default for all SSL operations
791 */
792CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
793{
794#ifdef HAVE_OPENSSL_ENGINE_H
795  if(data->state.engine) {
796    if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
797      infof(data,"set default crypto engine '%s'\n",
798            ENGINE_get_id(data->state.engine));
799    }
800    else {
801      failf(data, "set default crypto engine '%s' failed",
802            ENGINE_get_id(data->state.engine));
803      return CURLE_SSL_ENGINE_SETFAILED;
804    }
805  }
806#else
807  (void) data;
808#endif
809  return CURLE_OK;
810}
811
812/* Return list of OpenSSL crypto engine names.
813 */
814struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
815{
816  struct curl_slist *list = NULL;
817#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
818  struct curl_slist *beg;
819  ENGINE *e;
820
821  for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
822    beg = curl_slist_append(list, ENGINE_get_id(e));
823    if(!beg) {
824      curl_slist_free_all(list);
825      return NULL;
826    }
827    list = beg;
828  }
829#endif
830  (void) data;
831  return list;
832}
833
834
835/*
836 * This function is called when an SSL connection is closed.
837 */
838void Curl_ossl_close(struct connectdata *conn, int sockindex)
839{
840  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
841
842  if(connssl->handle) {
843    (void)SSL_shutdown(connssl->handle);
844    SSL_set_connect_state(connssl->handle);
845
846    SSL_free (connssl->handle);
847    connssl->handle = NULL;
848  }
849  if(connssl->ctx) {
850    SSL_CTX_free (connssl->ctx);
851    connssl->ctx = NULL;
852  }
853}
854
855/*
856 * This function is called to shut down the SSL layer but keep the
857 * socket open (CCC - Clear Command Channel)
858 */
859int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
860{
861  int retval = 0;
862  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
863  struct SessionHandle *data = conn->data;
864  char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
865                    to be at least 120 bytes long. */
866  unsigned long sslerror;
867  ssize_t nread;
868  int buffsize;
869  int err;
870  int done = 0;
871
872  /* This has only been tested on the proftpd server, and the mod_tls code
873     sends a close notify alert without waiting for a close notify alert in
874     response. Thus we wait for a close notify alert from the server, but
875     we do not send one. Let's hope other servers do the same... */
876
877  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
878      (void)SSL_shutdown(connssl->handle);
879
880  if(connssl->handle) {
881    buffsize = (int)sizeof(buf);
882    while(!done) {
883      int what = Curl_socket_ready(conn->sock[sockindex],
884                                   CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
885      if(what > 0) {
886        ERR_clear_error();
887
888        /* Something to read, let's do it and hope that it is the close
889           notify alert from the server */
890        nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
891                                  buffsize);
892        err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
893
894        switch(err) {
895        case SSL_ERROR_NONE: /* this is not an error */
896        case SSL_ERROR_ZERO_RETURN: /* no more data */
897          /* This is the expected response. There was no data but only
898             the close notify alert */
899          done = 1;
900          break;
901        case SSL_ERROR_WANT_READ:
902          /* there's data pending, re-invoke SSL_read() */
903          infof(data, "SSL_ERROR_WANT_READ\n");
904          break;
905        case SSL_ERROR_WANT_WRITE:
906          /* SSL wants a write. Really odd. Let's bail out. */
907          infof(data, "SSL_ERROR_WANT_WRITE\n");
908          done = 1;
909          break;
910        default:
911          /* openssl/ssl.h says "look at error stack/return value/errno" */
912          sslerror = ERR_get_error();
913          failf(conn->data, "SSL read: %s, errno %d",
914                ERR_error_string(sslerror, buf),
915                SOCKERRNO);
916          done = 1;
917          break;
918        }
919      }
920      else if(0 == what) {
921        /* timeout */
922        failf(data, "SSL shutdown timeout");
923        done = 1;
924      }
925      else {
926        /* anything that gets here is fatally bad */
927        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
928        retval = -1;
929        done = 1;
930      }
931    } /* while()-loop for the select() */
932
933    if(data->set.verbose) {
934#ifdef HAVE_SSL_GET_SHUTDOWN
935      switch(SSL_get_shutdown(connssl->handle)) {
936      case SSL_SENT_SHUTDOWN:
937        infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
938        break;
939      case SSL_RECEIVED_SHUTDOWN:
940        infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
941        break;
942      case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
943        infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
944              "SSL_RECEIVED__SHUTDOWN\n");
945        break;
946      }
947#endif
948    }
949
950    SSL_free (connssl->handle);
951    connssl->handle = NULL;
952  }
953  return retval;
954}
955
956void Curl_ossl_session_free(void *ptr)
957{
958  /* free the ID */
959  SSL_SESSION_free(ptr);
960}
961
962/*
963 * This function is called when the 'data' struct is going away. Close
964 * down everything and free all resources!
965 */
966int Curl_ossl_close_all(struct SessionHandle *data)
967{
968#ifdef HAVE_OPENSSL_ENGINE_H
969  if(data->state.engine) {
970    ENGINE_finish(data->state.engine);
971    ENGINE_free(data->state.engine);
972    data->state.engine = NULL;
973  }
974#else
975  (void)data;
976#endif
977  return 0;
978}
979
980static int asn1_output(const ASN1_UTCTIME *tm,
981                       char *buf,
982                       size_t sizeofbuf)
983{
984  const char *asn1_string;
985  int gmt=FALSE;
986  int i;
987  int year=0,month=0,day=0,hour=0,minute=0,second=0;
988
989  i=tm->length;
990  asn1_string=(const char *)tm->data;
991
992  if(i < 10)
993    return 1;
994  if(asn1_string[i-1] == 'Z')
995    gmt=TRUE;
996  for(i=0; i<10; i++)
997    if((asn1_string[i] > '9') || (asn1_string[i] < '0'))
998      return 2;
999
1000  year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0');
1001  if(year < 50)
1002    year+=100;
1003
1004  month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0');
1005  if((month > 12) || (month < 1))
1006    return 3;
1007
1008  day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0');
1009  hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0');
1010  minute=  (asn1_string[8]-'0')*10+(asn1_string[9]-'0');
1011
1012  if((asn1_string[10] >= '0') && (asn1_string[10] <= '9') &&
1013     (asn1_string[11] >= '0') && (asn1_string[11] <= '9'))
1014    second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0');
1015
1016  snprintf(buf, sizeofbuf,
1017           "%04d-%02d-%02d %02d:%02d:%02d %s",
1018           year+1900, month, day, hour, minute, second, (gmt?"GMT":""));
1019
1020  return 0;
1021}
1022
1023/* ====================================================== */
1024
1025
1026/* Quote from RFC2818 section 3.1 "Server Identity"
1027
1028   If a subjectAltName extension of type dNSName is present, that MUST
1029   be used as the identity. Otherwise, the (most specific) Common Name
1030   field in the Subject field of the certificate MUST be used. Although
1031   the use of the Common Name is existing practice, it is deprecated and
1032   Certification Authorities are encouraged to use the dNSName instead.
1033
1034   Matching is performed using the matching rules specified by
1035   [RFC2459].  If more than one identity of a given type is present in
1036   the certificate (e.g., more than one dNSName name, a match in any one
1037   of the set is considered acceptable.) Names may contain the wildcard
1038   character * which is considered to match any single domain name
1039   component or component fragment. E.g., *.a.com matches foo.a.com but
1040   not bar.foo.a.com. f*.com matches foo.com but not bar.com.
1041
1042   In some cases, the URI is specified as an IP address rather than a
1043   hostname. In this case, the iPAddress subjectAltName must be present
1044   in the certificate and must exactly match the IP in the URI.
1045
1046*/
1047static CURLcode verifyhost(struct connectdata *conn,
1048                           X509 *server_cert)
1049{
1050  int matched = -1; /* -1 is no alternative match yet, 1 means match and 0
1051                       means mismatch */
1052  int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
1053  size_t addrlen = 0;
1054  struct SessionHandle *data = conn->data;
1055  STACK_OF(GENERAL_NAME) *altnames;
1056#ifdef ENABLE_IPV6
1057  struct in6_addr addr;
1058#else
1059  struct in_addr addr;
1060#endif
1061  CURLcode res = CURLE_OK;
1062
1063#ifdef ENABLE_IPV6
1064  if(conn->bits.ipv6_ip &&
1065     Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
1066    target = GEN_IPADD;
1067    addrlen = sizeof(struct in6_addr);
1068  }
1069  else
1070#endif
1071    if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
1072      target = GEN_IPADD;
1073      addrlen = sizeof(struct in_addr);
1074    }
1075
1076  /* get a "list" of alternative names */
1077  altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
1078
1079  if(altnames) {
1080    int numalts;
1081    int i;
1082
1083    /* get amount of alternatives, RFC2459 claims there MUST be at least
1084       one, but we don't depend on it... */
1085    numalts = sk_GENERAL_NAME_num(altnames);
1086
1087    /* loop through all alternatives while none has matched */
1088    for(i=0; (i<numalts) && (matched != 1); i++) {
1089      /* get a handle to alternative name number i */
1090      const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
1091
1092      /* only check alternatives of the same type the target is */
1093      if(check->type == target) {
1094        /* get data and length */
1095        const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
1096        size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
1097
1098        switch(target) {
1099        case GEN_DNS: /* name/pattern comparison */
1100          /* The OpenSSL man page explicitly says: "In general it cannot be
1101             assumed that the data returned by ASN1_STRING_data() is null
1102             terminated or does not contain embedded nulls." But also that
1103             "The actual format of the data will depend on the actual string
1104             type itself: for example for and IA5String the data will be ASCII"
1105
1106             Gisle researched the OpenSSL sources:
1107             "I checked the 0.9.6 and 0.9.8 sources before my patch and
1108             it always 0-terminates an IA5String."
1109          */
1110          if((altlen == strlen(altptr)) &&
1111             /* if this isn't true, there was an embedded zero in the name
1112                string and we cannot match it. */
1113             Curl_cert_hostcheck(altptr, conn->host.name))
1114            matched = 1;
1115          else
1116            matched = 0;
1117          break;
1118
1119        case GEN_IPADD: /* IP address comparison */
1120          /* compare alternative IP address if the data chunk is the same size
1121             our server IP address is */
1122          if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
1123            matched = 1;
1124          else
1125            matched = 0;
1126          break;
1127        }
1128      }
1129    }
1130    GENERAL_NAMES_free(altnames);
1131  }
1132
1133  if(matched == 1)
1134    /* an alternative name matched the server hostname */
1135    infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
1136  else if(matched == 0) {
1137    /* an alternative name field existed, but didn't match and then
1138       we MUST fail */
1139    infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
1140    res = CURLE_PEER_FAILED_VERIFICATION;
1141  }
1142  else {
1143    /* we have to look to the last occurrence of a commonName in the
1144       distinguished one to get the most significant one. */
1145    int j,i=-1 ;
1146
1147/* The following is done because of a bug in 0.9.6b */
1148
1149    unsigned char *nulstr = (unsigned char *)"";
1150    unsigned char *peer_CN = nulstr;
1151
1152    X509_NAME *name = X509_get_subject_name(server_cert) ;
1153    if(name)
1154      while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i))>=0)
1155        i=j;
1156
1157    /* we have the name entry and we will now convert this to a string
1158       that we can use for comparison. Doing this we support BMPstring,
1159       UTF8 etc. */
1160
1161    if(i>=0) {
1162      ASN1_STRING *tmp = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
1163
1164      /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
1165         is already UTF-8 encoded. We check for this case and copy the raw
1166         string manually to avoid the problem. This code can be made
1167         conditional in the future when OpenSSL has been fixed. Work-around
1168         brought by Alexis S. L. Carvalho. */
1169      if(tmp) {
1170        if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
1171          j = ASN1_STRING_length(tmp);
1172          if(j >= 0) {
1173            peer_CN = OPENSSL_malloc(j+1);
1174            if(peer_CN) {
1175              memcpy(peer_CN, ASN1_STRING_data(tmp), j);
1176              peer_CN[j] = '\0';
1177            }
1178          }
1179        }
1180        else /* not a UTF8 name */
1181          j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
1182
1183        if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != j)) {
1184          /* there was a terminating zero before the end of string, this
1185             cannot match and we return failure! */
1186          failf(data, "SSL: illegal cert name field");
1187          res = CURLE_PEER_FAILED_VERIFICATION;
1188        }
1189      }
1190    }
1191
1192    if(peer_CN == nulstr)
1193       peer_CN = NULL;
1194    else {
1195      /* convert peer_CN from UTF8 */
1196      CURLcode rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
1197      /* Curl_convert_from_utf8 calls failf if unsuccessful */
1198      if(rc) {
1199        OPENSSL_free(peer_CN);
1200        return rc;
1201      }
1202    }
1203
1204    if(res)
1205      /* error already detected, pass through */
1206      ;
1207    else if(!peer_CN) {
1208      failf(data,
1209            "SSL: unable to obtain common name from peer certificate");
1210      res = CURLE_PEER_FAILED_VERIFICATION;
1211    }
1212    else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
1213      failf(data, "SSL: certificate subject name '%s' does not match "
1214            "target host name '%s'", peer_CN, conn->host.dispname);
1215      res = CURLE_PEER_FAILED_VERIFICATION;
1216    }
1217    else {
1218      infof(data, "\t common name: %s (matched)\n", peer_CN);
1219    }
1220    if(peer_CN)
1221      OPENSSL_free(peer_CN);
1222  }
1223  return res;
1224}
1225#endif /* USE_SSLEAY */
1226
1227/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
1228   and thus this cannot be done there. */
1229#ifdef SSL_CTRL_SET_MSG_CALLBACK
1230
1231static const char *ssl_msg_type(int ssl_ver, int msg)
1232{
1233  if(ssl_ver == SSL2_VERSION_MAJOR) {
1234    switch (msg) {
1235      case SSL2_MT_ERROR:
1236        return "Error";
1237      case SSL2_MT_CLIENT_HELLO:
1238        return "Client hello";
1239      case SSL2_MT_CLIENT_MASTER_KEY:
1240        return "Client key";
1241      case SSL2_MT_CLIENT_FINISHED:
1242        return "Client finished";
1243      case SSL2_MT_SERVER_HELLO:
1244        return "Server hello";
1245      case SSL2_MT_SERVER_VERIFY:
1246        return "Server verify";
1247      case SSL2_MT_SERVER_FINISHED:
1248        return "Server finished";
1249      case SSL2_MT_REQUEST_CERTIFICATE:
1250        return "Request CERT";
1251      case SSL2_MT_CLIENT_CERTIFICATE:
1252        return "Client CERT";
1253    }
1254  }
1255  else if(ssl_ver == SSL3_VERSION_MAJOR) {
1256    switch (msg) {
1257      case SSL3_MT_HELLO_REQUEST:
1258        return "Hello request";
1259      case SSL3_MT_CLIENT_HELLO:
1260        return "Client hello";
1261      case SSL3_MT_SERVER_HELLO:
1262        return "Server hello";
1263      case SSL3_MT_CERTIFICATE:
1264        return "CERT";
1265      case SSL3_MT_SERVER_KEY_EXCHANGE:
1266        return "Server key exchange";
1267      case SSL3_MT_CLIENT_KEY_EXCHANGE:
1268        return "Client key exchange";
1269      case SSL3_MT_CERTIFICATE_REQUEST:
1270        return "Request CERT";
1271      case SSL3_MT_SERVER_DONE:
1272        return "Server finished";
1273      case SSL3_MT_CERTIFICATE_VERIFY:
1274        return "CERT verify";
1275      case SSL3_MT_FINISHED:
1276        return "Finished";
1277    }
1278  }
1279  return "Unknown";
1280}
1281
1282static const char *tls_rt_type(int type)
1283{
1284  return (
1285    type == SSL3_RT_CHANGE_CIPHER_SPEC ? "TLS change cipher, " :
1286    type == SSL3_RT_ALERT              ? "TLS alert, "         :
1287    type == SSL3_RT_HANDSHAKE          ? "TLS handshake, "     :
1288    type == SSL3_RT_APPLICATION_DATA   ? "TLS app data, "      :
1289                                         "TLS Unknown, ");
1290}
1291
1292
1293/*
1294 * Our callback from the SSL/TLS layers.
1295 */
1296static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
1297                          const void *buf, size_t len, const SSL *ssl,
1298                          struct connectdata *conn)
1299{
1300  struct SessionHandle *data;
1301  const char *msg_name, *tls_rt_name;
1302  char ssl_buf[1024];
1303  int  ver, msg_type, txt_len;
1304
1305  if(!conn || !conn->data || !conn->data->set.fdebug ||
1306     (direction != 0 && direction != 1))
1307    return;
1308
1309  data = conn->data;
1310  ssl_ver >>= 8;
1311  ver = (ssl_ver == SSL2_VERSION_MAJOR ? '2' :
1312         ssl_ver == SSL3_VERSION_MAJOR ? '3' : '?');
1313
1314  /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
1315   * always pass-up content-type as 0. But the interesting message-type
1316   * is at 'buf[0]'.
1317   */
1318  if(ssl_ver == SSL3_VERSION_MAJOR && content_type != 0)
1319    tls_rt_name = tls_rt_type(content_type);
1320  else
1321    tls_rt_name = "";
1322
1323  msg_type = *(char*)buf;
1324  msg_name = ssl_msg_type(ssl_ver, msg_type);
1325
1326  txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n",
1327                     ver, tls_rt_name, msg_name, msg_type);
1328  Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
1329
1330  Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
1331             CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
1332  (void) ssl;
1333}
1334#endif
1335
1336#ifdef USE_SSLEAY
1337/* ====================================================== */
1338
1339#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1340#  define use_sni(x)  sni = (x)
1341#else
1342#  define use_sni(x)  Curl_nop_stmt
1343#endif
1344
1345static CURLcode
1346ossl_connect_step1(struct connectdata *conn,
1347                   int sockindex)
1348{
1349  CURLcode retcode = CURLE_OK;
1350
1351  struct SessionHandle *data = conn->data;
1352  SSL_METHOD_QUAL SSL_METHOD *req_method=NULL;
1353  void *ssl_sessionid=NULL;
1354  X509_LOOKUP *lookup=NULL;
1355  curl_socket_t sockfd = conn->sock[sockindex];
1356  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1357  long ctx_options;
1358#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1359  bool sni;
1360#ifdef ENABLE_IPV6
1361  struct in6_addr addr;
1362#else
1363  struct in_addr addr;
1364#endif
1365#endif
1366
1367  DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
1368
1369  /* Make funny stuff to get random input */
1370  Curl_ossl_seed(data);
1371
1372  /* check to see if we've been told to use an explicit SSL/TLS version */
1373
1374  switch(data->set.ssl.version) {
1375  default:
1376  case CURL_SSLVERSION_DEFAULT:
1377#ifdef USE_TLS_SRP
1378    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
1379      infof(data, "Set version TLSv1 for SRP authorisation\n");
1380      req_method = TLSv1_client_method() ;
1381    }
1382    else
1383#endif
1384    /* we try to figure out version */
1385    req_method = SSLv23_client_method();
1386    use_sni(TRUE);
1387    break;
1388  case CURL_SSLVERSION_TLSv1:
1389    req_method = TLSv1_client_method();
1390    use_sni(TRUE);
1391    break;
1392  case CURL_SSLVERSION_SSLv2:
1393#ifdef OPENSSL_NO_SSL2
1394    failf(data, "OpenSSL was built without SSLv2 support");
1395    return CURLE_NOT_BUILT_IN;
1396#else
1397#ifdef USE_TLS_SRP
1398    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
1399      return CURLE_SSL_CONNECT_ERROR;
1400#endif
1401    req_method = SSLv2_client_method();
1402    use_sni(FALSE);
1403    break;
1404#endif
1405  case CURL_SSLVERSION_SSLv3:
1406#ifdef USE_TLS_SRP
1407    if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
1408      return CURLE_SSL_CONNECT_ERROR;
1409#endif
1410    req_method = SSLv3_client_method();
1411    use_sni(FALSE);
1412    break;
1413  }
1414
1415  if(connssl->ctx)
1416    SSL_CTX_free(connssl->ctx);
1417  connssl->ctx = SSL_CTX_new(req_method);
1418
1419  if(!connssl->ctx) {
1420    failf(data, "SSL: couldn't create a context: %s",
1421          ERR_error_string(ERR_peek_error(), NULL));
1422    return CURLE_OUT_OF_MEMORY;
1423  }
1424
1425#ifdef SSL_MODE_RELEASE_BUFFERS
1426  SSL_CTX_set_mode(connssl->ctx, SSL_MODE_RELEASE_BUFFERS);
1427#endif
1428
1429#ifdef SSL_CTRL_SET_MSG_CALLBACK
1430  if(data->set.fdebug && data->set.verbose) {
1431    /* the SSL trace callback is only used for verbose logging so we only
1432       inform about failures of setting it */
1433    if(!SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
1434                               (void (*)(void))ssl_tls_trace)) {
1435      infof(data, "SSL: couldn't set callback!\n");
1436    }
1437    else if(!SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0,
1438                          conn)) {
1439      infof(data, "SSL: couldn't set callback argument!\n");
1440    }
1441  }
1442#endif
1443
1444  /* OpenSSL contains code to work-around lots of bugs and flaws in various
1445     SSL-implementations. SSL_CTX_set_options() is used to enabled those
1446     work-arounds. The man page for this option states that SSL_OP_ALL enables
1447     all the work-arounds and that "It is usually safe to use SSL_OP_ALL to
1448     enable the bug workaround options if compatibility with somewhat broken
1449     implementations is desired."
1450
1451     The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to
1452     disable "rfc4507bis session ticket support".  rfc4507bis was later turned
1453     into the proper RFC5077 it seems: http://tools.ietf.org/html/rfc5077
1454
1455     The enabled extension concerns the session management. I wonder how often
1456     libcurl stops a connection and then resumes a TLS session. also, sending
1457     the session data is some overhead. .I suggest that you just use your
1458     proposed patch (which explicitly disables TICKET).
1459
1460     If someone writes an application with libcurl and openssl who wants to
1461     enable the feature, one can do this in the SSL callback.
1462
1463     SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper
1464     interoperability with web server Netscape Enterprise Server 2.0.1 which
1465     was released back in 1996.
1466
1467     Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has
1468     become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate
1469     CVE-2010-4180 when using previous OpenSSL versions we no longer enable
1470     this option regardless of OpenSSL version and SSL_OP_ALL definition.
1471
1472     OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability
1473     (http://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to
1474     SSL_OP_ALL that _disables_ that work-around despite the fact that
1475     SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to
1476     keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit
1477     must not be set.
1478  */
1479
1480  ctx_options = SSL_OP_ALL;
1481
1482#ifdef SSL_OP_NO_TICKET
1483  ctx_options |= SSL_OP_NO_TICKET;
1484#endif
1485
1486#ifdef SSL_OP_NO_COMPRESSION
1487  ctx_options |= SSL_OP_NO_COMPRESSION;
1488#endif
1489
1490#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
1491  /* mitigate CVE-2010-4180 */
1492  ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
1493#endif
1494
1495#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
1496  /* unless the user explicitly ask to allow the protocol vulnerability we
1497     use the work-around */
1498  if(!conn->data->set.ssl_enable_beast)
1499    ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
1500#endif
1501
1502  /* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
1503  if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
1504    ctx_options |= SSL_OP_NO_SSLv2;
1505
1506  SSL_CTX_set_options(connssl->ctx, ctx_options);
1507
1508  if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) {
1509    if(!cert_stuff(conn,
1510                   connssl->ctx,
1511                   data->set.str[STRING_CERT],
1512                   data->set.str[STRING_CERT_TYPE],
1513                   data->set.str[STRING_KEY],
1514                   data->set.str[STRING_KEY_TYPE])) {
1515      /* failf() is already done in cert_stuff() */
1516      return CURLE_SSL_CERTPROBLEM;
1517    }
1518  }
1519
1520  if(data->set.str[STRING_SSL_CIPHER_LIST]) {
1521    if(!SSL_CTX_set_cipher_list(connssl->ctx,
1522                                data->set.str[STRING_SSL_CIPHER_LIST])) {
1523      failf(data, "failed setting cipher list");
1524      return CURLE_SSL_CIPHER;
1525    }
1526  }
1527
1528#ifdef USE_TLS_SRP
1529  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
1530    infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
1531
1532    if(!SSL_CTX_set_srp_username(connssl->ctx, data->set.ssl.username)) {
1533      failf(data, "Unable to set SRP user name");
1534      return CURLE_BAD_FUNCTION_ARGUMENT;
1535    }
1536    if(!SSL_CTX_set_srp_password(connssl->ctx,data->set.ssl.password)) {
1537      failf(data, "failed setting SRP password");
1538      return CURLE_BAD_FUNCTION_ARGUMENT;
1539    }
1540    if(!data->set.str[STRING_SSL_CIPHER_LIST]) {
1541      infof(data, "Setting cipher list SRP\n");
1542
1543      if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) {
1544        failf(data, "failed setting SRP cipher list");
1545        return CURLE_SSL_CIPHER;
1546      }
1547    }
1548  }
1549#endif
1550  if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) {
1551    /* tell SSL where to find CA certificates that are used to verify
1552       the servers certificate. */
1553    if(!SSL_CTX_load_verify_locations(connssl->ctx,
1554                                       data->set.str[STRING_SSL_CAFILE],
1555                                       data->set.str[STRING_SSL_CAPATH])) {
1556      if(data->set.ssl.verifypeer) {
1557        /* Fail if we insist on successfully verifying the server. */
1558        failf(data,"error setting certificate verify locations:\n"
1559              "  CAfile: %s\n  CApath: %s",
1560              data->set.str[STRING_SSL_CAFILE]?
1561              data->set.str[STRING_SSL_CAFILE]: "none",
1562              data->set.str[STRING_SSL_CAPATH]?
1563              data->set.str[STRING_SSL_CAPATH] : "none");
1564        return CURLE_SSL_CACERT_BADFILE;
1565      }
1566      else {
1567        /* Just continue with a warning if no strict  certificate verification
1568           is required. */
1569        infof(data, "error setting certificate verify locations,"
1570              " continuing anyway:\n");
1571      }
1572    }
1573    else {
1574      /* Everything is fine. */
1575      infof(data, "successfully set certificate verify locations:\n");
1576    }
1577    infof(data,
1578          "  CAfile: %s\n"
1579          "  CApath: %s\n",
1580          data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
1581          "none",
1582          data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
1583          "none");
1584  }
1585
1586  if(data->set.str[STRING_SSL_CRLFILE]) {
1587    /* tell SSL where to find CRL file that is used to check certificate
1588     * revocation */
1589    lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx),
1590                                 X509_LOOKUP_file());
1591    if(!lookup ||
1592       (!X509_load_crl_file(lookup,data->set.str[STRING_SSL_CRLFILE],
1593                            X509_FILETYPE_PEM)) ) {
1594      failf(data,"error loading CRL file: %s",
1595            data->set.str[STRING_SSL_CRLFILE]);
1596      return CURLE_SSL_CRL_BADFILE;
1597    }
1598    else {
1599      /* Everything is fine. */
1600      infof(data, "successfully load CRL file:\n");
1601      X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
1602                           X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1603    }
1604    infof(data,
1605          "  CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
1606          data->set.str[STRING_SSL_CRLFILE]: "none");
1607  }
1608
1609  /* SSL always tries to verify the peer, this only says whether it should
1610   * fail to connect if the verification fails, or if it should continue
1611   * anyway. In the latter case the result of the verification is checked with
1612   * SSL_get_verify_result() below. */
1613  SSL_CTX_set_verify(connssl->ctx,
1614                     data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
1615                     cert_verify_callback);
1616
1617  /* give application a chance to interfere with SSL set up. */
1618  if(data->set.ssl.fsslctx) {
1619    retcode = (*data->set.ssl.fsslctx)(data, connssl->ctx,
1620                                       data->set.ssl.fsslctxp);
1621    if(retcode) {
1622      failf(data,"error signaled by ssl ctx callback");
1623      return retcode;
1624    }
1625  }
1626
1627  /* Lets make an SSL structure */
1628  if(connssl->handle)
1629    SSL_free(connssl->handle);
1630  connssl->handle = SSL_new(connssl->ctx);
1631  if(!connssl->handle) {
1632    failf(data, "SSL: couldn't create a context (handle)!");
1633    return CURLE_OUT_OF_MEMORY;
1634  }
1635  SSL_set_connect_state(connssl->handle);
1636
1637  connssl->server_cert = 0x0;
1638
1639#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1640  if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
1641#ifdef ENABLE_IPV6
1642     (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
1643#endif
1644     sni &&
1645     !SSL_set_tlsext_host_name(connssl->handle, conn->host.name))
1646    infof(data, "WARNING: failed to configure server name indication (SNI) "
1647          "TLS extension\n");
1648#endif
1649
1650  /* Check if there's a cached ID we can/should use here! */
1651  if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
1652    /* we got a session id, use it! */
1653    if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
1654      failf(data, "SSL: SSL_set_session failed: %s",
1655            ERR_error_string(ERR_get_error(),NULL));
1656      return CURLE_SSL_CONNECT_ERROR;
1657    }
1658    /* Informational message */
1659    infof (data, "SSL re-using session ID\n");
1660  }
1661
1662  /* pass the raw socket into the SSL layers */
1663  if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
1664    failf(data, "SSL: SSL_set_fd failed: %s",
1665          ERR_error_string(ERR_get_error(),NULL));
1666    return CURLE_SSL_CONNECT_ERROR;
1667  }
1668
1669  connssl->connecting_state = ssl_connect_2;
1670  return CURLE_OK;
1671}
1672
1673static CURLcode
1674ossl_connect_step2(struct connectdata *conn, int sockindex)
1675{
1676  struct SessionHandle *data = conn->data;
1677  int err;
1678  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1679
1680  DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1681             || ssl_connect_2_reading == connssl->connecting_state
1682             || ssl_connect_2_writing == connssl->connecting_state);
1683
1684  ERR_clear_error();
1685
1686  err = SSL_connect(connssl->handle);
1687
1688  /* 1  is fine
1689     0  is "not successful but was shut down controlled"
1690     <0 is "handshake was not successful, because a fatal error occurred" */
1691  if(1 != err) {
1692    int detail = SSL_get_error(connssl->handle, err);
1693
1694    if(SSL_ERROR_WANT_READ == detail) {
1695      connssl->connecting_state = ssl_connect_2_reading;
1696      return CURLE_OK;
1697    }
1698    else if(SSL_ERROR_WANT_WRITE == detail) {
1699      connssl->connecting_state = ssl_connect_2_writing;
1700      return CURLE_OK;
1701    }
1702    else {
1703      /* untreated error */
1704      unsigned long errdetail;
1705      char error_buffer[256]; /* OpenSSL documents that this must be at least
1706                                 256 bytes long. */
1707      CURLcode rc;
1708      const char *cert_problem = NULL;
1709      long lerr;
1710
1711      connssl->connecting_state = ssl_connect_2; /* the connection failed,
1712                                                    we're not waiting for
1713                                                    anything else. */
1714
1715      errdetail = ERR_get_error(); /* Gets the earliest error code from the
1716                                      thread's error queue and removes the
1717                                      entry. */
1718
1719      switch(errdetail) {
1720      case 0x1407E086:
1721        /* 1407E086:
1722           SSL routines:
1723           SSL2_SET_CERTIFICATE:
1724           certificate verify failed */
1725        /* fall-through */
1726      case 0x14090086:
1727        /* 14090086:
1728           SSL routines:
1729           SSL3_GET_SERVER_CERTIFICATE:
1730           certificate verify failed */
1731        rc = CURLE_SSL_CACERT;
1732
1733        lerr = SSL_get_verify_result(connssl->handle);
1734        if(lerr != X509_V_OK) {
1735          snprintf(error_buffer, sizeof(error_buffer),
1736                   "SSL certificate problem: %s",
1737                   X509_verify_cert_error_string(lerr));
1738        }
1739        else
1740          cert_problem = "SSL certificate problem, verify that the CA cert is"
1741            " OK.";
1742
1743        break;
1744      default:
1745        rc = CURLE_SSL_CONNECT_ERROR;
1746        SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
1747        break;
1748      }
1749
1750      /* detail is already set to the SSL error above */
1751
1752      /* If we e.g. use SSLv2 request-method and the server doesn't like us
1753       * (RST connection etc.), OpenSSL gives no explanation whatsoever and
1754       * the SO_ERROR is also lost.
1755       */
1756      if(CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
1757        failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
1758              conn->host.name, conn->port);
1759        return rc;
1760      }
1761      /* Could be a CERT problem */
1762
1763      failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
1764      return rc;
1765    }
1766  }
1767  else {
1768    /* we have been connected fine, we're not waiting for anything else. */
1769    connssl->connecting_state = ssl_connect_3;
1770
1771    /* Informational message */
1772    infof (data, "SSL connection using %s\n",
1773           SSL_get_cipher(connssl->handle));
1774
1775    return CURLE_OK;
1776  }
1777}
1778
1779static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
1780{
1781  int i, ilen;
1782
1783  if((ilen = (int)len) < 0)
1784    return 1; /* buffer too big */
1785
1786  i = i2t_ASN1_OBJECT(buf, ilen, a);
1787
1788  if(i >= ilen)
1789    return 1; /* buffer too small */
1790
1791  return 0;
1792}
1793
1794static CURLcode push_certinfo_len(struct SessionHandle *data,
1795                                  int certnum,
1796                                  const char *label,
1797                                  const char *value,
1798                                  size_t valuelen)
1799{
1800  struct curl_certinfo *ci = &data->info.certs;
1801  char *output;
1802  struct curl_slist *nl;
1803  CURLcode res = CURLE_OK;
1804  size_t labellen = strlen(label);
1805  size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
1806
1807  output = malloc(outlen);
1808  if(!output)
1809    return CURLE_OUT_OF_MEMORY;
1810
1811  /* sprintf the label and colon */
1812  snprintf(output, outlen, "%s:", label);
1813
1814  /* memcpy the value (it might not be zero terminated) */
1815  memcpy(&output[labellen+1], value, valuelen);
1816
1817  /* zero terminate the output */
1818  output[labellen + 1 + valuelen] = 0;
1819
1820  /* TODO: we should rather introduce an internal API that can do the
1821     equivalent of curl_slist_append but doesn't strdup() the given data as
1822     like in this place the extra malloc/free is totally pointless */
1823  nl = curl_slist_append(ci->certinfo[certnum], output);
1824  free(output);
1825  if(!nl) {
1826    curl_slist_free_all(ci->certinfo[certnum]);
1827    ci->certinfo[certnum] = NULL;
1828    res = CURLE_OUT_OF_MEMORY;
1829  }
1830  else
1831    ci->certinfo[certnum] = nl;
1832
1833  return res;
1834}
1835
1836/* this is a convenience function for push_certinfo_len that takes a zero
1837   terminated value */
1838static CURLcode push_certinfo(struct SessionHandle *data,
1839                              int certnum,
1840                              const char *label,
1841                              const char *value)
1842{
1843  size_t valuelen = strlen(value);
1844
1845  return push_certinfo_len(data, certnum, label, value, valuelen);
1846}
1847
1848static void pubkey_show(struct SessionHandle *data,
1849                        int num,
1850                        const char *type,
1851                        const char *name,
1852                        unsigned char *raw,
1853                        int len)
1854{
1855  size_t left;
1856  int i;
1857  char namebuf[32];
1858  char *buffer;
1859
1860  left = len*3 + 1;
1861  buffer = malloc(left);
1862  if(buffer) {
1863    char *ptr=buffer;
1864    snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
1865    for(i=0; i< len; i++) {
1866      snprintf(ptr, left, "%02x:", raw[i]);
1867      ptr += 3;
1868      left -= 3;
1869    }
1870    infof(data, "   %s: %s\n", namebuf, buffer);
1871    push_certinfo(data, num, namebuf, buffer);
1872    free(buffer);
1873  }
1874}
1875
1876#define print_pubkey_BN(_type, _name, _num)    \
1877do {                              \
1878  if(pubkey->pkey._type->_name != NULL) { \
1879    int len = BN_num_bytes(pubkey->pkey._type->_name);  \
1880    if(len < CERTBUFFERSIZE) {                                    \
1881      BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)bufp); \
1882      bufp[len] = 0;                                                    \
1883      pubkey_show(data, _num, #_type, #_name, (unsigned char*)bufp, len); \
1884    } \
1885  } \
1886} WHILE_FALSE
1887
1888static int X509V3_ext(struct SessionHandle *data,
1889                      int certnum,
1890                      STACK_OF(X509_EXTENSION) *exts)
1891{
1892  int i;
1893  size_t j;
1894
1895  if(sk_X509_EXTENSION_num(exts) <= 0)
1896    /* no extensions, bail out */
1897    return 1;
1898
1899  for(i=0; i<sk_X509_EXTENSION_num(exts); i++) {
1900    ASN1_OBJECT *obj;
1901    X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
1902    BUF_MEM *biomem;
1903    char buf[512];
1904    char *ptr=buf;
1905    char namebuf[128];
1906    BIO *bio_out = BIO_new(BIO_s_mem());
1907
1908    if(!bio_out)
1909      return 1;
1910
1911    obj = X509_EXTENSION_get_object(ext);
1912
1913    asn1_object_dump(obj, namebuf, sizeof(namebuf));
1914
1915    infof(data, "%s: %s\n", namebuf,
1916          X509_EXTENSION_get_critical(ext)?"(critical)":"");
1917
1918    if(!X509V3_EXT_print(bio_out, ext, 0, 0))
1919      M_ASN1_OCTET_STRING_print(bio_out, ext->value);
1920
1921    BIO_get_mem_ptr(bio_out, &biomem);
1922
1923    /* biomem->length bytes at biomem->data, this little loop here is only
1924       done for the infof() call, we send the "raw" data to the certinfo
1925       function */
1926    for(j=0; j<(size_t)biomem->length; j++) {
1927      const char *sep="";
1928      if(biomem->data[j] == '\n') {
1929        sep=", ";
1930        j++; /* skip the newline */
1931      };
1932      while((biomem->data[j] == ' ') && (j<(size_t)biomem->length))
1933        j++;
1934      if(j<(size_t)biomem->length)
1935        ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
1936                      biomem->data[j]);
1937    }
1938    infof(data, "  %s\n", buf);
1939
1940    push_certinfo(data, certnum, namebuf, buf);
1941
1942    BIO_free(bio_out);
1943
1944  }
1945  return 0; /* all is fine */
1946}
1947
1948
1949static void X509_signature(struct SessionHandle *data,
1950                           int numcert,
1951                           ASN1_STRING *sig)
1952{
1953  char buf[1024];
1954  char *ptr = buf;
1955  int i;
1956  for(i=0; i<sig->length; i++)
1957    ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%02x:", sig->data[i]);
1958
1959  infof(data, " Signature: %s\n", buf);
1960  push_certinfo(data, numcert, "Signature", buf);
1961}
1962
1963static void dumpcert(struct SessionHandle *data, X509 *x, int numcert)
1964{
1965  BIO *bio_out = BIO_new(BIO_s_mem());
1966  BUF_MEM *biomem;
1967
1968  /* this outputs the cert in this 64 column wide style with newlines and
1969     -----BEGIN CERTIFICATE----- texts and more */
1970  PEM_write_bio_X509(bio_out, x);
1971
1972  BIO_get_mem_ptr(bio_out, &biomem);
1973
1974  infof(data, "%s\n", biomem->data);
1975
1976  push_certinfo_len(data, numcert, "Cert", biomem->data, biomem->length);
1977
1978  BIO_free(bio_out);
1979
1980}
1981
1982
1983static int init_certinfo(struct SessionHandle *data,
1984                         int num)
1985{
1986  struct curl_certinfo *ci = &data->info.certs;
1987  struct curl_slist **table;
1988
1989  Curl_ssl_free_certinfo(data);
1990
1991  ci->num_of_certs = num;
1992  table = calloc((size_t)num, sizeof(struct curl_slist *));
1993  if(!table)
1994    return 1;
1995
1996  ci->certinfo = table;
1997  return 0;
1998}
1999
2000/*
2001 * This size was previously 512 which has been reported "too small" without
2002 * any specifics, so it was enlarged to allow more data to get shown uncut.
2003 * The "perfect" size is yet to figure out.
2004 */
2005#define CERTBUFFERSIZE 8192
2006
2007static CURLcode get_cert_chain(struct connectdata *conn,
2008                               struct ssl_connect_data *connssl)
2009
2010{
2011  STACK_OF(X509) *sk;
2012  int i;
2013  char *bufp;
2014  struct SessionHandle *data = conn->data;
2015  int numcerts;
2016
2017  bufp = malloc(CERTBUFFERSIZE);
2018  if(!bufp)
2019    return CURLE_OUT_OF_MEMORY;
2020
2021  sk = SSL_get_peer_cert_chain(connssl->handle);
2022  if(!sk) {
2023    free(bufp);
2024    return CURLE_OUT_OF_MEMORY;
2025  }
2026
2027  numcerts = sk_X509_num(sk);
2028  if(init_certinfo(data, numcerts)) {
2029    free(bufp);
2030    return CURLE_OUT_OF_MEMORY;
2031  }
2032
2033  infof(data, "--- Certificate chain\n");
2034  for(i=0; i<numcerts; i++) {
2035    long value;
2036    ASN1_INTEGER *num;
2037    ASN1_TIME *certdate;
2038
2039    /* get the certs in "importance order" */
2040#if 0
2041    X509 *x = sk_X509_value(sk, numcerts - i - 1);
2042#else
2043    X509 *x = sk_X509_value(sk, i);
2044#endif
2045
2046    X509_CINF *cinf;
2047    EVP_PKEY *pubkey=NULL;
2048    int j;
2049    char *ptr;
2050
2051    (void)x509_name_oneline(X509_get_subject_name(x), bufp, CERTBUFFERSIZE);
2052    infof(data, "%2d Subject: %s\n", i, bufp);
2053    push_certinfo(data, i, "Subject", bufp);
2054
2055    (void)x509_name_oneline(X509_get_issuer_name(x), bufp, CERTBUFFERSIZE);
2056    infof(data, "   Issuer: %s\n", bufp);
2057    push_certinfo(data, i, "Issuer", bufp);
2058
2059    value = X509_get_version(x);
2060    infof(data, "   Version: %lu (0x%lx)\n", value+1, value);
2061    snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
2062    push_certinfo(data, i, "Version", bufp); /* hex */
2063
2064    num=X509_get_serialNumber(x);
2065    if(num->length <= 4) {
2066      value = ASN1_INTEGER_get(num);
2067      infof(data,"   Serial Number: %ld (0x%lx)\n", value, value);
2068      snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
2069    }
2070    else {
2071      int left = CERTBUFFERSIZE;
2072
2073      ptr = bufp;
2074      *ptr++ = 0;
2075      if(num->type == V_ASN1_NEG_INTEGER)
2076        *ptr++='-';
2077
2078      for(j=0; (j<num->length) && (left>=4); j++) {
2079        /* TODO: length restrictions */
2080        snprintf(ptr, 3, "%02x%c",num->data[j],
2081                 ((j+1 == num->length)?'\n':':'));
2082        ptr += 3;
2083        left-=4;
2084      }
2085      if(num->length)
2086        infof(data,"   Serial Number: %s\n", bufp);
2087      else
2088        bufp[0]=0;
2089    }
2090    if(bufp[0])
2091      push_certinfo(data, i, "Serial Number", bufp); /* hex */
2092
2093    cinf = x->cert_info;
2094
2095    j = asn1_object_dump(cinf->signature->algorithm, bufp, CERTBUFFERSIZE);
2096    if(!j) {
2097      infof(data, "   Signature Algorithm: %s\n", bufp);
2098      push_certinfo(data, i, "Signature Algorithm", bufp);
2099    }
2100
2101    certdate = X509_get_notBefore(x);
2102    asn1_output(certdate, bufp, CERTBUFFERSIZE);
2103    infof(data, "   Start date: %s\n", bufp);
2104    push_certinfo(data, i, "Start date", bufp);
2105
2106    certdate = X509_get_notAfter(x);
2107    asn1_output(certdate, bufp, CERTBUFFERSIZE);
2108    infof(data, "   Expire date: %s\n", bufp);
2109    push_certinfo(data, i, "Expire date", bufp);
2110
2111    j = asn1_object_dump(cinf->key->algor->algorithm, bufp, CERTBUFFERSIZE);
2112    if(!j) {
2113      infof(data, "   Public Key Algorithm: %s\n", bufp);
2114      push_certinfo(data, i, "Public Key Algorithm", bufp);
2115    }
2116
2117    pubkey = X509_get_pubkey(x);
2118    if(!pubkey)
2119      infof(data, "   Unable to load public key\n");
2120    else {
2121      switch(pubkey->type) {
2122      case EVP_PKEY_RSA:
2123        infof(data,  "   RSA Public Key (%d bits)\n",
2124              BN_num_bits(pubkey->pkey.rsa->n));
2125        snprintf(bufp, CERTBUFFERSIZE, "%d", BN_num_bits(pubkey->pkey.rsa->n));
2126        push_certinfo(data, i, "RSA Public Key", bufp);
2127
2128        print_pubkey_BN(rsa, n, i);
2129        print_pubkey_BN(rsa, e, i);
2130        print_pubkey_BN(rsa, d, i);
2131        print_pubkey_BN(rsa, p, i);
2132        print_pubkey_BN(rsa, q, i);
2133        print_pubkey_BN(rsa, dmp1, i);
2134        print_pubkey_BN(rsa, dmq1, i);
2135        print_pubkey_BN(rsa, iqmp, i);
2136        break;
2137      case EVP_PKEY_DSA:
2138        print_pubkey_BN(dsa, p, i);
2139        print_pubkey_BN(dsa, q, i);
2140        print_pubkey_BN(dsa, g, i);
2141        print_pubkey_BN(dsa, priv_key, i);
2142        print_pubkey_BN(dsa, pub_key, i);
2143        break;
2144      case EVP_PKEY_DH:
2145        print_pubkey_BN(dh, p, i);
2146        print_pubkey_BN(dh, g, i);
2147        print_pubkey_BN(dh, priv_key, i);
2148        print_pubkey_BN(dh, pub_key, i);
2149        break;
2150#if 0
2151      case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
2152        /* left TODO */
2153        break;
2154#endif
2155      }
2156      EVP_PKEY_free(pubkey);
2157    }
2158
2159    X509V3_ext(data, i, cinf->extensions);
2160
2161    X509_signature(data, i, x->signature);
2162
2163    dumpcert(data, x, i);
2164  }
2165
2166  free(bufp);
2167
2168  return CURLE_OK;
2169}
2170
2171/*
2172 * Get the server cert, verify it and show it etc, only call failf() if the
2173 * 'strict' argument is TRUE as otherwise all this is for informational
2174 * purposes only!
2175 *
2176 * We check certificates to authenticate the server; otherwise we risk
2177 * man-in-the-middle attack.
2178 */
2179static CURLcode servercert(struct connectdata *conn,
2180                           struct ssl_connect_data *connssl,
2181                           bool strict)
2182{
2183  CURLcode retcode = CURLE_OK;
2184  int rc;
2185  long lerr;
2186  ASN1_TIME *certdate;
2187  struct SessionHandle *data = conn->data;
2188  X509 *issuer;
2189  FILE *fp;
2190  char *buffer = data->state.buffer;
2191
2192  if(data->set.ssl.certinfo)
2193    /* we've been asked to gather certificate info! */
2194    (void)get_cert_chain(conn, connssl);
2195
2196  data->set.ssl.certverifyresult = !X509_V_OK;
2197
2198  connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
2199  if(!connssl->server_cert) {
2200    if(strict)
2201      failf(data, "SSL: couldn't get peer certificate!");
2202    return CURLE_PEER_FAILED_VERIFICATION;
2203  }
2204  infof (data, "Server certificate:\n");
2205
2206  rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
2207                         buffer, BUFSIZE);
2208  if(rc) {
2209    if(strict)
2210      failf(data, "SSL: couldn't get X509-subject!");
2211    X509_free(connssl->server_cert);
2212    connssl->server_cert = NULL;
2213    return CURLE_SSL_CONNECT_ERROR;
2214  }
2215  infof(data, "\t subject: %s\n", buffer);
2216
2217  certdate = X509_get_notBefore(connssl->server_cert);
2218  asn1_output(certdate, buffer, BUFSIZE);
2219  infof(data, "\t start date: %s\n", buffer);
2220
2221  certdate = X509_get_notAfter(connssl->server_cert);
2222  asn1_output(certdate, buffer, BUFSIZE);
2223  infof(data, "\t expire date: %s\n", buffer);
2224
2225  if(data->set.ssl.verifyhost) {
2226    retcode = verifyhost(conn, connssl->server_cert);
2227    if(retcode) {
2228      X509_free(connssl->server_cert);
2229      connssl->server_cert = NULL;
2230      return retcode;
2231    }
2232  }
2233
2234  rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert),
2235                         buffer, BUFSIZE);
2236  if(rc) {
2237    if(strict)
2238      failf(data, "SSL: couldn't get X509-issuer name!");
2239    retcode = CURLE_SSL_CONNECT_ERROR;
2240  }
2241  else {
2242    infof(data, "\t issuer: %s\n", buffer);
2243
2244    /* We could do all sorts of certificate verification stuff here before
2245       deallocating the certificate. */
2246
2247    /* e.g. match issuer name with provided issuer certificate */
2248    if(data->set.str[STRING_SSL_ISSUERCERT]) {
2249      fp=fopen(data->set.str[STRING_SSL_ISSUERCERT],"r");
2250      if(!fp) {
2251        if(strict)
2252          failf(data, "SSL: Unable to open issuer cert (%s)",
2253                data->set.str[STRING_SSL_ISSUERCERT]);
2254        X509_free(connssl->server_cert);
2255        connssl->server_cert = NULL;
2256        return CURLE_SSL_ISSUER_ERROR;
2257      }
2258      issuer = PEM_read_X509(fp,NULL,ZERO_NULL,NULL);
2259      if(!issuer) {
2260        if(strict)
2261          failf(data, "SSL: Unable to read issuer cert (%s)",
2262                data->set.str[STRING_SSL_ISSUERCERT]);
2263        X509_free(connssl->server_cert);
2264        X509_free(issuer);
2265        fclose(fp);
2266        return CURLE_SSL_ISSUER_ERROR;
2267      }
2268      fclose(fp);
2269      if(X509_check_issued(issuer,connssl->server_cert) != X509_V_OK) {
2270        if(strict)
2271          failf(data, "SSL: Certificate issuer check failed (%s)",
2272                data->set.str[STRING_SSL_ISSUERCERT]);
2273        X509_free(connssl->server_cert);
2274        X509_free(issuer);
2275        connssl->server_cert = NULL;
2276        return CURLE_SSL_ISSUER_ERROR;
2277      }
2278      infof(data, "\t SSL certificate issuer check ok (%s)\n",
2279            data->set.str[STRING_SSL_ISSUERCERT]);
2280      X509_free(issuer);
2281    }
2282
2283    lerr = data->set.ssl.certverifyresult=
2284      SSL_get_verify_result(connssl->handle);
2285    if(data->set.ssl.certverifyresult != X509_V_OK) {
2286      if(data->set.ssl.verifypeer) {
2287        /* We probably never reach this, because SSL_connect() will fail
2288           and we return earlier if verifypeer is set? */
2289        if(strict)
2290          failf(data, "SSL certificate verify result: %s (%ld)",
2291                X509_verify_cert_error_string(lerr), lerr);
2292        retcode = CURLE_PEER_FAILED_VERIFICATION;
2293      }
2294      else
2295        infof(data, "\t SSL certificate verify result: %s (%ld),"
2296              " continuing anyway.\n",
2297              X509_verify_cert_error_string(lerr), lerr);
2298    }
2299    else
2300      infof(data, "\t SSL certificate verify ok.\n");
2301  }
2302
2303  X509_free(connssl->server_cert);
2304  connssl->server_cert = NULL;
2305  connssl->connecting_state = ssl_connect_done;
2306
2307  return retcode;
2308}
2309
2310
2311static CURLcode
2312ossl_connect_step3(struct connectdata *conn,
2313                   int sockindex)
2314{
2315  CURLcode retcode = CURLE_OK;
2316  void *old_ssl_sessionid=NULL;
2317  struct SessionHandle *data = conn->data;
2318  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2319  int incache;
2320  SSL_SESSION *our_ssl_sessionid;
2321
2322  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
2323
2324#ifdef HAVE_SSL_GET1_SESSION
2325  our_ssl_sessionid = SSL_get1_session(connssl->handle);
2326
2327  /* SSL_get1_session() will increment the reference
2328     count and the session will stay in memory until explicitly freed with
2329     SSL_SESSION_free(3), regardless of its state.
2330     This function was introduced in openssl 0.9.5a. */
2331#else
2332  our_ssl_sessionid = SSL_get_session(connssl->handle);
2333
2334  /* if SSL_get1_session() is unavailable, use SSL_get_session().
2335     This is an inferior option because the session can be flushed
2336     at any time by openssl. It is included only so curl compiles
2337     under versions of openssl < 0.9.5a.
2338
2339     WARNING: How curl behaves if it's session is flushed is
2340     untested.
2341  */
2342#endif
2343
2344  incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
2345  if(incache) {
2346    if(old_ssl_sessionid != our_ssl_sessionid) {
2347      infof(data, "old SSL session ID is stale, removing\n");
2348      Curl_ssl_delsessionid(conn, old_ssl_sessionid);
2349      incache = FALSE;
2350    }
2351  }
2352  if(!incache) {
2353    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
2354                                    0 /* unknown size */);
2355    if(retcode) {
2356      failf(data, "failed to store ssl session");
2357      return retcode;
2358    }
2359  }
2360#ifdef HAVE_SSL_GET1_SESSION
2361  else {
2362    /* Session was incache, so refcount already incremented earlier.
2363     * Avoid further increments with each SSL_get1_session() call.
2364     * This does not free the session as refcount remains > 0
2365     */
2366    SSL_SESSION_free(our_ssl_sessionid);
2367  }
2368#endif
2369
2370  /*
2371   * We check certificates to authenticate the server; otherwise we risk
2372   * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to
2373   * verify the peer ignore faults and failures from the server cert
2374   * operations.
2375   */
2376
2377  if(!data->set.ssl.verifypeer)
2378    (void)servercert(conn, connssl, FALSE);
2379  else
2380    retcode = servercert(conn, connssl, TRUE);
2381
2382  if(CURLE_OK == retcode)
2383    connssl->connecting_state = ssl_connect_done;
2384  return retcode;
2385}
2386
2387static Curl_recv ossl_recv;
2388static Curl_send ossl_send;
2389
2390static CURLcode
2391ossl_connect_common(struct connectdata *conn,
2392                    int sockindex,
2393                    bool nonblocking,
2394                    bool *done)
2395{
2396  CURLcode retcode;
2397  struct SessionHandle *data = conn->data;
2398  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2399  curl_socket_t sockfd = conn->sock[sockindex];
2400  long timeout_ms;
2401  int what;
2402
2403  /* check if the connection has already been established */
2404  if(ssl_connection_complete == connssl->state) {
2405    *done = TRUE;
2406    return CURLE_OK;
2407  }
2408
2409  if(ssl_connect_1==connssl->connecting_state) {
2410    /* Find out how much more time we're allowed */
2411    timeout_ms = Curl_timeleft(data, NULL, TRUE);
2412
2413    if(timeout_ms < 0) {
2414      /* no need to continue if time already is up */
2415      failf(data, "SSL connection timeout");
2416      return CURLE_OPERATION_TIMEDOUT;
2417    }
2418    retcode = ossl_connect_step1(conn, sockindex);
2419    if(retcode)
2420      return retcode;
2421  }
2422
2423  while(ssl_connect_2 == connssl->connecting_state ||
2424        ssl_connect_2_reading == connssl->connecting_state ||
2425        ssl_connect_2_writing == connssl->connecting_state) {
2426
2427    /* check allowed time left */
2428    timeout_ms = Curl_timeleft(data, NULL, TRUE);
2429
2430    if(timeout_ms < 0) {
2431      /* no need to continue if time already is up */
2432      failf(data, "SSL connection timeout");
2433      return CURLE_OPERATION_TIMEDOUT;
2434    }
2435
2436    /* if ssl is expecting something, check if it's available. */
2437    if(connssl->connecting_state == ssl_connect_2_reading
2438        || connssl->connecting_state == ssl_connect_2_writing) {
2439
2440      curl_socket_t writefd = ssl_connect_2_writing==
2441        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2442      curl_socket_t readfd = ssl_connect_2_reading==
2443        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2444
2445      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
2446      if(what < 0) {
2447        /* fatal error */
2448        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2449        return CURLE_SSL_CONNECT_ERROR;
2450      }
2451      else if(0 == what) {
2452        if(nonblocking) {
2453          *done = FALSE;
2454          return CURLE_OK;
2455        }
2456        else {
2457          /* timeout */
2458          failf(data, "SSL connection timeout");
2459          return CURLE_OPERATION_TIMEDOUT;
2460        }
2461      }
2462      /* socket is readable or writable */
2463    }
2464
2465    /* Run transaction, and return to the caller if it failed or if this
2466     * connection is done nonblocking and this loop would execute again. This
2467     * permits the owner of a multi handle to abort a connection attempt
2468     * before step2 has completed while ensuring that a client using select()
2469     * or epoll() will always have a valid fdset to wait on.
2470     */
2471    retcode = ossl_connect_step2(conn, sockindex);
2472    if(retcode || (nonblocking &&
2473                   (ssl_connect_2 == connssl->connecting_state ||
2474                    ssl_connect_2_reading == connssl->connecting_state ||
2475                    ssl_connect_2_writing == connssl->connecting_state)))
2476      return retcode;
2477
2478  } /* repeat step2 until all transactions are done. */
2479
2480
2481  if(ssl_connect_3==connssl->connecting_state) {
2482    retcode = ossl_connect_step3(conn, sockindex);
2483    if(retcode)
2484      return retcode;
2485  }
2486
2487  if(ssl_connect_done==connssl->connecting_state) {
2488    connssl->state = ssl_connection_complete;
2489    conn->recv[sockindex] = ossl_recv;
2490    conn->send[sockindex] = ossl_send;
2491    *done = TRUE;
2492  }
2493  else
2494    *done = FALSE;
2495
2496  /* Reset our connect state machine */
2497  connssl->connecting_state = ssl_connect_1;
2498
2499  return CURLE_OK;
2500}
2501
2502CURLcode
2503Curl_ossl_connect_nonblocking(struct connectdata *conn,
2504                              int sockindex,
2505                              bool *done)
2506{
2507  return ossl_connect_common(conn, sockindex, TRUE, done);
2508}
2509
2510CURLcode
2511Curl_ossl_connect(struct connectdata *conn,
2512                  int sockindex)
2513{
2514  CURLcode retcode;
2515  bool done = FALSE;
2516
2517  retcode = ossl_connect_common(conn, sockindex, FALSE, &done);
2518  if(retcode)
2519    return retcode;
2520
2521  DEBUGASSERT(done);
2522
2523  return CURLE_OK;
2524}
2525
2526bool Curl_ossl_data_pending(const struct connectdata *conn,
2527                            int connindex)
2528{
2529  if(conn->ssl[connindex].handle)
2530    /* SSL is in use */
2531    return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
2532  else
2533    return FALSE;
2534}
2535
2536static ssize_t ossl_send(struct connectdata *conn,
2537                         int sockindex,
2538                         const void *mem,
2539                         size_t len,
2540                         CURLcode *curlcode)
2541{
2542  /* SSL_write() is said to return 'int' while write() and send() returns
2543     'size_t' */
2544  int err;
2545  char error_buffer[120]; /* OpenSSL documents that this must be at least 120
2546                             bytes long. */
2547  unsigned long sslerror;
2548  int memlen;
2549  int rc;
2550
2551  ERR_clear_error();
2552
2553  memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
2554  rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
2555
2556  if(rc < 0) {
2557    err = SSL_get_error(conn->ssl[sockindex].handle, rc);
2558
2559    switch(err) {
2560    case SSL_ERROR_WANT_READ:
2561    case SSL_ERROR_WANT_WRITE:
2562      /* The operation did not complete; the same TLS/SSL I/O function
2563         should be called again later. This is basically an EWOULDBLOCK
2564         equivalent. */
2565      *curlcode = CURLE_AGAIN;
2566      return -1;
2567    case SSL_ERROR_SYSCALL:
2568      failf(conn->data, "SSL_write() returned SYSCALL, errno = %d",
2569            SOCKERRNO);
2570      *curlcode = CURLE_SEND_ERROR;
2571      return -1;
2572    case SSL_ERROR_SSL:
2573      /*  A failure in the SSL library occurred, usually a protocol error.
2574          The OpenSSL error queue contains more information on the error. */
2575      sslerror = ERR_get_error();
2576      failf(conn->data, "SSL_write() error: %s",
2577            ERR_error_string(sslerror, error_buffer));
2578      *curlcode = CURLE_SEND_ERROR;
2579      return -1;
2580    }
2581    /* a true error */
2582    failf(conn->data, "SSL_write() return error %d", err);
2583    *curlcode = CURLE_SEND_ERROR;
2584    return -1;
2585  }
2586  return (ssize_t)rc; /* number of bytes */
2587}
2588
2589static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
2590                         int num,                  /* socketindex */
2591                         char *buf,                /* store read data here */
2592                         size_t buffersize,        /* max amount to read */
2593                         CURLcode *curlcode)
2594{
2595  char error_buffer[120]; /* OpenSSL documents that this must be at
2596                             least 120 bytes long. */
2597  unsigned long sslerror;
2598  ssize_t nread;
2599  int buffsize;
2600
2601  ERR_clear_error();
2602
2603  buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
2604  nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize);
2605  if(nread < 0) {
2606    /* failed SSL_read */
2607    int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
2608
2609    switch(err) {
2610    case SSL_ERROR_NONE: /* this is not an error */
2611    case SSL_ERROR_ZERO_RETURN: /* no more data */
2612      break;
2613    case SSL_ERROR_WANT_READ:
2614    case SSL_ERROR_WANT_WRITE:
2615      /* there's data pending, re-invoke SSL_read() */
2616      *curlcode = CURLE_AGAIN;
2617      return -1;
2618    default:
2619      /* openssl/ssl.h says "look at error stack/return value/errno" */
2620      sslerror = ERR_get_error();
2621      failf(conn->data, "SSL read: %s, errno %d",
2622            ERR_error_string(sslerror, error_buffer),
2623            SOCKERRNO);
2624      *curlcode = CURLE_RECV_ERROR;
2625      return -1;
2626    }
2627  }
2628  return nread;
2629}
2630
2631size_t Curl_ossl_version(char *buffer, size_t size)
2632{
2633#ifdef YASSL_VERSION
2634  /* yassl provides an OpenSSL API compatibility layer so it looks identical
2635     to OpenSSL in all other aspects */
2636  return snprintf(buffer, size, "yassl/%s", YASSL_VERSION);
2637#else /* YASSL_VERSION */
2638
2639#if(SSLEAY_VERSION_NUMBER >= 0x905000)
2640  {
2641    char sub[2];
2642    unsigned long ssleay_value;
2643    sub[1]='\0';
2644    ssleay_value=SSLeay();
2645    if(ssleay_value < 0x906000) {
2646      ssleay_value=SSLEAY_VERSION_NUMBER;
2647      sub[0]='\0';
2648    }
2649    else {
2650      if(ssleay_value&0xff0) {
2651        sub[0]=(char)(((ssleay_value>>4)&0xff) + 'a' -1);
2652      }
2653      else
2654        sub[0]='\0';
2655    }
2656
2657    return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx%s",
2658                    (ssleay_value>>28)&0xf,
2659                    (ssleay_value>>20)&0xff,
2660                    (ssleay_value>>12)&0xff,
2661                    sub);
2662  }
2663
2664#else /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
2665
2666#if(SSLEAY_VERSION_NUMBER >= 0x900000)
2667  return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx",
2668                  (SSLEAY_VERSION_NUMBER>>28)&0xff,
2669                  (SSLEAY_VERSION_NUMBER>>20)&0xff,
2670                  (SSLEAY_VERSION_NUMBER>>12)&0xf);
2671
2672#else /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
2673  {
2674    char sub[2];
2675    sub[1]='\0';
2676    if(SSLEAY_VERSION_NUMBER&0x0f) {
2677      sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
2678    }
2679    else
2680      sub[0]='\0';
2681
2682    return snprintf(buffer, size, "SSL/%x.%x.%x%s",
2683                    (SSLEAY_VERSION_NUMBER>>12)&0xff,
2684                    (SSLEAY_VERSION_NUMBER>>8)&0xf,
2685                    (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
2686  }
2687#endif /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
2688#endif /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
2689
2690#endif /* YASSL_VERSION */
2691}
2692
2693void Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy,
2694                      size_t length)
2695{
2696  Curl_ossl_seed(data); /* Initiate the seed if not already done */
2697  RAND_bytes(entropy, curlx_uztosi(length));
2698}
2699
2700void Curl_ossl_md5sum(unsigned char *tmp, /* input */
2701                      size_t tmplen,
2702                      unsigned char *md5sum /* output */,
2703                      size_t unused)
2704{
2705  MD5_CTX MD5pw;
2706  (void)unused;
2707  MD5_Init(&MD5pw);
2708  MD5_Update(&MD5pw, tmp, tmplen);
2709  MD5_Final(md5sum, &MD5pw);
2710}
2711#endif /* USE_SSLEAY */
2712