Fix crash at client disconnect when using PolarSSL >= 1.2.6
[umurmur.git] / src / ssl.c
1 /* Copyright (C) 2009-2012, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2012, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12    - Redistributions in binary form must reproduce the above copyright notice,
13      this list of conditions and the following disclaimer in the documentation
14      and/or other materials provided with the distribution.
15    - Neither the name of the Developers nor the names of its contributors may
16      be used to endorse or promote products derived from this software without
17      specific prior written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #include <string.h>
32 #include <stdlib.h>
33 #include <fcntl.h>
34
35 #include "conf.h"
36 #include "log.h"
37 #include "ssl.h"
38
39 #ifdef USE_POLARSSL
40 /*
41  * PolarSSL interface
42  */
43
44 #include <polarssl/havege.h>
45 #include <polarssl/certs.h>
46 #include <polarssl/x509.h>
47 #include <polarssl/ssl.h>
48 #include <polarssl/net.h>
49
50 #ifdef POLARSSL_API_V1_2
51 int ciphers[] =
52 {
53     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
54     TLS_RSA_WITH_AES_256_CBC_SHA,
55     TLS_RSA_WITH_AES_128_CBC_SHA,
56     0
57 };
58 #else
59 int ciphers[] =
60 {
61     SSL_EDH_RSA_AES_256_SHA,
62     SSL_RSA_AES_256_SHA,
63     SSL_RSA_AES_128_SHA,
64     0
65 };
66 #endif
67 static x509_cert certificate;
68 static rsa_context key;
69 bool_t builtInTestCertificate;
70
71 #ifdef USE_POLARSSL_HAVEGE
72 havege_state hs;
73 #else
74 int urandom_fd;
75 #endif
76
77 /* DH prime */
78 char *my_dhm_P =
79         "9CE85640903BF123906947FEDE767261" \
80         "D9B4A973EB8F7D984A8C656E2BCC161C" \
81         "183D4CA471BA78225F940F16D1D99CA3" \
82         "E66152CC68EDCE1311A390F307741835" \
83         "44FF6AB553EC7073AD0CB608F2A3B480" \
84         "19E6C02BCED40BD30E91BB2469089670" \
85         "DEF409C08E8AC24D1732A6128D2220DC53";
86 char *my_dhm_G = "4";
87
88 #ifdef USE_POLARSSL_TESTCERT
89 static void initTestCert()
90 {
91         int rc;
92         builtInTestCertificate = true;
93         rc = x509parse_crt(&certificate, (unsigned char *)test_srv_crt,
94                                            strlen(test_srv_crt));       
95         if (rc != 0)
96                 Log_fatal("Could not parse built-in test certificate");
97 }
98
99 static void initTestKey()
100 {
101         int rc;
102         
103         rc = x509parse_key(&key, (unsigned char *)test_srv_key,
104                                            strlen(test_srv_key), NULL, 0);
105         if (rc != 0)
106                 Log_fatal("Could not parse built-in test RSA key");
107 }
108 #endif
109
110 /*
111  * How to generate a self-signed cert with openssl:
112  * openssl genrsa 1024 > host.key
113  * openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert
114  */
115 static void initCert()
116 {
117         int rc;
118         char *crtfile = (char *)getStrConf(CERTIFICATE);
119         
120         if (crtfile == NULL) {
121 #ifdef USE_POLARSSL_TESTCERT
122                 Log_warn("No certificate file specified. Falling back to test certificate.");
123                 initTestCert();
124 #else
125                 Log_fatal("No certificate file specified");
126 #endif
127                 return;
128         }
129         rc = x509parse_crtfile(&certificate, crtfile);
130         if (rc != 0) {
131 #ifdef USE_POLARSSL_TESTCERT
132                 Log_warn("Could not read certificate file '%s'. Falling back to test certificate.", crtfile);
133                 initTestCert();
134 #else
135                 Log_fatal("Could not read certificate file '%s'", crtfile);
136 #endif
137                 return;
138         }
139 }
140
141 static void initKey()
142 {
143         int rc;
144         char *keyfile = (char *)getStrConf(KEY);
145
146         if (keyfile == NULL)
147                 Log_fatal("No key file specified"); 
148         rc = x509parse_keyfile(&key, keyfile, NULL);
149         if (rc != 0)
150                 Log_fatal("Could not read RSA key file %s", keyfile);
151 }
152
153 #ifndef USE_POLARSSL_HAVEGE
154 int urandom_bytes(void *ctx, unsigned char *dest, size_t len)
155 {
156         int cur;
157         
158         while (len) {
159                 cur = read(urandom_fd, dest, len);
160                 if (cur < 0)
161                         continue;
162                 len -= cur;
163         }
164 }
165 #endif
166
167 #define DEBUG_LEVEL 0
168 static void pssl_debug(void *ctx, int level, const char *str)
169 {
170     if (level <= DEBUG_LEVEL)
171                 Log_info("PolarSSL [level %d]: %s", level, str);
172 }
173
174 void SSLi_init(void)
175 {
176         char verstring[12];
177         
178         initCert();
179 #ifdef USE_POLARSSL_TESTCERT
180         if (builtInTestCertificate) {
181                 Log_warn("*** Using built-in test certificate and RSA key ***");
182                 Log_warn("*** This is not secure! Please use a CA-signed certificate or create a key and self-signed certificate ***");
183                 initTestKey();
184         }
185         else
186                 initKey();
187 #else
188         initKey();
189 #endif
190
191         /* Initialize random number generator */
192 #ifdef USE_POLARSSL_HAVEGE
193     havege_init(&hs);
194 #else
195     urandom_fd = open("/dev/urandom", O_RDONLY);
196     if (urandom_fd < 0)
197             Log_fatal("Cannot open /dev/urandom");
198 #endif
199     
200     version_get_string(verstring);
201     Log_info("PolarSSL library version %s initialized", verstring);
202 }
203
204 void SSLi_deinit(void)
205 {
206         x509_free(&certificate);
207         rsa_free(&key);
208 }
209
210 /* Create SHA1 of last certificate in the peer's chain. */
211 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
212 {
213         x509_cert const *cert;
214 #ifdef POLARSSL_API_V1_2
215         cert = ssl_get_peer_cert(ssl);
216 #else
217         cert = ssl->peer_cert;
218 #endif
219         if (!cert) {
220                 return false;
221         }       
222         sha1(cert->raw.p, cert->raw.len, hash);
223         return true;
224 }
225         
226 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
227 {
228         ssl_context *ssl;
229         ssl_session *ssn;
230         int rc;
231         
232         ssl = malloc(sizeof(ssl_context));
233         ssn = malloc(sizeof(ssl_session));
234         if (!ssl || !ssn)
235                 Log_fatal("Out of memory");
236         memset(ssl, 0, sizeof(ssl_context));
237         memset(ssn, 0, sizeof(ssl_session));
238         
239         rc = ssl_init(ssl);
240         if (rc != 0 )
241                 Log_fatal("Failed to initialize: %d", rc);
242         
243         ssl_set_endpoint(ssl, SSL_IS_SERVER);   
244         ssl_set_authmode(ssl, SSL_VERIFY_OPTIONAL);
245         
246 #ifdef USE_POLARSSL_HAVEGE
247         ssl_set_rng(ssl, HAVEGE_RAND, &hs);
248 #else
249         ssl_set_rng(ssl, urandom_bytes, NULL);
250 #endif
251         
252         ssl_set_dbg(ssl, pssl_debug, NULL);
253         ssl_set_bio(ssl, net_recv, fd, net_send, fd);
254
255         ssl_set_ciphersuites(ssl, ciphers);
256
257 #ifdef POLARSSL_API_V1_2
258     ssl_set_session(ssl, ssn);
259 #else
260     ssl_set_session(ssl, 0, 0, ssn);
261 #endif
262     
263     ssl_set_ca_chain(ssl, &certificate, NULL, NULL);
264         ssl_set_own_cert(ssl, &certificate, &key);
265         ssl_set_dh_param(ssl, my_dhm_P, my_dhm_G);
266
267         return ssl;
268 }
269
270 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
271 {
272         int rc;
273         
274         rc = ssl_handshake(ssl);
275         if (rc != 0) {
276                 if (rc == POLARSSL_ERR_NET_WANT_READ || rc == POLARSSL_ERR_NET_WANT_WRITE) {
277                         return 0;
278                 } else if (rc == POLARSSL_ERR_X509_CERT_VERIFY_FAILED) { /* Allow this (selfsigned etc) */
279                         return 0;                       
280                 } else {
281                         Log_warn("SSL handshake failed: %d", rc);
282                         return -1;
283                 }
284         }
285         *SSLready = true;
286         return 0;
287 }
288
289 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
290 {
291         int rc;
292
293         rc = ssl_read(ssl, buf, len);
294         if (rc == POLARSSL_ERR_NET_WANT_READ)
295                 return SSLI_ERROR_WANT_READ;
296         return rc;
297 }
298
299 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
300 {
301         int rc;
302         
303         rc = ssl_write(ssl, buf, len);
304         if (rc == POLARSSL_ERR_NET_WANT_WRITE)
305                 return SSLI_ERROR_WANT_WRITE;
306         return rc;
307 }
308
309 int SSLi_get_error(SSL_handle_t *ssl, int code)
310 {
311         return code;
312 }
313
314 bool_t SSLi_data_pending(SSL_handle_t *ssl)
315 {
316         return ssl_get_bytes_avail(ssl) > 0;
317 }
318
319 void SSLi_shutdown(SSL_handle_t *ssl)
320 {
321         ssl_close_notify(ssl);
322 }
323
324 void SSLi_free(SSL_handle_t *ssl)
325 {
326         Log_debug("SSLi_free");
327 #if (POLARSSL_VERSION_MINOR <= 2 && POLARSSL_VERSION_PATCH < 6)
328         free(ssl->session); /* Workaround for memory leak in PolarSSL < 1.2.6 */
329         ssl->session = NULL;
330 #endif
331         ssl_free(ssl);
332         free(ssl);
333 }
334
335 #else
336 /*
337  * OpenSSL interface
338  */
339
340 #include <openssl/x509v3.h>
341 #include <openssl/ssl.h>
342 #include <openssl/err.h>
343 #include <openssl/safestack.h>
344 static X509 *x509;
345 static RSA *rsa;
346 static SSL_CTX *context;
347 static EVP_PKEY *pkey;
348  
349 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx);
350
351 static int SSL_add_ext(X509 * crt, int nid, char *value) {
352         X509_EXTENSION *ex;
353         X509V3_CTX ctx;
354         X509V3_set_ctx_nodb(&ctx);
355         X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
356         ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
357         if (!ex)
358                 return 0;
359
360         X509_add_ext(crt, ex, -1);
361         X509_EXTENSION_free(ex);
362         return 1;
363 }
364
365 static X509 *SSL_readcert(char *certfile)
366 {
367         FILE *fp;
368         X509 *x509;
369                         
370         /* open the private key file */
371         fp = fopen(certfile, "r");
372         if (fp == NULL) {
373                 Log_warn("Unable to open the X509 file %s for reading.", certfile);
374                 return NULL;
375         }
376         
377         /* allocate memory for the cert structure */    
378         x509 = X509_new();
379         
380         if (PEM_read_X509(fp, &x509, NULL, NULL) == 0) {
381                 /* error reading the x509 information - check the error stack */
382                 Log_warn("Error trying to read X509 info.");
383                 fclose(fp);
384                 X509_free(x509);
385                 return NULL;
386         }
387         fclose(fp);
388         return x509;
389 }
390
391 static RSA *SSL_readprivatekey(char *keyfile)
392 {
393         FILE *fp;
394         RSA *rsa;
395
396 /* open the private key file for reading */
397         fp = fopen(keyfile, "r");
398         if (fp == NULL) {
399                 Log_warn("Unable to open the private key file %s for reading.", keyfile);
400                 return NULL;
401         }
402         
403 /* allocate memory for the RSA structure */
404         rsa = RSA_new();
405         
406         /* assign a callback function for the password */
407         
408         /* read a private key from file */      
409         if (PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) <= 0) {
410                 /* error reading the key - check the error stack */
411                 Log_warn("Error trying to read private key.");
412                 RSA_free(rsa);
413                 fclose(fp);
414                 return NULL;
415         }
416         fclose(fp);
417         return rsa;
418 }
419
420 static void SSL_writecert(char *certfile, X509 *x509)
421 {
422         FILE *fp;
423                 
424         /* open the private key file */
425         fp = fopen(certfile, "w");
426         if (fp == NULL) {
427                 Log_warn("Unable to open the X509 file %s for writing", certfile);
428                 return;
429         }               
430         if (PEM_write_X509(fp, x509) == 0) {
431                 Log_warn("Error trying to write X509 info.");
432         }
433         fclose(fp);
434 }
435
436 static void SSL_writekey(char *keyfile, RSA *rsa)
437 {
438         FILE *fp;
439         
440         /* open the private key file for reading */
441         fp = fopen(keyfile, "w");
442         if (fp == NULL) {
443                 Log_warn("Unable to open the private key file %s for writing.", keyfile);
444                 return;
445         }
446         
447         if (PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL) == 0) {
448                 Log_warn("Error trying to write private key");
449         }
450         fclose(fp);
451 }
452
453 static void SSL_initializeCert() {
454         char *crt, *key, *pass;
455         
456         crt = (char *)getStrConf(CERTIFICATE);
457         key = (char *)getStrConf(KEY);
458         pass = (char *)getStrConf(PASSPHRASE);
459
460         x509 = SSL_readcert(crt);
461         rsa = SSL_readprivatekey(key);
462         if (rsa != NULL) {
463                 pkey = EVP_PKEY_new();
464                 EVP_PKEY_assign_RSA(pkey, rsa);
465         }               
466         
467 #if 0
468         /* Later ... */
469         if (key && !x509) {             
470                 qscCert = QSslCertificate(key);
471                 if (! qscCert.isNull()) {
472                         logthis("Using certificate from key.");
473                 }
474         }
475
476         if (! qscCert.isNull()) {
477                 QSsl::KeyAlgorithm alg = qscCert.publicKey().algorithm();
478                 /* Fetch algorith from cert */
479                 if (! key.isEmpty()) {
480                         /* get key */
481                         qskKey = QSslKey(key, alg, QSsl::Pem, QSsl::PrivateKey, pass);
482                         if (qskKey.isNull()) {
483                                 logthis("Failed to parse key.");
484                         }
485                 }
486
487                 if (! crt.isEmpty() && qskKey.isNull()) {
488                         /* get key from certificate */
489                         qskKey = QSslKey(crt, alg, QSsl::Pem, QSsl::PrivateKey, pass);
490                         if (! qskKey.isNull()) {
491                                 logthis("Using key from certificate.");
492                         }
493                 }
494
495         }
496 #endif
497         
498         if (!rsa || !x509) {
499                 Log_info("Generating new server certificate.");
500
501                 
502                 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
503                                 
504                 x509 = X509_new();
505                 pkey = EVP_PKEY_new();
506                 rsa = RSA_generate_key(1024,RSA_F4,NULL,NULL);
507                 EVP_PKEY_assign_RSA(pkey, rsa);
508                 
509                 X509_set_version(x509, 2);
510                 ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
511                 X509_gmtime_adj(X509_get_notBefore(x509),0);
512                 X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365);
513                 X509_set_pubkey(x509, pkey);
514                 
515                 X509_NAME *name=X509_get_subject_name(x509);
516                 
517                 X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const uint8_t *)"Murmur Autogenerated Certificate v2", -1, -1, 0);
518                 X509_set_issuer_name(x509, name);
519                 SSL_add_ext(x509, NID_basic_constraints, "critical,CA:FALSE");
520                 SSL_add_ext(x509, NID_ext_key_usage, "serverAuth,clientAuth");
521                 SSL_add_ext(x509, NID_subject_key_identifier, "hash");
522                 SSL_add_ext(x509, NID_netscape_comment, "Generated from umurmur");
523                 
524                 X509_sign(x509, pkey, EVP_md5());
525                 
526                 SSL_writecert(crt, x509);
527                 SSL_writekey(key, rsa);
528         }
529
530 }
531
532 void SSLi_init(void)
533 {
534         const SSL_METHOD *method;
535         SSL *ssl;
536         int i, offset = 0, cipherstringlen = 0;
537         STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL;
538         SSL_CIPHER *cipher;
539         char *cipherstring, tempstring[128];
540                 
541         SSL_library_init();
542     OpenSSL_add_all_algorithms();               /* load & register all cryptos, etc. */
543     SSL_load_error_strings();                   /* load all error messages */
544     ERR_load_crypto_strings();                  /* load all error messages */
545     method = SSLv23_server_method();            /* create new server-method instance */
546     context = SSL_CTX_new(method);                      /* create new context from method */
547     if (context == NULL)
548     {
549         ERR_print_errors_fp(stderr);
550         abort();
551     }
552         SSL_initializeCert();
553         if (SSL_CTX_use_certificate(context, x509) <= 0)
554                 Log_fatal("Failed to initialize cert");
555         if (SSL_CTX_use_PrivateKey(context, pkey) <= 0) {
556                 ERR_print_errors_fp(stderr);
557                 Log_fatal("Failed to initialize private key");
558         }
559
560         /* Set cipher list */
561         ssl = SSL_new(context); 
562         cipherlist = (STACK_OF(SSL_CIPHER) *) SSL_get_ciphers(ssl);
563         cipherlist_new = (STACK_OF(SSL_CIPHER) *) sk_SSL_CIPHER_new_null();
564         
565         for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist, i)) != NULL; i++) {
566                 if (SSL_CIPHER_get_bits(cipher, NULL) >= 128) {
567                         sk_SSL_CIPHER_push(cipherlist_new, cipher);
568                 }
569         }
570         Log_debug("List of ciphers:");
571         if (cipherlist_new) {
572                 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
573                         Log_debug("%s", SSL_CIPHER_get_name(cipher));
574                         cipherstringlen += strlen(SSL_CIPHER_get_name(cipher)) + 1;
575                 }
576                 cipherstring = malloc(cipherstringlen + 1);
577                 if (cipherstring == NULL)
578                         Log_fatal("Out of memory");
579                 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
580                         offset += sprintf(cipherstring + offset, "%s:", SSL_CIPHER_get_name(cipher));
581                 }
582         }
583         
584         if (cipherlist_new)
585                 sk_SSL_CIPHER_free(cipherlist_new);
586         
587         if (strlen(cipherstring) == 0)
588                 Log_fatal("No suitable ciphers found!");
589         
590         if (SSL_CTX_set_cipher_list(context, cipherstring) == 0)
591                 Log_fatal("Failed to set cipher list!");
592
593         free(cipherstring);
594         
595         SSL_CTX_set_verify(context, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
596                            verify_callback);            
597         
598         SSL_free(ssl);
599         Log_info("OpenSSL library initialized");
600
601 }
602
603 void SSLi_deinit(void)
604 {
605         SSL_CTX_free(context);
606         EVP_cleanup();
607 }
608
609 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
610 {
611         int rc;
612         rc = SSL_accept(ssl);
613         if (rc < 0) {
614                 if (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ ||
615                         SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) {
616                         Log_debug("SSL not ready");
617                         return 0;
618                 } else {
619                         Log_warn("SSL error: %s", ERR_error_string(SSL_get_error(ssl, rc), NULL));
620                         return -1;
621                 }
622         }
623         *SSLready = true;
624         return 0;
625 }
626
627 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
628 {
629         SSL *ssl;
630         
631         *SSLready = false;
632         ssl = SSL_new(context);
633         SSL_set_fd(ssl, *fd);
634         if (SSLi_nonblockaccept(ssl, SSLready) < 0) {
635                 SSL_free(ssl);
636                 return NULL;
637         }
638         return ssl;
639 }
640
641 /* Create SHA1 of last certificate in the peer's chain. */
642 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
643 {
644         X509 *x509;
645         uint8_t *buf, *p;
646         int len;
647         
648         x509 = SSL_get_peer_certificate(ssl);
649         if (!x509) {
650                 return false;
651         }       
652         
653         len = i2d_X509(x509, NULL);
654         buf = malloc(len);
655         if (buf == NULL) {
656                 Log_fatal("malloc");
657         }
658
659         p = buf;
660         i2d_X509(x509, &p);     
661         
662         SHA1(buf, len, hash);
663         free(buf);
664         return true;
665 }
666  
667 void SSLi_closeconnection(SSL_handle_t *ssl)
668 {
669         SSL_free(ssl);
670 }
671
672 void SSLi_shutdown(SSL_handle_t *ssl)
673 {
674         SSL_shutdown(ssl);
675 }
676
677 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
678 {
679         return SSL_read(ssl, buf, len);
680 }
681
682 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
683 {
684         return SSL_write(ssl, buf, len);
685 }
686
687 int SSLi_get_error(SSL_handle_t *ssl, int code)
688 {
689         return SSL_get_error(ssl, code);
690 }
691
692 bool_t SSLi_data_pending(SSL_handle_t *ssl)
693 {
694         return SSL_pending(ssl);
695 }
696
697 void SSLi_free(SSL_handle_t *ssl)
698 {
699         SSL_free(ssl);
700 }
701
702 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
703 {
704         char    buf[256];
705         X509   *err_cert;
706         int     err, depth;
707         SSL    *ssl;
708     
709     err_cert = X509_STORE_CTX_get_current_cert(ctx);
710     err = X509_STORE_CTX_get_error(ctx);
711     depth = X509_STORE_CTX_get_error_depth(ctx);
712     
713     ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
714     X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
715         
716     if (depth > 5) {
717         preverify_ok = 0;
718         err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
719         X509_STORE_CTX_set_error(ctx, err);
720     }
721     if (!preverify_ok) {
722             Log_warn("SSL: verify error:num=%d:%s:depth=%d:%s\n", err,
723                      X509_verify_cert_error_string(err), depth, buf);
724     }
725     /*
726      * At this point, err contains the last verification error. We can use
727      * it for something special
728      */
729     if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) {
730             X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
731             Log_warn("issuer= %s", buf);
732     }
733     return 1;
734 }
735  
736 #endif