summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_cert.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/ssl_cert.c')
-rw-r--r--src/lib/libssl/ssl_cert.c130
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
130int SSL_get_ex_data_X509_STORE_CTX_idx(void) 133int 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
142CERT *ssl_cert_new(void) 154CERT *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 */
275err: 287err:
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
712int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, 737int 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
750err: 775err:
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
786int 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
825err:
826 FindClose(hFind);
827err_noclose:
828 if (d) closedir(d);
829 CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
830 return ret;
831 }
832
757#endif 833#endif