//wcrypt2.pas<br>{******************************************************************}<br>{ }<br>{ Borland Delphi Runtime Library }<br>{ Cryptographic API interface unit }<br>{ }<br>{ Portions created by Microsoft are }<br>{ Copyright (C) 1993-1998 Microsoft Corporation. }<br>{ All Rights Reserved. }<br>{ }<br>{ The original file is: wincrypt.h, 1992 - 1997 }<br>{ The original Pascal code is: wcrypt2.pas, released 01 Jan 1998 }<br>{ The initial developer of the Pascal code is }<br>{ Massimo Maria Ghisalberti (nissl@dada.it) }<br>{ }<br>{ Portions created by Massimo Maria Ghisalberti are }<br>{ Copyright (C) 1997-1998 Massimo Maria Ghisalberti }<br>{ }<br>{ Contributor(s): }<br>{ Peter Tang (peter.tang@citicorp.com) }<br>{ Phil Shrimpton (phil@shrimpton.co.uk) }<br>{ }<br>{ Obtained through: }<br>{ }<br>{ Joint Endeavour of Delphi Innovators (Project JEDI) }<br>{ }<br>{ You may retrieve the latest version of this file at the Project }<br>{ JEDI home page, located at http://delphi-jedi.org }<br>{ }<br>{ The contents of this file are used with permission, subject to }<br>{ the Mozilla Public License Version 1.1 (the "License"
; you may }<br>{ not use this file except in compliance with the License. You may }<br>{ obtain a copy of the License at }<br>{ http://www.mozilla.org/MPL/MPL-1.1.html }<br>{ }<br>{ Software distributed under the License is distributed on an }<br>{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }<br>{ implied. See the License for the specific language governing }<br>{ rights and limitations under the License. }<br>{ }<br>{******************************************************************}<br><br>unit wcrypt2;<br><br>{.DEFINE NT5}<br><br>{$ALIGN ON}<br><br>{$IFNDEF VER90}<br> {$WEAKPACKAGEUNIT}<br>{$ENDIF}<br><br>interface<br><br>uses<br> Windows<br> {$IFDEF VER90}<br> ,Ole2<br> {$ENDIF};<br><br>const<br> ADVAPI32 = 'advapi32.dll';<br> CRYPT32 = 'crypt32.dll';<br> SOFTPUB = 'softpub.dll';<br>{$IFDEF NT5}<br> ADVAPI32NT5 = 'advapi32.dll';<br>{$ENDIF}<br><br>{Support Type}<br><br>type<br> PVOID = Pointer;<br> LONG = DWORD;<br> {$IFDEF UNICODE}<br> LPAWSTR = PWideChar;<br> {$ELSE}<br> LPAWSTR = PAnsiChar;<br> {$ENDIF}<br><br>//-----------------------------------------------------------------------------<br> // Type support for a pointer to an array of pointer (type **name)<br> PLPSTR = Pointer; // type for a pointer to Array of pointer a type<br> PPCERT_INFO = Pointer; // type for a pointer to Array of pointer a type<br> PPVOID = Pointer; // type for a pointer to Array of pointer a type<br> PPCCERT_CONTEXT = Pointer; // type for a pointer to Array of pointer a type<br> PPCCTL_CONTEXT = Pointer; // type for a pointer to Array of pointer a type<br> PPCCRL_CONTEXT = Pointer; // type for a pointer to Array of pointer a type<br>//-----------------------------------------------------------------------------<br><br>//+---------------------------------------------------------------------------<br>//<br>// Microsoft Windows<br>// Copyright (C) Microsoft Corporation, 1992 - 1997.<br>//<br>// File: wincrypt.h<br>//<br>// Contents: Cryptographic API Prototypes and Definitions<br>//<br>//----------------------------------------------------------------------------<br><br><br>//<br>// Algorithm IDs and Flags<br>//<br><br>// ALG_ID crackers<br>function GET_ALG_CLASS(x:integer) :integer;<br>function GET_ALG_TYPE(x:integer) :integer;<br>function GET_ALG_SID(x:integer) :integer;<br><br>Const<br> // Algorithm classes<br> ALG_CLASS_ANY = 0;<br> ALG_CLASS_SIGNATURE = (1 shl 13);<br> ALG_CLASS_MSG_ENCRYPT = (2 shl 13);<br> ALG_CLASS_DATA_ENCRYPT = (3 shl 13);<br> ALG_CLASS_HASH = (4 shl 13);<br> ALG_CLASS_KEY_EXCHANGE = (5 shl 13);<br><br> // Algorithm types<br> ALG_TYPE_ANY = 0;<br> ALG_TYPE_DSS = (1 shl 9);<br> ALG_TYPE_RSA = (2 shl 9);<br> ALG_TYPE_BLOCK = (3 shl 9);<br> ALG_TYPE_STREAM = (4 shl 9);<br> ALG_TYPE_DH = (5 shl 9);<br> ALG_TYPE_SECURECHANNEL = (6 shl 9);<br><br> // Generic sub-ids<br> ALG_SID_ANY = 0;<br><br> // Some RSA sub-ids<br> ALG_SID_RSA_ANY = 0;<br> ALG_SID_RSA_PKCS = 1;<br> ALG_SID_RSA_MSATWORK = 2;<br> ALG_SID_RSA_ENTRUST = 3;<br> ALG_SID_RSA_PGP = 4;<br><br> // Some DSS sub-ids<br> ALG_SID_DSS_ANY = 0;<br> ALG_SID_DSS_PKCS = 1;<br> ALG_SID_DSS_DMS = 2;<br><br> // Block cipher sub ids<br> // DES sub_ids<br> ALG_SID_DES = 1;<br> ALG_SID_3DES = 3;<br> ALG_SID_DESX = 4;<br> ALG_SID_IDEA = 5;<br> ALG_SID_CAST = 6;<br> ALG_SID_SAFERSK64 = 7;<br> ALD_SID_SAFERSK128 = 8;<br> ALG_SID_SAFERSK128 = 8;<br> ALG_SID_3DES_112 = 9;<br> ALG_SID_CYLINK_MEK = 12;<br> ALG_SID_RC5 = 13;<br><br> // Fortezza sub-ids<br> ALG_SID_SKIPJACK = 10;<br> ALG_SID_TEK = 11;<br><br> // KP_MODE<br> CRYPT_MODE_CBCI = 6; {ANSI CBC Interleaved}<br> CRYPT_MODE_CFBP = 7; {ANSI CFB Pipelined}<br> CRYPT_MODE_OFBP = 8; {ANSI OFB Pipelined}<br> CRYPT_MODE_CBCOFM = 9; {ANSI CBC + OF Masking}<br> CRYPT_MODE_CBCOFMI = 10; {ANSI CBC + OFM Interleaved}<br><br> // RC2 sub-ids<br> ALG_SID_RC2 = 2;<br><br> // Stream cipher sub-ids<br> ALG_SID_RC4 = 1;<br> ALG_SID_SEAL = 2;<br><br> // Diffie-Hellman sub-ids<br> ALG_SID_DH_SANDF = 1;<br> ALG_SID_DH_EPHEM = 2;<br> ALG_SID_AGREED_KEY_ANY = 3;<br> ALG_SID_KEA = 4;<br><br> // Hash sub ids<br> ALG_SID_MD2 = 1;<br> ALG_SID_MD4 = 2;<br> ALG_SID_MD5 = 3;<br> ALG_SID_SHA = 4;<br> ALG_SID_SHA1 = 4;<br> ALG_SID_MAC = 5;<br> ALG_SID_RIPEMD = 6;<br> ALG_SID_RIPEMD160 = 7;<br> ALG_SID_SSL3SHAMD5 = 8;<br> ALG_SID_HMAC = 9;<br><br> // secure channel sub ids<br> ALG_SID_SSL3_MASTER = 1;<br> ALG_SID_SCHANNEL_MASTER_HASH = 2;<br> ALG_SID_SCHANNEL_MAC_KEY = 3;<br> ALG_SID_PCT1_MASTER = 4;<br> ALG_SID_SSL2_MASTER = 5;<br> ALG_SID_TLS1_MASTER = 6;<br> ALG_SID_SCHANNEL_ENC_KEY = 7;<br><br> // Our silly example sub-id<br> ALG_SID_EXAMPLE = 80;<br><br>{$IFNDEF ALGIDDEF}<br> {$DEFINE ALGIDDEF}<br>Type ALG_ID = ULONG;<br>{$ENDIF}<br><br>// algorithm identifier definitions<br>Const<br> CALG_MD2 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD2);<br> CALG_MD4 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD4);<br> CALG_MD5 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD5);<br> CALG_SHA = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_SHA);<br> CALG_SHA1 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_SHA1);<br> CALG_MAC = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MAC);<br> CALG_RSA_SIGN = (ALG_CLASS_SIGNATURE or ALG_TYPE_RSA or ALG_SID_RSA_ANY);<br> CALG_DSS_SIGN = (ALG_CLASS_SIGNATURE or ALG_TYPE_DSS or ALG_SID_DSS_ANY);<br> CALG_RSA_KEYX = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_RSA or ALG_SID_RSA_ANY);<br> CALG_DES = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_DES);<br> CALG_3DES_112 = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_3DES_112);<br> CALG_3DES = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_3DES);<br> CALG_RC2 = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_RC2);<br> CALG_RC4 = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_STREAM or ALG_SID_RC4);<br> CALG_SEAL = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_STREAM or ALG_SID_SEAL);<br> CALG_DH_SF = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_DH_SANDF);<br> CALG_DH_EPHEM = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_DH_EPHEM);<br> CALG_AGREEDKEY_ANY = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_AGREED_KEY_ANY);<br> CALG_KEA_KEYX = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_KEA);<br> CALG_HUGHES_MD5 = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_ANY or ALG_SID_MD5);<br> CALG_SKIPJACK = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_SKIPJACK);<br> CALG_TEK = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_TEK);<br> CALG_CYLINK_MEK = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_CYLINK_MEK);<br> CALG_SSL3_SHAMD5 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_SSL3SHAMD5);<br> CALG_SSL3_MASTER = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SSL3_MASTER);<br> CALG_SCHANNEL_MASTER_HASH = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SCHANNEL_MASTER_HASH);<br> CALG_SCHANNEL_MAC_KEY = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SCHANNEL_MAC_KEY);<br> CALG_SCHANNEL_ENC_KEY = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SCHANNEL_ENC_KEY);<br> CALG_PCT1_MASTER = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_PCT1_MASTER);<br> CALG_SSL2_MASTER = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SSL2_MASTER);<br> CALG_TLS1_MASTER = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_TLS1_MASTER);<br> CALG_RC5 = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_RC5);<br> CALG_HMAC = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_HMAC);<br><br>type<br> PVTableProvStruc = ^VTableProvStruc;<br> VTableProvStruc = record<br> Version
WORD;<br> FuncVerifyImage :TFarProc;<br> FuncReturnhWnd :TFarProc;<br> dwProvType
WORD;<br> pbContextInfo
BYTE;<br> cbContextInfo
WORD;<br>end;<br><br>//type HCRYPTPROV = ULONG;<br>//type HCRYPTKEY = ULONG;<br>//type HCRYPTHASH = ULONG;<br><br><br>const<br> // dwFlags definitions for CryptAcquireContext<br> CRYPT_VERIFYCONTEXT = $F0000000;<br> CRYPT_NEWKEYSET = $00000008;<br> CRYPT_DELETEKEYSET = $00000010;<br> CRYPT_MACHINE_KEYSET = $00000020;<br><br> // dwFlag definitions for CryptGenKey<br> CRYPT_EXPORTABLE = $00000001;<br> CRYPT_USER_PROTECTED = $00000002;<br> CRYPT_CREATE_SALT = $00000004;<br> CRYPT_UPDATE_KEY = $00000008;<br> CRYPT_NO_SALT = $00000010;<br> CRYPT_PREGEN = $00000040;<br> CRYPT_RECIPIENT = $00000010;<br> CRYPT_INITIATOR = $00000040;<br> CRYPT_ONLINE = $00000080;<br> CRYPT_SF = $00000100;<br> CRYPT_CREATE_IV = $00000200;<br> CRYPT_KEK = $00000400;<br> CRYPT_DATA_KEY = $00000800;<br><br> // dwFlags definitions for CryptDeriveKey<br> CRYPT_SERVER = $00000400;<br><br> KEY_LENGTH_MASK = $FFFF0000;<br><br> // dwFlag definitions for CryptExportKey<br> CRYPT_Y_ONLY = $00000001;<br> CRYPT_SSL2_SLUMMING = $00000002;<br><br> // dwFlags definitions for CryptHashSessionKey<br> CRYPT_LITTLE_ENDIAN = $00000001;<br><br> // dwFlag definitions for CryptSetProviderEx and CryptGetDefaultProvider<br> CRYPT_MACHINE_DEFAULT = $00000001;<br> CRYPT_USER_DEFAULT = $00000002;<br> CRYPT_DELETE_DEFAULT = $00000004;<br><br> // exported key blob definitions<br> SIMPLEBLOB = $1;<br> PUBLICKEYBLOB = $6;<br> PRIVATEKEYBLOB = $7;<br> PLAINTEXTKEYBLOB = $8;<br> AT_KEYEXCHANGE = 1;<br> AT_SIGNATURE = 2;<br> CRYPT_USERDATA = 1;<br><br> // dwParam<br> KP_IV = 1; // Initialization vector<br> KP_SALT = 2; // Salt value<br> KP_PADDING = 3; // Padding values<br> KP_MODE = 4; // Mode of the cipher<br> KP_MODE_BITS = 5; // Number of bits to feedback<br> KP_PERMISSIONS = 6; // Key permissions DWORD<br> KP_ALGID = 7; // Key algorithm<br> KP_BLOCKLEN = 8; // Block size of the cipher<br> KP_KEYLEN = 9; // Length of key in bits<br> KP_SALT_EX = 10; // Length of salt in bytes<br> KP_P = 11; // DSS/Diffie-Hellman P value<br> KP_G = 12; // DSS/Diffie-Hellman G value<br> KP_Q = 13; // DSS Q value<br> KP_X = 14; // Diffie-Hellman X value<br> KP_Y = 15; // Y value<br> KP_RA = 16; // Fortezza RA value<br> KP_RB = 17; // Fortezza RB value<br> KP_INFO = 18; // for putting information into an RSA envelope<br> KP_EFFECTIVE_KEYLEN = 19; // setting and getting RC2 effective key length<br> KP_SCHANNEL_ALG = 20; // for setting the Secure Channel algorithms<br> KP_CLIENT_RANDOM = 21; // for setting the Secure Channel client random data<br> KP_SERVER_RANDOM = 22; // for setting the Secure Channel server random data<br> KP_RP = 23;<br> KP_PRECOMP_MD5 = 24;<br> KP_PRECOMP_SHA = 25;<br> KP_CERTIFICATE = 26; // for setting Secure Channel certificate data (PCT1)<br> KP_CLEAR_KEY = 27; // for setting Secure Channel clear key data (PCT1)<br> KP_PUB_EX_LEN = 28;<br> KP_PUB_EX_VAL = 29;<br><br> // KP_PADDING<br> PKCS5_PADDING = 1; {PKCS 5 (sec 6.2) padding method}<br> RANDOM_PADDING = 2;<br> ZERO_PADDING = 3;<br><br> // KP_MODE<br> CRYPT_MODE_CBC = 1; // Cipher block chaining<br> CRYPT_MODE_ECB = 2; // Electronic code book<br> CRYPT_MODE_OFB = 3; // Output feedback mode<br> CRYPT_MODE_CFB = 4; // Cipher feedback mode<br> CRYPT_MODE_CTS = 5; // Ciphertext stealing mode<br><br> // KP_PERMISSIONS<br> CRYPT_ENCRYPT = $0001; // Allow encryption<br> CRYPT_DECRYPT = $0002; // Allow decryption<br> CRYPT_EXPORT = $0004; // Allow key to be exported<br> CRYPT_READ = $0008; // Allow parameters to be read<br> CRYPT_WRITE = $0010; // Allow parameters to be set<br> CRYPT_MAC = $0020; // Allow MACs to be used with key<br> CRYPT_EXPORT_KEY = $0040; // Allow key to be used for exporting keys<br> CRYPT_IMPORT_KEY = $0080; // Allow key to be used for importing keys<br><br> HP_ALGID = $0001; // Hash algorithm<br> HP_HASHVAL = $0002; // Hash value<br> HP_HASHSIZE = $0004; // Hash value size<br><br> HP_HMAC_INFO = $0005; // information for creating an HMAC<br><br> CRYPT_FAILED = FALSE;<br> CRYPT_SUCCEED = TRUE;<br><br>function RCRYPT_SUCCEEDED(rt:BOOL):BOOL;<br>function RCRYPT_FAILED(rt:BOOL):BOOL;<br><br>const<br> // CryptGetProvParam<br> PP_ENUMALGS = 1;<br> PP_ENUMCONTAINERS = 2;<br> PP_IMPTYPE = 3;<br> PP_NAME = 4;<br> PP_VERSION = 5;<br> PP_CONTAINER = 6;<br> PP_CHANGE_PASSWORD = 7;<br> PP_KEYSET_SEC_DESCR = 8; // get/set security descriptor of keyset<br> PP_CERTCHAIN = 9; // for retrieving certificates from tokens<br> PP_KEY_TYPE_SUBTYPE = 10;<br> PP_PROVTYPE = 16;<br> PP_KEYSTORAGE = 17;<br> PP_APPLI_CERT = 18;<br> PP_SYM_KEYSIZE = 19;<br> PP_SESSION_KEYSIZE = 20;<br> PP_UI_PROMPT = 21;<br> PP_ENUMALGS_EX = 22;<br> CRYPT_FIRST = 1;<br> CRYPT_NEXT = 2;<br> CRYPT_IMPL_HARDWARE = 1;<br> CRYPT_IMPL_SOFTWARE = 2;<br> CRYPT_IMPL_MIXED = 3;<br> CRYPT_IMPL_UNKNOWN = 4;<br><br> // key storage flags<br> CRYPT_SEC_DESCR = $00000001;<br> CRYPT_PSTORE = $00000002;<br> CRYPT_UI_PROMPT = $00000004;<br><br> // protocol flags<br> CRYPT_FLAG_PCT1 = $0001;<br> CRYPT_FLAG_SSL2 = $0002;<br> CRYPT_FLAG_SSL3 = $0004;<br> CRYPT_FLAG_TLS1 = $0008;<br><br> // CryptSetProvParam<br> PP_CLIENT_HWND = 1;<br> PP_CONTEXT_INFO = 11;<br> PP_KEYEXCHANGE_KEYSIZE = 12;<br> PP_SIGNATURE_KEYSIZE = 13;<br> PP_KEYEXCHANGE_ALG = 14;<br> PP_SIGNATURE_ALG = 15;<br> PP_DELETEKEY = 24;<br><br> PROV_RSA_FULL = 1;<br> PROV_RSA_SIG = 2;<br> PROV_DSS = 3;<br> PROV_FORTEZZA = 4;<br> PROV_MS_EXCHANGE = 5;<br> PROV_SSL = 6;<br><br>PROV_RSA_SCHANNEL = 12;<br>PROV_DSS_DH = 13;<br>PROV_EC_ECDSA_SIG = 14;<br>PROV_EC_ECNRA_SIG = 15;<br>PROV_EC_ECDSA_FULL = 16;<br>PROV_EC_ECNRA_FULL = 17;<br>PROV_SPYRUS_LYNKS = 20;<br><br><br> // STT defined Providers<br> PROV_STT_MER = 7;<br> PROV_STT_ACQ = 8;<br> PROV_STT_BRND = 9;<br> PROV_STT_ROOT = 10;<br> PROV_STT_ISS = 11;<br><br> // Provider friendly names<br> MS_DEF_PROV_A = 'Microsoft Base Cryptographic Provider v1.0';<br> {$IFNDEF VER90}<br> MS_DEF_PROV_W = WideString( 'Microsoft Base Cryptographic Provider v1.0');<br> {$ELSE}<br> MS_DEF_PROV_W = ( 'Microsoft Base Cryptographic Provider v1.0');<br> {$ENDIF}<br><br>{$IFDEF UNICODE}<br> MS_DEF_PROV = MS_DEF_PROV_W;<br>{$ELSE}<br> MS_DEF_PROV = MS_DEF_PROV_A;<br>{$ENDIF}<br><br> MS_ENHANCED_PROV_A = 'Microsoft Enhanced Cryptographic Provider v1.0';<br> {$IFNDEF VER90}<br> MS_ENHANCED_PROV_W = WideString('Microsoft Enhanced Cryptographic Provider v1.0');<br> {$ELSE}<br> MS_ENHANCED_PROV_W = ('Microsoft Enhanced Cryptographic Provider v1.0');<br> {$ENDIF}<br><br>{$IFDEF UNICODE}<br> MS_ENHANCED_PROV = MS_ENHANCED_PROV_W;<br>{$ELSE}<br> MS_ENHANCED_PROV = MS_ENHANCED_PROV_A;<br>{$ENDIF}<br><br> MS_DEF_RSA_SIG_PROV_A = 'Microsoft RSA Signature Cryptographic Provider';<br> {$IFNDEF VER90}<br> MS_DEF_RSA_SIG_PROV_W = WideString('Microsoft RSA Signature Cryptographic Provider');<br> {$ELSE}<br> MS_DEF_RSA_SIG_PROV_W = ('Microsoft RSA Signature Cryptographic Provider');<br> {$ENDIF}<br><br>{$IFDEF UNICODE}<br> MS_DEF_RSA_SIG_PROV = MS_DEF_RSA_SIG_PROV_W;<br>{$ELSE}<br> MS_DEF_RSA_SIG_PROV = MS_DEF_RSA_SIG_PROV_A;<br>{$ENDIF}<br><br> MS_DEF_RSA_SCHANNEL_PROV_A = 'Microsoft Base RSA SChannel Cryptographic Provider';<br> {$IFNDEF VER90}<br> MS_DEF_RSA_SCHANNEL_PROV_W = WideString('Microsoft Base RSA SChannel Cryptographic Provider');<br> {$ELSE}<br> MS_DEF_RSA_SCHANNEL_PROV_W = ('Microsoft Base RSA SChannel Cryptographic Provider');<br> {$ENDIF}<br><br><br>{$IFDEF UNICODE}<br> MS_DEF_RSA_SCHANNEL_PROV = MS_DEF_RSA_SCHANNEL_PROV_W;<br>{$ELSE}<br> MS_DEF_RSA_SCHANNEL_PROV = MS_DEF_RSA_SCHANNEL_PROV_A;<br>{$ENDIF}<br><br> MS_ENHANCED_RSA_SCHANNEL_PROV_A = 'Microsoft Enhanced RSA SChannel Cryptographic Provider';<br> {$IFNDEF VER90}<br> MS_ENHANCED_RSA_SCHANNEL_PROV_W = WideString('Microsoft Enhanced RSA SChannel Cryptographic Provider');<br> {$ELSE}<br> MS_ENHANCED_RSA_SCHANNEL_PROV_W = ('Microsoft Enhanced RSA SChannel Cryptographic Provider');<br> {$ENDIF}<br><br>{$IFDEF UNICODE}<br> MS_ENHANCED_RSA_SCHANNEL_PROV = MS_ENHANCED_RSA_SCHANNEL_PROV_W;<br>{$ELSE}<br> MS_ENHANCED_RSA_SCHANNEL_PROV = MS_ENHANCED_RSA_SCHANNEL_PROV_A;<br>{$ENDIF}<br><br> MS_DEF_DSS_PROV_A = 'Microsoft Base DSS Cryptographic Provider';<br> {$IFNDEF VER90}<br> MS_DEF_DSS_PROV_W = WideString('Microsoft Base DSS Cryptographic Provider');<br> {$ELSE}<br> MS_DEF_DSS_PROV_W = ('Microsoft Base DSS Cryptographic Provider');<br> {$ENDIF}<br><br>{$IFDEF UNICODE}<br> MS_DEF_DSS_PROV = MS_DEF_DSS_PROV_W;<br>{$ELSE}<br> MS_DEF_DSS_PROV = MS_DEF_DSS_PROV_A;<br>{$ENDIF}<br><br> MS_DEF_DSS_DH_PROV_A = 'Microsoft Base DSS and Diffie-Hellman Cryptographic Provider';<br> {$IFNDEF VER90}<br> MS_DEF_DSS_DH_PROV_W = WideString('Microsoft Base DSS and Diffie-Hellman Cryptographic Provider');<br> {$ELSE}<br> MS_DEF_DSS_DH_PROV_W = ('Microsoft Base DSS and Diffie-Hellman Cryptographic Provider');<br> {$ENDIF}<br><br>{$IFDEF UNICODE}<br> MS_DEF_DSS_DH_PROV = MS_DEF_DSS_DH_PROV_W;<br>{$ELSE}<br> MS_DEF_DSS_DH_PROV = MS_DEF_DSS_DH_PROV_A;<br>{$ENDIF}<br><br> MAXUIDLEN = 64;<br> CUR_BLOB_VERSION = 2;<br><br>{structure for use with CryptSetHashParam with CALG_HMAC}<br>type<br> PHMAC_INFO = ^HMAC_INFO;<br> HMAC_INFO = record<br> HashAlgid :ALG_ID;<br> pbInnerString
BYTE;<br> cbInnerString
WORD;<br> pbOuterString
BYTE;<br> cbOuterString
WORD;<br> end;<br><br>// structure for use with CryptSetHashParam with CALG_HMAC<br>type<br> PSCHANNEL_ALG = ^SCHANNEL_ALG;<br> SCHANNEL_ALG = record<br> dwUse
WORD;<br> Algid :ALG_ID;<br> cBits
WORD;<br> end;<br><br>// uses of algortihms for SCHANNEL_ALG structure<br>const<br> SCHANNEL_MAC_KEY = $00000000;<br> SCHANNEL_ENC_KEY = $00000001;<br><br>type<br> PPROV_ENUMALGS = ^PROV_ENUMALGS;<br> PROV_ENUMALGS = record<br> aiAlgid :ALG_ID;<br> dwBitLen
WORD;<br> dwNameLen
WORD;<br> szName :array[0..20-1] of Char;<br> end ;<br><br>type<br> PPROV_ENUMALGS_EX = ^PROV_ENUMALGS_EX;<br> PROV_ENUMALGS_EX = record<br> aiAlgid :ALG_ID;<br> dwDefaultLen
WORD;<br> dwMinLen
WORD;<br> dwMaxLen
WORD;<br> dwProtocols
WORD;<br> dwNameLen
WORD;<br> szName :array[0..20-1] of Char;<br> dwLongNameLen
WORD;<br> szLongName :array[0..40-1] of Char;<br> end;<br><br>type<br> PPUBLICKEYSTRUC = ^PUBLICKEYSTRUC;<br> PUBLICKEYSTRUC = record<br> bType :BYTE;<br> bVersion :BYTE;<br> reserved :Word;<br> aiKeyAlg :ALG_ID;<br> end;<br><br>type<br> BLOBHEADER = PUBLICKEYSTRUC;<br> PBLOBHEADER = ^BLOBHEADER;<br><br>type<br> PRSAPUBKEY = ^RSAPUBKEY;<br> RSAPUBKEY = record<br> magic
WORD; // Has to be RSA1<br> bitlen
WORD; // # of bits in modulus<br> pubexp
WORD; // public exponent<br> // Modulus data follows<br> end;<br><br>type<br> PPUBKEY = ^PUBKEY;<br> PUBKEY = record<br> magic
WORD;<br> bitlen
WORD; // # of bits in modulus<br> end;<br><br>type<br> DHPUBKEY = PUBKEY;<br> DSSPUBKEY = PUBKEY;<br> KEAPUBKEY = PUBKEY;<br> TEKPUBKEY = PUBKEY;<br><br><br>type<br> PDSSSEED = ^DSSSEED;<br> DSSSEED = record<br> counter
WORD;<br> seed :array[0..20-1] of BYTE;<br> end;<br><br>type<br> PKEY_TYPE_SUBTYPE = ^KEY_TYPE_SUBTYPE;<br> KEY_TYPE_SUBTYPE = record<br> dwKeySpec
WORD;<br> Type_ :TGUID; {conflict with base Delphi type: original name 'Type'}<br> Subtype :TGUID;<br> end;<br><br>type<br> HCRYPTPROV = ULONG;<br> PHCRYPTPROV = ^HCRYPTPROV;<br> HCRYPTKEY = ULONG;<br> PHCRYPTKEY = ^HCRYPTKEY;<br> HCRYPTHASH = ULONG;<br> PHCRYPTHASH = ^HCRYPTHASH;<br><br>function CryptAcquireContextA(phProv
HCRYPTPROV;<br> pszContainer
AnsiChar;<br> pszProvider
AnsiChar;<br> dwProvType
WORD;<br> dwFlags
WORD) :BOOL;stdcall;<br><br>function CryptAcquireContext(phProv
HCRYPTPROV;<br> pszContainer :LPAWSTR;<br> pszProvider :LPAWSTR;<br> dwProvType
WORD;<br> dwFlags
WORD) :BOOL;stdcall;<br><br>function CryptAcquireContextW(phProv
HCRYPTPROV;<br> pszContainer
WideChar;<br> pszProvider
WideChar;<br> dwProvType
WORD;<br> dwFlags
WORD) :BOOL ;stdcall;<br><br><br>function CryptReleaseContext(hProv :HCRYPTPROV;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br><br>function CryptGenKey(hProv :HCRYPTPROV;<br> Algid :ALG_ID;<br> dwFlags
WORD;<br> phKey
HCRYPTKEY) :BOOL;stdcall ;<br><br><br>function CryptDeriveKey(hProv :HCRYPTPROV;<br> Algid :ALG_ID;<br> hBaseData :HCRYPTHASH;<br> dwFlags
WORD;<br> phKey
HCRYPTKEY) :BOOL;stdcall ;<br><br><br><br>function CryptDestroyKey(hKey :HCRYPTKEY) :BOOL;stdcall ;<br><br><br>function CryptSetKeyParam(hKey :HCRYPTKEY;<br> dwParam
WORD;<br> pbData
BYTE;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptGetKeyParam(hKey :HCRYPTKEY;<br> dwParam
WORD;<br> pbData
BYTE;<br> pdwDataLen
DWORD;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptSetHashParam(hHash :HCRYPTHASH;<br> dwParam
WORD;<br> pbData
BYTE;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptGetHashParam(hHash :HCRYPTHASH;<br> dwParam
WORD;<br> pbData
BYTE;<br> pdwDataLen
DWORD;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptSetProvParam(hProv :HCRYPTPROV;<br> dwParam
WORD;<br> pbData
BYTE;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptGetProvParam(hProv :HCRYPTPROV;<br> dwParam
WORD;<br> pbData
BYTE;<br> pdwDataLen
DWORD;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptGenRandom(hProv :HCRYPTPROV;<br> dwLen
WORD;<br> pbBuffer
BYTE) :BOOL;stdcall;<br><br><br>function CryptGetUserKey(hProv :HCRYPTPROV;<br> dwKeySpec
WORD;<br> phUserKey
HCRYPTKEY) :BOOL;stdcall;<br><br><br>function CryptExportKey(hKey :HCRYPTKEY;<br> hExpKey :HCRYPTKEY;<br> dwBlobType
WORD;<br> dwFlags
WORD;<br> pbData
BYTE;<br> pdwDataLen
DWORD) :BOOL;stdcall;<br><br><br>function CryptImportKey(hProv :HCRYPTPROV;<br> pbData
BYTE;<br> dwDataLen
WORD;<br> hPubKey :HCRYPTKEY;<br> dwFlags
WORD;<br> phKey
HCRYPTKEY) :BOOL;stdcall;<br><br><br>function CryptEncrypt(hKey :HCRYPTKEY;<br> hHash :HCRYPTHASH;<br> Final :BOOL;<br> dwFlags
WORD;<br> pbData
BYTE;<br> pdwDataLen
DWORD;<br> dwBufLen
WORD) :BOOL;stdcall;<br><br><br>function CryptDecrypt(hKey :HCRYPTKEY;<br> hHash :HCRYPTHASH;<br> Final :BOOL;<br> dwFlags
WORD;<br> pbData
BYTE;<br> pdwDataLen
DWORD) :BOOL;stdcall;<br><br><br>function CryptCreateHash(hProv :HCRYPTPROV;<br> Algid :ALG_ID;<br> hKey :HCRYPTKEY;<br> dwFlags
WORD;<br> phHash
HCRYPTHASH) :BOOL;stdcall;<br><br><br>function CryptHashData(hHash :HCRYPTHASH;<br> const pbData
BYTE;<br> dwDataLen
WORD;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptHashSessionKey(hHash :HCRYPTHASH;<br> hKey :HCRYPTKEY;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptDestroyHash(hHash :HCRYPTHASH) :BOOL;stdcall;<br><br><br>function CryptSignHashA(hHash :HCRYPTHASH;<br> dwKeySpec
WORD;<br> sDescription
AnsiChar;<br> dwFlags
WORD;<br> pbSignature
BYTE;<br> pdwSigLen
DWORD) :BOOL;stdcall;<br><br><br>function CryptSignHash(hHash :HCRYPTHASH;<br> dwKeySpec
WORD;<br> sDescription :LPAWSTR;<br> dwFlags
WORD;<br> pbSignature
BYTE;<br> pdwSigLen
DWORD) :BOOL;stdcall;<br><br>function CryptSignHashW(hHash :HCRYPTHASH;<br> dwKeySpec
WORD;<br> sDescription
WideChar;<br> dwFlags
WORD;<br> pbSignature
BYTE;<br> pdwSigLen
DWORD) :BOOL;stdcall;<br><br>function CryptSignHashU(hHash :HCRYPTHASH;<br> dwKeySpec
WORD;<br> sDescription
WideChar;<br> dwFlags
WORD;<br> pbSignature
BYTE;<br> pdwSigLen
DWORD) :BOOL;stdcall;<br><br>function CryptVerifySignatureA(hHash :HCRYPTHASH;<br> const pbSignature
BYTE;<br> dwSigLen
WORD;<br> hPubKey :HCRYPTKEY;<br> sDescription
AnsiChar;<br> dwFlags
WORD) :BOOL;stdcall;<br><br>function CryptVerifySignature(hHash :HCRYPTHASH;<br> const pbSignature
BYTE;<br> dwSigLen
WORD;<br> hPubKey :HCRYPTKEY;<br> sDescription :LPAWSTR;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptVerifySignatureW(hHash :HCRYPTHASH;<br> const pbSignature
BYTE;<br> dwSigLen
WORD;<br> hPubKey :HCRYPTKEY;<br> sDescription
WideChar;<br> dwFlags
WORD) :BOOL;stdcall;<br><br><br>function CryptSetProviderA(pszProvName
AnsiChar;<br> dwProvType
WORD) :BOOL;stdcall;<br><br>function CryptSetProvider(pszProvName :LPAWSTR;<br> dwProvType
WORD) :BOOL;stdcall;<br><br>function CryptSetProviderW(pszProvName
WideChar;<br> dwProvType
WORD) :BOOL;stdcall;<br><br>function CryptSetProviderU(pszProvName
WideChar;<br> dwProvType
WORD) :BOOL;stdcall;<br><br>{$IFDEF NT5}<br><br>function CryptSetProviderExA(pszProvName :LPCSTR;<br> dwProvType
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD):BOOL;stdcall;<br><br>function CryptSetProviderExW(pszProvName :LPCWSTR;<br> dwProvType
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD):BOOL;stdcall;<br><br>function CryptSetProviderEx(pszProvName :LPAWSTR;<br> dwProvType
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD):BOOL;stdcall;<br><br><br>function CryptGetDefaultProviderA(dwProvType
WORD;<br> pdwReserved
WORD;<br> dwFlags
WORD;<br> pszProvName :LPSTR;<br> pcbProvName
DWORD):BOOL ; stdcall;<br><br>function CryptGetDefaultProviderW(dwProvType
WORD;<br> pdwReserved
WORD;<br> dwFlags
WORD;<br> pszProvName :LPWSTR;<br> pcbProvName
DWORD):BOOL ; stdcall;<br><br>function CryptGetDefaultProvider(dwProvType
WORD;<br> pdwReserved
WORD;<br> dwFlags
WORD;<br> pszProvName :LPAWSTR;<br> pcbProvName
DWORD):BOOL ; stdcall;<br><br>function CryptEnumProviderTypesA(dwIndex
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD;<br> pdwProvType
DWORD;<br> pszTypeName :LPSTR;<br> pcbTypeName
DWORD):BOOL ; stdcall;<br><br>function CryptEnumProviderTypesW(dwIndex
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD;<br> pdwProvType
DWORD;<br> pszTypeName :LPWSTR;<br> pcbTypeName
DWORD):BOOL ; stdcall;<br><br>function CryptEnumProviderTypes(dwIndex
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD;<br> pdwProvType
DWORD;<br> pszTypeName :LPAWSTR;<br> pcbTypeName
DWORD):BOOL ; stdcall;<br><br>function CryptEnumProvidersA(dwIndex
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD;<br> pdwProvType
DWORD;<br> pszProvName :LPSTR;<br> pcbProvName
DWORD):BOOL ; stdcall;<br><br>function CryptEnumProvidersW(dwIndex
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD;<br> pdwProvType
DWORD;<br> pszProvName :LPWSTR;<br> pcbProvName
DWORD):BOOL ; stdcall;<br><br>function CryptEnumProviders(dwIndex
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD;<br> pdwProvType
DWORD;<br> pszProvName :LPAWSTR;<br> pcbProvName
DWORD):BOOL ; stdcall;<br><br>function CryptContextAddRef(hProv :HCRYPTPROV;<br> pdwReserved
DWORD;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>function CryptDuplicateKey(hKey :HCRYPTKEY;<br> pdwReserved
DWORD;<br> dwFlags
WORD;<br> phKey
HCRYPTKEY):BOOL ; stdcall;<br><br>function CryptDuplicateHash(hHash :HCRYPTHASH;<br> pdwReserved
DWORD;<br> dwFlags
WORD;<br> phHash
HCRYPTHASH):BOOL ; stdcall;<br><br>{$ENDIF NT5}<br><br>function CryptEnumProvidersU(dwIndex
WORD;<br> pdwReserved
DWORD;<br> dwFlags
WORD;<br> pdwProvType
DWORD;<br> pszProvName :LPWSTR;<br> pcbProvName
DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// CRYPTOAPI BLOB definitions<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPTOAPI_BLOB = ^CRYPTOAPI_BLOB;<br> CRYPTOAPI_BLOB = record<br> cbData
WORD;<br> pbData
BYTE;<br> end;<br><br>type<br> CRYPT_INTEGER_BLOB = CRYPTOAPI_BLOB;<br> PCRYPT_INTEGER_BLOB = ^CRYPT_INTEGER_BLOB;<br> CRYPT_UINT_BLOB = CRYPTOAPI_BLOB;<br> PCRYPT_UINT_BLOB = ^CRYPT_UINT_BLOB;<br> CRYPT_OBJID_BLOB = CRYPTOAPI_BLOB;<br> PCRYPT_OBJID_BLOB = ^CRYPT_OBJID_BLOB;<br> CERT_NAME_BLOB = CRYPTOAPI_BLOB;<br> PCERT_NAME_BLOB = ^CERT_NAME_BLOB;<br> CERT_RDN_VALUE_BLOB = CRYPTOAPI_BLOB;<br> PCERT_RDN_VALUE_BLOB = ^CERT_RDN_VALUE_BLOB;<br> CERT_BLOB = CRYPTOAPI_BLOB;<br> PCERT_BLOB = ^CERT_BLOB;<br> CRL_BLOB = CRYPTOAPI_BLOB;<br> PCRL_BLOB = ^CRL_BLOB;<br> DATA_BLOB = CRYPTOAPI_BLOB;<br> PDATA_BLOB = ^DATA_BLOB; // JEFFJEFF temporary (too generic)<br> CRYPT_DATA_BLOB = CRYPTOAPI_BLOB;<br> PCRYPT_DATA_BLOB = ^CRYPT_DATA_BLOB;<br> CRYPT_HASH_BLOB = CRYPTOAPI_BLOB;<br> PCRYPT_HASH_BLOB = ^CRYPT_HASH_BLOB;<br> CRYPT_DIGEST_BLOB = CRYPTOAPI_BLOB;<br> PCRYPT_DIGEST_BLOB = ^CRYPT_DIGEST_BLOB;<br> CRYPT_DER_BLOB = CRYPTOAPI_BLOB;<br> PCRYPT_DER_BLOB = ^CRYPT_DER_BLOB;<br> CRYPT_ATTR_BLOB = CRYPTOAPI_BLOB;<br> PCRYPT_ATTR_BLOB = ^CRYPT_ATTR_BLOB;<br><br>//+-------------------------------------------------------------------------<br>// In a CRYPT_BIT_BLOB the last byte may contain 0-7 unused bits. Therefore, the<br>// overall bit length is cbData * 8 - cUnusedBits.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_BIT_BLOB = ^CRYPT_BIT_BLOB;<br> CRYPT_BIT_BLOB = record<br> cbData
WORD;<br> pbData
BYTE;<br> cUnusedBits
WORD;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Type used for any algorithm<br>//<br>// Where the Parameters CRYPT_OBJID_BLOB is in its encoded representation. For most<br>// algorithm types, the Parameters CRYPT_OBJID_BLOB is NULL (Parameters.cbData = 0).<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_ALGORITHM_IDENTIFIER = ^CRYPT_ALGORITHM_IDENTIFIER;<br> CRYPT_ALGORITHM_IDENTIFIER = record<br> pszObjId :LPSTR;<br> Parameters :CRYPT_OBJID_BLOB;<br> end;<br><br>// Following are the definitions of various algorithm object identifiers<br>// RSA<br>const <br> szOID_RSA = '1.2.840.113549';<br> szOID_PKCS = '1.2.840.113549.1';<br> szOID_RSA_HASH = '1.2.840.113549.2';<br> szOID_RSA_ENCRYPT = '1.2.840.113549.3';<br><br> szOID_PKCS_1 = '1.2.840.113549.1.1';<br> szOID_PKCS_2 = '1.2.840.113549.1.2';<br> szOID_PKCS_3 = '1.2.840.113549.1.3';<br> szOID_PKCS_4 = '1.2.840.113549.1.4';<br> szOID_PKCS_5 = '1.2.840.113549.1.5';<br> szOID_PKCS_6 = '1.2.840.113549.1.6';<br> szOID_PKCS_7 = '1.2.840.113549.1.7';<br> szOID_PKCS_8 = '1.2.840.113549.1.8';<br> szOID_PKCS_9 = '1.2.840.113549.1.9';<br> szOID_PKCS_10 = '1.2.840.113549.1.10';<br><br> szOID_RSA_RSA = '1.2.840.113549.1.1.1';<br> szOID_RSA_MD2RSA = '1.2.840.113549.1.1.2';<br> szOID_RSA_MD4RSA = '1.2.840.113549.1.1.3';<br> szOID_RSA_MD5RSA = '1.2.840.113549.1.1.4';<br> szOID_RSA_SHA1RSA = '1.2.840.113549.1.1.5';<br> szOID_RSA_SETOAEP_RSA = '1.2.840.113549.1.1.6';<br> <br> szOID_RSA_data = '1.2.840.113549.1.7.1';<br> szOID_RSA_signedData = '1.2.840.113549.1.7.2';<br> szOID_RSA_envelopedData = '1.2.840.113549.1.7.3';<br> szOID_RSA_signEnvData = '1.2.840.113549.1.7.4';<br> szOID_RSA_digestedData = '1.2.840.113549.1.7.5';<br> szOID_RSA_hashedData = '1.2.840.113549.1.7.5';<br> szOID_RSA_encryptedData = '1.2.840.113549.1.7.6';<br><br> szOID_RSA_emailAddr = '1.2.840.113549.1.9.1';<br> szOID_RSA_unstructName = '1.2.840.113549.1.9.2';<br> szOID_RSA_contentType = '1.2.840.113549.1.9.3';<br> szOID_RSA_messageDigest = '1.2.840.113549.1.9.4';<br> szOID_RSA_signingTime = '1.2.840.113549.1.9.5';<br> szOID_RSA_counterSign = '1.2.840.113549.1.9.6';<br> szOID_RSA_challengePwd = '1.2.840.113549.1.9.7';<br> szOID_RSA_unstructAddr = '1.2.840.113549.1.9.8';<br> szOID_RSA_extCertAttrs = '1.2.840.113549.1.9.9';<br> szOID_RSA_SMIMECapabilities = '1.2.840.113549.1.9.15';<br> szOID_RSA_preferSignedData = '1.2.840.113549.1.9.15.1';<br><br> szOID_RSA_MD2 = '1.2.840.113549.2.2';<br> szOID_RSA_MD4 = '1.2.840.113549.2.4';<br> szOID_RSA_MD5 = '1.2.840.113549.2.5';<br><br> szOID_RSA_RC2CBC = '1.2.840.113549.3.2';<br> szOID_RSA_RC4 = '1.2.840.113549.3.4';<br> szOID_RSA_DES_EDE3_CBC = '1.2.840.113549.3.7';<br> szOID_RSA_RC5_CBCPad = '1.2.840.113549.3.9';<br><br>// ITU-T UsefulDefinitions<br> szOID_DS = '2.5';<br> szOID_DSALG = '2.5.8';<br> szOID_DSALG_CRPT = '2.5.8.1';<br> szOID_DSALG_HASH = '2.5.8.2';<br> szOID_DSALG_SIGN = '2.5.8.3';<br> szOID_DSALG_RSA = '2.5.8.1.1';<br><br>// NIST OSE Implementors' Workshop (OIW)<br>// http://nemo.ncsl.nist.gov/oiw/agreements/stable/OSI/12s_9506.w51<br>// http://nemo.ncsl.nist.gov/oiw/agreements/working/OSI/12w_9503.w51<br> szOID_OIW = '1.3.14';<br>// NIST OSE Implementors' Workshop (OIW) Security SIG algorithm identifiers<br> szOID_OIWSEC = '1.3.14.3.2';<br> szOID_OIWSEC_md4RSA = '1.3.14.3.2.2';<br> szOID_OIWSEC_md5RSA = '1.3.14.3.2.3';<br> szOID_OIWSEC_md4RSA2 = '1.3.14.3.2.4';<br> szOID_OIWSEC_desECB = '1.3.14.3.2.6';<br> szOID_OIWSEC_desCBC = '1.3.14.3.2.7';<br> szOID_OIWSEC_desOFB = '1.3.14.3.2.8';<br> szOID_OIWSEC_desCFB = '1.3.14.3.2.9';<br> szOID_OIWSEC_desMAC = '1.3.14.3.2.10';<br> szOID_OIWSEC_rsaSign = '1.3.14.3.2.11';<br> szOID_OIWSEC_dsa = '1.3.14.3.2.12';<br> szOID_OIWSEC_shaDSA = '1.3.14.3.2.13';<br> szOID_OIWSEC_mdc2RSA = '1.3.14.3.2.14';<br> szOID_OIWSEC_shaRSA = '1.3.14.3.2.15';<br> szOID_OIWSEC_dhCommMod = '1.3.14.3.2.16';<br> szOID_OIWSEC_desEDE = '1.3.14.3.2.17';<br> szOID_OIWSEC_sha = '1.3.14.3.2.18';<br> szOID_OIWSEC_mdc2 = '1.3.14.3.2.19';<br> szOID_OIWSEC_dsaComm = '1.3.14.3.2.20';<br> szOID_OIWSEC_dsaCommSHA = '1.3.14.3.2.21';<br> szOID_OIWSEC_rsaXchg = '1.3.14.3.2.22';<br> szOID_OIWSEC_keyHashSeal = '1.3.14.3.2.23';<br> szOID_OIWSEC_md2RSASign = '1.3.14.3.2.24';<br> szOID_OIWSEC_md5RSASign = '1.3.14.3.2.25';<br> szOID_OIWSEC_sha1 = '1.3.14.3.2.26';<br> szOID_OIWSEC_dsaSHA1 = '1.3.14.3.2.27';<br> szOID_OIWSEC_dsaCommSHA1 = '1.3.14.3.2.28';<br> szOID_OIWSEC_sha1RSASign = '1.3.14.3.2.29';<br>// NIST OSE Implementors' Workshop (OIW) Directory SIG algorithm identifiers<br> szOID_OIWDIR = '1.3.14.7.2';<br> szOID_OIWDIR_CRPT = '1.3.14.7.2.1';<br> szOID_OIWDIR_HASH = '1.3.14.7.2.2';<br> szOID_OIWDIR_SIGN = '1.3.14.7.2.3';<br> szOID_OIWDIR_md2 = '1.3.14.7.2.2.1';<br> szOID_OIWDIR_md2RSA = '1.3.14.7.2.3.1';<br><br><br>// INFOSEC Algorithms<br>// joint-iso-ccitt(2) country(16) us(840) organization(1) us-government(101) dod(2) id-infosec(1)<br> szOID_INFOSEC = '2.16.840.1.101.2.1';<br> szOID_INFOSEC_sdnsSignature = '2.16.840.1.101.2.1.1.1';<br> szOID_INFOSEC_mosaicSignature = '2.16.840.1.101.2.1.1.2';<br> szOID_INFOSEC_sdnsConfidentiality = '2.16.840.1.101.2.1.1.3';<br> szOID_INFOSEC_mosaicConfidentiality = '2.16.840.1.101.2.1.1.4';<br> szOID_INFOSEC_sdnsIntegrity = '2.16.840.1.101.2.1.1.5';<br> szOID_INFOSEC_mosaicIntegrity = '2.16.840.1.101.2.1.1.6';<br> szOID_INFOSEC_sdnsTokenProtection = '2.16.840.1.101.2.1.1.7';<br> szOID_INFOSEC_mosaicTokenProtection = '2.16.840.1.101.2.1.1.8';<br> szOID_INFOSEC_sdnsKeyManagement = '2.16.840.1.101.2.1.1.9';<br> szOID_INFOSEC_mosaicKeyManagement = '2.16.840.1.101.2.1.1.10';<br> szOID_INFOSEC_sdnsKMandSig = '2.16.840.1.101.2.1.1.11';<br> szOID_INFOSEC_mosaicKMandSig = '2.16.840.1.101.2.1.1.12';<br> szOID_INFOSEC_SuiteASignature = '2.16.840.1.101.2.1.1.13';<br> szOID_INFOSEC_SuiteAConfidentiality = '2.16.840.1.101.2.1.1.14';<br> szOID_INFOSEC_SuiteAIntegrity = '2.16.840.1.101.2.1.1.15';<br> szOID_INFOSEC_SuiteATokenProtection = '2.16.840.1.101.2.1.1.16';<br> szOID_INFOSEC_SuiteAKeyManagement = '2.16.840.1.101.2.1.1.17';<br> szOID_INFOSEC_SuiteAKMandSig = '2.16.840.1.101.2.1.1.18';<br> szOID_INFOSEC_mosaicUpdatedSig = '2.16.840.1.101.2.1.1.19';<br> szOID_INFOSEC_mosaicKMandUpdSig = '2.16.840.1.101.2.1.1.20';<br> szOID_INFOSEC_mosaicUpdatedInteg = '2.16.840.1.101.2.1.1.21';<br><br>type<br> PCRYPT_OBJID_TABLE = ^CRYPT_OBJID_TABLE;<br> CRYPT_OBJID_TABLE = record<br> dwAlgId
WORD;<br> pszObjId :LPCSTR;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// PKCS #1 HashInfo (DigestInfo)<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_HASH_INFO = ^CRYPT_HASH_INFO;<br> CRYPT_HASH_INFO = record<br> HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> Hash :CRYPT_HASH_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Type used for an extension to an encoded content<br>//<br>// Where the Value's CRYPT_OBJID_BLOB is in its encoded representation.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_EXTENSION = ^CERT_EXTENSION;<br> CERT_EXTENSION = record<br> pszObjId :LPSTR;<br> fCritical :BOOL;<br> Value :CRYPT_OBJID_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// AttributeTypeValue<br>//<br>// Where the Value's CRYPT_OBJID_BLOB is in its encoded representation.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_ATTRIBUTE_TYPE_VALUE =^CRYPT_ATTRIBUTE_TYPE_VALUE;<br> CRYPT_ATTRIBUTE_TYPE_VALUE = record<br> pszObjId :LPSTR;<br> Value :CRYPT_OBJID_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Attributes<br>//<br>// Where the Value's PATTR_BLOBs are in their encoded representation.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_ATTRIBUTE = ^CRYPT_ATTRIBUTE;<br> CRYPT_ATTRIBUTE = record<br> pszObjId :LPSTR;<br> cValue
WORD;<br> rgValue
CRYPT_ATTR_BLOB;<br> end;<br><br>type<br> PCRYPT_ATTRIBUTES =^CRYPT_ATTRIBUTES;<br> CRYPT_ATTRIBUTES = record<br> cAttr
WORD; {IN}<br> rgAttr
CRYPT_ATTRIBUTE; {IN}<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Attributes making up a Relative Distinguished Name (CERT_RDN)<br>//<br>// The interpretation of the Value depends on the dwValueType.<br>// See below for a list of the types.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_RDN_ATTR = ^CERT_RDN_ATTR;<br> CERT_RDN_ATTR = record<br> pszObjId :LPSTR;<br> dwValueType
WORD;<br> Value :CERT_RDN_VALUE_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CERT_RDN attribute Object Identifiers<br>//--------------------------------------------------------------------------<br>// Labeling attribute types:<br>const <br> szOID_COMMON_NAME = '2.5.4.3'; // case-ignore string<br> szOID_SUR_NAME = '2.5.4.4'; // case-ignore string<br> szOID_DEVICE_SERIAL_NUMBER = '2.5.4.5'; // printable string<br><br>// Geographic attribute types:<br> szOID_COUNTRY_NAME = '2.5.4.6'; // printable 2char string<br> szOID_LOCALITY_NAME = '2.5.4.7'; // case-ignore string<br> szOID_STATE_OR_PROVINCE_NAME = '2.5.4.8'; // case-ignore string<br> szOID_STREET_ADDRESS = '2.5.4.9'; // case-ignore string<br><br>// Organizational attribute types:<br> szOID_ORGANIZATION_NAME = '2.5.4.10';// case-ignore string<br> szOID_ORGANIZATIONAL_UNIT_NAME = '2.5.4.11'; // case-ignore string<br> szOID_TITLE = '2.5.4.12'; // case-ignore string<br><br>// Explanatory attribute types:<br> szOID_DESCRIPTION = '2.5.4.13'; // case-ignore string<br> szOID_SEARCH_GUIDE = '2.5.4.14';<br> szOID_BUSINESS_CATEGORY = '2.5.4.15'; // case-ignore string<br><br>// Postal addressing attribute types:<br> szOID_POSTAL_ADDRESS = '2.5.4.16';<br> szOID_POSTAL_CODE = '2.5.4.17'; // case-ignore string<br> szOID_POST_OFFICE_BOX = '2.5.4.18'; // case-ignore string<br> szOID_PHYSICAL_DELIVERY_OFFICE_NAME = '2.5.4.19'; // case-ignore string<br><br>// Telecommunications addressing attribute types:<br> szOID_TELEPHONE_NUMBER = '2.5.4.20'; // telephone number<br> szOID_TELEX_NUMBER = '2.5.4.21';<br> szOID_TELETEXT_TERMINAL_IDENTIFIER = '2.5.4.22';<br> szOID_FACSIMILE_TELEPHONE_NUMBER = '2.5.4.23';<br> szOID_X21_ADDRESS = '2.5.4.24'; // numeric string<br> szOID_INTERNATIONAL_ISDN_NUMBER = '2.5.4.25'; // numeric string<br> szOID_REGISTERED_ADDRESS = '2.5.4.26';<br> szOID_DESTINATION_INDICATOR = '2.5.4.27'; // printable string<br><br>// Preference attribute types:<br> szOID_PREFERRED_DELIVERY_METHOD = '2.5.4.28';<br><br>// OSI application attribute types:<br> szOID_PRESENTATION_ADDRESS = '2.5.4.29';<br> szOID_SUPPORTED_APPLICATION_CONTEXT = '2.5.4.30';<br><br>// Relational application attribute types:<br> szOID_MEMBER = '2.5.4.31';<br> szOID_OWNER = '2.5.4.32';<br> szOID_ROLE_OCCUPANT = '2.5.4.33';<br> szOID_SEE_ALSO = '2.5.4.34';<br><br>// Security attribute types:<br> szOID_USER_PASSWORD = '2.5.4.35';<br> szOID_USER_CERTIFICATE = '2.5.4.36';<br> szOID_CA_CERTIFICATE = '2.5.4.37';<br> szOID_AUTHORITY_REVOCATION_LIST = '2.5.4.38';<br> szOID_CERTIFICATE_REVOCATION_LIST = '2.5.4.39';<br> szOID_CROSS_CERTIFICATE_PAIR = '2.5.4.40';<br><br>// Undocumented attribute types???<br>//#define szOID_??? '2.5.4.41'<br> szOID_GIVEN_NAME = '2.5.4.42'; // case-ignore string<br> szOID_INITIALS = '2.5.4.43'; // case-ignore string<br><br>// Pilot user attribute types:<br> szOID_DOMAIN_COMPONENT = '0.9.2342.19200300.100.1.25'; // IA5 string<br><br>//+-------------------------------------------------------------------------<br>// CERT_RDN Attribute Value Types<br>//<br>// For RDN_ENCODED_BLOB, the Value's CERT_RDN_VALUE_BLOB is in its encoded<br>// representation. Otherwise, its an array of bytes.<br>//<br>// For all CERT_RDN types, Value.cbData is always the number of bytes, not<br>// necessarily the number of elements in the string. For instance,<br>// RDN_UNIVERSAL_STRING is an array of ints (cbData == intCnt * 4) and<br>// RDN_BMP_STRING is an array of unsigned shorts (cbData == ushortCnt * 2).<br>//<br>// For CertDecodeName, two 0 bytes are always appended to the end of the<br>// string (ensures a CHAR or WCHAR string is null terminated).<br>// These added 0 bytes are't included in the BLOB.cbData.<br>//--------------------------------------------------------------------------<br><br>const <br> CERT_RDN_ANY_TYPE = 0;<br> CERT_RDN_ENCODED_BLOB = 1;<br> CERT_RDN_OCTET_STRING = 2;<br> CERT_RDN_NUMERIC_STRING = 3;<br> CERT_RDN_PRINTABLE_STRING = 4;<br> CERT_RDN_TELETEX_STRING = 5;<br> CERT_RDN_T61_STRING = 5;<br> CERT_RDN_VIDEOTEX_STRING = 6;<br> CERT_RDN_IA5_STRING = 7;<br> CERT_RDN_GRAPHIC_STRING = 8;<br> CERT_RDN_VISIBLE_STRING = 9;<br> CERT_RDN_ISO646_STRING = 9;<br> CERT_RDN_GENERAL_STRING = 10;<br> CERT_RDN_UNIVERSAL_STRING = 11;<br> CERT_RDN_INT4_STRING = 11;<br> CERT_RDN_BMP_STRING = 12;<br> CERT_RDN_UNICODE_STRING = 12;<br><br><br>// Macro to check that the dwValueType is a character string and not an<br>// encoded blob or octet string<br>function IS_CERT_RDN_CHAR_STRING(X
WORD) :BOOL;<br><br>//+-------------------------------------------------------------------------<br>// A CERT_RDN consists of an array of the above attributes<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_RDN = ^CERT_RDN;<br> CERT_RDN = record<br> cRDNAttr
WORD;<br> rgRDNAttr
CERT_RDN_ATTR;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Information stored in a subject's or issuer's name. The information<br>// is represented as an array of the above RDNs.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_NAME_INFO = ^CERT_NAME_INFO;<br> CERT_NAME_INFO = record<br> cRDN
WORD;<br> rgRDN
CERT_RDN;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Name attribute value without the Object Identifier<br>//<br>// The interpretation of the Value depends on the dwValueType.<br>// See above for a list of the types.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_NAME_VALUE = ^CERT_NAME_VALUE;<br> CERT_NAME_VALUE = record<br> dwValueType
WORD;<br> Value :CERT_RDN_VALUE_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Public Key Info<br>//<br>// The PublicKey is the encoded representation of the information as it is<br>// stored in the bit string<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_PUBLIC_KEY_INFO = ^CERT_PUBLIC_KEY_INFO;<br> CERT_PUBLIC_KEY_INFO = record<br> Algorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> PublicKey :CRYPT_BIT_BLOB;<br> end;<br><br>const <br> CERT_RSA_PUBLIC_KEY_OBJID = szOID_RSA_RSA;<br> CERT_DEFAULT_OID_PUBLIC_KEY_SIGN = szOID_RSA_RSA;<br> CERT_DEFAULT_OID_PUBLIC_KEY_XCHG = szOID_RSA_RSA;<br><br>//+-------------------------------------------------------------------------<br>// Information stored in a certificate<br>//<br>// The Issuer, Subject, Algorithm, PublicKey and Extension BLOBs are the<br>// encoded representation of the information.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_INFO = ^CERT_INFO;<br> CERT_INFO = record<br> dwVersion
WORD;<br> SerialNumber :CRYPT_INTEGER_BLOB;<br> SignatureAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> Issuer :CERT_NAME_BLOB;<br> NotBefore :TFILETIME;<br> NotAfter :TFILETIME;<br> Subject :CERT_NAME_BLOB;<br> SubjectPublicKeyInfo :CERT_PUBLIC_KEY_INFO;<br> IssuerUniqueId :CRYPT_BIT_BLOB;<br> SubjectUniqueId :CRYPT_BIT_BLOB;<br> cExtension
WORD;<br> rgExtension
CERT_EXTENSION;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Certificate versions<br>//--------------------------------------------------------------------------<br>const <br> CERT_V1 = 0;<br> CERT_V2 = 1;<br> CERT_V3 = 2;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Information Flags<br>//--------------------------------------------------------------------------<br><br> CERT_INFO_VERSION_FLAG = 1;<br> CERT_INFO_SERIAL_NUMBER_FLAG = 2;<br> CERT_INFO_SIGNATURE_ALGORITHM_FLAG = 3;<br> CERT_INFO_ISSUER_FLAG = 4;<br> CERT_INFO_NOT_BEFORE_FLAG = 5;<br> CERT_INFO_NOT_AFTER_FLAG = 6;<br> CERT_INFO_SUBJECT_FLAG = 7;<br> CERT_INFO_SUBJECT_PUBLIC_KEY_INFO_FLAG = 8;<br> CERT_INFO_ISSUER_UNIQUE_ID_FLAG = 9;<br> CERT_INFO_SUBJECT_UNIQUE_ID_FLAG = 10;<br> CERT_INFO_EXTENSION_FLAG = 11;<br><br>//+-------------------------------------------------------------------------<br>// An entry in a CRL<br>//<br>// The Extension BLOBs are the encoded representation of the information.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRL_ENTRY = ^CRL_ENTRY;<br> CRL_ENTRY = record<br> SerialNumber :CRYPT_INTEGER_BLOB;<br> RevocationDate :TFILETIME;<br> cExtension
WORD;<br> rgExtension
CERT_EXTENSION;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Information stored in a CRL<br>//<br>// The Issuer, Algorithm and Extension BLOBs are the encoded<br>// representation of the information.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRL_INFO = ^CRL_INFO;<br> CRL_INFO = record<br> dwVersion
WORD;<br> SignatureAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> Issuer :CERT_NAME_BLOB;<br> ThisUpdate :TFILETIME;<br> NextUpdate :TFILETIME;<br> cCRLEntry
WORD;<br> rgCRLEntry
CRL_ENTRY;<br> cExtension
WORD;<br> rgExtension
CERT_EXTENSION;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CRL versions<br>//--------------------------------------------------------------------------<br>const <br> CRL_V1 = 0;<br> CRL_V2 = 1;<br><br>//+-------------------------------------------------------------------------<br>// Information stored in a certificate request<br>//<br>// The Subject, Algorithm, PublicKey and Attribute BLOBs are the encoded<br>// representation of the information.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_REQUEST_INFO = ^CERT_REQUEST_INFO;<br> CERT_REQUEST_INFO = record<br> dwVersion
WORD;<br> Subject :CERT_NAME_BLOB;<br> SubjectPublicKeyInfo :CERT_PUBLIC_KEY_INFO;<br> cAttribute
WORD;<br> rgAttribute
CRYPT_ATTRIBUTE;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Request versions<br>//--------------------------------------------------------------------------<br>const CERT_REQUEST_V1 = 0;<br><br>//+-------------------------------------------------------------------------<br>// Information stored in Netscape's Keygen request<br>//--------------------------------------------------------------------------<br>type<br> PCERT_KEYGEN_REQUEST_INFO = ^CERT_KEYGEN_REQUEST_INFO;<br> CERT_KEYGEN_REQUEST_INFO = record<br> dwVersion
WORD;<br> SubjectPublicKeyInfo :CERT_PUBLIC_KEY_INFO;<br> pwszChallengeString :LPWSTR; // encoded as IA5<br> end;<br><br>const <br> CERT_KEYGEN_REQUEST_V1 = 0;<br><br><br>//+-------------------------------------------------------------------------<br>// Certificate, CRL, Certificate Request or Keygen Request Signed Content<br>//<br>// The "to be signed" encoded content plus its signature. The ToBeSigned<br>// is the encoded CERT_INFO, CRL_INFO, CERT_REQUEST_INFO or<br>// CERT_KEYGEN_REQUEST_INFO.<br>//--------------------------------------------------------------------------<br>type<br> PCERT_SIGNED_CONTENT_INFO = ^CERT_SIGNED_CONTENT_INFO;<br> CERT_SIGNED_CONTENT_INFO = record<br> ToBeSigned :CRYPT_DER_BLOB;<br> SignatureAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> Signature :CRYPT_BIT_BLOB;<br>end;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Trust List (CTL)<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CTL Usage. Also used for EnhancedKeyUsage extension.<br>//--------------------------------------------------------------------------<br><br>type<br> PCTL_USAGE =^CTL_USAGE;<br> CTL_USAGE = record<br> cUsageIdentifier
WORD;<br> rgpszUsageIdentifier
LPSTR; // array of pszObjId<br> end;<br><br>type<br> CERT_ENHKEY_USAGE = CTL_USAGE;<br> PCERT_ENHKEY_USAGE = ^CERT_ENHKEY_USAGE;<br><br><br>//+-------------------------------------------------------------------------<br>// An entry in a CTL<br>//--------------------------------------------------------------------------<br>type<br> PCTL_ENTRY = ^CTL_ENTRY;<br> CTL_ENTRY = record<br> SubjectIdentifier :CRYPT_DATA_BLOB; // For example, its hash<br> cAttribute
WORD;<br> rgAttribute
CRYPT_ATTRIBUTE; // OPTIONAL<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Information stored in a CTL<br>//--------------------------------------------------------------------------<br>type<br> PCTL_INFO = ^CTL_INFO;<br> CTL_INFO = record<br> dwVersion
WORD;<br> SubjectUsage :CTL_USAGE;<br> ListIdentifier :CRYPT_DATA_BLOB; // OPTIONAL<br> SequenceNumber :CRYPT_INTEGER_BLOB; // OPTIONAL<br> ThisUpdate :TFILETIME;<br> NextUpdate :TFILETIME; // OPTIONAL<br> SubjectAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> cCTLEntry
WORD;<br> rgCTLEntry
CTL_ENTRY; // OPTIONAL<br> cExtension
WORD;<br> rgExtension
CERT_EXTENSION; // OPTIONAL<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CTL versions<br>//--------------------------------------------------------------------------<br>const <br> CTL_V1 = 0;<br><br>//+-------------------------------------------------------------------------<br>// TimeStamp Request<br>//<br>// The pszTimeStamp is the OID for the Time type requested<br>// The pszContentType is the Content Type OID for the content, usually DATA<br>// The Content is a un-decoded blob<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_TIME_STAMP_REQUEST_INFO = ^CRYPT_TIME_STAMP_REQUEST_INFO;<br> CRYPT_TIME_STAMP_REQUEST_INFO = record<br> pszTimeStampAlgorithm :LPSTR; // pszObjId<br> pszContentType :LPSTR; // pszObjId<br> Content :CRYPT_OBJID_BLOB;<br> cAttribute
WORD;<br> rgAttribute
CRYPT_ATTRIBUTE;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Certificate and Message encoding types<br>//<br>// The encoding type is a DWORD containing both the certificate and message<br>// encoding types. The certificate encoding type is stored in the LOWORD.<br>// The message encoding type is stored in the HIWORD. Some functions or<br>// structure fields require only one of the encoding types. The following<br>// naming convention is used to indicate which encoding type(s) are<br>// required:<br>// dwEncodingType (both encoding types are required)<br>// dwMsgAndCertEncodingType (both encoding types are required)<br>// dwMsgEncodingType (only msg encoding type is required)<br>// dwCertEncodingType (only cert encoding type is required)<br>//<br>// Its always acceptable to specify both.<br>//--------------------------------------------------------------------------<br><br>const <br> CERT_ENCODING_TYPE_MASK = $0000FFFF;<br> CMSG_ENCODING_TYPE_MASK = $FFFF0000;<br><br>//#define GET_CERT_ENCODING_TYPE(X) (X & CERT_ENCODING_TYPE_MASK)<br>//#define GET_CMSG_ENCODING_TYPE(X) (X & CMSG_ENCODING_TYPE_MASK)<br>function GET_CERT_ENCODING_TYPE(X
WORD)
WORD;<br>function GET_CMSG_ENCODING_TYPE(X
WORD)
WORD;<br><br>const <br> CRYPT_ASN_ENCODING = $00000001;<br> CRYPT_NDR_ENCODING = $00000002;<br> X509_ASN_ENCODING = $00000001;<br> X509_NDR_ENCODING = $00000002;<br> PKCS_7_ASN_ENCODING = $00010000;<br> PKCS_7_NDR_ENCODING = $00020000;<br><br>//+-------------------------------------------------------------------------<br>// format the specified data structure according to the certificate<br>// encoding type.<br>//<br>//--------------------------------------------------------------------------<br><br>function CryptFormatObject(dwCertEncodingType
WORD;<br> dwFormatType
WORD;<br> dwFormatStrType
WORD;<br> pFormatStruct
VOID;<br> lpszStructType :LPCSTR;<br> const pbEncoded
BYTE;<br> cbEncoded
WORD;<br> pbFormat
VOID;<br> pcbFormat
DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Encode / decode the specified data structure according to the certificate<br>// encoding type.<br>//<br>// See below for a list of the predefined data structures.<br>//--------------------------------------------------------------------------<br><br>function CryptEncodeObject(dwCertEncodingType
WORD;<br> lpszStructType :LPCSTR;<br> const pvStructInfo
VOID;<br> pbEncoded
BYTE;<br> pcbEncoded
DWORD ):BOOL ; stdcall;<br><br>function CryptDecodeObject(dwCertEncodingType
WORD;<br> lpszStructType :LPCSTR;<br> const pbEncoded
BYTE;<br> cbEncoded
WORD;<br> dwFlags
WORD;<br> pvStructInfo
VOID;<br> pcbStructInfo
DWORD):BOOL ; stdcall;<br><br>// When the following flag is set the nocopy optimization is enabled.<br>// This optimization where appropriate, updates the pvStructInfo fields<br>// to point to content residing within pbEncoded instead of making a copy<br>// of and appending to pvStructInfo.<br>//<br>// Note, when set, pbEncoded can't be freed until pvStructInfo is freed.<br>const <br> CRYPT_DECODE_NOCOPY_FLAG = $1;<br><br>//+-------------------------------------------------------------------------<br>// Predefined X509 certificate data structures that can be encoded / decoded.<br>//--------------------------------------------------------------------------<br> CRYPT_ENCODE_DECODE_NONE = 0;<br> X509_CERT = (LPCSTR(1));<br> X509_CERT_TO_BE_SIGNED = (LPCSTR(2));<br> X509_CERT_CRL_TO_BE_SIGNED = (LPCSTR(3));<br> X509_CERT_REQUEST_TO_BE_SIGNED = (LPCSTR(4));<br> X509_EXTENSIONS = (LPCSTR(5));<br> X509_NAME_VALUE = (LPCSTR(6));<br> X509_NAME = (LPCSTR(7));<br> X509_PUBLIC_KEY_INFO = (LPCSTR(8));<br><br>//+-------------------------------------------------------------------------<br>// Predefined X509 certificate extension data structures that can be<br>// encoded / decoded.<br>//--------------------------------------------------------------------------<br> X509_AUTHORITY_KEY_ID = (LPCSTR(9));<br> X509_KEY_ATTRIBUTES = (LPCSTR(10));<br> X509_KEY_USAGE_RESTRICTION = (LPCSTR(11));<br> X509_ALTERNATE_NAME = (LPCSTR(12));<br> X509_BASIC_CONSTRAINTS = (LPCSTR(13));<br> X509_KEY_USAGE = (LPCSTR(14));<br> X509_BASIC_CONSTRAINTS2 = (LPCSTR(15));<br> X509_CERT_POLICIES = (LPCSTR(16));<br><br>//+-------------------------------------------------------------------------<br>// Additional predefined data structures that can be encoded / decoded.<br>//--------------------------------------------------------------------------<br> PKCS_UTC_TIME = (LPCSTR(17));<br> PKCS_TIME_REQUEST = (LPCSTR(18));<br> RSA_CSP_PUBLICKEYBLOB = (LPCSTR(19));<br> X509_UNICODE_NAME = (LPCSTR(20));<br><br> X509_KEYGEN_REQUEST_TO_BE_SIGNED = (LPCSTR(21));<br> PKCS_ATTRIBUTE = (LPCSTR(22));<br> PKCS_CONTENT_INFO_SEQUENCE_OF_ANY = (LPCSTR(23));<br><br>//+-------------------------------------------------------------------------<br>// Predefined primitive data structures that can be encoded / decoded.<br>//--------------------------------------------------------------------------<br> X509_UNICODE_NAME_VALUE = (LPCSTR(24));<br> X509_ANY_STRING = X509_NAME_VALUE;<br> X509_UNICODE_ANY_STRING = X509_UNICODE_NAME_VALUE;<br> X509_OCTET_STRING = (LPCSTR(25));<br> X509_BITS = (LPCSTR(26));<br> X509_INTEGER = (LPCSTR(27));<br> X509_MULTI_BYTE_INTEGER = (LPCSTR(28));<br> X509_ENUMERATED = (LPCSTR(29));<br> X509_CHOICE_OF_TIME = (LPCSTR(30));<br><br>//+-------------------------------------------------------------------------<br>// More predefined X509 certificate extension data structures that can be<br>// encoded / decoded.<br>//--------------------------------------------------------------------------<br><br> X509_AUTHORITY_KEY_ID2 = (LPCSTR(31));<br>// X509_AUTHORITY_INFO_ACCESS (LPCSTR(32));<br> X509_CRL_REASON_CODE = X509_ENUMERATED;<br> PKCS_CONTENT_INFO = (LPCSTR(33));<br> X509_SEQUENCE_OF_ANY = (LPCSTR(34));<br> X509_CRL_DIST_POINTS = (LPCSTR(35));<br> X509_ENHANCED_KEY_USAGE = (LPCSTR(36));<br> PKCS_CTL = (LPCSTR(37));<br><br> X509_MULTI_BYTE_UINT = (LPCSTR(38));<br> X509_DSS_PUBLICKEY = X509_MULTI_BYTE_UINT;<br> X509_DSS_PARAMETERS = (LPCSTR(39));<br> X509_DSS_SIGNATURE = (LPCSTR(40));<br> PKCS_RC2_CBC_PARAMETERS = (LPCSTR(41));<br> PKCS_SMIME_CAPABILITIES = (LPCSTR(42));<br><br>//+-------------------------------------------------------------------------<br>// Predefined PKCS #7 data structures that can be encoded / decoded.<br>//--------------------------------------------------------------------------<br> PKCS7_SIGNER_INFO = (LPCSTR(500));<br><br>//+-------------------------------------------------------------------------<br>// Predefined Software Publishing Credential (SPC) data structures that<br>// can be encoded / decoded.<br>//<br>// Predefined values: 2000 .. 2999<br>//<br>// See spc.h for value and data structure definitions.<br>//--------------------------------------------------------------------------<br>//+-------------------------------------------------------------------------<br>// Extension Object Identifiers<br>//--------------------------------------------------------------------------<br>const <br> szOID_AUTHORITY_KEY_IDENTIFIER = '2.5.29.1';<br> szOID_KEY_ATTRIBUTES = '2.5.29.2';<br> szOID_KEY_USAGE_RESTRICTION = '2.5.29.4';<br> szOID_SUBJECT_ALT_NAME = '2.5.29.7';<br> szOID_ISSUER_ALT_NAME = '2.5.29.8';<br> szOID_BASIC_CONSTRAINTS = '2.5.29.10';<br> szOID_KEY_USAGE = '2.5.29.15';<br> szOID_BASIC_CONSTRAINTS2 = '2.5.29.19';<br> szOID_CERT_POLICIES = '2.5.29.32';<br><br> szOID_AUTHORITY_KEY_IDENTIFIER2 = '2.5.29.35';<br> szOID_SUBJECT_KEY_IDENTIFIER = '2.5.29.14';<br> szOID_SUBJECT_ALT_NAME2 = '2.5.29.17';<br> szOID_ISSUER_ALT_NAME2 = '2.5.29.18';<br> szOID_CRL_REASON_CODE = '2.5.29.21';<br> szOID_CRL_DIST_POINTS = '2.5.29.31';<br> szOID_ENHANCED_KEY_USAGE = '2.5.29.37';<br><br><br>// Internet Public Key Infrastructure<br> szOID_PKIX = '1.3.6.1.5.5.7';<br> szOID_AUTHORITY_INFO_ACCESS = '1.3.6.1.5.5.7.2';<br><br>// Microsoft extensions or attributes<br> szOID_CERT_EXTENSIONS = '1.3.6.1.4.1.311.2.1.14';<br> szOID_NEXT_UPDATE_LOCATION = '1.3.6.1.4.1.311.10.2';<br><br>// Microsoft PKCS #7 ContentType Object Identifiers<br> szOID_CTL = '1.3.6.1.4.1.311.10.1';<br><br>//+-------------------------------------------------------------------------<br>// Extension Object Identifiers (currently not implemented)<br>//--------------------------------------------------------------------------<br> szOID_POLICY_MAPPINGS = '2.5.29.5';<br> szOID_SUBJECT_DIR_ATTRS = '2.5.29.9';<br><br>//+-------------------------------------------------------------------------<br>// Enhanced Key Usage (Purpose) Object Identifiers<br>//--------------------------------------------------------------------------<br>const szOID_PKIX_KP = '1.3.6.1.5.5.7.3';<br><br>// Consistent key usage bits: DIGITAL_SIGNATURE, KEY_ENCIPHERMENT<br>// or KEY_AGREEMENT<br> szOID_PKIX_KP_SERVER_AUTH = '1.3.6.1.5.5.7.3.1';<br><br>// Consistent key usage bits: DIGITAL_SIGNATURE<br> szOID_PKIX_KP_CLIENT_AUTH = '1.3.6.1.5.5.7.3.2';<br><br>// Consistent key usage bits: DIGITAL_SIGNATURE<br> szOID_PKIX_KP_CODE_SIGNING = '1.3.6.1.5.5.7.3.3';<br><br>// Consistent key usage bits: DIGITAL_SIGNATURE, NON_REPUDIATION and/or<br>// (KEY_ENCIPHERMENT or KEY_AGREEMENT)<br> szOID_PKIX_KP_EMAIL_PROTECTION = '1.3.6.1.5.5.7.3.4';<br><br>//+-------------------------------------------------------------------------<br>// Microsoft Enhanced Key Usage (Purpose) Object Identifiers<br>//+-------------------------------------------------------------------------<br><br>// Signer of CTLs<br> szOID_KP_CTL_USAGE_SIGNING = '1.3.6.1.4.1.311.10.3.1';<br><br>// Signer of TimeStamps<br> szOID_KP_TIME_STAMP_SIGNING = '1.3.6.1.4.1.311.10.3.2';<br><br>//+-------------------------------------------------------------------------<br>// Microsoft Attribute Object Identifiers<br>//+-------------------------------------------------------------------------<br> szOID_YESNO_TRUST_ATTR = '1.3.6.1.4.1.311.10.4.1';<br><br>//+-------------------------------------------------------------------------<br>// X509_CERT<br>//<br>// The "to be signed" encoded content plus its signature. The ToBeSigned<br>// content is the CryptEncodeObject() output for one of the following:<br>// X509_CERT_TO_BE_SIGNED, X509_CERT_CRL_TO_BE_SIGNED or<br>// X509_CERT_REQUEST_TO_BE_SIGNED.<br>//<br>// pvStructInfo points to CERT_SIGNED_CONTENT_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_CERT_TO_BE_SIGNED<br>//<br>// pvStructInfo points to CERT_INFO.<br>//<br>// For CryptDecodeObject(), the pbEncoded is the "to be signed" plus its<br>// signature (output of a X509_CERT CryptEncodeObject()).<br>//<br>// For CryptEncodeObject(), the pbEncoded is just the "to be signed".<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_CERT_CRL_TO_BE_SIGNED<br>//<br>// pvStructInfo points to CRL_INFO.<br>//<br>// For CryptDecodeObject(), the pbEncoded is the "to be signed" plus its<br>// signature (output of a X509_CERT CryptEncodeObject()).<br>//<br>// For CryptEncodeObject(), the pbEncoded is just the "to be signed".<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_CERT_REQUEST_TO_BE_SIGNED<br>//<br>// pvStructInfo points to CERT_REQUEST_INFO.<br>//<br>// For CryptDecodeObject(), the pbEncoded is the "to be signed" plus its<br>// signature (output of a X509_CERT CryptEncodeObject()).<br>//<br>// For CryptEncodeObject(), the pbEncoded is just the "to be signed".<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_EXTENSIONS<br>// szOID_CERT_EXTENSIONS<br>//<br>// pvStructInfo points to following CERT_EXTENSIONS.<br>//--------------------------------------------------------------------------<br>type<br> PCERT_EXTENSIONS = ^CERT_EXTENSIONS;<br> CERT_EXTENSIONS = record<br> cExtension
WORD;<br> rgExtension
CERT_EXTENSION;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// X509_NAME_VALUE<br>// X509_ANY_STRING<br>//<br>// pvStructInfo points to CERT_NAME_VALUE.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_UNICODE_NAME_VALUE<br>// X509_UNICODE_ANY_STRING<br>//<br>// pvStructInfo points to CERT_NAME_VALUE.<br>//<br>// The name values are unicode strings.<br>//<br>// For CryptEncodeObject:<br>// Value.pbData points to the unicode string.<br>// If Value.cbData = 0, then, the unicode string is NULL terminated.<br>// Otherwise, Value.cbData is the unicode string byte count. The byte count<br>// is twice the character count.<br>//<br>// If the unicode string contains an invalid character for the specified<br>// dwValueType, then, *pcbEncoded is updated with the unicode character<br>// index of the first invalid character. LastError is set to:<br>// CRYPT_E_INVALID_NUMERIC_STRING, CRYPT_E_INVALID_PRINTABLE_STRING or<br>// CRYPT_E_INVALID_IA5_STRING.<br>//<br>// The unicode string is converted before being encoded according to<br>// the specified dwValueType. If dwValueType is set to 0, LastError<br>// is set to E_INVALIDARG.<br>//<br>// If the dwValueType isn't one of the character strings (its a<br>// CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING), then, CryptEncodeObject<br>// will return FALSE with LastError set to CRYPT_E_NOT_CHAR_STRING.<br>//<br>// For CryptDecodeObject:<br>// Value.pbData points to a NULL terminated unicode string. Value.cbData<br>// contains the byte count of the unicode string excluding the NULL<br>// terminator. dwValueType contains the type used in the encoded object.<br>// Its not forced to CERT_RDN_UNICODE_STRING. The encoded value is<br>// converted to the unicode string according to the dwValueType.<br>//<br>// If the encoded object isn't one of the character string types, then,<br>// CryptDecodeObject will return FALSE with LastError set to<br>// CRYPT_E_NOT_CHAR_STRING. For a non character string, decode using<br>// X509_NAME_VALUE or X509_ANY_STRING.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_NAME<br>//<br>// pvStructInfo points to CERT_NAME_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_UNICODE_NAME<br>//<br>// pvStructInfo points to CERT_NAME_INFO.<br>//<br>// The RDN attribute values are unicode strings except for the dwValueTypes of<br>// CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING. These dwValueTypes are<br>// the same as for a X509_NAME. Their values aren't converted to/from unicode.<br>//<br>// For CryptEncodeObject:<br>// Value.pbData points to the unicode string.<br>// If Value.cbData = 0, then, the unicode string is NULL terminated.<br>// Otherwise, Value.cbData is the unicode string byte count. The byte count<br>// is twice the character count.<br>//<br>// If dwValueType = 0 (CERT_RDN_ANY_TYPE), the pszObjId is used to find<br>// an acceptable dwValueType. If the unicode string contains an<br>// invalid character for the found or specified dwValueType, then,<br>// *pcbEncoded is updated with the error location of the invalid character.<br>// See below for details. LastError is set to:<br>// CRYPT_E_INVALID_NUMERIC_STRING, CRYPT_E_INVALID_PRINTABLE_STRING or<br>// CRYPT_E_INVALID_IA5_STRING.<br>//<br>// The unicode string is converted before being encoded according to<br>// the specified or ObjId matching dwValueType.<br>//<br>// For CryptDecodeObject:<br>// Value.pbData points to a NULL terminated unicode string. Value.cbData<br>// contains the byte count of the unicode string excluding the NULL<br>// terminator. dwValueType contains the type used in the encoded object.<br>// Its not forced to CERT_RDN_UNICODE_STRING. The encoded value is<br>// converted to the unicode string according to the dwValueType.<br>//<br>// If the dwValueType of the encoded value isn't a character string<br>// type, then, it isn't converted to UNICODE. Use the<br>// IS_CERT_RDN_CHAR_STRING() macro on the dwValueType to check<br>// that Value.pbData points to a converted unicode string.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// Unicode Name Value Error Location Definitions<br>//<br>// Error location is returned in *pcbEncoded by<br>// CryptEncodeObject(X509_UNICODE_NAME)<br>//<br>// Error location consists of:<br>// RDN_INDEX - 10 bits << 22<br>// ATTR_INDEX - 6 bits << 16<br>// VALUE_INDEX - 16 bits (unicode character index)<br>//--------------------------------------------------------------------------<br>const <br> CERT_UNICODE_RDN_ERR_INDEX_MASK = $3FF;<br> CERT_UNICODE_RDN_ERR_INDEX_SHIFT = 22;<br> CERT_UNICODE_ATTR_ERR_INDEX_MASK = $003F;<br> CERT_UNICODE_ATTR_ERR_INDEX_SHIFT = 16;<br> CERT_UNICODE_VALUE_ERR_INDEX_MASK = $0000FFFF;<br> CERT_UNICODE_VALUE_ERR_INDEX_SHIFT = 0;<br><br>{#define GET_CERT_UNICODE_RDN_ERR_INDEX(X) /<br> ((X >> CERT_UNICODE_RDN_ERR_INDEX_SHIFT) & CERT_UNICODE_RDN_ERR_INDEX_MASK)}<br>function GET_CERT_UNICODE_RDN_ERR_INDEX(X :integer):integer;<br>{#define GET_CERT_UNICODE_ATTR_ERR_INDEX(X) /<br> ((X >> CERT_UNICODE_ATTR_ERR_INDEX_SHIFT) & CERT_UNICODE_ATTR_ERR_INDEX_MASK)}<br>function GET_CERT_UNICODE_ATTR_ERR_INDEX(X :integer):integer;<br>{#define GET_CERT_UNICODE_VALUE_ERR_INDEX(X) /<br> (X & CERT_UNICODE_VALUE_ERR_INDEX_MASK)}<br>function GET_CERT_UNICODE_VALUE_ERR_INDEX(X :integer):integer;<br><br>//+-------------------------------------------------------------------------<br>// X509_PUBLIC_KEY_INFO<br>//<br>// pvStructInfo points to CERT_PUBLIC_KEY_INFO.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// X509_AUTHORITY_KEY_ID<br>// szOID_AUTHORITY_KEY_IDENTIFIER<br>//<br>// pvStructInfo points to following CERT_AUTHORITY_KEY_ID_INFO.<br>//--------------------------------------------------------------------------<br>type<br> PCERT_AUTHORITY_KEY_ID_INFO = ^CERT_AUTHORITY_KEY_ID_INFO;<br> CERT_AUTHORITY_KEY_ID_INFO = record<br> KeyId :CRYPT_DATA_BLOB;<br> CertIssuer :CERT_NAME_BLOB;<br> CertSerialNumber :CRYPT_INTEGER_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// X509_KEY_ATTRIBUTES<br>// szOID_KEY_ATTRIBUTES<br>//<br>// pvStructInfo points to following CERT_KEY_ATTRIBUTES_INFO.<br>//--------------------------------------------------------------------------<br>type<br> PCERT_PRIVATE_KEY_VALIDITY = ^CERT_PRIVATE_KEY_VALIDITY;<br> CERT_PRIVATE_KEY_VALIDITY = record<br> NotBefore :TFILETIME;<br> NotAfter :TFILETIME;<br> end;<br><br>type<br> PCERT_KEY_ATTRIBUTES_INFO = ^CERT_KEY_ATTRIBUTES_INFO;<br> CERT_KEY_ATTRIBUTES_INFO = record<br> KeyId :CRYPT_DATA_BLOB;<br> IntendedKeyUsage :CRYPT_BIT_BLOB;<br> pPrivateKeyUsagePeriod
CERT_PRIVATE_KEY_VALIDITY; // OPTIONAL<br> end;<br><br>const <br> CERT_DIGITAL_SIGNATURE_KEY_USAGE = $80;<br> CERT_NON_REPUDIATION_KEY_USAGE = $40;<br> CERT_KEY_ENCIPHERMENT_KEY_USAGE = $20;<br> CERT_DATA_ENCIPHERMENT_KEY_USAGE = $10;<br> CERT_KEY_AGREEMENT_KEY_USAGE = $08;<br> CERT_KEY_CERT_SIGN_KEY_USAGE = $04;<br> CERT_OFFLINE_CRL_SIGN_KEY_USAGE = $02;<br><br> CERT_CRL_SIGN_KEY_USAGE = $02;<br><br>//+-------------------------------------------------------------------------<br>// X509_KEY_USAGE_RESTRICTION<br>// szOID_KEY_USAGE_RESTRICTION<br>//<br>// pvStructInfo points to following CERT_KEY_USAGE_RESTRICTION_INFO.<br>//--------------------------------------------------------------------------<br>type<br> PCERT_POLICY_ID = ^CERT_POLICY_ID;<br> CERT_POLICY_ID = record<br> cCertPolicyElementId
WORD;<br> rgpszCertPolicyElementId
LPSTR; // pszObjId<br> end;<br><br>type<br> PCERT_KEY_USAGE_RESTRICTION_INFO = ^CERT_KEY_USAGE_RESTRICTION_INFO;<br> CERT_KEY_USAGE_RESTRICTION_INFO = record<br> cCertPolicyId
WORD;<br> rgCertPolicyId
CERT_POLICY_ID;<br> RestrictedKeyUsage :CRYPT_BIT_BLOB;<br> end;<br><br>// See CERT_KEY_ATTRIBUTES_INFO for definition of the RestrictedKeyUsage bits<br><br>//+-------------------------------------------------------------------------<br>// X509_ALTERNATE_NAME<br>// szOID_SUBJECT_ALT_NAME<br>// szOID_ISSUER_ALT_NAME<br>// szOID_SUBJECT_ALT_NAME2<br>// szOID_ISSUER_ALT_NAME2<br>//<br>// pvStructInfo points to following CERT_ALT_NAME_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_ALT_NAME_ENTRY = ^CERT_ALT_NAME_ENTRY;<br> CERT_ALT_NAME_ENTRY = record<br> dwAltNameChoice
WORD;<br> case integer of<br> {1}0: ({OtherName :Not implemented});<br> {2}1: (pwszRfc822Name :LPWSTR); //(encoded IA5)<br> {3}2: (pwszDNSName :LPWSTR); //(encoded IA5)<br> {4}3: ({x400Address :Not implemented});<br> {5}4: (DirectoryName :CERT_NAME_BLOB);<br> {6}5: ({pEdiPartyName :Not implemented});<br> {7}6: (pwszURL :LPWSTR); //(encoded IA5)<br> {8}7: (IPAddress :CRYPT_DATA_BLOB); //(Octet String)<br> {9}8: (pszRegisteredID :LPSTR); //(Octet String)<br> end;<br><br>const <br> CERT_ALT_NAME_OTHER_NAME = 1;<br> CERT_ALT_NAME_RFC822_NAME = 2;<br> CERT_ALT_NAME_DNS_NAME = 3;<br> CERT_ALT_NAME_X400_ADDRESS = 4;<br> CERT_ALT_NAME_DIRECTORY_NAME = 5;<br> CERT_ALT_NAME_EDI_PARTY_NAME = 6;<br> CERT_ALT_NAME_URL = 7;<br> CERT_ALT_NAME_IP_ADDRESS = 8;<br> CERT_ALT_NAME_REGISTERED_ID = 9;<br><br>type<br> PCERT_ALT_NAME_INFO = ^CERT_ALT_NAME_INFO;<br> CERT_ALT_NAME_INFO = record<br> cAltEntry
WORD;<br> rgAltEntry
CERT_ALT_NAME_ENTRY;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Alternate name IA5 Error Location Definitions for<br>// CRYPT_E_INVALID_IA5_STRING.<br>//<br>// Error location is returned in *pcbEncoded by<br>// CryptEncodeObject(X509_ALTERNATE_NAME)<br>//<br>// Error location consists of:<br>// ENTRY_INDEX - 8 bits << 16<br>// VALUE_INDEX - 16 bits (unicode character index)<br>//--------------------------------------------------------------------------<br><br>const <br> CERT_ALT_NAME_ENTRY_ERR_INDEX_MASK = $FF;<br> CERT_ALT_NAME_ENTRY_ERR_INDEX_SHIFT = 16;<br> CERT_ALT_NAME_VALUE_ERR_INDEX_MASK = $0000FFFF;<br> CERT_ALT_NAME_VALUE_ERR_INDEX_SHIFT = 0;<br><br>{#define GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X) /<br> ((X >> CERT_ALT_NAME_ENTRY_ERR_INDEX_SHIFT) & /<br> CERT_ALT_NAME_ENTRY_ERR_INDEX_MASK)}<br>function GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X
WORD)
WORD;<br><br>{#define GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X) /<br> (X & CERT_ALT_NAME_VALUE_ERR_INDEX_MASK)}<br>function GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X
WORD)
WORD;<br><br>//+-------------------------------------------------------------------------<br>// X509_BASIC_CONSTRAINTS<br>// szOID_BASIC_CONSTRAINTS<br>//<br>// pvStructInfo points to following CERT_BASIC_CONSTRAINTS_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_BASIC_CONSTRAINTS_INFO = ^CERT_BASIC_CONSTRAINTS_INFO;<br> CERT_BASIC_CONSTRAINTS_INFO = record<br> SubjectType :CRYPT_BIT_BLOB;<br> fPathLenConstraint :BOOL;<br> dwPathLenConstraint
WORD;<br> cSubtreesConstraint
WORD;<br> rgSubtreesConstraint
CERT_NAME_BLOB;<br> end;<br><br>const <br> CERT_CA_SUBJECT_FLAG = $80;<br> CERT_END_ENTITY_SUBJECT_FLAG = $40;<br><br>//+-------------------------------------------------------------------------<br>// X509_BASIC_CONSTRAINTS2<br>// szOID_BASIC_CONSTRAINTS2<br>//<br>// pvStructInfo points to following CERT_BASIC_CONSTRAINTS2_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_BASIC_CONSTRAINTS2_INFO = ^CERT_BASIC_CONSTRAINTS2_INFO;<br> CERT_BASIC_CONSTRAINTS2_INFO = record<br> fCA :BOOL;<br> fPathLenConstraint :BOOL;<br> dwPathLenConstraint
WORD;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// X509_KEY_USAGE<br>// szOID_KEY_USAGE<br>//<br>// pvStructInfo points to a CRYPT_BIT_BLOB. Has same bit definitions as<br>// CERT_KEY_ATTRIBUTES_INFO's IntendedKeyUsage.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_CERT_POLICIES<br>// szOID_CERT_POLICIES<br>//<br>// pvStructInfo points to following CERT_POLICIES_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_POLICY_QUALIFIER_INFO = ^CERT_POLICY_QUALIFIER_INFO;<br> CERT_POLICY_QUALIFIER_INFO = record<br> pszPolicyQualifierId :LPSTR; // pszObjId<br> Qualifier :CRYPT_OBJID_BLOB; // optional<br> end;<br><br>type<br> PCERT_POLICY_INFO = ^CERT_POLICY_INFO;<br> CERT_POLICY_INFO = record<br> pszPolicyIdentifier :LPSTR; // pszObjId<br> cPolicyQualifier
WORD; // optional<br> rgPolicyQualifier
CERT_POLICY_QUALIFIER_INFO;<br> end;<br><br>type<br> PCERT_POLICIES_INFO = ^CERT_POLICIES_INFO;<br> CERT_POLICIES_INFO = record<br> cPolicyInfo
WORD;<br> rgPolicyInfo
CERT_POLICY_INFO;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// RSA_CSP_PUBLICKEYBLOB<br>//<br>// pvStructInfo points to a PUBLICKEYSTRUC immediately followed by a<br>// RSAPUBKEY and the modulus bytes.<br>//<br>// CryptExportKey outputs the above StructInfo for a dwBlobType of<br>// PUBLICKEYBLOB. CryptImportKey expects the above StructInfo when<br>// importing a public key.<br>//<br>// For dwCertEncodingType = X509_ASN_ENCODING, the RSA_CSP_PUBLICKEYBLOB is<br>// encoded as a PKCS #1 RSAPublicKey consisting of a SEQUENCE of a<br>// modulus INTEGER and a publicExponent INTEGER. The modulus is encoded<br>// as being a unsigned integer. When decoded, if the modulus was encoded<br>// as unsigned integer with a leading 0 byte, the 0 byte is removed before<br>// converting to the CSP modulus bytes.<br>//<br>// For decode, the aiKeyAlg field of PUBLICKEYSTRUC is always set to<br>// CALG_RSA_KEYX.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_KEYGEN_REQUEST_TO_BE_SIGNED<br>//<br>// pvStructInfo points to CERT_KEYGEN_REQUEST_INFO.<br>//<br>// For CryptDecodeObject(), the pbEncoded is the "to be signed" plus its<br>// signature (output of a X509_CERT CryptEncodeObject()).<br>//<br>// For CryptEncodeObject(), the pbEncoded is just the "to be signed".<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// PKCS_ATTRIBUTE data structure<br>//<br>// pvStructInfo points to a CRYPT_ATTRIBUTE.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// PKCS_CONTENT_INFO_SEQUENCE_OF_ANY data structure<br>//<br>// pvStructInfo points to following CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY.<br>//<br>// For X509_ASN_ENCODING: encoded as a PKCS#7 ContentInfo structure wrapping<br>// a sequence of ANY. The value of the contentType field is pszObjId,<br>// while the content field is the following structure:<br>// SequenceOfAny ::= SEQUENCE OF ANY<br>//<br>// The CRYPT_DER_BLOBs point to the already encoded ANY content.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY = ^CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY;<br> CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY = record<br> pszObjId :LPSTR;<br> cValue
WORD;<br> rgValue
CRYPT_DER_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// PKCS_CONTENT_INFO data structure<br>//<br>// pvStructInfo points to following CRYPT_CONTENT_INFO.<br>//<br>// For X509_ASN_ENCODING: encoded as a PKCS#7 ContentInfo structure.<br>// The CRYPT_DER_BLOB points to the already encoded ANY content.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_CONTENT_INFO = ^CRYPT_CONTENT_INFO;<br> CRYPT_CONTENT_INFO = record<br> pszObjId :LPSTR;<br> Content :CRYPT_DER_BLOB;<br> end;<br><br><br>//+-------------------------------------------------------------------------<br>// X509_OCTET_STRING data structure<br>//<br>// pvStructInfo points to a CRYPT_DATA_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_BITS data structure<br>//<br>// pvStructInfo points to a CRYPT_BIT_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_INTEGER data structure<br>//<br>// pvStructInfo points to an int.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_MULTI_BYTE_INTEGER data structure<br>//<br>// pvStructInfo points to a CRYPT_INTEGER_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_ENUMERATED data structure<br>//<br>// pvStructInfo points to an int containing the enumerated value<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_CHOICE_OF_TIME data structure<br>//<br>// pvStructInfo points to a FILETIME.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_SEQUENCE_OF_ANY data structure<br>//<br>// pvStructInfo points to following CRYPT_SEQUENCE_OF_ANY.<br>//<br>// The CRYPT_DER_BLOBs point to the already encoded ANY content.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_SEQUENCE_OF_ANY = ^CRYPT_SEQUENCE_OF_ANY;<br> CRYPT_SEQUENCE_OF_ANY = record<br> cValue
WORD;<br> rgValue
CRYPT_DER_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// X509_AUTHORITY_KEY_ID2<br>// szOID_AUTHORITY_KEY_IDENTIFIER2<br>//<br>// pvStructInfo points to following CERT_AUTHORITY_KEY_ID2_INFO.<br>//<br>// For CRYPT_E_INVALID_IA5_STRING, the error location is returned in<br>// *pcbEncoded by CryptEncodeObject(X509_AUTHORITY_KEY_ID2)<br>//<br>// See X509_ALTERNATE_NAME for error location defines.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_AUTHORITY_KEY_ID2_INFO = ^CERT_AUTHORITY_KEY_ID2_INFO;<br> CERT_AUTHORITY_KEY_ID2_INFO = record<br> KeyId :CRYPT_DATA_BLOB;<br> AuthorityCertIssuer :CERT_ALT_NAME_INFO; // Optional, set cAltEntry to 0 to omit.<br> AuthorityCertSerialNumber :CRYPT_INTEGER_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// szOID_SUBJECT_KEY_IDENTIFIER<br>//<br>// pvStructInfo points to a CRYPT_DATA_BLOB.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// X509_CRL_REASON_CODE<br>// szOID_CRL_REASON_CODE<br>//<br>// pvStructInfo points to an int which can be set to one of the following<br>// enumerated values:<br>//--------------------------------------------------------------------------<br><br>const <br> CRL_REASON_UNSPECIFIED = 0;<br> CRL_REASON_KEY_COMPROMISE = 1;<br> CRL_REASON_CA_COMPROMISE = 2;<br> CRL_REASON_AFFILIATION_CHANGED = 3;<br> CRL_REASON_SUPERSEDED = 4;<br> CRL_REASON_CESSATION_OF_OPERATION = 5;<br> CRL_REASON_CERTIFICATE_HOLD = 6;<br> CRL_REASON_REMOVE_FROM_CRL = 8;<br><br>//+-------------------------------------------------------------------------<br>// X509_CRL_DIST_POINTS<br>// szOID_CRL_DIST_POINTS<br>//<br>// pvStructInfo points to following CRL_DIST_POINTS_INFO.<br>//<br>// For CRYPT_E_INVALID_IA5_STRING, the error location is returned in<br>// *pcbEncoded by CryptEncodeObject(X509_CRL_DIST_POINTS)<br>//<br>// Error location consists of:<br>// CRL_ISSUER_BIT - 1 bit << 31 (0 for FullName, 1 for CRLIssuer)<br>// POINT_INDEX - 7 bits << 24<br>// ENTRY_INDEX - 8 bits << 16<br>// VALUE_INDEX - 16 bits (unicode character index)<br>//<br>// See X509_ALTERNATE_NAME for ENTRY_INDEX and VALUE_INDEX error location<br>// defines.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRL_DIST_POINT_NAME = ^CRL_DIST_POINT_NAME;<br> CRL_DIST_POINT_NAME = record<br> dwDistPointNameChoice
WORD;<br> case integer of<br> 0
FullName :CERT_ALT_NAME_INFO); {1}<br> 1
{IssuerRDN :Not implemented}); {2}<br> end;<br><br>const <br> CRL_DIST_POINT_NO_NAME = 0;<br> CRL_DIST_POINT_FULL_NAME = 1;<br> CRL_DIST_POINT_ISSUER_RDN_NAME = 2;<br><br>type<br> PCRL_DIST_POINT = ^CRL_DIST_POINT;<br> CRL_DIST_POINT = record<br> DistPointName :CRL_DIST_POINT_NAME; // OPTIONAL<br> ReasonFlags :CRYPT_BIT_BLOB; // OPTIONAL<br> CRLIssuer :CERT_ALT_NAME_INFO; // OPTIONAL<br> end;<br><br>const <br> CRL_REASON_UNUSED_FLAG = $80;<br> CRL_REASON_KEY_COMPROMISE_FLAG = $40;<br> CRL_REASON_CA_COMPROMISE_FLAG = $20;<br> CRL_REASON_AFFILIATION_CHANGED_FLAG = $10;<br> CRL_REASON_SUPERSEDED_FLAG = $08;<br> CRL_REASON_CESSATION_OF_OPERATION_FLAG = $04;<br> CRL_REASON_CERTIFICATE_HOLD_FLAG = $02;<br><br>type<br> PCRL_DIST_POINTS_INFO = ^CRL_DIST_POINTS_INFO;<br> CRL_DIST_POINTS_INFO = record<br> cDistPoint
WORD;<br> rgDistPoint
CRL_DIST_POINT;<br> end;<br><br>const <br> CRL_DIST_POINT_ERR_INDEX_MASK = $7F;<br> CRL_DIST_POINT_ERR_INDEX_SHIFT = 24;<br><br>{#define GET_CRL_DIST_POINT_ERR_INDEX(X) /<br> ((X >> CRL_DIST_POINT_ERR_INDEX_SHIFT) & CRL_DIST_POINT_ERR_INDEX_MASK)}<br>function GET_CRL_DIST_POINT_ERR_INDEX(X
WORD)
WORD;<br>const CRL_DIST_POINT_ERR_CRL_ISSUER_BIT = (DWORD($80000000));<br><br>{#define IS_CRL_DIST_POINT_ERR_CRL_ISSUER(X) /<br> (0 != (X & CRL_DIST_POINT_ERR_CRL_ISSUER_BIT))}<br>function IS_CRL_DIST_POINT_ERR_CRL_ISSUER(X
WORD):BOOL;<br><br>//+-------------------------------------------------------------------------<br>// X509_ENHANCED_KEY_USAGE<br>// szOID_ENHANCED_KEY_USAGE<br>//<br>// pvStructInfo points to a CERT_ENHKEY_USAGE, CTL_USAGE.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// szOID_NEXT_UPDATE_LOCATION<br>//<br>// pvStructInfo points to a CERT_ALT_NAME_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// PKCS_CTL<br>// szOID_CTL<br>//<br>// pvStructInfo points to a CTL_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_MULTI_BYTE_UINT<br>//<br>// pvStructInfo points to a CRYPT_UINT_BLOB. Before encoding, inserts a<br>// leading 0x00. After decoding, removes a leading 0x00.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_DSS_PUBLICKEY<br>//<br>// pvStructInfo points to a CRYPT_UINT_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// X509_DSS_PARAMETERS<br>//<br>// pvStructInfo points to following CERT_DSS_PARAMETERS data structure.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_DSS_PARAMETERS = ^CERT_DSS_PARAMETERS;<br> CERT_DSS_PARAMETERS = record<br> p :CRYPT_UINT_BLOB;<br> q :CRYPT_UINT_BLOB;<br> g :CRYPT_UINT_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// X509_DSS_SIGNATURE<br>//<br>// pvStructInfo is a BYTE rgbSignature[CERT_DSS_SIGNATURE_LEN]. The<br>// bytes are ordered as output by the DSS CSP's CryptSignHash().<br>//--------------------------------------------------------------------------<br><br>const <br> CERT_DSS_R_LEN = 20;<br> CERT_DSS_S_LEN = 20;<br> CERT_DSS_SIGNATURE_LEN = (CERT_DSS_R_LEN + CERT_DSS_S_LEN);<br><br>// Sequence of 2 unsigned integers (the extra +1 is for a potential leading<br>// 0x00 to make the integer unsigned)<br> CERT_MAX_ASN_ENCODED_DSS_SIGNATURE_LEN = (2 + 2*(2 + 20 +1));<br><br>//+-------------------------------------------------------------------------<br>// PKCS_RC2_CBC_PARAMETERS<br>// szOID_RSA_RC2CBC<br>//<br>// pvStructInfo points to following CRYPT_RC2_CBC_PARAMETERS data structure.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_RC2_CBC_PARAMETERS = ^CRYPT_RC2_CBC_PARAMETERS;<br> CRYPT_RC2_CBC_PARAMETERS = record<br> dwVersion
WORD;<br> fIV :BOOL; // set if has following IV<br> rgbIV :array[0..8-1] of BYTE;<br> end;<br><br>const <br> CRYPT_RC2_40BIT_VERSION = 160;<br> CRYPT_RC2_64BIT_VERSION = 120;<br> CRYPT_RC2_128BIT_VERSION = 58;<br><br><br>//+-------------------------------------------------------------------------<br>// PKCS_SMIME_CAPABILITIES<br>// szOID_RSA_SMIMECapabilities<br>//<br>// pvStructInfo points to following CRYPT_SMIME_CAPABILITIES data structure.<br>//<br>// Note, for CryptEncodeObject(X509_ASN_ENCODING), Parameters.cbData == 0<br>// causes the encoded parameters to be omitted and not encoded as a NULL<br>// (05 00) as is done when encoding a CRYPT_ALGORITHM_IDENTIFIER. This<br>// is per the SMIME specification for encoding capabilities.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_SMIME_CAPABILITY = ^CRYPT_SMIME_CAPABILITY;<br> CRYPT_SMIME_CAPABILITY = record<br> pszObjId :LPSTR;<br> Parameters :CRYPT_OBJID_BLOB;<br> end;<br><br>type<br> PCRYPT_SMIME_CAPABILITIES = ^CRYPT_SMIME_CAPABILITIES;<br> CRYPT_SMIME_CAPABILITIES = record<br> cCapability
WORD;<br> rgCapability
CRYPT_SMIME_CAPABILITY;<br> end;<br><br><br>//+-------------------------------------------------------------------------<br>// PKCS7_SIGNER_INFO<br>//<br>// pvStructInfo points to CMSG_SIGNER_INFO.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// Netscape Certificate Extension Object Identifiers<br>//--------------------------------------------------------------------------<br><br>const <br> szOID_NETSCAPE = '2.16.840.1.113730';<br> szOID_NETSCAPE_CERT_EXTENSION = '2.16.840.1.113730.1';<br> szOID_NETSCAPE_CERT_TYPE = '2.16.840.1.113730.1.1';<br> szOID_NETSCAPE_BASE_URL = '2.16.840.1.113730.1.2';<br> szOID_NETSCAPE_REVOCATION_URL = '2.16.840.1.113730.1.3';<br> szOID_NETSCAPE_CA_REVOCATION_URL = '2.16.840.1.113730.1.4';<br> szOID_NETSCAPE_CERT_RENEWAL_URL = '2.16.840.1.113730.1.7';<br> szOID_NETSCAPE_CA_POLICY_URL = '2.16.840.1.113730.1.8';<br> szOID_NETSCAPE_SSL_SERVER_NAME = '2.16.840.1.113730.1.12';<br> szOID_NETSCAPE_COMMENT = '2.16.840.1.113730.1.13';<br><br>//+-------------------------------------------------------------------------<br>// Netscape Certificate Data Type Object Identifiers<br>//--------------------------------------------------------------------------<br><br>const <br> szOID_NETSCAPE_DATA_TYPE = '2.16.840.1.113730.2';<br> szOID_NETSCAPE_CERT_SEQUENCE = '2.16.840.1.113730.2.5';<br><br>//+-------------------------------------------------------------------------<br>// szOID_NETSCAPE_CERT_TYPE extension<br>//<br>// Its value is a bit string. CryptDecodeObject/CryptEncodeObject using<br>// X509_BITS.<br>//<br>// The following bits are defined:<br>//--------------------------------------------------------------------------<br><br>const <br> NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE = $80;<br> NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE = $40;<br> NETSCAPE_SSL_CA_CERT_TYPE = $04;<br><br>//+-------------------------------------------------------------------------<br>// szOID_NETSCAPE_BASE_URL extension<br>//<br>// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// When present this string is added to the beginning of all relative URLs<br>// in the certificate. This extension can be considered an optimization<br>// to reduce the size of the URL extensions.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// szOID_NETSCAPE_REVOCATION_URL extension<br>//<br>// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// It is a relative or absolute URL that can be used to check the<br>// revocation status of a certificate. The revocation check will be<br>// performed as an HTTP GET method using a url that is the concatenation of<br>// revocation-url and certificate-serial-number.<br>// Where the certificate-serial-number is encoded as a string of<br>// ascii hexadecimal digits. For example, if the netscape-base-url is<br>// https://www.certs-r-us.com/, the netscape-revocation-url is<br>// cgi-bin/check-rev.cgi?, and the certificate serial number is 173420,<br>// the resulting URL would be:<br>// https://www.certs-r-us.com/cgi-bin/check-rev.cgi?02a56c<br>//<br>// The server should return a document with a Content-Type of<br>// application/x-netscape-revocation. The document should contain<br>// a single ascii digit, '1' if the certificate is not curently valid,<br>// and '0' if it is curently valid.<br>//<br>// Note: for all of the URLs that include the certificate serial number,<br>// the serial number will be encoded as a string which consists of an even<br>// number of hexadecimal digits. If the number of significant digits is odd,<br>// the string will have a single leading zero to ensure an even number of<br>// digits is generated.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// szOID_NETSCAPE_CA_REVOCATION_URL extension<br>//<br>// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// It is a relative or absolute URL that can be used to check the<br>// revocation status of any certificates that are signed by the CA that<br>// this certificate belongs to. This extension is only valid in CA<br>// certificates. The use of this extension is the same as the above<br>// szOID_NETSCAPE_REVOCATION_URL extension.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// szOID_NETSCAPE_CERT_RENEWAL_URL extension<br>//<br>// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// It is a relative or absolute URL that points to a certificate renewal<br>// form. The renewal form will be accessed with an HTTP GET method using a<br>// url that is the concatenation of renewal-url and<br>// certificate-serial-number. Where the certificate-serial-number is<br>// encoded as a string of ascii hexadecimal digits. For example, if the<br>// netscape-base-url is https://www.certs-r-us.com/, the<br>// netscape-cert-renewal-url is cgi-bin/check-renew.cgi?, and the<br>// certificate serial number is 173420, the resulting URL would be:<br>// https://www.certs-r-us.com/cgi-bin/check-renew.cgi?02a56c<br>// The document returned should be an HTML form that will allow the user<br>// to request a renewal of their certificate.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// szOID_NETSCAPE_CA_POLICY_URL extension<br>//<br>// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// It is a relative or absolute URL that points to a web page that<br>// describes the policies under which the certificate was issued.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// szOID_NETSCAPE_SSL_SERVER_NAME extension<br>//<br>// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// It is a "shell expression" that can be used to match the hostname of the<br>// SSL server that is using this certificate. It is recommended that if<br>// the server's hostname does not match this pattern the user be notified<br>// and given the option to terminate the SSL connection. If this extension<br>// is not present then the CommonName in the certificate subject's<br>// distinguished name is used for the same purpose.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// szOID_NETSCAPE_COMMENT extension<br>//<br>// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// It is a comment that may be displayed to the user when the certificate<br>// is viewed.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// szOID_NETSCAPE_CERT_SEQUENCE<br>//<br>// Its value is a PKCS#7 ContentInfo structure wrapping a sequence of<br>// certificates. The value of the contentType field is<br>// szOID_NETSCAPE_CERT_SEQUENCE, while the content field is the following<br>// structure:<br>// CertificateSequence ::= SEQUENCE OF Certificate.<br>//<br>// CryptDecodeObject/CryptEncodeObject using<br>// PKCS_CONTENT_INFO_SEQUENCE_OF_ANY, where,<br>// pszObjId = szOID_NETSCAPE_CERT_SEQUENCE and the CRYPT_DER_BLOBs point<br>// to encoded X509 certificates.<br>//--------------------------------------------------------------------------<br><br><br>//+=========================================================================<br>// Object IDentifier (OID) Installable Functions: Data Structures and APIs<br>//==========================================================================<br><br>type<br> HCRYPTOIDFUNCSET = procedure;<br> HCRYPTOIDFUNCADDR = procedure;<br><br>// Predefined OID Function Names<br>const <br> CRYPT_OID_ENCODE_OBJECT_FUNC = 'CryptDllEncodeObject';<br> CRYPT_OID_DECODE_OBJECT_FUNC = 'CryptDllDecodeObject';<br> CRYPT_OID_CREATE_COM_OBJECT_FUNC = 'CryptDllCreateCOMObject';<br> CRYPT_OID_VERIFY_REVOCATION_FUNC = 'CertDllVerifyRevocation';<br> CRYPT_OID_VERIFY_CTL_USAGE_FUNC = 'CertDllVerifyCTLUsage';<br> CRYPT_OID_FORMAT_OBJECT_FUNC = 'CryptDllFormatObject';<br> CRYPT_OID_FIND_OID_INFO_FUNC = 'CryptDllFindOIDInfo';<br><br>// CryptDllEncodeObject has same function signature as CryptEncodeObject.<br><br>// CryptDllDecodeObject has same function signature as CryptDecodeObject.<br><br>// CryptDllCreateCOMObject has the following signature:<br>// BOOL WINAPI CryptDllCreateCOMObject(<br>// IN DWORD dwEncodingType,<br>// IN LPCSTR pszOID,<br>// IN PCRYPT_DATA_BLOB pEncodedContent,<br>// IN DWORD dwFlags,<br>// IN REFIID riid,<br>// OUT void **ppvObj);<br><br>// CertDllVerifyRevocation has the same signature as CertVerifyRevocation<br>// (See CertVerifyRevocation for details on when called)<br><br>// CertDllVerifyCTLUsage has the same signature as CertVerifyCTLUsage<br><br>// CryptDllFindOIDInfo currently is only used to store values used by<br>// CryptFindOIDInfo. See CryptFindOIDInfo() for more details.<br><br>// Example of a complete OID Function Registry Name:<br>// HKEY_LOCAL_MACHINE/Software/Microsoft/Cryptography/OID<br>// Encoding Type 1/CryptDllEncodeObject/1.2.3<br>//<br>// The key's L"Dll" value contains the name of the Dll.<br>// The key's L"FuncName" value overrides the default function name<br><br>const <br> CRYPT_OID_REGPATH = 'Software//Microsoft//Cryptography//OID';<br> CRYPT_OID_REG_ENCODING_TYPE_PREFIX = 'EncodingType ';<br>{$IFNDEF VER90}<br> CRYPT_OID_REG_DLL_VALUE_NAME = WideString('Dll');<br> CRYPT_OID_REG_FUNC_NAME_VALUE_NAME = WideString('FuncName');<br>{$ELSE}<br> CRYPT_OID_REG_DLL_VALUE_NAME = ('Dll');<br> CRYPT_OID_REG_FUNC_NAME_VALUE_NAME = ('FuncName');<br>{$ENDIF}<br> CRYPT_OID_REG_FUNC_NAME_VALUE_NAME_A = 'FuncName';<br><br>// OID used for Default OID functions<br> CRYPT_DEFAULT_OID = 'DEFAULT';<br><br>type<br> PCRYPT_OID_FUNC_ENTRY = ^CRYPT_OID_FUNC_ENTRY;<br> CRYPT_OID_FUNC_ENTRY = record<br> pszOID :LPCSTR;<br> pvFuncAddr
VOID;<br> end;<br><br>const <br> CRYPT_INSTALL_OID_FUNC_BEFORE_FLAG = 1;<br><br>//+-------------------------------------------------------------------------<br>// Install a set of callable OID function addresses.<br>//<br>// By default the functions are installed at end of the list.<br>// Set CRYPT_INSTALL_OID_FUNC_BEFORE_FLAG to install at beginning of list.<br>//<br>// hModule should be updated with the hModule passed to DllMain to prevent<br>// the Dll containing the function addresses from being unloaded by<br>// CryptGetOIDFuncAddress/CryptFreeOIDFunctionAddress. This would be the<br>// case when the Dll has also regsvr32'ed OID functions via<br>// CryptRegisterOIDFunction.<br>//<br>// DEFAULT functions are installed by setting rgFuncEntry[].pszOID =<br>// CRYPT_DEFAULT_OID.<br>//--------------------------------------------------------------------------<br><br>function CryptInstallOIDFunctionAddress(hModule :HMODULE; // hModule passed to DllMain<br> dwEncodingType
WORD;<br> pszFuncName :LPCSTR;<br> cFuncEntry
WORD;<br> const rgFuncEntry :array of CRYPT_OID_FUNC_ENTRY;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Initialize and return handle to the OID function set identified by its<br>// function name.<br>//<br>// If the set already exists, a handle to the existing set is returned.<br>//--------------------------------------------------------------------------<br><br>function CryptInitOIDFunctionSet(pszFuncName :LPCSTR;<br> dwFlags
WORD ):HCRYPTOIDFUNCSET ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Search the list of installed functions for an encoding type and OID match.<br>// If not found, search the registry.<br>//<br>// For success, returns TRUE with *ppvFuncAddr updated with the function's<br>// address and *phFuncAddr updated with the function address's handle.<br>// The function's handle is AddRef'ed. CryptFreeOIDFunctionAddress needs to<br>// be called to release it.<br>//<br>// For a registry match, the Dll containing the function is loaded.<br>//--------------------------------------------------------------------------<br><br>function CryptGetOIDFunctionAddress(hFuncSet :HCRYPTOIDFUNCSET;<br> dwEncodingType
WORD;<br> pszOID :LPCSTR;<br> dwFlags
WORD;<br> var ppvFuncAddr :array of PVOID;<br> var phFuncAddr :HCRYPTOIDFUNCADDR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Get the list of registered default Dll entries for the specified<br>// function set and encoding type.<br>//<br>// The returned list consists of none, one or more null terminated Dll file<br>// names. The list is terminated with an empty (L"/0"
Dll file name.<br>// For example: L"first.dll" L"/0" L"second.dll" L"/0" L"/0"<br>//--------------------------------------------------------------------------<br><br>function CryptGetDefaultOIDDllList(hFuncSet :HCRYPTOIDFUNCSET;<br> dwEncodingType
WORD;<br> pwszDllList :LPWSTR;<br> pcchDllList
DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Either: get the first or next installed DEFAULT function OR<br>// load the Dll containing the DEFAULT function.<br>//<br>// If pwszDll is NULL, search the list of installed DEFAULT functions.<br>// *phFuncAddr must be set to NULL to get the first installed function.<br>// Successive installed functions are returned by setting *phFuncAddr<br>// to the hFuncAddr returned by the previous call.<br>//<br>// If pwszDll is NULL, the input *phFuncAddr<br>// is always CryptFreeOIDFunctionAddress'ed by this function, even for<br>// an error.<br>//<br>// If pwszDll isn't NULL, then, attempts to load the Dll and the DEFAULT<br>// function. *phFuncAddr is ignored upon entry and isn't<br>// CryptFreeOIDFunctionAddress'ed.<br>//<br>// For success, returns TRUE with *ppvFuncAddr updated with the function's<br>// address and *phFuncAddr updated with the function address's handle.<br>// The function's handle is AddRef'ed. CryptFreeOIDFunctionAddress needs to<br>// be called to release it or CryptGetDefaultOIDFunctionAddress can also<br>// be called for a NULL pwszDll.<br>//--------------------------------------------------------------------------<br><br>function CryptGetDefaultOIDFunctionAddress(hFuncSet :HCRYPTOIDFUNCSET;<br> dwEncodingType
WORD;<br> pwszDll
WORD;<br> dwFlags :LPCWSTR;<br> var ppvFuncAddr :array of PVOID;<br> var phFuncAddr :HCRYPTOIDFUNCADDR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Releases the handle AddRef'ed and returned by CryptGetOIDFunctionAddress<br>// or CryptGetDefaultOIDFunctionAddress.<br>//<br>// If a Dll was loaded for the function its unloaded. However, before doing<br>// the unload, the DllCanUnloadNow function exported by the loaded Dll is<br>// called. It should return S_FALSE to inhibit the unload or S_TRUE to enable<br>// the unload. If the Dll doesn't export DllCanUnloadNow, the Dll is unloaded.<br>//<br>// DllCanUnloadNow has the following signature:<br>// STDAPI DllCanUnloadNow(void);<br>//--------------------------------------------------------------------------<br><br>function CryptFreeOIDFunctionAddress(hFuncAddr :HCRYPTOIDFUNCADDR;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Register the Dll containing the function to be called for the specified<br>// encoding type, function name and OID.<br>//<br>// pwszDll may contain environment-variable strings<br>// which are ExpandEnvironmentStrings()'ed before loading the Dll.<br>//<br>// In addition to registering the DLL, you may override the<br>// name of the function to be called. For example,<br>// pszFuncName = "CryptDllEncodeObject",<br>// pszOverrideFuncName = "MyEncodeXyz".<br>// This allows a Dll to export multiple OID functions for the same<br>// function name without needing to interpose its own OID dispatcher function.<br>//--------------------------------------------------------------------------<br><br>function CryptRegisterOIDFunction(dwEncodingType
WORD;<br> pszFuncName :LPCSTR;<br> pszOID :LPCSTR; //OPTIONAL<br> pwszDll :LPCWSTR; //OPTIONAL<br> pszOverrideFuncName :LPCSTR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Unregister the Dll containing the function to be called for the specified<br>// encoding type, function name and OID.<br>//--------------------------------------------------------------------------<br><br>function CryptUnregisterOIDFunction(dwEncodingType
WORD;<br> pszFuncName :LPCSTR;<br> pszOID :LPCSTR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Register the Dll containing the default function to be called for the<br>// specified encoding type and function name.<br>//<br>// Unlike CryptRegisterOIDFunction, you can't override the function name<br>// needing to be exported by the Dll.<br>//<br>// The Dll is inserted before the entry specified by dwIndex.<br>// dwIndex == 0, inserts at the beginning.<br>// dwIndex == CRYPT_REGISTER_LAST_INDEX, appends at the end.<br>//<br>// pwszDll may contain environment-variable strings<br>// which are ExpandEnvironmentStrings()'ed before loading the Dll.<br>//--------------------------------------------------------------------------<br><br>function CryptRegisterDefaultOIDFunction(dwEncodingType
WORD;<br> pszFuncName :LPCSTR;<br> dwIndex
WORD;<br> pwszDll :LPCWSTR):BOOL ; stdcall;<br><br>const <br> CRYPT_REGISTER_FIRST_INDEX = 0;<br> CRYPT_REGISTER_LAST_INDEX = $FFFFFFFF;<br><br>//+-------------------------------------------------------------------------<br>// Unregister the Dll containing the default function to be called for<br>// the specified encoding type and function name.<br>//--------------------------------------------------------------------------<br><br>function CryptUnregisterDefaultOIDFunction(dwEncodingType
WORD;<br> pszFuncName :LPCSTR;<br> pwszDll :LPCWSTR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Set the value for the specified encoding type, function name, OID and<br>// value name.<br>//<br>// See RegSetValueEx for the possible value types.<br>//<br>// String types are UNICODE.<br>//--------------------------------------------------------------------------<br><br>function CryptSetOIDFunctionValue(dwEncodingType
WORD;<br> pszFuncName :LPCSTR;<br> pszOID :LPCSTR;<br> pwszValueName :LPCWSTR;<br> dwValueType
WORD;<br> const pbValueData
BYTE;<br> cbValueData
WORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Get the value for the specified encoding type, function name, OID and<br>// value name.<br>//<br>// See RegEnumValue for the possible value types.<br>//<br>// String types are UNICODE.<br>//--------------------------------------------------------------------------<br><br>function CryptGetOIDFunctionValue(dwEncodingType
WORD;<br> pszFuncName :LPCSTR;<br> pwszValueName :LPCSTR;<br> pszOID :LPCWSTR;<br> pdwValueType
DWORD;<br> pbValueData
BYTE;<br> pcbValueData
DWORD):BOOL ; stdcall;<br><br>type<br> PFN_CRYPT_ENUM_OID_FUNC = function (dwEncodingType
WORD;<br> pszFuncName :LPCSTR;<br> pszOID :LPCSTR;<br> cValue
WORD;<br> const rgdwValueType :array of DWORD;<br> const rgpwszValueName :array of LPCWSTR;<br> const rgpbValueData :array of PBYTE;<br> const rgcbValueData :array of DWORD;<br> pvArg
VOID):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Enumerate the OID functions identified by their encoding type,<br>// function name and OID.<br>//<br>// pfnEnumOIDFunc is called for each registry key matching the input<br>// parameters. Setting dwEncodingType to CRYPT_MATCH_ANY_ENCODING_TYPE matches<br>// any. Setting pszFuncName or pszOID to NULL matches any.<br>//<br>// Set pszOID == CRYPT_DEFAULT_OID to restrict the enumeration to only the<br>// DEFAULT functions<br>//<br>// String types are UNICODE.<br>//--------------------------------------------------------------------------<br><br>function CryptEnumOIDFunction(dwEncodingType
WORD;<br> pszFuncName :LPCSTR; //OPTIONAL<br> pszOID :LPCSTR; //OPTIONAL<br> dwFlags
WORD;<br> pvArg
VOID;<br> pfnEnumOIDFunc
FN_CRYPT_ENUM_OID_FUNC):BOOL ; stdcall;<br><br>const <br> CRYPT_MATCH_ANY_ENCODING_TYPE = $FFFFFFFF;<br><br>//+=========================================================================<br>// Object IDentifier (OID) Information: Data Structures and APIs<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// OID Information<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_OID_INFO = ^CRYPT_OID_INFO;<br> CRYPT_OID_INFO = record<br> cbSize
WORD;<br> pszOID :LPCSTR;<br> pwszName :LPCWSTR;<br> dwGroupId
WORD;<br> EnumValue : record {type EnumValue for the union part of the original struct --max--}<br> case integer of<br> 0
dwValue
WORD);<br> 1
Algid :ALG_ID);<br> 2
dwLength
WORD);<br> end;<br> ExtraInfo :CRYPT_DATA_BLOB;<br> end;<br><br>type<br> CCRYPT_OID_INFO = CRYPT_OID_INFO;<br> PCCRYPT_OID_INFO = ^CCRYPT_OID_INFO;<br><br>//+-------------------------------------------------------------------------<br>// OID Group IDs<br>//--------------------------------------------------------------------------<br><br>const<br> CRYPT_HASH_ALG_OID_GROUP_ID = 1;<br> CRYPT_ENCRYPT_ALG_OID_GROUP_ID = 2;<br> CRYPT_PUBKEY_ALG_OID_GROUP_ID = 3;<br> CRYPT_SIGN_ALG_OID_GROUP_ID = 4;<br> CRYPT_RDN_ATTR_OID_GROUP_ID = 5;<br> CRYPT_EXT_OR_ATTR_OID_GROUP_ID = 6;<br> CRYPT_ENHKEY_USAGE_OID_GROUP_ID = 7;<br> CRYPT_POLICY_OID_GROUP_ID = 8;<br> CRYPT_LAST_OID_GROUP_ID = 8;<br><br> CRYPT_FIRST_ALG_OID_GROUP_ID = CRYPT_HASH_ALG_OID_GROUP_ID;<br> CRYPT_LAST_ALG_OID_GROUP_ID = CRYPT_SIGN_ALG_OID_GROUP_ID;<br><br><br>// The CRYPT_*_ALG_OID_GROUP_ID's have an Algid. The CRYPT_RDN_ATTR_OID_GROUP_ID<br>// has a dwLength. The CRYPT_EXT_OR_ATTR_OID_GROUP_ID,<br>// CRYPT_ENHKEY_USAGE_OID_GROUP_ID or CRYPT_POLICY_OID_GROUP_ID don't have a<br>// dwValue.<br><br>// CRYPT_PUBKEY_ALG_OID_GROUP_ID has the following optional ExtraInfo:<br>// DWORD[0] - Flags. CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG can be set to<br>// inhibit the reformatting of the signature before<br>// CryptVerifySignature is called or after CryptSignHash<br>// is called. CRYPT_OID_USE_PUBKEY_PARA_FOR_PKCS7_FLAG can<br>// be set to include the public key algorithm's parameters<br>// in the PKCS7's digestEncryptionAlgorithm's parameters.<br><br> CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG = $1;<br> CRYPT_OID_USE_PUBKEY_PARA_FOR_PKCS7_FLAG = $2;<br><br>// CRYPT_SIGN_ALG_OID_GROUP_ID has the following optional ExtraInfo:<br>// DWORD[0] - Public Key Algid.<br>// DWORD[1] - Flags. Same as above for CRYPT_PUBKEY_ALG_OID_GROUP_ID.<br><br>// CRYPT_RDN_ATTR_OID_GROUP_ID has the following optional ExtraInfo:<br>// Array of DWORDs:<br>// [0 ..] - Null terminated list of acceptable RDN attribute<br>// value types. An empty list implies CERT_RDN_PRINTABLE_STRING,<br>// CERT_RDN_T61_STRING, 0.<br><br>//+-------------------------------------------------------------------------<br>// Find OID information. Returns NULL if unable to find any information<br>// for the specified key and group. Note, returns a pointer to a constant<br>// data structure. The returned pointer MUST NOT be freed.<br>//<br>// dwKeyType's:<br>// CRYPT_OID_INFO_OID_KEY, pvKey points to a szOID<br>// CRYPT_OID_INFO_NAME_KEY, pvKey points to a wszName<br>// CRYPT_OID_INFO_ALGID_KEY, pvKey points to an ALG_ID<br>// CRYPT_OID_INFO_SIGN_KEY, pvKey points to an array of two ALG_ID's:<br>// ALG_ID[0] - Hash Algid<br>// ALG_ID[1] - PubKey Algid<br>//<br>// Setting dwGroupId to 0, searches all groups according to the dwKeyType.<br>// Otherwise, only the dwGroupId is searched.<br>//--------------------------------------------------------------------------<br><br>function CryptFindOIDInfo(dwKeyType
WORD;<br> pvKey
VOID;<br> dwGroupId
WORD)
CCRYPT_OID_INFO ; stdcall;<br><br>const <br> CRYPT_OID_INFO_OID_KEY = 1;<br> CRYPT_OID_INFO_NAME_KEY = 2;<br> CRYPT_OID_INFO_ALGID_KEY = 3;<br> CRYPT_OID_INFO_SIGN_KEY = 4;<br><br>//+-------------------------------------------------------------------------<br>// Register OID information. The OID information specified in the<br>// CCRYPT_OID_INFO structure is persisted to the registry.<br>//<br>// crypt32.dll contains information for the commonly known OIDs. This function<br>// allows applications to augment crypt32.dll's OID information. During<br>// CryptFindOIDInfo's first call, the registered OID information is installed.<br>//<br>// By default the registered OID information is installed after crypt32.dll's<br>// OID entries. Set CRYPT_INSTALL_OID_INFO_BEFORE_FLAG to install before.<br>//--------------------------------------------------------------------------<br><br>function CryptRegisterOIDInfo(pInfo
CCRYPT_OID_INFO;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>const <br> CRYPT_INSTALL_OID_INFO_BEFORE_FLAG = 1;<br><br>//+-------------------------------------------------------------------------<br>// Unregister OID information. Only the pszOID and dwGroupId fields are<br>// used to identify the OID information to be unregistered.<br>//--------------------------------------------------------------------------<br><br>function CryptUnregisterOIDInfo(pInfo
CCRYPT_OID_INFO):BOOL ; stdcall;<br><br>//+=========================================================================<br>// Low Level Cryptographic Message Data Structures and APIs<br>//==========================================================================<br><br>type<br> HCRYPTMSG = Pointer;<br><br>const <br> szOID_PKCS_7_DATA = '1.2.840.113549.1.7.1';<br> szOID_PKCS_7_SIGNED = '1.2.840.113549.1.7.2';<br> szOID_PKCS_7_ENVELOPED = '1.2.840.113549.1.7.3';<br> szOID_PKCS_7_SIGNEDANDENVELOPED = '1.2.840.113549.1.7.4';<br> szOID_PKCS_7_DIGESTED = '1.2.840.113549.1.7.5';<br> szOID_PKCS_7_ENCRYPTED = '1.2.840.113549.1.7.6';<br><br> szOID_PKCS_9_CONTENT_TYPE = '1.2.840.113549.1.9.3';<br> szOID_PKCS_9_MESSAGE_DIGEST = '1.2.840.113549.1.9.4';<br><br>//+-------------------------------------------------------------------------<br>// Message types<br>//--------------------------------------------------------------------------<br><br>const <br> CMSG_DATA = 1;<br> CMSG_SIGNED = 2;<br> CMSG_ENVELOPED = 3;<br> CMSG_SIGNED_AND_ENVELOPED = 4;<br> CMSG_HASHED = 5;<br> CMSG_ENCRYPTED = 6;<br><br>//+-------------------------------------------------------------------------<br>// Message Type Bit Flags<br>//--------------------------------------------------------------------------<br><br> CMSG_ALL_FLAGS = (not ULONG(0));<br> CMSG_DATA_FLAG = (1 shl CMSG_DATA);<br> CMSG_SIGNED_FLAG = (1 shl CMSG_SIGNED);<br> CMSG_ENVELOPED_FLAG = (1 shl CMSG_ENVELOPED);<br> CMSG_SIGNED_AND_ENVELOPED_FLAG = (1 shl CMSG_SIGNED_AND_ENVELOPED);<br> CMSG_HASHED_FLAG = (1 shl CMSG_HASHED);<br> CMSG_ENCRYPTED_FLAG = (1 shl CMSG_ENCRYPTED);<br><br>//+-------------------------------------------------------------------------<br>// The message encode information (pvMsgEncodeInfo) is message type dependent<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_DATA: pvMsgEncodeInfo = NULL<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_SIGNED<br>//<br>// The pCertInfo in the CMSG_SIGNER_ENCODE_INFO provides the Issuer, SerialNumber<br>// and PublicKeyInfo.Algorithm. The PublicKeyInfo.Algorithm implicitly<br>// specifies the HashEncryptionAlgorithm to be used.<br>//<br>// The hCryptProv and dwKeySpec specify the private key to use. If dwKeySpec<br>// == 0, then, defaults to AT_SIGNATURE.<br>//<br>// pvHashAuxInfo currently isn't used and must be set to NULL.<br>//--------------------------------------------------------------------------<br><br>type<br> PCMSG_SIGNER_ENCODE_INFO = ^CMSG_SIGNER_ENCODE_INFO;<br> CMSG_SIGNER_ENCODE_INFO = record<br> cbSize
WORD;<br> pCertInfo
CERT_INFO;<br> hCryptProv :HCRYPTPROV;<br> dwKeySpec
WORD;<br> HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> pvHashAuxInfo
VOID;<br> cAuthAttr
WORD;<br> rgAuthAttr
CRYPT_ATTRIBUTE;<br> cUnauthAttr
WORD;<br> rgUnauthAttr
CRYPT_ATTRIBUTE;<br> end;<br><br>type<br> PCMSG_SIGNED_ENCODE_INFO = ^CMSG_SIGNED_ENCODE_INFO;<br> CMSG_SIGNED_ENCODE_INFO = record<br> cbSize
WORD;<br> cSigners
WORD;<br> rgSigners
CMSG_SIGNER_ENCODE_INFO;<br> cCertEncoded
WORD;<br> rgCertEncoded
CERT_BLOB;<br> cCrlEncoded
WORD;<br> rgCrlEncoded
CRL_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_ENVELOPED<br>//<br>// The PCERT_INFO for the rgRecipients provides the Issuer, SerialNumber<br>// and PublicKeyInfo. The PublicKeyInfo.Algorithm implicitly<br>// specifies the KeyEncryptionAlgorithm to be used.<br>//<br>// The PublicKeyInfo.PublicKey in PCERT_INFO is used to encrypt the content<br>// encryption key for the recipient.<br>//<br>// hCryptProv is used to do the content encryption, recipient key encryption<br>// and export. The hCryptProv's private keys aren't used.<br>//<br>// Note: CAPI currently doesn't support more than one KeyEncryptionAlgorithm<br>// per provider. This will need to be fixed.<br>//<br>// pvEncryptionAuxInfo currently isn't used and must be set to NULL.<br>//--------------------------------------------------------------------------<br><br>type<br> PCMSG_ENVELOPED_ENCODE_INFO = ^CMSG_ENVELOPED_ENCODE_INFO;<br> CMSG_ENVELOPED_ENCODE_INFO = record<br> cbSize
WORD;<br> hCryptProv :HCRYPTPROV;<br> ContentEncryptionAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> pvEncryptionAuxInfo
VOID;<br> cRecipients
WORD;<br> rgpRecipients
PCERT_INFO; // pointer to array of PCERT_INFO<br>end;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_SIGNED_AND_ENVELOPED<br>//<br>// For PKCS #7, a signed and enveloped message doesn't have the<br>// signer's authenticated or unauthenticated attributes. Otherwise, a<br>// combination of the CMSG_SIGNED_ENCODE_INFO and CMSG_ENVELOPED_ENCODE_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> PCMSG_SIGNED_AND_ENVELOPED_ENCODE_INFO = ^CMSG_SIGNED_AND_ENVELOPED_ENCODE_INFO;<br> CMSG_SIGNED_AND_ENVELOPED_ENCODE_INFO = record<br> cbSize
WORD;<br> SignedInfo :CMSG_SIGNED_ENCODE_INFO;<br> EnvelopedInfo :CMSG_ENVELOPED_ENCODE_INFO;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_HASHED<br>//<br>// hCryptProv is used to do the hash. Doesn't need to use a private key.<br>//<br>// If fDetachedHash is set, then, the encoded message doesn't contain<br>// any content (its treated as NULL Data)<br>//<br>// pvHashAuxInfo currently isn't used and must be set to NULL.<br>//--------------------------------------------------------------------------<br><br>type<br> PCMSG_HASHED_ENCODE_INFO = ^CMSG_HASHED_ENCODE_INFO;<br> CMSG_HASHED_ENCODE_INFO = record<br> cbSize
WORD;<br> hCryptProv :HCRYPTPROV;<br> HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> pvHashAuxInfo
VOID;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_ENCRYPTED<br>//<br>// The key used to encrypt the message is identified outside of the message<br>// content (for example, password).<br>//<br>// The content input to CryptMsgUpdate has already been encrypted.<br>//<br>// pvEncryptionAuxInfo currently isn't used and must be set to NULL.<br>//--------------------------------------------------------------------------<br><br>type<br> PCMSG_ENCRYPTED_ENCODE_INFO = ^CMSG_ENCRYPTED_ENCODE_INFO;<br> CMSG_ENCRYPTED_ENCODE_INFO = record<br> cbSize
WORD;<br> ContentEncryptionAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> pvEncryptionAuxInfo
VOID;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// This parameter allows messages to be of variable length with streamed<br>// output.<br>//<br>// By default, messages are of a definite length and<br>// CryptMsgGetParam(CMSG_CONTENT_PARAM) is<br>// called to get the cryptographically processed content. Until closed,<br>// the handle keeps a copy of the processed content.<br>//<br>// With streamed output, the processed content can be freed as its streamed.<br>//<br>// If the length of the content to be updated is known at the time of the<br>// open, then, ContentLength should be set to that length. Otherwise, it<br>// should be set to CMSG_INDEFINITE_LENGTH.<br>//--------------------------------------------------------------------------<br><br>type<br> PFN_CMSG_STREAM_OUTPUT = function (<br> const pvArg
VOID;<br> pbData
BYTE;<br> cbData
WORD;<br> fFinal :BOOL):BOOL ; stdcall;<br><br>const <br> CMSG_INDEFINITE_LENGTH = ($FFFFFFFF);<br><br>type<br> PCMSG_STREAM_INFO = ^CMSG_STREAM_INFO;<br> CMSG_STREAM_INFO = record<br> cbContent
WORD;<br> pfnStreamOutput
FN_CMSG_STREAM_OUTPUT;<br> pvArg
VOID;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Open dwFlags<br>//--------------------------------------------------------------------------<br><br>const <br> CMSG_BARE_CONTENT_FLAG = $00000001;<br> CMSG_LENGTH_ONLY_FLAG = $00000002;<br> CMSG_DETACHED_FLAG = $00000004;<br> CMSG_AUTHENTICATED_ATTRIBUTES_FLAG = $00000008;<br> CMSG_CONTENTS_OCTETS_FLAG = $00000010;<br> CMSG_MAX_LENGTH_FLAG = $00000020;<br><br>//+-------------------------------------------------------------------------<br>// Open a cryptographic message for encoding<br>//<br>// For PKCS #7:<br>// If the content to be passed to CryptMsgUpdate has already<br>// been message encoded (the input to CryptMsgUpdate is the streamed output<br>// from another message encode), then, the CMSG_ENCODED_CONTENT_INFO_FLAG should<br>// be set in dwFlags. If not set, then, the inner ContentType is Data and<br>// the input to CryptMsgUpdate is treated as the inner Data type's Content,<br>// a string of bytes.<br>// If CMSG_BARE_CONTENT_FLAG is specified for a streamed message,<br>// the streamed output will not have an outer ContentInfo wrapper. This<br>// makes it suitable to be streamed into an enclosing message.<br>//<br>// The pStreamInfo parameter needs to be set to stream the encoded message<br>// output.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgOpenToEncode(dwMsgEncodingType
WORD;<br> dwFlags
WORD;<br> dwMsgType
WORD;<br> pvMsgEncodeInfo
VOID;<br> pszInnerContentObjID :LPSTR; //OPTIONAL<br> pStreamInfo
CMSG_STREAM_INFO //OPTIONAL<br>  
:HCRYPTMSG ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Calculate the length of an encoded cryptographic message.<br>//<br>// Calculates the length of the encoded message given the<br>// message type, encoding parameters and total length of<br>// the data to be updated. Note, this might not be the exact length. However,<br>// it will always be greater than or equal to the actual length.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgCalculateEncodedLength(dwMsgEncodingType
WORD;<br> dwFlags
WORD;<br> dwMsgType
WORD;<br> pvMsgEncodeInfo
VOID;<br> pszInnerContentObjID :LPSTR; //OPTIONAL<br> cbData
WORD)
WORD ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Open a cryptographic message for decoding<br>//<br>// For PKCS #7: if the inner ContentType isn't Data, then, the inner<br>// ContentInfo consisting of both ContentType and Content is output.<br>// To also enable ContentInfo output for the Data ContentType, then,<br>// the CMSG_ENCODED_CONTENT_INFO_FLAG should be set<br>// in dwFlags. If not set, then, only the content portion of the inner<br>// ContentInfo is output for the Data ContentType.<br>//<br>// To only calculate the length of the decoded message, set the<br>// CMSG_LENGTH_ONLY_FLAG in dwFlags. After the final CryptMsgUpdate get the<br>// MSG_CONTENT_PARAM. Note, this might not be the exact length. However,<br>// it will always be greater than or equal to the actual length.<br>//<br>// hCryptProv specifies the crypto provider to use for hashing and/or<br>// decrypting the message. For enveloped messages, hCryptProv also specifies<br>// the private exchange key to use. For signed messages, hCryptProv is used<br>// when CryptMsgVerifySigner is called.<br>//<br>// For enveloped messages, the pRecipientInfo contains the Issuer and<br>// SerialNumber identifying the RecipientInfo in the message.<br>//<br>// Note, the pRecipientInfo should correspond to the provider's private<br>// exchange key.<br>//<br>// If pRecipientInfo is NULL, then, the message isn't decrypted. To decrypt<br>// the message, CryptMsgControl(CMSG_CTRL_DECRYPT) is called after the final<br>// CryptMsgUpdate.<br>//<br>// The pStreamInfo parameter needs to be set to stream the decoded content<br>// output. Note, if pRecipientInfo is NULL, then, the streamed output isn't<br>// decrypted.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgOpenToDecode(dwMsgEncodingType
WORD;<br> dwFlags
WORD;<br> dwMsgType
WORD;<br> hCryptProv :HCRYPTPROV;<br> pRecipientInfo
CERT_INFO; //OPTIONAL<br> pStreamInfo
CMSG_STREAM_INFO //OPTIONAL<br>  
:HCRYPTMSG ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Close a cryptographic message handle<br>//<br>// LastError is preserved unless FALSE is returned.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgClose(hCryptMsg :HCRYPTMSG):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Update the content of a cryptographic message. Depending on how the<br>// message was opened, the content is either encoded or decoded.<br>//<br>// This function is repetitively called to append to the message content.<br>// fFinal is set to identify the last update. On fFinal, the encode/decode<br>// is completed. The encoded/decoded content and the decoded parameters<br>// are valid until the open and all duplicated handles are closed.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgUpdate(hCryptMsg :HCRYPTMSG;<br> const pbData
BYTE;<br> cbData
WORD;<br> fFinal :BOOL):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Perform a special "control" function after the final CryptMsgUpdate of a<br>// encoded/decoded cryptographic message.<br>//<br>// The dwCtrlType parameter specifies the type of operation to be performed.<br>//<br>// The pvCtrlPara definition depends on the dwCtrlType value.<br>//<br>// See below for a list of the control operations and their pvCtrlPara<br>// type definition.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgControl(hCryptMsg :HCRYPTMSG;<br> dwFlags
WORD;<br> dwCtrlType
WORD;<br> pvCtrlPara
VOID):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Message control types<br>//--------------------------------------------------------------------------<br><br>const <br> CMSG_CTRL_VERIFY_SIGNATURE = 1;<br> CMSG_CTRL_DECRYPT = 2;<br> CMSG_CTRL_VERIFY_HASH = 5;<br> CMSG_CTRL_ADD_SIGNER = 6;<br> CMSG_CTRL_DEL_SIGNER = 7;<br> CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR = 8;<br> CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR = 9;<br> CMSG_CTRL_ADD_CERT = 10;<br> CMSG_CTRL_DEL_CERT = 11;<br> CMSG_CTRL_ADD_CRL = 12;<br> CMSG_CTRL_DEL_CRL = 13;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_VERIFY_SIGNATURE<br>//<br>// Verify the signature of a SIGNED or SIGNED_AND_ENVELOPED<br>// message after it has been decoded.<br>//<br>// For a SIGNED_AND_ENVELOPED message, called after<br>// CryptMsgControl(CMSG_CTRL_DECRYPT), if CryptMsgOpenToDecode was called<br>// with a NULL pRecipientInfo.<br>//<br>// pvCtrlPara points to a CERT_INFO struct.<br>//<br>// The CERT_INFO contains the Issuer and SerialNumber identifying<br>// the Signer of the message. The CERT_INFO also contains the<br>// PublicKeyInfo<br>// used to verify the signature. The cryptographic provider specified<br>// in CryptMsgOpenToDecode is used.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_DECRYPT<br>//<br>// Decrypt an ENVELOPED or SIGNED_AND_ENVELOPED message after it has been<br>// decoded.<br>//<br>// hCryptProv and dwKeySpec specify the private key to use. For dwKeySpec ==<br>// 0, defaults to AT_KEYEXCHANGE.<br>//<br>// dwRecipientIndex is the index of the recipient in the message associated<br>// with the hCryptProv's private key.<br>//<br>// This control function needs to be called, if you don't know the appropriate<br>// recipient before calling CryptMsgOpenToDecode. After the final<br>// CryptMsgUpdate, the list of recipients is obtained by iterating through<br>// CMSG_RECIPIENT_INFO_PARAM. The recipient corresponding to a private<br>// key owned by the caller is selected and passed to this function to decrypt<br>// the message.<br>//<br>// Note, the message can only be decrypted once.<br>//--------------------------------------------------------------------------<br><br>type<br> PCMSG_CTRL_DECRYPT_PARA = ^CMSG_CTRL_DECRYPT_PARA;<br> CMSG_CTRL_DECRYPT_PARA = record<br> cbSize
WORD;<br> hCryptProv :HCRYPTPROV;<br> dwKeySpec
WORD;<br> dwRecipientIndex
WORD;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_VERIFY_HASH<br>//<br>// Verify the hash of a HASHED message after it has been decoded.<br>//<br>// Only the hCryptMsg parameter is used, to specify the message whose<br>// hash is being verified.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_ADD_SIGNER<br>//<br>// Add a signer to a signed-data or signed-and-enveloped-data message.<br>//<br>// pvCtrlPara points to a CMSG_SIGNER_ENCODE_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_DEL_SIGNER<br>//<br>// Remove a signer from a signed-data or signed-and-enveloped-data message.<br>//<br>// pvCtrlPara points to a DWORD containing the 0-based index of the<br>// signer to be removed.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR<br>//<br>// Add an unauthenticated attribute to the SignerInfo of a signed-data or<br>// signed-and-enveloped-data message.<br>//<br>// The unauthenticated attribute is input in the form of an encoded blob.<br>//--------------------------------------------------------------------------<br><br>type<br> PCMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA = ^CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA;<br> CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA = record<br> cbSize
WORD;<br> dwSignerIndex
WORD;<br> blob :CRYPT_DATA_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR<br>//<br>// Delete an unauthenticated attribute from the SignerInfo of a signed-data<br>// or signed-and-enveloped-data message.<br>//<br>// The unauthenticated attribute to be removed is specified by<br>// a 0-based index.<br>//--------------------------------------------------------------------------<br><br>type<br> PCMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA = ^CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA;<br> CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA = record<br> cbSize
WORD;<br> dwSignerIndex
WORD;<br> dwUnauthAttrIndex
WORD;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_ADD_CERT<br>//<br>// Add a certificate to a signed-data or signed-and-enveloped-data message.<br>//<br>// pvCtrlPara points to a CRYPT_DATA_BLOB containing the certificate's<br>// encoded bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_DEL_CERT<br>//<br>// Delete a certificate from a signed-data or signed-and-enveloped-data<br>// message.<br>//<br>// pvCtrlPara points to a DWORD containing the 0-based index of the<br>// certificate to be removed.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_ADD_CRL<br>//<br>// Add a CRL to a signed-data or signed-and-enveloped-data message.<br>//<br>// pvCtrlPara points to a CRYPT_DATA_BLOB containing the CRL's<br>// encoded bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CTRL_DEL_CRL<br>//<br>// Delete a CRL from a signed-data or signed-and-enveloped-data message.<br>//<br>// pvCtrlPara points to a DWORD containing the 0-based index of the CRL<br>// to be removed.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// Verify a countersignature, at the SignerInfo level.<br>// ie. verify that pbSignerInfoCountersignature contains the encrypted<br>// hash of the encryptedDigest field of pbSignerInfo.<br>//<br>// hCryptProv is used to hash the encryptedDigest field of pbSignerInfo.<br>// The only fields referenced from pciCountersigner are SerialNumber, Issuer,<br>// and SubjectPublicKeyInfo.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgVerifyCountersignatureEncoded(hCryptProv :HCRYPTPROV;<br> dwEncodingType
WORD;<br> pbSignerInfo
BYTE;<br> cbSignerInfo
WORD;<br> pbSignerInfoCountersignature
BYTE;<br> cbSignerInfoCountersignature
WORD;<br> pciCountersigner
CERT_INFO):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Countersign an already-existing signature in a message<br>//<br>// dwIndex is a zero-based index of the SignerInfo to be countersigned.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgCountersign(hCryptMsg :HCRYPTMSG;<br> dwIndex
WORD;<br> cCountersigners
WORD;<br> rgCountersigners
CMSG_SIGNER_ENCODE_INFO):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Countersign an already-existing signature (encoded SignerInfo).<br>// Output an encoded SignerInfo blob, suitable for use as a countersignature<br>// attribute in the unauthenticated attributes of a signed-data or<br>// signed-and-enveloped-data message.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgCountersignEncoded(dwEncodingType
WORD;<br> pbSignerInfo
BYTE;<br> cbSignerInfo
WORD;<br> cCountersigners
WORD;<br> rgCountersigners
CMSG_SIGNER_ENCODE_INFO;<br> pbCountersignature
BYTE;<br> pcbCountersignature
DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Get a parameter after encoding/decoding a cryptographic message. Called<br>// after the final CryptMsgUpdate. Only the CMSG_CONTENT_PARAM and<br>// CMSG_COMPUTED_HASH_PARAM are valid for an encoded message.<br>//<br>// For an encoded HASHED message, the CMSG_COMPUTED_HASH_PARAM can be got<br>// before any CryptMsgUpdates to get its length.<br>//<br>// The pvData type definition depends on the dwParamType value.<br>//<br>// Elements pointed to by fields in the pvData structure follow the<br>// structure. Therefore, *pcbData may exceed the size of the structure.<br>//<br>// Upon input, if *pcbData == 0, then, *pcbData is updated with the length<br>// of the data and the pvData parameter is ignored.<br>//<br>// Upon return, *pcbData is updated with the length of the data.<br>//<br>// The OBJID BLOBs returned in the pvData structures point to<br>// their still encoded representation. The appropriate functions<br>// must be called to decode the information.<br>//<br>// See below for a list of the parameters to get.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgGetParam(hCryptMsg :HCRYPTMSG;<br> dwParamType
WORD;<br> dwIndex
WORD;<br> pvData
VOID;<br> pcbData
DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Get parameter types and their corresponding data structure definitions.<br>//--------------------------------------------------------------------------<br><br>const <br> CMSG_TYPE_PARAM = 1;<br> CMSG_CONTENT_PARAM = 2;<br> CMSG_BARE_CONTENT_PARAM = 3;<br> CMSG_INNER_CONTENT_TYPE_PARAM = 4;<br> CMSG_SIGNER_COUNT_PARAM = 5;<br> CMSG_SIGNER_INFO_PARAM = 6;<br> CMSG_SIGNER_CERT_INFO_PARAM = 7;<br> CMSG_SIGNER_HASH_ALGORITHM_PARAM = 8;<br> CMSG_SIGNER_AUTH_ATTR_PARAM = 9;<br> CMSG_SIGNER_UNAUTH_ATTR_PARAM = 10;<br> CMSG_CERT_COUNT_PARAM = 11;<br> CMSG_CERT_PARAM = 12;<br> CMSG_CRL_COUNT_PARAM = 13;<br> CMSG_CRL_PARAM = 14;<br> CMSG_ENVELOPE_ALGORITHM_PARAM = 15;<br> CMSG_RECIPIENT_COUNT_PARAM = 17;<br> CMSG_RECIPIENT_INDEX_PARAM = 18;<br> CMSG_RECIPIENT_INFO_PARAM = 19;<br> CMSG_HASH_ALGORITHM_PARAM = 20;<br> CMSG_HASH_DATA_PARAM = 21;<br> CMSG_COMPUTED_HASH_PARAM = 22;<br> CMSG_ENCRYPT_PARAM = 26;<br> CMSG_ENCRYPTED_DIGEST = 27;<br> CMSG_ENCODED_SIGNER = 28;<br> CMSG_ENCODED_MESSAGE = 29;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_TYPE_PARAM<br>//<br>// The type of the decoded message.<br>//<br>// pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CONTENT_PARAM<br>//<br>// The encoded content of a cryptographic message. Depending on how the<br>// message was opened, the content is either the whole PKCS#7<br>// message (opened to encode) or the inner content (opened to decode).<br>// In the decode case, the decrypted content is returned, if enveloped.<br>// If not enveloped, and if the inner content is of type DATA, the returned<br>// data is the contents octets of the inner content.<br>//<br>// pvData points to the buffer receiving the content bytes<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_BARE_CONTENT_PARAM<br>//<br>// The encoded content of an encoded cryptographic message, without the<br>// outer layer of ContentInfo. That is, only the encoding of the<br>// ContentInfo.content field is returned.<br>//<br>// pvData points to the buffer receiving the content bytes<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_INNER_CONTENT_TYPE_PARAM<br>//<br>// The type of the inner content of a decoded cryptographic message,<br>// in the form of a NULL-terminated object identifier string<br>// (eg. "1.2.840.113549.1.7.1"
.<br>//<br>// pvData points to the buffer receiving the object identifier string<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_SIGNER_COUNT_PARAM<br>//<br>// Count of signers in a SIGNED or SIGNED_AND_ENVELOPED message<br>//<br>// pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_SIGNER_CERT_INFO_PARAM<br>//<br>// To get all the signers, repetitively call CryptMsgGetParam, with<br>// dwIndex set to 0 .. SignerCount - 1.<br>//<br>// pvData points to a CERT_INFO struct.<br>//<br>// Only the following fields have been updated in the CERT_INFO struct:<br>// Issuer and SerialNumber.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_SIGNER_INFO_PARAM<br>//<br>// To get all the signers, repetitively call CryptMsgGetParam, with<br>// dwIndex set to 0 .. SignerCount - 1.<br>//<br>// pvData points to a CMSG_SIGNER_INFO struct.<br>//--------------------------------------------------------------------------<br><br>type<br> PCMSG_SIGNER_INFO = ^CMSG_SIGNER_INFO;<br> CMSG_SIGNER_INFO = record<br> dwVersion
WORD;<br> Issuer :CERT_NAME_BLOB;<br> SerialNumber :CRYPT_INTEGER_BLOB;<br> HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> HashEncryptionAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> EncryptedHash :CRYPT_DATA_BLOB;<br> AuthAttrs :CRYPT_ATTRIBUTES;<br> UnauthAttrs :CRYPT_ATTRIBUTES;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_SIGNER_HASH_ALGORITHM_PARAM<br>//<br>// This parameter specifies the HashAlgorithm that was used for the signer.<br>//<br>// Set dwIndex to iterate through all the signers.<br>//<br>// pvData points to an CRYPT_ALGORITHM_IDENTIFIER struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_SIGNER_AUTH_ATTR_PARAM<br>//<br>// The authenticated attributes for the signer.<br>//<br>// Set dwIndex to iterate through all the signers.<br>//<br>// pvData points to a CMSG_ATTR struct.<br>//--------------------------------------------------------------------------<br><br>type<br> CMSG_ATTR = CRYPT_ATTRIBUTES;<br> PCMSG_ATTR = ^CRYPT_ATTRIBUTES;<br><br>//+-------------------------------------------------------------------------<br>// CMSG_SIGNER_UNAUTH_ATTR_PARAM<br>//<br>// The unauthenticated attributes for the signer.<br>//<br>// Set dwIndex to iterate through all the signers.<br>//<br>// pvData points to a CMSG_ATTR struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CERT_COUNT_PARAM<br>//<br>// Count of certificates in a SIGNED or SIGNED_AND_ENVELOPED message.<br>//<br>// pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CERT_PARAM<br>//<br>// To get all the certificates, repetitively call CryptMsgGetParam, with<br>// dwIndex set to 0 .. CertCount - 1.<br>//<br>// pvData points to an array of the certificate's encoded bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CRL_COUNT_PARAM<br>//<br>// Count of CRLs in a SIGNED or SIGNED_AND_ENVELOPED message.<br>//<br>// pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_CRL_PARAM<br>//<br>// To get all the CRLs, repetitively call CryptMsgGetParam, with<br>// dwIndex set to 0 .. CrlCount - 1.<br>//<br>// pvData points to an array of the CRL's encoded bytes.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// CMSG_ENVELOPE_ALGORITHM_PARAM<br>//<br>// The ContentEncryptionAlgorithm that was used in<br>// an ENVELOPED or SIGNED_AND_ENVELOPED message.<br>//<br>// pvData points to an CRYPT_ALGORITHM_IDENTIFIER struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_RECIPIENT_COUNT_PARAM<br>//<br>// Count of recipients in an ENVELOPED or SIGNED_AND_ENVELOPED message.<br>//<br>// pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_RECIPIENT_INDEX_PARAM<br>//<br>// Index of the recipient used to decrypt an ENVELOPED or SIGNED_AND_ENVELOPED<br>// message.<br>//<br>// pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_RECIPIENT_INFO_PARAM<br>//<br>// To get all the recipients, repetitively call CryptMsgGetParam, with<br>// dwIndex set to 0 .. RecipientCount - 1.<br>//<br>// pvData points to a CERT_INFO struct.<br>//<br>// Only the following fields have been updated in the CERT_INFO struct:<br>// Issuer, SerialNumber and PublicKeyAlgorithm. The PublicKeyAlgorithm<br>// specifies the KeyEncryptionAlgorithm that was used.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_HASH_ALGORITHM_PARAM<br>//<br>// The HashAlgorithm in a HASHED message.<br>//<br>// pvData points to an CRYPT_ALGORITHM_IDENTIFIER struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_HASH_DATA_PARAM<br>//<br>// The hash in a HASHED message.<br>//<br>// pvData points to an array of bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_COMPUTED_HASH_PARAM<br>//<br>// The computed hash for a HASHED message.<br>//<br>// This may be called for either an encoded or decoded message.<br>// It also may be called before any encoded CryptMsgUpdates to get its length.<br>//<br>// pvData points to an array of bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_ENCRYPT_PARAM<br>//<br>// The ContentEncryptionAlgorithm that was used in an ENCRYPTED message.<br>//<br>// pvData points to an CRYPT_ALGORITHM_IDENTIFIER struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CMSG_ENCODED_MESSAGE<br>//<br>// The full encoded message. This is useful in the case of a decoded<br>// message which has been modified (eg. a signed-data or<br>// signed-and-enveloped-data message which has been countersigned).<br>//<br>// pvData points to an array of the message's encoded bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CryptMsg OID installable functions<br>//--------------------------------------------------------------------------<br><br>// If *phCryptProv is NULL upon entry, then, if supported, the installable<br>// function should acquire a default provider and return. Note, its up<br>// to the installable function to release at process detach.<br><br>const <br> CMSG_OID_GEN_ENCRYPT_KEY_FUNC = 'CryptMsgDllGenEncryptKey';<br><br>type<br> PFN_CMSG_GEN_ENCRYPT_KEY = function (phCryptProv
HCRYPTPROV;<br> paiEncrypt
CRYPT_ALGORITHM_IDENTIFIER;<br> pvEncryptAuxInfo
VOID;<br> pPublicKeyInfo
CERT_PUBLIC_KEY_INFO;<br> phEncryptKey
HCRYPTKEY<br> ):BOOL ; stdcall;<br><br>const <br> CMSG_OID_EXPORT_ENCRYPT_KEY_FUNC = 'CryptMsgDllExportEncryptKey';<br><br>type<br> PFN_CMSG_EXPORT_ENCRYPT_KEY = function (hCryptProv :HCRYPTPROV;<br> hEncryptKey :HCRYPTKEY;<br> pPublicKeyInfo
CERT_PUBLIC_KEY_INFO;<br> pbData
BYTE;<br> pcbData
DWORD):BOOL ; stdcall;<br><br>const <br> CMSG_OID_IMPORT_ENCRYPT_KEY_FUNC = 'CryptMsgDllImportEncryptKey';<br><br>type<br> PFN_CMSG_IMPORT_ENCRYPT_KEY = function (hCryptProv :HCRYPTPROV;<br> dwKeySpec
WORD;<br> paiEncrypt
CRYPT_ALGORITHM_IDENTIFIER;<br> paiPubKey
CRYPT_ALGORITHM_IDENTIFIER;<br> pbEncodedKey
BYTE;<br> cbEncodedKey
WORD;<br> phEncryptKey
HCRYPTKEY<br>  
:BOOL ; stdcall;<br><br>//+=========================================================================<br>// Certificate Store Data Structures and APIs<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// In its most basic implementation, a cert store is simply a<br>// collection of certificates and/or CRLs. This is the case when<br>// a cert store is opened with all of its certificates and CRLs<br>// coming from a PKCS #7 encoded cryptographic message.<br>//<br>// Nonetheless, all cert stores have the following properties:<br>// - A public key may have more than one certificate in the store.<br>// For example, a private/public key used for signing may have a<br>// certificate issued for VISA and another issued for<br>// Mastercard. Also, when a certificate is renewed there might<br>// be more than one certificate with the same subject and<br>// issuer.<br>// - However, each certificate in the store is uniquely<br>// identified by its Issuer and SerialNumber.<br>// - There's an issuer of subject certificate relationship. A<br>// certificate's issuer is found by doing a match of<br>// pSubjectCert->Issuer with pIssuerCert->Subject.<br>// The relationship is verified by using<br>// the issuer's public key to verify the subject certificate's<br>// signature. Note, there might be X.509 v3 extensions<br>// to assist in finding the issuer certificate.<br>// - Since issuer certificates might be renewed, a subject<br>// certificate might have more than one issuer certificate.<br>// - There's an issuer of CRL relationship. An<br>// issuer's CRL is found by doing a match of<br>// pIssuerCert->Subject with pCrl->Issuer.<br>// The relationship is verified by using<br>// the issuer's public key to verify the CRL's<br>// signature. Note, there might be X.509 v3 extensions<br>// to assist in finding the CRL.<br>// - Since some issuers might support the X.509 v3 delta CRL<br>// extensions, an issuer might have more than one CRL.<br>// - The store shouldn't have any redundant certificates or<br>// CRLs. There shouldn't be two certificates with the same<br>// Issuer and SerialNumber. There shouldn't be two CRLs with<br>// the same Issuer, ThisUpdate and NextUpdate.<br>// - The store has NO policy or trust information. No<br>// certificates are tagged as being "root". Its up to<br>// the application to maintain a list of CertIds (Issuer +<br>// SerialNumber) for certificates it trusts.<br>// - The store might contain bad certificates and/or CRLs.<br>// The issuer's signature of a subject certificate or CRL may<br>// not verify. Certificates or CRLs may not satisfy their<br>// time validity requirements. Certificates may be<br>// revoked.<br>//<br>// In addition to the certificates and CRLs, properties can be<br>// stored. There are two predefined property IDs for a user<br>// certificate: CERT_KEY_PROV_HANDLE_PROP_ID and<br>// CERT_KEY_PROV_INFO_PROP_ID. The CERT_KEY_PROV_HANDLE_PROP_ID<br>// is a HCRYPTPROV handle to the private key assoicated<br>// with the certificate. The CERT_KEY_PROV_INFO_PROP_ID contains<br>// information to be used to call<br>// CryptAcquireContext and CryptProvSetParam to get a handle<br>// to the private key associated with the certificate.<br>//<br>// There exists two more predefined property IDs for certificates<br>// and CRLs, CERT_SHA1_HASH_PROP_ID and CERT_MD5_HASH_PROP_ID.<br>// If these properties don't already exist, then, a hash of the<br>// content is computed. (CERT_HASH_PROP_ID maps to the default<br>// hash algorithm, currently, CERT_SHA1_HASH_PROP_ID).<br>//<br>// There are additional APIs for creating certificate and CRL<br>// contexts not in a store (CertCreateCertificateContext and<br>// CertCreateCRLContext).<br>//<br>//--------------------------------------------------------------------------<br><br>type<br> HCERTSTORE = PVOID;<br><br>//+-------------------------------------------------------------------------<br>// Certificate context.<br>//<br>// A certificate context contains both the encoded and decoded representation<br>// of a certificate. A certificate context returned by a cert store function<br>// must be freed by calling the CertFreeCertificateContext function. The<br>// CertDuplicateCertificateContext function can be called to make a duplicate<br>// copy (which also must be freed by calling CertFreeCertificateContext).<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_CONTEXT = ^CERT_CONTEXT;<br> CERT_CONTEXT = record<br> dwCertEncodingType
WORD;<br> pbCertEncoded
BYTE;<br> cbCertEncoded
WORD;<br> pCertInfo
CERT_INFO;<br> hCertStore :HCERTSTORE;<br> end;<br><br>type<br> PCCERT_CONTEXT = ^CERT_CONTEXT;<br><br>//+-------------------------------------------------------------------------<br>// CRL context.<br>//<br>// A CRL context contains both the encoded and decoded representation<br>// of a CRL. A CRL context returned by a cert store function<br>// must be freed by calling the CertFreeCRLContext function. The<br>// CertDuplicateCRLContext function can be called to make a duplicate<br>// copy (which also must be freed by calling CertFreeCRLContext).<br>//--------------------------------------------------------------------------<br><br>type<br> PCRL_CONTEXT = ^CRL_CONTEXT;<br> CRL_CONTEXT = record<br> dwCertEncodingType
WORD;<br> pbCrlEncoded
BYTE;<br> cbCrlEncoded
WORD;<br> pCrlInfo
CRL_INFO;<br> hCertStore :HCERTSTORE;<br> end;<br><br>type<br> PCCRL_CONTEXT = ^CRL_CONTEXT;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Trust List (CTL) context.<br>//<br>// A CTL context contains both the encoded and decoded representation<br>// of a CTL. Also contains an opened HCRYPTMSG handle to the decoded<br>// cryptographic signed message containing the CTL_INFO as its inner content.<br>// pbCtlContent is the encoded inner content of the signed message.<br>//<br>// The CryptMsg APIs can be used to extract additional signer information.<br>//--------------------------------------------------------------------------<br><br>type<br> PCTL_CONTEXT = ^CTL_CONTEXT;<br> CTL_CONTEXT = record<br> dwMsgAndCertEncodingType
WORD;<br> pbCtlEncoded
BYTE;<br> cbCtlEncoded
WORD;<br> pCtlInfo
CTL_INFO;<br> hCertStore :HCERTSTORE;<br> hCryptMsg :HCRYPTMSG;<br> pbCtlContent
BYTE;<br> cbCtlContent
WORD;<br> end;<br><br>type<br> PCCTL_CONTEXT = ^CTL_CONTEXT;<br><br>//+-------------------------------------------------------------------------<br>// Certificate, CRL and CTL property IDs<br>//<br>// See CertSetCertificateContextProperty or CertGetCertificateContextProperty<br>// for usage information.<br>//--------------------------------------------------------------------------<br><br>const <br> CERT_KEY_PROV_HANDLE_PROP_ID = 1;<br> CERT_KEY_PROV_INFO_PROP_ID = 2;<br> CERT_SHA1_HASH_PROP_ID = 3;<br> CERT_MD5_HASH_PROP_ID = 4;<br> CERT_HASH_PROP_ID = CERT_SHA1_HASH_PROP_ID;<br> CERT_KEY_CONTEXT_PROP_ID = 5;<br> CERT_KEY_SPEC_PROP_ID = 6;<br> CERT_IE30_RESERVED_PROP_ID = 7;<br> CERT_PUBKEY_HASH_RESERVED_PROP_ID = 8;<br> CERT_ENHKEY_USAGE_PROP_ID = 9;<br> CERT_CTL_USAGE_PROP_ID = CERT_ENHKEY_USAGE_PROP_ID;<br> CERT_NEXT_UPDATE_LOCATION_PROP_ID = 10;<br> CERT_FRIENDLY_NAME_PROP_ID = 11;<br> CERT_PVK_FILE_PROP_ID = 12;<br>// Note, 32 - 34 are reserved for the CERT, CRL and CTL file element IDs.<br> CERT_FIRST_RESERVED_PROP_ID = 13;<br><br> CERT_LAST_RESERVED_PROP_ID = $00007FFF;<br> CERT_FIRST_USER_PROP_ID = $00008000;<br> CERT_LAST_USER_PROP_ID = $0000FFFF;<br><br>function IS_CERT_HASH_PROP_ID( X
WORD):BOOL ;<br><br>//+-------------------------------------------------------------------------<br>// Cryptographic Key Provider Information<br>//<br>// CRYPT_KEY_PROV_INFO defines the CERT_KEY_PROV_INFO_PROP_ID's pvData.<br>//<br>// The CRYPT_KEY_PROV_INFO fields are passed to CryptAcquireContext<br>// to get a HCRYPTPROV handle. The optional CRYPT_KEY_PROV_PARAM fields are<br>// passed to CryptProvSetParam to further initialize the provider.<br>//<br>// The dwKeySpec field identifies the private key to use from the container<br>// For example, AT_KEYEXCHANGE or AT_SIGNATURE.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_KEY_PROV_PARAM = ^CRYPT_KEY_PROV_PARAM;<br> CRYPT_KEY_PROV_PARAM = record<br> dwParam
WORD;<br> pbData
BYTE;<br> cbData
WORD;<br> dwFlags
WORD;<br> end;<br><br>type<br> PCRYPT_KEY_PROV_INFO = ^CRYPT_KEY_PROV_INFO;<br> CRYPT_KEY_PROV_INFO = record<br> pwszContainerName :LPWSTR;<br> pwszProvName :LPWSTR;<br> dwProvType
WORD;<br> dwFlags
WORD;<br> cProvParam
WORD;<br> rgProvParam
CRYPT_KEY_PROV_PARAM;<br> dwKeySpec
WORD;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// The following flag should be set in the above dwFlags to enable<br>// a CertSetCertificateContextProperty(CERT_KEY_CONTEXT_PROP_ID) after a<br>// CryptAcquireContext is done in the Sign or Decrypt Message functions.<br>//<br>// The following define must not collide with any of the<br>// CryptAcquireContext dwFlag defines.<br>//--------------------------------------------------------------------------<br><br>const <br> CERT_SET_KEY_PROV_HANDLE_PROP_ID = $00000001;<br> CERT_SET_KEY_CONTEXT_PROP_ID = $00000001;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Key Context<br>//<br>// CERT_KEY_CONTEXT defines the CERT_KEY_CONTEXT_PROP_ID's pvData.<br>//--------------------------------------------------------------------------<br><br>type<br> PCERT_KEY_CONTEXT = ^CERT_KEY_CONTEXT;<br> CERT_KEY_CONTEXT = record<br> cbSize
WORD; // sizeof(CERT_KEY_CONTEXT)<br> hCryptProv :HCRYPTPROV;<br> dwKeySpec
WORD;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Store Provider Types<br>//--------------------------------------------------------------------------<br><br>const <br> CERT_STORE_PROV_MSG = (LPCSTR(1));<br> CERT_STORE_PROV_MEMORY = (LPCSTR(2));<br> CERT_STORE_PROV_FILE = (LPCSTR(3));<br> CERT_STORE_PROV_REG = (LPCSTR(4));<br><br> CERT_STORE_PROV_PKCS7 = (LPCSTR(5));<br> CERT_STORE_PROV_SERIALIZED = (LPCSTR(6));<br> CERT_STORE_PROV_FILENAME_A = (LPCSTR(7));<br> CERT_STORE_PROV_FILENAME_W = (LPCSTR(8));<br> CERT_STORE_PROV_FILENAME = CERT_STORE_PROV_FILENAME_W;<br> CERT_STORE_PROV_SYSTEM_A = (LPCSTR(9));<br> CERT_STORE_PROV_SYSTEM_W = (LPCSTR(10));<br> CERT_STORE_PROV_SYSTEM = CERT_STORE_PROV_SYSTEM_W;<br><br> sz_CERT_STORE_PROV_MEMORY = 'Memory';<br> sz_CERT_STORE_PROV_FILENAME_W = 'File';<br> sz_CERT_STORE_PROV_FILENAME = sz_CERT_STORE_PROV_FILENAME_W;<br> sz_CERT_STORE_PROV_SYSTEM_W = 'System';<br> sz_CERT_STORE_PROV_SYSTEM = sz_CERT_STORE_PROV_SYSTEM_W;<br> sz_CERT_STORE_PROV_PKCS7 = 'PKCS7';<br> sz_CERT_STORE_PROV_SERIALIZED = 'Serialized';<br><br>//+-------------------------------------------------------------------------<br>// Certificate Store verify/results flags<br>//--------------------------------------------------------------------------<br><br> CERT_STORE_SIGNATURE_FLAG = $00000001;<br> CERT_STORE_TIME_VALIDITY_FLAG = $00000002;<br> CERT_STORE_REVOCATION_FLAG = $00000004;<br> CERT_STORE_NO_CRL_FLAG = $00010000;<br> CERT_STORE_NO_ISSUER_FLAG = $00020000;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Store open/property flags<br>//--------------------------------------------------------------------------<br><br> CERT_STORE_NO_CRYPT_RELEASE_FLAG = $00000001;<br> CERT_STORE_READONLY_FLAG = $00008000;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Store Provider flags are in the HiWord (0xFFFF0000)<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// Certificate System Store Flag Values<br>//--------------------------------------------------------------------------<br>// Location of the system store in the registry:<br>// HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE<br> CERT_SYSTEM_STORE_LOCATION_MASK = $00030000;<br> CERT_SYSTEM_STORE_CURRENT_USER = $00010000;<br> CERT_SYSTEM_STORE_LOCAL_MACHINE = $00020000;<br><br>//+-------------------------------------------------------------------------<br>// Open the cert store using the specified store provider.<br>//<br>// hCryptProv specifies the crypto provider to use to create the hash<br>// properties or verify the signature of a subject certificate or CRL.<br>// The store doesn't need to use a private<br>// key. If the CERT_STORE_NO_CRYPT_RELEASE_FLAG isn't set, hCryptProv is<br>// CryptReleaseContext'ed on the final CertCloseStore.<br>//<br>// Note, if the open fails, hCryptProv is released if it would have been<br>// released when the store was closed.<br>//<br>// If hCryptProv is zero, then, the default provider and container for the<br>// PROV_RSA_FULL provider type is CryptAcquireContext'ed with<br>// CRYPT_VERIFYCONTEXT access. The CryptAcquireContext is deferred until<br>// the first create hash or verify signature. In addition, once acquired,<br>// the default provider isn't released until process exit when crypt32.dll<br>// is unloaded. The acquired default provider is shared across all stores<br>// and threads.<br>//<br>// After initializing the store's data structures and optionally acquiring a<br>// default crypt provider, CertOpenStore calls CryptGetOIDFunctionAddress to<br>// get the address of the CRYPT_OID_OPEN_STORE_PROV_FUNC specified by<br>// lpszStoreProvider. Since a store can contain certificates with different<br>// encoding types, CryptGetOIDFunctionAddress is called with dwEncodingType<br>// set to 0 and not the dwEncodingType passed to CertOpenStore.<br>// PFN_CERT_DLL_OPEN_STORE_FUNC specifies the signature of the provider's<br>// open function. This provider open function is called to load the<br>// store's certificates and CRLs. Optionally, the provider may return an<br>// array of functions called before a certificate or CRL is added or deleted<br>// or has a property that is set.<br>//<br>// Use of the dwEncodingType parameter is provider dependent. The type<br>// definition for pvPara also depends on the provider.<br>//<br>// Store providers are installed or registered via<br>// CryptInstallOIDFunctionAddress or CryptRegisterOIDFunction, where,<br>// dwEncodingType is 0 and pszFuncName is CRYPT_OID_OPEN_STORE_PROV_FUNC.<br>//<br>// Here's a list of the predefined provider types (implemented in crypt32.dll):<br>//<br>// CERT_STORE_PROV_MSG:<br>// Gets the certificates and CRLs from the specified cryptographic message.<br>// dwEncodingType contains the message and certificate encoding types.<br>// The message's handle is passed in pvPara. Given,<br>// HCRYPTMSG hCryptMsg; pvPara = (const void *) hCryptMsg;<br>//<br>// CERT_STORE_PROV_MEMORY<br>// sz_CERT_STORE_PROV_MEMORY:<br>// Opens a store without any initial certificates or CRLs. pvPara<br>// isn't used.<br>//<br>// CERT_STORE_PROV_FILE:<br>// Reads the certificates and CRLs from the specified file. The file's<br>// handle is passed in pvPara. Given,<br>// HANDLE hFile; pvPara = (const void *) hFile;<br>//<br>// For a successful open, the file pointer is advanced past<br>// the certificates and CRLs and their properties read from the file.<br>// Note, only expects a serialized store and not a file containing<br>// either a PKCS #7 signed message or a single encoded certificate.<br>//<br>// The hFile isn't closed.<br>//<br>// CERT_STORE_PROV_REG:<br>// Reads the certificates and CRLs from the registry. The registry's<br>// key handle is passed in pvPara. Given,<br>// HKEY hKey; pvPara = (const void *) hKey;<br>//<br>// The input hKey isn't closed by the provider. Before returning, the<br>// provider opens/creates "Certificates" and "CRLs" subkeys. These<br>// subkeys remain open until the store is closed.<br>//<br>// If CERT_STORE_READONLY_FLAG is set, then, the registry subkeys are<br>// RegOpenKey'ed with KEY_READ_ACCESS. Otherwise, the registry subkeys<br>// are RegCreateKey'ed with KEY_ALL_ACCESS.<br>//<br>// This provider returns the array of functions for reading, writing,<br>// deleting and property setting certificates and CRLs.<br>// Any changes to the opened store are immediately pushed through to<br>// the registry. However, if CERT_STORE_READONLY_FLAG is set, then,<br>// writing, deleting or property setting results in a<br>// SetLastError(E_ACCESSDENIED).<br>//<br>// Note, all the certificates and CRLs are read from the registry<br>// when the store is opened. The opened store serves as a write through<br>// cache. However, the opened store isn't notified of other changes<br>// made to the registry. Note, RegNotifyChangeKeyValue is supported<br>// on NT but not supported on Windows95.<br>//<br>// CERT_STORE_PROV_PKCS7:<br>// sz_CERT_STORE_PROV_PKCS7:<br>// Gets the certificates and CRLs from the encoded PKCS #7 signed message.<br>// dwEncodingType specifies the message and certificate encoding types.<br>// The pointer to the encoded message's blob is passed in pvPara. Given,<br>// CRYPT_DATA_BLOB EncodedMsg; pvPara = (const void *) &EncodedMsg;<br>//<br>// Note, also supports the IE3.0 special version of a<br>// PKCS #7 signed message referred to as a "SPC" formatted message.<br>//<br>// CERT_STORE_PROV_SERIALIZED:<br>// sz_CERT_STORE_PROV_SERIALIZED:<br>// Gets the certificates and CRLs from memory containing a serialized<br>// store. The pointer to the serialized memory blob is passed in pvPara.<br>// Given,<br>// CRYPT_DATA_BLOB Serialized; pvPara = (const void *) &Serialized;<br>//<br>// CERT_STORE_PROV_FILENAME_A:<br>// CERT_STORE_PROV_FILENAME_W:<br>// CERT_STORE_PROV_FILENAME:<br>// sz_CERT_STORE_PROV_FILENAME_W:<br>// sz_CERT_STORE_PROV_FILENAME:<br>// Opens the file and first attempts to read as a serialized store. Then,<br>// as a PKCS #7 signed message. Finally, as a single encoded certificate.<br>// The filename is passed in pvPara. The filename is UNICODE for the<br>// "_W" provider and ASCII for the "_A" provider. For "_W": given,<br>// LPCWSTR pwszFilename; pvPara = (const void *) pwszFilename;<br>// For "_A": given,<br>// LPCSTR pszFilename; pvPara = (const void *) pszFilename;<br>//<br>// Note, the default (without "_A" or "_W"
is unicode.<br>//<br>// Note, also supports the reading of the IE3.0 special version of a<br>// PKCS #7 signed message file referred to as a "SPC" formatted file.<br>//<br>// CERT_STORE_PROV_SYSTEM_A:<br>// CERT_STORE_PROV_SYSTEM_W:<br>// CERT_STORE_PROV_SYSTEM:<br>// sz_CERT_STORE_PROV_SYSTEM_W:<br>// sz_CERT_STORE_PROV_SYSTEM:<br>// Opens the specified "system" store. Currently, all the system<br>// stores are stored in the registry. The upper word of the dwFlags<br>// parameter is used to specify the location of the system store. It<br>// should be set to either CERT_SYSTEM_STORE_CURRENT_USER for<br>// HKEY_CURRENT_USER or CERT_SYSTEM_STORE_LOCAL_MACHINE for<br>// HKEY_LOCAL_MACHINE.<br>//<br>// After opening the registry key associated with the system name,<br>// the CERT_STORE_PROV_REG provider is called to complete the open.<br>//<br>// The system store name is passed in pvPara. The name is UNICODE for the<br>// "_W" provider and ASCII for the "_A" provider. For "_W": given,<br>// LPCWSTR pwszSystemName; pvPara = (const void *) pwszSystemName;<br>// For "_A": given,<br>// LPCSTR pszSystemName; pvPara = (const void *) pszSystemName;<br>//<br>// Note, the default (without "_A" or "_W"
is UNICODE.<br>//<br>// If CERT_STORE_READONLY_FLAG is set, then, the registry is<br>// RegOpenKey'ed with KEY_READ_ACCESS. Otherwise, the registry is<br>// RegCreateKey'ed with KEY_ALL_ACCESS.<br>//<br>// The "root" store is treated differently from the other system<br>// stores. Before a certificate is added to or deleted from the "root"<br>// store, a pop up message box is displayed. The certificate's subject,<br>// issuer, serial number, time validity, sha1 and md5 thumbprints are<br>// displayed. The user is given the option to do the add or delete.<br>// If they don't allow the operation, LastError is set to E_ACCESSDENIED.<br>//--------------------------------------------------------------------------<br><br>function CertOpenStore(lpszStoreProvider :LPCSTR;<br> dwEncodingType
WORD;<br> hCryptProv :HCRYPTPROV;<br> dwFlags
WORD;<br> const pvPara
VOID):HCERTSTORE ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// OID Installable Certificate Store Provider Data Structures<br>//--------------------------------------------------------------------------<br><br>// Handle returned by the store provider when opened.<br>type <br> HCERTSTOREPROV = PVOID;<br><br>// Store Provider OID function's pszFuncName.<br>const <br> CRYPT_OID_OPEN_STORE_PROV_FUNC = 'CertDllOpenStoreProv';<br><br>// Note, the Store Provider OID function's dwEncodingType is always 0.<br><br>// The following information is returned by the provider when opened. Its<br>// zeroed with cbSize set before the provider is called. If the provider<br>// doesn't need to be called again after the open it doesn't need to<br>// make any updates to the CERT_STORE_PROV_INFO.<br><br>type<br> PCERT_STORE_PROV_INFO = ^CERT_STORE_PROV_INFO;<br> CERT_STORE_PROV_INFO = record<br> cbSize
WORD;<br> cStoreProvFunc
WORD;<br> rgpvStoreProvFunc
PVOID;<br> hStoreProv :HCERTSTOREPROV;<br> dwStoreProvFlags
WORD;<br> end;<br><br>// Definition of the store provider's open function.<br>//<br>// *pStoreProvInfo has been zeroed before the call.<br>//<br>// Note, pStoreProvInfo->cStoreProvFunc should be set last. Once set,<br>// all subsequent store calls, such as CertAddSerializedElementToStore will<br>// call the appropriate provider callback function.<br><br>type<br> PFN_CERT_DLL_OPEN_STORE_PROV_FUNC = function (lpszStoreProvider :LPCSTR;<br> dwEncodingType
WORD;<br> hCryptProv :HCRYPTPROV;<br> dwFlags
WORD;<br> const pvPara
VOID;<br> hCertStore :HCERTSTORE;<br> pStoreProvInfo
CERT_STORE_PROV_INFO<br>  
:BOOL ; stdcall;<br><br>// Indices into the store provider's array of callback functions.<br>//<br>// The provider can implement any subset of the following functions. It<br>// sets pStoreProvInfo->cStoreProvFunc to the last index + 1 and any<br>// preceding not implemented functions to NULL.<br><br>const <br> CERT_STORE_PROV_CLOSE_FUNC = 0;<br> CERT_STORE_PROV_READ_CERT_FUNC = 1;<br> CERT_STORE_PROV_WRITE_CERT_FUNC = 2;<br> CERT_STORE_PROV_DELETE_CERT_FUNC = 3;<br> CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC = 4;<br> CERT_STORE_PROV_READ_CRL_FUNC = 5;<br> CERT_STORE_PROV_WRITE_CRL_FUNC = 6;<br> CERT_STORE_PROV_DELETE_CRL_FUNC = 7;<br> CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC = 8;<br> CERT_STORE_PROV_READ_CTL_FUNC = 9;<br> CERT_STORE_PROV_WRITE_CTL_FUNC = 10;<br> CERT_STORE_PROV_DELETE_CTL_FUNC = 11;<br> CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC = 12;<br><br>// Called by CertCloseStore when the store's reference count is<br>// decremented to 0.<br><br>type<br> PFN_CERT_STORE_PROV_CLOSE = procedure(hStoreProv :HCERTSTOREPROV;<br> dwFlags
WORD) ; stdcall;<br><br>// Currently not called directly by the store APIs. However, may be exported<br>// to support other providers based on it.<br>//<br>// Reads the provider's copy of the certificate context. If it exists,<br>// creates a new certificate context.<br><br>type<br> PFN_CERT_STORE_PROV_READ_CERT = function (hStoreProv :HCERTSTOREPROV;<br> pStoreCertContext
CCERT_CONTEXT;<br> dwFlags
WORD;<br> var ppProvCertContext
CCERT_CONTEXT<br>  
:BOOL ; stdcall;<br><br>const <br> CERT_STORE_PROV_WRITE_ADD_FLAG = $1;<br><br>// Called by CertAddEncodedCertificateToStore,<br>// CertAddCertificateContextToStore or CertAddSerializedElementToStore before<br>// adding to the store. The CERT_STORE_PROV_WRITE_ADD_FLAG is set. In<br>// addition to the encoded certificate, the added pCertContext might also<br>// have properties.<br>//<br>// Returns TRUE if its OK to update the the store.<br><br>type<br> PFN_CERT_STORE_PROV_WRITE_CERT = function (hStoreProv :HCERTSTOREPROV;<br> pCertContext
CCERT_CONTEXT;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>// Called by CertDeleteCertificateFromStore before deleting from the<br>// store.<br>//<br>// Returns TRUE if its OK to delete from the store.<br><br>type<br> PFN_CERT_STORE_PROV_DELETE_CERT = function (hStoreProv :HCERTSTOREPROV;<br> pCertContext
CCERT_CONTEXT;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>// Called by CertSetCertificateContextProperty before setting the<br>// certificate's property. Also called by CertGetCertificateContextProperty,<br>// when getting a hash property that needs to be created and then persisted<br>// via the set.<br>//<br>// Upon input, the property hasn't been set for the pCertContext parameter.<br>//<br>// Returns TRUE if its OK to set the property.<br><br>type<br> PFN_CERT_STORE_PROV_SET_CERT_PROPERTY = function (hStoreProv :HCERTSTOREPROV;<br> pCertContext
CCERT_CONTEXT;<br> dwPropId
WORD;<br> dwFlags
WORD;<br> const pvData
VOID<br>  
:BOOL ; stdcall;<br><br>// Currently not called directly by the store APIs. However, may be exported<br>// to support other providers based on it.<br>//<br>// Reads the provider's copy of the CRL context. If it exists,<br>// creates a new CRL context.<br><br>type<br> PFN_CERT_STORE_PROV_READ_CRL = function (hStoreProv :HCERTSTOREPROV;<br> pStoreCrlContext
CCRL_CONTEXT;<br> dwFlags
WORD;<br> var ppProvCrlContext
CCRL_CONTEXT<br> ):BOOL ; stdcall;<br><br>// Called by CertAddEncodedCRLToStore,<br>// CertAddCRLContextToStore or CertAddSerializedElementToStore before<br>// adding to the store. The CERT_STORE_PROV_WRITE_ADD_FLAG is set. In<br>// addition to the encoded CRL, the added pCertContext might also<br>// have properties.<br>//<br>// Returns TRUE if its OK to update the the store.<br><br>type<br> PFN_CERT_STORE_PROV_WRITE_CRL = function (hStoreProv :HCERTSTOREPROV;<br> pCrlContext
CCRL_CONTEXT;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>// Called by CertDeleteCRLFromStore before deleting from the store.<br>//<br>// Returns TRUE if its OK to delete from the store.<br><br>type<br> PFN_CERT_STORE_PROV_DELETE_CRL = function (hStoreProv :HCERTSTOREPROV;<br> pCrlContext
CCRL_CONTEXT;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>// Called by CertDeleteCRLFromStore before deleting from the store.<br>//<br>// Returns TRUE if its OK to delete from the store.<br><br>type<br> PFN_CERT_STORE_PROV_SET_CRL_PROPERTY = function (hStoreProv :HCERTSTOREPROV;<br> pCrlContext
CCRL_CONTEXT;<br> dwPropId
WORD;<br> dwFlags
WORD;<br> pvData
VOID):BOOL ; stdcall;<br><br>// Currently not called directly by the store APIs. However, may be exported<br>// to support other providers based on it.<br>//<br>// Reads the provider's copy of the CTL context. If it exists,<br>// creates a new CTL context.<br><br>type<br> PFN_CERT_STORE_PROV_READ_CTL = function (hStoreProv :HCERTSTOREPROV;<br> pStoreCtlContext
CCTL_CONTEXT;<br> dwFlags
WORD;<br> var ppProvCtlContext
CCTL_CONTEXT<br> ):BOOL ; stdcall;<br><br>// Called by CertAddEncodedCTLToStore,<br>// CertAddCTLContextToStore or CertAddSerializedElementToStore before<br>// adding to the store. The CERT_STORE_PROV_WRITE_ADD_FLAG is set. In<br>// addition to the encoded CTL, the added pCertContext might also<br>// have properties.<br>//<br>// Returns TRUE if its OK to update the the store.<br><br>type<br> PFN_CERT_STORE_PROV_WRITE_CTL = function (hStoreProv :HCERTSTOREPROV;<br> pCtlContext
CCTL_CONTEXT;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>// Called by CertDeleteCTLFromStore before deleting from the store.<br>//<br>// Returns TRUE if its OK to delete from the store.<br><br>type<br> PFN_CERT_STORE_PROV_DELETE_CTL = function (hStoreProv :HCERTSTOREPROV;<br> pCtlContext
CCTL_CONTEXT;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>// Called by CertSetCTLContextProperty before setting the<br>// CTL's property. Also called by CertGetCTLContextProperty,<br>// when getting a hash property that needs to be created and then persisted<br>// via the set.<br>//<br>// Upon input, the property hasn't been set for the pCtlContext parameter.<br>//<br>// Returns TRUE if its OK to set the property.<br><br>type<br> PFN_CERT_STORE_PROV_SET_CTL_PROPERTY = function (hStoreProv :HCERTSTOREPROV;<br> pCtlContext
CCTL_CONTEXT;<br> dwPropId
WORD;<br> dwFlags
WORD;<br> const pvData
VOID<br> ):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Duplicate a cert store handle<br>//--------------------------------------------------------------------------<br><br>function CertDuplicateStore(hCertStore :HCERTSTORE):HCERTSTORE ; stdcall;<br><br>const CERT_STORE_SAVE_AS_STORE = 1;<br>const CERT_STORE_SAVE_AS_PKCS7 = 2;<br><br>const CERT_STORE_SAVE_TO_FILE = 1;<br>const CERT_STORE_SAVE_TO_MEMORY = 2;<br>const CERT_STORE_SAVE_TO_FILENAME_A = 3;<br>const CERT_STORE_SAVE_TO_FILENAME_W = 4;<br>const CERT_STORE_SAVE_TO_FILENAME = CERT_STORE_SAVE_TO_FILENAME_W;<br><br>//+-------------------------------------------------------------------------<br>// Save the cert store. Extended version with lots of options.<br>//<br>// According to the dwSaveAs parameter, the store can be saved as a<br>// serialized store (CERT_STORE_SAVE_AS_STORE) containing properties in<br>// addition to encoded certificates, CRLs and CTLs or the store can be saved<br>// as a PKCS #7 signed message (CERT_STORE_SAVE_AS_PKCS7) which doesn't<br>// include the properties or CTLs.<br>//<br>// Note, the CERT_KEY_CONTEXT_PROP_ID property (and its<br>// CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_SPEC_PROP_ID) isn't saved into<br>// a serialized store.<br>//<br>// For CERT_STORE_SAVE_AS_PKCS7, the dwEncodingType specifies the message<br>// encoding type. The dwEncodingType parameter isn't used for<br>// CERT_STORE_SAVE_AS_STORE.<br>//<br>// The dwFlags parameter currently isn't used and should be set to 0.<br>//<br>// The dwSaveTo and pvSaveToPara parameters specify where to save the<br>// store as follows:<br>// CERT_STORE_SAVE_TO_FILE:<br>// Saves to the specified file. The file's handle is passed in<br>// pvSaveToPara. Given,<br>// HANDLE hFile; pvSaveToPara = (void *) hFile;<br>//<br>// For a successful save, the file pointer is positioned after the<br>// last write.<br>//<br>// CERT_STORE_SAVE_TO_MEMORY:<br>// Saves to the specified memory blob. The pointer to<br>// the memory blob is passed in pvSaveToPara. Given,<br>// CRYPT_DATA_BLOB SaveBlob; pvSaveToPara = (void *) &SaveBlob;<br>// Upon entry, the SaveBlob's pbData and cbData need to be initialized.<br>// Upon return, cbData is updated with the actual length.<br>// For a length only calculation, pbData should be set to NULL. If<br>// pbData is non-NULL and cbData isn't large enough, FALSE is returned<br>// with a last error of ERRROR_MORE_DATA.<br>//<br>// CERT_STORE_SAVE_TO_FILENAME_A:<br>// CERT_STORE_SAVE_TO_FILENAME_W:<br>// CERT_STORE_SAVE_TO_FILENAME:<br>// Opens the file and saves to it. The filename is passed in pvSaveToPara.<br>// The filename is UNICODE for the "_W" option and ASCII for the "_A"<br>// option. For "_W": given,<br>// LPCWSTR pwszFilename; pvSaveToPara = (void *) pwszFilename;<br>// For "_A": given,<br>// LPCSTR pszFilename; pvSaveToPara = (void *) pszFilename;<br>//<br>// Note, the default (without "_A" or "_W"
is UNICODE.<br>//<br>//--------------------------------------------------------------------------<br><br>function CertSaveStore(hCertStore :HCERTSTORE;<br> dwEncodingType
WORD;<br> dwSaveAs
WORD;<br> dwSaveTo
WORD;<br> pvSaveToPara
VOID;<br> dwFlags
WORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Store close flags<br>//--------------------------------------------------------------------------<br>const CERT_CLOSE_STORE_FORCE_FLAG = $00000001;<br>const CERT_CLOSE_STORE_CHECK_FLAG = $00000002;<br><br>//+-------------------------------------------------------------------------<br>// Close a cert store handle.<br>//<br>// There needs to be a corresponding close for each open and duplicate.<br>//<br>// Even on the final close, the cert store isn't freed until all of its<br>// certificate and CRL contexts have also been freed.<br>//<br>// On the final close, the hCryptProv passed to CertStoreOpen is<br>// CryptReleaseContext'ed.<br>//<br>// To force the closure of the store with all of its memory freed, set the<br>// CERT_STORE_CLOSE_FORCE_FLAG. This flag should be set when the caller does<br>// its own reference counting and wants everything to vanish.<br>//<br>// To check if all the store's certificates and CRLs have been freed and that<br>// this is the last CertCloseStore, set the CERT_CLOSE_STORE_CHECK_FLAG. If<br>// set and certs, CRLs or stores still need to be freed/closed, FALSE is<br>// returned with LastError set to CRYPT_E_PENDING_CLOSE. Note, for FALSE,<br>// the store is still closed. This is a diagnostic flag.<br>//<br>// LastError is preserved unless CERT_CLOSE_STORE_CHECK_FLAG is set and FALSE<br>// is returned.<br>//--------------------------------------------------------------------------<br><br>function CertCloseStore(hCertStore :HCERTSTORE; dwFlags
WORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Get the subject certificate context uniquely identified by its Issuer and<br>// SerialNumber from the store.<br>//<br>// If the certificate isn't found, NULL is returned. Otherwise, a pointer to<br>// a read only CERT_CONTEXT is returned. CERT_CONTEXT must be freed by calling<br>// CertFreeCertificateContext. CertDuplicateCertificateContext can be called to make a<br>// duplicate.<br>//<br>// The returned certificate might not be valid. Normally, it would be<br>// verified when getting its issuer certificate (CertGetIssuerCertificateFromStore).<br>//--------------------------------------------------------------------------<br><br>function CertGetSubjectCertificateFromStore(hCertStore :HCERTSTORE;<br> dwCertEncodingType
WORD;<br> pCertId
CERT_INFO // Only the Issuer and SerialNumber<br>  
CCERT_CONTEXT ; stdcall; // fields are used<br><br>//+-------------------------------------------------------------------------<br>// Enumerate the certificate contexts in the store.<br>//<br>// If a certificate isn't found, NULL is returned.<br>// Otherwise, a pointer to a read only CERT_CONTEXT is returned. CERT_CONTEXT<br>// must be freed by calling CertFreeCertificateContext or is freed when passed as the<br>// pPrevCertContext on a subsequent call. CertDuplicateCertificateContext<br>// can be called to make a duplicate.<br>//<br>// pPrevCertContext MUST BE NULL to enumerate the first<br>// certificate in the store. Successive certificates are enumerated by setting<br>// pPrevCertContext to the CERT_CONTEXT returned by a previous call.<br>//<br>// NOTE: a NON-NULL pPrevCertContext is always CertFreeCertificateContext'ed by<br>// this function, even for an error.<br>//--------------------------------------------------------------------------<br><br>function CertEnumCertificatesInStore(hCertStore :HCERTSTORE;<br> pPrevCertContext
CCERT_CONTEXT<br> )
CCERT_CONTEXT ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Find the first or next certificate context in the store.<br>//<br>// The certificate is found according to the dwFindType and its pvFindPara.<br>// See below for a list of the find types and its parameters.<br>//<br>// Currently dwFindFlags is only used for CERT_FIND_SUBJECT_ATTR,<br>// CERT_FIND_ISSUER_ATTR or CERT_FIND_CTL_USAGE. Otherwise, must be set to 0.<br>//<br>// Usage of dwCertEncodingType depends on the dwFindType.<br>//<br>// If the first or next certificate isn't found, NULL is returned.<br>// Otherwise, a pointer to a read only CERT_CONTEXT is returned. CERT_CONTEXT<br>// must be freed by calling CertFreeCertificateContext or is freed when passed as the<br>// pPrevCertContext on a subsequent call. CertDuplicateCertificateContext<br>// can be called to make a duplicate.<br>//<br>// pPrevCertContext MUST BE NULL on the first<br>// call to find the certificate. To find the next certificate, the<br>// pPrevCertContext is set to the CERT_CONTEXT returned by a previous call.<br>//<br>// NOTE: a NON-NULL pPrevCertContext is always CertFreeCertificateContext'ed by<br>// this function, even for an error.<br>//--------------------------------------------------------------------------<br><br>function CertFindCertificateInStore(hCertStore :HCERTSTORE;<br> dwCertEncodingType
WORD;<br> dwFindFlags
WORD;<br> dwFindType
WORD;<br> const pvFindPara
VOID;<br> pPrevCertContext
CCERT_CONTEXT<br>  
CCERT_CONTEXT ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Certificate comparison functions<br>//--------------------------------------------------------------------------<br><br>const CERT_COMPARE_SHIFT = 16;<br>const CERT_COMPARE_ANY = 0;<br>const CERT_COMPARE_SHA1_HASH = 1;<br>const CERT_COMPARE_NAME = 2;<br>const CERT_COMPARE_ATTR = 3;<br>const CERT_COMPARE_MD5_HASH = 4;<br>const CERT_COMPARE_PROPERTY = 5;<br>const CERT_COMPARE_PUBLIC_KEY = 6;<br>const CERT_COMPARE_HASH = CERT_COMPARE_SHA1_HASH;<br>const CERT_COMPARE_NAME_STR_A = 7;<br>const CERT_COMPARE_NAME_STR_W = 8;<br>const CERT_COMPARE_KEY_SPEC = 9;<br>const CERT_COMPARE_ENHKEY_USAGE = 10;<br>const CERT_COMPARE_CTL_USAGE = CERT_COMPARE_ENHKEY_USAGE;<br><br>//+-------------------------------------------------------------------------<br>// dwFindType<br>//<br>// The dwFindType definition consists of two components:<br>// - comparison function<br>// - certificate information flag<br>//--------------------------------------------------------------------------<br><br>const CERT_FIND_ANY = (CERT_COMPARE_ANY shl CERT_COMPARE_SHIFT);<br>const CERT_FIND_SHA1_HASH = (CERT_COMPARE_SHA1_HASH shl CERT_COMPARE_SHIFT);<br>const CERT_FIND_MD5_HASH = (CERT_COMPARE_MD5_HASH shl CERT_COMPARE_SHIFT);<br>const CERT_FIND_HASH = CERT_FIND_SHA1_HASH;<br>const CERT_FIND_PROPERTY = (CERT_COMPARE_PROPERTY shl CERT_COMPARE_SHIFT);<br>const CERT_FIND_PUBLIC_KEY = (CERT_COMPARE_PUBLIC_KEY shl CERT_COMPARE_SHIFT);<br><br>const CERT_FIND_SUBJECT_NAME = (CERT_COMPARE_NAME shl CERT_COMPARE_SHIFT or CERT_INFO_SUBJECT_FLAG);<br>const CERT_FIND_SUBJECT_ATTR = (CERT_COMPARE_ATTR shl CERT_COMPARE_SHIFT or CERT_INFO_SUBJECT_FLAG);<br>const CERT_FIND_ISSUER_NAME = (CERT_COMPARE_NAME shl CERT_COMPARE_SHIFT or CERT_INFO_ISSUER_FLAG);<br>const CERT_FIND_ISSUER_ATTR = (CERT_COMPARE_ATTR shl CERT_COMPARE_SHIFT or CERT_INFO_ISSUER_FLAG);<br>const CERT_FIND_SUBJECT_STR_A = (CERT_COMPARE_NAME_STR_A shl CERT_COMPARE_SHIFT or CERT_INFO_SUBJECT_FLAG);<br>const CERT_FIND_SUBJECT_STR_W = (CERT_COMPARE_NAME_STR_W shl CERT_COMPARE_SHIFT or CERT_INFO_SUBJECT_FLAG);<br>const CERT_FIND_SUBJECT_STR = CERT_FIND_SUBJECT_STR_W;<br>const CERT_FIND_ISSUER_STR_A = (CERT_COMPARE_NAME_STR_A shl CERT_COMPARE_SHIFT or CERT_INFO_ISSUER_FLAG);<br>const CERT_FIND_ISSUER_STR_W = (CERT_COMPARE_NAME_STR_W shl CERT_COMPARE_SHIFT or CERT_INFO_ISSUER_FLAG);<br>const CERT_FIND_ISSUER_STR = CERT_FIND_ISSUER_STR_W;<br>const CERT_FIND_KEY_SPEC = (CERT_COMPARE_KEY_SPEC shl CERT_COMPARE_SHIFT);<br>const CERT_FIND_ENHKEY_USAGE = (CERT_COMPARE_ENHKEY_USAGE shl CERT_COMPARE_SHIFT);<br>const CERT_FIND_CTL_USAGE = CERT_FIND_ENHKEY_USAGE;<br><br>//+-------------------------------------------------------------------------<br>// CERT_FIND_ANY<br>//<br>// Find any certificate.<br>//<br>// pvFindPara isn't used.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CERT_FIND_HASH<br>//<br>// Find a certificate with the specified hash.<br>//<br>// pvFindPara points to a CRYPT_HASH_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CERT_FIND_PROPERTY<br>//<br>// Find a certificate having the specified property.<br>//<br>// pvFindPara points to a DWORD containing the PROP_ID<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CERT_FIND_PUBLIC_KEY<br>//<br>// Find a certificate matching the specified public key.<br>//<br>// pvFindPara points to a CERT_PUBLIC_KEY_INFO containing the public key<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CERT_FIND_SUBJECT_NAME<br>// CERT_FIND_ISSUER_NAME<br>//<br>// Find a certificate with the specified subject/issuer name. Does an exact<br>// match of the entire name.<br>//<br>// Restricts search to certificates matching the dwCertEncodingType.<br>//<br>// pvFindPara points to a CERT_NAME_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CERT_FIND_SUBJECT_ATTR<br>// CERT_FIND_ISSUER_ATTR<br>//<br>// Find a certificate with the specified subject/issuer attributes.<br>//<br>// Compares the attributes in the subject/issuer name with the<br>// Relative Distinguished Name's (CERT_RDN) array of attributes specified in<br>// pvFindPara. The comparison iterates through the CERT_RDN attributes and looks<br>// for an attribute match in any of the subject/issuer's RDNs.<br>//<br>// The CERT_RDN_ATTR fields can have the following special values:<br>// pszObjId == NULL - ignore the attribute object identifier<br>// dwValueType == RDN_ANY_TYPE - ignore the value type<br>// Value.pbData == NULL - match any value<br>//<br>// Currently only an exact, case sensitive match is supported.<br>//<br>// CERT_UNICODE_IS_RDN_ATTRS_FLAG should be set in dwFindFlags if the RDN was<br>// initialized with unicode strings as for<br>// CryptEncodeObject(X509_UNICODE_NAME).<br>//<br>// Restricts search to certificates matching the dwCertEncodingType.<br>//<br>// pvFindPara points to a CERT_RDN (defined in wincert.h).<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CERT_FIND_SUBJECT_STR_A<br>// CERT_FIND_SUBJECT_STR_W | CERT_FIND_SUBJECT_STR<br>// CERT_FIND_ISSUER_STR_A<br>// CERT_FIND_ISSUER_STR_W | CERT_FIND_ISSUER_STR<br>//<br>// Find a certificate containing the specified subject/issuer name string.<br>//<br>// First, the certificate's subject/issuer is converted to a name string<br>// via CertNameToStrA/CertNameToStrW(CERT_SIMPLE_NAME_STR). Then, a<br>// case insensitive substring within string match is performed.<br>//<br>// Restricts search to certificates matching the dwCertEncodingType.<br>//<br>// For *_STR_A, pvFindPara points to a null terminated character string.<br>// For *_STR_W, pvFindPara points to a null terminated wide character string.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CERT_FIND_KEY_SPEC<br>//<br>// Find a certificate having a CERT_KEY_SPEC_PROP_ID property matching<br>// the specified KeySpec.<br>//<br>// pvFindPara points to a DWORD containing the KeySpec.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CERT_FIND_ENHKEY_USAGE<br>//<br>// Find a certificate having the szOID_ENHANCED_KEY_USAGE extension or<br>// the CERT_ENHKEY_USAGE_PROP_ID and matching the specified pszUsageIdentifers.<br>//<br>// pvFindPara points to a CERT_ENHKEY_USAGE data structure. If pvFindPara<br>// is NULL or CERT_ENHKEY_USAGE's cUsageIdentifier is 0, then, matches any<br>// certificate having enhanced key usage.<br>//<br>// The CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG can be set in dwFindFlags to<br>// also match a certificate without either the extension or property.<br>//<br>// If CERT_FIND_NO_ENHKEY_USAGE_FLAG is set in dwFindFlags, finds<br>// certificates without the key usage extension or property. Setting this<br>// flag takes precedence over pvFindPara being NULL.<br>//<br>// If the CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG is set, then, only does a match<br>// using the extension. If pvFindPara is NULL or cUsageIdentifier is set to<br>// 0, finds certificates having the extension. If<br>// CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is set, also matches a certificate<br>// without the extension. If CERT_FIND_NO_ENHKEY_USAGE_FLAG is set, finds<br>// certificates without the extension.<br>//<br>// If the CERT_FIND_EXT_PROP_ENHKEY_USAGE_FLAG is set, then, only does a match<br>// using the property. If pvFindPara is NULL or cUsageIdentifier is set to<br>// 0, finds certificates having the property. If<br>// CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is set, also matches a certificate<br>// without the property. If CERT_FIND_NO_ENHKEY_USAGE_FLAG is set, finds<br>// certificates without the property.<br>//--------------------------------------------------------------------------<br><br>const CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG = $1;<br>const CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG = $2;<br>const CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG = $4;<br>const CERT_FIND_NO_ENHKEY_USAGE_FLAG = $8;<br>const CERT_FIND_OPTIONAL_CTL_USAGE_FLAG = CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG;<br>const CERT_FIND_EXT_ONLY_CTL_USAGE_FLAG = CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG;<br>const CERT_FIND_PROP_ONLY_CTL_USAGE_FLAG = CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG;<br>const CERT_FIND_NO_CTL_USAGE_FLAG = CERT_FIND_NO_ENHKEY_USAGE_FLAG;<br><br>//+-------------------------------------------------------------------------<br>// Get the certificate context from the store for the first or next issuer<br>// of the specified subject certificate. Perform the enabled<br>// verification checks on the subject. (Note, the checks are on the subject<br>// using the returned issuer certificate.)<br>//<br>// If the first or next issuer certificate isn't found, NULL is returned.<br>// Otherwise, a pointer to a read only CERT_CONTEXT is returned. CERT_CONTEXT<br>// must be freed by calling CertFreeCertificateContext or is freed when passed as the<br>// pPrevIssuerContext on a subsequent call. CertDuplicateCertificateContext<br>// can be called to make a duplicate.<br>//<br>// For a self signed subject certificate, NULL is returned with LastError set<br>// to CERT_STORE_SELF_SIGNED. The enabled verification checks are still done.<br>//<br>// The pSubjectContext may have been obtained from this store, another store<br>// or created by the caller application. When created by the caller, the<br>// CertCreateCertificateContext function must have been called.<br>//<br>// An issuer may have multiple certificates. This may occur when the validity<br>// period is about to change. pPrevIssuerContext MUST BE NULL on the first<br>// call to get the issuer. To get the next certificate for the issuer, the<br>// pPrevIssuerContext is set to the CERT_CONTEXT returned by a previous call.<br>//<br>// NOTE: a NON-NULL pPrevIssuerContext is always CertFreeCertificateContext'ed by<br>// this function, even for an error.<br>//<br>// The following flags can be set in *pdwFlags to enable verification checks<br>// on the subject certificate context:<br>// CERT_STORE_SIGNATURE_FLAG - use the public key in the returned<br>// issuer certificate to verify the<br>// signature on the subject certificate.<br>// Note, if pSubjectContext->hCertStore ==<br>// hCertStore, the store provider might<br>// be able to eliminate a redo of<br>// the signature verify.<br>// CERT_STORE_TIME_VALIDITY_FLAG - get the current time and verify that<br>// its within the subject certificate's<br>// validity period<br>// CERT_STORE_REVOCATION_FLAG - check if the subject certificate is on<br>// the issuer's revocation list<br>//<br>// If an enabled verification check fails, then, its flag is set upon return.<br>// If CERT_STORE_REVOCATION_FLAG was enabled and the issuer doesn't have a<br>// CRL in the store, then, CERT_STORE_NO_CRL_FLAG is set in addition to<br>// the CERT_STORE_REVOCATION_FLAG.<br>//<br>// If CERT_STORE_SIGNATURE_FLAG or CERT_STORE_REVOCATION_FLAG is set, then,<br>// CERT_STORE_NO_ISSUER_FLAG is set if it doesn't have an issuer certificate<br>// in the store.<br>//<br>// For a verification check failure, a pointer to the issuer's CERT_CONTEXT<br>// is still returned and SetLastError isn't updated.<br>//--------------------------------------------------------------------------<br>function CertGetIssuerCertificateFromStore(hCertStore :HCERTSTORE;<br> pSubjectContext
CCERT_CONTEXT;<br> pPrevIssuerContext
CCERT_CONTEXT; //OPTIONAL<br> pdwFlags
DWORD)
CCERT_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Perform the enabled verification checks on the subject certificate<br>// using the issuer. Same checks and flags definitions as for the above<br>// CertGetIssuerCertificateFromStore.<br>//<br>// If you are only checking CERT_STORE_TIME_VALIDITY_FLAG, then, the<br>// issuer can be NULL.<br>//<br>// For a verification check failure, SUCCESS is still returned.<br>//--------------------------------------------------------------------------<br><br>function CertVerifySubjectCertificateContext(pSubject
CCERT_CONTEXT;<br> pIssuer
CCERT_CONTEXT; //OPTIONAL<br> pdwFlags
DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Duplicate a certificate context<br>//--------------------------------------------------------------------------<br><br>function CertDuplicateCertificateContext(pCertContext
CCERT_CONTEXT)
CCERT_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Create a certificate context from the encoded certificate. The created<br>// context isn't put in a store.<br>//<br>// Makes a copy of the encoded certificate in the created context.<br>//<br>// If unable to decode and create the certificate context, NULL is returned.<br>// Otherwise, a pointer to a read only CERT_CONTEXT is returned.<br>// CERT_CONTEXT must be freed by calling CertFreeCertificateContext.<br>// CertDuplicateCertificateContext can be called to make a duplicate.<br>//<br>// CertSetCertificateContextProperty and CertGetCertificateContextProperty can be called<br>// to store properties for the certificate.<br>//--------------------------------------------------------------------------<br>function CertCreateCertificateContext(dwCertEncodingType
WORD;<br> pbCertEncoded
BYTE;<br> cbCertEncoded
WORD)
CCERT_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Free a certificate context<br>//<br>// There needs to be a corresponding free for each context obtained by a<br>// get, find, duplicate or create.<br>//--------------------------------------------------------------------------<br>function CertFreeCertificateContext(pCertContext
CCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Set the property for the specified certificate context.<br>//<br>// The type definition for pvData depends on the dwPropId value. There are<br>// five predefined types:<br>// CERT_KEY_PROV_HANDLE_PROP_ID - a HCRYPTPROV for the certificate's<br>// private key is passed in pvData. Updates the hCryptProv field<br>// of the CERT_KEY_CONTEXT_PROP_ID. If the CERT_KEY_CONTEXT_PROP_ID<br>// doesn't exist, its created with all the other fields zeroed out. If<br>// CERT_STORE_NO_CRYPT_RELEASE_FLAG isn't set, HCRYPTPROV is implicitly<br>// released when either the property is set to NULL or on the final<br>// free of the CertContext.<br>//<br>// CERT_KEY_PROV_INFO_PROP_ID - a PCRYPT_KEY_PROV_INFO for the certificate's<br>// private key is passed in pvData.<br>//<br>// CERT_SHA1_HASH_PROP_ID -<br>// CERT_MD5_HASH_PROP_ID - normally, either property is implicitly<br>// set by doing a CertGetCertificateContextProperty. pvData points to a<br>// CRYPT_HASH_BLOB.<br>//<br>// CERT_KEY_CONTEXT_PROP_ID - a PCERT_KEY_CONTEXT for the certificate's<br>// private key is passed in pvData. The CERT_KEY_CONTEXT contains both the<br>// hCryptProv and dwKeySpec for the private key.<br>// See the CERT_KEY_PROV_HANDLE_PROP_ID for more information about<br>// the hCryptProv field and dwFlags settings. Note, more fields may<br>// be added for this property. The cbSize field value will be adjusted<br>// accordingly.<br>//<br>// CERT_KEY_SPEC_PROP_ID - the dwKeySpec for the private key. pvData<br>// points to a DWORD containing the KeySpec<br>//<br>// CERT_ENHKEY_USAGE_PROP_ID - enhanced key usage definition for the<br>// certificate. pvData points to a CRYPT_DATA_BLOB containing an<br>// ASN.1 encoded CERT_ENHKEY_USAGE (encoded via<br>// CryptEncodeObject(X509_ENHANCED_KEY_USAGE).<br>//<br>// CERT_NEXT_UPDATE_LOCATION_PROP_ID - location of the next update.<br>// Currently only applicable to CTLs. pvData points to a CRYPT_DATA_BLOB<br>// containing an ASN.1 encoded CERT_ALT_NAME_INFO (encoded via<br>// CryptEncodeObject(X509_ALTERNATE_NAME)).<br>//<br>// CERT_FRIENDLY_NAME_PROP_ID - friendly name for the cert, CRL or CTL.<br>// pvData points to a CRYPT_DATA_BLOB. pbData is a pointer to a NULL<br>// terminated unicode, wide character string.<br>// cbData = (wcslen((LPWSTR) pbData) + 1) * sizeof(WCHAR).<br>//<br>// For all the other PROP_IDs: an encoded PCRYPT_DATA_BLOB is passed in pvData.<br>//<br>// If the property already exists, then, the old value is deleted and silently<br>// replaced. Setting, pvData to NULL, deletes the property.<br>//--------------------------------------------------------------------------<br>function CertSetCertificateContextProperty(pCertContext
CCERT_CONTEXT;<br> dwPropId
WORD;<br> dwFlags
WORD;<br> pvData
VOID):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Get the property for the specified certificate context.<br>//<br>// For CERT_KEY_PROV_HANDLE_PROP_ID, pvData points to a HCRYPTPROV.<br>//<br>// For CERT_KEY_PROV_INFO_PROP_ID, pvData points to a CRYPT_KEY_PROV_INFO structure.<br>// Elements pointed to by fields in the pvData structure follow the<br>// structure. Therefore, *pcbData may exceed the size of the structure.<br>//<br>// For CERT_KEY_CONTEXT_PROP_ID, pvData points to a CERT_KEY_CONTEXT structure.<br>//<br>// For CERT_KEY_SPEC_PROP_ID, pvData points to a DWORD containing the KeySpec.<br>// If the CERT_KEY_CONTEXT_PROP_ID exists, the KeySpec is obtained from there.<br>// Otherwise, if the CERT_KEY_PROV_INFO_PROP_ID exists, its the source<br>// of the KeySpec.<br>//<br>// For CERT_SHA1_HASH_PROP_ID or CERT_MD5_HASH_PROP_ID, if the hash<br>// doesn't already exist, then, its computed via CryptHashCertificate()<br>// and then set. pvData points to the computed hash. Normally, the length<br>// is 20 bytes for SHA and 16 for MD5.<br>//<br>// For all other PROP_IDs, pvData points to an encoded array of bytes.<br>//--------------------------------------------------------------------------<br>function CertGetCertificateContextProperty(pCertContext
CCERT_CONTEXT;<br> dwPropId
WORD;<br> pvData
VOID;<br> pcbData
DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Enumerate the properties for the specified certificate context.<br>//<br>// To get the first property, set dwPropId to 0. The ID of the first<br>// property is returned. To get the next property, set dwPropId to the<br>// ID returned by the last call. To enumerate all the properties continue<br>// until 0 is returned.<br>//<br>// CertGetCertificateContextProperty is called to get the property's data.<br>//<br>// Note, since, the CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_SPEC_PROP_ID<br>// properties are stored as fields in the CERT_KEY_CONTEXT_PROP_ID<br>// property, they aren't enumerated individually.<br>//--------------------------------------------------------------------------<br>function CertEnumCertificateContextProperties(pCertContext
CCERT_CONTEXT;<br> dwPropId
WORD)
WORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Get the first or next CRL context from the store for the specified<br>// issuer certificate. Perform the enabled verification checks on the CRL.<br>//<br>// If the first or next CRL isn't found, NULL is returned.<br>// Otherwise, a pointer to a read only CRL_CONTEXT is returned. CRL_CONTEXT<br>// must be freed by calling CertFreeCRLContext. However, the free must be<br>// pPrevCrlContext on a subsequent call. CertDuplicateCRLContext<br>// can be called to make a duplicate.<br>//<br>// The pIssuerContext may have been obtained from this store, another store<br>// or created by the caller application. When created by the caller, the<br>// CertCreateCertificateContext function must have been called.<br>//<br>// If pIssuerContext == NULL, finds all the CRLs in the store.<br>//<br>// An issuer may have multiple CRLs. For example, it generates delta CRLs<br>// using a X.509 v3 extension. pPrevCrlContext MUST BE NULL on the first<br>// call to get the CRL. To get the next CRL for the issuer, the<br>// pPrevCrlContext is set to the CRL_CONTEXT returned by a previous call.<br>//<br>// NOTE: a NON-NULL pPrevCrlContext is always CertFreeCRLContext'ed by<br>// this function, even for an error.<br>//<br>// The following flags can be set in *pdwFlags to enable verification checks<br>// on the returned CRL:<br>// CERT_STORE_SIGNATURE_FLAG - use the public key in the<br>// issuer's certificate to verify the<br>// signature on the returned CRL.<br>// Note, if pIssuerContext->hCertStore ==<br>// hCertStore, the store provider might<br>// be able to eliminate a redo of<br>// the signature verify.<br>// CERT_STORE_TIME_VALIDITY_FLAG - get the current time and verify that<br>// its within the CRL's ThisUpdate and<br>// NextUpdate validity period.<br>//<br>// If an enabled verification check fails, then, its flag is set upon return.<br>//<br>// If pIssuerContext == NULL, then, an enabled CERT_STORE_SIGNATURE_FLAG<br>// always fails and the CERT_STORE_NO_ISSUER_FLAG is also set.<br>//<br>// For a verification check failure, a pointer to the first or next<br>// CRL_CONTEXT is still returned and SetLastError isn't updated.<br>//--------------------------------------------------------------------------<br>function CertGetCRLFromStore(hCertStore :HCERTSTORE;<br> pIssuerContext
CCERT_CONTEXT; //OPTIONAL<br> pPrevCrlContext
CCRL_CONTEXT;<br> pdwFlags
DWORD)
CCRL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Duplicate a CRL context<br>//--------------------------------------------------------------------------<br>function CertDuplicateCRLContext(pCrlContext
CCRL_CONTEXT)
CCRL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Create a CRL context from the encoded CRL. The created<br>// context isn't put in a store.<br>//<br>// Makes a copy of the encoded CRL in the created context.<br>//<br>// If unable to decode and create the CRL context, NULL is returned.<br>// Otherwise, a pointer to a read only CRL_CONTEXT is returned.<br>// CRL_CONTEXT must be freed by calling CertFreeCRLContext.<br>// CertDuplicateCRLContext can be called to make a duplicate.<br>//<br>// CertSetCRLContextProperty and CertGetCRLContextProperty can be called<br>// to store properties for the CRL.<br>//--------------------------------------------------------------------------<br>function CertCreateCRLContext(dwCertEncodingType
WORD;<br> pbCrlEncoded
BYTE;<br> cbCrlEncoded
WORD)
CCRL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Free a CRL context<br>//<br>// There needs to be a corresponding free for each context obtained by a<br>// get, duplicate or create.<br>//--------------------------------------------------------------------------<br>function CertFreeCRLContext(pCrlContext
CCRL_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Set the property for the specified CRL context.<br>//<br>// Same Property Ids and semantics as CertSetCertificateContextProperty.<br>//--------------------------------------------------------------------------<br>function CertSetCRLContextProperty(pCrlContext
CCRL_CONTEXT;<br> dwPropId
WORD;<br> dwFlags
WORD;<br> const pvData
VOID):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Get the property for the specified CRL context.<br>//<br>// Same Property Ids and semantics as CertGetCertificateContextProperty.<br>//<br>// CERT_SHA1_HASH_PROP_ID or CERT_MD5_HASH_PROP_ID is the predefined<br>// property of most interest.<br>//--------------------------------------------------------------------------<br>function CertGetCRLContextProperty(pCrlContext
CCRL_CONTEXT;<br> dwPropId
WORD;<br> pvData
VOID;<br> pcbData
DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Enumerate the properties for the specified CRL context.<br>//<br>// To get the first property, set dwPropId to 0. The ID of the first<br>// property is returned. To get the next property, set dwPropId to the<br>// ID returned by the last call. To enumerate all the properties continue<br>// until 0 is returned.<br>//<br>// CertGetCRLContextProperty is called to get the property's data.<br>//--------------------------------------------------------------------------<br>function CertEnumCRLContextProperties(pCrlContext
CCRL_CONTEXT;<br> dwPropId
WORD)
WORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Add certificate/CRL, encoded, context or element disposition values.<br>//--------------------------------------------------------------------------<br>const CERT_STORE_ADD_NEW = 1;<br>const CERT_STORE_ADD_USE_EXISTING = 2;<br>const CERT_STORE_ADD_REPLACE_EXISTING = 3;<br>const CERT_STORE_ADD_ALWAYS = 4;<br><br>//+-------------------------------------------------------------------------<br>// Add the encoded certificate to the store according to the specified<br>// disposition action.<br>//<br>// Makes a copy of the encoded certificate before adding to the store.<br>//<br>// dwAddDispostion specifies the action to take if the certificate<br>// already exists in the store. This parameter must be one of the following<br>// values:<br>// CERT_STORE_ADD_NEW<br>// Fails if the certificate already exists in the store. LastError<br>// is set to CRYPT_E_EXISTS.<br>// CERT_STORE_ADD_USE_EXISTING<br>// If the certifcate already exists, then, its used and if ppCertContext<br>// is non-NULL, the existing context is duplicated.<br>// CERT_STORE_ADD_REPLACE_EXISTING<br>// If the certificate already exists, then, the existing certificate<br>// context is deleted before creating and adding the new context.<br>// CERT_STORE_ADD_ALWAYS<br>// No check is made to see if the certificate already exists. A<br>// new certificate context is always created. This may lead to<br>// duplicates in the store.<br>//<br>// CertGetSubjectCertificateFromStore is called to determine if the<br>// certificate already exists in the store.<br>//<br>// ppCertContext can be NULL, indicating the caller isn't interested<br>// in getting the CERT_CONTEXT of the added or existing certificate.<br>//--------------------------------------------------------------------------<br>function CertAddEncodedCertificateToStore(hCertStore :HCERTSTORE;<br> dwCertEncodingType
WORD;<br> const pbCertEncoded
BYTE;<br> cbCertEncoded
WORD;<br> dwAddDisposition
WORD;<br> var ppCertContext
CCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Add the certificate context to the store according to the specified<br>// disposition action.<br>//<br>// In addition to the encoded certificate, the context's properties are<br>// also copied. Note, the CERT_KEY_CONTEXT_PROP_ID property (and its<br>// CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_SPEC_PROP_ID) isn't copied.<br>//<br>// Makes a copy of the certificate context before adding to the store.<br>//<br>// dwAddDispostion specifies the action to take if the certificate<br>// already exists in the store. This parameter must be one of the following<br>// values:<br>// CERT_STORE_ADD_NEW<br>// Fails if the certificate already exists in the store. LastError<br>// is set to CRYPT_E_EXISTS.<br>// CERT_STORE_ADD_USE_EXISTING<br>// If the certifcate already exists, then, its used and if ppStoreContext<br>// is non-NULL, the existing context is duplicated. Iterates<br>// through pCertContext's properties and only copies the properties<br>// that don't already exist. The SHA1 and MD5 hash properties aren't<br>// copied.<br>// CERT_STORE_ADD_REPLACE_EXISTING<br>// If the certificate already exists, then, the existing certificate<br>// context is deleted before creating and adding a new context.<br>// Properties are copied before doing the add.<br>// CERT_STORE_ADD_ALWAYS<br>// No check is made to see if the certificate already exists. A<br>// new certificate context is always created and added. This may lead to<br>// duplicates in the store. Properties are<br>// copied before doing the add.<br>//<br>// CertGetSubjectCertificateFromStore is called to determine if the<br>// certificate already exists in the store.<br>//<br>// ppStoreContext can be NULL, indicating the caller isn't interested<br>// in getting the CERT_CONTEXT of the added or existing certificate.<br>//--------------------------------------------------------------------------<br>function CertAddCertificateContextToStore(hCertStore :HCERTSTORE;<br> pCertContext
CCERT_CONTEXT;<br> dwAddDisposition
WORD;<br> var ppStoreContext
CCERT_CONTEXT //OPTIONAL<br>  
:BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Store Context Types<br>//--------------------------------------------------------------------------<br>const CERT_STORE_CERTIFICATE_CONTEXT = 1;<br>const CERT_STORE_CRL_CONTEXT = 2;<br>const CERT_STORE_CTL_CONTEXT = 3;<br><br>//+-------------------------------------------------------------------------<br>// Certificate Store Context Bit Flags<br>//--------------------------------------------------------------------------<br>const CERT_STORE_ALL_CONTEXT_FLAG = (not ULONG(0));<br>const CERT_STORE_CERTIFICATE_CONTEXT_FLAG = (1 shl CERT_STORE_CERTIFICATE_CONTEXT);<br>const CERT_STORE_CRL_CONTEXT_FLAG = (1 shl CERT_STORE_CRL_CONTEXT);<br>const CERT_STORE_CTL_CONTEXT_FLAG = (1 shl CERT_STORE_CTL_CONTEXT);<br><br>//+-------------------------------------------------------------------------<br>// Add the serialized certificate or CRL element to the store.<br>//<br>// The serialized element contains the encoded certificate, CRL or CTL and<br>// its properties, such as, CERT_KEY_PROV_INFO_PROP_ID.<br>//<br>// If hCertStore is NULL, creates a certificate, CRL or CTL context not<br>// residing in any store.<br>//<br>// dwAddDispostion specifies the action to take if the certificate or CRL<br>// already exists in the store. See CertAddCertificateContextToStore for a<br>// list of and actions taken.<br>//<br>// dwFlags currently isn't used and should be set to 0.<br>//<br>// dwContextTypeFlags specifies the set of allowable contexts. For example, to<br>// add either a certificate or CRL, set dwContextTypeFlags to:<br>// CERT_STORE_CERTIFICATE_CONTEXT_FLAG | CERT_STORE_CRL_CONTEXT_FLAG<br>//<br>// *pdwContextType is updated with the type of the context returned in<br>// *ppvContxt. pdwContextType or ppvContext can be NULL, indicating the<br>// caller isn't interested in getting the output. If *ppvContext is<br>// returned it must be freed by calling CertFreeCertificateContext or<br>// CertFreeCRLContext.<br>//--------------------------------------------------------------------------<br>function CertAddSerializedElementToStore(hCertStore :HCERTSTORE;<br> pbElement
BYTE;<br> cbElement
WORD;<br> dwAddDisposition
WORD;<br> dwFlags
WORD;<br> dwContextTypeFlags
WORD;<br> pdwContextType
DWORD;<br> var ppvContext : array of PVOID):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Delete the specified certificate from the store.<br>//<br>// All subsequent gets or finds for the certificate will fail. However,<br>// memory allocated for the certificate isn't freed until all of its contexts<br>// have also been freed.<br>//<br>// The pCertContext is obtained from a get, enum, find or duplicate.<br>//<br>// Some store provider implementations might also delete the issuer's CRLs<br>// if this is the last certificate for the issuer in the store.<br>//<br>// NOTE: the pCertContext is always CertFreeCertificateContext'ed by<br>// this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertDeleteCertificateFromStore(pCertContext
CCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Add the encoded CRL to the store according to the specified<br>// disposition option.<br>//<br>// Makes a copy of the encoded CRL before adding to the store.<br>//<br>// dwAddDispostion specifies the action to take if the CRL<br>// already exists in the store. See CertAddEncodedCertificateToStore for a<br>// list of and actions taken.<br>//<br>// Compares the CRL's Issuer to determine if the CRL already exists in the<br>// store.<br>//<br>// ppCrlContext can be NULL, indicating the caller isn't interested<br>// in getting the CRL_CONTEXT of the added or existing CRL.<br>//--------------------------------------------------------------------------<br>function CertAddEncodedCRLToStore(hCertStore :HCERTSTORE;<br> dwCertEncodingType
WORD;<br> pbCrlEncoded
BYTE;<br> cbCrlEncoded
WORD;<br> dwAddDisposition
WORD;<br> var ppCrlContext
CCRL_CONTEXT<br>  
:BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Add the CRL context to the store according to the specified<br>// disposition option.<br>//<br>// In addition to the encoded CRL, the context's properties are<br>// also copied. Note, the CERT_KEY_CONTEXT_PROP_ID property (and its<br>// CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_SPEC_PROP_ID) isn't copied.<br>//<br>// Makes a copy of the encoded CRL before adding to the store.<br>//<br>// dwAddDispostion specifies the action to take if the CRL<br>// already exists in the store. See CertAddCertificateContextToStore for a<br>// list of and actions taken.<br>//<br>// Compares the CRL's Issuer, ThisUpdate and NextUpdate to determine<br>// if the CRL already exists in the store.<br>//<br>// ppStoreContext can be NULL, indicating the caller isn't interested<br>// in getting the CRL_CONTEXT of the added or existing CRL.<br>//--------------------------------------------------------------------------<br>function CertAddCRLContextToStore(hCertStore :HCERTSTORE;<br> pCrlContext
CCRL_CONTEXT;<br> dwAddDisposition
WORD;<br> var ppStoreContext
CCRL_CONTEXT<br>  
:BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Delete the specified CRL from the store.<br>//<br>// All subsequent gets for the CRL will fail. However,<br>// memory allocated for the CRL isn't freed until all of its contexts<br>// have also been freed.<br>//<br>// The pCrlContext is obtained from a get or duplicate.<br>//<br>// NOTE: the pCrlContext is always CertFreeCRLContext'ed by<br>// this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertDeleteCRLFromStore(pCrlContext
CCRL_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Serialize the certificate context's encoded certificate and its<br>// properties.<br>//--------------------------------------------------------------------------<br>function CertSerializeCertificateStoreElement(pCertContext
CCERT_CONTEXT;<br> dwFlags
WORD;<br> pbElement
BYTE;<br> pcbElement
DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Serialize the CRL context's encoded CRL and its properties.<br>//--------------------------------------------------------------------------<br>function CertSerializeCRLStoreElement(pCrlContext
CCRL_CONTEXT;<br> dwFlags
WORD;<br> pbElement
BYTE;<br> pcbElement
DWORD):BOOL ; stdcall;<br>//+=========================================================================<br>// Certificate Trust List (CTL) Store Data Structures and APIs<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// Duplicate a CTL context<br>//--------------------------------------------------------------------------<br>function CertDuplicateCTLContext(pCtlContext
CCTL_CONTEXT)
CCTL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Create a CTL context from the encoded CTL. The created<br>// context isn't put in a store.<br>//<br>// Makes a copy of the encoded CTL in the created context.<br>//<br>// If unable to decode and create the CTL context, NULL is returned.<br>// Otherwise, a pointer to a read only CTL_CONTEXT is returned.<br>// CTL_CONTEXT must be freed by calling CertFreeCTLContext.<br>// CertDuplicateCTLContext can be called to make a duplicate.<br>//<br>// CertSetCTLContextProperty and CertGetCTLContextProperty can be called<br>// to store properties for the CTL.<br>//--------------------------------------------------------------------------<br>function CertCreateCTLContext(dwMsgAndCertEncodingType
WORD;<br> const pbCtlEncoded
BYTE;<br> cbCtlEncoded
WORD)
CCTL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Free a CTL context<br>//<br>// There needs to be a corresponding free for each context obtained by a<br>// get, duplicate or create.<br>//--------------------------------------------------------------------------<br>function CertFreeCTLContext(pCtlContext
CCTL_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Set the property for the specified CTL context.<br>//<br>// Same Property Ids and semantics as CertSetCertificateContextProperty.<br>//--------------------------------------------------------------------------<br>function CertSetCTLContextProperty(pCtlContext
CCTL_CONTEXT;<br> dwPropId
WORD;<br> dwFlags
WORD;<br> const pvData
VOID):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Get the property for the specified CTL context.<br>//<br>// Same Property Ids and semantics as CertGetCertificateContextProperty.<br>//<br>// CERT_SHA1_HASH_PROP_ID or CERT_NEXT_UPDATE_LOCATION_PROP_ID are the<br>// predefined properties of most interest.<br>//--------------------------------------------------------------------------<br>function CertGetCTLContextProperty(pCtlContext
CCTL_CONTEXT;<br> dwPropId
WORD;<br> pvData
VOID;<br> pcbData
DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Enumerate the properties for the specified CTL context.<br>//--------------------------------------------------------------------------<br>function CertEnumCTLContextProperties(pCtlContext
CCTL_CONTEXT;<br> dwPropId
WORD)
WORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Enumerate the CTL contexts in the store.<br>//<br>// If a CTL isn't found, NULL is returned.<br>// Otherwise, a pointer to a read only CTL_CONTEXT is returned. CTL_CONTEXT<br>// must be freed by calling CertFreeCTLContext or is freed when passed as the<br>// pPrevCtlContext on a subsequent call. CertDuplicateCTLContext<br>// can be called to make a duplicate.<br>//<br>// pPrevCtlContext MUST BE NULL to enumerate the first<br>// CTL in the store. Successive CTLs are enumerated by setting<br>// pPrevCtlContext to the CTL_CONTEXT returned by a previous call.<br>//<br>// NOTE: a NON-NULL pPrevCtlContext is always CertFreeCTLContext'ed by<br>// this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertEnumCTLsInStore(hCertStore :HCERTSTORE;<br> pPrevCtlContext
CCTL_CONTEXT<br> )
CCTL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Attempt to find the specified subject in the CTL.<br>//<br>// For CTL_CERT_SUBJECT_TYPE, pvSubject points to a CERT_CONTEXT. The CTL's<br>// SubjectAlgorithm is examined to determine the representation of the<br>// subject's identity. Initially, only SHA1 or MD5 hash will be supported.<br>// The appropriate hash property is obtained from the CERT_CONTEXT.<br>//<br>// For CTL_ANY_SUBJECT_TYPE, pvSubject points to the CTL_ANY_SUBJECT_INFO<br>// structure which contains the SubjectAlgorithm to be matched in the CTL<br>// and the SubjectIdentifer to be matched in one of the CTL entries.<br>//<br>// The certificate's hash or the CTL_ANY_SUBJECT_INFO's SubjectIdentifier<br>// is used as the key in searching the subject entries. A binary<br>// memory comparison is done between the key and the entry's SubjectIdentifer.<br>//<br>// dwEncodingType isn't used for either of the above SubjectTypes.<br>//--------------------------------------------------------------------------<br>function CertFindSubjectInCTL(dwEncodingType
WORD;<br> dwSubjectType
WORD;<br> pvSubject
VOID;<br> pCtlContext
CCTL_CONTEXT;<br> dwFlags
WORD)
CTL_ENTRY ; stdcall;<br>// Subject Types:<br>// CTL_ANY_SUBJECT_TYPE, pvSubject points to following CTL_ANY_SUBJECT_INFO.<br>// CTL_CERT_SUBJECT_TYPE, pvSubject points to CERT_CONTEXT.<br>const CTL_ANY_SUBJECT_TYPE = 1;<br>const CTL_CERT_SUBJECT_TYPE = 2;<br><br>type<br> PCTL_ANY_SUBJECT_INFO = ^CTL_ANY_SUBJECT_INFO;<br> CTL_ANY_SUBJECT_INFO = record<br> SubjectAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> SubjectIdentifier :CRYPT_DATA_BLOB;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Find the first or next CTL context in the store.<br>//<br>// The CTL is found according to the dwFindType and its pvFindPara.<br>// See below for a list of the find types and its parameters.<br>//<br>// Currently dwFindFlags isn't used and must be set to 0.<br>//<br>// Usage of dwMsgAndCertEncodingType depends on the dwFindType.<br>//<br>// If the first or next CTL isn't found, NULL is returned.<br>// Otherwise, a pointer to a read only CTL_CONTEXT is returned. CTL_CONTEXT<br>// must be freed by calling CertFreeCTLContext or is freed when passed as the<br>// pPrevCtlContext on a subsequent call. CertDuplicateCTLContext<br>// can be called to make a duplicate.<br>//<br>// pPrevCtlContext MUST BE NULL on the first<br>// call to find the CTL. To find the next CTL, the<br>// pPrevCtlContext is set to the CTL_CONTEXT returned by a previous call.<br>//<br>// NOTE: a NON-NULL pPrevCtlContext is always CertFreeCTLContext'ed by<br>// this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertFindCTLInStore(hCertStore :HCERTSTORE;<br> dwMsgAndCertEncodingType
WORD;<br> dwFindFlags
WORD;<br> dwFindType
WORD;<br> const pvFindPara
VOID;<br> pPrevCtlContext
CCTL_CONTEXT)
CCTL_CONTEXT ; stdcall;<br><br>const CTL_FIND_ANY = 0;<br>const CTL_FIND_SHA1_HASH = 1;<br>const CTL_FIND_MD5_HASH = 2;<br>const CTL_FIND_USAGE = 3;<br>const CTL_FIND_SUBJECT = 4;<br><br>type<br> PCTL_FIND_USAGE_PARA = ^CTL_FIND_USAGE_PARA;<br> CTL_FIND_USAGE_PARA = record<br> cbSize
WORD;<br> SubjectUsage :CTL_USAGE; // optional<br> ListIdentifier :CRYPT_DATA_BLOB; // optional<br> pSigner
CERT_INFO; // optional<br> end;<br><br>const CTL_FIND_NO_LIST_ID_CBDATA = $FFFFFFFF;<br>const CTL_FIND_NO_SIGNER_PTR = (PCERT_INFO($FFFFFFFF));<br><br>const CTL_FIND_SAME_USAGE_FLAG = $1;<br><br>type<br> PCTL_FIND_SUBJECT_PARA = ^CTL_FIND_SUBJECT_PARA;<br> CTL_FIND_SUBJECT_PARA = record<br> cbSize
WORD;<br> pUsagePara
CTL_FIND_USAGE_PARA; // optional<br> dwSubjectType
WORD;<br> pvSubject
VOID;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// CTL_FIND_ANY<br>//<br>// Find any CTL.<br>//<br>// pvFindPara isn't used.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CTL_FIND_SHA1_HASH<br>// CTL_FIND_MD5_HASH<br>//<br>// Find a CTL with the specified hash.<br>//<br>// pvFindPara points to a CRYPT_HASH_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CTL_FIND_USAGE<br>//<br>// Find a CTL having the specified usage identifiers, list identifier or<br>// signer. The CertEncodingType of the signer is obtained from the<br>// dwMsgAndCertEncodingType parameter.<br>//<br>// pvFindPara points to a CTL_FIND_USAGE_PARA data structure. The<br>// SubjectUsage.cUsageIdentifer can be 0 to match any usage. The<br>// ListIdentifier.cbData can be 0 to match any list identifier. To only match<br>// CTLs without a ListIdentifier, cbData must be set to<br>// CTL_FIND_NO_LIST_ID_CBDATA. pSigner can be NULL to match any signer. Only<br>// the Issuer and SerialNumber fields of the pSigner's PCERT_INFO are used.<br>// To only match CTLs without a signer, pSigner must be set to<br>// CTL_FIND_NO_SIGNER_PTR.<br>//<br>// The CTL_FIND_SAME_USAGE_FLAG can be set in dwFindFlags to<br>// only match CTLs with the same usage identifiers. CTLs having additional<br>// usage identifiers aren't matched. For example, if only "1.2.3" is specified<br>// in CTL_FIND_USAGE_PARA, then, for a match, the CTL must only contain<br>// "1.2.3" and not any additional usage identifers.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// CTL_FIND_SUBJECT<br>//<br>// Find a CTL having the specified subject. CertFindSubjectInCTL can be<br>// called to get a pointer to the subject's entry in the CTL. pUsagePara can<br>// optionally be set to enable the above CTL_FIND_USAGE matching.<br>//<br>// pvFindPara points to a CTL_FIND_SUBJECT_PARA data structure.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// Add the encoded CTL to the store according to the specified<br>// disposition option.<br>//<br>// Makes a copy of the encoded CTL before adding to the store.<br>//<br>// dwAddDispostion specifies the action to take if the CTL<br>// already exists in the store. See CertAddEncodedCertificateToStore for a<br>// list of and actions taken.<br>//<br>// Compares the CTL's SubjectUsage, ListIdentifier and any of its signers<br>// to determine if the CTL already exists in the store.<br>//<br>// ppCtlContext can be NULL, indicating the caller isn't interested<br>// in getting the CTL_CONTEXT of the added or existing CTL.<br>//--------------------------------------------------------------------------<br>function CertAddEncodedCTLToStore(hCertStore :HCERTSTORE;<br> dwMsgAndCertEncodingType
WORD;<br> const pbCtlEncoded
BYTE;<br> cbCtlEncoded
WORD;<br> dwAddDisposition
WORD;<br> var ppCtlContext
CCTL_CONTEXT //OPTIONAL<br>  
:BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Add the CTL context to the store according to the specified<br>// disposition option.<br>//<br>// In addition to the encoded CTL, the context's properties are<br>// also copied. Note, the CERT_KEY_CONTEXT_PROP_ID property (and its<br>// CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_SPEC_PROP_ID) isn't copied.<br>//<br>// Makes a copy of the encoded CTL before adding to the store.<br>//<br>// dwAddDispostion specifies the action to take if the CTL<br>// already exists in the store. See CertAddCertificateContextToStore for a<br>// list of and actions taken.<br>//<br>// Compares the CTL's SubjectUsage, ListIdentifier and any of its signers<br>// to determine if the CTL already exists in the store.<br>//<br>// ppStoreContext can be NULL, indicating the caller isn't interested<br>// in getting the CTL_CONTEXT of the added or existing CTL.<br>//--------------------------------------------------------------------------<br>function CertAddCTLContextToStore(hCertStore :HCERTSTORE;<br> pCtlContext
CCTL_CONTEXT;<br> dwAddDisposition
WORD;<br> var ppStoreContext
CCTL_CONTEXT<br>  
:BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Serialize the CTL context's encoded CTL and its properties.<br>//--------------------------------------------------------------------------<br>function CertSerializeCTLStoreElement(pCtlContext
CCTL_CONTEXT;<br> dwFlags
WORD;<br> pbElement
BYTE;<br> pcbElement
DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Delete the specified CTL from the store.<br>//<br>// All subsequent gets for the CTL will fail. However,<br>// memory allocated for the CTL isn't freed until all of its contexts<br>// have also been freed.<br>//<br>// The pCtlContext is obtained from a get or duplicate.<br>//<br>// NOTE: the pCtlContext is always CertFreeCTLContext'ed by<br>// this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertDeleteCTLFromStore(pCtlContext
CCTL_CONTEXT):BOOL ; stdcall;<br>//+=========================================================================<br>// Enhanced Key Usage Helper Functions<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// Get the enhanced key usage extension or property from the certificate<br>// and decode.<br>//<br>// If the CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG is set, then, only get the<br>// extension.<br>//<br>// If the CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG is set, then, only get the<br>// property.<br>//--------------------------------------------------------------------------<br>function CertGetEnhancedKeyUsage(pCertContext
CCERT_CONTEXT;<br> dwFlags
WORD;<br> pUsage
CERT_ENHKEY_USAGE;<br> pcbUsage
DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Set the enhanced key usage property for the certificate.<br>//--------------------------------------------------------------------------<br>function CertSetEnhancedKeyUsage(pCertContext
CCERT_CONTEXT;<br> pUsage
CERT_ENHKEY_USAGE<br> ):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Add the usage identifier to the certificate's enhanced key usage property.<br>//--------------------------------------------------------------------------<br>function CertAddEnhancedKeyUsageIdentifier(pCertContext
CCERT_CONTEXT;<br> pszUsageIdentifier :LPCSTR<br> ):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Remove the usage identifier from the certificate's enhanced key usage<br>// property.<br>//--------------------------------------------------------------------------<br>function CertRemoveEnhancedKeyUsageIdentifier(pCertContext
CCERT_CONTEXT;<br> pszUsageIdentifier :LPCSTR<br>  
:BOOL ; stdcall;<br><br>//+=========================================================================<br>// Cryptographic Message helper functions for verifying and signing a<br>// CTL.<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// Get and verify the signer of a cryptographic message.<br>//<br>// To verify a CTL, the hCryptMsg is obtained from the CTL_CONTEXT's<br>// hCryptMsg field.<br>//<br>// If CMSG_TRUSTED_SIGNER_FLAG is set, then, treat the Signer stores as being<br>// trusted and only search them to find the certificate corresponding to the<br>// signer's issuer and serial number. Otherwise, the SignerStores are<br>// optionally provided to supplement the message's store of certificates.<br>// If a signer certificate is found, its public key is used to verify<br>// the message signature. The CMSG_SIGNER_ONLY_FLAG can be set to<br>// return the signer without doing the signature verify.<br>//<br>// If CMSG_USE_SIGNER_INDEX_FLAG is set, then, only get the signer specified<br>// by *pdwSignerIndex. Otherwise, iterate through all the signers<br>// until a signer verifies or no more signers.<br>//<br>// For a verified signature, *ppSigner is updated with certificate context<br>// of the signer and *pdwSignerIndex is updated with the index of the signer.<br>// ppSigner and/or pdwSignerIndex can be NULL, indicating the caller isn't<br>// interested in getting the CertContext and/or index of the signer.<br>//--------------------------------------------------------------------------<br>function CryptMsgGetAndVerifySigner(hCryptMsg :HCRYPTMSG;<br> cSignerStore
WORD;<br> var rghSignerStore :HCERTSTORE;<br> dwFlags
WORD;<br> var ppSigner
CCERT_CONTEXT;<br> pdwSignerIndex
DWORD):BOOL ; stdcall;<br><br>const CMSG_TRUSTED_SIGNER_FLAG = $1;<br>const CMSG_SIGNER_ONLY_FLAG = $2;<br>const CMSG_USE_SIGNER_INDEX_FLAG = $4;<br><br>//+-------------------------------------------------------------------------<br>// Sign an encoded CTL.<br>//<br>// The pbCtlContent can be obtained via a CTL_CONTEXT's pbCtlContent<br>// field or via a CryptEncodeObject(PKCS_CTL).<br>//--------------------------------------------------------------------------<br>function CryptMsgSignCTL(dwMsgEncodingType
WORD;<br> pbCtlContent
BYTE;<br> cbCtlContent
WORD;<br> pSignInfo
CMSG_SIGNED_ENCODE_INFO;<br> dwFlags
WORD;<br> pbEncoded
BYTE;<br> pcbEncoded
DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Encode the CTL and create a signed message containing the encoded CTL.<br>//--------------------------------------------------------------------------<br>function CryptMsgEncodeAndSignCTL(dwMsgEncodingType
WORD;<br> pCtlInfo
CTL_INFO;<br> pSignInfo
CMSG_SIGNED_ENCODE_INFO;<br> dwFlags
WORD;<br> pbEncoded
BYTE;<br> pcbEncoded
DWORD):BOOL ; stdcall;<br><br>//+=========================================================================<br>// Certificate Verify CTL Usage Data Structures and APIs<br>//==========================================================================<br>type<br> PHCERTSTORE = ^HCERTSTORE;<br><br>type<br> PCTL_VERIFY_USAGE_PARA = ^CTL_VERIFY_USAGE_PARA;<br> CTL_VERIFY_USAGE_PARA = record<br> cbSize
WORD;<br> ListIdentifier :CRYPT_DATA_BLOB;// OPTIONAL<br> cCtlStore
WORD;<br> rghCtlStore
HCERTSTORE; // OPTIONAL<br> cSignerStore
WORD;<br> rghSignerStore
HCERTSTORE; // OPTIONAL<br> end;<br><br>type<br> PCTL_VERIFY_USAGE_STATUS = ^CTL_VERIFY_USAGE_STATUS;<br> CTL_VERIFY_USAGE_STATUS = record<br> cbSize
WORD;<br> dwError
WORD;<br> dwFlags
WORD;<br> ppCtl
PCCTL_CONTEXT; // IN OUT OPTIONAL<br> dwCtlEntryIndex
WORD;<br> ppSigner
PCCERT_CONTEXT ; // IN OUT OPTIONAL<br> dwSignerIndex
WORD;<br> end;<br><br>const CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG = $1;<br>const CERT_VERIFY_TRUSTED_SIGNERS_FLAG = $2;<br>const CERT_VERIFY_NO_TIME_CHECK_FLAG = $4;<br>const CERT_VERIFY_ALLOW_MORE_USAGE_FLAG = $8;<br><br>const CERT_VERIFY_UPDATED_CTL_FLAG = $1;<br><br>//+-------------------------------------------------------------------------<br>// Verify that a subject is trusted for the specified usage by finding a<br>// signed and time valid CTL with the usage identifiers and containing the<br>// the subject. A subject can be identified by either its certificate context<br>// or any identifier such as its SHA1 hash.<br>//<br>// See CertFindSubjectInCTL for definition of dwSubjectType and pvSubject<br>// parameters.<br>//<br>// Via pVerifyUsagePara, the caller can specify the stores to be searched<br>// to find the CTL. The caller can also specify the stores containing<br>// acceptable CTL signers. By setting the ListIdentifier, the caller<br>// can also restrict to a particular signer CTL list.<br>//<br>// Via pVerifyUsageStatus, the CTL containing the subject, the subject's<br>// index into the CTL's array of entries, and the signer of the CTL<br>// are returned. If the caller is not interested, ppCtl and ppSigner can be set<br>// to NULL. Returned contexts must be freed via the store's free context APIs.<br>//<br>// If the CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG isn't set, then, a time<br>// invalid CTL in one of the CtlStores may be replaced. When replaced, the<br>// CERT_VERIFY_UPDATED_CTL_FLAG is set in pVerifyUsageStatus->dwFlags.<br>//<br>// If the CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, then, only the<br>// SignerStores specified in pVerifyUsageStatus are searched to find<br>// the signer. Otherwise, the SignerStores provide additional sources<br>// to find the signer's certificate.<br>//<br>// If CERT_VERIFY_NO_TIME_CHECK_FLAG is set, then, the CTLs aren't checked<br>// for time validity.<br>//<br>// If CERT_VERIFY_ALLOW_MORE_USAGE_FLAG is set, then, the CTL may contain<br>// additional usage identifiers than specified by pSubjectUsage. Otherwise,<br>// the found CTL will contain the same usage identifers and no more.<br>//<br>// CertVerifyCTLUsage will be implemented as a dispatcher to OID installable<br>// functions. First, it will try to find an OID function matching the first<br>// usage object identifier in the pUsage sequence. Next, it will dispatch<br>// to the default CertDllVerifyCTLUsage functions.<br>//<br>// If the subject is trusted for the specified usage, then, TRUE is<br>// returned. Otherwise, FALSE is returned with dwError set to one of the<br>// following:<br>// CRYPT_E_NO_VERIFY_USAGE_DLL<br>// CRYPT_E_NO_VERIFY_USAGE_CHECK<br>// CRYPT_E_VERIFY_USAGE_OFFLINE<br>// CRYPT_E_NOT_IN_CTL<br>// CRYPT_E_NO_TRUSTED_SIGNER<br>//--------------------------------------------------------------------------<br>function CertVerifyCTLUsage(dwEncodingType
WORD;<br> dwSubjectType
WORD;<br> pvSubject
VOID;<br> pSubjectUsage
CTL_USAGE;<br> dwFlags
WORD;<br> pVerifyUsagePara
CTL_VERIFY_USAGE_PARA;<br> pVerifyUsageStatus
CTL_VERIFY_USAGE_STATUS<br>  
:BOOL ; stdcall;<br><br>//+=========================================================================<br>// Certificate Revocation Data Structures and APIs<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// The following data structure may be passed to CertVerifyRevocation to<br>// assist in finding the issuer of the context to be verified.<br>//<br>// When pIssuerCert is specified, pIssuerCert is the issuer of<br>// rgpvContext[cContext - 1].<br>//<br>// When cCertStore and rgCertStore are specified, these stores may contain<br>// an issuer certificate.<br>//--------------------------------------------------------------------------<br>type<br> PCERT_REVOCATION_PARA = ^CERT_REVOCATION_PARA;<br> CERT_REVOCATION_PARA = record<br> cbSize
WORD;<br> pIssuerCert
CCERT_CONTEXT;<br> cCertStore
WORD;<br> rgCertStore
HCERTSTORE ;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// The following data structure is returned by CertVerifyRevocation to<br>// specify the status of the revoked or unchecked context. Review the<br>// following CertVerifyRevocation comments for details.<br>//<br>// Upon input to CertVerifyRevocation, cbSize must be set to a size<br>// >= sizeof(CERT_REVOCATION_STATUS). Otherwise, CertVerifyRevocation<br>// returns FALSE and sets LastError to E_INVALIDARG.<br>//<br>// Upon input to the installed or registered CRYPT_OID_VERIFY_REVOCATION_FUNC<br>// functions, the dwIndex, dwError and dwReason have been zero'ed.<br>//--------------------------------------------------------------------------<br>type<br> PCERT_REVOCATION_STATUS = ^CERT_REVOCATION_STATUS;<br> CERT_REVOCATION_STATUS = record<br> cbSize
WORD;<br> dwIndex
WORD;<br> dwError
WORD;<br> dwReason
WORD;<br> end;<br>//+-------------------------------------------------------------------------<br>// Verifies the array of contexts for revocation. The dwRevType parameter<br>// indicates the type of the context data structure passed in rgpvContext.<br>// Currently only the revocation of certificates is defined.<br>//<br>// If the CERT_VERIFY_REV_CHAIN_FLAG flag is set, then, CertVerifyRevocation<br>// is verifying a chain of certs where, rgpvContext[i + 1] is the issuer<br>// of rgpvContext
. Otherwise, CertVerifyRevocation makes no assumptions<br>// about the order of the contexts.<br>//<br>// To assist in finding the issuer, the pRevPara may optionally be set. See<br>// the CERT_REVOCATION_PARA data structure for details.<br>//<br>// The contexts must contain enough information to allow the<br>// installable or registered revocation DLLs to find the revocation server. For<br>// certificates, this information would normally be conveyed in an<br>// extension such as the IETF's AuthorityInfoAccess extension.<br>//<br>// CertVerifyRevocation returns TRUE if all of the contexts were successfully<br>// checked and none were revoked. Otherwise, returns FALSE and updates the<br>// returned pRevStatus data structure as follows:<br>// dwIndex<br>// Index of the first context that was revoked or unable to<br>// be checked for revocation<br>// dwError<br>// Error status. LastError is also set to this error status.<br>// dwError can be set to one of the following error codes defined<br>// in winerror.h:<br>// ERROR_SUCCESS - good context<br>// CRYPT_E_REVOKED - context was revoked. dwReason contains the<br>// reason for revocation<br>// CRYPT_E_REVOCATION_OFFLINE - unable to connect to the<br>// revocation server<br>// CRYPT_E_NOT_IN_REVOCATION_DATABASE - the context to be checked<br>// was not found in the revocation server's database.<br>// CRYPT_E_NO_REVOCATION_CHECK - the called revocation function<br>// wasn't able to do a revocation check on the context<br>// CRYPT_E_NO_REVOCATION_DLL - no installed or registered Dll was<br>// found to verify revocation<br>// dwReason<br>// The dwReason is currently only set for CRYPT_E_REVOKED and contains<br>// the reason why the context was revoked. May be one of the following<br>// CRL reasons defined by the CRL Reason Code extension ("2.5.29.21"<br>// CRL_REASON_UNSPECIFIED 0<br>// CRL_REASON_KEY_COMPROMISE 1<br>// CRL_REASON_CA_COMPROMISE 2<br>// CRL_REASON_AFFILIATION_CHANGED 3<br>// CRL_REASON_SUPERSEDED 4<br>// CRL_REASON_CESSATION_OF_OPERATION 5<br>// CRL_REASON_CERTIFICATE_HOLD 6<br>//<br>// For each entry in rgpvContext, CertVerifyRevocation iterates<br>// through the CRYPT_OID_VERIFY_REVOCATION_FUNC<br>// function set's list of installed DEFAULT functions.<br>// CryptGetDefaultOIDFunctionAddress is called with pwszDll = NULL. If no<br>// installed functions are found capable of doing the revocation verification,<br>// CryptVerifyRevocation iterates through CRYPT_OID_VERIFY_REVOCATION_FUNC's<br>// list of registered DEFAULT Dlls. CryptGetDefaultOIDDllList is called to<br>// get the list. CryptGetDefaultOIDFunctionAddress is called to load the Dll.<br>//<br>// The called functions have the same signature as CertVerifyRevocation. A<br>// called function returns TRUE if it was able to successfully check all of<br>// the contexts and none were revoked. Otherwise, the called function returns<br>// FALSE and updates pRevStatus. dwIndex is set to the index of<br>// the first context that was found to be revoked or unable to be checked.<br>// dwError and LastError are updated. For CRYPT_E_REVOKED, dwReason<br>// is updated. Upon input to the called function, dwIndex, dwError and<br>// dwReason have been zero'ed. cbSize has been checked to be >=<br>// sizeof(CERT_REVOCATION_STATUS).<br>//<br>// If the called function returns FALSE, and dwError isn't set to<br>// CRYPT_E_REVOKED, then, CertVerifyRevocation either continues on to the<br>// next DLL in the list for a returned dwIndex of 0 or for a returned<br>// dwIndex > 0, restarts the process of finding a verify function by<br>// advancing the start of the context array to the returned dwIndex and<br>// decrementing the count of remaining contexts.<br>//--------------------------------------------------------------------------<br>function CertVerifyRevocation(dwEncodingType WORD;<br> dwRevType WORD;<br> cContext WORD;<br> rgpvContext :array of PVOID;<br> dwFlags WORD;<br> pRevPara CERT_REVOCATION_PARA;<br> pRevStatus CERT_REVOCATION_STATUS<br>  :BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Revocation types<br>//--------------------------------------------------------------------------<br>const CERT_CONTEXT_REVOCATION_TYPE = 1;<br><br>//+-------------------------------------------------------------------------<br>// When the following flag is set, rgpvContext[] consists of a chain<br>// of certificates, where rgpvContext[i + 1] is the issuer of rgpvContext.<br>//--------------------------------------------------------------------------<br>const CERT_VERIFY_REV_CHAIN_FLAG = $1;<br><br>//+-------------------------------------------------------------------------<br>// CERT_CONTEXT_REVOCATION_TYPE<br>//<br>// pvContext points to a const CERT_CONTEXT.<br>//--------------------------------------------------------------------------<br><br>//+=========================================================================<br>// Certificate Helper APIs<br>//==========================================================================<br><br><br>//+-------------------------------------------------------------------------<br>// Compare two multiple byte integer blobs to see if they are identical.<br>//<br>// Before doing the comparison, leading zero bytes are removed from a<br>// positive number and leading 0xFF bytes are removed from a negative<br>// number.<br>//<br>// The multiple byte integers are treated as Little Endian. pbData[0] is the<br>// least significant byte and pbData[cbData - 1] is the most significant<br>// byte.<br>//<br>// Returns TRUE if the integer blobs are identical after removing leading<br>// 0 or 0xFF bytes.<br>//--------------------------------------------------------------------------<br>function CertCompareIntegerBlob(pInt1 CRYPT_INTEGER_BLOB;<br> pInt2 CRYPT_INTEGER_BLOB<br>  :BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Compare two certificates to see if they are identical.<br>//<br>// Since a certificate is uniquely identified by its Issuer and SerialNumber,<br>// these are the only fields needing to be compared.<br>//<br>// Returns TRUE if the certificates are identical.<br>//--------------------------------------------------------------------------<br>function CertCompareCertificate(dwCertEncodingType WORD;<br> pCertId1 CERT_INFO;<br> pCertId2 CERT_INFO):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Compare two certificate names to see if they are identical.<br>//<br>// Returns TRUE if the names are identical.<br>//--------------------------------------------------------------------------<br>function CertCompareCertificateName(dwCertEncodingType WORD;<br> pCertName1 CERT_NAME_BLOB;<br> pCertName2 CERT_NAME_BLOB):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Compare the attributes in the certificate name with the specified<br>// Relative Distinguished Name's (CERT_RDN) array of attributes.<br>// The comparison iterates through the CERT_RDN attributes and looks for an<br>// attribute match in any of the certificate name's RDNs.<br>// Returns TRUE if all the attributes are found and match.<br>//<br>// The CERT_RDN_ATTR fields can have the following special values:<br>// pszObjId == NULL - ignore the attribute object identifier<br>// dwValueType == RDN_ANY_TYPE - ignore the value type<br>//<br>// Currently only an exact, case sensitive match is supported.<br>//<br>// CERT_UNICODE_IS_RDN_ATTRS_FLAG should be set if the pRDN was initialized<br>// with unicode strings as for CryptEncodeObject(X509_UNICODE_NAME).<br>//--------------------------------------------------------------------------<br>function CertIsRDNAttrsInCertificateName(dwCertEncodingType WORD;<br> dwFlags WORD;<br> pCertName CERT_NAME_BLOB;<br> pRDN CERT_RDN):BOOL ; stdcall;<br><br>const CERT_UNICODE_IS_RDN_ATTRS_FLAG = $1;<br><br>//+-------------------------------------------------------------------------<br>// Compare two public keys to see if they are identical.<br>//<br>// Returns TRUE if the keys are identical.<br>//--------------------------------------------------------------------------<br>function CertComparePublicKeyInfo(dwCertEncodingType WORD;<br> pPublicKey1 CERT_PUBLIC_KEY_INFO;<br> pPublicKey2 CERT_PUBLIC_KEY_INFO<br>  :BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Get the public/private key's bit length.<br>//<br>// Returns 0 if unable to determine the key's length.<br>//--------------------------------------------------------------------------<br>function CertGetPublicKeyLength(dwCertEncodingType WORD;<br> pPublicKey CERT_PUBLIC_KEY_INFO<br>  WORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Verify the signature of a subject certificate or a CRL using the<br>// public key info<br>//<br>// Returns TRUE for a valid signature.<br>//<br>// hCryptProv specifies the crypto provider to use to verify the signature.<br>// It doesn't need to use a private key.<br>//--------------------------------------------------------------------------<br>function CryptVerifyCertificateSignature(hCryptProv :HCRYPTPROV;<br> dwCertEncodingType WORD;<br> const pbEncoded BYTE;<br> cbEncoded WORD;<br> pPublicKey CERT_PUBLIC_KEY_INFO<br> ):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Compute the hash of the "to be signed" information in the encoded<br>// signed content (CERT_SIGNED_CONTENT_INFO).<br>//<br>// hCryptProv specifies the crypto provider to use to compute the hash.<br>// It doesn't need to use a private key.<br>//--------------------------------------------------------------------------<br>function CryptHashToBeSigned(hCryptProv :HCRYPTPROV;<br> dwCertEncodingType WORD;<br> const pbEncoded BYTE;<br> cbEncoded WORD;<br> pbComputedHash BYTE;<br> pcbComputedHash DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Hash the encoded content.<br>//<br>// hCryptProv specifies the crypto provider to use to compute the hash.<br>// It doesn't need to use a private key.<br>//<br>// Algid specifies the CAPI hash algorithm to use. If Algid is 0, then, the<br>// default hash algorithm (currently SHA1) is used.<br>//--------------------------------------------------------------------------<br>function CryptHashCertificate(hCryptProv :HCRYPTPROV;<br> Algid :ALG_ID;<br> dwFlags WORD;<br> const pbEncoded BYTE;<br> cbEncoded WORD;<br> pbComputedHash BYTE;<br> pcbComputedHash DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Sign the "to be signed" information in the encoded signed content.<br>//<br>// hCryptProv specifies the crypto provider to use to do the signature.<br>// It uses the specified private key.<br>//--------------------------------------------------------------------------<br>function CryptSignCertificate(hCryptProv :HCRYPTPROV;<br> dwKeySpec WORD;<br> dwCertEncodingType WORD;<br> const pbEncodedToBeSigned BYTE;<br> cbEncodedToBeSigned WORD;<br> pSignatureAlgorithm CRYPT_ALGORITHM_IDENTIFIER;<br> const pvHashAuxInfo VOID;<br> pbSignature BYTE;<br> pcbSignatureDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Encode the "to be signed" information. Sign the encoded "to be signed".<br>// Encode the "to be signed" and the signature.<br>//<br>// hCryptProv specifies the crypto provider to use to do the signature.<br>// It uses the specified private key.<br>//--------------------------------------------------------------------------<br>function CryptSignAndEncodeCertificate(hCryptProv :HCRYPTPROV;<br> dwKeySpec WORD;<br> dwCertEncodingType WORD;<br> const lpszStructType :LPCSTR; // "to be signed"<br> pvStructInfo VOID;<br> pSignatureAlgorithm CRYPT_ALGORITHM_IDENTIFIER;<br> const pvHashAuxInfo VOID;<br> pbEncoded BYTE;<br> pcbEncoded DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Verify the time validity of a certificate.<br>//<br>// Returns -1 if before NotBefore, +1 if after NotAfter and otherwise 0 for<br>// a valid certificate<br>//<br>// If pTimeToVerify is NULL, uses the current time.<br>//--------------------------------------------------------------------------<br>function CertVerifyTimeValidity(pTimeToVerify FILETIME;<br> pCertInfo CERT_INFO):LONG ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Verify the time validity of a CRL.<br>//<br>// Returns -1 if before ThisUpdate, +1 if after NextUpdate and otherwise 0 for<br>// a valid CRL<br>//<br>// If pTimeToVerify is NULL, uses the current time.<br>//--------------------------------------------------------------------------<br>function CertVerifyCRLTimeValidity(pTimeToVerify FILETIME;<br> pCrlInfo CRL_INFO):LONG ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Verify that the subject's time validity nests within the issuer's time<br>// validity.<br>//<br>// Returns TRUE if it nests. Otherwise, returns FALSE.<br>//--------------------------------------------------------------------------<br>function CertVerifyValidityNesting(pSubjectInfo CERT_INFO;<br> pIssuerInfo CERT_INFO):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Verify that the subject certificate isn't on its issuer CRL.<br>//<br>// Returns true if the certificate isn't on the CRL.<br>//--------------------------------------------------------------------------<br>function CertVerifyCRLRevocation(dwCertEncodingType WORD;<br> pCertId CERT_INFO; // Only the Issuer and SerialNumber<br> cCrlInfo WORD; // fields are used<br> rgpCrlInfo :array of PCRL_INFO):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Convert the CAPI AlgId to the ASN.1 Object Identifier string<br>//<br>// Returns NULL if there isn't an ObjId corresponding to the AlgId.<br>//--------------------------------------------------------------------------<br>function CertAlgIdToOID(dwAlgId WORD):LPCSTR ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Convert the ASN.1 Object Identifier string to the CAPI AlgId.<br>//<br>// Returns 0 if there isn't an AlgId corresponding to the ObjId.<br>//--------------------------------------------------------------------------<br>function CertOIDToAlgId(pszObjId :LPCSTR)WORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Find an extension identified by its Object Identifier.<br>//<br>// If found, returns pointer to the extension. Otherwise, returns NULL.<br>//--------------------------------------------------------------------------<br>function CertFindExtension(pszObjId :LPCSTR;<br> cExtensions WORD;<br> rgExtensions :array of CERT_EXTENSION)CERT_EXTENSION ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Find the first attribute identified by its Object Identifier.<br>//<br>// If found, returns pointer to the attribute. Otherwise, returns NULL.<br>//--------------------------------------------------------------------------<br>function CertFindAttribute(pszObjId :LPCSTR;<br> cAttr WORD;<br> rgAttr :array of CRYPT_ATTRIBUTE)CRYPT_ATTRIBUTE ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Find the first CERT_RDN attribute identified by its Object Identifier in<br>// the name's list of Relative Distinguished Names.<br>//<br>// If found, returns pointer to the attribute. Otherwise, returns NULL.<br>//--------------------------------------------------------------------------<br>function CertFindRDNAttr(pszObjId :LPCSTR;<br> pName CERT_NAME_INFO )CERT_RDN_ATTR ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Get the intended key usage bytes from the certificate.<br>//<br>// If the certificate doesn't have any intended key usage bytes, returns FALSE<br>// and *pbKeyUsage is zeroed. Otherwise, returns TRUE and up through<br>// cbKeyUsage bytes are copied into *pbKeyUsage. Any remaining uncopied<br>// bytes are zeroed.<br>//--------------------------------------------------------------------------<br>function CertGetIntendedKeyUsage(dwCertEncodingType WORD;<br> pCertInfo CERT_INFO;<br> pbKeyUsage BYTE;<br> cbKeyUsage WORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Export the public key info associated with the provider's corresponding<br>// private key.<br>//<br>// Calls CryptExportPublicKeyInfo with pszPublicKeyObjId = szOID_RSA_RSA,<br>// dwFlags = 0 and pvAuxInfo = NULL.<br>//--------------------------------------------------------------------------<br>function CryptExportPublicKeyInfo(hCryptProv :HCRYPTPROV;<br> dwKeySpec WORD;<br> dwCertEncodingType WORD;<br> pInfo CERT_PUBLIC_KEY_INFO;<br> pcbInfo DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Export the public key info associated with the provider's corresponding<br>// private key.<br>//<br>// Uses the dwCertEncodingType and pszPublicKeyObjId to call the<br>// installable CRYPT_OID_EXPORT_PUBLIC_KEY_INFO_FUNC. The called function<br>// has the same signature as CryptExportPublicKeyInfoEx.<br>//<br>// If unable to find an installable OID function for the pszPublicKeyObjId,<br>// attempts to export as a RSA Public Key (szOID_RSA_RSA).<br>//<br>// The dwFlags and pvAuxInfo aren't used for szOID_RSA_RSA.<br>//--------------------------------------------------------------------------<br>const CRYPT_OID_EXPORT_PUBLIC_KEY_INFO_FUNC = 'CryptDllExportPublicKeyInfoEx';<br><br>function CryptExportPublicKeyInfoEx(hCryptProv :HCRYPTPROV;<br> dwKeySpec WORD;<br> dwCertEncodingType WORD;<br> pszPublicKeyObjId :LPSTR;<br> dwFlags WORD;<br> pvAuxInfo VOID;<br> pInfo CERT_PUBLIC_KEY_INFO;<br> pcbInfo DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Convert and import the public key info into the provider and return a<br>// handle to the public key.<br>//<br>// Calls CryptImportPublicKeyInfoEx with aiKeyAlg = 0, dwFlags = 0 and<br>// pvAuxInfo = NULL.<br>//--------------------------------------------------------------------------<br>function CryptImportPublicKeyInfo(hCryptProv :HCRYPTPROV;<br> dwCertEncodingType WORD;<br> pInfo CERT_PUBLIC_KEY_INFO;<br> phKey HCRYPTKEY):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Convert and import the public key info into the provider and return a<br>// handle to the public key.<br>//<br>// Uses the dwCertEncodingType and pInfo->Algorithm.pszObjId to call the<br>// installable CRYPT_OID_IMPORT_PUBLIC_KEY_INFO_FUNC. The called function<br>// has the same signature as CryptImportPublicKeyInfoEx.<br>//<br>// If unable to find an installable OID function for the pszObjId,<br>// attempts to import as a RSA Public Key (szOID_RSA_RSA).<br>//<br>// For szOID_RSA_RSA: aiKeyAlg may be set to CALG_RSA_SIGN or CALG_RSA_KEYX.<br>// Defaults to CALG_RSA_KEYX. The dwFlags and pvAuxInfo aren't used.<br>//--------------------------------------------------------------------------<br>const CRYPT_OID_IMPORT_PUBLIC_KEY_INFO_FUNC = 'CryptDllImportPublicKeyInfoEx';<br><br>function CryptImportPublicKeyInfoEx(hCryptProv :HCRYPTPROV;<br> dwCertEncodingType WORD;<br> pInfo CERT_PUBLIC_KEY_INFO;<br> aiKeyAlg :ALG_ID;<br> dwFlags WORD;<br> pvAuxInfo VOID;<br> phKey HCRYPTKEY<br>  :BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Compute the hash of the encoded public key info.<br>//<br>// The public key info is encoded and then hashed.<br>//--------------------------------------------------------------------------<br>function CryptHashPublicKeyInfo(hCryptProv :HCRYPTPROV;<br> Algid :ALG_ID;<br> dwFlags WORD;<br> dwCertEncodingType WORD;<br> pInfo CERT_PUBLIC_KEY_INFO;<br> pbComputedHash BYTE;<br> pcbComputedHash DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Convert a Name Value to a null terminated char string<br>//<br>// Returns the number of characters converted including the terminating null<br>// character. If psz is NULL or csz is 0, returns the required size of the<br>// destination string (including the terminating null char).<br>//<br>// If psz != NULL && csz != 0, returned psz is always NULL terminated.<br>//<br>// Note: csz includes the NULL char.<br>//--------------------------------------------------------------------------<br>function CertRDNValueToStrA(dwValueType WORD;<br> pValue CERT_RDN_VALUE_BLOB;<br> psz :LPSTR; //OPTIONAL<br> csz WORD)WORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Convert a Name Value to a null terminated char string<br>//<br>// Returns the number of characters converted including the terminating null<br>// character. If psz is NULL or csz is 0, returns the required size of the<br>// destination string (including the terminating null char).<br>//<br>// If psz != NULL && csz != 0, returned psz is always NULL terminated.<br>//<br>// Note: csz includes the NULL char.<br>//--------------------------------------------------------------------------<br>function CertRDNValueToStrW(dwValueType WORD;<br> pValue CERT_RDN_VALUE_BLOB;<br> psz :LPWSTR; //OPTIONAL<br> csz WORD)WORD ; stdcall;<br><br>function CertRDNValueToStr(dwValueType WORD;<br> pValue CERT_RDN_VALUE_BLOB;<br> psz :LPAWSTR; //OPTIONAL<br> csz WORD)WORD ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Convert the certificate name blob to a null terminated char string.<br>//<br>// Follows the string representation of distinguished names specified in<br>// RFC 1779. (Note, added double quoting "" for embedded quotes, quote<br>// empty strings and don't quote strings containing consecutive spaces).<br>// RDN values of type CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING are<br>// formatted in hexadecimal (e.g. #0A56CF).<br>//<br>// The name string is formatted according to the dwStrType:<br>// CERT_SIMPLE_NAME_STR<br>// The object identifiers are discarded. CERT_RDN entries are separated<br>// by ", ". Multiple attributes per CERT_RDN are separated by " + ".<br>// For example:<br>// Microsoft, Joe Cool + Programmer<br>// CERT_OID_NAME_STR<br>// The object identifiers are included with a "=" separator from their<br>// attribute value. CERT_RDN entries are separated by ", ".<br>// Multiple attributes per CERT_RDN are separated by " + ". For example:<br>// 2.5.4.11=Microsoft, 2.5.4.3=Joe Cool + 2.5.4.12=Programmer<br>// CERT_X500_NAME_STR<br>// The object identifiers are converted to their X500 key name. Otherwise,<br>// same as CERT_OID_NAME_STR. If the object identifier doesn't have<br>// a corresponding X500 key name, then, the object identifier is used with<br>// a "OID." prefix. For example:<br>// OU=Microsoft, CN=Joe Cool + T=Programmer, OID.1.2.3.4.5.6=Unknown<br>//<br>// We quote the RDN value if it contains leading or trailing whitespace<br>// or one of the following characters: ",", "+", "=", """, "/n", "<", ">",<br>// "#" or ";". The quoting character is ". If the the RDN Value contains<br>// a " it is double quoted ("". For example:<br>// OU=" Microsoft", CN="Joe ""Cool""" + T="Programmer, Manager"<br>//<br>// CERT_NAME_STR_SEMICOLON_FLAG can be or'ed into dwStrType to replace<br>// the ", " separator with a "; " separator.<br>//<br>// CERT_NAME_STR_CRLF_FLAG can be or'ed into dwStrType to replace<br>// the ", " separator with a "/r/n" separator.<br>//<br>// CERT_NAME_STR_NO_PLUS_FLAG can be or'ed into dwStrType to replace the<br>// " + " separator with a single space, " ".<br>//<br>// CERT_NAME_STR_NO_QUOTING_FLAG can be or'ed into dwStrType to inhibit<br>// the above quoting.<br>//<br>// Returns the number of characters converted including the terminating null<br>// character. If psz is NULL or csz is 0, returns the required size of the<br>// destination string (including the terminating null char).<br>//<br>// If psz != NULL && csz != 0, returned psz is always NULL terminated.<br>//<br>// Note: csz includes the NULL char.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>//--------------------------------------------------------------------------<br>function CertNameToStrA(dwCertEncodingType WORD;<br> pName CERT_NAME_BLOB;<br> dwStrType WORD;<br> psz :LPSTR; //OPTIONAL<br> csz WORD)WORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>//--------------------------------------------------------------------------<br>function CertNameToStrW(dwCertEncodingType WORD;<br> pName CERT_NAME_BLOB;<br> dwStrType WORD;<br> psz :LPWSTR; //OPTIONAL<br> csz WORD)WORD ; stdcall;<br><br>function CertNameToStr(dwCertEncodingType WORD;<br> pName CERT_NAME_BLOB;<br> dwStrType WORD;<br> psz :LPAWSTR; //OPTIONAL<br> csz WORD)WORD ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// Certificate name string types<br>//--------------------------------------------------------------------------<br>const CERT_SIMPLE_NAME_STR = 1;<br>const CERT_OID_NAME_STR = 2;<br>const CERT_X500_NAME_STR = 3;<br><br>//+-------------------------------------------------------------------------<br>// Certificate name string type flags OR'ed with the above types<br>//--------------------------------------------------------------------------<br>const CERT_NAME_STR_SEMICOLON_FLAG = $40000000;<br>const CERT_NAME_STR_NO_PLUS_FLAG = $20000000;<br>const CERT_NAME_STR_NO_QUOTING_FLAG = $10000000;<br>const CERT_NAME_STR_CRLF_FLAG = $08000000;<br>const CERT_NAME_STR_COMMA_FLAG = $04000000;<br><br><br>//+-------------------------------------------------------------------------<br>// Convert the null terminated X500 string to an encoded certificate name.<br>//<br>// The input string is expected to be formatted the same as the output<br>// from the above CertNameToStr API.<br>//<br>// The CERT_SIMPLE_NAME_STR type isn't supported. Otherwise, when dwStrType<br>// is set to 0, CERT_OID_NAME_STR or CERT_X500_NAME_STR, allow either a<br>// case insensitive X500 key (CN=), case insensitive "OID." prefixed<br>// object identifier (OID.1.2.3.4.5.6=) or an object identifier (1.2.3.4=).<br>//<br>// If no flags are OR'ed into dwStrType, then, allow "," or ";" as RDN<br>// separators and "+" as the multiple RDN value separator. Quoting is<br>// supported. A quote may be included in a quoted value by double quoting,<br>// for example (CN="Joe ""Cool""". A value starting with a "#" is treated<br>// as ascii hex and converted to a CERT_RDN_OCTET_STRING. Embedded whitespace<br>// is skipped (1.2.3 = # AB CD 01 is the same as 1.2.3=#ABCD01).<br>//<br>// Whitespace surrounding the keys, object identifers and values is removed.<br>//<br>// CERT_NAME_STR_COMMA_FLAG can be or'ed into dwStrType to only allow the<br>// "," as the RDN separator.<br>//<br>// CERT_NAME_STR_SEMICOLON_FLAG can be or'ed into dwStrType to only allow the<br>// ";" as the RDN separator.<br>//<br>// CERT_NAME_STR_CRLF_FLAG can be or'ed into dwStrType to only allow<br>// "/r" or "/n" as the RDN separator.<br>//<br>// CERT_NAME_STR_NO_PLUS_FLAG can be or'ed into dwStrType to ignore "+"<br>// as a separator and not allow multiple values per RDN.<br>//<br>// CERT_NAME_STR_NO_QUOTING_FLAG can be or'ed into dwStrType to inhibit<br>// quoting.<br>//<br>// Support the following X500 Keys:<br>//<br>// Key Object Identifier RDN Value Type(s)<br>// --- ----------------- -----------------<br>// CN szOID_COMMON_NAME Printable, T61<br>// L szOID_LOCALITY_NAME Printable, T61<br>// O szOID_ORGANIZATION_NAME Printable, T61<br>// OU szOID_ORGANIZATIONAL_UNIT_NAME Printable, T61<br>// Email szOID_RSA_emailAddr Only IA5<br>// C szOID_COUNTRY_NAME Only Printable<br>// S szOID_STATE_OR_PROVINCE_NAME Printable, T61<br>// ST szOID_STATE_OR_PROVINCE_NAME Printable, T61<br>// STREET szOID_STREET_ADDRESS Printable, T61<br>// T szOID_TITLE Printable, T61<br>// Title szOID_TITLE Printable, T61<br>// G szOID_GIVEN_NAME Printable, T61<br>// GivenName szOID_GIVEN_NAME Printable, T61<br>// I szOID_INITIALS Printable, T61<br>// Initials szOID_INITIALS Printable, T61<br>// SN szOID_SUR_NAME Printable, T61<br>// DC szOID_DOMAIN_COMPONENT Only IA5<br>//<br>// The T61 types are UTF-8 encoded.<br>//<br>// Returns TRUE if successfully parsed the input string and encoded<br>// the name.<br>//<br>// If the input string is detected to be invalid, *ppszError is updated<br>// to point to the beginning of the invalid character sequence. Otherwise,<br>// *ppszError is set to NULL. *ppszError is updated with a non-NULL pointer<br>// for the following errors:<br>// CRYPT_E_INVALID_X500_STRING<br>// CRYPT_E_INVALID_NUMERIC_STRING<br>// CRYPT_E_INVALID_PRINTABLE_STRING<br>// CRYPT_E_INVALID_IA5_STRING<br>//<br>// ppszError can be set to NULL if not interested in getting a pointer<br>// to the invalid character sequence.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>//--------------------------------------------------------------------------<br>function CertStrToNameA(dwCertEncodingType WORD;<br> pszX500 :LPCSTR;<br> dwStrType WORD;<br> pvReserved VOID;<br> pbEncoded BYTE;<br> pcbEncoded DWORD;<br> var ppszError :array of LPCSTR):BOOL ; stdcall; {--max-- iniziato qui}<br>//+-------------------------------------------------------------------------<br>//--------------------------------------------------------------------------<br>function CertStrToNameW(dwCertEncodingType WORD;<br> pszX500 :LPCWSTR;<br> dwStrType WORD;<br> pvReserved VOID;<br> pbEncoded BYTE;<br> pcbEncoded DWORD;<br> var ppszError :array of LPWSTR):BOOL ; stdcall;<br><br>function CertStrToName(dwCertEncodingType WORD;<br> pszX500 :LPAWSTR;<br> dwStrType WORD;<br> pvReserved VOID;<br> pbEncoded BYTE;<br> pcbEncoded DWORD;<br> var ppszError :array of LPAWSTR):BOOL ; stdcall;<br><br>//+=========================================================================<br>// Simplified Cryptographic Message Data Structures and APIs<br>//==========================================================================<br><br><br>//+-------------------------------------------------------------------------<br>// Conventions for the *pb and *pcb output parameters:<br>//<br>// Upon entry to the function:<br>// if pcb is OPTIONAL && pcb == NULL, then,<br>// No output is returned<br>// else if pb == NULL && pcb != NULL, then,<br>// Length only determination. No length error is<br>// returned.<br>// otherwise where (pb != NULL && pcb != NULL && *pcb != 0)<br>// Output is returned. If *pcb isn't big enough a<br>// length error is returned. In all cases *pcb is updated<br>// with the actual length needed/returned.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// Type definitions of the parameters used for doing the cryptographic<br>// operations.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// Callback to get and verify the signer's certificate.<br>//<br>// Passed the CertId of the signer (its Issuer and SerialNumber) and a<br>// handle to its cryptographic signed message's cert store.<br>//<br>// For CRYPT_E_NO_SIGNER, called with pSignerId == NULL.<br>//<br>// For a valid signer certificate, returns a pointer to a read only<br>// CERT_CONTEXT. The returned CERT_CONTEXT is either obtained from a<br>// cert store or was created via CertCreateCertificateContext. For either case,<br>// its freed via CertFreeCertificateContext.<br>//<br>// If a valid certificate isn't found, this callback returns NULL with<br>// LastError set via SetLastError().<br>//<br>// The NULL implementation tries to get the Signer certificate from the<br>// message cert store. It doesn't verify the certificate.<br>//--------------------------------------------------------------------------<br><br>type<br> PFN_CRYPT_GET_SIGNER_CERTIFICATE = function (pvGetArg VOID;<br> dwCertEncodingType WORD;<br> pSignerId CERT_INFO; // Only the Issuer and SerialNumber<br> hMsgCertStore :HCERTSTORE // fields have been updated<br> )CCERT_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// The CRYPT_SIGN_MESSAGE_PARA are used for signing messages using the<br>// specified signing certificate contexts. (Note, allows multiple signers.)<br>//<br>// Either the CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_PROV_INFO_PROP_ID must<br>// be set for each rgpSigningCert[]. Either one specifies the private<br>// signature key to use.<br>//<br>// If any certificates and/or CRLs are to be included in the signed message,<br>// then, the MsgCert and MsgCrl parameters need to be updated. If the<br>// rgpSigningCerts are to be included, then, they must also be in the<br>// rgpMsgCert array.<br>//<br>// cbSize must be set to the sizeof(CRYPT_SIGN_MESSAGE_PARA) or else<br>// LastError will be updated with E_INVALIDARG.<br>//<br>// pvHashAuxInfo currently isn't used and must be set to NULL.<br>//<br>// dwFlags normally is set to 0. However, if the encoded output<br>// is to be a CMSG_SIGNED inner content of an outer cryptographic message,<br>// such as a CMSG_ENVELOPED, then, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG<br>// should be set. If not set, then it would be encoded as an inner content<br>// type of CMSG_DATA.<br>//<br>// dwInnerContentType is normally set to 0. It needs to be set if the<br>// ToBeSigned input is the encoded output of another cryptographic<br>// message, such as, an CMSG_ENVELOPED. When set, it's one of the cryptographic<br>// message types, for example, CMSG_ENVELOPED.<br>//<br>// If the inner content of a nested cryptographic message is data (CMSG_DATA<br>// the default), then, neither dwFlags or dwInnerContentType need to be set.<br>//--------------------------------------------------------------------------<br><br>type<br> PCRYPT_SIGN_MESSAGE_PARA = ^CRYPT_SIGN_MESSAGE_PARA;<br> CRYPT_SIGN_MESSAGE_PARA = record<br> cbSize WORD;<br> dwMsgEncodingType WORD;<br> pSigningCert CCERT_CONTEXT;<br> HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> pvHashAuxInfo VOID;<br> cMsgCert WORD;<br> rgpMsgCert PCCERT_CONTEXT;// pointer to array of PCCERT_CONTEXT<br> cMsgCrl WORD;<br> rgpMsgCrl PCCRL_CONTEXT; // pointer to array of PCCERT_CO<br> cAuthAttr WORD;<br> rgAuthAttr CRYPT_ATTRIBUTE;<br> cUnauthAttr WORD;<br> rgUnauthAttr CRYPT_ATTRIBUTE;<br> dwFlags WORD;<br> dwInnerContentType WORD;<br> end;<br>const CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG = $1;<br><br>//+-------------------------------------------------------------------------<br>// The CRYPT_VERIFY_MESSAGE_PARA are used to verify signed messages.<br>//<br>// hCryptProv is used to do hashing and signature verification.<br>//<br>// The dwCertEncodingType specifies the encoding type of the certificates<br>// and/or CRLs in the message.<br>//<br>// pfnGetSignerCertificate is called to get and verify the message signer's<br>// certificate.<br>//<br>// cbSize must be set to the sizeof(CRYPT_VERIFY_MESSAGE_PARA) or else<br>// LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> PCRYPT_VERIFY_MESSAGE_PARA = ^CRYPT_VERIFY_MESSAGE_PARA;<br> CRYPT_VERIFY_MESSAGE_PARA = record<br> cbSize WORD;<br> dwMsgAndCertEncodingType WORD;<br> hCryptProv :HCRYPTPROV;<br> pfnGetSignerCertificate FN_CRYPT_GET_SIGNER_CERTIFICATE;<br> pvGetArg VOID;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// The CRYPT_ENCRYPT_MESSAGE_PARA are used for encrypting messages.<br>//<br>// hCryptProv is used to do content encryption, recipient key<br>// encryption, and recipient key export. Its private key<br>// isn't used.<br>//<br>// pvEncryptionAuxInfo currently isn't used and must be set to NULL.<br>//<br>// cbSize must be set to the sizeof(CRYPT_ENCRYPT_MESSAGE_PARA) or else<br>// LastError will be updated with E_INVALIDARG.<br>//<br>// dwFlags normally is set to 0. However, if the encoded output<br>// is to be a CMSG_ENVELOPED inner content of an outer cryptographic message,<br>// such as a CMSG_SIGNED, then, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG<br>// should be set. If not set, then it would be encoded as an inner content<br>// type of CMSG_DATA.<br>//<br>// dwInnerContentType is normally set to 0. It needs to be set if the<br>// ToBeEncrypted input is the encoded output of another cryptographic<br>// message, such as, an CMSG_SIGNED. When set, it's one of the cryptographic<br>// message types, for example, CMSG_SIGNED.<br>//<br>// If the inner content of a nested cryptographic message is data (CMSG_DATA<br>// the default), then, neither dwFlags or dwInnerContentType need to be set.<br>//--------------------------------------------------------------------------<br>type<br> PCRYPT_ENCRYPT_MESSAGE_PARA = ^CRYPT_ENCRYPT_MESSAGE_PARA;<br> CRYPT_ENCRYPT_MESSAGE_PARA = record<br> cbSize WORD;<br> dwMsgEncodingType WORD;<br> hCryptProv :HCRYPTPROV;<br> ContentEncryptionAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> pvEncryptionAuxInfo VOID;<br> dwFlags WORD;<br> dwInnerContentType WORD;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// The CRYPT_DECRYPT_MESSAGE_PARA are used for decrypting messages.<br>//<br>// The CertContext to use for decrypting a message is obtained from one<br>// of the specified cert stores. An encrypted message can have one or<br>// more recipients. The recipients are identified by their CertId (Issuer<br>// and SerialNumber). The cert stores are searched to find the CertContext<br>// corresponding to the CertId.<br>//<br>// Only CertContexts in the store with either<br>// the CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_PROV_INFO_PROP_ID set<br>// can be used. Either property specifies the private exchange key to use.<br>//<br>// cbSize must be set to the sizeof(CRYPT_DECRYPT_MESSAGE_PARA) or else<br>// LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> PCRYPT_DECRYPT_MESSAGE_PARA = ^CRYPT_DECRYPT_MESSAGE_PARA;<br> CRYPT_DECRYPT_MESSAGE_PARA = record<br> cbSize WORD;<br> dwMsgAndCertEncodingType WORD;<br> cCertStore WORD;<br> rghCertStore HCERTSTORE;<br> end;<br>//+-------------------------------------------------------------------------<br>// The CRYPT_HASH_MESSAGE_PARA are used for hashing or unhashing<br>// messages.<br>//<br>// hCryptProv is used to compute the hash.<br>//<br>// pvHashAuxInfo currently isn't used and must be set to NULL.<br>//<br>// cbSize must be set to the sizeof(CRYPT_HASH_MESSAGE_PARA) or else<br>// LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> PCRYPT_HASH_MESSAGE_PARA = ^CRYPT_HASH_MESSAGE_PARA;<br> CRYPT_HASH_MESSAGE_PARA = record<br> cbSize WORD;<br> dwMsgEncodingType WORD;<br> hCryptProv :HCRYPTPROV;<br> HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> pvHashAuxInfo VOID;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// The CRYPT_KEY_SIGN_MESSAGE_PARA are used for signing messages until a<br>// certificate has been created for the signature key.<br>//<br>// pvHashAuxInfo currently isn't used and must be set to NULL.<br>//<br>// If PubKeyAlgorithm isn't set, defaults to szOID_RSA_RSA.<br>//<br>// cbSize must be set to the sizeof(CRYPT_KEY_SIGN_MESSAGE_PARA) or else<br>// LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> PCRYPT_KEY_SIGN_MESSAGE_PARA = ^CRYPT_KEY_SIGN_MESSAGE_PARA;<br> CRYPT_KEY_SIGN_MESSAGE_PARA = record<br> cbSize WORD;<br> dwMsgAndCertEncodingType WORD;<br> hCryptProv :HCRYPTPROV;<br> dwKeySpec WORD;<br> HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> pvHashAuxInfo VOID;<br> PubKeyAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// The CRYPT_KEY_VERIFY_MESSAGE_PARA are used to verify signed messages without<br>// a certificate for the signer.<br>//<br>// Normally used until a certificate has been created for the key.<br>//<br>// hCryptProv is used to do hashing and signature verification.<br>//<br>// cbSize must be set to the sizeof(CRYPT_KEY_VERIFY_MESSAGE_PARA) or else<br>// LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> PCRYPT_KEY_VERIFY_MESSAGE_PARA = ^CRYPT_KEY_VERIFY_MESSAGE_PARA;<br> CRYPT_KEY_VERIFY_MESSAGE_PARA = record<br> cbSize WORD;<br> dwMsgEncodingType WORD;<br> hCryptProv :HCRYPTPROV;<br> end;<br><br>//+-------------------------------------------------------------------------<br>// Sign the message.<br>//<br>// If fDetachedSignature is TRUE, the "to be signed" content isn't included<br>// in the encoded signed blob.<br>//--------------------------------------------------------------------------<br>function CryptSignMessage(pSignPara CRYPT_SIGN_MESSAGE_PARA;<br> fDetachedSignature :BOOL;<br> cToBeSigned WORD;<br> const rgpbToBeSigned :array of PBYTE;<br> rgcbToBeSigned :array of DWORD;<br> pbSignedBlob BYTE;<br> pcbSignedBlob DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Verify a signed message.<br>//<br>// If pbDecoded == NULL, then, *pcbDecoded is implicitly set to 0 on input.<br>// For *pcbDecoded == 0 && ppSignerCert == NULL on input, the signer isn't<br>// verified.<br>//<br>// A message might have more than one signer. Set dwSignerIndex to iterate<br>// through all the signers. dwSignerIndex == 0 selects the first signer.<br>//<br>// pVerifyPara's pfnGetSignerCertificate is called to get the signer's<br>// certificate.<br>//<br>// For a verified signer and message, *ppSignerCert is updated<br>// with the CertContext of the signer. It must be freed by calling<br>// CertFreeCertificateContext. Otherwise, *ppSignerCert is set to NULL.<br>//<br>// ppSignerCert can be NULL, indicating the caller isn't interested<br>// in getting the CertContext of the signer.<br>//<br>// pcbDecoded can be NULL, indicating the caller isn't interested in getting<br>// the decoded content. Furthermore, if the message doesn't contain any<br>// content or signers, then, pcbDecoded must be set to NULL, to allow the<br>// pVerifyPara->pfnGetCertificate to be called. Normally, this would be<br>// the case when the signed message contains only certficates and CRLs.<br>// If pcbDecoded is NULL and the message doesn't have the indicated signer,<br>// pfnGetCertificate is called with pSignerId set to NULL.<br>//<br>// If the message doesn't contain any signers || dwSignerIndex > message's<br>// SignerCount, then, an error is returned with LastError set to<br>// CRYPT_E_NO_SIGNER. Also, for CRYPT_E_NO_SIGNER, pfnGetSignerCertificate<br>// is still called with pSignerId set to NULL.<br>//<br>// Note, an alternative way to get the certificates and CRLs from a<br>// signed message is to call CryptGetMessageCertificates.<br>//--------------------------------------------------------------------------<br>function CryptVerifyMessageSignature(pVerifyPara CRYPT_VERIFY_MESSAGE_PARA;<br> dwSignerIndex WORD;<br> const pbSignedBlob BYTE;<br> cbSignedBlob WORD;<br> pbDecoded BYTE;<br> pcbDecoded WORD;<br> ppSignerCert CCERT_CONTEXT<br> ):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Returns the count of signers in the signed message. For no signers, returns<br>// 0. For an error returns -1 with LastError updated accordingly.<br>//--------------------------------------------------------------------------<br>function CryptGetMessageSignerCount(dwMsgEncodingType WORD;<br> const pbSignedBlob BYTE;<br> cbSignedBlob WORD):LONG ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Returns the cert store containing the message's certs and CRLs.<br>// For an error, returns NULL with LastError updated.<br>//--------------------------------------------------------------------------<br>function CryptGetMessageCertificates(dwMsgAndCertEncodingType WORD;<br> hCryptProv :HCRYPTPROV; // passed to CertOpenStore<br> dwFlags WORD; // passed to CertOpenStore<br> const pbSignedBlob BYTE;<br> cbSignedBlob WORD):HCERTSTORE ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Verify a signed message containing detached signature(s).<br>// The "to be signed" content is passed in separately. No<br>// decoded output. Otherwise, identical to CryptVerifyMessageSignature.<br>//--------------------------------------------------------------------------<br>function CryptVerifyDetachedMessageSignature(pVerifyPara CRYPT_VERIFY_MESSAGE_PARA;<br> dwSignerIndex WORD;<br> const pbDetachedSignBlob BYTE;<br> cbDetachedSignBlob WORD;<br> cToBeSigned WORD;<br> const rgpbToBeSigned :array of PBYTE;<br> rgcbToBeSigned :array of DWORD;<br> ppSignerCert PCCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Encrypts the message for the recipient(s).<br>//--------------------------------------------------------------------------<br>function CryptEncryptMessage(pEncryptPara CRYPT_ENCRYPT_MESSAGE_PARA;<br> cRecipientCert WORD;<br> rgpRecipientCert :array of PCCERT_CONTEXT;<br> const pbToBeEncrypted BYTE;<br> cbToBeEncrypted WORD;<br> pbEncryptedBlob BYTE;<br> pcbEncryptedBlob DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Decrypts the message.<br>//<br>// If pbDecrypted == NULL, then, *pcbDecrypted is implicitly set to 0 on input.<br>// For *pcbDecrypted == 0 && ppXchgCert == NULL on input, the message isn't<br>// decrypted.<br>//<br>// For a successfully decrypted message, *ppXchgCert is updated<br>// with the CertContext used to decrypt. It must be freed by calling<br>// CertStoreFreeCert. Otherwise, *ppXchgCert is set to NULL.<br>//<br>// ppXchgCert can be NULL, indicating the caller isn't interested<br>// in getting the CertContext used to decrypt.<br>//--------------------------------------------------------------------------<br>function CryptDecryptMessage(pDecryptPara CRYPT_DECRYPT_MESSAGE_PARA;<br> const pbEncryptedBlob BYTE;<br> cbEncryptedBlob WORD;<br> pbDecrypted BYTE;<br> pcbDecrypted DWORD;<br> ppXchgCert PCCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Sign the message and encrypt for the recipient(s). Does a CryptSignMessage<br>// followed with a CryptEncryptMessage.<br>//<br>// Note: this isn't the CMSG_SIGNED_AND_ENVELOPED. Its a CMSG_SIGNED<br>// inside of an CMSG_ENVELOPED.<br>//--------------------------------------------------------------------------<br>function CryptSignAndEncryptMessage(pSignPara CRYPT_SIGN_MESSAGE_PARA;<br> pEncryptPara CRYPT_ENCRYPT_MESSAGE_PARA;<br> cRecipientCert WORD;<br> rgpRecipientCert :array of PCCERT_CONTEXT;<br> const pbToBeSignedAndEncrypted BYTE;<br> cbToBeSignedAndEncrypted WORD;<br> pbSignedAndEncryptedBlob BYTE;<br> pcbSignedAndEncryptedBlob DWORD<br>  :BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Decrypts the message and verifies the signer. Does a CryptDecryptMessage<br>// followed with a CryptVerifyMessageSignature.<br>//<br>// If pbDecrypted == NULL, then, *pcbDecrypted is implicitly set to 0 on input.<br>// For *pcbDecrypted == 0 && ppSignerCert == NULL on input, the signer isn't<br>// verified.<br>//<br>// A message might have more than one signer. Set dwSignerIndex to iterate<br>// through all the signers. dwSignerIndex == 0 selects the first signer.<br>//<br>// The pVerifyPara's VerifySignerPolicy is called to verify the signer's<br>// certificate.<br>//<br>// For a successfully decrypted and verified message, *ppXchgCert and<br>// *ppSignerCert are updated. They must be freed by calling<br>// CertStoreFreeCert. Otherwise, they are set to NULL.<br>//<br>// ppXchgCert and/or ppSignerCert can be NULL, indicating the<br>// caller isn't interested in getting the CertContext.<br>//<br>// Note: this isn't the CMSG_SIGNED_AND_ENVELOPED. Its a CMSG_SIGNED<br>// inside of an CMSG_ENVELOPED.<br>//<br>// The message always needs to be decrypted to allow access to the<br>// signed message. Therefore, if ppXchgCert != NULL, its always updated.<br>//--------------------------------------------------------------------------<br>function CryptDecryptAndVerifyMessageSignature(pDecryptPara CRYPT_DECRYPT_MESSAGE_PARA;<br> pVerifyPara CRYPT_VERIFY_MESSAGE_PARA;<br> dwSignerIndex WORD;<br> const pbEncryptedBlob BYTE;<br> cbEncryptedBlob WORD;<br> pbDecrypted BYTE;<br> pcbDecrypted DWORD;<br> var ppXchgCert :array of PCCERT_CONTEXT;<br> var ppSignerCert :array of PCCERT_CONTEXT<br> ):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Decodes a cryptographic message which may be one of the following types:<br>// CMSG_DATA<br>// CMSG_SIGNED<br>// CMSG_ENVELOPED<br>// CMSG_SIGNED_AND_ENVELOPED<br>// CMSG_HASHED<br>//<br>// dwMsgTypeFlags specifies the set of allowable messages. For example, to<br>// decode either SIGNED or ENVELOPED messages, set dwMsgTypeFlags to:<br>// CMSG_SIGNED_FLAG | CMSG_ENVELOPED_FLAG.<br>//<br>// dwProvInnerContentType is only applicable when processing nested<br>// crytographic messages. When processing an outer crytographic message<br>// it must be set to 0. When decoding a nested cryptographic message<br>// its the dwInnerContentType returned by a previous CryptDecodeMessage<br>// of the outer message. The InnerContentType can be any of the CMSG types,<br>// for example, CMSG_DATA, CMSG_SIGNED, ...<br>//<br>// The optional *pdwMsgType is updated with the type of message.<br>//<br>// The optional *pdwInnerContentType is updated with the type of the inner<br>// message. Unless there is cryptographic message nesting, CMSG_DATA<br>// is returned.<br>//<br>// For CMSG_DATA: returns decoded content.<br>// For CMSG_SIGNED: same as CryptVerifyMessageSignature.<br>// For CMSG_ENVELOPED: same as CryptDecryptMessage.<br>// For CMSG_SIGNED_AND_ENVELOPED: same as CryptDecryptMessage plus<br>// CryptVerifyMessageSignature.<br>// For CMSG_HASHED: verifies the hash and returns decoded content.<br>//--------------------------------------------------------------------------<br>function CryptDecodeMessage(dwMsgTypeFlags WORD;<br> pDecryptPara CRYPT_DECRYPT_MESSAGE_PARA;<br> pVerifyPara CRYPT_VERIFY_MESSAGE_PARA ;<br> dwSignerIndex WORD;<br> const pbEncodedBlob BYTE;<br> cbEncodedBlob WORD;<br> dwPrevInnerContentType WORD;<br> pdwMsgType DWORD;<br> pdwInnerContentType DWORD;<br> pbDecoded BYTE;<br> pcbDecoded DWORD;<br> var ppXchgCert :array of PCCERT_CONTEXT;<br> var ppSignerCert :array of PCCERT_CONTEXT<br>  :BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Hash the message.<br>//<br>// If fDetachedHash is TRUE, only the ComputedHash is encoded in the<br>// pbHashedBlob. Otherwise, both the ToBeHashed and ComputedHash<br>// are encoded.<br>//<br>// pcbHashedBlob or pcbComputedHash can be NULL, indicating the caller<br>// isn't interested in getting the output.<br>//--------------------------------------------------------------------------<br>function CryptHashMessage(pHashPara CRYPT_HASH_MESSAGE_PARA;<br> fDetachedHash :BOOL;<br> cToBeHashed WORD;<br> const rgpbToBeHashed :array of PBYTE;<br> rgcbToBeHashed :array of DWORD;<br> pbHashedBlob BYTE;<br> pcbHashedBlob DWORD;<br> pbComputedHash BYTE;<br> pcbComputedHash DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Verify a hashed message.<br>//<br>// pcbToBeHashed or pcbComputedHash can be NULL,<br>// indicating the caller isn't interested in getting the output.<br>//--------------------------------------------------------------------------<br>function CryptVerifyMessageHash(pHashPara CRYPT_HASH_MESSAGE_PARA;<br> pbHashedBlob BYTE;<br> cbHashedBlob WORD;<br> pbToBeHashed BYTE;<br> pcbToBeHashed DWORD;<br> pbComputedHash BYTE;<br> pcbComputedHash DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Verify a hashed message containing a detached hash.<br>// The "to be hashed" content is passed in separately. No<br>// decoded output. Otherwise, identical to CryptVerifyMessageHash.<br>//<br>// pcbComputedHash can be NULL, indicating the caller isn't interested<br>// in getting the output.<br>//--------------------------------------------------------------------------<br>function CryptVerifyDetachedMessageHash(pHashPara CRYPT_HASH_MESSAGE_PARA;<br> pbDetachedHashBlob BYTE;<br> cbDetachedHashBlob WORD;<br> cToBeHashed WORD;<br> rgpbToBeHashed :array of PBYTE;<br> rgcbToBeHashed :array of DWORD;<br> pbComputedHash BYTE;<br> pcbComputedHash DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Sign the message using the provider's private key specified in the<br>// parameters. A dummy SignerId is created and stored in the message.<br>//<br>// Normally used until a certificate has been created for the key.<br>//--------------------------------------------------------------------------<br>function CryptSignMessageWithKey(pSignPara CRYPT_KEY_SIGN_MESSAGE_PARA;<br> const pbToBeSigned BYTE;<br> cbToBeSigned WORD;<br> pbSignedBlob BYTE;<br> pcbSignedBlob DWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// Verify a signed message using the specified public key info.<br>//<br>// Normally called by a CA until it has created a certificate for the<br>// key.<br>//<br>// pPublicKeyInfo contains the public key to use to verify the signed<br>// message. If NULL, the signature isn't verified (for instance, the decoded<br>// content may contain the PublicKeyInfo).<br>//<br>// pcbDecoded can be NULL, indicating the caller isn't interested<br>// in getting the decoded content.<br>//--------------------------------------------------------------------------<br>function CryptVerifyMessageSignatureWithKey(pVerifyPara CRYPT_KEY_VERIFY_MESSAGE_PARA;<br> pPublicKeyInfo CERT_PUBLIC_KEY_INFO;<br> const pbSignedBlob BYTE;<br> cbSignedBlob WORD;<br> pbDecoded BYTE;<br> pcbDecoded DWORD):BOOL ; stdcall;<br><br>//+=========================================================================<br>// System Certificate Store Data Structures and APIs<br>//==========================================================================<br><br><br>//+-------------------------------------------------------------------------<br>// Get a system certificate store based on a subsystem protocol.<br>//<br>// Current examples of subsystems protocols are:<br>// "MY" Cert Store hold certs with associated Private Keys<br>// "CA" Certifying Authority certs<br>// "ROOT" Root Certs<br>// "SPC" Software publisher certs<br>//<br>//<br>// If hProv is NULL the default provider "1" is opened for you.<br>// When the store is closed the provider is release. Otherwise<br>// if hProv is not NULL, no provider is created or released.<br>//<br>// The returned Cert Store can be searched for an appropriate Cert<br>// using the Cert Store API's (see certstor.h)<br>//<br>// When done, the cert store should be closed using CertStoreClose<br>//--------------------------------------------------------------------------<br><br>function CertOpenSystemStoreA(hProv :HCRYPTPROV;<br> szSubsystemProtocol :LPCSTR):HCERTSTORE ; stdcall;<br><br>function CertOpenSystemStoreW(hProv :HCRYPTPROV;<br> szSubsystemProtocol :LPCWSTR):HCERTSTORE ; stdcall;<br><br>function CertOpenSystemStore(hProv :HCRYPTPROV;<br> szSubsystemProtocol :LPAWSTR):HCERTSTORE ; stdcall;<br><br>function CertAddEncodedCertificateToSystemStoreA(szCertStoreName :LPCSTR;<br> const pbCertEncoded BYTE;<br> cbCertEncoded WORD):BOOL ; stdcall;<br><br>function CertAddEncodedCertificateToSystemStoreW(szCertStoreName :LPCWSTR;<br> const pbCertEncoded BYTE;<br> cbCertEncoded WORD):BOOL ; stdcall;<br><br>function CertAddEncodedCertificateToSystemStore(szCertStoreName :LPAWSTR;<br> const pbCertEncoded BYTE;<br> cbCertEncoded WORD):BOOL ; stdcall;<br><br><br>//+-------------------------------------------------------------------------<br>// Find all certificate chains tying the given issuer name to any certificate<br>// that the current user has a private key for.<br>//<br>// If no certificate chain is found, FALSE is returned with LastError set<br>// to CRYPT_E_NOT_FOUND and the counts zeroed.<br>//<br>// IE 3.0 ASSUMPTION:<br>// The client certificates are in the "My" system store. The issuer<br>// cerificates may be in the "Root", "CA" or "My" system stores.<br>//--------------------------------------------------------------------------<br>type<br> PCERT_CHAIN = ^CERT_CHAIN;<br> CERT_CHAIN = record<br> cCerts WORD; // number of certs in chain<br> certs CERT_BLOB; // pointer to array of cert chain blobs representing the certs<br> keyLocatorInfo :CRYPT_KEY_PROV_INFO; // key locator for cert<br> end;<br><br><br>// WINCRYPT32API This is not exported by crypt32, it is exported by softpub<br>function FindCertsByIssuer(pCertChains CERT_CHAIN;<br> pcbCertChains DWORD;<br> pcCertChains DWORD; // count of certificates chains returned<br> pbEncodedIssuerName BYTE; // DER encoded issuer name<br> cbEncodedIssuerName WORD; // count in bytes of encoded issuer name<br> pwszPurpose :LPCWSTR; // "ClientAuth" or "CodeSigning"<br> dwKeySpec WORD // only return signers supporting this keyspec<br> ):HRESULT ; stdcall;<br><br>//////////////////////////// VERSION 2 ////////////////////////////////////////////////////////////////////<br><br>implementation<br><br>{Macro inplementation}<br>function GET_ALG_CLASS(x:integer) :integer;<br>begin<br> Result:=(x and (7 shl 13));<br>end;<br><br>function GET_ALG_TYPE(x:integer) :integer;<br>begin<br> Result:=(x and (15 shl 9));<br>end;<br><br>function GET_ALG_SID(x:integer) :integer;<br>begin<br> Result:=(x and (511));<br>end;<br><br>function RCRYPT_SUCCEEDED(rt:BOOL):BOOL;<br>begin<br> Result:= rt = CRYPT_SUCCEED;<br>end;<br><br>function RCRYPT_FAILED(rt:BOOL):BOOL;<br>begin<br> Result:= rt = CRYPT_FAILED;<br>end ;<br><br>function GET_CERT_UNICODE_RDN_ERR_INDEX(X :integer):integer;<br>begin<br> Result := ((X shr CERT_UNICODE_RDN_ERR_INDEX_SHIFT) and CERT_UNICODE_RDN_ERR_INDEX_MASK);<br>end;<br><br>function GET_CERT_UNICODE_ATTR_ERR_INDEX(X :integer):integer;<br>begin<br> Result := ((X shr CERT_UNICODE_ATTR_ERR_INDEX_SHIFT) and CERT_UNICODE_ATTR_ERR_INDEX_MASK);<br>end;<br><br>function GET_CERT_UNICODE_VALUE_ERR_INDEX(X :integer):integer;<br>begin<br> Result := (X and CERT_UNICODE_VALUE_ERR_INDEX_MASK);<br>end;<br><br>function GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X WORD)WORD;<br>begin<br> Result := ((X shr CERT_ALT_NAME_ENTRY_ERR_INDEX_SHIFT) and CERT_ALT_NAME_ENTRY_ERR_INDEX_MASK);<br>end;<br><br>function GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X WORD)WORD;<br>begin<br> Result := (X and CERT_ALT_NAME_VALUE_ERR_INDEX_MASK);<br>end;<br><br>function GET_CRL_DIST_POINT_ERR_INDEX(X WORD)WORD;<br>begin<br>Result := ((X shr CRL_DIST_POINT_ERR_INDEX_SHIFT) and CRL_DIST_POINT_ERR_INDEX_MASK);<br>end;<br><br>function IS_CRL_DIST_POINT_ERR_CRL_ISSUER(X WORD):BOOL;<br>begin<br> Result := (0 <> (X and CRL_DIST_POINT_ERR_CRL_ISSUER_BIT));<br>end;<br>///////////////////////////////////////version 2 /////////////////////////<br><br>function IS_CERT_RDN_CHAR_STRING(X WORD) :BOOL;<br>begin<br> Result :=BOOL(X >= CERT_RDN_NUMERIC_STRING);<br> end;<br><br>function GET_CERT_ENCODING_TYPE(X WORD)WORD;<br>begin<br> Result := (X and CERT_ENCODING_TYPE_MASK);<br>end;<br><br>function GET_CMSG_ENCODING_TYPE(X WORD)WORD;<br>begin<br> Result := (X and CMSG_ENCODING_TYPE_MASK);<br>end;<br><br>function IS_CERT_HASH_PROP_ID( X WORD):BOOL ;<br>begin<br> if (X = CERT_SHA1_HASH_PROP_ID) or (X = CERT_MD5_HASH_PROP_ID) then<br> Result := True<br> else<br> Result := False;<br>end;<br>{end Macro}<br><br>function CryptAcquireContextA ;external ADVAPI32 name 'CryptAcquireContextA';<br>{$IFDEF UNICODE}<br>function CryptAcquireContext ;external ADVAPI32 name 'CryptAcquireContextW';<br>{$ELSE}<br>function CryptAcquireContext ;external ADVAPI32 name 'CryptAcquireContextA';<br>{$ENDIF}<br>function CryptAcquireContextW ;external ADVAPI32 name 'CryptAcquireContextW';<br>function CryptReleaseContext ;external ADVAPI32 name 'CryptReleaseContext';<br>function CryptGenKey ;external ADVAPI32 name 'CryptGenKey';<br>function CryptDeriveKey ;external ADVAPI32 name 'CryptDeriveKey';<br>function CryptDestroyKey ;external ADVAPI32 name 'CryptDestroyKey';<br>function CryptSetKeyParam ;external ADVAPI32 name 'CryptSetKeyParam';<br>function CryptGetKeyParam ;external ADVAPI32 name 'CryptGetKeyParam';<br>function CryptSetHashParam ;external ADVAPI32 name 'CryptSetHashParam';<br>function CryptGetHashParam ;external ADVAPI32 name 'CryptGetHashParam';<br>function CryptSetProvParam ;external ADVAPI32 name 'CryptSetProvParam';<br>function CryptGetProvParam ;external ADVAPI32 name 'CryptGetProvParam';<br>function CryptGenRandom ;external ADVAPI32 name 'CryptGenRandom';<br>function CryptGetUserKey ;external ADVAPI32 name 'CryptGetUserKey';<br>function CryptExportKey ;external ADVAPI32 name 'CryptExportKey';<br>function CryptImportKey ;external ADVAPI32 name 'CryptImportKey';<br>function CryptEncrypt ;external ADVAPI32 name 'CryptEncrypt';<br>function CryptDecrypt ;external ADVAPI32 name 'CryptDecrypt';<br>function CryptCreateHash ;external ADVAPI32 name 'CryptCreateHash';<br>function CryptHashData ;external ADVAPI32 name 'CryptHashData';<br>function CryptHashSessionKey ;external ADVAPI32 name 'CryptHashSessionKey';<br>function CryptDestroyHash ;external ADVAPI32 name 'CryptDestroyHash';<br>function CryptSignHashA ;external ADVAPI32 name 'CryptSignHashA';<br>function CryptSignHashW ;external ADVAPI32 name 'CryptSignHashW';<br>function CryptSignHashU ;external CRYPT32 name 'CryptSignHashU';<br>{$IFDEF UNICODE}<br>function CryptSignHash ;external ADVAPI32 name 'CryptSignHashW';<br>{$ELSE}<br>function CryptSignHash ;external ADVAPI32 name 'CryptSignHashA';<br>{$ENDIF}<br>function CryptVerifySignatureA ;external ADVAPI32 name 'CryptVerifySignatureA';<br>function CryptVerifySignatureW ;external ADVAPI32 name 'CryptVerifySignatureW';<br>{$IFDEF UNICODE}<br>function CryptVerifySignature ;external ADVAPI32 name 'CryptVerifySignatureW';<br>{$ELSE}<br>function CryptVerifySignature ;external ADVAPI32 name 'CryptVerifySignatureA';<br>{$ENDIF}<br>function CryptSetProviderW ;external ADVAPI32 name 'CryptSetProviderW';<br>function CryptSetProviderA ;external ADVAPI32 name 'CryptSetProviderA';<br>function CryptSetProviderU ;external CRYPT32 name 'CryptSetProviderU';<br>{$IFDEF UNICODE}<br>function CryptSetProvider ;external ADVAPI32 name 'CryptSetProviderW';<br>{$ELSE}<br>function CryptSetProvider ;external ADVAPI32 name 'CryptSetProviderA';<br>{$ENDIF}<br><br>{$IFDEF NT5}<br>function CryptSetProviderExA ;external ADVAPI32NT5 name 'CryptSetProviderExA';//nt5 advapi32<br>function CryptSetProviderExW ;external ADVAPI32NT5 name 'CryptSetProviderExW';<br>{$IFDEF UNICODE}<br>function CryptSetProviderEx ;external ADVAPI32NT5 name 'CryptSetProviderExW';<br>{$ELSE}<br>function CryptSetProviderEx ;external ADVAPI32NT5 name 'CryptSetProviderExA';<br>{$ENDIF} // !UNICODE<br><br>function CryptGetDefaultProviderA ; external ADVAPI32NT5 name 'CryptGetDefaultProviderA';//nt5 advapi32<br>function CryptGetDefaultProviderW ; external ADVAPI32NT5 name 'CryptGetDefaultProviderW';<br>{$IFDEF UNICODE}<br>function CryptGetDefaultProvider ; external ADVAPI32NT5 name 'CryptGetDefaultProviderW';<br>{$ELSE}<br>function CryptGetDefaultProvider; external ADVAPI32NT5 name 'CryptGetDefaultProviderA';<br>{$ENDIF} // !UNICODE<br><br>function CryptEnumProviderTypesA ; external ADVAPI32NT5 name 'CryptEnumProviderTypesA';//nt5 advapi32<br>function CryptEnumProviderTypesW ; external ADVAPI32NT5 name 'CryptEnumProviderTypesW';<br>{$IFDEF UNICODE}<br>function CryptEnumProviderTypes ; external ADVAPI32NT5 name 'CryptEnumProviderTypesW';<br>{$ELSE}<br>function CryptEnumProviderTypes ; external ADVAPI32NT5 name 'CryptEnumProviderTypesA';<br>{$ENDIF} // !UNICODE<br><br>function CryptEnumProvidersA; external ADVAPI32NT5 name 'CryptEnumProvidersA';//nt5 advapi32<br>function CryptEnumProvidersW; external ADVAPI32NT5 name 'CryptEnumProvidersW';<br><br>{$IFDEF UNICODE}<br>function CryptEnumProviders; external ADVAPI32NT5 name 'CryptEnumProvidersW';<br>{$ELSE}<br>function CryptEnumProviders; external ADVAPI32NT5 name 'CryptEnumProvidersA';<br>{$ENDIF} // !UNICODE<br>function CryptContextAddRef; external ADVAPI32NT5 name 'CryptContextAddRef';//nt5 advapi32<br>function CryptDuplicateKey; external ADVAPI32NT5 name 'CryptDuplicateKey';//nt5 advapi32<br>function CryptDuplicateHash; external ADVAPI32NT5 name 'CryptDuplicateHash';//nt5 advapi32<br>{$ENDIF NT5}<br><br>function CryptEnumProvidersU; external CRYPT32 name 'CryptEnumProvidersU';<br>function CryptFormatObject; external CRYPT32 name 'CryptFormatObject';<br>function CryptEncodeObject; external CRYPT32 name 'CryptEncodeObject';<br>function CryptDecodeObject; external CRYPT32 name 'CryptDecodeObject';<br>function CryptInstallOIDFunctionAddress; external CRYPT32 name 'CryptInstallOIDFunctionAddress';<br>function CryptInitOIDFunctionSet; external CRYPT32 name 'CryptInitOIDFunctionSet';<br>function CryptGetOIDFunctionAddress; external CRYPT32 name 'CryptGetOIDFunctionAddress';<br>function CryptGetDefaultOIDDllList; external CRYPT32 name 'CryptGetDefaultOIDDllList';<br>function CryptGetDefaultOIDFunctionAddress; external CRYPT32 name 'CryptGetDefaultOIDFunctionAddress';<br>function CryptFreeOIDFunctionAddress; external CRYPT32 name 'CryptFreeOIDFunctionAddress';<br>function CryptRegisterOIDFunction; external CRYPT32 name 'CryptRegisterOIDFunction';<br>function CryptUnregisterOIDFunction; external CRYPT32 name 'CryptUnregisterOIDFunction';<br>function CryptRegisterDefaultOIDFunction; external CRYPT32 name 'CryptRegisterDefaultOIDFunction';<br>function CryptUnregisterDefaultOIDFunction; external CRYPT32 name 'CryptUnregisterDefaultOIDFunction';<br>function CryptSetOIDFunctionValue; external CRYPT32 name 'CryptSetOIDFunctionValue';<br>function CryptGetOIDFunctionValue; external CRYPT32 name 'CryptGetOIDFunctionValue';<br>function CryptEnumOIDFunction; external CRYPT32 name 'CryptEnumOIDFunction';<br>function CryptFindOIDInfo; external CRYPT32 name 'CryptFindOIDInfo';<br><br>function CryptRegisterOIDInfo; external CRYPT32 name 'CryptRegisterOIDInfo';<br>function CryptUnregisterOIDInfo; external CRYPT32 name 'CryptUnregisterOIDInfo';<br>function CryptMsgOpenToEncode; external CRYPT32 name 'CryptMsgOpenToEncode';<br>function CryptMsgCalculateEncodedLength; external CRYPT32 name 'CryptMsgCalculateEncodedLength';<br>function CryptMsgOpenToDecode; external CRYPT32 name 'CryptMsgOpenToDecode';<br>function CryptMsgClose; external CRYPT32 name 'CryptMsgClose';<br>function CryptMsgUpdate; external CRYPT32 name 'CryptMsgUpdate';<br>function CryptMsgControl; external CRYPT32 name 'CryptMsgControl';<br>function CryptMsgVerifyCountersignatureEncoded; external CRYPT32 name 'CryptMsgVerifyCountersignatureEncoded';<br>function CryptMsgCountersign; external CRYPT32 name 'CryptMsgCountersign';<br>function CryptMsgCountersignEncoded; external CRYPT32 name 'CryptMsgCountersignEncoded';<br>function CryptMsgGetParam; external CRYPT32 name 'CryptMsgGetParam';<br>function CertOpenStore; external CRYPT32 name 'CertOpenStore';<br>function CertDuplicateStore; external CRYPT32 name 'CertDuplicateStore';<br>function CertSaveStore; external CRYPT32 name 'CertSaveStore';<br>function CertCloseStore; external CRYPT32 name 'CertCloseStore';<br>function CertGetSubjectCertificateFromStore; external CRYPT32 name 'CertGetSubjectCertificateFromStore';<br>function CertEnumCertificatesInStore; external CRYPT32 name 'CertEnumCertificatesInStore';<br>function CertFindCertificateInStore; external CRYPT32 name 'CertFindCertificateInStore';<br>function CertGetIssuerCertificateFromStore; external CRYPT32 name 'CertGetIssuerCertificateFromStore';<br>function CertVerifySubjectCertificateContext; external CRYPT32 name 'CertVerifySubjectCertificateContext';<br>function CertDuplicateCertificateContext; external CRYPT32 name 'CertDuplicateCertificateContext';<br>function CertCreateCertificateContext; external CRYPT32 name 'CertCreateCertificateContext';<br>function CertFreeCertificateContext; external CRYPT32 name 'CertFreeCertificateContext';<br>function CertSetCertificateContextProperty; external CRYPT32 name 'CertSetCertificateContextProperty';<br>function CertGetCertificateContextProperty; external CRYPT32 name 'CertGetCertificateContextProperty';<br>function CertEnumCertificateContextProperties; external CRYPT32 name 'CertEnumCertificateContextProperties';<br>function CertGetCRLFromStore; external CRYPT32 name 'CertGetCRLFromStore';<br>function CertDuplicateCRLContext; external CRYPT32 name 'CertDuplicateCRLContext';<br>function CertCreateCRLContext; external CRYPT32 name 'CertCreateCRLContext';<br>function CertFreeCRLContext; external CRYPT32 name 'CertFreeCRLContext';<br>function CertSetCRLContextProperty; external CRYPT32 name 'CertSetCRLContextProperty';<br>function CertGetCRLContextProperty; external CRYPT32 name 'CertGetCRLContextProperty';<br>function CertEnumCRLContextProperties; external CRYPT32 name 'CertEnumCRLContextProperties';<br>function CertAddEncodedCertificateToStore; external CRYPT32 name 'CertAddEncodedCertificateToStore';<br>function CertAddCertificateContextToStore; external CRYPT32 name 'CertAddCertificateContextToStore';<br>function CertAddSerializedElementToStore; external CRYPT32 name 'CertAddSerializedElementToStore';<br>function CertDeleteCertificateFromStore; external CRYPT32 name 'CertDeleteCertificateFromStore';<br>function CertAddEncodedCRLToStore; external CRYPT32 name 'CertAddEncodedCRLToStore';<br>function CertAddCRLContextToStore; external CRYPT32 name 'CertAddCRLContextToStore';<br>function CertDeleteCRLFromStore; external CRYPT32 name 'CertDeleteCRLFromStore';<br>function CertSerializeCertificateStoreElement; external CRYPT32 name 'CertSerializeCertificateStoreElement';<br>function CertSerializeCRLStoreElement; external CRYPT32 name 'CertSerializeCRLStoreElement';<br>function CertDuplicateCTLContext; external CRYPT32 name 'CertDuplicateCTLContext';<br>function CertCreateCTLContext; external CRYPT32 name 'CertCreateCTLContext';<br>function CertFreeCTLContext; external CRYPT32 name 'CertFreeCTLContext';<br>function CertSetCTLContextProperty; external CRYPT32 name 'CertSetCTLContextProperty';<br>function CertGetCTLContextProperty; external CRYPT32 name 'CertGetCTLContextProperty';<br>function CertEnumCTLContextProperties; external CRYPT32 name 'CertEnumCTLContextProperties';<br>function CertEnumCTLsInStore; external CRYPT32 name 'CertEnumCTLsInStore';<br>function CertFindSubjectInCTL; external CRYPT32 name 'CertFindSubjectInCTL';<br>function CertFindCTLInStore; external CRYPT32 name 'CertFindCTLInStore';<br>function CertAddEncodedCTLToStore; external CRYPT32 name 'CertAddEncodedCTLToStore';<br>function CertAddCTLContextToStore; external CRYPT32 name 'CertAddCTLContextToStore';<br>function CertSerializeCTLStoreElement; external CRYPT32 name 'CertSerializeCTLStoreElement';<br>function CertDeleteCTLFromStore; external CRYPT32 name 'CertDeleteCTLFromStore';<br>function CertGetEnhancedKeyUsage; external CRYPT32 name 'CertGetEnhancedKeyUsage';<br>function CertSetEnhancedKeyUsage; external CRYPT32 name 'CertSetEnhancedKeyUsage';<br>function CertAddEnhancedKeyUsageIdentifier; external CRYPT32 name 'CertAddEnhancedKeyUsageIdentifier';<br>function CertRemoveEnhancedKeyUsageIdentifier; external CRYPT32 name 'CertRemoveEnhancedKeyUsageIdentifier';<br>function CryptMsgGetAndVerifySigner; external CRYPT32 name 'CryptMsgGetAndVerifySigner';<br>function CryptMsgSignCTL; external CRYPT32 name 'CryptMsgSignCTL';<br>function CryptMsgEncodeAndSignCTL; external CRYPT32 name 'CryptMsgEncodeAndSignCTL';<br>function CertVerifyCTLUsage; external CRYPT32 name 'CertVerifyCTLUsage';<br>function CertVerifyRevocation; external CRYPT32 name 'CertVerifyRevocation';<br>function CertCompareIntegerBlob; external CRYPT32 name 'CertCompareIntegerBlob';<br>function CertCompareCertificate; external CRYPT32 name 'CertCompareCertificate';<br>function CertCompareCertificateName; external CRYPT32 name 'CertCompareCertificateName';<br>function CertIsRDNAttrsInCertificateName; external CRYPT32 name 'CertIsRDNAttrsInCertificateName';<br>function CertComparePublicKeyInfo; external CRYPT32 name 'CertComparePublicKeyInfo';<br>function CertGetPublicKeyLength; external CRYPT32 name 'CertGetPublicKeyLength';<br>function CryptVerifyCertificateSignature; external CRYPT32 name 'CryptVerifyCertificateSignature';<br>function CryptHashToBeSigned; external CRYPT32 name 'CryptHashToBeSigned';<br>function CryptHashCertificate; external CRYPT32 name 'CryptHashCertificate';<br>function CryptSignCertificate; external CRYPT32 name 'CryptSignCertificate';<br>function CryptSignAndEncodeCertificate; external CRYPT32 name 'CryptSignAndEncodeCertificate';<br>function CertVerifyTimeValidity; external CRYPT32 name 'CertVerifyTimeValidity';<br>function CertVerifyCRLTimeValidity; external CRYPT32 name 'CertVerifyCRLTimeValidity';<br>function CertVerifyValidityNesting; external CRYPT32 name 'CertVerifyValidityNesting';<br>function CertVerifyCRLRevocation; external CRYPT32 name 'CertVerifyCRLRevocation';<br>function CertAlgIdToOID; external CRYPT32 name 'CertAlgIdToOID';<br>function CertOIDToAlgId; external CRYPT32 name 'CertOIDToAlgId';<br>function CertFindExtension; external CRYPT32 name 'CertFindExtension';<br>function CertFindAttribute; external CRYPT32 name 'CertFindAttribute';<br>function CertFindRDNAttr; external CRYPT32 name 'CertFindRDNAttr';<br>function CertGetIntendedKeyUsage; external CRYPT32 name 'CertGetIntendedKeyUsage';<br>function CryptExportPublicKeyInfo; external CRYPT32 name 'CryptExportPublicKeyInfo';<br>function CryptExportPublicKeyInfoEx; external CRYPT32 name 'CryptExportPublicKeyInfoEx';<br>function CryptImportPublicKeyInfo; external CRYPT32 name 'CryptImportPublicKeyInfo';<br>function CryptImportPublicKeyInfoEx; external CRYPT32 name 'CryptImportPublicKeyInfoEx';<br>function CryptHashPublicKeyInfo; external CRYPT32 name 'CryptHashPublicKeyInfo';<br>function CertRDNValueToStrA; external CRYPT32 name 'CertRDNValueToStrA';<br>function CertRDNValueToStrW; external CRYPT32 name 'CertRDNValueToStrW';<br>{$IFDEF UNICODE}<br>function CertRDNValueToStr; external CRYPT32 name 'CertRDNValueToStrW';<br>{$ELSE}<br>function CertRDNValueToStr; external CRYPT32 name 'CertRDNValueToStrA';<br>{$ENDIF} // !UNICODE<br>function CertNameToStrA; external CRYPT32 name 'CertNameToStrA';<br>function CertNameToStrW; external CRYPT32 name 'CertNameToStrW';<br>{$IFDEF UNICODE}<br>function CertNameToStr; external CRYPT32 name 'CertNameToStrW';<br>{$ELSE}<br>function CertNameToStr; external CRYPT32 name 'CertNameToStrA';<br>{$ENDIF} // !UNICODE<br>function CertStrToNameW; external CRYPT32 name 'CertStrToNameW';<br>function CertStrToNameA; external CRYPT32 name 'CertStrToNameA';<br>{$IFDEF UNICODE}<br>function CertStrToName; external CRYPT32 name 'CertStrToNameW';<br>{$ELSE}<br>function CertStrToName; external CRYPT32 name 'CertStrToNameA';<br>{$ENDIF} // !UNICODE<br>function CryptSignMessage; external CRYPT32 name 'CryptSignMessage';<br>//function CryptSignMessageWithKey; external CRYPT32 name 'CryptSignMessageWithKey';<br>function CryptVerifyMessageSignature; external CRYPT32 name 'CryptVerifyMessageSignature';<br>//function CryptVerifyMessageSignatureWithKey; external CRYPT32 name 'CryptVerifyMessageSignatureWithKey';<br>function CryptGetMessageSignerCount; external CRYPT32 name 'CryptGetMessageSignerCount';<br>function CryptGetMessageCertificates; external CRYPT32 name 'CryptGetMessageCertificates';<br>function CryptVerifyDetachedMessageSignature; external CRYPT32 name 'CryptVerifyDetachedMessageSignature';<br>function CryptEncryptMessage; external CRYPT32 name 'CryptEncryptMessage';<br>function CryptDecryptMessage; external CRYPT32 name 'CryptDecryptMessage';<br>function CryptSignAndEncryptMessage; external CRYPT32 name 'CryptSignAndEncryptMessage';<br>function CryptDecryptAndVerifyMessageSignature; external CRYPT32 name 'CryptDecryptAndVerifyMessageSignature';<br>function CryptDecodeMessage; external CRYPT32 name 'CryptDecodeMessage';<br>function CryptHashMessage; external CRYPT32 name 'CryptHashMessage';<br>function CryptVerifyMessageHash; external CRYPT32 name 'CryptVerifyMessageHash';<br>function CryptVerifyDetachedMessageHash; external CRYPT32 name 'CryptVerifyDetachedMessageHash';<br>function CryptSignMessageWithKey; external CRYPT32 name 'CryptSignMessageWithKey';<br>function CryptVerifyMessageSignatureWithKey; external CRYPT32 name 'CryptVerifyMessageSignatureWithKey';<br>function CertOpenSystemStoreA; external CRYPT32 name 'CertOpenSystemStoreA';<br>function CertOpenSystemStoreW; external CRYPT32 name 'CertOpenSystemStoreW';<br>{$IFDEF UNICODE}<br>function CertOpenSystemStore; external CRYPT32 name 'CertOpenSystemStoreW';<br>{$ELSE}<br>function CertOpenSystemStore; external CRYPT32 name 'CertOpenSystemStoreA';<br>{$ENDIF} // !UNICODE<br>function CertAddEncodedCertificateToSystemStoreA; external CRYPT32 name 'CertAddEncodedCertificateToSystemStoreA';<br>function CertAddEncodedCertificateToSystemStoreW; external CRYPT32 name 'CertAddEncodedCertificateToSystemStoreW';<br>{$IFDEF UNICODE}<br>function CertAddEncodedCertificateToSystemStore; external CRYPT32 name 'CertAddEncodedCertificateToSystemStoreW';<br>{$ELSE}<br>function CertAddEncodedCertificateToSystemStore; external CRYPT32 name 'CertAddEncodedCertificateToSystemStoreA';<br>{$ENDIF} // !UNICODE<br>function FindCertsByIssuer; external SOFTPUB name 'FindCertsByIssuer';<br>end.