diff options
Diffstat (limited to 'src/lib/libssl/ssl_cert.c')
-rw-r--r-- | src/lib/libssl/ssl_cert.c | 243 |
1 files changed, 87 insertions, 156 deletions
diff --git a/src/lib/libssl/ssl_cert.c b/src/lib/libssl/ssl_cert.c index b779e6bb4d..a32b2d4446 100644 --- a/src/lib/libssl/ssl_cert.c +++ b/src/lib/libssl/ssl_cert.c | |||
@@ -56,7 +56,7 @@ | |||
56 | * [including the GNU Public Licence.] | 56 | * [including the GNU Public Licence.] |
57 | */ | 57 | */ |
58 | /* ==================================================================== | 58 | /* ==================================================================== |
59 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | 59 | * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. |
60 | * | 60 | * |
61 | * Redistribution and use in source and binary forms, with or without | 61 | * Redistribution and use in source and binary forms, with or without |
62 | * modification, are permitted provided that the following conditions | 62 | * modification, are permitted provided that the following conditions |
@@ -73,12 +73,12 @@ | |||
73 | * 3. All advertising materials mentioning features or use of this | 73 | * 3. All advertising materials mentioning features or use of this |
74 | * software must display the following acknowledgment: | 74 | * software must display the following acknowledgment: |
75 | * "This product includes software developed by the OpenSSL Project | 75 | * "This product includes software developed by the OpenSSL Project |
76 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | 76 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
77 | * | 77 | * |
78 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | 78 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
79 | * endorse or promote products derived from this software without | 79 | * endorse or promote products derived from this software without |
80 | * prior written permission. For written permission, please contact | 80 | * prior written permission. For written permission, please contact |
81 | * openssl-core@OpenSSL.org. | 81 | * openssl-core@openssl.org. |
82 | * | 82 | * |
83 | * 5. Products derived from this software may not be called "OpenSSL" | 83 | * 5. Products derived from this software may not be called "OpenSSL" |
84 | * nor may "OpenSSL" appear in their names without prior written | 84 | * nor may "OpenSSL" appear in their names without prior written |
@@ -87,7 +87,7 @@ | |||
87 | * 6. Redistributions of any form whatsoever must retain the following | 87 | * 6. Redistributions of any form whatsoever must retain the following |
88 | * acknowledgment: | 88 | * acknowledgment: |
89 | * "This product includes software developed by the OpenSSL Project | 89 | * "This product includes software developed by the OpenSSL Project |
90 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | 90 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
91 | * | 91 | * |
92 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | 92 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
93 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 93 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
@@ -102,6 +102,16 @@ | |||
102 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 102 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
103 | * OF THE POSSIBILITY OF SUCH DAMAGE. | 103 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
104 | * ==================================================================== | 104 | * ==================================================================== |
105 | * | ||
106 | * This product includes cryptographic software written by Eric Young | ||
107 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
108 | * Hudson (tjh@cryptsoft.com). | ||
109 | * | ||
110 | */ | ||
111 | /* ==================================================================== | ||
112 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
113 | * ECC cipher suite support in OpenSSL originally developed by | ||
114 | * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. | ||
105 | */ | 115 | */ |
106 | 116 | ||
107 | #include <stdio.h> | 117 | #include <stdio.h> |
@@ -111,45 +121,42 @@ | |||
111 | # include <sys/types.h> | 121 | # include <sys/types.h> |
112 | #endif | 122 | #endif |
113 | 123 | ||
114 | #if !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS) && !defined(NeXT) && !defined(MAC_OS_pre_X) | 124 | #include "o_dir.h" |
115 | #include <dirent.h> | ||
116 | #endif | ||
117 | |||
118 | #if defined(WIN32) | ||
119 | #include <windows.h> | ||
120 | #include <tchar.h> | ||
121 | #endif | ||
122 | |||
123 | #ifdef NeXT | ||
124 | #include <sys/dir.h> | ||
125 | #define dirent direct | ||
126 | #endif | ||
127 | |||
128 | #include <openssl/objects.h> | 125 | #include <openssl/objects.h> |
129 | #include <openssl/bio.h> | 126 | #include <openssl/bio.h> |
130 | #include <openssl/pem.h> | 127 | #include <openssl/pem.h> |
131 | #include <openssl/x509v3.h> | 128 | #include <openssl/x509v3.h> |
129 | #ifndef OPENSSL_NO_DH | ||
130 | #include <openssl/dh.h> | ||
131 | #endif | ||
132 | #include <openssl/bn.h> | ||
132 | #include "ssl_locl.h" | 133 | #include "ssl_locl.h" |
133 | #include <openssl/fips.h> | ||
134 | 134 | ||
135 | int SSL_get_ex_data_X509_STORE_CTX_idx(void) | 135 | int SSL_get_ex_data_X509_STORE_CTX_idx(void) |
136 | { | 136 | { |
137 | static volatile int ssl_x509_store_ctx_idx= -1; | 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); | ||
138 | 141 | ||
139 | if (ssl_x509_store_ctx_idx < 0) | 142 | if (ssl_x509_store_ctx_idx < 0) |
140 | { | 143 | { |
141 | /* any write lock will do; usually this branch | 144 | CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); |
142 | * will only be taken once anyway */ | ||
143 | CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); | 145 | CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); |
146 | got_write_lock = 1; | ||
144 | 147 | ||
145 | if (ssl_x509_store_ctx_idx < 0) | 148 | if (ssl_x509_store_ctx_idx < 0) |
146 | { | 149 | { |
147 | ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index( | 150 | ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index( |
148 | 0,"SSL for verify callback",NULL,NULL,NULL); | 151 | 0,"SSL for verify callback",NULL,NULL,NULL); |
149 | } | 152 | } |
150 | |||
151 | CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); | ||
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 | |||
153 | return ssl_x509_store_ctx_idx; | 160 | return ssl_x509_store_ctx_idx; |
154 | } | 161 | } |
155 | 162 | ||
@@ -205,7 +212,6 @@ CERT *ssl_cert_dup(CERT *cert) | |||
205 | #ifndef OPENSSL_NO_DH | 212 | #ifndef OPENSSL_NO_DH |
206 | if (cert->dh_tmp != NULL) | 213 | if (cert->dh_tmp != NULL) |
207 | { | 214 | { |
208 | /* DH parameters don't have a reference count */ | ||
209 | ret->dh_tmp = DHparams_dup(cert->dh_tmp); | 215 | ret->dh_tmp = DHparams_dup(cert->dh_tmp); |
210 | if (ret->dh_tmp == NULL) | 216 | if (ret->dh_tmp == NULL) |
211 | { | 217 | { |
@@ -236,6 +242,19 @@ CERT *ssl_cert_dup(CERT *cert) | |||
236 | ret->dh_tmp_cb = cert->dh_tmp_cb; | 242 | ret->dh_tmp_cb = cert->dh_tmp_cb; |
237 | #endif | 243 | #endif |
238 | 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 | |||
239 | for (i = 0; i < SSL_PKEY_NUM; i++) | 258 | for (i = 0; i < SSL_PKEY_NUM; i++) |
240 | { | 259 | { |
241 | if (cert->pkeys[i].x509 != NULL) | 260 | if (cert->pkeys[i].x509 != NULL) |
@@ -270,7 +289,11 @@ CERT *ssl_cert_dup(CERT *cert) | |||
270 | case SSL_PKEY_DH_DSA: | 289 | case SSL_PKEY_DH_DSA: |
271 | /* We have a DH key. */ | 290 | /* We have a DH key. */ |
272 | break; | 291 | break; |
273 | 292 | ||
293 | case SSL_PKEY_ECC: | ||
294 | /* We have an ECC key */ | ||
295 | break; | ||
296 | |||
274 | default: | 297 | default: |
275 | /* Can't happen. */ | 298 | /* Can't happen. */ |
276 | SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG); | 299 | SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG); |
@@ -285,7 +308,7 @@ CERT *ssl_cert_dup(CERT *cert) | |||
285 | 308 | ||
286 | return(ret); | 309 | return(ret); |
287 | 310 | ||
288 | #ifndef OPENSSL_NO_DH /* avoid 'unreferenced label' warning if OPENSSL_NO_DH is defined */ | 311 | #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) |
289 | err: | 312 | err: |
290 | #endif | 313 | #endif |
291 | #ifndef OPENSSL_NO_RSA | 314 | #ifndef OPENSSL_NO_RSA |
@@ -296,6 +319,10 @@ err: | |||
296 | if (ret->dh_tmp != NULL) | 319 | if (ret->dh_tmp != NULL) |
297 | DH_free(ret->dh_tmp); | 320 | DH_free(ret->dh_tmp); |
298 | #endif | 321 | #endif |
322 | #ifndef OPENSSL_NO_ECDH | ||
323 | if (ret->ecdh_tmp != NULL) | ||
324 | EC_KEY_free(ret->ecdh_tmp); | ||
325 | #endif | ||
299 | 326 | ||
300 | for (i = 0; i < SSL_PKEY_NUM; i++) | 327 | for (i = 0; i < SSL_PKEY_NUM; i++) |
301 | { | 328 | { |
@@ -335,6 +362,9 @@ void ssl_cert_free(CERT *c) | |||
335 | #ifndef OPENSSL_NO_DH | 362 | #ifndef OPENSSL_NO_DH |
336 | if (c->dh_tmp) DH_free(c->dh_tmp); | 363 | if (c->dh_tmp) DH_free(c->dh_tmp); |
337 | #endif | 364 | #endif |
365 | #ifndef OPENSSL_NO_ECDH | ||
366 | if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp); | ||
367 | #endif | ||
338 | 368 | ||
339 | for (i=0; i<SSL_PKEY_NUM; i++) | 369 | for (i=0; i<SSL_PKEY_NUM; i++) |
340 | { | 370 | { |
@@ -441,6 +471,10 @@ void ssl_sess_cert_free(SESS_CERT *sc) | |||
441 | if (sc->peer_dh_tmp != NULL) | 471 | if (sc->peer_dh_tmp != NULL) |
442 | DH_free(sc->peer_dh_tmp); | 472 | DH_free(sc->peer_dh_tmp); |
443 | #endif | 473 | #endif |
474 | #ifndef OPENSSL_NO_ECDH | ||
475 | if (sc->peer_ecdh_tmp != NULL) | ||
476 | EC_KEY_free(sc->peer_ecdh_tmp); | ||
477 | #endif | ||
444 | 478 | ||
445 | OPENSSL_free(sc); | 479 | OPENSSL_free(sc); |
446 | } | 480 | } |
@@ -466,20 +500,22 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk) | |||
466 | SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB); | 500 | SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB); |
467 | return(0); | 501 | return(0); |
468 | } | 502 | } |
503 | if (s->param) | ||
504 | X509_VERIFY_PARAM_inherit(X509_STORE_CTX_get0_param(&ctx), | ||
505 | s->param); | ||
506 | #if 0 | ||
469 | if (SSL_get_verify_depth(s) >= 0) | 507 | if (SSL_get_verify_depth(s) >= 0) |
470 | X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); | 508 | X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); |
509 | #endif | ||
471 | X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s); | 510 | X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s); |
472 | 511 | ||
473 | /* We need to set the verify purpose. The purpose can be determined by | 512 | /* We need to inherit the verify parameters. These can be determined by |
474 | * the context: if its a server it will verify SSL client certificates | 513 | * the context: if its a server it will verify SSL client certificates |
475 | * or vice versa. | 514 | * or vice versa. |
476 | */ | 515 | */ |
477 | if (s->server) | ||
478 | i = X509_PURPOSE_SSL_CLIENT; | ||
479 | else | ||
480 | i = X509_PURPOSE_SSL_SERVER; | ||
481 | 516 | ||
482 | X509_STORE_CTX_purpose_inherit(&ctx, i, s->purpose, s->trust); | 517 | X509_STORE_CTX_set_default(&ctx, |
518 | s->server ? "ssl_client" : "ssl_server"); | ||
483 | 519 | ||
484 | if (s->verify_callback) | 520 | if (s->verify_callback) |
485 | X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); | 521 | X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); |
@@ -726,7 +762,7 @@ err: | |||
726 | if(x != NULL) | 762 | if(x != NULL) |
727 | X509_free(x); | 763 | X509_free(x); |
728 | 764 | ||
729 | sk_X509_NAME_set_cmp_func(stack,oldcmp); | 765 | (void)sk_X509_NAME_set_cmp_func(stack,oldcmp); |
730 | 766 | ||
731 | return ret; | 767 | return ret; |
732 | } | 768 | } |
@@ -742,157 +778,52 @@ err: | |||
742 | * certs may have been added to \c stack. | 778 | * certs may have been added to \c stack. |
743 | */ | 779 | */ |
744 | 780 | ||
745 | #ifndef OPENSSL_SYS_WIN32 | ||
746 | #ifndef OPENSSL_SYS_VMS /* XXXX This may be fixed in the future */ | ||
747 | #ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! */ | ||
748 | |||
749 | int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, | 781 | int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, |
750 | const char *dir) | 782 | const char *dir) |
751 | { | 783 | { |
752 | DIR *d; | 784 | OPENSSL_DIR_CTX *d = NULL; |
753 | struct dirent *dstruct; | 785 | const char *filename; |
754 | int ret = 0; | 786 | int ret = 0; |
755 | 787 | ||
756 | CRYPTO_w_lock(CRYPTO_LOCK_READDIR); | 788 | CRYPTO_w_lock(CRYPTO_LOCK_READDIR); |
757 | d = opendir(dir); | ||
758 | 789 | ||
759 | /* Note that a side effect is that the CAs will be sorted by name */ | 790 | /* Note that a side effect is that the CAs will be sorted by name */ |
760 | if(!d) | 791 | |
761 | { | 792 | while((filename = OPENSSL_DIR_read(&d, dir))) |
762 | SYSerr(SYS_F_OPENDIR, get_last_sys_error()); | ||
763 | ERR_add_error_data(3, "opendir('", dir, "')"); | ||
764 | SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); | ||
765 | goto err; | ||
766 | } | ||
767 | |||
768 | while((dstruct=readdir(d))) | ||
769 | { | 793 | { |
770 | char buf[1024]; | 794 | char buf[1024]; |
771 | int r; | 795 | int r; |
772 | 796 | ||
773 | if(strlen(dir)+strlen(dstruct->d_name)+2 > sizeof buf) | 797 | if(strlen(dir)+strlen(filename)+2 > sizeof buf) |
774 | { | 798 | { |
775 | SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG); | 799 | SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG); |
776 | goto err; | 800 | goto err; |
777 | } | 801 | } |
778 | 802 | ||
779 | r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,dstruct->d_name); | 803 | #ifdef OPENSSL_SYS_VMS |
780 | if (r <= 0 || r >= sizeof buf) | 804 | r = BIO_snprintf(buf,sizeof buf,"%s%s",dir,filename); |
805 | #else | ||
806 | r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,filename); | ||
807 | #endif | ||
808 | if (r <= 0 || r >= (int)sizeof(buf)) | ||
781 | goto err; | 809 | goto err; |
782 | if(!SSL_add_file_cert_subjects_to_stack(stack,buf)) | 810 | if(!SSL_add_file_cert_subjects_to_stack(stack,buf)) |
783 | goto err; | 811 | goto err; |
784 | } | 812 | } |
785 | ret = 1; | ||
786 | |||
787 | err: | ||
788 | if (d) closedir(d); | ||
789 | CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); | ||
790 | return ret; | ||
791 | } | ||
792 | |||
793 | #endif | ||
794 | #endif | ||
795 | |||
796 | #else /* OPENSSL_SYS_WIN32 */ | ||
797 | |||
798 | #if defined(_WIN32_WCE) | ||
799 | # ifndef UNICODE | ||
800 | # error "WinCE comes in UNICODE flavor only..." | ||
801 | # endif | ||
802 | # if _WIN32_WCE<101 && !defined(OPENSSL_NO_MULTIBYTE) | ||
803 | # define OPENSSL_NO_MULTIBYTE | ||
804 | # endif | ||
805 | # ifndef FindFirstFile | ||
806 | # define FindFirstFile FindFirstFileW | ||
807 | # endif | ||
808 | # ifndef FindNextFile | ||
809 | # define FindNextFile FindNextFileW | ||
810 | # endif | ||
811 | #endif | ||
812 | |||
813 | int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, | ||
814 | const char *dir) | ||
815 | { | ||
816 | WIN32_FIND_DATA FindFileData; | ||
817 | HANDLE hFind; | ||
818 | int ret = 0; | ||
819 | TCHAR *wdir = NULL; | ||
820 | size_t i,len_0 = strlen(dir)+1; /* len_0 accounts for trailing 0 */ | ||
821 | char buf[1024],*slash; | ||
822 | |||
823 | if (len_0 > (sizeof(buf)-14)) /* 14 is just some value... */ | ||
824 | { | ||
825 | SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG); | ||
826 | return ret; | ||
827 | } | ||
828 | |||
829 | CRYPTO_w_lock(CRYPTO_LOCK_READDIR); | ||
830 | |||
831 | if (sizeof(TCHAR) != sizeof(char)) | ||
832 | { | ||
833 | wdir = (TCHAR *)malloc(len_0*sizeof(TCHAR)); | ||
834 | if (wdir == NULL) | ||
835 | goto err_noclose; | ||
836 | #ifndef OPENSSL_NO_MULTIBYTE | ||
837 | if (!MultiByteToWideChar(CP_ACP,0,dir,len_0, | ||
838 | (WCHAR *)wdir,len_0)) | ||
839 | #endif | ||
840 | for (i=0;i<len_0;i++) wdir[i]=(TCHAR)dir[i]; | ||
841 | |||
842 | hFind = FindFirstFile(wdir, &FindFileData); | ||
843 | } | ||
844 | else hFind = FindFirstFile((const TCHAR *)dir, &FindFileData); | ||
845 | 813 | ||
846 | /* Note that a side effect is that the CAs will be sorted by name */ | 814 | if (errno) |
847 | if(hFind == INVALID_HANDLE_VALUE) | ||
848 | { | 815 | { |
849 | SYSerr(SYS_F_OPENDIR, get_last_sys_error()); | 816 | SYSerr(SYS_F_OPENDIR, get_last_sys_error()); |
850 | ERR_add_error_data(3, "opendir('", dir, "')"); | 817 | ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); |
851 | SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); | 818 | SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); |
852 | goto err_noclose; | 819 | goto err; |
853 | } | 820 | } |
854 | 821 | ||
855 | strncpy(buf,dir,sizeof(buf)); /* strcpy is safe too... */ | ||
856 | buf[len_0-1]='/'; /* no trailing zero! */ | ||
857 | slash=buf+len_0; | ||
858 | |||
859 | do { | ||
860 | const TCHAR *fnam=FindFileData.cFileName; | ||
861 | size_t flen_0=_tcslen(fnam)+1; | ||
862 | |||
863 | if (flen_0 > (sizeof(buf)-len_0)) | ||
864 | { | ||
865 | SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG); | ||
866 | goto err; | ||
867 | } | ||
868 | /* else strcpy would be safe too... */ | ||
869 | |||
870 | if (sizeof(TCHAR) != sizeof(char)) | ||
871 | { | ||
872 | #ifndef OPENSSL_NO_MULTIBYTE | ||
873 | if (!WideCharToMultiByte(CP_ACP,0, | ||
874 | (WCHAR *)fnam,flen_0, | ||
875 | slash,sizeof(buf)-len_0, | ||
876 | NULL,0)) | ||
877 | #endif | ||
878 | for (i=0;i<flen_0;i++) slash[i]=(char)fnam[i]; | ||
879 | } | ||
880 | else strncpy(slash,(const char *)fnam,sizeof(buf)-len_0); | ||
881 | |||
882 | if(!SSL_add_file_cert_subjects_to_stack(stack,buf)) | ||
883 | goto err; | ||
884 | } | ||
885 | while (FindNextFile(hFind, &FindFileData) != FALSE); | ||
886 | ret = 1; | 822 | ret = 1; |
887 | 823 | ||
888 | err: | 824 | err: |
889 | FindClose(hFind); | 825 | if (d) OPENSSL_DIR_end(&d); |
890 | err_noclose: | ||
891 | if (wdir != NULL) | ||
892 | free(wdir); | ||
893 | |||
894 | CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); | 826 | CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); |
895 | return ret; | 827 | return ret; |
896 | } | 828 | } |
897 | 829 | ||
898 | #endif | ||