*-------------------------------------------------------------------------------------------------------------------------------------------------------- * (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