Bear Giles wrote: > > > I'll dig out the code. It was largely based around the PKCS#11 > > functionality but with an OpenSSL flavour. That is you have a load of > > objects each of which is a set of attributes. You can then lookup based > > on exact matches of each attribute. > > This is "query by example." It has some benefits, but can be a real > pain to implement. >
Yes I noticed that :-) Its what PKCS#11 uses and it was *almost* what OpenSSL could use. I was originally thinking in terms of a database looking up based on matches on one attribute (whichever matched an index or would likely result in the smallest list) and then running a generic matching function to prune the rest. I realised OpenSSL only really needs single matching for just about everything. > > One problem was that it returned matching entries as STACK_OF. That > > would work for small numbers of matches but would be awkward for huge > > databases with large numbers of matches for which some kind of "get > > first n matching" and "get next n matching" (with n >=1) might be more > > appropriate. > > One classic approach is to have all lookup functions return a > list of unique keys. The caller then requests each object individually > via a lookup that guarantees uniqueness. Uniqueness is easy to guarantee > on any hashed or relational store - make it the primary key! > > A good candidate for this is the issuer-and-serial-number hash. (The > full 20 bytes, not a 4 byte variant.) Even if you base64-encode it so > the keys will be 7-bit safe, you're only talking about 28 bytes per key. > An earlier attempt used a hash of the entire certificate which, if it isn't unique would be the least of your worries... In any case the problem with returning a list is the amount of work that might be involved in satisfying a huge query. If it were simply a matter of space then returning keys would indeed be OK. > > I'd got one of the databases partly going which was a simple memory > > based database. > > If I have an API, I could probably knock out a simple Berkerley DB 1.x > store for certs and private keys pretty quickly, complete with dynamic > library binding. This is good enough for a single user, with multiple > users you would want to go to 2.x with transaction handling. > > The schema I had in mind was: > > certs: > > key: > char iands[28]; // base64 encoded SHA-1 hash of issuer DN + SN > > data: > struct { > char version[2]; // { 0, 0 } > char state; // V)alid, E)xpired, R)evoked, other? > char dateRevoked[16]; // YYYYMMDDHHMMSS, GMT > // maybe a list of hashes, for efficienciency? > char cert[0]; // ASN.1 encoded cert > }; > > the date is split out, not time_t, because this is Y2038 safe and > eliminates byte ordering issues. > > private keys: > > key: > char kid[28]; // base-64 encoded SHA-1 hash of public key > > data: > struct { > char version[2]; // { 0, 0 } > char cert[0]; // ASN.1 encoded key, normally PKCS8 > } > > The Cert API could be: > > struct CertDB { > int (*close)(CertDB *); > > int (*store)(CertDB *, const X509 *x); > > int (*revoke)(CertDB *, const char *iands); > > int (*remove)(CertDB *, const char *iands); > > X509 (*lookup)(CertDB *, const char *iands); > char (*getStatus)(CertDB *, const char *iands); > char (*getDateRevoked)(CertDB *, const char *iands); > > int (*findBySubject)(CertDB *, const X509_NAME *, char **results); > int (*findByIssuer)(CertDB *, const X509_NAME *, char **results); > int (*findBySubjectHash)(CertDB *, const char *, char **results); > int (*findByIssuerHash)(CertDB *, const char *, char **results); > int (*findByKeyID)(CertDB *, const char *, char **results); > > int (*listRevoked)(CertDB *, char **results); > > int (*expire)(CertDB *); > }; > typedef struct CertDB CertDB; > > CertDB * certdb_open(parameters to be determined...) > That's the kind of thing I looked at when I started on a revision ages ago. One problem with that is how to add additional lookup methods when they are needed without breaking existing code. For general OpenSSL use quite a few other lookup types would be needed anyway such as lookup by email address, issuer and serial number etc. Additional info would also need to be added to certificates such as trust settings and S/MIME capabilities, though that's partly covered by the X509_TRUSTED stuff. Steve. -- Dr Stephen N. Henson. http://www.drh-consultancy.demon.co.uk/ Personal Email: [EMAIL PROTECTED] Senior crypto engineer, Gemplus: http://www.gemplus.com/ Core developer of the OpenSSL project: http://www.openssl.org/ Business Email: [EMAIL PROTECTED] PGP key: via homepage. ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]