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