We're getting a clash with C++ because it has a type called 'list'.
[openssl.git] / ssl / ssl_cert.c
index 8a53b9fa4b750fb9bf416c22b7f535da7ac27d3a..9fa4e616337571d3d243ebf93a8e93506b509d9d 100644 (file)
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  * ====================================================================
  */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
 
 #include <stdio.h>
 
 #include <dirent.h>
 #endif
 
+#if defined(WIN32)
+#include <windows.h>
+#endif
+
 #ifdef NeXT
 #include <sys/dir.h>
 #define dirent direct
@@ -190,8 +199,8 @@ CERT *ssl_cert_dup(CERT *cert)
 #ifndef OPENSSL_NO_RSA
        if (cert->rsa_tmp != NULL)
                {
+               RSA_up_ref(cert->rsa_tmp);
                ret->rsa_tmp = cert->rsa_tmp;
-               CRYPTO_add(&ret->rsa_tmp->references, 1, CRYPTO_LOCK_RSA);
                }
        ret->rsa_tmp_cb = cert->rsa_tmp_cb;
 #endif
@@ -230,6 +239,15 @@ CERT *ssl_cert_dup(CERT *cert)
        ret->dh_tmp_cb = cert->dh_tmp_cb;
 #endif
 
+#ifndef OPENSSL_NO_ECDH
+       if (cert->ecdh_tmp)
+               {
+               EC_KEY_up_ref(cert->ecdh_tmp);
+               ret->ecdh_tmp = cert->ecdh_tmp;
+               }
+       ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
+#endif
+
        for (i = 0; i < SSL_PKEY_NUM; i++)
                {
                if (cert->pkeys[i].x509 != NULL)
@@ -264,7 +282,11 @@ CERT *ssl_cert_dup(CERT *cert)
                        case SSL_PKEY_DH_DSA:
                                /* We have a DH key. */
                                break;
-                               
+
+                       case SSL_PKEY_ECC:
+                               /* We have an ECC key */
+                               break;
+
                        default:
                                /* Can't happen. */
                                SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
@@ -290,6 +312,10 @@ err:
        if (ret->dh_tmp != NULL)
                DH_free(ret->dh_tmp);
 #endif
+#ifndef OPENSSL_NO_ECDH
+       if (ret->ecdh_tmp != NULL)
+               EC_KEY_free(ret->ecdh_tmp);
+#endif
 
        for (i = 0; i < SSL_PKEY_NUM; i++)
                {
@@ -329,6 +355,9 @@ void ssl_cert_free(CERT *c)
 #ifndef OPENSSL_NO_DH
        if (c->dh_tmp) DH_free(c->dh_tmp);
 #endif
+#ifndef OPENSSL_NO_ECDH
+       if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp);
+#endif
 
        for (i=0; i<SSL_PKEY_NUM; i++)
                {
@@ -435,6 +464,10 @@ void ssl_sess_cert_free(SESS_CERT *sc)
        if (sc->peer_dh_tmp != NULL)
                DH_free(sc->peer_dh_tmp);
 #endif
+#ifndef OPENSSL_NO_ECDH
+       if (sc->peer_ecdh_tmp != NULL)
+               EC_KEY_free(sc->peer_ecdh_tmp);
+#endif
 
        OPENSSL_free(sc);
        }
@@ -455,7 +488,11 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
                return(0);
 
        x=sk_X509_value(sk,0);
-       X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk);
+       if(!X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk))
+               {
+               SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
+               return(0);
+               }
        if (SSL_get_verify_depth(s) >= 0)
                X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
        X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s);
@@ -471,10 +508,15 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
 
        X509_STORE_CTX_purpose_inherit(&ctx, i, s->purpose, s->trust);
 
-       X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
+       if (s->verify_callback)
+               X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
 
        if (s->ctx->app_verify_callback != NULL)
+#if 1 /* new with OpenSSL 0.9.7 */
+               i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 
+#else
                i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
+#endif
        else
                {
 #ifndef OPENSSL_NO_X509_VERIFY
@@ -492,12 +534,12 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
        return(i);
        }
 
-static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *list)
+static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
        {
        if (*ca_list != NULL)
                sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
 
-       *ca_list=list;
+       *ca_list=name_list;
        }
 
 STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
@@ -519,14 +561,14 @@ STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
        return(ret);
        }
 
-void SSL_set_client_CA_list(SSL *s,STACK_OF(X509_NAME) *list)
+void SSL_set_client_CA_list(SSL *s,STACK_OF(X509_NAME) *name_list)
        {
-       set_client_CA_list(&(s->client_CA),list);
+       set_client_CA_list(&(s->client_CA),name_list);
        }
 
-void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,STACK_OF(X509_NAME) *list)
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,STACK_OF(X509_NAME) *name_list)
        {
-       set_client_CA_list(&(ctx->client_CA),list);
+       set_client_CA_list(&(ctx->client_CA),name_list);
        }
 
 STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(SSL_CTX *ctx)
@@ -719,7 +761,7 @@ err:
 
 #ifndef OPENSSL_SYS_WIN32
 #ifndef OPENSSL_SYS_VMS                /* XXXX This may be fixed in the future */
-#ifndef MAC_OS_pre_X
+#ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! */
 
 int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
                                       const char *dir)
@@ -752,7 +794,7 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
                        }
                
                r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,dstruct->d_name);
-               if (r <= 0 || r >= sizeof buf)
+               if (r <= 0 || r >= (int)sizeof(buf))
                        goto err;
                if(!SSL_add_file_cert_subjects_to_stack(stack,buf))
                        goto err;
@@ -760,10 +802,88 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
        ret = 1;
 
 err:   
+       if (d) closedir(d);
        CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
        return ret;
        }
 
 #endif
 #endif
+
+#else /* OPENSSL_SYS_WIN32 */
+
+int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+                                      const char *dir)
+       {
+       WIN32_FIND_DATA FindFileData;
+       HANDLE hFind;
+       int ret = 0;
+#ifdef OPENSSL_SYS_WINCE
+       WCHAR* wdir = NULL;
+#endif
+
+       CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
+       
+#ifdef OPENSSL_SYS_WINCE
+       /* convert strings to UNICODE */
+       {
+               BOOL result = FALSE;
+               int i;
+               wdir = malloc((strlen(dir)+1)*2);
+               if (wdir == NULL)
+                       goto err_noclose;
+               for (i=0; i<(int)strlen(dir)+1; i++)
+                       wdir[i] = (short)dir[i];
+       }
+#endif
+
+#ifdef OPENSSL_SYS_WINCE
+       hFind = FindFirstFile(wdir, &FindFileData);
+#else
+       hFind = FindFirstFile(dir, &FindFileData);
+#endif
+       /* Note that a side effect is that the CAs will be sorted by name */
+       if(hFind == INVALID_HANDLE_VALUE)
+               {
+               SYSerr(SYS_F_OPENDIR, get_last_sys_error());
+               ERR_add_error_data(3, "opendir('", dir, "')");
+               SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
+               goto err_noclose;
+               }
+       
+       do 
+               {
+               char buf[1024];
+               int r;
+               
+#ifdef OPENSSL_SYS_WINCE
+               if(strlen(dir)+_tcslen(FindFileData.cFileName)+2 > sizeof buf)
+#else
+               if(strlen(dir)+strlen(FindFileData.cFileName)+2 > sizeof buf)
+#endif
+                       {
+                       SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG);
+                       goto err;
+                       }
+               
+               r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,FindFileData.cFileName);
+               if (r <= 0 || r >= sizeof buf)
+                       goto err;
+               if(!SSL_add_file_cert_subjects_to_stack(stack,buf))
+                       goto err;
+               }
+       while (FindNextFile(hFind, &FindFileData) != FALSE);
+       ret = 1;
+
+err:
+       FindClose(hFind);
+err_noclose:
+#ifdef OPENSSL_SYS_WINCE
+       if (wdir != NULL)
+               free(wdir);
+#endif
+       CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
+       return ret;
+       }
+
 #endif