summaryrefslogtreecommitdiff
path: root/ckcapi-cert.c
diff options
context:
space:
mode:
Diffstat (limited to 'ckcapi-cert.c')
-rw-r--r--ckcapi-cert.c90
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;