Permalink
Switch branches/tags
Nothing to show
Find file Copy path
c8c3a29 Sep 9, 2011
1 contributor

Users who have contributed to this file

7871 lines (7106 sloc) 319 KB
{******************************************************************}
{ }
{ Borland Delphi Runtime Library }
{ Cryptographic API interface unit }
{ }
{ Portions created by Microsoft are }
{ Copyright (C) 1993-1998 Microsoft Corporation. }
{ All Rights Reserved. }
{ }
{ The original file is: wincrypt.h, 1992 - 1997 }
{ The original Pascal code is: wcrypt2.pas, released 01 Jan 1998 }
{ The initial developer of the Pascal code is }
{ Massimo Maria Ghisalberti (nissl@dada.it) }
{ }
{ Portions created by Massimo Maria Ghisalberti are }
{ Copyright (C) 1997-1998 Massimo Maria Ghisalberti }
{ }
{ Contributor(s): }
{ Peter Tang (peter.tang@citicorp.com) }
{ Phil Shrimpton (phil@shrimpton.co.uk) }
{ }
{ Obtained through: }
{ }
{ Joint Endeavour of Delphi Innovators (Project JEDI) }
{ }
{ You may retrieve the latest version of this file at the Project }
{ JEDI home page, located at http://delphi-jedi.org }
{ }
{ The contents of this file are used with permission, subject to }
{ the Mozilla Public License Version 1.1 (the "License"); you may }
{ not use this file except in compliance with the License. You may }
{ obtain a copy of the License at }
{ http://www.mozilla.org/MPL/MPL-1.1.html }
{ }
{ Software distributed under the License is distributed on an }
{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
{ implied. See the License for the specific language governing }
{ rights and limitations under the License. }
{ }
{******************************************************************}
//$Id: Wcrypt2.pas,v 1.2 2006/11/15 21:01:44 sergev Exp $
unit wcrypt2;
{.DEFINE NT5}
{$ALIGN ON}
{$IFNDEF VER90}
{$WEAKPACKAGEUNIT}
{$ENDIF}
interface
uses
Windows
{$IFDEF VER90}
, Ole2
{$ENDIF};
const
ADVAPI32 = 'advapi32.dll';
CRYPT32 = 'crypt32.dll';
SOFTPUB = 'softpub.dll';
{$IFDEF NT5}
ADVAPI32NT5 = 'advapi32.dll';
{$ENDIF}
{Support Type}
type
PVOID = Pointer;
LONG = DWORD;
{$IFDEF UNICODE}
LPAWSTR = PWideChar;
{$ELSE}
LPAWSTR = PAnsiChar;
{$ENDIF}
//-----------------------------------------------------------------------------
// Type support for a pointer to an array of pointer (type **name)
PLPSTR = Pointer; // type for a pointer to Array of pointer a type
PPCERT_INFO = Pointer; // type for a pointer to Array of pointer a type
PPVOID = Pointer; // type for a pointer to Array of pointer a type
PPCCERT_CONTEXT = Pointer; // type for a pointer to Array of pointer a type
PPCCTL_CONTEXT = Pointer; // type for a pointer to Array of pointer a type
PPCCRL_CONTEXT = Pointer; // type for a pointer to Array of pointer a type
//-----------------------------------------------------------------------------
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1997.
//
// File: wincrypt.h
//
// Contents: Cryptographic API Prototypes and Definitions
//
//----------------------------------------------------------------------------
//
// Algorithm IDs and Flags
//
// ALG_ID crackers
function GET_ALG_CLASS(x: integer): integer;
function GET_ALG_TYPE(x: integer): integer;
function GET_ALG_SID(x: integer): integer;
const
// Algorithm classes
ALG_CLASS_ANY = 0;
ALG_CLASS_SIGNATURE = (1 shl 13);
ALG_CLASS_MSG_ENCRYPT = (2 shl 13);
ALG_CLASS_DATA_ENCRYPT = (3 shl 13);
ALG_CLASS_HASH = (4 shl 13);
ALG_CLASS_KEY_EXCHANGE = (5 shl 13);
// Algorithm types
ALG_TYPE_ANY = 0;
ALG_TYPE_DSS = (1 shl 9);
ALG_TYPE_RSA = (2 shl 9);
ALG_TYPE_BLOCK = (3 shl 9);
ALG_TYPE_STREAM = (4 shl 9);
ALG_TYPE_DH = (5 shl 9);
ALG_TYPE_SECURECHANNEL = (6 shl 9);
// Generic sub-ids
ALG_SID_ANY = 0;
// Some RSA sub-ids
ALG_SID_RSA_ANY = 0;
ALG_SID_RSA_PKCS = 1;
ALG_SID_RSA_MSATWORK = 2;
ALG_SID_RSA_ENTRUST = 3;
ALG_SID_RSA_PGP = 4;
// Some DSS sub-ids
ALG_SID_DSS_ANY = 0;
ALG_SID_DSS_PKCS = 1;
ALG_SID_DSS_DMS = 2;
// Block cipher sub ids
// DES sub_ids
ALG_SID_DES = 1;
ALG_SID_3DES = 3;
ALG_SID_DESX = 4;
ALG_SID_IDEA = 5;
ALG_SID_CAST = 6;
ALG_SID_SAFERSK64 = 7;
ALD_SID_SAFERSK128 = 8;
ALG_SID_SAFERSK128 = 8;
ALG_SID_3DES_112 = 9;
ALG_SID_CYLINK_MEK = 12;
ALG_SID_RC5 = 13;
// Fortezza sub-ids
ALG_SID_SKIPJACK = 10;
ALG_SID_TEK = 11;
// KP_MODE
CRYPT_MODE_CBCI = 6; {ANSI CBC Interleaved}
CRYPT_MODE_CFBP = 7; {ANSI CFB Pipelined}
CRYPT_MODE_OFBP = 8; {ANSI OFB Pipelined}
CRYPT_MODE_CBCOFM = 9; {ANSI CBC + OF Masking}
CRYPT_MODE_CBCOFMI = 10; {ANSI CBC + OFM Interleaved}
// RC2 sub-ids
ALG_SID_RC2 = 2;
// Stream cipher sub-ids
ALG_SID_RC4 = 1;
ALG_SID_SEAL = 2;
// Diffie-Hellman sub-ids
ALG_SID_DH_SANDF = 1;
ALG_SID_DH_EPHEM = 2;
ALG_SID_AGREED_KEY_ANY = 3;
ALG_SID_KEA = 4;
// Hash sub ids
ALG_SID_MD2 = 1;
ALG_SID_MD4 = 2;
ALG_SID_MD5 = 3;
ALG_SID_SHA = 4;
ALG_SID_SHA1 = 4;
ALG_SID_MAC = 5;
ALG_SID_RIPEMD = 6;
ALG_SID_RIPEMD160 = 7;
ALG_SID_SSL3SHAMD5 = 8;
ALG_SID_HMAC = 9;
// secure channel sub ids
ALG_SID_SSL3_MASTER = 1;
ALG_SID_SCHANNEL_MASTER_HASH = 2;
ALG_SID_SCHANNEL_MAC_KEY = 3;
ALG_SID_PCT1_MASTER = 4;
ALG_SID_SSL2_MASTER = 5;
ALG_SID_TLS1_MASTER = 6;
ALG_SID_SCHANNEL_ENC_KEY = 7;
// Our silly example sub-id
ALG_SID_EXAMPLE = 80;
{$IFNDEF ALGIDDEF}
{$DEFINE ALGIDDEF}
type ALG_ID = ULONG;
{$ENDIF}
// algorithm identifier definitions
const
CALG_MD2 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD2);
CALG_MD4 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD4);
CALG_MD5 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD5);
CALG_SHA = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_SHA);
CALG_SHA1 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_SHA1);
CALG_MAC = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MAC);
CALG_RSA_SIGN = (ALG_CLASS_SIGNATURE or ALG_TYPE_RSA or ALG_SID_RSA_ANY);
CALG_DSS_SIGN = (ALG_CLASS_SIGNATURE or ALG_TYPE_DSS or ALG_SID_DSS_ANY);
CALG_RSA_KEYX = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_RSA or ALG_SID_RSA_ANY);
CALG_DES = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_DES);
CALG_3DES_112 = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_3DES_112);
CALG_3DES = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_3DES);
CALG_RC2 = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_RC2);
CALG_RC4 = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_STREAM or ALG_SID_RC4);
CALG_SEAL = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_STREAM or ALG_SID_SEAL);
CALG_DH_SF = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_DH_SANDF);
CALG_DH_EPHEM = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_DH_EPHEM);
CALG_AGREEDKEY_ANY = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_AGREED_KEY_ANY);
CALG_KEA_KEYX = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_DH or ALG_SID_KEA);
CALG_HUGHES_MD5 = (ALG_CLASS_KEY_EXCHANGE or ALG_TYPE_ANY or ALG_SID_MD5);
CALG_SKIPJACK = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_SKIPJACK);
CALG_TEK = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_TEK);
CALG_CYLINK_MEK = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_CYLINK_MEK);
CALG_SSL3_SHAMD5 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_SSL3SHAMD5);
CALG_SSL3_MASTER = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SSL3_MASTER);
CALG_SCHANNEL_MASTER_HASH = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SCHANNEL_MASTER_HASH);
CALG_SCHANNEL_MAC_KEY = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SCHANNEL_MAC_KEY);
CALG_SCHANNEL_ENC_KEY = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SCHANNEL_ENC_KEY);
CALG_PCT1_MASTER = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_PCT1_MASTER);
CALG_SSL2_MASTER = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_SSL2_MASTER);
CALG_TLS1_MASTER = (ALG_CLASS_MSG_ENCRYPT or ALG_TYPE_SECURECHANNEL or ALG_SID_TLS1_MASTER);
CALG_RC5 = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or ALG_SID_RC5);
CALG_HMAC = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_HMAC);
type
PVTableProvStruc = ^VTableProvStruc;
VTableProvStruc = record
Version: DWORD;
FuncVerifyImage: TFarProc;
FuncReturnhWnd: TFarProc;
dwProvType: DWORD;
pbContextInfo: PBYTE;
cbContextInfo: DWORD;
end;
//type HCRYPTPROV = ULONG;
//type HCRYPTKEY = ULONG;
//type HCRYPTHASH = ULONG;
const
// dwFlags definitions for CryptAcquireContext
CRYPT_VERIFYCONTEXT = $F0000000;
CRYPT_NEWKEYSET = $00000008;
CRYPT_DELETEKEYSET = $00000010;
CRYPT_MACHINE_KEYSET = $00000020;
// dwFlag definitions for CryptGenKey
CRYPT_EXPORTABLE = $00000001;
CRYPT_USER_PROTECTED = $00000002;
CRYPT_CREATE_SALT = $00000004;
CRYPT_UPDATE_KEY = $00000008;
CRYPT_NO_SALT = $00000010;
CRYPT_PREGEN = $00000040;
CRYPT_RECIPIENT = $00000010;
CRYPT_INITIATOR = $00000040;
CRYPT_ONLINE = $00000080;
CRYPT_SF = $00000100;
CRYPT_CREATE_IV = $00000200;
CRYPT_KEK = $00000400;
CRYPT_DATA_KEY = $00000800;
// dwFlags definitions for CryptDeriveKey
CRYPT_SERVER = $00000400;
KEY_LENGTH_MASK = $FFFF0000;
// dwFlag definitions for CryptExportKey
CRYPT_Y_ONLY = $00000001;
CRYPT_SSL2_SLUMMING = $00000002;
// dwFlags definitions for CryptHashSessionKey
CRYPT_LITTLE_ENDIAN = $00000001;
// dwFlag definitions for CryptSetProviderEx and CryptGetDefaultProvider
CRYPT_MACHINE_DEFAULT = $00000001;
CRYPT_USER_DEFAULT = $00000002;
CRYPT_DELETE_DEFAULT = $00000004;
// exported key blob definitions
SIMPLEBLOB = $1;
PUBLICKEYBLOB = $6;
PRIVATEKEYBLOB = $7;
PLAINTEXTKEYBLOB = $8;
AT_KEYEXCHANGE = 1;
AT_SIGNATURE = 2;
CRYPT_USERDATA = 1;
// dwParam
KP_IV = 1; // Initialization vector
KP_SALT = 2; // Salt value
KP_PADDING = 3; // Padding values
KP_MODE = 4; // Mode of the cipher
KP_MODE_BITS = 5; // Number of bits to feedback
KP_PERMISSIONS = 6; // Key permissions DWORD
KP_ALGID = 7; // Key algorithm
KP_BLOCKLEN = 8; // Block size of the cipher
KP_KEYLEN = 9; // Length of key in bits
KP_SALT_EX = 10; // Length of salt in bytes
KP_P = 11; // DSS/Diffie-Hellman P value
KP_G = 12; // DSS/Diffie-Hellman G value
KP_Q = 13; // DSS Q value
KP_X = 14; // Diffie-Hellman X value
KP_Y = 15; // Y value
KP_RA = 16; // Fortezza RA value
KP_RB = 17; // Fortezza RB value
KP_INFO = 18; // for putting information into an RSA envelope
KP_EFFECTIVE_KEYLEN = 19; // setting and getting RC2 effective key length
KP_SCHANNEL_ALG = 20; // for setting the Secure Channel algorithms
KP_CLIENT_RANDOM = 21; // for setting the Secure Channel client random data
KP_SERVER_RANDOM = 22; // for setting the Secure Channel server random data
KP_RP = 23;
KP_PRECOMP_MD5 = 24;
KP_PRECOMP_SHA = 25;
KP_CERTIFICATE = 26; // for setting Secure Channel certificate data (PCT1)
KP_CLEAR_KEY = 27; // for setting Secure Channel clear key data (PCT1)
KP_PUB_EX_LEN = 28;
KP_PUB_EX_VAL = 29;
// KP_PADDING
PKCS5_PADDING = 1; {PKCS 5 (sec 6.2) padding method}
RANDOM_PADDING = 2;
ZERO_PADDING = 3;
// KP_MODE
CRYPT_MODE_CBC = 1; // Cipher block chaining
CRYPT_MODE_ECB = 2; // Electronic code book
CRYPT_MODE_OFB = 3; // Output feedback mode
CRYPT_MODE_CFB = 4; // Cipher feedback mode
CRYPT_MODE_CTS = 5; // Ciphertext stealing mode
// KP_PERMISSIONS
CRYPT_ENCRYPT = $0001; // Allow encryption
CRYPT_DECRYPT = $0002; // Allow decryption
CRYPT_EXPORT = $0004; // Allow key to be exported
CRYPT_READ = $0008; // Allow parameters to be read
CRYPT_WRITE = $0010; // Allow parameters to be set
CRYPT_MAC = $0020; // Allow MACs to be used with key
CRYPT_EXPORT_KEY = $0040; // Allow key to be used for exporting keys
CRYPT_IMPORT_KEY = $0080; // Allow key to be used for importing keys
HP_ALGID = $0001; // Hash algorithm
HP_HASHVAL = $0002; // Hash value
HP_HASHSIZE = $0004; // Hash value size
HP_HMAC_INFO = $0005; // information for creating an HMAC
CRYPT_FAILED = FALSE;
CRYPT_SUCCEED = TRUE;
function RCRYPT_SUCCEEDED(rt: BOOL): BOOL;
function RCRYPT_FAILED(rt: BOOL): BOOL;
const
// CryptGetProvParam
PP_ENUMALGS = 1;
PP_ENUMCONTAINERS = 2;
PP_IMPTYPE = 3;
PP_NAME = 4;
PP_VERSION = 5;
PP_CONTAINER = 6;
PP_CHANGE_PASSWORD = 7;
PP_KEYSET_SEC_DESCR = 8; // get/set security descriptor of keyset
PP_CERTCHAIN = 9; // for retrieving certificates from tokens
PP_KEY_TYPE_SUBTYPE = 10;
PP_PROVTYPE = 16;
PP_KEYSTORAGE = 17;
PP_APPLI_CERT = 18;
PP_SYM_KEYSIZE = 19;
PP_SESSION_KEYSIZE = 20;
PP_UI_PROMPT = 21;
PP_ENUMALGS_EX = 22;
CRYPT_FIRST = 1;
CRYPT_NEXT = 2;
CRYPT_IMPL_HARDWARE = 1;
CRYPT_IMPL_SOFTWARE = 2;
CRYPT_IMPL_MIXED = 3;
CRYPT_IMPL_UNKNOWN = 4;
// key storage flags
CRYPT_SEC_DESCR = $00000001;
CRYPT_PSTORE = $00000002;
CRYPT_UI_PROMPT = $00000004;
// protocol flags
CRYPT_FLAG_PCT1 = $0001;
CRYPT_FLAG_SSL2 = $0002;
CRYPT_FLAG_SSL3 = $0004;
CRYPT_FLAG_TLS1 = $0008;
// CryptSetProvParam
PP_CLIENT_HWND = 1;
PP_CONTEXT_INFO = 11;
PP_KEYEXCHANGE_KEYSIZE = 12;
PP_SIGNATURE_KEYSIZE = 13;
PP_KEYEXCHANGE_ALG = 14;
PP_SIGNATURE_ALG = 15;
PP_DELETEKEY = 24;
PROV_RSA_FULL = 1;
PROV_RSA_SIG = 2;
PROV_DSS = 3;
PROV_FORTEZZA = 4;
PROV_MS_EXCHANGE = 5;
PROV_SSL = 6;
PROV_RSA_SCHANNEL = 12;
PROV_DSS_DH = 13;
PROV_EC_ECDSA_SIG = 14;
PROV_EC_ECNRA_SIG = 15;
PROV_EC_ECDSA_FULL = 16;
PROV_EC_ECNRA_FULL = 17;
PROV_SPYRUS_LYNKS = 20;
// STT defined Providers
PROV_STT_MER = 7;
PROV_STT_ACQ = 8;
PROV_STT_BRND = 9;
PROV_STT_ROOT = 10;
PROV_STT_ISS = 11;
// Provider friendly names
MS_DEF_PROV_A = 'Microsoft Base Cryptographic Provider v1.0';
{$IFNDEF VER90}
MS_DEF_PROV_W = WideString('Microsoft Base Cryptographic Provider v1.0');
{$ELSE}
MS_DEF_PROV_W = ('Microsoft Base Cryptographic Provider v1.0');
{$ENDIF}
{$IFDEF UNICODE}
MS_DEF_PROV = MS_DEF_PROV_W;
{$ELSE}
MS_DEF_PROV = MS_DEF_PROV_A;
{$ENDIF}
MS_ENHANCED_PROV_A = 'Microsoft Enhanced Cryptographic Provider v1.0';
{$IFNDEF VER90}
MS_ENHANCED_PROV_W = WideString('Microsoft Enhanced Cryptographic Provider v1.0');
{$ELSE}
MS_ENHANCED_PROV_W = ('Microsoft Enhanced Cryptographic Provider v1.0');
{$ENDIF}
{$IFDEF UNICODE}
MS_ENHANCED_PROV = MS_ENHANCED_PROV_W;
{$ELSE}
MS_ENHANCED_PROV = MS_ENHANCED_PROV_A;
{$ENDIF}
MS_DEF_RSA_SIG_PROV_A = 'Microsoft RSA Signature Cryptographic Provider';
{$IFNDEF VER90}
MS_DEF_RSA_SIG_PROV_W = WideString('Microsoft RSA Signature Cryptographic Provider');
{$ELSE}
MS_DEF_RSA_SIG_PROV_W = ('Microsoft RSA Signature Cryptographic Provider');
{$ENDIF}
{$IFDEF UNICODE}
MS_DEF_RSA_SIG_PROV = MS_DEF_RSA_SIG_PROV_W;
{$ELSE}
MS_DEF_RSA_SIG_PROV = MS_DEF_RSA_SIG_PROV_A;
{$ENDIF}
MS_DEF_RSA_SCHANNEL_PROV_A = 'Microsoft Base RSA SChannel Cryptographic Provider';
{$IFNDEF VER90}
MS_DEF_RSA_SCHANNEL_PROV_W = WideString('Microsoft Base RSA SChannel Cryptographic Provider');
{$ELSE}
MS_DEF_RSA_SCHANNEL_PROV_W = ('Microsoft Base RSA SChannel Cryptographic Provider');
{$ENDIF}
{$IFDEF UNICODE}
MS_DEF_RSA_SCHANNEL_PROV = MS_DEF_RSA_SCHANNEL_PROV_W;
{$ELSE}
MS_DEF_RSA_SCHANNEL_PROV = MS_DEF_RSA_SCHANNEL_PROV_A;
{$ENDIF}
MS_ENHANCED_RSA_SCHANNEL_PROV_A = 'Microsoft Enhanced RSA SChannel Cryptographic Provider';
{$IFNDEF VER90}
MS_ENHANCED_RSA_SCHANNEL_PROV_W = WideString('Microsoft Enhanced RSA SChannel Cryptographic Provider');
{$ELSE}
MS_ENHANCED_RSA_SCHANNEL_PROV_W = ('Microsoft Enhanced RSA SChannel Cryptographic Provider');
{$ENDIF}
{$IFDEF UNICODE}
MS_ENHANCED_RSA_SCHANNEL_PROV = MS_ENHANCED_RSA_SCHANNEL_PROV_W;
{$ELSE}
MS_ENHANCED_RSA_SCHANNEL_PROV = MS_ENHANCED_RSA_SCHANNEL_PROV_A;
{$ENDIF}
MS_DEF_DSS_PROV_A = 'Microsoft Base DSS Cryptographic Provider';
{$IFNDEF VER90}
MS_DEF_DSS_PROV_W = WideString('Microsoft Base DSS Cryptographic Provider');
{$ELSE}
MS_DEF_DSS_PROV_W = ('Microsoft Base DSS Cryptographic Provider');
{$ENDIF}
{$IFDEF UNICODE}
MS_DEF_DSS_PROV = MS_DEF_DSS_PROV_W;
{$ELSE}
MS_DEF_DSS_PROV = MS_DEF_DSS_PROV_A;
{$ENDIF}
MS_DEF_DSS_DH_PROV_A = 'Microsoft Base DSS and Diffie-Hellman Cryptographic Provider';
{$IFNDEF VER90}
MS_DEF_DSS_DH_PROV_W = WideString('Microsoft Base DSS and Diffie-Hellman Cryptographic Provider');
{$ELSE}
MS_DEF_DSS_DH_PROV_W = ('Microsoft Base DSS and Diffie-Hellman Cryptographic Provider');
{$ENDIF}
{$IFDEF UNICODE}
MS_DEF_DSS_DH_PROV = MS_DEF_DSS_DH_PROV_W;
{$ELSE}
MS_DEF_DSS_DH_PROV = MS_DEF_DSS_DH_PROV_A;
{$ENDIF}
MAXUIDLEN = 64;
CUR_BLOB_VERSION = 2;
{structure for use with CryptSetHashParam with CALG_HMAC}
type
PHMAC_INFO = ^HMAC_INFO;
HMAC_INFO = record
HashAlgid: ALG_ID;
pbInnerString: PBYTE;
cbInnerString: DWORD;
pbOuterString: PBYTE;
cbOuterString: DWORD;
end;
// structure for use with CryptSetHashParam with CALG_HMAC
type
PSCHANNEL_ALG = ^SCHANNEL_ALG;
SCHANNEL_ALG = record
dwUse: DWORD;
Algid: ALG_ID;
cBits: DWORD;
end;
// uses of algortihms for SCHANNEL_ALG structure
const
SCHANNEL_MAC_KEY = $00000000;
SCHANNEL_ENC_KEY = $00000001;
type
PPROV_ENUMALGS = ^PROV_ENUMALGS;
PROV_ENUMALGS = record
aiAlgid: ALG_ID;
dwBitLen: DWORD;
dwNameLen: DWORD;
szName: array[0..20 - 1] of Char;
end;
type
PPROV_ENUMALGS_EX = ^PROV_ENUMALGS_EX;
PROV_ENUMALGS_EX = record
aiAlgid: ALG_ID;
dwDefaultLen: DWORD;
dwMinLen: DWORD;
dwMaxLen: DWORD;
dwProtocols: DWORD;
dwNameLen: DWORD;
szName: array[0..20 - 1] of Char;
dwLongNameLen: DWORD;
szLongName: array[0..40 - 1] of Char;
end;
type
PPUBLICKEYSTRUC = ^PUBLICKEYSTRUC;
PUBLICKEYSTRUC = record
bType: BYTE;
bVersion: BYTE;
reserved: Word;
aiKeyAlg: ALG_ID;
end;
type
BLOBHEADER = PUBLICKEYSTRUC;
PBLOBHEADER = ^BLOBHEADER;
type
PRSAPUBKEY = ^RSAPUBKEY;
RSAPUBKEY = record
magic: DWORD; // Has to be RSA1
bitlen: DWORD; // # of bits in modulus
pubexp: DWORD; // public exponent
// Modulus data follows
end;
type
PPUBKEY = ^PUBKEY;
PUBKEY = record
magic: DWORD;
bitlen: DWORD; // # of bits in modulus
end;
type
DHPUBKEY = PUBKEY;
DSSPUBKEY = PUBKEY;
KEAPUBKEY = PUBKEY;
TEKPUBKEY = PUBKEY;
type
PDSSSEED = ^DSSSEED;
DSSSEED = record
counter: DWORD;
seed: array[0..20 - 1] of BYTE;
end;
type
PKEY_TYPE_SUBTYPE = ^KEY_TYPE_SUBTYPE;
KEY_TYPE_SUBTYPE = record
dwKeySpec: DWORD;
Type_: TGUID; {conflict with base Delphi type: original name 'Type'}
Subtype: TGUID;
end;
type
HCRYPTPROV = ULONG;
PHCRYPTPROV = ^HCRYPTPROV;
HCRYPTKEY = ULONG;
PHCRYPTKEY = ^HCRYPTKEY;
HCRYPTHASH = ULONG;
PHCRYPTHASH = ^HCRYPTHASH;
function CryptAcquireContextA(phProv: PHCRYPTPROV;
pszContainer: PAnsiChar;
pszProvider: PAnsiChar;
dwProvType: DWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptAcquireContext(phProv: PHCRYPTPROV;
pszContainer: LPAWSTR;
pszProvider: LPAWSTR;
dwProvType: DWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptAcquireContextW(phProv: PHCRYPTPROV;
pszContainer: PWideChar;
pszProvider: PWideChar;
dwProvType: DWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptReleaseContext(hProv: HCRYPTPROV;
dwFlags: DWORD): BOOL; stdcall;
function CryptGenKey(hProv: HCRYPTPROV;
Algid: ALG_ID;
dwFlags: DWORD;
phKey: PHCRYPTKEY): BOOL; stdcall;
function CryptDeriveKey(hProv: HCRYPTPROV;
Algid: ALG_ID;
hBaseData: HCRYPTHASH;
dwFlags: DWORD;
phKey: PHCRYPTKEY): BOOL; stdcall;
function CryptDestroyKey(hKey: HCRYPTKEY): BOOL; stdcall;
function CryptSetKeyParam(hKey: HCRYPTKEY;
dwParam: DWORD;
pbData: PBYTE;
dwFlags: DWORD): BOOL; stdcall;
function CryptGetKeyParam(hKey: HCRYPTKEY;
dwParam: DWORD;
pbData: PBYTE;
pdwDataLen: PDWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptSetHashParam(hHash: HCRYPTHASH;
dwParam: DWORD;
pbData: PBYTE;
dwFlags: DWORD): BOOL; stdcall;
function CryptGetHashParam(hHash: HCRYPTHASH;
dwParam: DWORD;
pbData: PBYTE;
pdwDataLen: PDWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptSetProvParam(hProv: HCRYPTPROV;
dwParam: DWORD;
pbData: PBYTE;
dwFlags: DWORD): BOOL; stdcall;
function CryptGetProvParam(hProv: HCRYPTPROV;
dwParam: DWORD;
pbData: PBYTE;
pdwDataLen: PDWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptGenRandom(hProv: HCRYPTPROV;
dwLen: DWORD;
pbBuffer: PBYTE): BOOL; stdcall;
function CryptGetUserKey(hProv: HCRYPTPROV;
dwKeySpec: DWORD;
phUserKey: PHCRYPTKEY): BOOL; stdcall;
function CryptExportKey(hKey: HCRYPTKEY;
hExpKey: HCRYPTKEY;
dwBlobType: DWORD;
dwFlags: DWORD;
pbData: PBYTE;
pdwDataLen: PDWORD): BOOL; stdcall;
function CryptImportKey(hProv: HCRYPTPROV;
pbData: PBYTE;
dwDataLen: DWORD;
hPubKey: HCRYPTKEY;
dwFlags: DWORD;
phKey: PHCRYPTKEY): BOOL; stdcall;
function CryptEncrypt(hKey: HCRYPTKEY;
hHash: HCRYPTHASH;
Final: BOOL;
dwFlags: DWORD;
pbData: PBYTE;
pdwDataLen: PDWORD;
dwBufLen: DWORD): BOOL; stdcall;
function CryptDecrypt(hKey: HCRYPTKEY;
hHash: HCRYPTHASH;
Final: BOOL;
dwFlags: DWORD;
pbData: PBYTE;
pdwDataLen: PDWORD): BOOL; stdcall;
function CryptCreateHash(hProv: HCRYPTPROV;
Algid: ALG_ID;
hKey: HCRYPTKEY;
dwFlags: DWORD;
phHash: PHCRYPTHASH): BOOL; stdcall;
function CryptHashData(hHash: HCRYPTHASH;
const pbData: PBYTE;
dwDataLen: DWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptHashSessionKey(hHash: HCRYPTHASH;
hKey: HCRYPTKEY;
dwFlags: DWORD): BOOL; stdcall;
function CryptDestroyHash(hHash: HCRYPTHASH): BOOL; stdcall;
function CryptSignHashA(hHash: HCRYPTHASH;
dwKeySpec: DWORD;
sDescription: PAnsiChar;
dwFlags: DWORD;
pbSignature: PBYTE;
pdwSigLen: PDWORD): BOOL; stdcall;
function CryptSignHash(hHash: HCRYPTHASH;
dwKeySpec: DWORD;
sDescription: LPAWSTR;
dwFlags: DWORD;
pbSignature: PBYTE;
pdwSigLen: PDWORD): BOOL; stdcall;
function CryptSignHashW(hHash: HCRYPTHASH;
dwKeySpec: DWORD;
sDescription: PWideChar;
dwFlags: DWORD;
pbSignature: PBYTE;
pdwSigLen: PDWORD): BOOL; stdcall;
function CryptSignHashU(hHash: HCRYPTHASH;
dwKeySpec: DWORD;
sDescription: PWideChar;
dwFlags: DWORD;
pbSignature: PBYTE;
pdwSigLen: PDWORD): BOOL; stdcall;
function CryptVerifySignatureA(hHash: HCRYPTHASH;
const pbSignature: PBYTE;
dwSigLen: DWORD;
hPubKey: HCRYPTKEY;
sDescription: PAnsiChar;
dwFlags: DWORD): BOOL; stdcall;
function CryptVerifySignature(hHash: HCRYPTHASH;
const pbSignature: PBYTE;
dwSigLen: DWORD;
hPubKey: HCRYPTKEY;
sDescription: LPAWSTR;
dwFlags: DWORD): BOOL; stdcall;
function CryptVerifySignatureW(hHash: HCRYPTHASH;
const pbSignature: PBYTE;
dwSigLen: DWORD;
hPubKey: HCRYPTKEY;
sDescription: PWideChar;
dwFlags: DWORD): BOOL; stdcall;
function CryptSetProviderA(pszProvName: PAnsiChar;
dwProvType: DWORD): BOOL; stdcall;
function CryptSetProvider(pszProvName: LPAWSTR;
dwProvType: DWORD): BOOL; stdcall;
function CryptSetProviderW(pszProvName: PWideChar;
dwProvType: DWORD): BOOL; stdcall;
function CryptSetProviderU(pszProvName: PWideChar;
dwProvType: DWORD): BOOL; stdcall;
{$IFDEF NT5}
function CryptSetProviderExA(pszProvName: LPCSTR;
dwProvType: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptSetProviderExW(pszProvName: LPCWSTR;
dwProvType: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptSetProviderEx(pszProvName: LPAWSTR;
dwProvType: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptGetDefaultProviderA(dwProvType: DWORD;
pdwReserved: DWORD;
dwFlags: DWORD;
pszProvName: LPSTR;
pcbProvName: PDWORD): BOOL; stdcall;
function CryptGetDefaultProviderW(dwProvType: DWORD;
pdwReserved: DWORD;
dwFlags: DWORD;
pszProvName: LPWSTR;
pcbProvName: PDWORD): BOOL; stdcall;
function CryptGetDefaultProvider(dwProvType: DWORD;
pdwReserved: DWORD;
dwFlags: DWORD;
pszProvName: LPAWSTR;
pcbProvName: PDWORD): BOOL; stdcall;
function CryptEnumProviderTypesA(dwIndex: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD;
pdwProvType: PDWORD;
pszTypeName: LPSTR;
pcbTypeName: PDWORD): BOOL; stdcall;
function CryptEnumProviderTypesW(dwIndex: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD;
pdwProvType: PDWORD;
pszTypeName: LPWSTR;
pcbTypeName: PDWORD): BOOL; stdcall;
function CryptEnumProviderTypes(dwIndex: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD;
pdwProvType: PDWORD;
pszTypeName: LPAWSTR;
pcbTypeName: PDWORD): BOOL; stdcall;
function CryptEnumProvidersA(dwIndex: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD;
pdwProvType: PDWORD;
pszProvName: LPSTR;
pcbProvName: PDWORD): BOOL; stdcall;
function CryptEnumProvidersW(dwIndex: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD;
pdwProvType: PDWORD;
pszProvName: LPWSTR;
pcbProvName: PDWORD): BOOL; stdcall;
function CryptEnumProviders(dwIndex: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD;
pdwProvType: PDWORD;
pszProvName: LPAWSTR;
pcbProvName: PDWORD): BOOL; stdcall;
function CryptContextAddRef(hProv: HCRYPTPROV;
pdwReserved: PDWORD;
dwFlags: DWORD): BOOL; stdcall;
function CryptDuplicateKey(hKey: HCRYPTKEY;
pdwReserved: PDWORD;
dwFlags: DWORD;
phKey: PHCRYPTKEY): BOOL; stdcall;
function CryptDuplicateHash(hHash: HCRYPTHASH;
pdwReserved: PDWORD;
dwFlags: DWORD;
phHash: PHCRYPTHASH): BOOL; stdcall;
{$ENDIF NT5}
function CryptEnumProvidersU(dwIndex: DWORD;
pdwReserved: PDWORD;
dwFlags: DWORD;
pdwProvType: PDWORD;
pszProvName: LPWSTR;
pcbProvName: PDWORD): BOOL; stdcall;
//+-------------------------------------------------------------------------
// CRYPTOAPI BLOB definitions
//--------------------------------------------------------------------------
type
PCRYPTOAPI_BLOB = ^CRYPTOAPI_BLOB;
CRYPTOAPI_BLOB = record
cbData: DWORD;
pbData: PBYTE;
end;
type
CRYPT_INTEGER_BLOB = CRYPTOAPI_BLOB;
PCRYPT_INTEGER_BLOB = ^CRYPT_INTEGER_BLOB;
CRYPT_UINT_BLOB = CRYPTOAPI_BLOB;
PCRYPT_UINT_BLOB = ^CRYPT_UINT_BLOB;
CRYPT_OBJID_BLOB = CRYPTOAPI_BLOB;
PCRYPT_OBJID_BLOB = ^CRYPT_OBJID_BLOB;
CERT_NAME_BLOB = CRYPTOAPI_BLOB;
PCERT_NAME_BLOB = ^CERT_NAME_BLOB;
CERT_RDN_VALUE_BLOB = CRYPTOAPI_BLOB;
PCERT_RDN_VALUE_BLOB = ^CERT_RDN_VALUE_BLOB;
CERT_BLOB = CRYPTOAPI_BLOB;
PCERT_BLOB = ^CERT_BLOB;
CRL_BLOB = CRYPTOAPI_BLOB;
PCRL_BLOB = ^CRL_BLOB;
DATA_BLOB = CRYPTOAPI_BLOB;
PDATA_BLOB = ^DATA_BLOB; // JEFFJEFF temporary (too generic)
CRYPT_DATA_BLOB = CRYPTOAPI_BLOB;
PCRYPT_DATA_BLOB = ^CRYPT_DATA_BLOB;
CRYPT_HASH_BLOB = CRYPTOAPI_BLOB;
PCRYPT_HASH_BLOB = ^CRYPT_HASH_BLOB;
CRYPT_DIGEST_BLOB = CRYPTOAPI_BLOB;
PCRYPT_DIGEST_BLOB = ^CRYPT_DIGEST_BLOB;
CRYPT_DER_BLOB = CRYPTOAPI_BLOB;
PCRYPT_DER_BLOB = ^CRYPT_DER_BLOB;
CRYPT_ATTR_BLOB = CRYPTOAPI_BLOB;
PCRYPT_ATTR_BLOB = ^CRYPT_ATTR_BLOB;
//+-------------------------------------------------------------------------
// In a CRYPT_BIT_BLOB the last byte may contain 0-7 unused bits. Therefore, the
// overall bit length is cbData * 8 - cUnusedBits.
//--------------------------------------------------------------------------
type
PCRYPT_BIT_BLOB = ^CRYPT_BIT_BLOB;
CRYPT_BIT_BLOB = record
cbData: DWORD;
pbData: PBYTE;
cUnusedBits: DWORD;
end;
//+-------------------------------------------------------------------------
// Type used for any algorithm
//
// Where the Parameters CRYPT_OBJID_BLOB is in its encoded representation. For most
// algorithm types, the Parameters CRYPT_OBJID_BLOB is NULL (Parameters.cbData = 0).
//--------------------------------------------------------------------------
type
PCRYPT_ALGORITHM_IDENTIFIER = ^CRYPT_ALGORITHM_IDENTIFIER;
CRYPT_ALGORITHM_IDENTIFIER = record
pszObjId: LPSTR;
Parameters: CRYPT_OBJID_BLOB;
end;
// Following are the definitions of various algorithm object identifiers
// RSA
const
szOID_RSA = '1.2.840.113549';
szOID_PKCS = '1.2.840.113549.1';
szOID_RSA_HASH = '1.2.840.113549.2';
szOID_RSA_ENCRYPT = '1.2.840.113549.3';
szOID_PKCS_1 = '1.2.840.113549.1.1';
szOID_PKCS_2 = '1.2.840.113549.1.2';
szOID_PKCS_3 = '1.2.840.113549.1.3';
szOID_PKCS_4 = '1.2.840.113549.1.4';
szOID_PKCS_5 = '1.2.840.113549.1.5';
szOID_PKCS_6 = '1.2.840.113549.1.6';
szOID_PKCS_7 = '1.2.840.113549.1.7';
szOID_PKCS_8 = '1.2.840.113549.1.8';
szOID_PKCS_9 = '1.2.840.113549.1.9';
szOID_PKCS_10 = '1.2.840.113549.1.10';
szOID_RSA_RSA = '1.2.840.113549.1.1.1';
szOID_RSA_MD2RSA = '1.2.840.113549.1.1.2';
szOID_RSA_MD4RSA = '1.2.840.113549.1.1.3';
szOID_RSA_MD5RSA = '1.2.840.113549.1.1.4';
szOID_RSA_SHA1RSA = '1.2.840.113549.1.1.5';
szOID_RSA_SETOAEP_RSA = '1.2.840.113549.1.1.6';
szOID_RSA_data = '1.2.840.113549.1.7.1';
szOID_RSA_signedData = '1.2.840.113549.1.7.2';
szOID_RSA_envelopedData = '1.2.840.113549.1.7.3';
szOID_RSA_signEnvData = '1.2.840.113549.1.7.4';
szOID_RSA_digestedData = '1.2.840.113549.1.7.5';
szOID_RSA_hashedData = '1.2.840.113549.1.7.5';
szOID_RSA_encryptedData = '1.2.840.113549.1.7.6';
szOID_RSA_emailAddr = '1.2.840.113549.1.9.1';
szOID_RSA_unstructName = '1.2.840.113549.1.9.2';
szOID_RSA_contentType = '1.2.840.113549.1.9.3';
szOID_RSA_messageDigest = '1.2.840.113549.1.9.4';
szOID_RSA_signingTime = '1.2.840.113549.1.9.5';
szOID_RSA_counterSign = '1.2.840.113549.1.9.6';
szOID_RSA_challengePwd = '1.2.840.113549.1.9.7';
szOID_RSA_unstructAddr = '1.2.840.113549.1.9.8';
szOID_RSA_extCertAttrs = '1.2.840.113549.1.9.9';
szOID_RSA_SMIMECapabilities = '1.2.840.113549.1.9.15';
szOID_RSA_preferSignedData = '1.2.840.113549.1.9.15.1';
szOID_RSA_MD2 = '1.2.840.113549.2.2';
szOID_RSA_MD4 = '1.2.840.113549.2.4';
szOID_RSA_MD5 = '1.2.840.113549.2.5';
szOID_RSA_RC2CBC = '1.2.840.113549.3.2';
szOID_RSA_RC4 = '1.2.840.113549.3.4';
szOID_RSA_DES_EDE3_CBC = '1.2.840.113549.3.7';
szOID_RSA_RC5_CBCPad = '1.2.840.113549.3.9';
// ITU-T UsefulDefinitions
szOID_DS = '2.5';
szOID_DSALG = '2.5.8';
szOID_DSALG_CRPT = '2.5.8.1';
szOID_DSALG_HASH = '2.5.8.2';
szOID_DSALG_SIGN = '2.5.8.3';
szOID_DSALG_RSA = '2.5.8.1.1';
// NIST OSE Implementors' Workshop (OIW)
// http://nemo.ncsl.nist.gov/oiw/agreements/stable/OSI/12s_9506.w51
// http://nemo.ncsl.nist.gov/oiw/agreements/working/OSI/12w_9503.w51
szOID_OIW = '1.3.14';
// NIST OSE Implementors' Workshop (OIW) Security SIG algorithm identifiers
szOID_OIWSEC = '1.3.14.3.2';
szOID_OIWSEC_md4RSA = '1.3.14.3.2.2';
szOID_OIWSEC_md5RSA = '1.3.14.3.2.3';
szOID_OIWSEC_md4RSA2 = '1.3.14.3.2.4';
szOID_OIWSEC_desECB = '1.3.14.3.2.6';
szOID_OIWSEC_desCBC = '1.3.14.3.2.7';
szOID_OIWSEC_desOFB = '1.3.14.3.2.8';
szOID_OIWSEC_desCFB = '1.3.14.3.2.9';
szOID_OIWSEC_desMAC = '1.3.14.3.2.10';
szOID_OIWSEC_rsaSign = '1.3.14.3.2.11';
szOID_OIWSEC_dsa = '1.3.14.3.2.12';
szOID_OIWSEC_shaDSA = '1.3.14.3.2.13';
szOID_OIWSEC_mdc2RSA = '1.3.14.3.2.14';
szOID_OIWSEC_shaRSA = '1.3.14.3.2.15';
szOID_OIWSEC_dhCommMod = '1.3.14.3.2.16';
szOID_OIWSEC_desEDE = '1.3.14.3.2.17';
szOID_OIWSEC_sha = '1.3.14.3.2.18';
szOID_OIWSEC_mdc2 = '1.3.14.3.2.19';
szOID_OIWSEC_dsaComm = '1.3.14.3.2.20';
szOID_OIWSEC_dsaCommSHA = '1.3.14.3.2.21';
szOID_OIWSEC_rsaXchg = '1.3.14.3.2.22';
szOID_OIWSEC_keyHashSeal = '1.3.14.3.2.23';
szOID_OIWSEC_md2RSASign = '1.3.14.3.2.24';
szOID_OIWSEC_md5RSASign = '1.3.14.3.2.25';
szOID_OIWSEC_sha1 = '1.3.14.3.2.26';
szOID_OIWSEC_dsaSHA1 = '1.3.14.3.2.27';
szOID_OIWSEC_dsaCommSHA1 = '1.3.14.3.2.28';
szOID_OIWSEC_sha1RSASign = '1.3.14.3.2.29';
// NIST OSE Implementors' Workshop (OIW) Directory SIG algorithm identifiers
szOID_OIWDIR = '1.3.14.7.2';
szOID_OIWDIR_CRPT = '1.3.14.7.2.1';
szOID_OIWDIR_HASH = '1.3.14.7.2.2';
szOID_OIWDIR_SIGN = '1.3.14.7.2.3';
szOID_OIWDIR_md2 = '1.3.14.7.2.2.1';
szOID_OIWDIR_md2RSA = '1.3.14.7.2.3.1';
// INFOSEC Algorithms
// joint-iso-ccitt(2) country(16) us(840) organization(1) us-government(101) dod(2) id-infosec(1)
szOID_INFOSEC = '2.16.840.1.101.2.1';
szOID_INFOSEC_sdnsSignature = '2.16.840.1.101.2.1.1.1';
szOID_INFOSEC_mosaicSignature = '2.16.840.1.101.2.1.1.2';
szOID_INFOSEC_sdnsConfidentiality = '2.16.840.1.101.2.1.1.3';
szOID_INFOSEC_mosaicConfidentiality = '2.16.840.1.101.2.1.1.4';
szOID_INFOSEC_sdnsIntegrity = '2.16.840.1.101.2.1.1.5';
szOID_INFOSEC_mosaicIntegrity = '2.16.840.1.101.2.1.1.6';
szOID_INFOSEC_sdnsTokenProtection = '2.16.840.1.101.2.1.1.7';
szOID_INFOSEC_mosaicTokenProtection = '2.16.840.1.101.2.1.1.8';
szOID_INFOSEC_sdnsKeyManagement = '2.16.840.1.101.2.1.1.9';
szOID_INFOSEC_mosaicKeyManagement = '2.16.840.1.101.2.1.1.10';
szOID_INFOSEC_sdnsKMandSig = '2.16.840.1.101.2.1.1.11';
szOID_INFOSEC_mosaicKMandSig = '2.16.840.1.101.2.1.1.12';
szOID_INFOSEC_SuiteASignature = '2.16.840.1.101.2.1.1.13';
szOID_INFOSEC_SuiteAConfidentiality = '2.16.840.1.101.2.1.1.14';
szOID_INFOSEC_SuiteAIntegrity = '2.16.840.1.101.2.1.1.15';
szOID_INFOSEC_SuiteATokenProtection = '2.16.840.1.101.2.1.1.16';
szOID_INFOSEC_SuiteAKeyManagement = '2.16.840.1.101.2.1.1.17';
szOID_INFOSEC_SuiteAKMandSig = '2.16.840.1.101.2.1.1.18';
szOID_INFOSEC_mosaicUpdatedSig = '2.16.840.1.101.2.1.1.19';
szOID_INFOSEC_mosaicKMandUpdSig = '2.16.840.1.101.2.1.1.20';
szOID_INFOSEC_mosaicUpdatedInteg = '2.16.840.1.101.2.1.1.21';
type
PCRYPT_OBJID_TABLE = ^CRYPT_OBJID_TABLE;
CRYPT_OBJID_TABLE = record
dwAlgId: DWORD;
pszObjId: LPCSTR;
end;
//+-------------------------------------------------------------------------
// PKCS #1 HashInfo (DigestInfo)
//--------------------------------------------------------------------------
type
PCRYPT_HASH_INFO = ^CRYPT_HASH_INFO;
CRYPT_HASH_INFO = record
HashAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
Hash: CRYPT_HASH_BLOB;
end;
//+-------------------------------------------------------------------------
// Type used for an extension to an encoded content
//
// Where the Value's CRYPT_OBJID_BLOB is in its encoded representation.
//--------------------------------------------------------------------------
type
PCERT_EXTENSION = ^CERT_EXTENSION;
CERT_EXTENSION = record
pszObjId: LPSTR;
fCritical: BOOL;
Value: CRYPT_OBJID_BLOB;
end;
//+-------------------------------------------------------------------------
// AttributeTypeValue
//
// Where the Value's CRYPT_OBJID_BLOB is in its encoded representation.
//--------------------------------------------------------------------------
type
PCRYPT_ATTRIBUTE_TYPE_VALUE = ^CRYPT_ATTRIBUTE_TYPE_VALUE;
CRYPT_ATTRIBUTE_TYPE_VALUE = record
pszObjId: LPSTR;
Value: CRYPT_OBJID_BLOB;
end;
//+-------------------------------------------------------------------------
// Attributes
//
// Where the Value's PATTR_BLOBs are in their encoded representation.
//--------------------------------------------------------------------------
type
PCRYPT_ATTRIBUTE = ^CRYPT_ATTRIBUTE;
CRYPT_ATTRIBUTE = record
pszObjId: LPSTR;
cValue: DWORD;
rgValue: PCRYPT_ATTR_BLOB;
end;
type
PCRYPT_ATTRIBUTES = ^CRYPT_ATTRIBUTES;
CRYPT_ATTRIBUTES = record
cAttr: DWORD; {IN}
rgAttr: PCRYPT_ATTRIBUTE; {IN}
end;
//+-------------------------------------------------------------------------
// Attributes making up a Relative Distinguished Name (CERT_RDN)
//
// The interpretation of the Value depends on the dwValueType.
// See below for a list of the types.
//--------------------------------------------------------------------------
type
PCERT_RDN_ATTR = ^CERT_RDN_ATTR;
CERT_RDN_ATTR = record
pszObjId: LPSTR;
dwValueType: DWORD;
Value: CERT_RDN_VALUE_BLOB;
end;
//+-------------------------------------------------------------------------
// CERT_RDN attribute Object Identifiers
//--------------------------------------------------------------------------
// Labeling attribute types:
const
szOID_COMMON_NAME = '2.5.4.3'; // case-ignore string
szOID_SUR_NAME = '2.5.4.4'; // case-ignore string
szOID_DEVICE_SERIAL_NUMBER = '2.5.4.5'; // printable string
// Geographic attribute types:
szOID_COUNTRY_NAME = '2.5.4.6'; // printable 2char string
szOID_LOCALITY_NAME = '2.5.4.7'; // case-ignore string
szOID_STATE_OR_PROVINCE_NAME = '2.5.4.8'; // case-ignore string
szOID_STREET_ADDRESS = '2.5.4.9'; // case-ignore string
// Organizational attribute types:
szOID_ORGANIZATION_NAME = '2.5.4.10'; // case-ignore string
szOID_ORGANIZATIONAL_UNIT_NAME = '2.5.4.11'; // case-ignore string
szOID_TITLE = '2.5.4.12'; // case-ignore string
// Explanatory attribute types:
szOID_DESCRIPTION = '2.5.4.13'; // case-ignore string
szOID_SEARCH_GUIDE = '2.5.4.14';
szOID_BUSINESS_CATEGORY = '2.5.4.15'; // case-ignore string
// Postal addressing attribute types:
szOID_POSTAL_ADDRESS = '2.5.4.16';
szOID_POSTAL_CODE = '2.5.4.17'; // case-ignore string
szOID_POST_OFFICE_BOX = '2.5.4.18'; // case-ignore string
szOID_PHYSICAL_DELIVERY_OFFICE_NAME = '2.5.4.19'; // case-ignore string
// Telecommunications addressing attribute types:
szOID_TELEPHONE_NUMBER = '2.5.4.20'; // telephone number
szOID_TELEX_NUMBER = '2.5.4.21';
szOID_TELETEXT_TERMINAL_IDENTIFIER = '2.5.4.22';
szOID_FACSIMILE_TELEPHONE_NUMBER = '2.5.4.23';
szOID_X21_ADDRESS = '2.5.4.24'; // numeric string
szOID_INTERNATIONAL_ISDN_NUMBER = '2.5.4.25'; // numeric string
szOID_REGISTERED_ADDRESS = '2.5.4.26';
szOID_DESTINATION_INDICATOR = '2.5.4.27'; // printable string
// Preference attribute types:
szOID_PREFERRED_DELIVERY_METHOD = '2.5.4.28';
// OSI application attribute types:
szOID_PRESENTATION_ADDRESS = '2.5.4.29';
szOID_SUPPORTED_APPLICATION_CONTEXT = '2.5.4.30';
// Relational application attribute types:
szOID_MEMBER = '2.5.4.31';
szOID_OWNER = '2.5.4.32';
szOID_ROLE_OCCUPANT = '2.5.4.33';
szOID_SEE_ALSO = '2.5.4.34';
// Security attribute types:
szOID_USER_PASSWORD = '2.5.4.35';
szOID_USER_CERTIFICATE = '2.5.4.36';
szOID_CA_CERTIFICATE = '2.5.4.37';
szOID_AUTHORITY_REVOCATION_LIST = '2.5.4.38';
szOID_CERTIFICATE_REVOCATION_LIST = '2.5.4.39';
szOID_CROSS_CERTIFICATE_PAIR = '2.5.4.40';
// Undocumented attribute types???
//#define szOID_??? '2.5.4.41'
szOID_GIVEN_NAME = '2.5.4.42'; // case-ignore string
szOID_INITIALS = '2.5.4.43'; // case-ignore string
// Pilot user attribute types:
szOID_DOMAIN_COMPONENT = '0.9.2342.19200300.100.1.25'; // IA5 string
//+-------------------------------------------------------------------------
// CERT_RDN Attribute Value Types
//
// For RDN_ENCODED_BLOB, the Value's CERT_RDN_VALUE_BLOB is in its encoded
// representation. Otherwise, its an array of bytes.
//
// For all CERT_RDN types, Value.cbData is always the number of bytes, not
// necessarily the number of elements in the string. For instance,
// RDN_UNIVERSAL_STRING is an array of ints (cbData == intCnt * 4) and
// RDN_BMP_STRING is an array of unsigned shorts (cbData == ushortCnt * 2).
//
// For CertDecodeName, two 0 bytes are always appended to the end of the
// string (ensures a CHAR or WCHAR string is null terminated).
// These added 0 bytes are't included in the BLOB.cbData.
//--------------------------------------------------------------------------
const
CERT_RDN_ANY_TYPE = 0;
CERT_RDN_ENCODED_BLOB = 1;
CERT_RDN_OCTET_STRING = 2;
CERT_RDN_NUMERIC_STRING = 3;
CERT_RDN_PRINTABLE_STRING = 4;
CERT_RDN_TELETEX_STRING = 5;
CERT_RDN_T61_STRING = 5;
CERT_RDN_VIDEOTEX_STRING = 6;
CERT_RDN_IA5_STRING = 7;
CERT_RDN_GRAPHIC_STRING = 8;
CERT_RDN_VISIBLE_STRING = 9;
CERT_RDN_ISO646_STRING = 9;
CERT_RDN_GENERAL_STRING = 10;
CERT_RDN_UNIVERSAL_STRING = 11;
CERT_RDN_INT4_STRING = 11;
CERT_RDN_BMP_STRING = 12;
CERT_RDN_UNICODE_STRING = 12;
// Macro to check that the dwValueType is a character string and not an
// encoded blob or octet string
function IS_CERT_RDN_CHAR_STRING(X: DWORD): BOOL;
//+-------------------------------------------------------------------------
// A CERT_RDN consists of an array of the above attributes
//--------------------------------------------------------------------------
type
PCERT_RDN = ^CERT_RDN;
CERT_RDN = record
cRDNAttr: DWORD;
rgRDNAttr: PCERT_RDN_ATTR;
end;
//+-------------------------------------------------------------------------
// Information stored in a subject's or issuer's name. The information
// is represented as an array of the above RDNs.
//--------------------------------------------------------------------------
type
PCERT_NAME_INFO = ^CERT_NAME_INFO;
CERT_NAME_INFO = record
cRDN: DWORD;
rgRDN: PCERT_RDN;
end;
//+-------------------------------------------------------------------------
// Name attribute value without the Object Identifier
//
// The interpretation of the Value depends on the dwValueType.
// See above for a list of the types.
//--------------------------------------------------------------------------
type
PCERT_NAME_VALUE = ^CERT_NAME_VALUE;
CERT_NAME_VALUE = record
dwValueType: DWORD;
Value: CERT_RDN_VALUE_BLOB;
end;
//+-------------------------------------------------------------------------
// Public Key Info
//
// The PublicKey is the encoded representation of the information as it is
// stored in the bit string
//--------------------------------------------------------------------------
type
PCERT_PUBLIC_KEY_INFO = ^CERT_PUBLIC_KEY_INFO;
CERT_PUBLIC_KEY_INFO = record
Algorithm: CRYPT_ALGORITHM_IDENTIFIER;
PublicKey: CRYPT_BIT_BLOB;
end;
const
CERT_RSA_PUBLIC_KEY_OBJID = szOID_RSA_RSA;
CERT_DEFAULT_OID_PUBLIC_KEY_SIGN = szOID_RSA_RSA;
CERT_DEFAULT_OID_PUBLIC_KEY_XCHG = szOID_RSA_RSA;
//+-------------------------------------------------------------------------
// Information stored in a certificate
//
// The Issuer, Subject, Algorithm, PublicKey and Extension BLOBs are the
// encoded representation of the information.
//--------------------------------------------------------------------------
type
PCERT_INFO = ^CERT_INFO;
CERT_INFO = record
dwVersion: DWORD;
SerialNumber: CRYPT_INTEGER_BLOB;
SignatureAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
Issuer: CERT_NAME_BLOB;
NotBefore: TFILETIME;
NotAfter: TFILETIME;
Subject: CERT_NAME_BLOB;
SubjectPublicKeyInfo: CERT_PUBLIC_KEY_INFO;
IssuerUniqueId: CRYPT_BIT_BLOB;
SubjectUniqueId: CRYPT_BIT_BLOB;
cExtension: DWORD;
rgExtension: PCERT_EXTENSION;
end;
//+-------------------------------------------------------------------------
// Certificate versions
//--------------------------------------------------------------------------
const
CERT_V1 = 0;
CERT_V2 = 1;
CERT_V3 = 2;
//+-------------------------------------------------------------------------
// Certificate Information Flags
//--------------------------------------------------------------------------
CERT_INFO_VERSION_FLAG = 1;
CERT_INFO_SERIAL_NUMBER_FLAG = 2;
CERT_INFO_SIGNATURE_ALGORITHM_FLAG = 3;
CERT_INFO_ISSUER_FLAG = 4;
CERT_INFO_NOT_BEFORE_FLAG = 5;
CERT_INFO_NOT_AFTER_FLAG = 6;
CERT_INFO_SUBJECT_FLAG = 7;
CERT_INFO_SUBJECT_PUBLIC_KEY_INFO_FLAG = 8;
CERT_INFO_ISSUER_UNIQUE_ID_FLAG = 9;
CERT_INFO_SUBJECT_UNIQUE_ID_FLAG = 10;
CERT_INFO_EXTENSION_FLAG = 11;
//+-------------------------------------------------------------------------
// An entry in a CRL
//
// The Extension BLOBs are the encoded representation of the information.
//--------------------------------------------------------------------------
type
PCRL_ENTRY = ^CRL_ENTRY;
CRL_ENTRY = record
SerialNumber: CRYPT_INTEGER_BLOB;
RevocationDate: TFILETIME;
cExtension: DWORD;
rgExtension: PCERT_EXTENSION;
end;
//+-------------------------------------------------------------------------
// Information stored in a CRL
//
// The Issuer, Algorithm and Extension BLOBs are the encoded
// representation of the information.
//--------------------------------------------------------------------------
type
PCRL_INFO = ^CRL_INFO;
CRL_INFO = record
dwVersion: DWORD;
SignatureAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
Issuer: CERT_NAME_BLOB;
ThisUpdate: TFILETIME;
NextUpdate: TFILETIME;
cCRLEntry: DWORD;
rgCRLEntry: PCRL_ENTRY;
cExtension: DWORD;
rgExtension: PCERT_EXTENSION;
end;
//+-------------------------------------------------------------------------
// CRL versions
//--------------------------------------------------------------------------
const
CRL_V1 = 0;
CRL_V2 = 1;
//+-------------------------------------------------------------------------
// Information stored in a certificate request
//
// The Subject, Algorithm, PublicKey and Attribute BLOBs are the encoded
// representation of the information.
//--------------------------------------------------------------------------
type
PCERT_REQUEST_INFO = ^CERT_REQUEST_INFO;
CERT_REQUEST_INFO = record
dwVersion: DWORD;
Subject: CERT_NAME_BLOB;
SubjectPublicKeyInfo: CERT_PUBLIC_KEY_INFO;
cAttribute: DWORD;
rgAttribute: PCRYPT_ATTRIBUTE;
end;
//+-------------------------------------------------------------------------
// Certificate Request versions
//--------------------------------------------------------------------------
const CERT_REQUEST_V1 = 0;
//+-------------------------------------------------------------------------
// Information stored in Netscape's Keygen request
//--------------------------------------------------------------------------
type
PCERT_KEYGEN_REQUEST_INFO = ^CERT_KEYGEN_REQUEST_INFO;
CERT_KEYGEN_REQUEST_INFO = record
dwVersion: DWORD;
SubjectPublicKeyInfo: CERT_PUBLIC_KEY_INFO;
pwszChallengeString: LPWSTR; // encoded as IA5
end;
const
CERT_KEYGEN_REQUEST_V1 = 0;
//+-------------------------------------------------------------------------
// Certificate, CRL, Certificate Request or Keygen Request Signed Content
//
// The "to be signed" encoded content plus its signature. The ToBeSigned
// is the encoded CERT_INFO, CRL_INFO, CERT_REQUEST_INFO or
// CERT_KEYGEN_REQUEST_INFO.
//--------------------------------------------------------------------------
type
PCERT_SIGNED_CONTENT_INFO = ^CERT_SIGNED_CONTENT_INFO;
CERT_SIGNED_CONTENT_INFO = record
ToBeSigned: CRYPT_DER_BLOB;
SignatureAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
Signature: CRYPT_BIT_BLOB;
end;
//+-------------------------------------------------------------------------
// Certificate Trust List (CTL)
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CTL Usage. Also used for EnhancedKeyUsage extension.
//--------------------------------------------------------------------------
type
PCTL_USAGE = ^CTL_USAGE;
CTL_USAGE = record
cUsageIdentifier: DWORD;
rgpszUsageIdentifier: PLPSTR; // array of pszObjId
end;
type
CERT_ENHKEY_USAGE = CTL_USAGE;
PCERT_ENHKEY_USAGE = ^CERT_ENHKEY_USAGE;
//+-------------------------------------------------------------------------
// An entry in a CTL
//--------------------------------------------------------------------------
type
PCTL_ENTRY = ^CTL_ENTRY;
CTL_ENTRY = record
SubjectIdentifier: CRYPT_DATA_BLOB; // For example, its hash
cAttribute: DWORD;
rgAttribute: PCRYPT_ATTRIBUTE; // OPTIONAL
end;
//+-------------------------------------------------------------------------
// Information stored in a CTL
//--------------------------------------------------------------------------
type
PCTL_INFO = ^CTL_INFO;
CTL_INFO = record
dwVersion: DWORD;
SubjectUsage: CTL_USAGE;
ListIdentifier: CRYPT_DATA_BLOB; // OPTIONAL
SequenceNumber: CRYPT_INTEGER_BLOB; // OPTIONAL
ThisUpdate: TFILETIME;
NextUpdate: TFILETIME; // OPTIONAL
SubjectAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
cCTLEntry: DWORD;
rgCTLEntry: PCTL_ENTRY; // OPTIONAL
cExtension: DWORD;
rgExtension: PCERT_EXTENSION; // OPTIONAL
end;
//+-------------------------------------------------------------------------
// CTL versions
//--------------------------------------------------------------------------
const
CTL_V1 = 0;
//+-------------------------------------------------------------------------
// TimeStamp Request
//
// The pszTimeStamp is the OID for the Time type requested
// The pszContentType is the Content Type OID for the content, usually DATA
// The Content is a un-decoded blob
//--------------------------------------------------------------------------
type
PCRYPT_TIME_STAMP_REQUEST_INFO = ^CRYPT_TIME_STAMP_REQUEST_INFO;
CRYPT_TIME_STAMP_REQUEST_INFO = record
pszTimeStampAlgorithm: LPSTR; // pszObjId
pszContentType: LPSTR; // pszObjId
Content: CRYPT_OBJID_BLOB;
cAttribute: DWORD;
rgAttribute: PCRYPT_ATTRIBUTE;
end;
//+-------------------------------------------------------------------------
// Certificate and Message encoding types
//
// The encoding type is a DWORD containing both the certificate and message
// encoding types. The certificate encoding type is stored in the LOWORD.
// The message encoding type is stored in the HIWORD. Some functions or
// structure fields require only one of the encoding types. The following
// naming convention is used to indicate which encoding type(s) are
// required:
// dwEncodingType (both encoding types are required)
// dwMsgAndCertEncodingType (both encoding types are required)
// dwMsgEncodingType (only msg encoding type is required)
// dwCertEncodingType (only cert encoding type is required)
//
// Its always acceptable to specify both.
//--------------------------------------------------------------------------
const
CERT_ENCODING_TYPE_MASK = $0000FFFF;
CMSG_ENCODING_TYPE_MASK = $FFFF0000;
//#define GET_CERT_ENCODING_TYPE(X) (X & CERT_ENCODING_TYPE_MASK)
//#define GET_CMSG_ENCODING_TYPE(X) (X & CMSG_ENCODING_TYPE_MASK)
function GET_CERT_ENCODING_TYPE(X: DWORD): DWORD;
function GET_CMSG_ENCODING_TYPE(X: DWORD): DWORD;
const
CRYPT_ASN_ENCODING = $00000001;
CRYPT_NDR_ENCODING = $00000002;
X509_ASN_ENCODING = $00000001;
X509_NDR_ENCODING = $00000002;
PKCS_7_ASN_ENCODING = $00010000;
PKCS_7_NDR_ENCODING = $00020000;
//+-------------------------------------------------------------------------
// format the specified data structure according to the certificate
// encoding type.
//
//--------------------------------------------------------------------------
function CryptFormatObject(dwCertEncodingType: DWORD;
dwFormatType: DWORD;
dwFormatStrType: DWORD;
pFormatStruct: PVOID;
lpszStructType: LPCSTR;
const pbEncoded: PBYTE;
cbEncoded: DWORD;
pbFormat: PVOID;
pcbFormat: PDWORD): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Encode / decode the specified data structure according to the certificate
// encoding type.
//
// See below for a list of the predefined data structures.
//--------------------------------------------------------------------------
function CryptEncodeObject(dwCertEncodingType: DWORD;
lpszStructType: LPCSTR;
const pvStructInfo: PVOID;
pbEncoded: PBYTE;
pcbEncoded: PDWORD): BOOL; stdcall;
function CryptDecodeObject(dwCertEncodingType: DWORD;
lpszStructType: LPCSTR;
const pbEncoded: PBYTE;
cbEncoded: DWORD;
dwFlags: DWORD;
pvStructInfo: PVOID;
pcbStructInfo: PDWORD): BOOL; stdcall;
// When the following flag is set the nocopy optimization is enabled.
// This optimization where appropriate, updates the pvStructInfo fields
// to point to content residing within pbEncoded instead of making a copy
// of and appending to pvStructInfo.
//
// Note, when set, pbEncoded can't be freed until pvStructInfo is freed.
const
CRYPT_DECODE_NOCOPY_FLAG = $1;
//+-------------------------------------------------------------------------
// Predefined X509 certificate data structures that can be encoded / decoded.
//--------------------------------------------------------------------------
CRYPT_ENCODE_DECODE_NONE = 0;
X509_CERT = (LPCSTR(1));
X509_CERT_TO_BE_SIGNED = (LPCSTR(2));
X509_CERT_CRL_TO_BE_SIGNED = (LPCSTR(3));
X509_CERT_REQUEST_TO_BE_SIGNED = (LPCSTR(4));
X509_EXTENSIONS = (LPCSTR(5));
X509_NAME_VALUE = (LPCSTR(6));
X509_NAME = (LPCSTR(7));
X509_PUBLIC_KEY_INFO = (LPCSTR(8));
//+-------------------------------------------------------------------------
// Predefined X509 certificate extension data structures that can be
// encoded / decoded.
//--------------------------------------------------------------------------
X509_AUTHORITY_KEY_ID = (LPCSTR(9));
X509_KEY_ATTRIBUTES = (LPCSTR(10));
X509_KEY_USAGE_RESTRICTION = (LPCSTR(11));
X509_ALTERNATE_NAME = (LPCSTR(12));
X509_BASIC_CONSTRAINTS = (LPCSTR(13));
X509_KEY_USAGE = (LPCSTR(14));
X509_BASIC_CONSTRAINTS2 = (LPCSTR(15));
X509_CERT_POLICIES = (LPCSTR(16));
//+-------------------------------------------------------------------------
// Additional predefined data structures that can be encoded / decoded.
//--------------------------------------------------------------------------
PKCS_UTC_TIME = (LPCSTR(17));
PKCS_TIME_REQUEST = (LPCSTR(18));
RSA_CSP_PUBLICKEYBLOB = (LPCSTR(19));
X509_UNICODE_NAME = (LPCSTR(20));
X509_KEYGEN_REQUEST_TO_BE_SIGNED = (LPCSTR(21));
PKCS_ATTRIBUTE = (LPCSTR(22));
PKCS_CONTENT_INFO_SEQUENCE_OF_ANY = (LPCSTR(23));
//+-------------------------------------------------------------------------
// Predefined primitive data structures that can be encoded / decoded.
//--------------------------------------------------------------------------
X509_UNICODE_NAME_VALUE = (LPCSTR(24));
X509_ANY_STRING = X509_NAME_VALUE;
X509_UNICODE_ANY_STRING = X509_UNICODE_NAME_VALUE;
X509_OCTET_STRING = (LPCSTR(25));
X509_BITS = (LPCSTR(26));
X509_INTEGER = (LPCSTR(27));
X509_MULTI_BYTE_INTEGER = (LPCSTR(28));
X509_ENUMERATED = (LPCSTR(29));
X509_CHOICE_OF_TIME = (LPCSTR(30));
//+-------------------------------------------------------------------------
// More predefined X509 certificate extension data structures that can be
// encoded / decoded.
//--------------------------------------------------------------------------
X509_AUTHORITY_KEY_ID2 = (LPCSTR(31));
// X509_AUTHORITY_INFO_ACCESS (LPCSTR(32));
X509_CRL_REASON_CODE = X509_ENUMERATED;
PKCS_CONTENT_INFO = (LPCSTR(33));
X509_SEQUENCE_OF_ANY = (LPCSTR(34));
X509_CRL_DIST_POINTS = (LPCSTR(35));
X509_ENHANCED_KEY_USAGE = (LPCSTR(36));
PKCS_CTL = (LPCSTR(37));
X509_MULTI_BYTE_UINT = (LPCSTR(38));
X509_DSS_PUBLICKEY = X509_MULTI_BYTE_UINT;
X509_DSS_PARAMETERS = (LPCSTR(39));
X509_DSS_SIGNATURE = (LPCSTR(40));
PKCS_RC2_CBC_PARAMETERS = (LPCSTR(41));
PKCS_SMIME_CAPABILITIES = (LPCSTR(42));
//+-------------------------------------------------------------------------
// Predefined PKCS #7 data structures that can be encoded / decoded.
//--------------------------------------------------------------------------
PKCS7_SIGNER_INFO = (LPCSTR(500));
//+-------------------------------------------------------------------------
// Predefined Software Publishing Credential (SPC) data structures that
// can be encoded / decoded.
//
// Predefined values: 2000 .. 2999
//
// See spc.h for value and data structure definitions.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// Extension Object Identifiers
//--------------------------------------------------------------------------
const
szOID_AUTHORITY_KEY_IDENTIFIER = '2.5.29.1';
szOID_KEY_ATTRIBUTES = '2.5.29.2';
szOID_KEY_USAGE_RESTRICTION = '2.5.29.4';
szOID_SUBJECT_ALT_NAME = '2.5.29.7';
szOID_ISSUER_ALT_NAME = '2.5.29.8';
szOID_BASIC_CONSTRAINTS = '2.5.29.10';
szOID_KEY_USAGE = '2.5.29.15';
szOID_BASIC_CONSTRAINTS2 = '2.5.29.19';
szOID_CERT_POLICIES = '2.5.29.32';
szOID_AUTHORITY_KEY_IDENTIFIER2 = '2.5.29.35';
szOID_SUBJECT_KEY_IDENTIFIER = '2.5.29.14';
szOID_SUBJECT_ALT_NAME2 = '2.5.29.17';
szOID_ISSUER_ALT_NAME2 = '2.5.29.18';
szOID_CRL_REASON_CODE = '2.5.29.21';
szOID_CRL_DIST_POINTS = '2.5.29.31';
szOID_ENHANCED_KEY_USAGE = '2.5.29.37';
// Internet Public Key Infrastructure
szOID_PKIX = '1.3.6.1.5.5.7';
szOID_AUTHORITY_INFO_ACCESS = '1.3.6.1.5.5.7.2';
// Microsoft extensions or attributes
szOID_CERT_EXTENSIONS = '1.3.6.1.4.1.311.2.1.14';
szOID_NEXT_UPDATE_LOCATION = '1.3.6.1.4.1.311.10.2';
// Microsoft PKCS #7 ContentType Object Identifiers
szOID_CTL = '1.3.6.1.4.1.311.10.1';
//+-------------------------------------------------------------------------
// Extension Object Identifiers (currently not implemented)
//--------------------------------------------------------------------------
szOID_POLICY_MAPPINGS = '2.5.29.5';
szOID_SUBJECT_DIR_ATTRS = '2.5.29.9';
//+-------------------------------------------------------------------------
// Enhanced Key Usage (Purpose) Object Identifiers
//--------------------------------------------------------------------------
const szOID_PKIX_KP = '1.3.6.1.5.5.7.3';
// Consistent key usage bits: DIGITAL_SIGNATURE, KEY_ENCIPHERMENT
// or KEY_AGREEMENT
szOID_PKIX_KP_SERVER_AUTH = '1.3.6.1.5.5.7.3.1';
// Consistent key usage bits: DIGITAL_SIGNATURE
szOID_PKIX_KP_CLIENT_AUTH = '1.3.6.1.5.5.7.3.2';
// Consistent key usage bits: DIGITAL_SIGNATURE
szOID_PKIX_KP_CODE_SIGNING = '1.3.6.1.5.5.7.3.3';
// Consistent key usage bits: DIGITAL_SIGNATURE, NON_REPUDIATION and/or
// (KEY_ENCIPHERMENT or KEY_AGREEMENT)
szOID_PKIX_KP_EMAIL_PROTECTION = '1.3.6.1.5.5.7.3.4';
//+-------------------------------------------------------------------------
// Microsoft Enhanced Key Usage (Purpose) Object Identifiers
//+-------------------------------------------------------------------------
// Signer of CTLs
szOID_KP_CTL_USAGE_SIGNING = '1.3.6.1.4.1.311.10.3.1';
// Signer of TimeStamps
szOID_KP_TIME_STAMP_SIGNING = '1.3.6.1.4.1.311.10.3.2';
//+-------------------------------------------------------------------------
// Microsoft Attribute Object Identifiers
//+-------------------------------------------------------------------------
szOID_YESNO_TRUST_ATTR = '1.3.6.1.4.1.311.10.4.1';
//+-------------------------------------------------------------------------
// X509_CERT
//
// The "to be signed" encoded content plus its signature. The ToBeSigned
// content is the CryptEncodeObject() output for one of the following:
// X509_CERT_TO_BE_SIGNED, X509_CERT_CRL_TO_BE_SIGNED or
// X509_CERT_REQUEST_TO_BE_SIGNED.
//
// pvStructInfo points to CERT_SIGNED_CONTENT_INFO.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_CERT_TO_BE_SIGNED
//
// pvStructInfo points to CERT_INFO.
//
// For CryptDecodeObject(), the pbEncoded is the "to be signed" plus its
// signature (output of a X509_CERT CryptEncodeObject()).
//
// For CryptEncodeObject(), the pbEncoded is just the "to be signed".
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_CERT_CRL_TO_BE_SIGNED
//
// pvStructInfo points to CRL_INFO.
//
// For CryptDecodeObject(), the pbEncoded is the "to be signed" plus its
// signature (output of a X509_CERT CryptEncodeObject()).
//
// For CryptEncodeObject(), the pbEncoded is just the "to be signed".
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_CERT_REQUEST_TO_BE_SIGNED
//
// pvStructInfo points to CERT_REQUEST_INFO.
//
// For CryptDecodeObject(), the pbEncoded is the "to be signed" plus its
// signature (output of a X509_CERT CryptEncodeObject()).
//
// For CryptEncodeObject(), the pbEncoded is just the "to be signed".
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_EXTENSIONS
// szOID_CERT_EXTENSIONS
//
// pvStructInfo points to following CERT_EXTENSIONS.
//--------------------------------------------------------------------------
type
PCERT_EXTENSIONS = ^CERT_EXTENSIONS;
CERT_EXTENSIONS = record
cExtension: DWORD;
rgExtension: PCERT_EXTENSION;
end;
//+-------------------------------------------------------------------------
// X509_NAME_VALUE
// X509_ANY_STRING
//
// pvStructInfo points to CERT_NAME_VALUE.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_UNICODE_NAME_VALUE
// X509_UNICODE_ANY_STRING
//
// pvStructInfo points to CERT_NAME_VALUE.
//
// The name values are unicode strings.
//
// For CryptEncodeObject:
// Value.pbData points to the unicode string.
// If Value.cbData = 0, then, the unicode string is NULL terminated.
// Otherwise, Value.cbData is the unicode string byte count. The byte count
// is twice the character count.
//
// If the unicode string contains an invalid character for the specified
// dwValueType, then, *pcbEncoded is updated with the unicode character
// index of the first invalid character. LastError is set to:
// CRYPT_E_INVALID_NUMERIC_STRING, CRYPT_E_INVALID_PRINTABLE_STRING or
// CRYPT_E_INVALID_IA5_STRING.
//
// The unicode string is converted before being encoded according to
// the specified dwValueType. If dwValueType is set to 0, LastError
// is set to E_INVALIDARG.
//
// If the dwValueType isn't one of the character strings (its a
// CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING), then, CryptEncodeObject
// will return FALSE with LastError set to CRYPT_E_NOT_CHAR_STRING.
//
// For CryptDecodeObject:
// Value.pbData points to a NULL terminated unicode string. Value.cbData
// contains the byte count of the unicode string excluding the NULL
// terminator. dwValueType contains the type used in the encoded object.
// Its not forced to CERT_RDN_UNICODE_STRING. The encoded value is
// converted to the unicode string according to the dwValueType.
//
// If the encoded object isn't one of the character string types, then,
// CryptDecodeObject will return FALSE with LastError set to
// CRYPT_E_NOT_CHAR_STRING. For a non character string, decode using
// X509_NAME_VALUE or X509_ANY_STRING.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_NAME
//
// pvStructInfo points to CERT_NAME_INFO.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_UNICODE_NAME
//
// pvStructInfo points to CERT_NAME_INFO.
//
// The RDN attribute values are unicode strings except for the dwValueTypes of
// CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING. These dwValueTypes are
// the same as for a X509_NAME. Their values aren't converted to/from unicode.
//
// For CryptEncodeObject:
// Value.pbData points to the unicode string.
// If Value.cbData = 0, then, the unicode string is NULL terminated.
// Otherwise, Value.cbData is the unicode string byte count. The byte count
// is twice the character count.
//
// If dwValueType = 0 (CERT_RDN_ANY_TYPE), the pszObjId is used to find
// an acceptable dwValueType. If the unicode string contains an
// invalid character for the found or specified dwValueType, then,
// *pcbEncoded is updated with the error location of the invalid character.
// See below for details. LastError is set to:
// CRYPT_E_INVALID_NUMERIC_STRING, CRYPT_E_INVALID_PRINTABLE_STRING or
// CRYPT_E_INVALID_IA5_STRING.
//
// The unicode string is converted before being encoded according to
// the specified or ObjId matching dwValueType.
//
// For CryptDecodeObject:
// Value.pbData points to a NULL terminated unicode string. Value.cbData
// contains the byte count of the unicode string excluding the NULL
// terminator. dwValueType contains the type used in the encoded object.
// Its not forced to CERT_RDN_UNICODE_STRING. The encoded value is
// converted to the unicode string according to the dwValueType.
//
// If the dwValueType of the encoded value isn't a character string
// type, then, it isn't converted to UNICODE. Use the
// IS_CERT_RDN_CHAR_STRING() macro on the dwValueType to check
// that Value.pbData points to a converted unicode string.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// Unicode Name Value Error Location Definitions
//
// Error location is returned in *pcbEncoded by
// CryptEncodeObject(X509_UNICODE_NAME)
//
// Error location consists of:
// RDN_INDEX - 10 bits << 22
// ATTR_INDEX - 6 bits << 16
// VALUE_INDEX - 16 bits (unicode character index)
//--------------------------------------------------------------------------
const
CERT_UNICODE_RDN_ERR_INDEX_MASK = $3FF;
CERT_UNICODE_RDN_ERR_INDEX_SHIFT = 22;
CERT_UNICODE_ATTR_ERR_INDEX_MASK = $003F;
CERT_UNICODE_ATTR_ERR_INDEX_SHIFT = 16;
CERT_UNICODE_VALUE_ERR_INDEX_MASK = $0000FFFF;
CERT_UNICODE_VALUE_ERR_INDEX_SHIFT = 0;
{#define GET_CERT_UNICODE_RDN_ERR_INDEX(X) \
((X >> CERT_UNICODE_RDN_ERR_INDEX_SHIFT) & CERT_UNICODE_RDN_ERR_INDEX_MASK)}
function GET_CERT_UNICODE_RDN_ERR_INDEX(X: integer): integer;
{#define GET_CERT_UNICODE_ATTR_ERR_INDEX(X) \
((X >> CERT_UNICODE_ATTR_ERR_INDEX_SHIFT) & CERT_UNICODE_ATTR_ERR_INDEX_MASK)}
function GET_CERT_UNICODE_ATTR_ERR_INDEX(X: integer): integer;
{#define GET_CERT_UNICODE_VALUE_ERR_INDEX(X) \
(X & CERT_UNICODE_VALUE_ERR_INDEX_MASK)}
function GET_CERT_UNICODE_VALUE_ERR_INDEX(X: integer): integer;
//+-------------------------------------------------------------------------
// X509_PUBLIC_KEY_INFO
//
// pvStructInfo points to CERT_PUBLIC_KEY_INFO.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_AUTHORITY_KEY_ID
// szOID_AUTHORITY_KEY_IDENTIFIER
//
// pvStructInfo points to following CERT_AUTHORITY_KEY_ID_INFO.
//--------------------------------------------------------------------------
type
PCERT_AUTHORITY_KEY_ID_INFO = ^CERT_AUTHORITY_KEY_ID_INFO;
CERT_AUTHORITY_KEY_ID_INFO = record
KeyId: CRYPT_DATA_BLOB;
CertIssuer: CERT_NAME_BLOB;
CertSerialNumber: CRYPT_INTEGER_BLOB;
end;
//+-------------------------------------------------------------------------
// X509_KEY_ATTRIBUTES
// szOID_KEY_ATTRIBUTES
//
// pvStructInfo points to following CERT_KEY_ATTRIBUTES_INFO.
//--------------------------------------------------------------------------
type
PCERT_PRIVATE_KEY_VALIDITY = ^CERT_PRIVATE_KEY_VALIDITY;
CERT_PRIVATE_KEY_VALIDITY = record
NotBefore: TFILETIME;
NotAfter: TFILETIME;
end;
type
PCERT_KEY_ATTRIBUTES_INFO = ^CERT_KEY_ATTRIBUTES_INFO;
CERT_KEY_ATTRIBUTES_INFO = record
KeyId: CRYPT_DATA_BLOB;
IntendedKeyUsage: CRYPT_BIT_BLOB;
pPrivateKeyUsagePeriod: PCERT_PRIVATE_KEY_VALIDITY; // OPTIONAL
end;
const
CERT_DIGITAL_SIGNATURE_KEY_USAGE = $80;
CERT_NON_REPUDIATION_KEY_USAGE = $40;
CERT_KEY_ENCIPHERMENT_KEY_USAGE = $20;
CERT_DATA_ENCIPHERMENT_KEY_USAGE = $10;
CERT_KEY_AGREEMENT_KEY_USAGE = $08;
CERT_KEY_CERT_SIGN_KEY_USAGE = $04;
CERT_OFFLINE_CRL_SIGN_KEY_USAGE = $02;
CERT_CRL_SIGN_KEY_USAGE = $02;
//+-------------------------------------------------------------------------
// X509_KEY_USAGE_RESTRICTION
// szOID_KEY_USAGE_RESTRICTION
//
// pvStructInfo points to following CERT_KEY_USAGE_RESTRICTION_INFO.
//--------------------------------------------------------------------------
type
PCERT_POLICY_ID = ^CERT_POLICY_ID;
CERT_POLICY_ID = record
cCertPolicyElementId: DWORD;
rgpszCertPolicyElementId: PLPSTR; // pszObjId
end;
type
PCERT_KEY_USAGE_RESTRICTION_INFO = ^CERT_KEY_USAGE_RESTRICTION_INFO;
CERT_KEY_USAGE_RESTRICTION_INFO = record
cCertPolicyId: DWORD;
rgCertPolicyId: PCERT_POLICY_ID;
RestrictedKeyUsage: CRYPT_BIT_BLOB;
end;
// See CERT_KEY_ATTRIBUTES_INFO for definition of the RestrictedKeyUsage bits
//+-------------------------------------------------------------------------
// X509_ALTERNATE_NAME
// szOID_SUBJECT_ALT_NAME
// szOID_ISSUER_ALT_NAME
// szOID_SUBJECT_ALT_NAME2
// szOID_ISSUER_ALT_NAME2
//
// pvStructInfo points to following CERT_ALT_NAME_INFO.
//--------------------------------------------------------------------------
type
PCERT_ALT_NAME_ENTRY = ^CERT_ALT_NAME_ENTRY;
CERT_ALT_NAME_ENTRY = record
dwAltNameChoice: DWORD;
case integer of
{1}0: ({OtherName :Not implemented});
{2}1: (pwszRfc822Name: LPWSTR); //(encoded IA5)
{3}2: (pwszDNSName: LPWSTR); //(encoded IA5)
{4}3: ({x400Address :Not implemented});
{5}4: (DirectoryName: CERT_NAME_BLOB);
{6}5: ({pEdiPartyName :Not implemented});
{7}6: (pwszURL: LPWSTR); //(encoded IA5)
{8}7: (IPAddress: CRYPT_DATA_BLOB); //(Octet String)
{9}8: (pszRegisteredID: LPSTR); //(Octet String)
end;
const
CERT_ALT_NAME_OTHER_NAME = 1;
CERT_ALT_NAME_RFC822_NAME = 2;
CERT_ALT_NAME_DNS_NAME = 3;
CERT_ALT_NAME_X400_ADDRESS = 4;
CERT_ALT_NAME_DIRECTORY_NAME = 5;
CERT_ALT_NAME_EDI_PARTY_NAME = 6;
CERT_ALT_NAME_URL = 7;
CERT_ALT_NAME_IP_ADDRESS = 8;
CERT_ALT_NAME_REGISTERED_ID = 9;
type
PCERT_ALT_NAME_INFO = ^CERT_ALT_NAME_INFO;
CERT_ALT_NAME_INFO = record
cAltEntry: DWORD;
rgAltEntry: PCERT_ALT_NAME_ENTRY;
end;
//+-------------------------------------------------------------------------
// Alternate name IA5 Error Location Definitions for
// CRYPT_E_INVALID_IA5_STRING.
//
// Error location is returned in *pcbEncoded by
// CryptEncodeObject(X509_ALTERNATE_NAME)
//
// Error location consists of:
// ENTRY_INDEX - 8 bits << 16
// VALUE_INDEX - 16 bits (unicode character index)
//--------------------------------------------------------------------------
const
CERT_ALT_NAME_ENTRY_ERR_INDEX_MASK = $FF;
CERT_ALT_NAME_ENTRY_ERR_INDEX_SHIFT = 16;
CERT_ALT_NAME_VALUE_ERR_INDEX_MASK = $0000FFFF;
CERT_ALT_NAME_VALUE_ERR_INDEX_SHIFT = 0;
{#define GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X) \
((X >> CERT_ALT_NAME_ENTRY_ERR_INDEX_SHIFT) & \
CERT_ALT_NAME_ENTRY_ERR_INDEX_MASK)}
function GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X: DWORD): DWORD;
{#define GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X) \
(X & CERT_ALT_NAME_VALUE_ERR_INDEX_MASK)}
function GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X: DWORD): DWORD;
//+-------------------------------------------------------------------------
// X509_BASIC_CONSTRAINTS
// szOID_BASIC_CONSTRAINTS
//
// pvStructInfo points to following CERT_BASIC_CONSTRAINTS_INFO.
//--------------------------------------------------------------------------
type
PCERT_BASIC_CONSTRAINTS_INFO = ^CERT_BASIC_CONSTRAINTS_INFO;
CERT_BASIC_CONSTRAINTS_INFO = record
SubjectType: CRYPT_BIT_BLOB;
fPathLenConstraint: BOOL;
dwPathLenConstraint: DWORD;
cSubtreesConstraint: DWORD;
rgSubtreesConstraint: PCERT_NAME_BLOB;
end;
const
CERT_CA_SUBJECT_FLAG = $80;
CERT_END_ENTITY_SUBJECT_FLAG = $40;
//+-------------------------------------------------------------------------
// X509_BASIC_CONSTRAINTS2
// szOID_BASIC_CONSTRAINTS2
//
// pvStructInfo points to following CERT_BASIC_CONSTRAINTS2_INFO.
//--------------------------------------------------------------------------
type
PCERT_BASIC_CONSTRAINTS2_INFO = ^CERT_BASIC_CONSTRAINTS2_INFO;
CERT_BASIC_CONSTRAINTS2_INFO = record
fCA: BOOL;
fPathLenConstraint: BOOL;
dwPathLenConstraint: DWORD;
end;
//+-------------------------------------------------------------------------
// X509_KEY_USAGE
// szOID_KEY_USAGE
//
// pvStructInfo points to a CRYPT_BIT_BLOB. Has same bit definitions as
// CERT_KEY_ATTRIBUTES_INFO's IntendedKeyUsage.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_CERT_POLICIES
// szOID_CERT_POLICIES
//
// pvStructInfo points to following CERT_POLICIES_INFO.
//--------------------------------------------------------------------------
type
PCERT_POLICY_QUALIFIER_INFO = ^CERT_POLICY_QUALIFIER_INFO;
CERT_POLICY_QUALIFIER_INFO = record
pszPolicyQualifierId: LPSTR; // pszObjId
Qualifier: CRYPT_OBJID_BLOB; // optional
end;
type
PCERT_POLICY_INFO = ^CERT_POLICY_INFO;
CERT_POLICY_INFO = record
pszPolicyIdentifier: LPSTR; // pszObjId
cPolicyQualifier: DWORD; // optional
rgPolicyQualifier: PCERT_POLICY_QUALIFIER_INFO;
end;
type
PCERT_POLICIES_INFO = ^CERT_POLICIES_INFO;
CERT_POLICIES_INFO = record
cPolicyInfo: DWORD;
rgPolicyInfo: PCERT_POLICY_INFO;
end;
//+-------------------------------------------------------------------------
// RSA_CSP_PUBLICKEYBLOB
//
// pvStructInfo points to a PUBLICKEYSTRUC immediately followed by a
// RSAPUBKEY and the modulus bytes.
//
// CryptExportKey outputs the above StructInfo for a dwBlobType of
// PUBLICKEYBLOB. CryptImportKey expects the above StructInfo when
// importing a public key.
//
// For dwCertEncodingType = X509_ASN_ENCODING, the RSA_CSP_PUBLICKEYBLOB is
// encoded as a PKCS #1 RSAPublicKey consisting of a SEQUENCE of a
// modulus INTEGER and a publicExponent INTEGER. The modulus is encoded
// as being a unsigned integer. When decoded, if the modulus was encoded
// as unsigned integer with a leading 0 byte, the 0 byte is removed before
// converting to the CSP modulus bytes.
//
// For decode, the aiKeyAlg field of PUBLICKEYSTRUC is always set to
// CALG_RSA_KEYX.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_KEYGEN_REQUEST_TO_BE_SIGNED
//
// pvStructInfo points to CERT_KEYGEN_REQUEST_INFO.
//
// For CryptDecodeObject(), the pbEncoded is the "to be signed" plus its
// signature (output of a X509_CERT CryptEncodeObject()).
//
// For CryptEncodeObject(), the pbEncoded is just the "to be signed".
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// PKCS_ATTRIBUTE data structure
//
// pvStructInfo points to a CRYPT_ATTRIBUTE.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// PKCS_CONTENT_INFO_SEQUENCE_OF_ANY data structure
//
// pvStructInfo points to following CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY.
//
// For X509_ASN_ENCODING: encoded as a PKCS#7 ContentInfo structure wrapping
// a sequence of ANY. The value of the contentType field is pszObjId,
// while the content field is the following structure:
// SequenceOfAny ::= SEQUENCE OF ANY
//
// The CRYPT_DER_BLOBs point to the already encoded ANY content.
//--------------------------------------------------------------------------
type
PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY = ^CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY;
CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY = record
pszObjId: LPSTR;
cValue: DWORD;
rgValue: PCRYPT_DER_BLOB;
end;
//+-------------------------------------------------------------------------
// PKCS_CONTENT_INFO data structure
//
// pvStructInfo points to following CRYPT_CONTENT_INFO.
//
// For X509_ASN_ENCODING: encoded as a PKCS#7 ContentInfo structure.
// The CRYPT_DER_BLOB points to the already encoded ANY content.
//--------------------------------------------------------------------------
type
PCRYPT_CONTENT_INFO = ^CRYPT_CONTENT_INFO;
CRYPT_CONTENT_INFO = record
pszObjId: LPSTR;
Content: CRYPT_DER_BLOB;
end;
//+-------------------------------------------------------------------------
// X509_OCTET_STRING data structure
//
// pvStructInfo points to a CRYPT_DATA_BLOB.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_BITS data structure
//
// pvStructInfo points to a CRYPT_BIT_BLOB.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_INTEGER data structure
//
// pvStructInfo points to an int.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_MULTI_BYTE_INTEGER data structure
//
// pvStructInfo points to a CRYPT_INTEGER_BLOB.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_ENUMERATED data structure
//
// pvStructInfo points to an int containing the enumerated value
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_CHOICE_OF_TIME data structure
//
// pvStructInfo points to a FILETIME.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_SEQUENCE_OF_ANY data structure
//
// pvStructInfo points to following CRYPT_SEQUENCE_OF_ANY.
//
// The CRYPT_DER_BLOBs point to the already encoded ANY content.
//--------------------------------------------------------------------------
type
PCRYPT_SEQUENCE_OF_ANY = ^CRYPT_SEQUENCE_OF_ANY;
CRYPT_SEQUENCE_OF_ANY = record
cValue: DWORD;
rgValue: PCRYPT_DER_BLOB;
end;
//+-------------------------------------------------------------------------
// X509_AUTHORITY_KEY_ID2
// szOID_AUTHORITY_KEY_IDENTIFIER2
//
// pvStructInfo points to following CERT_AUTHORITY_KEY_ID2_INFO.
//
// For CRYPT_E_INVALID_IA5_STRING, the error location is returned in
// *pcbEncoded by CryptEncodeObject(X509_AUTHORITY_KEY_ID2)
//
// See X509_ALTERNATE_NAME for error location defines.
//--------------------------------------------------------------------------
type
PCERT_AUTHORITY_KEY_ID2_INFO = ^CERT_AUTHORITY_KEY_ID2_INFO;
CERT_AUTHORITY_KEY_ID2_INFO = record
KeyId: CRYPT_DATA_BLOB;
AuthorityCertIssuer: CERT_ALT_NAME_INFO; // Optional, set cAltEntry to 0 to omit.
AuthorityCertSerialNumber: CRYPT_INTEGER_BLOB;
end;
//+-------------------------------------------------------------------------
// szOID_SUBJECT_KEY_IDENTIFIER
//
// pvStructInfo points to a CRYPT_DATA_BLOB.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_CRL_REASON_CODE
// szOID_CRL_REASON_CODE
//
// pvStructInfo points to an int which can be set to one of the following
// enumerated values:
//--------------------------------------------------------------------------
const
CRL_REASON_UNSPECIFIED = 0;
CRL_REASON_KEY_COMPROMISE = 1;
CRL_REASON_CA_COMPROMISE = 2;
CRL_REASON_AFFILIATION_CHANGED = 3;
CRL_REASON_SUPERSEDED = 4;
CRL_REASON_CESSATION_OF_OPERATION = 5;
CRL_REASON_CERTIFICATE_HOLD = 6;
CRL_REASON_REMOVE_FROM_CRL = 8;
//+-------------------------------------------------------------------------
// X509_CRL_DIST_POINTS
// szOID_CRL_DIST_POINTS
//
// pvStructInfo points to following CRL_DIST_POINTS_INFO.
//
// For CRYPT_E_INVALID_IA5_STRING, the error location is returned in
// *pcbEncoded by CryptEncodeObject(X509_CRL_DIST_POINTS)
//
// Error location consists of:
// CRL_ISSUER_BIT - 1 bit << 31 (0 for FullName, 1 for CRLIssuer)
// POINT_INDEX - 7 bits << 24
// ENTRY_INDEX - 8 bits << 16
// VALUE_INDEX - 16 bits (unicode character index)
//
// See X509_ALTERNATE_NAME for ENTRY_INDEX and VALUE_INDEX error location
// defines.
//--------------------------------------------------------------------------
type
PCRL_DIST_POINT_NAME = ^CRL_DIST_POINT_NAME;
CRL_DIST_POINT_NAME = record
dwDistPointNameChoice: DWORD;
case integer of
0: (FullName: CERT_ALT_NAME_INFO); {1}
1: ({IssuerRDN :Not implemented}); {2}
end;
const
CRL_DIST_POINT_NO_NAME = 0;
CRL_DIST_POINT_FULL_NAME = 1;
CRL_DIST_POINT_ISSUER_RDN_NAME = 2;
type
PCRL_DIST_POINT = ^CRL_DIST_POINT;
CRL_DIST_POINT = record
DistPointName: CRL_DIST_POINT_NAME; // OPTIONAL
ReasonFlags: CRYPT_BIT_BLOB; // OPTIONAL
CRLIssuer: CERT_ALT_NAME_INFO; // OPTIONAL
end;
const
CRL_REASON_UNUSED_FLAG = $80;
CRL_REASON_KEY_COMPROMISE_FLAG = $40;
CRL_REASON_CA_COMPROMISE_FLAG = $20;
CRL_REASON_AFFILIATION_CHANGED_FLAG = $10;
CRL_REASON_SUPERSEDED_FLAG = $08;
CRL_REASON_CESSATION_OF_OPERATION_FLAG = $04;
CRL_REASON_CERTIFICATE_HOLD_FLAG = $02;
type
PCRL_DIST_POINTS_INFO = ^CRL_DIST_POINTS_INFO;
CRL_DIST_POINTS_INFO = record
cDistPoint: DWORD;
rgDistPoint: PCRL_DIST_POINT;
end;
const
CRL_DIST_POINT_ERR_INDEX_MASK = $7F;
CRL_DIST_POINT_ERR_INDEX_SHIFT = 24;
{#define GET_CRL_DIST_POINT_ERR_INDEX(X) \
((X >> CRL_DIST_POINT_ERR_INDEX_SHIFT) & CRL_DIST_POINT_ERR_INDEX_MASK)}
function GET_CRL_DIST_POINT_ERR_INDEX(X: DWORD): DWORD;
const CRL_DIST_POINT_ERR_CRL_ISSUER_BIT = (DWORD($80000000));
{#define IS_CRL_DIST_POINT_ERR_CRL_ISSUER(X) \
(0 != (X & CRL_DIST_POINT_ERR_CRL_ISSUER_BIT))}
function IS_CRL_DIST_POINT_ERR_CRL_ISSUER(X: DWORD): BOOL;
//+-------------------------------------------------------------------------
// X509_ENHANCED_KEY_USAGE
// szOID_ENHANCED_KEY_USAGE
//
// pvStructInfo points to a CERT_ENHKEY_USAGE, CTL_USAGE.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// szOID_NEXT_UPDATE_LOCATION
//
// pvStructInfo points to a CERT_ALT_NAME_INFO.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// PKCS_CTL
// szOID_CTL
//
// pvStructInfo points to a CTL_INFO.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_MULTI_BYTE_UINT
//
// pvStructInfo points to a CRYPT_UINT_BLOB. Before encoding, inserts a
// leading 0x00. After decoding, removes a leading 0x00.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_DSS_PUBLICKEY
//
// pvStructInfo points to a CRYPT_UINT_BLOB.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// X509_DSS_PARAMETERS
//
// pvStructInfo points to following CERT_DSS_PARAMETERS data structure.
//--------------------------------------------------------------------------
type
PCERT_DSS_PARAMETERS = ^CERT_DSS_PARAMETERS;
CERT_DSS_PARAMETERS = record
p: CRYPT_UINT_BLOB;
q: CRYPT_UINT_BLOB;
g: CRYPT_UINT_BLOB;
end;
//+-------------------------------------------------------------------------
// X509_DSS_SIGNATURE
//
// pvStructInfo is a BYTE rgbSignature[CERT_DSS_SIGNATURE_LEN]. The
// bytes are ordered as output by the DSS CSP's CryptSignHash().
//--------------------------------------------------------------------------
const
CERT_DSS_R_LEN = 20;
CERT_DSS_S_LEN = 20;
CERT_DSS_SIGNATURE_LEN = (CERT_DSS_R_LEN + CERT_DSS_S_LEN);
// Sequence of 2 unsigned integers (the extra +1 is for a potential leading
// 0x00 to make the integer unsigned)
CERT_MAX_ASN_ENCODED_DSS_SIGNATURE_LEN = (2 + 2 * (2 + 20 + 1));
//+-------------------------------------------------------------------------
// PKCS_RC2_CBC_PARAMETERS
// szOID_RSA_RC2CBC
//
// pvStructInfo points to following CRYPT_RC2_CBC_PARAMETERS data structure.
//--------------------------------------------------------------------------
type
PCRYPT_RC2_CBC_PARAMETERS = ^CRYPT_RC2_CBC_PARAMETERS;
CRYPT_RC2_CBC_PARAMETERS = record
dwVersion: DWORD;
fIV: BOOL; // set if has following IV
rgbIV: array[0..8 - 1] of BYTE;
end;
const
CRYPT_RC2_40BIT_VERSION = 160;
CRYPT_RC2_64BIT_VERSION = 120;
CRYPT_RC2_128BIT_VERSION = 58;
//+-------------------------------------------------------------------------
// PKCS_SMIME_CAPABILITIES
// szOID_RSA_SMIMECapabilities
//
// pvStructInfo points to following CRYPT_SMIME_CAPABILITIES data structure.
//
// Note, for CryptEncodeObject(X509_ASN_ENCODING), Parameters.cbData == 0
// causes the encoded parameters to be omitted and not encoded as a NULL
// (05 00) as is done when encoding a CRYPT_ALGORITHM_IDENTIFIER. This
// is per the SMIME specification for encoding capabilities.
//--------------------------------------------------------------------------
type
PCRYPT_SMIME_CAPABILITY = ^CRYPT_SMIME_CAPABILITY;
CRYPT_SMIME_CAPABILITY = record
pszObjId: LPSTR;
Parameters: CRYPT_OBJID_BLOB;
end;
type
PCRYPT_SMIME_CAPABILITIES = ^CRYPT_SMIME_CAPABILITIES;
CRYPT_SMIME_CAPABILITIES = record
cCapability: DWORD;
rgCapability: PCRYPT_SMIME_CAPABILITY;
end;
//+-------------------------------------------------------------------------
// PKCS7_SIGNER_INFO
//
// pvStructInfo points to CMSG_SIGNER_INFO.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// Netscape Certificate Extension Object Identifiers
//--------------------------------------------------------------------------
const
szOID_NETSCAPE = '2.16.840.1.113730';
szOID_NETSCAPE_CERT_EXTENSION = '2.16.840.1.113730.1';
szOID_NETSCAPE_CERT_TYPE = '2.16.840.1.113730.1.1';
szOID_NETSCAPE_BASE_URL = '2.16.840.1.113730.1.2';
szOID_NETSCAPE_REVOCATION_URL = '2.16.840.1.113730.1.3';
szOID_NETSCAPE_CA_REVOCATION_URL = '2.16.840.1.113730.1.4';
szOID_NETSCAPE_CERT_RENEWAL_URL = '2.16.840.1.113730.1.7';
szOID_NETSCAPE_CA_POLICY_URL = '2.16.840.1.113730.1.8';
szOID_NETSCAPE_SSL_SERVER_NAME = '2.16.840.1.113730.1.12';
szOID_NETSCAPE_COMMENT = '2.16.840.1.113730.1.13';
//+-------------------------------------------------------------------------
// Netscape Certificate Data Type Object Identifiers
//--------------------------------------------------------------------------
const
szOID_NETSCAPE_DATA_TYPE = '2.16.840.1.113730.2';
szOID_NETSCAPE_CERT_SEQUENCE = '2.16.840.1.113730.2.5';
//+-------------------------------------------------------------------------
// szOID_NETSCAPE_CERT_TYPE extension
//
// Its value is a bit string. CryptDecodeObject/CryptEncodeObject using
// X509_BITS.
//
// The following bits are defined:
//--------------------------------------------------------------------------
const
NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE = $80;
NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE = $40;
NETSCAPE_SSL_CA_CERT_TYPE = $04;
//+-------------------------------------------------------------------------
// szOID_NETSCAPE_BASE_URL extension
//
// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using
// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,
// dwValueType = CERT_RDN_IA5_STRING.
//
// When present this string is added to the beginning of all relative URLs
// in the certificate. This extension can be considered an optimization
// to reduce the size of the URL extensions.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// szOID_NETSCAPE_REVOCATION_URL extension
//
// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using
// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,
// dwValueType = CERT_RDN_IA5_STRING.
//
// It is a relative or absolute URL that can be used to check the
// revocation status of a certificate. The revocation check will be
// performed as an HTTP GET method using a url that is the concatenation of
// revocation-url and certificate-serial-number.
// Where the certificate-serial-number is encoded as a string of
// ascii hexadecimal digits. For example, if the netscape-base-url is
// https://www.certs-r-us.com/, the netscape-revocation-url is
// cgi-bin/check-rev.cgi?, and the certificate serial number is 173420,
// the resulting URL would be:
// https://www.certs-r-us.com/cgi-bin/check-rev.cgi?02a56c
//
// The server should return a document with a Content-Type of
// application/x-netscape-revocation. The document should contain
// a single ascii digit, '1' if the certificate is not curently valid,
// and '0' if it is curently valid.
//
// Note: for all of the URLs that include the certificate serial number,
// the serial number will be encoded as a string which consists of an even
// number of hexadecimal digits. If the number of significant digits is odd,
// the string will have a single leading zero to ensure an even number of
// digits is generated.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// szOID_NETSCAPE_CA_REVOCATION_URL extension
//
// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using
// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,
// dwValueType = CERT_RDN_IA5_STRING.
//
// It is a relative or absolute URL that can be used to check the
// revocation status of any certificates that are signed by the CA that
// this certificate belongs to. This extension is only valid in CA
// certificates. The use of this extension is the same as the above
// szOID_NETSCAPE_REVOCATION_URL extension.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// szOID_NETSCAPE_CERT_RENEWAL_URL extension
//
// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using
// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,
// dwValueType = CERT_RDN_IA5_STRING.
//
// It is a relative or absolute URL that points to a certificate renewal
// form. The renewal form will be accessed with an HTTP GET method using a
// url that is the concatenation of renewal-url and
// certificate-serial-number. Where the certificate-serial-number is
// encoded as a string of ascii hexadecimal digits. For example, if the
// netscape-base-url is https://www.certs-r-us.com/, the
// netscape-cert-renewal-url is cgi-bin/check-renew.cgi?, and the
// certificate serial number is 173420, the resulting URL would be:
// https://www.certs-r-us.com/cgi-bin/check-renew.cgi?02a56c
// The document returned should be an HTML form that will allow the user
// to request a renewal of their certificate.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// szOID_NETSCAPE_CA_POLICY_URL extension
//
// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using
// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,
// dwValueType = CERT_RDN_IA5_STRING.
//
// It is a relative or absolute URL that points to a web page that
// describes the policies under which the certificate was issued.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// szOID_NETSCAPE_SSL_SERVER_NAME extension
//
// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using
// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,
// dwValueType = CERT_RDN_IA5_STRING.
//
// It is a "shell expression" that can be used to match the hostname of the
// SSL server that is using this certificate. It is recommended that if
// the server's hostname does not match this pattern the user be notified
// and given the option to terminate the SSL connection. If this extension
// is not present then the CommonName in the certificate subject's
// distinguished name is used for the same purpose.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// szOID_NETSCAPE_COMMENT extension
//
// Its value is an IA5_STRING. CryptDecodeObject/CryptEncodeObject using
// X509_ANY_STRING or X509_UNICODE_ANY_STRING, where,
// dwValueType = CERT_RDN_IA5_STRING.
//
// It is a comment that may be displayed to the user when the certificate
// is viewed.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// szOID_NETSCAPE_CERT_SEQUENCE
//
// Its value is a PKCS#7 ContentInfo structure wrapping a sequence of
// certificates. The value of the contentType field is
// szOID_NETSCAPE_CERT_SEQUENCE, while the content field is the following
// structure:
// CertificateSequence ::= SEQUENCE OF Certificate.
//
// CryptDecodeObject/CryptEncodeObject using
// PKCS_CONTENT_INFO_SEQUENCE_OF_ANY, where,
// pszObjId = szOID_NETSCAPE_CERT_SEQUENCE and the CRYPT_DER_BLOBs point
// to encoded X509 certificates.
//--------------------------------------------------------------------------
//+=========================================================================
// Object IDentifier (OID) Installable Functions: Data Structures and APIs
//==========================================================================
type
HCRYPTOIDFUNCSET = procedure;
HCRYPTOIDFUNCADDR = procedure;
// Predefined OID Function Names
const
CRYPT_OID_ENCODE_OBJECT_FUNC = 'CryptDllEncodeObject';
CRYPT_OID_DECODE_OBJECT_FUNC = 'CryptDllDecodeObject';
CRYPT_OID_CREATE_COM_OBJECT_FUNC = 'CryptDllCreateCOMObject';
CRYPT_OID_VERIFY_REVOCATION_FUNC = 'CertDllVerifyRevocation';
CRYPT_OID_VERIFY_CTL_USAGE_FUNC = 'CertDllVerifyCTLUsage';
CRYPT_OID_FORMAT_OBJECT_FUNC = 'CryptDllFormatObject';
CRYPT_OID_FIND_OID_INFO_FUNC = 'CryptDllFindOIDInfo';
// CryptDllEncodeObject has same function signature as CryptEncodeObject.
// CryptDllDecodeObject has same function signature as CryptDecodeObject.
// CryptDllCreateCOMObject has the following signature:
// BOOL WINAPI CryptDllCreateCOMObject(
// IN DWORD dwEncodingType,
// IN LPCSTR pszOID,
// IN PCRYPT_DATA_BLOB pEncodedContent,
// IN DWORD dwFlags,
// IN REFIID riid,
// OUT void **ppvObj);
// CertDllVerifyRevocation has the same signature as CertVerifyRevocation
// (See CertVerifyRevocation for details on when called)
// CertDllVerifyCTLUsage has the same signature as CertVerifyCTLUsage
// CryptDllFindOIDInfo currently is only used to store values used by
// CryptFindOIDInfo. See CryptFindOIDInfo() for more details.
// Example of a complete OID Function Registry Name:
// HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\OID
// Encoding Type 1\CryptDllEncodeObject\1.2.3
//
// The key's L"Dll" value contains the name of the Dll.
// The key's L"FuncName" value overrides the default function name
const
CRYPT_OID_REGPATH = 'Software\\Microsoft\\Cryptography\\OID';
CRYPT_OID_REG_ENCODING_TYPE_PREFIX = 'EncodingType ';
{$IFNDEF VER90}
CRYPT_OID_REG_DLL_VALUE_NAME = WideString('Dll');
CRYPT_OID_REG_FUNC_NAME_VALUE_NAME = WideString('FuncName');
{$ELSE}
CRYPT_OID_REG_DLL_VALUE_NAME = ('Dll');
CRYPT_OID_REG_FUNC_NAME_VALUE_NAME = ('FuncName');
{$ENDIF}
CRYPT_OID_REG_FUNC_NAME_VALUE_NAME_A = 'FuncName';
// OID used for Default OID functions
CRYPT_DEFAULT_OID = 'DEFAULT';
type
PCRYPT_OID_FUNC_ENTRY = ^CRYPT_OID_FUNC_ENTRY;
CRYPT_OID_FUNC_ENTRY = record
pszOID: LPCSTR;
pvFuncAddr: PVOID;
end;
const
CRYPT_INSTALL_OID_FUNC_BEFORE_FLAG = 1;
//+-------------------------------------------------------------------------
// Install a set of callable OID function addresses.
//
// By default the functions are installed at end of the list.
// Set CRYPT_INSTALL_OID_FUNC_BEFORE_FLAG to install at beginning of list.
//
// hModule should be updated with the hModule passed to DllMain to prevent
// the Dll containing the function addresses from being unloaded by
// CryptGetOIDFuncAddress/CryptFreeOIDFunctionAddress. This would be the
// case when the Dll has also regsvr32'ed OID functions via
// CryptRegisterOIDFunction.
//
// DEFAULT functions are installed by setting rgFuncEntry[].pszOID =
// CRYPT_DEFAULT_OID.
//--------------------------------------------------------------------------
function CryptInstallOIDFunctionAddress(hModule: HMODULE; // hModule passed to DllMain
dwEncodingType: DWORD;
pszFuncName: LPCSTR;
cFuncEntry: DWORD;
const rgFuncEntry: array of CRYPT_OID_FUNC_ENTRY;
dwFlags: DWORD): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Initialize and return handle to the OID function set identified by its
// function name.
//
// If the set already exists, a handle to the existing set is returned.
//--------------------------------------------------------------------------
function CryptInitOIDFunctionSet(pszFuncName: LPCSTR;
dwFlags: DWORD): HCRYPTOIDFUNCSET; stdcall;
//+-------------------------------------------------------------------------
// Search the list of installed functions for an encoding type and OID match.
// If not found, search the registry.
//
// For success, returns TRUE with *ppvFuncAddr updated with the function's
// address and *phFuncAddr updated with the function address's handle.
// The function's handle is AddRef'ed. CryptFreeOIDFunctionAddress needs to
// be called to release it.
//
// For a registry match, the Dll containing the function is loaded.
//--------------------------------------------------------------------------
function CryptGetOIDFunctionAddress(hFuncSet: HCRYPTOIDFUNCSET;
dwEncodingType: DWORD;
pszOID: LPCSTR;
dwFlags: DWORD;
var ppvFuncAddr: array of PVOID;
var phFuncAddr: HCRYPTOIDFUNCADDR): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Get the list of registered default Dll entries for the specified
// function set and encoding type.
//
// The returned list consists of none, one or more null terminated Dll file
// names. The list is terminated with an empty (L"\0") Dll file name.
// For example: L"first.dll" L"\0" L"second.dll" L"\0" L"\0"
//--------------------------------------------------------------------------
function CryptGetDefaultOIDDllList(hFuncSet: HCRYPTOIDFUNCSET;
dwEncodingType: DWORD;
pwszDllList: LPWSTR;
pcchDllList: PDWORD): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Either: get the first or next installed DEFAULT function OR
// load the Dll containing the DEFAULT function.
//
// If pwszDll is NULL, search the list of installed DEFAULT functions.
// *phFuncAddr must be set to NULL to get the first installed function.
// Successive installed functions are returned by setting *phFuncAddr
// to the hFuncAddr returned by the previous call.
//
// If pwszDll is NULL, the input *phFuncAddr
// is always CryptFreeOIDFunctionAddress'ed by this function, even for
// an error.
//
// If pwszDll isn't NULL, then, attempts to load the Dll and the DEFAULT
// function. *phFuncAddr is ignored upon entry and isn't
// CryptFreeOIDFunctionAddress'ed.
//
// For success, returns TRUE with *ppvFuncAddr updated with the function's
// address and *phFuncAddr updated with the function address's handle.
// The function's handle is AddRef'ed. CryptFreeOIDFunctionAddress needs to
// be called to release it or CryptGetDefaultOIDFunctionAddress can also
// be called for a NULL pwszDll.
//--------------------------------------------------------------------------
function CryptGetDefaultOIDFunctionAddress(hFuncSet: HCRYPTOIDFUNCSET;
dwEncodingType: DWORD;
pwszDll: DWORD;
dwFlags: LPCWSTR;
var ppvFuncAddr: array of PVOID;
var phFuncAddr: HCRYPTOIDFUNCADDR): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Releases the handle AddRef'ed and returned by CryptGetOIDFunctionAddress
// or CryptGetDefaultOIDFunctionAddress.
//
// If a Dll was loaded for the function its unloaded. However, before doing
// the unload, the DllCanUnloadNow function exported by the loaded Dll is
// called. It should return S_FALSE to inhibit the unload or S_TRUE to enable
// the unload. If the Dll doesn't export DllCanUnloadNow, the Dll is unloaded.
//
// DllCanUnloadNow has the following signature:
// STDAPI DllCanUnloadNow(void);
//--------------------------------------------------------------------------
function CryptFreeOIDFunctionAddress(hFuncAddr: HCRYPTOIDFUNCADDR;
dwFlags: DWORD): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Register the Dll containing the function to be called for the specified
// encoding type, function name and OID.
//
// pwszDll may contain environment-variable strings
// which are ExpandEnvironmentStrings()'ed before loading the Dll.
//
// In addition to registering the DLL, you may override the
// name of the function to be called. For example,
// pszFuncName = "CryptDllEncodeObject",
// pszOverrideFuncName = "MyEncodeXyz".
// This allows a Dll to export multiple OID functions for the same
// function name without needing to interpose its own OID dispatcher function.
//--------------------------------------------------------------------------
function CryptRegisterOIDFunction(dwEncodingType: DWORD;
pszFuncName: LPCSTR;
pszOID: LPCSTR; //OPTIONAL
pwszDll: LPCWSTR; //OPTIONAL
pszOverrideFuncName: LPCSTR): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Unregister the Dll containing the function to be called for the specified
// encoding type, function name and OID.
//--------------------------------------------------------------------------
function CryptUnregisterOIDFunction(dwEncodingType: DWORD;
pszFuncName: LPCSTR;
pszOID: LPCSTR): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Register the Dll containing the default function to be called for the
// specified encoding type and function name.
//
// Unlike CryptRegisterOIDFunction, you can't override the function name
// needing to be exported by the Dll.
//
// The Dll is inserted before the entry specified by dwIndex.
// dwIndex == 0, inserts at the beginning.
// dwIndex == CRYPT_REGISTER_LAST_INDEX, appends at the end.
//
// pwszDll may contain environment-variable strings
// which are ExpandEnvironmentStrings()'ed before loading the Dll.
//--------------------------------------------------------------------------
function CryptRegisterDefaultOIDFunction(dwEncodingType: DWORD;
pszFuncName: LPCSTR;
dwIndex: DWORD;
pwszDll: LPCWSTR): BOOL; stdcall;
const
CRYPT_REGISTER_FIRST_INDEX = 0;
CRYPT_REGISTER_LAST_INDEX = $FFFFFFFF;
//+-------------------------------------------------------------------------
// Unregister the Dll containing the default function to be called for
// the specified encoding type and function name.
//--------------------------------------------------------------------------
function CryptUnregisterDefaultOIDFunction(dwEncodingType: DWORD;
pszFuncName: LPCSTR;
pwszDll: LPCWSTR): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Set the value for the specified encoding type, function name, OID and
// value name.
//
// See RegSetValueEx for the possible value types.
//
// String types are UNICODE.
//--------------------------------------------------------------------------
function CryptSetOIDFunctionValue(dwEncodingType: DWORD;
pszFuncName: LPCSTR;
pszOID: LPCSTR;
pwszValueName: LPCWSTR;
dwValueType: DWORD;
const pbValueData: PBYTE;
cbValueData: DWORD): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Get the value for the specified encoding type, function name, OID and
// value name.
//
// See RegEnumValue for the possible value types.
//
// String types are UNICODE.
//--------------------------------------------------------------------------
function CryptGetOIDFunctionValue(dwEncodingType: DWORD;
pszFuncName: LPCSTR;
pwszValueName: LPCSTR;
pszOID: LPCWSTR;
pdwValueType: PDWORD;
pbValueData: PBYTE;
pcbValueData: PDWORD): BOOL; stdcall;
type
PFN_CRYPT_ENUM_OID_FUNC = function(dwEncodingType: DWORD;
pszFuncName: LPCSTR;
pszOID: LPCSTR;
cValue: DWORD;
const rgdwValueType: array of DWORD;
const rgpwszValueName: array of LPCWSTR;
const rgpbValueData: array of PBYTE;
const rgcbValueData: array of DWORD;
pvArg: PVOID): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Enumerate the OID functions identified by their encoding type,
// function name and OID.
//
// pfnEnumOIDFunc is called for each registry key matching the input
// parameters. Setting dwEncodingType to CRYPT_MATCH_ANY_ENCODING_TYPE matches
// any. Setting pszFuncName or pszOID to NULL matches any.
//
// Set pszOID == CRYPT_DEFAULT_OID to restrict the enumeration to only the
// DEFAULT functions
//
// String types are UNICODE.
//--------------------------------------------------------------------------
function CryptEnumOIDFunction(dwEncodingType: DWORD;
pszFuncName: LPCSTR; //OPTIONAL
pszOID: LPCSTR; //OPTIONAL
dwFlags: DWORD;
pvArg: PVOID;
pfnEnumOIDFunc: PFN_CRYPT_ENUM_OID_FUNC): BOOL; stdcall;
const
CRYPT_MATCH_ANY_ENCODING_TYPE = $FFFFFFFF;
//+=========================================================================
// Object IDentifier (OID) Information: Data Structures and APIs
//==========================================================================
//+-------------------------------------------------------------------------
// OID Information
//--------------------------------------------------------------------------
type
PCRYPT_OID_INFO = ^CRYPT_OID_INFO;
CRYPT_OID_INFO = record
cbSize: DWORD;
pszOID: LPCSTR;
pwszName: LPCWSTR;
dwGroupId: DWORD;
EnumValue: record {type EnumValue for the union part of the original struct --max--}
case integer of
0: (dwValue: DWORD);
1: (Algid: ALG_ID);
2: (dwLength: DWORD);
end;
ExtraInfo: CRYPT_DATA_BLOB;
end;
type
CCRYPT_OID_INFO = CRYPT_OID_INFO;
PCCRYPT_OID_INFO = ^CCRYPT_OID_INFO;
//+-------------------------------------------------------------------------
// OID Group IDs
//--------------------------------------------------------------------------
const
CRYPT_HASH_ALG_OID_GROUP_ID = 1;
CRYPT_ENCRYPT_ALG_OID_GROUP_ID = 2;
CRYPT_PUBKEY_ALG_OID_GROUP_ID = 3;
CRYPT_SIGN_ALG_OID_GROUP_ID = 4;
CRYPT_RDN_ATTR_OID_GROUP_ID = 5;
CRYPT_EXT_OR_ATTR_OID_GROUP_ID = 6;
CRYPT_ENHKEY_USAGE_OID_GROUP_ID = 7;
CRYPT_POLICY_OID_GROUP_ID = 8;
CRYPT_LAST_OID_GROUP_ID = 8;
CRYPT_FIRST_ALG_OID_GROUP_ID = CRYPT_HASH_ALG_OID_GROUP_ID;
CRYPT_LAST_ALG_OID_GROUP_ID = CRYPT_SIGN_ALG_OID_GROUP_ID;
// The CRYPT_*_ALG_OID_GROUP_ID's have an Algid. The CRYPT_RDN_ATTR_OID_GROUP_ID
// has a dwLength. The CRYPT_EXT_OR_ATTR_OID_GROUP_ID,
// CRYPT_ENHKEY_USAGE_OID_GROUP_ID or CRYPT_POLICY_OID_GROUP_ID don't have a
// dwValue.
// CRYPT_PUBKEY_ALG_OID_GROUP_ID has the following optional ExtraInfo:
// DWORD[0] - Flags. CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG can be set to
// inhibit the reformatting of the signature before
// CryptVerifySignature is called or after CryptSignHash
// is called. CRYPT_OID_USE_PUBKEY_PARA_FOR_PKCS7_FLAG can
// be set to include the public key algorithm's parameters
// in the PKCS7's digestEncryptionAlgorithm's parameters.
CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG = $1;
CRYPT_OID_USE_PUBKEY_PARA_FOR_PKCS7_FLAG = $2;
// CRYPT_SIGN_ALG_OID_GROUP_ID has the following optional ExtraInfo:
// DWORD[0] - Public Key Algid.
// DWORD[1] - Flags. Same as above for CRYPT_PUBKEY_ALG_OID_GROUP_ID.
// CRYPT_RDN_ATTR_OID_GROUP_ID has the following optional ExtraInfo:
// Array of DWORDs:
// [0 ..] - Null terminated list of acceptable RDN attribute
// value types. An empty list implies CERT_RDN_PRINTABLE_STRING,
// CERT_RDN_T61_STRING, 0.
//+-------------------------------------------------------------------------
// Find OID information. Returns NULL if unable to find any information
// for the specified key and group. Note, returns a pointer to a constant
// data structure. The returned pointer MUST NOT be freed.
//
// dwKeyType's:
// CRYPT_OID_INFO_OID_KEY, pvKey points to a szOID
// CRYPT_OID_INFO_NAME_KEY, pvKey points to a wszName
// CRYPT_OID_INFO_ALGID_KEY, pvKey points to an ALG_ID
// CRYPT_OID_INFO_SIGN_KEY, pvKey points to an array of two ALG_ID's:
// ALG_ID[0] - Hash Algid
// ALG_ID[1] - PubKey Algid
//
// Setting dwGroupId to 0, searches all groups according to the dwKeyType.
// Otherwise, only the dwGroupId is searched.
//--------------------------------------------------------------------------
function CryptFindOIDInfo(dwKeyType: DWORD;
pvKey: PVOID;
dwGroupId: DWORD): PCCRYPT_OID_INFO; stdcall;
const
CRYPT_OID_INFO_OID_KEY = 1;
CRYPT_OID_INFO_NAME_KEY = 2;
CRYPT_OID_INFO_ALGID_KEY = 3;
CRYPT_OID_INFO_SIGN_KEY = 4;
//+-------------------------------------------------------------------------
// Register OID information. The OID information specified in the
// CCRYPT_OID_INFO structure is persisted to the registry.
//
// crypt32.dll contains information for the commonly known OIDs. This function
// allows applications to augment crypt32.dll's OID information. During
// CryptFindOIDInfo's first call, the registered OID information is installed.
//
// By default the registered OID information is installed after crypt32.dll's
// OID entries. Set CRYPT_INSTALL_OID_INFO_BEFORE_FLAG to install before.
//--------------------------------------------------------------------------
function CryptRegisterOIDInfo(pInfo: PCCRYPT_OID_INFO;
dwFlags: DWORD): BOOL; stdcall;
const
CRYPT_INSTALL_OID_INFO_BEFORE_FLAG = 1;
//+-------------------------------------------------------------------------
// Unregister OID information. Only the pszOID and dwGroupId fields are
// used to identify the OID information to be unregistered.
//--------------------------------------------------------------------------
function CryptUnregisterOIDInfo(pInfo: PCCRYPT_OID_INFO): BOOL; stdcall;
//+=========================================================================
// Low Level Cryptographic Message Data Structures and APIs
//==========================================================================
type
HCRYPTMSG = Pointer;
const
szOID_PKCS_7_DATA = '1.2.840.113549.1.7.1';
szOID_PKCS_7_SIGNED = '1.2.840.113549.1.7.2';
szOID_PKCS_7_ENVELOPED = '1.2.840.113549.1.7.3';
szOID_PKCS_7_SIGNEDANDENVELOPED = '1.2.840.113549.1.7.4';
szOID_PKCS_7_DIGESTED = '1.2.840.113549.1.7.5';
szOID_PKCS_7_ENCRYPTED = '1.2.840.113549.1.7.6';
szOID_PKCS_9_CONTENT_TYPE = '1.2.840.113549.1.9.3';
szOID_PKCS_9_MESSAGE_DIGEST = '1.2.840.113549.1.9.4';
//+-------------------------------------------------------------------------
// Message types
//--------------------------------------------------------------------------
const
CMSG_DATA = 1;
CMSG_SIGNED = 2;
CMSG_ENVELOPED = 3;
CMSG_SIGNED_AND_ENVELOPED = 4;
CMSG_HASHED = 5;
CMSG_ENCRYPTED = 6;
//+-------------------------------------------------------------------------
// Message Type Bit Flags
//--------------------------------------------------------------------------
CMSG_ALL_FLAGS = (not ULONG(0));
CMSG_DATA_FLAG = (1 shl CMSG_DATA);
CMSG_SIGNED_FLAG = (1 shl CMSG_SIGNED);
CMSG_ENVELOPED_FLAG = (1 shl CMSG_ENVELOPED);
CMSG_SIGNED_AND_ENVELOPED_FLAG = (1 shl CMSG_SIGNED_AND_ENVELOPED);
CMSG_HASHED_FLAG = (1 shl CMSG_HASHED);
CMSG_ENCRYPTED_FLAG = (1 shl CMSG_ENCRYPTED);
//+-------------------------------------------------------------------------
// The message encode information (pvMsgEncodeInfo) is message type dependent
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_DATA: pvMsgEncodeInfo = NULL
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_SIGNED
//
// The pCertInfo in the CMSG_SIGNER_ENCODE_INFO provides the Issuer, SerialNumber
// and PublicKeyInfo.Algorithm. The PublicKeyInfo.Algorithm implicitly
// specifies the HashEncryptionAlgorithm to be used.
//
// The hCryptProv and dwKeySpec specify the private key to use. If dwKeySpec
// == 0, then, defaults to AT_SIGNATURE.
//
// pvHashAuxInfo currently isn't used and must be set to NULL.
//--------------------------------------------------------------------------
type
PCMSG_SIGNER_ENCODE_INFO = ^CMSG_SIGNER_ENCODE_INFO;
CMSG_SIGNER_ENCODE_INFO = record
cbSize: DWORD;
pCertInfo: PCERT_INFO;
hCryptProv: HCRYPTPROV;
dwKeySpec: DWORD;
HashAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
pvHashAuxInfo: PVOID;
cAuthAttr: DWORD;
rgAuthAttr: PCRYPT_ATTRIBUTE;
cUnauthAttr: DWORD;
rgUnauthAttr: PCRYPT_ATTRIBUTE;
end;
type
PCMSG_SIGNED_ENCODE_INFO = ^CMSG_SIGNED_ENCODE_INFO;
CMSG_SIGNED_ENCODE_INFO = record
cbSize: DWORD;
cSigners: DWORD;
rgSigners: PCMSG_SIGNER_ENCODE_INFO;
cCertEncoded: DWORD;
rgCertEncoded: PCERT_BLOB;
cCrlEncoded: DWORD;
rgCrlEncoded: PCRL_BLOB;
end;
//+-------------------------------------------------------------------------
// CMSG_ENVELOPED
//
// The PCERT_INFO for the rgRecipients provides the Issuer, SerialNumber
// and PublicKeyInfo. The PublicKeyInfo.Algorithm implicitly
// specifies the KeyEncryptionAlgorithm to be used.
//
// The PublicKeyInfo.PublicKey in PCERT_INFO is used to encrypt the content
// encryption key for the recipient.
//
// hCryptProv is used to do the content encryption, recipient key encryption
// and export. The hCryptProv's private keys aren't used.
//
// Note: CAPI currently doesn't support more than one KeyEncryptionAlgorithm
// per provider. This will need to be fixed.
//
// pvEncryptionAuxInfo currently isn't used and must be set to NULL.
//--------------------------------------------------------------------------
type
PCMSG_ENVELOPED_ENCODE_INFO = ^CMSG_ENVELOPED_ENCODE_INFO;
CMSG_ENVELOPED_ENCODE_INFO = record
cbSize: DWORD;
hCryptProv: HCRYPTPROV;
ContentEncryptionAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
pvEncryptionAuxInfo: PVOID;
cRecipients: DWORD;
rgpRecipients: PPCERT_INFO; // pointer to array of PCERT_INFO
end;
//+-------------------------------------------------------------------------
// CMSG_SIGNED_AND_ENVELOPED
//
// For PKCS #7, a signed and enveloped message doesn't have the
// signer's authenticated or unauthenticated attributes. Otherwise, a
// combination of the CMSG_SIGNED_ENCODE_INFO and CMSG_ENVELOPED_ENCODE_INFO.
//--------------------------------------------------------------------------
type
PCMSG_SIGNED_AND_ENVELOPED_ENCODE_INFO = ^CMSG_SIGNED_AND_ENVELOPED_ENCODE_INFO;
CMSG_SIGNED_AND_ENVELOPED_ENCODE_INFO = record
cbSize: DWORD;
SignedInfo: CMSG_SIGNED_ENCODE_INFO;
EnvelopedInfo: CMSG_ENVELOPED_ENCODE_INFO;
end;
//+-------------------------------------------------------------------------
// CMSG_HASHED
//
// hCryptProv is used to do the hash. Doesn't need to use a private key.
//
// If fDetachedHash is set, then, the encoded message doesn't contain
// any content (its treated as NULL Data)
//
// pvHashAuxInfo currently isn't used and must be set to NULL.
//--------------------------------------------------------------------------
type
PCMSG_HASHED_ENCODE_INFO = ^CMSG_HASHED_ENCODE_INFO;
CMSG_HASHED_ENCODE_INFO = record
cbSize: DWORD;
hCryptProv: HCRYPTPROV;
HashAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
pvHashAuxInfo: PVOID;
end;
//+-------------------------------------------------------------------------
// CMSG_ENCRYPTED
//
// The key used to encrypt the message is identified outside of the message
// content (for example, password).
//
// The content input to CryptMsgUpdate has already been encrypted.
//
// pvEncryptionAuxInfo currently isn't used and must be set to NULL.
//--------------------------------------------------------------------------
type
PCMSG_ENCRYPTED_ENCODE_INFO = ^CMSG_ENCRYPTED_ENCODE_INFO;
CMSG_ENCRYPTED_ENCODE_INFO = record
cbSize: DWORD;
ContentEncryptionAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
pvEncryptionAuxInfo: PVOID;
end;
//+-------------------------------------------------------------------------
// This parameter allows messages to be of variable length with streamed
// output.
//
// By default, messages are of a definite length and
// CryptMsgGetParam(CMSG_CONTENT_PARAM) is
// called to get the cryptographically processed content. Until closed,
// the handle keeps a copy of the processed content.
//
// With streamed output, the processed content can be freed as its streamed.
//
// If the length of the content to be updated is known at the time of the
// open, then, ContentLength should be set to that length. Otherwise, it
// should be set to CMSG_INDEFINITE_LENGTH.
//--------------------------------------------------------------------------
type
PFN_CMSG_STREAM_OUTPUT = function(
const pvArg: PVOID;
pbData: PBYTE;
cbData: DWORD;
fFinal: BOOL): BOOL; stdcall;
const
CMSG_INDEFINITE_LENGTH = ($FFFFFFFF);
type
PCMSG_STREAM_INFO = ^CMSG_STREAM_INFO;
CMSG_STREAM_INFO = record
cbContent: DWORD;
pfnStreamOutput: PFN_CMSG_STREAM_OUTPUT;
pvArg: PVOID;
end;
//+-------------------------------------------------------------------------
// Open dwFlags
//--------------------------------------------------------------------------
const
CMSG_BARE_CONTENT_FLAG = $00000001;
CMSG_LENGTH_ONLY_FLAG = $00000002;
CMSG_DETACHED_FLAG = $00000004;
CMSG_AUTHENTICATED_ATTRIBUTES_FLAG = $00000008;
CMSG_CONTENTS_OCTETS_FLAG = $00000010;
CMSG_MAX_LENGTH_FLAG = $00000020;
//+-------------------------------------------------------------------------
// Open a cryptographic message for encoding
//
// For PKCS #7:
// If the content to be passed to CryptMsgUpdate has already
// been message encoded (the input to CryptMsgUpdate is the streamed output
// from another message encode), then, the CMSG_ENCODED_CONTENT_INFO_FLAG should
// be set in dwFlags. If not set, then, the inner ContentType is Data and
// the input to CryptMsgUpdate is treated as the inner Data type's Content,
// a string of bytes.
// If CMSG_BARE_CONTENT_FLAG is specified for a streamed message,
// the streamed output will not have an outer ContentInfo wrapper. This
// makes it suitable to be streamed into an enclosing message.
//
// The pStreamInfo parameter needs to be set to stream the encoded message
// output.
//--------------------------------------------------------------------------
function CryptMsgOpenToEncode(dwMsgEncodingType: DWORD;
dwFlags: DWORD;
dwMsgType: DWORD;
pvMsgEncodeInfo: PVOID;
pszInnerContentObjID: LPSTR; //OPTIONAL
pStreamInfo: PCMSG_STREAM_INFO //OPTIONAL
): HCRYPTMSG; stdcall;
//+-------------------------------------------------------------------------
// Calculate the length of an encoded cryptographic message.
//
// Calculates the length of the encoded message given the
// message type, encoding parameters and total length of
// the data to be updated. Note, this might not be the exact length. However,
// it will always be greater than or equal to the actual length.
//--------------------------------------------------------------------------
function CryptMsgCalculateEncodedLength(dwMsgEncodingType: DWORD;
dwFlags: DWORD;
dwMsgType: DWORD;
pvMsgEncodeInfo: PVOID;
pszInnerContentObjID: LPSTR; //OPTIONAL
cbData: DWORD): DWORD; stdcall;
//+-------------------------------------------------------------------------
// Open a cryptographic message for decoding
//
// For PKCS #7: if the inner ContentType isn't Data, then, the inner
// ContentInfo consisting of both ContentType and Content is output.
// To also enable ContentInfo output for the Data ContentType, then,
// the CMSG_ENCODED_CONTENT_INFO_FLAG should be set
// in dwFlags. If not set, then, only the content portion of the inner
// ContentInfo is output for the Data ContentType.
//
// To only calculate the length of the decoded message, set the
// CMSG_LENGTH_ONLY_FLAG in dwFlags. After the final CryptMsgUpdate get the
// MSG_CONTENT_PARAM. Note, this might not be the exact length. However,
// it will always be greater than or equal to the actual length.
//
// hCryptProv specifies the crypto provider to use for hashing and/or
// decrypting the message. For enveloped messages, hCryptProv also specifies
// the private exchange key to use. For signed messages, hCryptProv is used
// when CryptMsgVerifySigner is called.
//
// For enveloped messages, the pRecipientInfo contains the Issuer and
// SerialNumber identifying the RecipientInfo in the message.
//
// Note, the pRecipientInfo should correspond to the provider's private
// exchange key.
//
// If pRecipientInfo is NULL, then, the message isn't decrypted. To decrypt
// the message, CryptMsgControl(CMSG_CTRL_DECRYPT) is called after the final
// CryptMsgUpdate.
//
// The pStreamInfo parameter needs to be set to stream the decoded content
// output. Note, if pRecipientInfo is NULL, then, the streamed output isn't
// decrypted.
//--------------------------------------------------------------------------
function CryptMsgOpenToDecode(dwMsgEncodingType: DWORD;
dwFlags: DWORD;
dwMsgType: DWORD;
hCryptProv: HCRYPTPROV;
pRecipientInfo: PCERT_INFO; //OPTIONAL
pStreamInfo: PCMSG_STREAM_INFO //OPTIONAL
): HCRYPTMSG; stdcall;
//+-------------------------------------------------------------------------
// Close a cryptographic message handle
//
// LastError is preserved unless FALSE is returned.
//--------------------------------------------------------------------------
function CryptMsgClose(hCryptMsg: HCRYPTMSG): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Update the content of a cryptographic message. Depending on how the
// message was opened, the content is either encoded or decoded.
//
// This function is repetitively called to append to the message content.
// fFinal is set to identify the last update. On fFinal, the encode/decode
// is completed. The encoded/decoded content and the decoded parameters
// are valid until the open and all duplicated handles are closed.
//--------------------------------------------------------------------------
function CryptMsgUpdate(hCryptMsg: HCRYPTMSG;
const pbData: PBYTE;
cbData: DWORD;
fFinal: BOOL): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Perform a special "control" function after the final CryptMsgUpdate of a
// encoded/decoded cryptographic message.
//
// The dwCtrlType parameter specifies the type of operation to be performed.
//
// The pvCtrlPara definition depends on the dwCtrlType value.
//
// See below for a list of the control operations and their pvCtrlPara
// type definition.
//--------------------------------------------------------------------------
function CryptMsgControl(hCryptMsg: HCRYPTMSG;
dwFlags: DWORD;
dwCtrlType: DWORD;
pvCtrlPara: PVOID): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Message control types
//--------------------------------------------------------------------------
const
CMSG_CTRL_VERIFY_SIGNATURE = 1;
CMSG_CTRL_DECRYPT = 2;
CMSG_CTRL_VERIFY_HASH = 5;
CMSG_CTRL_ADD_SIGNER = 6;
CMSG_CTRL_DEL_SIGNER = 7;
CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR = 8;
CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR = 9;
CMSG_CTRL_ADD_CERT = 10;
CMSG_CTRL_DEL_CERT = 11;
CMSG_CTRL_ADD_CRL = 12;
CMSG_CTRL_DEL_CRL = 13;
//+-------------------------------------------------------------------------
// CMSG_CTRL_VERIFY_SIGNATURE
//
// Verify the signature of a SIGNED or SIGNED_AND_ENVELOPED
// message after it has been decoded.
//
// For a SIGNED_AND_ENVELOPED message, called after
// CryptMsgControl(CMSG_CTRL_DECRYPT), if CryptMsgOpenToDecode was called
// with a NULL pRecipientInfo.
//
// pvCtrlPara points to a CERT_INFO struct.
//
// The CERT_INFO contains the Issuer and SerialNumber identifying
// the Signer of the message. The CERT_INFO also contains the
// PublicKeyInfo
// used to verify the signature. The cryptographic provider specified
// in CryptMsgOpenToDecode is used.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CTRL_DECRYPT
//
// Decrypt an ENVELOPED or SIGNED_AND_ENVELOPED message after it has been
// decoded.
//
// hCryptProv and dwKeySpec specify the private key to use. For dwKeySpec ==
// 0, defaults to AT_KEYEXCHANGE.
//
// dwRecipientIndex is the index of the recipient in the message associated
// with the hCryptProv's private key.
//
// This control function needs to be called, if you don't know the appropriate
// recipient before calling CryptMsgOpenToDecode. After the final
// CryptMsgUpdate, the list of recipients is obtained by iterating through
// CMSG_RECIPIENT_INFO_PARAM. The recipient corresponding to a private
// key owned by the caller is selected and passed to this function to decrypt
// the message.
//
// Note, the message can only be decrypted once.
//--------------------------------------------------------------------------
type
PCMSG_CTRL_DECRYPT_PARA = ^CMSG_CTRL_DECRYPT_PARA;
CMSG_CTRL_DECRYPT_PARA = record
cbSize: DWORD;
hCryptProv: HCRYPTPROV;
dwKeySpec: DWORD;
dwRecipientIndex: DWORD;
end;
//+-------------------------------------------------------------------------
// CMSG_CTRL_VERIFY_HASH
//
// Verify the hash of a HASHED message after it has been decoded.
//
// Only the hCryptMsg parameter is used, to specify the message whose
// hash is being verified.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CTRL_ADD_SIGNER
//
// Add a signer to a signed-data or signed-and-enveloped-data message.
//
// pvCtrlPara points to a CMSG_SIGNER_ENCODE_INFO.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CTRL_DEL_SIGNER
//
// Remove a signer from a signed-data or signed-and-enveloped-data message.
//
// pvCtrlPara points to a DWORD containing the 0-based index of the
// signer to be removed.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR
//
// Add an unauthenticated attribute to the SignerInfo of a signed-data or
// signed-and-enveloped-data message.
//
// The unauthenticated attribute is input in the form of an encoded blob.
//--------------------------------------------------------------------------
type
PCMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA = ^CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA;
CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA = record
cbSize: DWORD;
dwSignerIndex: DWORD;
blob: CRYPT_DATA_BLOB;
end;
//+-------------------------------------------------------------------------
// CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR
//
// Delete an unauthenticated attribute from the SignerInfo of a signed-data
// or signed-and-enveloped-data message.
//
// The unauthenticated attribute to be removed is specified by
// a 0-based index.
//--------------------------------------------------------------------------
type
PCMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA = ^CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA;
CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA = record
cbSize: DWORD;
dwSignerIndex: DWORD;
dwUnauthAttrIndex: DWORD;
end;
//+-------------------------------------------------------------------------
// CMSG_CTRL_ADD_CERT
//
// Add a certificate to a signed-data or signed-and-enveloped-data message.
//
// pvCtrlPara points to a CRYPT_DATA_BLOB containing the certificate's
// encoded bytes.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CTRL_DEL_CERT
//
// Delete a certificate from a signed-data or signed-and-enveloped-data
// message.
//
// pvCtrlPara points to a DWORD containing the 0-based index of the
// certificate to be removed.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CTRL_ADD_CRL
//
// Add a CRL to a signed-data or signed-and-enveloped-data message.
//
// pvCtrlPara points to a CRYPT_DATA_BLOB containing the CRL's
// encoded bytes.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CTRL_DEL_CRL
//
// Delete a CRL from a signed-data or signed-and-enveloped-data message.
//
// pvCtrlPara points to a DWORD containing the 0-based index of the CRL
// to be removed.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// Verify a countersignature, at the SignerInfo level.
// ie. verify that pbSignerInfoCountersignature contains the encrypted
// hash of the encryptedDigest field of pbSignerInfo.
//
// hCryptProv is used to hash the encryptedDigest field of pbSignerInfo.
// The only fields referenced from pciCountersigner are SerialNumber, Issuer,
// and SubjectPublicKeyInfo.
//--------------------------------------------------------------------------
function CryptMsgVerifyCountersignatureEncoded(hCryptProv: HCRYPTPROV;
dwEncodingType: DWORD;
pbSignerInfo: PBYTE;
cbSignerInfo: DWORD;
pbSignerInfoCountersignature: PBYTE;
cbSignerInfoCountersignature: DWORD;
pciCountersigner: PCERT_INFO): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Countersign an already-existing signature in a message
//
// dwIndex is a zero-based index of the SignerInfo to be countersigned.
//--------------------------------------------------------------------------
function CryptMsgCountersign(hCryptMsg: HCRYPTMSG;
dwIndex: DWORD;
cCountersigners: DWORD;
rgCountersigners: PCMSG_SIGNER_ENCODE_INFO): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Countersign an already-existing signature (encoded SignerInfo).
// Output an encoded SignerInfo blob, suitable for use as a countersignature
// attribute in the unauthenticated attributes of a signed-data or
// signed-and-enveloped-data message.
//--------------------------------------------------------------------------
function CryptMsgCountersignEncoded(dwEncodingType: DWORD;
pbSignerInfo: PBYTE;
cbSignerInfo: DWORD;
cCountersigners: DWORD;
rgCountersigners: PCMSG_SIGNER_ENCODE_INFO;
pbCountersignature: PBYTE;
pcbCountersignature: PDWORD): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Get a parameter after encoding/decoding a cryptographic message. Called
// after the final CryptMsgUpdate. Only the CMSG_CONTENT_PARAM and
// CMSG_COMPUTED_HASH_PARAM are valid for an encoded message.
//
// For an encoded HASHED message, the CMSG_COMPUTED_HASH_PARAM can be got
// before any CryptMsgUpdates to get its length.
//
// The pvData type definition depends on the dwParamType value.
//
// Elements pointed to by fields in the pvData structure follow the
// structure. Therefore, *pcbData may exceed the size of the structure.
//
// Upon input, if *pcbData == 0, then, *pcbData is updated with the length
// of the data and the pvData parameter is ignored.
//
// Upon return, *pcbData is updated with the length of the data.
//
// The OBJID BLOBs returned in the pvData structures point to
// their still encoded representation. The appropriate functions
// must be called to decode the information.
//
// See below for a list of the parameters to get.
//--------------------------------------------------------------------------
function CryptMsgGetParam(hCryptMsg: HCRYPTMSG;
dwParamType: DWORD;
dwIndex: DWORD;
pvData: PVOID;
pcbData: PDWORD): BOOL; stdcall;
//+-------------------------------------------------------------------------
// Get parameter types and their corresponding data structure definitions.
//--------------------------------------------------------------------------
const
CMSG_TYPE_PARAM = 1;
CMSG_CONTENT_PARAM = 2;
CMSG_BARE_CONTENT_PARAM = 3;
CMSG_INNER_CONTENT_TYPE_PARAM = 4;
CMSG_SIGNER_COUNT_PARAM = 5;
CMSG_SIGNER_INFO_PARAM = 6;
CMSG_SIGNER_CERT_INFO_PARAM = 7;
CMSG_SIGNER_HASH_ALGORITHM_PARAM = 8;
CMSG_SIGNER_AUTH_ATTR_PARAM = 9;
CMSG_SIGNER_UNAUTH_ATTR_PARAM = 10;
CMSG_CERT_COUNT_PARAM = 11;
CMSG_CERT_PARAM = 12;
CMSG_CRL_COUNT_PARAM = 13;
CMSG_CRL_PARAM = 14;
CMSG_ENVELOPE_ALGORITHM_PARAM = 15;
CMSG_RECIPIENT_COUNT_PARAM = 17;
CMSG_RECIPIENT_INDEX_PARAM = 18;
CMSG_RECIPIENT_INFO_PARAM = 19;
CMSG_HASH_ALGORITHM_PARAM = 20;
CMSG_HASH_DATA_PARAM = 21;
CMSG_COMPUTED_HASH_PARAM = 22;
CMSG_ENCRYPT_PARAM = 26;
CMSG_ENCRYPTED_DIGEST = 27;
CMSG_ENCODED_SIGNER = 28;
CMSG_ENCODED_MESSAGE = 29;
//+-------------------------------------------------------------------------
// CMSG_TYPE_PARAM
//
// The type of the decoded message.
//
// pvData points to a DWORD
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CONTENT_PARAM
//
// The encoded content of a cryptographic message. Depending on how the
// message was opened, the content is either the whole PKCS#7
// message (opened to encode) or the inner content (opened to decode).
// In the decode case, the decrypted content is returned, if enveloped.
// If not enveloped, and if the inner content is of type DATA, the returned
// data is the contents octets of the inner content.
//
// pvData points to the buffer receiving the content bytes
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_BARE_CONTENT_PARAM
//
// The encoded content of an encoded cryptographic message, without the
// outer layer of ContentInfo. That is, only the encoding of the
// ContentInfo.content field is returned.
//
// pvData points to the buffer receiving the content bytes
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_INNER_CONTENT_TYPE_PARAM
//
// The type of the inner content of a decoded cryptographic message,
// in the form of a NULL-terminated object identifier string
// (eg. "1.2.840.113549.1.7.1").
//
// pvData points to the buffer receiving the object identifier string
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_SIGNER_COUNT_PARAM
//
// Count of signers in a SIGNED or SIGNED_AND_ENVELOPED message
//
// pvData points to a DWORD
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_SIGNER_CERT_INFO_PARAM
//
// To get all the signers, repetitively call CryptMsgGetParam, with
// dwIndex set to 0 .. SignerCount - 1.
//
// pvData points to a CERT_INFO struct.
//
// Only the following fields have been updated in the CERT_INFO struct:
// Issuer and SerialNumber.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_SIGNER_INFO_PARAM
//
// To get all the signers, repetitively call CryptMsgGetParam, with
// dwIndex set to 0 .. SignerCount - 1.
//
// pvData points to a CMSG_SIGNER_INFO struct.
//--------------------------------------------------------------------------
type
PCMSG_SIGNER_INFO = ^CMSG_SIGNER_INFO;
CMSG_SIGNER_INFO = record
dwVersion: DWORD;
Issuer: CERT_NAME_BLOB;
SerialNumber: CRYPT_INTEGER_BLOB;
HashAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
HashEncryptionAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
EncryptedHash: CRYPT_DATA_BLOB;
AuthAttrs: CRYPT_ATTRIBUTES;
UnauthAttrs: CRYPT_ATTRIBUTES;
end;
//+-------------------------------------------------------------------------
// CMSG_SIGNER_HASH_ALGORITHM_PARAM
//
// This parameter specifies the HashAlgorithm that was used for the signer.
//
// Set dwIndex to iterate through all the signers.
//
// pvData points to an CRYPT_ALGORITHM_IDENTIFIER struct.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_SIGNER_AUTH_ATTR_PARAM
//
// The authenticated attributes for the signer.
//
// Set dwIndex to iterate through all the signers.
//
// pvData points to a CMSG_ATTR struct.
//--------------------------------------------------------------------------
type
CMSG_ATTR = CRYPT_ATTRIBUTES;
PCMSG_ATTR = ^CRYPT_ATTRIBUTES;
//+-------------------------------------------------------------------------
// CMSG_SIGNER_UNAUTH_ATTR_PARAM
//
// The unauthenticated attributes for the signer.
//
// Set dwIndex to iterate through all the signers.
//
// pvData points to a CMSG_ATTR struct.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CERT_COUNT_PARAM
//
// Count of certificates in a SIGNED or SIGNED_AND_ENVELOPED message.
//
// pvData points to a DWORD
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// CMSG_CERT_PARAM
//