xref: /minix3/crypto/external/bsd/openssl/dist/demos/tunala/cb.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1ebfedea0SLionel Sambuc #include "tunala.h"
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc #ifndef NO_OPENSSL
4ebfedea0SLionel Sambuc 
5ebfedea0SLionel Sambuc /* For callbacks generating output, here are their file-descriptors. */
6ebfedea0SLionel Sambuc static FILE *fp_cb_ssl_info = NULL;
7ebfedea0SLionel Sambuc static FILE *fp_cb_ssl_verify = NULL;
8*0a6a1f1dSLionel Sambuc /*-
9*0a6a1f1dSLionel Sambuc  * Output level:
10ebfedea0SLionel Sambuc  *     0 = nothing,
11ebfedea0SLionel Sambuc  *     1 = minimal, just errors,
12ebfedea0SLionel Sambuc  *     2 = minimal, all steps,
13ebfedea0SLionel Sambuc  *     3 = detail, all steps */
14ebfedea0SLionel Sambuc static unsigned int cb_ssl_verify_level = 1;
15ebfedea0SLionel Sambuc 
16ebfedea0SLionel Sambuc /* Other static rubbish (to mirror s_cb.c where required) */
17ebfedea0SLionel Sambuc static int int_verify_depth = 10;
18ebfedea0SLionel Sambuc 
19*0a6a1f1dSLionel Sambuc /*
20*0a6a1f1dSLionel Sambuc  * This function is largely borrowed from the one used in OpenSSL's
21*0a6a1f1dSLionel Sambuc  * "s_client" and "s_server" utilities.
22*0a6a1f1dSLionel Sambuc  */
cb_ssl_info(const SSL * s,int where,int ret)23ebfedea0SLionel Sambuc void cb_ssl_info(const SSL *s, int where, int ret)
24ebfedea0SLionel Sambuc {
25ebfedea0SLionel Sambuc     const char *str1, *str2;
26ebfedea0SLionel Sambuc     int w;
27ebfedea0SLionel Sambuc 
28ebfedea0SLionel Sambuc     if (!fp_cb_ssl_info)
29ebfedea0SLionel Sambuc         return;
30ebfedea0SLionel Sambuc 
31ebfedea0SLionel Sambuc     w = where & ~SSL_ST_MASK;
32ebfedea0SLionel Sambuc     str1 = (w & SSL_ST_CONNECT ? "SSL_connect" : (w & SSL_ST_ACCEPT ?
33*0a6a1f1dSLionel Sambuc                                                   "SSL_accept" :
34*0a6a1f1dSLionel Sambuc                                                   "undefined")), str2 =
35*0a6a1f1dSLionel Sambuc         SSL_state_string_long(s);
36ebfedea0SLionel Sambuc 
37ebfedea0SLionel Sambuc     if (where & SSL_CB_LOOP)
38ebfedea0SLionel Sambuc         fprintf(fp_cb_ssl_info, "(%s) %s\n", str1, str2);
39ebfedea0SLionel Sambuc     else if (where & SSL_CB_EXIT) {
40ebfedea0SLionel Sambuc         if (ret == 0)
41ebfedea0SLionel Sambuc             fprintf(fp_cb_ssl_info, "(%s) failed in %s\n", str1, str2);
42*0a6a1f1dSLionel Sambuc         /*
43*0a6a1f1dSLionel Sambuc          * In a non-blocking model, we get a few of these "error"s simply
44*0a6a1f1dSLionel Sambuc          * because we're calling "reads" and "writes" on the state-machine
45*0a6a1f1dSLionel Sambuc          * that are virtual NOPs simply to avoid wasting the time seeing if
46*0a6a1f1dSLionel Sambuc          * we *should* call them. Removing this case makes the "-out_state"
47*0a6a1f1dSLionel Sambuc          * output a lot easier on the eye.
48*0a6a1f1dSLionel Sambuc          */
49ebfedea0SLionel Sambuc # if 0
50ebfedea0SLionel Sambuc         else if (ret < 0)
51ebfedea0SLionel Sambuc             fprintf(fp_cb_ssl_info, "%s:error in %s\n", str1, str2);
52ebfedea0SLionel Sambuc # endif
53ebfedea0SLionel Sambuc     }
54ebfedea0SLionel Sambuc }
55ebfedea0SLionel Sambuc 
cb_ssl_info_set_output(FILE * fp)56ebfedea0SLionel Sambuc void cb_ssl_info_set_output(FILE *fp)
57ebfedea0SLionel Sambuc {
58ebfedea0SLionel Sambuc     fp_cb_ssl_info = fp;
59ebfedea0SLionel Sambuc }
60ebfedea0SLionel Sambuc 
61*0a6a1f1dSLionel Sambuc static const char *int_reason_no_issuer =
62*0a6a1f1dSLionel Sambuc     "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT";
63ebfedea0SLionel Sambuc static const char *int_reason_not_yet = "X509_V_ERR_CERT_NOT_YET_VALID";
64*0a6a1f1dSLionel Sambuc static const char *int_reason_before =
65*0a6a1f1dSLionel Sambuc     "X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD";
66ebfedea0SLionel Sambuc static const char *int_reason_expired = "X509_V_ERR_CERT_HAS_EXPIRED";
67*0a6a1f1dSLionel Sambuc static const char *int_reason_after =
68*0a6a1f1dSLionel Sambuc     "X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD";
69ebfedea0SLionel Sambuc 
70ebfedea0SLionel Sambuc /* Stolen wholesale from apps/s_cb.c :-) And since then, mutilated ... */
cb_ssl_verify(int ok,X509_STORE_CTX * ctx)71ebfedea0SLionel Sambuc int cb_ssl_verify(int ok, X509_STORE_CTX *ctx)
72ebfedea0SLionel Sambuc {
73ebfedea0SLionel Sambuc     char buf1[256];             /* Used for the subject name */
74ebfedea0SLionel Sambuc     char buf2[256];             /* Used for the issuer name */
75ebfedea0SLionel Sambuc     const char *reason = NULL;  /* Error reason (if any) */
76ebfedea0SLionel Sambuc     X509 *err_cert;
77ebfedea0SLionel Sambuc     int err, depth;
78ebfedea0SLionel Sambuc 
79ebfedea0SLionel Sambuc     if (!fp_cb_ssl_verify || (cb_ssl_verify_level == 0))
80ebfedea0SLionel Sambuc         return ok;
81ebfedea0SLionel Sambuc     err_cert = X509_STORE_CTX_get_current_cert(ctx);
82ebfedea0SLionel Sambuc     err = X509_STORE_CTX_get_error(ctx);
83ebfedea0SLionel Sambuc     depth = X509_STORE_CTX_get_error_depth(ctx);
84ebfedea0SLionel Sambuc 
85ebfedea0SLionel Sambuc     buf1[0] = buf2[0] = '\0';
86ebfedea0SLionel Sambuc     /* Fill buf1 */
87ebfedea0SLionel Sambuc     X509_NAME_oneline(X509_get_subject_name(err_cert), buf1, 256);
88ebfedea0SLionel Sambuc     /* Fill buf2 */
89ebfedea0SLionel Sambuc     X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf2, 256);
90ebfedea0SLionel Sambuc     switch (ctx->error) {
91ebfedea0SLionel Sambuc     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
92ebfedea0SLionel Sambuc         reason = int_reason_no_issuer;
93ebfedea0SLionel Sambuc         break;
94ebfedea0SLionel Sambuc     case X509_V_ERR_CERT_NOT_YET_VALID:
95ebfedea0SLionel Sambuc         reason = int_reason_not_yet;
96ebfedea0SLionel Sambuc         break;
97ebfedea0SLionel Sambuc     case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
98ebfedea0SLionel Sambuc         reason = int_reason_before;
99ebfedea0SLionel Sambuc         break;
100ebfedea0SLionel Sambuc     case X509_V_ERR_CERT_HAS_EXPIRED:
101ebfedea0SLionel Sambuc         reason = int_reason_expired;
102ebfedea0SLionel Sambuc         break;
103ebfedea0SLionel Sambuc     case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
104ebfedea0SLionel Sambuc         reason = int_reason_after;
105ebfedea0SLionel Sambuc         break;
106ebfedea0SLionel Sambuc     }
107ebfedea0SLionel Sambuc 
108ebfedea0SLionel Sambuc     if ((cb_ssl_verify_level == 1) && ok)
109ebfedea0SLionel Sambuc         return ok;
110ebfedea0SLionel Sambuc     fprintf(fp_cb_ssl_verify, "chain-depth=%d, ", depth);
111ebfedea0SLionel Sambuc     if (reason)
112ebfedea0SLionel Sambuc         fprintf(fp_cb_ssl_verify, "error=%s\n", reason);
113ebfedea0SLionel Sambuc     else
114ebfedea0SLionel Sambuc         fprintf(fp_cb_ssl_verify, "error=%d\n", err);
115ebfedea0SLionel Sambuc     if (cb_ssl_verify_level < 3)
116ebfedea0SLionel Sambuc         return ok;
117ebfedea0SLionel Sambuc     fprintf(fp_cb_ssl_verify, "--> subject = %s\n", buf1);
118ebfedea0SLionel Sambuc     fprintf(fp_cb_ssl_verify, "--> issuer  = %s\n", buf2);
119ebfedea0SLionel Sambuc     if (!ok)
120ebfedea0SLionel Sambuc         fprintf(fp_cb_ssl_verify, "--> verify error:num=%d:%s\n", err,
121ebfedea0SLionel Sambuc                 X509_verify_cert_error_string(err));
122ebfedea0SLionel Sambuc     fprintf(fp_cb_ssl_verify, "--> verify return:%d\n", ok);
123ebfedea0SLionel Sambuc     return ok;
124ebfedea0SLionel Sambuc }
125ebfedea0SLionel Sambuc 
cb_ssl_verify_set_output(FILE * fp)126ebfedea0SLionel Sambuc void cb_ssl_verify_set_output(FILE *fp)
127ebfedea0SLionel Sambuc {
128ebfedea0SLionel Sambuc     fp_cb_ssl_verify = fp;
129ebfedea0SLionel Sambuc }
130ebfedea0SLionel Sambuc 
cb_ssl_verify_set_depth(unsigned int verify_depth)131ebfedea0SLionel Sambuc void cb_ssl_verify_set_depth(unsigned int verify_depth)
132ebfedea0SLionel Sambuc {
133ebfedea0SLionel Sambuc     int_verify_depth = verify_depth;
134ebfedea0SLionel Sambuc }
135ebfedea0SLionel Sambuc 
cb_ssl_verify_set_level(unsigned int level)136ebfedea0SLionel Sambuc void cb_ssl_verify_set_level(unsigned int level)
137ebfedea0SLionel Sambuc {
138ebfedea0SLionel Sambuc     if (level < 4)
139ebfedea0SLionel Sambuc         cb_ssl_verify_level = level;
140ebfedea0SLionel Sambuc }
141ebfedea0SLionel Sambuc 
cb_generate_tmp_rsa(SSL * s,int is_export,int keylength)142ebfedea0SLionel Sambuc RSA *cb_generate_tmp_rsa(SSL *s, int is_export, int keylength)
143ebfedea0SLionel Sambuc {
144*0a6a1f1dSLionel Sambuc     /*
145*0a6a1f1dSLionel Sambuc      * TODO: Perhaps make it so our global key can be generated on-the-fly
146*0a6a1f1dSLionel Sambuc      * after certain intervals?
147*0a6a1f1dSLionel Sambuc      */
148ebfedea0SLionel Sambuc     static RSA *rsa_tmp = NULL;
149ebfedea0SLionel Sambuc     BIGNUM *bn = NULL;
150ebfedea0SLionel Sambuc     int ok = 1;
151ebfedea0SLionel Sambuc     if (!rsa_tmp) {
152ebfedea0SLionel Sambuc         ok = 0;
153ebfedea0SLionel Sambuc         if (!(bn = BN_new()))
154ebfedea0SLionel Sambuc             goto end;
155ebfedea0SLionel Sambuc         if (!BN_set_word(bn, RSA_F4))
156ebfedea0SLionel Sambuc             goto end;
157ebfedea0SLionel Sambuc         if (!(rsa_tmp = RSA_new()))
158ebfedea0SLionel Sambuc             goto end;
159ebfedea0SLionel Sambuc         if (!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
160ebfedea0SLionel Sambuc             goto end;
161ebfedea0SLionel Sambuc         ok = 1;
162ebfedea0SLionel Sambuc     }
163ebfedea0SLionel Sambuc  end:
164ebfedea0SLionel Sambuc     if (bn)
165ebfedea0SLionel Sambuc         BN_free(bn);
166ebfedea0SLionel Sambuc     if (!ok) {
167ebfedea0SLionel Sambuc         RSA_free(rsa_tmp);
168ebfedea0SLionel Sambuc         rsa_tmp = NULL;
169ebfedea0SLionel Sambuc     }
170ebfedea0SLionel Sambuc     return rsa_tmp;
171ebfedea0SLionel Sambuc }
172ebfedea0SLionel Sambuc 
173ebfedea0SLionel Sambuc #endif                          /* !defined(NO_OPENSSL) */
174