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