请问如何使用delphi调用cryptoapi?我想要使用哈希算法加密(100分)

  • 主题发起人 主题发起人 kaiery
  • 开始时间 开始时间
K

kaiery

Unregistered / Unconfirmed
GUEST, unregistred user!
请问如何使用delphi调用cryptoapi?我想要使用哈希算法加密<br><br>能给出具体例子或者代码吗? 小弟在此感谢了
 
//wcrypt2.pas<br>{******************************************************************}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Borland Delphi Runtime Library &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ Cryptographic API interface unit &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Portions created by Microsoft are &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Copyright (C) 1993-1998 Microsoft Corporation. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ All Rights Reserved. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ The original file is: wincrypt.h, 1992 - 1997 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ The original Pascal code is: wcrypt2.pas, released 01 Jan 1998 &nbsp; }<br>{ The initial developer of the Pascal code is &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp;Massimo Maria Ghisalberti &nbsp;(nissl@dada.it) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Portions created by Massimo Maria Ghisalberti are &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Copyright (C) 1997-1998 Massimo Maria Ghisalberti &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Contributor(s): &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; Peter Tang (peter.tang@citicorp.com) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; Phil Shrimpton (phil@shrimpton.co.uk) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Obtained through: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Joint Endeavour of Delphi Innovators (Project JEDI) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ You may retrieve the latest version of this file at the Project &nbsp;}<br>{ JEDI home page, located at http://delphi-jedi.org &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ The contents of this file are used with permission, subject to &nbsp; }<br>{ the Mozilla Public License Version 1.1 (the &quot;License&quot;); you may &nbsp;}<br>{ not use this file except in compliance with the License. You may }<br>{ obtain a copy of the License at &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ http://www.mozilla.org/MPL/MPL-1.1.html &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Software distributed under the License is distributed on an &nbsp; &nbsp; &nbsp;}<br>{ &quot;AS IS&quot; basis, WITHOUT WARRANTY OF ANY KIND, either express or &nbsp; }<br>{ implied. See the License for the specific language governing &nbsp; &nbsp; }<br>{ rights and limitations under the License. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{******************************************************************}<br><br>unit wcrypt2;<br><br>{.DEFINE NT5}<br><br>{$ALIGN ON}<br><br>{$IFNDEF VER90}<br> &nbsp;{$WEAKPACKAGEUNIT}<br>{$ENDIF}<br><br>interface<br><br>uses<br> &nbsp;Windows<br> &nbsp;{$IFDEF VER90}<br> &nbsp;,Ole2<br> &nbsp;{$ENDIF};<br><br>const<br> &nbsp;ADVAPI32 &nbsp; &nbsp;= 'advapi32.dll';<br> &nbsp;CRYPT32 &nbsp; &nbsp; = 'crypt32.dll';<br> &nbsp;SOFTPUB &nbsp; &nbsp; = 'softpub.dll';<br>{$IFDEF NT5}<br> &nbsp;ADVAPI32NT5 = 'advapi32.dll';<br>{$ENDIF}<br><br>{Support Type}<br><br>type<br> &nbsp; &nbsp;PVOID = Pointer;<br> &nbsp; &nbsp;LONG &nbsp;= DWORD;<br> &nbsp; &nbsp;{$IFDEF UNICODE}<br> &nbsp; &nbsp; &nbsp;LPAWSTR = PWideChar;<br> &nbsp; &nbsp;{$ELSE}<br> &nbsp; &nbsp; &nbsp;LPAWSTR = PAnsiChar;<br> &nbsp; &nbsp;{$ENDIF}<br><br>//-----------------------------------------------------------------------------<br> &nbsp; &nbsp;// Type support for a pointer to an array of pointer (type **name)<br> &nbsp; &nbsp;PLPSTR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= Pointer; // type for a pointer to Array of pointer a type<br> &nbsp; &nbsp;PPCERT_INFO &nbsp; &nbsp; = Pointer; // type for a pointer to Array of pointer a type<br> &nbsp; &nbsp;PPVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= Pointer; // type for a pointer to Array of pointer a type<br> &nbsp; &nbsp;PPCCERT_CONTEXT = Pointer; // type for a pointer to Array of pointer a type<br> &nbsp; &nbsp;PPCCTL_CONTEXT &nbsp;= Pointer; // type for a pointer to Array of pointer a type<br> &nbsp; &nbsp;PPCCRL_CONTEXT &nbsp;= Pointer; // type for a pointer to Array of pointer a type<br>//-----------------------------------------------------------------------------<br><br>//+---------------------------------------------------------------------------<br>//<br>// &nbsp;Microsoft Windows<br>// &nbsp;Copyright (C) Microsoft Corporation, 1992 - 1997.<br>//<br>// &nbsp;File: &nbsp; &nbsp; &nbsp; wincrypt.h<br>//<br>// &nbsp;Contents: &nbsp; 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> &nbsp;// Algorithm classes<br> &nbsp;ALG_CLASS_ANY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 0;<br> &nbsp;ALG_CLASS_SIGNATURE &nbsp; &nbsp;= (1 shl 13);<br> &nbsp;ALG_CLASS_MSG_ENCRYPT &nbsp;= (2 shl 13);<br> &nbsp;ALG_CLASS_DATA_ENCRYPT = (3 shl 13);<br> &nbsp;ALG_CLASS_HASH &nbsp; &nbsp; &nbsp; &nbsp; = (4 shl 13);<br> &nbsp;ALG_CLASS_KEY_EXCHANGE = (5 shl 13);<br><br> &nbsp;// Algorithm types<br> &nbsp;ALG_TYPE_ANY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 0;<br> &nbsp;ALG_TYPE_DSS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (1 shl 9);<br> &nbsp;ALG_TYPE_RSA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (2 shl 9);<br> &nbsp;ALG_TYPE_BLOCK &nbsp; &nbsp; &nbsp; &nbsp; = (3 shl 9);<br> &nbsp;ALG_TYPE_STREAM &nbsp; &nbsp; &nbsp; &nbsp;= (4 shl 9);<br> &nbsp;ALG_TYPE_DH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (5 shl 9);<br> &nbsp;ALG_TYPE_SECURECHANNEL = (6 shl 9);<br><br> &nbsp;// Generic sub-ids<br> &nbsp;ALG_SID_ANY = 0;<br><br> &nbsp;// Some RSA sub-ids<br> &nbsp;ALG_SID_RSA_ANY &nbsp; &nbsp; &nbsp; &nbsp;= 0;<br> &nbsp;ALG_SID_RSA_PKCS &nbsp; &nbsp; &nbsp; = 1;<br> &nbsp;ALG_SID_RSA_MSATWORK &nbsp; = 2;<br> &nbsp;ALG_SID_RSA_ENTRUST &nbsp; &nbsp;= 3;<br> &nbsp;ALG_SID_RSA_PGP &nbsp; &nbsp; &nbsp; &nbsp;= 4;<br><br> &nbsp;// Some DSS sub-ids<br> &nbsp;ALG_SID_DSS_ANY &nbsp; &nbsp; &nbsp; &nbsp;= 0;<br> &nbsp;ALG_SID_DSS_PKCS &nbsp; &nbsp; &nbsp; = 1;<br> &nbsp;ALG_SID_DSS_DMS &nbsp; &nbsp; &nbsp; &nbsp;= 2;<br><br> &nbsp;// Block cipher sub ids<br> &nbsp;// DES sub_ids<br> &nbsp;ALG_SID_DES &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;ALG_SID_3DES &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 3;<br> &nbsp;ALG_SID_DESX &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 4;<br> &nbsp;ALG_SID_IDEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 5;<br> &nbsp;ALG_SID_CAST &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 6;<br> &nbsp;ALG_SID_SAFERSK64 &nbsp; &nbsp; &nbsp;= 7;<br> &nbsp;ALD_SID_SAFERSK128 &nbsp; &nbsp; = 8;<br> &nbsp;ALG_SID_SAFERSK128 &nbsp; &nbsp; = 8;<br> &nbsp;ALG_SID_3DES_112 &nbsp; &nbsp; &nbsp; = 9;<br> &nbsp;ALG_SID_CYLINK_MEK &nbsp; &nbsp; = 12;<br> &nbsp;ALG_SID_RC5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 13;<br><br> &nbsp;// Fortezza sub-ids<br> &nbsp;ALG_SID_SKIPJACK &nbsp; &nbsp; &nbsp; = 10;<br> &nbsp;ALG_SID_TEK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 11;<br><br> &nbsp;// KP_MODE<br> &nbsp;CRYPT_MODE_CBCI &nbsp; &nbsp; &nbsp; &nbsp;= 6; &nbsp;{ANSI CBC Interleaved}<br> &nbsp;CRYPT_MODE_CFBP &nbsp; &nbsp; &nbsp; &nbsp;= 7; &nbsp;{ANSI CFB Pipelined}<br> &nbsp;CRYPT_MODE_OFBP &nbsp; &nbsp; &nbsp; &nbsp;= 8; &nbsp;{ANSI OFB Pipelined}<br> &nbsp;CRYPT_MODE_CBCOFM &nbsp; &nbsp; &nbsp;= 9; &nbsp;{ANSI CBC + OF Masking}<br> &nbsp;CRYPT_MODE_CBCOFMI &nbsp; &nbsp; = 10; {ANSI CBC + OFM Interleaved}<br><br> &nbsp;// RC2 sub-ids<br> &nbsp;ALG_SID_RC2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 2;<br><br> &nbsp;// Stream cipher sub-ids<br> &nbsp;ALG_SID_RC4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;ALG_SID_SEAL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 2;<br><br> &nbsp;// Diffie-Hellman sub-ids<br> &nbsp;ALG_SID_DH_SANDF &nbsp; &nbsp; &nbsp; = 1;<br> &nbsp;ALG_SID_DH_EPHEM &nbsp; &nbsp; &nbsp; = 2;<br> &nbsp;ALG_SID_AGREED_KEY_ANY = 3;<br> &nbsp;ALG_SID_KEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 4;<br><br> &nbsp;// Hash sub ids<br> &nbsp;ALG_SID_MD2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;ALG_SID_MD4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 2;<br> &nbsp;ALG_SID_MD5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 3;<br> &nbsp;ALG_SID_SHA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 4;<br> &nbsp;ALG_SID_SHA1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 4;<br> &nbsp;ALG_SID_MAC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 5;<br> &nbsp;ALG_SID_RIPEMD &nbsp; &nbsp; &nbsp; &nbsp; = 6;<br> &nbsp;ALG_SID_RIPEMD160 &nbsp; &nbsp; &nbsp;= 7;<br> &nbsp;ALG_SID_SSL3SHAMD5 &nbsp; &nbsp; = 8;<br> &nbsp;ALG_SID_HMAC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 9;<br><br> &nbsp;// secure channel sub ids<br> &nbsp;ALG_SID_SSL3_MASTER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;ALG_SID_SCHANNEL_MASTER_HASH = 2;<br> &nbsp;ALG_SID_SCHANNEL_MAC_KEY &nbsp; &nbsp; = 3;<br> &nbsp;ALG_SID_PCT1_MASTER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 4;<br> &nbsp;ALG_SID_SSL2_MASTER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 5;<br> &nbsp;ALG_SID_TLS1_MASTER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 6;<br> &nbsp;ALG_SID_SCHANNEL_ENC_KEY &nbsp; &nbsp; = 7;<br><br> &nbsp;// Our silly example sub-id<br> &nbsp;ALG_SID_EXAMPLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 80;<br><br>{$IFNDEF ALGIDDEF}<br> &nbsp;{$DEFINE ALGIDDEF}<br>Type ALG_ID = ULONG;<br>{$ENDIF}<br><br>// algorithm identifier definitions<br>Const<br> &nbsp;CALG_MD2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD2);<br> &nbsp;CALG_MD4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD4);<br> &nbsp;CALG_MD5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD5);<br> &nbsp;CALG_SHA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_SHA);<br> &nbsp;CALG_SHA1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_SHA1);<br> &nbsp;CALG_MAC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MAC);<br> &nbsp;CALG_RSA_SIGN &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_SIGNATURE or ALG_TYPE_RSA or ALG_SID_RSA_ANY);<br> &nbsp;CALG_DSS_SIGN &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_SIGNATURE or ALG_TYPE_DSS or ALG_SID_DSS_ANY);<br> &nbsp;CALG_RSA_KEYX &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_RSA or ALG_SID_RSA_ANY);<br> &nbsp;CALG_DES &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_DES);<br> &nbsp;CALG_3DES_112 &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_3DES_112);<br> &nbsp;CALG_3DES &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_3DES);<br> &nbsp;CALG_RC2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_RC2);<br> &nbsp;CALG_RC4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_STREAM or ALG_SID_RC4);<br> &nbsp;CALG_SEAL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_STREAM or ALG_SID_SEAL);<br> &nbsp;CALG_DH_SF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_DH_SANDF);<br> &nbsp;CALG_DH_EPHEM &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_KEY_EXCHANGE &nbsp;or &nbsp;ALG_TYPE_DH &nbsp;or &nbsp;ALG_SID_DH_EPHEM);<br> &nbsp;CALG_AGREEDKEY_ANY &nbsp; &nbsp;= (ALG_CLASS_KEY_EXCHANGE &nbsp;or ALG_TYPE_DH or ALG_SID_AGREED_KEY_ANY);<br> &nbsp;CALG_KEA_KEYX &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_KEA);<br> &nbsp;CALG_HUGHES_MD5 &nbsp; &nbsp; &nbsp; = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_ANY or ALG_SID_MD5);<br> &nbsp;CALG_SKIPJACK &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_SKIPJACK);<br> &nbsp;CALG_TEK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_TEK);<br> &nbsp;CALG_CYLINK_MEK &nbsp; &nbsp; &nbsp; = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_CYLINK_MEK);<br> &nbsp;CALG_SSL3_SHAMD5 &nbsp; &nbsp; &nbsp;= (ALG_CLASS_HASH &nbsp;or &nbsp;ALG_TYPE_ANY &nbsp;or &nbsp;ALG_SID_SSL3SHAMD5);<br> &nbsp;CALG_SSL3_MASTER &nbsp; &nbsp; &nbsp;= (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SSL3_MASTER);<br> &nbsp;CALG_SCHANNEL_MASTER_HASH = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SCHANNEL_MASTER_HASH);<br> &nbsp;CALG_SCHANNEL_MAC_KEY = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SCHANNEL_MAC_KEY);<br> &nbsp;CALG_SCHANNEL_ENC_KEY = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SCHANNEL_ENC_KEY);<br> &nbsp;CALG_PCT1_MASTER &nbsp; &nbsp; &nbsp;= (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_PCT1_MASTER);<br> &nbsp;CALG_SSL2_MASTER &nbsp; &nbsp; &nbsp;= (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SSL2_MASTER);<br> &nbsp;CALG_TLS1_MASTER &nbsp; &nbsp; &nbsp;= (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_TLS1_MASTER);<br> &nbsp;CALG_RC5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_RC5);<br> &nbsp;CALG_HMAC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (ALG_CLASS_HASH &nbsp;or &nbsp;ALG_TYPE_ANY &nbsp;or &nbsp;ALG_SID_HMAC);<br><br>type<br> &nbsp;PVTableProvStruc = ^VTableProvStruc;<br> &nbsp;VTableProvStruc = record<br> &nbsp; &nbsp;Version &nbsp; &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;FuncVerifyImage :TFarProc;<br> &nbsp; &nbsp;FuncReturnhWnd &nbsp;:TFarProc;<br> &nbsp; &nbsp;dwProvType &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;pbContextInfo &nbsp; :PBYTE;<br> &nbsp; &nbsp;cbContextInfo &nbsp; :DWORD;<br>end;<br><br>//type HCRYPTPROV = ULONG;<br>//type HCRYPTKEY &nbsp;= ULONG;<br>//type HCRYPTHASH = ULONG;<br><br><br>const<br> &nbsp;// dwFlags definitions for CryptAcquireContext<br> &nbsp;CRYPT_VERIFYCONTEXT &nbsp;= $F0000000;<br> &nbsp;CRYPT_NEWKEYSET &nbsp; &nbsp; &nbsp;= $00000008;<br> &nbsp;CRYPT_DELETEKEYSET &nbsp; = $00000010;<br> &nbsp;CRYPT_MACHINE_KEYSET = $00000020;<br><br> &nbsp;// dwFlag definitions for CryptGenKey<br> &nbsp;CRYPT_EXPORTABLE &nbsp; &nbsp; = $00000001;<br> &nbsp;CRYPT_USER_PROTECTED = $00000002;<br> &nbsp;CRYPT_CREATE_SALT &nbsp; &nbsp;= $00000004;<br> &nbsp;CRYPT_UPDATE_KEY &nbsp; &nbsp; = $00000008;<br> &nbsp;CRYPT_NO_SALT &nbsp; &nbsp; &nbsp; &nbsp;= $00000010;<br> &nbsp;CRYPT_PREGEN &nbsp; &nbsp; &nbsp; &nbsp; = $00000040;<br> &nbsp;CRYPT_RECIPIENT &nbsp; &nbsp; &nbsp;= $00000010;<br> &nbsp;CRYPT_INITIATOR &nbsp; &nbsp; &nbsp;= $00000040;<br> &nbsp;CRYPT_ONLINE &nbsp; &nbsp; &nbsp; &nbsp; = $00000080;<br> &nbsp;CRYPT_SF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $00000100;<br> &nbsp;CRYPT_CREATE_IV &nbsp; &nbsp; &nbsp;= $00000200;<br> &nbsp;CRYPT_KEK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $00000400;<br> &nbsp;CRYPT_DATA_KEY &nbsp; &nbsp; &nbsp; = $00000800;<br><br> &nbsp;// dwFlags definitions for CryptDeriveKey<br> &nbsp;CRYPT_SERVER &nbsp; &nbsp; &nbsp; &nbsp; = $00000400;<br><br> &nbsp;KEY_LENGTH_MASK &nbsp; &nbsp; &nbsp;= $FFFF0000;<br><br> &nbsp;// dwFlag definitions for CryptExportKey<br> &nbsp;CRYPT_Y_ONLY &nbsp; &nbsp; &nbsp; &nbsp;= $00000001;<br> &nbsp;CRYPT_SSL2_SLUMMING = $00000002;<br><br> &nbsp;// dwFlags definitions for CryptHashSessionKey<br> &nbsp;CRYPT_LITTLE_ENDIAN = $00000001;<br><br> &nbsp;// dwFlag definitions for CryptSetProviderEx and CryptGetDefaultProvider<br> &nbsp;CRYPT_MACHINE_DEFAULT = $00000001;<br> &nbsp;CRYPT_USER_DEFAULT &nbsp; &nbsp;= $00000002;<br> &nbsp;CRYPT_DELETE_DEFAULT &nbsp;= $00000004;<br><br> &nbsp;// exported key blob definitions<br> &nbsp;SIMPLEBLOB &nbsp; &nbsp; &nbsp; &nbsp;= $1;<br> &nbsp;PUBLICKEYBLOB &nbsp; &nbsp; = $6;<br> &nbsp;PRIVATEKEYBLOB &nbsp; &nbsp;= $7;<br> &nbsp;PLAINTEXTKEYBLOB &nbsp;= $8;<br> &nbsp;AT_KEYEXCHANGE &nbsp; &nbsp;= 1;<br> &nbsp;AT_SIGNATURE &nbsp; &nbsp; &nbsp;= 2;<br> &nbsp;CRYPT_USERDATA &nbsp; &nbsp;= 1;<br><br> &nbsp;// dwParam<br> &nbsp;KP_IV &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 1; &nbsp;// Initialization vector<br> &nbsp;KP_SALT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 2; &nbsp;// Salt value<br> &nbsp;KP_PADDING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 3; &nbsp;// Padding values<br> &nbsp;KP_MODE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 4; &nbsp;// Mode of the cipher<br> &nbsp;KP_MODE_BITS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 5; &nbsp;// Number of bits to feedback<br> &nbsp;KP_PERMISSIONS &nbsp; &nbsp; &nbsp; &nbsp;= 6; &nbsp;// Key permissions DWORD<br> &nbsp;KP_ALGID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 7; &nbsp;// Key algorithm<br> &nbsp;KP_BLOCKLEN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 8; &nbsp;// Block size of the cipher<br> &nbsp;KP_KEYLEN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 9; &nbsp;// Length of key in bits<br> &nbsp;KP_SALT_EX &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 10; // Length of salt in bytes<br> &nbsp;KP_P &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 11; // DSS/Diffie-Hellman P value<br> &nbsp;KP_G &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 12; // DSS/Diffie-Hellman G value<br> &nbsp;KP_Q &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 13; // DSS Q value<br> &nbsp;KP_X &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 14; // Diffie-Hellman X value<br> &nbsp;KP_Y &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 15; // Y value<br> &nbsp;KP_RA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 16; // Fortezza RA value<br> &nbsp;KP_RB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 17; // Fortezza RB value<br> &nbsp;KP_INFO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 18; // for putting information into an RSA envelope<br> &nbsp;KP_EFFECTIVE_KEYLEN &nbsp; = 19; // setting and getting RC2 effective key length<br> &nbsp;KP_SCHANNEL_ALG = 20; // for setting the Secure Channel algorithms<br> &nbsp;KP_CLIENT_RANDOM &nbsp; &nbsp; &nbsp;= 21; // for setting the Secure Channel client random data<br> &nbsp;KP_SERVER_RANDOM &nbsp; &nbsp; &nbsp;= 22; // for setting the Secure Channel server random data<br> &nbsp;KP_RP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 23;<br> &nbsp;KP_PRECOMP_MD5 &nbsp; &nbsp; &nbsp; &nbsp;= 24;<br> &nbsp;KP_PRECOMP_SHA &nbsp; &nbsp; &nbsp; &nbsp;= 25;<br> &nbsp;KP_CERTIFICATE &nbsp; &nbsp; &nbsp; &nbsp;= 26; // for setting Secure Channel certificate data (PCT1)<br> &nbsp;KP_CLEAR_KEY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 27; // for setting Secure Channel clear key data (PCT1)<br> &nbsp;KP_PUB_EX_LEN &nbsp; &nbsp; &nbsp; &nbsp; = 28;<br> &nbsp;KP_PUB_EX_VAL &nbsp; &nbsp; &nbsp; &nbsp; = 29;<br><br> &nbsp;// KP_PADDING<br> &nbsp;PKCS5_PADDING &nbsp; &nbsp; &nbsp; &nbsp; = 1; {PKCS 5 (sec 6.2) padding method}<br> &nbsp;RANDOM_PADDING &nbsp; &nbsp; &nbsp; &nbsp;= 2;<br> &nbsp;ZERO_PADDING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 3;<br><br> &nbsp;// KP_MODE<br> &nbsp;CRYPT_MODE_CBC &nbsp; &nbsp;= 1; // Cipher block chaining<br> &nbsp;CRYPT_MODE_ECB &nbsp; &nbsp;= 2; // Electronic code book<br> &nbsp;CRYPT_MODE_OFB &nbsp; &nbsp;= 3; // Output feedback mode<br> &nbsp;CRYPT_MODE_CFB &nbsp; &nbsp;= 4; // Cipher feedback mode<br> &nbsp;CRYPT_MODE_CTS &nbsp; &nbsp;= 5; // Ciphertext stealing mode<br><br> &nbsp;// KP_PERMISSIONS<br> &nbsp;CRYPT_ENCRYPT &nbsp; &nbsp; = $0001; // Allow encryption<br> &nbsp;CRYPT_DECRYPT &nbsp; &nbsp; = $0002; // Allow decryption<br> &nbsp;CRYPT_EXPORT &nbsp; &nbsp; &nbsp;= $0004; // Allow key to be exported<br> &nbsp;CRYPT_READ &nbsp; &nbsp; &nbsp; &nbsp;= $0008; // Allow parameters to be read<br> &nbsp;CRYPT_WRITE &nbsp; &nbsp; &nbsp; = $0010; // Allow parameters to be set<br> &nbsp;CRYPT_MAC &nbsp; &nbsp; &nbsp; &nbsp; = $0020; // Allow MACs to be used with key<br> &nbsp;CRYPT_EXPORT_KEY &nbsp;= $0040; // Allow key to be used for exporting keys<br> &nbsp;CRYPT_IMPORT_KEY &nbsp;= $0080; // Allow key to be used for importing keys<br><br> &nbsp;HP_ALGID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $0001; // Hash algorithm<br> &nbsp;HP_HASHVAL &nbsp; &nbsp; &nbsp; &nbsp;= $0002; // Hash value<br> &nbsp;HP_HASHSIZE &nbsp; &nbsp; &nbsp; = $0004; // Hash value size<br><br> &nbsp;HP_HMAC_INFO &nbsp; &nbsp; &nbsp;= $0005; // information for creating an HMAC<br><br> &nbsp;CRYPT_FAILED &nbsp; &nbsp; &nbsp;= FALSE;<br> &nbsp;CRYPT_SUCCEED &nbsp; &nbsp; = TRUE;<br><br>function RCRYPT_SUCCEEDED(rt:BOOL):BOOL;<br>function RCRYPT_FAILED(rt:BOOL):BOOL;<br><br>const<br> &nbsp;// CryptGetProvParam<br> &nbsp;PP_ENUMALGS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;PP_ENUMCONTAINERS &nbsp; &nbsp; &nbsp;= 2;<br> &nbsp;PP_IMPTYPE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 3;<br> &nbsp;PP_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 4;<br> &nbsp;PP_VERSION &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 5;<br> &nbsp;PP_CONTAINER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 6;<br> &nbsp;PP_CHANGE_PASSWORD &nbsp; &nbsp; = 7;<br> &nbsp;PP_KEYSET_SEC_DESCR &nbsp; &nbsp;= 8; &nbsp;// get/set security descriptor of keyset<br> &nbsp;PP_CERTCHAIN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 9; &nbsp;// for retrieving certificates from tokens<br> &nbsp;PP_KEY_TYPE_SUBTYPE &nbsp; &nbsp;= 10;<br> &nbsp;PP_PROVTYPE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 16;<br> &nbsp;PP_KEYSTORAGE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 17;<br> &nbsp;PP_APPLI_CERT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 18;<br> &nbsp;PP_SYM_KEYSIZE &nbsp; &nbsp; &nbsp; &nbsp; = 19;<br> &nbsp;PP_SESSION_KEYSIZE &nbsp; &nbsp; = 20;<br> &nbsp;PP_UI_PROMPT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 21;<br> &nbsp;PP_ENUMALGS_EX &nbsp; &nbsp; &nbsp; &nbsp; = 22;<br> &nbsp;CRYPT_FIRST &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;CRYPT_NEXT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 2;<br> &nbsp;CRYPT_IMPL_HARDWARE &nbsp; &nbsp;= 1;<br> &nbsp;CRYPT_IMPL_SOFTWARE &nbsp; &nbsp;= 2;<br> &nbsp;CRYPT_IMPL_MIXED &nbsp; &nbsp; &nbsp; = 3;<br> &nbsp;CRYPT_IMPL_UNKNOWN &nbsp; &nbsp; = 4;<br><br> &nbsp;// key storage flags<br> &nbsp;CRYPT_SEC_DESCR &nbsp; &nbsp; &nbsp; &nbsp;= $00000001;<br> &nbsp;CRYPT_PSTORE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $00000002;<br> &nbsp;CRYPT_UI_PROMPT &nbsp; &nbsp; &nbsp; &nbsp;= $00000004;<br><br> &nbsp;// protocol flags<br> &nbsp;CRYPT_FLAG_PCT1 &nbsp; &nbsp; &nbsp; &nbsp;= $0001;<br> &nbsp;CRYPT_FLAG_SSL2 &nbsp; &nbsp; &nbsp; &nbsp;= $0002;<br> &nbsp;CRYPT_FLAG_SSL3 &nbsp; &nbsp; &nbsp; &nbsp;= $0004;<br> &nbsp;CRYPT_FLAG_TLS1 &nbsp; &nbsp; &nbsp; &nbsp;= $0008;<br><br> &nbsp;// CryptSetProvParam<br> &nbsp;PP_CLIENT_HWND &nbsp; &nbsp; &nbsp; &nbsp; = 1;<br> &nbsp;PP_CONTEXT_INFO &nbsp; &nbsp; &nbsp; &nbsp;= 11;<br> &nbsp;PP_KEYEXCHANGE_KEYSIZE = 12;<br> &nbsp;PP_SIGNATURE_KEYSIZE &nbsp; = 13;<br> &nbsp;PP_KEYEXCHANGE_ALG &nbsp; &nbsp; = 14;<br> &nbsp;PP_SIGNATURE_ALG &nbsp; &nbsp; &nbsp; = 15;<br> &nbsp;PP_DELETEKEY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 24;<br><br> &nbsp;PROV_RSA_FULL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;PROV_RSA_SIG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 2;<br> &nbsp;PROV_DSS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 3;<br> &nbsp;PROV_FORTEZZA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 4;<br> &nbsp;PROV_MS_EXCHANGE &nbsp; &nbsp; &nbsp; = 5;<br> &nbsp;PROV_SSL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 6;<br><br>PROV_RSA_SCHANNEL &nbsp; &nbsp; &nbsp; &nbsp;= 12;<br>PROV_DSS_DH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 13;<br>PROV_EC_ECDSA_SIG &nbsp; &nbsp; &nbsp; &nbsp;= 14;<br>PROV_EC_ECNRA_SIG &nbsp; &nbsp; &nbsp; &nbsp;= 15;<br>PROV_EC_ECDSA_FULL &nbsp; &nbsp; &nbsp; = 16;<br>PROV_EC_ECNRA_FULL &nbsp; &nbsp; &nbsp; = 17;<br>PROV_SPYRUS_LYNKS &nbsp; &nbsp; &nbsp; &nbsp;= 20;<br><br><br> &nbsp;// STT defined Providers<br> &nbsp;PROV_STT_MER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 7;<br> &nbsp;PROV_STT_ACQ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 8;<br> &nbsp;PROV_STT_BRND &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 9;<br> &nbsp;PROV_STT_ROOT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 10;<br> &nbsp;PROV_STT_ISS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 11;<br><br> &nbsp;// Provider friendly names<br> &nbsp;MS_DEF_PROV_A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 'Microsoft Base Cryptographic Provider v1.0';<br> &nbsp;{$IFNDEF VER90}<br> &nbsp; &nbsp;MS_DEF_PROV_W &nbsp; &nbsp; &nbsp; &nbsp;= WideString( 'Microsoft Base Cryptographic Provider v1.0');<br> &nbsp;{$ELSE}<br> &nbsp; &nbsp;MS_DEF_PROV_W &nbsp; &nbsp; &nbsp; &nbsp;= ( 'Microsoft Base Cryptographic Provider v1.0');<br> &nbsp;{$ENDIF}<br><br>{$IFDEF UNICODE}<br> &nbsp;MS_DEF_PROV &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= MS_DEF_PROV_W;<br>{$ELSE}<br> &nbsp;MS_DEF_PROV &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= MS_DEF_PROV_A;<br>{$ENDIF}<br><br> &nbsp;MS_ENHANCED_PROV_A &nbsp; = 'Microsoft Enhanced Cryptographic Provider v1.0';<br> &nbsp;{$IFNDEF VER90}<br> &nbsp; &nbsp;MS_ENHANCED_PROV_W = WideString('Microsoft Enhanced Cryptographic Provider v1.0');<br> &nbsp;{$ELSE}<br> &nbsp; &nbsp;MS_ENHANCED_PROV_W = ('Microsoft Enhanced Cryptographic Provider v1.0');<br> &nbsp;{$ENDIF}<br><br>{$IFDEF UNICODE}<br> &nbsp;MS_ENHANCED_PROV = MS_ENHANCED_PROV_W;<br>{$ELSE}<br> &nbsp;MS_ENHANCED_PROV = MS_ENHANCED_PROV_A;<br>{$ENDIF}<br><br> &nbsp;MS_DEF_RSA_SIG_PROV_A &nbsp; &nbsp;= 'Microsoft RSA Signature Cryptographic Provider';<br> &nbsp;{$IFNDEF VER90}<br> &nbsp; &nbsp;MS_DEF_RSA_SIG_PROV_W &nbsp;= WideString('Microsoft RSA Signature Cryptographic Provider');<br> &nbsp;{$ELSE}<br> &nbsp; &nbsp;MS_DEF_RSA_SIG_PROV_W &nbsp;= ('Microsoft RSA Signature Cryptographic Provider');<br> &nbsp;{$ENDIF}<br><br>{$IFDEF UNICODE}<br> &nbsp;MS_DEF_RSA_SIG_PROV = MS_DEF_RSA_SIG_PROV_W;<br>{$ELSE}<br> &nbsp;MS_DEF_RSA_SIG_PROV = MS_DEF_RSA_SIG_PROV_A;<br>{$ENDIF}<br><br> &nbsp;MS_DEF_RSA_SCHANNEL_PROV_A &nbsp; &nbsp;= 'Microsoft Base RSA SChannel Cryptographic Provider';<br> &nbsp;{$IFNDEF VER90}<br> &nbsp; &nbsp;MS_DEF_RSA_SCHANNEL_PROV_W &nbsp;= WideString('Microsoft Base RSA SChannel Cryptographic Provider');<br> &nbsp;{$ELSE}<br> &nbsp; &nbsp;MS_DEF_RSA_SCHANNEL_PROV_W &nbsp;= ('Microsoft Base RSA SChannel Cryptographic Provider');<br> &nbsp;{$ENDIF}<br><br><br>{$IFDEF UNICODE}<br> &nbsp;MS_DEF_RSA_SCHANNEL_PROV = MS_DEF_RSA_SCHANNEL_PROV_W;<br>{$ELSE}<br> &nbsp;MS_DEF_RSA_SCHANNEL_PROV = MS_DEF_RSA_SCHANNEL_PROV_A;<br>{$ENDIF}<br><br> &nbsp;MS_ENHANCED_RSA_SCHANNEL_PROV_A &nbsp; &nbsp;= 'Microsoft Enhanced RSA SChannel Cryptographic Provider';<br> &nbsp;{$IFNDEF VER90}<br> &nbsp; &nbsp;MS_ENHANCED_RSA_SCHANNEL_PROV_W &nbsp;= WideString('Microsoft Enhanced RSA SChannel Cryptographic Provider');<br> &nbsp;{$ELSE}<br> &nbsp; &nbsp;MS_ENHANCED_RSA_SCHANNEL_PROV_W &nbsp;= ('Microsoft Enhanced RSA SChannel Cryptographic Provider');<br> &nbsp;{$ENDIF}<br><br>{$IFDEF UNICODE}<br> &nbsp;MS_ENHANCED_RSA_SCHANNEL_PROV = MS_ENHANCED_RSA_SCHANNEL_PROV_W;<br>{$ELSE}<br> &nbsp;MS_ENHANCED_RSA_SCHANNEL_PROV = MS_ENHANCED_RSA_SCHANNEL_PROV_A;<br>{$ENDIF}<br><br> &nbsp;MS_DEF_DSS_PROV_A &nbsp; &nbsp;= &nbsp;'Microsoft Base DSS Cryptographic Provider';<br> &nbsp;{$IFNDEF VER90}<br> &nbsp; &nbsp;MS_DEF_DSS_PROV_W &nbsp;= WideString('Microsoft Base DSS Cryptographic Provider');<br> &nbsp;{$ELSE}<br> &nbsp; &nbsp;MS_DEF_DSS_PROV_W &nbsp;= ('Microsoft Base DSS Cryptographic Provider');<br> &nbsp;{$ENDIF}<br><br>{$IFDEF UNICODE}<br> &nbsp;MS_DEF_DSS_PROV = MS_DEF_DSS_PROV_W;<br>{$ELSE}<br> &nbsp;MS_DEF_DSS_PROV = MS_DEF_DSS_PROV_A;<br>{$ENDIF}<br><br> &nbsp;MS_DEF_DSS_DH_PROV_A &nbsp; &nbsp;= 'Microsoft Base DSS and Diffie-Hellman Cryptographic Provider';<br> &nbsp;{$IFNDEF VER90}<br> &nbsp; &nbsp;MS_DEF_DSS_DH_PROV_W &nbsp;= WideString('Microsoft Base DSS and Diffie-Hellman Cryptographic Provider');<br> &nbsp;{$ELSE}<br> &nbsp; &nbsp;MS_DEF_DSS_DH_PROV_W &nbsp;= ('Microsoft Base DSS and Diffie-Hellman Cryptographic Provider');<br> &nbsp;{$ENDIF}<br><br>{$IFDEF UNICODE}<br> &nbsp;MS_DEF_DSS_DH_PROV = MS_DEF_DSS_DH_PROV_W;<br>{$ELSE}<br> &nbsp;MS_DEF_DSS_DH_PROV = MS_DEF_DSS_DH_PROV_A;<br>{$ENDIF}<br><br> &nbsp;MAXUIDLEN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 64;<br> &nbsp;CUR_BLOB_VERSION &nbsp; &nbsp; &nbsp; = 2;<br><br>{structure for use with CryptSetHashParam with CALG_HMAC}<br>type<br> &nbsp;PHMAC_INFO = ^HMAC_INFO;<br> &nbsp;HMAC_INFO = record<br> &nbsp; &nbsp;HashAlgid &nbsp; &nbsp; :ALG_ID;<br> &nbsp; &nbsp;pbInnerString :PBYTE;<br> &nbsp; &nbsp;cbInnerString :DWORD;<br> &nbsp; &nbsp;pbOuterString :PBYTE;<br> &nbsp; &nbsp;cbOuterString :DWORD;<br> &nbsp;end;<br><br>// structure for use with CryptSetHashParam with CALG_HMAC<br>type<br> &nbsp;PSCHANNEL_ALG = ^SCHANNEL_ALG;<br> &nbsp;SCHANNEL_ALG &nbsp;= record<br> &nbsp; &nbsp;dwUse :DWORD;<br> &nbsp; &nbsp;Algid :ALG_ID;<br> &nbsp; &nbsp;cBits :DWORD;<br> &nbsp;end;<br><br>// uses of algortihms for SCHANNEL_ALG structure<br>const<br> &nbsp;SCHANNEL_MAC_KEY = $00000000;<br> &nbsp;SCHANNEL_ENC_KEY = $00000001;<br><br>type<br> &nbsp;PPROV_ENUMALGS = ^PROV_ENUMALGS;<br> &nbsp;PROV_ENUMALGS = record<br> &nbsp; &nbsp;aiAlgid &nbsp; :ALG_ID;<br> &nbsp; &nbsp;dwBitLen &nbsp;:DWORD;<br> &nbsp; &nbsp;dwNameLen :DWORD;<br> &nbsp; &nbsp;szName &nbsp; &nbsp;:array[0..20-1] of Char;<br> &nbsp;end ;<br><br>type<br> &nbsp;PPROV_ENUMALGS_EX = ^PROV_ENUMALGS_EX;<br> &nbsp;PROV_ENUMALGS_EX = record<br> &nbsp; &nbsp;aiAlgid &nbsp; &nbsp; &nbsp; :ALG_ID;<br> &nbsp; &nbsp;dwDefaultLen &nbsp;:DWORD;<br> &nbsp; &nbsp;dwMinLen &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;dwMaxLen &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;dwProtocols &nbsp; :DWORD;<br> &nbsp; &nbsp;dwNameLen &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;szName &nbsp; &nbsp; &nbsp; &nbsp;:array[0..20-1] of Char;<br> &nbsp; &nbsp;dwLongNameLen :DWORD;<br> &nbsp; &nbsp;szLongName &nbsp; &nbsp;:array[0..40-1] of Char;<br> &nbsp; &nbsp;end;<br><br>type<br> &nbsp;PPUBLICKEYSTRUC = ^PUBLICKEYSTRUC;<br> &nbsp;PUBLICKEYSTRUC = record<br> &nbsp; &nbsp;bType &nbsp; &nbsp;:BYTE;<br> &nbsp; &nbsp;bVersion :BYTE;<br> &nbsp; &nbsp;reserved :Word;<br> &nbsp; &nbsp;aiKeyAlg :ALG_ID;<br> &nbsp;end;<br><br>type<br> &nbsp;BLOBHEADER &nbsp;= PUBLICKEYSTRUC;<br> &nbsp;PBLOBHEADER = ^BLOBHEADER;<br><br>type<br> &nbsp;PRSAPUBKEY = ^RSAPUBKEY;<br> &nbsp;RSAPUBKEY = record<br> &nbsp; &nbsp;magic &nbsp;:DWORD; &nbsp;// Has to be RSA1<br> &nbsp; &nbsp;bitlen :DWORD; &nbsp;// # of bits in modulus<br> &nbsp; &nbsp;pubexp :DWORD; &nbsp;// public exponent<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Modulus data follows<br> &nbsp; &nbsp;end;<br><br>type<br> &nbsp;PPUBKEY = ^PUBKEY;<br> &nbsp;PUBKEY = record<br> &nbsp; &nbsp;magic &nbsp;:DWORD;<br> &nbsp; &nbsp;bitlen :DWORD; // # of bits in modulus<br> &nbsp;end;<br><br>type<br> &nbsp;DHPUBKEY &nbsp;= PUBKEY;<br> &nbsp;DSSPUBKEY = PUBKEY;<br> &nbsp;KEAPUBKEY = PUBKEY;<br> &nbsp;TEKPUBKEY = PUBKEY;<br><br><br>type<br> &nbsp;PDSSSEED = ^DSSSEED;<br> &nbsp;DSSSEED = record<br> &nbsp; &nbsp;counter :DWORD;<br> &nbsp; &nbsp;seed &nbsp; &nbsp;:array[0..20-1] of BYTE;<br> &nbsp;end;<br><br>type<br> &nbsp;PKEY_TYPE_SUBTYPE = ^KEY_TYPE_SUBTYPE;<br> &nbsp;KEY_TYPE_SUBTYPE = record<br> &nbsp; &nbsp;dwKeySpec :DWORD;<br> &nbsp; &nbsp;Type_ &nbsp; &nbsp; :TGUID; {conflict with base Delphi type: original name 'Type'}<br> &nbsp; &nbsp;Subtype &nbsp; :TGUID;<br> &nbsp;end;<br><br>type<br> &nbsp;HCRYPTPROV &nbsp;= ULONG;<br> &nbsp;PHCRYPTPROV = ^HCRYPTPROV;<br> &nbsp;HCRYPTKEY &nbsp; = ULONG;<br> &nbsp;PHCRYPTKEY &nbsp;= ^HCRYPTKEY;<br> &nbsp;HCRYPTHASH &nbsp;= ULONG;<br> &nbsp;PHCRYPTHASH = ^HCRYPTHASH;<br><br>function CryptAcquireContextA(phProv &nbsp; &nbsp; &nbsp; :PHCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszContainer :PAnsiChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszProvider &nbsp;:PAnsiChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwProvType &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; &nbsp;:DWORD) :BOOL;stdcall;<br><br>function CryptAcquireContext(phProv &nbsp; &nbsp; &nbsp; &nbsp;:PHCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszContainer :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszProvider &nbsp;:LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwProvType &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; &nbsp;:DWORD) :BOOL;stdcall;<br><br>function CryptAcquireContextW(phProv &nbsp; &nbsp; &nbsp; :PHCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszContainer :PWideChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszProvider &nbsp;:PWideChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwProvType &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; &nbsp;:DWORD) :BOOL ;stdcall;<br><br><br>function CryptReleaseContext(hProv &nbsp; :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD) :BOOL;stdcall;<br><br><br><br>function CryptGenKey(hProv &nbsp; :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Algid &nbsp; :ALG_ID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; phKey &nbsp; :PHCRYPTKEY) :BOOL;stdcall ;<br><br><br>function CryptDeriveKey(hProv &nbsp; &nbsp; :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Algid &nbsp; &nbsp; :ALG_ID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hBaseData :HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;phKey &nbsp; &nbsp; :PHCRYPTKEY) :BOOL;stdcall ;<br><br><br><br>function CryptDestroyKey(hKey &nbsp;:HCRYPTKEY) :BOOL;stdcall ;<br><br><br>function CryptSetKeyParam(hKey &nbsp; &nbsp;:HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwParam :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbData &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD) :BOOL;stdcall;<br><br><br>function CryptGetKeyParam(hKey &nbsp; &nbsp; &nbsp; :HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwParam &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbData &nbsp; &nbsp; :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwDataLen :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp;:DWORD) :BOOL;stdcall;<br><br><br>function CryptSetHashParam(hHash &nbsp; :HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwParam :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbData &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD) :BOOL;stdcall;<br><br><br>function CryptGetHashParam(hHash &nbsp; &nbsp; &nbsp;:HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwParam &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbData &nbsp; &nbsp; :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwDataLen :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp;:DWORD) :BOOL;stdcall;<br><br><br>function CryptSetProvParam(hProv &nbsp; :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwParam :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbData &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD) :BOOL;stdcall;<br><br><br>function CryptGetProvParam(hProv &nbsp; &nbsp; &nbsp;:HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwParam &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbData &nbsp; &nbsp; :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwDataLen :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp;:DWORD) :BOOL;stdcall;<br><br><br>function CryptGenRandom(hProv &nbsp; &nbsp;:HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwLen &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbBuffer :PBYTE) :BOOL;stdcall;<br><br><br>function CryptGetUserKey(hProv &nbsp; &nbsp; :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwKeySpec :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; phUserKey :PHCRYPTKEY) :BOOL;stdcall;<br><br><br>function CryptExportKey(hKey &nbsp; &nbsp; &nbsp; :HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hExpKey &nbsp; &nbsp;:HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwBlobType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbData &nbsp; &nbsp; :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwDataLen :PDWORD) :BOOL;stdcall;<br><br><br>function CryptImportKey(hProv &nbsp; &nbsp; :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbData &nbsp; &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwDataLen :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hPubKey &nbsp; :HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;phKey &nbsp; &nbsp; :PHCRYPTKEY) :BOOL;stdcall;<br><br><br>function CryptEncrypt(hKey &nbsp; &nbsp; &nbsp; :HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hHash &nbsp; &nbsp; &nbsp;:HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Final &nbsp; &nbsp; &nbsp;:BOOL;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbData &nbsp; &nbsp; :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwDataLen :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwBufLen &nbsp; :DWORD) :BOOL;stdcall;<br><br><br>function CryptDecrypt(hKey &nbsp; &nbsp; &nbsp; :HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hHash &nbsp; &nbsp; &nbsp;:HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Final &nbsp; &nbsp; &nbsp;:BOOL;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbData &nbsp; &nbsp; :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwDataLen :PDWORD) :BOOL;stdcall;<br><br><br>function CryptCreateHash(hProv &nbsp; :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Algid &nbsp; :ALG_ID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hKey &nbsp; &nbsp;:HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; phHash &nbsp;:PHCRYPTHASH) :BOOL;stdcall;<br><br><br>function CryptHashData(hHash &nbsp; &nbsp; &nbsp; :HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbData &nbsp; &nbsp; &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwDataLen &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD) :BOOL;stdcall;<br><br><br>function CryptHashSessionKey(hHash &nbsp; :HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hKey &nbsp; &nbsp;:HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD) :BOOL;stdcall;<br><br><br>function CryptDestroyHash(hHash :HCRYPTHASH) :BOOL;stdcall;<br><br><br>function CryptSignHashA(hHash &nbsp; &nbsp; &nbsp; &nbsp;:HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwKeySpec &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sDescription :PAnsiChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbSignature &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwSigLen &nbsp; &nbsp;:PDWORD) :BOOL;stdcall;<br><br><br>function CryptSignHash(hHash &nbsp; &nbsp; &nbsp; &nbsp; :HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwKeySpec &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sDescription :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbSignature &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwSigLen &nbsp; &nbsp;:PDWORD) :BOOL;stdcall;<br><br>function CryptSignHashW(hHash &nbsp; &nbsp; &nbsp; &nbsp;:HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwKeySpec &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sDescription :PWideChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbSignature &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwSigLen &nbsp; &nbsp;:PDWORD) :BOOL;stdcall;<br><br>function CryptSignHashU(hHash &nbsp; &nbsp; &nbsp; &nbsp;:HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwKeySpec &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sDescription :PWideChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbSignature &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwSigLen &nbsp; &nbsp;:PDWORD) :BOOL;stdcall;<br><br>function CryptVerifySignatureA(hHash &nbsp; &nbsp; &nbsp; &nbsp;:HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbSignature &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwSigLen &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hPubKey &nbsp; &nbsp; &nbsp;:HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sDescription :PAnsiChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; &nbsp;:DWORD) :BOOL;stdcall;<br><br>function CryptVerifySignature(hHash &nbsp; &nbsp; &nbsp; &nbsp; :HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbSignature &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwSigLen &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hPubKey &nbsp; &nbsp; &nbsp;:HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sDescription :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; &nbsp;:DWORD) :BOOL;stdcall;<br><br><br>function CryptVerifySignatureW(hHash &nbsp; &nbsp; &nbsp; &nbsp;:HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbSignature &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwSigLen &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hPubKey &nbsp; &nbsp; &nbsp;:HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sDescription :PWideChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; &nbsp;:DWORD) :BOOL;stdcall;<br><br><br>function CryptSetProviderA(pszProvName :PAnsiChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwProvType &nbsp;:DWORD) :BOOL;stdcall;<br><br>function CryptSetProvider(pszProvName :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwProvType :DWORD) :BOOL;stdcall;<br><br>function CryptSetProviderW(pszProvName :PWideChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwProvType &nbsp;:DWORD) :BOOL;stdcall;<br><br>function CryptSetProviderU(pszProvName :PWideChar;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwProvType &nbsp;:DWORD) :BOOL;stdcall;<br><br>{$IFDEF NT5}<br><br>function CryptSetProviderExA(pszProvName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwProvType &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD):BOOL;stdcall;<br><br>function CryptSetProviderExW(pszProvName :LPCWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwProvType &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD):BOOL;stdcall;<br><br>function CryptSetProviderEx(pszProvName :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwProvType &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; :DWORD):BOOL;stdcall;<br><br><br>function CryptGetDefaultProviderA(dwProvType &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwReserved :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszProvName :LPSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbProvName :PDWORD):BOOL ; stdcall;<br><br>function CryptGetDefaultProviderW(dwProvType &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwReserved :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszProvName :LPWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbProvName :PDWORD):BOOL ; stdcall;<br><br>function CryptGetDefaultProvider(dwProvType &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszProvName :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbProvName :PDWORD):BOOL ; stdcall;<br><br>function CryptEnumProviderTypesA(dwIndex &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwProvType :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszTypeName :LPSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbTypeName :PDWORD):BOOL ; stdcall;<br><br>function CryptEnumProviderTypesW(dwIndex &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwProvType :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszTypeName :LPWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbTypeName :PDWORD):BOOL ; stdcall;<br><br>function CryptEnumProviderTypes(dwIndex &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwProvType :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszTypeName :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbTypeName :PDWORD):BOOL ; stdcall;<br><br>function CryptEnumProvidersA(dwIndex &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwProvType :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszProvName :LPSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbProvName :PDWORD):BOOL ; stdcall;<br><br>function CryptEnumProvidersW(dwIndex &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwProvType :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszProvName :LPWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbProvName :PDWORD):BOOL ; stdcall;<br><br>function CryptEnumProviders(dwIndex &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwProvType :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszProvName :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbProvName :PDWORD):BOOL ; stdcall;<br><br>function CryptContextAddRef(hProv &nbsp; &nbsp; &nbsp; :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; :DWORD):BOOL ; stdcall;<br><br>function CryptDuplicateKey(hKey &nbsp; &nbsp; &nbsp; &nbsp;:HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; phKey &nbsp; &nbsp; &nbsp; :PHCRYPTKEY):BOOL ; stdcall;<br><br>function CryptDuplicateHash(hHash &nbsp; &nbsp; &nbsp; :HCRYPTHASH;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;phHash &nbsp; &nbsp; &nbsp;:PHCRYPTHASH):BOOL ; stdcall;<br><br>{$ENDIF NT5}<br><br>function CryptEnumProvidersU(dwIndex &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwReserved :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwProvType :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszProvName :LPWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbProvName :PDWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CRYPTOAPI BLOB definitions<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPTOAPI_BLOB = ^CRYPTOAPI_BLOB;<br> &nbsp;CRYPTOAPI_BLOB = record<br> &nbsp; &nbsp;cbData :DWORD;<br> &nbsp; &nbsp;pbData :PBYTE;<br> &nbsp;end;<br><br>type<br> &nbsp;CRYPT_INTEGER_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= CRYPTOAPI_BLOB;<br> &nbsp;PCRYPT_INTEGER_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = ^CRYPT_INTEGER_BLOB;<br> &nbsp;CRYPT_UINT_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = CRYPTOAPI_BLOB;<br> &nbsp;PCRYPT_UINT_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= ^CRYPT_UINT_BLOB;<br> &nbsp;CRYPT_OBJID_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= CRYPTOAPI_BLOB;<br> &nbsp;PCRYPT_OBJID_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = ^CRYPT_OBJID_BLOB;<br> &nbsp;CERT_NAME_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= CRYPTOAPI_BLOB;<br> &nbsp;PCERT_NAME_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = ^CERT_NAME_BLOB;<br> &nbsp;CERT_RDN_VALUE_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = CRYPTOAPI_BLOB;<br> &nbsp;PCERT_RDN_VALUE_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= ^CERT_RDN_VALUE_BLOB;<br> &nbsp;CERT_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = CRYPTOAPI_BLOB;<br> &nbsp;PCERT_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= ^CERT_BLOB;<br> &nbsp;CRL_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= CRYPTOAPI_BLOB;<br> &nbsp;PCRL_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = ^CRL_BLOB;<br> &nbsp;DATA_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = CRYPTOAPI_BLOB;<br> &nbsp;PDATA_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= ^DATA_BLOB; &nbsp; &nbsp; // JEFFJEFF temporary (too generic)<br> &nbsp;CRYPT_DATA_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = CRYPTOAPI_BLOB;<br> &nbsp;PCRYPT_DATA_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= ^CRYPT_DATA_BLOB;<br> &nbsp;CRYPT_HASH_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = CRYPTOAPI_BLOB;<br> &nbsp;PCRYPT_HASH_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= ^CRYPT_HASH_BLOB;<br> &nbsp;CRYPT_DIGEST_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = CRYPTOAPI_BLOB;<br> &nbsp;PCRYPT_DIGEST_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= ^CRYPT_DIGEST_BLOB;<br> &nbsp;CRYPT_DER_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= CRYPTOAPI_BLOB;<br> &nbsp;PCRYPT_DER_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = ^CRYPT_DER_BLOB;<br> &nbsp;CRYPT_ATTR_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = CRYPTOAPI_BLOB;<br> &nbsp;PCRYPT_ATTR_BLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= ^CRYPT_ATTR_BLOB;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;In a CRYPT_BIT_BLOB the last byte may contain 0-7 unused bits. Therefore, the<br>// &nbsp;overall bit length is cbData * 8 - cUnusedBits.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_BIT_BLOB = ^CRYPT_BIT_BLOB;<br> &nbsp;CRYPT_BIT_BLOB = record<br> &nbsp; &nbsp;cbData &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;pbData &nbsp; &nbsp; &nbsp;:PBYTE;<br> &nbsp; &nbsp;cUnusedBits :DWORD;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Type used for any algorithm<br>//<br>// &nbsp;Where the Parameters CRYPT_OBJID_BLOB is in its encoded representation. For most<br>// &nbsp;algorithm types, the Parameters CRYPT_OBJID_BLOB is NULL (Parameters.cbData = 0).<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_ALGORITHM_IDENTIFIER = ^CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp;CRYPT_ALGORITHM_IDENTIFIER = record<br> &nbsp; &nbsp;pszObjId &nbsp; :LPSTR;<br> &nbsp; &nbsp;Parameters :CRYPT_OBJID_BLOB;<br> &nbsp;end;<br><br>// Following are the definitions of various algorithm object identifiers<br>// RSA<br>const <br> &nbsp;szOID_RSA &nbsp; &nbsp; &nbsp; &nbsp; = '1.2.840.113549';<br> &nbsp;szOID_PKCS &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1';<br> &nbsp;szOID_RSA_HASH &nbsp; &nbsp;= '1.2.840.113549.2';<br> &nbsp;szOID_RSA_ENCRYPT = '1.2.840.113549.3';<br><br> &nbsp;szOID_PKCS_1 &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.1';<br> &nbsp;szOID_PKCS_2 &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.2';<br> &nbsp;szOID_PKCS_3 &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.3';<br> &nbsp;szOID_PKCS_4 &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.4';<br> &nbsp;szOID_PKCS_5 &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.5';<br> &nbsp;szOID_PKCS_6 &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.6';<br> &nbsp;szOID_PKCS_7 &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.7';<br> &nbsp;szOID_PKCS_8 &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.8';<br> &nbsp;szOID_PKCS_9 &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.9';<br> &nbsp;szOID_PKCS_10 &nbsp; &nbsp; = '1.2.840.113549.1.10';<br><br> &nbsp;szOID_RSA_RSA &nbsp; &nbsp; = '1.2.840.113549.1.1.1';<br> &nbsp;szOID_RSA_MD2RSA &nbsp;= '1.2.840.113549.1.1.2';<br> &nbsp;szOID_RSA_MD4RSA &nbsp;= '1.2.840.113549.1.1.3';<br> &nbsp;szOID_RSA_MD5RSA &nbsp;= '1.2.840.113549.1.1.4';<br> &nbsp;szOID_RSA_SHA1RSA = '1.2.840.113549.1.1.5';<br> &nbsp;szOID_RSA_SETOAEP_RSA &nbsp;= '1.2.840.113549.1.1.6';<br> &nbsp;<br> &nbsp;szOID_RSA_data &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.7.1';<br> &nbsp;szOID_RSA_signedData &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.7.2';<br> &nbsp;szOID_RSA_envelopedData &nbsp; &nbsp;= '1.2.840.113549.1.7.3';<br> &nbsp;szOID_RSA_signEnvData &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.7.4';<br> &nbsp;szOID_RSA_digestedData &nbsp; &nbsp; = '1.2.840.113549.1.7.5';<br> &nbsp;szOID_RSA_hashedData &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.7.5';<br> &nbsp;szOID_RSA_encryptedData &nbsp; &nbsp;= '1.2.840.113549.1.7.6';<br><br> &nbsp;szOID_RSA_emailAddr &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.9.1';<br> &nbsp;szOID_RSA_unstructName &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.9.2';<br> &nbsp;szOID_RSA_contentType &nbsp; &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.9.3';<br> &nbsp;szOID_RSA_messageDigest &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.9.4';<br> &nbsp;szOID_RSA_signingTime &nbsp; &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.9.5';<br> &nbsp;szOID_RSA_counterSign &nbsp; &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.9.6';<br> &nbsp;szOID_RSA_challengePwd &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.9.7';<br> &nbsp;szOID_RSA_unstructAddr &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.9.8';<br> &nbsp;szOID_RSA_extCertAttrs &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.9.9';<br> &nbsp;szOID_RSA_SMIMECapabilities &nbsp; = '1.2.840.113549.1.9.15';<br> &nbsp;szOID_RSA_preferSignedData &nbsp; &nbsp;= '1.2.840.113549.1.9.15.1';<br><br> &nbsp;szOID_RSA_MD2 = '1.2.840.113549.2.2';<br> &nbsp;szOID_RSA_MD4 = '1.2.840.113549.2.4';<br> &nbsp;szOID_RSA_MD5 = '1.2.840.113549.2.5';<br><br> &nbsp;szOID_RSA_RC2CBC &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.3.2';<br> &nbsp;szOID_RSA_RC4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.2.840.113549.3.4';<br> &nbsp;szOID_RSA_DES_EDE3_CBC &nbsp;= '1.2.840.113549.3.7';<br> &nbsp;szOID_RSA_RC5_CBCPad &nbsp; &nbsp;= '1.2.840.113549.3.9';<br><br>// ITU-T UsefulDefinitions<br> &nbsp;szOID_DS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5';<br> &nbsp;szOID_DSALG &nbsp; &nbsp; &nbsp; = '2.5.8';<br> &nbsp;szOID_DSALG_CRPT &nbsp;= '2.5.8.1';<br> &nbsp;szOID_DSALG_HASH &nbsp;= '2.5.8.2';<br> &nbsp;szOID_DSALG_SIGN &nbsp;= '2.5.8.3';<br> &nbsp;szOID_DSALG_RSA &nbsp; = '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> &nbsp;szOID_OIW &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '1.3.14';<br>// NIST OSE Implementors' Workshop (OIW) Security SIG algorithm identifiers<br> &nbsp;szOID_OIWSEC &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.14.3.2';<br> &nbsp;szOID_OIWSEC_md4RSA &nbsp;= '1.3.14.3.2.2';<br> &nbsp;szOID_OIWSEC_md5RSA &nbsp;= '1.3.14.3.2.3';<br> &nbsp;szOID_OIWSEC_md4RSA2 = '1.3.14.3.2.4';<br> &nbsp;szOID_OIWSEC_desECB &nbsp;= '1.3.14.3.2.6';<br> &nbsp;szOID_OIWSEC_desCBC &nbsp;= '1.3.14.3.2.7';<br> &nbsp;szOID_OIWSEC_desOFB &nbsp;= '1.3.14.3.2.8';<br> &nbsp;szOID_OIWSEC_desCFB &nbsp;= '1.3.14.3.2.9';<br> &nbsp;szOID_OIWSEC_desMAC &nbsp;= '1.3.14.3.2.10';<br> &nbsp;szOID_OIWSEC_rsaSign = '1.3.14.3.2.11';<br> &nbsp;szOID_OIWSEC_dsa &nbsp; &nbsp; = '1.3.14.3.2.12';<br> &nbsp;szOID_OIWSEC_shaDSA &nbsp;= '1.3.14.3.2.13';<br> &nbsp;szOID_OIWSEC_mdc2RSA = '1.3.14.3.2.14';<br> &nbsp;szOID_OIWSEC_shaRSA &nbsp;= '1.3.14.3.2.15';<br> &nbsp;szOID_OIWSEC_dhCommMod = '1.3.14.3.2.16';<br> &nbsp;szOID_OIWSEC_desEDE &nbsp; &nbsp;= '1.3.14.3.2.17';<br> &nbsp;szOID_OIWSEC_sha &nbsp; &nbsp; &nbsp; = '1.3.14.3.2.18';<br> &nbsp;szOID_OIWSEC_mdc2 &nbsp; &nbsp; &nbsp;= '1.3.14.3.2.19';<br> &nbsp;szOID_OIWSEC_dsaComm &nbsp; = '1.3.14.3.2.20';<br> &nbsp;szOID_OIWSEC_dsaCommSHA &nbsp;= '1.3.14.3.2.21';<br> &nbsp;szOID_OIWSEC_rsaXchg &nbsp; &nbsp; = '1.3.14.3.2.22';<br> &nbsp;szOID_OIWSEC_keyHashSeal = '1.3.14.3.2.23';<br> &nbsp;szOID_OIWSEC_md2RSASign &nbsp;= '1.3.14.3.2.24';<br> &nbsp;szOID_OIWSEC_md5RSASign &nbsp;= '1.3.14.3.2.25';<br> &nbsp;szOID_OIWSEC_sha1 &nbsp; &nbsp; &nbsp; &nbsp;= '1.3.14.3.2.26';<br> &nbsp;szOID_OIWSEC_dsaSHA1 &nbsp; &nbsp; = '1.3.14.3.2.27';<br> &nbsp;szOID_OIWSEC_dsaCommSHA1 = &nbsp;'1.3.14.3.2.28';<br> &nbsp;szOID_OIWSEC_sha1RSASign = &nbsp;'1.3.14.3.2.29';<br>// NIST OSE Implementors' Workshop (OIW) Directory SIG algorithm identifiers<br> &nbsp;szOID_OIWDIR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.14.7.2';<br> &nbsp;szOID_OIWDIR_CRPT &nbsp; &nbsp; &nbsp; &nbsp;= '1.3.14.7.2.1';<br> &nbsp;szOID_OIWDIR_HASH &nbsp; &nbsp; &nbsp; &nbsp;= '1.3.14.7.2.2';<br> &nbsp;szOID_OIWDIR_SIGN &nbsp; &nbsp; &nbsp; &nbsp;= '1.3.14.7.2.3';<br> &nbsp;szOID_OIWDIR_md2 &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.14.7.2.2.1';<br> &nbsp;szOID_OIWDIR_md2RSA &nbsp; &nbsp; &nbsp;= '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> &nbsp;szOID_INFOSEC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.16.840.1.101.2.1';<br> &nbsp;szOID_INFOSEC_sdnsSignature &nbsp; &nbsp; &nbsp; &nbsp; = '2.16.840.1.101.2.1.1.1';<br> &nbsp;szOID_INFOSEC_mosaicSignature &nbsp; &nbsp; &nbsp; = '2.16.840.1.101.2.1.1.2';<br> &nbsp;szOID_INFOSEC_sdnsConfidentiality &nbsp; = '2.16.840.1.101.2.1.1.3';<br> &nbsp;szOID_INFOSEC_mosaicConfidentiality = '2.16.840.1.101.2.1.1.4';<br> &nbsp;szOID_INFOSEC_sdnsIntegrity &nbsp; &nbsp; &nbsp; &nbsp; = '2.16.840.1.101.2.1.1.5';<br> &nbsp;szOID_INFOSEC_mosaicIntegrity &nbsp; &nbsp; &nbsp; = '2.16.840.1.101.2.1.1.6';<br> &nbsp;szOID_INFOSEC_sdnsTokenProtection &nbsp; = '2.16.840.1.101.2.1.1.7';<br> &nbsp;szOID_INFOSEC_mosaicTokenProtection = '2.16.840.1.101.2.1.1.8';<br> &nbsp;szOID_INFOSEC_sdnsKeyManagement &nbsp; &nbsp; = '2.16.840.1.101.2.1.1.9';<br> &nbsp;szOID_INFOSEC_mosaicKeyManagement &nbsp; = '2.16.840.1.101.2.1.1.10';<br> &nbsp;szOID_INFOSEC_sdnsKMandSig &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.16.840.1.101.2.1.1.11';<br> &nbsp;szOID_INFOSEC_mosaicKMandSig &nbsp; &nbsp; &nbsp; &nbsp;= '2.16.840.1.101.2.1.1.12';<br> &nbsp;szOID_INFOSEC_SuiteASignature &nbsp; &nbsp; &nbsp; = '2.16.840.1.101.2.1.1.13';<br> &nbsp;szOID_INFOSEC_SuiteAConfidentiality = '2.16.840.1.101.2.1.1.14';<br> &nbsp;szOID_INFOSEC_SuiteAIntegrity &nbsp; &nbsp; &nbsp; = '2.16.840.1.101.2.1.1.15';<br> &nbsp;szOID_INFOSEC_SuiteATokenProtection = '2.16.840.1.101.2.1.1.16';<br> &nbsp;szOID_INFOSEC_SuiteAKeyManagement &nbsp; = '2.16.840.1.101.2.1.1.17';<br> &nbsp;szOID_INFOSEC_SuiteAKMandSig &nbsp; &nbsp; &nbsp; &nbsp;= '2.16.840.1.101.2.1.1.18';<br> &nbsp;szOID_INFOSEC_mosaicUpdatedSig &nbsp; &nbsp; &nbsp;= '2.16.840.1.101.2.1.1.19';<br> &nbsp;szOID_INFOSEC_mosaicKMandUpdSig &nbsp; &nbsp; = '2.16.840.1.101.2.1.1.20';<br> &nbsp;szOID_INFOSEC_mosaicUpdatedInteg &nbsp; &nbsp;= '2.16.840.1.101.2.1.1.21';<br><br>type<br> &nbsp;PCRYPT_OBJID_TABLE = ^CRYPT_OBJID_TABLE;<br> &nbsp;CRYPT_OBJID_TABLE = record<br> &nbsp; &nbsp;dwAlgId &nbsp;:DWORD;<br> &nbsp; &nbsp;pszObjId :LPCSTR;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;PKCS #1 HashInfo (DigestInfo)<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_HASH_INFO = ^CRYPT_HASH_INFO;<br> &nbsp;CRYPT_HASH_INFO = record<br> &nbsp; &nbsp;HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;Hash :CRYPT_HASH_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Type used for an extension to an encoded content<br>//<br>// &nbsp;Where the Value's CRYPT_OBJID_BLOB is in its encoded representation.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_EXTENSION = ^CERT_EXTENSION;<br> &nbsp;CERT_EXTENSION = record<br> &nbsp; &nbsp;pszObjId :LPSTR;<br> &nbsp; &nbsp;fCritical :BOOL;<br> &nbsp; &nbsp;Value :CRYPT_OBJID_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;AttributeTypeValue<br>//<br>// &nbsp;Where the Value's CRYPT_OBJID_BLOB is in its encoded representation.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_ATTRIBUTE_TYPE_VALUE =^CRYPT_ATTRIBUTE_TYPE_VALUE;<br> &nbsp;CRYPT_ATTRIBUTE_TYPE_VALUE = record<br> &nbsp; &nbsp;pszObjId :LPSTR;<br> &nbsp; &nbsp;Value :CRYPT_OBJID_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Attributes<br>//<br>// &nbsp;Where the Value's PATTR_BLOBs are in their encoded representation.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_ATTRIBUTE = ^CRYPT_ATTRIBUTE;<br> &nbsp;CRYPT_ATTRIBUTE = record<br> &nbsp; &nbsp; pszObjId :LPSTR;<br> &nbsp; &nbsp; cValue :DWORD;<br> &nbsp; &nbsp; rgValue :PCRYPT_ATTR_BLOB;<br> &nbsp;end;<br><br>type<br> &nbsp;PCRYPT_ATTRIBUTES =^CRYPT_ATTRIBUTES;<br> &nbsp;CRYPT_ATTRIBUTES = record<br> &nbsp; &nbsp;cAttr &nbsp;:DWORD; {IN}<br> &nbsp; &nbsp;rgAttr :PCRYPT_ATTRIBUTE; {IN}<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Attributes making up a Relative Distinguished Name (CERT_RDN)<br>//<br>// &nbsp;The interpretation of the Value depends on the dwValueType.<br>// &nbsp;See below for a list of the types.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_RDN_ATTR = ^CERT_RDN_ATTR;<br> &nbsp;CERT_RDN_ATTR = record<br> &nbsp; &nbsp;pszObjId :LPSTR;<br> &nbsp; &nbsp;dwValueType :DWORD;<br> &nbsp; &nbsp;Value :CERT_RDN_VALUE_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_RDN attribute Object Identifiers<br>//--------------------------------------------------------------------------<br>// Labeling attribute types:<br>const <br> &nbsp;szOID_COMMON_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.3'; &nbsp;// case-ignore string<br> &nbsp;szOID_SUR_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.4.4'; &nbsp;// case-ignore string<br> &nbsp;szOID_DEVICE_SERIAL_NUMBER = '2.5.4.5'; &nbsp;// printable string<br><br>// Geographic attribute types:<br> &nbsp;szOID_COUNTRY_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.6'; &nbsp;// printable 2char string<br> &nbsp;szOID_LOCALITY_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.4.7'; &nbsp;// case-ignore string<br> &nbsp;szOID_STATE_OR_PROVINCE_NAME &nbsp;= '2.5.4.8'; &nbsp;// case-ignore string<br> &nbsp;szOID_STREET_ADDRESS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.9'; &nbsp;// case-ignore string<br><br>// Organizational attribute types:<br> &nbsp;szOID_ORGANIZATION_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.10';// case-ignore string<br> &nbsp;szOID_ORGANIZATIONAL_UNIT_NAME &nbsp; = '2.5.4.11'; // case-ignore string<br> &nbsp;szOID_TITLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.12'; // case-ignore string<br><br>// Explanatory attribute types:<br> &nbsp;szOID_DESCRIPTION &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.13'; // case-ignore string<br> &nbsp;szOID_SEARCH_GUIDE &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.4.14';<br> &nbsp;szOID_BUSINESS_CATEGORY &nbsp; &nbsp;= '2.5.4.15'; // case-ignore string<br><br>// Postal addressing attribute types:<br> &nbsp;szOID_POSTAL_ADDRESS &nbsp; &nbsp; &nbsp; = '2.5.4.16';<br> &nbsp;szOID_POSTAL_CODE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.17'; // case-ignore string<br> &nbsp;szOID_POST_OFFICE_BOX &nbsp; &nbsp; &nbsp;= '2.5.4.18'; // case-ignore string<br> &nbsp;szOID_PHYSICAL_DELIVERY_OFFICE_NAME = '2.5.4.19'; // case-ignore string<br><br>// Telecommunications addressing attribute types:<br> &nbsp;szOID_TELEPHONE_NUMBER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.20'; // telephone number<br> &nbsp;szOID_TELEX_NUMBER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.21';<br> &nbsp;szOID_TELETEXT_TERMINAL_IDENTIFIER &nbsp;= '2.5.4.22';<br> &nbsp;szOID_FACSIMILE_TELEPHONE_NUMBER &nbsp; &nbsp;= '2.5.4.23';<br> &nbsp;szOID_X21_ADDRESS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.4.24'; // numeric string<br> &nbsp;szOID_INTERNATIONAL_ISDN_NUMBER &nbsp; &nbsp; = '2.5.4.25'; // numeric string<br> &nbsp;szOID_REGISTERED_ADDRESS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.26';<br> &nbsp;szOID_DESTINATION_INDICATOR &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.4.27'; // printable string<br><br>// Preference attribute types:<br> &nbsp;szOID_PREFERRED_DELIVERY_METHOD &nbsp; &nbsp; = '2.5.4.28';<br><br>// OSI application attribute types:<br> &nbsp;szOID_PRESENTATION_ADDRESS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.29';<br> &nbsp;szOID_SUPPORTED_APPLICATION_CONTEXT = '2.5.4.30';<br><br>// Relational application attribute types:<br> &nbsp;szOID_MEMBER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.31';<br> &nbsp;szOID_OWNER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.4.32';<br> &nbsp;szOID_ROLE_OCCUPANT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.4.33';<br> &nbsp;szOID_SEE_ALSO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.34';<br><br>// Security attribute types:<br> &nbsp;szOID_USER_PASSWORD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.4.35';<br> &nbsp;szOID_USER_CERTIFICATE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.36';<br> &nbsp;szOID_CA_CERTIFICATE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.37';<br> &nbsp;szOID_AUTHORITY_REVOCATION_LIST &nbsp; &nbsp; = '2.5.4.38';<br> &nbsp;szOID_CERTIFICATE_REVOCATION_LIST &nbsp; = '2.5.4.39';<br> &nbsp;szOID_CROSS_CERTIFICATE_PAIR &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.40';<br><br>// Undocumented attribute types???<br>//#define szOID_??? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '2.5.4.41'<br> &nbsp;szOID_GIVEN_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.42'; // case-ignore string<br> &nbsp;szOID_INITIALS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.4.43'; // case-ignore string<br><br>// Pilot user attribute types:<br> &nbsp;szOID_DOMAIN_COMPONENT &nbsp; &nbsp; &nbsp;= '0.9.2342.19200300.100.1.25'; // IA5 string<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_RDN Attribute Value Types<br>//<br>// &nbsp;For RDN_ENCODED_BLOB, the Value's CERT_RDN_VALUE_BLOB is in its encoded<br>// &nbsp;representation. Otherwise, its an array of bytes.<br>//<br>// &nbsp;For all CERT_RDN types, Value.cbData is always the number of bytes, not<br>// &nbsp;necessarily the number of elements in the string. For instance,<br>// &nbsp;RDN_UNIVERSAL_STRING is an array of ints (cbData == intCnt * 4) and<br>// &nbsp;RDN_BMP_STRING is an array of unsigned shorts (cbData == ushortCnt * 2).<br>//<br>// &nbsp;For CertDecodeName, two 0 bytes are always appended to the end of the<br>// &nbsp;string (ensures a CHAR or WCHAR string is null terminated).<br>// &nbsp;These added 0 bytes are't included in the BLOB.cbData.<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CERT_RDN_ANY_TYPE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 0;<br> &nbsp;CERT_RDN_ENCODED_BLOB &nbsp; &nbsp; &nbsp; &nbsp; = 1;<br> &nbsp;CERT_RDN_OCTET_STRING &nbsp; &nbsp; &nbsp; &nbsp; = 2;<br> &nbsp;CERT_RDN_NUMERIC_STRING &nbsp; &nbsp; &nbsp; = 3;<br> &nbsp;CERT_RDN_PRINTABLE_STRING &nbsp; &nbsp; = 4;<br> &nbsp;CERT_RDN_TELETEX_STRING &nbsp; &nbsp; &nbsp; = 5;<br> &nbsp;CERT_RDN_T61_STRING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 5;<br> &nbsp;CERT_RDN_VIDEOTEX_STRING &nbsp; &nbsp; &nbsp;= 6;<br> &nbsp;CERT_RDN_IA5_STRING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 7;<br> &nbsp;CERT_RDN_GRAPHIC_STRING &nbsp; &nbsp; &nbsp; = 8;<br> &nbsp;CERT_RDN_VISIBLE_STRING &nbsp; &nbsp; &nbsp; = 9;<br> &nbsp;CERT_RDN_ISO646_STRING &nbsp; &nbsp; &nbsp; &nbsp;= 9;<br> &nbsp;CERT_RDN_GENERAL_STRING &nbsp; &nbsp; &nbsp; = 10;<br> &nbsp;CERT_RDN_UNIVERSAL_STRING &nbsp; &nbsp; = 11;<br> &nbsp;CERT_RDN_INT4_STRING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 11;<br> &nbsp;CERT_RDN_BMP_STRING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 12;<br> &nbsp;CERT_RDN_UNICODE_STRING &nbsp; &nbsp; &nbsp; = 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 :DWORD) :BOOL;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;A CERT_RDN consists of an array of the above attributes<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_RDN = ^CERT_RDN;<br> &nbsp;CERT_RDN = record<br> &nbsp; &nbsp;cRDNAttr :DWORD;<br> &nbsp; &nbsp;rgRDNAttr :PCERT_RDN_ATTR;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Information stored in a subject's or issuer's name. The information<br>// &nbsp;is represented as an array of the above RDNs.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_NAME_INFO = ^CERT_NAME_INFO;<br> &nbsp;CERT_NAME_INFO = record<br> &nbsp; &nbsp;cRDN :DWORD;<br> &nbsp; &nbsp;rgRDN :PCERT_RDN;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Name attribute value without the Object Identifier<br>//<br>// &nbsp;The interpretation of the Value depends on the dwValueType.<br>// &nbsp;See above for a list of the types.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_NAME_VALUE = ^CERT_NAME_VALUE;<br> &nbsp;CERT_NAME_VALUE = record<br> &nbsp; &nbsp;dwValueType :DWORD;<br> &nbsp; &nbsp;Value :CERT_RDN_VALUE_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Public Key Info<br>//<br>// &nbsp;The PublicKey is the encoded representation of the information as it is<br>// &nbsp;stored in the bit string<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_PUBLIC_KEY_INFO = ^CERT_PUBLIC_KEY_INFO;<br> &nbsp;CERT_PUBLIC_KEY_INFO = record<br> &nbsp; &nbsp;Algorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;PublicKey :CRYPT_BIT_BLOB;<br> &nbsp;end;<br><br>const <br> &nbsp;CERT_RSA_PUBLIC_KEY_OBJID &nbsp; &nbsp; &nbsp; &nbsp;= szOID_RSA_RSA;<br> &nbsp;CERT_DEFAULT_OID_PUBLIC_KEY_SIGN = szOID_RSA_RSA;<br> &nbsp;CERT_DEFAULT_OID_PUBLIC_KEY_XCHG = szOID_RSA_RSA;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Information stored in a certificate<br>//<br>// &nbsp;The Issuer, Subject, Algorithm, PublicKey and Extension BLOBs are the<br>// &nbsp;encoded representation of the information.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_INFO = ^CERT_INFO;<br> &nbsp;CERT_INFO = record<br> &nbsp; &nbsp;dwVersion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;SerialNumber &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :CRYPT_INTEGER_BLOB;<br> &nbsp; &nbsp;SignatureAlgorithm &nbsp; &nbsp; :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;Issuer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :CERT_NAME_BLOB;<br> &nbsp; &nbsp;NotBefore &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:TFILETIME;<br> &nbsp; &nbsp;NotAfter &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :TFILETIME;<br> &nbsp; &nbsp;Subject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:CERT_NAME_BLOB;<br> &nbsp; &nbsp;SubjectPublicKeyInfo &nbsp; :CERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp;IssuerUniqueId &nbsp; &nbsp; &nbsp; &nbsp; :CRYPT_BIT_BLOB;<br> &nbsp; &nbsp;SubjectUniqueId &nbsp; &nbsp; &nbsp; &nbsp;:CRYPT_BIT_BLOB;<br> &nbsp; &nbsp;cExtension &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;rgExtension &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:PCERT_EXTENSION;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate versions<br>//--------------------------------------------------------------------------<br>const <br> &nbsp;CERT_V1 = 0;<br> &nbsp;CERT_V2 = 1;<br> &nbsp;CERT_V3 = 2;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Information Flags<br>//--------------------------------------------------------------------------<br><br> &nbsp;CERT_INFO_VERSION_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 1;<br> &nbsp;CERT_INFO_SERIAL_NUMBER_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 2;<br> &nbsp;CERT_INFO_SIGNATURE_ALGORITHM_FLAG &nbsp; &nbsp; = 3;<br> &nbsp;CERT_INFO_ISSUER_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 4;<br> &nbsp;CERT_INFO_NOT_BEFORE_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 5;<br> &nbsp;CERT_INFO_NOT_AFTER_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 6;<br> &nbsp;CERT_INFO_SUBJECT_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 7;<br> &nbsp;CERT_INFO_SUBJECT_PUBLIC_KEY_INFO_FLAG = 8;<br> &nbsp;CERT_INFO_ISSUER_UNIQUE_ID_FLAG &nbsp; &nbsp; &nbsp; &nbsp;= 9;<br> &nbsp;CERT_INFO_SUBJECT_UNIQUE_ID_FLAG &nbsp; &nbsp; &nbsp; = 10;<br> &nbsp;CERT_INFO_EXTENSION_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 11;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;An entry in a CRL<br>//<br>// &nbsp;The Extension BLOBs are the encoded representation of the information.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRL_ENTRY = ^CRL_ENTRY;<br> &nbsp;CRL_ENTRY = record<br> &nbsp; &nbsp;SerialNumber :CRYPT_INTEGER_BLOB;<br> &nbsp; &nbsp;RevocationDate :TFILETIME;<br> &nbsp; &nbsp;cExtension :DWORD;<br> &nbsp; &nbsp;rgExtension :PCERT_EXTENSION;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Information stored in a CRL<br>//<br>// &nbsp;The Issuer, Algorithm and Extension BLOBs are the encoded<br>// &nbsp;representation of the information.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRL_INFO = ^CRL_INFO;<br> &nbsp;CRL_INFO = record<br> &nbsp; &nbsp;dwVersion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;SignatureAlgorithm &nbsp;:CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;Issuer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:CERT_NAME_BLOB;<br> &nbsp; &nbsp;ThisUpdate &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:TFILETIME;<br> &nbsp; &nbsp;NextUpdate &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:TFILETIME;<br> &nbsp; &nbsp;cCRLEntry &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;rgCRLEntry &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:PCRL_ENTRY;<br> &nbsp; &nbsp;cExtension &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;rgExtension &nbsp; &nbsp; &nbsp; &nbsp; :PCERT_EXTENSION;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CRL versions<br>//--------------------------------------------------------------------------<br>const <br> &nbsp;CRL_V1 = 0;<br> &nbsp;CRL_V2 = 1;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Information stored in a certificate request<br>//<br>// &nbsp;The Subject, Algorithm, PublicKey and Attribute BLOBs are the encoded<br>// &nbsp;representation of the information.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_REQUEST_INFO = ^CERT_REQUEST_INFO;<br> &nbsp;CERT_REQUEST_INFO = record<br> &nbsp; &nbsp;dwVersion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;Subject &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:CERT_NAME_BLOB;<br> &nbsp; &nbsp;SubjectPublicKeyInfo :CERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp;cAttribute &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;rgAttribute &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:PCRYPT_ATTRIBUTE;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Request versions<br>//--------------------------------------------------------------------------<br>const CERT_REQUEST_V1 = 0;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Information stored in Netscape's Keygen request<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCERT_KEYGEN_REQUEST_INFO = ^CERT_KEYGEN_REQUEST_INFO;<br> &nbsp;CERT_KEYGEN_REQUEST_INFO = record<br> &nbsp; &nbsp;dwVersion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;SubjectPublicKeyInfo :CERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp;pwszChallengeString &nbsp;:LPWSTR; &nbsp; &nbsp; &nbsp; &nbsp;// encoded as IA5<br> &nbsp;end;<br><br>const <br> &nbsp;CERT_KEYGEN_REQUEST_V1 = 0;<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate, CRL, Certificate Request or Keygen Request Signed Content<br>//<br>// &nbsp;The &quot;to be signed&quot; encoded content plus its signature. The ToBeSigned<br>// &nbsp;is the encoded CERT_INFO, CRL_INFO, CERT_REQUEST_INFO or<br>// &nbsp;CERT_KEYGEN_REQUEST_INFO.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCERT_SIGNED_CONTENT_INFO = ^CERT_SIGNED_CONTENT_INFO;<br> &nbsp;CERT_SIGNED_CONTENT_INFO = record<br> &nbsp; &nbsp;ToBeSigned &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:CRYPT_DER_BLOB;<br> &nbsp; &nbsp;SignatureAlgorithm &nbsp;:CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;Signature &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :CRYPT_BIT_BLOB;<br>end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Trust List (CTL)<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CTL Usage. Also used for EnhancedKeyUsage extension.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCTL_USAGE =^CTL_USAGE;<br> &nbsp;CTL_USAGE = record<br> &nbsp; &nbsp;cUsageIdentifier :DWORD;<br> &nbsp; &nbsp;rgpszUsageIdentifier :PLPSTR; &nbsp; &nbsp; &nbsp;// array of pszObjId<br> &nbsp;end;<br><br>type<br> &nbsp;CERT_ENHKEY_USAGE = CTL_USAGE;<br> &nbsp;PCERT_ENHKEY_USAGE = ^CERT_ENHKEY_USAGE;<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;An entry in a CTL<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCTL_ENTRY = ^CTL_ENTRY;<br> &nbsp;CTL_ENTRY = record<br> &nbsp; &nbsp;SubjectIdentifier :CRYPT_DATA_BLOB; &nbsp; &nbsp;// For example, its hash<br> &nbsp; &nbsp;cAttribute &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;rgAttribute &nbsp; &nbsp; &nbsp; :PCRYPT_ATTRIBUTE; &nbsp; // OPTIONAL<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Information stored in a CTL<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCTL_INFO = ^CTL_INFO;<br> &nbsp;CTL_INFO = record<br> &nbsp; &nbsp;dwVersion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;SubjectUsage &nbsp; &nbsp; &nbsp; &nbsp;:CTL_USAGE;<br> &nbsp; &nbsp;ListIdentifier &nbsp; &nbsp; &nbsp;:CRYPT_DATA_BLOB; &nbsp; &nbsp; // OPTIONAL<br> &nbsp; &nbsp;SequenceNumber &nbsp; &nbsp; &nbsp;:CRYPT_INTEGER_BLOB; &nbsp;// OPTIONAL<br> &nbsp; &nbsp;ThisUpdate &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:TFILETIME;<br> &nbsp; &nbsp;NextUpdate &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:TFILETIME; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // OPTIONAL<br> &nbsp; &nbsp;SubjectAlgorithm &nbsp; &nbsp;:CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;cCTLEntry &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;rgCTLEntry &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:PCTL_ENTRY; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// OPTIONAL<br> &nbsp; &nbsp;cExtension &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;rgExtension &nbsp; &nbsp; &nbsp; &nbsp; :PCERT_EXTENSION; &nbsp; &nbsp; // OPTIONAL<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CTL versions<br>//--------------------------------------------------------------------------<br>const <br> &nbsp;CTL_V1 = 0;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;TimeStamp Request<br>//<br>// &nbsp;The pszTimeStamp is the OID for the Time type requested<br>// &nbsp;The pszContentType is the Content Type OID for the content, usually DATA<br>// &nbsp;The Content is a un-decoded blob<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_TIME_STAMP_REQUEST_INFO = ^CRYPT_TIME_STAMP_REQUEST_INFO;<br> &nbsp;CRYPT_TIME_STAMP_REQUEST_INFO = record<br> &nbsp; &nbsp;pszTimeStampAlgorithm :LPSTR; &nbsp; // pszObjId<br> &nbsp; &nbsp;pszContentType &nbsp; &nbsp; &nbsp; &nbsp;:LPSTR; &nbsp; // pszObjId<br> &nbsp; &nbsp;Content &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :CRYPT_OBJID_BLOB;<br> &nbsp; &nbsp;cAttribute &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;rgAttribute &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :PCRYPT_ATTRIBUTE;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate and Message encoding types<br>//<br>// &nbsp;The encoding type is a DWORD containing both the certificate and message<br>// &nbsp;encoding types. The certificate encoding type is stored in the LOWORD.<br>// &nbsp;The message encoding type is stored in the HIWORD. Some functions or<br>// &nbsp;structure fields require only one of the encoding types. The following<br>// &nbsp;naming convention is used to indicate which encoding type(s) are<br>// &nbsp;required:<br>// &nbsp; &nbsp; &nbsp;dwEncodingType &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(both encoding types are required)<br>// &nbsp; &nbsp; &nbsp;dwMsgAndCertEncodingType &nbsp; &nbsp;(both encoding types are required)<br>// &nbsp; &nbsp; &nbsp;dwMsgEncodingType &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (only msg encoding type is required)<br>// &nbsp; &nbsp; &nbsp;dwCertEncodingType &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(only cert encoding type is required)<br>//<br>// &nbsp;Its always acceptable to specify both.<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CERT_ENCODING_TYPE_MASK = $0000FFFF;<br> &nbsp;CMSG_ENCODING_TYPE_MASK = $FFFF0000;<br><br>//#define GET_CERT_ENCODING_TYPE(X) &nbsp; (X & CERT_ENCODING_TYPE_MASK)<br>//#define GET_CMSG_ENCODING_TYPE(X) &nbsp; (X & CMSG_ENCODING_TYPE_MASK)<br>function GET_CERT_ENCODING_TYPE(X :DWORD):DWORD;<br>function GET_CMSG_ENCODING_TYPE(X :DWORD):DWORD;<br><br>const <br> &nbsp;CRYPT_ASN_ENCODING &nbsp;= $00000001;<br> &nbsp;CRYPT_NDR_ENCODING = $00000002;<br> &nbsp;X509_ASN_ENCODING = $00000001;<br> &nbsp;X509_NDR_ENCODING = $00000002;<br> &nbsp;PKCS_7_ASN_ENCODING = $00010000;<br> &nbsp;PKCS_7_NDR_ENCODING = $00020000;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;format the specified data structure according to the certificate<br>// &nbsp;encoding type.<br>//<br>//--------------------------------------------------------------------------<br><br>function CryptFormatObject(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFormatType &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFormatStrType &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pFormatStruct &nbsp; &nbsp; &nbsp;:PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lpszStructType &nbsp; &nbsp; :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbEncoded &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbEncoded &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbFormat &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbFormat &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:PDWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Encode / decode the specified data structure according to the certificate<br>// &nbsp;encoding type.<br>//<br>// &nbsp;See below for a list of the predefined data structures.<br>//--------------------------------------------------------------------------<br><br>function CryptEncodeObject(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lpszStructType &nbsp; &nbsp; :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pvStructInfo &nbsp; &nbsp; &nbsp; :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbEncoded &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbEncoded &nbsp; &nbsp; &nbsp; &nbsp; :PDWORD ):BOOL ; stdcall;<br><br>function CryptDecodeObject(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lpszStructType &nbsp; &nbsp; :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbEncoded &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbEncoded &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvStructInfo &nbsp; &nbsp; &nbsp; :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbStructInfo &nbsp; &nbsp; &nbsp;:PDWORD):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> &nbsp;CRYPT_DECODE_NOCOPY_FLAG = $1;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Predefined X509 certificate data structures that can be encoded / decoded.<br>//--------------------------------------------------------------------------<br> &nbsp;CRYPT_ENCODE_DECODE_NONE &nbsp; &nbsp; &nbsp; &nbsp; = 0;<br> &nbsp;X509_CERT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(1));<br> &nbsp;X509_CERT_TO_BE_SIGNED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (LPCSTR(2));<br> &nbsp;X509_CERT_CRL_TO_BE_SIGNED &nbsp; &nbsp; &nbsp; = (LPCSTR(3));<br> &nbsp;X509_CERT_REQUEST_TO_BE_SIGNED &nbsp; = (LPCSTR(4));<br> &nbsp;X509_EXTENSIONS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(5));<br> &nbsp;X509_NAME_VALUE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(6));<br> &nbsp;X509_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(7));<br> &nbsp;X509_PUBLIC_KEY_INFO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (LPCSTR(8));<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Predefined X509 certificate extension data structures that can be<br>// &nbsp;encoded / decoded.<br>//--------------------------------------------------------------------------<br> &nbsp;X509_AUTHORITY_KEY_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(9));<br> &nbsp;X509_KEY_ATTRIBUTES &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(10));<br> &nbsp;X509_KEY_USAGE_RESTRICTION &nbsp; &nbsp; &nbsp; = (LPCSTR(11));<br> &nbsp;X509_ALTERNATE_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(12));<br> &nbsp;X509_BASIC_CONSTRAINTS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(13));<br> &nbsp;X509_KEY_USAGE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (LPCSTR(14));<br> &nbsp;X509_BASIC_CONSTRAINTS2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(15));<br> &nbsp;X509_CERT_POLICIES &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (LPCSTR(16));<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Additional predefined data structures that can be encoded / decoded.<br>//--------------------------------------------------------------------------<br> &nbsp;PKCS_UTC_TIME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(17));<br> &nbsp;PKCS_TIME_REQUEST &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(18));<br> &nbsp;RSA_CSP_PUBLICKEYBLOB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(19));<br> &nbsp;X509_UNICODE_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(20));<br><br> &nbsp;X509_KEYGEN_REQUEST_TO_BE_SIGNED &nbsp;= (LPCSTR(21));<br> &nbsp;PKCS_ATTRIBUTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(22));<br> &nbsp;PKCS_CONTENT_INFO_SEQUENCE_OF_ANY = (LPCSTR(23));<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Predefined primitive data structures that can be encoded / decoded.<br>//--------------------------------------------------------------------------<br> &nbsp;X509_UNICODE_NAME_VALUE &nbsp; &nbsp;= (LPCSTR(24));<br> &nbsp;X509_ANY_STRING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= X509_NAME_VALUE;<br> &nbsp;X509_UNICODE_ANY_STRING &nbsp; &nbsp;= X509_UNICODE_NAME_VALUE;<br> &nbsp;X509_OCTET_STRING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(25));<br> &nbsp;X509_BITS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(26));<br> &nbsp;X509_INTEGER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (LPCSTR(27));<br> &nbsp;X509_MULTI_BYTE_INTEGER &nbsp; &nbsp;= (LPCSTR(28));<br> &nbsp;X509_ENUMERATED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(29));<br> &nbsp;X509_CHOICE_OF_TIME &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(30));<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;More predefined X509 certificate extension data structures that can be<br>// &nbsp;encoded / decoded.<br>//--------------------------------------------------------------------------<br><br> &nbsp;X509_AUTHORITY_KEY_ID2 &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(31));<br>// &nbsp;X509_AUTHORITY_INFO_ACCESS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(LPCSTR(32));<br> &nbsp;X509_CRL_REASON_CODE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= X509_ENUMERATED;<br> &nbsp;PKCS_CONTENT_INFO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (LPCSTR(33));<br> &nbsp;X509_SEQUENCE_OF_ANY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(34));<br> &nbsp;X509_CRL_DIST_POINTS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(35));<br> &nbsp;X509_ENHANCED_KEY_USAGE &nbsp; &nbsp; &nbsp; = (LPCSTR(36));<br> &nbsp;PKCS_CTL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(37));<br><br> &nbsp;X509_MULTI_BYTE_UINT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(38));<br> &nbsp;X509_DSS_PUBLICKEY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= &nbsp;X509_MULTI_BYTE_UINT;<br> &nbsp;X509_DSS_PARAMETERS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (LPCSTR(39));<br> &nbsp;X509_DSS_SIGNATURE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (LPCSTR(40));<br> &nbsp;PKCS_RC2_CBC_PARAMETERS &nbsp; &nbsp; &nbsp; = (LPCSTR(41));<br> &nbsp;PKCS_SMIME_CAPABILITIES &nbsp; &nbsp; &nbsp; = (LPCSTR(42));<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Predefined PKCS #7 data structures that can be encoded / decoded.<br>//--------------------------------------------------------------------------<br> &nbsp;PKCS7_SIGNER_INFO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (LPCSTR(500));<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Predefined Software Publishing Credential (SPC) &nbsp;data structures that<br>// &nbsp;can be encoded / decoded.<br>//<br>// &nbsp;Predefined values: 2000 .. 2999<br>//<br>// &nbsp;See spc.h for value and data structure definitions.<br>//--------------------------------------------------------------------------<br>//+-------------------------------------------------------------------------<br>// &nbsp;Extension Object Identifiers<br>//--------------------------------------------------------------------------<br>const <br> &nbsp;szOID_AUTHORITY_KEY_IDENTIFIER &nbsp; &nbsp; &nbsp;= '2.5.29.1';<br> &nbsp;szOID_KEY_ATTRIBUTES &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.29.2';<br> &nbsp;szOID_KEY_USAGE_RESTRICTION &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.4';<br> &nbsp;szOID_SUBJECT_ALT_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.29.7';<br> &nbsp;szOID_ISSUER_ALT_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.8';<br> &nbsp;szOID_BASIC_CONSTRAINTS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.10';<br> &nbsp;szOID_KEY_USAGE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.15';<br> &nbsp;szOID_BASIC_CONSTRAINTS2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.29.19';<br> &nbsp;szOID_CERT_POLICIES &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.32';<br><br> &nbsp;szOID_AUTHORITY_KEY_IDENTIFIER2 &nbsp; &nbsp; = &nbsp;'2.5.29.35';<br> &nbsp;szOID_SUBJECT_KEY_IDENTIFIER &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.29.14';<br> &nbsp;szOID_SUBJECT_ALT_NAME2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.17';<br> &nbsp;szOID_ISSUER_ALT_NAME2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.29.18';<br> &nbsp;szOID_CRL_REASON_CODE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.21';<br> &nbsp;szOID_CRL_DIST_POINTS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.31';<br> &nbsp;szOID_ENHANCED_KEY_USAGE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.5.29.37';<br><br><br>// Internet Public Key Infrastructure<br> &nbsp;szOID_PKIX &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '1.3.6.1.5.5.7';<br> &nbsp;szOID_AUTHORITY_INFO_ACCESS &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.6.1.5.5.7.2';<br><br>// Microsoft extensions or attributes<br> &nbsp;szOID_CERT_EXTENSIONS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.6.1.4.1.311.2.1.14';<br> &nbsp;szOID_NEXT_UPDATE_LOCATION &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '1.3.6.1.4.1.311.10.2';<br><br>// &nbsp;Microsoft PKCS #7 ContentType Object Identifiers<br> &nbsp;szOID_CTL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.6.1.4.1.311.10.1';<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Extension Object Identifiers (currently not implemented)<br>//--------------------------------------------------------------------------<br> &nbsp;szOID_POLICY_MAPPINGS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.5';<br> &nbsp;szOID_SUBJECT_DIR_ATTRS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.5.29.9';<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Enhanced Key Usage (Purpose) Object Identifiers<br>//--------------------------------------------------------------------------<br>const szOID_PKIX_KP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.6.1.5.5.7.3';<br><br>// Consistent key usage bits: DIGITAL_SIGNATURE, KEY_ENCIPHERMENT<br>// or KEY_AGREEMENT<br> &nbsp;szOID_PKIX_KP_SERVER_AUTH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.6.1.5.5.7.3.1';<br><br>// Consistent key usage bits: DIGITAL_SIGNATURE<br> &nbsp;szOID_PKIX_KP_CLIENT_AUTH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.6.1.5.5.7.3.2';<br><br>// Consistent key usage bits: DIGITAL_SIGNATURE<br> &nbsp;szOID_PKIX_KP_CODE_SIGNING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '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> &nbsp;szOID_PKIX_KP_EMAIL_PROTECTION &nbsp; &nbsp; &nbsp;= '1.3.6.1.5.5.7.3.4';<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Microsoft Enhanced Key Usage (Purpose) Object Identifiers<br>//+-------------------------------------------------------------------------<br><br>// &nbsp;Signer of CTLs<br> &nbsp;szOID_KP_CTL_USAGE_SIGNING &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '1.3.6.1.4.1.311.10.3.1';<br><br>// &nbsp;Signer of TimeStamps<br> &nbsp;szOID_KP_TIME_STAMP_SIGNING &nbsp; &nbsp; &nbsp; &nbsp; = '1.3.6.1.4.1.311.10.3.2';<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Microsoft Attribute Object Identifiers<br>//+-------------------------------------------------------------------------<br> &nbsp;szOID_YESNO_TRUST_ATTR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '1.3.6.1.4.1.311.10.4.1';<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_CERT<br>//<br>// &nbsp;The &quot;to be signed&quot; encoded content plus its signature. The ToBeSigned<br>// &nbsp;content is the CryptEncodeObject() output for one of the following:<br>// &nbsp;X509_CERT_TO_BE_SIGNED, X509_CERT_CRL_TO_BE_SIGNED or<br>// &nbsp;X509_CERT_REQUEST_TO_BE_SIGNED.<br>//<br>// &nbsp;pvStructInfo points to CERT_SIGNED_CONTENT_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_CERT_TO_BE_SIGNED<br>//<br>// &nbsp;pvStructInfo points to CERT_INFO.<br>//<br>// &nbsp;For CryptDecodeObject(), the pbEncoded is the &quot;to be signed&quot; plus its<br>// &nbsp;signature (output of a X509_CERT CryptEncodeObject()).<br>//<br>// &nbsp;For CryptEncodeObject(), the pbEncoded is just the &quot;to be signed&quot;.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_CERT_CRL_TO_BE_SIGNED<br>//<br>// &nbsp;pvStructInfo points to CRL_INFO.<br>//<br>// &nbsp;For CryptDecodeObject(), the pbEncoded is the &quot;to be signed&quot; plus its<br>// &nbsp;signature (output of a X509_CERT CryptEncodeObject()).<br>//<br>// &nbsp;For CryptEncodeObject(), the pbEncoded is just the &quot;to be signed&quot;.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_CERT_REQUEST_TO_BE_SIGNED<br>//<br>// &nbsp;pvStructInfo points to CERT_REQUEST_INFO.<br>//<br>// &nbsp;For CryptDecodeObject(), the pbEncoded is the &quot;to be signed&quot; plus its<br>// &nbsp;signature (output of a X509_CERT CryptEncodeObject()).<br>//<br>// &nbsp;For CryptEncodeObject(), the pbEncoded is just the &quot;to be signed&quot;.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_EXTENSIONS<br>// &nbsp;szOID_CERT_EXTENSIONS<br>//<br>// &nbsp;pvStructInfo points to following CERT_EXTENSIONS.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCERT_EXTENSIONS = ^CERT_EXTENSIONS;<br> &nbsp;CERT_EXTENSIONS = record<br> &nbsp; &nbsp;cExtension &nbsp;:DWORD;<br> &nbsp; &nbsp;rgExtension :PCERT_EXTENSION;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_NAME_VALUE<br>// &nbsp;X509_ANY_STRING<br>//<br>// &nbsp;pvStructInfo points to CERT_NAME_VALUE.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_UNICODE_NAME_VALUE<br>// &nbsp;X509_UNICODE_ANY_STRING<br>//<br>// &nbsp;pvStructInfo points to CERT_NAME_VALUE.<br>//<br>// &nbsp;The name values are unicode strings.<br>//<br>// &nbsp;For CryptEncodeObject:<br>// &nbsp; &nbsp;Value.pbData points to the unicode string.<br>// &nbsp; &nbsp;If Value.cbData = 0, then, the unicode string is NULL terminated.<br>// &nbsp; &nbsp;Otherwise, Value.cbData is the unicode string byte count. The byte count<br>// &nbsp; &nbsp;is twice the character count.<br>//<br>// &nbsp; &nbsp;If the unicode string contains an invalid character for the specified<br>// &nbsp; &nbsp;dwValueType, then, *pcbEncoded is updated with the unicode character<br>// &nbsp; &nbsp;index of the first invalid character. LastError is set to:<br>// &nbsp; &nbsp;CRYPT_E_INVALID_NUMERIC_STRING, CRYPT_E_INVALID_PRINTABLE_STRING or<br>// &nbsp; &nbsp;CRYPT_E_INVALID_IA5_STRING.<br>//<br>// &nbsp; &nbsp;The unicode string is converted before being encoded according to<br>// &nbsp; &nbsp;the specified dwValueType. If dwValueType is set to 0, LastError<br>// &nbsp; &nbsp;is set to E_INVALIDARG.<br>//<br>// &nbsp; &nbsp;If the dwValueType isn't one of the character strings (its a<br>// &nbsp; &nbsp;CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING), then, CryptEncodeObject<br>// &nbsp; &nbsp;will return FALSE with LastError set to CRYPT_E_NOT_CHAR_STRING.<br>//<br>// &nbsp;For CryptDecodeObject:<br>// &nbsp; &nbsp;Value.pbData points to a NULL terminated unicode string. Value.cbData<br>// &nbsp; &nbsp;contains the byte count of the unicode string excluding the NULL<br>// &nbsp; &nbsp;terminator. dwValueType contains the type used in the encoded object.<br>// &nbsp; &nbsp;Its not forced to CERT_RDN_UNICODE_STRING. The encoded value is<br>// &nbsp; &nbsp;converted to the unicode string according to the dwValueType.<br>//<br>// &nbsp; &nbsp;If the encoded object isn't one of the character string types, then,<br>// &nbsp; &nbsp;CryptDecodeObject will return FALSE with LastError set to<br>// &nbsp; &nbsp;CRYPT_E_NOT_CHAR_STRING. For a non character string, decode using<br>// &nbsp; &nbsp;X509_NAME_VALUE or X509_ANY_STRING.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_NAME<br>//<br>// &nbsp;pvStructInfo points to CERT_NAME_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_UNICODE_NAME<br>//<br>// &nbsp;pvStructInfo points to CERT_NAME_INFO.<br>//<br>// &nbsp;The RDN attribute values are unicode strings except for the dwValueTypes of<br>// &nbsp;CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING. These dwValueTypes are<br>// &nbsp;the same as for a X509_NAME. Their values aren't converted to/from unicode.<br>//<br>// &nbsp;For CryptEncodeObject:<br>// &nbsp; &nbsp;Value.pbData points to the unicode string.<br>// &nbsp; &nbsp;If Value.cbData = 0, then, the unicode string is NULL terminated.<br>// &nbsp; &nbsp;Otherwise, Value.cbData is the unicode string byte count. The byte count<br>// &nbsp; &nbsp;is twice the character count.<br>//<br>// &nbsp; &nbsp;If dwValueType = 0 (CERT_RDN_ANY_TYPE), the pszObjId is used to find<br>// &nbsp; &nbsp;an acceptable dwValueType. If the unicode string contains an<br>// &nbsp; &nbsp;invalid character for the found or specified dwValueType, then,<br>// &nbsp; &nbsp;*pcbEncoded is updated with the error location of the invalid character.<br>// &nbsp; &nbsp;See below for details. LastError is set to:<br>// &nbsp; &nbsp;CRYPT_E_INVALID_NUMERIC_STRING, CRYPT_E_INVALID_PRINTABLE_STRING or<br>// &nbsp; &nbsp;CRYPT_E_INVALID_IA5_STRING.<br>//<br>// &nbsp; &nbsp;The unicode string is converted before being encoded according to<br>// &nbsp; &nbsp;the specified or ObjId matching dwValueType.<br>//<br>// &nbsp;For CryptDecodeObject:<br>// &nbsp; &nbsp;Value.pbData points to a NULL terminated unicode string. Value.cbData<br>// &nbsp; &nbsp;contains the byte count of the unicode string excluding the NULL<br>// &nbsp; &nbsp;terminator. dwValueType contains the type used in the encoded object.<br>// &nbsp; &nbsp;Its not forced to CERT_RDN_UNICODE_STRING. The encoded value is<br>// &nbsp; &nbsp;converted to the unicode string according to the dwValueType.<br>//<br>// &nbsp; &nbsp;If the dwValueType of the encoded value isn't a character string<br>// &nbsp; &nbsp;type, then, it isn't converted to UNICODE. Use the<br>// &nbsp; &nbsp;IS_CERT_RDN_CHAR_STRING() macro on the dwValueType to check<br>// &nbsp; &nbsp;that Value.pbData points to a converted unicode string.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Unicode Name Value Error Location Definitions<br>//<br>// &nbsp;Error location is returned in *pcbEncoded by<br>// &nbsp;CryptEncodeObject(X509_UNICODE_NAME)<br>//<br>// &nbsp;Error location consists of:<br>// &nbsp; &nbsp;RDN_INDEX &nbsp; &nbsp; - 10 bits &lt;&lt; 22<br>// &nbsp; &nbsp;ATTR_INDEX &nbsp; &nbsp;- 6 bits &lt;&lt; 16<br>// &nbsp; &nbsp;VALUE_INDEX &nbsp; - 16 bits (unicode character index)<br>//--------------------------------------------------------------------------<br>const <br> &nbsp;CERT_UNICODE_RDN_ERR_INDEX_MASK &nbsp; &nbsp; = $3FF;<br> &nbsp;CERT_UNICODE_RDN_ERR_INDEX_SHIFT &nbsp; &nbsp;= 22;<br> &nbsp;CERT_UNICODE_ATTR_ERR_INDEX_MASK &nbsp; &nbsp;= $003F;<br> &nbsp;CERT_UNICODE_ATTR_ERR_INDEX_SHIFT &nbsp; = 16;<br> &nbsp;CERT_UNICODE_VALUE_ERR_INDEX_MASK &nbsp; = $0000FFFF;<br> &nbsp;CERT_UNICODE_VALUE_ERR_INDEX_SHIFT &nbsp;= 0;<br><br>{#define GET_CERT_UNICODE_RDN_ERR_INDEX(X) &nbsp; /<br> &nbsp; &nbsp;((X &gt;&gt; CERT_UNICODE_RDN_ERR_INDEX_SHIFT) & CERT_UNICODE_RDN_ERR_INDEX_MASK)}<br>function &nbsp;GET_CERT_UNICODE_RDN_ERR_INDEX(X :integer):integer;<br>{#define GET_CERT_UNICODE_ATTR_ERR_INDEX(X) &nbsp;/<br> &nbsp; &nbsp;((X &gt;&gt; CERT_UNICODE_ATTR_ERR_INDEX_SHIFT) & CERT_UNICODE_ATTR_ERR_INDEX_MASK)}<br>function &nbsp;GET_CERT_UNICODE_ATTR_ERR_INDEX(X :integer):integer;<br>{#define GET_CERT_UNICODE_VALUE_ERR_INDEX(X) /<br> &nbsp; &nbsp;(X & CERT_UNICODE_VALUE_ERR_INDEX_MASK)}<br>function &nbsp;GET_CERT_UNICODE_VALUE_ERR_INDEX(X :integer):integer;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_PUBLIC_KEY_INFO<br>//<br>// &nbsp;pvStructInfo points to CERT_PUBLIC_KEY_INFO.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_AUTHORITY_KEY_ID<br>// &nbsp;szOID_AUTHORITY_KEY_IDENTIFIER<br>//<br>// &nbsp;pvStructInfo points to following CERT_AUTHORITY_KEY_ID_INFO.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCERT_AUTHORITY_KEY_ID_INFO = ^CERT_AUTHORITY_KEY_ID_INFO;<br> &nbsp;CERT_AUTHORITY_KEY_ID_INFO = record<br> &nbsp; &nbsp;KeyId &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:CRYPT_DATA_BLOB;<br> &nbsp; &nbsp;CertIssuer &nbsp; &nbsp; &nbsp; :CERT_NAME_BLOB;<br> &nbsp; &nbsp;CertSerialNumber :CRYPT_INTEGER_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_KEY_ATTRIBUTES<br>// &nbsp;szOID_KEY_ATTRIBUTES<br>//<br>// &nbsp;pvStructInfo points to following CERT_KEY_ATTRIBUTES_INFO.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCERT_PRIVATE_KEY_VALIDITY = ^CERT_PRIVATE_KEY_VALIDITY;<br> &nbsp;CERT_PRIVATE_KEY_VALIDITY = record<br> &nbsp; &nbsp;NotBefore :TFILETIME;<br> &nbsp; &nbsp;NotAfter &nbsp;:TFILETIME;<br> &nbsp;end;<br><br>type<br> &nbsp;PCERT_KEY_ATTRIBUTES_INFO = ^CERT_KEY_ATTRIBUTES_INFO;<br> &nbsp;CERT_KEY_ATTRIBUTES_INFO = record<br> &nbsp; &nbsp;KeyId &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:CRYPT_DATA_BLOB;<br> &nbsp; &nbsp;IntendedKeyUsage &nbsp; &nbsp; &nbsp; :CRYPT_BIT_BLOB;<br> &nbsp; &nbsp;pPrivateKeyUsagePeriod :PCERT_PRIVATE_KEY_VALIDITY; &nbsp; &nbsp; // OPTIONAL<br> &nbsp;end;<br><br>const <br> &nbsp;CERT_DIGITAL_SIGNATURE_KEY_USAGE &nbsp; &nbsp;= $80;<br> &nbsp;CERT_NON_REPUDIATION_KEY_USAGE &nbsp; &nbsp; &nbsp;= $40;<br> &nbsp;CERT_KEY_ENCIPHERMENT_KEY_USAGE &nbsp; &nbsp; = $20;<br> &nbsp;CERT_DATA_ENCIPHERMENT_KEY_USAGE &nbsp; &nbsp;= $10;<br> &nbsp;CERT_KEY_AGREEMENT_KEY_USAGE &nbsp; &nbsp; &nbsp; &nbsp;= $08;<br> &nbsp;CERT_KEY_CERT_SIGN_KEY_USAGE &nbsp; &nbsp; &nbsp; &nbsp;= $04;<br> &nbsp;CERT_OFFLINE_CRL_SIGN_KEY_USAGE &nbsp; &nbsp; = $02;<br><br> &nbsp;CERT_CRL_SIGN_KEY_USAGE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $02;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_KEY_USAGE_RESTRICTION<br>// &nbsp;szOID_KEY_USAGE_RESTRICTION<br>//<br>// &nbsp;pvStructInfo points to following CERT_KEY_USAGE_RESTRICTION_INFO.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCERT_POLICY_ID = ^CERT_POLICY_ID;<br> &nbsp;CERT_POLICY_ID = record<br> &nbsp; &nbsp;cCertPolicyElementId &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;rgpszCertPolicyElementId :PLPSTR; &nbsp;// pszObjId<br> &nbsp;end;<br><br>type<br> &nbsp;PCERT_KEY_USAGE_RESTRICTION_INFO = ^CERT_KEY_USAGE_RESTRICTION_INFO;<br> &nbsp;CERT_KEY_USAGE_RESTRICTION_INFO = record<br> &nbsp; &nbsp;cCertPolicyId &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;rgCertPolicyId &nbsp; &nbsp; :PCERT_POLICY_ID;<br> &nbsp; &nbsp;RestrictedKeyUsage :CRYPT_BIT_BLOB;<br> &nbsp;end;<br><br>// See CERT_KEY_ATTRIBUTES_INFO for definition of the RestrictedKeyUsage bits<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_ALTERNATE_NAME<br>// &nbsp;szOID_SUBJECT_ALT_NAME<br>// &nbsp;szOID_ISSUER_ALT_NAME<br>// &nbsp;szOID_SUBJECT_ALT_NAME2<br>// &nbsp;szOID_ISSUER_ALT_NAME2<br>//<br>// &nbsp;pvStructInfo points to following CERT_ALT_NAME_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_ALT_NAME_ENTRY = ^CERT_ALT_NAME_ENTRY;<br> &nbsp;CERT_ALT_NAME_ENTRY = record<br> &nbsp; &nbsp;dwAltNameChoice :DWORD;<br> &nbsp; &nbsp;case integer of<br> &nbsp; &nbsp;{1}0: ({OtherName :Not implemented});<br> &nbsp; &nbsp;{2}1: (pwszRfc822Name &nbsp;:LPWSTR); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//(encoded IA5)<br> &nbsp; &nbsp;{3}2: (pwszDNSName &nbsp; &nbsp; :LPWSTR); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//(encoded IA5)<br> &nbsp; &nbsp;{4}3: ({x400Address &nbsp; &nbsp;:Not implemented});<br> &nbsp; &nbsp;{5}4: (DirectoryName &nbsp; :CERT_NAME_BLOB);<br> &nbsp; &nbsp;{6}5: ({pEdiPartyName &nbsp;:Not implemented});<br> &nbsp; &nbsp;{7}6: (pwszURL &nbsp; &nbsp; &nbsp; &nbsp; :LPWSTR); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//(encoded IA5)<br> &nbsp; &nbsp;{8}7: (IPAddress &nbsp; &nbsp; &nbsp; :CRYPT_DATA_BLOB); &nbsp; //(Octet String)<br> &nbsp; &nbsp;{9}8: (pszRegisteredID :LPSTR); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //(Octet String)<br> &nbsp; &nbsp;end;<br><br>const <br> &nbsp;CERT_ALT_NAME_OTHER_NAME &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;CERT_ALT_NAME_RFC822_NAME &nbsp; &nbsp; = 2;<br> &nbsp;CERT_ALT_NAME_DNS_NAME &nbsp; &nbsp; &nbsp; &nbsp;= 3;<br> &nbsp;CERT_ALT_NAME_X400_ADDRESS &nbsp; &nbsp;= 4;<br> &nbsp;CERT_ALT_NAME_DIRECTORY_NAME &nbsp;= 5;<br> &nbsp;CERT_ALT_NAME_EDI_PARTY_NAME &nbsp;= 6;<br> &nbsp;CERT_ALT_NAME_URL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 7;<br> &nbsp;CERT_ALT_NAME_IP_ADDRESS &nbsp; &nbsp; &nbsp;= 8;<br> &nbsp;CERT_ALT_NAME_REGISTERED_ID &nbsp; = 9;<br><br>type<br> &nbsp;PCERT_ALT_NAME_INFO = ^CERT_ALT_NAME_INFO;<br> &nbsp;CERT_ALT_NAME_INFO = record<br> &nbsp; &nbsp;cAltEntry &nbsp;:DWORD;<br> &nbsp; &nbsp;rgAltEntry :PCERT_ALT_NAME_ENTRY;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Alternate name IA5 Error Location Definitions for<br>// &nbsp;CRYPT_E_INVALID_IA5_STRING.<br>//<br>// &nbsp;Error location is returned in *pcbEncoded by<br>// &nbsp;CryptEncodeObject(X509_ALTERNATE_NAME)<br>//<br>// &nbsp;Error location consists of:<br>// &nbsp; &nbsp;ENTRY_INDEX &nbsp; - 8 bits &lt;&lt; 16<br>// &nbsp; &nbsp;VALUE_INDEX &nbsp; - 16 bits (unicode character index)<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CERT_ALT_NAME_ENTRY_ERR_INDEX_MASK &nbsp;= $FF;<br> &nbsp;CERT_ALT_NAME_ENTRY_ERR_INDEX_SHIFT = 16;<br> &nbsp;CERT_ALT_NAME_VALUE_ERR_INDEX_MASK &nbsp;= $0000FFFF;<br> &nbsp;CERT_ALT_NAME_VALUE_ERR_INDEX_SHIFT = 0;<br><br>{#define GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X) &nbsp; /<br> &nbsp; &nbsp;((X &gt;&gt; CERT_ALT_NAME_ENTRY_ERR_INDEX_SHIFT) & /<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CERT_ALT_NAME_ENTRY_ERR_INDEX_MASK)}<br>function GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X :DWORD):DWORD;<br><br>{#define GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X) /<br> &nbsp; &nbsp;(X & CERT_ALT_NAME_VALUE_ERR_INDEX_MASK)}<br>function GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X :DWORD):DWORD;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_BASIC_CONSTRAINTS<br>// &nbsp;szOID_BASIC_CONSTRAINTS<br>//<br>// &nbsp;pvStructInfo points to following CERT_BASIC_CONSTRAINTS_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_BASIC_CONSTRAINTS_INFO = ^CERT_BASIC_CONSTRAINTS_INFO;<br> &nbsp;CERT_BASIC_CONSTRAINTS_INFO = record<br> &nbsp; &nbsp;SubjectType &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:CRYPT_BIT_BLOB;<br> &nbsp; &nbsp;fPathLenConstraint &nbsp; :BOOL;<br> &nbsp; &nbsp;dwPathLenConstraint &nbsp;:DWORD;<br> &nbsp; &nbsp;cSubtreesConstraint &nbsp;:DWORD;<br> &nbsp; &nbsp;rgSubtreesConstraint :PCERT_NAME_BLOB;<br> &nbsp;end;<br><br>const <br> &nbsp;CERT_CA_SUBJECT_FLAG &nbsp; &nbsp; &nbsp; &nbsp; = $80;<br> &nbsp;CERT_END_ENTITY_SUBJECT_FLAG = $40;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_BASIC_CONSTRAINTS2<br>// &nbsp;szOID_BASIC_CONSTRAINTS2<br>//<br>// &nbsp;pvStructInfo points to following CERT_BASIC_CONSTRAINTS2_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_BASIC_CONSTRAINTS2_INFO = ^CERT_BASIC_CONSTRAINTS2_INFO;<br> &nbsp;CERT_BASIC_CONSTRAINTS2_INFO = record<br> &nbsp; &nbsp;fCA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :BOOL;<br> &nbsp; &nbsp;fPathLenConstraint &nbsp;:BOOL;<br> &nbsp; &nbsp;dwPathLenConstraint :DWORD;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_KEY_USAGE<br>// &nbsp;szOID_KEY_USAGE<br>//<br>// &nbsp;pvStructInfo points to a CRYPT_BIT_BLOB. Has same bit definitions as<br>// &nbsp;CERT_KEY_ATTRIBUTES_INFO's IntendedKeyUsage.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_CERT_POLICIES<br>// &nbsp;szOID_CERT_POLICIES<br>//<br>// &nbsp;pvStructInfo points to following CERT_POLICIES_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_POLICY_QUALIFIER_INFO = ^CERT_POLICY_QUALIFIER_INFO;<br> &nbsp;CERT_POLICY_QUALIFIER_INFO = record<br> &nbsp; &nbsp;pszPolicyQualifierId &nbsp;:LPSTR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// pszObjId<br> &nbsp; &nbsp;Qualifier &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :CRYPT_OBJID_BLOB; // optional<br> &nbsp;end;<br><br>type<br> &nbsp;PCERT_POLICY_INFO = ^CERT_POLICY_INFO;<br> &nbsp;CERT_POLICY_INFO = record<br> &nbsp; &nbsp;pszPolicyIdentifier :LPSTR; &nbsp; &nbsp;// pszObjId<br> &nbsp; &nbsp;cPolicyQualifier &nbsp; &nbsp;:DWORD; &nbsp; &nbsp; &nbsp; // optional<br> &nbsp; &nbsp;rgPolicyQualifier &nbsp; :PCERT_POLICY_QUALIFIER_INFO;<br> &nbsp;end;<br><br>type<br> &nbsp;PCERT_POLICIES_INFO = ^CERT_POLICIES_INFO;<br> &nbsp;CERT_POLICIES_INFO = record<br> &nbsp; &nbsp;cPolicyInfo &nbsp;:DWORD;<br> &nbsp; &nbsp;rgPolicyInfo :PCERT_POLICY_INFO;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;RSA_CSP_PUBLICKEYBLOB<br>//<br>// &nbsp;pvStructInfo points to a PUBLICKEYSTRUC immediately followed by a<br>// &nbsp;RSAPUBKEY and the modulus bytes.<br>//<br>// &nbsp;CryptExportKey outputs the above StructInfo for a dwBlobType of<br>// &nbsp;PUBLICKEYBLOB. CryptImportKey expects the above StructInfo when<br>// &nbsp;importing a public key.<br>//<br>// &nbsp;For dwCertEncodingType = X509_ASN_ENCODING, the RSA_CSP_PUBLICKEYBLOB is<br>// &nbsp;encoded as a PKCS #1 RSAPublicKey consisting of a SEQUENCE of a<br>// &nbsp;modulus INTEGER and a publicExponent INTEGER. The modulus is encoded<br>// &nbsp;as being a unsigned integer. When decoded, if the modulus was encoded<br>// &nbsp;as unsigned integer with a leading 0 byte, the 0 byte is removed before<br>// &nbsp;converting to the CSP modulus bytes.<br>//<br>// &nbsp;For decode, the aiKeyAlg field of PUBLICKEYSTRUC is always set to<br>// &nbsp;CALG_RSA_KEYX.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_KEYGEN_REQUEST_TO_BE_SIGNED<br>//<br>// &nbsp;pvStructInfo points to CERT_KEYGEN_REQUEST_INFO.<br>//<br>// &nbsp;For CryptDecodeObject(), the pbEncoded is the &quot;to be signed&quot; plus its<br>// &nbsp;signature (output of a X509_CERT CryptEncodeObject()).<br>//<br>// &nbsp;For CryptEncodeObject(), the pbEncoded is just the &quot;to be signed&quot;.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;PKCS_ATTRIBUTE data structure<br>//<br>// &nbsp;pvStructInfo points to a CRYPT_ATTRIBUTE.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;PKCS_CONTENT_INFO_SEQUENCE_OF_ANY data structure<br>//<br>// &nbsp;pvStructInfo points to following CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY.<br>//<br>// &nbsp;For X509_ASN_ENCODING: encoded as a PKCS#7 ContentInfo structure wrapping<br>// &nbsp;a sequence of ANY. The value of the contentType field is pszObjId,<br>// &nbsp;while the content field is the following structure:<br>// &nbsp; &nbsp; &nbsp;SequenceOfAny ::= SEQUENCE OF ANY<br>//<br>// &nbsp;The CRYPT_DER_BLOBs point to the already encoded ANY content.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY = ^CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY;<br> &nbsp;CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY = record<br> &nbsp; &nbsp;pszObjId :LPSTR;<br> &nbsp; &nbsp;cValue &nbsp; :DWORD;<br> &nbsp; &nbsp;rgValue &nbsp;:PCRYPT_DER_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;PKCS_CONTENT_INFO data structure<br>//<br>// &nbsp;pvStructInfo points to following CRYPT_CONTENT_INFO.<br>//<br>// &nbsp;For X509_ASN_ENCODING: encoded as a PKCS#7 ContentInfo structure.<br>// &nbsp;The CRYPT_DER_BLOB points to the already encoded ANY content.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_CONTENT_INFO = ^CRYPT_CONTENT_INFO;<br> &nbsp;CRYPT_CONTENT_INFO = record<br> &nbsp; &nbsp;pszObjId :LPSTR;<br> &nbsp; &nbsp;Content &nbsp;:CRYPT_DER_BLOB;<br> &nbsp;end;<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_OCTET_STRING data structure<br>//<br>// &nbsp;pvStructInfo points to a CRYPT_DATA_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_BITS data structure<br>//<br>// &nbsp;pvStructInfo points to a CRYPT_BIT_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_INTEGER data structure<br>//<br>// &nbsp;pvStructInfo points to an int.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_MULTI_BYTE_INTEGER data structure<br>//<br>// &nbsp;pvStructInfo points to a CRYPT_INTEGER_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_ENUMERATED data structure<br>//<br>// &nbsp;pvStructInfo points to an int containing the enumerated value<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_CHOICE_OF_TIME data structure<br>//<br>// &nbsp;pvStructInfo points to a FILETIME.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_SEQUENCE_OF_ANY data structure<br>//<br>// &nbsp;pvStructInfo points to following CRYPT_SEQUENCE_OF_ANY.<br>//<br>// &nbsp;The CRYPT_DER_BLOBs point to the already encoded ANY content.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_SEQUENCE_OF_ANY = ^CRYPT_SEQUENCE_OF_ANY;<br> &nbsp;CRYPT_SEQUENCE_OF_ANY = record<br> &nbsp; &nbsp;cValue &nbsp;:DWORD;<br> &nbsp; &nbsp;rgValue :PCRYPT_DER_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_AUTHORITY_KEY_ID2<br>// &nbsp;szOID_AUTHORITY_KEY_IDENTIFIER2<br>//<br>// &nbsp;pvStructInfo points to following CERT_AUTHORITY_KEY_ID2_INFO.<br>//<br>// &nbsp;For CRYPT_E_INVALID_IA5_STRING, the error location is returned in<br>// &nbsp;*pcbEncoded by CryptEncodeObject(X509_AUTHORITY_KEY_ID2)<br>//<br>// &nbsp;See X509_ALTERNATE_NAME for error location defines.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_AUTHORITY_KEY_ID2_INFO = ^CERT_AUTHORITY_KEY_ID2_INFO;<br> &nbsp;CERT_AUTHORITY_KEY_ID2_INFO = record<br> &nbsp; &nbsp;KeyId &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :CRYPT_DATA_BLOB;<br> &nbsp; &nbsp;AuthorityCertIssuer &nbsp; &nbsp; &nbsp; :CERT_ALT_NAME_INFO; &nbsp;// Optional, set cAltEntry to 0 to omit.<br> &nbsp; &nbsp;AuthorityCertSerialNumber :CRYPT_INTEGER_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_SUBJECT_KEY_IDENTIFIER<br>//<br>// &nbsp;pvStructInfo points to a CRYPT_DATA_BLOB.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_CRL_REASON_CODE<br>// &nbsp;szOID_CRL_REASON_CODE<br>//<br>// &nbsp;pvStructInfo points to an int which can be set to one of the following<br>// &nbsp;enumerated values:<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CRL_REASON_UNSPECIFIED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 0;<br> &nbsp;CRL_REASON_KEY_COMPROMISE &nbsp; &nbsp; &nbsp; &nbsp; = 1;<br> &nbsp;CRL_REASON_CA_COMPROMISE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 2;<br> &nbsp;CRL_REASON_AFFILIATION_CHANGED &nbsp; &nbsp;= 3;<br> &nbsp;CRL_REASON_SUPERSEDED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 4;<br> &nbsp;CRL_REASON_CESSATION_OF_OPERATION = 5;<br> &nbsp;CRL_REASON_CERTIFICATE_HOLD &nbsp; &nbsp; &nbsp; = 6;<br> &nbsp;CRL_REASON_REMOVE_FROM_CRL &nbsp; &nbsp; &nbsp; &nbsp;= 8;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_CRL_DIST_POINTS<br>// &nbsp;szOID_CRL_DIST_POINTS<br>//<br>// &nbsp;pvStructInfo points to following CRL_DIST_POINTS_INFO.<br>//<br>// &nbsp;For CRYPT_E_INVALID_IA5_STRING, the error location is returned in<br>// &nbsp;*pcbEncoded by CryptEncodeObject(X509_CRL_DIST_POINTS)<br>//<br>// &nbsp;Error location consists of:<br>// &nbsp; &nbsp;CRL_ISSUER_BIT &nbsp; &nbsp;- 1 bit &nbsp;&lt;&lt; 31 (0 for FullName, 1 for CRLIssuer)<br>// &nbsp; &nbsp;POINT_INDEX &nbsp; &nbsp; &nbsp; - 7 bits &lt;&lt; 24<br>// &nbsp; &nbsp;ENTRY_INDEX &nbsp; &nbsp; &nbsp; - 8 bits &lt;&lt; 16<br>// &nbsp; &nbsp;VALUE_INDEX &nbsp; &nbsp; &nbsp; - 16 bits (unicode character index)<br>//<br>// &nbsp;See X509_ALTERNATE_NAME for ENTRY_INDEX and VALUE_INDEX error location<br>// &nbsp;defines.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRL_DIST_POINT_NAME = ^CRL_DIST_POINT_NAME;<br> &nbsp;CRL_DIST_POINT_NAME = record<br> &nbsp; &nbsp;dwDistPointNameChoice :DWORD;<br> &nbsp; &nbsp;case integer of<br> &nbsp; &nbsp; &nbsp;0:(FullName :CERT_ALT_NAME_INFO); &nbsp;{1}<br> &nbsp; &nbsp; &nbsp;1:({IssuerRDN :Not implemented}); &nbsp;{2}<br> &nbsp;end;<br><br>const <br> &nbsp;CRL_DIST_POINT_NO_NAME &nbsp; &nbsp; &nbsp; &nbsp; = 0;<br> &nbsp;CRL_DIST_POINT_FULL_NAME &nbsp; &nbsp; &nbsp; = 1;<br> &nbsp;CRL_DIST_POINT_ISSUER_RDN_NAME = 2;<br><br>type<br> &nbsp;PCRL_DIST_POINT = ^CRL_DIST_POINT;<br> &nbsp;CRL_DIST_POINT = record<br> &nbsp; &nbsp;DistPointName :CRL_DIST_POINT_NAME; &nbsp; // OPTIONAL<br> &nbsp; &nbsp;ReasonFlags &nbsp; :CRYPT_BIT_BLOB; &nbsp; &nbsp; &nbsp; &nbsp;// OPTIONAL<br> &nbsp; &nbsp;CRLIssuer &nbsp; &nbsp; :CERT_ALT_NAME_INFO; &nbsp; &nbsp;// OPTIONAL<br> &nbsp;end;<br><br>const <br> &nbsp;CRL_REASON_UNUSED_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $80;<br> &nbsp;CRL_REASON_KEY_COMPROMISE_FLAG &nbsp; &nbsp; &nbsp; &nbsp; = $40;<br> &nbsp;CRL_REASON_CA_COMPROMISE_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $20;<br> &nbsp;CRL_REASON_AFFILIATION_CHANGED_FLAG &nbsp; &nbsp;= $10;<br> &nbsp;CRL_REASON_SUPERSEDED_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $08;<br> &nbsp;CRL_REASON_CESSATION_OF_OPERATION_FLAG = $04;<br> &nbsp;CRL_REASON_CERTIFICATE_HOLD_FLAG &nbsp; &nbsp; &nbsp; = $02;<br><br>type<br> &nbsp;PCRL_DIST_POINTS_INFO = ^CRL_DIST_POINTS_INFO;<br> &nbsp;CRL_DIST_POINTS_INFO = record<br> &nbsp; &nbsp;cDistPoint &nbsp;:DWORD;<br> &nbsp; &nbsp;rgDistPoint :PCRL_DIST_POINT;<br> &nbsp;end;<br><br>const <br> &nbsp;CRL_DIST_POINT_ERR_INDEX_MASK &nbsp;= $7F;<br> &nbsp;CRL_DIST_POINT_ERR_INDEX_SHIFT = 24;<br><br>{#define GET_CRL_DIST_POINT_ERR_INDEX(X) &nbsp; /<br> &nbsp; &nbsp;((X &gt;&gt; CRL_DIST_POINT_ERR_INDEX_SHIFT) & CRL_DIST_POINT_ERR_INDEX_MASK)}<br>function GET_CRL_DIST_POINT_ERR_INDEX(X :DWORD):DWORD;<br>const CRL_DIST_POINT_ERR_CRL_ISSUER_BIT = (DWORD($80000000));<br><br>{#define IS_CRL_DIST_POINT_ERR_CRL_ISSUER(X) &nbsp; /<br> &nbsp; &nbsp;(0 != (X & CRL_DIST_POINT_ERR_CRL_ISSUER_BIT))}<br>function IS_CRL_DIST_POINT_ERR_CRL_ISSUER(X :DWORD):BOOL;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_ENHANCED_KEY_USAGE<br>// &nbsp;szOID_ENHANCED_KEY_USAGE<br>//<br>// &nbsp;pvStructInfo points to a CERT_ENHKEY_USAGE, CTL_USAGE.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NEXT_UPDATE_LOCATION<br>//<br>// &nbsp;pvStructInfo points to a CERT_ALT_NAME_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;PKCS_CTL<br>// &nbsp;szOID_CTL<br>//<br>// &nbsp;pvStructInfo points to a CTL_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_MULTI_BYTE_UINT<br>//<br>// &nbsp;pvStructInfo points to a CRYPT_UINT_BLOB. Before encoding, inserts a<br>// &nbsp;leading 0x00. After decoding, removes a leading 0x00.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_DSS_PUBLICKEY<br>//<br>// &nbsp;pvStructInfo points to a CRYPT_UINT_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_DSS_PARAMETERS<br>//<br>// &nbsp;pvStructInfo points to following CERT_DSS_PARAMETERS data structure.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_DSS_PARAMETERS = ^CERT_DSS_PARAMETERS;<br> &nbsp;CERT_DSS_PARAMETERS = record<br> &nbsp; &nbsp;p :CRYPT_UINT_BLOB;<br> &nbsp; &nbsp;q :CRYPT_UINT_BLOB;<br> &nbsp; &nbsp;g :CRYPT_UINT_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;X509_DSS_SIGNATURE<br>//<br>// &nbsp;pvStructInfo is a BYTE rgbSignature[CERT_DSS_SIGNATURE_LEN]. The<br>// &nbsp;bytes are ordered as output by the DSS CSP's CryptSignHash().<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CERT_DSS_R_LEN &nbsp; &nbsp; &nbsp; &nbsp; = 20;<br> &nbsp;CERT_DSS_S_LEN &nbsp; &nbsp; &nbsp; &nbsp; = 20;<br> &nbsp;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> &nbsp;CERT_MAX_ASN_ENCODED_DSS_SIGNATURE_LEN = (2 + 2*(2 + 20 +1));<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;PKCS_RC2_CBC_PARAMETERS<br>// &nbsp;szOID_RSA_RC2CBC<br>//<br>// &nbsp;pvStructInfo points to following CRYPT_RC2_CBC_PARAMETERS data structure.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_RC2_CBC_PARAMETERS = ^CRYPT_RC2_CBC_PARAMETERS;<br> &nbsp;CRYPT_RC2_CBC_PARAMETERS = record<br> &nbsp; &nbsp;dwVersion :DWORD;<br> &nbsp; &nbsp;fIV &nbsp; &nbsp; &nbsp; :BOOL; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // set if has following IV<br> &nbsp; &nbsp;rgbIV &nbsp; &nbsp; :array[0..8-1] of BYTE;<br> &nbsp;end;<br><br>const <br> &nbsp;CRYPT_RC2_40BIT_VERSION &nbsp;= 160;<br> &nbsp;CRYPT_RC2_64BIT_VERSION &nbsp;= 120;<br> &nbsp;CRYPT_RC2_128BIT_VERSION = 58;<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;PKCS_SMIME_CAPABILITIES<br>// &nbsp;szOID_RSA_SMIMECapabilities<br>//<br>// &nbsp;pvStructInfo points to following CRYPT_SMIME_CAPABILITIES data structure.<br>//<br>// &nbsp;Note, for CryptEncodeObject(X509_ASN_ENCODING), Parameters.cbData == 0<br>// &nbsp;causes the encoded parameters to be omitted and not encoded as a NULL<br>// &nbsp;(05 00) as is done when encoding a CRYPT_ALGORITHM_IDENTIFIER. This<br>// &nbsp;is per the SMIME specification for encoding capabilities.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_SMIME_CAPABILITY = ^CRYPT_SMIME_CAPABILITY;<br> &nbsp;CRYPT_SMIME_CAPABILITY = record<br> &nbsp; &nbsp;pszObjId &nbsp; :LPSTR;<br> &nbsp; &nbsp;Parameters :CRYPT_OBJID_BLOB;<br> &nbsp;end;<br><br>type<br> &nbsp;PCRYPT_SMIME_CAPABILITIES = ^CRYPT_SMIME_CAPABILITIES;<br> &nbsp;CRYPT_SMIME_CAPABILITIES = record<br> &nbsp; &nbsp;cCapability &nbsp;:DWORD;<br> &nbsp; &nbsp;rgCapability :PCRYPT_SMIME_CAPABILITY;<br> &nbsp;end;<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;PKCS7_SIGNER_INFO<br>//<br>// &nbsp;pvStructInfo points to CMSG_SIGNER_INFO.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Netscape Certificate Extension Object Identifiers<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;szOID_NETSCAPE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.16.840.1.113730';<br> &nbsp;szOID_NETSCAPE_CERT_EXTENSION &nbsp; &nbsp;= '2.16.840.1.113730.1';<br> &nbsp;szOID_NETSCAPE_CERT_TYPE &nbsp; &nbsp; &nbsp; &nbsp; = '2.16.840.1.113730.1.1';<br> &nbsp;szOID_NETSCAPE_BASE_URL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '2.16.840.1.113730.1.2';<br> &nbsp;szOID_NETSCAPE_REVOCATION_URL &nbsp; &nbsp;= '2.16.840.1.113730.1.3';<br> &nbsp;szOID_NETSCAPE_CA_REVOCATION_URL = '2.16.840.1.113730.1.4';<br> &nbsp;szOID_NETSCAPE_CERT_RENEWAL_URL &nbsp;= '2.16.840.1.113730.1.7';<br> &nbsp;szOID_NETSCAPE_CA_POLICY_URL &nbsp; &nbsp; = '2.16.840.1.113730.1.8';<br> &nbsp;szOID_NETSCAPE_SSL_SERVER_NAME &nbsp; = '2.16.840.1.113730.1.12';<br> &nbsp;szOID_NETSCAPE_COMMENT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '2.16.840.1.113730.1.13';<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Netscape Certificate Data Type Object Identifiers<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;szOID_NETSCAPE_DATA_TYPE &nbsp; &nbsp; &nbsp;= '2.16.840.1.113730.2';<br> &nbsp;szOID_NETSCAPE_CERT_SEQUENCE &nbsp;= '2.16.840.1.113730.2.5';<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NETSCAPE_CERT_TYPE extension<br>//<br>// &nbsp;Its value is a bit string. CryptDecodeObject/CryptEncodeObject using<br>// &nbsp;X509_BITS.<br>//<br>// &nbsp;The following bits are defined:<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE &nbsp;= $80;<br> &nbsp;NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE &nbsp;= $40;<br> &nbsp;NETSCAPE_SSL_CA_CERT_TYPE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $04;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NETSCAPE_BASE_URL extension<br>//<br>// &nbsp;Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// &nbsp;X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// &nbsp;dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// &nbsp;When present this string is added to the beginning of all relative URLs<br>// &nbsp;in the certificate. &nbsp;This extension can be considered an optimization<br>// &nbsp;to reduce the size of the URL extensions.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NETSCAPE_REVOCATION_URL extension<br>//<br>// &nbsp;Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// &nbsp;X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// &nbsp;dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// &nbsp;It is a relative or absolute URL that can be used to check the<br>// &nbsp;revocation status of a certificate. The revocation check will be<br>// &nbsp;performed as an HTTP GET method using a url that is the concatenation of<br>// &nbsp;revocation-url and certificate-serial-number.<br>// &nbsp;Where the certificate-serial-number is encoded as a string of<br>// &nbsp;ascii hexadecimal digits. For example, if the netscape-base-url is<br>// &nbsp;https://www.certs-r-us.com/, the netscape-revocation-url is<br>// &nbsp;cgi-bin/check-rev.cgi?, and the certificate serial number is 173420,<br>// &nbsp;the resulting URL would be:<br>// &nbsp;https://www.certs-r-us.com/cgi-bin/check-rev.cgi?02a56c<br>//<br>// &nbsp;The server should return a document with a Content-Type of<br>// &nbsp;application/x-netscape-revocation. &nbsp;The document should contain<br>// &nbsp;a single ascii digit, '1' if the certificate is not curently valid,<br>// &nbsp;and '0' if it is curently valid.<br>//<br>// &nbsp;Note: for all of the URLs that include the certificate serial number,<br>// &nbsp;the serial number will be encoded as a string which consists of an even<br>// &nbsp;number of hexadecimal digits. &nbsp;If the number of significant digits is odd,<br>// &nbsp;the string will have a single leading zero to ensure an even number of<br>// &nbsp;digits is generated.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NETSCAPE_CA_REVOCATION_URL extension<br>//<br>// &nbsp;Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// &nbsp;X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// &nbsp;dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// &nbsp;It is a relative or absolute URL that can be used to check the<br>// &nbsp;revocation status of any certificates that are signed by the CA that<br>// &nbsp;this certificate belongs to. This extension is only valid in CA<br>// &nbsp;certificates. &nbsp;The use of this extension is the same as the above<br>// &nbsp;szOID_NETSCAPE_REVOCATION_URL extension.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NETSCAPE_CERT_RENEWAL_URL extension<br>//<br>// &nbsp;Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// &nbsp;X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// &nbsp;dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// &nbsp;It is a relative or absolute URL that points to a certificate renewal<br>// &nbsp;form. The renewal form will be accessed with an HTTP GET method using a<br>// &nbsp;url that is the concatenation of renewal-url and<br>// &nbsp;certificate-serial-number. Where the certificate-serial-number is<br>// &nbsp;encoded as a string of ascii hexadecimal digits. For example, if the<br>// &nbsp;netscape-base-url is https://www.certs-r-us.com/, the<br>// &nbsp;netscape-cert-renewal-url is cgi-bin/check-renew.cgi?, and the<br>// &nbsp;certificate serial number is 173420, the resulting URL would be:<br>// &nbsp;https://www.certs-r-us.com/cgi-bin/check-renew.cgi?02a56c<br>// &nbsp;The document returned should be an HTML form that will allow the user<br>// &nbsp;to request a renewal of their certificate.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NETSCAPE_CA_POLICY_URL extension<br>//<br>// &nbsp;Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// &nbsp;X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// &nbsp;dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// &nbsp;It is a relative or absolute URL that points to a web page that<br>// &nbsp;describes the policies under which the certificate was issued.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NETSCAPE_SSL_SERVER_NAME extension<br>//<br>// &nbsp;Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// &nbsp;X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// &nbsp;dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// &nbsp;It is a &quot;shell expression&quot; that can be used to match the hostname of the<br>// &nbsp;SSL server that is using this certificate. &nbsp;It is recommended that if<br>// &nbsp;the server's hostname does not match this pattern the user be notified<br>// &nbsp;and given the option to terminate the SSL connection. &nbsp;If this extension<br>// &nbsp;is not present then the CommonName in the certificate subject's<br>// &nbsp;distinguished name is used for the same purpose.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NETSCAPE_COMMENT extension<br>//<br>// &nbsp;Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using<br>// &nbsp;X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,<br>// &nbsp;dwValueType = CERT_RDN_IA5_STRING.<br>//<br>// &nbsp;It is a comment that may be displayed to the user when the certificate<br>// &nbsp;is viewed.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;szOID_NETSCAPE_CERT_SEQUENCE<br>//<br>// &nbsp;Its value is a PKCS#7 ContentInfo structure wrapping a sequence of<br>// &nbsp;certificates. The value of the contentType field is<br>// &nbsp;szOID_NETSCAPE_CERT_SEQUENCE, while the content field is the following<br>// &nbsp;structure:<br>// &nbsp; &nbsp; &nbsp;CertificateSequence ::= SEQUENCE OF Certificate.<br>//<br>// &nbsp;CryptDecodeObject/CryptEncodeObject using<br>// &nbsp;PKCS_CONTENT_INFO_SEQUENCE_OF_ANY, where,<br>// &nbsp;pszObjId = szOID_NETSCAPE_CERT_SEQUENCE and the CRYPT_DER_BLOBs point<br>// &nbsp;to encoded X509 certificates.<br>//--------------------------------------------------------------------------<br><br><br>//+=========================================================================<br>// &nbsp;Object IDentifier (OID) Installable Functions: &nbsp;Data Structures and APIs<br>//==========================================================================<br><br>type<br> &nbsp;HCRYPTOIDFUNCSET = procedure;<br> &nbsp;HCRYPTOIDFUNCADDR = procedure;<br><br>// Predefined OID Function Names<br>const <br> &nbsp;CRYPT_OID_ENCODE_OBJECT_FUNC &nbsp; &nbsp; = 'CryptDllEncodeObject';<br> &nbsp;CRYPT_OID_DECODE_OBJECT_FUNC &nbsp; &nbsp; = 'CryptDllDecodeObject';<br> &nbsp;CRYPT_OID_CREATE_COM_OBJECT_FUNC = 'CryptDllCreateCOMObject';<br> &nbsp;CRYPT_OID_VERIFY_REVOCATION_FUNC = 'CertDllVerifyRevocation';<br> &nbsp;CRYPT_OID_VERIFY_CTL_USAGE_FUNC &nbsp;= 'CertDllVerifyCTLUsage';<br> &nbsp;CRYPT_OID_FORMAT_OBJECT_FUNC &nbsp; &nbsp; = 'CryptDllFormatObject';<br> &nbsp;CRYPT_OID_FIND_OID_INFO_FUNC &nbsp; &nbsp; = '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>// &nbsp; &nbsp; &nbsp;BOOL WINAPI CryptDllCreateCOMObject(<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IN DWORD dwEncodingType,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IN LPCSTR pszOID,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IN PCRYPT_DATA_BLOB pEncodedContent,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IN DWORD dwFlags,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IN REFIID riid,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OUT void **ppvObj);<br><br>// CertDllVerifyRevocation has the same signature as CertVerifyRevocation<br>// &nbsp;(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>// &nbsp;Example of a complete OID Function Registry Name:<br>// &nbsp; &nbsp;HKEY_LOCAL_MACHINE/Software/Microsoft/Cryptography/OID<br>// &nbsp; &nbsp; &nbsp;Encoding Type 1/CryptDllEncodeObject/1.2.3<br>//<br>// &nbsp;The key's L&quot;Dll&quot; value contains the name of the Dll.<br>// &nbsp;The key's L&quot;FuncName&quot; value overrides the default function name<br><br>const <br> &nbsp;CRYPT_OID_REGPATH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 'Software//Microsoft//Cryptography//OID';<br> &nbsp;CRYPT_OID_REG_ENCODING_TYPE_PREFIX &nbsp; = 'EncodingType ';<br>{$IFNDEF VER90}<br> &nbsp; &nbsp;CRYPT_OID_REG_DLL_VALUE_NAME &nbsp; &nbsp; &nbsp; &nbsp; = WideString('Dll');<br> &nbsp; &nbsp;CRYPT_OID_REG_FUNC_NAME_VALUE_NAME &nbsp; = WideString('FuncName');<br>{$ELSE}<br> &nbsp; &nbsp;CRYPT_OID_REG_DLL_VALUE_NAME &nbsp; &nbsp; &nbsp; &nbsp; = ('Dll');<br> &nbsp; &nbsp;CRYPT_OID_REG_FUNC_NAME_VALUE_NAME &nbsp; = ('FuncName');<br>{$ENDIF}<br> &nbsp;CRYPT_OID_REG_FUNC_NAME_VALUE_NAME_A = 'FuncName';<br><br>// OID used for Default OID functions<br> &nbsp;CRYPT_DEFAULT_OID &nbsp; &nbsp;= 'DEFAULT';<br><br>type<br> &nbsp;PCRYPT_OID_FUNC_ENTRY = ^CRYPT_OID_FUNC_ENTRY;<br> &nbsp;CRYPT_OID_FUNC_ENTRY = record<br> &nbsp; &nbsp;pszOID &nbsp; &nbsp; :LPCSTR;<br> &nbsp; &nbsp;pvFuncAddr :PVOID;<br> &nbsp;end;<br><br>const <br> &nbsp;CRYPT_INSTALL_OID_FUNC_BEFORE_FLAG = 1;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Install a set of callable OID function addresses.<br>//<br>// &nbsp;By default the functions are installed at end of the list.<br>// &nbsp;Set CRYPT_INSTALL_OID_FUNC_BEFORE_FLAG to install at beginning of list.<br>//<br>// &nbsp;hModule should be updated with the hModule passed to DllMain to prevent<br>// &nbsp;the Dll containing the function addresses from being unloaded by<br>// &nbsp;CryptGetOIDFuncAddress/CryptFreeOIDFunctionAddress. This would be the<br>// &nbsp;case when the Dll has also regsvr32'ed OID functions via<br>// &nbsp;CryptRegisterOIDFunction.<br>//<br>// &nbsp;DEFAULT functions are installed by setting rgFuncEntry[].pszOID =<br>// &nbsp;CRYPT_DEFAULT_OID.<br>//--------------------------------------------------------------------------<br><br>function CryptInstallOIDFunctionAddress(hModule :HMODULE; &nbsp;// hModule passed to DllMain<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszFuncName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cFuncEntry :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const rgFuncEntry :array of CRYPT_OID_FUNC_ENTRY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Initialize and return handle to the OID function set identified by its<br>// &nbsp;function name.<br>//<br>// &nbsp;If the set already exists, a handle to the existing set is returned.<br>//--------------------------------------------------------------------------<br><br>function CryptInitOIDFunctionSet(pszFuncName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD ):HCRYPTOIDFUNCSET ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Search the list of installed functions for an encoding type and OID match.<br>// &nbsp;If not found, search the registry.<br>//<br>// &nbsp;For success, returns TRUE with *ppvFuncAddr updated with the function's<br>// &nbsp;address and *phFuncAddr updated with the function address's handle.<br>// &nbsp;The function's handle is AddRef'ed. CryptFreeOIDFunctionAddress needs to<br>// &nbsp;be called to release it.<br>//<br>// &nbsp;For a registry match, the Dll containing the function is loaded.<br>//--------------------------------------------------------------------------<br><br>function CryptGetOIDFunctionAddress(hFuncSet :HCRYPTOIDFUNCSET;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszOID :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppvFuncAddr :array of PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var phFuncAddr :HCRYPTOIDFUNCADDR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the list of registered default Dll entries for the specified<br>// &nbsp;function set and encoding type.<br>//<br>// &nbsp;The returned list consists of none, one or more null terminated Dll file<br>// &nbsp;names. The list is terminated with an empty (L&quot;/0&quot;) Dll file name.<br>// &nbsp;For example: L&quot;first.dll&quot; L&quot;/0&quot; L&quot;second.dll&quot; L&quot;/0&quot; L&quot;/0&quot;<br>//--------------------------------------------------------------------------<br><br>function CryptGetDefaultOIDDllList(hFuncSet :HCRYPTOIDFUNCSET;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pwszDllList &nbsp; &nbsp;:LPWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcchDllList &nbsp; &nbsp;:PDWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Either: get the first or next installed DEFAULT function OR<br>// &nbsp;load the Dll containing the DEFAULT function.<br>//<br>// &nbsp;If pwszDll is NULL, search the list of installed DEFAULT functions.<br>// &nbsp;*phFuncAddr must be set to NULL to get the first installed function.<br>// &nbsp;Successive installed functions are returned by setting *phFuncAddr<br>// &nbsp;to the hFuncAddr returned by the previous call.<br>//<br>// &nbsp;If pwszDll is NULL, the input *phFuncAddr<br>// &nbsp;is always CryptFreeOIDFunctionAddress'ed by this function, even for<br>// &nbsp;an error.<br>//<br>// &nbsp;If pwszDll isn't NULL, then, attempts to load the Dll and the DEFAULT<br>// &nbsp;function. *phFuncAddr is ignored upon entry and isn't<br>// &nbsp;CryptFreeOIDFunctionAddress'ed.<br>//<br>// &nbsp;For success, returns TRUE with *ppvFuncAddr updated with the function's<br>// &nbsp;address and *phFuncAddr updated with the function address's handle.<br>// &nbsp;The function's handle is AddRef'ed. CryptFreeOIDFunctionAddress needs to<br>// &nbsp;be called to release it or CryptGetDefaultOIDFunctionAddress can also<br>// &nbsp;be called for a NULL pwszDll.<br>//--------------------------------------------------------------------------<br><br>function CryptGetDefaultOIDFunctionAddress(hFuncSet :HCRYPTOIDFUNCSET;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pwszDll :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :LPCWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var ppvFuncAddr :array of PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var phFuncAddr :HCRYPTOIDFUNCADDR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Releases the handle AddRef'ed and returned by CryptGetOIDFunctionAddress<br>// &nbsp;or CryptGetDefaultOIDFunctionAddress.<br>//<br>// &nbsp;If a Dll was loaded for the function its unloaded. However, before doing<br>// &nbsp;the unload, the DllCanUnloadNow function exported by the loaded Dll is<br>// &nbsp;called. It should return S_FALSE to inhibit the unload or S_TRUE to enable<br>// &nbsp;the unload. If the Dll doesn't export DllCanUnloadNow, the Dll is unloaded.<br>//<br>// &nbsp;DllCanUnloadNow has the following signature:<br>// &nbsp; &nbsp; &nbsp;STDAPI &nbsp;DllCanUnloadNow(void);<br>//--------------------------------------------------------------------------<br><br>function CryptFreeOIDFunctionAddress(hFuncAddr :HCRYPTOIDFUNCADDR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Register the Dll containing the function to be called for the specified<br>// &nbsp;encoding type, function name and OID.<br>//<br>// &nbsp;pwszDll may contain environment-variable strings<br>// &nbsp;which are ExpandEnvironmentStrings()'ed before loading the Dll.<br>//<br>// &nbsp;In addition to registering the DLL, you may override the<br>// &nbsp;name of the function to be called. For example,<br>// &nbsp; &nbsp; &nbsp;pszFuncName = &quot;CryptDllEncodeObject&quot;,<br>// &nbsp; &nbsp; &nbsp;pszOverrideFuncName = &quot;MyEncodeXyz&quot;.<br>// &nbsp;This allows a Dll to export multiple OID functions for the same<br>// &nbsp;function name without needing to interpose its own OID dispatcher function.<br>//--------------------------------------------------------------------------<br><br>function CryptRegisterOIDFunction(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszFuncName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszOID :LPCSTR; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pwszDll :LPCWSTR; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszOverrideFuncName :LPCSTR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Unregister the Dll containing the function to be called for the specified<br>// &nbsp;encoding type, function name and OID.<br>//--------------------------------------------------------------------------<br><br>function CryptUnregisterOIDFunction(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszFuncName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszOID :LPCSTR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Register the Dll containing the default function to be called for the<br>// &nbsp;specified encoding type and function name.<br>//<br>// &nbsp;Unlike CryptRegisterOIDFunction, you can't override the function name<br>// &nbsp;needing to be exported by the Dll.<br>//<br>// &nbsp;The Dll is inserted before the entry specified by dwIndex.<br>// &nbsp; &nbsp;dwIndex == 0, inserts at the beginning.<br>// &nbsp; &nbsp;dwIndex == CRYPT_REGISTER_LAST_INDEX, appends at the end.<br>//<br>// &nbsp;pwszDll may contain environment-variable strings<br>// &nbsp;which are ExpandEnvironmentStrings()'ed before loading the Dll.<br>//--------------------------------------------------------------------------<br><br>function CryptRegisterDefaultOIDFunction(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszFuncName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwIndex :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pwszDll :LPCWSTR):BOOL ; stdcall;<br><br>const <br> &nbsp;CRYPT_REGISTER_FIRST_INDEX = 0;<br> &nbsp;CRYPT_REGISTER_LAST_INDEX &nbsp;= $FFFFFFFF;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Unregister the Dll containing the default function to be called for<br>// &nbsp;the specified encoding type and function name.<br>//--------------------------------------------------------------------------<br><br>function CryptUnregisterDefaultOIDFunction(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszFuncName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pwszDll :LPCWSTR):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Set the value for the specified encoding type, function name, OID and<br>// &nbsp;value name.<br>//<br>// &nbsp;See RegSetValueEx for the possible value types.<br>//<br>// &nbsp;String types are UNICODE.<br>//--------------------------------------------------------------------------<br><br>function CryptSetOIDFunctionValue(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszFuncName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszOID :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pwszValueName :LPCWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwValueType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbValueData :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbValueData :DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the value for the specified encoding type, function name, OID and<br>// &nbsp;value name.<br>//<br>// &nbsp;See RegEnumValue for the possible value types.<br>//<br>// &nbsp;String types are UNICODE.<br>//--------------------------------------------------------------------------<br><br>function CryptGetOIDFunctionValue(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszFuncName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pwszValueName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszOID :LPCWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwValueType &nbsp;:PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbValueData &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbValueData :PDWORD):BOOL ; stdcall;<br><br>type<br> &nbsp;PFN_CRYPT_ENUM_OID_FUNC = function (dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszFuncName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszOID :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cValue :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const rgdwValueType :array of DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const rgpwszValueName :array of LPCWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const rgpbValueData :array of PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const rgcbValueData :array of DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvArg :PVOID):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Enumerate the OID functions identified by their encoding type,<br>// &nbsp;function name and OID.<br>//<br>// &nbsp;pfnEnumOIDFunc is called for each registry key matching the input<br>// &nbsp;parameters. Setting dwEncodingType to CRYPT_MATCH_ANY_ENCODING_TYPE matches<br>// &nbsp;any. Setting pszFuncName or pszOID to NULL matches any.<br>//<br>// &nbsp;Set pszOID == CRYPT_DEFAULT_OID to restrict the enumeration to only the<br>// &nbsp;DEFAULT functions<br>//<br>// &nbsp;String types are UNICODE.<br>//--------------------------------------------------------------------------<br><br>function CryptEnumOIDFunction(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszFuncName :LPCSTR; &nbsp; &nbsp;//OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszOID :LPCSTR; &nbsp; &nbsp; &nbsp; &nbsp; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvArg :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pfnEnumOIDFunc :PFN_CRYPT_ENUM_OID_FUNC):BOOL ; stdcall;<br><br>const <br> &nbsp;CRYPT_MATCH_ANY_ENCODING_TYPE = $FFFFFFFF;<br><br>//+=========================================================================<br>// &nbsp;Object IDentifier (OID) Information: &nbsp;Data Structures and APIs<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;OID Information<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_OID_INFO = ^CRYPT_OID_INFO;<br> &nbsp;CRYPT_OID_INFO = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;pszOID :LPCSTR;<br> &nbsp; &nbsp;pwszName :LPCWSTR;<br> &nbsp; &nbsp;dwGroupId :DWORD;<br> &nbsp; &nbsp;EnumValue : record {type EnumValue for the union part of the original struct --max--}<br> &nbsp; &nbsp;case integer of<br> &nbsp; &nbsp; &nbsp;0:(dwValue :DWORD);<br> &nbsp; &nbsp; &nbsp;1:(Algid :ALG_ID);<br> &nbsp; &nbsp; &nbsp;2:(dwLength :DWORD);<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;ExtraInfo :CRYPT_DATA_BLOB;<br> &nbsp;end;<br><br>type<br> &nbsp;CCRYPT_OID_INFO &nbsp;= CRYPT_OID_INFO;<br> &nbsp;PCCRYPT_OID_INFO = ^CCRYPT_OID_INFO;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;OID Group IDs<br>//--------------------------------------------------------------------------<br><br>const<br> &nbsp;CRYPT_HASH_ALG_OID_GROUP_ID &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;CRYPT_ENCRYPT_ALG_OID_GROUP_ID &nbsp; = 2;<br> &nbsp;CRYPT_PUBKEY_ALG_OID_GROUP_ID &nbsp; &nbsp;= 3;<br> &nbsp;CRYPT_SIGN_ALG_OID_GROUP_ID &nbsp; &nbsp; &nbsp;= 4;<br> &nbsp;CRYPT_RDN_ATTR_OID_GROUP_ID &nbsp; &nbsp; &nbsp;= 5;<br> &nbsp;CRYPT_EXT_OR_ATTR_OID_GROUP_ID &nbsp; = 6;<br> &nbsp;CRYPT_ENHKEY_USAGE_OID_GROUP_ID &nbsp;= 7;<br> &nbsp;CRYPT_POLICY_OID_GROUP_ID &nbsp; &nbsp; &nbsp; &nbsp;= 8;<br> &nbsp;CRYPT_LAST_OID_GROUP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 8;<br><br> &nbsp;CRYPT_FIRST_ALG_OID_GROUP_ID &nbsp; &nbsp; = CRYPT_HASH_ALG_OID_GROUP_ID;<br> &nbsp;CRYPT_LAST_ALG_OID_GROUP_ID &nbsp; &nbsp; &nbsp;= 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>// &nbsp;DWORD[0] - Flags. CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG can be set to<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inhibit the reformatting of the signature before<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CryptVerifySignature is called or after CryptSignHash<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is called. CRYPT_OID_USE_PUBKEY_PARA_FOR_PKCS7_FLAG can<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; be set to include the public key algorithm's parameters<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in the PKCS7's digestEncryptionAlgorithm's parameters.<br><br> &nbsp;CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG &nbsp;= $1;<br> &nbsp;CRYPT_OID_USE_PUBKEY_PARA_FOR_PKCS7_FLAG = $2;<br><br>// CRYPT_SIGN_ALG_OID_GROUP_ID has the following optional ExtraInfo:<br>// &nbsp;DWORD[0] - Public Key Algid.<br>// &nbsp;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>// &nbsp;Array of DWORDs:<br>// &nbsp; [0 ..] - Null terminated list of acceptable RDN attribute<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;value types. An empty list implies CERT_RDN_PRINTABLE_STRING,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CERT_RDN_T61_STRING, 0.<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Find OID information. Returns NULL if unable to find any information<br>// &nbsp;for the specified key and group. Note, returns a pointer to a constant<br>// &nbsp;data structure. The returned pointer MUST NOT be freed.<br>//<br>// &nbsp;dwKeyType's:<br>// &nbsp; &nbsp;CRYPT_OID_INFO_OID_KEY, pvKey points to a szOID<br>// &nbsp; &nbsp;CRYPT_OID_INFO_NAME_KEY, pvKey points to a wszName<br>// &nbsp; &nbsp;CRYPT_OID_INFO_ALGID_KEY, pvKey points to an ALG_ID<br>// &nbsp; &nbsp;CRYPT_OID_INFO_SIGN_KEY, pvKey points to an array of two ALG_ID's:<br>// &nbsp; &nbsp; &nbsp;ALG_ID[0] - Hash Algid<br>// &nbsp; &nbsp; &nbsp;ALG_ID[1] - PubKey Algid<br>//<br>// &nbsp;Setting dwGroupId to 0, searches all groups according to the dwKeyType.<br>// &nbsp;Otherwise, only the dwGroupId is searched.<br>//--------------------------------------------------------------------------<br><br>function CryptFindOIDInfo(dwKeyType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvKey :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwGroupId :DWORD):PCCRYPT_OID_INFO ; stdcall;<br><br>const <br> &nbsp;CRYPT_OID_INFO_OID_KEY &nbsp; = 1;<br> &nbsp;CRYPT_OID_INFO_NAME_KEY &nbsp;= 2;<br> &nbsp;CRYPT_OID_INFO_ALGID_KEY = 3;<br> &nbsp;CRYPT_OID_INFO_SIGN_KEY &nbsp;= 4;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Register OID information. The OID information specified in the<br>// &nbsp;CCRYPT_OID_INFO structure is persisted to the registry.<br>//<br>// &nbsp;crypt32.dll contains information for the commonly known OIDs. This function<br>// &nbsp;allows applications to augment crypt32.dll's OID information. During<br>// &nbsp;CryptFindOIDInfo's first call, the registered OID information is installed.<br>//<br>// &nbsp;By default the registered OID information is installed after crypt32.dll's<br>// &nbsp;OID entries. Set CRYPT_INSTALL_OID_INFO_BEFORE_FLAG to install before.<br>//--------------------------------------------------------------------------<br><br>function CryptRegisterOIDInfo(pInfo :PCCRYPT_OID_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags:DWORD):BOOL ; stdcall;<br><br>const <br> &nbsp;CRYPT_INSTALL_OID_INFO_BEFORE_FLAG = 1;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Unregister OID information. Only the pszOID and dwGroupId fields are<br>// &nbsp;used to identify the OID information to be unregistered.<br>//--------------------------------------------------------------------------<br><br>function CryptUnregisterOIDInfo(pInfo :PCCRYPT_OID_INFO):BOOL ; stdcall;<br><br>//+=========================================================================<br>// &nbsp;Low Level Cryptographic Message Data Structures and APIs<br>//==========================================================================<br><br>type<br> &nbsp;HCRYPTMSG = Pointer;<br><br>const <br> &nbsp;szOID_PKCS_7_DATA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.7.1';<br> &nbsp;szOID_PKCS_7_SIGNED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.7.2';<br> &nbsp;szOID_PKCS_7_ENVELOPED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.7.3';<br> &nbsp;szOID_PKCS_7_SIGNEDANDENVELOPED &nbsp;= '1.2.840.113549.1.7.4';<br> &nbsp;szOID_PKCS_7_DIGESTED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.7.5';<br> &nbsp;szOID_PKCS_7_ENCRYPTED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = '1.2.840.113549.1.7.6';<br><br> &nbsp;szOID_PKCS_9_CONTENT_TYPE &nbsp; &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.9.3';<br> &nbsp;szOID_PKCS_9_MESSAGE_DIGEST &nbsp; &nbsp; &nbsp;= '1.2.840.113549.1.9.4';<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Message types<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CMSG_DATA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;CMSG_SIGNED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 2;<br> &nbsp;CMSG_ENVELOPED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 3;<br> &nbsp;CMSG_SIGNED_AND_ENVELOPED &nbsp;= 4;<br> &nbsp;CMSG_HASHED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 5;<br> &nbsp;CMSG_ENCRYPTED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 6;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Message Type Bit Flags<br>//--------------------------------------------------------------------------<br><br> &nbsp;CMSG_ALL_FLAGS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (not ULONG(0));<br> &nbsp;CMSG_DATA_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (1 shl CMSG_DATA);<br> &nbsp;CMSG_SIGNED_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (1 shl CMSG_SIGNED);<br> &nbsp;CMSG_ENVELOPED_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (1 shl CMSG_ENVELOPED);<br> &nbsp;CMSG_SIGNED_AND_ENVELOPED_FLAG = (1 shl CMSG_SIGNED_AND_ENVELOPED);<br> &nbsp;CMSG_HASHED_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (1 shl CMSG_HASHED);<br> &nbsp;CMSG_ENCRYPTED_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= (1 shl CMSG_ENCRYPTED);<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;The message encode information (pvMsgEncodeInfo) is message type dependent<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_DATA: pvMsgEncodeInfo = NULL<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_SIGNED<br>//<br>// &nbsp;The pCertInfo in the CMSG_SIGNER_ENCODE_INFO provides the Issuer, SerialNumber<br>// &nbsp;and PublicKeyInfo.Algorithm. The PublicKeyInfo.Algorithm implicitly<br>// &nbsp;specifies the HashEncryptionAlgorithm to be used.<br>//<br>// &nbsp;The hCryptProv and dwKeySpec specify the private key to use. If dwKeySpec<br>// &nbsp;== 0, then, defaults to AT_SIGNATURE.<br>//<br>// &nbsp;pvHashAuxInfo currently isn't used and must be set to NULL.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCMSG_SIGNER_ENCODE_INFO = ^CMSG_SIGNER_ENCODE_INFO;<br> &nbsp;CMSG_SIGNER_ENCODE_INFO = record<br> &nbsp; &nbsp;cbSize &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;pCertInfo &nbsp; &nbsp; :PCERT_INFO;<br> &nbsp; &nbsp;hCryptProv &nbsp; &nbsp;:HCRYPTPROV;<br> &nbsp; &nbsp;dwKeySpec &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;pvHashAuxInfo :PVOID;<br> &nbsp; &nbsp;cAuthAttr &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;rgAuthAttr &nbsp; &nbsp;:PCRYPT_ATTRIBUTE;<br> &nbsp; &nbsp;cUnauthAttr &nbsp; :DWORD;<br> &nbsp; &nbsp;rgUnauthAttr &nbsp;:PCRYPT_ATTRIBUTE;<br> &nbsp;end;<br><br>type<br> &nbsp;PCMSG_SIGNED_ENCODE_INFO = ^CMSG_SIGNED_ENCODE_INFO;<br> &nbsp;CMSG_SIGNED_ENCODE_INFO = record<br> &nbsp; &nbsp;cbSize &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;cSigners &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;rgSigners &nbsp; &nbsp; :PCMSG_SIGNER_ENCODE_INFO;<br> &nbsp; &nbsp;cCertEncoded &nbsp;:DWORD;<br> &nbsp; &nbsp;rgCertEncoded :PCERT_BLOB;<br> &nbsp; &nbsp;cCrlEncoded &nbsp; :DWORD;<br> &nbsp; &nbsp;rgCrlEncoded &nbsp;:PCRL_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_ENVELOPED<br>//<br>// &nbsp;The PCERT_INFO for the rgRecipients provides the Issuer, SerialNumber<br>// &nbsp;and PublicKeyInfo. The PublicKeyInfo.Algorithm implicitly<br>// &nbsp;specifies the KeyEncryptionAlgorithm to be used.<br>//<br>// &nbsp;The PublicKeyInfo.PublicKey in PCERT_INFO is used to encrypt the content<br>// &nbsp;encryption key for the recipient.<br>//<br>// &nbsp;hCryptProv is used to do the content encryption, recipient key encryption<br>// &nbsp;and export. The hCryptProv's private keys aren't used.<br>//<br>// &nbsp;Note: CAPI currently doesn't support more than one KeyEncryptionAlgorithm<br>// &nbsp;per provider. This will need to be fixed.<br>//<br>// &nbsp;pvEncryptionAuxInfo currently isn't used and must be set to NULL.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCMSG_ENVELOPED_ENCODE_INFO = ^CMSG_ENVELOPED_ENCODE_INFO;<br> &nbsp;CMSG_ENVELOPED_ENCODE_INFO = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp;ContentEncryptionAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;pvEncryptionAuxInfo :PVOID;<br> &nbsp; &nbsp;cRecipients :DWORD;<br> &nbsp; &nbsp;rgpRecipients :PPCERT_INFO; // pointer to array of PCERT_INFO<br>end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_SIGNED_AND_ENVELOPED<br>//<br>// &nbsp;For PKCS #7, a signed and enveloped message doesn't have the<br>// &nbsp;signer's authenticated or unauthenticated attributes. Otherwise, a<br>// &nbsp;combination of the CMSG_SIGNED_ENCODE_INFO and CMSG_ENVELOPED_ENCODE_INFO.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCMSG_SIGNED_AND_ENVELOPED_ENCODE_INFO = ^CMSG_SIGNED_AND_ENVELOPED_ENCODE_INFO;<br> &nbsp;CMSG_SIGNED_AND_ENVELOPED_ENCODE_INFO = record<br> &nbsp; &nbsp;cbSize &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;SignedInfo &nbsp; &nbsp;:CMSG_SIGNED_ENCODE_INFO;<br> &nbsp; &nbsp;EnvelopedInfo :CMSG_ENVELOPED_ENCODE_INFO;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_HASHED<br>//<br>// &nbsp;hCryptProv is used to do the hash. Doesn't need to use a private key.<br>//<br>// &nbsp;If fDetachedHash is set, then, the encoded message doesn't contain<br>// &nbsp;any content (its treated as NULL Data)<br>//<br>// &nbsp;pvHashAuxInfo currently isn't used and must be set to NULL.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCMSG_HASHED_ENCODE_INFO = ^CMSG_HASHED_ENCODE_INFO;<br> &nbsp;CMSG_HASHED_ENCODE_INFO = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp;HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;pvHashAuxInfo :PVOID;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_ENCRYPTED<br>//<br>// &nbsp;The key used to encrypt the message is identified outside of the message<br>// &nbsp;content (for example, password).<br>//<br>// &nbsp;The content input to CryptMsgUpdate has already been encrypted.<br>//<br>// &nbsp;pvEncryptionAuxInfo currently isn't used and must be set to NULL.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCMSG_ENCRYPTED_ENCODE_INFO = ^CMSG_ENCRYPTED_ENCODE_INFO;<br> &nbsp;CMSG_ENCRYPTED_ENCODE_INFO = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;ContentEncryptionAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;pvEncryptionAuxInfo :PVOID;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;This parameter allows messages to be of variable length with streamed<br>// &nbsp;output.<br>//<br>// &nbsp;By default, messages are of a definite length and<br>// &nbsp;CryptMsgGetParam(CMSG_CONTENT_PARAM) is<br>// &nbsp;called to get the cryptographically processed content. Until closed,<br>// &nbsp;the handle keeps a copy of the processed content.<br>//<br>// &nbsp;With streamed output, the processed content can be freed as its streamed.<br>//<br>// &nbsp;If the length of the content to be updated is known at the time of the<br>// &nbsp;open, then, ContentLength should be set to that length. Otherwise, it<br>// &nbsp;should be set to CMSG_INDEFINITE_LENGTH.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PFN_CMSG_STREAM_OUTPUT = function (<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pvArg :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbData :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbData :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fFinal :BOOL):BOOL ; stdcall;<br><br>const <br> &nbsp;CMSG_INDEFINITE_LENGTH = ($FFFFFFFF);<br><br>type<br> &nbsp;PCMSG_STREAM_INFO = ^CMSG_STREAM_INFO;<br> &nbsp;CMSG_STREAM_INFO = record<br> &nbsp; &nbsp;cbContent :DWORD;<br> &nbsp; &nbsp;pfnStreamOutput :PFN_CMSG_STREAM_OUTPUT;<br> &nbsp; &nbsp;pvArg :PVOID;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Open dwFlags<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CMSG_BARE_CONTENT_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $00000001;<br> &nbsp;CMSG_LENGTH_ONLY_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $00000002;<br> &nbsp;CMSG_DETACHED_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $00000004;<br> &nbsp;CMSG_AUTHENTICATED_ATTRIBUTES_FLAG &nbsp;= $00000008;<br> &nbsp;CMSG_CONTENTS_OCTETS_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $00000010;<br> &nbsp;CMSG_MAX_LENGTH_FLAG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $00000020;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Open a cryptographic message for encoding<br>//<br>// &nbsp;For PKCS #7:<br>// &nbsp;If the content to be passed to CryptMsgUpdate has already<br>// &nbsp;been message encoded (the input to CryptMsgUpdate is the streamed output<br>// &nbsp;from another message encode), then, the CMSG_ENCODED_CONTENT_INFO_FLAG should<br>// &nbsp;be set in dwFlags. If not set, then, the inner ContentType is Data and<br>// &nbsp;the input to CryptMsgUpdate is treated as the inner Data type's Content,<br>// &nbsp;a string of bytes.<br>// &nbsp;If CMSG_BARE_CONTENT_FLAG is specified for a streamed message,<br>// &nbsp;the streamed output will not have an outer ContentInfo wrapper. This<br>// &nbsp;makes it suitable to be streamed into an enclosing message.<br>//<br>// &nbsp;The pStreamInfo parameter needs to be set to stream the encoded message<br>// &nbsp;output.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgOpenToEncode(dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwMsgType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvMsgEncodeInfo :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszInnerContentObjID :LPSTR; &nbsp; &nbsp; &nbsp;//OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pStreamInfo :PCMSG_STREAM_INFO &nbsp; &nbsp;//OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):HCRYPTMSG ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Calculate the length of an encoded cryptographic message.<br>//<br>// &nbsp;Calculates the length of the encoded message given the<br>// &nbsp;message type, encoding parameters and total length of<br>// &nbsp;the data to be updated. Note, this might not be the exact length. However,<br>// &nbsp;it will always be greater than or equal to the actual length.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgCalculateEncodedLength(dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwMsgType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvMsgEncodeInfo :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszInnerContentObjID :LPSTR; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbData :DWORD):DWORD ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Open a cryptographic message for decoding<br>//<br>// &nbsp;For PKCS #7: if the inner ContentType isn't Data, then, the inner<br>// &nbsp;ContentInfo consisting of both ContentType and Content is output.<br>// &nbsp;To also enable ContentInfo output for the Data ContentType, then,<br>// &nbsp;the CMSG_ENCODED_CONTENT_INFO_FLAG should be set<br>// &nbsp;in dwFlags. If not set, then, only the content portion of the inner<br>// &nbsp;ContentInfo is output for the Data ContentType.<br>//<br>// &nbsp;To only calculate the length of the decoded message, set the<br>// &nbsp;CMSG_LENGTH_ONLY_FLAG in dwFlags. After the final CryptMsgUpdate get the<br>// &nbsp;MSG_CONTENT_PARAM. Note, this might not be the exact length. However,<br>// &nbsp;it will always be greater than or equal to the actual length.<br>//<br>// &nbsp;hCryptProv specifies the crypto provider to use for hashing and/or<br>// &nbsp;decrypting the message. For enveloped messages, hCryptProv also specifies<br>// &nbsp;the private exchange key to use. For signed messages, hCryptProv is used<br>// &nbsp;when CryptMsgVerifySigner is called.<br>//<br>// &nbsp;For enveloped messages, the pRecipientInfo contains the Issuer and<br>// &nbsp;SerialNumber identifying the RecipientInfo in the message.<br>//<br>// &nbsp;Note, the pRecipientInfo should correspond to the provider's private<br>// &nbsp;exchange key.<br>//<br>// &nbsp;If pRecipientInfo is NULL, then, the message isn't decrypted. To decrypt<br>// &nbsp;the message, CryptMsgControl(CMSG_CTRL_DECRYPT) is called after the final<br>// &nbsp;CryptMsgUpdate.<br>//<br>// &nbsp;The pStreamInfo parameter needs to be set to stream the decoded content<br>// &nbsp;output. Note, if pRecipientInfo is NULL, then, the streamed output isn't<br>// &nbsp;decrypted.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgOpenToDecode(dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwMsgType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pRecipientInfo :PCERT_INFO; &nbsp; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pStreamInfo:PCMSG_STREAM_INFO //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):HCRYPTMSG ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Close a cryptographic message handle<br>//<br>// &nbsp;LastError is preserved unless FALSE is returned.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgClose(hCryptMsg :HCRYPTMSG):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Update the content of a cryptographic message. Depending on how the<br>// &nbsp;message was opened, the content is either encoded or decoded.<br>//<br>// &nbsp;This function is repetitively called to append to the message content.<br>// &nbsp;fFinal is set to identify the last update. On fFinal, the encode/decode<br>// &nbsp;is completed. The encoded/decoded content and the decoded parameters<br>// &nbsp;are valid until the open and all duplicated handles are closed.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgUpdate(hCryptMsg :HCRYPTMSG;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbData :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbData :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fFinal :BOOL):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Perform a special &quot;control&quot; function after the final CryptMsgUpdate of a<br>// &nbsp;encoded/decoded cryptographic message.<br>//<br>// &nbsp;The dwCtrlType parameter specifies the type of operation to be performed.<br>//<br>// &nbsp;The pvCtrlPara definition depends on the dwCtrlType value.<br>//<br>// &nbsp;See below for a list of the control operations and their pvCtrlPara<br>// &nbsp;type definition.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgControl(hCryptMsg :HCRYPTMSG;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwCtrlType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvCtrlPara :PVOID):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Message control types<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CMSG_CTRL_VERIFY_SIGNATURE &nbsp; &nbsp; &nbsp; = 1;<br> &nbsp;CMSG_CTRL_DECRYPT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 2;<br> &nbsp;CMSG_CTRL_VERIFY_HASH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 5;<br> &nbsp;CMSG_CTRL_ADD_SIGNER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 6;<br> &nbsp;CMSG_CTRL_DEL_SIGNER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 7;<br> &nbsp;CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR = 8;<br> &nbsp;CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR = 9;<br> &nbsp;CMSG_CTRL_ADD_CERT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 10;<br> &nbsp;CMSG_CTRL_DEL_CERT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 11;<br> &nbsp;CMSG_CTRL_ADD_CRL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 12;<br> &nbsp;CMSG_CTRL_DEL_CRL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 13;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_VERIFY_SIGNATURE<br>//<br>// &nbsp;Verify the signature of a SIGNED or SIGNED_AND_ENVELOPED<br>// &nbsp;message after it has been decoded.<br>//<br>// &nbsp;For a SIGNED_AND_ENVELOPED message, called after<br>// &nbsp;CryptMsgControl(CMSG_CTRL_DECRYPT), if CryptMsgOpenToDecode was called<br>// &nbsp;with a NULL pRecipientInfo.<br>//<br>// &nbsp;pvCtrlPara points to a CERT_INFO struct.<br>//<br>// &nbsp;The CERT_INFO contains the Issuer and SerialNumber identifying<br>// &nbsp;the Signer of the message. The CERT_INFO also contains the<br>// &nbsp;PublicKeyInfo<br>// &nbsp;used to verify the signature. The cryptographic provider specified<br>// &nbsp;in CryptMsgOpenToDecode is used.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_DECRYPT<br>//<br>// &nbsp;Decrypt an ENVELOPED or SIGNED_AND_ENVELOPED message after it has been<br>// &nbsp;decoded.<br>//<br>// &nbsp;hCryptProv and dwKeySpec specify the private key to use. For dwKeySpec ==<br>// &nbsp;0, defaults to AT_KEYEXCHANGE.<br>//<br>// &nbsp;dwRecipientIndex is the index of the recipient in the message associated<br>// &nbsp;with the hCryptProv's private key.<br>//<br>// &nbsp;This control function needs to be called, if you don't know the appropriate<br>// &nbsp;recipient before calling CryptMsgOpenToDecode. After the final<br>// &nbsp;CryptMsgUpdate, the list of recipients is obtained by iterating through<br>// &nbsp;CMSG_RECIPIENT_INFO_PARAM. The recipient corresponding to a private<br>// &nbsp;key owned by the caller is selected and passed to this function to decrypt<br>// &nbsp;the message.<br>//<br>// &nbsp;Note, the message can only be decrypted once.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCMSG_CTRL_DECRYPT_PARA = ^CMSG_CTRL_DECRYPT_PARA;<br> &nbsp;CMSG_CTRL_DECRYPT_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp;dwKeySpec :DWORD;<br> &nbsp; &nbsp;dwRecipientIndex :DWORD;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_VERIFY_HASH<br>//<br>// &nbsp;Verify the hash of a HASHED message after it has been decoded.<br>//<br>// &nbsp;Only the hCryptMsg parameter is used, to specify the message whose<br>// &nbsp;hash is being verified.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_ADD_SIGNER<br>//<br>// &nbsp;Add a signer to a signed-data or signed-and-enveloped-data message.<br>//<br>// &nbsp;pvCtrlPara points to a CMSG_SIGNER_ENCODE_INFO.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_DEL_SIGNER<br>//<br>// &nbsp;Remove a signer from a signed-data or signed-and-enveloped-data message.<br>//<br>// &nbsp;pvCtrlPara points to a DWORD containing the 0-based index of the<br>// &nbsp;signer to be removed.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR<br>//<br>// &nbsp;Add an unauthenticated attribute to the SignerInfo of a signed-data or<br>// &nbsp;signed-and-enveloped-data message.<br>//<br>// &nbsp;The unauthenticated attribute is input in the form of an encoded blob.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA = ^CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA;<br> &nbsp;CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwSignerIndex :DWORD;<br> &nbsp; &nbsp;blob :CRYPT_DATA_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR<br>//<br>// &nbsp;Delete an unauthenticated attribute from the SignerInfo of a signed-data<br>// &nbsp;or signed-and-enveloped-data message.<br>//<br>// &nbsp;The unauthenticated attribute to be removed is specified by<br>// &nbsp;a 0-based index.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA = ^CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA;<br> &nbsp;CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwSignerIndex :DWORD;<br> &nbsp; &nbsp;dwUnauthAttrIndex :DWORD;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_ADD_CERT<br>//<br>// &nbsp;Add a certificate to a signed-data or signed-and-enveloped-data message.<br>//<br>// &nbsp;pvCtrlPara points to a CRYPT_DATA_BLOB containing the certificate's<br>// &nbsp;encoded bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_DEL_CERT<br>//<br>// &nbsp;Delete a certificate from a signed-data or signed-and-enveloped-data<br>// &nbsp;message.<br>//<br>// &nbsp;pvCtrlPara points to a DWORD containing the 0-based index of the<br>// &nbsp;certificate to be removed.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_ADD_CRL<br>//<br>// &nbsp;Add a CRL to a signed-data or signed-and-enveloped-data message.<br>//<br>// &nbsp;pvCtrlPara points to a CRYPT_DATA_BLOB containing the CRL's<br>// &nbsp;encoded bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CTRL_DEL_CRL<br>//<br>// &nbsp;Delete a CRL from a signed-data or signed-and-enveloped-data message.<br>//<br>// &nbsp;pvCtrlPara points to a DWORD containing the 0-based index of the CRL<br>// &nbsp;to be removed.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify a countersignature, at the SignerInfo level.<br>// &nbsp;ie. verify that pbSignerInfoCountersignature contains the encrypted<br>// &nbsp;hash of the encryptedDigest field of pbSignerInfo.<br>//<br>// &nbsp;hCryptProv is used to hash the encryptedDigest field of pbSignerInfo.<br>// &nbsp;The only fields referenced from pciCountersigner are SerialNumber, Issuer,<br>// &nbsp;and SubjectPublicKeyInfo.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgVerifyCountersignatureEncoded(hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbSignerInfo :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbSignerInfo :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbSignerInfoCountersignature :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbSignerInfoCountersignature :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pciCountersigner :PCERT_INFO):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Countersign an already-existing signature in a message<br>//<br>// &nbsp;dwIndex is a zero-based index of the SignerInfo to be countersigned.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgCountersign(hCryptMsg :HCRYPTMSG;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwIndex :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cCountersigners :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rgCountersigners :PCMSG_SIGNER_ENCODE_INFO):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Countersign an already-existing signature (encoded SignerInfo).<br>// &nbsp;Output an encoded SignerInfo blob, suitable for use as a countersignature<br>// &nbsp;attribute in the unauthenticated attributes of a signed-data or<br>// &nbsp;signed-and-enveloped-data message.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgCountersignEncoded(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbSignerInfo :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbSignerInfo :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cCountersigners :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rgCountersigners :PCMSG_SIGNER_ENCODE_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbCountersignature :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbCountersignature :PDWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Get a parameter after encoding/decoding a cryptographic message. Called<br>// &nbsp;after the final CryptMsgUpdate. Only the CMSG_CONTENT_PARAM and<br>// &nbsp;CMSG_COMPUTED_HASH_PARAM are valid for an encoded message.<br>//<br>// &nbsp;For an encoded HASHED message, the CMSG_COMPUTED_HASH_PARAM can be got<br>// &nbsp;before any CryptMsgUpdates to get its length.<br>//<br>// &nbsp;The pvData type definition depends on the dwParamType value.<br>//<br>// &nbsp;Elements pointed to by fields in the pvData structure follow the<br>// &nbsp;structure. Therefore, *pcbData may exceed the size of the structure.<br>//<br>// &nbsp;Upon input, if *pcbData == 0, then, *pcbData is updated with the length<br>// &nbsp;of the data and the pvData parameter is ignored.<br>//<br>// &nbsp;Upon return, *pcbData is updated with the length of the data.<br>//<br>// &nbsp;The OBJID BLOBs returned in the pvData structures point to<br>// &nbsp;their still encoded representation. The appropriate functions<br>// &nbsp;must be called to decode the information.<br>//<br>// &nbsp;See below for a list of the parameters to get.<br>//--------------------------------------------------------------------------<br><br>function CryptMsgGetParam(hCryptMsg :HCRYPTMSG;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwParamType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwIndex :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvData :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbData :PDWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Get parameter types and their corresponding data structure definitions.<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CMSG_TYPE_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;CMSG_CONTENT_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 2;<br> &nbsp;CMSG_BARE_CONTENT_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 3;<br> &nbsp;CMSG_INNER_CONTENT_TYPE_PARAM &nbsp; &nbsp;= 4;<br> &nbsp;CMSG_SIGNER_COUNT_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 5;<br> &nbsp;CMSG_SIGNER_INFO_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 6;<br> &nbsp;CMSG_SIGNER_CERT_INFO_PARAM &nbsp; &nbsp; &nbsp;= 7;<br> &nbsp;CMSG_SIGNER_HASH_ALGORITHM_PARAM = 8;<br> &nbsp;CMSG_SIGNER_AUTH_ATTR_PARAM &nbsp; &nbsp; &nbsp;= 9;<br> &nbsp;CMSG_SIGNER_UNAUTH_ATTR_PARAM &nbsp; &nbsp;= 10;<br> &nbsp;CMSG_CERT_COUNT_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 11;<br> &nbsp;CMSG_CERT_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 12;<br> &nbsp;CMSG_CRL_COUNT_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 13;<br> &nbsp;CMSG_CRL_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 14;<br> &nbsp;CMSG_ENVELOPE_ALGORITHM_PARAM &nbsp; &nbsp;= 15;<br> &nbsp;CMSG_RECIPIENT_COUNT_PARAM &nbsp; &nbsp; &nbsp; = 17;<br> &nbsp;CMSG_RECIPIENT_INDEX_PARAM &nbsp; &nbsp; &nbsp; = 18;<br> &nbsp;CMSG_RECIPIENT_INFO_PARAM &nbsp; &nbsp; &nbsp; &nbsp;= 19;<br> &nbsp;CMSG_HASH_ALGORITHM_PARAM &nbsp; &nbsp; &nbsp; &nbsp;= 20;<br> &nbsp;CMSG_HASH_DATA_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 21;<br> &nbsp;CMSG_COMPUTED_HASH_PARAM &nbsp; &nbsp; &nbsp; &nbsp; = 22;<br> &nbsp;CMSG_ENCRYPT_PARAM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 26;<br> &nbsp;CMSG_ENCRYPTED_DIGEST &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 27;<br> &nbsp;CMSG_ENCODED_SIGNER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 28;<br> &nbsp;CMSG_ENCODED_MESSAGE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 29;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_TYPE_PARAM<br>//<br>// &nbsp;The type of the decoded message.<br>//<br>// &nbsp;pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CONTENT_PARAM<br>//<br>// &nbsp;The encoded content of a cryptographic message. Depending on how the<br>// &nbsp;message was opened, the content is either the whole PKCS#7<br>// &nbsp;message (opened to encode) or the inner content (opened to decode).<br>// &nbsp;In the decode case, the decrypted content is returned, if enveloped.<br>// &nbsp;If not enveloped, and if the inner content is of type DATA, the returned<br>// &nbsp;data is the contents octets of the inner content.<br>//<br>// &nbsp;pvData points to the buffer receiving the content bytes<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_BARE_CONTENT_PARAM<br>//<br>// &nbsp;The encoded content of an encoded cryptographic message, without the<br>// &nbsp;outer layer of ContentInfo. That is, only the encoding of the<br>// &nbsp;ContentInfo.content field is returned.<br>//<br>// &nbsp;pvData points to the buffer receiving the content bytes<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_INNER_CONTENT_TYPE_PARAM<br>//<br>// &nbsp;The type of the inner content of a decoded cryptographic message,<br>// &nbsp;in the form of a NULL-terminated object identifier string<br>// &nbsp;(eg. &quot;1.2.840.113549.1.7.1&quot;).<br>//<br>// &nbsp;pvData points to the buffer receiving the object identifier string<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_SIGNER_COUNT_PARAM<br>//<br>// &nbsp;Count of signers in a SIGNED or SIGNED_AND_ENVELOPED message<br>//<br>// &nbsp;pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_SIGNER_CERT_INFO_PARAM<br>//<br>// &nbsp;To get all the signers, repetitively call CryptMsgGetParam, with<br>// &nbsp;dwIndex set to 0 .. SignerCount - 1.<br>//<br>// &nbsp;pvData points to a CERT_INFO struct.<br>//<br>// &nbsp;Only the following fields have been updated in the CERT_INFO struct:<br>// &nbsp;Issuer and SerialNumber.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_SIGNER_INFO_PARAM<br>//<br>// &nbsp;To get all the signers, repetitively call CryptMsgGetParam, with<br>// &nbsp;dwIndex set to 0 .. SignerCount - 1.<br>//<br>// &nbsp;pvData points to a CMSG_SIGNER_INFO struct.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCMSG_SIGNER_INFO = ^CMSG_SIGNER_INFO;<br> &nbsp;CMSG_SIGNER_INFO = record<br> &nbsp; &nbsp;dwVersion :DWORD;<br> &nbsp; &nbsp;Issuer :CERT_NAME_BLOB;<br> &nbsp; &nbsp;SerialNumber :CRYPT_INTEGER_BLOB;<br> &nbsp; &nbsp;HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;HashEncryptionAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;EncryptedHash :CRYPT_DATA_BLOB;<br> &nbsp; &nbsp;AuthAttrs :CRYPT_ATTRIBUTES;<br> &nbsp; &nbsp;UnauthAttrs :CRYPT_ATTRIBUTES;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_SIGNER_HASH_ALGORITHM_PARAM<br>//<br>// &nbsp;This parameter specifies the HashAlgorithm that was used for the signer.<br>//<br>// &nbsp;Set dwIndex to iterate through all the signers.<br>//<br>// &nbsp;pvData points to an CRYPT_ALGORITHM_IDENTIFIER struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_SIGNER_AUTH_ATTR_PARAM<br>//<br>// &nbsp;The authenticated attributes for the signer.<br>//<br>// &nbsp;Set dwIndex to iterate through all the signers.<br>//<br>// &nbsp;pvData points to a CMSG_ATTR struct.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;CMSG_ATTR &nbsp; = CRYPT_ATTRIBUTES;<br> &nbsp;PCMSG_ATTR &nbsp;= ^CRYPT_ATTRIBUTES;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_SIGNER_UNAUTH_ATTR_PARAM<br>//<br>// &nbsp;The unauthenticated attributes for the signer.<br>//<br>// &nbsp;Set dwIndex to iterate through all the signers.<br>//<br>// &nbsp;pvData points to a CMSG_ATTR struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CERT_COUNT_PARAM<br>//<br>// &nbsp;Count of certificates in a SIGNED or SIGNED_AND_ENVELOPED message.<br>//<br>// &nbsp;pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CERT_PARAM<br>//<br>// &nbsp;To get all the certificates, repetitively call CryptMsgGetParam, with<br>// &nbsp;dwIndex set to 0 .. CertCount - 1.<br>//<br>// &nbsp;pvData points to an array of the certificate's encoded bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CRL_COUNT_PARAM<br>//<br>// &nbsp;Count of CRLs in a SIGNED or SIGNED_AND_ENVELOPED message.<br>//<br>// &nbsp;pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_CRL_PARAM<br>//<br>// &nbsp;To get all the CRLs, repetitively call CryptMsgGetParam, with<br>// &nbsp;dwIndex set to 0 .. CrlCount - 1.<br>//<br>// &nbsp;pvData points to an array of the CRL's encoded bytes.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_ENVELOPE_ALGORITHM_PARAM<br>//<br>// &nbsp;The ContentEncryptionAlgorithm that was used in<br>// &nbsp;an ENVELOPED or SIGNED_AND_ENVELOPED message.<br>//<br>// &nbsp;pvData points to an CRYPT_ALGORITHM_IDENTIFIER struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_RECIPIENT_COUNT_PARAM<br>//<br>// &nbsp;Count of recipients in an ENVELOPED or SIGNED_AND_ENVELOPED message.<br>//<br>// &nbsp;pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_RECIPIENT_INDEX_PARAM<br>//<br>// &nbsp;Index of the recipient used to decrypt an ENVELOPED or SIGNED_AND_ENVELOPED<br>// &nbsp;message.<br>//<br>// &nbsp;pvData points to a DWORD<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_RECIPIENT_INFO_PARAM<br>//<br>// &nbsp;To get all the recipients, repetitively call CryptMsgGetParam, with<br>// &nbsp;dwIndex set to 0 .. RecipientCount - 1.<br>//<br>// &nbsp;pvData points to a CERT_INFO struct.<br>//<br>// &nbsp;Only the following fields have been updated in the CERT_INFO struct:<br>// &nbsp;Issuer, SerialNumber and PublicKeyAlgorithm. The PublicKeyAlgorithm<br>// &nbsp;specifies the KeyEncryptionAlgorithm that was used.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_HASH_ALGORITHM_PARAM<br>//<br>// &nbsp;The HashAlgorithm in a HASHED message.<br>//<br>// &nbsp;pvData points to an CRYPT_ALGORITHM_IDENTIFIER struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_HASH_DATA_PARAM<br>//<br>// &nbsp;The hash in a HASHED message.<br>//<br>// &nbsp;pvData points to an array of bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_COMPUTED_HASH_PARAM<br>//<br>// &nbsp;The computed hash for a HASHED message.<br>//<br>// &nbsp;This may be called for either an encoded or decoded message.<br>// &nbsp;It also may be called before any encoded CryptMsgUpdates to get its length.<br>//<br>// &nbsp;pvData points to an array of bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_ENCRYPT_PARAM<br>//<br>// &nbsp;The ContentEncryptionAlgorithm that was used in an ENCRYPTED message.<br>//<br>// &nbsp;pvData points to an CRYPT_ALGORITHM_IDENTIFIER struct.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CMSG_ENCODED_MESSAGE<br>//<br>// &nbsp;The full encoded message. This is useful in the case of a decoded<br>// &nbsp;message which has been modified (eg. a signed-data or<br>// &nbsp;signed-and-enveloped-data message which has been countersigned).<br>//<br>// &nbsp;pvData points to an array of the message's encoded bytes.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;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> &nbsp;CMSG_OID_GEN_ENCRYPT_KEY_FUNC = 'CryptMsgDllGenEncryptKey';<br><br>type<br> &nbsp;PFN_CMSG_GEN_ENCRYPT_KEY = function (phCryptProv :PHCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; paiEncrypt :PCRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvEncryptAuxInfo :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pPublicKeyInfo :PCERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; phEncryptKey :PHCRYPTKEY<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):BOOL ; stdcall;<br><br>const <br> &nbsp;CMSG_OID_EXPORT_ENCRYPT_KEY_FUNC = 'CryptMsgDllExportEncryptKey';<br><br>type<br> &nbsp;PFN_CMSG_EXPORT_ENCRYPT_KEY = function (hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hEncryptKey :HCRYPTKEY;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pPublicKeyInfo :PCERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbData :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbData :PDWORD):BOOL ; stdcall;<br><br>const <br> &nbsp;CMSG_OID_IMPORT_ENCRYPT_KEY_FUNC = 'CryptMsgDllImportEncryptKey';<br><br>type<br> &nbsp;PFN_CMSG_IMPORT_ENCRYPT_KEY = function (hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwKeySpec :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;paiEncrypt :PCRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;paiPubKey :PCRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbEncodedKey :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbEncodedKey :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;phEncryptKey :PHCRYPTKEY<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br><br>//+=========================================================================<br>// &nbsp;Certificate Store Data Structures and APIs<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;In its most basic implementation, a cert store is simply a<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;collection of certificates and/or CRLs. This is the case when<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a cert store is opened with all of its certificates and CRLs<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;coming from a PKCS #7 encoded cryptographic message.<br>//<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Nonetheless, all cert stores have the following properties:<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - A public key may have more than one certificate in the store.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; For example, a private/public key used for signing may have a<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; certificate issued for VISA and another issued for<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Mastercard. Also, when a certificate is renewed there might<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; be more than one certificate with the same subject and<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; issuer.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - However, each certificate in the store is uniquely<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; identified by its Issuer and SerialNumber.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - There's an issuer of subject certificate relationship. A<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; certificate's issuer is found by doing a match of<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pSubjectCert-&gt;Issuer with pIssuerCert-&gt;Subject.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; The relationship is verified by using<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; the issuer's public key to verify the subject certificate's<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; signature. Note, there might be X.509 v3 extensions<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; to assist in finding the issuer certificate.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - Since issuer certificates might be renewed, a subject<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; certificate might have more than one issuer certificate.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - There's an issuer of CRL relationship. An<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; issuer's CRL is found by doing a match of<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pIssuerCert-&gt;Subject with pCrl-&gt;Issuer.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; The relationship is verified by using<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; the issuer's public key to verify the CRL's<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; signature. Note, there might be X.509 v3 extensions<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; to assist in finding the CRL.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - Since some issuers might support the X.509 v3 delta CRL<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; extensions, an issuer might have more than one CRL.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - The store shouldn't have any redundant certificates or<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CRLs. There shouldn't be two certificates with the same<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Issuer and SerialNumber. There shouldn't be two CRLs with<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; the same Issuer, ThisUpdate and NextUpdate.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - The store has NO policy or trust information. No<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; certificates are tagged as being &quot;root&quot;. Its up to<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; the application to maintain a list of CertIds (Issuer +<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SerialNumber) for certificates it trusts.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - The store might contain bad certificates and/or CRLs.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; The issuer's signature of a subject certificate or CRL may<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; not verify. Certificates or CRLs may not satisfy their<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time validity requirements. Certificates may be<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; revoked.<br>//<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;In addition to the certificates and CRLs, properties can be<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;stored. There are two predefined property IDs for a user<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;certificate: CERT_KEY_PROV_HANDLE_PROP_ID and<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CERT_KEY_PROV_INFO_PROP_ID. The CERT_KEY_PROV_HANDLE_PROP_ID<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;is a HCRYPTPROV handle to the private key assoicated<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;with the certificate. The CERT_KEY_PROV_INFO_PROP_ID contains<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;information to be used to call<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CryptAcquireContext and CryptProvSetParam to get a handle<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;to the private key associated with the certificate.<br>//<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;There exists two more predefined property IDs for certificates<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;and CRLs, CERT_SHA1_HASH_PROP_ID and CERT_MD5_HASH_PROP_ID.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If these properties don't already exist, then, a hash of the<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;content is computed. (CERT_HASH_PROP_ID maps to the default<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hash algorithm, currently, CERT_SHA1_HASH_PROP_ID).<br>//<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;There are additional APIs for creating certificate and CRL<br>// &nbsp; &nbsp; &nbsp;contexts not in a store (CertCreateCertificateContext and<br>// &nbsp; &nbsp; &nbsp;CertCreateCRLContext).<br>//<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;HCERTSTORE = PVOID;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate context.<br>//<br>// &nbsp;A certificate context contains both the encoded and decoded representation<br>// &nbsp;of a certificate. A certificate context returned by a cert store function<br>// &nbsp;must be freed by calling the CertFreeCertificateContext function. The<br>// &nbsp;CertDuplicateCertificateContext function can be called to make a duplicate<br>// &nbsp;copy (which also must be freed by calling CertFreeCertificateContext).<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_CONTEXT = ^CERT_CONTEXT;<br> &nbsp;CERT_CONTEXT = record<br> &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp;pbCertEncoded :PBYTE;<br> &nbsp; &nbsp;cbCertEncoded :DWORD;<br> &nbsp; &nbsp;pCertInfo :PCERT_INFO;<br> &nbsp; &nbsp;hCertStore :HCERTSTORE;<br> &nbsp;end;<br><br>type<br> &nbsp;PCCERT_CONTEXT = ^CERT_CONTEXT;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CRL context.<br>//<br>// &nbsp;A CRL context contains both the encoded and decoded representation<br>// &nbsp;of a CRL. A CRL context returned by a cert store function<br>// &nbsp;must be freed by calling the CertFreeCRLContext function. The<br>// &nbsp;CertDuplicateCRLContext function can be called to make a duplicate<br>// &nbsp;copy (which also must be freed by calling CertFreeCRLContext).<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRL_CONTEXT = ^CRL_CONTEXT;<br> &nbsp;CRL_CONTEXT = record<br> &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp;pbCrlEncoded :PBYTE;<br> &nbsp; &nbsp;cbCrlEncoded :DWORD;<br> &nbsp; &nbsp;pCrlInfo :PCRL_INFO;<br> &nbsp; &nbsp;hCertStore :HCERTSTORE;<br> &nbsp;end;<br><br>type<br> &nbsp;PCCRL_CONTEXT = ^CRL_CONTEXT;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Trust List (CTL) context.<br>//<br>// &nbsp;A CTL context contains both the encoded and decoded representation<br>// &nbsp;of a CTL. Also contains an opened HCRYPTMSG handle to the decoded<br>// &nbsp;cryptographic signed message containing the CTL_INFO as its inner content.<br>// &nbsp;pbCtlContent is the encoded inner content of the signed message.<br>//<br>// &nbsp;The CryptMsg APIs can be used to extract additional signer information.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCTL_CONTEXT = ^CTL_CONTEXT;<br> &nbsp;CTL_CONTEXT = record<br> &nbsp; &nbsp;dwMsgAndCertEncodingType :DWORD;<br> &nbsp; &nbsp;pbCtlEncoded :PBYTE;<br> &nbsp; &nbsp;cbCtlEncoded :DWORD;<br> &nbsp; &nbsp;pCtlInfo :PCTL_INFO;<br> &nbsp; &nbsp;hCertStore :HCERTSTORE;<br> &nbsp; &nbsp;hCryptMsg :HCRYPTMSG;<br> &nbsp; &nbsp;pbCtlContent :PBYTE;<br> &nbsp; &nbsp;cbCtlContent :DWORD;<br> &nbsp;end;<br><br>type<br> &nbsp;PCCTL_CONTEXT = ^CTL_CONTEXT;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate, CRL and CTL property IDs<br>//<br>// &nbsp;See CertSetCertificateContextProperty or CertGetCertificateContextProperty<br>// &nbsp;for usage information.<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CERT_KEY_PROV_HANDLE_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp;= 1;<br> &nbsp;CERT_KEY_PROV_INFO_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 2;<br> &nbsp;CERT_SHA1_HASH_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 3;<br> &nbsp;CERT_MD5_HASH_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 4;<br> &nbsp;CERT_HASH_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = CERT_SHA1_HASH_PROP_ID;<br> &nbsp;CERT_KEY_CONTEXT_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 5;<br> &nbsp;CERT_KEY_SPEC_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 6;<br> &nbsp;CERT_IE30_RESERVED_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 7;<br> &nbsp;CERT_PUBKEY_HASH_RESERVED_PROP_ID &nbsp; = 8;<br> &nbsp;CERT_ENHKEY_USAGE_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 9;<br> &nbsp;CERT_CTL_USAGE_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= CERT_ENHKEY_USAGE_PROP_ID;<br> &nbsp;CERT_NEXT_UPDATE_LOCATION_PROP_ID &nbsp; = 10;<br> &nbsp;CERT_FRIENDLY_NAME_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 11;<br> &nbsp;CERT_PVK_FILE_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 12;<br>// Note, 32 - 34 are reserved for the CERT, CRL and CTL file element IDs.<br> &nbsp;CERT_FIRST_RESERVED_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; = 13;<br><br> &nbsp;CERT_LAST_RESERVED_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $00007FFF;<br> &nbsp;CERT_FIRST_USER_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $00008000;<br> &nbsp;CERT_LAST_USER_PROP_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $0000FFFF;<br><br>function IS_CERT_HASH_PROP_ID( X :DWORD):BOOL ;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Cryptographic Key Provider Information<br>//<br>// &nbsp;CRYPT_KEY_PROV_INFO defines the CERT_KEY_PROV_INFO_PROP_ID's pvData.<br>//<br>// &nbsp;The CRYPT_KEY_PROV_INFO fields are passed to CryptAcquireContext<br>// &nbsp;to get a HCRYPTPROV handle. The optional CRYPT_KEY_PROV_PARAM fields are<br>// &nbsp;passed to CryptProvSetParam to further initialize the provider.<br>//<br>// &nbsp;The dwKeySpec field identifies the private key to use from the container<br>// &nbsp;For example, AT_KEYEXCHANGE or AT_SIGNATURE.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_KEY_PROV_PARAM = ^CRYPT_KEY_PROV_PARAM;<br> &nbsp;CRYPT_KEY_PROV_PARAM = record<br> &nbsp; &nbsp;dwParam :DWORD;<br> &nbsp; &nbsp;pbData &nbsp;:PBYTE;<br> &nbsp; &nbsp;cbData &nbsp;:DWORD;<br> &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp;end;<br><br>type<br> &nbsp;PCRYPT_KEY_PROV_INFO = ^CRYPT_KEY_PROV_INFO;<br> &nbsp;CRYPT_KEY_PROV_INFO = record<br> &nbsp; &nbsp;pwszContainerName :LPWSTR;<br> &nbsp; &nbsp;pwszProvName &nbsp; &nbsp; &nbsp;:LPWSTR;<br> &nbsp; &nbsp;dwProvType &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;dwFlags &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp; &nbsp;cProvParam &nbsp; &nbsp; &nbsp; &nbsp;:DWORD;<br> &nbsp; &nbsp;rgProvParam &nbsp; &nbsp; &nbsp; :PCRYPT_KEY_PROV_PARAM;<br> &nbsp; &nbsp;dwKeySpec &nbsp; &nbsp; &nbsp; &nbsp; :DWORD;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;The following flag should be set in the above dwFlags to enable<br>// &nbsp;a CertSetCertificateContextProperty(CERT_KEY_CONTEXT_PROP_ID) after a<br>// &nbsp;CryptAcquireContext is done in the Sign or Decrypt Message functions.<br>//<br>// &nbsp;The following define must not collide with any of the<br>// &nbsp;CryptAcquireContext dwFlag defines.<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CERT_SET_KEY_PROV_HANDLE_PROP_ID = $00000001;<br> &nbsp;CERT_SET_KEY_CONTEXT_PROP_ID &nbsp; &nbsp; = $00000001;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Key Context<br>//<br>// &nbsp;CERT_KEY_CONTEXT defines the CERT_KEY_CONTEXT_PROP_ID's pvData.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCERT_KEY_CONTEXT = ^CERT_KEY_CONTEXT;<br> &nbsp;CERT_KEY_CONTEXT = record<br> &nbsp; &nbsp;cbSize &nbsp; &nbsp; :DWORD; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // sizeof(CERT_KEY_CONTEXT)<br> &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp;dwKeySpec &nbsp;:DWORD;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Store Provider Types<br>//--------------------------------------------------------------------------<br><br>const <br> &nbsp;CERT_STORE_PROV_MSG = (LPCSTR(1));<br> &nbsp;CERT_STORE_PROV_MEMORY = (LPCSTR(2));<br> &nbsp;CERT_STORE_PROV_FILE = (LPCSTR(3));<br> &nbsp;CERT_STORE_PROV_REG = (LPCSTR(4));<br><br> &nbsp;CERT_STORE_PROV_PKCS7 = (LPCSTR(5));<br> &nbsp;CERT_STORE_PROV_SERIALIZED = (LPCSTR(6));<br> &nbsp;CERT_STORE_PROV_FILENAME_A = (LPCSTR(7));<br> &nbsp;CERT_STORE_PROV_FILENAME_W = (LPCSTR(8));<br> &nbsp;CERT_STORE_PROV_FILENAME = &nbsp;CERT_STORE_PROV_FILENAME_W;<br> &nbsp;CERT_STORE_PROV_SYSTEM_A = (LPCSTR(9));<br> &nbsp;CERT_STORE_PROV_SYSTEM_W = &nbsp;(LPCSTR(10));<br> &nbsp;CERT_STORE_PROV_SYSTEM = CERT_STORE_PROV_SYSTEM_W;<br><br> &nbsp;sz_CERT_STORE_PROV_MEMORY = 'Memory';<br> &nbsp;sz_CERT_STORE_PROV_FILENAME_W = 'File';<br> &nbsp;sz_CERT_STORE_PROV_FILENAME = sz_CERT_STORE_PROV_FILENAME_W;<br> &nbsp;sz_CERT_STORE_PROV_SYSTEM_W = 'System';<br> &nbsp;sz_CERT_STORE_PROV_SYSTEM = sz_CERT_STORE_PROV_SYSTEM_W;<br> &nbsp;sz_CERT_STORE_PROV_PKCS7 = 'PKCS7';<br> &nbsp;sz_CERT_STORE_PROV_SERIALIZED = 'Serialized';<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Store verify/results flags<br>//--------------------------------------------------------------------------<br><br> &nbsp;CERT_STORE_SIGNATURE_FLAG = $00000001;<br> &nbsp;CERT_STORE_TIME_VALIDITY_FLAG = $00000002;<br> &nbsp;CERT_STORE_REVOCATION_FLAG = $00000004;<br> &nbsp;CERT_STORE_NO_CRL_FLAG = $00010000;<br> &nbsp;CERT_STORE_NO_ISSUER_FLAG = $00020000;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Store open/property flags<br>//--------------------------------------------------------------------------<br><br> &nbsp;CERT_STORE_NO_CRYPT_RELEASE_FLAG = $00000001;<br> &nbsp;CERT_STORE_READONLY_FLAG = $00008000;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Store Provider flags are in the HiWord (0xFFFF0000)<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate System Store Flag Values<br>//--------------------------------------------------------------------------<br>// Location of the system store in the registry:<br>// &nbsp;HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE<br> &nbsp;CERT_SYSTEM_STORE_LOCATION_MASK = $00030000;<br> &nbsp;CERT_SYSTEM_STORE_CURRENT_USER &nbsp;= $00010000;<br> &nbsp;CERT_SYSTEM_STORE_LOCAL_MACHINE = $00020000;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Open the cert store using the specified store provider.<br>//<br>// &nbsp;hCryptProv specifies the crypto provider to use to create the hash<br>// &nbsp;properties or verify the signature of a subject certificate or CRL.<br>// &nbsp;The store doesn't need to use a private<br>// &nbsp;key. If the CERT_STORE_NO_CRYPT_RELEASE_FLAG isn't set, hCryptProv is<br>// &nbsp;CryptReleaseContext'ed on the final CertCloseStore.<br>//<br>// &nbsp;Note, if the open fails, hCryptProv is released if it would have been<br>// &nbsp;released when the store was closed.<br>//<br>// &nbsp;If hCryptProv is zero, then, the default provider and container for the<br>// &nbsp;PROV_RSA_FULL provider type is CryptAcquireContext'ed with<br>// &nbsp;CRYPT_VERIFYCONTEXT access. The CryptAcquireContext is deferred until<br>// &nbsp;the first create hash or verify signature. In addition, once acquired,<br>// &nbsp;the default provider isn't released until process exit when crypt32.dll<br>// &nbsp;is unloaded. The acquired default provider is shared across all stores<br>// &nbsp;and threads.<br>//<br>// &nbsp;After initializing the store's data structures and optionally acquiring a<br>// &nbsp;default crypt provider, CertOpenStore calls CryptGetOIDFunctionAddress to<br>// &nbsp;get the address of the CRYPT_OID_OPEN_STORE_PROV_FUNC specified by<br>// &nbsp;lpszStoreProvider. Since a store can contain certificates with different<br>// &nbsp;encoding types, CryptGetOIDFunctionAddress is called with dwEncodingType<br>// &nbsp;set to 0 and not the dwEncodingType passed to CertOpenStore.<br>// &nbsp;PFN_CERT_DLL_OPEN_STORE_FUNC specifies the signature of the provider's<br>// &nbsp;open function. This provider open function is called to load the<br>// &nbsp;store's certificates and CRLs. Optionally, the provider may return an<br>// &nbsp;array of functions called before a certificate or CRL is added or deleted<br>// &nbsp;or has a property that is set.<br>//<br>// &nbsp;Use of the dwEncodingType parameter is provider dependent. The type<br>// &nbsp;definition for pvPara also depends on the provider.<br>//<br>// &nbsp;Store providers are installed or registered via<br>// &nbsp;CryptInstallOIDFunctionAddress or CryptRegisterOIDFunction, where,<br>// &nbsp;dwEncodingType is 0 and pszFuncName is CRYPT_OID_OPEN_STORE_PROV_FUNC.<br>//<br>// &nbsp;Here's a list of the predefined provider types (implemented in crypt32.dll):<br>//<br>// &nbsp;CERT_STORE_PROV_MSG:<br>// &nbsp; &nbsp; &nbsp;Gets the certificates and CRLs from the specified cryptographic message.<br>// &nbsp; &nbsp; &nbsp;dwEncodingType contains the message and certificate encoding types.<br>// &nbsp; &nbsp; &nbsp;The message's handle is passed in pvPara. Given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HCRYPTMSG hCryptMsg; pvPara = (const void *) hCryptMsg;<br>//<br>// &nbsp;CERT_STORE_PROV_MEMORY<br>// &nbsp;sz_CERT_STORE_PROV_MEMORY:<br>// &nbsp; &nbsp; &nbsp;Opens a store without any initial certificates or CRLs. pvPara<br>// &nbsp; &nbsp; &nbsp;isn't used.<br>//<br>// &nbsp;CERT_STORE_PROV_FILE:<br>// &nbsp; &nbsp; &nbsp;Reads the certificates and CRLs from the specified file. The file's<br>// &nbsp; &nbsp; &nbsp;handle is passed in pvPara. Given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HANDLE hFile; pvPara = (const void *) hFile;<br>//<br>// &nbsp; &nbsp; &nbsp;For a successful open, the file pointer is advanced past<br>// &nbsp; &nbsp; &nbsp;the certificates and CRLs and their properties read from the file.<br>// &nbsp; &nbsp; &nbsp;Note, only expects a serialized store and not a file containing<br>// &nbsp; &nbsp; &nbsp;either a PKCS #7 signed message or a single encoded certificate.<br>//<br>// &nbsp; &nbsp; &nbsp;The hFile isn't closed.<br>//<br>// &nbsp;CERT_STORE_PROV_REG:<br>// &nbsp; &nbsp; &nbsp;Reads the certificates and CRLs from the registry. The registry's<br>// &nbsp; &nbsp; &nbsp;key handle is passed in pvPara. Given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HKEY hKey; pvPara = (const void *) hKey;<br>//<br>// &nbsp; &nbsp; &nbsp;The input hKey isn't closed by the provider. Before returning, the<br>// &nbsp; &nbsp; &nbsp;provider opens/creates &quot;Certificates&quot; and &quot;CRLs&quot; subkeys. These<br>// &nbsp; &nbsp; &nbsp;subkeys remain open until the store is closed.<br>//<br>// &nbsp; &nbsp; &nbsp;If CERT_STORE_READONLY_FLAG is set, then, the registry subkeys are<br>// &nbsp; &nbsp; &nbsp;RegOpenKey'ed with KEY_READ_ACCESS. Otherwise, the registry subkeys<br>// &nbsp; &nbsp; &nbsp;are RegCreateKey'ed with KEY_ALL_ACCESS.<br>//<br>// &nbsp; &nbsp; &nbsp;This provider returns the array of functions for reading, writing,<br>// &nbsp; &nbsp; &nbsp;deleting and property setting certificates and CRLs.<br>// &nbsp; &nbsp; &nbsp;Any changes to the opened store are immediately pushed through to<br>// &nbsp; &nbsp; &nbsp;the registry. However, if CERT_STORE_READONLY_FLAG is set, then,<br>// &nbsp; &nbsp; &nbsp;writing, deleting or property setting results in a<br>// &nbsp; &nbsp; &nbsp;SetLastError(E_ACCESSDENIED).<br>//<br>// &nbsp; &nbsp; &nbsp;Note, all the certificates and CRLs are read from the registry<br>// &nbsp; &nbsp; &nbsp;when the store is opened. The opened store serves as a write through<br>// &nbsp; &nbsp; &nbsp;cache. However, the opened store isn't notified of other changes<br>// &nbsp; &nbsp; &nbsp;made to the registry. Note, RegNotifyChangeKeyValue is supported<br>// &nbsp; &nbsp; &nbsp;on NT but not supported on Windows95.<br>//<br>// &nbsp;CERT_STORE_PROV_PKCS7:<br>// &nbsp;sz_CERT_STORE_PROV_PKCS7:<br>// &nbsp; &nbsp; &nbsp;Gets the certificates and CRLs from the encoded PKCS #7 signed message.<br>// &nbsp; &nbsp; &nbsp;dwEncodingType specifies the message and certificate encoding types.<br>// &nbsp; &nbsp; &nbsp;The pointer to the encoded message's blob is passed in pvPara. Given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRYPT_DATA_BLOB EncodedMsg; pvPara = (const void *) &EncodedMsg;<br>//<br>// &nbsp; &nbsp; &nbsp;Note, also supports the IE3.0 special version of a<br>// &nbsp; &nbsp; &nbsp;PKCS #7 signed message referred to as a &quot;SPC&quot; formatted message.<br>//<br>// &nbsp;CERT_STORE_PROV_SERIALIZED:<br>// &nbsp;sz_CERT_STORE_PROV_SERIALIZED:<br>// &nbsp; &nbsp; &nbsp;Gets the certificates and CRLs from memory containing a serialized<br>// &nbsp; &nbsp; &nbsp;store. &nbsp;The pointer to the serialized memory blob is passed in pvPara.<br>// &nbsp; &nbsp; &nbsp;Given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRYPT_DATA_BLOB Serialized; pvPara = (const void *) &Serialized;<br>//<br>// &nbsp;CERT_STORE_PROV_FILENAME_A:<br>// &nbsp;CERT_STORE_PROV_FILENAME_W:<br>// &nbsp;CERT_STORE_PROV_FILENAME:<br>// &nbsp;sz_CERT_STORE_PROV_FILENAME_W:<br>// &nbsp;sz_CERT_STORE_PROV_FILENAME:<br>// &nbsp; &nbsp; &nbsp;Opens the file and first attempts to read as a serialized store. Then,<br>// &nbsp; &nbsp; &nbsp;as a PKCS #7 signed message. Finally, as a single encoded certificate.<br>// &nbsp; &nbsp; &nbsp;The filename is passed in pvPara. The filename is UNICODE for the<br>// &nbsp; &nbsp; &nbsp;&quot;_W&quot; provider and ASCII for the &quot;_A&quot; provider. For &quot;_W&quot;: given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCWSTR pwszFilename; pvPara = (const void *) pwszFilename;<br>// &nbsp; &nbsp; &nbsp;For &quot;_A&quot;: given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCSTR pszFilename; pvPara = (const void *) pszFilename;<br>//<br>// &nbsp; &nbsp; &nbsp;Note, the default (without &quot;_A&quot; or &quot;_W&quot;) is unicode.<br>//<br>// &nbsp; &nbsp; &nbsp;Note, also supports the reading of the IE3.0 special version of a<br>// &nbsp; &nbsp; &nbsp;PKCS #7 signed message file referred to as a &quot;SPC&quot; formatted file.<br>//<br>// &nbsp;CERT_STORE_PROV_SYSTEM_A:<br>// &nbsp;CERT_STORE_PROV_SYSTEM_W:<br>// &nbsp;CERT_STORE_PROV_SYSTEM:<br>// &nbsp;sz_CERT_STORE_PROV_SYSTEM_W:<br>// &nbsp;sz_CERT_STORE_PROV_SYSTEM:<br>// &nbsp; &nbsp; &nbsp;Opens the specified &quot;system&quot; store. Currently, all the system<br>// &nbsp; &nbsp; &nbsp;stores are stored in the registry. The upper word of the dwFlags<br>// &nbsp; &nbsp; &nbsp;parameter is used to specify the location of the system store. It<br>// &nbsp; &nbsp; &nbsp;should be set to either CERT_SYSTEM_STORE_CURRENT_USER for<br>// &nbsp; &nbsp; &nbsp;HKEY_CURRENT_USER or CERT_SYSTEM_STORE_LOCAL_MACHINE for<br>// &nbsp; &nbsp; &nbsp;HKEY_LOCAL_MACHINE.<br>//<br>// &nbsp; &nbsp; &nbsp;After opening the registry key associated with the system name,<br>// &nbsp; &nbsp; &nbsp;the CERT_STORE_PROV_REG provider is called to complete the open.<br>//<br>// &nbsp; &nbsp; &nbsp;The system store name is passed in pvPara. The name is UNICODE for the<br>// &nbsp; &nbsp; &nbsp;&quot;_W&quot; provider and ASCII for the &quot;_A&quot; provider. For &quot;_W&quot;: given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCWSTR pwszSystemName; pvPara = (const void *) pwszSystemName;<br>// &nbsp; &nbsp; &nbsp;For &quot;_A&quot;: given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCSTR pszSystemName; pvPara = (const void *) pszSystemName;<br>//<br>// &nbsp; &nbsp; &nbsp;Note, the default (without &quot;_A&quot; or &quot;_W&quot;) is UNICODE.<br>//<br>// &nbsp; &nbsp; &nbsp;If CERT_STORE_READONLY_FLAG is set, then, the registry is<br>// &nbsp; &nbsp; &nbsp;RegOpenKey'ed with KEY_READ_ACCESS. Otherwise, the registry is<br>// &nbsp; &nbsp; &nbsp;RegCreateKey'ed with KEY_ALL_ACCESS.<br>//<br>// &nbsp; &nbsp; &nbsp;The &quot;root&quot; store is treated differently from the other system<br>// &nbsp; &nbsp; &nbsp;stores. Before a certificate is added to or deleted from the &quot;root&quot;<br>// &nbsp; &nbsp; &nbsp;store, a pop up message box is displayed. The certificate's subject,<br>// &nbsp; &nbsp; &nbsp;issuer, serial number, time validity, sha1 and md5 thumbprints are<br>// &nbsp; &nbsp; &nbsp;displayed. The user is given the option to do the add or delete.<br>// &nbsp; &nbsp; &nbsp;If they don't allow the operation, LastError is set to E_ACCESSDENIED.<br>//--------------------------------------------------------------------------<br><br>function CertOpenStore(lpszStoreProvider :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pvPara :PVOID):HCERTSTORE ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;OID Installable Certificate Store Provider Data Structures<br>//--------------------------------------------------------------------------<br><br>// Handle returned by the store provider when opened.<br>type <br> &nbsp;HCERTSTOREPROV = PVOID;<br><br>// Store Provider OID function's pszFuncName.<br>const <br> &nbsp;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> &nbsp;PCERT_STORE_PROV_INFO = ^CERT_STORE_PROV_INFO;<br> &nbsp;CERT_STORE_PROV_INFO = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;cStoreProvFunc :DWORD;<br> &nbsp; &nbsp;rgpvStoreProvFunc :PPVOID;<br> &nbsp; &nbsp;hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp;dwStoreProvFlags :DWORD;<br> &nbsp;end;<br><br>// Definition of the store provider's open function.<br>//<br>// *pStoreProvInfo has been zeroed before the call.<br>//<br>// Note, pStoreProvInfo-&gt;cStoreProvFunc should be set last. &nbsp;Once set,<br>// all subsequent store calls, such as CertAddSerializedElementToStore will<br>// call the appropriate provider callback function.<br><br>type<br> &nbsp;PFN_CERT_DLL_OPEN_STORE_PROV_FUNC = function (lpszStoreProvider :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pvPara :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pStoreProvInfo :PCERT_STORE_PROV_INFO<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):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-&gt;cStoreProvFunc to the last index + 1 and any<br>// preceding not implemented functions to NULL.<br><br>const <br> &nbsp;CERT_STORE_PROV_CLOSE_FUNC = 0;<br> &nbsp;CERT_STORE_PROV_READ_CERT_FUNC = 1;<br> &nbsp;CERT_STORE_PROV_WRITE_CERT_FUNC = 2;<br> &nbsp;CERT_STORE_PROV_DELETE_CERT_FUNC = 3;<br> &nbsp;CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC = 4;<br> &nbsp;CERT_STORE_PROV_READ_CRL_FUNC = 5;<br> &nbsp;CERT_STORE_PROV_WRITE_CRL_FUNC = 6;<br> &nbsp;CERT_STORE_PROV_DELETE_CRL_FUNC = 7;<br> &nbsp;CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC = 8;<br> &nbsp;CERT_STORE_PROV_READ_CTL_FUNC = 9;<br> &nbsp;CERT_STORE_PROV_WRITE_CTL_FUNC = 10;<br> &nbsp;CERT_STORE_PROV_DELETE_CTL_FUNC = 11;<br> &nbsp;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> &nbsp;PFN_CERT_STORE_PROV_CLOSE = procedure(hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD) ; 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> &nbsp;PFN_CERT_STORE_PROV_READ_CERT = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pStoreCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppProvCertContext :PCCERT_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br><br>const <br> &nbsp;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> &nbsp;PFN_CERT_STORE_PROV_WRITE_CERT = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD):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> &nbsp;PFN_CERT_STORE_PROV_DELETE_CERT = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD):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> &nbsp;PFN_CERT_STORE_PROV_SET_CERT_PROPERTY = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwPropId :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pvData :PVOID<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):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> &nbsp;PFN_CERT_STORE_PROV_READ_CRL = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pStoreCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var ppProvCrlContext :PCCRL_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):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> &nbsp;PFN_CERT_STORE_PROV_WRITE_CRL = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD):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> &nbsp;PFN_CERT_STORE_PROV_DELETE_CRL = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD):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> &nbsp;PFN_CERT_STORE_PROV_SET_CRL_PROPERTY = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwPropId :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvData :PVOID):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> &nbsp;PFN_CERT_STORE_PROV_READ_CTL = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pStoreCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var ppProvCtlContext :PCCTL_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):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> &nbsp;PFN_CERT_STORE_PROV_WRITE_CTL = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD):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> &nbsp;PFN_CERT_STORE_PROV_DELETE_CTL = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD):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> &nbsp;PFN_CERT_STORE_PROV_SET_CTL_PROPERTY = function (hStoreProv :HCERTSTOREPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwPropId :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pvData :PVOID<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;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>// &nbsp;Save the cert store. Extended version with lots of options.<br>//<br>// &nbsp;According to the dwSaveAs parameter, the store can be saved as a<br>// &nbsp;serialized store (CERT_STORE_SAVE_AS_STORE) containing properties in<br>// &nbsp;addition to encoded certificates, CRLs and CTLs or the store can be saved<br>// &nbsp;as a PKCS #7 signed message (CERT_STORE_SAVE_AS_PKCS7) which doesn't<br>// &nbsp;include the properties or CTLs.<br>//<br>// &nbsp;Note, the CERT_KEY_CONTEXT_PROP_ID property (and its<br>// &nbsp;CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_SPEC_PROP_ID) isn't saved into<br>// &nbsp;a serialized store.<br>//<br>// &nbsp;For CERT_STORE_SAVE_AS_PKCS7, the dwEncodingType specifies the message<br>// &nbsp;encoding type. The dwEncodingType parameter isn't used for<br>// &nbsp;CERT_STORE_SAVE_AS_STORE.<br>//<br>// &nbsp;The dwFlags parameter currently isn't used and should be set to 0.<br>//<br>// &nbsp;The dwSaveTo and pvSaveToPara parameters specify where to save the<br>// &nbsp;store as follows:<br>// &nbsp; &nbsp;CERT_STORE_SAVE_TO_FILE:<br>// &nbsp; &nbsp; &nbsp;Saves to the specified file. The file's handle is passed in<br>// &nbsp; &nbsp; &nbsp;pvSaveToPara. Given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HANDLE hFile; pvSaveToPara = (void *) hFile;<br>//<br>// &nbsp; &nbsp; &nbsp;For a successful save, the file pointer is positioned after the<br>// &nbsp; &nbsp; &nbsp;last write.<br>//<br>// &nbsp; &nbsp;CERT_STORE_SAVE_TO_MEMORY:<br>// &nbsp; &nbsp; &nbsp;Saves to the specified memory blob. The pointer to<br>// &nbsp; &nbsp; &nbsp;the memory blob is passed in pvSaveToPara. Given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRYPT_DATA_BLOB SaveBlob; pvSaveToPara = (void *) &SaveBlob;<br>// &nbsp; &nbsp; &nbsp;Upon entry, the SaveBlob's pbData and cbData need to be initialized.<br>// &nbsp; &nbsp; &nbsp;Upon return, cbData is updated with the actual length.<br>// &nbsp; &nbsp; &nbsp;For a length only calculation, pbData should be set to NULL. If<br>// &nbsp; &nbsp; &nbsp;pbData is non-NULL and cbData isn't large enough, FALSE is returned<br>// &nbsp; &nbsp; &nbsp;with a last error of ERRROR_MORE_DATA.<br>//<br>// &nbsp; &nbsp;CERT_STORE_SAVE_TO_FILENAME_A:<br>// &nbsp; &nbsp;CERT_STORE_SAVE_TO_FILENAME_W:<br>// &nbsp; &nbsp;CERT_STORE_SAVE_TO_FILENAME:<br>// &nbsp; &nbsp; &nbsp;Opens the file and saves to it. The filename is passed in pvSaveToPara.<br>// &nbsp; &nbsp; &nbsp;The filename is UNICODE for the &quot;_W&quot; option and ASCII for the &quot;_A&quot;<br>// &nbsp; &nbsp; &nbsp;option. For &quot;_W&quot;: given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCWSTR pwszFilename; pvSaveToPara = (void *) pwszFilename;<br>// &nbsp; &nbsp; &nbsp;For &quot;_A&quot;: given,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPCSTR pszFilename; pvSaveToPara = (void *) pszFilename;<br>//<br>// &nbsp; &nbsp; &nbsp;Note, the default (without &quot;_A&quot; or &quot;_W&quot;) is UNICODE.<br>//<br>//--------------------------------------------------------------------------<br><br>function CertSaveStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwSaveAs :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwSaveTo :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvSaveToPara :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Certificate Store close flags<br>//--------------------------------------------------------------------------<br>const CERT_CLOSE_STORE_FORCE_FLAG = $00000001;<br>const CERT_CLOSE_STORE_CHECK_FLAG = $00000002;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Close a cert store handle.<br>//<br>// &nbsp;There needs to be a corresponding close for each open and duplicate.<br>//<br>// &nbsp;Even on the final close, the cert store isn't freed until all of its<br>// &nbsp;certificate and CRL contexts have also been freed.<br>//<br>// &nbsp;On the final close, the hCryptProv passed to CertStoreOpen is<br>// &nbsp;CryptReleaseContext'ed.<br>//<br>// &nbsp;To force the closure of the store with all of its memory freed, set the<br>// &nbsp;CERT_STORE_CLOSE_FORCE_FLAG. This flag should be set when the caller does<br>// &nbsp;its own reference counting and wants everything to vanish.<br>//<br>// &nbsp;To check if all the store's certificates and CRLs have been freed and that<br>// &nbsp;this is the last CertCloseStore, set the CERT_CLOSE_STORE_CHECK_FLAG. If<br>// &nbsp;set and certs, CRLs or stores still need to be freed/closed, FALSE is<br>// &nbsp;returned with LastError set to CRYPT_E_PENDING_CLOSE. Note, for FALSE,<br>// &nbsp;the store is still closed. This is a diagnostic flag.<br>//<br>// &nbsp;LastError is preserved unless CERT_CLOSE_STORE_CHECK_FLAG is set and FALSE<br>// &nbsp;is returned.<br>//--------------------------------------------------------------------------<br><br>function CertCloseStore(hCertStore :HCERTSTORE; dwFlags :DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the subject certificate context uniquely identified by its Issuer and<br>// &nbsp;SerialNumber from the store.<br>//<br>// &nbsp;If the certificate isn't found, NULL is returned. Otherwise, a pointer to<br>// &nbsp;a read only CERT_CONTEXT is returned. CERT_CONTEXT must be freed by calling<br>// &nbsp;CertFreeCertificateContext. CertDuplicateCertificateContext can be called to make a<br>// &nbsp;duplicate.<br>//<br>// &nbsp;The returned certificate might not be valid. Normally, it would be<br>// &nbsp;verified when getting its issuer certificate (CertGetIssuerCertificateFromStore).<br>//--------------------------------------------------------------------------<br><br>function CertGetSubjectCertificateFromStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCertId :PCERT_INFO &nbsp; &nbsp; &nbsp; &nbsp; // Only the Issuer and SerialNumber<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):PCCERT_CONTEXT ; stdcall; // fields are used<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Enumerate the certificate contexts in the store.<br>//<br>// &nbsp;If a certificate isn't found, NULL is returned.<br>// &nbsp;Otherwise, a pointer to a read only CERT_CONTEXT is returned. CERT_CONTEXT<br>// &nbsp;must be freed by calling CertFreeCertificateContext or is freed when passed as the<br>// &nbsp;pPrevCertContext on a subsequent call. CertDuplicateCertificateContext<br>// &nbsp;can be called to make a duplicate.<br>//<br>// &nbsp;pPrevCertContext MUST BE NULL to enumerate the first<br>// &nbsp;certificate in the store. Successive certificates are enumerated by setting<br>// &nbsp;pPrevCertContext to the CERT_CONTEXT returned by a previous call.<br>//<br>// &nbsp;NOTE: a NON-NULL pPrevCertContext is always CertFreeCertificateContext'ed by<br>// &nbsp;this function, even for an error.<br>//--------------------------------------------------------------------------<br><br>function CertEnumCertificatesInStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pPrevCertContext :PCCERT_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):PCCERT_CONTEXT ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Find the first or next certificate context in the store.<br>//<br>// &nbsp;The certificate is found according to the dwFindType and its pvFindPara.<br>// &nbsp;See below for a list of the find types and its parameters.<br>//<br>// &nbsp;Currently dwFindFlags is only used for CERT_FIND_SUBJECT_ATTR,<br>// &nbsp;CERT_FIND_ISSUER_ATTR or CERT_FIND_CTL_USAGE. Otherwise, must be set to 0.<br>//<br>// &nbsp;Usage of dwCertEncodingType depends on the dwFindType.<br>//<br>// &nbsp;If the first or next certificate isn't found, NULL is returned.<br>// &nbsp;Otherwise, a pointer to a read only CERT_CONTEXT is returned. CERT_CONTEXT<br>// &nbsp;must be freed by calling CertFreeCertificateContext or is freed when passed as the<br>// &nbsp;pPrevCertContext on a subsequent call. CertDuplicateCertificateContext<br>// &nbsp;can be called to make a duplicate.<br>//<br>// &nbsp;pPrevCertContext MUST BE NULL on the first<br>// &nbsp;call to find the certificate. To find the next certificate, the<br>// &nbsp;pPrevCertContext is set to the CERT_CONTEXT returned by a previous call.<br>//<br>// &nbsp;NOTE: a NON-NULL pPrevCertContext is always CertFreeCertificateContext'ed by<br>// &nbsp;this function, even for an error.<br>//--------------------------------------------------------------------------<br><br>function CertFindCertificateInStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFindFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFindType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pvFindPara :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pPrevCertContext :PCCERT_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):PCCERT_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 &nbsp;= 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>// &nbsp;dwFindType<br>//<br>// &nbsp;The dwFindType definition consists of two components:<br>// &nbsp; - comparison function<br>// &nbsp; - 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 &nbsp;CERT_INFO_SUBJECT_FLAG);<br>const CERT_FIND_ISSUER_NAME = (CERT_COMPARE_NAME shl CERT_COMPARE_SHIFT or &nbsp;CERT_INFO_ISSUER_FLAG);<br>const CERT_FIND_ISSUER_ATTR = (CERT_COMPARE_ATTR shl CERT_COMPARE_SHIFT or &nbsp; CERT_INFO_ISSUER_FLAG);<br>const CERT_FIND_SUBJECT_STR_A = &nbsp;(CERT_COMPARE_NAME_STR_A shl CERT_COMPARE_SHIFT or &nbsp; CERT_INFO_SUBJECT_FLAG);<br>const CERT_FIND_SUBJECT_STR_W = &nbsp;(CERT_COMPARE_NAME_STR_W shl CERT_COMPARE_SHIFT or &nbsp; 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 &nbsp;CERT_INFO_ISSUER_FLAG);<br>const CERT_FIND_ISSUER_STR_W = &nbsp;(CERT_COMPARE_NAME_STR_W shl CERT_COMPARE_SHIFT or &nbsp;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>// &nbsp;CERT_FIND_ANY<br>//<br>// &nbsp;Find any certificate.<br>//<br>// &nbsp;pvFindPara isn't used.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_FIND_HASH<br>//<br>// &nbsp;Find a certificate with the specified hash.<br>//<br>// &nbsp;pvFindPara points to a CRYPT_HASH_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_FIND_PROPERTY<br>//<br>// &nbsp;Find a certificate having the specified property.<br>//<br>// &nbsp;pvFindPara points to a DWORD containing the PROP_ID<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_FIND_PUBLIC_KEY<br>//<br>// &nbsp;Find a certificate matching the specified public key.<br>//<br>// &nbsp;pvFindPara points to a CERT_PUBLIC_KEY_INFO containing the public key<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_FIND_SUBJECT_NAME<br>// &nbsp;CERT_FIND_ISSUER_NAME<br>//<br>// &nbsp;Find a certificate with the specified subject/issuer name. Does an exact<br>// &nbsp;match of the entire name.<br>//<br>// &nbsp;Restricts search to certificates matching the dwCertEncodingType.<br>//<br>// &nbsp;pvFindPara points to a CERT_NAME_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_FIND_SUBJECT_ATTR<br>// &nbsp;CERT_FIND_ISSUER_ATTR<br>//<br>// &nbsp;Find a certificate with the specified subject/issuer attributes.<br>//<br>// &nbsp;Compares the attributes in the subject/issuer name with the<br>// &nbsp;Relative Distinguished Name's (CERT_RDN) array of attributes specified in<br>// &nbsp;pvFindPara. The comparison iterates through the CERT_RDN attributes and looks<br>// &nbsp;for an attribute match in any of the subject/issuer's RDNs.<br>//<br>// &nbsp;The CERT_RDN_ATTR fields can have the following special values:<br>// &nbsp; &nbsp;pszObjId == NULL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- ignore the attribute object identifier<br>// &nbsp; &nbsp;dwValueType == RDN_ANY_TYPE &nbsp; - ignore the value type<br>// &nbsp; &nbsp;Value.pbData == NULL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- match any value<br>//<br>// &nbsp;Currently only an exact, case sensitive match is supported.<br>//<br>// &nbsp;CERT_UNICODE_IS_RDN_ATTRS_FLAG should be set in dwFindFlags if the RDN was<br>// &nbsp;initialized with unicode strings as for<br>// &nbsp;CryptEncodeObject(X509_UNICODE_NAME).<br>//<br>// &nbsp;Restricts search to certificates matching the dwCertEncodingType.<br>//<br>// &nbsp;pvFindPara points to a CERT_RDN (defined in wincert.h).<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_FIND_SUBJECT_STR_A<br>// &nbsp;CERT_FIND_SUBJECT_STR_W | CERT_FIND_SUBJECT_STR<br>// &nbsp;CERT_FIND_ISSUER_STR_A<br>// &nbsp;CERT_FIND_ISSUER_STR_W &nbsp;| CERT_FIND_ISSUER_STR<br>//<br>// &nbsp;Find a certificate containing the specified subject/issuer name string.<br>//<br>// &nbsp;First, the certificate's subject/issuer is converted to a name string<br>// &nbsp;via CertNameToStrA/CertNameToStrW(CERT_SIMPLE_NAME_STR). Then, a<br>// &nbsp;case insensitive substring within string match is performed.<br>//<br>// &nbsp;Restricts search to certificates matching the dwCertEncodingType.<br>//<br>// &nbsp;For *_STR_A, pvFindPara points to a null terminated character string.<br>// &nbsp;For *_STR_W, pvFindPara points to a null terminated wide character string.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_FIND_KEY_SPEC<br>//<br>// &nbsp;Find a certificate having a CERT_KEY_SPEC_PROP_ID property matching<br>// &nbsp;the specified KeySpec.<br>//<br>// &nbsp;pvFindPara points to a DWORD containing the KeySpec.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_FIND_ENHKEY_USAGE<br>//<br>// &nbsp;Find a certificate having the szOID_ENHANCED_KEY_USAGE extension or<br>// &nbsp;the CERT_ENHKEY_USAGE_PROP_ID and matching the specified pszUsageIdentifers.<br>//<br>// &nbsp;pvFindPara points to a CERT_ENHKEY_USAGE data structure. If pvFindPara<br>// &nbsp;is NULL or CERT_ENHKEY_USAGE's cUsageIdentifier is 0, then, matches any<br>// &nbsp;certificate having enhanced key usage.<br>//<br>// &nbsp;The CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG can be set in dwFindFlags to<br>// &nbsp;also match a certificate without either the extension or property.<br>//<br>// &nbsp;If CERT_FIND_NO_ENHKEY_USAGE_FLAG is set in dwFindFlags, finds<br>// &nbsp;certificates without the key usage extension or property. Setting this<br>// &nbsp;flag takes precedence over pvFindPara being NULL.<br>//<br>// &nbsp;If the CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG is set, then, only does a match<br>// &nbsp;using the extension. If pvFindPara is NULL or cUsageIdentifier is set to<br>// &nbsp;0, finds certificates having the extension. If<br>// &nbsp;CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is set, also matches a certificate<br>// &nbsp;without the extension. If CERT_FIND_NO_ENHKEY_USAGE_FLAG is set, finds<br>// &nbsp;certificates without the extension.<br>//<br>// &nbsp;If the CERT_FIND_EXT_PROP_ENHKEY_USAGE_FLAG is set, then, only does a match<br>// &nbsp;using the property. If pvFindPara is NULL or cUsageIdentifier is set to<br>// &nbsp;0, finds certificates having the property. If<br>// &nbsp;CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is set, also matches a certificate<br>// &nbsp;without the property. If CERT_FIND_NO_ENHKEY_USAGE_FLAG is set, finds<br>// &nbsp;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>// &nbsp;Get the certificate context from the store for the first or next issuer<br>// &nbsp;of the specified subject certificate. Perform the enabled<br>// &nbsp;verification checks on the subject. (Note, the checks are on the subject<br>// &nbsp;using the returned issuer certificate.)<br>//<br>// &nbsp;If the first or next issuer certificate isn't found, NULL is returned.<br>// &nbsp;Otherwise, a pointer to a read only CERT_CONTEXT is returned. CERT_CONTEXT<br>// &nbsp;must be freed by calling CertFreeCertificateContext or is freed when passed as the<br>// &nbsp;pPrevIssuerContext on a subsequent call. CertDuplicateCertificateContext<br>// &nbsp;can be called to make a duplicate.<br>//<br>// &nbsp;For a self signed subject certificate, NULL is returned with LastError set<br>// &nbsp;to CERT_STORE_SELF_SIGNED. The enabled verification checks are still done.<br>//<br>// &nbsp;The pSubjectContext may have been obtained from this store, another store<br>// &nbsp;or created by the caller application. When created by the caller, the<br>// &nbsp;CertCreateCertificateContext function must have been called.<br>//<br>// &nbsp;An issuer may have multiple certificates. This may occur when the validity<br>// &nbsp;period is about to change. pPrevIssuerContext MUST BE NULL on the first<br>// &nbsp;call to get the issuer. To get the next certificate for the issuer, the<br>// &nbsp;pPrevIssuerContext is set to the CERT_CONTEXT returned by a previous call.<br>//<br>// &nbsp;NOTE: a NON-NULL pPrevIssuerContext is always CertFreeCertificateContext'ed by<br>// &nbsp;this function, even for an error.<br>//<br>// &nbsp;The following flags can be set in *pdwFlags to enable verification checks<br>// &nbsp;on the subject certificate context:<br>// &nbsp; &nbsp; &nbsp;CERT_STORE_SIGNATURE_FLAG &nbsp; &nbsp; - use the public key in the returned<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;issuer certificate to verify the<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;signature on the subject certificate.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Note, if pSubjectContext-&gt;hCertStore ==<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hCertStore, the store provider might<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;be able to eliminate a redo of<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;the signature verify.<br>// &nbsp; &nbsp; &nbsp;CERT_STORE_TIME_VALIDITY_FLAG - get the current time and verify that<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;its within the subject certificate's<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;validity period<br>// &nbsp; &nbsp; &nbsp;CERT_STORE_REVOCATION_FLAG &nbsp; &nbsp;- check if the subject certificate is on<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;the issuer's revocation list<br>//<br>// &nbsp;If an enabled verification check fails, then, its flag is set upon return.<br>// &nbsp;If CERT_STORE_REVOCATION_FLAG was enabled and the issuer doesn't have a<br>// &nbsp;CRL in the store, then, CERT_STORE_NO_CRL_FLAG is set in addition to<br>// &nbsp;the CERT_STORE_REVOCATION_FLAG.<br>//<br>// &nbsp;If CERT_STORE_SIGNATURE_FLAG or CERT_STORE_REVOCATION_FLAG is set, then,<br>// &nbsp;CERT_STORE_NO_ISSUER_FLAG is set if it doesn't have an issuer certificate<br>// &nbsp;in the store.<br>//<br>// &nbsp;For a verification check failure, a pointer to the issuer's CERT_CONTEXT<br>// &nbsp;is still returned and SetLastError isn't updated.<br>//--------------------------------------------------------------------------<br>function CertGetIssuerCertificateFromStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pSubjectContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pPrevIssuerContext :PCCERT_CONTEXT; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwFlags :PDWORD):PCCERT_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Perform the enabled verification checks on the subject certificate<br>// &nbsp;using the issuer. Same checks and flags definitions as for the above<br>// &nbsp;CertGetIssuerCertificateFromStore.<br>//<br>// &nbsp;If you are only checking CERT_STORE_TIME_VALIDITY_FLAG, then, the<br>// &nbsp;issuer can be NULL.<br>//<br>// &nbsp;For a verification check failure, SUCCESS is still returned.<br>//--------------------------------------------------------------------------<br><br>function CertVerifySubjectCertificateContext(pSubject :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pIssuer :PCCERT_CONTEXT; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwFlags :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Duplicate a certificate context<br>//--------------------------------------------------------------------------<br><br>function CertDuplicateCertificateContext(pCertContext :PCCERT_CONTEXT):PCCERT_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Create a certificate context from the encoded certificate. The created<br>// &nbsp;context isn't put in a store.<br>//<br>// &nbsp;Makes a copy of the encoded certificate in the created context.<br>//<br>// &nbsp;If unable to decode and create the certificate context, NULL is returned.<br>// &nbsp;Otherwise, a pointer to a read only CERT_CONTEXT is returned.<br>// &nbsp;CERT_CONTEXT must be freed by calling CertFreeCertificateContext.<br>// &nbsp;CertDuplicateCertificateContext can be called to make a duplicate.<br>//<br>// &nbsp;CertSetCertificateContextProperty and CertGetCertificateContextProperty can be called<br>// &nbsp;to store properties for the certificate.<br>//--------------------------------------------------------------------------<br>function CertCreateCertificateContext(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbCertEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbCertEncoded :DWORD):PCCERT_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Free a certificate context<br>//<br>// &nbsp;There needs to be a corresponding free for each context obtained by a<br>// &nbsp;get, find, duplicate or create.<br>//--------------------------------------------------------------------------<br>function CertFreeCertificateContext(pCertContext :PCCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Set the property for the specified certificate context.<br>//<br>// &nbsp;The type definition for pvData depends on the dwPropId value. There are<br>// &nbsp;five predefined types:<br>// &nbsp; &nbsp; &nbsp;CERT_KEY_PROV_HANDLE_PROP_ID - a HCRYPTPROV for the certificate's<br>// &nbsp; &nbsp; &nbsp;private key is passed in pvData. Updates the hCryptProv field<br>// &nbsp; &nbsp; &nbsp;of the CERT_KEY_CONTEXT_PROP_ID. If the CERT_KEY_CONTEXT_PROP_ID<br>// &nbsp; &nbsp; &nbsp;doesn't exist, its created with all the other fields zeroed out. If<br>// &nbsp; &nbsp; &nbsp;CERT_STORE_NO_CRYPT_RELEASE_FLAG isn't set, HCRYPTPROV is implicitly<br>// &nbsp; &nbsp; &nbsp;released when either the property is set to NULL or on the final<br>// &nbsp; &nbsp; &nbsp;free of the CertContext.<br>//<br>// &nbsp; &nbsp; &nbsp;CERT_KEY_PROV_INFO_PROP_ID - a PCRYPT_KEY_PROV_INFO for the certificate's<br>// &nbsp; &nbsp; &nbsp;private key is passed in pvData.<br>//<br>// &nbsp; &nbsp; &nbsp;CERT_SHA1_HASH_PROP_ID -<br>// &nbsp; &nbsp; &nbsp;CERT_MD5_HASH_PROP_ID &nbsp;- normally, either property is implicitly<br>// &nbsp; &nbsp; &nbsp;set by doing a CertGetCertificateContextProperty. pvData points to a<br>// &nbsp; &nbsp; &nbsp;CRYPT_HASH_BLOB.<br>//<br>// &nbsp; &nbsp; &nbsp;CERT_KEY_CONTEXT_PROP_ID - a PCERT_KEY_CONTEXT for the certificate's<br>// &nbsp; &nbsp; &nbsp;private key is passed in pvData. The CERT_KEY_CONTEXT contains both the<br>// &nbsp; &nbsp; &nbsp;hCryptProv and dwKeySpec for the private key.<br>// &nbsp; &nbsp; &nbsp;See the CERT_KEY_PROV_HANDLE_PROP_ID for more information about<br>// &nbsp; &nbsp; &nbsp;the hCryptProv field and dwFlags settings. Note, more fields may<br>// &nbsp; &nbsp; &nbsp;be added for this property. The cbSize field value will be adjusted<br>// &nbsp; &nbsp; &nbsp;accordingly.<br>//<br>// &nbsp; &nbsp; &nbsp;CERT_KEY_SPEC_PROP_ID - the dwKeySpec for the private key. pvData<br>// &nbsp; &nbsp; &nbsp;points to a DWORD containing the KeySpec<br>//<br>// &nbsp; &nbsp; &nbsp;CERT_ENHKEY_USAGE_PROP_ID - enhanced key usage definition for the<br>// &nbsp; &nbsp; &nbsp;certificate. pvData points to a CRYPT_DATA_BLOB containing an<br>// &nbsp; &nbsp; &nbsp;ASN.1 encoded CERT_ENHKEY_USAGE (encoded via<br>// &nbsp; &nbsp; &nbsp;CryptEncodeObject(X509_ENHANCED_KEY_USAGE).<br>//<br>// &nbsp; &nbsp; &nbsp;CERT_NEXT_UPDATE_LOCATION_PROP_ID - location of the next update.<br>// &nbsp; &nbsp; &nbsp;Currently only applicable to CTLs. pvData points to a CRYPT_DATA_BLOB<br>// &nbsp; &nbsp; &nbsp;containing an ASN.1 encoded CERT_ALT_NAME_INFO (encoded via<br>// &nbsp; &nbsp; &nbsp;CryptEncodeObject(X509_ALTERNATE_NAME)).<br>//<br>// &nbsp; &nbsp; &nbsp;CERT_FRIENDLY_NAME_PROP_ID - friendly name for the cert, CRL or CTL.<br>// &nbsp; &nbsp; &nbsp;pvData points to a CRYPT_DATA_BLOB. pbData is a pointer to a NULL<br>// &nbsp; &nbsp; &nbsp;terminated unicode, wide character string.<br>// &nbsp; &nbsp; &nbsp;cbData = (wcslen((LPWSTR) pbData) + 1) * sizeof(WCHAR).<br>//<br>// &nbsp;For all the other PROP_IDs: an encoded PCRYPT_DATA_BLOB is passed in pvData.<br>//<br>// &nbsp;If the property already exists, then, the old value is deleted and silently<br>// &nbsp;replaced. Setting, pvData to NULL, deletes the property.<br>//--------------------------------------------------------------------------<br>function CertSetCertificateContextProperty(pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwPropId :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvData :PVOID):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the property for the specified certificate context.<br>//<br>// &nbsp;For CERT_KEY_PROV_HANDLE_PROP_ID, pvData points to a HCRYPTPROV.<br>//<br>// &nbsp;For CERT_KEY_PROV_INFO_PROP_ID, pvData points to a CRYPT_KEY_PROV_INFO structure.<br>// &nbsp;Elements pointed to by fields in the pvData structure follow the<br>// &nbsp;structure. Therefore, *pcbData may exceed the size of the structure.<br>//<br>// &nbsp;For CERT_KEY_CONTEXT_PROP_ID, pvData points to a CERT_KEY_CONTEXT structure.<br>//<br>// &nbsp;For CERT_KEY_SPEC_PROP_ID, pvData points to a DWORD containing the KeySpec.<br>// &nbsp;If the CERT_KEY_CONTEXT_PROP_ID exists, the KeySpec is obtained from there.<br>// &nbsp;Otherwise, if the CERT_KEY_PROV_INFO_PROP_ID exists, its the source<br>// &nbsp;of the KeySpec.<br>//<br>// &nbsp;For CERT_SHA1_HASH_PROP_ID or CERT_MD5_HASH_PROP_ID, if the hash<br>// &nbsp;doesn't already exist, then, its computed via CryptHashCertificate()<br>// &nbsp;and then set. pvData points to the computed hash. Normally, the length<br>// &nbsp;is 20 bytes for SHA and 16 for MD5.<br>//<br>// &nbsp;For all other PROP_IDs, pvData points to an encoded array of bytes.<br>//--------------------------------------------------------------------------<br>function CertGetCertificateContextProperty(pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwPropId :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvData :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbData :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Enumerate the properties for the specified certificate context.<br>//<br>// &nbsp;To get the first property, set dwPropId to 0. The ID of the first<br>// &nbsp;property is returned. To get the next property, set dwPropId to the<br>// &nbsp;ID returned by the last call. To enumerate all the properties continue<br>// &nbsp;until 0 is returned.<br>//<br>// &nbsp;CertGetCertificateContextProperty is called to get the property's data.<br>//<br>// &nbsp;Note, since, the CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_SPEC_PROP_ID<br>// &nbsp;properties are stored as fields in the CERT_KEY_CONTEXT_PROP_ID<br>// &nbsp;property, they aren't enumerated individually.<br>//--------------------------------------------------------------------------<br>function CertEnumCertificateContextProperties(pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwPropId :DWORD):DWORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the first or next CRL context from the store for the specified<br>// &nbsp;issuer certificate. Perform the enabled verification checks on the CRL.<br>//<br>// &nbsp;If the first or next CRL isn't found, NULL is returned.<br>// &nbsp;Otherwise, a pointer to a read only CRL_CONTEXT is returned. CRL_CONTEXT<br>// &nbsp;must be freed by calling CertFreeCRLContext. However, the free must be<br>// &nbsp;pPrevCrlContext on a subsequent call. CertDuplicateCRLContext<br>// &nbsp;can be called to make a duplicate.<br>//<br>// &nbsp;The pIssuerContext may have been obtained from this store, another store<br>// &nbsp;or created by the caller application. When created by the caller, the<br>// &nbsp;CertCreateCertificateContext function must have been called.<br>//<br>// &nbsp;If pIssuerContext == NULL, finds all the CRLs in the store.<br>//<br>// &nbsp;An issuer may have multiple CRLs. For example, it generates delta CRLs<br>// &nbsp;using a X.509 v3 extension. pPrevCrlContext MUST BE NULL on the first<br>// &nbsp;call to get the CRL. To get the next CRL for the issuer, the<br>// &nbsp;pPrevCrlContext is set to the CRL_CONTEXT returned by a previous call.<br>//<br>// &nbsp;NOTE: a NON-NULL pPrevCrlContext is always CertFreeCRLContext'ed by<br>// &nbsp;this function, even for an error.<br>//<br>// &nbsp;The following flags can be set in *pdwFlags to enable verification checks<br>// &nbsp;on the returned CRL:<br>// &nbsp; &nbsp; &nbsp;CERT_STORE_SIGNATURE_FLAG &nbsp; &nbsp; - use the public key in the<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;issuer's certificate to verify the<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;signature on the returned CRL.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Note, if pIssuerContext-&gt;hCertStore ==<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hCertStore, the store provider might<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;be able to eliminate a redo of<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;the signature verify.<br>// &nbsp; &nbsp; &nbsp;CERT_STORE_TIME_VALIDITY_FLAG - get the current time and verify that<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;its within the CRL's ThisUpdate and<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NextUpdate validity period.<br>//<br>// &nbsp;If an enabled verification check fails, then, its flag is set upon return.<br>//<br>// &nbsp;If pIssuerContext == NULL, then, an enabled CERT_STORE_SIGNATURE_FLAG<br>// &nbsp;always fails and the CERT_STORE_NO_ISSUER_FLAG is also set.<br>//<br>// &nbsp;For a verification check failure, a pointer to the first or next<br>// &nbsp;CRL_CONTEXT is still returned and SetLastError isn't updated.<br>//--------------------------------------------------------------------------<br>function CertGetCRLFromStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pIssuerContext :PCCERT_CONTEXT; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pPrevCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwFlags :PDWORD):PCCRL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Duplicate a CRL context<br>//--------------------------------------------------------------------------<br>function CertDuplicateCRLContext(pCrlContext :PCCRL_CONTEXT):PCCRL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Create a CRL context from the encoded CRL. The created<br>// &nbsp;context isn't put in a store.<br>//<br>// &nbsp;Makes a copy of the encoded CRL in the created context.<br>//<br>// &nbsp;If unable to decode and create the CRL context, NULL is returned.<br>// &nbsp;Otherwise, a pointer to a read only CRL_CONTEXT is returned.<br>// &nbsp;CRL_CONTEXT must be freed by calling CertFreeCRLContext.<br>// &nbsp;CertDuplicateCRLContext can be called to make a duplicate.<br>//<br>// &nbsp;CertSetCRLContextProperty and CertGetCRLContextProperty can be called<br>// &nbsp;to store properties for the CRL.<br>//--------------------------------------------------------------------------<br>function CertCreateCRLContext(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbCrlEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbCrlEncoded :DWORD):PCCRL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Free a CRL context<br>//<br>// &nbsp;There needs to be a corresponding free for each context obtained by a<br>// &nbsp;get, duplicate or create.<br>//--------------------------------------------------------------------------<br>function CertFreeCRLContext(pCrlContext :PCCRL_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Set the property for the specified CRL context.<br>//<br>// &nbsp;Same Property Ids and semantics as CertSetCertificateContextProperty.<br>//--------------------------------------------------------------------------<br>function CertSetCRLContextProperty(pCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwPropId :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pvData :PVOID):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the property for the specified CRL context.<br>//<br>// &nbsp;Same Property Ids and semantics as CertGetCertificateContextProperty.<br>//<br>// &nbsp;CERT_SHA1_HASH_PROP_ID or CERT_MD5_HASH_PROP_ID is the predefined<br>// &nbsp;property of most interest.<br>//--------------------------------------------------------------------------<br>function CertGetCRLContextProperty(pCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwPropId :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvData :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbData :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Enumerate the properties for the specified CRL context.<br>//<br>// &nbsp;To get the first property, set dwPropId to 0. The ID of the first<br>// &nbsp;property is returned. To get the next property, set dwPropId to the<br>// &nbsp;ID returned by the last call. To enumerate all the properties continue<br>// &nbsp;until 0 is returned.<br>//<br>// &nbsp;CertGetCRLContextProperty is called to get the property's data.<br>//--------------------------------------------------------------------------<br>function CertEnumCRLContextProperties(pCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwPropId :DWORD):DWORD ; 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>// &nbsp;Add the encoded certificate to the store according to the specified<br>// &nbsp;disposition action.<br>//<br>// &nbsp;Makes a copy of the encoded certificate before adding to the store.<br>//<br>// &nbsp;dwAddDispostion specifies the action to take if the certificate<br>// &nbsp;already exists in the store. This parameter must be one of the following<br>// &nbsp;values:<br>// &nbsp; &nbsp;CERT_STORE_ADD_NEW<br>// &nbsp; &nbsp; &nbsp;Fails if the certificate already exists in the store. LastError<br>// &nbsp; &nbsp; &nbsp;is set to CRYPT_E_EXISTS.<br>// &nbsp; &nbsp;CERT_STORE_ADD_USE_EXISTING<br>// &nbsp; &nbsp; &nbsp;If the certifcate already exists, then, its used and if ppCertContext<br>// &nbsp; &nbsp; &nbsp;is non-NULL, the existing context is duplicated.<br>// &nbsp; &nbsp;CERT_STORE_ADD_REPLACE_EXISTING<br>// &nbsp; &nbsp; &nbsp;If the certificate already exists, then, the existing certificate<br>// &nbsp; &nbsp; &nbsp;context is deleted before creating and adding the new context.<br>// &nbsp; &nbsp;CERT_STORE_ADD_ALWAYS<br>// &nbsp; &nbsp; &nbsp;No check is made to see if the certificate already exists. A<br>// &nbsp; &nbsp; &nbsp;new certificate context is always created. This may lead to<br>// &nbsp; &nbsp; &nbsp;duplicates in the store.<br>//<br>// &nbsp;CertGetSubjectCertificateFromStore is called to determine if the<br>// &nbsp;certificate already exists in the store.<br>//<br>// &nbsp;ppCertContext can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the CERT_CONTEXT of the added or existing certificate.<br>//--------------------------------------------------------------------------<br>function CertAddEncodedCertificateToStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbCertEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbCertEncoded :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwAddDisposition :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppCertContext :PCCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Add the certificate context to the store according to the specified<br>// &nbsp;disposition action.<br>//<br>// &nbsp;In addition to the encoded certificate, the context's properties are<br>// &nbsp;also copied. &nbsp;Note, the CERT_KEY_CONTEXT_PROP_ID property (and its<br>// &nbsp;CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_SPEC_PROP_ID) isn't copied.<br>//<br>// &nbsp;Makes a copy of the certificate context before adding to the store.<br>//<br>// &nbsp;dwAddDispostion specifies the action to take if the certificate<br>// &nbsp;already exists in the store. This parameter must be one of the following<br>// &nbsp;values:<br>// &nbsp; &nbsp;CERT_STORE_ADD_NEW<br>// &nbsp; &nbsp; &nbsp;Fails if the certificate already exists in the store. LastError<br>// &nbsp; &nbsp; &nbsp;is set to CRYPT_E_EXISTS.<br>// &nbsp; &nbsp;CERT_STORE_ADD_USE_EXISTING<br>// &nbsp; &nbsp; &nbsp;If the certifcate already exists, then, its used and if ppStoreContext<br>// &nbsp; &nbsp; &nbsp;is non-NULL, the existing context is duplicated. Iterates<br>// &nbsp; &nbsp; &nbsp;through pCertContext's properties and only copies the properties<br>// &nbsp; &nbsp; &nbsp;that don't already exist. The SHA1 and MD5 hash properties aren't<br>// &nbsp; &nbsp; &nbsp;copied.<br>// &nbsp; &nbsp;CERT_STORE_ADD_REPLACE_EXISTING<br>// &nbsp; &nbsp; &nbsp;If the certificate already exists, then, the existing certificate<br>// &nbsp; &nbsp; &nbsp;context is deleted before creating and adding a new context.<br>// &nbsp; &nbsp; &nbsp;Properties are copied before doing the add.<br>// &nbsp; &nbsp;CERT_STORE_ADD_ALWAYS<br>// &nbsp; &nbsp; &nbsp;No check is made to see if the certificate already exists. A<br>// &nbsp; &nbsp; &nbsp;new certificate context is always created and added. This may lead to<br>// &nbsp; &nbsp; &nbsp;duplicates in the store. Properties are<br>// &nbsp; &nbsp; &nbsp;copied before doing the add.<br>//<br>// &nbsp;CertGetSubjectCertificateFromStore is called to determine if the<br>// &nbsp;certificate already exists in the store.<br>//<br>// &nbsp;ppStoreContext can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the CERT_CONTEXT of the added or existing certificate.<br>//--------------------------------------------------------------------------<br>function CertAddCertificateContextToStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwAddDisposition :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppStoreContext :PCCERT_CONTEXT //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;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>// &nbsp;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 = &nbsp;(1 shl CERT_STORE_CRL_CONTEXT);<br>const CERT_STORE_CTL_CONTEXT_FLAG = (1 shl CERT_STORE_CTL_CONTEXT);<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Add the serialized certificate or CRL element to the store.<br>//<br>// &nbsp;The serialized element contains the encoded certificate, CRL or CTL and<br>// &nbsp;its properties, such as, CERT_KEY_PROV_INFO_PROP_ID.<br>//<br>// &nbsp;If hCertStore is NULL, creates a certificate, CRL or CTL context not<br>// &nbsp;residing in any store.<br>//<br>// &nbsp;dwAddDispostion specifies the action to take if the certificate or CRL<br>// &nbsp;already exists in the store. See CertAddCertificateContextToStore for a<br>// &nbsp;list of and actions taken.<br>//<br>// &nbsp;dwFlags currently isn't used and should be set to 0.<br>//<br>// &nbsp;dwContextTypeFlags specifies the set of allowable contexts. For example, to<br>// &nbsp;add either a certificate or CRL, set dwContextTypeFlags to:<br>// &nbsp; &nbsp; &nbsp;CERT_STORE_CERTIFICATE_CONTEXT_FLAG | CERT_STORE_CRL_CONTEXT_FLAG<br>//<br>// &nbsp;*pdwContextType is updated with the type of the context returned in<br>// &nbsp;*ppvContxt. pdwContextType or ppvContext can be NULL, indicating the<br>// &nbsp;caller isn't interested in getting the output. If *ppvContext is<br>// &nbsp;returned it must be freed by calling CertFreeCertificateContext or<br>// &nbsp;CertFreeCRLContext.<br>//--------------------------------------------------------------------------<br>function CertAddSerializedElementToStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbElement :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbElement :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwAddDisposition :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwContextTypeFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdwContextType :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var ppvContext : array of PVOID):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Delete the specified certificate from the store.<br>//<br>// &nbsp;All subsequent gets or finds for the certificate will fail. However,<br>// &nbsp;memory allocated for the certificate isn't freed until all of its contexts<br>// &nbsp;have also been freed.<br>//<br>// &nbsp;The pCertContext is obtained from a get, enum, find or duplicate.<br>//<br>// &nbsp;Some store provider implementations might also delete the issuer's CRLs<br>// &nbsp;if this is the last certificate for the issuer in the store.<br>//<br>// &nbsp;NOTE: the pCertContext is always CertFreeCertificateContext'ed by<br>// &nbsp;this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertDeleteCertificateFromStore(pCertContext :PCCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Add the encoded CRL to the store according to the specified<br>// &nbsp;disposition option.<br>//<br>// &nbsp;Makes a copy of the encoded CRL before adding to the store.<br>//<br>// &nbsp;dwAddDispostion specifies the action to take if the CRL<br>// &nbsp;already exists in the store. See CertAddEncodedCertificateToStore for a<br>// &nbsp;list of and actions taken.<br>//<br>// &nbsp;Compares the CRL's Issuer to determine if the CRL already exists in the<br>// &nbsp;store.<br>//<br>// &nbsp;ppCrlContext can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the CRL_CONTEXT of the added or existing CRL.<br>//--------------------------------------------------------------------------<br>function CertAddEncodedCRLToStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbCrlEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbCrlEncoded :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwAddDisposition :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppCrlContext :PCCRL_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Add the CRL context to the store according to the specified<br>// &nbsp;disposition option.<br>//<br>// &nbsp;In addition to the encoded CRL, the context's properties are<br>// &nbsp;also copied. &nbsp;Note, the CERT_KEY_CONTEXT_PROP_ID property (and its<br>// &nbsp;CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_SPEC_PROP_ID) isn't copied.<br>//<br>// &nbsp;Makes a copy of the encoded CRL before adding to the store.<br>//<br>// &nbsp;dwAddDispostion specifies the action to take if the CRL<br>// &nbsp;already exists in the store. See CertAddCertificateContextToStore for a<br>// &nbsp;list of and actions taken.<br>//<br>// &nbsp;Compares the CRL's Issuer, ThisUpdate and NextUpdate to determine<br>// &nbsp;if the CRL already exists in the store.<br>//<br>// &nbsp;ppStoreContext can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the CRL_CONTEXT of the added or existing CRL.<br>//--------------------------------------------------------------------------<br>function CertAddCRLContextToStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwAddDisposition :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppStoreContext :PCCRL_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Delete the specified CRL from the store.<br>//<br>// &nbsp;All subsequent gets for the CRL will fail. However,<br>// &nbsp;memory allocated for the CRL isn't freed until all of its contexts<br>// &nbsp;have also been freed.<br>//<br>// &nbsp;The pCrlContext is obtained from a get or duplicate.<br>//<br>// &nbsp;NOTE: the pCrlContext is always CertFreeCRLContext'ed by<br>// &nbsp;this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertDeleteCRLFromStore(pCrlContext :PCCRL_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Serialize the certificate context's encoded certificate and its<br>// &nbsp;properties.<br>//--------------------------------------------------------------------------<br>function CertSerializeCertificateStoreElement(pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbElement :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbElement :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Serialize the CRL context's encoded CRL and its properties.<br>//--------------------------------------------------------------------------<br>function CertSerializeCRLStoreElement(pCrlContext :PCCRL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbElement :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbElement :PDWORD):BOOL ; stdcall;<br>//+=========================================================================<br>// &nbsp;Certificate Trust List (CTL) Store Data Structures and APIs<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Duplicate a CTL context<br>//--------------------------------------------------------------------------<br>function CertDuplicateCTLContext(pCtlContext :PCCTL_CONTEXT):PCCTL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Create a CTL context from the encoded CTL. The created<br>// &nbsp;context isn't put in a store.<br>//<br>// &nbsp;Makes a copy of the encoded CTL in the created context.<br>//<br>// &nbsp;If unable to decode and create the CTL context, NULL is returned.<br>// &nbsp;Otherwise, a pointer to a read only CTL_CONTEXT is returned.<br>// &nbsp;CTL_CONTEXT must be freed by calling CertFreeCTLContext.<br>// &nbsp;CertDuplicateCTLContext can be called to make a duplicate.<br>//<br>// &nbsp;CertSetCTLContextProperty and CertGetCTLContextProperty can be called<br>// &nbsp;to store properties for the CTL.<br>//--------------------------------------------------------------------------<br>function CertCreateCTLContext(dwMsgAndCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbCtlEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbCtlEncoded :DWORD):PCCTL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Free a CTL context<br>//<br>// &nbsp;There needs to be a corresponding free for each context obtained by a<br>// &nbsp;get, duplicate or create.<br>//--------------------------------------------------------------------------<br>function CertFreeCTLContext(pCtlContext :PCCTL_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Set the property for the specified CTL context.<br>//<br>// &nbsp;Same Property Ids and semantics as CertSetCertificateContextProperty.<br>//--------------------------------------------------------------------------<br>function CertSetCTLContextProperty(pCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwPropId :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pvData :PVOID):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the property for the specified CTL context.<br>//<br>// &nbsp;Same Property Ids and semantics as CertGetCertificateContextProperty.<br>//<br>// &nbsp;CERT_SHA1_HASH_PROP_ID or CERT_NEXT_UPDATE_LOCATION_PROP_ID are the<br>// &nbsp;predefined properties of most interest.<br>//--------------------------------------------------------------------------<br>function CertGetCTLContextProperty(pCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwPropId :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvData :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbData :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Enumerate the properties for the specified CTL context.<br>//--------------------------------------------------------------------------<br>function CertEnumCTLContextProperties(pCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwPropId :DWORD):DWORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Enumerate the CTL contexts in the store.<br>//<br>// &nbsp;If a CTL isn't found, NULL is returned.<br>// &nbsp;Otherwise, a pointer to a read only CTL_CONTEXT is returned. CTL_CONTEXT<br>// &nbsp;must be freed by calling CertFreeCTLContext or is freed when passed as the<br>// &nbsp;pPrevCtlContext on a subsequent call. CertDuplicateCTLContext<br>// &nbsp;can be called to make a duplicate.<br>//<br>// &nbsp;pPrevCtlContext MUST BE NULL to enumerate the first<br>// &nbsp;CTL in the store. Successive CTLs are enumerated by setting<br>// &nbsp;pPrevCtlContext to the CTL_CONTEXT returned by a previous call.<br>//<br>// &nbsp;NOTE: a NON-NULL pPrevCtlContext is always CertFreeCTLContext'ed by<br>// &nbsp;this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertEnumCTLsInStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pPrevCtlContext :PCCTL_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):PCCTL_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Attempt to find the specified subject in the CTL.<br>//<br>// &nbsp;For CTL_CERT_SUBJECT_TYPE, pvSubject points to a CERT_CONTEXT. The CTL's<br>// &nbsp;SubjectAlgorithm is examined to determine the representation of the<br>// &nbsp;subject's identity. Initially, only SHA1 or MD5 hash will be supported.<br>// &nbsp;The appropriate hash property is obtained from the CERT_CONTEXT.<br>//<br>// &nbsp;For CTL_ANY_SUBJECT_TYPE, pvSubject points to the CTL_ANY_SUBJECT_INFO<br>// &nbsp;structure which contains the SubjectAlgorithm to be matched in the CTL<br>// &nbsp;and the SubjectIdentifer to be matched in one of the CTL entries.<br>//<br>// &nbsp;The certificate's hash or the CTL_ANY_SUBJECT_INFO's SubjectIdentifier<br>// &nbsp;is used as the key in searching the subject entries. A binary<br>// &nbsp;memory comparison is done between the key and the entry's SubjectIdentifer.<br>//<br>// &nbsp;dwEncodingType isn't used for either of the above SubjectTypes.<br>//--------------------------------------------------------------------------<br>function CertFindSubjectInCTL(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwSubjectType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvSubject :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD):PCTL_ENTRY ; stdcall;<br>// Subject Types:<br>// &nbsp;CTL_ANY_SUBJECT_TYPE, pvSubject points to following CTL_ANY_SUBJECT_INFO.<br>// &nbsp;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> &nbsp;PCTL_ANY_SUBJECT_INFO = ^CTL_ANY_SUBJECT_INFO;<br> &nbsp;CTL_ANY_SUBJECT_INFO = record<br> &nbsp; &nbsp;SubjectAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;SubjectIdentifier :CRYPT_DATA_BLOB;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Find the first or next CTL context in the store.<br>//<br>// &nbsp;The CTL is found according to the dwFindType and its pvFindPara.<br>// &nbsp;See below for a list of the find types and its parameters.<br>//<br>// &nbsp;Currently dwFindFlags isn't used and must be set to 0.<br>//<br>// &nbsp;Usage of dwMsgAndCertEncodingType depends on the dwFindType.<br>//<br>// &nbsp;If the first or next CTL isn't found, NULL is returned.<br>// &nbsp;Otherwise, a pointer to a read only CTL_CONTEXT is returned. CTL_CONTEXT<br>// &nbsp;must be freed by calling CertFreeCTLContext or is freed when passed as the<br>// &nbsp;pPrevCtlContext on a subsequent call. CertDuplicateCTLContext<br>// &nbsp;can be called to make a duplicate.<br>//<br>// &nbsp;pPrevCtlContext MUST BE NULL on the first<br>// &nbsp;call to find the CTL. To find the next CTL, the<br>// &nbsp;pPrevCtlContext is set to the CTL_CONTEXT returned by a previous call.<br>//<br>// &nbsp;NOTE: a NON-NULL pPrevCtlContext is always CertFreeCTLContext'ed by<br>// &nbsp;this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertFindCTLInStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwMsgAndCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFindFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFindType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pvFindPara :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pPrevCtlContext :PCCTL_CONTEXT):PCCTL_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> &nbsp;PCTL_FIND_USAGE_PARA = ^CTL_FIND_USAGE_PARA;<br> &nbsp;CTL_FIND_USAGE_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;SubjectUsage :CTL_USAGE; &nbsp; &nbsp; &nbsp; &nbsp; // optional<br> &nbsp; &nbsp;ListIdentifier :CRYPT_DATA_BLOB; // optional<br> &nbsp; &nbsp;pSigner :PCERT_INFO; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // optional<br> &nbsp;end;<br><br>const CTL_FIND_NO_LIST_ID_CBDATA = $FFFFFFFF;<br>const CTL_FIND_NO_SIGNER_PTR &nbsp; &nbsp; = (PCERT_INFO($FFFFFFFF));<br><br>const CTL_FIND_SAME_USAGE_FLAG &nbsp; = $1;<br><br>type<br> &nbsp;PCTL_FIND_SUBJECT_PARA = ^CTL_FIND_SUBJECT_PARA;<br> &nbsp;CTL_FIND_SUBJECT_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;pUsagePara :PCTL_FIND_USAGE_PARA; // optional<br> &nbsp; &nbsp;dwSubjectType :DWORD;<br> &nbsp; &nbsp;pvSubject :PVOID;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CTL_FIND_ANY<br>//<br>// &nbsp;Find any CTL.<br>//<br>// &nbsp;pvFindPara isn't used.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CTL_FIND_SHA1_HASH<br>// &nbsp;CTL_FIND_MD5_HASH<br>//<br>// &nbsp;Find a CTL with the specified hash.<br>//<br>// &nbsp;pvFindPara points to a CRYPT_HASH_BLOB.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CTL_FIND_USAGE<br>//<br>// &nbsp;Find a CTL having the specified usage identifiers, list identifier or<br>// &nbsp;signer. The CertEncodingType of the signer is obtained from the<br>// &nbsp;dwMsgAndCertEncodingType parameter.<br>//<br>// &nbsp;pvFindPara points to a CTL_FIND_USAGE_PARA data structure. The<br>// &nbsp;SubjectUsage.cUsageIdentifer can be 0 to match any usage. The<br>// &nbsp;ListIdentifier.cbData can be 0 to match any list identifier. To only match<br>// &nbsp;CTLs without a ListIdentifier, cbData must be set to<br>// &nbsp;CTL_FIND_NO_LIST_ID_CBDATA. pSigner can be NULL to match any signer. Only<br>// &nbsp;the Issuer and SerialNumber fields of the pSigner's PCERT_INFO are used.<br>// &nbsp;To only match CTLs without a signer, pSigner must be set to<br>// &nbsp;CTL_FIND_NO_SIGNER_PTR.<br>//<br>// &nbsp;The CTL_FIND_SAME_USAGE_FLAG can be set in dwFindFlags to<br>// &nbsp;only match CTLs with the same usage identifiers. CTLs having additional<br>// &nbsp;usage identifiers aren't matched. For example, if only &quot;1.2.3&quot; is specified<br>// &nbsp;in CTL_FIND_USAGE_PARA, then, for a match, the CTL must only contain<br>// &nbsp;&quot;1.2.3&quot; and not any additional usage identifers.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CTL_FIND_SUBJECT<br>//<br>// &nbsp;Find a CTL having the specified subject. CertFindSubjectInCTL can be<br>// &nbsp;called to get a pointer to the subject's entry in the CTL. &nbsp;pUsagePara can<br>// &nbsp;optionally be set to enable the above CTL_FIND_USAGE matching.<br>//<br>// &nbsp;pvFindPara points to a CTL_FIND_SUBJECT_PARA data structure.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Add the encoded CTL to the store according to the specified<br>// &nbsp;disposition option.<br>//<br>// &nbsp;Makes a copy of the encoded CTL before adding to the store.<br>//<br>// &nbsp;dwAddDispostion specifies the action to take if the CTL<br>// &nbsp;already exists in the store. See CertAddEncodedCertificateToStore for a<br>// &nbsp;list of and actions taken.<br>//<br>// &nbsp;Compares the CTL's SubjectUsage, ListIdentifier and any of its signers<br>// &nbsp;to determine if the CTL already exists in the store.<br>//<br>// &nbsp;ppCtlContext can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the CTL_CONTEXT of the added or existing CTL.<br>//--------------------------------------------------------------------------<br>function CertAddEncodedCTLToStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwMsgAndCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbCtlEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbCtlEncoded :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwAddDisposition :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppCtlContext :PCCTL_CONTEXT //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Add the CTL context to the store according to the specified<br>// &nbsp;disposition option.<br>//<br>// &nbsp;In addition to the encoded CTL, the context's properties are<br>// &nbsp;also copied. &nbsp;Note, the CERT_KEY_CONTEXT_PROP_ID property (and its<br>// &nbsp;CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_SPEC_PROP_ID) isn't copied.<br>//<br>// &nbsp;Makes a copy of the encoded CTL before adding to the store.<br>//<br>// &nbsp;dwAddDispostion specifies the action to take if the CTL<br>// &nbsp;already exists in the store. See CertAddCertificateContextToStore for a<br>// &nbsp;list of and actions taken.<br>//<br>// &nbsp;Compares the CTL's SubjectUsage, ListIdentifier and any of its signers<br>// &nbsp;to determine if the CTL already exists in the store.<br>//<br>// &nbsp;ppStoreContext can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the CTL_CONTEXT of the added or existing CTL.<br>//--------------------------------------------------------------------------<br>function CertAddCTLContextToStore(hCertStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwAddDisposition :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppStoreContext :PCCTL_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Serialize the CTL context's encoded CTL and its properties.<br>//--------------------------------------------------------------------------<br>function CertSerializeCTLStoreElement(pCtlContext :PCCTL_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbElement :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbElement :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Delete the specified CTL from the store.<br>//<br>// &nbsp;All subsequent gets for the CTL will fail. However,<br>// &nbsp;memory allocated for the CTL isn't freed until all of its contexts<br>// &nbsp;have also been freed.<br>//<br>// &nbsp;The pCtlContext is obtained from a get or duplicate.<br>//<br>// &nbsp;NOTE: the pCtlContext is always CertFreeCTLContext'ed by<br>// &nbsp;this function, even for an error.<br>//--------------------------------------------------------------------------<br>function CertDeleteCTLFromStore(pCtlContext :PCCTL_CONTEXT):BOOL ; stdcall;<br>//+=========================================================================<br>// &nbsp;Enhanced Key Usage Helper Functions<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the enhanced key usage extension or property from the certificate<br>// &nbsp;and decode.<br>//<br>// &nbsp;If the CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG is set, then, only get the<br>// &nbsp;extension.<br>//<br>// &nbsp;If the CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG is set, then, only get the<br>// &nbsp;property.<br>//--------------------------------------------------------------------------<br>function CertGetEnhancedKeyUsage(pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pUsage :PCERT_ENHKEY_USAGE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbUsage :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Set the enhanced key usage property for the certificate.<br>//--------------------------------------------------------------------------<br>function CertSetEnhancedKeyUsage(pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pUsage :PCERT_ENHKEY_USAGE<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Add the usage identifier to the certificate's enhanced key usage property.<br>//--------------------------------------------------------------------------<br>function CertAddEnhancedKeyUsageIdentifier(pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszUsageIdentifier :LPCSTR<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Remove the usage identifier from the certificate's enhanced key usage<br>// &nbsp;property.<br>//--------------------------------------------------------------------------<br>function CertRemoveEnhancedKeyUsageIdentifier(pCertContext :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszUsageIdentifier :LPCSTR<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br><br>//+=========================================================================<br>// &nbsp;Cryptographic Message helper functions for verifying and signing a<br>// &nbsp;CTL.<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Get and verify the signer of a cryptographic message.<br>//<br>// &nbsp;To verify a CTL, the hCryptMsg is obtained from the CTL_CONTEXT's<br>// &nbsp;hCryptMsg field.<br>//<br>// &nbsp;If CMSG_TRUSTED_SIGNER_FLAG is set, then, treat the Signer stores as being<br>// &nbsp;trusted and only search them to find the certificate corresponding to the<br>// &nbsp;signer's issuer and serial number. &nbsp;Otherwise, the SignerStores are<br>// &nbsp;optionally provided to supplement the message's store of certificates.<br>// &nbsp;If a signer certificate is found, its public key is used to verify<br>// &nbsp;the message signature. The CMSG_SIGNER_ONLY_FLAG can be set to<br>// &nbsp;return the signer without doing the signature verify.<br>//<br>// &nbsp;If CMSG_USE_SIGNER_INDEX_FLAG is set, then, only get the signer specified<br>// &nbsp;by *pdwSignerIndex. Otherwise, iterate through all the signers<br>// &nbsp;until a signer verifies or no more signers.<br>//<br>// &nbsp;For a verified signature, *ppSigner is updated with certificate context<br>// &nbsp;of the signer and *pdwSignerIndex is updated with the index of the signer.<br>// &nbsp;ppSigner and/or pdwSignerIndex can be NULL, indicating the caller isn't<br>// &nbsp;interested in getting the CertContext and/or index of the signer.<br>//--------------------------------------------------------------------------<br>function CryptMsgGetAndVerifySigner(hCryptMsg :HCRYPTMSG;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cSignerStore :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var rghSignerStore :HCERTSTORE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppSigner :PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwSignerIndex :PDWORD):BOOL ; stdcall;<br><br>const CMSG_TRUSTED_SIGNER_FLAG &nbsp; = $1;<br>const CMSG_SIGNER_ONLY_FLAG &nbsp; &nbsp; &nbsp;= $2;<br>const CMSG_USE_SIGNER_INDEX_FLAG = $4;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Sign an encoded CTL.<br>//<br>// &nbsp;The pbCtlContent can be obtained via a CTL_CONTEXT's pbCtlContent<br>// &nbsp;field or via a CryptEncodeObject(PKCS_CTL).<br>//--------------------------------------------------------------------------<br>function CryptMsgSignCTL(dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbCtlContent :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbCtlContent :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pSignInfo :PCMSG_SIGNED_ENCODE_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbEncoded :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Encode the CTL and create a signed message containing the encoded CTL.<br>//--------------------------------------------------------------------------<br>function CryptMsgEncodeAndSignCTL(dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCtlInfo :PCTL_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pSignInfo :PCMSG_SIGNED_ENCODE_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbEncoded :PDWORD):BOOL ; stdcall;<br><br>//+=========================================================================<br>// &nbsp;Certificate Verify CTL Usage Data Structures and APIs<br>//==========================================================================<br>type<br> &nbsp;PHCERTSTORE = ^HCERTSTORE;<br><br>type<br> &nbsp;PCTL_VERIFY_USAGE_PARA = ^CTL_VERIFY_USAGE_PARA;<br> &nbsp;CTL_VERIFY_USAGE_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;ListIdentifier :CRYPT_DATA_BLOB;// OPTIONAL<br> &nbsp; &nbsp;cCtlStore :DWORD;<br> &nbsp; &nbsp;rghCtlStore :PHCERTSTORE; &nbsp; &nbsp; &nbsp; // OPTIONAL<br> &nbsp; &nbsp;cSignerStore :DWORD;<br> &nbsp; &nbsp;rghSignerStore :PHCERTSTORE; &nbsp; &nbsp;// OPTIONAL<br> &nbsp;end;<br><br>type<br> &nbsp;PCTL_VERIFY_USAGE_STATUS = ^CTL_VERIFY_USAGE_STATUS;<br> &nbsp;CTL_VERIFY_USAGE_STATUS = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwError :DWORD;<br> &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp;ppCtl :PPCCTL_CONTEXT; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // IN OUT OPTIONAL<br> &nbsp; &nbsp;dwCtlEntryIndex :DWORD;<br> &nbsp; &nbsp;ppSigner :PPCCERT_CONTEXT ; &nbsp; &nbsp; &nbsp; &nbsp;// IN OUT OPTIONAL<br> &nbsp; &nbsp;dwSignerIndex :DWORD;<br> &nbsp;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>// &nbsp;Verify that a subject is trusted for the specified usage by finding a<br>// &nbsp;signed and time valid CTL with the usage identifiers and containing the<br>// &nbsp;the subject. A subject can be identified by either its certificate context<br>// &nbsp;or any identifier such as its SHA1 hash.<br>//<br>// &nbsp;See CertFindSubjectInCTL for definition of dwSubjectType and pvSubject<br>// &nbsp;parameters.<br>//<br>// &nbsp;Via pVerifyUsagePara, the caller can specify the stores to be searched<br>// &nbsp;to find the CTL. The caller can also specify the stores containing<br>// &nbsp;acceptable CTL signers. By setting the ListIdentifier, the caller<br>// &nbsp;can also restrict to a particular signer CTL list.<br>//<br>// &nbsp;Via pVerifyUsageStatus, the CTL containing the subject, the subject's<br>// &nbsp;index into the CTL's array of entries, and the signer of the CTL<br>// &nbsp;are returned. If the caller is not interested, ppCtl and ppSigner can be set<br>// &nbsp;to NULL. Returned contexts must be freed via the store's free context APIs.<br>//<br>// &nbsp;If the CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG isn't set, then, a time<br>// &nbsp;invalid CTL in one of the CtlStores may be replaced. When replaced, the<br>// &nbsp;CERT_VERIFY_UPDATED_CTL_FLAG is set in pVerifyUsageStatus-&gt;dwFlags.<br>//<br>// &nbsp;If the CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, then, only the<br>// &nbsp;SignerStores specified in pVerifyUsageStatus are searched to find<br>// &nbsp;the signer. Otherwise, the SignerStores provide additional sources<br>// &nbsp;to find the signer's certificate.<br>//<br>// &nbsp;If CERT_VERIFY_NO_TIME_CHECK_FLAG is set, then, the CTLs aren't checked<br>// &nbsp;for time validity.<br>//<br>// &nbsp;If CERT_VERIFY_ALLOW_MORE_USAGE_FLAG is set, then, the CTL may contain<br>// &nbsp;additional usage identifiers than specified by pSubjectUsage. Otherwise,<br>// &nbsp;the found CTL will contain the same usage identifers and no more.<br>//<br>// &nbsp;CertVerifyCTLUsage will be implemented as a dispatcher to OID installable<br>// &nbsp;functions. First, it will try to find an OID function matching the first<br>// &nbsp;usage object identifier in the pUsage sequence. Next, it will dispatch<br>// &nbsp;to the default CertDllVerifyCTLUsage functions.<br>//<br>// &nbsp;If the subject is trusted for the specified usage, then, TRUE is<br>// &nbsp;returned. Otherwise, FALSE is returned with dwError set to one of the<br>// &nbsp;following:<br>// &nbsp; &nbsp; &nbsp;CRYPT_E_NO_VERIFY_USAGE_DLL<br>// &nbsp; &nbsp; &nbsp;CRYPT_E_NO_VERIFY_USAGE_CHECK<br>// &nbsp; &nbsp; &nbsp;CRYPT_E_VERIFY_USAGE_OFFLINE<br>// &nbsp; &nbsp; &nbsp;CRYPT_E_NOT_IN_CTL<br>// &nbsp; &nbsp; &nbsp;CRYPT_E_NO_TRUSTED_SIGNER<br>//--------------------------------------------------------------------------<br>function CertVerifyCTLUsage(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwSubjectType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvSubject :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pSubjectUsage :PCTL_USAGE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pVerifyUsagePara :PCTL_VERIFY_USAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pVerifyUsageStatus:PCTL_VERIFY_USAGE_STATUS<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br><br>//+=========================================================================<br>// &nbsp;Certificate Revocation Data Structures and APIs<br>//==========================================================================<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;The following data structure may be passed to CertVerifyRevocation to<br>// &nbsp;assist in finding the issuer of the context to be verified.<br>//<br>// &nbsp;When pIssuerCert is specified, pIssuerCert is the issuer of<br>// &nbsp;rgpvContext[cContext - 1].<br>//<br>// &nbsp;When cCertStore and rgCertStore are specified, these stores may contain<br>// &nbsp;an issuer certificate.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCERT_REVOCATION_PARA = ^CERT_REVOCATION_PARA;<br> &nbsp;CERT_REVOCATION_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;pIssuerCert :PCCERT_CONTEXT;<br> &nbsp; &nbsp;cCertStore :DWORD;<br> &nbsp; &nbsp;rgCertStore :PHCERTSTORE ;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;The following data structure is returned by CertVerifyRevocation to<br>// &nbsp;specify the status of the revoked or unchecked context. Review the<br>// &nbsp;following CertVerifyRevocation comments for details.<br>//<br>// &nbsp;Upon input to CertVerifyRevocation, cbSize must be set to a size<br>// &nbsp;&gt;= sizeof(CERT_REVOCATION_STATUS). Otherwise, CertVerifyRevocation<br>// &nbsp;returns FALSE and sets LastError to E_INVALIDARG.<br>//<br>// &nbsp;Upon input to the installed or registered CRYPT_OID_VERIFY_REVOCATION_FUNC<br>// &nbsp;functions, the dwIndex, dwError and dwReason have been zero'ed.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCERT_REVOCATION_STATUS = ^CERT_REVOCATION_STATUS;<br> &nbsp;CERT_REVOCATION_STATUS = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwIndex :DWORD;<br> &nbsp; &nbsp;dwError :DWORD;<br> &nbsp; &nbsp;dwReason :DWORD;<br> &nbsp;end;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Verifies the array of contexts for revocation. The dwRevType parameter<br>// &nbsp;indicates the type of the context data structure passed in rgpvContext.<br>// &nbsp;Currently only the revocation of certificates is defined.<br>//<br>// &nbsp;If the CERT_VERIFY_REV_CHAIN_FLAG flag is set, then, CertVerifyRevocation<br>// &nbsp;is verifying a chain of certs where, rgpvContext[i + 1] is the issuer<br>// &nbsp;of rgpvContext. Otherwise, CertVerifyRevocation makes no assumptions<br>// &nbsp;about the order of the contexts.<br>//<br>// &nbsp;To assist in finding the issuer, the pRevPara may optionally be set. See<br>// &nbsp;the CERT_REVOCATION_PARA data structure for details.<br>//<br>// &nbsp;The contexts must contain enough information to allow the<br>// &nbsp;installable or registered revocation DLLs to find the revocation server. For<br>// &nbsp;certificates, this information would normally be conveyed in an<br>// &nbsp;extension such as the IETF's AuthorityInfoAccess extension.<br>//<br>// &nbsp;CertVerifyRevocation returns TRUE if all of the contexts were successfully<br>// &nbsp;checked and none were revoked. Otherwise, returns FALSE and updates the<br>// &nbsp;returned pRevStatus data structure as follows:<br>// &nbsp; &nbsp;dwIndex<br>// &nbsp; &nbsp; &nbsp;Index of the first context that was revoked or unable to<br>// &nbsp; &nbsp; &nbsp;be checked for revocation<br>// &nbsp; &nbsp;dwError<br>// &nbsp; &nbsp; &nbsp;Error status. LastError is also set to this error status.<br>// &nbsp; &nbsp; &nbsp;dwError can be set to one of the following error codes defined<br>// &nbsp; &nbsp; &nbsp;in winerror.h:<br>// &nbsp; &nbsp; &nbsp; &nbsp;ERROR_SUCCESS - good context<br>// &nbsp; &nbsp; &nbsp; &nbsp;CRYPT_E_REVOKED - context was revoked. dwReason contains the<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reason for revocation<br>// &nbsp; &nbsp; &nbsp; &nbsp;CRYPT_E_REVOCATION_OFFLINE - unable to connect to the<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; revocation server<br>// &nbsp; &nbsp; &nbsp; &nbsp;CRYPT_E_NOT_IN_REVOCATION_DATABASE - the context to be checked<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; was not found in the revocation server's database.<br>// &nbsp; &nbsp; &nbsp; &nbsp;CRYPT_E_NO_REVOCATION_CHECK - the called revocation function<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wasn't able to do a revocation check on the context<br>// &nbsp; &nbsp; &nbsp; &nbsp;CRYPT_E_NO_REVOCATION_DLL - no installed or registered Dll was<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; found to verify revocation<br>// &nbsp; &nbsp;dwReason<br>// &nbsp; &nbsp; &nbsp;The dwReason is currently only set for CRYPT_E_REVOKED and contains<br>// &nbsp; &nbsp; &nbsp;the reason why the context was revoked. May be one of the following<br>// &nbsp; &nbsp; &nbsp;CRL reasons defined by the CRL Reason Code extension (&quot;2.5.29.21&quot;)<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRL_REASON_UNSPECIFIED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRL_REASON_KEY_COMPROMISE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRL_REASON_CA_COMPROMISE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRL_REASON_AFFILIATION_CHANGED &nbsp; &nbsp; &nbsp;3<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRL_REASON_SUPERSEDED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRL_REASON_CESSATION_OF_OPERATION &nbsp; 5<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CRL_REASON_CERTIFICATE_HOLD &nbsp; &nbsp; &nbsp; &nbsp; 6<br>//<br>// &nbsp;For each entry in rgpvContext, CertVerifyRevocation iterates<br>// &nbsp;through the CRYPT_OID_VERIFY_REVOCATION_FUNC<br>// &nbsp;function set's list of installed DEFAULT functions.<br>// &nbsp;CryptGetDefaultOIDFunctionAddress is called with pwszDll = NULL. If no<br>// &nbsp;installed functions are found capable of doing the revocation verification,<br>// &nbsp;CryptVerifyRevocation iterates through CRYPT_OID_VERIFY_REVOCATION_FUNC's<br>// &nbsp;list of registered DEFAULT Dlls. CryptGetDefaultOIDDllList is called to<br>// &nbsp;get the list. CryptGetDefaultOIDFunctionAddress is called to load the Dll.<br>//<br>// &nbsp;The called functions have the same signature as CertVerifyRevocation. A<br>// &nbsp;called function returns TRUE if it was able to successfully check all of<br>// &nbsp;the contexts and none were revoked. Otherwise, the called function returns<br>// &nbsp;FALSE and updates pRevStatus. dwIndex is set to the index of<br>// &nbsp;the first context that was found to be revoked or unable to be checked.<br>// &nbsp;dwError and LastError are updated. For CRYPT_E_REVOKED, dwReason<br>// &nbsp;is updated. Upon input to the called function, dwIndex, dwError and<br>// &nbsp;dwReason have been zero'ed. cbSize has been checked to be &gt;=<br>// &nbsp;sizeof(CERT_REVOCATION_STATUS).<br>//<br>// &nbsp;If the called function returns FALSE, and dwError isn't set to<br>// &nbsp;CRYPT_E_REVOKED, then, CertVerifyRevocation either continues on to the<br>// &nbsp;next DLL in the list for a returned dwIndex of 0 or for a returned<br>// &nbsp;dwIndex &gt; 0, restarts the process of finding a verify function by<br>// &nbsp;advancing the start of the context array to the returned dwIndex and<br>// &nbsp;decrementing the count of remaining contexts.<br>//--------------------------------------------------------------------------<br>function CertVerifyRevocation(dwEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwRevType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cContext :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rgpvContext :array of PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pRevPara :PCERT_REVOCATION_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pRevStatus :PCERT_REVOCATION_STATUS<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Revocation types<br>//--------------------------------------------------------------------------<br>const CERT_CONTEXT_REVOCATION_TYPE = 1;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;When the following flag is set, rgpvContext[] consists of a chain<br>// &nbsp;of certificates, where rgpvContext[i + 1] is the issuer of rgpvContext.<br>//--------------------------------------------------------------------------<br>const CERT_VERIFY_REV_CHAIN_FLAG = $1;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;CERT_CONTEXT_REVOCATION_TYPE<br>//<br>// &nbsp;pvContext points to a const CERT_CONTEXT.<br>//--------------------------------------------------------------------------<br><br>//+=========================================================================<br>// &nbsp;Certificate Helper APIs<br>//==========================================================================<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Compare two multiple byte integer blobs to see if they are identical.<br>//<br>// &nbsp;Before doing the comparison, leading zero bytes are removed from a<br>// &nbsp;positive number and leading 0xFF bytes are removed from a negative<br>// &nbsp;number.<br>//<br>// &nbsp;The multiple byte integers are treated as Little Endian. pbData[0] is the<br>// &nbsp;least significant byte and pbData[cbData - 1] is the most significant<br>// &nbsp;byte.<br>//<br>// &nbsp;Returns TRUE if the integer blobs are identical after removing leading<br>// &nbsp;0 or 0xFF bytes.<br>//--------------------------------------------------------------------------<br>function CertCompareIntegerBlob(pInt1 :PCRYPT_INTEGER_BLOB;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pInt2 :PCRYPT_INTEGER_BLOB<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Compare two certificates to see if they are identical.<br>//<br>// &nbsp;Since a certificate is uniquely identified by its Issuer and SerialNumber,<br>// &nbsp;these are the only fields needing to be compared.<br>//<br>// &nbsp;Returns TRUE if the certificates are identical.<br>//--------------------------------------------------------------------------<br>function CertCompareCertificate(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCertId1 :PCERT_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCertId2 :PCERT_INFO):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Compare two certificate names to see if they are identical.<br>//<br>// &nbsp;Returns TRUE if the names are identical.<br>//--------------------------------------------------------------------------<br>function CertCompareCertificateName(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCertName1 :PCERT_NAME_BLOB;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCertName2 :PCERT_NAME_BLOB):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Compare the attributes in the certificate name with the specified<br>// &nbsp;Relative Distinguished Name's (CERT_RDN) array of attributes.<br>// &nbsp;The comparison iterates through the CERT_RDN attributes and looks for an<br>// &nbsp;attribute match in any of the certificate name's RDNs.<br>// &nbsp;Returns TRUE if all the attributes are found and match.<br>//<br>// &nbsp;The CERT_RDN_ATTR fields can have the following special values:<br>// &nbsp; &nbsp;pszObjId == NULL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- ignore the attribute object identifier<br>// &nbsp; &nbsp;dwValueType == RDN_ANY_TYPE &nbsp; - ignore the value type<br>//<br>// &nbsp;Currently only an exact, case sensitive match is supported.<br>//<br>// &nbsp;CERT_UNICODE_IS_RDN_ATTRS_FLAG should be set if the pRDN was initialized<br>// &nbsp;with unicode strings as for CryptEncodeObject(X509_UNICODE_NAME).<br>//--------------------------------------------------------------------------<br>function CertIsRDNAttrsInCertificateName(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCertName :PCERT_NAME_BLOB;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pRDN :PCERT_RDN):BOOL ; stdcall;<br><br>const CERT_UNICODE_IS_RDN_ATTRS_FLAG = $1;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Compare two public keys to see if they are identical.<br>//<br>// &nbsp;Returns TRUE if the keys are identical.<br>//--------------------------------------------------------------------------<br>function CertComparePublicKeyInfo(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pPublicKey1 :PCERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pPublicKey2 :PCERT_PUBLIC_KEY_INFO<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the public/private key's bit length.<br>//<br>// &nbsp;Returns 0 if unable to determine the key's length.<br>//--------------------------------------------------------------------------<br>function CertGetPublicKeyLength(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pPublicKey :PCERT_PUBLIC_KEY_INFO<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):DWORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify the signature of a subject certificate or a CRL using the<br>// &nbsp;public key info<br>//<br>// &nbsp;Returns TRUE for a valid signature.<br>//<br>// &nbsp;hCryptProv specifies the crypto provider to use to verify the signature.<br>// &nbsp;It doesn't need to use a private key.<br>//--------------------------------------------------------------------------<br>function CryptVerifyCertificateSignature(hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbEncoded :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pPublicKey :PCERT_PUBLIC_KEY_INFO<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Compute the hash of the &quot;to be signed&quot; information in the encoded<br>// &nbsp;signed content (CERT_SIGNED_CONTENT_INFO).<br>//<br>// &nbsp;hCryptProv specifies the crypto provider to use to compute the hash.<br>// &nbsp;It doesn't need to use a private key.<br>//--------------------------------------------------------------------------<br>function CryptHashToBeSigned(hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbEncoded :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbComputedHash :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbComputedHash :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Hash the encoded content.<br>//<br>// &nbsp;hCryptProv specifies the crypto provider to use to compute the hash.<br>// &nbsp;It doesn't need to use a private key.<br>//<br>// &nbsp;Algid specifies the CAPI hash algorithm to use. If Algid is 0, then, the<br>// &nbsp;default hash algorithm (currently SHA1) is used.<br>//--------------------------------------------------------------------------<br>function CryptHashCertificate(hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Algid :ALG_ID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbEncoded :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbComputedHash :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbComputedHash :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Sign the &quot;to be signed&quot; information in the encoded signed content.<br>//<br>// &nbsp;hCryptProv specifies the crypto provider to use to do the signature.<br>// &nbsp;It uses the specified private key.<br>//--------------------------------------------------------------------------<br>function CryptSignCertificate(hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwKeySpec :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbEncodedToBeSigned :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbEncodedToBeSigned :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pSignatureAlgorithm :PCRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pvHashAuxInfo :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbSignature :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbSignature:PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Encode the &quot;to be signed&quot; information. Sign the encoded &quot;to be signed&quot;.<br>// &nbsp;Encode the &quot;to be signed&quot; and the signature.<br>//<br>// &nbsp;hCryptProv specifies the crypto provider to use to do the signature.<br>// &nbsp;It uses the specified private key.<br>//--------------------------------------------------------------------------<br>function CryptSignAndEncodeCertificate(hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwKeySpec :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const lpszStructType :LPCSTR; // &quot;to be signed&quot;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvStructInfo :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pSignatureAlgorithm :PCRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pvHashAuxInfo :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbEncoded :PDWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify the time validity of a certificate.<br>//<br>// &nbsp;Returns -1 if before NotBefore, +1 if after NotAfter and otherwise 0 for<br>// &nbsp;a valid certificate<br>//<br>// &nbsp;If pTimeToVerify is NULL, uses the current time.<br>//--------------------------------------------------------------------------<br>function CertVerifyTimeValidity(pTimeToVerify :PFILETIME;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pCertInfo :PCERT_INFO):LONG ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify the time validity of a CRL.<br>//<br>// &nbsp;Returns -1 if before ThisUpdate, +1 if after NextUpdate and otherwise 0 for<br>// &nbsp;a valid CRL<br>//<br>// &nbsp;If pTimeToVerify is NULL, uses the current time.<br>//--------------------------------------------------------------------------<br>function CertVerifyCRLTimeValidity(pTimeToVerify :PFILETIME;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCrlInfo :PCRL_INFO):LONG ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify that the subject's time validity nests within the issuer's time<br>// &nbsp;validity.<br>//<br>// &nbsp;Returns TRUE if it nests. Otherwise, returns FALSE.<br>//--------------------------------------------------------------------------<br>function CertVerifyValidityNesting(pSubjectInfo :PCERT_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pIssuerInfo :PCERT_INFO):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify that the subject certificate isn't on its issuer CRL.<br>//<br>// &nbsp;Returns true if the certificate isn't on the CRL.<br>//--------------------------------------------------------------------------<br>function CertVerifyCRLRevocation(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCertId :PCERT_INFO; &nbsp; &nbsp;// Only the Issuer and SerialNumber<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cCrlInfo :DWORD; &nbsp; &nbsp; &nbsp; &nbsp;// fields are used<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rgpCrlInfo :array of PCRL_INFO):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Convert the CAPI AlgId to the ASN.1 Object Identifier string<br>//<br>// &nbsp;Returns NULL if there isn't an ObjId corresponding to the AlgId.<br>//--------------------------------------------------------------------------<br>function CertAlgIdToOID(dwAlgId :DWORD):LPCSTR ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Convert the ASN.1 Object Identifier string to the CAPI AlgId.<br>//<br>// &nbsp;Returns 0 if there isn't an AlgId corresponding to the ObjId.<br>//--------------------------------------------------------------------------<br>function CertOIDToAlgId(pszObjId :LPCSTR):DWORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Find an extension identified by its Object Identifier.<br>//<br>// &nbsp;If found, returns pointer to the extension. Otherwise, returns NULL.<br>//--------------------------------------------------------------------------<br>function CertFindExtension(pszObjId :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cExtensions :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rgExtensions :array of CERT_EXTENSION):PCERT_EXTENSION ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Find the first attribute identified by its Object Identifier.<br>//<br>// &nbsp;If found, returns pointer to the attribute. Otherwise, returns NULL.<br>//--------------------------------------------------------------------------<br>function CertFindAttribute(pszObjId :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cAttr :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rgAttr :array of CRYPT_ATTRIBUTE):PCRYPT_ATTRIBUTE ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Find the first CERT_RDN attribute identified by its Object Identifier in<br>// &nbsp;the name's list of Relative Distinguished Names.<br>//<br>// &nbsp;If found, returns pointer to the attribute. Otherwise, returns NULL.<br>//--------------------------------------------------------------------------<br>function CertFindRDNAttr(pszObjId :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pName :PCERT_NAME_INFO ):PCERT_RDN_ATTR ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Get the intended key usage bytes from the certificate.<br>//<br>// &nbsp;If the certificate doesn't have any intended key usage bytes, returns FALSE<br>// &nbsp;and *pbKeyUsage is zeroed. Otherwise, returns TRUE and up through<br>// &nbsp;cbKeyUsage bytes are copied into *pbKeyUsage. Any remaining uncopied<br>// &nbsp;bytes are zeroed.<br>//--------------------------------------------------------------------------<br>function CertGetIntendedKeyUsage(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCertInfo :PCERT_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbKeyUsage :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbKeyUsage :DWORD):BOOL ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Export the public key info associated with the provider's corresponding<br>// &nbsp;private key.<br>//<br>// &nbsp;Calls CryptExportPublicKeyInfo with pszPublicKeyObjId = szOID_RSA_RSA,<br>// &nbsp;dwFlags = 0 and pvAuxInfo = NULL.<br>//--------------------------------------------------------------------------<br>function CryptExportPublicKeyInfo(hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwKeySpec :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pInfo :PCERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbInfo :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Export the public key info associated with the provider's corresponding<br>// &nbsp;private key.<br>//<br>// &nbsp;Uses the dwCertEncodingType and pszPublicKeyObjId to call the<br>// &nbsp;installable CRYPT_OID_EXPORT_PUBLIC_KEY_INFO_FUNC. The called function<br>// &nbsp;has the same signature as CryptExportPublicKeyInfoEx.<br>//<br>// &nbsp;If unable to find an installable OID function for the pszPublicKeyObjId,<br>// &nbsp;attempts to export as a RSA Public Key (szOID_RSA_RSA).<br>//<br>// &nbsp;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> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwKeySpec :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszPublicKeyObjId :LPSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvAuxInfo :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pInfo :PCERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbInfo :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Convert and import the public key info into the provider and return a<br>// &nbsp;handle to the public key.<br>//<br>// &nbsp;Calls CryptImportPublicKeyInfoEx with aiKeyAlg = 0, dwFlags = 0 and<br>// &nbsp;pvAuxInfo = NULL.<br>//--------------------------------------------------------------------------<br>function CryptImportPublicKeyInfo(hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pInfo :PCERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;phKey :PHCRYPTKEY):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Convert and import the public key info into the provider and return a<br>// &nbsp;handle to the public key.<br>//<br>// &nbsp;Uses the dwCertEncodingType and pInfo-&gt;Algorithm.pszObjId to call the<br>// &nbsp;installable CRYPT_OID_IMPORT_PUBLIC_KEY_INFO_FUNC. The called function<br>// &nbsp;has the same signature as CryptImportPublicKeyInfoEx.<br>//<br>// &nbsp;If unable to find an installable OID function for the pszObjId,<br>// &nbsp;attempts to import as a RSA Public Key (szOID_RSA_RSA).<br>//<br>// &nbsp;For szOID_RSA_RSA: aiKeyAlg may be set to CALG_RSA_SIGN or CALG_RSA_KEYX.<br>// &nbsp;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> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pInfo :PCERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;aiKeyAlg :ALG_ID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvAuxInfo :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;phKey :PHCRYPTKEY<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Compute the hash of the encoded public key info.<br>//<br>// &nbsp;The public key info is encoded and then hashed.<br>//--------------------------------------------------------------------------<br>function CryptHashPublicKeyInfo(hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Algid :ALG_ID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pInfo :PCERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbComputedHash :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbComputedHash :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Convert a Name Value to a null terminated char string<br>//<br>// &nbsp;Returns the number of characters converted including the terminating null<br>// &nbsp;character. If psz is NULL or csz is 0, returns the required size of the<br>// &nbsp;destination string (including the terminating null char).<br>//<br>// &nbsp;If psz != NULL && csz != 0, returned psz is always NULL terminated.<br>//<br>// &nbsp;Note: csz includes the NULL char.<br>//--------------------------------------------------------------------------<br>function CertRDNValueToStrA(dwValueType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pValue :PCERT_RDN_VALUE_BLOB;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;psz :LPSTR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;csz :DWORD):DWORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Convert a Name Value to a null terminated char string<br>//<br>// &nbsp;Returns the number of characters converted including the terminating null<br>// &nbsp;character. If psz is NULL or csz is 0, returns the required size of the<br>// &nbsp;destination string (including the terminating null char).<br>//<br>// &nbsp;If psz != NULL && csz != 0, returned psz is always NULL terminated.<br>//<br>// &nbsp;Note: csz includes the NULL char.<br>//--------------------------------------------------------------------------<br>function CertRDNValueToStrW(dwValueType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pValue :PCERT_RDN_VALUE_BLOB;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;psz :LPWSTR; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;csz :DWORD):DWORD ; stdcall;<br><br>function CertRDNValueToStr(dwValueType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pValue :PCERT_RDN_VALUE_BLOB;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; psz :LPAWSTR; &nbsp; &nbsp; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; csz :DWORD):DWORD ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Convert the certificate name blob to a null terminated char string.<br>//<br>// &nbsp;Follows the string representation of distinguished names specified in<br>// &nbsp;RFC 1779. (Note, added double quoting &quot;&quot; for embedded quotes, quote<br>// &nbsp;empty strings and don't quote strings containing consecutive spaces).<br>// &nbsp;RDN values of type CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING are<br>// &nbsp;formatted in hexadecimal (e.g. #0A56CF).<br>//<br>// &nbsp;The name string is formatted according to the dwStrType:<br>// &nbsp; &nbsp;CERT_SIMPLE_NAME_STR<br>// &nbsp; &nbsp; &nbsp;The object identifiers are discarded. CERT_RDN entries are separated<br>// &nbsp; &nbsp; &nbsp;by &quot;, &quot;. Multiple attributes per CERT_RDN are separated by &quot; + &quot;.<br>// &nbsp; &nbsp; &nbsp;For example:<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Microsoft, Joe Cool + Programmer<br>// &nbsp; &nbsp;CERT_OID_NAME_STR<br>// &nbsp; &nbsp; &nbsp;The object identifiers are included with a &quot;=&quot; separator from their<br>// &nbsp; &nbsp; &nbsp;attribute value. CERT_RDN entries are separated by &quot;, &quot;.<br>// &nbsp; &nbsp; &nbsp;Multiple attributes per CERT_RDN are separated by &quot; + &quot;. For example:<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2.5.4.11=Microsoft, 2.5.4.3=Joe Cool + 2.5.4.12=Programmer<br>// &nbsp; &nbsp;CERT_X500_NAME_STR<br>// &nbsp; &nbsp; &nbsp;The object identifiers are converted to their X500 key name. Otherwise,<br>// &nbsp; &nbsp; &nbsp;same as CERT_OID_NAME_STR. If the object identifier doesn't have<br>// &nbsp; &nbsp; &nbsp;a corresponding X500 key name, then, the object identifier is used with<br>// &nbsp; &nbsp; &nbsp;a &quot;OID.&quot; prefix. For example:<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OU=Microsoft, CN=Joe Cool + T=Programmer, OID.1.2.3.4.5.6=Unknown<br>//<br>// &nbsp;We quote the RDN value if it contains leading or trailing whitespace<br>// &nbsp;or one of the following characters: &quot;,&quot;, &quot;+&quot;, &quot;=&quot;, &quot;&quot;&quot;, &quot;/n&quot;, &nbsp;&quot;&lt;&quot;, &quot;&gt;&quot;,<br>// &nbsp;&quot;#&quot; or &quot;;&quot;. The quoting character is &quot;. If the the RDN Value contains<br>// &nbsp;a &quot; it is double quoted (&quot;&quot;). For example:<br>// &nbsp; &nbsp; &nbsp;OU=&quot; &nbsp;Microsoft&quot;, CN=&quot;Joe &quot;&quot;Cool&quot;&quot;&quot; + T=&quot;Programmer, Manager&quot;<br>//<br>// &nbsp;CERT_NAME_STR_SEMICOLON_FLAG can be or'ed into dwStrType to replace<br>// &nbsp;the &quot;, &quot; separator with a &quot;; &quot; separator.<br>//<br>// &nbsp;CERT_NAME_STR_CRLF_FLAG can be or'ed into dwStrType to replace<br>// &nbsp;the &quot;, &quot; separator with a &quot;/r/n&quot; separator.<br>//<br>// &nbsp;CERT_NAME_STR_NO_PLUS_FLAG can be or'ed into dwStrType to replace the<br>// &nbsp;&quot; + &quot; separator with a single space, &quot; &quot;.<br>//<br>// &nbsp;CERT_NAME_STR_NO_QUOTING_FLAG can be or'ed into dwStrType to inhibit<br>// &nbsp;the above quoting.<br>//<br>// &nbsp;Returns the number of characters converted including the terminating null<br>// &nbsp;character. If psz is NULL or csz is 0, returns the required size of the<br>// &nbsp;destination string (including the terminating null char).<br>//<br>// &nbsp;If psz != NULL && csz != 0, returned psz is always NULL terminated.<br>//<br>// &nbsp;Note: csz includes the NULL char.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>//--------------------------------------------------------------------------<br>function CertNameToStrA(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pName :PCERT_NAME_BLOB;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwStrType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;psz :LPSTR; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;csz :DWORD):DWORD ; stdcall;<br>//+-------------------------------------------------------------------------<br>//--------------------------------------------------------------------------<br>function CertNameToStrW(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pName :PCERT_NAME_BLOB;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwStrType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;psz :LPWSTR; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;csz :DWORD):DWORD ; stdcall;<br><br>function CertNameToStr(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pName :PCERT_NAME_BLOB;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwStrType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; psz :LPAWSTR; //OPTIONAL<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; csz :DWORD):DWORD ; stdcall;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;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>// &nbsp;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>// &nbsp;Convert the null terminated X500 string to an encoded certificate name.<br>//<br>// &nbsp;The input string is expected to be formatted the same as the output<br>// &nbsp;from the above CertNameToStr API.<br>//<br>// &nbsp;The CERT_SIMPLE_NAME_STR type isn't supported. Otherwise, when dwStrType<br>// &nbsp;is set to 0, CERT_OID_NAME_STR or CERT_X500_NAME_STR, allow either a<br>// &nbsp;case insensitive X500 key (CN=), case insensitive &quot;OID.&quot; prefixed<br>// &nbsp;object identifier (OID.1.2.3.4.5.6=) or an object identifier (1.2.3.4=).<br>//<br>// &nbsp;If no flags are OR'ed into dwStrType, then, allow &quot;,&quot; or &quot;;&quot; as RDN<br>// &nbsp;separators and &quot;+&quot; as the multiple RDN value separator. Quoting is<br>// &nbsp;supported. A quote may be included in a quoted value by double quoting,<br>// &nbsp;for example (CN=&quot;Joe &quot;&quot;Cool&quot;&quot;&quot;). A value starting with a &quot;#&quot; is treated<br>// &nbsp;as ascii hex and converted to a CERT_RDN_OCTET_STRING. Embedded whitespace<br>// &nbsp;is skipped (1.2.3 = # AB CD 01 &nbsp;is the same as 1.2.3=#ABCD01).<br>//<br>// &nbsp;Whitespace surrounding the keys, object identifers and values is removed.<br>//<br>// &nbsp;CERT_NAME_STR_COMMA_FLAG can be or'ed into dwStrType to only allow the<br>// &nbsp;&quot;,&quot; as the RDN separator.<br>//<br>// &nbsp;CERT_NAME_STR_SEMICOLON_FLAG can be or'ed into dwStrType to only allow the<br>// &nbsp;&quot;;&quot; as the RDN separator.<br>//<br>// &nbsp;CERT_NAME_STR_CRLF_FLAG can be or'ed into dwStrType to only allow<br>// &nbsp;&quot;/r&quot; or &quot;/n&quot; as the RDN separator.<br>//<br>// &nbsp;CERT_NAME_STR_NO_PLUS_FLAG can be or'ed into dwStrType to ignore &quot;+&quot;<br>// &nbsp;as a separator and not allow multiple values per RDN.<br>//<br>// &nbsp;CERT_NAME_STR_NO_QUOTING_FLAG can be or'ed into dwStrType to inhibit<br>// &nbsp;quoting.<br>//<br>// &nbsp;Support the following X500 Keys:<br>//<br>// &nbsp;Key &nbsp; &nbsp; &nbsp; &nbsp; Object Identifier &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RDN Value Type(s)<br>// &nbsp;--- &nbsp; &nbsp; &nbsp; &nbsp; ----------------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -----------------<br>// &nbsp;CN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;szOID_COMMON_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Printable, T61<br>// &nbsp;L &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; szOID_LOCALITY_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Printable, T61<br>// &nbsp;O &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; szOID_ORGANIZATION_NAME &nbsp; &nbsp; &nbsp; &nbsp; Printable, T61<br>// &nbsp;OU &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;szOID_ORGANIZATIONAL_UNIT_NAME &nbsp;Printable, T61<br>// &nbsp;Email &nbsp; &nbsp; &nbsp; szOID_RSA_emailAddr &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Only IA5<br>// &nbsp;C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; szOID_COUNTRY_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Only Printable<br>// &nbsp;S &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; szOID_STATE_OR_PROVINCE_NAME &nbsp; &nbsp;Printable, T61<br>// &nbsp;ST &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;szOID_STATE_OR_PROVINCE_NAME &nbsp; &nbsp;Printable, T61<br>// &nbsp;STREET &nbsp; &nbsp; &nbsp;szOID_STREET_ADDRESS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Printable, T61<br>// &nbsp;T &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; szOID_TITLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Printable, T61<br>// &nbsp;Title &nbsp; &nbsp; &nbsp; szOID_TITLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Printable, T61<br>// &nbsp;G &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; szOID_GIVEN_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Printable, T61<br>// &nbsp;GivenName &nbsp; szOID_GIVEN_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Printable, T61<br>// &nbsp;I &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; szOID_INITIALS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Printable, T61<br>// &nbsp;Initials &nbsp; &nbsp;szOID_INITIALS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Printable, T61<br>// &nbsp;SN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;szOID_SUR_NAME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Printable, T61<br>// &nbsp;DC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;szOID_DOMAIN_COMPONENT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Only IA5<br>//<br>// &nbsp;The T61 types are UTF-8 encoded.<br>//<br>// &nbsp;Returns TRUE if successfully parsed the input string and encoded<br>// &nbsp;the name.<br>//<br>// &nbsp;If the input string is detected to be invalid, *ppszError is updated<br>// &nbsp;to point to the beginning of the invalid character sequence. Otherwise,<br>// &nbsp;*ppszError is set to NULL. *ppszError is updated with a non-NULL pointer<br>// &nbsp;for the following errors:<br>// &nbsp; &nbsp; &nbsp;CRYPT_E_INVALID_X500_STRING<br>// &nbsp; &nbsp; &nbsp;CRYPT_E_INVALID_NUMERIC_STRING<br>// &nbsp; &nbsp; &nbsp;CRYPT_E_INVALID_PRINTABLE_STRING<br>// &nbsp; &nbsp; &nbsp;CRYPT_E_INVALID_IA5_STRING<br>//<br>// &nbsp;ppszError can be set to NULL if not interested in getting a pointer<br>// &nbsp;to the invalid character sequence.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>//--------------------------------------------------------------------------<br>function CertStrToNameA(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszX500 :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwStrType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvReserved :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbEncoded :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var ppszError :array of LPCSTR):BOOL ; stdcall; &nbsp;{--max-- iniziato qui}<br>//+-------------------------------------------------------------------------<br>//--------------------------------------------------------------------------<br>function CertStrToNameW(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszX500 :LPCWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwStrType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pvReserved :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbEncoded :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppszError :array of LPWSTR):BOOL ; stdcall;<br><br>function CertStrToName(dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pszX500 :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwStrType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pvReserved :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbEncoded :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var ppszError :array of LPAWSTR):BOOL ; stdcall;<br><br>//+=========================================================================<br>// &nbsp;Simplified Cryptographic Message Data Structures and APIs<br>//==========================================================================<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Conventions for the *pb and *pcb output parameters:<br>//<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Upon entry to the function:<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if pcb is OPTIONAL && pcb == NULL, then,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;No output is returned<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else if pb == NULL && pcb != NULL, then,<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Length only determination. No length error is<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;returned.<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;otherwise where (pb != NULL && pcb != NULL && *pcb != 0)<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Output is returned. If *pcb isn't big enough a<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;length error is returned. In all cases *pcb is updated<br>// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;with the actual length needed/returned.<br>//--------------------------------------------------------------------------<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Type definitions of the parameters used for doing the cryptographic<br>// &nbsp;operations.<br>//--------------------------------------------------------------------------<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Callback to get and verify the signer's certificate.<br>//<br>// &nbsp;Passed the CertId of the signer (its Issuer and SerialNumber) and a<br>// &nbsp;handle to its cryptographic signed message's cert store.<br>//<br>// &nbsp;For CRYPT_E_NO_SIGNER, called with pSignerId == NULL.<br>//<br>// &nbsp;For a valid signer certificate, returns a pointer to a read only<br>// &nbsp;CERT_CONTEXT. The returned CERT_CONTEXT is either obtained from a<br>// &nbsp;cert store or was created via CertCreateCertificateContext. For either case,<br>// &nbsp;its freed via CertFreeCertificateContext.<br>//<br>// &nbsp;If a valid certificate isn't found, this callback returns NULL with<br>// &nbsp;LastError set via SetLastError().<br>//<br>// &nbsp;The NULL implementation tries to get the Signer certificate from the<br>// &nbsp;message cert store. It doesn't verify the certificate.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp; &nbsp;PFN_CRYPT_GET_SIGNER_CERTIFICATE = function (pvGetArg :PVOID;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pSignerId :PCERT_INFO; &nbsp; &nbsp; &nbsp; &nbsp;// Only the Issuer and SerialNumber<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hMsgCertStore :HCERTSTORE &nbsp; &nbsp; // fields have been updated<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):PCCERT_CONTEXT ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;The CRYPT_SIGN_MESSAGE_PARA are used for signing messages using the<br>// &nbsp;specified signing certificate contexts. (Note, allows multiple signers.)<br>//<br>// &nbsp;Either the CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_PROV_INFO_PROP_ID must<br>// &nbsp;be set for each rgpSigningCert[]. Either one specifies the private<br>// &nbsp;signature key to use.<br>//<br>// &nbsp;If any certificates and/or CRLs are to be included in the signed message,<br>// &nbsp;then, the MsgCert and MsgCrl parameters need to be updated. If the<br>// &nbsp;rgpSigningCerts are to be included, then, they must also be in the<br>// &nbsp;rgpMsgCert array.<br>//<br>// &nbsp;cbSize must be set to the sizeof(CRYPT_SIGN_MESSAGE_PARA) or else<br>// &nbsp;LastError will be updated with E_INVALIDARG.<br>//<br>// &nbsp;pvHashAuxInfo currently isn't used and must be set to NULL.<br>//<br>// &nbsp;dwFlags normally is set to 0. However, if the encoded output<br>// &nbsp;is to be a CMSG_SIGNED inner content of an outer cryptographic message,<br>// &nbsp;such as a CMSG_ENVELOPED, then, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG<br>// &nbsp;should be set. If not set, then it would be encoded as an inner content<br>// &nbsp;type of CMSG_DATA.<br>//<br>// &nbsp;dwInnerContentType is normally set to 0. It needs to be set if the<br>// &nbsp;ToBeSigned input is the encoded output of another cryptographic<br>// &nbsp;message, such as, an CMSG_ENVELOPED. When set, it's one of the cryptographic<br>// &nbsp;message types, for example, CMSG_ENVELOPED.<br>//<br>// &nbsp;If the inner content of a nested cryptographic message is data (CMSG_DATA<br>// &nbsp;the default), then, neither dwFlags or dwInnerContentType need to be set.<br>//--------------------------------------------------------------------------<br><br>type<br> &nbsp;PCRYPT_SIGN_MESSAGE_PARA = ^CRYPT_SIGN_MESSAGE_PARA;<br> &nbsp;CRYPT_SIGN_MESSAGE_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp;pSigningCert :PCCERT_CONTEXT;<br> &nbsp; &nbsp;HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;pvHashAuxInfo :PVOID;<br> &nbsp; &nbsp;cMsgCert :DWORD;<br> &nbsp; &nbsp;rgpMsgCert :PPCCERT_CONTEXT;// pointer to array of PCCERT_CONTEXT<br> &nbsp; &nbsp;cMsgCrl :DWORD;<br> &nbsp; &nbsp;rgpMsgCrl :PPCCRL_CONTEXT; // pointer to array of PCCERT_CO<br> &nbsp; &nbsp;cAuthAttr :DWORD;<br> &nbsp; &nbsp;rgAuthAttr :PCRYPT_ATTRIBUTE;<br> &nbsp; &nbsp;cUnauthAttr :DWORD;<br> &nbsp; &nbsp;rgUnauthAttr :PCRYPT_ATTRIBUTE;<br> &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp;dwInnerContentType :DWORD;<br> &nbsp;end;<br>const CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG = $1;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;The CRYPT_VERIFY_MESSAGE_PARA are used to verify signed messages.<br>//<br>// &nbsp;hCryptProv is used to do hashing and signature verification.<br>//<br>// &nbsp;The dwCertEncodingType specifies the encoding type of the certificates<br>// &nbsp;and/or CRLs in the message.<br>//<br>// &nbsp;pfnGetSignerCertificate is called to get and verify the message signer's<br>// &nbsp;certificate.<br>//<br>// &nbsp;cbSize must be set to the sizeof(CRYPT_VERIFY_MESSAGE_PARA) or else<br>// &nbsp;LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCRYPT_VERIFY_MESSAGE_PARA = ^CRYPT_VERIFY_MESSAGE_PARA;<br> &nbsp;CRYPT_VERIFY_MESSAGE_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwMsgAndCertEncodingType :DWORD;<br> &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp;pfnGetSignerCertificate :PFN_CRYPT_GET_SIGNER_CERTIFICATE;<br> &nbsp; &nbsp;pvGetArg :PVOID;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;The CRYPT_ENCRYPT_MESSAGE_PARA are used for encrypting messages.<br>//<br>// &nbsp;hCryptProv is used to do content encryption, recipient key<br>// &nbsp;encryption, and recipient key export. Its private key<br>// &nbsp;isn't used.<br>//<br>// &nbsp;pvEncryptionAuxInfo currently isn't used and must be set to NULL.<br>//<br>// &nbsp;cbSize must be set to the sizeof(CRYPT_ENCRYPT_MESSAGE_PARA) or else<br>// &nbsp;LastError will be updated with E_INVALIDARG.<br>//<br>// &nbsp;dwFlags normally is set to 0. However, if the encoded output<br>// &nbsp;is to be a CMSG_ENVELOPED inner content of an outer cryptographic message,<br>// &nbsp;such as a CMSG_SIGNED, then, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG<br>// &nbsp;should be set. If not set, then it would be encoded as an inner content<br>// &nbsp;type of CMSG_DATA.<br>//<br>// &nbsp;dwInnerContentType is normally set to 0. It needs to be set if the<br>// &nbsp;ToBeEncrypted input is the encoded output of another cryptographic<br>// &nbsp;message, such as, an CMSG_SIGNED. When set, it's one of the cryptographic<br>// &nbsp;message types, for example, CMSG_SIGNED.<br>//<br>// &nbsp;If the inner content of a nested cryptographic message is data (CMSG_DATA<br>// &nbsp;the default), then, neither dwFlags or dwInnerContentType need to be set.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCRYPT_ENCRYPT_MESSAGE_PARA = ^CRYPT_ENCRYPT_MESSAGE_PARA;<br> &nbsp;CRYPT_ENCRYPT_MESSAGE_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp;ContentEncryptionAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;pvEncryptionAuxInfo :PVOID;<br> &nbsp; &nbsp;dwFlags :DWORD;<br> &nbsp; &nbsp;dwInnerContentType :DWORD;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;The CRYPT_DECRYPT_MESSAGE_PARA are used for decrypting messages.<br>//<br>// &nbsp;The CertContext to use for decrypting a message is obtained from one<br>// &nbsp;of the specified cert stores. An encrypted message can have one or<br>// &nbsp;more recipients. The recipients are identified by their CertId (Issuer<br>// &nbsp;and SerialNumber). The cert stores are searched to find the CertContext<br>// &nbsp;corresponding to the CertId.<br>//<br>// &nbsp;Only CertContexts in the store with either<br>// &nbsp;the CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_PROV_INFO_PROP_ID set<br>// &nbsp;can be used. Either property specifies the private exchange key to use.<br>//<br>// &nbsp;cbSize must be set to the sizeof(CRYPT_DECRYPT_MESSAGE_PARA) or else<br>// &nbsp;LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCRYPT_DECRYPT_MESSAGE_PARA = ^CRYPT_DECRYPT_MESSAGE_PARA;<br> &nbsp;CRYPT_DECRYPT_MESSAGE_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwMsgAndCertEncodingType :DWORD;<br> &nbsp; &nbsp;cCertStore :DWORD;<br> &nbsp; &nbsp;rghCertStore :PHCERTSTORE;<br> &nbsp;end;<br>//+-------------------------------------------------------------------------<br>// &nbsp;The CRYPT_HASH_MESSAGE_PARA are used for hashing or unhashing<br>// &nbsp;messages.<br>//<br>// &nbsp;hCryptProv is used to compute the hash.<br>//<br>// &nbsp;pvHashAuxInfo currently isn't used and must be set to NULL.<br>//<br>// &nbsp;cbSize must be set to the sizeof(CRYPT_HASH_MESSAGE_PARA) or else<br>// &nbsp;LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCRYPT_HASH_MESSAGE_PARA = ^CRYPT_HASH_MESSAGE_PARA;<br> &nbsp;CRYPT_HASH_MESSAGE_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp;HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;pvHashAuxInfo :PVOID;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;The CRYPT_KEY_SIGN_MESSAGE_PARA are used for signing messages until a<br>// &nbsp;certificate has been created for the signature key.<br>//<br>// &nbsp;pvHashAuxInfo currently isn't used and must be set to NULL.<br>//<br>// &nbsp;If PubKeyAlgorithm isn't set, defaults to szOID_RSA_RSA.<br>//<br>// &nbsp;cbSize must be set to the sizeof(CRYPT_KEY_SIGN_MESSAGE_PARA) or else<br>// &nbsp;LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCRYPT_KEY_SIGN_MESSAGE_PARA = ^CRYPT_KEY_SIGN_MESSAGE_PARA;<br> &nbsp;CRYPT_KEY_SIGN_MESSAGE_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwMsgAndCertEncodingType :DWORD;<br> &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp; &nbsp;dwKeySpec :DWORD;<br> &nbsp; &nbsp;HashAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp; &nbsp;pvHashAuxInfo :PVOID;<br> &nbsp; &nbsp;PubKeyAlgorithm :CRYPT_ALGORITHM_IDENTIFIER;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;The CRYPT_KEY_VERIFY_MESSAGE_PARA are used to verify signed messages without<br>// &nbsp;a certificate for the signer.<br>//<br>// &nbsp;Normally used until a certificate has been created for the key.<br>//<br>// &nbsp;hCryptProv is used to do hashing and signature verification.<br>//<br>// &nbsp;cbSize must be set to the sizeof(CRYPT_KEY_VERIFY_MESSAGE_PARA) or else<br>// &nbsp;LastError will be updated with E_INVALIDARG.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCRYPT_KEY_VERIFY_MESSAGE_PARA = ^CRYPT_KEY_VERIFY_MESSAGE_PARA;<br> &nbsp;CRYPT_KEY_VERIFY_MESSAGE_PARA = record<br> &nbsp; &nbsp;cbSize :DWORD;<br> &nbsp; &nbsp;dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp;hCryptProv :HCRYPTPROV;<br> &nbsp;end;<br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Sign the message.<br>//<br>// &nbsp;If fDetachedSignature is TRUE, the &quot;to be signed&quot; content isn't included<br>// &nbsp;in the encoded signed blob.<br>//--------------------------------------------------------------------------<br>function CryptSignMessage(pSignPara :PCRYPT_SIGN_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fDetachedSignature :BOOL;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cToBeSigned :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const rgpbToBeSigned :array of PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rgcbToBeSigned :array of DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbSignedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbSignedBlob :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify a signed message.<br>//<br>// &nbsp;If pbDecoded == NULL, then, *pcbDecoded is implicitly set to 0 on input.<br>// &nbsp;For *pcbDecoded == 0 && ppSignerCert == NULL on input, the signer isn't<br>// &nbsp;verified.<br>//<br>// &nbsp;A message might have more than one signer. Set dwSignerIndex to iterate<br>// &nbsp;through all the signers. dwSignerIndex == 0 selects the first signer.<br>//<br>// &nbsp;pVerifyPara's pfnGetSignerCertificate is called to get the signer's<br>// &nbsp;certificate.<br>//<br>// &nbsp;For a verified signer and message, *ppSignerCert is updated<br>// &nbsp;with the CertContext of the signer. It must be freed by calling<br>// &nbsp;CertFreeCertificateContext. Otherwise, *ppSignerCert is set to NULL.<br>//<br>// &nbsp;ppSignerCert can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the CertContext of the signer.<br>//<br>// &nbsp;pcbDecoded can be NULL, indicating the caller isn't interested in getting<br>// &nbsp;the decoded content. Furthermore, if the message doesn't contain any<br>// &nbsp;content or signers, then, pcbDecoded must be set to NULL, to allow the<br>// &nbsp;pVerifyPara-&gt;pfnGetCertificate to be called. Normally, this would be<br>// &nbsp;the case when the signed message contains only certficates and CRLs.<br>// &nbsp;If pcbDecoded is NULL and the message doesn't have the indicated signer,<br>// &nbsp;pfnGetCertificate is called with pSignerId set to NULL.<br>//<br>// &nbsp;If the message doesn't contain any signers || dwSignerIndex &gt; message's<br>// &nbsp;SignerCount, then, an error is returned with LastError set to<br>// &nbsp;CRYPT_E_NO_SIGNER. Also, for CRYPT_E_NO_SIGNER, pfnGetSignerCertificate<br>// &nbsp;is still called with pSignerId set to NULL.<br>//<br>// &nbsp;Note, an alternative way to get the certificates and CRLs from a<br>// &nbsp;signed message is to call CryptGetMessageCertificates.<br>//--------------------------------------------------------------------------<br>function CryptVerifyMessageSignature(pVerifyPara :PCRYPT_VERIFY_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwSignerIndex :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbSignedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbSignedBlob :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbDecoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbDecoded :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ppSignerCert :PCCERT_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Returns the count of signers in the signed message. For no signers, returns<br>// &nbsp;0. For an error returns -1 with LastError updated accordingly.<br>//--------------------------------------------------------------------------<br>function CryptGetMessageSignerCount(dwMsgEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbSignedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbSignedBlob :DWORD):LONG ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Returns the cert store containing the message's certs and CRLs.<br>// &nbsp;For an error, returns NULL with LastError updated.<br>//--------------------------------------------------------------------------<br>function CryptGetMessageCertificates(dwMsgAndCertEncodingType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hCryptProv :HCRYPTPROV; // passed to CertOpenStore<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags :DWORD; &nbsp;// passed to CertOpenStore<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbSignedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbSignedBlob :DWORD):HCERTSTORE ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify a signed message containing detached signature(s).<br>// &nbsp;The &quot;to be signed&quot; content is passed in separately. No<br>// &nbsp;decoded output. Otherwise, identical to CryptVerifyMessageSignature.<br>//--------------------------------------------------------------------------<br>function CryptVerifyDetachedMessageSignature(pVerifyPara :PCRYPT_VERIFY_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwSignerIndex :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbDetachedSignBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbDetachedSignBlob :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cToBeSigned :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const rgpbToBeSigned :array of PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rgcbToBeSigned :array of DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ppSignerCert :PPCCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Encrypts the message for the recipient(s).<br>//--------------------------------------------------------------------------<br>function CryptEncryptMessage(pEncryptPara :PCRYPT_ENCRYPT_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cRecipientCert :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rgpRecipientCert :array of PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbToBeEncrypted :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbToBeEncrypted :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbEncryptedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbEncryptedBlob :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Decrypts the message.<br>//<br>// &nbsp;If pbDecrypted == NULL, then, *pcbDecrypted is implicitly set to 0 on input.<br>// &nbsp;For *pcbDecrypted == 0 && ppXchgCert == NULL on input, the message isn't<br>// &nbsp;decrypted.<br>//<br>// &nbsp;For a successfully decrypted message, *ppXchgCert is updated<br>// &nbsp;with the CertContext used to decrypt. It must be freed by calling<br>// &nbsp;CertStoreFreeCert. Otherwise, *ppXchgCert is set to NULL.<br>//<br>// &nbsp;ppXchgCert can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the CertContext used to decrypt.<br>//--------------------------------------------------------------------------<br>function CryptDecryptMessage(pDecryptPara :PCRYPT_DECRYPT_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbEncryptedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbEncryptedBlob :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbDecrypted :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbDecrypted :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ppXchgCert :PPCCERT_CONTEXT):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Sign the message and encrypt for the recipient(s). Does a CryptSignMessage<br>// &nbsp;followed with a CryptEncryptMessage.<br>//<br>// &nbsp;Note: this isn't the CMSG_SIGNED_AND_ENVELOPED. Its a CMSG_SIGNED<br>// &nbsp;inside of an CMSG_ENVELOPED.<br>//--------------------------------------------------------------------------<br>function CryptSignAndEncryptMessage(pSignPara :PCRYPT_SIGN_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pEncryptPara :PCRYPT_ENCRYPT_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cRecipientCert :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rgpRecipientCert :array of PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbToBeSignedAndEncrypted :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbToBeSignedAndEncrypted :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbSignedAndEncryptedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbSignedAndEncryptedBlob :PDWORD<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Decrypts the message and verifies the signer. Does a CryptDecryptMessage<br>// &nbsp;followed with a CryptVerifyMessageSignature.<br>//<br>// &nbsp;If pbDecrypted == NULL, then, *pcbDecrypted is implicitly set to 0 on input.<br>// &nbsp;For *pcbDecrypted == 0 && ppSignerCert == NULL on input, the signer isn't<br>// &nbsp;verified.<br>//<br>// &nbsp;A message might have more than one signer. Set dwSignerIndex to iterate<br>// &nbsp;through all the signers. dwSignerIndex == 0 selects the first signer.<br>//<br>// &nbsp;The pVerifyPara's VerifySignerPolicy is called to verify the signer's<br>// &nbsp;certificate.<br>//<br>// &nbsp;For a successfully decrypted and verified message, *ppXchgCert and<br>// &nbsp;*ppSignerCert are updated. They must be freed by calling<br>// &nbsp;CertStoreFreeCert. Otherwise, they are set to NULL.<br>//<br>// &nbsp;ppXchgCert and/or ppSignerCert can be NULL, indicating the<br>// &nbsp;caller isn't interested in getting the CertContext.<br>//<br>// &nbsp;Note: this isn't the CMSG_SIGNED_AND_ENVELOPED. Its a CMSG_SIGNED<br>// &nbsp;inside of an CMSG_ENVELOPED.<br>//<br>// &nbsp;The message always needs to be decrypted to allow access to the<br>// &nbsp;signed message. Therefore, if ppXchgCert != NULL, its always updated.<br>//--------------------------------------------------------------------------<br>function CryptDecryptAndVerifyMessageSignature(pDecryptPara :PCRYPT_DECRYPT_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pVerifyPara :PCRYPT_VERIFY_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwSignerIndex :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbEncryptedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbEncryptedBlob :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbDecrypted :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbDecrypted :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var ppXchgCert :array of PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var ppSignerCert :array of PCCERT_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Decodes a cryptographic message which may be one of the following types:<br>// &nbsp; &nbsp;CMSG_DATA<br>// &nbsp; &nbsp;CMSG_SIGNED<br>// &nbsp; &nbsp;CMSG_ENVELOPED<br>// &nbsp; &nbsp;CMSG_SIGNED_AND_ENVELOPED<br>// &nbsp; &nbsp;CMSG_HASHED<br>//<br>// &nbsp;dwMsgTypeFlags specifies the set of allowable messages. For example, to<br>// &nbsp;decode either SIGNED or ENVELOPED messages, set dwMsgTypeFlags to:<br>// &nbsp; &nbsp; &nbsp;CMSG_SIGNED_FLAG | CMSG_ENVELOPED_FLAG.<br>//<br>// &nbsp;dwProvInnerContentType is only applicable when processing nested<br>// &nbsp;crytographic messages. When processing an outer crytographic message<br>// &nbsp;it must be set to 0. When decoding a nested cryptographic message<br>// &nbsp;its the dwInnerContentType returned by a previous CryptDecodeMessage<br>// &nbsp;of the outer message. The InnerContentType can be any of the CMSG types,<br>// &nbsp;for example, CMSG_DATA, CMSG_SIGNED, ...<br>//<br>// &nbsp;The optional *pdwMsgType is updated with the type of message.<br>//<br>// &nbsp;The optional *pdwInnerContentType is updated with the type of the inner<br>// &nbsp;message. Unless there is cryptographic message nesting, CMSG_DATA<br>// &nbsp;is returned.<br>//<br>// &nbsp;For CMSG_DATA: returns decoded content.<br>// &nbsp;For CMSG_SIGNED: same as CryptVerifyMessageSignature.<br>// &nbsp;For CMSG_ENVELOPED: same as CryptDecryptMessage.<br>// &nbsp;For CMSG_SIGNED_AND_ENVELOPED: same as CryptDecryptMessage plus<br>// &nbsp; &nbsp; &nbsp;CryptVerifyMessageSignature.<br>// &nbsp;For CMSG_HASHED: verifies the hash and returns decoded content.<br>//--------------------------------------------------------------------------<br>function CryptDecodeMessage(dwMsgTypeFlags :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pDecryptPara &nbsp; :PCRYPT_DECRYPT_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pVerifyPara &nbsp; &nbsp;:PCRYPT_VERIFY_MESSAGE_PARA ;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwSignerIndex &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbEncodedBlob &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbEncodedBlob &nbsp;:DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwPrevInnerContentType :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwMsgType &nbsp; &nbsp; :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pdwInnerContentType :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbDecoded &nbsp; &nbsp; &nbsp;:PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbDecoded &nbsp; &nbsp; :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppXchgCert &nbsp; &nbsp; :array of PCCERT_CONTEXT;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ppSignerCert &nbsp; :array of PCCERT_CONTEXT<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Hash the message.<br>//<br>// &nbsp;If fDetachedHash is TRUE, only the ComputedHash is encoded in the<br>// &nbsp;pbHashedBlob. Otherwise, both the ToBeHashed and ComputedHash<br>// &nbsp;are encoded.<br>//<br>// &nbsp;pcbHashedBlob or pcbComputedHash can be NULL, indicating the caller<br>// &nbsp;isn't interested in getting the output.<br>//--------------------------------------------------------------------------<br>function CryptHashMessage(pHashPara :PCRYPT_HASH_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fDetachedHash :BOOL;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cToBeHashed :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const rgpbToBeHashed :array of PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rgcbToBeHashed :array of DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbHashedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbHashedBlob :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbComputedHash :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbComputedHash :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify a hashed message.<br>//<br>// &nbsp;pcbToBeHashed or pcbComputedHash can be NULL,<br>// &nbsp;indicating the caller isn't interested in getting the output.<br>//--------------------------------------------------------------------------<br>function CryptVerifyMessageHash(pHashPara :PCRYPT_HASH_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbHashedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbHashedBlob :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbToBeHashed :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbToBeHashed :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbComputedHash :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbComputedHash :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify a hashed message containing a detached hash.<br>// &nbsp;The &quot;to be hashed&quot; content is passed in separately. No<br>// &nbsp;decoded output. Otherwise, identical to CryptVerifyMessageHash.<br>//<br>// &nbsp;pcbComputedHash can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the output.<br>//--------------------------------------------------------------------------<br>function CryptVerifyDetachedMessageHash(pHashPara :PCRYPT_HASH_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbDetachedHashBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbDetachedHashBlob :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cToBeHashed :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rgpbToBeHashed :array of PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rgcbToBeHashed :array of DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbComputedHash :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbComputedHash :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Sign the message using the provider's private key specified in the<br>// &nbsp;parameters. A dummy SignerId is created and stored in the message.<br>//<br>// &nbsp;Normally used until a certificate has been created for the key.<br>//--------------------------------------------------------------------------<br>function CryptSignMessageWithKey(pSignPara :PCRYPT_KEY_SIGN_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbToBeSigned :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbToBeSigned :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbSignedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbSignedBlob :PDWORD):BOOL ; stdcall;<br>//+-------------------------------------------------------------------------<br>// &nbsp;Verify a signed message using the specified public key info.<br>//<br>// &nbsp;Normally called by a CA until it has created a certificate for the<br>// &nbsp;key.<br>//<br>// &nbsp;pPublicKeyInfo contains the public key to use to verify the signed<br>// &nbsp;message. If NULL, the signature isn't verified (for instance, the decoded<br>// &nbsp;content may contain the PublicKeyInfo).<br>//<br>// &nbsp;pcbDecoded can be NULL, indicating the caller isn't interested<br>// &nbsp;in getting the decoded content.<br>//--------------------------------------------------------------------------<br>function CryptVerifyMessageSignatureWithKey(pVerifyPara :PCRYPT_KEY_VERIFY_MESSAGE_PARA;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pPublicKeyInfo :PCERT_PUBLIC_KEY_INFO;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbSignedBlob :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbSignedBlob :DWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pbDecoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pcbDecoded :PDWORD):BOOL ; stdcall;<br><br>//+=========================================================================<br>// &nbsp;System Certificate Store Data Structures and APIs<br>//==========================================================================<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Get a system certificate store based on a subsystem protocol.<br>//<br>// &nbsp;Current examples of subsystems protocols are:<br>// &nbsp; &nbsp; &nbsp;&quot;MY&quot; &nbsp; &nbsp;Cert Store hold certs with associated Private Keys<br>// &nbsp; &nbsp; &nbsp;&quot;CA&quot; &nbsp; &nbsp;Certifying Authority certs<br>// &nbsp; &nbsp; &nbsp;&quot;ROOT&quot; &nbsp;Root Certs<br>// &nbsp; &nbsp; &nbsp;&quot;SPC&quot; &nbsp; Software publisher certs<br>//<br>//<br>// &nbsp;If hProv is NULL the default provider &quot;1&quot; is opened for you.<br>// &nbsp;When the store is closed the provider is release. Otherwise<br>// &nbsp;if hProv is not NULL, no provider is created or released.<br>//<br>// &nbsp;The returned Cert Store can be searched for an appropriate Cert<br>// &nbsp;using the Cert Store API's (see certstor.h)<br>//<br>// &nbsp;When done, the cert store should be closed using CertStoreClose<br>//--------------------------------------------------------------------------<br><br>function CertOpenSystemStoreA(hProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;szSubsystemProtocol :LPCSTR):HCERTSTORE ; stdcall;<br><br>function CertOpenSystemStoreW(hProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;szSubsystemProtocol :LPCWSTR):HCERTSTORE ; stdcall;<br><br>function CertOpenSystemStore(hProv :HCRYPTPROV;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; szSubsystemProtocol :LPAWSTR):HCERTSTORE ; stdcall;<br><br>function CertAddEncodedCertificateToSystemStoreA(szCertStoreName :LPCSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbCertEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbCertEncoded :DWORD):BOOL ; stdcall;<br><br>function CertAddEncodedCertificateToSystemStoreW(szCertStoreName :LPCWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const pbCertEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbCertEncoded :DWORD):BOOL ; stdcall;<br><br>function CertAddEncodedCertificateToSystemStore(szCertStoreName :LPAWSTR;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pbCertEncoded :PBYTE;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbCertEncoded :DWORD):BOOL ; stdcall;<br><br><br>//+-------------------------------------------------------------------------<br>// &nbsp;Find all certificate chains tying the given issuer name to any certificate<br>// &nbsp;that the current user has a private key for.<br>//<br>// &nbsp;If no certificate chain is found, FALSE is returned with LastError set<br>// &nbsp;to CRYPT_E_NOT_FOUND and the counts zeroed.<br>//<br>// &nbsp;IE 3.0 ASSUMPTION:<br>// &nbsp; The client certificates are in the &quot;My&quot; system store. The issuer<br>// &nbsp; cerificates may be in the &quot;Root&quot;, &quot;CA&quot; or &quot;My&quot; system stores.<br>//--------------------------------------------------------------------------<br>type<br> &nbsp;PCERT_CHAIN = ^CERT_CHAIN;<br> &nbsp;CERT_CHAIN = record<br> &nbsp; &nbsp;cCerts :DWORD; &nbsp; &nbsp; // number of certs in chain<br> &nbsp; &nbsp;certs :PCERT_BLOB; &nbsp; &nbsp; &nbsp;// pointer to array of cert chain blobs representing the certs<br> &nbsp; &nbsp;keyLocatorInfo :CRYPT_KEY_PROV_INFO; // key locator for cert<br> &nbsp;end;<br><br><br>// WINCRYPT32API &nbsp; &nbsp;This is not exported by crypt32, it is exported by softpub<br>function FindCertsByIssuer(pCertChains :PCERT_CHAIN;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcbCertChains :PDWORD;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pcCertChains :PDWORD; &nbsp; &nbsp; &nbsp; // count of certificates chains returned<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pbEncodedIssuerName :PBYTE; &nbsp; // DER encoded issuer name<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbEncodedIssuerName :DWORD; // count in bytes of encoded issuer name<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pwszPurpose :LPCWSTR; // &quot;ClientAuth&quot; or &quot;CodeSigning&quot;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwKeySpec :DWORD &nbsp;// only return signers supporting this keyspec<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ):HRESULT ; stdcall;<br><br>//////////////////////////// VERSION 2 ////////////////////////////////////////////////////////////////////<br><br>implementation<br><br>{Macro inplementation}<br>function GET_ALG_CLASS(x:integer) :integer;<br>begin<br> &nbsp;Result:=(x and (7 shl 13));<br>end;<br><br>function GET_ALG_TYPE(x:integer) :integer;<br>begin<br> &nbsp;Result:=(x and (15 shl 9));<br>end;<br><br>function GET_ALG_SID(x:integer) :integer;<br>begin<br> &nbsp;Result:=(x and (511));<br>end;<br><br>function RCRYPT_SUCCEEDED(rt:BOOL):BOOL;<br>begin<br> &nbsp;Result:= rt = CRYPT_SUCCEED;<br>end;<br><br>function RCRYPT_FAILED(rt:BOOL):BOOL;<br>begin<br> &nbsp;Result:= rt = CRYPT_FAILED;<br>end ;<br><br>function &nbsp;GET_CERT_UNICODE_RDN_ERR_INDEX(X :integer):integer;<br>begin<br> &nbsp; &nbsp;Result := &nbsp;((X shr CERT_UNICODE_RDN_ERR_INDEX_SHIFT) and CERT_UNICODE_RDN_ERR_INDEX_MASK);<br>end;<br><br>function &nbsp;GET_CERT_UNICODE_ATTR_ERR_INDEX(X :integer):integer;<br>begin<br> &nbsp; &nbsp;Result := ((X shr CERT_UNICODE_ATTR_ERR_INDEX_SHIFT) and CERT_UNICODE_ATTR_ERR_INDEX_MASK);<br>end;<br><br>function &nbsp;GET_CERT_UNICODE_VALUE_ERR_INDEX(X :integer):integer;<br>begin<br> &nbsp; &nbsp;Result := (X and CERT_UNICODE_VALUE_ERR_INDEX_MASK);<br>end;<br><br>function GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X :DWORD):DWORD;<br>begin<br> &nbsp; &nbsp;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 :DWORD):DWORD;<br>begin<br> &nbsp; &nbsp;Result := (X and CERT_ALT_NAME_VALUE_ERR_INDEX_MASK);<br>end;<br><br>function GET_CRL_DIST_POINT_ERR_INDEX(X :DWORD):DWORD;<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 :DWORD):BOOL;<br>begin<br> &nbsp; &nbsp;Result := (0 &lt;&gt; (X and CRL_DIST_POINT_ERR_CRL_ISSUER_BIT));<br>end;<br>///////////////////////////////////////version 2 /////////////////////////<br><br>function IS_CERT_RDN_CHAR_STRING(X :DWORD) :BOOL;<br>begin<br> &nbsp; &nbsp;Result :=BOOL(X &gt;= CERT_RDN_NUMERIC_STRING);<br> end;<br><br>function GET_CERT_ENCODING_TYPE(X :DWORD):DWORD;<br>begin<br> &nbsp; &nbsp;Result := (X and CERT_ENCODING_TYPE_MASK);<br>end;<br><br>function GET_CMSG_ENCODING_TYPE(X :DWORD):DWORD;<br>begin<br> &nbsp; &nbsp;Result := (X and CMSG_ENCODING_TYPE_MASK);<br>end;<br><br>function IS_CERT_HASH_PROP_ID( X :DWORD):BOOL ;<br>begin<br> &nbsp; &nbsp;if (X = CERT_SHA1_HASH_PROP_ID) or (X = CERT_MD5_HASH_PROP_ID) then<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := True<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := False;<br>end;<br>{end Macro}<br><br>function CryptAcquireContextA &nbsp; &nbsp;;external ADVAPI32 name 'CryptAcquireContextA';<br>{$IFDEF UNICODE}<br>function CryptAcquireContext &nbsp; &nbsp; ;external ADVAPI32 name 'CryptAcquireContextW';<br>{$ELSE}<br>function CryptAcquireContext &nbsp; &nbsp; ;external ADVAPI32 name 'CryptAcquireContextA';<br>{$ENDIF}<br>function CryptAcquireContextW &nbsp; &nbsp;;external ADVAPI32 name 'CryptAcquireContextW';<br>function CryptReleaseContext &nbsp; &nbsp; ;external ADVAPI32 name 'CryptReleaseContext';<br>function CryptGenKey &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptGenKey';<br>function CryptDeriveKey &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptDeriveKey';<br>function CryptDestroyKey &nbsp; &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptDestroyKey';<br>function CryptSetKeyParam &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptSetKeyParam';<br>function CryptGetKeyParam &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptGetKeyParam';<br>function CryptSetHashParam &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptSetHashParam';<br>function CryptGetHashParam &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptGetHashParam';<br>function CryptSetProvParam &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptSetProvParam';<br>function CryptGetProvParam &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptGetProvParam';<br>function CryptGenRandom &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptGenRandom';<br>function CryptGetUserKey &nbsp; &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptGetUserKey';<br>function CryptExportKey &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptExportKey';<br>function CryptImportKey &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptImportKey';<br>function CryptEncrypt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptEncrypt';<br>function CryptDecrypt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptDecrypt';<br>function CryptCreateHash &nbsp; &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptCreateHash';<br>function CryptHashData &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptHashData';<br>function CryptHashSessionKey &nbsp; &nbsp; ;external ADVAPI32 name 'CryptHashSessionKey';<br>function CryptDestroyHash &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptDestroyHash';<br>function CryptSignHashA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptSignHashA';<br>function CryptSignHashW &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptSignHashW';<br>function CryptSignHashU &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;external CRYPT32 name 'CryptSignHashU';<br>{$IFDEF UNICODE}<br>function CryptSignHash &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptSignHashW';<br>{$ELSE}<br>function CryptSignHash &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptSignHashA';<br>{$ENDIF}<br>function CryptVerifySignatureA &nbsp; ;external ADVAPI32 name 'CryptVerifySignatureA';<br>function CryptVerifySignatureW &nbsp; ;external ADVAPI32 name 'CryptVerifySignatureW';<br>{$IFDEF UNICODE}<br>function CryptVerifySignature &nbsp; &nbsp;;external ADVAPI32 name 'CryptVerifySignatureW';<br>{$ELSE}<br>function CryptVerifySignature &nbsp; &nbsp;;external ADVAPI32 name 'CryptVerifySignatureA';<br>{$ENDIF}<br>function CryptSetProviderW &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptSetProviderW';<br>function CryptSetProviderA &nbsp; &nbsp; &nbsp; ;external ADVAPI32 name 'CryptSetProviderA';<br>function CryptSetProviderU &nbsp; &nbsp; &nbsp; ;external CRYPT32 name 'CryptSetProviderU';<br>{$IFDEF UNICODE}<br>function CryptSetProvider &nbsp; &nbsp; &nbsp; &nbsp;;external ADVAPI32 name 'CryptSetProviderW';<br>{$ELSE}<br>function CryptSetProvider &nbsp; &nbsp; &nbsp; &nbsp;;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 &nbsp;CryptSetProviderEx &nbsp;;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.
 
后退
顶部