@keeex/crypto
Advanced tools
Comparing version 3.3.3 to 3.4.0
@@ -31,10 +31,6 @@ /** | ||
export { Algorithms, CipherProvider, }; | ||
/** | ||
* Return the expected IV size for a given algorithm | ||
*/ | ||
/** Return the expected IV size for a given algorithm */ | ||
export declare const getIVSize: (algorithm: Algorithms) => Promise<number>; | ||
export declare const generateIV: (algorithm: Algorithms) => Promise<Uint8Array>; | ||
/** | ||
* Encrypt a buffer in one call, returning the result | ||
*/ | ||
/** Encrypt a buffer in one call, returning the result */ | ||
export declare const encryptRawImmediate: (data: Uint8Array, iv: Uint8Array, key: CryptoKey) => Promise<Uint8Array>; | ||
@@ -56,17 +52,9 @@ /** | ||
export declare const encryptImmediate: (data: Uint8Array, key: CryptoKey) => Promise<Uint8Array>; | ||
/** | ||
* Decipher a buffer in one call | ||
*/ | ||
/** Decipher a buffer in one call */ | ||
export declare const decryptRawImmediate: (data: Uint8Array, iv: Uint8Array, key: CryptoKey) => Promise<Uint8Array>; | ||
/** | ||
* Decrypt data from a buffer ciphered using encryptImmediate() | ||
*/ | ||
/** Decrypt data from a buffer ciphered using encryptImmediate() */ | ||
export declare const decryptImmediate: (data: Uint8Array, key: CryptoKey) => Promise<Uint8Array>; | ||
/** | ||
* Create an encryption context, to encrypt data in chunks | ||
*/ | ||
/** Create an encryption context, to encrypt data in chunks */ | ||
export declare const createEncryptionContext: (key: CryptoKey, iv: Uint8Array) => Promise<CipherContext>; | ||
/** | ||
* Create a decryption context, to decrypt data in chunks | ||
*/ | ||
/** Create a decryption context, to decrypt data in chunks */ | ||
export declare const createDecryptionContext: (key: CryptoKey, iv: Uint8Array) => Promise<CipherContext>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{buf82str as e,concatenateBuf8List as t,concatenatedBuf8ListSize as r,explodeBuf8List as n,getUint8Array as o,merge as i,str2buf8 as a}from"@keeex/js-utils/lib/uint8array.js";import{getProvider as c,getProviderOptions as p}from"./provider.js";import{Algorithms as s}from"./ciphertypes.js";import{notImplemented as m}from"./exception.js";import{randomBytes as d}from"./random.js";import{getPureCipher as y,getPureKeys as w}from"./pureprovider.js";export{s as Algorithms};export const getIVSize=async e=>{const t=c().cipherProvider;if(t.getIVSize)return t.getIVSize(e);if(t.generateIV)return(await t.generateIV(e)).byteLength;switch(e){case s.AESCBC:case s.AESCTR:return 16}};export const generateIV=async e=>{const t=c().cipherProvider;if(t.generateIV)return t.generateIV(e);const r=await getIVSize(e);return d(r)};export const encryptRawImmediate=(e,t,r)=>{const n=c().cipherProvider;return n.encryptRawImmediate?n.encryptRawImmediate(e,t,r):(async(e,t,r)=>{const n=c().cipherProvider;if(!n.createEncryptionContext)throw m();const o=await n.createEncryptionContext(r,t),a=await o.update(e),p=await o.final();return i([a,p])})(e,t,r)};export const encryptImmediateEncoding=(e,r,n)=>{const o=a(e.algorithm()),i=n??new Uint8Array;return t([o,r,i],void 0===n)};export const encryptImmediate=async(e,t)=>{const r=await generateIV(t.algorithm()),n=await encryptRawImmediate(e,r,t);return encryptImmediateEncoding(t,o(r),o(n))};export const decryptRawImmediate=async(e,t,r)=>{const n=c().cipherProvider;return n.decryptRawImmediate?n.decryptRawImmediate(e,t,r):(async(e,t,r)=>{const n=c().cipherProvider;if(!n.createDecryptionContext)throw m();const o=await n.createDecryptionContext(r,t),a=await o.update(e),p=await o.final();return i([a,p])})(e,t,r)};export const decryptImmediate=async(t,o)=>{const[i,a,c]=n(t);let p;if(c.byteLength>0)p=c;else{const e=r(t);p=t.slice(e)}const s=e(i);if(s!==o.algorithm())throw new Error(`Invalid key for "${o.algorithm()}" used to decipher "${s}"`);return decryptRawImmediate(p,a,o)};export const createEncryptionContext=async(e,t)=>{const r=c().cipherProvider;if(r.createEncryptionContext)return r.createEncryptionContext(e,t);if(p().noImmediateFallback){const r=(await y()).createEncryptionContext;if(!r)throw new Error("Unexpected state");const n=await w();return r(await n.importCryptoKey(e.algorithm(),await e.export()),t)}return((e,t)=>{const r=c().cipherProvider;if(!r.encryptRawImmediate)throw m();const n=[];return{update:e=>(n.push(o(e,void 0,void 0,!0)),Promise.resolve(new Uint8Array)),final:async()=>{const o=i(n);if(!r.encryptRawImmediate)throw m();return r.encryptRawImmediate(o,t,e)}}})(e,t)};export const createDecryptionContext=async(e,t)=>{const r=c().cipherProvider;if(r.createDecryptionContext)return r.createDecryptionContext(e,t);if(p().noImmediateFallback){const r=(await y()).createEncryptionContext;if(!r)throw new Error("Unexpected state");const n=await w();return r(await n.importCryptoKey(e.algorithm(),await e.export()),t)}return Promise.resolve(((e,t)=>{const r=c().cipherProvider;if(!r.decryptRawImmediate)throw m();const n=[];return{update:e=>(n.push(o(e,void 0,void 0,!0)),Promise.resolve(new Uint8Array)),final:async()=>{const o=i(n);if(!r.decryptRawImmediate)throw m();return r.decryptRawImmediate(o,t,e)}}})(e,t))}; | ||
import{buf82str as e,concatenateBuf8List as t,concatenatedBuf8ListSize as r,explodeBuf8List as n,getUint8Array as o,merge as i,str2buf8 as a}from"@keeex/js-utils/lib/uint8array.js";import{getProvider as c,getProviderOptions as p}from"./provider.js";import{Algorithms as s}from"./ciphertypes.js";import{notImplemented as m}from"./exception.js";import{randomBytes as d}from"./random.js";import{getPureCipher as y,getPureKeys as w}from"./pureprovider.js";export{s as Algorithms};export const getIVSize=async e=>{const t=c().cipherProvider;if(t.getIVSize)return t.getIVSize(e);if(t.generateIV)return(await t.generateIV(e)).byteLength;switch(e){case s.AESCBC:case s.AESCTR:return 16}};export const generateIV=async e=>{const t=c().cipherProvider;if(t.generateIV)return t.generateIV(e);const r=await getIVSize(e);return d(r)};export const encryptRawImmediate=async(e,t,r)=>{const n=c().cipherProvider;return n.encryptRawImmediate?n.encryptRawImmediate(e,t,r):(async(e,t,r)=>{const n=c().cipherProvider;if(!n.createEncryptionContext)throw m();const o=await n.createEncryptionContext(r,t),a=await o.update(e),p=await o.final();return i([a,p])})(e,t,r)};export const encryptImmediateEncoding=(e,r,n)=>{const o=a(e.algorithm()),i=n??new Uint8Array;return t([o,r,i],void 0===n)};export const encryptImmediate=async(e,t)=>{const r=await generateIV(t.algorithm()),n=await encryptRawImmediate(e,r,t);return encryptImmediateEncoding(t,o(r),o(n))};export const decryptRawImmediate=async(e,t,r)=>{const n=c().cipherProvider;return n.decryptRawImmediate?n.decryptRawImmediate(e,t,r):(async(e,t,r)=>{const n=c().cipherProvider;if(!n.createDecryptionContext)throw m();const o=await n.createDecryptionContext(r,t),a=await o.update(e),p=await o.final();return i([a,p])})(e,t,r)};export const decryptImmediate=async(t,o)=>{const[i,a,c]=n(t);let p;if(c.byteLength>0)p=c;else{const e=r(t);p=t.slice(e)}const s=e(i);if(s!==o.algorithm())throw new Error(`Invalid key for "${o.algorithm()}" used to decipher "${s}"`);return decryptRawImmediate(p,a,o)};export const createEncryptionContext=async(e,t)=>{const r=c().cipherProvider;if(r.createEncryptionContext)return r.createEncryptionContext(e,t);if(p().noImmediateFallback){const r=(await y()).createEncryptionContext;if(!r)throw new Error("Unexpected state");const n=await w();return r(await n.importCryptoKey(e.algorithm(),await e.export()),t)}return((e,t)=>{const r=c().cipherProvider;if(!r.encryptRawImmediate)throw m();const n=[];return{update:e=>(n.push(o(e,void 0,void 0,!0)),Promise.resolve(new Uint8Array)),final:async()=>{const o=i(n);if(!r.encryptRawImmediate)throw m();return r.encryptRawImmediate(o,t,e)}}})(e,t)};export const createDecryptionContext=async(e,t)=>{const r=c().cipherProvider;if(r.createDecryptionContext)return r.createDecryptionContext(e,t);if(p().noImmediateFallback){const r=(await y()).createEncryptionContext;if(!r)throw new Error("Unexpected state");const n=await w();return r(await n.importCryptoKey(e.algorithm(),await e.export()),t)}return Promise.resolve(((e,t)=>{const r=c().cipherProvider;if(!r.decryptRawImmediate)throw m();const n=[];return{update:e=>(n.push(o(e,void 0,void 0,!0)),Promise.resolve(new Uint8Array)),final:async()=>{const o=i(n);if(!r.decryptRawImmediate)throw m();return r.decryptRawImmediate(o,t,e)}}})(e,t))}; |
@@ -29,2 +29,3 @@ /** | ||
import { CryptoKey } from "./keys.js"; | ||
import { Awaitable } from "./utils.js"; | ||
export declare enum Algorithms { | ||
@@ -34,37 +35,23 @@ AESCTR = "AES-CTR", | ||
} | ||
/** | ||
* A basic cipher context that provide means to encrypt/decrypt data | ||
*/ | ||
/** A basic cipher context that provide means to encrypt/decrypt data */ | ||
export interface CipherContext { | ||
/** | ||
* Add input data | ||
*/ | ||
update: (data: Uint8Array) => Promise<Uint8Array>; | ||
/** | ||
* Must be called after processing to return the last block of data | ||
*/ | ||
final: () => Promise<Uint8Array>; | ||
/** Add input data */ | ||
update: (data: Uint8Array) => Awaitable<Uint8Array>; | ||
/** Must be called after processing to return the last block of data */ | ||
final: () => Awaitable<Uint8Array>; | ||
} | ||
export interface CipherProvider { | ||
/** | ||
* Return the expected size of the IV for the given algorithm. | ||
*/ | ||
getIVSize?(algorithm: Algorithms): Promise<number>; | ||
/** | ||
* Generate an IV for the given algorithm | ||
*/ | ||
generateIV?(algorithm: Algorithms): Promise<Uint8Array>; | ||
/** Return the expected size of the IV for the given algorithm. */ | ||
getIVSize?(algorithm: Algorithms): Awaitable<number>; | ||
/** Generate an IV for the given algorithm */ | ||
generateIV?(algorithm: Algorithms): Awaitable<Uint8Array>; | ||
/** Simple interface to cipher a buffer in one call. */ | ||
encryptRawImmediate?(data: Uint8Array, iv: Uint8Array, key: CryptoKey): Promise<Uint8Array>; | ||
encryptRawImmediate?(data: Uint8Array, iv: Uint8Array, key: CryptoKey): Awaitable<Uint8Array>; | ||
/** Counterpart to encryptRawImmediate() */ | ||
decryptRawImmediate?(data: Uint8Array, iv: Uint8Array, key: CryptoKey): Promise<Uint8Array>; | ||
/** | ||
* Create a generic encryption context | ||
*/ | ||
createEncryptionContext?(key: CryptoKey, iv: Uint8Array): Promise<CipherContext>; | ||
/** | ||
* Create a generic decryption context | ||
*/ | ||
createDecryptionContext?(key: CryptoKey, iv: Uint8Array): Promise<CipherContext>; | ||
decryptRawImmediate?(data: Uint8Array, iv: Uint8Array, key: CryptoKey): Awaitable<Uint8Array>; | ||
/** Create a generic encryption context */ | ||
createEncryptionContext?(key: CryptoKey, iv: Uint8Array): Awaitable<CipherContext>; | ||
/** Create a generic decryption context */ | ||
createDecryptionContext?(key: CryptoKey, iv: Uint8Array): Awaitable<CipherContext>; | ||
} | ||
export declare const isCipherProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<CipherProvider>; |
@@ -30,21 +30,11 @@ /** | ||
export { Algorithms, Digest, DigestProvider, }; | ||
/** | ||
* Return the internal block size for a given digest algorithm, in bytes | ||
*/ | ||
/** Return the internal block size for a given digest algorithm, in bytes */ | ||
export declare const digestBlockSize: (algorithm: Algorithms) => number; | ||
/** | ||
* Return the output size for a given digest algorithm, in bytes | ||
*/ | ||
/** Return the output size for a given digest algorithm, in bytes */ | ||
export declare const digestOutputSize: (algorithm: Algorithms) => number; | ||
/** | ||
* Compute the digest of a full buffer | ||
*/ | ||
/** Compute the digest of a full buffer */ | ||
export declare const digestImmediate: (algorithm: Algorithms, data: Uint8Array) => Promise<Uint8Array>; | ||
/** | ||
* Compute the digest of a string | ||
*/ | ||
/** Compute the digest of a string */ | ||
export declare const digestString: (algorithm: Algorithms, data: string) => Promise<Uint8Array>; | ||
/** | ||
* Return a chunk-based digest object | ||
*/ | ||
/** Return a chunk-based digest object */ | ||
export declare const digest: (algorithm: Algorithms) => Promise<Digest>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{utf82buf8 as e}from"@keeex/js-utils/lib/uint8array.js";import{getProvider as r,getProviderOptions as t}from"./provider.js";import{notImplemented as s}from"./exception.js";import i from"./digest/chunkdigest.js";import{Algorithms as n}from"./digesttypes.js";import{getPureDigest as c}from"./pureprovider.js";export{n as Algorithms};export const digestBlockSize=e=>{switch(e){case n.SHA1:case n.SHA224:case n.SHA256:return 64;case n.SHA512:return 128;case n.RIPEMD160:return 64;case n.SHA3_224:return 144;case n.SHA3_256:return 136;case n.SHA3_384:return 104;case n.SHA3_512:return 72;case n.KECCAK224:return 144;case n.KECCAK256:return 136;case n.KECCAK384:return 104;case n.KECCAK512:return 72}};export const digestOutputSize=e=>{switch(e){case n.SHA1:return 20;case n.SHA224:return 28;case n.SHA256:return 32;case n.SHA512:return 64;case n.RIPEMD160:return 20;case n.SHA3_224:return 28;case n.SHA3_256:return 32;case n.SHA3_384:return 48;case n.SHA3_512:return 64;case n.KECCAK224:return 28;case n.KECCAK256:return 32;case n.KECCAK384:return 48;case n.KECCAK512:return 64}};export const digestImmediate=(e,t)=>{const i=r().digestProvider;return i.digestImmediate?i.digestImmediate(e,t):(async(e,t)=>{const i=r().digestProvider;if(!i.digest)throw s();return(await i.digest(e)).digest(t)})(e,t)};export const digestString=(r,t)=>digestImmediate(r,e(t));export const digest=e=>{const s=r().digestProvider;return s.digest?s.digest(e):(async e=>{if(t().noImmediateFallback){const r=(await c()).digest;if(!r)throw new Error("Unexpected state");return r(e)}return new i(e,digestImmediate)})(e)}; | ||
import{utf82buf8 as e}from"@keeex/js-utils/lib/uint8array.js";import{getProvider as r,getProviderOptions as t}from"./provider.js";import{notImplemented as s}from"./exception.js";import i from"./digest/chunkdigest.js";import{Algorithms as n}from"./digesttypes.js";import{getPureDigest as c}from"./pureprovider.js";export{n as Algorithms};export const digestBlockSize=e=>{switch(e){case n.SHA1:case n.SHA224:case n.SHA256:return 64;case n.SHA512:return 128;case n.RIPEMD160:return 64;case n.SHA3_224:return 144;case n.SHA3_256:return 136;case n.SHA3_384:return 104;case n.SHA3_512:return 72;case n.KECCAK224:return 144;case n.KECCAK256:return 136;case n.KECCAK384:return 104;case n.KECCAK512:return 72}};export const digestOutputSize=e=>{switch(e){case n.SHA1:return 20;case n.SHA224:return 28;case n.SHA256:return 32;case n.SHA512:return 64;case n.RIPEMD160:return 20;case n.SHA3_224:return 28;case n.SHA3_256:return 32;case n.SHA3_384:return 48;case n.SHA3_512:return 64;case n.KECCAK224:return 28;case n.KECCAK256:return 32;case n.KECCAK384:return 48;case n.KECCAK512:return 64}};export const digestImmediate=async(e,t)=>{const i=r().digestProvider;return i.digestImmediate?i.digestImmediate(e,t):(async(e,t)=>{const i=r().digestProvider;if(!i.digest)throw s();return(await i.digest(e)).digest(t)})(e,t)};export const digestString=(r,t)=>digestImmediate(r,e(t));export const digest=async e=>{const s=r().digestProvider;return s.digest?s.digest(e):(async e=>{if(t().noImmediateFallback){const r=(await c()).digest;if(!r)throw new Error("Unexpected state");return r(e)}return new i(e,digestImmediate)})(e)}; |
@@ -30,18 +30,10 @@ /** | ||
import { Algorithms as DigestAlgorithms, DigestImmediateFunc } from "../digesttypes.js"; | ||
/** | ||
* Dummy implementation that falls back to using digestImmediate() | ||
*/ | ||
/** Dummy implementation that falls back to using digestImmediate() */ | ||
export default class ChunkDigest implements Digest { | ||
private algorithm; | ||
private digestImmediate; | ||
private buffer; | ||
#private; | ||
constructor(algorithm: DigestAlgorithms, digestImmediateFunc: DigestImmediateFunc); | ||
/** | ||
* Append an input chunk of data | ||
*/ | ||
update(bytes: Uint8Array): Promise<void>; | ||
/** | ||
* Optionnaly append data and return the result of the digest | ||
*/ | ||
digest(data?: Uint8Array): Promise<Uint8Array>; | ||
/** Append an input chunk of data */ | ||
update: (bytes: Uint8Array) => void; | ||
/** Optionnaly append data and return the result of the digest */ | ||
digest: (data?: Uint8Array) => Promise<Uint8Array>; | ||
} |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{merge as t}from"@keeex/js-utils/lib/uint8array.js";export default class e{algorithm;digestImmediate;buffer;constructor(t,e){this.algorithm=t,this.buffer=new Uint8Array,this.digestImmediate=e}update(e){return this.buffer=t([this.buffer,e]),Promise.resolve()}async digest(t){return t&&await this.update(t),this.digestImmediate(this.algorithm,this.buffer)}} | ||
import{merge as t}from"@keeex/js-utils/lib/uint8array.js";export default class i{#t;#i;#e;constructor(t,i){this.#t=t,this.#e=new Uint8Array,this.#i=i}update=i=>{this.#e=t([this.#e,i])};digest=async t=>(t&&this.update(t),this.#i(this.#t,this.#e))} |
@@ -28,2 +28,3 @@ /** | ||
*/ | ||
import { Awaitable } from "./utils.js"; | ||
/** | ||
@@ -33,4 +34,4 @@ * Interface for chunk-based digest | ||
export interface Digest { | ||
update(data: Uint8Array): Promise<void>; | ||
digest(data?: Uint8Array): Promise<Uint8Array>; | ||
update(data: Uint8Array): Awaitable<void>; | ||
digest(data?: Uint8Array): Awaitable<Uint8Array>; | ||
} | ||
@@ -56,10 +57,8 @@ /** | ||
/** Function to compute the hash of a buffer in one call */ | ||
export type DigestImmediateFunc = (algorithm: Algorithms, data: Uint8Array) => Promise<Uint8Array>; | ||
/** | ||
* Interface that any digest provider must implement | ||
*/ | ||
export type DigestImmediateFunc = (algorithm: Algorithms, data: Uint8Array) => Awaitable<Uint8Array>; | ||
/** Interface that any digest provider must implement */ | ||
export interface DigestProvider { | ||
digestImmediate?: DigestImmediateFunc; | ||
digest?: (algorithm: Algorithms) => Promise<Digest>; | ||
digest?: (algorithm: Algorithms) => Awaitable<Digest>; | ||
} | ||
export declare const isDigestProvider: import("@keeex/js-utils/lib/types/types").TypePredicate<DigestProvider>; | ||
export declare const isDigestProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<DigestProvider>; |
@@ -30,9 +30,5 @@ /** | ||
export { Algorithms, HmacProvider, }; | ||
/** | ||
* Return an object that can process hmac in chunks | ||
*/ | ||
/** Return an object that can process hmac in chunks */ | ||
export declare const hmac: (algorithm: Algorithms, key: Uint8Array) => Promise<Hmac>; | ||
/** | ||
* Compute a HMAC on a single buffer | ||
*/ | ||
/** Compute a HMAC on a single buffer */ | ||
export declare const hmacImmediate: (algorithm: Algorithms, data: Uint8Array, key: Uint8Array) => Promise<Uint8Array>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{getProvider as m}from"./provider.js";import{Algorithms as r}from"./hmactypes.js";import a from"./hmac/chunkhmac.js";export{r as Algorithms};export const hmac=(r,c)=>{const e=m().hmacProvider;return e.hmac?e.hmac(r,c):Promise.resolve(new a(r,c))};export const hmacImmediate=(r,a,c)=>{const e=m().hmacProvider;return e.hmacImmediate?e.hmacImmediate(r,a,c):(async(m,r,a)=>(await hmac(m,a)).hmac(r))(r,a,c)}; | ||
import{getProvider as m}from"./provider.js";import{Algorithms as a}from"./hmactypes.js";import c from"./hmac/chunkhmac.js";export{a as Algorithms};export const hmac=async(a,r)=>{const e=m().hmacProvider;return e.hmac?e.hmac(a,r):Promise.resolve(new c(a,r))};export const hmacImmediate=async(a,c,r)=>{const e=m().hmacProvider;return e.hmacImmediate?e.hmacImmediate(a,c,r):(async(m,a,c)=>(await hmac(m,c)).hmac(a))(a,c,r)}; |
@@ -36,18 +36,10 @@ /** | ||
export default class ChunkHmac implements Hmac { | ||
private algorithm; | ||
private key?; | ||
private outerKeyPad?; | ||
private innerDigest?; | ||
#private; | ||
constructor(algorithm: Algorithms, key: Uint8Array); | ||
/** | ||
* Return an appropriate length key for HMAC | ||
*/ | ||
static padKey(algorithm: Algorithms, key: Uint8Array): Promise<Uint8Array>; | ||
/** | ||
* XOR a byte buffer with the given byte | ||
*/ | ||
static xorBuffer(input: Uint8Array, byteKey: number): Uint8Array; | ||
update(data: Uint8Array): Promise<void>; | ||
hmac(data?: Uint8Array): Promise<Uint8Array>; | ||
private computeKeyPads; | ||
/** Return an appropriate length key for HMAC */ | ||
static padKey: (algorithm: Algorithms, key: Uint8Array) => Promise<Uint8Array>; | ||
/** XOR a byte buffer with the given byte */ | ||
static xorBuffer: (input: Uint8Array, byteKey: number) => Uint8Array; | ||
update: (data: Uint8Array) => Promise<void>; | ||
hmac: (data?: Uint8Array) => Promise<Uint8Array>; | ||
} |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{getUint8Array as t}from"@keeex/js-utils/lib/uint8array.js";import{digest as e,digestBlockSize as i,digestImmediate as s}from"../digest.js";export default class r{algorithm;key;outerKeyPad;innerDigest;constructor(e,i){this.algorithm=e,this.key=t(i,void 0,void 0,!0)}static async padKey(t,e){const r=i(t);if(e.byteLength>r)return s(t,e);if(e.byteLength<r){const t=new Uint8Array(r);return t.set(e),t.fill(0,e.byteLength),t}return e}static xorBuffer(t,e){const i=new Uint8Array(t.byteLength);for(let s=0;s<t.byteLength;++s)i[s]=t[s]^e;return i}async update(t){if(!this.innerDigest){const t=await this.computeKeyPads();this.outerKeyPad=t.outerKeyPad,this.innerDigest=t.innerDigest}await this.innerDigest.update(t)}async hmac(t){if(t&&await this.update(t),!this.outerKeyPad||!this.innerDigest){const t=await this.computeKeyPads();this.outerKeyPad=t.outerKeyPad,this.innerDigest=t.innerDigest}const i=await e(this.algorithm);return await i.update(this.outerKeyPad),i.digest(await this.innerDigest.digest())}async computeKeyPads(){if(!this.key)throw new Error("Unexpected state");const t=await r.padKey(this.algorithm,this.key);this.key=void 0;const i=r.xorBuffer(t,92),s=r.xorBuffer(t,54),a=await e(this.algorithm);return await a.update(s),{outerKeyPad:i,innerDigest:a}}} | ||
import{getUint8Array as t}from"@keeex/js-utils/lib/uint8array.js";import{digest as e,digestBlockSize as i,digestImmediate as s}from"../digest.js";export default class r{#t;#e;#i;#s;constructor(e,i){this.#t=e,this.#e=t(i,void 0,void 0,!0)}static padKey=async(t,e)=>{const r=i(t);if(e.byteLength>r)return s(t,e);if(e.byteLength<r){const t=new Uint8Array(r);return t.set(e),t.fill(0,e.byteLength),t}return e};static xorBuffer=(t,e)=>{const i=new Uint8Array(t.byteLength);for(let s=0;s<t.byteLength;++s)i[s]=t[s]^e;return i};update=async t=>{if(!this.#s){const t=await this.#r();this.#i=t.outerKeyPad,this.#s=t.innerDigest}await this.#s.update(t)};hmac=async t=>{if(t&&await this.update(t),!this.#i||!this.#s){const t=await this.#r();this.#i=t.outerKeyPad,this.#s=t.innerDigest}const i=await e(this.#t);return await i.update(this.#i),i.digest(await this.#s.digest())};#r=async()=>{if(!this.#e)throw new Error("Unexpected state");const t=await r.padKey(this.#t,this.#e);this.#e=void 0;const i=r.xorBuffer(t,92),s=r.xorBuffer(t,54),a=await e(this.#t);return await a.update(s),{outerKeyPad:i,innerDigest:a}}} |
@@ -28,2 +28,3 @@ /** | ||
*/ | ||
import { Awaitable } from "./utils.js"; | ||
export declare enum Algorithms { | ||
@@ -34,15 +35,11 @@ SHA256 = "SHA-256", | ||
export interface Hmac { | ||
update: (data: Uint8Array) => Promise<void>; | ||
hmac: (data?: Uint8Array) => Promise<Uint8Array>; | ||
update: (data: Uint8Array) => Awaitable<void>; | ||
hmac: (data?: Uint8Array) => Awaitable<Uint8Array>; | ||
} | ||
export interface HmacProvider { | ||
/** | ||
* Generate a hmac value | ||
*/ | ||
hmacImmediate?: (algorithm: Algorithms, data: Uint8Array, key: Uint8Array) => Promise<Uint8Array>; | ||
/** | ||
* Return a hmac context to process input in chunks | ||
*/ | ||
hmac?: (algorithm: Algorithms, key: Uint8Array) => Promise<Hmac>; | ||
/** Generate a hmac value */ | ||
hmacImmediate?: (algorithm: Algorithms, data: Uint8Array, key: Uint8Array) => Awaitable<Uint8Array>; | ||
/** Return a hmac context to process input in chunks */ | ||
hmac?: (algorithm: Algorithms, key: Uint8Array) => Awaitable<Hmac>; | ||
} | ||
export declare const isHmacProvider: import("@keeex/js-utils/lib/types/types").TypePredicate<HmacProvider>; | ||
export declare const isHmacProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<HmacProvider>; |
@@ -32,17 +32,9 @@ /** | ||
export { CryptoKey, KeysProvider, }; | ||
/** | ||
* Generate a random CryptoKey | ||
*/ | ||
/** Generate a random CryptoKey */ | ||
export declare const generateCryptoKey: (algorithm: CipherAlgorithms, keyLen: number) => Promise<CryptoKey>; | ||
/** | ||
* Transform raw data into a CryptoKey instance | ||
*/ | ||
/** Transform raw data into a CryptoKey instance */ | ||
export declare const importCryptoKey: (algorithm: CipherAlgorithms, keyData: Uint8Array) => Promise<CryptoKey>; | ||
/** | ||
* Create a CryptoKey from a low-entropy input using PBKDF2 | ||
*/ | ||
/** Create a CryptoKey from a low-entropy input using PBKDF2 */ | ||
export declare const deriveKey: (data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, targetAlgorithm: CipherAlgorithms, keyLen: number) => Promise<CryptoKey>; | ||
/** | ||
* Derive a fixed-size buffer from a low entropy source using PBKDF2 | ||
*/ | ||
/** Derive a fixed-size buffer from a low entropy source using PBKDF2 */ | ||
export declare const deriveKeyRaw: (data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, outLen: number) => Promise<Uint8Array>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{getProvider as e}from"./provider.js";import{randomBytes as r}from"./random.js";export const generateCryptoKey=(o,t)=>{const y=e().keysProvider;return y.generateCryptoKey?y.generateCryptoKey(o,t):(async(o,t)=>{const y=e().keysProvider,i=await r(t);return y.importCryptoKey(o,i)})(o,t)};export const importCryptoKey=(r,o)=>e().keysProvider.importCryptoKey(r,o);export const deriveKey=(r,o,t,y,i,n)=>{const p=e().keysProvider;return p.deriveKey?p.deriveKey(r,o,t,y,i,n):(async(r,o,t,y,i,n)=>{const p=e().keysProvider,s=await p.deriveKeyRaw(r,o,t,y,n);return p.importCryptoKey(i,s)})(r,o,t,y,i,n)};export const deriveKeyRaw=(r,o,t,y,i)=>e().keysProvider.deriveKeyRaw(r,o,t,y,i); | ||
import{getProvider as e}from"./provider.js";import{randomBytes as r}from"./random.js";export const generateCryptoKey=async(o,t)=>{const y=e().keysProvider;return y.generateCryptoKey?y.generateCryptoKey(o,t):(async(o,t)=>{const y=e().keysProvider,n=await r(t);return y.importCryptoKey(o,n)})(o,t)};export const importCryptoKey=async(r,o)=>e().keysProvider.importCryptoKey(r,o);export const deriveKey=async(r,o,t,y,n,s)=>{const i=e().keysProvider;return i.deriveKey?i.deriveKey(r,o,t,y,n,s):(async(r,o,t,y,n,s)=>{const i=e().keysProvider,p=await i.deriveKeyRaw(r,o,t,y,s);return i.importCryptoKey(n,p)})(r,o,t,y,n,s)};export const deriveKeyRaw=async(r,o,t,y,n)=>e().keysProvider.deriveKeyRaw(r,o,t,y,n); |
@@ -30,19 +30,14 @@ /** | ||
import { Algorithms as DigestAlgorithms } from "./digest.js"; | ||
/** | ||
* Basic key interface shared by all implementations | ||
*/ | ||
import { Awaitable } from "./utils.js"; | ||
/** Basic key interface shared by all implementations */ | ||
export interface CryptoKey { | ||
export(): Promise<Uint8Array>; | ||
export(): Awaitable<Uint8Array>; | ||
algorithm(): CipherAlgorithms; | ||
} | ||
export interface KeysProvider { | ||
/** Generate a new random key for symetric encryption */ | ||
generateCryptoKey?(algorithm: CipherAlgorithms, keyLen: number): Awaitable<CryptoKey>; | ||
/** Create a key based on existing data for symetric encryption */ | ||
importCryptoKey(algorithm: CipherAlgorithms, keyData: Uint8Array): Awaitable<CryptoKey>; | ||
/** | ||
* Generate a new random key for symetric encryption | ||
*/ | ||
generateCryptoKey?(algorithm: CipherAlgorithms, keyLen: number): Promise<CryptoKey>; | ||
/** | ||
* Create a key based on existing data for symetric encryption | ||
*/ | ||
importCryptoKey(algorithm: CipherAlgorithms, keyData: Uint8Array): Promise<CryptoKey>; | ||
/** | ||
* Derive a key from potentially not strong data source (passwords) | ||
@@ -54,3 +49,3 @@ * | ||
*/ | ||
deriveKey?(data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, targetAlgorithm: CipherAlgorithms, keyLen: number): Promise<CryptoKey>; | ||
deriveKey?(data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, targetAlgorithm: CipherAlgorithms, keyLen: number): Awaitable<CryptoKey>; | ||
/** | ||
@@ -61,4 +56,4 @@ * Derive a raw buffer from passwords using PBKDF2 | ||
*/ | ||
deriveKeyRaw(data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, outLen: number): Promise<Uint8Array>; | ||
deriveKeyRaw(data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, outLen: number): Awaitable<Uint8Array>; | ||
} | ||
export declare const isKeysProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<KeysProvider>; |
@@ -33,9 +33,5 @@ /** | ||
import { HmacProvider } from "./hmac.js"; | ||
/** | ||
* Interface that a cryptographic provider must implement | ||
*/ | ||
/** Interface that a cryptographic provider must implement */ | ||
export interface CryptoProvider { | ||
/** | ||
* Major version of `@keeex/crypto` supported by the provider. | ||
*/ | ||
/** Major version of `@keeex/crypto` supported by the provider. */ | ||
majorVersion: number; | ||
@@ -42,0 +38,0 @@ digestProvider: DigestProvider; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
export const getPureDigest=async()=>(await import("@keeex/crypto-provider-purejs/lib/digest/index.js")).default;export const getPureRandom=async()=>(await import("@keeex/crypto-provider-purejs/lib/random.js")).default;export const getPureCipher=async()=>(await import("@keeex/crypto-provider-purejs/lib/cipher/index.js")).default;export const getPureKeys=async()=>(await import("@keeex/crypto-provider-purejs/lib/keys/index.js")).default;export const getPureHMAC=async()=>(await import("@keeex/crypto-provider-purejs/lib/hmac.js")).default; | ||
export const getPureDigest=async()=>(await import("./purejs/digest/index.js")).default;export const getPureRandom=async()=>(await import("./purejs/random.js")).default;export const getPureCipher=async()=>(await import("./purejs/cipher/index.js")).default;export const getPureKeys=async()=>(await import("./purejs/keys/index.js")).default;export const getPureHMAC=async()=>(await import("./purejs/hmac.js")).default; |
@@ -30,5 +30,4 @@ /** | ||
export { RandomProvider }; | ||
/** | ||
* Return a set of random bytes | ||
*/ | ||
/** Return a set of random bytes */ | ||
export declare const randomBytes: (bytesCount: number) => Promise<Uint8Array>; | ||
export declare const randomFill: (buffer: ArrayBuffer | Uint8Array) => Promise<void>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{getProvider as r}from"./provider.js";export const randomBytes=o=>r().randomProvider.randomBytes(o); | ||
import{getProvider as r}from"./provider.js";export const randomBytes=async n=>{const o=r().randomProvider;if(o.randomBytes)return o.randomBytes(n);if(o.randomFill){const r=new Uint8Array(n);return await o.randomFill(r),r}throw new Error("Provider missing random source")};export const randomFill=async n=>{const o=r().randomProvider,t=(r=>r instanceof Uint8Array?r:new Uint8Array(r,0,r.byteLength))(n);if(o.randomFill)return o.randomFill(t);if(!o.randomBytes)throw new Error("Provider missing random source");{const r=await o.randomBytes(t.byteLength);t.set(r)}}; |
@@ -28,5 +28,8 @@ /** | ||
*/ | ||
import { Awaitable } from "./utils.js"; | ||
/** A random provider must implement at least one of `randomBytes()` or `randomFill()` */ | ||
export interface RandomProvider { | ||
randomBytes: (bytesCount: number) => Promise<Uint8Array>; | ||
randomBytes?: (bytesCount: number) => Awaitable<Uint8Array>; | ||
randomFill?: (buffer: Uint8Array) => Awaitable<void>; | ||
} | ||
export declare const isRandomProvider: import("@keeex/js-utils/lib/types/types").TypePredicate<RandomProvider>; | ||
export declare const isRandomProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<RandomProvider>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{makeProfilePredicate as o}from"@keeex/js-utils/lib/types/record.js";export const isRandomProvider=o({randomBytes:"function"}); | ||
import{makeProfilePredicate as o}from"@keeex/js-utils/lib/types/record.js";export const isRandomProvider=o({randomBytes:"?function",randomFill:"?function"}); |
@@ -38,18 +38,4 @@ /** | ||
export default class Decrypt extends Transform { | ||
private key; | ||
private state; | ||
#private; | ||
/** | ||
* Input chunk being processed. | ||
* The "read" methods get their input from this. It is set in `_transform()` and consummed | ||
* entirely each time. | ||
*/ | ||
private inputChunk; | ||
private inputChunkOffset; | ||
/** | ||
* The temporary read buffer to mimic explodeBuf8List() | ||
*/ | ||
private readBuffer; | ||
private settings; | ||
private context?; | ||
/** | ||
* Construct the encryption stream | ||
@@ -64,62 +50,5 @@ * | ||
constructor({ encryptionKey, objectMode, ...options }: EncryptOptions); | ||
/** | ||
* Decrypt input after extracting decryption data | ||
*/ | ||
_transform(chunk: Buffer | string, encoding: string, callback: TransformCallback): void; | ||
_flush(callback: TransformCallback): void; | ||
/** | ||
* Consume inputChunk. | ||
* Written in a separate function from _transform() to make it easier to handle with async | ||
*/ | ||
private processInputChunk; | ||
/** | ||
* Output the final bits of output, if any. | ||
*/ | ||
private processFinal; | ||
/** | ||
* Process a small portion of inputChunk. | ||
* | ||
* Called repeatedly as long as inputChunk is not processed entirely | ||
*/ | ||
private processTempBuffer; | ||
private readAlgoNameSize; | ||
private readAlgoName; | ||
private readIVSize; | ||
private readIV; | ||
private readCiphertextSize; | ||
/** | ||
* Only called if cipherSize === 0, meaning we need to read *after* the concatenated buffer's end | ||
*/ | ||
private readHeaderEnd; | ||
/** | ||
* Process ciphered buffer into output | ||
*/ | ||
private readCiphertext; | ||
/** | ||
* Initialize the decipher context | ||
*/ | ||
private initContext; | ||
/** | ||
* Read a byte from inputChunk, return null if end of buffer reached. | ||
* This advance the offset, and clear inputChunk when the end is reached. | ||
*/ | ||
private getByte; | ||
/** | ||
* Read from inputChunk to populate the temporary read buffer. | ||
* | ||
* Return true if the readBuffer is at least of the expected length. | ||
*/ | ||
private populateReadBuffer; | ||
/** | ||
* Read a buffer header from concatenateBuf8List(). | ||
* | ||
* If there's not enough input data (yet), return null. | ||
*/ | ||
private readBufferSize; | ||
/** | ||
* Read a buffer value as a string from concatenateBuf8List() | ||
* | ||
* If there isn't enough input data, return null | ||
*/ | ||
private readString; | ||
/** Decrypt input after extracting decryption data */ | ||
_transform: (chunk: Buffer | string, encoding: string, callback: TransformCallback) => void; | ||
_flush: (callback: TransformCallback) => void; | ||
} |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{Transform as e}from"stream";import{getUint8Array as t}from"@keeex/js-utils/lib/uint8array.js";import{createDecryptionContext as i}from"../../cipher.js";import{extractString as r,getChunkBuffer as n}from"./util.js";var s;!function(e){e.readingAlgoNameSize="ALGOSIZE",e.readingAlgoName="ALGO",e.readingIVSize="IVSIZE",e.readingIV="IV",e.readingCiphertextSize="CIPHERSIZE",e.readingHeaderEnd="HEADEREND",e.readingCipher="CIPHER"}(s||(s={}));export default class h extends e{key;state=s.readingAlgoNameSize;inputChunk=null;inputChunkOffset=null;readBuffer=[];settings={alreadyProcessed:0};context;constructor({encryptionKey:e,objectMode:t,...i}){if(super(i),t)throw new Error("Object mode not supported on encryption stream");this.key=e}_transform(e,t,i){this.inputChunk=n(e,t),this.inputChunkOffset=0,this.processInputChunk(i).catch(i)}_flush(e){this.processFinal(e).catch(e)}async processInputChunk(e){for(;this.inputChunk;)await this.processTempBuffer();e()}async processFinal(e){if(!this.context)return void e();const t=await this.context.final();0!==t.byteLength&&this.push(t),e()}async processTempBuffer(){switch(this.state){case s.readingAlgoNameSize:return this.readAlgoNameSize();case s.readingAlgoName:return this.readAlgoName();case s.readingIVSize:return this.readIVSize();case s.readingIV:return this.readIV();case s.readingCiphertextSize:return this.readCiphertextSize();case s.readingHeaderEnd:return this.readHeaderEnd();case s.readingCipher:return this.readCiphertext()}}readAlgoNameSize(){const e=this.readBufferSize();null!==e&&(this.settings.algoNameLength=e,this.state=s.readingAlgoName)}readAlgoName(){if(void 0===this.settings.algoNameLength)throw new Error("Unexpected state");const e=this.readString(this.settings.algoNameLength);if(null!==e){if(e!==this.key.algorithm())throw new Error("Unexpected algorithm");this.settings.algoName=e,this.state=s.readingIVSize}}readIVSize(){const e=this.readBufferSize();null!==e&&(this.settings.ivLength=e,this.state=s.readingIV)}readIV(){if(void 0===this.settings.ivLength)throw new Error("Unexpected state");this.populateReadBuffer(this.settings.ivLength)&&(this.settings.iv=new Uint8Array(this.readBuffer),this.readBuffer.length=0,this.state=s.readingCiphertextSize)}readCiphertextSize(){const e=this.readBufferSize();null!==e&&(this.settings.cipherSize=e,this.state=0===e?s.readingHeaderEnd:s.readingCipher)}readHeaderEnd(){if(this.getByte()!=="#".charCodeAt(0))throw new Error("Unexpected header end");this.state=s.readingCipher}async readCiphertext(){if(null===this.inputChunk||null===this.inputChunkOffset)throw new Error("Missing input");if(void 0===this.settings.cipherSize)throw new Error("Unexpected state");this.context||(this.context=await this.initContext());const e=0===this.inputChunkOffset?this.inputChunk:t(this.inputChunk,this.inputChunkOffset);let i;if(0===this.settings.cipherSize)i=e;else{const t=this.settings.cipherSize-this.settings.alreadyProcessed;i=e.byteLength<=t?e:e.slice(0,t)}this.settings.alreadyProcessed+=i.byteLength;const r=await this.context.update(i);this.push(r),this.inputChunk=null,this.inputChunkOffset=null}async initContext(){if(!this.settings.iv)throw new Error("Unexpected state");return i(this.key,this.settings.iv)}getByte(){if(null===this.inputChunk||null===this.inputChunkOffset)return null;const e=this.inputChunk[this.inputChunkOffset++];return this.inputChunkOffset===this.inputChunk.byteLength&&(this.inputChunk=null,this.inputChunkOffset=null),e}populateReadBuffer(e){for(;this.readBuffer.length<e;){const e=this.getByte();if(null===e)break;this.readBuffer.push(e)}return this.readBuffer.length>=e}readBufferSize(){if(!this.populateReadBuffer(2))return null;if(this.readBuffer[0]!=="!".charCodeAt(0))throw new Error("Unexpected buffer input");const e=this.readBuffer[1];if(!this.populateReadBuffer(2+e))return null;const t=parseInt(r(this.readBuffer,2),36);return this.readBuffer.length=0,t}readString(e){if(!this.populateReadBuffer(e))return null;const t=r(this.readBuffer);return this.readBuffer.length=0,t}} | ||
import{Transform as e}from"stream";import{getUint8Array as t}from"@keeex/js-utils/lib/uint8array.js";import{createDecryptionContext as i}from"../../cipher.js";import{extractString as r,getChunkBuffer as n}from"./util.js";var s;!function(e){e.readingAlgoNameSize="ALGOSIZE",e.readingAlgoName="ALGO",e.readingIVSize="IVSIZE",e.readingIV="IV",e.readingCiphertextSize="CIPHERSIZE",e.readingHeaderEnd="HEADEREND",e.readingCipher="CIPHER"}(s||(s={}));export default class h extends e{#e;#t=s.readingAlgoNameSize;#i=null;#r=null;#n=[];#s={alreadyProcessed:0};#h;constructor({encryptionKey:e,objectMode:t,...i}){if(super(i),t)throw new Error("Object mode not supported on encryption stream");this.#e=e}_transform=(e,t,i)=>{this.#i=n(e,t),this.#r=0,this.#a(i).catch(i)};_flush=e=>{this.#u(e).catch(e)};#a=async e=>{for(;this.#i;)await this.#o();e()};#u=async e=>{if(!this.#h)return void e();const t=await this.#h.final();0!==t.byteLength&&this.push(t),e()};#o=async()=>{switch(this.#t){case s.readingAlgoNameSize:return this.#d();case s.readingAlgoName:return this.#f();case s.readingIVSize:return this.#p();case s.readingIV:return this.#l();case s.readingCiphertextSize:return this.#g();case s.readingHeaderEnd:return this.#c();case s.readingCipher:return this.#C()}};#d=()=>{const e=this.#m();null!==e&&(this.#s.algoNameLength=e,this.#t=s.readingAlgoName)};#f=()=>{if(void 0===this.#s.algoNameLength)throw new Error("Unexpected state");const e=this.#k(this.#s.algoNameLength);if(null!==e){if(e!==this.#e.algorithm())throw new Error("Unexpected algorithm");this.#s.algoName=e,this.#t=s.readingIVSize}};#p=()=>{const e=this.#m();null!==e&&(this.#s.ivLength=e,this.#t=s.readingIV)};#l=()=>{if(void 0===this.#s.ivLength)throw new Error("Unexpected state");this.#S(this.#s.ivLength)&&(this.#s.iv=new Uint8Array(this.#n),this.#n.length=0,this.#t=s.readingCiphertextSize)};#g=()=>{const e=this.#m();null!==e&&(this.#s.cipherSize=e,this.#t=0===e?s.readingHeaderEnd:s.readingCipher)};#c(){if(this.#B()!=="#".charCodeAt(0))throw new Error("Unexpected header end");this.#t=s.readingCipher}#C=async()=>{if(null===this.#i||null===this.#r)throw new Error("Missing input");if(void 0===this.#s.cipherSize)throw new Error("Unexpected state");this.#h||(this.#h=await this.#x());const e=0===this.#r?this.#i:t(this.#i,this.#r);let i;if(0===this.#s.cipherSize)i=e;else{const t=this.#s.cipherSize-this.#s.alreadyProcessed;i=e.byteLength<=t?e:e.slice(0,t)}this.#s.alreadyProcessed+=i.byteLength;const r=await this.#h.update(i);this.push(r),this.#i=null,this.#r=null};#x=async()=>{if(!this.#s.iv)throw new Error("Unexpected state");return i(this.#e,this.#s.iv)};#B=()=>{if(null===this.#i||null===this.#r)return null;const e=this.#i[this.#r++];return this.#r===this.#i.byteLength&&(this.#i=null,this.#r=null),e};#S=e=>{for(;this.#n.length<e;){const e=this.#B();if(null===e)break;this.#n.push(e)}return this.#n.length>=e};#m=()=>{if(!this.#S(2))return null;if(this.#n[0]!=="!".charCodeAt(0))throw new Error("Unexpected buffer input");const e=this.#n[1];if(!this.#S(2+e))return null;const t=parseInt(r(this.#n,2),36);return this.#n.length=0,t};#k=e=>{if(!this.#S(e))return null;const t=r(this.#n);return this.#n.length=0,t}} |
@@ -38,4 +38,3 @@ /** | ||
export default class Encrypt extends Transform { | ||
private key; | ||
private context?; | ||
#private; | ||
/** | ||
@@ -54,10 +53,4 @@ * Construct the encryption stream | ||
*/ | ||
_transform(chunk: Buffer | string, encoding: string, callback: TransformCallback): void; | ||
_flush(callback: TransformCallback): void; | ||
/** | ||
* Consume the whole input chunk | ||
*/ | ||
private processInputChunk; | ||
private writeHeaderCreateContext; | ||
private processFinal; | ||
_transform: (chunk: Buffer | string, encoding: string, callback: TransformCallback) => void; | ||
_flush: (callback: TransformCallback) => void; | ||
} |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{Transform as t}from"stream";import{getUint8Array as e}from"@keeex/js-utils/lib/uint8array.js";import{createEncryptionContext as s,encryptImmediateEncoding as r,generateIV as o}from"../../cipher.js";import{getChunkBuffer as i}from"./util.js";export default class n extends t{key;context;constructor({encryptionKey:t,objectMode:e,...s}){if(super(s),e)throw new Error("Object mode not supported on encryption stream");this.key=t}_transform(t,e,s){const r=i(t,e);this.processInputChunk(r,s).catch(s)}_flush(t){this.processFinal(t).catch(t)}async processInputChunk(t,e){this.context||(this.context=await this.writeHeaderCreateContext());const s=await this.context.update(t);this.push(s),e()}async writeHeaderCreateContext(){const t=await o(this.key.algorithm()),i=r(this.key,e(t));return this.push(e(i)),s(this.key,e(t))}async processFinal(t){if(!this.context)return void t();const e=await this.context.final();0!==e.byteLength&&this.push(e),t()}} | ||
import{Transform as t}from"stream";import{getUint8Array as e}from"@keeex/js-utils/lib/uint8array.js";import{createEncryptionContext as s,encryptImmediateEncoding as r,generateIV as o}from"../../cipher.js";import{getChunkBuffer as i}from"./util.js";export default class n extends t{#t;#e;constructor({encryptionKey:t,objectMode:e,...s}){if(super(s),e)throw new Error("Object mode not supported on encryption stream");this.#t=t}_transform=(t,e,s)=>{const r=i(t,e);this.#s(r,s).catch(s)};_flush=t=>{this.#r(t).catch(t)};#s=async(t,e)=>{this.#e||(this.#e=await this.#o());const s=await this.#e.update(t);this.push(s),e()};#o=async()=>{const t=await o(this.#t.algorithm()),i=r(this.#t,e(t));return this.push(e(i)),s(this.#t,e(t))};#r=async t=>{if(!this.#e)return void t();const e=await this.#e.final();0!==e.byteLength&&this.push(e),t()}} |
@@ -29,9 +29,5 @@ /** | ||
/// <reference types="node" /> | ||
/** | ||
* Return an Uint8Array from a stream chunk | ||
*/ | ||
/** Return an Uint8Array from a stream chunk */ | ||
export declare const getChunkBuffer: (chunk: Buffer | string, encoding: string) => Uint8Array; | ||
/** | ||
* Rebuild a string from a byte array, starting at given offset | ||
*/ | ||
/** Rebuild a string from a byte array, starting at given offset */ | ||
export declare const extractString: (src: Array<number>, offset?: number) => string; |
@@ -1,1 +0,1 @@ | ||
{"author":"KeeeX SAS","contributors":[{"name":"Gabriel Paul \"Cley Faye\" Risterucci","email":"gabriel@keeex.net"}],"dependencies":{"@keeex/js-utils":"^6.14.0"},"description":"Crypto provider selection","files":["lib","web"],"homepage":"https://keeex.me/oss","license":"SEE LICENSE IN LICENSE","main":"lib/provider.js","name":"@keeex/crypto","peerDependencies":{"@keeex/crypto-provider-purejs":"^3.2.0"},"peerDependenciesMeta":{"@keeex/crypto-provider-purejs":{"optional":false}},"scripts":{},"type":"module","version":"3.3.3"} | ||
{"author":"KeeeX SAS","contributors":[{"name":"Gabriel Paul \"Cley Faye\" Risterucci","email":"gabriel@keeex.net"}],"dependencies":{"@keeex/asmcrypto.js":"^4.0.2","@keeex/js-utils":"^6.14.0","js-sha1":"^0.6.0","js-sha3":"^0.8.0","jssha":"^3.3.0"},"description":"Crypto provider selection","files":["lib","web"],"homepage":"https://keeex.me/oss","license":"SEE LICENSE IN LICENSE","main":"lib/provider.js","name":"@keeex/crypto","scripts":{},"type":"module","version":"3.4.0"} |
@@ -16,4 +16,2 @@ KeeeX Cryptography helper | ||
- `@keeex/crypto-provider-purejs`: the pure JavaScript implementation. Does not provide safe random | ||
source. | ||
- `@keeex/crypto-provider-browser`: based on Subtle Crypto available in most web browsers | ||
@@ -23,2 +21,6 @@ - `@keeex/crypto-provider-node`: based on Node's crypto module | ||
There is also a pure JavaScript implementation available by calling `usePureJSProvider()` instead of | ||
importing one of these packages. | ||
This implementation does not provide a safe random number generation. | ||
Aside from the `purejs` one, all implementations provides at least a secure source of randomness. | ||
@@ -61,5 +63,2 @@ Some feature/algorithms might not be supported natively everywhere; providers usually fallback to | ||
-------------------------------------------------- | ||
The PureJS implementation uses `asmcrypto.js` for most hash and AES encryption. | ||
Another library (`jsSHA`) is used for SHA-224. | ||
The random source when using the pure JavaScript library is *not safe* for cryptographic uses; it is | ||
@@ -191,1 +190,10 @@ merely provided as a way to start developping. | ||
Same for `hmac()`. | ||
Testing | ||
------- | ||
The core crypto library (shared implementations and general data handling) can be tested locally | ||
using `npm test`. | ||
It runs against the built-in pure JavaScript implementation. | ||
To test other cryptographic providers, import them in the regular fashion and call `runTest()`. | ||
Depending on the environment provided, stream features might be skipped for testing. |
@@ -31,10 +31,6 @@ /** | ||
export { Algorithms, CipherProvider, }; | ||
/** | ||
* Return the expected IV size for a given algorithm | ||
*/ | ||
/** Return the expected IV size for a given algorithm */ | ||
export declare const getIVSize: (algorithm: Algorithms) => Promise<number>; | ||
export declare const generateIV: (algorithm: Algorithms) => Promise<Uint8Array>; | ||
/** | ||
* Encrypt a buffer in one call, returning the result | ||
*/ | ||
/** Encrypt a buffer in one call, returning the result */ | ||
export declare const encryptRawImmediate: (data: Uint8Array, iv: Uint8Array, key: CryptoKey) => Promise<Uint8Array>; | ||
@@ -56,17 +52,9 @@ /** | ||
export declare const encryptImmediate: (data: Uint8Array, key: CryptoKey) => Promise<Uint8Array>; | ||
/** | ||
* Decipher a buffer in one call | ||
*/ | ||
/** Decipher a buffer in one call */ | ||
export declare const decryptRawImmediate: (data: Uint8Array, iv: Uint8Array, key: CryptoKey) => Promise<Uint8Array>; | ||
/** | ||
* Decrypt data from a buffer ciphered using encryptImmediate() | ||
*/ | ||
/** Decrypt data from a buffer ciphered using encryptImmediate() */ | ||
export declare const decryptImmediate: (data: Uint8Array, key: CryptoKey) => Promise<Uint8Array>; | ||
/** | ||
* Create an encryption context, to encrypt data in chunks | ||
*/ | ||
/** Create an encryption context, to encrypt data in chunks */ | ||
export declare const createEncryptionContext: (key: CryptoKey, iv: Uint8Array) => Promise<CipherContext>; | ||
/** | ||
* Create a decryption context, to decrypt data in chunks | ||
*/ | ||
/** Create a decryption context, to decrypt data in chunks */ | ||
export declare const createDecryptionContext: (key: CryptoKey, iv: Uint8Array) => Promise<CipherContext>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{buf82str as e,concatenateBuf8List as t,concatenatedBuf8ListSize as r,explodeBuf8List as n,getUint8Array as a,merge as o,str2buf8 as i}from"@keeex/js-utils/web/uint8array.js";import{getProvider as c,getProviderOptions as s}from"./provider.js";import{Algorithms as p}from"./ciphertypes.js";import{notImplemented as m}from"./exception.js";import{randomBytes as d}from"./random.js";import{getPureCipher as y,getPureKeys as w}from"./pureprovider.js";export{p as Algorithms};export const getIVSize=async e=>{const t=c().cipherProvider;if(t.getIVSize)return t.getIVSize(e);if(t.generateIV)return(await t.generateIV(e)).byteLength;switch(e){case p.AESCBC:case p.AESCTR:return 16}};export const generateIV=async e=>{const t=c().cipherProvider;if(t.generateIV)return t.generateIV(e);const r=await getIVSize(e);return d(r)};export const encryptRawImmediate=(e,t,r)=>{const n=c().cipherProvider;return n.encryptRawImmediate?n.encryptRawImmediate(e,t,r):(async(e,t,r)=>{const n=c().cipherProvider;if(!n.createEncryptionContext)throw m();const a=await n.createEncryptionContext(r,t),i=await a.update(e),s=await a.final();return o([i,s])})(e,t,r)};export const encryptImmediateEncoding=(e,r,n)=>{const a=i(e.algorithm()),o=n??new Uint8Array;return t([a,r,o],void 0===n)};export const encryptImmediate=async(e,t)=>{const r=await generateIV(t.algorithm()),n=await encryptRawImmediate(e,r,t);return encryptImmediateEncoding(t,a(r),a(n))};export const decryptRawImmediate=async(e,t,r)=>{const n=c().cipherProvider;return n.decryptRawImmediate?n.decryptRawImmediate(e,t,r):(async(e,t,r)=>{const n=c().cipherProvider;if(!n.createDecryptionContext)throw m();const a=await n.createDecryptionContext(r,t),i=await a.update(e),s=await a.final();return o([i,s])})(e,t,r)};export const decryptImmediate=async(t,a)=>{const[o,i,c]=n(t);let s;if(c.byteLength>0)s=c;else{const e=r(t);s=t.slice(e)}const p=e(o);if(p!==a.algorithm())throw new Error(`Invalid key for "${a.algorithm()}" used to decipher "${p}"`);return decryptRawImmediate(s,i,a)};export const createEncryptionContext=async(e,t)=>{const r=c().cipherProvider;if(r.createEncryptionContext)return r.createEncryptionContext(e,t);if(s().noImmediateFallback){const r=(await y()).createEncryptionContext;if(!r)throw new Error("Unexpected state");const n=await w();return r(await n.importCryptoKey(e.algorithm(),await e.export()),t)}return((e,t)=>{const r=c().cipherProvider;if(!r.encryptRawImmediate)throw m();const n=[];return{update:e=>(n.push(a(e,void 0,void 0,!0)),Promise.resolve(new Uint8Array)),final:async()=>{const a=o(n);if(!r.encryptRawImmediate)throw m();return r.encryptRawImmediate(a,t,e)}}})(e,t)};export const createDecryptionContext=async(e,t)=>{const r=c().cipherProvider;if(r.createDecryptionContext)return r.createDecryptionContext(e,t);if(s().noImmediateFallback){const r=(await y()).createEncryptionContext;if(!r)throw new Error("Unexpected state");const n=await w();return r(await n.importCryptoKey(e.algorithm(),await e.export()),t)}return Promise.resolve(((e,t)=>{const r=c().cipherProvider;if(!r.decryptRawImmediate)throw m();const n=[];return{update:e=>(n.push(a(e,void 0,void 0,!0)),Promise.resolve(new Uint8Array)),final:async()=>{const a=o(n);if(!r.decryptRawImmediate)throw m();return r.decryptRawImmediate(a,t,e)}}})(e,t))}; | ||
import{buf82str as e,concatenateBuf8List as t,concatenatedBuf8ListSize as r,explodeBuf8List as n,getUint8Array as a,merge as o,str2buf8 as i}from"@keeex/js-utils/web/uint8array.js";import{getProvider as c,getProviderOptions as s}from"./provider.js";import{Algorithms as p}from"./ciphertypes.js";import{notImplemented as m}from"./exception.js";import{randomBytes as d}from"./random.js";import{getPureCipher as y,getPureKeys as w}from"./pureprovider.js";export{p as Algorithms};export const getIVSize=async e=>{const t=c().cipherProvider;if(t.getIVSize)return t.getIVSize(e);if(t.generateIV)return(await t.generateIV(e)).byteLength;switch(e){case p.AESCBC:case p.AESCTR:return 16}};export const generateIV=async e=>{const t=c().cipherProvider;if(t.generateIV)return t.generateIV(e);const r=await getIVSize(e);return d(r)};export const encryptRawImmediate=async(e,t,r)=>{const n=c().cipherProvider;return n.encryptRawImmediate?n.encryptRawImmediate(e,t,r):(async(e,t,r)=>{const n=c().cipherProvider;if(!n.createEncryptionContext)throw m();const a=await n.createEncryptionContext(r,t),i=await a.update(e),s=await a.final();return o([i,s])})(e,t,r)};export const encryptImmediateEncoding=(e,r,n)=>{const a=i(e.algorithm()),o=n??new Uint8Array;return t([a,r,o],void 0===n)};export const encryptImmediate=async(e,t)=>{const r=await generateIV(t.algorithm()),n=await encryptRawImmediate(e,r,t);return encryptImmediateEncoding(t,a(r),a(n))};export const decryptRawImmediate=async(e,t,r)=>{const n=c().cipherProvider;return n.decryptRawImmediate?n.decryptRawImmediate(e,t,r):(async(e,t,r)=>{const n=c().cipherProvider;if(!n.createDecryptionContext)throw m();const a=await n.createDecryptionContext(r,t),i=await a.update(e),s=await a.final();return o([i,s])})(e,t,r)};export const decryptImmediate=async(t,a)=>{const[o,i,c]=n(t);let s;if(c.byteLength>0)s=c;else{const e=r(t);s=t.slice(e)}const p=e(o);if(p!==a.algorithm())throw new Error(`Invalid key for "${a.algorithm()}" used to decipher "${p}"`);return decryptRawImmediate(s,i,a)};export const createEncryptionContext=async(e,t)=>{const r=c().cipherProvider;if(r.createEncryptionContext)return r.createEncryptionContext(e,t);if(s().noImmediateFallback){const r=(await y()).createEncryptionContext;if(!r)throw new Error("Unexpected state");const n=await w();return r(await n.importCryptoKey(e.algorithm(),await e.export()),t)}return((e,t)=>{const r=c().cipherProvider;if(!r.encryptRawImmediate)throw m();const n=[];return{update:e=>(n.push(a(e,void 0,void 0,!0)),Promise.resolve(new Uint8Array)),final:async()=>{const a=o(n);if(!r.encryptRawImmediate)throw m();return r.encryptRawImmediate(a,t,e)}}})(e,t)};export const createDecryptionContext=async(e,t)=>{const r=c().cipherProvider;if(r.createDecryptionContext)return r.createDecryptionContext(e,t);if(s().noImmediateFallback){const r=(await y()).createEncryptionContext;if(!r)throw new Error("Unexpected state");const n=await w();return r(await n.importCryptoKey(e.algorithm(),await e.export()),t)}return Promise.resolve(((e,t)=>{const r=c().cipherProvider;if(!r.decryptRawImmediate)throw m();const n=[];return{update:e=>(n.push(a(e,void 0,void 0,!0)),Promise.resolve(new Uint8Array)),final:async()=>{const a=o(n);if(!r.decryptRawImmediate)throw m();return r.decryptRawImmediate(a,t,e)}}})(e,t))}; |
@@ -29,2 +29,3 @@ /** | ||
import { CryptoKey } from "./keys.js"; | ||
import { Awaitable } from "./utils.js"; | ||
export declare enum Algorithms { | ||
@@ -34,37 +35,23 @@ AESCTR = "AES-CTR", | ||
} | ||
/** | ||
* A basic cipher context that provide means to encrypt/decrypt data | ||
*/ | ||
/** A basic cipher context that provide means to encrypt/decrypt data */ | ||
export interface CipherContext { | ||
/** | ||
* Add input data | ||
*/ | ||
update: (data: Uint8Array) => Promise<Uint8Array>; | ||
/** | ||
* Must be called after processing to return the last block of data | ||
*/ | ||
final: () => Promise<Uint8Array>; | ||
/** Add input data */ | ||
update: (data: Uint8Array) => Awaitable<Uint8Array>; | ||
/** Must be called after processing to return the last block of data */ | ||
final: () => Awaitable<Uint8Array>; | ||
} | ||
export interface CipherProvider { | ||
/** | ||
* Return the expected size of the IV for the given algorithm. | ||
*/ | ||
getIVSize?(algorithm: Algorithms): Promise<number>; | ||
/** | ||
* Generate an IV for the given algorithm | ||
*/ | ||
generateIV?(algorithm: Algorithms): Promise<Uint8Array>; | ||
/** Return the expected size of the IV for the given algorithm. */ | ||
getIVSize?(algorithm: Algorithms): Awaitable<number>; | ||
/** Generate an IV for the given algorithm */ | ||
generateIV?(algorithm: Algorithms): Awaitable<Uint8Array>; | ||
/** Simple interface to cipher a buffer in one call. */ | ||
encryptRawImmediate?(data: Uint8Array, iv: Uint8Array, key: CryptoKey): Promise<Uint8Array>; | ||
encryptRawImmediate?(data: Uint8Array, iv: Uint8Array, key: CryptoKey): Awaitable<Uint8Array>; | ||
/** Counterpart to encryptRawImmediate() */ | ||
decryptRawImmediate?(data: Uint8Array, iv: Uint8Array, key: CryptoKey): Promise<Uint8Array>; | ||
/** | ||
* Create a generic encryption context | ||
*/ | ||
createEncryptionContext?(key: CryptoKey, iv: Uint8Array): Promise<CipherContext>; | ||
/** | ||
* Create a generic decryption context | ||
*/ | ||
createDecryptionContext?(key: CryptoKey, iv: Uint8Array): Promise<CipherContext>; | ||
decryptRawImmediate?(data: Uint8Array, iv: Uint8Array, key: CryptoKey): Awaitable<Uint8Array>; | ||
/** Create a generic encryption context */ | ||
createEncryptionContext?(key: CryptoKey, iv: Uint8Array): Awaitable<CipherContext>; | ||
/** Create a generic decryption context */ | ||
createDecryptionContext?(key: CryptoKey, iv: Uint8Array): Awaitable<CipherContext>; | ||
} | ||
export declare const isCipherProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<CipherProvider>; |
@@ -30,21 +30,11 @@ /** | ||
export { Algorithms, Digest, DigestProvider, }; | ||
/** | ||
* Return the internal block size for a given digest algorithm, in bytes | ||
*/ | ||
/** Return the internal block size for a given digest algorithm, in bytes */ | ||
export declare const digestBlockSize: (algorithm: Algorithms) => number; | ||
/** | ||
* Return the output size for a given digest algorithm, in bytes | ||
*/ | ||
/** Return the output size for a given digest algorithm, in bytes */ | ||
export declare const digestOutputSize: (algorithm: Algorithms) => number; | ||
/** | ||
* Compute the digest of a full buffer | ||
*/ | ||
/** Compute the digest of a full buffer */ | ||
export declare const digestImmediate: (algorithm: Algorithms, data: Uint8Array) => Promise<Uint8Array>; | ||
/** | ||
* Compute the digest of a string | ||
*/ | ||
/** Compute the digest of a string */ | ||
export declare const digestString: (algorithm: Algorithms, data: string) => Promise<Uint8Array>; | ||
/** | ||
* Return a chunk-based digest object | ||
*/ | ||
/** Return a chunk-based digest object */ | ||
export declare const digest: (algorithm: Algorithms) => Promise<Digest>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{utf82buf8 as e}from"@keeex/js-utils/web/uint8array.js";import{getProvider as t,getProviderOptions as r}from"./provider.js";import{notImplemented as s}from"./exception.js";import i from"./digest/chunkdigest.js";import{Algorithms as n}from"./digesttypes.js";import{getPureDigest as a}from"./pureprovider.js";export{n as Algorithms};export const digestBlockSize=e=>{switch(e){case n.SHA1:case n.SHA224:case n.SHA256:return 64;case n.SHA512:return 128;case n.RIPEMD160:return 64;case n.SHA3_224:return 144;case n.SHA3_256:return 136;case n.SHA3_384:return 104;case n.SHA3_512:return 72;case n.KECCAK224:return 144;case n.KECCAK256:return 136;case n.KECCAK384:return 104;case n.KECCAK512:return 72}};export const digestOutputSize=e=>{switch(e){case n.SHA1:return 20;case n.SHA224:return 28;case n.SHA256:return 32;case n.SHA512:return 64;case n.RIPEMD160:return 20;case n.SHA3_224:return 28;case n.SHA3_256:return 32;case n.SHA3_384:return 48;case n.SHA3_512:return 64;case n.KECCAK224:return 28;case n.KECCAK256:return 32;case n.KECCAK384:return 48;case n.KECCAK512:return 64}};export const digestImmediate=(e,r)=>{const i=t().digestProvider;return i.digestImmediate?i.digestImmediate(e,r):(async(e,r)=>{const i=t().digestProvider;if(!i.digest)throw s();return(await i.digest(e)).digest(r)})(e,r)};export const digestString=(t,r)=>digestImmediate(t,e(r));export const digest=e=>{const s=t().digestProvider;return s.digest?s.digest(e):(async e=>{if(r().noImmediateFallback){const t=(await a()).digest;if(!t)throw new Error("Unexpected state");return t(e)}return new i(e,digestImmediate)})(e)}; | ||
import{utf82buf8 as e}from"@keeex/js-utils/web/uint8array.js";import{getProvider as t,getProviderOptions as r}from"./provider.js";import{notImplemented as s}from"./exception.js";import i from"./digest/chunkdigest.js";import{Algorithms as n}from"./digesttypes.js";import{getPureDigest as a}from"./pureprovider.js";export{n as Algorithms};export const digestBlockSize=e=>{switch(e){case n.SHA1:case n.SHA224:case n.SHA256:return 64;case n.SHA512:return 128;case n.RIPEMD160:return 64;case n.SHA3_224:return 144;case n.SHA3_256:return 136;case n.SHA3_384:return 104;case n.SHA3_512:return 72;case n.KECCAK224:return 144;case n.KECCAK256:return 136;case n.KECCAK384:return 104;case n.KECCAK512:return 72}};export const digestOutputSize=e=>{switch(e){case n.SHA1:return 20;case n.SHA224:return 28;case n.SHA256:return 32;case n.SHA512:return 64;case n.RIPEMD160:return 20;case n.SHA3_224:return 28;case n.SHA3_256:return 32;case n.SHA3_384:return 48;case n.SHA3_512:return 64;case n.KECCAK224:return 28;case n.KECCAK256:return 32;case n.KECCAK384:return 48;case n.KECCAK512:return 64}};export const digestImmediate=async(e,r)=>{const i=t().digestProvider;return i.digestImmediate?i.digestImmediate(e,r):(async(e,r)=>{const i=t().digestProvider;if(!i.digest)throw s();return(await i.digest(e)).digest(r)})(e,r)};export const digestString=(t,r)=>digestImmediate(t,e(r));export const digest=async e=>{const s=t().digestProvider;return s.digest?s.digest(e):(async e=>{if(r().noImmediateFallback){const t=(await a()).digest;if(!t)throw new Error("Unexpected state");return t(e)}return new i(e,digestImmediate)})(e)}; |
@@ -30,18 +30,10 @@ /** | ||
import { Algorithms as DigestAlgorithms, DigestImmediateFunc } from "../digesttypes.js"; | ||
/** | ||
* Dummy implementation that falls back to using digestImmediate() | ||
*/ | ||
/** Dummy implementation that falls back to using digestImmediate() */ | ||
export default class ChunkDigest implements Digest { | ||
private algorithm; | ||
private digestImmediate; | ||
private buffer; | ||
#private; | ||
constructor(algorithm: DigestAlgorithms, digestImmediateFunc: DigestImmediateFunc); | ||
/** | ||
* Append an input chunk of data | ||
*/ | ||
update(bytes: Uint8Array): Promise<void>; | ||
/** | ||
* Optionnaly append data and return the result of the digest | ||
*/ | ||
digest(data?: Uint8Array): Promise<Uint8Array>; | ||
/** Append an input chunk of data */ | ||
update: (bytes: Uint8Array) => void; | ||
/** Optionnaly append data and return the result of the digest */ | ||
digest: (data?: Uint8Array) => Promise<Uint8Array>; | ||
} |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{merge as t}from"@keeex/js-utils/web/uint8array.js";export default class e{algorithm;digestImmediate;buffer;constructor(t,e){this.algorithm=t,this.buffer=new Uint8Array,this.digestImmediate=e}update(e){return this.buffer=t([this.buffer,e]),Promise.resolve()}async digest(t){return t&&await this.update(t),this.digestImmediate(this.algorithm,this.buffer)}} | ||
import{merge as t}from"@keeex/js-utils/web/uint8array.js";export default class s{#t;#s;#e;constructor(t,s){this.#t=t,this.#e=new Uint8Array,this.#s=s}update=s=>{this.#e=t([this.#e,s])};digest=async t=>(t&&this.update(t),this.#s(this.#t,this.#e))} |
@@ -28,2 +28,3 @@ /** | ||
*/ | ||
import { Awaitable } from "./utils.js"; | ||
/** | ||
@@ -33,4 +34,4 @@ * Interface for chunk-based digest | ||
export interface Digest { | ||
update(data: Uint8Array): Promise<void>; | ||
digest(data?: Uint8Array): Promise<Uint8Array>; | ||
update(data: Uint8Array): Awaitable<void>; | ||
digest(data?: Uint8Array): Awaitable<Uint8Array>; | ||
} | ||
@@ -56,10 +57,8 @@ /** | ||
/** Function to compute the hash of a buffer in one call */ | ||
export type DigestImmediateFunc = (algorithm: Algorithms, data: Uint8Array) => Promise<Uint8Array>; | ||
/** | ||
* Interface that any digest provider must implement | ||
*/ | ||
export type DigestImmediateFunc = (algorithm: Algorithms, data: Uint8Array) => Awaitable<Uint8Array>; | ||
/** Interface that any digest provider must implement */ | ||
export interface DigestProvider { | ||
digestImmediate?: DigestImmediateFunc; | ||
digest?: (algorithm: Algorithms) => Promise<Digest>; | ||
digest?: (algorithm: Algorithms) => Awaitable<Digest>; | ||
} | ||
export declare const isDigestProvider: import("@keeex/js-utils/lib/types/types").TypePredicate<DigestProvider>; | ||
export declare const isDigestProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<DigestProvider>; |
@@ -30,9 +30,5 @@ /** | ||
export { Algorithms, HmacProvider, }; | ||
/** | ||
* Return an object that can process hmac in chunks | ||
*/ | ||
/** Return an object that can process hmac in chunks */ | ||
export declare const hmac: (algorithm: Algorithms, key: Uint8Array) => Promise<Hmac>; | ||
/** | ||
* Compute a HMAC on a single buffer | ||
*/ | ||
/** Compute a HMAC on a single buffer */ | ||
export declare const hmacImmediate: (algorithm: Algorithms, data: Uint8Array, key: Uint8Array) => Promise<Uint8Array>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{getProvider as m}from"./provider.js";import{Algorithms as r}from"./hmactypes.js";import a from"./hmac/chunkhmac.js";export{r as Algorithms};export const hmac=(r,e)=>{const o=m().hmacProvider;return o.hmac?o.hmac(r,e):Promise.resolve(new a(r,e))};export const hmacImmediate=(r,a,e)=>{const o=m().hmacProvider;return o.hmacImmediate?o.hmacImmediate(r,a,e):(async(m,r,a)=>(await hmac(m,a)).hmac(r))(r,a,e)}; | ||
import{getProvider as m}from"./provider.js";import{Algorithms as r}from"./hmactypes.js";import a from"./hmac/chunkhmac.js";export{r as Algorithms};export const hmac=async(r,c)=>{const e=m().hmacProvider;return e.hmac?e.hmac(r,c):Promise.resolve(new a(r,c))};export const hmacImmediate=async(r,a,c)=>{const e=m().hmacProvider;return e.hmacImmediate?e.hmacImmediate(r,a,c):(async(m,r,a)=>(await hmac(m,a)).hmac(r))(r,a,c)}; |
@@ -36,18 +36,10 @@ /** | ||
export default class ChunkHmac implements Hmac { | ||
private algorithm; | ||
private key?; | ||
private outerKeyPad?; | ||
private innerDigest?; | ||
#private; | ||
constructor(algorithm: Algorithms, key: Uint8Array); | ||
/** | ||
* Return an appropriate length key for HMAC | ||
*/ | ||
static padKey(algorithm: Algorithms, key: Uint8Array): Promise<Uint8Array>; | ||
/** | ||
* XOR a byte buffer with the given byte | ||
*/ | ||
static xorBuffer(input: Uint8Array, byteKey: number): Uint8Array; | ||
update(data: Uint8Array): Promise<void>; | ||
hmac(data?: Uint8Array): Promise<Uint8Array>; | ||
private computeKeyPads; | ||
/** Return an appropriate length key for HMAC */ | ||
static padKey: (algorithm: Algorithms, key: Uint8Array) => Promise<Uint8Array>; | ||
/** XOR a byte buffer with the given byte */ | ||
static xorBuffer: (input: Uint8Array, byteKey: number) => Uint8Array; | ||
update: (data: Uint8Array) => Promise<void>; | ||
hmac: (data?: Uint8Array) => Promise<Uint8Array>; | ||
} |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{getUint8Array as t}from"@keeex/js-utils/web/uint8array.js";import{digest as e,digestBlockSize as i,digestImmediate as s}from"../digest.js";export default class a{algorithm;key;outerKeyPad;innerDigest;constructor(e,i){this.algorithm=e,this.key=t(i,void 0,void 0,!0)}static async padKey(t,e){const a=i(t);if(e.byteLength>a)return s(t,e);if(e.byteLength<a){const t=new Uint8Array(a);return t.set(e),t.fill(0,e.byteLength),t}return e}static xorBuffer(t,e){const i=new Uint8Array(t.byteLength);for(let s=0;s<t.byteLength;++s)i[s]=t[s]^e;return i}async update(t){if(!this.innerDigest){const t=await this.computeKeyPads();this.outerKeyPad=t.outerKeyPad,this.innerDigest=t.innerDigest}await this.innerDigest.update(t)}async hmac(t){if(t&&await this.update(t),!this.outerKeyPad||!this.innerDigest){const t=await this.computeKeyPads();this.outerKeyPad=t.outerKeyPad,this.innerDigest=t.innerDigest}const i=await e(this.algorithm);return await i.update(this.outerKeyPad),i.digest(await this.innerDigest.digest())}async computeKeyPads(){if(!this.key)throw new Error("Unexpected state");const t=await a.padKey(this.algorithm,this.key);this.key=void 0;const i=a.xorBuffer(t,92),s=a.xorBuffer(t,54),r=await e(this.algorithm);return await r.update(s),{outerKeyPad:i,innerDigest:r}}} | ||
import{getUint8Array as t}from"@keeex/js-utils/web/uint8array.js";import{digest as e,digestBlockSize as i,digestImmediate as s}from"../digest.js";export default class a{#t;#e;#i;#s;constructor(e,i){this.#t=e,this.#e=t(i,void 0,void 0,!0)}static padKey=async(t,e)=>{const a=i(t);if(e.byteLength>a)return s(t,e);if(e.byteLength<a){const t=new Uint8Array(a);return t.set(e),t.fill(0,e.byteLength),t}return e};static xorBuffer=(t,e)=>{const i=new Uint8Array(t.byteLength);for(let s=0;s<t.byteLength;++s)i[s]=t[s]^e;return i};update=async t=>{if(!this.#s){const t=await this.#a();this.#i=t.outerKeyPad,this.#s=t.innerDigest}await this.#s.update(t)};hmac=async t=>{if(t&&await this.update(t),!this.#i||!this.#s){const t=await this.#a();this.#i=t.outerKeyPad,this.#s=t.innerDigest}const i=await e(this.#t);return await i.update(this.#i),i.digest(await this.#s.digest())};#a=async()=>{if(!this.#e)throw new Error("Unexpected state");const t=await a.padKey(this.#t,this.#e);this.#e=void 0;const i=a.xorBuffer(t,92),s=a.xorBuffer(t,54),r=await e(this.#t);return await r.update(s),{outerKeyPad:i,innerDigest:r}}} |
@@ -28,2 +28,3 @@ /** | ||
*/ | ||
import { Awaitable } from "./utils.js"; | ||
export declare enum Algorithms { | ||
@@ -34,15 +35,11 @@ SHA256 = "SHA-256", | ||
export interface Hmac { | ||
update: (data: Uint8Array) => Promise<void>; | ||
hmac: (data?: Uint8Array) => Promise<Uint8Array>; | ||
update: (data: Uint8Array) => Awaitable<void>; | ||
hmac: (data?: Uint8Array) => Awaitable<Uint8Array>; | ||
} | ||
export interface HmacProvider { | ||
/** | ||
* Generate a hmac value | ||
*/ | ||
hmacImmediate?: (algorithm: Algorithms, data: Uint8Array, key: Uint8Array) => Promise<Uint8Array>; | ||
/** | ||
* Return a hmac context to process input in chunks | ||
*/ | ||
hmac?: (algorithm: Algorithms, key: Uint8Array) => Promise<Hmac>; | ||
/** Generate a hmac value */ | ||
hmacImmediate?: (algorithm: Algorithms, data: Uint8Array, key: Uint8Array) => Awaitable<Uint8Array>; | ||
/** Return a hmac context to process input in chunks */ | ||
hmac?: (algorithm: Algorithms, key: Uint8Array) => Awaitable<Hmac>; | ||
} | ||
export declare const isHmacProvider: import("@keeex/js-utils/lib/types/types").TypePredicate<HmacProvider>; | ||
export declare const isHmacProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<HmacProvider>; |
@@ -32,17 +32,9 @@ /** | ||
export { CryptoKey, KeysProvider, }; | ||
/** | ||
* Generate a random CryptoKey | ||
*/ | ||
/** Generate a random CryptoKey */ | ||
export declare const generateCryptoKey: (algorithm: CipherAlgorithms, keyLen: number) => Promise<CryptoKey>; | ||
/** | ||
* Transform raw data into a CryptoKey instance | ||
*/ | ||
/** Transform raw data into a CryptoKey instance */ | ||
export declare const importCryptoKey: (algorithm: CipherAlgorithms, keyData: Uint8Array) => Promise<CryptoKey>; | ||
/** | ||
* Create a CryptoKey from a low-entropy input using PBKDF2 | ||
*/ | ||
/** Create a CryptoKey from a low-entropy input using PBKDF2 */ | ||
export declare const deriveKey: (data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, targetAlgorithm: CipherAlgorithms, keyLen: number) => Promise<CryptoKey>; | ||
/** | ||
* Derive a fixed-size buffer from a low entropy source using PBKDF2 | ||
*/ | ||
/** Derive a fixed-size buffer from a low entropy source using PBKDF2 */ | ||
export declare const deriveKeyRaw: (data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, outLen: number) => Promise<Uint8Array>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{getProvider as e}from"./provider.js";import{randomBytes as r}from"./random.js";export const generateCryptoKey=(o,t)=>{const y=e().keysProvider;return y.generateCryptoKey?y.generateCryptoKey(o,t):(async(o,t)=>{const y=e().keysProvider,i=await r(t);return y.importCryptoKey(o,i)})(o,t)};export const importCryptoKey=(r,o)=>e().keysProvider.importCryptoKey(r,o);export const deriveKey=(r,o,t,y,i,s)=>{const n=e().keysProvider;return n.deriveKey?n.deriveKey(r,o,t,y,i,s):(async(r,o,t,y,i,s)=>{const n=e().keysProvider,p=await n.deriveKeyRaw(r,o,t,y,s);return n.importCryptoKey(i,p)})(r,o,t,y,i,s)};export const deriveKeyRaw=(r,o,t,y,i)=>e().keysProvider.deriveKeyRaw(r,o,t,y,i); | ||
import{getProvider as e}from"./provider.js";import{randomBytes as r}from"./random.js";export const generateCryptoKey=async(o,t)=>{const y=e().keysProvider;return y.generateCryptoKey?y.generateCryptoKey(o,t):(async(o,t)=>{const y=e().keysProvider,s=await r(t);return y.importCryptoKey(o,s)})(o,t)};export const importCryptoKey=async(r,o)=>e().keysProvider.importCryptoKey(r,o);export const deriveKey=async(r,o,t,y,s,n)=>{const i=e().keysProvider;return i.deriveKey?i.deriveKey(r,o,t,y,s,n):(async(r,o,t,y,s,n)=>{const i=e().keysProvider,a=await i.deriveKeyRaw(r,o,t,y,n);return i.importCryptoKey(s,a)})(r,o,t,y,s,n)};export const deriveKeyRaw=async(r,o,t,y,s)=>e().keysProvider.deriveKeyRaw(r,o,t,y,s); |
@@ -30,19 +30,14 @@ /** | ||
import { Algorithms as DigestAlgorithms } from "./digest.js"; | ||
/** | ||
* Basic key interface shared by all implementations | ||
*/ | ||
import { Awaitable } from "./utils.js"; | ||
/** Basic key interface shared by all implementations */ | ||
export interface CryptoKey { | ||
export(): Promise<Uint8Array>; | ||
export(): Awaitable<Uint8Array>; | ||
algorithm(): CipherAlgorithms; | ||
} | ||
export interface KeysProvider { | ||
/** Generate a new random key for symetric encryption */ | ||
generateCryptoKey?(algorithm: CipherAlgorithms, keyLen: number): Awaitable<CryptoKey>; | ||
/** Create a key based on existing data for symetric encryption */ | ||
importCryptoKey(algorithm: CipherAlgorithms, keyData: Uint8Array): Awaitable<CryptoKey>; | ||
/** | ||
* Generate a new random key for symetric encryption | ||
*/ | ||
generateCryptoKey?(algorithm: CipherAlgorithms, keyLen: number): Promise<CryptoKey>; | ||
/** | ||
* Create a key based on existing data for symetric encryption | ||
*/ | ||
importCryptoKey(algorithm: CipherAlgorithms, keyData: Uint8Array): Promise<CryptoKey>; | ||
/** | ||
* Derive a key from potentially not strong data source (passwords) | ||
@@ -54,3 +49,3 @@ * | ||
*/ | ||
deriveKey?(data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, targetAlgorithm: CipherAlgorithms, keyLen: number): Promise<CryptoKey>; | ||
deriveKey?(data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, targetAlgorithm: CipherAlgorithms, keyLen: number): Awaitable<CryptoKey>; | ||
/** | ||
@@ -61,4 +56,4 @@ * Derive a raw buffer from passwords using PBKDF2 | ||
*/ | ||
deriveKeyRaw(data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, outLen: number): Promise<Uint8Array>; | ||
deriveKeyRaw(data: string, salt: Uint8Array, digestAlgorithm: DigestAlgorithms, rounds: number, outLen: number): Awaitable<Uint8Array>; | ||
} | ||
export declare const isKeysProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<KeysProvider>; |
@@ -33,9 +33,5 @@ /** | ||
import { HmacProvider } from "./hmac.js"; | ||
/** | ||
* Interface that a cryptographic provider must implement | ||
*/ | ||
/** Interface that a cryptographic provider must implement */ | ||
export interface CryptoProvider { | ||
/** | ||
* Major version of `@keeex/crypto` supported by the provider. | ||
*/ | ||
/** Major version of `@keeex/crypto` supported by the provider. */ | ||
majorVersion: number; | ||
@@ -42,0 +38,0 @@ digestProvider: DigestProvider; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
export const getPureDigest=async()=>(await import("@keeex/crypto-provider-purejs/lib/digest/index.js")).default;export const getPureRandom=async()=>(await import("@keeex/crypto-provider-purejs/lib/random.js")).default;export const getPureCipher=async()=>(await import("@keeex/crypto-provider-purejs/lib/cipher/index.js")).default;export const getPureKeys=async()=>(await import("@keeex/crypto-provider-purejs/lib/keys/index.js")).default;export const getPureHMAC=async()=>(await import("@keeex/crypto-provider-purejs/lib/hmac.js")).default; | ||
export const getPureDigest=async()=>(await import("./purejs/digest/index.js")).default;export const getPureRandom=async()=>(await import("./purejs/random.js")).default;export const getPureCipher=async()=>(await import("./purejs/cipher/index.js")).default;export const getPureKeys=async()=>(await import("./purejs/keys/index.js")).default;export const getPureHMAC=async()=>(await import("./purejs/hmac.js")).default; |
@@ -30,5 +30,4 @@ /** | ||
export { RandomProvider }; | ||
/** | ||
* Return a set of random bytes | ||
*/ | ||
/** Return a set of random bytes */ | ||
export declare const randomBytes: (bytesCount: number) => Promise<Uint8Array>; | ||
export declare const randomFill: (buffer: ArrayBuffer | Uint8Array) => Promise<void>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{getProvider as r}from"./provider.js";export const randomBytes=o=>r().randomProvider.randomBytes(o); | ||
import{getProvider as r}from"./provider.js";export const randomBytes=async n=>{const o=r().randomProvider;if(o.randomBytes)return o.randomBytes(n);if(o.randomFill){const r=new Uint8Array(n);return await o.randomFill(r),r}throw new Error("Provider missing random source")};export const randomFill=async n=>{const o=r().randomProvider,t=(r=>r instanceof Uint8Array?r:new Uint8Array(r,0,r.byteLength))(n);if(o.randomFill)return o.randomFill(t);if(!o.randomBytes)throw new Error("Provider missing random source");{const r=await o.randomBytes(t.byteLength);t.set(r)}}; |
@@ -28,5 +28,8 @@ /** | ||
*/ | ||
import { Awaitable } from "./utils.js"; | ||
/** A random provider must implement at least one of `randomBytes()` or `randomFill()` */ | ||
export interface RandomProvider { | ||
randomBytes: (bytesCount: number) => Promise<Uint8Array>; | ||
randomBytes?: (bytesCount: number) => Awaitable<Uint8Array>; | ||
randomFill?: (buffer: Uint8Array) => Awaitable<void>; | ||
} | ||
export declare const isRandomProvider: import("@keeex/js-utils/lib/types/types").TypePredicate<RandomProvider>; | ||
export declare const isRandomProvider: import("@keeex/js-utils/lib/types/types.js").TypePredicate<RandomProvider>; |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{makeProfilePredicate as e}from"@keeex/js-utils/web/types/record.js";export const isRandomProvider=e({randomBytes:"function"}); | ||
import{makeProfilePredicate as e}from"@keeex/js-utils/web/types/record.js";export const isRandomProvider=e({randomBytes:"?function",randomFill:"?function"}); |
@@ -38,18 +38,4 @@ /** | ||
export default class Decrypt extends Transform { | ||
private key; | ||
private state; | ||
#private; | ||
/** | ||
* Input chunk being processed. | ||
* The "read" methods get their input from this. It is set in `_transform()` and consummed | ||
* entirely each time. | ||
*/ | ||
private inputChunk; | ||
private inputChunkOffset; | ||
/** | ||
* The temporary read buffer to mimic explodeBuf8List() | ||
*/ | ||
private readBuffer; | ||
private settings; | ||
private context?; | ||
/** | ||
* Construct the encryption stream | ||
@@ -64,62 +50,5 @@ * | ||
constructor({ encryptionKey, objectMode, ...options }: EncryptOptions); | ||
/** | ||
* Decrypt input after extracting decryption data | ||
*/ | ||
_transform(chunk: Buffer | string, encoding: string, callback: TransformCallback): void; | ||
_flush(callback: TransformCallback): void; | ||
/** | ||
* Consume inputChunk. | ||
* Written in a separate function from _transform() to make it easier to handle with async | ||
*/ | ||
private processInputChunk; | ||
/** | ||
* Output the final bits of output, if any. | ||
*/ | ||
private processFinal; | ||
/** | ||
* Process a small portion of inputChunk. | ||
* | ||
* Called repeatedly as long as inputChunk is not processed entirely | ||
*/ | ||
private processTempBuffer; | ||
private readAlgoNameSize; | ||
private readAlgoName; | ||
private readIVSize; | ||
private readIV; | ||
private readCiphertextSize; | ||
/** | ||
* Only called if cipherSize === 0, meaning we need to read *after* the concatenated buffer's end | ||
*/ | ||
private readHeaderEnd; | ||
/** | ||
* Process ciphered buffer into output | ||
*/ | ||
private readCiphertext; | ||
/** | ||
* Initialize the decipher context | ||
*/ | ||
private initContext; | ||
/** | ||
* Read a byte from inputChunk, return null if end of buffer reached. | ||
* This advance the offset, and clear inputChunk when the end is reached. | ||
*/ | ||
private getByte; | ||
/** | ||
* Read from inputChunk to populate the temporary read buffer. | ||
* | ||
* Return true if the readBuffer is at least of the expected length. | ||
*/ | ||
private populateReadBuffer; | ||
/** | ||
* Read a buffer header from concatenateBuf8List(). | ||
* | ||
* If there's not enough input data (yet), return null. | ||
*/ | ||
private readBufferSize; | ||
/** | ||
* Read a buffer value as a string from concatenateBuf8List() | ||
* | ||
* If there isn't enough input data, return null | ||
*/ | ||
private readString; | ||
/** Decrypt input after extracting decryption data */ | ||
_transform: (chunk: Buffer | string, encoding: string, callback: TransformCallback) => void; | ||
_flush: (callback: TransformCallback) => void; | ||
} |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{Transform as e}from"stream";import{getUint8Array as t}from"@keeex/js-utils/web/uint8array.js";import{createDecryptionContext as i}from"../../cipher.js";import{extractString as r,getChunkBuffer as n}from"./util.js";var s;!function(e){e.readingAlgoNameSize="ALGOSIZE",e.readingAlgoName="ALGO",e.readingIVSize="IVSIZE",e.readingIV="IV",e.readingCiphertextSize="CIPHERSIZE",e.readingHeaderEnd="HEADEREND",e.readingCipher="CIPHER"}(s||(s={}));export default class h extends e{key;state=s.readingAlgoNameSize;inputChunk=null;inputChunkOffset=null;readBuffer=[];settings={alreadyProcessed:0};context;constructor(e){let{encryptionKey:t,objectMode:i,...r}=e;if(super(r),i)throw new Error("Object mode not supported on encryption stream");this.key=t}_transform(e,t,i){this.inputChunk=n(e,t),this.inputChunkOffset=0,this.processInputChunk(i).catch(i)}_flush(e){this.processFinal(e).catch(e)}async processInputChunk(e){for(;this.inputChunk;)await this.processTempBuffer();e()}async processFinal(e){if(!this.context)return void e();const t=await this.context.final();0!==t.byteLength&&this.push(t),e()}async processTempBuffer(){switch(this.state){case s.readingAlgoNameSize:return this.readAlgoNameSize();case s.readingAlgoName:return this.readAlgoName();case s.readingIVSize:return this.readIVSize();case s.readingIV:return this.readIV();case s.readingCiphertextSize:return this.readCiphertextSize();case s.readingHeaderEnd:return this.readHeaderEnd();case s.readingCipher:return this.readCiphertext()}}readAlgoNameSize(){const e=this.readBufferSize();null!==e&&(this.settings.algoNameLength=e,this.state=s.readingAlgoName)}readAlgoName(){if(void 0===this.settings.algoNameLength)throw new Error("Unexpected state");const e=this.readString(this.settings.algoNameLength);if(null!==e){if(e!==this.key.algorithm())throw new Error("Unexpected algorithm");this.settings.algoName=e,this.state=s.readingIVSize}}readIVSize(){const e=this.readBufferSize();null!==e&&(this.settings.ivLength=e,this.state=s.readingIV)}readIV(){if(void 0===this.settings.ivLength)throw new Error("Unexpected state");this.populateReadBuffer(this.settings.ivLength)&&(this.settings.iv=new Uint8Array(this.readBuffer),this.readBuffer.length=0,this.state=s.readingCiphertextSize)}readCiphertextSize(){const e=this.readBufferSize();null!==e&&(this.settings.cipherSize=e,this.state=0===e?s.readingHeaderEnd:s.readingCipher)}readHeaderEnd(){if(this.getByte()!=="#".charCodeAt(0))throw new Error("Unexpected header end");this.state=s.readingCipher}async readCiphertext(){if(null===this.inputChunk||null===this.inputChunkOffset)throw new Error("Missing input");if(void 0===this.settings.cipherSize)throw new Error("Unexpected state");this.context||(this.context=await this.initContext());const e=0===this.inputChunkOffset?this.inputChunk:t(this.inputChunk,this.inputChunkOffset);let i;if(0===this.settings.cipherSize)i=e;else{const t=this.settings.cipherSize-this.settings.alreadyProcessed;i=e.byteLength<=t?e:e.slice(0,t)}this.settings.alreadyProcessed+=i.byteLength;const r=await this.context.update(i);this.push(r),this.inputChunk=null,this.inputChunkOffset=null}async initContext(){if(!this.settings.iv)throw new Error("Unexpected state");return i(this.key,this.settings.iv)}getByte(){if(null===this.inputChunk||null===this.inputChunkOffset)return null;const e=this.inputChunk[this.inputChunkOffset++];return this.inputChunkOffset===this.inputChunk.byteLength&&(this.inputChunk=null,this.inputChunkOffset=null),e}populateReadBuffer(e){for(;this.readBuffer.length<e;){const e=this.getByte();if(null===e)break;this.readBuffer.push(e)}return this.readBuffer.length>=e}readBufferSize(){if(!this.populateReadBuffer(2))return null;if(this.readBuffer[0]!=="!".charCodeAt(0))throw new Error("Unexpected buffer input");const e=this.readBuffer[1];if(!this.populateReadBuffer(2+e))return null;const t=parseInt(r(this.readBuffer,2),36);return this.readBuffer.length=0,t}readString(e){if(!this.populateReadBuffer(e))return null;const t=r(this.readBuffer);return this.readBuffer.length=0,t}} | ||
import{Transform as t}from"stream";import{getUint8Array as e}from"@keeex/js-utils/web/uint8array.js";import{createDecryptionContext as i}from"../../cipher.js";import{extractString as r,getChunkBuffer as s}from"./util.js";var n;!function(t){t.readingAlgoNameSize="ALGOSIZE",t.readingAlgoName="ALGO",t.readingIVSize="IVSIZE",t.readingIV="IV",t.readingCiphertextSize="CIPHERSIZE",t.readingHeaderEnd="HEADEREND",t.readingCipher="CIPHER"}(n||(n={}));export default class h extends t{#t;#e=n.readingAlgoNameSize;#i=null;#r=null;#s=[];#n={alreadyProcessed:0};#h;constructor(t){let{encryptionKey:e,objectMode:i,...r}=t;if(super(r),i)throw new Error("Object mode not supported on encryption stream");this.#t=e}_transform=(t,e,i)=>{this.#i=s(t,e),this.#r=0,this.#a(i).catch(i)};_flush=t=>{this.#o(t).catch(t)};#a=async t=>{for(;this.#i;)await this.#l();t()};#o=async t=>{if(!this.#h)return void t();const e=await this.#h.final();0!==e.byteLength&&this.push(e),t()};#l=async()=>{switch(this.#e){case n.readingAlgoNameSize:return this.#c();case n.readingAlgoName:return this.#d();case n.readingIVSize:return this.#u();case n.readingIV:return this.#g();case n.readingCiphertextSize:return this.#p();case n.readingHeaderEnd:return this.#f();case n.readingCipher:return this.#m()}};#c=()=>{const t=this.#w();null!==t&&(this.#n.algoNameLength=t,this.#e=n.readingAlgoName)};#d=()=>{if(void 0===this.#n.algoNameLength)throw new Error("Unexpected state");const t=this.#S(this.#n.algoNameLength);if(null!==t){if(t!==this.#t.algorithm())throw new Error("Unexpected algorithm");this.#n.algoName=t,this.#e=n.readingIVSize}};#u=()=>{const t=this.#w();null!==t&&(this.#n.ivLength=t,this.#e=n.readingIV)};#g=()=>{if(void 0===this.#n.ivLength)throw new Error("Unexpected state");this.#E(this.#n.ivLength)&&(this.#n.iv=new Uint8Array(this.#s),this.#s.length=0,this.#e=n.readingCiphertextSize)};#p=()=>{const t=this.#w();null!==t&&(this.#n.cipherSize=t,this.#e=0===t?n.readingHeaderEnd:n.readingCipher)};#f(){if(this.#y()!=="#".charCodeAt(0))throw new Error("Unexpected header end");this.#e=n.readingCipher}#m=async()=>{if(null===this.#i||null===this.#r)throw new Error("Missing input");if(void 0===this.#n.cipherSize)throw new Error("Unexpected state");this.#h||(this.#h=await this.#x());const t=0===this.#r?this.#i:e(this.#i,this.#r);let i;if(0===this.#n.cipherSize)i=t;else{const e=this.#n.cipherSize-this.#n.alreadyProcessed;i=t.byteLength<=e?t:t.slice(0,e)}this.#n.alreadyProcessed+=i.byteLength;const r=await this.#h.update(i);this.push(r),this.#i=null,this.#r=null};#x=async()=>{if(!this.#n.iv)throw new Error("Unexpected state");return i(this.#t,this.#n.iv)};#y=()=>{if(null===this.#i||null===this.#r)return null;const t=this.#i[this.#r++];return this.#r===this.#i.byteLength&&(this.#i=null,this.#r=null),t};#E=t=>{for(;this.#s.length<t;){const t=this.#y();if(null===t)break;this.#s.push(t)}return this.#s.length>=t};#w=()=>{if(!this.#E(2))return null;if(this.#s[0]!=="!".charCodeAt(0))throw new Error("Unexpected buffer input");const t=this.#s[1];if(!this.#E(2+t))return null;const e=parseInt(r(this.#s,2),36);return this.#s.length=0,e};#S=t=>{if(!this.#E(t))return null;const e=r(this.#s);return this.#s.length=0,e}} |
@@ -38,4 +38,3 @@ /** | ||
export default class Encrypt extends Transform { | ||
private key; | ||
private context?; | ||
#private; | ||
/** | ||
@@ -54,10 +53,4 @@ * Construct the encryption stream | ||
*/ | ||
_transform(chunk: Buffer | string, encoding: string, callback: TransformCallback): void; | ||
_flush(callback: TransformCallback): void; | ||
/** | ||
* Consume the whole input chunk | ||
*/ | ||
private processInputChunk; | ||
private writeHeaderCreateContext; | ||
private processFinal; | ||
_transform: (chunk: Buffer | string, encoding: string, callback: TransformCallback) => void; | ||
_flush: (callback: TransformCallback) => void; | ||
} |
@@ -28,2 +28,2 @@ /** | ||
*/ | ||
import{Transform as t}from"stream";import{getUint8Array as e}from"@keeex/js-utils/web/uint8array.js";import{createEncryptionContext as s,encryptImmediateEncoding as r,generateIV as n}from"../../cipher.js";import{getChunkBuffer as o}from"./util.js";export default class i extends t{key;context;constructor(t){let{encryptionKey:e,objectMode:s,...r}=t;if(super(r),s)throw new Error("Object mode not supported on encryption stream");this.key=e}_transform(t,e,s){const r=o(t,e);this.processInputChunk(r,s).catch(s)}_flush(t){this.processFinal(t).catch(t)}async processInputChunk(t,e){this.context||(this.context=await this.writeHeaderCreateContext());const s=await this.context.update(t);this.push(s),e()}async writeHeaderCreateContext(){const t=await n(this.key.algorithm()),o=r(this.key,e(t));return this.push(e(o)),s(this.key,e(t))}async processFinal(t){if(!this.context)return void t();const e=await this.context.final();0!==e.byteLength&&this.push(e),t()}} | ||
import{Transform as t}from"stream";import{getUint8Array as s}from"@keeex/js-utils/web/uint8array.js";import{createEncryptionContext as e,encryptImmediateEncoding as r,generateIV as i}from"../../cipher.js";import{getChunkBuffer as a}from"./util.js";export default class o extends t{#t;#s;constructor(t){let{encryptionKey:s,objectMode:e,...r}=t;if(super(r),e)throw new Error("Object mode not supported on encryption stream");this.#t=s}_transform=(t,s,e)=>{const r=a(t,s);this.#e(r,e).catch(e)};_flush=t=>{this.#r(t).catch(t)};#e=async(t,s)=>{this.#s||(this.#s=await this.#i());const e=await this.#s.update(t);this.push(e),s()};#i=async()=>{const t=await i(this.#t.algorithm()),a=r(this.#t,s(t));return this.push(s(a)),e(this.#t,s(t))};#r=async t=>{if(!this.#s)return void t();const s=await this.#s.final();0!==s.byteLength&&this.push(s),t()}} |
@@ -29,9 +29,5 @@ /** | ||
/// <reference types="node" /> | ||
/** | ||
* Return an Uint8Array from a stream chunk | ||
*/ | ||
/** Return an Uint8Array from a stream chunk */ | ||
export declare const getChunkBuffer: (chunk: Buffer | string, encoding: string) => Uint8Array; | ||
/** | ||
* Rebuild a string from a byte array, starting at given offset | ||
*/ | ||
/** Rebuild a string from a byte array, starting at given offset */ | ||
export declare const extractString: (src: Array<number>, offset?: number) => string; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
238151
151
4852
196
5
+ Added@keeex/asmcrypto.js@^4.0.2
+ Addedjs-sha1@^0.6.0
+ Addedjs-sha3@^0.8.0
+ Addedjssha@^3.3.0
+ Addedjs-sha1@0.6.0(transitive)
+ Addedjs-sha3@0.8.0(transitive)
+ Addedjssha@3.3.1(transitive)
- Removed@keeex/crypto@3.7.5(transitive)
- Removed@keeex/crypto-provider-purejs@3.3.0(transitive)
- Removed@keeex/jssha@3.3.1(transitive)
- Removedjs-sha1@0.7.0(transitive)
- Removedjs-sha3@0.9.3(transitive)