diff options
author | Stef Walter <stef@memberwebs.com> | 2007-04-28 04:35:20 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2007-04-28 04:35:20 +0000 |
commit | 0ba89ba85a58264e4b1b44a5593e84fb070126e3 (patch) | |
tree | fa4179ef40460b8276de649ce297930584ad946b /ckcapi-cert.c | |
parent | 4928a4bff079c140d261cb3fefdc07c60c0bdebf (diff) |
Show windows CAPI certificates. Basic implementation and functionality complete.
Diffstat (limited to 'ckcapi-cert.c')
-rw-r--r-- | ckcapi-cert.c | 90 |
1 files changed, 59 insertions, 31 deletions
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 <wincrypt.h> +#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; |