import { CryptoProvider , PBKDF2Params , AESKey , RSAPublicKey , RSAPrivateKey , HMACKey , SymmetricKey , AESKeyParams , RSAKeyParams , HMACParams , HMACKeyParams , AESEncryptionParams , RSAEncryptionParams , HashParams , RSASigningParams } from "./crypto" ; import { concatBytes as concat , equalBytes as equal } from "./encoding" ; import { Err , ErrorCode } from "./error" ; /**
 * StubCryptoProvider is a stub implementation of the [[CryptoProvider]]
 * interface mainly used for testing. All methods merely emulate the behavior
 * of an actual implementation in a way that makes it compatible for use
 * with the rest of the **@padloc/core** package. Needless to say, this
 * class is **NOT SECURE AND SHOULD NEVER BE USED IN A PRODUCTION ENVIRONMENT**.
 */ export class StubCryptoProvider implements CryptoProvider { async randomBytes ( n ) { const bytes = new Uint8Array ( n ) ; for ( let i = 0 ; i < n ; i ++ ) { bytes [ i ] = Math . random ( ) * 255 ; } return bytes ; } async hash ( input , _params ) { return input . slice ( 0 , 32 ) ; } generateKey ( params ) ; generateKey ( params ) ; generateKey ( params ) ; async generateKey ( params ) { switch ( params . algorithm ) { case "AES" : case "HMAC" : return this . randomBytes ( params . keySize / 8 ) ; case "RSA" : const key = await this . randomBytes ( 32 ) ; return { publicKey : key , privateKey : key } ; } } async deriveKey ( password , params ) { const bytes = new Uint8Array ( params . keySize ) ; bytes . set ( concat ( [ password , params . salt ] ) ) ; return bytes . slice ( 0 , 32 ) ; } encrypt ( key , data , params ) ; encrypt ( publicKey , data , params ) ; async encrypt ( key , data , params ) { switch ( params . algorithm ) { case "AES-GCM" : return concat ( [ key , params . iv , params . additionalData , data ] ) ; case "RSA-OAEP" : return concat ( [ key , data ] ) ; default : throw new Err ( ErrorCode . NOT_SUPPORTED ) ; } } decrypt ( key , data , params ) ; decrypt ( publicKey , data , params ) ; async decrypt ( key , data , params ) { if ( params . algorithm . startsWith ( "AES" ) ) { params = params as AESEncryptionParams ; const keyLength = key . length ; const ivLength = params . iv . length ; const adataLength = params . additionalData . length ; const extractedKey = data . slice ( 0 , keyLength ) ; const iv = data . slice ( keyLength , keyLength + ivLength ) ; const adata = data . slice ( keyLength + ivLength , keyLength + ivLength + adataLength ) ; if ( ! equal ( key , extractedKey ) || ! equal ( iv , params . iv ) || ! equal ( adata , params . additionalData ) ) { throw new Err ( ErrorCode . DECRYPTION_FAILED ) ; } return data . slice ( keyLength + adataLength + ivLength ) ; } else { const keyLength = key . length ; const extractedKey = data . slice ( 0 , keyLength ) ; if ( ! equal ( key , extractedKey ) ) { throw new Err ( ErrorCode . DECRYPTION_FAILED ) ; } return data . slice ( keyLength ) ; } } async fingerprint ( key ) { return key ; } async sign ( key , data , params ) ; async sign ( key , data , params ) ; async sign ( key , data , _params ) { return concat ( [ key , data ] ) ; } async verify ( key , signature , data , params ) ; async verify ( key , signature , data , params ) ; async verify ( key , signature , data , _params ) { const keyLength = key . length ; const extractedKey = signature . slice ( 0 , keyLength ) ; const extractedData = signature . slice ( keyLength ) ; return equal ( key , extractedKey ) && equal ( data , extractedData ) ; } }