X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_cert.c;h=f50de34a065b29c5116436c28b25c0688af0d694;hp=e5e1b9998e2098be2475d29c15cabbc4119ffeeb;hb=72e442a3a66ad7b5a9f97c8b0165b6d3955ebc43;hpb=15d21c2df4335f1cea72472b8e71a76d9004d38e diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index e5e1b9998e..f50de34a06 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -1,4 +1,4 @@ -/* ssl/ssl_cert.c */ +/*! \file ssl/ssl_cert.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -57,6 +57,10 @@ */ #include +#include +#ifndef WIN32 +#include +#endif #include "objects.h" #include "bio.h" #include "pem.h" @@ -100,8 +104,7 @@ CERT *ssl_cert_new() return(ret); } -void ssl_cert_free(c) -CERT *c; +void ssl_cert_free(CERT *c) { int i; @@ -152,7 +155,7 @@ int ssl_cert_instantiate(CERT **o, CERT *d) SSLerr(SSL_F_SSL_CERT_INSTANTIATE, ERR_R_PASSED_NULL_PARAMETER); return(0); } - if (*o != NULL && d != NULL && *o != d) + if (*o != NULL && (d == NULL || *o != d)) return(1); if ((n = ssl_cert_new()) == NULL) { @@ -165,17 +168,13 @@ int ssl_cert_instantiate(CERT **o, CERT *d) return(1); } -int ssl_set_cert_type(c, type) -CERT *c; -int type; +int ssl_set_cert_type(CERT *c,int type) { c->cert_type=type; return(1); } -int ssl_verify_cert_chain(s,sk) -SSL *s; -STACK *sk; +int ssl_verify_cert_chain(SSL *s,STACK *sk) { X509 *x; int i; @@ -208,9 +207,7 @@ STACK *sk; return(i); } -static void set_client_CA_list(ca_list,list) -STACK **ca_list; -STACK *list; +static void set_client_CA_list(STACK **ca_list,STACK *list) { if (*ca_list != NULL) sk_pop_free(*ca_list,X509_NAME_free); @@ -218,8 +215,7 @@ STACK *list; *ca_list=list; } -STACK *SSL_dup_CA_list(sk) -STACK *sk; +STACK *SSL_dup_CA_list(STACK *sk) { int i; STACK *ret; @@ -238,28 +234,22 @@ STACK *sk; return(ret); } -void SSL_set_client_CA_list(s,list) -SSL *s; -STACK *list; +void SSL_set_client_CA_list(SSL *s,STACK *list) { set_client_CA_list(&(s->client_CA),list); } -void SSL_CTX_set_client_CA_list(ctx,list) -SSL_CTX *ctx; -STACK *list; +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,STACK *list) { set_client_CA_list(&(ctx->client_CA),list); } -STACK *SSL_CTX_get_client_CA_list(ctx) -SSL_CTX *ctx; +STACK *SSL_CTX_get_client_CA_list(SSL_CTX *ctx) { return(ctx->client_CA); } -STACK *SSL_get_client_CA_list(s) -SSL *s; +STACK *SSL_get_client_CA_list(SSL *s) { if (s->type == SSL_ST_CONNECT) { /* we are in the client */ @@ -278,9 +268,7 @@ SSL *s; } } -static int add_client_CA(sk,x) -STACK **sk; -X509 *x; +static int add_client_CA(STACK **sk,X509 *x) { X509_NAME *name; @@ -299,29 +287,31 @@ X509 *x; return(1); } -int SSL_add_client_CA(ssl,x) -SSL *ssl; -X509 *x; +int SSL_add_client_CA(SSL *ssl,X509 *x) { return(add_client_CA(&(ssl->client_CA),x)); } -int SSL_CTX_add_client_CA(ctx,x) -SSL_CTX *ctx; -X509 *x; +int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x) { return(add_client_CA(&(ctx->client_CA),x)); } -static int name_cmp(a,b) -X509_NAME **a,**b; +static int name_cmp(X509_NAME **a,X509_NAME **b) { return(X509_NAME_cmp(*a,*b)); } #ifndef NO_STDIO -STACK *SSL_load_client_CA_file(file) -char *file; +/*! + * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; + * it doesn't really have anything to do with clients (except that a common use + * for a stack of CAs is to send it to the client). Actually, it doesn't have + * much to do with CAs, either, since it will load any old cert. + * \param file the file containing one or more certs. + * \return a ::STACK containing the certs. + */ +STACK *SSL_load_client_CA_file(char *file) { BIO *in; X509 *x=NULL; @@ -372,3 +362,105 @@ err: } #endif +/*! + * Add a file of certs to a stack. + * \param stack the stack to add to. + * \param file the file to add from. All certs in this file that are not + * already in the stack will be added. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +int SSL_add_file_cert_subjects_to_stack(STACK *stack,const char *file) + { + BIO *in; + X509 *x=NULL; + X509_NAME *xn=NULL; + int ret=1; + int (*oldcmp)(); + + oldcmp=sk_set_cmp_func(stack,name_cmp); + + in=BIO_new(BIO_s_file_internal()); + + if (in == NULL) + { + SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in,file)) + goto err; + + for (;;) + { + if (PEM_read_bio_X509(in,&x,NULL) == NULL) + break; + if ((xn=X509_get_subject_name(x)) == NULL) goto err; + xn=X509_NAME_dup(xn); + if (xn == NULL) goto err; + if (sk_find(stack,(char *)xn) >= 0) + X509_NAME_free(xn); + else + sk_push(stack,(char *)xn); + } + + if (0) + { +err: + ret=0; + } + if(in != NULL) + BIO_free(in); + if(x != NULL) + X509_free(x); + + sk_set_cmp_func(stack,oldcmp); + + return ret; + } + +/*! + * Add a directory of certs to a stack. + * \param stack the stack to append to. + * \param dir the directory to append from. All files in this directory will be + * examined as potential certs. Any that are acceptable to + * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be + * included. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +#ifndef WIN32 + +int SSL_add_dir_cert_subjects_to_stack(STACK *stack,const char *dir) + { + DIR *d=opendir(dir); + struct dirent *dstruct; + + /* Note that a side effect is that the CAs will be sorted by name */ + if(!d) + { + SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,ERR_R_MALLOC_FAILURE); + return 0; + } + + while((dstruct=readdir(d))) + { + char buf[1024]; + + if(strlen(dir)+strlen(dstruct->d_name)+2 > sizeof buf) + { + SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG); + return 0; + } + + sprintf(buf,"%s/%s",dir,dstruct->d_name); + if(!SSL_add_file_cert_subjects_to_stack(stack,buf)) + return 0; + } + + return 1; + } + +#endif