*BIG* verify code reorganisation.
[openssl.git] / crypto / x509 / by_dir.c
index 6676a2e4042ae17dcb85295f59f85eb198f88cf5..cac64a6f40451dfd47d08f1bc88f1970abaca2df 100644 (file)
@@ -1,5 +1,5 @@
 /* crypto/x509/by_dir.c */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
  * This package is an SSL implementation written
 #include <stdio.h>
 #include <time.h>
 #include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 
 #include "cryptlib.h"
-#include "lhash.h"
-#include "x509.h"
-#include "pem.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef MAC_OS_pre_X
+# include <stat.h>
+#else
+# include <sys/stat.h>
+#endif
+
+#include <openssl/lhash.h>
+#include <openssl/x509.h>
 
 typedef struct lookup_dir_st
        {
@@ -76,21 +83,13 @@ typedef struct lookup_dir_st
        int num_dirs_alloced;
        } BY_DIR;
 
-#ifndef NOPROTO
-static int dir_ctrl(X509_LOOKUP *ctx,int cmd,char *argp,long argl,char **ret);
+static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
+       char **ret);
 static int new_dir(X509_LOOKUP *lu);
 static void free_dir(X509_LOOKUP *lu);
-static int add_cert_dir(BY_DIR *ctx,char *dir,int type);
+static int add_cert_dir(BY_DIR *ctx,const char *dir,int type);
 static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name,
        X509_OBJECT *ret);
-#else
-static int dir_ctrl();
-static int new_dir();
-static void free_dir();
-static int add_cert_dir();
-static int get_cert_by_subject();
-#endif
-
 X509_LOOKUP_METHOD x509_dir_lookup=
        {
        "Load certs from files in a directory",
@@ -105,17 +104,13 @@ X509_LOOKUP_METHOD x509_dir_lookup=
        NULL,                   /* get_by_alias */
        };
 
-X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir()
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
        {
        return(&x509_dir_lookup);
        }
 
-static int dir_ctrl(ctx,cmd,argp,argl,retp)
-X509_LOOKUP *ctx;
-int cmd;
-long argl;
-char *argp;
-char **retp;
+static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
+            char **retp)
        {
        int ret=0;
        BY_DIR *ld;
@@ -147,16 +142,15 @@ char **retp;
        return(ret);
        }
 
-static int new_dir(lu)
-X509_LOOKUP *lu;
+static int new_dir(X509_LOOKUP *lu)
        {
        BY_DIR *a;
 
-       if ((a=(BY_DIR *)Malloc(sizeof(BY_DIR))) == NULL)
+       if ((a=(BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
                return(0);
        if ((a->buffer=BUF_MEM_new()) == NULL)
                {
-               Free(a);
+               OPENSSL_free(a);
                return(0);
                }
        a->num_dirs=0;
@@ -167,32 +161,32 @@ X509_LOOKUP *lu;
        return(1);
        }
 
-static void free_dir(lu)
-X509_LOOKUP *lu;
+static void free_dir(X509_LOOKUP *lu)
        {
        BY_DIR *a;
        int i;
 
        a=(BY_DIR *)lu->method_data;
        for (i=0; i<a->num_dirs; i++)
-               if (a->dirs[i] != NULL) Free(a->dirs[i]);
-       if (a->dirs != NULL) Free(a->dirs);
-       if (a->dirs_type != NULL) Free(a->dirs_type);
+               if (a->dirs[i] != NULL) OPENSSL_free(a->dirs[i]);
+       if (a->dirs != NULL) OPENSSL_free(a->dirs);
+       if (a->dirs_type != NULL) OPENSSL_free(a->dirs_type);
        if (a->buffer != NULL) BUF_MEM_free(a->buffer);
-       Free(a);
+       OPENSSL_free(a);
        }
 
-static int add_cert_dir(ctx,dir, type)
-BY_DIR *ctx;
-char *dir;
-int type;
+static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
        {
        int j,len;
        int *ip;
-       char *s,*ss,*p;
+       const char *s,*ss,*p;
        char **pp;
 
-       if (dir == NULL) return(0);
+       if (dir == NULL || !*dir)
+           {
+           X509err(X509_F_ADD_CERT_DIR,X509_R_INVALID_DIRECTORY);
+           return 0;
+           }
 
        s=dir;
        p=s;
@@ -210,9 +204,9 @@ int type;
                        if (ctx->num_dirs_alloced < (ctx->num_dirs+1))
                                {
                                ctx->num_dirs_alloced+=10;
-                               pp=(char **)Malloc(ctx->num_dirs_alloced*
+                               pp=(char **)OPENSSL_malloc(ctx->num_dirs_alloced*
                                        sizeof(char *));
-                               ip=(int *)Malloc(ctx->num_dirs_alloced*
+                               ip=(int *)OPENSSL_malloc(ctx->num_dirs_alloced*
                                        sizeof(int));
                                if ((pp == NULL) || (ip == NULL))
                                        {
@@ -224,14 +218,14 @@ int type;
                                memcpy(ip,ctx->dirs_type,(ctx->num_dirs_alloced-10)*
                                        sizeof(int));
                                if (ctx->dirs != NULL)
-                                       Free((char *)ctx->dirs);
+                                       OPENSSL_free(ctx->dirs);
                                if (ctx->dirs_type != NULL)
-                                       Free((char *)ctx->dirs_type);
+                                       OPENSSL_free(ctx->dirs_type);
                                ctx->dirs=pp;
                                ctx->dirs_type=ip;
                                }
                        ctx->dirs_type[ctx->num_dirs]=type;
-                       ctx->dirs[ctx->num_dirs]=(char *)Malloc((unsigned int)len+1);
+                       ctx->dirs[ctx->num_dirs]=(char *)OPENSSL_malloc((unsigned int)len+1);
                        if (ctx->dirs[ctx->num_dirs] == NULL) return(0);
                        strncpy(ctx->dirs[ctx->num_dirs],ss,(unsigned int)len);
                        ctx->dirs[ctx->num_dirs][len]='\0';
@@ -243,28 +237,50 @@ int type;
        return(1);
        }
 
-static int get_cert_by_subject(xl,type,name,ret)
-X509_LOOKUP *xl;
-int type;
-X509_NAME *name;
-X509_OBJECT *ret;
+static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
+            X509_OBJECT *ret)
        {
        BY_DIR *ctx;
-       X509 st_x509;
-       X509_CINF st_x509_cinf;
+       union   {
+               struct  {
+                       X509 st_x509;
+                       X509_CINF st_x509_cinf;
+                       } x509;
+               struct  {
+                       X509_CRL st_crl;
+                       X509_CRL_INFO st_crl_info;
+                       } crl;
+               } data;
        int ok=0;
        int i,j,k;
        unsigned long h;
        BUF_MEM *b=NULL;
        struct stat st;
        X509_OBJECT stmp,*tmp;
+       const char *postfix="";
 
        if (name == NULL) return(0);
 
-       st_x509.cert_info= &st_x509_cinf;
-       st_x509_cinf.subject=name;
-       stmp.data.x509= &st_x509;
        stmp.type=type;
+       if (type == X509_LU_X509)
+               {
+               data.x509.st_x509.cert_info= &data.x509.st_x509_cinf;
+               data.x509.st_x509_cinf.subject=name;
+               stmp.data.x509= &data.x509.st_x509;
+               postfix="";
+               }
+       else if (type == X509_LU_CRL)
+               {
+               data.crl.st_crl.crl= &data.crl.st_crl_info;
+               data.crl.st_crl_info.issuer=name;
+               stmp.data.crl= &data.crl.st_crl;
+               postfix="r";
+               }
+       else
+               {
+               X509err(X509_F_GET_CERT_BY_SUBJECT,X509_R_WRONG_LOOKUP_TYPE);
+               goto finish;
+               }
 
        if ((b=BUF_MEM_new()) == NULL)
                {
@@ -277,7 +293,7 @@ X509_OBJECT *ret;
        h=X509_NAME_hash(name);
        for (i=0; i<ctx->num_dirs; i++)
                {
-               j=strlen(ctx->dirs[i])+1+8+6+1;
+               j=strlen(ctx->dirs[i])+1+8+6+1+1;
                if (!BUF_MEM_grow(b,j))
                        {
                        X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE);
@@ -286,28 +302,43 @@ X509_OBJECT *ret;
                k=0;
                for (;;)
                        {
-                       sprintf(b->data,"%s/%08lx.%d",ctx->dirs[i],h,k);
+                       sprintf(b->data,"%s/%08lx.%s%d",ctx->dirs[i],h,
+                               postfix,k);
                        k++;
                        if (stat(b->data,&st) < 0)
                                break;
                        /* found one. */
-                       if ((X509_load_cert_file(xl,b->data,
-                               ctx->dirs_type[i])) == 0)
+                       if (type == X509_LU_X509)
+                               {
+                               if ((X509_load_cert_file(xl,b->data,
+                                       ctx->dirs_type[i])) == 0)
                                        break;
+                               }
+                       else if (type == X509_LU_CRL)
+                               {
+                               if ((X509_load_crl_file(xl,b->data,
+                                       ctx->dirs_type[i])) == 0)
+                                       break;
+                               }
+                       /* else case will caught higher up */
                        }
 
                /* we have added it to the cache so now pull
                 * it out again */
                CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
-               tmp=(X509_OBJECT *)lh_retrieve(xl->store_ctx->certs,
-                       (char *)&stmp);
+               j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp);
+               if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,i);
+               else tmp = NULL;
                CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
 
                if (tmp != NULL)
                        {
                        ok=1;
                        ret->type=tmp->type;
-                       ret->data.x509=tmp->data.x509;
+                       memcpy(&ret->data,&tmp->data,sizeof(ret->data));
+                       /* If we were going to up the reference count,
+                        * we would need to do it on a perl 'type'
+                        * basis */
        /*              CRYPTO_add(&tmp->data.x509->references,1,
                                CRYPTO_LOCK_X509);*/
                        goto finish;