diff options
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; | 
