*--------------------------------------------------------------------------------------------------------------------------------------------------------
* (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!!
*--------------------------------------------------------------------------------------------------------------------------------------------------------
*< FOXBIN2PRG: Version="1.21" SourceFile="_crypt.vcx" CPID="1252" /> (Solo para binarios VFP 9 / Only for VFP 9 binaries)
*
*
DEFINE CLASS _cryptapi AS custom && Windows Crypt API Library
*< CLASSDATA: Baseclass="custom" Timestamp="" Scale="Pixels" Uniqueid="" />
#INCLUDE "wincrypt.h"
*
*m: apideclarations && Declare API Fnuctions
*m: apierror && Get the Last Error Number from the System and Display an Error Message on the Screen
*m: apisetup && Initalization Code for this Class
*m: bintostr && Convert a Number to a byte stream, puttnig the least significate byte first and the most significan last.
*m: createnewkeycontainer && Create a New Named Key Container in the Cryptography Service Provider for storage of Signature and Exchange Pairs
*m: createrandomcryptkeys && Create a Key Container, Signature and Exchange Public/Private Key Pairs for that Container.
*m: cryptacquirecontext && See Crypto API documentation.
*m: cryptcreatehash && See Crypto API documentation.
*m: cryptdecrypt && See Crypto API documentation.
*m: cryptderivekey && See Crypto API documentation.
*m: cryptdestroyhash && See Crypto API documentation.
*m: cryptdestroykey && See Crypto API documentation.
*m: cryptencrypt && See Crypto API documentation.
*m: cryptexportkey && See Crypto API documentation.
*m: cryptgenkey && See Crypto API documentation.
*m: cryptgetkeyparam && See Crypto API documentation.
*m: cryptgetprovparam && See Crypto API documentation.
*m: cryptgetuserkey && See Crypto API documentation.
*m: crypthashdata && See Crypto API documentation.
*m: cryptimportkey && See Crypto API documentation.
*m: cryptreleasecontext && See Crypto API documentation.
*m: cryptsignhash && Sign a Hash with a Private Key.
*m: cryptverifysignature && Verify a Signed Hash
*m: decryptsessionblockfile && Decrypt a File using a Session Block Key
*m: decryptsessionblockstring && Decrypt a Strnig using a Block Session Key
*m: decryptsessionstreamfile && Decrypt a File with a session stream key
*m: decryptsessionstreamstring && Decrypt a String using a Session Stream Key
*m: decryptstr && Simple call that returns a decrypted string.
*m: deletekeycontainer && Delete a Cryptography Service Provider Named Key Container
*m: doubledecrypterror
*m: doubleencrypterror && Calculation of Error Number returned by getlasterror() for Double Encryption/Decryption of a Block String
*m: encryptsessionblockfile && Encrypt a File using a Session Block Key
*m: encryptsessionblockstring && Encrypt a Strnig Using a Session Block Key
*m: encryptsessionstreamfile && Encrypt a File using a Session Stream Key
*m: encryptsessionstreamstring && Encrypt a Strnig using a SessionStream Key
*m: encryptstrblock
*m: encryptstrstream
*m: exportexchangepairkeys && Export the Exchange Key Pair
*m: exportexchangepublickey && Export an Exchange Key from a named key container
*m: exportsessionkey && Export a Session Key Encrypted with an Exchange Key
*m: exportsignaturepairkeys && Export the Signature Key Pair
*m: exportsignaturepublickey && Export a Signature Key from a named Container
*m: formatmessage && Formats a system error message into a string for display.
*m: getcryptblocklength && Returns the Block length of a block key. This is need to calculate even block boundries during a block encryption of a large amount of text. To break it down into smaller chunks.
*m: getcryptsessionkeyhandle && Simple call for returning a session key handle.
*m: getcryptuserkeyhandle && Simple call for returning a user key. (Public Key part of a private.public key pair)
*m: getdoubledecrypterror && Return Logical Error Value of Last Rnu of Block Decryption
*m: getdoubleencrypterror && Return Logical Error Value of Last Rnu of Block Encryption
*m: getisinstalled && Return the Flag value for the init check of the Crypto Service Provider Installation
*m: getlastapierror && Returns the last error message trapped by this api. Each low level API call traps the error number returned in this parameter. This is needed for an error check from a form. By the time a form looks for the error number, another one may have occured.
*m: getlastapierrorcode && Returns the code from an error number (BITS 1-16)
*m: getlastapierrorcustomercodeflag && Returns the Customer flag from a system error number (Bit 29)
*m: getlastapierrorfacility && Returns the facitily code of an error number. (Bits 17-28)
*m: getlastapierrorseverity && Return the severity code of an error number (BITS 31-32)
*m: getlasterror && Return the last system error number.
*m: importpublickey && Import a Public Key into a Key Handle Structure
*m: releasecryptkeyhandle && Release handle and free memory allocated to it.
*m: signfile && Create a Signature for a File.
*m: strtobin && Convert a byte stream with the least significate byte first and the most significan last into a Number.
*m: systemmessage && Look an Error Number up in the system table and return the string message text.
*m: usekeycontanier && Make a Named or Default key container the one currently in use
*m: verifyfilesignature && Verify File Signature
*p: ccontainername && Name of Crypto Container for Use with this Class
*p: cprovidername && Name of Crypto Provider for use with this class
*p: hproviderhandle && Handle of Crypto Provider/Containter Initialized during setup of this class. For use within this class.
*p: ldisplayhighlevelapierrors
*p: ldisplaylowlevelapierrors && Display Low Level API Error's as they are encountered (in apierror function)
*p: ldoubledecrypterror && Error for Last Run of Block Decryption
*p: ldoubleencrypterror && Error for Last Run of Block Encryption
*p: lisinstalled && Flag for Crypt Provider Installed
*p: nlastapierror && See Crypto API documentation.
*
HIDDEN hproviderhandle,ldoubledecrypterror,ldoubleencrypterror,lisinstalled,nlastapierror
*
ldisplayhighlevelapierrors = .T.
Name = "_cryptapi"
nlastapierror = 0
*
HIDDEN PROCEDURE apideclarations && Declare API Fnuctions
*** Declare Parameter Types and Location
*** of the Windows API Crypt Functions
*** See Crypto API Documentation for Information on Calls
Declare INTEGER CryptAcquireContextA ;
IN WIN32API AS CryptAcquireContext ;
INTEGER @hProvHandle, ;
STRING cContainer, ;
STRING cProvider, ;
INTEGER nProvType, ;
INTEGER nFlags
Declare INTEGER CryptCreateHash ;
IN WIN32API AS CryptCreateHash ;
INTEGER hProviderHandle, ;
INTEGER nALG_ID, ;
INTEGER hKeyhandle, ;
INTEGER nFlags, ;
INTEGER @hCryptHashHandle
Declare INTEGER CryptDeriveKey ;
IN WIN32API AS CryptDeriveKey ;
INTEGER hProviderHandle, ;
INTEGER nALG_ID, ;
INTEGER hBaseDataHandle, ;
INTEGER nFlags, ;
INTEGER @hCryptKeyHandle
Declare INTEGER CryptDecrypt ;
IN WIN32API as CryptDecrypt ;
INTEGER hKeyHandle, ;
INTEGER hHashHandle, ;
SHORT nFinished, ;
INTEGER nFlags, ;
STRING @cData, ;
STRING @nDataLen && Pointer to DWORD INTEGER
Declare INTEGER CryptDestroyKey ;
IN WIN32API AS CryptDestroyKey;
INTEGER hKeyHandle
Declare INTEGER CryptDestroyHash ;
IN WIN32API AS CryptDestroyHash;
INTEGER hKeyHandle
Declare INTEGER CryptEncrypt ;
IN WIN32API as CryptEncrypt ;
INTEGER hKeyHandle, ;
INTEGER hHashHandle, ;
SHORT nFinished, ;
INTEGER nFlags, ;
STRING @cData, ;
STRING @cDataLen, ; && Pointer to DWORD value
INTEGER nBufLen
Declare INTEGER CryptExportKey ;
IN WIN32API AS CryptExportKey ;
INTEGER hKey, ;
INTEGER hExpKey, ;
INTEGER nBlobType, ;
INTEGER nFlags, ;
STRING @lcData, ;
STRING @lcDataLen && Pointer to DWORD INTEGER
Declare INTEGER CryptGenKey ;
IN WIN32API AS CryptGenKey ;
INTEGER hProviderHandle, ;
INTEGER nALG_ID, ;
INTEGER nFlags, ;
INTEGER @hCryptKeyHandle
Declare INTEGER CryptGetUserKey ;
IN WIN32API AS CryptGetUserKey;
INTEGER hProvHandle, ;
INTEGER nKeySpec, ;
INTEGER @hUserKey
Declare INTEGER CryptGetKeyParam ;
IN WIN32API as CryptGetKeyParam ;
INTEGER hKeyHandle, ;
INTEGER nParam, ;
STRING @cData, ;
STRING @nDataLen, ; && Pointer to DWORD INTEGER
INTEGER nFlags
Declare INTEGER CryptGetProvParam ;
IN WIN32API as CryptGetProvParam ;
INTEGER hKeyHandle, ;
INTEGER nParam, ;
STRING @cData, ;
STRING @nDataLen, ; && Pointer to DWROD INTEGER
INTEGER nFlags
Declare INTEGER CryptHashData ;
IN WIN32API AS CryptHashData ;
INTEGER hHashHandle, ;
STRING @cData, ;
INTEGER nDataLen, ;
INTEGER nFlags
Declare INTEGER CryptImportKey ;
IN WIN32API AS CryptImportKey ;
INTEGER hProviderHandle, ;
STRING @cEncryptedBlob, ;
INTEGER nEncryptedBlobLen, ;
INTEGER hDecryptionKeyHandle, ;
INTEGER nFlags, ;
STRING @cImportKeyHandle
Declare INTEGER CryptReleaseContext ;
IN WIN32API AS CryptReleaseContext ;
INTEGER hProvHandle, ;
INTEGER nReserved
Declare INTEGER CryptSignHash ;
IN WIN32API AS CryptSignHash ;
INTEGER hHashKeyHandle, ;
INTEGER nKeyType, ;
STRING @cDescription, ;
INTEGER inFlags, ;
STRING @cSignature, ;
STRING @cSignatureLen && Pointer to DWROD INTEGER
Declare INTEGER CryptVerifySignature ;
IN WIN32API AS CryptVerifySignature ;
INTEGER hHashKeyHandle, ;
STRING @cSignature, ;
INTEGER nSignatureLen, ;
INTEGER inPublicKeyHandle, ;
STRING @cDescription, ;
INTEGER inFlags
Declare INTEGER GetLastError ;
in win32api as GetLastError
Declare INTEGER FindWindow ;
IN WIN32API ;
STRING cNull, ;
STRING cWinName
Declare INTEGER FormatMessage ;
IN WIN32API ;
INTEGER nFlags, ;
STRING @cSource, ;
INTEGER nMessageId, ;
INTEGER nLanguageId, ;
STRING @cMessage, ;
INTEGER nMessageLen, ;
STRING @cArgum
ENDPROC
PROCEDURE apierror && Get the Last Error Number from the System and Display an Error Message on the Screen
LPARAMETER picProgram
LOCAL lnError, lcErrorMessage
*** picProgram - Progrm/User Defined Message String
*** that Initiated the Call
*** Returns - .T.
***
*** Displays the last Windows error using the Windows API
***
lnError = this.getlasterror()
lcErrorMessage = this.SystemMessage(lnError)
if this.lDisplayLowLevelApiErrors then
messagebox(dcErrorIn+picProgram+chr(13)+chr(10)+ ;
dcErrorSeverity+alltrim(str(this.GetLastApiErrorSeverity(),10))+chr(13)+chr(10)+ ;
dcErrorFacility+alltrim(str(this.GetLastApiErrorFacility(),10))+chr(13)+chr(10)+ ;
dcErrorCode+alltrim(str(this.GetLastApiErrorCode(),10))+chr(13)+chr(10)+ ;
lcErrorMessage+chr(13)+chr(10), ;
16, ;
dcError)
endif
ENDPROC
HIDDEN PROCEDURE apisetup && Initalization Code for this Class
LOCAL lhProviderHandle, lcProviderName, lcContainerName
*** Create Handle to Crypto Provider
If type('this.cProviderName') != T_CHARACTER then
this.cProviderName = dcEmpty && Default
EndIf
lcProviderName = this.cProviderName
If type('this.cContainerName') != T_CHARACTER then
this.cContainerName = dcFOXPRO_APP && Default
EndIf
lcContainerName = this.cContainerName
lhProviderHandle = 0
if !this.CreateRandomCryptKeys(lcContainerName,lcProviderName,dnPROV_RSA_FULL)
return .F.
endif
this.CryptAcquireContext(@lhProviderHandle,lcContainerName,lcProviderName,dnPROV_RSA_FULL,0)
this.hProviderHandle = lhProviderHandle
Return .T.
ENDPROC
HIDDEN PROCEDURE bintostr && Convert a Number to a byte stream, puttnig the least significate byte first and the most significan last.
LPARAMETER pinInput, pinStringLen
*** pinInput - Integer to be encoded into a character string
*** return - Integer represented by character string
*** Left most Character is least significant
*** Right most character is most significant
*** Converts an Integer into a Character String
LOCAL lnreturn, lnCounter
lcReturn = dcEmpty
for lnCounter = 1 to pinStringLen
lcReturn = lcReturn + chr(bitand(bitrshift(pinInput,bitlshift((lnCounter-1),3)),255))
endfor
return lcReturn
ENDPROC
PROCEDURE createnewkeycontainer && Create a New Named Key Container in the Cryptography Service Provider for storage of Signature and Exchange Pairs
LPARAMETER pcContainerName
*** Creates a new Key Container and Makes it the Container Currently in Use
LOCAL lnError, lhProviderHandle
lhProviderHandle = 0
this.cContainerName = pcContainerName
lnError = this.CryptAcquireContext(@lhProviderHandle,pcContainerName,this.cProviderName,dnPROV_RSA_FULL,dnCRYPT_NEWKEYSET)
If lnError = 0
this.hProviderHandle = 0
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTNEWKEYCONTAINER_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.nlastapierror = getlasterror()
this.apierror(program())
return .F.
else
this.nlastapierror = 0
this.hProviderHandle = lhProviderHandle
endif
return .T.
ENDPROC
HIDDEN PROCEDURE createrandomcryptkeys && Create a Key Container, Signature and Exchange Public/Private Key Pairs for that Container.
LPARAMETER picContainerName, picProviderName, pinProviderType
* pihProviderHandle - Handle of CSP
* picContainerName - Name of Container to Create (NULL is Default)
* picProviderName - Name of CSP Provider (NULL is Default)
* pihProviderType - MS Windows Defnied CSP provider Type
* Returns - .T. Success, .F. Error
** Creates a Key Container in the CSP Provider
local lnError, lhUserKey, lhProviderHandle
lhProviderHandle = 0
lhUserKey = 0
* Create New Key Container
lnError = CryptAcquireContext(@lhProviderHandle,picContainerName,picProviderName,pinProviderType,dnCRYPT_NEWKEYSET)
if lnError = 0 then
do case
* Test for Key Containter Already Exists (This is an OK Condition)
case bitxor(getlasterror(),0x8009000F)=0
this.nlastapierror = 0
* Open Context Normally
lnError = CryptAcquireContext(@lhProviderHandle,picContainerName,picProviderName,pinProviderType,0)
if lnError = 0
this.nlastapierror = getlasterror()
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTPROVTYP_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.apierror(program())
return .F.
endif
* Test for Service Provider Not Defined Error
case bitxor(getlasterror(),0x80090017)=0
this.nlastapierror = getlasterror()
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTPROVTYP_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.apierror(program())
return .F.
* Any Other Error
otherwise
this.nlastapierror = getlasterror()
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTINITIALIZE_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.apierror(program())
return .F.
endcase
else
this.nlastapierror = 0
endif
* Try to Retrieve Signature Key
lnError = CryptGetUserKey(lhProviderHandle,dnAT_SIGNATURE,@lhUserKey)
if lnError = 0 then
* Test for NTE_NO_KEY
if bitxor(getlasterror(),0x8009000D)=0 then
* (Attempt to Create a Key)
lnError = CryptGenKey(lhProviderHandle,dnAT_SIGNATURE,0,@lhUserKey)
if lnError = 0 then
this.nlastapierror = getlasterror()
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTSIGGENKEY_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.apierror(program())
this.CryptReleaseContext(lhProviderHandle)
return .F.
else
this.nlastapierror = 0
endif
else
this.nlastapierror = getlasterror()
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTSIGGETKEY_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.apierror(program())
this.CryptReleaseContext(lhProviderHandle)
return .F.
endif
else
this.nlastapierror = 0
endif
lnError = CryptDestroyKey(lhUserKey)
* Try to Retrieve Exchange Key
lnError = CryptGetUserKey(lhProviderHandle,dnAT_KEYEXCHANGE,@lhUserKey)
if lnError = 0 then
* Test for NTE_NO_KEY
if bitxor(getlasterror(),0x8009000D)=0 then
* (Attempt to Create a Key)
lnError = CryptGenKey(lhProviderHandle,dnAT_KEYEXCHANGE,0,@lhUserKey)
if lnError = 0 then
this.nlastapierror = getlasterror()
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTEXCGENKEY_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.apierror(program())
this.CryptReleaseContext(lhProviderHandle)
return .F.
else
this.nlastapierror = 0
endif
else
this.nlastapierror = getlasterror()
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTEXCGETKEY_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.apierror(program())
this.CryptReleaseContext(lhProviderHandle)
return .F.
endif
else
this.nlastapierror = 0
endif
lnError = CryptDestroyKey(lhUserKey)
this.CryptReleaseContext(lhProviderHandle)
this.lIsInstalled = .T.
return .T.
ENDPROC
HIDDEN PROCEDURE cryptacquirecontext && See Crypto API documentation.
Lparameter pihProvhandle, picContainer, picProvider, pinProvType, pinFlags
*** pihProvHandle - Variable passed by reference and defnied as REPLICATE(CHR(0),4)
*** picContainer - CHR(0) terminated String Name of the Key Container
*** null means a default key container will be used
*** A container is where the keys are stored
*** Depending on the Crypt Provider
*** it could be stored internally,
*** In the registry, on the hard drive,
*** or in a special hardware device.
*** picProvider - CHR(0) terminated String Name of the Crypt Provider
*** Null means the user default provider is used
*** The user default provider is identified in the Registry
*** HKEY_LOCAL_MACHINE\Software\Microsoft\;
*** cryptography\defaults\provider types\typexx\name
*** Windows supports multiple providers
*** The provider is the program that does all
*** of the work. It's conforms to the Windows API
*** calls that interface with it.
*** pinProvType - Identifies the Crypt Provider Type
*** Defined in WinCrypt.h
*** i.e. PROV_RSA_FULL
*** pinFlags - Normally 0
*** Defined in WinCrypt.h
*** Used to carry out specific functions
*** Return - Handle to the Crypt Provider in pihProvHandle
*** Creates a Crypt Key Container handle for Use in Most Crypt Functions
Local lnError
lnError = CryptAcquireContext( ;
@pihProvhandle, ;
picContainer, ;
picProvider, ;
pinProvType, ;
pinFlags)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return
ENDPROC
HIDDEN PROCEDURE cryptcreatehash && See Crypto API documentation.
Lparameter pihProvHandle, pinALG_ID, pihKeyHandle, pinFlags, pihCryptHashHandle
*** pihProvHandle - Crypto Service Provider Handle,
*** Returned by CryptAcquireContext()
*** pinALG_ID - Algorith Identifier (defined in wincrypt.h) for hashing
*** pihKeyHandle - If Keyed Hash, Handle of the Key
*** Returned by CryptDeriveKey()
*** or CryptGenKey(), else 0
*** pinFlags - Must be 0, reserved for future use
*** pihCryptHashHandle - Reference to Pointer to HashHandle
*** Return - Handle of the Hash Object in pihCryptHashHandle,
*** Used by CryptHashKey() or
*** CryptHashSessionKey()
*** Create a Hash Object Handle for se in Hashing Functions
Local lnError
lnError = CryptCreateHash( ;
pihProvHandle, ;
pinALG_ID, ;
pihKeyHandle, ;
pinFlags, ;
@pihCryptHashHandle)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return
ENDPROC
HIDDEN PROCEDURE cryptdecrypt && See Crypto API documentation.
Lparameter pihKeyHandle, pihHashKeyHandle, pinFinal, ;
pinFlags, ptcData, ptcDataLen
*** pihKeyHandle - Handle of Key Objcet,
*** Returned by CryptGenKey() or CryptImportKey()
*** pihHashKeyHandle - 0 if no hash is to be done, else
*** Handle of Hash Object Returned by CryptCreateHash()
*** pinFinal - -1 (True) if last block,
*** 0 (False) if not the last block to decrypt
*** pinFlags - Optional: CRYPT_OAEP when Enhanced and RSA Decryption
*** for PKCS #1 version 2 formatting
*** ptcData - in: Data String to be Decrypted; out: decrypted data
*** ptcDataLen - in: Length of pcData to decrypt; out: length of decrypted data
*** Encoded as a 4 character string (use - BinToStr(n,4) to create
*** use - StrToBin(c) to read)
*** Return - Decrypted Data via Left(pcData,lnDataLenLen)
*** Used to Decrypt and Simultaneously Hash (Optional:pnHashKey) the Decrypted Data to Verify it's
*** signature
Local lnError
lnError = CryptDecrypt( ;
pihKeyHandle, ;
pihHashKeyHandle, ;
pinFinal, ;
pinFlags, ;
@ptcData, ;
@ptcDataLen)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return left(ptcData,this.StrToBin(ptcDataLen))
ENDPROC
HIDDEN PROCEDURE cryptderivekey && See Crypto API documentation.
Lparameter pihProvHandle, pinALG_ID, pihBaseDataHandle, pinFlags, pihCryptKeyHandle
*** pihProvHandle - Handle Returned by CryptAcquireContext()
*** pinALG_ID - Algorithm Identifier (defined in wincrypt.h), cypher to use
*** --- Session Keys ---
*** --- Microsoft Base CSP ---
*** dnCALG_RC2 block
*** dnCALG_RC4 stream
*** --- Microsoft Enhamced CSP ---
*** CALG_DES DES block
*** CALG_3DES Triple DES Block
*** CALG_3DES_112 Triple DES 2 Key Block
*** --- Diffie-Hellman CSP ---
*** CALG_DH_EPHEM
*** CALG_DH_SF
*** --- Public/Private Key Pairs ---
*** dnAT_KEYEXCHANGE
*** dnAT_SIGNATURE
*** pihBaseDataHandle - Handle of Hashed Key Returned by CryptHashData
*** pinFlags - Upper 16 bits - The Size of the Session key to Generate
*** 0x0080???? = 128 bits
*** 0x0028???? = 40 bits
*** Lower 16 Bits: (Defined in wincrypt.h)
*** CRYPT_CREATE_SALT - value calculated
*** from unused session key bits
*** retrieved with CryptGetKeyParam()
*** dnCRYPT_EXPORTABLE - Can Export Key with CryptExportKey()
*** CRYPT_NO_SALT - Do not Create a Salt Value
*** CRYPT_PREGEN - Initial DSS Key Generation
*** CRYPT_UPDATE_KEY - If multiple hash vales are required
*** then use this flag to update the last
*** key with this hash value. MicroSoft's
*** CSP does not support this functionality
*** Returns - Handle of Crypt Key in pihCryptKeyHandle
*** Used to Create a Key Handle for use in CryptEncrypt() and CryptDecrypt()
Local lnError
lnError = CryptDeriveKey( ;
pihProvHandle, ;
pinALG_ID, ;
pihBaseDatahandle, ;
pinFlags, ;
@pihCryptKeyHandle)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return
ENDPROC
HIDDEN PROCEDURE cryptdestroyhash && See Crypto API documentation.
Lparameter pihHashKeyHandle
*** pihHashKeyHandle - Handle of Hashed Key returned by CryptCreateHash()
*** Return - .T.
*** Destroys the Hashed Key Pointer where the hashed crypt key was located
*** This is suggested for Security Reasons
*** Many CSP's also scrub the key before removing the handle. This function is
*** not required to scrub the container, just to destroy the pointer.
Local lnError
lnError = cryptdestroyhash(pihHashKeyHandle)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
return
ENDPROC
HIDDEN PROCEDURE cryptdestroykey && See Crypto API documentation.
Lparameter pihKeyHandle
*** pihKeyHandle - Handle of CSP Key returned by CryptAcquireContext()
*** Return - .T.
*** Destroys the Key Container Pointer where the encrypt/decrypt key was located
*** This is suggested for Security Reasons
*** Many CSP's also scrub the key before removing the handle. This function is
*** not required to scrub the container, just to destroy the pointer.
Local lnError
lnError = cryptdestroykey(pihKeyHandle)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
return
ENDPROC
HIDDEN PROCEDURE cryptencrypt && See Crypto API documentation.
Lparameter pihKeyHandle, pihHashKeyHandle, pinFinal, ;
pinFlags, ptcData, ptcDataLen, pinMaxDataLen
*** pihKeyHandle - Handle of Key Objcet,
*** Returned by CryptGenKey() or CryptImportKey()
*** pihHashKeyHandle - 0 if no hash is to be done, else
*** Handle of Hash Object, Returned by CryptCreateHash()
*** pinFinal - -1 (True) if last block, 0 (False) if not the last block to decrypt
*** pinFlags - Optional: CRYPT_OAEP when Enhanced and RSA Encryption
*** for PKCS #1 version 2 formatting
*** ptcData - in: Data String to be Encrypted; out: Encrypted data
*** ptcDataLen - in: Length of pcData to Encrypt; out: length of Encrypted data
*** Encoded as a 4 character string (use - BinToStr(n,4) to create
*** use - StrToBin(c) to read)
*** pinMaxDataLen - Length of pcData buffer (Block Encryption Requires extra buffer space
*** by as much as 1 Block Length
*** Return - Decrypted Data via Left(pcData,lnDataLenLen)
*** Used to Encrypt and Simultaneously Hash (Optional:pnHashKey) the Data
*** for use by the CryptGetHashParam() or CryptSignHash() signature
Local lnError
lnError = CryptEncrypt( ;
pihKeyHandle, ;
pihHashKeyHandle, ;
pinFinal, ;
pinFlags, ;
@ptcData, ;
@ptcDataLen, ;
pinMaxDataLen)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return left(ptcData,this.strtobin(ptcDataLen))
ENDPROC
HIDDEN PROCEDURE cryptexportkey && See Crypto API documentation.
Lparameter pihKeyHandle, pihExpKeyHandle, pinBlobType, pinFlags, poKeyString
*** pihKeyHandle - Handle of the Key to Be Exported
*** pihExpKeyHandle - Handle of a Crypt Key to use to encrypt this key
*** If Public Key is to be exported, then set to 0
*** Usually this is the public key of the destination Computer/User
*** pinBlobType - (defined in wincrypt.h)
*** OPAQUEKEYBLOB - Store an encrypted session key in the CSP
*** dnPRIVATEKEYBLOB - Private/Public Key pair
*** dnPUBLICKEYBLOB - Public Key
*** dnSIMPLEBLOB - Session Key
*** pinFlags - (defined in wincrypt.h)
*** CRYPT_DESTROYKEY - destroy OPAQUEKEYBLOB key in CSP
*** CRYPT_SSL2_FALLBACK -
*** CRYPT_OAEP - when Enhanced and RSA Encryption
*** for PKCS #1 version 2 formatting
*** poKeyString - Encrypted Key String
*** Returns .T. success
*** .F. Failure
*** Exports a crypto key from a Crypto Service Provider in a Secure Manner.
Local lcData, lnError
Local lcLen, lcEmptyString
lcLen = this.BinToStr(0,4)
lcEmptyString = dcEmpty
* Get the Len of the String First
* pihExpKeyHandle, ;
CryptExportKey( ;
pihKeyHandle, ;
pihExpKeyHandle, ;
pinBlobType, ;
pinFlags, ;
@lcEmptyString, ;
@lcLen)
* Create the String and Stuff it with the BLOB
lcData = space(this.StrToBin(lcLen))
lnError = CryptExportKey( ;
pihKeyHandle, ;
pihExpKeyHandle, ;
pinBlobType, ;
pinFlags, ;
@lcData, ;
@lcLen)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
Return .F.
else
this.nlastapierror = 0
endif
poKeyString = lcData
Return .T.
ENDPROC
HIDDEN PROCEDURE cryptgenkey && See Crypto API documentation.
Lparameter pihProvHandle, pinALG_ID, pinFlags, pihCryptKeyHandle
*** pihProvHandle - Handle Returned by CryptAcquireContext()
*** pinALG_ID - Algorithm Identifier (defined in wincrypt.h), cypher to use
*** --- Session Keys ---
*** --- Microsoft Base CSP ---
*** dnCALG_RC2 block
*** dnCALG_RC4 stream
*** --- Microsoft Enhamced CSP ---
*** CALG_DES DES block
*** CALG_3DES Triple DES Block
*** CALG_3DES_112 Triple DES 2 Key Block
*** --- Diffie-Hellman CSP ---
*** CALG_DH_EPHEM
*** CALG_DH_SF
*** --- Public/Private Key Pairs ---
*** dnAT_KEYEXCHANGE
*** dnAT_SIGNATURE
*** pinFlags - Upper 16 bits - The Size of the key to Generate
*** 0x0800???? = 2048 bits
*** Lower 16 Bits: (Defined in wincrypt.h)
*** CRYPT_CREATE_SALT - value calculated
*** from unused session key bits
*** retrieved with CryptGetKeyParam()
*** dnCRYPT_EXPORTABLE - Can Export Key with CryptExportKey()
*** CRYPT_NO_SALT - Do not Create a Salt Value
*** CRYPT_PREGEN - Initial DSS Key Generation
*** CRYPT_USER_PROTECTED - Notify User via Dialog
*** on certain access functions
*** of this key (IE4 or greater)
*** pihCryptKeyHandle - Reference to CryptKeyHandle, Initialize as replicate(chr(0),4)
*** Returns - Handle of Generated Crypt Key
*** Used to Create a Random Key Handle for use in CryptEncrypt() and CryptDecrypt()
Local lnError
lnError = CryptGenKey( ;
pihProvHandle, ;
pinALG_ID, ;
pinFlags, ;
@pihCryptKeyHandle)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return
ENDPROC
HIDDEN PROCEDURE cryptgetkeyparam && See Crypto API documentation.
Lparameter pihKeyHandle, pinParam, ptcData, ;
ptcDataLen, pinFlags
*** pihKeyHandle - Handle of Key Objcet,
*** Returned by CryptGenKey() or CryptImportKey()
*** pinParam - Parameter to Retrieve(defined in wincrypt.h)
*** --- All Keys Support ---
*** dnKP_IV Initialization vector
*** dnKP_SALT Salt value
*** dnKP_PADDING Padding values
*** dnKP_MODE Mode of the cipher
*** dnKP_MODE_BITS Number of bits to feedback
*** dnKP_PERMISSIONS Key permissions DWORD
*** dnKP_ALGID Key algorithm
*** dnKP_BLOCKLEN Block size of the cipher
*** --- pihKeyHandle is DSS Key BLOB Pointer ---
*** dnKP_P Prime Modulus from DSS Key BLOB
*** dnKP_Q Prime Q from DSS Key BLOB
*** dnKP_G Generator from DSS Key BLOB
*** --- pihKeyHandle is Block Session Key Pointer ---
*** dnKP_IV Initialization vector
*** dnKP_SALT Salt value
*** dnKP_PADDING Padding values
*** dnKP_MODE Mode of the cipher
*** dnKP_MODE_BITS Number of bits to feedback
*** dnKP_PERMISSIONS Key permissions DWORD
*** dnKP_ALGID Key algorithm
*** dnKP_BLOCKLEN Block size of the cipher
*** ptcData - in: Buffer String; out:Parameter String
*** ptcDataLen - in: Length of ptcData Buffer;
*** out: length of Parameter String
*** Encoded as a 4 character string (use - BinToStr(n,4) to create
*** use - StrToBin(c) to read)
*** Return - Requested Parameter as a String Value
*** Used to return a Parameter from the CSP that pihKeyHandle points to
Local lnError
lnError = CryptGetKeyParam( ;
pihKeyHandle, ;
pinParam, ;
@ptcData, ;
@ptcDataLen, ;
pinFlags)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return left(ptcData,this.StrToBin(ptcDataLen))
ENDPROC
HIDDEN PROCEDURE cryptgetprovparam && See Crypto API documentation.
Lparameter pihKeyHandle, pinParam, ptcData, ;
ptcDataLen, pinFlags
*** pihKeyHandle - Handle of Key Objcet,
*** Returned by CryptGenKey() or CryptImportKey()
*** pinParam - Parameter to Retrieve(defined in wincrypt.h)
*** dnPP_ENUMALGS
*** dnPP_ENUMCONTAINERS
*** dnPP_IMPTYPE
*** dnPP_NAME
*** dnPP_VERSION
*** dnPP_CONTAINER
*** PP_SIG_KEYSIZE_INC
*** PP_KEYX_KEYSIZE_INC
*** PP_ENUMALGS_EX
*** PP_KEYSET_SEC_DESCR
*** PP_UNIQUE_CONTAINER
*** PP_PROVTYPE
*** PP_USE_HARDWARE_RNG
*** ptcData - in: Buffer String; out:Parameter String
*** ptcDataLen - in: Length of ptcData Buffer;
*** out: length of Parameter String
*** Encoded as a 4 character string (use - BinToStr(n,4) to create
*** use - StrToBin(c) to read)
*** Return - Requested Parameter as a String Value
*** Used to return a Parameter from the CSP that pihKeyHandle points to
Local lnError
lnError = CryptGetProvParam( ;
pihKeyHandle, ;
pinParam, ;
@ptcData, ;
@ptcDataLen, ;
pinFlags)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return left(ptcData,this.StrToBin(ptnDataLen))
ENDPROC
HIDDEN PROCEDURE cryptgetuserkey && See Crypto API documentation.
Lparameter pihProvHandle, pinKeySpec, pohUserKeyHandle
*** pihProvHandle - Handle of Service Provider
*** Returned by CryptGenKey() or CryptImportKey()
*** pinKeySpec - defined in WinCrypt.h
*** dnAT_SIGNATURE
*** dnAT_KEYEXCHANGE
*** pohUserKeyHandle - Handle to User Key
Local lnUserKey, lnError
lnError = CryptGetUserKey( ;
pihProvHandle, ;
pinKeySpec, ;
@pohUserKeyHandle)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
Return .F.
else
this.nlastapierror = 0
endif
Return .T.
ENDPROC
HIDDEN PROCEDURE crypthashdata && See Crypto API documentation.
Lparameter pihHashKeyHandle, picData, pinDataLen, pinFlags
*** pihHashKeyHandle - Handle of Hash Object, Returned by CryptCreateHash()
*** picData - Data String to be added to Hash Key
*** pinDataLen - Length of picData
*** pinFlags - Length of pcData buffer (Block Encryption Requires extra buffer space
*** by as much as 1 Block Length
*** Return - .T.
*** Used to added data to the hash key pointed to by hash handle
Local lnError
lnError = CryptHashData( ;
pihHashKeyHandle, ;
@picData, ;
pinDataLen, ;
pinFlags)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return
ENDPROC
HIDDEN PROCEDURE cryptimportkey && See Crypto API documentation.
Lparameter pihProviderHandle, picBlob, pinBlobLen, pihImpKeyHandle, pinFlags, pthKeyHandle
*** pihProviderHandle - Handle of the CSP
*** @picBlob - Encrypted Blob
*** pinBlobLen - Length of Encrypted Blob
*** pihImpKeyHandle - Handle of a Crypt Key to use to decrypt this key
*** Usually this is the private key of the this Computer
*** pinFlags - (defined in wincrypt.h)
*** CRYPT_DESTROYKEY - destroy OPAQUEKEYBLOB key in CSP
*** CRYPT_SSL2_FALLBACK -
*** CRYPT_OAEP - when Enhanced and RSA Encryption
*** for PKCS #1 version 2 formatting
*** pthKeyHandle - Handle of the Key to Be Exported
*** Returns - Sesion Key Handle
*** Imports a crypto key by Decrypting a Key Blob and converting it into a key Handle
Local lnError
Local lcKeyHandle
lcKeyHandle = this.BinToStr(pthKeyHandle,4)
lnError = CryptImportKey( ;
pihProviderHandle, ;
@picBlob, ;
pinBlobLen, ;
pihImpKeyHandle, ;
pinFlags, ;
@lcKeyHandle ;
)
pthKeyHandle = this.StrToBin(lcKeyHandle)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return
ENDPROC
HIDDEN PROCEDURE cryptreleasecontext && See Crypto API documentation.
LPARAMETER pihProviderHandle
*** pihContextHandle - Handle of CSP to Release
*** Release a CSP Handle and Frees up Memory Reserved by it
CryptReleaseContext(pihProviderHandle,0)
Return
ENDPROC
HIDDEN PROCEDURE cryptsignhash && Sign a Hash with a Private Key.
Lparameter pihHashKeyHandle, pinKeyType, pinFlags
*** pihHashKeyHandle - Handle of Hash Object, Returned by CryptCreateHash()
*** pinKeyType - Private Key to Sign with (usually AT_SIGNATURE)
*** pinFlags - Flags (See Crypto API Documentation)
*** by as much as 1 Block Length
*** Returned - Signed String in picSignature
*** Used to Sign a Hash for storage as a signanture.
Local lnError, lnSignatureLen
Local lcDescription, lcSignature, lcSingatureLen
*** lcDescription - No Longer used, set to NULL
lcDescription = dcEmpty
lcSignature = dcEmpty
lcSignatureLen = this.BinToStr(0,4)
* Get the Signature Length
lnError = CryptSignHash( ;
pihHashKeyHandle, ;
pinKeyType, ;
@lcDescription, ;
pinFlags, ;
@lcSignature, ;
@lcSignatureLen ;
)
*** Do not check for error, since More Data Needed may result from 0 length
lcSignature = space(this.StrToBin(lcSignatureLen))
lnError = CryptSignHash( ;
pihHashKeyHandle, ;
pinKeyType, ;
@lcDescription, ;
pinFlags, ;
@lcSignature, ;
@lcSignatureLen ;
)
if lnError = 0 then
this.nlastapierror = getlasterror()
this.apierror(program())
else
this.nlastapierror = 0
endif
Return lcSignature
ENDPROC
HIDDEN PROCEDURE cryptverifysignature && Verify a Signed Hash
Lparameter pihHashKeyHandle, picSignature, pihPublicKeyHandle, pinFlags
*** pihHashKeyHandle - Handle of Hash Object, Returned by CryptCreateHash()
*** picSignature - Signature String to Verify
*** pihPublicKeyHandle - Handle of Public Signature Key
*** pinFlags - Flags (See Crypto API Documentation)
*** Returns - .T. if verified, .F. if not verified or a different error occured
*** Used to Verify a Signature
Local lnError, lnSignatureLen
lnSignatureLen = len(picSignature)
lnError = CryptVerifySignature( ;
pihHashKeyHandle, ;
@picSignature, ;
lnSignatureLen, ;
pihPublicKeyHandle, ;
dcEmpty, ;
pinFlags ;
)
if lnError = 0 then
* Signature did not verify or a different error occured.
* Error Number for NTE_BAD_SIGNATURE 0x80090006
* getlasterror() returns a signed number and 0x??????? is unsigned,
* getlasterror() and 0x???? cannot be compared with an =
* compare with bitxor()
this.nlastapierror = getlasterror()
this.apierror(program())
Return .F.
else
* Signature Verified
this.nlastapierror = 0
Return .T.
endif
ENDPROC
PROCEDURE decryptsessionblockfile && Decrypt a File using a Session Block Key
LPARAMETER pcEncryptedFileName, pcPassword, pcDecryptedFileName
*** pcEncryptedFileName - File Path and Name of file with Encrypted Contents
*** pcPassword - Password
*** pcDecryptedFileName - File Path and Name of file to Create with Decrypted Contents
*** Returns .T. - Successful
*** .F. - Error
LOCAL lhKeyHandle, lhExportKeyHandle, lhEncryptedFileHandle, lhDecryptedFileHandle
LOCAL lnYN, lnBytesWritten, lnKeyLength, lnBlockReadSize, lnCryptBlockLen
LOCAL lcEncryptedSessionKey, lcEncryptedText, lcTestLength
this.lDoubleDecryptError = .F.
if (empty(pcEncryptedFileName) or empty(pcEncryptedFileName) or empty(pcPassword)) and this.ldisplayhighlevelapierrors
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileParameter_ERR_LOC)
endif
return .F.
endif
lhEncryptedFileHandle = fopen(alltrim(pcEncryptedFileName))
if lhEncryptedFileHandle = -1 and this.ldisplayhighlevelapierrors then
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileNoFile_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
return .F.
endif
if file(alltrim(pcDecryptedFileName))
if this.ldisplayhighlevelapierrors then
lnYN =messagebox(dcDecryptSessionFileExists_ERR_LOC, MB_APPLMODAL + MB_YESNO + MB_ICONQUESTION, dcFileExists)
if lnYN = IDNo then
fclose(lhEncryptedFileHandle)
return .F.
endif
endif
endif
lhDecryptedFileHandle = fcreate(alltrim(pcDecryptedFileName))
if lhDecryptedFileHandle = -1 then
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileCreate_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
fclose(lhEncryptedFileHandle)
return .F.
endif
lhKeyHandle = 0
lhExchangeKeyHandle = 0
this.GetCryptSessionKeyHandle(this.hProviderHandle,@lhKeyHandle, dcB,rtrim(pcPassword))
if lhKeyHandle <> 0 then
*** Get Block Length for this Encryption Key
lnCryptBlockLen = this.GetCryptBlockLength(lhKeyHandle)
lnBlockReadSize = 1024 - mod(1024,lnCryptBlockLen)
*** See what encryption Length would be for an ecrypted block of this size
lcTestLength = space(lnBlockReadSize)
lnBlockReadSize = len(this.EncryptStrBlock(lcTestLength, lhKeyHandle, .F.))
fseek(lhEncryptedFileHandle,0,0)
do while !feof(lhEncryptedFileHandle)
lcEncryptedText = fread(lhEncryptedFileHandle,lnBlockReadSize)
lnBytesWritten = fwrite(lhDecryptedFileHandle,this.DecryptStr(lcEncryptedText, lhKeyHandle, feof(lhEncryptedFileHandle)))
if this.GetLastApiError() <> 0 or lnBytesWritten = 0 then
if this.GetLastApiError() = this.DoubleDecryptError()
this.lDoubleDecryptError = .T.
else
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileWrite_ERR_LOC)
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
endif
fclose(lhDecryptedFileHandle)
fclose(lhEncryptedFileHandle)
return .F.
endif
enddo
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileComplete_LOC, MB_OK, dcCompleted)
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
endif
fclose(lhDecryptedFileHandle)
fclose(lhEncryptedFileHandle)
return .T.
ENDPROC
PROCEDURE decryptsessionblockstring && Decrypt a Strnig using a Block Session Key
LPARAMETERS pcEncryptedString, pcPassword, pcDecryptedString
*** pcEncryptedString - String to Decrypt
*** pcPassword - Password
*** pcDecryptedString - Decrypted String
*** Returns .T. - Ok
*** .F. - Error
LOCAL lhKeyHandle, lhExchangeKeyHandle
LOCAL lcSaveText, lcReturn, llOk
lhKeyHandle = 0
lhExchangeKeyHandle = 0
llOk = .F.
this.GetCryptSessionKeyHandle(this.hProviderHandle,@lhKeyHandle,dcB,rtrim(pcPassword))
if lhKeyHandle <> 0 then
if len(pcEncryptedString) > 0 then
lcSaveText = this.DecryptStr(pcEncryptedString, lhKeyHandle, .T.)
if this.GetLastApiError() = 0 then
pcDecryptedString = lcSaveText
llOk = .T.
else
if this.GetLastApiError() = this.DoubleDecryptError()
this.lDoubleDecryptError = .T.
endif
endif
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
endif
return llOk
ENDPROC
PROCEDURE decryptsessionstreamfile && Decrypt a File with a session stream key
LParameter pcEncryptedFileName, pcPassword, pcDecryptedFileName
*** pcEncryptedFileName - File Path and Name of file to Decrypt
*** pcPassword - Password
*** pcDecryptedFileName - File Path and Name of file to Place Decrypted Contents Into
*** Returns .T. - Successful
*** .F. - Error
LOCAL lhKeyHandle, lhExportKeyHandle, lhEncryptedFileHandle, lhDecryptedFileHandle
LOCAL lnYN, lnBytesWritten, lnKeyLength
LOCAL lcEncryptedSessionKey, lcEncryptedText
if empty(pcEncryptedFileName) or empty(pcEncryptedFileName) or empty(pcPassword)
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileParameter_ERR_LOC)
endif
return .F.
endif
lhEncryptedFileHandle = fopen(alltrim(pcEncryptedFileName))
if lhEncryptedFileHandle = -1 then
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileNoFile_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
return .F.
endif
if file(alltrim(pcDecryptedFileName))
if this.ldisplayhighlevelapierrors then
lnYN =messagebox(dcDecryptSessionFileExists_ERR_LOC, MB_APPLMODAL + MB_YESNO + MB_ICONQUESTION, dcFileExists)
if lnYN = IDNo then
fclose(lhEncryptedFileHandle)
return .F.
endif
endif
endif
lhDecryptedFileHandle = fcreate(alltrim(pcDecryptedFileName))
if lhDecryptedFileHandle = -1 then
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileCreate_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
fclose(lhEncryptedFileHandle)
return .F.
endif
lhKeyHandle = 0
lhExchangeKeyHandle = 0
this.GetCryptSessionKeyHandle(this.hProviderHandle,@lhKeyHandle, dcS,rtrim(pcPassword))
if lhKeyHandle <> 0 then
fseek(lhEncryptedFileHandle,0,0)
do while !feof(lhEncryptedFileHandle)
lcEncryptedText = fread(lhEncryptedFileHandle,1024)
lnBytesWritten = fwrite(lhDecryptedFileHandle,this.DecryptStr(lcEncryptedText, lhKeyHandle, feof(lhEncryptedFileHandle)))
if this.GetLastApiError() <> 0 or lnBytesWritten = 0 then
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileWrite_ERR_LOC)
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
fclose(lhDecryptedFileHandle)
fclose(lhEncryptedFileHandle)
return .F.
endif
enddo
if this.ldisplayhighlevelapierrors then
messagebox(dcDecryptSessionFileComplete_LOC, MB_OK, dcCompleted)
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
endif
fclose(lhDecryptedFileHandle)
fclose(lhEncryptedFileHandle)
return .T.
ENDPROC
PROCEDURE decryptsessionstreamstring && Decrypt a String using a Session Stream Key
LPARAMETERS pcEncryptedString, pcPassword, pcDecryptedString
*** pcEncryptedString - String to Decrypt
*** pcPassword - Password
*** Returns != '' - Decrypton of pcEncryptedString
*** == '' - Error
LOCAL lhKeyHandle, lhExchangeKeyHandle
lhKeyHandle = 0
lhExchangeKeyHandle = 0
this.GetCryptSessionKeyHandle(this.hProviderHandle,@lhKeyHandle, dcS,rtrim(pcPassword))
if lhKeyHandle <> 0 then
if len(pcEncryptedString) > 0 then
lcSaveText = this.DecryptStr(pcEncryptedString, lhKeyHandle, .T.)
if this.GetLastApiError() = 0 then
pcDecryptedString = lcSaveText
else
pcDecryptedString = dcEmpty
this.ReleaseCryptKeyHandle(lhKeyHandle)
return .F.
endif
else
pcDecryptedString = dcEmpty
this.ReleaseCryptKeyHandle(lhKeyHandle)
return .F.
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
endif
return .T.
ENDPROC
HIDDEN PROCEDURE decryptstr && Simple call that returns a decrypted string.
Lparameter picData, pihKeyHandle, pilLastString
*** picData - Data to be Decrypted
*** pihKeyHandle - Handle to Decryption Key (Type determine Block or Stream)
*** pilLastString - .T. when this is the last string to decrypt
*** Returns - Decrypted String
*** Wrapper to decrypt a string
Local lcDataLen
lcDataLen = this.BinToStr(len(picData),4)
Return this.CryptDecrypt( ;
pihKeyHandle, ;
0, ;
iif(pilLastString,-1,0), ;
0, ;
picData, ;
lcDataLen)
ENDPROC
PROCEDURE deletekeycontainer && Delete a Cryptography Service Provider Named Key Container
LPARAMETER pcContainer
*** pcContainer - Container Name of the Key Container to Delete
*** Deletes a Key Container and
*** Releases the Provider Handle when the Container to Delete is the one currently in use
LOCAL lhProviderHandle
lhProviderHandle = 0
if this.cContainerName = pcContainer then
this.CryptReleaseContext(this.hProviderHandle)
this.hProviderHandle = 0
endif
lnError = this.CryptAcquireContext(@lhProviderHandle,pcContainerName,this.cProviderName,dnPROV_RSA_FULL,dnCRYPT_DELETEKEYSET)
if lnError = 0
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTDELETEKEYCONTAINER_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.nlastapierror = getlasterror()
this.apierror(program())
return .F.
else
this.nlastapierror = 0
endif
return .T.
ENDPROC
HIDDEN PROCEDURE doubledecrypterror
*** Convert 0x80090005 to two's complement
return -1 * ( bitxor(0x80090005,0xffffffff) + 1 )
ENDPROC
HIDDEN PROCEDURE doubleencrypterror && Calculation of Error Number returned by getlasterror() for Double Encryption/Decryption of a Block String
*** Convert 0x80090012 to two's complement
return -1 * ( bitxor(0x80090012,0xffffffff) + 1 )
ENDPROC
PROCEDURE encryptsessionblockfile && Encrypt a File using a Session Block Key
LPARAMETER pcDecryptedFileName, pcPassword, pcEncryptedFileName
*** pcDecryptedFileName - File Path and Name of file with Decrypted Contents
*** pcPassword - Password
*** pcEncryptedFileName - File Path and Name of file to Create with Encrypted Contents
*** Returns .T. - Successful
*** .F. - Error
LOCAL lhKeyHandle, lhExportKeyHandle, lhEncryptedFileHandle, lhDecryptedFileHandle
LOCAL lnYN, lnBytesWritten, lnCryptBlockLen, lnBlockReadSize
LOCAL lcEncryptedSessionKey, lcDecryptedText
if empty(pcDecryptedFileName) or empty(pcEncryptedFileName) or empty(pcPassword)
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileParameter_ERR_LOC)
endif
return .F.
endif
lhDecryptedFileHandle = fopen(alltrim(pcDecryptedFileName))
if lhDecryptedFileHandle = -1 then
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileNoFile_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
return .F.
endif
if file(alltrim(pcEncryptedFileName))
if this.ldisplayhighlevelapierrors then
lnYN =messagebox(dcEncryptSessionFileExists_ERR_LOC, MB_APPLMODAL + MB_YESNO + MB_ICONQUESTION, dcFileExists)
if lnYN = IDNo then
fclose(lhDecryptedFileHandle)
return .F.
endif
endif
endif
lhEncryptedFileHandle = fcreate(alltrim(pcEncryptedFileName))
if lhEncryptedFileHandle = -1 then
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileCreate_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
fclose(lhDecryptedFileHandle)
return .F.
endif
lhKeyHandle = 0
lhExchangeKeyHandle = 0
lcEncryptedSessionKey = dcEmpty
this.GetCryptSessionKeyHandle(this.hProviderHandle,@lhKeyHandle,dcB,rtrim(pcPassword))
if lhKeyHandle <> 0 then
*** Get Block Length for this Encryption Key
lnCryptBlockLen = this.GetCryptBlockLength(lhKeyHandle)
lnBlockReadSize = 1024 - mod(1024,lnCryptBlockLen)
fseek(lhDecryptedFileHandle,0,0)
do while !feof(lhDecryptedFileHandle)
lcDecryptedText = fread(lhDecryptedFileHandle,lnBlockReadSize)
lnBytesWritten = fwrite(lhEncryptedFileHandle,this.EncryptStrBlock(lcDecryptedText, lhKeyHandle, feof(lhDecryptedFileHandle)))
if this.GetLastApiError() <> 0 or lnBytesWritten = 0 then
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileWrite_ERR_LOC)
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
fclose(lhDecryptedFileHandle)
fclose(lhEncryptedFileHandle)
return .F.
endif
enddo
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileComplete_LOC, MB_OK, dcCompleted)
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
endif
fclose(lhDecryptedFileHandle)
fclose(lhEncryptedFileHandle)
return .T.
ENDPROC
PROCEDURE encryptsessionblockstring && Encrypt a Strnig Using a Session Block Key
LPARAMETERS pcDecryptedString, pcPassword, pcEncryptedString
*** pcDecryptedString - String to Encrypt
*** pcEncryptedString - Reference to String to Hold Encrypted Value
*** pcPassword - Password
*** Returns != '' - Encryption of pcDecryptedString
*** == '' - Error
LOCAL lhKeyHandle, lhExchangeKeyHandle
LOCAL llOk, lcSaveString
lhKeyHandle = 0
lhExchangeKeyHandle = 0
llOk = .F.
this.lDoubleEncryptError = .F.
this.GetCryptSessionKeyHandle(this.hProviderHandle,@lhKeyHandle,dcB,rtrim(pcPassword))
if lhKeyHandle <> 0 then
if len(pcDecryptedString) > 0 then
lcSaveString = this.EncryptStrBlock(pcDecryptedString, lhKeyHandle, .T.)
if this.GetLastApiError() = 0 then
pcEncryptedString = lcSaveString
llOk = .T.
else
if this.GetLastApiError() = this.DoubleEncryptError()
this.lDoubleEncryptError = .T.
endif
endif
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
endif
return llOk
ENDPROC
PROCEDURE encryptsessionstreamfile && Encrypt a File using a Session Stream Key
LPARAMETER pcDecryptedFileName, pcPassword, pcEncryptedFileName
*** pcDecryptedFileName - File Path and Name of file with Decrypted Contents
*** pcPassword - Password
*** pcEncryptedFileName - File Path and Name of file to Create with Encrypted Contents
*** Returns .T. - Successful
*** .F. - Error
LOCAL lhKeyHandle, lhExportKeyHandle, lhEncryptedFileHandle, lhDecryptedFileHandle
LOCAL lnYN, lnBytesWritten
LOCAL lcEncryptedSessionKey, lcDecryptedText
if empty(pcDecryptedFileName) or empty(pcEncryptedFileName) or empty(pcPassword)
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileParameter_ERR_LOC)
endif
return .F.
endif
lhDecryptedFileHandle = fopen(alltrim(pcDecryptedFileName))
if lhDecryptedFileHandle = -1 then
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileNoFile_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
return .F.
endif
if file(alltrim(pcEncryptedFileName))
if this.ldisplayhighlevelapierrors then
lnYN =messagebox(dcEncryptSessionFileExists_ERR_LOC, MB_APPLMODAL + MB_YESNO + MB_ICONQUESTION, dcFileExists)
if lnYN = IDNo then
fclose(lhDecryptedFileHandle)
return .F.
endif
endif
endif
lhEncryptedFileHandle = fcreate(alltrim(pcEncryptedFileName))
if lhEncryptedFileHandle = -1 then
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileCreate_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
fclose(lhDecryptedFileHandle)
return .F.
endif
lhKeyHandle = 0
lhExchangeKeyHandle = 0
lcEncryptedSessionKey = dcEmpty
this.GetCryptSessionKeyHandle(this.hProviderHandle,@lhKeyHandle, dcS,rtrim(pcPassword))
if lhKeyHandle <> 0 then
fseek(lhDecryptedFileHandle,0,0)
do while !feof(lhDecryptedFileHandle)
lcDecryptedText = fread(lhDecryptedFileHandle,1024)
lnBytesWritten = fwrite(lhEncryptedFileHandle,this.EncryptStrStream(lcDecryptedText, lhKeyHandle, feof(lhDecryptedFileHandle)))
if this.GetLastApiError() <> 0 or lnBytesWritten = 0 then
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileWrite_ERR_LOC)
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
fclose(lhDecryptedFileHandle)
fclose(lhEncryptedFileHandle)
return .F.
endif
enddo
if this.ldisplayhighlevelapierrors then
messagebox(dcEncryptSessionFileComplete_LOC, MB_OK, dcCompleted)
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
endif
fclose(lhDecryptedFileHandle)
fclose(lhEncryptedFileHandle)
return .T.
ENDPROC
PROCEDURE encryptsessionstreamstring && Encrypt a Strnig using a SessionStream Key
LPARAMETERS pcDecryptedString, pcPassword, pcEncryptedString
*** pcDecryptedString - String to Encrypt
*** pcPassword - Password
*** pcEncryptedString - Refrence to a String to hold the Encrypted String Value
*** Returns != '' - Encryption of pcDecryptedString
*** == '' - Error
LOCAL lhKeyHandle, lhExportKeyHandle
LOCAL lcEncryptedSessionKey, llOk, lcSaveString
lhKeyHandle = 0
lhExchangeKeyHandle = 0
lcEncryptedSessionKey = dcEmpty
llOk = .F.
this.GetCryptSessionKeyHandle(this.hProviderHandle,@lhKeyHandle,dcS,rtrim(pcPassword))
if lhKeyHandle <> 0 then
if len(pcDecryptedString) > 0 then
lcSaveString = this.EncryptStrStream(pcDecryptedString, lhKeyHandle, .T.)
if this.GetLastApiError() = 0 then
pcEncryptedString = lcSaveString
llOk = .T.
endif
endif
this.ReleaseCryptKeyHandle(lhKeyHandle)
endif
return llOk
ENDPROC
HIDDEN PROCEDURE encryptstrblock
Lparameter picData, pihKeyHandle, pilLastString
*** picData - Data to be Encrypted
*** pihKeyHandle - Handle to Encryption Key (Type determines Block or Stream)
*** pilLastString - Last String to Encrypt with this Key
*** Returns - Encrypted String
*** Wrapper to encrypt a string
Local lnDataLen, lnMaxLen
LOCAL lcDataLen, lcEmptySpace
lnDataLen = len(picData)
lcDataLen = this.BinToStr(lnDataLen,4)
*** The following is needed, Just in case a stream key is passed
*** When called with a Stream pihKeyHandle, this routine encrypts the
*** EmptySpace string even though maxlen = 0
*** Leaving this out would corrupt memory and result in a GPF
lcEmptySpace = space(lnDataLen)
CryptEncrypt( ;
pihKeyHandle, ;
0, ;
-1, ;
0, ;
@lcEmptySpace, ;
@lcDataLen, ;
0)
*** Do not check lnError since more data is available error will result from this call
*** on a block, when the data length is shorter (Not a multiple of the block length)
lnMaxLen = this.strtobin(lcDataLen)
* ReSet lcDataLen, since last cryptencrypt call changed it
lcDataLen = this.BinToStr(lnDataLen,4)
picData = picData + space(lnMaxLen - lnDataLen)
Return this.CryptEncrypt( ;
pihKeyHandle, ;
0, ;
iif(pilLastString,-1,0), ;
0, ;
picData, ;
lcDataLen, ;
lnMaxLen)
ENDPROC
HIDDEN PROCEDURE encryptstrstream
Lparameter picData, pihKeyHandle, pilLastString
*** picData - Data to be Encrypted
*** pihKeyHandle - Handle to Encryption Key (Type determines Block or Stream)
*** pilLastString - Last String to Encrypt with this Key
*** Returns - Encrypted String
*** Wrapper to encrypt a string
Local lnDataLen
LOCAL lcDataLen
lnDataLen = len(picData)
lcDataLen = this.BinToStr(lnDataLen,4)
Return this.CryptEncrypt( ;
pihKeyHandle, ;
0, ;
iif(pilLastString,-1,0), ;
0, ;
@picData, ;
@lcDataLen, ;
lnDataLen)
ENDPROC
HIDDEN PROCEDURE exportexchangepairkeys && Export the Exchange Key Pair
LPARAMETER pcPassword, pcPairKey
*** pcPassword - Password for Encryption of Exported Key
*** pcPairKey - Reference String to pass Encrypted Key back to caller
*** Return .T. - Success
*** .F. - Failure
LOCAL lcPairKey, lhHash, lhEncryptKey, lhExchangeKey, lhExchangeKey
lhHash = 0
lhExchangeKey = 0
lhexchangeKey = 0
lhEncryptKey = 0
lcPairKey = dcEmpty
if !this.cryptcreatehash(this.hProviderHandle, dnCALG_MD5, 0, 0, @lhHash)
return .F.
endif
if !this.crypthashdata(lhHash, pcPassword, len(pcPassword), 0)
return .F.
endif
if !this.cryptderivekey(this.hProviderHandle, dnCALG_RC2, lhHash, dnCRYPT_EXPORTABLE, @lhEncryptKey)
return .F.
endif
if !this.cryptgetuserkey(this.hProviderHandle, dnAT_KEYEXCHANGE, @lhExchangeKey)
return .F.
endif
if !this.cryptgetuserkey(this.hProviderHandle, dnAT_KEYEXCHANGE, @lhExchangeKey)
return .F.
endif
if !this.cryptexportkey(lhExchangeKey ,lhEncryptKey, dnPRIVATEKEYBLOB, 0, @lcPairKey)
return .F.
endif
pcPairKey = lcPairKey
return .T.
ENDPROC
PROCEDURE exportexchangepublickey && Export an Exchange Key from a named key container
LPARAMETER pcPublicKey
LOCAL lcPublicKey, lhExchangeKey
lhExchangeKey = 0
lcPublicKey = dcEmpty
if !this.cryptgetuserkey(this.hProviderHandle,dnAT_KEYEXCHANGE,@lhExchangeKey)
return .F.
endif
if !this.cryptexportkey(lhExchangeKey,0,dnPUBLICKEYBLOB,0,@lcPublicKey)
return .F.
endif
pcPublicKey = lcPublicKey
return .T.
ENDPROC
PROCEDURE exportsessionkey && Export a Session Key Encrypted with an Exchange Key
LPARAMETER pcPassword, pcSessionKey
*** pcPassword - Password for Encryption of Exported Key
*** pcSessionKey - Reference String to pass Encrypted Key back to caller
*** Return .T. - Success
*** .F. - Failure
*** Exports a session key encrypted with the Exchange Private Key of the Current Key Container
LOCAL lcPairKey, lhHash, lhEncryptKey, lhExchangeKey
lhHash = 0
lhExchangeKey = 0
lhEncryptKey = 0
lcPairKey = dcEmpty
if !this.cryptcreatehash(this.hProviderHandle, dnCALG_MD5, 0, 0, @lhHash)
return .F.
endif
if !this.crypthashdata(lhHash, pcPassword, len(pcPassword), 0)
return .F.
endif
if !this.cryptderivekey(this.hProviderHandle, dnCALG_RC2, lhHash, dnCRYPT_EXPORTABLE, @lhEncryptKey)
return .F.
endif
if !this.cryptgetuserkey(this.hProviderHandle, dnAT_KEYEXCHANGE, @lhExchangeKey)
return .F.
endif
if !this.cryptexportkey(lhEncryptKey ,lhExchangeKey, dnSIMPLEBLOB, 0, @lcPairKey)
return .F.
endif
pcSessionKey = lcPairKey
return .T.
ENDPROC
HIDDEN PROCEDURE exportsignaturepairkeys && Export the Signature Key Pair
LPARAMETER pcPassword, pcPairKey
*** pcPassword - Password for Encryption of Exported Key
*** pcPairKey - Reference String to pass Encrypted Key back to caller
*** Return .T. - Success
*** .F. - Failure
LOCAL lcPairKey, lhHash, lhEncryptKey, lhExchangeKey, lhSignatureKey
lhHash = 0
lhExchangeKey = 0
lhSignatureKey = 0
lhEncryptKey = 0
lcPairKey = dcEmpty
if !this.cryptcreatehash(this.hProviderHandle, dnCALG_MD5, 0, 0, @lhHash)
return .F.
endif
if !this.crypthashdata(lhHash, pcPassword, len(pcPassword), 0)
return .F.
endif
if !this.cryptderivekey(this.hProviderHandle, dnCALG_RC2, lhHash, dnCRYPT_EXPORTABLE, @lhEncryptKey)
return .F.
endif
if !this.cryptgetuserkey(this.hProviderHandle, dnAT_KEYEXCHANGE, @lhExchangeKey)
return .F.
endif
if !this.cryptgetuserkey(this.hProviderHandle, dnAT_SIGNATURE, @lhSignatureKey)
return .F.
endif
if !this.cryptexportkey(lhSignatureKey ,lhEncryptKey, dnPRIVATEKEYBLOB, 0, @lcPairKey)
return .F.
endif
pcPairKey = lcPairKey
return .T.
ENDPROC
PROCEDURE exportsignaturepublickey && Export a Signature Key from a named Container
LPARAMETER pcPublicKey
LOCAL lcPublicKey, lhSignatureKey
lhSignatureKey = 0
lcPublicKey = dcEmpty
if !this.cryptgetuserkey(this.hProviderHandle,dnAT_SIGNATURE,@lhSignatureKey)
return .F.
endif
if !this.cryptexportkey(lhSignatureKey,0,dnPUBLICKEYBLOB,0,@lcPublicKey)
return .F.
endif
pcPublicKey = lcPublicKey
return .T.
ENDPROC
HIDDEN PROCEDURE formatmessage && Formats a system error message into a string for display.
Lparameter pinFlags, pinMessageNum
*** pinFlags - Windows API defined flags for Format Message
*** pinMessageNum - Windows API Message Number
*** Returns - Formated Message String Associated
*** with the Message Number that was input
***
*** Windows API call to FormatMessage
*** Returns the Windows String Text Assocaited with
*** the Windows Message Number that a Windows API
*** returns, formated based on the flags that were passed to it.
*** currently does not support C like printf() ability
***
Local lcMessage, lcNull
lcMessage = space(256)
lcNull = dcEmpty
lnMessageLen = FormatMessage( ;
pinFlags, ;
@lcNull, ;
pinMessageNum, ;
0, ;
@lcMessage, ;
256, ;
@lcNull)
Return left(lcMessage,lnMessageLen)
ENDPROC
HIDDEN PROCEDURE getcryptblocklength && Returns the Block length of a block key. This is need to calculate even block boundries during a block encryption of a large amount of text. To break it down into smaller chunks.
LPARAMETER pihKeyHandle
*** pihKeyHandle - Handle of Key Objcet,
*** Returned by CryptGenKey() or CryptImportKey()
*** Return - Length of an encryption block for the current key
*** Used to return a Parameter from a Crypt Key
Local lnParamLen, lnReturn
Local lcParam, lcParamLen
lnReturn = 0
lnParamLen = 4
lcParam = space(lnParamLen)
lcParamLen = this.BinToStr(lnParamLen,4)
lcParam = this.CryptGetKeyParam( ;
pihKeyHandle, ;
dnKP_BLOCKLEN, ;
lcParam, ;
lcParamLen, ;
0)
return this.StrToBin(lcParam)
ENDPROC
HIDDEN PROCEDURE getcryptsessionkeyhandle && Simple call for returning a session key handle.
LPARAMETER pihProviderHandle,pihCryptKeyHandle, picType, picPassword
***
*** pihProviderHandle - Handle of the CSP
*** pihCryptKeyHandle - Handle to a cryptographic session key
*** picPassword - Password to use as Encryption Key
*** picType - 'B' Use Block Cypher (Harder to Crack, but takes longer and results
*** in longer encrypted string than decryphered
*** by as much as one block length)
*** - 'S' Use Stream Cyper (Easier to Crack, but runs faster and results
*** in same length encrypted string as decyphered string)
*** - 'BR' Random, Use Block Cypher (Harder to Crack, but takes longer and results
*** in longer encrypted string than decryphered
*** by as much as one block length)
*** - 'SR' Random, Use Stream Cyper (Easier to Crack, but runs faster and results
*** in same length encrypted string as decyphered string)
*** Returns - Handle to Session Crypt Key (Numberic)
***
*** Uses Microsoft Windows Base Cryptographic Provider
*** to Return a Handle to a cryptographic key that can be used to Encrypt/Decrypt Data
***
Local lhCryptHashHandle, lnSaveError
If !(picType $ dcgetcryptsessionkeyhandleparam ) and this.ldisplayhighlevelapierrors
if this.ldisplayhighlevelapierrors then
Messagebox(program()+ ;
dcgetcryptsessionkeyhandleERR_LOC)
endif
Return 0
Endif
lhCryptHashHandle = 0
lnSaveError = 0
Do case
Case picType == dcB
this.CryptCreateHash(pihProviderHandle,dnCALG_MD5,0,0,@lhCryptHashHandle)
if this.nlastapierror <> 0 then
lnSaveError = this.nlastapierror
endif
this.CryptHashData(lhCryptHashHandle, picPassword , len(picPassword),0)
if this.nlastapierror <> 0 then
lnSaveError = this.nlastapierror
endif
this.CryptDeriveKey(;
pihProviderHandle, ;
dnCALG_RC2, ;
lhCryptHashHandle, ;
dnCRYPT_EXPORTABLE, ;
@pihCryptKeyHandle)
if this.nlastapierror <> 0 then
lnSaveError = this.nlastapierror
endif
this.CryptDestroyHash(lhCryptHashHandle)
if this.nlastapierror = 0 then
this.nlastapierror = lnSaveError
endif
Case picType == dcS
this.CryptCreateHash(pihProviderHandle,dnCALG_MD5,0,0,@lhCryptHashHandle)
if this.nlastapierror <> 0 then
lnSaveError = this.nlastapierror
endif
This.CryptHashData(lhCryptHashHandle, picPassword, len(picPassword), 0)
if this.nlastapierror <> 0 then
lnSaveError = this.nlastapierror
endif
this.CryptDeriveKey(;
pihProviderHandle, ;
dnCALG_RC4, ;
lhCryptHashHandle, ;
dnCRYPT_EXPORTABLE, ;
@pihCryptKeyHandle)
if this.nlastapierror <> 0 then
lnSaveError = this.nlastapierror
endif
this.CryptDestroyHash(lhCryptHashHandle)
if this.nlastapierror = 0 then
this.nlastapierror = lnSaveError
endif
Case picType == dcBR
this.CryptGenKey( ;
pihProviderHandle, ;
dnCALG_RC2, ;
dnCRYPT_EXPORTABLE, ;
@pihCryptKeyHandle)
Case picType == dcSR
this.CryptGenKey(;
pihProviderHandle, ;
dnCALG_RC4, ;
dnCRYPT_EXPORTABLE, ;
@pihCryptKeyHandle)
Endcase
Return
ENDPROC
HIDDEN PROCEDURE getcryptuserkeyhandle && Simple call for returning a user key. (Public Key part of a private.public key pair)
LPARAMETER pihProviderHandle, pihUserKey, pinKeySpec
*** pihProvHandle - Handle of CSP
*** pinKeySpec - Type of a User Key to Generate
*** Returns Handle to the User Key of Specified Type
this.CryptGetUserKey( ;
pihProviderHandle, ;
pinKeySpec, ;
@pihUserKey ;
)
Return
ENDPROC
PROCEDURE getdoubledecrypterror && Return Logical Error Value of Last Rnu of Block Decryption
return this.lDoubleDecryptError
ENDPROC
PROCEDURE getdoubleencrypterror && Return Logical Error Value of Last Rnu of Block Encryption
return this.lDoubleEncryptError
ENDPROC
PROCEDURE getisinstalled && Return the Flag value for the init check of the Crypto Service Provider Installation
return this.lIsInstalled
ENDPROC
PROCEDURE getlastapierror && Returns the last error message trapped by this api. Each low level API call traps the error number returned in this parameter. This is needed for an error check from a form. By the time a form looks for the error number, another one may have occured.
*** Returns the last error from the last crypto API call
return this.nlastapierror
ENDPROC
HIDDEN PROCEDURE getlastapierrorcode && Returns the code from an error number (BITS 1-16)
*** Returns the code of the last error from the last crypto API call
return bitand(this.nlastapierror,0xFFFF)
ENDPROC
HIDDEN PROCEDURE getlastapierrorcustomercodeflag && Returns the Customer flag from a system error number (Bit 29)
*** Returns the severity code of the last error from the last crypto API call
*** 00 - Windows Code
*** 01 - Customer Code
return bitand(bitrshift(this.nlastapierror,29),1)
ENDPROC
HIDDEN PROCEDURE getlastapierrorfacility && Returns the facitily code of an error number. (Bits 17-28)
*** Returns the facility code of the last error from the last crypto API call
*** FACILITY_NULL 0
*** FACILITY_RPC 1
*** FACILITY_DISPATCH 2
*** FACILITY_STORAGE 3
*** FACILITY_ITF 4
*** FACILITY_WIN32 7
*** FACILITY_WINDOWS 8
*** FACILITY_SSPI 9
*** FACILITY_CONTROL 10
*** FACILITY_CERT 11
*** FACILITY_INTERNET 12
*** FACILITY_MEDIASERVER 13
*** FACILITY_MSMQ 14
*** FACILITY_SETUPAPI 15
return bitand(bitrshift(this.nlastapierror,16),0xFFF)
ENDPROC
HIDDEN PROCEDURE getlastapierrorseverity && Return the severity code of an error number (BITS 31-32)
*** Returns the severity code of the last error from the last crypto API call
*** 00 - Success
*** 01 - Informational
*** 10 - Warning
*** 11 - Error
return bitrshift(this.nlastapierror,30)
ENDPROC
PROCEDURE getlasterror && Return the last system error number.
*** Call to the Windows API
RETURN getlasterror()
ENDPROC
PROCEDURE importpublickey && Import a Public Key into a Key Handle Structure
LPARAMETERS pcPublicKey, phPublicKeyHandle
*** pcPublicKey - Public Key to Import
*** phPublicKeyHandle - Reference to a Handle, in which the Public Key is Returned
*** Returns - Public Key Handle in phPublicKeyHandle
*** .T. - Success
*** .F. - Failure
LOCAL lhPublicKeyHandle, lnError
lhPublicKeyHandle = 0
if !this.CryptImportKey(this.hProviderHandle, pcPublicKey, len(pcPublicKey), 0, 0, @lhPublicKeyHandle)
Return .F.
endif
phPublicKeyHandle = lhPublicKeyHandle
Return .T.
ENDPROC
PROCEDURE Init
* this.ldisplaylowlevelapierrors = .T.
this.ApiDeclarations && Declare API Functions
this.ApiSetup && Create CSP Handle for use with this class
ENDPROC
HIDDEN PROCEDURE releasecryptkeyhandle && Release handle and free memory allocated to it.
LPARAMETER pihKeyHandle
*** pihKeyHandle - Handle to the Key structure to destroy
*** Returns - .T. (Logical)
*** Releases the memory where the key structure was stored.
*** Most Cryptographic Service Providers Scramble the Structure Contents
*** as well as freeing it up. This is done so that another program can't query
*** looking for keys that are left laying around.
this.cryptdestroykey(pihKeyHandle)
ENDPROC
PROCEDURE signfile && Create a Signature for a File.
LPARAMETERS pcDecryptedFileName, pcSignature, pcSignaturePublicKey
*** pcDecryptedFileName - File name to Create an Encrypted Signature for
*** pcSignature - Reference to a Signature String
*** pcSignaturePublicKey - Reference to a Signature Public Key String
*** Return Signature in pcSignature
*** Signature PublicKey in pcSignaturePublicKey
*** .T. - Success
*** .F. - Failure
*** Create a Signature for the given file.
Local lhHashHandle, lnError, lnYN, lhSignFileHandle, lhDecryptedFileHandle, lnBytesWritten, lhKey
Local lcInput, lcSignature, lcDecrytedText
if empty(pcDecryptedFileName)
if this.ldisplayhighlevelapierrors then
messagebox(dcSignFileParamter_ERR_LOC)
endif
return .F.
endif
lhDecryptedFileHandle = fopen(alltrim(pcDecryptedFileName))
if lhDecryptedFileHandle = -1 then
if this.ldisplayhighlevelapierrors then
messagebox(dcSignFileDecryptedFile_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
return .F.
endif
lhHashHandle = 0
this.CryptCreateHash(this.hProviderHandle,dnCALG_MD5,0,0,@lhHashHandle)
if this.GetLastApiError() <> 0 then
if this.ldisplayhighlevelapierrors then
messagebox (dcSignFileHashObject_ERR_LOC)
endif
fclose(lhDecryptedFileHandle)
return .F.
endif
do while !feof(lhDecryptedFileHandle)
lcDecryptedText = fread(lhDecryptedFileHandle,1024)
this.CryptHashData(lhHashHandle, lcDecryptedText, len(lcDecryptedText), 0)
if this.GetLastApiError() <> 0 then
if this.ldisplayhighlevelapierrors then
messagebox (dcSignFileHashing_ERR_LOC)
endif
this.CryptDestroyHash(lhHashHandle)
fclose(lhDecryptedFileHandle)
return .F.
endif
enddo
lcSignature = this.CryptSignHash(lhHashHandle, dnAT_SIGNATURE, 0)
if this.GetLastApiError() <> 0
if this.ldisplayhighlevelapierrors then
messagebox (ErrorSigningData)
endif
this.CryptDestroyHash(lhHashHandle)
fclose(lhDecryptedFileHandle)
return .F.
endif
pcSignature = lcSignature
this.CryptDestroyHash(lhHashHandle)
this.ExportSignaturePublicKey(@pcSignaturePublicKey)
fclose(lhDecryptedFileHandle)
return .T.
ENDPROC
HIDDEN PROCEDURE strtobin && Convert a byte stream with the least significate byte first and the most significan last into a Number.
LPARAMETER picInput
*** picInput - Integer encoded into a character string
*** Left most Character is least significant
*** Right most character is most significant
*** return - Integer represented by character string
*** Converts Integer encoded Character String into an Integer
LOCAL lnreturn, lnCounter
lnReturn = 0
for lnCounter = 1 to len(picInput)
lnReturn = lnReturn + bitlshift(asc(substr(picInput,lnCounter,1)),bitlshift((lnCounter-1),3))
endfor
return lnReturn
ENDPROC
HIDDEN PROCEDURE systemmessage && Look an Error Number up in the system table and return the string message text.
LPARAMETER pinError
*** pinError - Windows API Error Number
*** returns - Formated Windows API Error Message String
*** Sets flags and calls for Windows API Format Message which
*** Returns the Windows Error Message associated
*** with the Windows Error Number Input
***
return this.FormatMessage(BITOR(dnFORMAT_MESSAGE_FROM_SYSTEM, ;
dnFORMAT_MESSAGE_IGNORE_INSERTS) , ;
pinError)
ENDPROC
PROCEDURE usekeycontanier && Make a Named or Default key container the one currently in use
LParameter pcContainerName
*** Change Key Container Currently in Use
LOCAL lhProviderHandle
this.cContainerName = pcContainerName
this.CryptReleaseContext(this.hProviderHandle)
lnError = this.CryptAcquireContext(@lhProviderHandle,pcContainerName,this.cProviderName,dnPROV_RSA_FULL,0)
If lnError = 0
this.hProviderHandle = 0
if this.lDisplayLowLevelApiErrors
messagebox(dcCRYPTUSEKEYCONTAINER_ERR_LOC,MB_APPLMODAL+MB_ICONEXCLAMATION+MB_OK,dcError)
endif
this.nlastapierror = getlasterror()
this.apierror(program())
return .F.
else
this.nlastapierror = 0
this.hProviderHandle = lhProviderHandle
endif
return .T.
ENDPROC
PROCEDURE verifyfilesignature && Verify File Signature
LPARAMETERS pcDecryptedFileName, pcSignature, pcSignaturePublicKey, plVerified
*** pcDecryptedFileName - File name to Create an Encrypted Signature for
*** pcSignature - Signature String
*** pcSignaturePublicKey - Public Key String
*** plVerified - Reference to Verification Logical
*** Return Signature in pcSignature
*** Signature PublicKey in pcSignaturePublicKey
*** .T. - Success
*** .F. - Failure
*** Logical Variable to Return Verification Information
Local lhHashHandle, lnError, lnYN, lhSignFileHandle, lhDecryptedFileHandle, lnBytesWritten, lhPublicKey
Local lcInput, lcSignature, lcDecrytedText
if empty(pcDecryptedFileName)
if this.ldisplayhighlevelapierrors then
messagebox(dcSignFileParamter_ERR_LOC)
endif
return .F.
endif
lhDecryptedFileHandle = fopen(alltrim(pcDecryptedFileName))
if lhDecryptedFileHandle = -1 then
if this.ldisplayhighlevelapierrors then
messagebox(dcSignFileDecryptedFile_ERR_LOC,MB_ICONEXCLAMATION + MB_APPLMODAL + MB_OK)
endif
return .F.
endif
lhHashHandle = 0
this.CryptCreateHash(this.hProviderHandle,dnCALG_MD5,0,0,@lhHashHandle)
if this.GetLastApiError() <> 0 then
if this.ldisplayhighlevelapierrors then
messagebox (dcSignFileHashObject_ERR_LOC)
endif
fclose(lhDecryptedFileHandle)
return .F.
endif
do while !feof(lhDecryptedFileHandle)
lcDecryptedText = fread(lhDecryptedFileHandle,1024)
this.CryptHashData(lhHashHandle, lcDecryptedText, len(lcDecryptedText), 0)
if this.GetLastApiError() <> 0 then
if this.ldisplayhighlevelapierrors then
messagebox (dcSignFileHashing_ERR_LOC)
endif
this.CryptDestroyHash(lhHashHandle)
fclose(lhDecryptedFileHandle)
return .F.
endif
enddo
lhPublicKey = 0
this.ImportPublicKey(pcSignaturePublicKey, @lhPublicKey)
if this.CryptVerifySignature(lhHashHandle, pcSignature, lhPublicKey, 0)
this.CryptDestroyHash(lhHashHandle)
fclose(lhDecryptedFileHandle)
plVerified = .T.
else
this.CryptDestroyHash(lhHashHandle)
fclose(lhDecryptedFileHandle)
return .F.
endif
return .T.
ENDPROC
ENDDEFINE