From 31366290fcfbb7b51332e41755ba3f0c4b01084f Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 28 Apr 2007 22:39:24 +0000 Subject: A complete but slow implementation for certificate listing. --- ckcapi-cert.c | 86 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 31 deletions(-) (limited to 'ckcapi-cert.c') diff --git a/ckcapi-cert.c b/ckcapi-cert.c index 0605ef9..672e189 100644 --- a/ckcapi-cert.c +++ b/ckcapi-cert.c @@ -13,15 +13,33 @@ #define CERT_KEY_IDENTIFIER_PROP_ID 20 #endif +#define USE_ENCODINGS (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING) + typedef struct _CertObject { CkCapiObject obj; const char* store; - BYTE* key_id; - DWORD key_id_len; + + /* Together these can uniquely identify a certificate */ + CRYPT_INTEGER_BLOB serial; + CERT_NAME_BLOB issuer; + + /* + * This must stay together. It comprises a unique + * key, together with the data that runs off the end. + */ + int otype; + BYTE cert_data[1]; } CertObject; +typedef struct _CertUnique +{ + int otype; + BYTE key[1]; +} +CertUnique; + static CK_RV copy_static_data(CK_VOID_PTR val, CK_ULONG_PTR len, CK_VOID_PTR data, DWORD cb) @@ -364,8 +382,8 @@ cert_load(CkCapiObject* obj, CkCapiObjectData* objdata) { CertObject* cobj = (CertObject*)obj; HCERTSTORE store; + CERT_INFO info; PCCERT_CONTEXT cert; - CRYPT_HASH_BLOB blob; ASSERT(cobj); ASSERT(objdata); @@ -375,13 +393,17 @@ cert_load(CkCapiObject* obj, CkCapiObjectData* objdata) if(!store) return ckcapi_winerr_to_ckr(GetLastError()); - ASSERT(cobj->key_id); - ASSERT(cobj->key_id_len); - blob.pbData = cobj->key_id; - blob.cbData = cobj->key_id_len; + ASSERT(cobj->issuer.pbData); + ASSERT(cobj->issuer.cbData); + ASSERT(cobj->serial.pbData); + ASSERT(cobj->serial.cbData); + + /* Setup our search */ + memset(&info, 0, sizeof(info)); + memcpy(&info.SerialNumber, &cobj->serial, sizeof(info.SerialNumber)); + memcpy(&info.Issuer, &cobj->issuer, sizeof(info.Issuer)); - cert = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - 0, CERT_FIND_KEY_IDENTIFIER, &blob, NULL); + cert = CertGetSubjectCertificateFromStore(store, USE_ENCODINGS, &info); CertCloseStore(store, 0); @@ -422,36 +444,38 @@ register_cert_object(CkCapiSession* sess, const char* store, PCCERT_CONTEXT cert { CertObject* cobj; CK_RV ret; - DWORD len; - - if(!CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &len)) - { - DBG(("cannot get certificate key identifier: %d", GetLastError())); - return CKR_ATTRIBUTE_TYPE_INVALID; - } + size_t len; + + /* We save the Issuer and SerialNumber for identification later */ + len = cert->pCertInfo->SerialNumber.cbData + + cert->pCertInfo->Issuer.cbData; + + /* Add one in case null termination is needed */ + len++; cobj = calloc(sizeof(CertObject) + len, 1); if(!cobj) return CKR_HOST_MEMORY; - /* Store keyid in allocated area after CertObject */ - cobj->key_id = (BYTE*)(cobj + 1); - cobj->key_id_len = len; - - if(!CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, - cobj->key_id, &(cobj->key_id_len))) - { - DBG(("cannot read certificate key identifier: %d", GetLastError())); - free(cobj); - return CKR_ATTRIBUTE_TYPE_INVALID; - } - + cobj->otype = OBJECT_CERT; cobj->store = store; + cobj->obj.id = 0; - cobj->obj.unique_key = cobj->key_id; - cobj->obj.unique_len = cobj->key_id_len; + cobj->obj.unique_key = UNIQUE_KEY_AT(cobj, otype); + cobj->obj.unique_len = UNIQUE_KEY_VAR_LEN(cobj, otype, cert_data, len); cobj->obj.obj_funcs = cert_object_vtable; - cobj->obj.data_funcs = cert_objdata_vtable; + + /* Copy Issuer data in */ + cobj->issuer.cbData = cert->pCertInfo->Issuer.cbData; + cobj->issuer.pbData = cobj->cert_data; + memcpy(cobj->issuer.pbData, cert->pCertInfo->Issuer.pbData, + cobj->issuer.cbData); + + /* Copy Serial Number data in */ + cobj->serial.cbData = cert->pCertInfo->SerialNumber.cbData; + cobj->serial.pbData = cobj->cert_data + cobj->issuer.cbData; + memcpy(cobj->serial.pbData, cert->pCertInfo->SerialNumber.pbData, + cobj->serial.cbData); ret = ckcapi_object_register(sess, &(cobj->obj)); if(ret != CKR_OK) -- cgit v1.2.3