From 0ba89ba85a58264e4b1b44a5593e84fb070126e3 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 28 Apr 2007 04:35:20 +0000 Subject: Show windows CAPI certificates. Basic implementation and functionality complete. --- ckcapi-cert.c | 90 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 31 deletions(-) (limited to 'ckcapi-cert.c') diff --git a/ckcapi-cert.c b/ckcapi-cert.c index 7436307..0605ef9 100644 --- a/ckcapi-cert.c +++ b/ckcapi-cert.c @@ -5,6 +5,14 @@ #include +#ifndef CERT_FIND_KEY_IDENTIFIER +#define CERT_FIND_KEY_IDENTIFIER 983040 +#endif + +#ifndef CERT_KEY_IDENTIFIER_PROP_ID +#define CERT_KEY_IDENTIFIER_PROP_ID 20 +#endif + typedef struct _CertObject { CkCapiObject obj; @@ -145,7 +153,8 @@ cert_bytes_attribute(void* obj, CK_ATTRIBUTE_TYPE type, CK_VOID_PTR data, CK_ULONG_PTR len) { PCCERT_CONTEXT cert = (PCCERT_CONTEXT)obj; - + DWORD err; + ASSERT(sizeof(CK_ULONG) == sizeof(DWORD)); ASSERT(obj); @@ -161,27 +170,49 @@ cert_bytes_attribute(void* obj, CK_ATTRIBUTE_TYPE type, */ case CKA_LABEL: { - WCHAR* utf16; + WCHAR* utf16 = NULL; + DWORD size; /* Get the UTF16 string, a worst case of twice as long as UTF8 */ - (*len) *= sizeof(WCHAR); - utf16 = _alloca(*len); + if(data) + { + size = *len * sizeof(WCHAR); + utf16 = _alloca(size); + } + if(!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, - utf16, (DWORD*)len)) + utf16, &size)) { - DWORD err = GetLastError(); + err = GetLastError(); if(err == CRYPT_E_NOT_FOUND) - utf16 = L"Unnamed Certificate"; + utf16 = L""; else return ckcapi_winerr_to_ckr(err); } - /* Convert the data into the buffer */ - if(!WideCharToMultiByte(CP_UTF8, 0, utf16, -1, data, *len, "?", NULL)) - return ckcapi_winerr_to_ckr(GetLastError()); - return CKR_OK; + if(utf16) + { + /* Always have a default name */ + if(!utf16[0]) + { + utf16 = L"Unnamed Certificate"; + size = wcslen(utf16) * 2; + } + + /* Convert the data into the buffer */ + *len = WideCharToMultiByte(CP_UTF8, 0, utf16, size / sizeof(WCHAR), + data, *len, NULL, NULL); + if(!*len) + return ckcapi_winerr_to_ckr(GetLastError()); + } + else + { + /* Just return an appropriate allocation length */ + *len = (size / sizeof(WCHAR)) + sizeof(WCHAR); + } + } - break; + return CKR_OK; /* * A byte array unique to this certificate. The CKA_ID of @@ -191,17 +222,16 @@ cert_bytes_attribute(void* obj, CK_ATTRIBUTE_TYPE type, * We use CAPI's CERT_KEY_IDENTIFIER_PROP_ID property directly. */ case CKA_ID: - { - if(!CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, + if(!CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, data, (DWORD*)len)) - { - DWORD err = GetLastError(); - if(err == CRYPT_E_NOT_FOUND) - return CKR_ATTRIBUTE_TYPE_INVALID; - return ckcapi_winerr_to_ckr(err); - } + { + err = GetLastError(); + if(err == CRYPT_E_NOT_FOUND) + return CKR_ATTRIBUTE_TYPE_INVALID; + return ckcapi_winerr_to_ckr(err); } - break; + return CKR_OK; + /* * DER-encoding of the certificate subject name. @@ -234,17 +264,15 @@ cert_bytes_attribute(void* obj, CK_ATTRIBUTE_TYPE type, * &size); */ case CKA_SERIAL_NUMBER: + if(!CryptEncodeObject(X509_ASN_ENCODING, X509_MULTI_BYTE_INTEGER, + &cert->pCertInfo->SerialNumber, data, len)) { - if(!CryptEncodeObject(X509_ASN_ENCODING, X509_MULTI_BYTE_INTEGER, - &cert->pCertInfo->SerialNumber, data, len)) - { - DWORD err = GetLastError(); - if(err == ERROR_FILE_NOT_FOUND) - return CKR_GENERAL_ERROR; - return ckcapi_winerr_to_ckr(err); - } + err = GetLastError(); + if(err == ERROR_FILE_NOT_FOUND) + return CKR_GENERAL_ERROR; + return ckcapi_winerr_to_ckr(err); } - break; + return CKR_OK; /* * BER-encoding of the full certificate. @@ -469,7 +497,7 @@ ckcapi_cert_find_in_store(CkCapiSession* sess, const char* store_name, if(ckcapi_object_data_match(&objdata, match, count)) { - ret = register_cert_object(sess, store, cert, &obj); + ret = register_cert_object(sess, store_name, cert, &obj); if(ret != CKR_OK) break; -- cgit v1.2.3