summaryrefslogtreecommitdiff
path: root/ckcapi-cert.c
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2007-04-28 22:39:24 +0000
committerStef Walter <stef@memberwebs.com>2007-04-28 22:39:24 +0000
commit31366290fcfbb7b51332e41755ba3f0c4b01084f (patch)
tree00f34d27b7d610e11b1fc71d0a45ec5af8ade028 /ckcapi-cert.c
parent0ba89ba85a58264e4b1b44a5593e84fb070126e3 (diff)
A complete but slow implementation for certificate listing.
Diffstat (limited to 'ckcapi-cert.c')
-rw-r--r--ckcapi-cert.c86
1 files changed, 55 insertions, 31 deletions
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)