UNPKG

@wordpress/sync

Version:
128 lines (121 loc) 3.26 kB
// File copied as is from the y-webrtc package. /* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable eslint-comments/no-unlimited-disable */ /* eslint-disable */ // @ts-nocheck /* eslint-env browser */ import * as encoding from 'lib0/encoding'; import * as decoding from 'lib0/decoding'; import * as promise from 'lib0/promise'; import * as error from 'lib0/error'; import * as string from 'lib0/string'; /** * @param {string} secret * @param {string} roomName * @return {PromiseLike<CryptoKey>} */ export const deriveKey = ( secret, roomName ) => { const secretBuffer = string.encodeUtf8( secret ).buffer; const salt = string.encodeUtf8( roomName ).buffer; return crypto.subtle .importKey( 'raw', secretBuffer, 'PBKDF2', false, [ 'deriveKey' ] ) .then( ( keyMaterial ) => crypto.subtle.deriveKey( { name: 'PBKDF2', salt, iterations: 100000, hash: 'SHA-256', }, keyMaterial, { name: 'AES-GCM', length: 256, }, true, [ 'encrypt', 'decrypt' ] ) ); }; /** * @param {Uint8Array} data data to be encrypted * @param {CryptoKey?} key * @return {PromiseLike<Uint8Array>} encrypted, base64 encoded message */ export const encrypt = ( data, key ) => { if ( ! key ) { return /** @type {PromiseLike<Uint8Array>} */ ( promise.resolve( data ) ); } const iv = crypto.getRandomValues( new Uint8Array( 12 ) ); return crypto.subtle .encrypt( { name: 'AES-GCM', iv, }, key, data ) .then( ( cipher ) => { const encryptedDataEncoder = encoding.createEncoder(); encoding.writeVarString( encryptedDataEncoder, 'AES-GCM' ); encoding.writeVarUint8Array( encryptedDataEncoder, iv ); encoding.writeVarUint8Array( encryptedDataEncoder, new Uint8Array( cipher ) ); return encoding.toUint8Array( encryptedDataEncoder ); } ); }; /** * @param {Object} data data to be encrypted * @param {CryptoKey?} key * @return {PromiseLike<Uint8Array>} encrypted data, if key is provided */ export const encryptJson = ( data, key ) => { const dataEncoder = encoding.createEncoder(); encoding.writeAny( dataEncoder, data ); return encrypt( encoding.toUint8Array( dataEncoder ), key ); }; /** * @param {Uint8Array} data * @param {CryptoKey?} key * @return {PromiseLike<Uint8Array>} decrypted buffer */ export const decrypt = ( data, key ) => { if ( ! key ) { return /** @type {PromiseLike<Uint8Array>} */ ( promise.resolve( data ) ); } const dataDecoder = decoding.createDecoder( data ); const algorithm = decoding.readVarString( dataDecoder ); if ( algorithm !== 'AES-GCM' ) { promise.reject( error.create( 'Unknown encryption algorithm' ) ); } const iv = decoding.readVarUint8Array( dataDecoder ); const cipher = decoding.readVarUint8Array( dataDecoder ); return crypto.subtle .decrypt( { name: 'AES-GCM', iv, }, key, cipher ) .then( ( data ) => new Uint8Array( data ) ); }; /** * @param {Uint8Array} data * @param {CryptoKey?} key * @return {PromiseLike<Object>} decrypted object */ export const decryptJson = ( data, key ) => decrypt( data, key ).then( ( decryptedValue ) => decoding.readAny( decoding.createDecoder( new Uint8Array( decryptedValue ) ) ) );