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