Handle nicknames on certificates.

Fix bug where we weren't allocating enough space for wchar (wide, utf16, etc).
strings in ckcapi_UTF8ToWide().
This commit is contained in:
relyea%netscape.com 2005-11-16 01:17:25 +00:00
Родитель 827599e91e
Коммит a8e0c27896
2 изменённых файлов: 100 добавлений и 14 удалений

Просмотреть файл

@ -1,6 +1,7 @@
This Cryptoki module provides acces to certs and keys stored in This Cryptoki module provides acces to certs and keys stored in
Microsofts CAPI certificate store. Microsofts CAPI certificate store.
Currently this module is read only. It does not import or export CA Root trust from the CAPI.
It does not export CA Root trust from the CAPI. It does not import or export CRLs from the CAPI.
It does not export CRLs from the CAPI. It does not handle S/MIME objects (pkcs #7 in capi terms?).
It does not yet handle it's own PIN. (CAPI does all the pin prompting).

Просмотреть файл

@ -36,7 +36,7 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#ifdef DEBUG #ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: cobject.c,v $ $Revision: 1.3 $ $Date: 2005/11/15 00:13:58 $"; static const char CVS_ID[] = "@(#) $RCSfile: cobject.c,v $ $Revision: 1.4 $ $Date: 2005/11/16 01:17:25 $";
#endif /* DEBUG */ #endif /* DEBUG */
#include "ckcapi.h" #include "ckcapi.h"
@ -326,6 +326,39 @@ nss_ckcapi_GetBoolAttribute
return *(CK_BBOOL *)item.data; return *(CK_BBOOL *)item.data;
} }
/*
* get an attribute which is type CK_BBOOL.
*/
char *
nss_ckcapi_GetStringAttribute
(
CK_ATTRIBUTE_TYPE type,
CK_ATTRIBUTE *template,
CK_ULONG templateSize,
CK_RV *pError
)
{
NSSItem item;
char *str;
/* get the attribute */
*pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
if (CKR_OK != *pError) {
return (char *)NULL;
}
/* make sure it is null terminated */
str = nss_ZNEWARRAY(NULL, char, item.size+1);
if ((char *)NULL == str) {
*pError = CKR_HOST_MEMORY;
return (char *)NULL;
}
nsslibc_memcpy(str, item.data, item.size);
str[item.size] = 0;
return str;
}
/* /*
* Return the size in bytes of a wide string * Return the size in bytes of a wide string
*/ */
@ -335,7 +368,12 @@ nss_ckcapi_WideSize
LPCWSTR wide LPCWSTR wide
) )
{ {
DWORD size = wcslen(wide)+1; DWORD size;
if ((LPWSTR)NULL == wide) {
return 0;
}
size = wcslen(wide)+1;
return size*2; return size*2;
} }
@ -348,19 +386,25 @@ nss_ckcapi_WideToUTF8
LPCWSTR wide LPCWSTR wide
) )
{ {
DWORD len = nss_ckcapi_WideSize(wide); DWORD len;
DWORD size; DWORD size;
char *buf; char *buf;
if ((LPWSTR)NULL == wide) {
return (char *)NULL;
}
len = nss_ckcapi_WideSize(wide);
size = WideCharToMultiByte(CP_UTF8, 0, wide, len, NULL, 0, NULL, 0); size = WideCharToMultiByte(CP_UTF8, 0, wide, len, NULL, 0, NULL, 0);
if (size == 0) { if (size == 0) {
return NULL; return (char *)NULL;
} }
buf = nss_ZNEWARRAY(NULL, char, size); buf = nss_ZNEWARRAY(NULL, char, size);
size = WideCharToMultiByte(CP_UTF8, 0, wide, len, buf, size, NULL, 0); size = WideCharToMultiByte(CP_UTF8, 0, wide, len, buf, size, NULL, 0);
if (size == 0) { if (size == 0) {
nss_ZFreeIf(buf); nss_ZFreeIf(buf);
return NULL; return (char *)NULL;
} }
return buf; return buf;
} }
@ -377,6 +421,12 @@ nss_ckcapi_WideDup
DWORD len = nss_ckcapi_WideSize(wide); DWORD len = nss_ckcapi_WideSize(wide);
LPWSTR buf; LPWSTR buf;
if ((LPWSTR)NULL == wide) {
return (LPWSTR)NULL;
}
len = nss_ckcapi_WideSize(wide);
buf = (LPWSTR) nss_ZNEWARRAY(NULL, char, len); buf = (LPWSTR) nss_ZNEWARRAY(NULL, char, len);
if ((LPWSTR) NULL == buf) { if ((LPWSTR) NULL == buf) {
return buf; return buf;
@ -398,15 +448,21 @@ nss_ckcapi_UTF8ToWide
DWORD len = strlen(buf)+1; DWORD len = strlen(buf)+1;
LPWSTR wide; LPWSTR wide;
if ((char *)NULL == buf) {
return (LPWSTR) NULL;
}
len = strlen(buf)+1;
size = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0); size = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
if (size == 0) { if (size == 0) {
return NULL; return (LPWSTR) NULL;
} }
wide = (LPWSTR)nss_ZNEWARRAY(NULL, char, size); wide = nss_ZNEWARRAY(NULL, WCHAR, size);
size = MultiByteToWideChar(CP_UTF8, 0, buf, len, wide, size); size = MultiByteToWideChar(CP_UTF8, 0, buf, len, wide, size);
if (size == 0) { if (size == 0) {
nss_ZFreeIf(wide); nss_ZFreeIf(wide);
return NULL; return (LPWSTR) NULL;
} }
return wide; return wide;
} }
@ -1253,7 +1309,7 @@ ckcapi_cert_getPrivateKeyInfo
if (!rc) { if (!rc) {
return (CRYPT_KEY_PROV_INFO *)NULL; return (CRYPT_KEY_PROV_INFO *)NULL;
} }
prov = (CRYPT_KEY_PROV_INFO *)nss_ZNEWARRAY(NULL, char, size); prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
if ((CRYPT_KEY_PROV_INFO *)prov == NULL) { if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
return (CRYPT_KEY_PROV_INFO *) NULL; return (CRYPT_KEY_PROV_INFO *) NULL;
} }
@ -1286,7 +1342,7 @@ ckcapi_cert_getProvInfo
if (!rc) { if (!rc) {
return (CRYPT_KEY_PROV_INFO *)NULL; return (CRYPT_KEY_PROV_INFO *)NULL;
} }
prov = (CRYPT_KEY_PROV_INFO *)nss_ZNEWARRAY(NULL, char, size); prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
if ((CRYPT_KEY_PROV_INFO *)prov == NULL) { if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
return (CRYPT_KEY_PROV_INFO *) NULL; return (CRYPT_KEY_PROV_INFO *) NULL;
} }
@ -1732,9 +1788,11 @@ nss_ckcapi_CreateCertificate
PCCERT_CONTEXT certContext = NULL; PCCERT_CONTEXT certContext = NULL;
PCCERT_CONTEXT storedCertContext = NULL; PCCERT_CONTEXT storedCertContext = NULL;
CRYPT_KEY_PROV_INFO *prov_info = NULL; CRYPT_KEY_PROV_INFO *prov_info = NULL;
char *nickname = NULL;
HCERTSTORE hStore = 0; HCERTSTORE hStore = 0;
DWORD msError = 0; DWORD msError = 0;
PRBool hasID; PRBool hasID;
CK_RV dummy;
BOOL rc; BOOL rc;
*pError = nss_ckcapi_GetAttribute(CKA_VALUE, pTemplate, *pError = nss_ckcapi_GetAttribute(CKA_VALUE, pTemplate,
@ -1790,6 +1848,7 @@ nss_ckcapi_CreateCertificate
*pError = CKR_DEVICE_ERROR; *pError = CKR_DEVICE_ERROR;
goto loser; goto loser;
} }
/* does it look like a CA */ /* does it look like a CA */
} else if (ckcapi_cert_isCA(certContext)) { } else if (ckcapi_cert_isCA(certContext)) {
storeStr = ckcapi_cert_isRoot(certContext) ? "CA" : "Root"; storeStr = ckcapi_cert_isRoot(certContext) ? "CA" : "Root";
@ -1801,6 +1860,32 @@ nss_ckcapi_CreateCertificate
storeStr = "CA"; storeStr = "CA";
} }
/* get the nickname, not an error if we can't find it */
nickname = nss_ckcapi_GetStringAttribute(CKA_LABEL, pTemplate,
ulAttributeCount, &dummy);
if (nickname) {
LPWSTR nicknameUTF16 = NULL;
CRYPT_DATA_BLOB nicknameBlob;
nicknameUTF16 = nss_ckcapi_UTF8ToWide(nickname);
nss_ZFreeIf(nickname);
nickname = NULL;
if ((LPWSTR)NULL == nicknameUTF16) {
*pError = CKR_HOST_MEMORY;
goto loser;
}
nicknameBlob.cbData = nss_ckcapi_WideSize(nicknameUTF16);
nicknameBlob.pbData = (BYTE *)nicknameUTF16;
rc = CertSetCertificateContextProperty(certContext,
CERT_FRIENDLY_NAME_PROP_ID, 0, &nicknameBlob);
nss_ZFreeIf(nicknameUTF16);
if (!rc) {
msError = GetLastError();
*pError = CKR_DEVICE_ERROR;
goto loser;
}
}
hStore = CertOpenSystemStore((HCRYPTPROV) NULL, storeStr); hStore = CertOpenSystemStore((HCRYPTPROV) NULL, storeStr);
if (0 == hStore) { if (0 == hStore) {
msError = GetLastError(); msError = GetLastError();
@ -1946,7 +2031,7 @@ ckcapi_buildPrivateKeyBlob
goto loser; goto loser;
} }
dataSize = (modSize*4)+(modSize/2) + sizeof(CAPI_RSA_KEY_BLOB); dataSize = (modSize*4)+(modSize/2) + sizeof(CAPI_RSA_KEY_BLOB);
keyBlobData = (CAPI_RSA_KEY_BLOB *)nss_ZNEWARRAY(NULL, char, dataSize); keyBlobData = (CAPI_RSA_KEY_BLOB *)nss_ZAlloc(NULL, dataSize);
if ((CAPI_RSA_KEY_BLOB *)NULL == keyBlobData) { if ((CAPI_RSA_KEY_BLOB *)NULL == keyBlobData) {
error = CKR_HOST_MEMORY; error = CKR_HOST_MEMORY;
goto loser; goto loser;