📄 ms_capi.c
字号:
/****************************************************************************
* *
* cryptlib CryptoAPI Routines *
* Copyright Peter Gutmann 1998-2004 *
* *
****************************************************************************/
#include <stdlib.h>
#include <string.h>
#if defined( INC_ALL )
#include "crypt.h"
#include "context.h"
#include "device.h"
#include "asn1.h"
#include "asn1_ext.h"
#elif defined( INC_CHILD )
#include "../crypt.h"
#include "../context/context.h"
#include "device.h"
#include "../misc/asn1.h"
#include "../misc/asn1_ext.h"
#else
#include "crypt.h"
#include "context/context.h"
#include "device/device.h"
#include "misc/asn1.h"
#include "misc/asn1_ext.h"
#endif /* Compiler-specific includes */
/* The size of the (packed) header used for key blobs */
#define BLOBHEADER_SIZE 8
/* Occasionally we need to read things into host memory from a device in a
manner that can't be handled by a dynBuf since the data is coming from a
device rather than a cryptlib object. The following value defines the
maximum size of the on-stack buffer, if the data is larger than this we
dynamically allocate the buffer (this almost never occurs) */
#define MAX_BUFFER_SIZE 1024
/* Prototypes for functions in cryptcap.c */
const void FAR_BSS *findCapabilityInfo( const void FAR_BSS *capabilityInfoPtr,
const CRYPT_ALGO_TYPE cryptAlgo );
#ifdef USE_CRYPTOAPI
/* The following define is needed to enable crypto functions in the include
file. This would probably be defined by the compiler since it's not
defined in any header file, but it doesn't seem to be enabled by
default */
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif /* _WIN32_WINNT */
/* cryptlib.h includes a trap for inclusion of wincrypt.h before cryptlib.h
which results in a compiler error if both files are included. To disable
this, we need to undefine the CRYPT_MODE_ECB defined in cryptlib.h */
#undef CRYPT_MODE_ECB
#include <wincrypt.h>
/* CryptoAPI uses the same mode names as cryptlib but different values,
fortunately this is done with #defines so we can remove them at this
point */
#undef CRYPT_MODE_ECB
#undef CRYPT_MODE_CBC
#undef CRYPT_MODE_CFB
#undef CRYPT_MODE_OFB
/* Some parts of CryptoAPI (inconsistently) require the use of Unicode,
winnls.h was already included via the global include of windows.h however
it isn't needed for any other part of cryptlib so it was disabled via
NONLS. Since winnls.h is now locked out, we have to un-define the guards
used earlier to get it included */
#undef _WINNLS_
#undef NONLS
#include <winnls.h>
/* Older versions of wincrypt.h don't contain defines and typedefs that we
require. Defines can be detected with #ifdef but typedefs can't, to
handle this we rely on checking for values that aren't defined in older
versions of wincrypt.h, which only go up to KP_PUB_EX_VAL */
#ifndef KP_ADMIN_PIN
/* Misc values */
#define HCERTCHAINENGINE void *
#define USAGE_MATCH_TYPE_AND 0
#define USAGE_MATCH_TYPE_OR 1
#define CERT_COMPARE_KEY_IDENTIFIER 15
#define CERT_FIND_KEY_IDENTIFIER ( CERT_COMPARE_KEY_IDENTIFIER << CERT_COMPARE_SHIFT )
#define CERT_CHAIN_CACHE_END_CERT 0x00000001
#define CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 0x80000000
#define CRYPT_ACQUIRE_CACHE_FLAG 0x00000001
/* Cert chain match info */
typedef struct {
DWORD dwType;
CERT_ENHKEY_USAGE Usage;
} CERT_USAGE_MATCH;
typedef struct {
DWORD cbSize;
CERT_USAGE_MATCH RequestedUsage;
CERT_USAGE_MATCH RequestedIssuancePolicy;
DWORD dwUrlRetrievalTimeout;
BOOL fCheckRevocationFreshnessTime;
DWORD dwRevocationFreshnessTime;
} CERT_CHAIN_PARA, *PCERT_CHAIN_PARA;
/* Cert chain info */
typedef struct {
DWORD dwErrorStatus;
DWORD dwInfoStatus;
} CERT_TRUST_STATUS, *PCERT_TRUST_STATUS;
typedef struct {
DWORD cbSize;
PCCERT_CONTEXT pCertContext;
CERT_TRUST_STATUS TrustStatus;
void *pRevocationInfo; // PCERT_REVOCATION_INFO pRevocationInfo;
void *pIssuanceUsage; // PCERT_ENHKEY_USAGE pIssuanceUsage;
void *pApplicationUsage; // PCERT_ENHKEY_USAGE pApplicationUsage;
LPCWSTR pwszExtendedErrorInfo;
} CERT_CHAIN_ELEMENT, *PCERT_CHAIN_ELEMENT;
typedef struct {
DWORD cbSize;
PCTL_ENTRY pCtlEntry;
PCCTL_CONTEXT pCtlContext;
} CERT_TRUST_LIST_INFO, *PCERT_TRUST_LIST_INFO;
typedef struct {
DWORD cbSize;
CERT_TRUST_STATUS TrustStatus;
DWORD cElement;
PCERT_CHAIN_ELEMENT *rgpElement;
PCERT_TRUST_LIST_INFO pTrustListInfo;
BOOL fHasRevocationFreshnessTime;
DWORD dwRevocationFreshnessTime;
} CERT_SIMPLE_CHAIN, *PCERT_SIMPLE_CHAIN;
typedef struct CCC {
DWORD cbSize;
CERT_TRUST_STATUS TrustStatus;
DWORD cChain;
PCERT_SIMPLE_CHAIN *rgpChain;
DWORD cLowerQualityChainContext;
struct CCC **rgpLowerQualityChainContext;
BOOL fHasRevocationFreshnessTime;
DWORD dwRevocationFreshnessTime;
} CERT_CHAIN_CONTEXT;
typedef const CERT_CHAIN_CONTEXT *PCCERT_CHAIN_CONTEXT;
#endif /* Pre-1999 wincrypt.h */
/****************************************************************************
* *
* Init/Shutdown Routines *
* *
****************************************************************************/
/* Global function pointers. These are necessary because the functions need
to be dynamically linked since not all systems contain the necessary
DLL's. Explicitly linking to them will make cryptlib unloadable on some
systems */
#define NULL_HINSTANCE ( HINSTANCE ) NULL
static HINSTANCE hCryptoAPI = NULL_HINSTANCE;
static HINSTANCE hAdvAPI32 = NULL_HINSTANCE;
typedef BOOL ( WINAPI *CERTADDCERTIFICATETOSTORE )( HCERTSTORE hCertStore,
PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
PCCERT_CONTEXT *ppStoreContext );
typedef BOOL ( WINAPI *CERTADDENCODEDCERTIFICATETOSTORE )( HCERTSTORE hCertStore,
DWORD dwCertEncodingType, const BYTE *pbCertEncoded,
DWORD cbCertEncoded, DWORD dwAddDisposition,
PCCERT_CONTEXT *ppCertContext );
typedef BOOL ( WINAPI *CERTCLOSESTORE )( HCERTSTORE hCertStore, DWORD dwFlags );
typedef PCCERT_CONTEXT ( WINAPI *CERTCREATECERTIFICATECONTEXT )( DWORD dwCertEncodingType,
const BYTE *pbCertEncoded, DWORD cbCertEncoded );
typedef BOOL ( WINAPI *CERTDELETECERTIFICATEFROMSTORE )( PCCERT_CONTEXT pCertContext );
typedef PCCERT_CONTEXT ( WINAPI *CERTFINDCERTIFICATEINSTORE )( HCERTSTORE hCertStore,
DWORD dwCertEncodingType, DWORD dwFindFlags,
DWORD dwFindType, const void *pvFindPara,
PCCERT_CONTEXT pPrevCertContext );
typedef VOID ( WINAPI *CERTFREECERTIFICATECHAIN )( PCCERT_CHAIN_CONTEXT pChainContext );
typedef BOOL ( WINAPI *CERTFREECERTIFICATECONTEXT )( PCCERT_CONTEXT pCertContext );
typedef BOOL ( WINAPI *CERTGETCERTIFICATECHAIN )( HCERTCHAINENGINE hChainEngine,
PCCERT_CONTEXT pCertContext, LPFILETIME pTime,
HCERTSTORE hAdditionalStore, PCERT_CHAIN_PARA pChainPara,
DWORD dwFlags, LPVOID pvReserved,
PCCERT_CHAIN_CONTEXT *ppChainContext );
typedef BOOL ( WINAPI *CERTGETCERTIFICATECONTEXTPROPERTY )( PCCERT_CONTEXT pCertContext,
DWORD dwPropId, void *pvData, DWORD *pcbData );
typedef PCCERT_CONTEXT ( WINAPI *CERTGETSUBJECTCERTIFICATEFROMSTORE )( HCERTSTORE hCertStore,
DWORD dwCertEncodingType, PCERT_INFO pCertId );
typedef BOOL ( WINAPI *CERTSETCERTIFICATEPROPERTY )( PCCERT_CONTEXT pCertContext,
DWORD dwPropId, DWORD dwFlags, const void *pvData );
typedef HCERTSTORE ( WINAPI *CERTOPENSYSTEMSTORE )( HCRYPTPROV hprov,
LPCSTR szSubsystemProtocol );
typedef BOOL ( WINAPI *CRYPTACQUIRECERTIFICATEPRIVATEKEY )( PCCERT_CONTEXT pCert,
DWORD dwFlags, void *pvReserved, HCRYPTPROV *phCryptProv,
DWORD *pdwKeySpec, BOOL *pfCallerFreeProv );
typedef BOOL ( WINAPI *CRYPTACQUIRECONTEXTA )( HCRYPTPROV *phProv, LPCSTR pszContainer,
LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags );
typedef BOOL ( WINAPI *CRYPTCREATEHASH )( HCRYPTPROV hProv, ALG_ID Algid,
HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH* phHash );
typedef BOOL ( WINAPI *CRYPTDECRYPT )( HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen );
typedef BOOL ( WINAPI *CRYPTDESTROYHASH )( HCRYPTHASH hHash );
typedef BOOL ( WINAPI *CRYPTDESTROYKEY )( HCRYPTKEY hKey );
typedef BOOL ( WINAPI *CRYPTENCRYPT )( HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen );
typedef BOOL ( WINAPI *CRYPTEXPORTKEY )( HCRYPTKEY hKey, HCRYPTKEY hExpKey,
DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen );
typedef BOOL ( WINAPI *CRYPTFINDCERTIFICATEKEYPROVINFO )( PCCERT_CONTEXT pCert,
DWORD dwFlags, void *pvReserved );
typedef BOOL ( WINAPI *CRYPTGENKEY )( HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags,
HCRYPTKEY *phKey );
typedef BOOL ( WINAPI *CRYPTGENRANDOM )( HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer );
typedef BOOL ( WINAPI *CRYPTGETKEYPARAM )( HCRYPTKEY hKey, DWORD dwParam, BYTE* pbData,
DWORD* pdwDataLen, DWORD dwFlags );
typedef BOOL ( WINAPI *CRYPTGETPROVPARAM )( HCRYPTPROV hProv, DWORD dwParam,
BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags );
typedef BOOL ( WINAPI *CRYPTGETUSERKEY )( HCRYPTPROV hProv, DWORD dwKeySpec,
HCRYPTKEY* phUserKey );
typedef BOOL ( WINAPI *CRYPTHASHDATA )( HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen,
DWORD dwFlags );
typedef BOOL ( WINAPI *CRYPTIMPORTKEY )( HCRYPTPROV hProv, CONST BYTE *pbData,
DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey );
typedef BOOL ( WINAPI *CRYPTRELEASECONTEXT )( HCRYPTPROV hProv, DWORD dwFlags );
typedef BOOL ( WINAPI *CRYPTSETHASHPARAM )( HCRYPTHASH hHash, DWORD dwParam,
BYTE* pbData, DWORD dwFlags );
typedef BOOL ( WINAPI *CRYPTSETKEYPARAM )( HCRYPTKEY hKey, DWORD dwParam,
BYTE *pbData, DWORD dwFlags );
typedef BOOL ( WINAPI *CRYPTSIGNHASH )( HCRYPTHASH hHash, DWORD dwKeySpec,
LPCTSTR sDescription, DWORD dwFlags, BYTE* pbSignature,
DWORD* pdwSigLen );
static CERTADDCERTIFICATETOSTORE pCertAddCertificateContextToStore = NULL;
static CERTADDENCODEDCERTIFICATETOSTORE pCertAddEncodedCertificateToStore = NULL;
static CERTCREATECERTIFICATECONTEXT pCertCreateCertificateContext = NULL;
static CERTDELETECERTIFICATEFROMSTORE pCertDeleteCertificateFromStore = NULL;
static CERTCLOSESTORE pCertCloseStore = NULL;
static CERTFINDCERTIFICATEINSTORE pCertFindCertificateInStore = NULL;
static CERTFREECERTIFICATECHAIN pCertFreeCertificateChain = NULL;
static CERTFREECERTIFICATECONTEXT pCertFreeCertificateContext = NULL;
static CERTGETCERTIFICATECHAIN pCertGetCertificateChain = NULL;
static CERTGETCERTIFICATECONTEXTPROPERTY pCertGetCertificateContextProperty = NULL;
static CERTGETSUBJECTCERTIFICATEFROMSTORE pCertGetSubjectCertificateFromStore = NULL;
static CERTSETCERTIFICATEPROPERTY pCertSetCertificateContextProperty = NULL;
static CERTOPENSYSTEMSTORE pCertOpenSystemStore = NULL;
static CRYPTACQUIRECERTIFICATEPRIVATEKEY pCryptAcquireCertificatePrivateKey = NULL;
static CRYPTACQUIRECONTEXTA pCryptAcquireContextA = NULL;
static CRYPTCREATEHASH pCryptCreateHash = NULL;
static CRYPTDECRYPT pCryptDecrypt = NULL;
static CRYPTDESTROYHASH pCryptDestroyHash = NULL;
static CRYPTDESTROYKEY pCryptDestroyKey = NULL;
static CRYPTENCRYPT pCryptEncrypt = NULL;
static CRYPTEXPORTKEY pCryptExportKey = NULL;
static CRYPTFINDCERTIFICATEKEYPROVINFO pCryptFindCertificateKeyProvInfo = NULL;
static CRYPTGENKEY pCryptGenKey = NULL;
static CRYPTGENRANDOM pCryptGenRandom = NULL;
static CRYPTGETKEYPARAM pCryptGetKeyParam = NULL;
static CRYPTGETPROVPARAM pCryptGetProvParam = NULL;
static CRYPTGETUSERKEY pCryptGetUserKey = NULL;
static CRYPTHASHDATA pCryptHashData = NULL;
static CRYPTIMPORTKEY pCryptImportKey = NULL;
static CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
static CRYPTSETHASHPARAM pCryptSetHashParam = NULL;
static CRYPTSETKEYPARAM pCryptSetKeyParam = NULL;
static CRYPTSIGNHASH pCryptSignHash = NULL;
/* Dynamically load and unload any necessary DBMS libraries */
int deviceInitCryptoAPI( void )
{
/* If the CryptoAPI module is already linked in, don't do anything */
if( hCryptoAPI != NULL_HINSTANCE )
return( CRYPT_OK );
/* Obtain handles to the modules containing the CryptoAPI functions */
if( ( hAdvAPI32 = GetModuleHandle( "AdvAPI32.DLL" ) ) == NULL )
return( CRYPT_ERROR );
if( ( hCryptoAPI = LoadLibrary( "Crypt32.dll" ) ) == NULL_HINSTANCE )
return( CRYPT_ERROR );
/* Get pointers to the crypt functions */
pCryptAcquireCertificatePrivateKey = ( CRYPTACQUIRECERTIFICATEPRIVATEKEY ) GetProcAddress( hCryptoAPI, "CryptAcquireCertificatePrivateKey" );
pCryptAcquireContextA = ( CRYPTACQUIRECONTEXTA ) GetProcAddress( hAdvAPI32, "CryptAcquireContextA" );
pCryptCreateHash = ( CRYPTCREATEHASH ) GetProcAddress( hAdvAPI32, "CryptCreateHash" );
pCryptDecrypt = ( CRYPTDECRYPT ) GetProcAddress( hAdvAPI32, "CryptDecrypt" );
pCryptDestroyHash = ( CRYPTDESTROYHASH ) GetProcAddress( hAdvAPI32, "CryptDestroyHash" );
pCryptDestroyKey = ( CRYPTDESTROYKEY ) GetProcAddress( hAdvAPI32, "CryptDestroyKey" );
pCryptEncrypt = ( CRYPTENCRYPT ) GetProcAddress( hAdvAPI32, "CryptEncrypt" );
pCryptExportKey = ( CRYPTEXPORTKEY ) GetProcAddress( hAdvAPI32, "CryptExportKey" );
pCryptFindCertificateKeyProvInfo = ( CRYPTFINDCERTIFICATEKEYPROVINFO ) GetProcAddress( hCryptoAPI, "CryptFindCertificateKeyProvInfo" );
pCryptGenKey = ( CRYPTGENKEY ) GetProcAddress( hAdvAPI32, "CryptGenKey" );
pCryptGenRandom = ( CRYPTGENRANDOM ) GetProcAddress( hAdvAPI32, "CryptGenRandom" );
pCryptGetKeyParam = ( CRYPTGETKEYPARAM ) GetProcAddress( hAdvAPI32, "CryptGetKeyParam" );
pCryptGetProvParam = ( CRYPTGETPROVPARAM ) GetProcAddress( hAdvAPI32, "CryptGetProvParam" );
pCryptGetUserKey = ( CRYPTGETUSERKEY ) GetProcAddress( hAdvAPI32, "CryptGetUserKey" );
pCryptHashData = ( CRYPTHASHDATA ) GetProcAddress( hAdvAPI32, "CryptHashData" );
pCryptImportKey = ( CRYPTIMPORTKEY ) GetProcAddress( hAdvAPI32, "CryptImportKey" );
pCryptReleaseContext = ( CRYPTRELEASECONTEXT ) GetProcAddress( hAdvAPI32, "CryptReleaseContext" );
pCryptSetHashParam = ( CRYPTSETHASHPARAM ) GetProcAddress( hAdvAPI32, "CryptSetHashParam" );
pCryptSetKeyParam = ( CRYPTSETKEYPARAM ) GetProcAddress( hAdvAPI32, "CryptSetKeyParam" );
pCryptSignHash = ( CRYPTSIGNHASH ) GetProcAddress( hAdvAPI32, "CryptSignHashA" );
/* Get pointers to the cert functions */
pCertAddCertificateContextToStore = ( CERTADDCERTIFICATETOSTORE ) GetProcAddress( hCryptoAPI, "CertAddCertificateContextToStore" );
pCertAddEncodedCertificateToStore = ( CERTADDENCODEDCERTIFICATETOSTORE ) GetProcAddress( hCryptoAPI, "CertAddEncodedCertificateToStore" );
pCertCreateCertificateContext = ( CERTCREATECERTIFICATECONTEXT ) GetProcAddress( hCryptoAPI, "CertCreateCertificateContext" );
pCertDeleteCertificateFromStore = ( CERTDELETECERTIFICATEFROMSTORE ) GetProcAddress( hCryptoAPI, "CertDeleteCertificateFromStore" );
pCertCloseStore = ( CERTCLOSESTORE ) GetProcAddress( hCryptoAPI, "CertCloseStore" );
pCertFindCertificateInStore = ( CERTFINDCERTIFICATEINSTORE ) GetProcAddress( hCryptoAPI, "CertFindCertificateInStore" );
pCertFreeCertificateChain = ( CERTFREECERTIFICATECHAIN ) GetProcAddress( hCryptoAPI, "CertFreeCertificateChain" );
pCertFreeCertificateContext = ( CERTFREECERTIFICATECONTEXT ) GetProcAddress( hCryptoAPI, "CertFreeCertificateContext" );
pCertGetCertificateChain = ( CERTGETCERTIFICATECHAIN ) GetProcAddress( hCryptoAPI, "CertGetCertificateChain" );
pCertGetCertificateContextProperty = ( CERTGETCERTIFICATECONTEXTPROPERTY ) GetProcAddress( hCryptoAPI, "CertGetCertificateContextProperty" );
pCertGetSubjectCertificateFromStore = ( CERTGETSUBJECTCERTIFICATEFROMSTORE ) GetProcAddress( hCryptoAPI, "CertGetSubjectCertificateFromStore" );
pCertSetCertificateContextProperty = ( CERTSETCERTIFICATEPROPERTY ) GetProcAddress( hCryptoAPI, "CertSetCertificateContextProperty" );
pCertOpenSystemStore = ( CERTOPENSYSTEMSTORE ) GetProcAddress( hCryptoAPI, "CertOpenSystemStoreA" );
/* Make sure that we got valid pointers for every CryptoAPI function */
if( pCertAddCertificateContextToStore == NULL || \
pCertAddEncodedCertificateToStore == NULL ||
pCertCreateCertificateContext == NULL ||
pCertDeleteCertificateFromStore == NULL ||
pCertCloseStore == NULL || pCertFindCertificateInStore == NULL ||
pCertFreeCertificateChain == NULL ||
pCertFreeCertificateContext == NULL ||
pCertGetCertificateChain == NULL ||
pCertGetCertificateContextProperty == NULL ||
pCertGetSubjectCertificateFromStore == NULL ||
pCertSetCertificateContextProperty == NULL ||
pCertOpenSystemStore == NULL ||
pCryptAcquireCertificatePrivateKey == NULL ||
pCryptAcquireContextA == NULL || pCryptCreateHash == NULL ||
pCryptDecrypt == NULL || pCryptEncrypt == NULL ||
pCryptExportKey == NULL || pCryptDestroyHash == NULL ||
pCryptDestroyKey == NULL ||
pCryptFindCertificateKeyProvInfo == NULL || pCryptGenKey == NULL ||
pCryptGenRandom == NULL || pCryptGetKeyParam == NULL ||
pCryptGetProvParam == NULL || pCryptGetUserKey == NULL ||
pCryptHashData == NULL || pCryptImportKey == NULL ||
pCryptReleaseContext == NULL || pCryptSetHashParam == NULL ||
pCryptSetKeyParam == NULL || pCryptSignHash == NULL )
{
/* Free the library reference and reset the handle */
FreeLibrary( hCryptoAPI );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -