Cleanup old support for pre PolarSSL 1.0.0
[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     Log_info("Using random number generator /dev/urandom");
199 #endif
200     
201 #ifdef POLARSSL_VERSION_MAJOR
202     version_get_string(verstring);
203     Log_info("PolarSSL library version %s initialized", verstring);
204 #else
205         Log_info("PolarSSL library initialized");
206 #endif
207 }
208
209 void SSLi_deinit(void)
210 {
211         x509_free(&certificate);
212         rsa_free(&key);
213 }
214
215 /* Create SHA1 of last certificate in the peer's chain. */
216 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
217 {
218         x509_cert const *cert;
219 #ifdef POLARSSL_API_V1_2
220         cert = ssl_get_peer_cert(ssl);
221 #else
222         cert = ssl->peer_cert;
223 #endif
224         if (!cert) {
225                 return false;
226         }       
227         sha1(cert->raw.p, cert->raw.len, hash);
228         return true;
229 }
230         
231 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
232 {
233         ssl_context *ssl;
234         ssl_session *ssn;
235         int rc;
236         
237         ssl = malloc(sizeof(ssl_context));
238         ssn = malloc(sizeof(ssl_session));
239         if (!ssl || !ssn)
240                 Log_fatal("Out of memory");
241         memset(ssl, 0, sizeof(ssl_context));
242         memset(ssn, 0, sizeof(ssl_session));
243         
244         rc = ssl_init(ssl);
245         if (rc != 0 )
246                 Log_fatal("Failed to initialize: %d", rc);
247         
248         ssl_set_endpoint(ssl, SSL_IS_SERVER);   
249         ssl_set_authmode(ssl, SSL_VERIFY_OPTIONAL);
250         
251 #ifdef USE_POLARSSL_HAVEGE
252         ssl_set_rng(ssl, HAVEGE_RAND, &hs);
253 #else
254         ssl_set_rng(ssl, urandom_bytes, NULL);
255 #endif
256         
257         ssl_set_dbg(ssl, pssl_debug, NULL);
258         ssl_set_bio(ssl, net_recv, fd, net_send, fd);
259
260         ssl_set_ciphersuites(ssl, ciphers);
261
262 #ifdef POLARSSL_API_V1_2
263     ssl_set_session(ssl, ssn);
264 #else
265     ssl_set_session(ssl, 0, 0, ssn);
266 #endif
267     
268     ssl_set_ca_chain(ssl, &certificate, NULL, NULL);
269         ssl_set_own_cert(ssl, &certificate, &key);
270         ssl_set_dh_param(ssl, my_dhm_P, my_dhm_G);
271
272         return ssl;
273 }
274
275 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
276 {
277         int rc;
278         
279         rc = ssl_handshake(ssl);
280         if (rc != 0) {
281                 if (rc == POLARSSL_ERR_NET_WANT_READ || rc == POLARSSL_ERR_NET_WANT_WRITE) {
282                         return 0;
283                 } else if (POLARSSL_ERR_X509_CERT_VERIFY_FAILED) { /* Allow this (selfsigned etc) */
284                         return 0;                       
285                 } else {
286                         Log_warn("SSL handshake failed: %d", rc);
287                         return -1;
288                 }
289         }
290         *SSLready = true;
291         return 0;
292 }
293
294 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
295 {
296         int rc;
297
298         rc = ssl_read(ssl, buf, len);
299         if (rc == POLARSSL_ERR_NET_WANT_READ)
300                 return SSLI_ERROR_WANT_READ;
301         return rc;
302 }
303
304 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
305 {
306         int rc;
307         
308         rc = ssl_write(ssl, buf, len);
309         if (rc == POLARSSL_ERR_NET_WANT_WRITE)
310                 return SSLI_ERROR_WANT_WRITE;
311         return rc;
312 }
313
314 int SSLi_get_error(SSL_handle_t *ssl, int code)
315 {
316         return code;
317 }
318
319 bool_t SSLi_data_pending(SSL_handle_t *ssl)
320 {
321         return ssl_get_bytes_avail(ssl) > 0;
322 }
323
324 void SSLi_shutdown(SSL_handle_t *ssl)
325 {
326         ssl_close_notify(ssl);
327 }
328
329 void SSLi_free(SSL_handle_t *ssl)
330 {
331         Log_debug("SSLi_free");
332         free(ssl->session); /* XXX - Hmmm. */
333         ssl_free(ssl);
334         free(ssl);
335 }
336
337 #else
338 /*
339  * OpenSSL interface
340  */
341
342 #include <openssl/x509v3.h>
343 #include <openssl/ssl.h>
344 #include <openssl/err.h>
345 #include <openssl/safestack.h>
346 static X509 *x509;
347 static RSA *rsa;
348 static SSL_CTX *context;
349 static EVP_PKEY *pkey;
350  
351 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx);
352
353 static int SSL_add_ext(X509 * crt, int nid, char *value) {
354         X509_EXTENSION *ex;
355         X509V3_CTX ctx;
356         X509V3_set_ctx_nodb(&ctx);
357         X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
358         ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
359         if (!ex)
360                 return 0;
361
362         X509_add_ext(crt, ex, -1);
363         X509_EXTENSION_free(ex);
364         return 1;
365 }
366
367 static X509 *SSL_readcert(char *certfile)
368 {
369         FILE *fp;
370         X509 *x509;
371                         
372         /* open the private key file */
373         fp = fopen(certfile, "r");
374         if (fp == NULL) {
375                 Log_warn("Unable to open the X509 file %s for reading.", certfile);
376                 return NULL;
377         }
378         
379         /* allocate memory for the cert structure */    
380         x509 = X509_new();
381         
382         if (PEM_read_X509(fp, &x509, NULL, NULL) == 0) {
383                 /* error reading the x509 information - check the error stack */
384                 Log_warn("Error trying to read X509 info.");
385                 fclose(fp);
386                 X509_free(x509);
387                 return NULL;
388         }
389         fclose(fp);
390         return x509;
391 }
392
393 static RSA *SSL_readprivatekey(char *keyfile)
394 {
395         FILE *fp;
396         RSA *rsa;
397
398 /* open the private key file for reading */
399         fp = fopen(keyfile, "r");
400         if (fp == NULL) {
401                 Log_warn("Unable to open the private key file %s for reading.", keyfile);
402                 return NULL;
403         }
404         
405 /* allocate memory for the RSA structure */
406         rsa = RSA_new();
407         
408         /* assign a callback function for the password */
409         
410         /* read a private key from file */      
411         if (PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) <= 0) {
412                 /* error reading the key - check the error stack */
413                 Log_warn("Error trying to read private key.");
414                 RSA_free(rsa);
415                 fclose(fp);
416                 return NULL;
417         }
418         fclose(fp);
419         return rsa;
420 }
421
422 static void SSL_writecert(char *certfile, X509 *x509)
423 {
424         FILE *fp;
425         BIO *err_output;
426         
427         /* prepare a BIO for outputting error messages */
428         
429         err_output = BIO_new_fp(stderr,BIO_NOCLOSE);
430         
431         /* open the private key file */
432         fp = fopen(certfile, "w");
433         if (fp == NULL) {
434                 BIO_printf(err_output, "Unable to open the X509 file for writing.\n");
435                 BIO_free(err_output);
436                 return;
437         }
438                 
439         if (PEM_write_X509(fp, x509) == 0) {
440                 BIO_printf(err_output, "Error trying to write X509 info.\n");
441                 ERR_print_errors(err_output);
442         }
443         fclose(fp);
444 }
445
446 static void SSL_writekey(char *keyfile, RSA *rsa)
447 {
448         FILE *fp;
449         BIO *err_output;
450         /* prepare a BIO for outputing error messages */        
451         err_output = BIO_new_fp(stderr, BIO_NOCLOSE);
452         
453         /* open the private key file for reading */
454         fp = fopen(keyfile, "w");
455         if (fp == NULL) {
456                 BIO_printf(err_output, "Unable to open the private key file %s for writing.\n", keyfile);
457                 BIO_free(err_output);
458                 return;
459         }
460         
461         if (PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL) == 0) {
462                 /* error reading the key - check the error stack */
463                 BIO_printf(err_output, "Error trying to write private key\n");
464                 ERR_print_errors(err_output);
465         }
466         fclose(fp);
467 }
468
469 static void SSL_initializeCert() {
470         char *crt, *key, *pass;
471         
472         crt = (char *)getStrConf(CERTIFICATE);
473         key = (char *)getStrConf(KEY);
474         pass = (char *)getStrConf(PASSPHRASE);
475
476         x509 = SSL_readcert(crt);
477         rsa = SSL_readprivatekey(key);
478         if (rsa != NULL) {
479                 pkey = EVP_PKEY_new();
480                 EVP_PKEY_assign_RSA(pkey, rsa);
481         }               
482         
483 #if 0
484         /* Later ... */
485         if (key && !x509) {             
486                 qscCert = QSslCertificate(key);
487                 if (! qscCert.isNull()) {
488                         logthis("Using certificate from key.");
489                 }
490         }
491
492         if (! qscCert.isNull()) {
493                 QSsl::KeyAlgorithm alg = qscCert.publicKey().algorithm();
494                 /* Fetch algorith from cert */
495                 if (! key.isEmpty()) {
496                         /* get key */
497                         qskKey = QSslKey(key, alg, QSsl::Pem, QSsl::PrivateKey, pass);
498                         if (qskKey.isNull()) {
499                                 logthis("Failed to parse key.");
500                         }
501                 }
502
503                 if (! crt.isEmpty() && qskKey.isNull()) {
504                         /* get key from certificate */
505                         qskKey = QSslKey(crt, alg, QSsl::Pem, QSsl::PrivateKey, pass);
506                         if (! qskKey.isNull()) {
507                                 logthis("Using key from certificate.");
508                         }
509                 }
510
511         }
512 #endif
513         
514         if (!rsa || !x509) {
515                 logthis("Generating new server certificate.");
516
517                 BIO *bio_err;
518                 
519                 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
520                 
521                 bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
522                 
523                 x509 = X509_new();
524                 pkey = EVP_PKEY_new();
525                 rsa = RSA_generate_key(1024,RSA_F4,NULL,NULL);
526                 EVP_PKEY_assign_RSA(pkey, rsa);
527                 
528                 X509_set_version(x509, 2);
529                 ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
530                 X509_gmtime_adj(X509_get_notBefore(x509),0);
531                 X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365);
532                 X509_set_pubkey(x509, pkey);
533                 
534                 X509_NAME *name=X509_get_subject_name(x509);
535                 
536                 X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const uint8_t *)"Murmur Autogenerated Certificate v2", -1, -1, 0);
537                 X509_set_issuer_name(x509, name);
538                 SSL_add_ext(x509, NID_basic_constraints, "critical,CA:FALSE");
539                 SSL_add_ext(x509, NID_ext_key_usage, "serverAuth,clientAuth");
540                 SSL_add_ext(x509, NID_subject_key_identifier, "hash");
541                 SSL_add_ext(x509, NID_netscape_comment, "Generated from umurmur");
542                 
543                 X509_sign(x509, pkey, EVP_md5());
544                 
545                 SSL_writecert(crt, x509);
546                 SSL_writekey(key, rsa);
547         }
548
549 }
550
551 void SSLi_init(void)
552 {
553         const SSL_METHOD *method;
554         SSL *ssl;
555         int i, offset = 0, cipherstringlen = 0;
556         STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL;
557         SSL_CIPHER *cipher;
558         char *cipherstring, tempstring[128];
559                 
560         SSL_library_init();
561     OpenSSL_add_all_algorithms();               /* load & register all cryptos, etc. */
562     SSL_load_error_strings();                   /* load all error messages */
563     ERR_load_crypto_strings();                  /* load all error messages */
564     method = SSLv23_server_method();            /* create new server-method instance */
565     context = SSL_CTX_new(method);                      /* create new context from method */
566     if (context == NULL)
567     {
568         ERR_print_errors_fp(stderr);
569         abort();
570     }
571         SSL_initializeCert();
572         if (SSL_CTX_use_certificate(context, x509) <= 0)
573                 Log_fatal("Failed to initialize cert");
574         if (SSL_CTX_use_PrivateKey(context, pkey) <= 0) {
575                 ERR_print_errors_fp(stderr);
576                 Log_fatal("Failed to initialize private key");
577         }
578
579         /* Set cipher list */
580         ssl = SSL_new(context); 
581         cipherlist = (STACK_OF(SSL_CIPHER) *) SSL_get_ciphers(ssl);
582         cipherlist_new = (STACK_OF(SSL_CIPHER) *) sk_SSL_CIPHER_new_null();
583         
584         for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist, i)) != NULL; i++) {
585                 if (SSL_CIPHER_get_bits(cipher, NULL) >= 128) {
586                         sk_SSL_CIPHER_push(cipherlist_new, cipher);
587                 }
588         }
589         Log_debug("List of ciphers:");
590         if (cipherlist_new) {
591                 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
592                         Log_debug("%s", SSL_CIPHER_get_name(cipher));
593                         cipherstringlen += strlen(SSL_CIPHER_get_name(cipher)) + 1;
594                 }
595                 cipherstring = malloc(cipherstringlen + 1);
596                 if (cipherstring == NULL)
597                         Log_fatal("Out of memory");
598                 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
599                         offset += sprintf(cipherstring + offset, "%s:", SSL_CIPHER_get_name(cipher));
600                 }
601         }
602         
603         if (cipherlist_new)
604                 sk_SSL_CIPHER_free(cipherlist_new);
605         
606         if (strlen(cipherstring) == 0)
607                 Log_fatal("No suitable ciphers found!");
608         
609         if (SSL_CTX_set_cipher_list(context, cipherstring) == 0)
610                 Log_fatal("Failed to set cipher list!");
611
612         free(cipherstring);
613         
614         SSL_CTX_set_verify(context, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
615                            verify_callback);            
616         
617         SSL_free(ssl);
618         Log_info("OpenSSL library initialized");
619
620 }
621
622 void SSLi_deinit(void)
623 {
624         SSL_CTX_free(context);
625         EVP_cleanup();
626 }
627
628 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
629 {
630         int rc;
631         rc = SSL_accept(ssl);
632         if (rc < 0) {
633                 if (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ ||
634                         SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) {
635                         Log_debug("SSL not ready");
636                         return 0;
637                 } else {
638                         Log_warn("SSL error: %s", ERR_error_string(SSL_get_error(ssl, rc), NULL));
639                         return -1;
640                 }
641         }
642         *SSLready = true;
643         return 0;
644 }
645
646 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
647 {
648         SSL *ssl;
649         
650         *SSLready = false;
651         ssl = SSL_new(context);
652         SSL_set_fd(ssl, *fd);
653         if (SSLi_nonblockaccept(ssl, SSLready) < 0) {
654                 SSL_free(ssl);
655                 return NULL;
656         }
657         return ssl;
658 }
659
660 /* Create SHA1 of last certificate in the peer's chain. */
661 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
662 {
663         X509 *x509;
664         uint8_t *buf, *p;
665         int len;
666         
667         x509 = SSL_get_peer_certificate(ssl);
668         if (!x509) {
669                 return false;
670         }       
671         
672         len = i2d_X509(x509, NULL);
673         buf = malloc(len);
674         if (buf == NULL) {
675                 Log_fatal("malloc");
676         }
677
678         p = buf;
679         i2d_X509(x509, &p);     
680         
681         SHA1(buf, len, hash);
682         free(buf);
683         return true;
684 }
685  
686 void SSLi_closeconnection(SSL_handle_t *ssl)
687 {
688         SSL_free(ssl);
689 }
690
691 void SSLi_shutdown(SSL_handle_t *ssl)
692 {
693         SSL_shutdown(ssl);
694 }
695
696 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
697 {
698         return SSL_read(ssl, buf, len);
699 }
700
701 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
702 {
703         return SSL_write(ssl, buf, len);
704 }
705
706 int SSLi_get_error(SSL_handle_t *ssl, int code)
707 {
708         return SSL_get_error(ssl, code);
709 }
710
711 bool_t SSLi_data_pending(SSL_handle_t *ssl)
712 {
713         return SSL_pending(ssl);
714 }
715
716 void SSLi_free(SSL_handle_t *ssl)
717 {
718         SSL_free(ssl);
719 }
720
721 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
722 {
723         char    buf[256];
724         X509   *err_cert;
725         int     err, depth;
726         SSL    *ssl;
727     
728     err_cert = X509_STORE_CTX_get_current_cert(ctx);
729     err = X509_STORE_CTX_get_error(ctx);
730     depth = X509_STORE_CTX_get_error_depth(ctx);
731     
732     ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
733     X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
734         
735     if (depth > 5) {
736         preverify_ok = 0;
737         err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
738         X509_STORE_CTX_set_error(ctx, err);
739     }
740     if (!preverify_ok) {
741             Log_warn("SSL: verify error:num=%d:%s:depth=%d:%s\n", err,
742                      X509_verify_cert_error_string(err), depth, buf);
743     }
744     /*
745      * At this point, err contains the last verification error. We can use
746      * it for something special
747      */
748     if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) {
749             X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
750             Log_warn("issuer= %s", buf);
751     }
752     return 1;
753 }
754  
755 #endif