13 #if defined( INC_ALL )
31 #define BLOBHEADER_SIZE 8
39 #define MAX_BUFFER_SIZE 1024
43 #if defined( _MSC_VER )
44 #pragma message( " Building with CAPI device interface enabled." )
53 #define _WIN32_WINNT 0x0500
76 #define HCRYPTPROV_NONE 0
95 #define HCERTCHAINENGINE void *
96 #define USAGE_MATCH_TYPE_AND 0
97 #define USAGE_MATCH_TYPE_OR 1
98 #define CERT_COMPARE_KEY_IDENTIFIER 15
99 #define CERT_FIND_KEY_IDENTIFIER ( CERT_COMPARE_KEY_IDENTIFIER << CERT_COMPARE_SHIFT )
100 #define CERT_CHAIN_CACHE_END_CERT 0x00000001
101 #define CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 0x80000000
102 #define CRYPT_ACQUIRE_CACHE_FLAG 0x00000001
107 CERT_ENHKEY_USAGE Usage;
111 CERT_USAGE_MATCH RequestedUsage;
112 CERT_USAGE_MATCH RequestedIssuancePolicy;
113 DWORD dwUrlRetrievalTimeout;
114 BOOL fCheckRevocationFreshnessTime;
115 DWORD dwRevocationFreshnessTime;
116 } CERT_CHAIN_PARA, *PCERT_CHAIN_PARA;
122 } CERT_TRUST_STATUS, *PCERT_TRUST_STATUS;
125 PCCERT_CONTEXT pCertContext;
126 CERT_TRUST_STATUS TrustStatus;
127 void *pRevocationInfo;
128 void *pIssuanceUsage;
129 void *pApplicationUsage;
130 LPCWSTR pwszExtendedErrorInfo;
131 } CERT_CHAIN_ELEMENT, *PCERT_CHAIN_ELEMENT;
134 PCTL_ENTRY pCtlEntry;
135 PCCTL_CONTEXT pCtlContext;
136 } CERT_TRUST_LIST_INFO, *PCERT_TRUST_LIST_INFO;
139 CERT_TRUST_STATUS TrustStatus;
141 PCERT_CHAIN_ELEMENT *rgpElement;
142 PCERT_TRUST_LIST_INFO pTrustListInfo;
143 BOOL fHasRevocationFreshnessTime;
144 DWORD dwRevocationFreshnessTime;
145 } CERT_SIMPLE_CHAIN, *PCERT_SIMPLE_CHAIN;
148 CERT_TRUST_STATUS TrustStatus;
150 PCERT_SIMPLE_CHAIN *rgpChain;
151 DWORD cLowerQualityChainContext;
152 struct CCC **rgpLowerQualityChainContext;
153 BOOL fHasRevocationFreshnessTime;
154 DWORD dwRevocationFreshnessTime;
155 } CERT_CHAIN_CONTEXT;
156 typedef const CERT_CHAIN_CONTEXT *PCCERT_CHAIN_CONTEXT;
170 #define NULL_HINSTANCE ( HINSTANCE ) NULL
172 static HINSTANCE hCryptoAPI = NULL_HINSTANCE;
173 static HINSTANCE hAdvAPI32 = NULL_HINSTANCE;
175 typedef BOOL ( WINAPI *CERTADDCERTIFICATETOSTORE )( HCERTSTORE hCertStore,
176 PCCERT_CONTEXT pCertContext,
DWORD dwAddDisposition,
177 PCCERT_CONTEXT *ppStoreContext );
178 typedef BOOL ( WINAPI *CERTADDENCODEDCERTIFICATETOSTORE )( HCERTSTORE hCertStore,
179 DWORD dwCertEncodingType,
const BYTE *pbCertEncoded,
181 PCCERT_CONTEXT *ppCertContext );
182 typedef BOOL ( WINAPI *CERTCLOSESTORE )( HCERTSTORE hCertStore,
DWORD dwFlags );
183 typedef PCCERT_CONTEXT ( WINAPI *CERTCREATECERTIFICATECONTEXT )(
DWORD dwCertEncodingType,
184 const BYTE *pbCertEncoded,
DWORD cbCertEncoded );
185 typedef BOOL ( WINAPI *CERTDELETECERTIFICATEFROMSTORE )( PCCERT_CONTEXT pCertContext );
186 typedef PCCERT_CONTEXT ( WINAPI *CERTFINDCERTIFICATEINSTORE )( HCERTSTORE hCertStore,
188 DWORD dwFindType,
const void *pvFindPara,
189 PCCERT_CONTEXT pPrevCertContext );
190 typedef VOID ( WINAPI *CERTFREECERTIFICATECHAIN )( PCCERT_CHAIN_CONTEXT pChainContext );
191 typedef BOOL ( WINAPI *CERTFREECERTIFICATECONTEXT )( PCCERT_CONTEXT pCertContext );
192 typedef BOOL ( WINAPI *CERTGETCERTIFICATECHAIN )( HCERTCHAINENGINE hChainEngine,
193 PCCERT_CONTEXT pCertContext, LPFILETIME pTime,
194 HCERTSTORE hAdditionalStore, PCERT_CHAIN_PARA pChainPara,
196 PCCERT_CHAIN_CONTEXT *ppChainContext );
197 typedef BOOL ( WINAPI *CERTGETCERTIFICATECONTEXTPROPERTY )( PCCERT_CONTEXT pCertContext,
198 DWORD dwPropId,
void *pvData,
DWORD *pcbData );
199 typedef PCCERT_CONTEXT ( WINAPI *CERTGETSUBJECTCERTIFICATEFROMSTORE )( HCERTSTORE hCertStore,
200 DWORD dwCertEncodingType, PCERT_INFO pCertId );
201 typedef BOOL ( WINAPI *CERTSETCERTIFICATEPROPERTY )( PCCERT_CONTEXT pCertContext,
203 typedef HCERTSTORE ( WINAPI *CERTOPENSYSTEMSTORE )(
HCRYPTPROV hprov,
204 LPCSTR szSubsystemProtocol );
206 typedef BOOL ( WINAPI *CRYPTACQUIRECERTIFICATEPRIVATEKEY )( PCCERT_CONTEXT pCert,
208 DWORD *pdwKeySpec,
BOOL *pfCallerFreeProv );
211 typedef BOOL ( WINAPI *CRYPTCREATEHASH )(
HCRYPTPROV hProv, ALG_ID Algid,
213 typedef BOOL ( WINAPI *CRYPTDECRYPT )( HCRYPTKEY hKey, HCRYPTHASH hHash,
BOOL Final,
215 typedef BOOL ( WINAPI *CRYPTDESTROYHASH )( HCRYPTHASH hHash );
216 typedef BOOL ( WINAPI *CRYPTDESTROYKEY )( HCRYPTKEY hKey );
217 typedef BOOL ( WINAPI *CRYPTENCRYPT )( HCRYPTKEY hKey, HCRYPTHASH hHash,
BOOL Final,
219 typedef BOOL ( WINAPI *CRYPTEXPORTKEY )( HCRYPTKEY hKey, HCRYPTKEY hExpKey,
221 typedef BOOL ( WINAPI *CRYPTFINDCERTIFICATEKEYPROVINFO )( PCCERT_CONTEXT pCert,
226 typedef BOOL ( WINAPI *CRYPTGETKEYPARAM )( HCRYPTKEY hKey,
DWORD dwParam,
BYTE* pbData,
231 HCRYPTKEY* phUserKey );
232 typedef BOOL ( WINAPI *CRYPTHASHDATA )( HCRYPTHASH hHash,
BYTE *pbData,
DWORD dwDataLen,
237 typedef BOOL ( WINAPI *CRYPTSETHASHPARAM )( HCRYPTHASH hHash,
DWORD dwParam,
239 typedef BOOL ( WINAPI *CRYPTSETKEYPARAM )( HCRYPTKEY hKey,
DWORD dwParam,
241 typedef BOOL ( WINAPI *CRYPTSIGNHASH )( HCRYPTHASH hHash,
DWORD dwKeySpec,
245 static CERTADDCERTIFICATETOSTORE pCertAddCertificateContextToStore = NULL;
246 static CERTADDENCODEDCERTIFICATETOSTORE pCertAddEncodedCertificateToStore = NULL;
247 static CERTCREATECERTIFICATECONTEXT pCertCreateCertificateContext = NULL;
248 static CERTDELETECERTIFICATEFROMSTORE pCertDeleteCertificateFromStore = NULL;
249 static CERTCLOSESTORE pCertCloseStore = NULL;
250 static CERTFINDCERTIFICATEINSTORE pCertFindCertificateInStore = NULL;
251 static CERTFREECERTIFICATECHAIN pCertFreeCertificateChain = NULL;
252 static CERTFREECERTIFICATECONTEXT pCertFreeCertificateContext = NULL;
253 static CERTGETCERTIFICATECHAIN pCertGetCertificateChain = NULL;
254 static CERTGETCERTIFICATECONTEXTPROPERTY pCertGetCertificateContextProperty = NULL;
255 static CERTGETSUBJECTCERTIFICATEFROMSTORE pCertGetSubjectCertificateFromStore = NULL;
256 static CERTSETCERTIFICATEPROPERTY pCertSetCertificateContextProperty = NULL;
257 static CERTOPENSYSTEMSTORE pCertOpenSystemStore = NULL;
259 static CRYPTACQUIRECERTIFICATEPRIVATEKEY pCryptAcquireCertificatePrivateKey = NULL;
260 static CRYPTACQUIRECONTEXTA pCryptAcquireContextA = NULL;
261 static CRYPTCREATEHASH pCryptCreateHash = NULL;
262 static CRYPTDECRYPT pCryptDecrypt = NULL;
263 static CRYPTDESTROYHASH pCryptDestroyHash = NULL;
264 static CRYPTDESTROYKEY pCryptDestroyKey = NULL;
265 static CRYPTENCRYPT pCryptEncrypt = NULL;
266 static CRYPTEXPORTKEY pCryptExportKey = NULL;
267 static CRYPTFINDCERTIFICATEKEYPROVINFO pCryptFindCertificateKeyProvInfo = NULL;
268 static CRYPTGENKEY pCryptGenKey = NULL;
269 static CRYPTGENRANDOM pCryptGenRandom = NULL;
270 static CRYPTGETKEYPARAM pCryptGetKeyParam = NULL;
271 static CRYPTGETPROVPARAM pCryptGetProvParam = NULL;
272 static CRYPTGETUSERKEY pCryptGetUserKey = NULL;
273 static CRYPTHASHDATA pCryptHashData = NULL;
274 static CRYPTIMPORTKEY pCryptImportKey = NULL;
275 static CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
276 static CRYPTSETHASHPARAM pCryptSetHashParam = NULL;
277 static CRYPTSETKEYPARAM pCryptSetKeyParam = NULL;
278 static CRYPTSIGNHASH pCryptSignHash = NULL;
285 if( hCryptoAPI != NULL_HINSTANCE )
289 if( ( hAdvAPI32 = GetModuleHandle(
"AdvAPI32.DLL" ) ) == NULL )
291 if( ( hCryptoAPI = DynamicLoad(
"Crypt32.dll" ) ) == NULL_HINSTANCE )
295 pCryptAcquireCertificatePrivateKey = ( CRYPTACQUIRECERTIFICATEPRIVATEKEY ) GetProcAddress( hCryptoAPI,
"CryptAcquireCertificatePrivateKey" );
296 pCryptAcquireContextA = ( CRYPTACQUIRECONTEXTA ) GetProcAddress( hAdvAPI32,
"CryptAcquireContextA" );
297 pCryptCreateHash = ( CRYPTCREATEHASH ) GetProcAddress( hAdvAPI32,
"CryptCreateHash" );
298 pCryptDecrypt = ( CRYPTDECRYPT ) GetProcAddress( hAdvAPI32,
"CryptDecrypt" );
299 pCryptDestroyHash = ( CRYPTDESTROYHASH ) GetProcAddress( hAdvAPI32,
"CryptDestroyHash" );
300 pCryptDestroyKey = ( CRYPTDESTROYKEY ) GetProcAddress( hAdvAPI32,
"CryptDestroyKey" );
301 pCryptEncrypt = ( CRYPTENCRYPT ) GetProcAddress( hAdvAPI32,
"CryptEncrypt" );
302 pCryptExportKey = ( CRYPTEXPORTKEY ) GetProcAddress( hAdvAPI32,
"CryptExportKey" );
303 pCryptFindCertificateKeyProvInfo = ( CRYPTFINDCERTIFICATEKEYPROVINFO ) GetProcAddress( hCryptoAPI,
"CryptFindCertificateKeyProvInfo" );
304 pCryptGenKey = ( CRYPTGENKEY ) GetProcAddress( hAdvAPI32,
"CryptGenKey" );
305 pCryptGenRandom = ( CRYPTGENRANDOM ) GetProcAddress( hAdvAPI32,
"CryptGenRandom" );
306 pCryptGetKeyParam = ( CRYPTGETKEYPARAM ) GetProcAddress( hAdvAPI32,
"CryptGetKeyParam" );
307 pCryptGetProvParam = ( CRYPTGETPROVPARAM ) GetProcAddress( hAdvAPI32,
"CryptGetProvParam" );
308 pCryptGetUserKey = ( CRYPTGETUSERKEY ) GetProcAddress( hAdvAPI32,
"CryptGetUserKey" );
309 pCryptHashData = ( CRYPTHASHDATA ) GetProcAddress( hAdvAPI32,
"CryptHashData" );
310 pCryptImportKey = ( CRYPTIMPORTKEY ) GetProcAddress( hAdvAPI32,
"CryptImportKey" );
311 pCryptReleaseContext = ( CRYPTRELEASECONTEXT ) GetProcAddress( hAdvAPI32,
"CryptReleaseContext" );
312 pCryptSetHashParam = ( CRYPTSETHASHPARAM ) GetProcAddress( hAdvAPI32,
"CryptSetHashParam" );
313 pCryptSetKeyParam = ( CRYPTSETKEYPARAM ) GetProcAddress( hAdvAPI32,
"CryptSetKeyParam" );
314 pCryptSignHash = ( CRYPTSIGNHASH ) GetProcAddress( hAdvAPI32,
"CryptSignHashA" );
317 pCertAddCertificateContextToStore = ( CERTADDCERTIFICATETOSTORE ) GetProcAddress( hCryptoAPI,
"CertAddCertificateContextToStore" );
318 pCertAddEncodedCertificateToStore = ( CERTADDENCODEDCERTIFICATETOSTORE ) GetProcAddress( hCryptoAPI,
"CertAddEncodedCertificateToStore" );
319 pCertCreateCertificateContext = ( CERTCREATECERTIFICATECONTEXT ) GetProcAddress( hCryptoAPI,
"CertCreateCertificateContext" );
320 pCertDeleteCertificateFromStore = ( CERTDELETECERTIFICATEFROMSTORE ) GetProcAddress( hCryptoAPI,
"CertDeleteCertificateFromStore" );
321 pCertCloseStore = ( CERTCLOSESTORE ) GetProcAddress( hCryptoAPI,
"CertCloseStore" );
322 pCertFindCertificateInStore = ( CERTFINDCERTIFICATEINSTORE ) GetProcAddress( hCryptoAPI,
"CertFindCertificateInStore" );
323 pCertFreeCertificateChain = ( CERTFREECERTIFICATECHAIN ) GetProcAddress( hCryptoAPI,
"CertFreeCertificateChain" );
324 pCertFreeCertificateContext = ( CERTFREECERTIFICATECONTEXT ) GetProcAddress( hCryptoAPI,
"CertFreeCertificateContext" );
325 pCertGetCertificateChain = ( CERTGETCERTIFICATECHAIN ) GetProcAddress( hCryptoAPI,
"CertGetCertificateChain" );
326 pCertGetCertificateContextProperty = ( CERTGETCERTIFICATECONTEXTPROPERTY ) GetProcAddress( hCryptoAPI,
"CertGetCertificateContextProperty" );
327 pCertGetSubjectCertificateFromStore = ( CERTGETSUBJECTCERTIFICATEFROMSTORE ) GetProcAddress( hCryptoAPI,
"CertGetSubjectCertificateFromStore" );
328 pCertSetCertificateContextProperty = ( CERTSETCERTIFICATEPROPERTY ) GetProcAddress( hCryptoAPI,
"CertSetCertificateContextProperty" );
329 pCertOpenSystemStore = ( CERTOPENSYSTEMSTORE ) GetProcAddress( hCryptoAPI,
"CertOpenSystemStoreA" );
332 if( pCertAddCertificateContextToStore == NULL || \
333 pCertAddEncodedCertificateToStore == NULL ||
334 pCertCreateCertificateContext == NULL ||
335 pCertDeleteCertificateFromStore == NULL ||
336 pCertCloseStore == NULL || pCertFindCertificateInStore == NULL ||
337 pCertFreeCertificateChain == NULL ||
338 pCertFreeCertificateContext == NULL ||
339 pCertGetCertificateChain == NULL ||
340 pCertGetCertificateContextProperty == NULL ||
341 pCertGetSubjectCertificateFromStore == NULL ||
342 pCertSetCertificateContextProperty == NULL ||
343 pCertOpenSystemStore == NULL ||
344 pCryptAcquireCertificatePrivateKey == NULL ||
345 pCryptAcquireContextA == NULL || pCryptCreateHash == NULL ||
346 pCryptDecrypt == NULL || pCryptEncrypt == NULL ||
347 pCryptExportKey == NULL || pCryptDestroyHash == NULL ||
348 pCryptDestroyKey == NULL ||
349 pCryptFindCertificateKeyProvInfo == NULL || pCryptGenKey == NULL ||
350 pCryptGenRandom == NULL || pCryptGetKeyParam == NULL ||
351 pCryptGetProvParam == NULL || pCryptGetUserKey == NULL ||
352 pCryptHashData == NULL || pCryptImportKey == NULL ||
353 pCryptReleaseContext == NULL || pCryptSetHashParam == NULL ||
354 pCryptSetKeyParam == NULL || pCryptSignHash == NULL )
357 DynamicUnload( hCryptoAPI );
358 hCryptoAPI = NULL_HINSTANCE;
367 if( hCryptoAPI != NULL_HINSTANCE )
368 DynamicUnload( hCryptoAPI );
369 hCryptoAPI = NULL_HINSTANCE;
390 *cryptoapiInfoPtrPtr = NULL;
396 return( cryptStatus );
400 (
void ** ) &deviceInfo,
403 return( cryptStatus );
404 *iCryptDevice = iLocalDevice;
405 *cryptoapiInfoPtrPtr = deviceInfo->deviceCryptoAPI;
412 static int mapError(
CRYPTOAPI_INFO *cryptoapiInfo,
const int defaultError )
430 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorCode, 0,
432 for( messageLength = strlen( errorInfo->errorString );
433 messageLength > 0 && \
434 ( errorInfo->errorString[ messageLength - 1 ] ==
'\n' || \
435 errorInfo->errorString[ messageLength - 1 ] ==
'\r' );
443 case CRYPT_E_UNKNOWN_ALGO:
449 case ERROR_MORE_DATA:
452 case ERROR_NO_MORE_ITEMS:
462 case ERROR_NOT_ENOUGH_MEMORY:
466 case CRYPT_E_SECURITY_SETTINGS:
470 case NTE_BAD_SIGNATURE:
473 case CRYPT_E_NO_MATCH:
474 case CRYPT_E_NOT_FOUND:
475 case NTE_KEYSET_NOT_DEF:
477 case NTE_PROV_DLL_NOT_FOUND:
478 case NTE_PROV_TYPE_NO_MATCH:
479 case NTE_PROV_TYPE_NOT_DEF:
483 return( defaultError );
494 status = getContextDeviceInfo( contextInfoPtr->
objectHandle,
495 &iCryptDevice, &cryptoapiInfo );
498 status = mapError( cryptoapiInfo, defaultError );
528 status = mapValue( cryptAlgo, &value, algoMapTbl,
542 if( ( ALG_ID ) algoMapTbl[ i ].
destination == algID )
549 return( algoMapTbl[ i ].source );
556 const int srcRequiredLen )
561 for( i = 0; i < srcLen; i++ )
564 if( srcLen < srcRequiredLen )
570 for( i = 0; i < srcRequiredLen - srcLen; i++ )
580 static int createExportKey(
const HCRYPTPROV hProv, HCRYPTKEY *hPrivateKey,
581 int *privateKeySize )
583 BLOBHEADER *blobHeaderPtr;
584 RSAPUBKEY *pubKeyPtr;
585 BYTE keyBlob[ 1024 + 8 ], *keyBlobPtr;
586 DWORD keyBlobLen = 1024;
610 if( !pCryptGenKey( hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, hPrivateKey ) || \
611 !pCryptExportKey( *hPrivateKey, 0, PRIVATEKEYBLOB, 0, keyBlob, &keyBlobLen ) || \
612 !pCryptDestroyKey( *hPrivateKey ) )
616 blobHeaderPtr = ( BLOBHEADER * ) keyBlob;
617 if( blobHeaderPtr->bType != PRIVATEKEYBLOB || \
618 blobHeaderPtr->bVersion != CUR_BLOB_VERSION || \
619 blobHeaderPtr->aiKeyAlg != CALG_RSA_KEYX )
621 pCryptDestroyKey( *hPrivateKey );
628 bitLen16 = ( pubKeyPtr->bitlen / 16 );
629 pubKeyPtr->pubexp = 1;
630 keyBlobPtr = keyBlob + 20 + ( pubKeyPtr->bitlen / 8 ) + bitLen16 + bitLen16;
634 memset( keyBlobPtr, 0, bitLen16 - 1 );
635 keyBlobPtr += bitLen16 - 1;
637 memset( keyBlobPtr, 0, bitLen16 - 1 );
638 keyBlobPtr += bitLen16 - 1;
641 keyBlobPtr += bitLen16;
643 memset( keyBlobPtr, 0, bitLen16 - 1 );
644 keyBlobPtr += bitLen16 - 1;
647 result = pCryptImportKey( hProv, keyBlob, keyBlobLen, 0, 0, hPrivateKey );
649 *privateKeySize = pubKeyPtr->bitlen / 8;
652 zeroise( keyBlob, keyBlobLen );
659 static int importPlainKey(
const HCRYPTPROV hProv,
660 const HCRYPTKEY hPrivateKey,
661 const int privateKeySize, HCRYPTKEY *hSessionKey,
663 const int keyDataSize,
void *errorInfoPtr )
665 BLOBHEADER *blobHeaderPtr;
666 BYTE keyBlob[ 1024 + 8 ], *keyBlobPtr;
670 const int blobSize =
sizeof( BLOBHEADER ) +
sizeof( ALG_ID ) + privateKeySize;
683 memset( keyBlob, 0, 1024 );
684 algID = cryptlibToCapiID( cryptAlgo );
689 blobHeaderPtr = ( BLOBHEADER * ) keyBlob;
690 blobHeaderPtr->bType = SIMPLEBLOB;
691 blobHeaderPtr->bVersion = CUR_BLOB_VERSION;
692 blobHeaderPtr->aiKeyAlg = algID;
696 *dwPtr = CALG_RSA_KEYX;
700 keyBlobPtr = keyBlob + 12;
701 for( i = keyDataSize - 1; i >= 0; i-- )
702 *keyBlobPtr++ = keyData[ i ];
704 memset( keyBlobPtr, 2, privateKeySize - ( keyDataSize + 2 ) );
707 result = pCryptImportKey( hProv, keyBlob, blobSize, hPrivateKey, 0, hSessionKey );
718 const HCRYPTKEY hKey,
BYTE *
n,
int *nLen,
721 BLOBHEADER *blobHeaderPtr;
722 RSAPUBKEY *pubKeyPtr;
734 if( !pCryptExportKey( hKey, 0, PUBLICKEYBLOB, 0, keyBlob, &keyBlobLen ) )
738 blobHeaderPtr = ( BLOBHEADER * ) keyBlob;
739 if( blobHeaderPtr->bType != PUBLICKEYBLOB || \
740 blobHeaderPtr->bVersion != CUR_BLOB_VERSION )
745 exponent = pubKeyPtr->pubexp;
747 length = pubKeyPtr->bitlen / 8;
748 while( length > 0 && nPtr[ length ] == 0 )
750 copyMPI( n, nPtr, length, length );
752 length = ( exponent <= 0xFF ) ? 1 : \
753 ( exponent <= 0xFFFF ) ? 2 : \
754 ( exponent <= 0xFFFFFFL ) ? 3 : 4;
756 memcpy( e, buffer + ( 4 - length ), length );
763 const HCRYPTKEY hKey,
776 status = getPubkeyComponents( cryptoapiInfo, hKey, n, &nLen, e, &eLen );
811 DEBUG_DIAG((
"Failed to load CryptoAPI public key data" ));
825 const HCRYPTKEY hKey,
836 PCCERT_CONTEXT *pCertContextPtr )
838 PCCERT_CONTEXT pCertContext = NULL;
845 CERT_RDN_ATTR certRDNAttr;
848 memset( &certRDNAttr, 0,
sizeof( CERT_RDN_ATTR ) );
849 certRDNAttr.pszObjId = szOID_COMMON_NAME;
850 certRDNAttr.dwValueType = CERT_RDN_ANY_TYPE;
851 certRDNAttr.Value.pbData = (
void * ) keyID;
853 memset( &certRDN, 0,
sizeof( CERT_RDN ) );
854 certRDN.rgRDNAttr = &certRDNAttr;
855 certRDN.cRDNAttr = 1;
857 pCertFindCertificateInStore( cryptoapiInfo->
hCertStore,
858 X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_ATTR,
866 CERT_RDN_ATTR certRDNAttr;
872 memset( &certRDNAttr, 0,
sizeof( CERT_RDN_ATTR ) );
873 certRDNAttr.pszObjId = szOID_RSA_emailAddr ;
874 certRDNAttr.dwValueType = CERT_RDN_ANY_TYPE;
875 certRDNAttr.Value.pbData = (
void * ) keyID;
877 memset( &certRDN, 0,
sizeof( CERT_RDN ) );
878 certRDN.rgRDNAttr = &certRDNAttr;
879 certRDN.cRDNAttr = 1;
881 pCertFindCertificateInStore( cryptoapiInfo->
hCertStore,
882 X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_ATTR,
887 case CRYPT_IKEYID_CERTID:
889 CRYPT_DATA_BLOB cryptDataBlob;
891 memset( &cryptDataBlob, 0,
sizeof( CRYPT_DATA_BLOB ) );
892 cryptDataBlob.pbData = (
void * ) keyID;
895 pCertFindCertificateInStore( cryptoapiInfo->
hCertStore,
896 X509_ASN_ENCODING, 0, CERT_FIND_SHA1_HASH,
897 &cryptDataBlob, NULL );
901 case CRYPT_IKEYID_KEYID:
906 certID.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
907 certID.KeyId.pbData = (
void * ) keyID;
910 pCertFindCertificateInStore( cryptoapiInfo->
hCertStore,
911 X509_ASN_ENCODING, 0, CERT_FIND_CERT_ID,
914 CRYPT_HASH_BLOB hashBlob;
916 hashBlob.pbData = (
void * ) keyID;
919 pCertFindCertificateInStore( cryptoapiInfo->
hCertStore,
920 X509_ASN_ENCODING, 0, CERT_FIND_KEY_IDENTIFIER,
926 case CRYPT_IKEYID_ISSUERANDSERIALNUMBER:
933 memset( &certInfo, 0,
sizeof(
CERT_INFO ) );
934 sMemConnect( &stream, keyID, keyIDlength );
935 readSequence( &stream, NULL );
936 status = getStreamObjectLength( &stream, &length );
938 status = sMemGetDataBlock( &stream, &dataPtr, length );
941 sMemDisconnect( &stream );
944 certInfo.Issuer.pbData = dataPtr;
945 certInfo.Issuer.cbData =
length;
946 sSkip( &stream, length );
947 status = getStreamObjectLength( &stream, &length );
949 status = sMemGetDataBlock( &stream, &dataPtr, length );
952 certInfo.SerialNumber.pbData = dataPtr;
953 certInfo.SerialNumber.cbData =
length;
954 status = sSkip( &stream, length );
956 sMemDisconnect( &stream );
960 pCertGetSubjectCertificateFromStore( cryptoapiInfo->
hCertStore,
961 X509_ASN_ENCODING, &certInfo );
968 if( pCertContext == NULL )
970 *pCertContextPtr = pCertContext;
977 const PCCERT_CONTEXT pCertContext,
978 PCCERT_CHAIN_CONTEXT *pChainContextPtr )
980 CERT_CHAIN_PARA chainPara;
981 CERT_USAGE_MATCH certUsage;
982 CERT_ENHKEY_USAGE enhkeyUsage;
983 PCCERT_CHAIN_CONTEXT pChainContext;
986 *pChainContextPtr = NULL;
990 memset( &enhkeyUsage, 0,
sizeof( CERT_ENHKEY_USAGE ) );
991 enhkeyUsage.cUsageIdentifier = 0;
992 enhkeyUsage.rgpszUsageIdentifier = NULL;
993 memset( &certUsage, 0,
sizeof( CERT_USAGE_MATCH ) );
994 certUsage.dwType = USAGE_MATCH_TYPE_AND;
995 certUsage.Usage = enhkeyUsage;
996 memset( &chainPara, 0,
sizeof( CERT_CHAIN_PARA ) );
997 chainPara.cbSize =
sizeof( CERT_CHAIN_PARA );
998 chainPara.RequestedUsage = certUsage;
999 if( !pCertGetCertificateChain( NULL, pCertContext, NULL, NULL, &chainPara,
1000 CERT_CHAIN_CACHE_END_CERT | \
1001 CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY,
1002 NULL, &pChainContext ) )
1004 *pChainContextPtr = pChainContext;
1011 const HCRYPTKEY hKey,
1013 PCCERT_CONTEXT *pCertContextPtr )
1015 PCCERT_CONTEXT pCertContext;
1016 CERT_PUBLIC_KEY_INFO pubKeyInfo;
1021 *pCertContextPtr = NULL;
1024 if( !pCryptExportKey( hKey, 0, PUBLICKEYBLOB, 0, keyBlob, &keyBlobLen ) )
1026 pCryptDestroyKey( hKey );
1031 memset( &pubKeyInfo, 0,
sizeof( CERT_PUBLIC_KEY_INFO ) );
1032 pubKeyInfo.Algorithm.pszObjId = isSigningKey ? \
1033 CERT_DEFAULT_OID_PUBLIC_KEY_SIGN : \
1034 CERT_DEFAULT_OID_PUBLIC_KEY_XCHG;
1035 pubKeyInfo.PublicKey.pbData = keyBlob;
1036 pubKeyInfo.PublicKey.cbData = keyBlobLen;
1038 pCertFindCertificateInStore( cryptoapiInfo->
hCertStore,
1039 X509_ASN_ENCODING, 0, CERT_FIND_PUBLIC_KEY,
1040 &pubKeyInfo, NULL );
1041 if( pCertContext == NULL )
1043 *pCertContextPtr = pCertContext;
1049 static int getPrivKeyFromCertificate(
CRYPTOAPI_INFO *cryptoapiInfo,
1050 const PCCERT_CONTEXT pCertContext,
1051 HCRYPTKEY *hKeyPtr )
1056 BOOL fCallerFreeProv;
1063 if( !pCryptAcquireCertificatePrivateKey( pCertContext,
1064 CRYPT_ACQUIRE_CACHE_FLAG, NULL,
1065 &hProv, &dwKeySpec, &fCallerFreeProv ) )
1067 if( !pCryptGetUserKey( hProv, dwKeySpec, &hKey ) )
1076 static int createPrivkeyContext(
DEVICE_INFO *deviceInfo,
1079 const HCRYPTKEY hKey,
1083 DWORD dwDataLen =
sizeof( ALG_ID );
1094 if( !pCryptGetKeyParam( hKey, KP_ALGID, (
BYTE * ) &algID, &dwDataLen,
1100 if( capabilityInfoPtr == NULL )
1106 status = createContextFromCapability( iCryptContext,
1115 (
MESSAGE_CAST ) &hKey, CRYPT_IATTRIBUTE_DEVICEOBJECT );
1128 cryptStatus = rsaSetPublicComponents( deviceInfo, *iCryptContext,
1132 &
keySize, CRYPT_IATTRIBUTE_KEYSIZE );
1140 CRYPT_IATTRIBUTE_INITIALISED );
1158 static int getCapabilities(
DEVICE_INFO *deviceInfo );
1159 static void freeCapabilities(
DEVICE_INFO *deviceInfo );
1165 static void shutdownFunction(
DEVICE_INFO *deviceInfo )
1174 pCryptReleaseContext( cryptoapiInfo->
hProv, 0 );
1178 pCertCloseStore( cryptoapiInfo->
hCertStore, 0 );
1181 cryptoapiInfo->
hProv = HCRYPTPROV_NONE;
1185 freeCapabilities( deviceInfo );
1191 const int nameLength )
1195 HCERTSTORE hCertStore;
1198 const char *keysetName = NULL;
1200 int i, driverNameLength = nameLength,
status;
1204 for( i = 1; i < nameLength - 1; i++ )
1206 if( name[ i ] ==
':' && name[ i + 1 ] ==
':' )
1208 const int keysetNameLength = nameLength - ( i + 2 );
1216 memcpy( providerNameBuffer, name, i );
1217 providerNameBuffer[ i ] =
'\0';
1218 memcpy( keysetNameBuffer, name + i + 2, keysetNameLength );
1219 keysetNameBuffer[ keysetNameLength ] =
'\0';
1220 name = providerNameBuffer;
1221 keysetName = keysetNameBuffer;
1227 if( driverNameLength == 12 && \
1228 !strnicmp(
"[Autodetect]", name, driverNameLength ) )
1230 if( CryptAcquireContextA( &hProv, keysetName, MS_ENHANCED_PROV,
1231 PROV_RSA_FULL, 0 ) )
1232 cryptoapiInfo->
hProv = hProv;
1235 if( CryptAcquireContextA( &hProv, keysetName, MS_DEF_PROV,
1236 PROV_RSA_FULL, 0 ) )
1237 cryptoapiInfo->
hProv = hProv;
1245 if( CryptAcquireContextA( &hProv, keysetName, name, PROV_RSA_FULL, 0 ) )
1246 cryptoapiInfo->
hProv = hProv;
1251 if( !CryptGetProvParam( cryptoapiInfo->
hProv, PP_NAME,
1252 cryptoapiInfo->label, &value, 0 ) )
1255 deviceInfo->label = cryptoapiInfo->label;
1260 status = getCapabilities( deviceInfo );
1263 shutdownFunction( deviceInfo );
1268 status = createExportKey( cryptoapiInfo->
hProv,
1273 shutdownFunction( deviceInfo );
1278 hCertStore = pCertOpenSystemStore( cryptoapiInfo->
hProv,
1280 if( hCertStore == NULL )
1282 shutdownFunction( deviceInfo );
1292 static int controlFunction(
DEVICE_INFO *deviceInfo,
1308 static int getRandomFunction(
DEVICE_INFO *deviceInfo,
void *buffer,
1314 if( pCryptGenRandom( cryptoapiInfo->
hProv, length, buffer ) )
1340 static int getItemFunction(
DEVICE_INFO *deviceInfo,
1344 const void *keyID,
const int keyIDlength,
1351 PCCERT_CONTEXT pCertContext = NULL;
1352 PCCERT_CHAIN_CONTEXT pChainContext = NULL;
1353 DWORD dwKeySpec = 0;
1356 const char *label =
"Private key";
1366 if( keyIDlength == 13 && \
1367 !memcmp( keyID,
"Signature key", 13 ) )
1368 dwKeySpec = AT_SIGNATURE;
1370 if( keyIDlength == 14 && \
1371 !memcmp( keyID,
"Encryption key", 14 ) )
1372 dwKeySpec = AT_KEYEXCHANGE;
1380 dwKeySpec = AT_SIGNATURE;
1383 dwKeySpec = AT_KEYEXCHANGE;
1388 if( dwKeySpec != 0 )
1391 if( !pCryptGetUserKey( cryptoapiInfo->
hProv, dwKeySpec, &hKey ) )
1393 label = ( dwKeySpec == AT_SIGNATURE ) ? \
1394 "Signature key" :
"Encryption key";
1400 pCryptDestroyKey( hKey );
1409 strlcpy_s( auxInfo, *auxInfoLength, label );
1410 *auxInfoLength = strlen( label );
1411 pCryptDestroyKey( hKey );
1416 status = getCertificateFromKey( cryptoapiInfo, hKey,
1417 ( flags & KEYMGMT_FLAG_USAGE_SIGN ) ? \
1424 status = capiToCryptlibContext( cryptoapiInfo, hKey,
1426 pCryptDestroyKey( hKey );
1432 assert( !( flags & KEYMGMT_FLAG_LABEL_ONLY ) );
1436 status = getCertificate( cryptoapiInfo, keyIDtype, keyID, keyIDlength,
1443 if( flags & KEYMGMT_FLAG_CHECK_ONLY )
1445 pCertFreeCertificateContext( pCertContext );
1454 CERT_KEY_CONTEXT certKeyContext;
1455 DWORD certKeyContextSize =
sizeof( CERT_KEY_CONTEXT );
1457 if( !pCertGetCertificateContextProperty( pCertContext,
1458 CERT_KEY_CONTEXT_PROP_ID,
1459 &certKeyContext, &certKeyContextSize ) || \
1460 !pCryptGetUserKey( certKeyContext.hCryptProv,
1461 certKeyContext.dwKeySpec, &hKey ) )
1465 status = getPrivKeyFromCertificate( cryptoapiInfo, pCertContext,
1470 pCertFreeCertificateContext( pCertContext );
1479 status = createPrivkeyContext( deviceInfo, iCryptContext,
1480 &cryptAlgo, hKey, label );
1483 if( pCertContext != NULL )
1484 pCertFreeCertificateContext( pCertContext );
1490 if( pCertContext == NULL )
1498 status = iCryptImportCertIndirect( &iCryptCert,
1500 keyIDlength, publicComponentsOnly ? \
1523 pCertFreeCertificateContext( pCertContext );
1524 pCertFreeCertificateChain( pChainContext );
1529 const int keyTemplateCount = ( keyID == NULL ) ? 1 : 2;
1535 &pubkeyClass : &privkeyClass );
1538 if( keyIDtype == CRYPT_IKEYID_KEYID )
1539 keyTemplate[ 1 ].type =
CKA_ID;
1543 cryptStatus = findObject( deviceInfo, &hObject, keyTemplate,
1554 keyTemplate[ 0 ].pValue = (
CK_VOID_PTR ) &privkeyClass;
1555 cryptStatus = findObject( deviceInfo, &hObject, keyTemplate,
1558 return( cryptStatus );
1563 certViaPrivateKey =
TRUE;
1586 ( keyIDtype == CRYPT_IKEYID_ISSUERANDSERIALNUMBER && \
1596 cryptStatus = findObject( deviceInfo, &hObject,
1597 decryptKeyTemplate, 2 );
1601 cryptStatus = findObject( deviceInfo, &hObject,
1602 decryptKeyTemplate, 2 );
1606 return( cryptStatus );
1610 if( flags & KEYMGMT_FLAG_CHECK_ONLY )
1612 if( flags & KEYMGMT_FLAG_LABEL_ONLY )
1613 return( getObjectLabel( deviceInfo, hObject, auxInfo,
1618 keyTypeTemplate.pValue = &
keyType;
1619 C_GetAttributeValue( cryptoapiInfo->
hProv, hObject,
1620 &keyTypeTemplate, 1 );
1638 C_GetAttributeValue( cryptoapiInfo->
hProv, hObject,
1639 &keySizeTemplate, 1 );
1640 keySize = keySizeTemplate.ulValueLen;
1641 capabilityInfoPtr = findCapabilityInfo( deviceInfo->capabilityInfo,
1643 if( capabilityInfoPtr == NULL )
1666 if( privateKeyViaCert )
1670 cryptStatus = instantiateCert( deviceInfo, hCertificate,
1671 &iCryptCert,
FALSE );
1673 return( cryptStatus );
1678 cryptStatus = findCertFromObject( deviceInfo, hObject, &iCryptCert,
1680 FINDCERT_NORMAL : FINDCERT_DATAONLY );
1689 return( cryptStatus );
1709 static int setItemFunction(
DEVICE_INFO *deviceInfo,
1714 DWORD dwKeySpec = 0;
1717 int iterationCount = 0,
status;
1735 if( pCryptGetUserKey( cryptoapiInfo->
hProv, AT_KEYEXCHANGE, &hKey ) )
1737 if( isCertKey( cryptoapiInfo, hKey, iCryptCert ) )
1738 dwKeySpec = AT_KEYEXCHANGE;
1739 pCryptDestroyKey( hKey );
1743 if( pCryptGetUserKey( cryptoapiInfo->
hProv, AT_SIGNATURE, &hKey ) )
1745 if( isCertKey( cryptoapiInfo, hKey, iCryptCert ) )
1746 dwKeySpec = AT_SIGNATURE;
1747 pCryptDestroyKey( hKey );
1758 status = dynCreate( &certDB, iCryptHandle,
1766 if( dwKeySpec != 0 )
1768 PCCERT_CONTEXT pCertContext;
1769 CERT_KEY_CONTEXT certKeyContext;
1770 DWORD certKeyContextSize =
sizeof( CERT_KEY_CONTEXT );
1774 pCertContext = pCertCreateCertificateContext( X509_ASN_ENCODING,
1776 if( pCertContext != NULL && \
1777 !pCertGetCertificateContextProperty( pCertContext,
1778 CERT_KEY_CONTEXT_PROP_ID,
1779 &certKeyContext, &certKeyContextSize ) )
1785 pCryptFindCertificateKeyProvInfo( pCertContext, 0, NULL );
1787 CRYPT_KEY_PROV_INFO keyProvInfo;
1788 BYTE buffer[ 256 + 8 ];
1790 wchar_t provName[ 256 + 8 ], container[ 256 + 8 ];
1792 if( pCryptGetProvParam( cryptoapiInfo->
hProv, PP_NAME,
1793 buffer, &length, 0 ) )
1794 MultiByteToWideChar( GetACP(), 0, buffer, length + 1,
1796 if( pCryptGetProvParam( cryptoapiInfo->
hProv, PP_CONTAINER,
1797 buffer, &length, 0 ) )
1798 MultiByteToWideChar( GetACP(), 0, buffer, length + 1,
1800 memset( &keyProvInfo, 0,
sizeof( CRYPT_KEY_PROV_INFO ) );
1801 keyProvInfo.pwszContainerName = container;
1802 keyProvInfo.pwszProvName = provName;
1803 keyProvInfo.dwProvType = PROV_RSA_FULL;
1804 keyProvInfo.cProvParam = 0;
1805 keyProvInfo.dwKeySpec = dwKeySpec;
1806 pCertSetCertificateContextProperty( pCertContext,
1807 CERT_KEY_PROV_HANDLE_PROP_ID, 0,
1810 memset( &certKeyContext, 0,
sizeof( CERT_KEY_CONTEXT ) );
1811 certKeyContext.cbSize =
sizeof( CERT_KEY_CONTEXT );
1812 certKeyContext.dwKeySpec = dwKeySpec;
1813 certKeyContext.hCryptProv = cryptoapiInfo->
hProv;
1814 pCertSetCertificateContextProperty( pCertContext,
1815 CERT_KEY_CONTEXT_PROP_ID, 0,
1821 if( pCertContext != NULL )
1823 result = pCertAddCertificateContextToStore( cryptoapiInfo->
hCertStore,
1824 pCertContext, CERT_STORE_ADD_NEW, NULL );
1825 pCertFreeCertificateContext( pCertContext );
1835 result = pCertAddEncodedCertificateToStore( cryptoapiInfo->
hCertStore,
1836 X509_ASN_ENCODING,
dynData( certDB ),
1837 dynLength( certDB ), CERT_STORE_ADD_NEW, NULL );
1839 dynDestroy( &certDB );
1841 seenNonDuplicate =
TRUE;
1851 CRYPT_IATTRIBUTE_LOCKED );
1858 static int deleteItemFunction(
DEVICE_INFO *deviceInfo,
1861 const void *keyID,
const int keyIDlength )
1900 cryptStatus = findObjectEx( deviceInfo, &hCertificate, certTemplate, 3 );
1905 cryptStatus = findObjectFromObject( deviceInfo, hCertificate,
1909 cryptStatus = findObjectFromObject( deviceInfo, hCertificate,
1918 cryptStatus = findObjectEx( deviceInfo, &hPubkey, keyTemplate, 2 );
1921 keyTemplate[ 0 ].pValue = (
CK_VOID_PTR ) &privkeyClass;
1922 cryptStatus = findObjectEx( deviceInfo, &hPrivkey, keyTemplate, 2 );
1930 cryptStatus = findObjectFromObject( deviceInfo,
1942 cryptStatus = findObjectFromObject( deviceInfo, hPubkey,
1949 cryptStatus = findObjectFromObject( deviceInfo, hPrivkey,
1964 status = C_DestroyObject( cryptoapiInfo->
hProv, hCertificate );
1969 status2 = C_DestroyObject( cryptoapiInfo->
hProv, hPubkey );
1977 status2 = C_DestroyObject( cryptoapiInfo->
hProv, hPrivkey );
1983 return( cryptStatus );
1996 static int getFirstItemFunction(
DEVICE_INFO *deviceInfo,
2000 const void *keyID,
const int keyIDlength,
2005 PCCERT_CONTEXT pCertContext;
2006 PCCERT_CHAIN_CONTEXT pChainContext;
2011 assert( keyIDtype == CRYPT_IKEYID_KEYID );
2012 assert(
isReadPtr( keyID, keyIDlength ) );
2014 assert(
isWritePtr( stateInfo,
sizeof(
int ) ) );
2025 status = getCertificate( cryptoapiInfo, keyIDtype, keyID, keyIDlength,
2029 DEBUG_DIAG((
"Failed to load CryptoAPI certificate data" ));
2036 status = getCertificateChain( cryptoapiInfo, pCertContext,
2043 pCertContext->pbCertEncoded,
2044 pCertContext->cbCertEncoded,
2050 pCertFreeCertificateContext( pCertContext );
2054 pCertFreeCertificateChain( cryptoapiInfo->
hCertChain );
2059 assert( pChainContext->cChain == 1 );
2064 static int getNextItemFunction(
DEVICE_INFO *deviceInfo,
2066 int *stateInfo,
const int options )
2069 PCCERT_CHAIN_CONTEXT pChainContext = cryptoapiInfo->
hCertChain;
2070 PCERT_SIMPLE_CHAIN pCertSimpleChain;
2071 PCERT_CHAIN_ELEMENT pCertChainElement;
2076 assert(
isWritePtr( stateInfo,
sizeof(
int ) ) );
2077 assert( *stateInfo ==
CRYPT_ERROR || *stateInfo >= 1 );
2089 pCertSimpleChain = pChainContext->rgpChain[ 0 ];
2090 if( *stateInfo < 1 || *stateInfo > pCertSimpleChain->cElement )
2092 pCertFreeCertificateChain( cryptoapiInfo->
hCertChain );
2099 pCertChainElement = pCertSimpleChain->rgpElement[ *
stateInfo ];
2101 pCertChainElement->pCertContext->pbCertEncoded,
2102 pCertChainElement->pCertContext->cbCertEncoded,
2110 pCertFreeCertificateChain( cryptoapiInfo->
hCertChain );
2127 static int genericEndFunction(
CONTEXT_INFO *contextInfoPtr )
2138 pCryptDestroyKey( contextInfoPtr->deviceObject );
2140 pCryptDestroyHash( contextInfoPtr->deviceObject );
2154 int nLen, eLen, keyDataSize,
status;
2157 status = getPubkeyComponents( cryptoapiInfo,
2158 contextInfoPtr->deviceObject,
2159 n, &nLen, e, &eLen );
2172 n, nLen, e, eLen, NULL, 0, NULL, 0 );
2178 CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL );
2190 BLOBHEADER *blobHeaderPtr;
2191 RSAPUBKEY *pubKeyPtr;
2193 DWORD exponent = 0L;
2216 exponent = ( exponent << 8 ) | rsaKey->
e[ i ];
2219 status = getContextDeviceInfo( contextInfoPtr->
objectHandle,
2220 &iCryptDevice, &cryptoapiInfo );
2244 blobHeaderPtr = ( BLOBHEADER * ) keyBlob;
2246 PUBLICKEYBLOB : PRIVATEKEYBLOB );
2247 blobHeaderPtr->bVersion = CUR_BLOB_VERSION;
2248 blobHeaderPtr->aiKeyAlg = CALG_RSA_KEYX;
2254 pubKeyPtr->magic = ( rsaKey->
isPublicKey ) ? 0x31415352 : 0x32415352;
2258 keyBlobPtr = copyMPI( keyBlobPtr, rsaKey->
n, nLen, nLen );
2263 keyBlobPtr = copyMPI( keyBlobPtr, rsaKey->
p,
2265 keyBlobPtr = copyMPI( keyBlobPtr, rsaKey->
q,
2267 keyBlobPtr = copyMPI( keyBlobPtr, rsaKey->
e1,
2269 keyBlobPtr = copyMPI( keyBlobPtr, rsaKey->
e2,
2271 keyBlobPtr = copyMPI( keyBlobPtr, rsaKey->
u,
2273 keyBlobPtr = copyMPI( keyBlobPtr, rsaKey->
d,
2278 result = pCryptImportKey( cryptoapiInfo->
hProv, keyBlob,
2279 keyBlobPtr - keyBlob, 0, 0, &hKey );
2286 contextInfoPtr->deviceObject = ( long ) hKey;
2295 status = rsaSetKeyInfo( cryptoapiInfo, contextInfoPtr );
2301 static int rsaGenerateKey(
CONTEXT_INFO *contextInfoPtr,
const int keysizeBits )
2305 HCRYPTKEY hPrivateKey;
2310 status = getContextDeviceInfo( contextInfoPtr->
objectHandle,
2311 &iCryptDevice, &cryptoapiInfo );
2319 result = pCryptGenKey( cryptoapiInfo->
hProv, AT_KEYEXCHANGE,
2320 CRYPT_EXPORTABLE | ( keysizeBits << 16 ),
2328 contextInfoPtr->deviceObject = ( long ) hPrivateKey;
2336 status = rsaSetKeyInfo( cryptoapiInfo, contextInfoPtr );
2342 static int rsaSign(
CONTEXT_INFO *contextInfoPtr,
void *buffer,
int length )
2358 assert( bufPtr[ 0 ] == 0 && bufPtr[ 1 ] == 1 );
2359 for( i = 2; i <
length; i++ )
2361 if( bufPtr[ i ] == 0 )
2365 sMemConnect( &stream, bufPtr + i, length - i );
2366 status = readMessageDigest( &stream, &cryptAlgo, hashBuffer,
2368 sMemDisconnect( &stream );
2371 algID = cryptlibToCapiID( cryptAlgo );
2376 status = getContextDeviceInfo( contextInfoPtr->
objectHandle,
2377 &iCryptDevice, &cryptoapiInfo );
2392 result = pCryptCreateHash( cryptoapiInfo->
hProv, algID, 0, 0, &hHash );
2399 result = pCryptSetHashParam( hHash, HP_HASHVAL, hashBuffer, 0 );
2401 result = pCryptSignHash( hHash, AT_KEYEXCHANGE, NULL, 0,
2402 tempBuffer, &resultLength );
2403 pCryptDestroyHash( hHash );
2406 copyMPI( buffer, tempBuffer, resultLength, resultLength );
2410 if( resultLength < length )
2412 const int delta = length - resultLength;
2414 memmove( (
BYTE * ) buffer + delta, tempBuffer, resultLength );
2415 memset( buffer, 0, delta );
2425 static int rsaVerify(
CONTEXT_INFO *contextInfoPtr,
void *buffer,
int length )
2435 static int rsaEncrypt(
CONTEXT_INFO *contextInfoPtr,
void *buffer,
int length )
2443 assert( bufPtr[ 0 ] == 0 && bufPtr[ 1 ] == 2 );
2444 for( i = 2; i <
length; i++ )
2446 if( bufPtr[ i ] == 0 )
2453 tempPtr = copyMPI( tempBuffer, bufPtr + i, length - i, length - i );
2454 resultLength = tempPtr - tempBuffer;
2455 if( !pCryptEncrypt( contextInfoPtr->deviceObject, 0,
TRUE, 0,
2456 tempBuffer, &resultLength, length ) )
2461 copyMPI( buffer, tempBuffer, resultLength, resultLength );
2465 if( resultLength < length )
2467 const int delta = length - resultLength;
2469 memmove( (
BYTE * ) buffer + delta, tempBuffer, resultLength );
2470 memset( buffer, 0, delta );
2475 static int rsaDecrypt(
CONTEXT_INFO *contextInfoPtr,
void *buffer,
int length )
2483 tempPtr = copyMPI( tempBuffer, bufPtr, length, length );
2484 resultLength = tempPtr - tempBuffer;
2485 if( !pCryptDecrypt( contextInfoPtr->deviceObject, 0,
FALSE, 0,
2486 tempBuffer, &resultLength ) )
2491 copyMPI( buffer, tempBuffer, resultLength, resultLength );
2495 memmove( bufPtr + length - resultLength, bufPtr, resultLength );
2498 for( i = 2; i < length - resultLength - 1; i++ )
2501 assert( i + 1 + resultLength == length );
2512 const void *
p,
const int pLen,
2513 const void *q,
const int qLen,
2514 const void *g,
const int gLen,
2515 const void *y,
const int yLen )
2520 int keyDataSize, cryptStatus;
2529 cryptStatus = keyDataSize = writeFlatPublicKey( NULL, 0,
CRYPT_ALGO_DSA,
2541 CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL );
2544 return( cryptStatus );
2549 CRYPT_IATTRIBUTE_DEVICEOBJECT );
2557 CRYPT_IATTRIBUTE_KEYID );
2564 C_SetAttributeValue( cryptoapiInfo->
hProv, hPublicKey,
2567 C_SetAttributeValue( cryptoapiInfo->
hProv, hPrivateKey,
2571 return( cryptStatus );
2576 static int dsaInitKey(
CONTEXT_INFO *contextInfoPtr,
const void *key,
2577 const int keyLength )
2583 BLOBHEADER *blobHeaderPtr;
2584 DSSPUBKEY *pubKeyPtr;
2593 if( dlpKey->
pLen > 1024 )
2597 status = getContextDeviceInfo( contextInfoPtr->
objectHandle,
2598 &iCryptDevice, &cryptoapiInfo );
2618 blobHeaderPtr = ( BLOBHEADER * ) keyBlob;
2620 PUBLICKEYBLOB : PRIVATEKEYBLOB );
2621 blobHeaderPtr->bVersion = CUR_BLOB_VERSION;
2622 blobHeaderPtr->aiKeyAlg = CALG_DSS_SIGN;
2628 pubKeyPtr->magic = 0x31535344;
2631 keyBlobPtr = copyMPI( keyBlobPtr, dlpKey->
p, pLen, 128 );
2632 keyBlobPtr = copyMPI( keyBlobPtr, dlpKey->
q,
2634 keyBlobPtr = copyMPI( keyBlobPtr, dlpKey->
g,
2636 keyBlobPtr = copyMPI( keyBlobPtr, dlpKey->
y,
2645 result = pCryptImportKey( cryptoapiInfo->
hProv, keyBlob,
2646 keyBlobPtr - keyBlob, 0, 0, &hKey );
2653 contextInfoPtr->deviceObject = ( long ) hKey;
2663 static int dsaGenerateKey(
CONTEXT_INFO *contextInfoPtr,
const int keysizeBits )
2668 const CK_ULONG modulusBits = keysizeBits;
2693 int keyLength =
bitsToBytes( keysizeBits ), cryptStatus;
2712 return( cryptStatus );
2715 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
2727 CRYPT_IATTRIBUTE_KEY_SPKI );
2731 return( cryptStatus );
2739 sMemConnect( &stream, pubkeyBuffer, msgData.
length );
2740 readSequence( &stream, NULL );
2741 readSequence( &stream, NULL );
2742 readUniversal( &stream );
2743 readSequence( &stream, NULL );
2744 readGenericHole( &stream, &length );
2745 publicKeyTemplate[ 3 ].
pValue = sMemBufPtr( &stream );
2747 sSkip( &stream, length );
2748 readGenericHole( &stream, &length );
2749 publicKeyTemplate[ 4 ].
pValue = sMemBufPtr( &stream );
2751 sSkip( &stream, length );
2752 readGenericHole( &stream, &length );
2753 publicKeyTemplate[ 5 ].
pValue = sMemBufPtr( &stream );
2756 sMemDisconnect( &stream );
2759 status = getContextDeviceInfo( contextInfoPtr->
objectHandle,
2760 &iCryptDevice, &cryptoapiInfo );
2765 status = C_GenerateKeyPair( cryptoapiInfo->
hProv,
2769 &hPublicKey, &hPrivateKey );
2774 return( cryptStatus );
2781 status = C_GetAttributeValue( cryptoapiInfo->
hProv, hPublicKey,
2782 &yValueTemplate, 1 );
2785 yValueTemplate.
pValue = pubkeyBuffer;
2786 status = C_GetAttributeValue( cryptoapiInfo->
hProv, hPublicKey,
2787 &yValueTemplate, 1 );
2791 cryptStatus = dsaSetKeyInfo( deviceInfo, contextInfoPtr,
2792 hPrivateKey, hPublicKey,
2793 publicKeyTemplate[ 3 ].pValue, publicKeyTemplate[ 3 ].ulValueLen,
2794 publicKeyTemplate[ 4 ].pValue, publicKeyTemplate[ 4 ].ulValueLen,
2795 publicKeyTemplate[ 5 ].pValue, publicKeyTemplate[ 5 ].ulValueLen,
2799 C_DestroyObject( cryptoapiInfo->
hProv, hPublicKey );
2800 C_DestroyObject( cryptoapiInfo->
hProv, hPrivateKey );
2804 return( cryptStatus );
2809 static int dsaSign(
CONTEXT_INFO *contextInfoPtr,
void *buffer,
int length )
2820 assert( dlpParams->inParam1 != NULL && \
2821 dlpParams->
inLen1 == 20 );
2822 assert( dlpParams->inParam2 == NULL && dlpParams->
inLen2 == 0 );
2823 assert( dlpParams->outParam != NULL && \
2824 dlpParams->
outLen >= ( 2 + 20 ) * 2 );
2827 status = getContextDeviceInfo( contextInfoPtr->
objectHandle,
2828 &iCryptDevice, &cryptoapiInfo );
2831 cryptStatus = genericSign( deviceInfo, contextInfoPtr, &mechanism,
2832 dlpParams->inParam1, dlpParams->
inLen1,
2836 return( cryptStatus );
2843 if( r != NULL && s != NULL )
2847 cryptStatus = encodeDLValues( dlpParams->outParam, dlpParams->
outLen,
2851 dlpParams->
outLen = cryptStatus;
2857 return( cryptStatus );
2862 static int dsaVerify(
CONTEXT_INFO *contextInfoPtr,
void *buffer,
int length )
2869 BYTE signature[ 40 + 8 ];
2878 assert( dlpParams->inParam1 != NULL && dlpParams->
inLen1 == 20 );
2879 assert( dlpParams->inParam2 != NULL && \
2881 dlpParams->
inLen2 >= 46 ) || \
2883 dlpParams->
inLen2 == 44 ) || \
2884 ( dlpParams->
formatType == CRYPT_IFORMAT_SSH && \
2885 dlpParams->
inLen2 == 40 ) ) );
2886 assert( dlpParams->outParam == NULL && dlpParams->
outLen == 0 );
2890 cryptStatus = decodeDLValues( dlpParams->inParam2, dlpParams->
inLen2,
2893 return( cryptStatus );
2900 status = getContextDeviceInfo( contextInfoPtr->
objectHandle,
2901 &iCryptDevice, &cryptoapiInfo );
2904 cryptStatus = genericVerify( deviceInfo, contextInfoPtr, &mechanism, buffer,
2905 20, signature, 40 );
2907 return( cryptStatus );
2914 static int cipherInitKey(
CONTEXT_INFO *contextInfoPtr,
const void *key,
2915 const int keyLength )
2919 HCRYPTKEY hSessionKey;
2923 status = getContextDeviceInfo( contextInfoPtr->
objectHandle,
2924 &iCryptDevice, &cryptoapiInfo );
2929 if( contextInfoPtr->ctxConv->userKey != key )
2930 memcpy( contextInfoPtr->ctxConv->userKey, key, keyLength );
2931 contextInfoPtr->ctxConv->userKeyLength =
keyLength;
2941 memcpy( contextInfoPtr->ctxConv->userKey +
bitsToBytes( 64 * 2 ),
2942 contextInfoPtr->ctxConv->userKey,
bitsToBytes( 64 ) );
2948 status = importPlainKey( cryptoapiInfo->
hProv,
2952 key, keySize, contextInfoPtr );
2959 contextInfoPtr->deviceObject = ( long ) hSessionKey;
2968 static int initCryptParams(
CONTEXT_INFO *contextInfoPtr )
2970 enum { CAPI_CRYPT_MODE_NONE, CAPI_CRYPT_MODE_CBC,
2971 CAPI_CRYPT_MODE_ECB, CAPI_CRYPT_MODE_OFB,
2972 CAPI_CRYPT_MODE_CFB };
2994 dwMode = CAPI_CRYPT_MODE_ECB;
2997 dwMode = CAPI_CRYPT_MODE_CBC;
3000 dwMode = CAPI_CRYPT_MODE_CFB;
3003 dwMode = CAPI_CRYPT_MODE_OFB;
3010 if( !CryptSetKeyParam( contextInfoPtr->deviceObject, KP_MODE,
3011 (
BYTE * ) &dwMode, 0 ) )
3019 if( !CryptSetKeyParam( contextInfoPtr->deviceObject, KP_MODE_BITS,
3020 (
BYTE * ) &dwModeBits, 0 ) )
3029 if( !CryptSetKeyParam( contextInfoPtr->deviceObject, KP_IV,
3030 contextInfoPtr->ctxConv->currentIV, 0 ) )
3038 static int cipherEncrypt(
CONTEXT_INFO *contextInfoPtr,
void *buffer,
int length )
3049 status = initCryptParams( contextInfoPtr );
3058 if( !pCryptEncrypt( contextInfoPtr->deviceObject, 0,
FALSE, 0, buffer,
3059 &resultLength, length ) )
3064 static int cipherDecrypt(
CONTEXT_INFO *contextInfoPtr,
void *buffer,
int length )
3075 status = initCryptParams( contextInfoPtr );
3084 if( !pCryptDecrypt( contextInfoPtr->deviceObject, 0,
FALSE, 0, buffer,
3094 if( !pCryptHashData( contextInfoPtr->deviceObject, buffer, length, 0 ) )
3153 const ALG_ID algoID;
3154 const ALG_ID altAlgoID;
3170 NULL, rsaInitKey, rsaGenerateKey,
3171 rsaEncrypt, rsaDecrypt, rsaSign, rsaVerify },
3173 NULL, dsaInitKey, dsaGenerateKey,
3174 NULL, NULL, dsaSign, dsaVerify },
3176 genericEndFunction, cipherInitKey, NULL,
3177 cipherEncrypt, cipherDecrypt, NULL, NULL },
3179 genericEndFunction, cipherInitKey, NULL,
3180 cipherEncrypt, cipherDecrypt, NULL, NULL },
3182 genericEndFunction, cipherInitKey, NULL,
3183 cipherEncrypt, cipherDecrypt, NULL, NULL },
3185 genericEndFunction, cipherInitKey, NULL,
3186 cipherEncrypt, cipherDecrypt, NULL, NULL },
3188 genericEndFunction, cipherInitKey, NULL,
3189 cipherEncrypt, cipherDecrypt, NULL, NULL },
3191 genericEndFunction, cipherInitKey, NULL,
3192 cipherEncrypt, cipherDecrypt, NULL, NULL },
3194 genericEndFunction, cipherInitKey, NULL,
3195 cipherEncrypt, cipherDecrypt, NULL, NULL },
3199 genericEndFunction, NULL, NULL,
3202 genericEndFunction, NULL, NULL,
3213 const PROV_ENUMALGS_EX *capiAlgoInfo,
3214 const MECHANISM_INFO *mechanismInfoPtr,
3223 if( capabilityInfo == NULL )
3225 if( ( capabilityInfo = \
3229 capabilityTemplates[ i ].cryptAlgo != mechanismInfoPtr->cryptAlgo && \
3235 assert( i <
sizeof( capabilityTemplates ) /
sizeof(
CAPABILITY_INFO ) && \
3237 memcpy( capabilityInfo, &capabilityTemplates[ i ],
3249 if( capabilityInfo->
keySize > 0 )
3258 minKeySize = maxKeySize = 8;
3264 minKeySize = maxKeySize = 24;
3266 if( minKeySize > capabilityInfo->
minKeySize )
3274 capabilityInfo->endFunction = genericEndFunction;
3278 capabilityInfo->getInfoFunction = getDefaultInfo;
3281 capabilityInfo->initParamsFunction = initGenericParams;
3282 capabilityInfo->endFunction = mechanismInfoPtr->endFunction;
3283 capabilityInfo->initKeyFunction = mechanismInfoPtr->initKeyFunction;
3284 capabilityInfo->generateKeyFunction = mechanismInfoPtr->generateKeyFunction;
3285 if( mechanismInfoPtr->algoID == capiAlgoInfo->aiAlgid )
3290 capabilityInfo->encryptOFBFunction = mechanismInfoPtr->encryptFunction;
3293 capabilityInfo->encryptFunction = mechanismInfoPtr->encryptFunction;
3297 capabilityInfo->decryptOFBFunction = mechanismInfoPtr->decryptFunction;
3300 capabilityInfo->decryptFunction = mechanismInfoPtr->decryptFunction;
3304 capabilityInfo->encryptCBCFunction = \
3305 mechanismInfoPtr->encryptFunction;
3306 capabilityInfo->decryptCBCFunction = \
3307 mechanismInfoPtr->decryptFunction;
3312 capabilityInfo->encryptCFBFunction = \
3313 mechanismInfoPtr->encryptFunction;
3314 capabilityInfo->decryptCFBFunction = \
3315 mechanismInfoPtr->decryptFunction;
3316 capabilityInfo->encryptOFBFunction = \
3317 mechanismInfoPtr->encryptFunction;
3318 capabilityInfo->decryptOFBFunction = \
3319 mechanismInfoPtr->decryptFunction;
3323 if( mechanismInfoPtr->altAlgoID == capiAlgoInfo->aiAlgid )
3325 capabilityInfo->signFunction = mechanismInfoPtr->signFunction;
3326 capabilityInfo->sigCheckFunction = mechanismInfoPtr->sigCheckFunction;
3337 static void freeCapabilities(
DEVICE_INFO *deviceInfo )
3343 if( capabilityInfoListPtr == NULL )
3347 while( capabilityInfoListPtr != NULL )
3352 capabilityInfoListPtr = capabilityInfoListPtr->
next;
3354 clFree(
"freeCapabilities", itemToFree );
3356 clFree(
"freeCapabilities", listItemToFree );
3360 static int getCapabilities(
DEVICE_INFO *deviceInfo )
3365 PROV_ENUMALGS_EX capiAlgoInfo;
3366 DWORD length =
sizeof( PROV_ENUMALGS_EX );
3367 int iterationCount = 0;
3373 if( !pCryptGetProvParam( cryptoapiInfo->
hProv, PP_ENUMALGS_EX,
3374 (
BYTE * ) &capiAlgoInfo, &length, CRYPT_FIRST ) )
3389 if( mechanismInfo[ i ].algoID == capiAlgoInfo.aiAlgid || \
3390 ( mechanismInfo[ i ].altAlgoID != CALG_NONE && \
3391 mechanismInfo[ i ].altAlgoID == capiAlgoInfo.aiAlgid ) )
3398 cryptAlgo = mechanismInfo[ i ].cryptAlgo;
3402 deviceInfo->capabilityInfoList;
3403 capabilityInfoListPtr != NULL && \
3405 capabilityInfoListPtr = capabilityInfoListPtr->
next );
3406 if( capabilityInfoListPtr != NULL )
3408 addCapability( deviceInfo, &capiAlgoInfo, &mechanismInfo[ i ],
3409 capabilityInfoListPtr->
info );
3426 newCapability = addCapability( deviceInfo, &capiAlgoInfo,
3427 &mechanismInfo[ i ], NULL );
3428 if( newCapability == NULL )
3430 REQUIRES( sanityCheckCapability( newCapability,
3433 if( ( newCapabilityList = \
3437 clFree(
"getCapabilities", newCapability );
3440 newCapabilityList->
info = newCapability;
3441 newCapabilityList->
next = NULL;
3445 capabilityInfoListTail->
next = newCapabilityList;
3446 capabilityInfoListTail = newCapabilityList;
3448 while( pCryptGetProvParam( cryptoapiInfo->
hProv, PP_ENUMALGS_EX,
3449 (
BYTE * ) &capiAlgoInfo, &length, 0 ) && \
3508 if( hCryptoAPI == NULL_HINSTANCE )
3511 deviceInfo->initFunction = initFunction;
3512 deviceInfo->shutdownFunction = shutdownFunction;
3513 deviceInfo->controlFunction = controlFunction;
3514 deviceInfo->getItemFunction = getItemFunction;
3515 deviceInfo->setItemFunction = setItemFunction;
3516 deviceInfo->deleteItemFunction = deleteItemFunction;
3517 deviceInfo->getFirstItemFunction = getFirstItemFunction;
3518 deviceInfo->getNextItemFunction = getNextItemFunction;
3519 deviceInfo->getRandomFunction = getRandomFunction;
3520 deviceInfo->mechanismFunctions = mechanismFunctions;
3521 deviceInfo->mechanismFunctionCount = \