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