Fix hash functions.
[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                 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;
512         STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL;
513         SSL_CIPHER *cipher;
514         char cipherstring[1024];
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                         offset += snprintf(cipherstring + offset, 1024 - offset, "%s:", SSL_CIPHER_get_name(cipher));
550                 }
551                 cipherstring[offset - 1] = '\0';
552         }
553         
554         if (cipherlist_new)
555                 sk_SSL_CIPHER_free(cipherlist_new);
556         
557         if (strlen(cipherstring) == 0)
558                 Log_fatal("No suitable ciphers found!");
559         
560         if (SSL_CTX_set_cipher_list(context, cipherstring) == 0)
561                 Log_fatal("Failed to set cipher list!");
562         
563         SSL_CTX_set_verify(context, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
564                            verify_callback);            
565         
566         SSL_free(ssl);
567         Log_info("OpenSSL library initialized");
568
569 }
570
571 void SSLi_deinit(void)
572 {
573         SSL_CTX_free(context);
574         EVP_cleanup();
575 }
576
577 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
578 {
579         int rc;
580         rc = SSL_accept(ssl);
581         if (rc < 0) {
582                 if (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ ||
583                         SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) {
584                         Log_debug("SSL not ready");
585                         return 0;
586                 } else {
587                         Log_warn("SSL error: %s", ERR_error_string(SSL_get_error(ssl, rc), NULL));
588                         return -1;
589                 }
590         }
591         *SSLready = true;
592         return 0;
593 }
594
595 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
596 {
597         SSL *ssl;
598         
599         *SSLready = false;
600         ssl = SSL_new(context);
601         SSL_set_fd(ssl, *fd);
602         if (SSLi_nonblockaccept(ssl, SSLready) < 0) {
603                 SSL_free(ssl);
604                 return NULL;
605         }
606         return ssl;
607 }
608
609 /* Create SHA1 of last certificate in the peer's chain. */
610 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
611 {
612         X509 *x509;
613         uint8_t *buf, *p;
614         int len;
615         
616         x509 = SSL_get_peer_certificate(ssl);
617         if (!x509) {
618                 return false;
619         }       
620         
621         len = i2d_X509(x509, NULL);
622         buf = malloc(len);
623         if (buf == NULL) {
624                 Log_fatal("malloc");
625         }
626
627         p = buf;
628         i2d_X509(x509, &p);     
629         
630         SHA1(buf, 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