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