diff options
Diffstat (limited to 'src/lib/libssl/ssl_cert.c')
-rw-r--r-- | src/lib/libssl/ssl_cert.c | 130 |
1 files changed, 103 insertions, 27 deletions
diff --git a/src/lib/libssl/ssl_cert.c b/src/lib/libssl/ssl_cert.c index 27e7fcc60a..79e89fe14a 100644 --- a/src/lib/libssl/ssl_cert.c +++ b/src/lib/libssl/ssl_cert.c | |||
@@ -106,16 +106,19 @@ | |||
106 | 106 | ||
107 | #include <stdio.h> | 107 | #include <stdio.h> |
108 | 108 | ||
109 | #include "openssl/e_os.h" | 109 | #include "e_os.h" |
110 | |||
111 | #ifndef NO_SYS_TYPES_H | 110 | #ifndef NO_SYS_TYPES_H |
112 | # include <sys/types.h> | 111 | # include <sys/types.h> |
113 | #endif | 112 | #endif |
114 | 113 | ||
115 | #if !defined(WIN32) && !defined(VSM) && !defined(NeXT) && !defined(MAC_OS_pre_X) | 114 | #if !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS) && !defined(NeXT) && !defined(MAC_OS_pre_X) |
116 | #include <dirent.h> | 115 | #include <dirent.h> |
117 | #endif | 116 | #endif |
118 | 117 | ||
118 | #if defined(WIN32) | ||
119 | #include <windows.h> | ||
120 | #endif | ||
121 | |||
119 | #ifdef NeXT | 122 | #ifdef NeXT |
120 | #include <sys/dir.h> | 123 | #include <sys/dir.h> |
121 | #define dirent direct | 124 | #define dirent direct |
@@ -129,14 +132,23 @@ | |||
129 | 132 | ||
130 | int SSL_get_ex_data_X509_STORE_CTX_idx(void) | 133 | int SSL_get_ex_data_X509_STORE_CTX_idx(void) |
131 | { | 134 | { |
132 | static int ssl_x509_store_ctx_idx= -1; | 135 | static volatile int ssl_x509_store_ctx_idx= -1; |
133 | 136 | ||
134 | if (ssl_x509_store_ctx_idx < 0) | 137 | if (ssl_x509_store_ctx_idx < 0) |
135 | { | 138 | { |
136 | ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index( | 139 | /* any write lock will do; usually this branch |
137 | 0,"SSL for verify callback",NULL,NULL,NULL); | 140 | * will only be taken once anyway */ |
141 | CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); | ||
142 | |||
143 | if (ssl_x509_store_ctx_idx < 0) | ||
144 | { | ||
145 | ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index( | ||
146 | 0,"SSL for verify callback",NULL,NULL,NULL); | ||
147 | } | ||
148 | |||
149 | CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); | ||
138 | } | 150 | } |
139 | return(ssl_x509_store_ctx_idx); | 151 | return ssl_x509_store_ctx_idx; |
140 | } | 152 | } |
141 | 153 | ||
142 | CERT *ssl_cert_new(void) | 154 | CERT *ssl_cert_new(void) |
@@ -179,16 +191,16 @@ CERT *ssl_cert_dup(CERT *cert) | |||
179 | ret->mask = cert->mask; | 191 | ret->mask = cert->mask; |
180 | ret->export_mask = cert->export_mask; | 192 | ret->export_mask = cert->export_mask; |
181 | 193 | ||
182 | #ifndef NO_RSA | 194 | #ifndef OPENSSL_NO_RSA |
183 | if (cert->rsa_tmp != NULL) | 195 | if (cert->rsa_tmp != NULL) |
184 | { | 196 | { |
197 | RSA_up_ref(cert->rsa_tmp); | ||
185 | ret->rsa_tmp = cert->rsa_tmp; | 198 | ret->rsa_tmp = cert->rsa_tmp; |
186 | CRYPTO_add(&ret->rsa_tmp->references, 1, CRYPTO_LOCK_RSA); | ||
187 | } | 199 | } |
188 | ret->rsa_tmp_cb = cert->rsa_tmp_cb; | 200 | ret->rsa_tmp_cb = cert->rsa_tmp_cb; |
189 | #endif | 201 | #endif |
190 | 202 | ||
191 | #ifndef NO_DH | 203 | #ifndef OPENSSL_NO_DH |
192 | if (cert->dh_tmp != NULL) | 204 | if (cert->dh_tmp != NULL) |
193 | { | 205 | { |
194 | /* DH parameters don't have a reference count */ | 206 | /* DH parameters don't have a reference count */ |
@@ -271,14 +283,14 @@ CERT *ssl_cert_dup(CERT *cert) | |||
271 | 283 | ||
272 | return(ret); | 284 | return(ret); |
273 | 285 | ||
274 | #ifndef NO_DH /* avoid 'unreferenced label' warning if NO_DH is defined */ | 286 | #ifndef OPENSSL_NO_DH /* avoid 'unreferenced label' warning if OPENSSL_NO_DH is defined */ |
275 | err: | 287 | err: |
276 | #endif | 288 | #endif |
277 | #ifndef NO_RSA | 289 | #ifndef OPENSSL_NO_RSA |
278 | if (ret->rsa_tmp != NULL) | 290 | if (ret->rsa_tmp != NULL) |
279 | RSA_free(ret->rsa_tmp); | 291 | RSA_free(ret->rsa_tmp); |
280 | #endif | 292 | #endif |
281 | #ifndef NO_DH | 293 | #ifndef OPENSSL_NO_DH |
282 | if (ret->dh_tmp != NULL) | 294 | if (ret->dh_tmp != NULL) |
283 | DH_free(ret->dh_tmp); | 295 | DH_free(ret->dh_tmp); |
284 | #endif | 296 | #endif |
@@ -315,10 +327,10 @@ void ssl_cert_free(CERT *c) | |||
315 | } | 327 | } |
316 | #endif | 328 | #endif |
317 | 329 | ||
318 | #ifndef NO_RSA | 330 | #ifndef OPENSSL_NO_RSA |
319 | if (c->rsa_tmp) RSA_free(c->rsa_tmp); | 331 | if (c->rsa_tmp) RSA_free(c->rsa_tmp); |
320 | #endif | 332 | #endif |
321 | #ifndef NO_DH | 333 | #ifndef OPENSSL_NO_DH |
322 | if (c->dh_tmp) DH_free(c->dh_tmp); | 334 | if (c->dh_tmp) DH_free(c->dh_tmp); |
323 | #endif | 335 | #endif |
324 | 336 | ||
@@ -419,11 +431,11 @@ void ssl_sess_cert_free(SESS_CERT *sc) | |||
419 | #endif | 431 | #endif |
420 | } | 432 | } |
421 | 433 | ||
422 | #ifndef NO_RSA | 434 | #ifndef OPENSSL_NO_RSA |
423 | if (sc->peer_rsa_tmp != NULL) | 435 | if (sc->peer_rsa_tmp != NULL) |
424 | RSA_free(sc->peer_rsa_tmp); | 436 | RSA_free(sc->peer_rsa_tmp); |
425 | #endif | 437 | #endif |
426 | #ifndef NO_DH | 438 | #ifndef OPENSSL_NO_DH |
427 | if (sc->peer_dh_tmp != NULL) | 439 | if (sc->peer_dh_tmp != NULL) |
428 | DH_free(sc->peer_dh_tmp); | 440 | DH_free(sc->peer_dh_tmp); |
429 | #endif | 441 | #endif |
@@ -447,25 +459,38 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk) | |||
447 | return(0); | 459 | return(0); |
448 | 460 | ||
449 | x=sk_X509_value(sk,0); | 461 | x=sk_X509_value(sk,0); |
450 | X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk); | 462 | if(!X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk)) |
463 | { | ||
464 | SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB); | ||
465 | return(0); | ||
466 | } | ||
451 | if (SSL_get_verify_depth(s) >= 0) | 467 | if (SSL_get_verify_depth(s) >= 0) |
452 | X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); | 468 | X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); |
453 | X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s); | 469 | X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s); |
470 | |||
454 | /* We need to set the verify purpose. The purpose can be determined by | 471 | /* We need to set the verify purpose. The purpose can be determined by |
455 | * the context: if its a server it will verify SSL client certificates | 472 | * the context: if its a server it will verify SSL client certificates |
456 | * or vice versa. | 473 | * or vice versa. |
457 | */ | 474 | */ |
458 | 475 | if (s->server) | |
459 | if(s->server) i = X509_PURPOSE_SSL_CLIENT; | 476 | i = X509_PURPOSE_SSL_CLIENT; |
460 | else i = X509_PURPOSE_SSL_SERVER; | 477 | else |
478 | i = X509_PURPOSE_SSL_SERVER; | ||
461 | 479 | ||
462 | X509_STORE_CTX_purpose_inherit(&ctx, i, s->purpose, s->trust); | 480 | X509_STORE_CTX_purpose_inherit(&ctx, i, s->purpose, s->trust); |
463 | 481 | ||
482 | if (s->verify_callback) | ||
483 | X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); | ||
484 | |||
464 | if (s->ctx->app_verify_callback != NULL) | 485 | if (s->ctx->app_verify_callback != NULL) |
486 | #if 1 /* new with OpenSSL 0.9.7 */ | ||
487 | i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); | ||
488 | #else | ||
465 | i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ | 489 | i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ |
490 | #endif | ||
466 | else | 491 | else |
467 | { | 492 | { |
468 | #ifndef NO_X509_VERIFY | 493 | #ifndef OPENSSL_NO_X509_VERIFY |
469 | i=X509_verify_cert(&ctx); | 494 | i=X509_verify_cert(&ctx); |
470 | #else | 495 | #else |
471 | i=0; | 496 | i=0; |
@@ -575,7 +600,7 @@ static int xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b) | |||
575 | return(X509_NAME_cmp(*a,*b)); | 600 | return(X509_NAME_cmp(*a,*b)); |
576 | } | 601 | } |
577 | 602 | ||
578 | #ifndef NO_STDIO | 603 | #ifndef OPENSSL_NO_STDIO |
579 | /*! | 604 | /*! |
580 | * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; | 605 | * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; |
581 | * it doesn't really have anything to do with clients (except that a common use | 606 | * it doesn't really have anything to do with clients (except that a common use |
@@ -705,9 +730,9 @@ err: | |||
705 | * certs may have been added to \c stack. | 730 | * certs may have been added to \c stack. |
706 | */ | 731 | */ |
707 | 732 | ||
708 | #ifndef WIN32 | 733 | #ifndef OPENSSL_SYS_WIN32 |
709 | #ifndef VMS /* XXXX This may be fixed in the future */ | 734 | #ifndef OPENSSL_SYS_VMS /* XXXX This may be fixed in the future */ |
710 | #ifndef MAC_OS_pre_X | 735 | #ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! */ |
711 | 736 | ||
712 | int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, | 737 | int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, |
713 | const char *dir) | 738 | const char *dir) |
@@ -748,10 +773,61 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, | |||
748 | ret = 1; | 773 | ret = 1; |
749 | 774 | ||
750 | err: | 775 | err: |
776 | if (d) closedir(d); | ||
751 | CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); | 777 | CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); |
752 | return ret; | 778 | return ret; |
753 | } | 779 | } |
754 | 780 | ||
755 | #endif | 781 | #endif |
756 | #endif | 782 | #endif |
783 | |||
784 | #else | ||
785 | |||
786 | int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, | ||
787 | const char *dir) | ||
788 | { | ||
789 | WIN32_FIND_DATA FindFileData; | ||
790 | HANDLE hFind; | ||
791 | int ret = 0; | ||
792 | |||
793 | CRYPTO_w_lock(CRYPTO_LOCK_READDIR); | ||
794 | |||
795 | hFind = FindFirstFile(dir, &FindFileData); | ||
796 | /* Note that a side effect is that the CAs will be sorted by name */ | ||
797 | if(hFind == INVALID_HANDLE_VALUE) | ||
798 | { | ||
799 | SYSerr(SYS_F_OPENDIR, get_last_sys_error()); | ||
800 | ERR_add_error_data(3, "opendir('", dir, "')"); | ||
801 | SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); | ||
802 | goto err_noclose; | ||
803 | } | ||
804 | |||
805 | do | ||
806 | { | ||
807 | char buf[1024]; | ||
808 | int r; | ||
809 | |||
810 | if(strlen(dir)+strlen(FindFileData.cFileName)+2 > sizeof buf) | ||
811 | { | ||
812 | SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG); | ||
813 | goto err; | ||
814 | } | ||
815 | |||
816 | r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,FindFileData.cFileName); | ||
817 | if (r <= 0 || r >= sizeof buf) | ||
818 | goto err; | ||
819 | if(!SSL_add_file_cert_subjects_to_stack(stack,buf)) | ||
820 | goto err; | ||
821 | } | ||
822 | while (FindNextFile(hFind, &FindFileData) != FALSE); | ||
823 | ret = 1; | ||
824 | |||
825 | err: | ||
826 | FindClose(hFind); | ||
827 | err_noclose: | ||
828 | if (d) closedir(d); | ||
829 | CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); | ||
830 | return ret; | ||
831 | } | ||
832 | |||
757 | #endif | 833 | #endif |