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