More little changes to the tunala demo;
[openssl.git] / demos / tunala / cb.c
1 #include "tunala.h"
2
3 #ifndef NO_OPENSSL
4
5 /* For callbacks generating output, here are their file-descriptors. */
6 static FILE *fp_cb_ssl_info = NULL;
7 static FILE *fp_cb_ssl_verify = NULL;
8
9 /* Other static rubbish (to mirror s_cb.c where required) */
10 static int int_verify_depth = 10;
11 static int int_verify_error = X509_V_OK;
12
13 /* This function is largely borrowed from the one used in OpenSSL's "s_client"
14  * and "s_server" utilities. */
15 void cb_ssl_info(SSL *s, int where, int ret)
16 {
17         char *str1, *str2;
18         int w;
19
20         if(!fp_cb_ssl_info)
21                 return;
22
23         w = where & ~SSL_ST_MASK;
24         str1 = (w & SSL_ST_CONNECT ? "SSL_connect" : (w & SSL_ST_ACCEPT ?
25                                 "SSL_accept" : "undefined")),
26         str2 = SSL_state_string_long(s);
27
28         if (where & SSL_CB_LOOP)
29                 fprintf(fp_cb_ssl_info, "%s:%s\n", str1, str2);
30         else if (where & SSL_CB_EXIT) {
31                 if (ret == 0)
32                         fprintf(fp_cb_ssl_info, "%s:failed in %s\n", str1, str2);
33                 else if (ret < 0)
34                         fprintf(fp_cb_ssl_info, "%s:error in %s\n", str1, str2);
35         }
36 }
37
38 void cb_ssl_info_set_output(FILE *fp)
39 {
40         fp_cb_ssl_info = fp;
41 }
42
43 /* Stolen wholesale from apps/s_cb.c :-) */
44 int cb_ssl_verify(int ok, X509_STORE_CTX *ctx)
45 {
46         char buf[256];
47         X509 *err_cert;
48         int err, depth;
49         BIO *bio;
50
51         if(!fp_cb_ssl_verify)
52                 return ok;
53         /* There's no <damned>FILE*</damned> version of ASN1_TIME_print */
54         bio = BIO_new_fp(fp_cb_ssl_verify, BIO_NOCLOSE);
55         err_cert = X509_STORE_CTX_get_current_cert(ctx);
56         err = X509_STORE_CTX_get_error(ctx);
57         depth = X509_STORE_CTX_get_error_depth(ctx);
58
59         X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
60         fprintf(fp_cb_ssl_verify, "depth=%d %s\n", depth, buf);
61         if(!ok) {
62                 fprintf(fp_cb_ssl_verify,"verify error:num=%d:%s\n",err,
63                         X509_verify_cert_error_string(err));
64                 if((int)int_verify_depth >= depth)
65                         int_verify_error = err;
66                 else
67                         int_verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
68         }
69         switch (ctx->error) {
70         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
71                 X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),
72                                 buf, 256);
73                 fprintf(fp_cb_ssl_verify, "issuer= %s\n", buf);
74                 break;
75         case X509_V_ERR_CERT_NOT_YET_VALID:
76         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
77                 fprintf(fp_cb_ssl_verify, "notBefore=");
78                 ASN1_TIME_print(bio, X509_get_notBefore(ctx->current_cert));
79                 fprintf(fp_cb_ssl_verify, "\n");
80                 break;
81         case X509_V_ERR_CERT_HAS_EXPIRED:
82         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
83                 fprintf(fp_cb_ssl_verify, "notAfter=");
84                 ASN1_TIME_print(bio, X509_get_notAfter(ctx->current_cert));
85                 fprintf(fp_cb_ssl_verify, "\n");
86                 break;
87         }
88         fprintf(fp_cb_ssl_verify, "verify return:%d\n",ok);
89         return ok;
90 }
91
92 void cb_ssl_verify_set_output(FILE *fp)
93 {
94         fp_cb_ssl_verify = fp;
95 }
96
97 void cb_ssl_verify_set_depth(unsigned int verify_depth)
98 {
99         int_verify_depth = verify_depth;
100 }
101
102 #endif /* !defined(NO_OPENSSL) */
103