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