import { NodeMaterialsManager , EncryptionRequest , DecryptionRequest , EncryptionContext , NodeAlgorithmSuite , NodeEncryptionMaterial , NodeDecryptionMaterial , SignatureKey , needs , VerificationKey , immutableClass , readOnlyProperty , KeyringNode , GetEncryptionMaterials , GetDecryptMaterials , CommitmentPolicySuites , } from '@aws-crypto/material-management' ; import { ENCODED_SIGNER_KEY } from '@aws-crypto/serialize' ; import { createECDH } from 'crypto' ; export type NodeEncryptionRequest = EncryptionRequest < NodeAlgorithmSuite > ; export type NodeDecryptionRequest = DecryptionRequest < NodeAlgorithmSuite > ; export type NodeGetEncryptionMaterials = GetEncryptionMaterials < NodeAlgorithmSuite > ; export type NodeGetDecryptMaterials = GetDecryptMaterials < NodeAlgorithmSuite > ; /**
 * The NodeDefaultCryptographicMaterialsManager is a specific implementation of the CryptographicMaterialsManager.
 * New cryptography materials managers SHOULD extend from NodeMaterialsManager.
 * Users should never need to create an instance of a NodeDefaultCryptographicMaterialsManager.
 */ export class NodeDefaultCryptographicMaterialsManager implements NodeMaterialsManager { declare readonly keyring : KeyringNode ; constructor ( keyring ) { needs ( keyring instanceof KeyringNode , 'Unsupported type.' ) ; readOnlyProperty ( this , 'keyring' , keyring ) ; } async getEncryptionMaterials ( { suite , encryptionContext , commitmentPolicy , } ) { suite = suite || new NodeAlgorithmSuite ( CommitmentPolicySuites [ commitmentPolicy ] . defaultAlgorithmSuite ) ; needs ( ! Object . prototype . hasOwnProperty . call ( encryptionContext , ENCODED_SIGNER_KEY ) , `Reserved encryptionContext value ${ ENCODED_SIGNER_KEY } not allowed.` ) ; const material = await this . keyring . onEncrypt ( this . _initializeEncryptionMaterial ( suite , encryptionContext ) ) ; needs ( material . getUnencryptedDataKey ( ) , 'Unencrypted data key is invalid.' ) ; needs ( material . encryptedDataKeys . length , 'No EncryptedDataKeys: the ciphertext can never be decrypted.' ) ; return material ; } async decryptMaterials ( { suite , encryptedDataKeys , encryptionContext , } ) { const material = await this . keyring . onDecrypt ( this . _initializeDecryptionMaterial ( suite , encryptionContext ) , encryptedDataKeys . slice ( ) ) ; needs ( material . getUnencryptedDataKey ( ) , 'Unencrypted data key is invalid.' ) ; return material ; } _initializeEncryptionMaterial ( suite , encryptionContext ) { const { signatureCurve : namedCurve } = suite ; if ( ! namedCurve ) return new NodeEncryptionMaterial ( suite , encryptionContext ) ; const ecdh = createECDH ( namedCurve ) ; ecdh . generateKeys ( ) ; const compressPoint = ecdh . getPublicKey ( undefined , 'compressed' ) ; const privateKey = ecdh . getPrivateKey ( ) ; const signatureKey = new SignatureKey ( privateKey , new Uint8Array ( compressPoint ) , suite ) ; return new NodeEncryptionMaterial ( suite , { ... encryptionContext , [ ENCODED_SIGNER_KEY ] : compressPoint . toString ( 'base64' ) , } ) . setSignatureKey ( signatureKey ) ; } _initializeDecryptionMaterial ( suite , encryptionContext ) { const { signatureCurve : namedCurve } = suite ; if ( ! namedCurve ) { needs ( ! Object . prototype . hasOwnProperty . call ( encryptionContext , ENCODED_SIGNER_KEY ) , 'Encryption context contains public verification key for unsigned algorithm suite.' ) ; return new NodeDecryptionMaterial ( suite , encryptionContext ) ; } if ( ! encryptionContext ) throw new Error ( 'Encryption context does not contain required public key.' ) ; const { [ ENCODED_SIGNER_KEY ] : compressPoint } = encryptionContext ; needs ( compressPoint , 'Context does not contain required public key.' ) ; const publicKeyBytes = VerificationKey . decodeCompressPoint ( Buffer . from ( compressPoint , 'base64' ) , suite ) ; return new NodeDecryptionMaterial ( suite , encryptionContext ) . setVerificationKey ( new VerificationKey ( publicKeyBytes , suite ) ) ; } } immutableClass ( NodeDefaultCryptographicMaterialsManager ) ;