|
|
@@ -277,6 +277,8 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, |
|
|
|
int ok=0; |
|
|
|
int i,j,k; |
|
|
|
unsigned long h; |
|
|
|
unsigned long hash_array[2]; |
|
|
|
int hash_index; |
|
|
|
BUF_MEM *b=NULL; |
|
|
|
X509_OBJECT stmp,*tmp; |
|
|
|
const char *postfix=""; |
|
|
@@ -312,156 +314,161 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, |
|
|
|
|
|
|
|
ctx=(BY_DIR *)xl->method_data; |
|
|
|
|
|
|
|
h=X509_NAME_hash(name); |
|
|
|
for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) |
|
|
|
hash_array[0]=X509_NAME_hash(name); |
|
|
|
hash_array[1]=X509_NAME_hash_old(name); |
|
|
|
for (hash_index=0; hash_index < 2; ++hash_index) |
|
|
|
{ |
|
|
|
BY_DIR_ENTRY *ent; |
|
|
|
size_t idx; |
|
|
|
BY_DIR_HASH htmp, *hent; |
|
|
|
ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); |
|
|
|
j=strlen(ent->dir)+1+8+6+1+1; |
|
|
|
if (!BUF_MEM_grow(b,j)) |
|
|
|
h=hash_array[hash_index]; |
|
|
|
for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) |
|
|
|
{ |
|
|
|
OPENSSL_PUT_ERROR(X509, get_cert_by_subject, ERR_R_MALLOC_FAILURE); |
|
|
|
goto finish; |
|
|
|
} |
|
|
|
if (type == X509_LU_CRL && ent->hashes) |
|
|
|
{ |
|
|
|
htmp.hash = h; |
|
|
|
CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); |
|
|
|
if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) |
|
|
|
BY_DIR_ENTRY *ent; |
|
|
|
size_t idx; |
|
|
|
BY_DIR_HASH htmp, *hent; |
|
|
|
ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); |
|
|
|
j=strlen(ent->dir)+1+8+6+1+1; |
|
|
|
if (!BUF_MEM_grow(b,j)) |
|
|
|
{ |
|
|
|
hent = sk_BY_DIR_HASH_value(ent->hashes, idx); |
|
|
|
k = hent->suffix; |
|
|
|
OPENSSL_PUT_ERROR(X509, get_cert_by_subject, ERR_R_MALLOC_FAILURE); |
|
|
|
goto finish; |
|
|
|
} |
|
|
|
else |
|
|
|
if (type == X509_LU_CRL && ent->hashes) |
|
|
|
{ |
|
|
|
hent = NULL; |
|
|
|
k=0; |
|
|
|
} |
|
|
|
CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
k = 0; |
|
|
|
hent = NULL; |
|
|
|
} |
|
|
|
for (;;) |
|
|
|
{ |
|
|
|
char c = '/'; |
|
|
|
#ifdef OPENSSL_SYS_VMS |
|
|
|
c = ent->dir[strlen(ent->dir)-1]; |
|
|
|
if (c != ':' && c != '>' && c != ']') |
|
|
|
{ |
|
|
|
/* If no separator is present, we assume the |
|
|
|
directory specifier is a logical name, and |
|
|
|
add a colon. We really should use better |
|
|
|
VMS routines for merging things like this, |
|
|
|
but this will do for now... |
|
|
|
-- Richard Levitte */ |
|
|
|
c = ':'; |
|
|
|
htmp.hash = h; |
|
|
|
CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); |
|
|
|
if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) |
|
|
|
{ |
|
|
|
hent = sk_BY_DIR_HASH_value(ent->hashes, idx); |
|
|
|
k = hent->suffix; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
hent = NULL; |
|
|
|
k=0; |
|
|
|
} |
|
|
|
CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
c = '\0'; |
|
|
|
} |
|
|
|
#endif |
|
|
|
if (c == '\0') |
|
|
|
{ |
|
|
|
/* This is special. When c == '\0', no |
|
|
|
directory separator should be added. */ |
|
|
|
BIO_snprintf(b->data,b->max, |
|
|
|
"%s%08lx.%s%d",ent->dir,h, |
|
|
|
postfix,k); |
|
|
|
k = 0; |
|
|
|
hent = NULL; |
|
|
|
} |
|
|
|
else |
|
|
|
for (;;) |
|
|
|
{ |
|
|
|
BIO_snprintf(b->data,b->max, |
|
|
|
"%s%c%08lx.%s%d",ent->dir,c,h, |
|
|
|
postfix,k); |
|
|
|
} |
|
|
|
char c = '/'; |
|
|
|
#ifdef OPENSSL_SYS_VMS |
|
|
|
c = ent->dir[strlen(ent->dir)-1]; |
|
|
|
if (c != ':' && c != '>' && c != ']') |
|
|
|
{ |
|
|
|
/* If no separator is present, we assume the |
|
|
|
directory specifier is a logical name, and |
|
|
|
add a colon. We really should use better |
|
|
|
VMS routines for merging things like this, |
|
|
|
but this will do for now... |
|
|
|
-- Richard Levitte */ |
|
|
|
c = ':'; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
c = '\0'; |
|
|
|
} |
|
|
|
#endif |
|
|
|
if (c == '\0') |
|
|
|
{ |
|
|
|
/* This is special. When c == '\0', no |
|
|
|
directory separator should be added. */ |
|
|
|
BIO_snprintf(b->data,b->max, |
|
|
|
"%s%08lx.%s%d",ent->dir,h, |
|
|
|
postfix,k); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
BIO_snprintf(b->data,b->max, |
|
|
|
"%s%c%08lx.%s%d",ent->dir,c,h, |
|
|
|
postfix,k); |
|
|
|
} |
|
|
|
#ifndef OPENSSL_NO_POSIX_IO |
|
|
|
#ifdef _WIN32 |
|
|
|
#define stat _stat |
|
|
|
#endif |
|
|
|
{ |
|
|
|
struct stat st; |
|
|
|
if (stat(b->data,&st) < 0) |
|
|
|
break; |
|
|
|
} |
|
|
|
#endif |
|
|
|
/* found one. */ |
|
|
|
if (type == X509_LU_X509) |
|
|
|
{ |
|
|
|
if ((X509_load_cert_file(xl,b->data, |
|
|
|
ent->dir_type)) == 0) |
|
|
|
struct stat st; |
|
|
|
if (stat(b->data,&st) < 0) |
|
|
|
break; |
|
|
|
} |
|
|
|
else if (type == X509_LU_CRL) |
|
|
|
{ |
|
|
|
if ((X509_load_crl_file(xl,b->data, |
|
|
|
ent->dir_type)) == 0) |
|
|
|
break; |
|
|
|
#endif |
|
|
|
/* found one. */ |
|
|
|
if (type == X509_LU_X509) |
|
|
|
{ |
|
|
|
if ((X509_load_cert_file(xl,b->data, |
|
|
|
ent->dir_type)) == 0) |
|
|
|
break; |
|
|
|
} |
|
|
|
else if (type == X509_LU_CRL) |
|
|
|
{ |
|
|
|
if ((X509_load_crl_file(xl,b->data, |
|
|
|
ent->dir_type)) == 0) |
|
|
|
break; |
|
|
|
} |
|
|
|
/* else case will caught higher up */ |
|
|
|
k++; |
|
|
|
} |
|
|
|
/* else case will caught higher up */ |
|
|
|
k++; |
|
|
|
} |
|
|
|
|
|
|
|
/* we have added it to the cache so now pull |
|
|
|
* it out again */ |
|
|
|
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
|
|
|
tmp = NULL; |
|
|
|
if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) { |
|
|
|
tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,idx); |
|
|
|
} |
|
|
|
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
|
|
|
/* we have added it to the cache so now pull |
|
|
|
* it out again */ |
|
|
|
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
|
|
|
tmp = NULL; |
|
|
|
if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) { |
|
|
|
tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,idx); |
|
|
|
} |
|
|
|
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
|
|
|
|
|
|
|
|
|
|
|
/* If a CRL, update the last file suffix added for this */ |
|
|
|
/* If a CRL, update the last file suffix added for this */ |
|
|
|
|
|
|
|
if (type == X509_LU_CRL) |
|
|
|
{ |
|
|
|
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
|
|
|
/* Look for entry again in case another thread added |
|
|
|
* an entry first. |
|
|
|
*/ |
|
|
|
if (!hent) |
|
|
|
{ |
|
|
|
htmp.hash = h; |
|
|
|
if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) |
|
|
|
hent = sk_BY_DIR_HASH_value(ent->hashes, idx); |
|
|
|
} |
|
|
|
if (!hent) |
|
|
|
if (type == X509_LU_CRL) |
|
|
|
{ |
|
|
|
hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); |
|
|
|
hent->hash = h; |
|
|
|
hent->suffix = k; |
|
|
|
if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) |
|
|
|
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
|
|
|
/* Look for entry again in case another thread added |
|
|
|
* an entry first. |
|
|
|
*/ |
|
|
|
if (!hent) |
|
|
|
{ |
|
|
|
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
|
|
|
OPENSSL_free(hent); |
|
|
|
ok = 0; |
|
|
|
goto finish; |
|
|
|
htmp.hash = h; |
|
|
|
if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) |
|
|
|
hent = sk_BY_DIR_HASH_value(ent->hashes, idx); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (hent->suffix < k) |
|
|
|
hent->suffix = k; |
|
|
|
if (!hent) |
|
|
|
{ |
|
|
|
hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); |
|
|
|
hent->hash = h; |
|
|
|
hent->suffix = k; |
|
|
|
if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) |
|
|
|
{ |
|
|
|
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
|
|
|
OPENSSL_free(hent); |
|
|
|
ok = 0; |
|
|
|
goto finish; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (hent->suffix < k) |
|
|
|
hent->suffix = k; |
|
|
|
|
|
|
|
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
|
|
|
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (tmp != NULL) |
|
|
|
{ |
|
|
|
ok=1; |
|
|
|
ret->type=tmp->type; |
|
|
|
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; |
|
|
|
if (tmp != NULL) |
|
|
|
{ |
|
|
|
ok=1; |
|
|
|
ret->type=tmp->type; |
|
|
|
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; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
finish: |
|
|
|