1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117: #include <stdio.h>
118:
119: #include "e_os.h"
120: #ifndef NO_SYS_TYPES_H
121: # include <sys/types.h>
122: #endif
123:
124: #include "o_dir.h"
125: #include <openssl/objects.h>
126: #include <openssl/bio.h>
127: #include <openssl/pem.h>
128: #include <openssl/x509v3.h>
129: #ifndef OPENSSL_NO_DH
130: #include <openssl/dh.h>
131: #endif
132: #include <openssl/bn.h>
133: #include "ssl_locl.h"
134:
135: int SSL_get_ex_data_X509_STORE_CTX_idx(void)
136: {
137: static volatile int ssl_x509_store_ctx_idx= -1;
138: int got_write_lock = 0;
139:
140: CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
141:
142: if (ssl_x509_store_ctx_idx < 0)
143: {
144: CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
145: CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
146: got_write_lock = 1;
147:
148: if (ssl_x509_store_ctx_idx < 0)
149: {
150: ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index(
151: 0,"SSL for verify callback",NULL,NULL,NULL);
152: }
153: }
154:
155: if (got_write_lock)
156: CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
157: else
158: CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
159:
160: return ssl_x509_store_ctx_idx;
161: }
162:
163: CERT *ssl_cert_new(void)
164: {
165: CERT *ret;
166:
167: ret=(CERT *)OPENSSL_malloc(sizeof(CERT));
168: if (ret == NULL)
169: {
170: SSLerr(SSL_F_SSL_CERT_NEW,ERR_R_MALLOC_FAILURE);
171: return(NULL);
172: }
173: memset(ret,0,sizeof(CERT));
174:
175: ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
176: ret->references=1;
177:
178: return(ret);
179: }
180:
181: CERT *ssl_cert_dup(CERT *cert)
182: {
183: CERT *ret;
184: int i;
185:
186: ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
187: if (ret == NULL)
188: {
189: SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
190: return(NULL);
191: }
192:
193: memset(ret, 0, sizeof(CERT));
194:
195: ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
196:
197:
198:
199: ret->valid = cert->valid;
200: ret->mask = cert->mask;
201: ret->export_mask = cert->export_mask;
202:
203: #ifndef OPENSSL_NO_RSA
204: if (cert->rsa_tmp != NULL)
205: {
206: RSA_up_ref(cert->rsa_tmp);
207: ret->rsa_tmp = cert->rsa_tmp;
208: }
209: ret->rsa_tmp_cb = cert->rsa_tmp_cb;
210: #endif
211:
212: #ifndef OPENSSL_NO_DH
213: if (cert->dh_tmp != NULL)
214: {
215: ret->dh_tmp = DHparams_dup(cert->dh_tmp);
216: if (ret->dh_tmp == NULL)
217: {
218: SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
219: goto err;
220: }
221: if (cert->dh_tmp->priv_key)
222: {
223: BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
224: if (!b)
225: {
226: SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
227: goto err;
228: }
229: ret->dh_tmp->priv_key = b;
230: }
231: if (cert->dh_tmp->pub_key)
232: {
233: BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
234: if (!b)
235: {
236: SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
237: goto err;
238: }
239: ret->dh_tmp->pub_key = b;
240: }
241: }
242: ret->dh_tmp_cb = cert->dh_tmp_cb;
243: #endif
244:
245: #ifndef OPENSSL_NO_ECDH
246: if (cert->ecdh_tmp)
247: {
248: ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
249: if (ret->ecdh_tmp == NULL)
250: {
251: SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
252: goto err;
253: }
254: }
255: ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
256: #endif
257:
258: for (i = 0; i < SSL_PKEY_NUM; i++)
259: {
260: if (cert->pkeys[i].x509 != NULL)
261: {
262: ret->pkeys[i].x509 = cert->pkeys[i].x509;
263: CRYPTO_add(&ret->pkeys[i].x509->references, 1,
264: CRYPTO_LOCK_X509);
265: }
266:
267: if (cert->pkeys[i].privatekey != NULL)
268: {
269: ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
270: CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
271: CRYPTO_LOCK_EVP_PKEY);
272:
273: switch(i)
274: {
275:
276:
277:
278:
279: case SSL_PKEY_RSA_ENC:
280: case SSL_PKEY_RSA_SIGN:
281:
282: break;
283:
284: case SSL_PKEY_DSA_SIGN:
285:
286: break;
287:
288: case SSL_PKEY_DH_RSA:
289: case SSL_PKEY_DH_DSA:
290:
291: break;
292:
293: case SSL_PKEY_ECC:
294:
295: break;
296:
297: default:
298:
299: SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
300: }
301: }
302: }
303:
304:
305:
306:
307: ret->references=1;
308:
309: return(ret);
310:
311: #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
312: err:
313: #endif
314: #ifndef OPENSSL_NO_RSA
315: if (ret->rsa_tmp != NULL)
316: RSA_free(ret->rsa_tmp);
317: #endif
318: #ifndef OPENSSL_NO_DH
319: if (ret->dh_tmp != NULL)
320: DH_free(ret->dh_tmp);
321: #endif
322: #ifndef OPENSSL_NO_ECDH
323: if (ret->ecdh_tmp != NULL)
324: EC_KEY_free(ret->ecdh_tmp);
325: #endif
326:
327: for (i = 0; i < SSL_PKEY_NUM; i++)
328: {
329: if (ret->pkeys[i].x509 != NULL)
330: X509_free(ret->pkeys[i].x509);
331: if (ret->pkeys[i].privatekey != NULL)
332: EVP_PKEY_free(ret->pkeys[i].privatekey);
333: }
334:
335: return NULL;
336: }
337:
338:
339: void ssl_cert_free(CERT *c)
340: {
341: int i;
342:
343: if(c == NULL)
344: return;
345:
346: i=CRYPTO_add(&c->references,-1,CRYPTO_LOCK_SSL_CERT);
347: #ifdef REF_PRINT
348: REF_PRINT("CERT",c);
349: #endif
350: if (i > 0) return;
351: #ifdef REF_CHECK
352: if (i < 0)
353: {
354: fprintf(stderr,"ssl_cert_free, bad reference count\n");
355: abort();
356: }
357: #endif
358:
359: #ifndef OPENSSL_NO_RSA
360: if (c->rsa_tmp) RSA_free(c->rsa_tmp);
361: #endif
362: #ifndef OPENSSL_NO_DH
363: if (c->dh_tmp) DH_free(c->dh_tmp);
364: #endif
365: #ifndef OPENSSL_NO_ECDH
366: if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp);
367: #endif
368:
369: for (i=0; i<SSL_PKEY_NUM; i++)
370: {
371: if (c->pkeys[i].x509 != NULL)
372: X509_free(c->pkeys[i].x509);
373: if (c->pkeys[i].privatekey != NULL)
374: EVP_PKEY_free(c->pkeys[i].privatekey);
375: #if 0
376: if (c->pkeys[i].publickey != NULL)
377: EVP_PKEY_free(c->pkeys[i].publickey);
378: #endif
379: }
380: OPENSSL_free(c);
381: }
382:
383: int ssl_cert_inst(CERT **o)
384: {
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395: if (o == NULL)
396: {
397: SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
398: return(0);
399: }
400: if (*o == NULL)
401: {
402: if ((*o = ssl_cert_new()) == NULL)
403: {
404: SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
405: return(0);
406: }
407: }
408: return(1);
409: }
410:
411:
412: SESS_CERT *ssl_sess_cert_new(void)
413: {
414: SESS_CERT *ret;
415:
416: ret = OPENSSL_malloc(sizeof *ret);
417: if (ret == NULL)
418: {
419: SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
420: return NULL;
421: }
422:
423: memset(ret, 0 ,sizeof *ret);
424: ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
425: ret->references = 1;
426:
427: return ret;
428: }
429:
430: void ssl_sess_cert_free(SESS_CERT *sc)
431: {
432: int i;
433:
434: if (sc == NULL)
435: return;
436:
437: i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
438: #ifdef REF_PRINT
439: REF_PRINT("SESS_CERT", sc);
440: #endif
441: if (i > 0)
442: return;
443: #ifdef REF_CHECK
444: if (i < 0)
445: {
446: fprintf(stderr,"ssl_sess_cert_free, bad reference count\n");
447: abort();
448: }
449: #endif
450:
451:
452: if (sc->cert_chain != NULL)
453: sk_X509_pop_free(sc->cert_chain, X509_free);
454: for (i = 0; i < SSL_PKEY_NUM; i++)
455: {
456: if (sc->peer_pkeys[i].x509 != NULL)
457: X509_free(sc->peer_pkeys[i].x509);
458: #if 0
459:
460:
461: if (sc->peer_pkeys[i].privatekey != NULL)
462: EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
463: #endif
464: }
465:
466: #ifndef OPENSSL_NO_RSA
467: if (sc->peer_rsa_tmp != NULL)
468: RSA_free(sc->peer_rsa_tmp);
469: #endif
470: #ifndef OPENSSL_NO_DH
471: if (sc->peer_dh_tmp != NULL)
472: DH_free(sc->peer_dh_tmp);
473: #endif
474: #ifndef OPENSSL_NO_ECDH
475: if (sc->peer_ecdh_tmp != NULL)
476: EC_KEY_free(sc->peer_ecdh_tmp);
477: #endif
478:
479: OPENSSL_free(sc);
480: }
481:
482: int ssl_set_peer_cert_type(SESS_CERT *sc,int type)
483: {
484: sc->peer_cert_type = type;
485: return(1);
486: }
487:
488: int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
489: {
490: X509 *x;
491: int i;
492: X509_STORE_CTX ctx;
493:
494: if ((sk == NULL) || (sk_X509_num(sk) == 0))
495: return(0);
496:
497: x=sk_X509_value(sk,0);
498: if(!X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk))
499: {
500: SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
501: return(0);
502: }
503: if (s->param)
504: X509_VERIFY_PARAM_inherit(X509_STORE_CTX_get0_param(&ctx),
505: s->param);
506: #if 0
507: if (SSL_get_verify_depth(s) >= 0)
508: X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
509: #endif
510: X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s);
511:
512:
513:
514:
515:
516:
517: X509_STORE_CTX_set_default(&ctx,
518: s->server ? "ssl_client" : "ssl_server");
519:
520: if (s->verify_callback)
521: X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
522:
523: if (s->ctx->app_verify_callback != NULL)
524: #if 1
525: i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
526: #else
527: i=s->ctx->app_verify_callback(&ctx);
528: #endif
529: else
530: {
531: #ifndef OPENSSL_NO_X509_VERIFY
532: i=X509_verify_cert(&ctx);
533: #else
534: i=0;
535: ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
536: SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_NO_VERIFY_CALLBACK);
537: #endif
538: }
539:
540: s->verify_result=ctx.error;
541: X509_STORE_CTX_cleanup(&ctx);
542:
543: return(i);
544: }
545:
546: static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
547: {
548: if (*ca_list != NULL)
549: sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
550:
551: *ca_list=name_list;
552: }
553:
554: STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
555: {
556: int i;
557: STACK_OF(X509_NAME) *ret;
558: X509_NAME *name;
559:
560: ret=sk_X509_NAME_new_null();
561: for (i=0; i<sk_X509_NAME_num(sk); i++)
562: {
563: name=X509_NAME_dup(sk_X509_NAME_value(sk,i));
564: if ((name == NULL) || !sk_X509_NAME_push(ret,name))
565: {
566: sk_X509_NAME_pop_free(ret,X509_NAME_free);
567: return(NULL);
568: }
569: }
570: return(ret);