In the OpenSSL API there's a method for looking up certificates/CRLs in the
given directory based on a hash.  Namely X509_LOOKUP_hash_dir() (see
x509_vfy.h).  The typical usage is to add X509_LOOKUP_hash_dir() to the
X509_STORE store and then add directories to the lookup object.  Usually
the store is used for certificate chain verification and is used as the
*trusted* store.  This is perfectly valid for looking up trusted
certificates but poses a question whether it's appropriate for CRLs.

Given that CRLs are stored in a separate directory, one would like to take
advantage of the naming scheme, where the CRL is named as follow:

<issuer hash>.r<n>

where:
- issuer hash is calculated as per "openssl crl -hash" command
- <n> is a zero-based monotonically increasing integer used to
differentiate CRLs when their hashes collide

This is where X509_LOOKUP_hash_dir() could help.  But adding that lookup to
the trusted store may subvert the chain of trust if someone inadvertently
(or deliberately) adds any certificates to the directory containing CRLs.
 Given that CRLs are not fully trusted (their signatures are verified), I
wonder whether looking them up through the trusted store "spoils" the
store.  Of course one might say that the directory where CRLs are stored
should be strictly controlled but logically the problem still exists.

In this situation, wouldn't it be useful to have a CRL specific lookup
method added?  E.g. X509_LOOKUP_CRL_hash_dir().  This would work as follows
(code reused in by_dir.c):

X509_LOOKUP_METHOD x509_crl_dir_lookup=
{
"Load CRLs from files in a directory",
new_dir, /* new */
free_dir,                    /* free */
NULL, /* init */
NULL, /* shutdown */
dir_ctrl, /* ctrl */
get_crl_by_subject, /* get_by_subject */
NULL, /* get_by_issuer_serial */
NULL, /* get_by_fingerprint */
NULL, /* get_by_alias */
};

X509_LOOKUP_METHOD *X509_LOOKUP_CRL_hash_dir(void)
{
return(&x509_crl_dir_lookup);
}

static int get_crl_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
     X509_OBJECT *ret)
{
    return X509_LU_CRL == type ?
        get_cert_by_subject(xl, type, name, ret) :
        X509_LU_FAIL;
}

This way if the verifier attempts to use this method to look up CRLs and
there are any certificates in the same directory, it'll filter them out.
 This could be used as follows (no error checking for code brevity):

X509_STORE trusted_store = X509_STORE_new();

// CA
char* ca_path = "path to CA file";
X509_LOOKUP* lookup_ca = X509_STORE_add_lookup(trusted_store,
X509_LOOKUP_file());
X509_LOOKUP_load_file(lookup_ca, ca_path, X509_FILETYPE_PEM);

// CRLs
char* crl_dir_path = "path to CRL dir";
X509_LOOKUP* lookup_crls = X509_STORE_add_lookup(trusted_store,
509_LOOKUP_CRL_hash_dir());
X509_LOOKUP_add_dir(lookup_crls, crl_dir_path, X509_FILETYPE_PEM);

// initialise X509_STORE_CTX with trusted_store to verify a certificate
chain


Maybe I'm completely missing the point.
What do you think?

Cheers,
Kris

Reply via email to