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