I've been looking at the Java KeyStore API (which reflects the work of
a other bright people looking at the same problem) and have a revised
schema and proposed API.

SECOND PROPOSAL
---------------

The primary key is an opaque string henceforce known as the "alias".
The plugin may treat this as a primary key, but must not attempt to
interpret it as a hash, email address, keyid, serial number, etc.  
This means that all searches will be sequential scans unless a 
secondary index has been explicitly created, even for hashed or 
indexed storage mechanisms like Berkeley DB.

The attributes for each alias include:

 - key (PKCS8?)

 - certificate (X509)

 - cert chain (stack of X509, PKCS7 or PKCS12 format?)

 - creation date for entry

plus other attributes TBD, cached components, etc.  

A "KEY ENTRY" may contain a key alone (secret key), or a key and 
certificate (private key).  In the latter case, the entry should also
contain the cert chain returned from the CA.

A "CERTIFICATE ENTRY" contains a certificate alone.

The required operations are:

  int containsAlias(char *alias)
  Check if specified alias exists in the keystore

  void deleteEntry(char *alias)
  Delete the specified entry.  May fail if against plugin security policy

  Enumeration getAliases()
  List all aliases in the keystore

  X509 * getCertificate(char *alias)
  Retrieve the certificate associated with the specified alias

  char * getCertificateAlias(X509 *cert)
  Retrieve the alias of the first keystore entry whose certificate
  matches the specified certificate.

  ?? * getCertificateChain(char *alias)
  Retrieve the certificate chain associated with the specified alias

  time_t getCreationDate(char *alias)
  retrieve creation date for the entry.  This is when the entry was
  added to the keystore, not when the data itself was created.

  PKCS8 *getKey(char *alias)
  Retrieve the key associated with the specified alias

  int getSize()
  Retrieve the number of entries in the keystore

  bool isCertificateEntry(char *alias)
  return true if the entry is a CERTIFICATE ENTRY, false otherwise.

  bool isKeyEntry(char *alias)
  return true if the entry is a KEY ENTRY, false otherwise.

  void load(BIO *)
  copy BIO stream into keystore.

  void setCertificateEntry(char *alias, X509 *cert)
  associate the alias and certificate.  May merge with existing KEY ENTRY
  if the keys match.  Will overwrite existing CERTIFICATE ENTRY.

  void setKeyEntry(char *alias, PKCS8 *key, ?? *chain)
  associate the alias, key and optional cert chain.  The first cert in
  the chain is treated as the 'certificate.' entry.

  void store(BIO *)
  copy keystore into BIO stream.

(Remember that java communicates errors through exceptions - we'll need
to change the return types on most functions.)

In addition, we would define additional functions including

  Enumeration list(PATTERN *p)
  list subset of aliases which satisfy some pattern.  PATTERN would
  be like we discussed earlier - something like

    typedef struct {
          enum {
                SUBJECT,      // X509_NAME
                ISSUER,       // X509_NAME
                SERIAL,       // ASN1_INTEGER
                SHASH,        // unsigned char[] (assuming SHA1 from Gutman paper)
                IHASH,        // unsigned char[] 
                IANDSHASH,    // unsigned char[]
                CERTHASH,     // unsigned char[]
                B64SHASH,     // char *
                B64IHASH,     // char *
                B64IANDSHASH, // char *
                B64CERTHASH,  // char *
                COMMON_NAME,  // char *
                EMAIL,        // char *
          } type;
      union {
        type1 a;
        type2 b;
        ...
      } u;
    };

and others TBD.

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to