All files / src/client-side-encryption crypto_callbacks.ts

86.66% Statements 39/45
50% Branches 1/2
100% Functions 7/7
86.66% Lines 39/45

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88404x       404x       1616x     752364x 752364x 752364x 752364x 752364x 752364x             752364x 752364x       404x 452867x 452867x       452867x     404x   13092x 13092x         13092x 13092x       404x 808x   4990988x 4990988x         4990988x 4990988x       404x   3445x 3445x 3445x       3445x         3445x 3445x     404x 404x 404x 404x 404x 404x  
import * as crypto from 'crypto';
 
type AES256Callback = (key: Buffer, iv: Buffer, input: Buffer, output: Buffer) => number | Error;
 
export function makeAES256Hook(
  method: 'createCipheriv' | 'createDecipheriv',
  mode: 'aes-256-cbc' | 'aes-256-ctr'
): AES256Callback {
  return function (key: Buffer, iv: Buffer, input: Buffer, output: Buffer): number | Error {
    let result;
 
    try {
      const cipher = crypto[method](mode, key, iv);
      cipher.setAutoPadding(false);
      result = cipher.update(input);
      const final = cipher.final();
      Iif (final.length > 0) {
        result = Buffer.concat([result, final]);
      }
    } catch (e) {
      return e;
    }
 
    result.copy(output);
    return result.length;
  };
}
 
export function randomHook(buffer: Buffer, count: number): number | Error {
  try {
    crypto.randomFillSync(buffer, 0, count);
  } catch (e) {
    return e;
  }
  return count;
}
 
export function sha256Hook(input: Buffer, output: Buffer): number | Error {
  let result;
  try {
    result = crypto.createHash('sha256').update(input).digest();
  } catch (e) {
    return e;
  }
 
  result.copy(output);
  return result.length;
}
 
type HMACHook = (key: Buffer, input: Buffer, output: Buffer) => number | Error;
export function makeHmacHook(algorithm: 'sha512' | 'sha256'): HMACHook {
  return (key: Buffer, input: Buffer, output: Buffer): number | Error => {
    let result;
    try {
      result = crypto.createHmac(algorithm, key).update(input).digest();
    } catch (e) {
      return e;
    }
 
    result.copy(output);
    return result.length;
  };
}
 
export function signRsaSha256Hook(key: Buffer, input: Buffer, output: Buffer): number | Error {
  let result;
  try {
    const signer = crypto.createSign('sha256WithRSAEncryption');
    const privateKey = Buffer.from(
      `-----BEGIN PRIVATE KEY-----\n${key.toString('base64')}\n-----END PRIVATE KEY-----\n`
    );
 
    result = signer.update(input).end().sign(privateKey);
  } catch (e) {
    return e;
  }
 
  result.copy(output);
  return result.length;
}
 
export const aes256CbcEncryptHook = makeAES256Hook('createCipheriv', 'aes-256-cbc');
export const aes256CbcDecryptHook = makeAES256Hook('createDecipheriv', 'aes-256-cbc');
export const aes256CtrEncryptHook = makeAES256Hook('createCipheriv', 'aes-256-ctr');
export const aes256CtrDecryptHook = makeAES256Hook('createDecipheriv', 'aes-256-ctr');
export const hmacSha512Hook = makeHmacHook('sha512');
export const hmacSha256Hook = makeHmacHook('sha256');