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 88143x       143x       572x     424038x 424038x 424038x 424038x 424038x 424038x             424038x 424038x       143x 248614x 248614x       248614x     143x   8114x 8114x         8114x 8114x       143x 286x   2690536x 2690536x         2690536x 2690536x       143x   2018x 2018x 2018x       2018x         2018x 2018x     143x 143x 143x 143x 143x 143x  
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');