All files / src ASN1.ts

89.28% Statements 25/28
36.36% Branches 4/11
100% Functions 5/5
89.28% Lines 25/28

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 88 89 90 91  1x 1x 1x 1x 1x 1x       1x   1x   1x         4x             4x 4x         4x         4x               5x             1x       1x                         1x         1x 1x 1x               3x 3x 3x 3x      
import {ASN1Module} from './asn1/ASN1Module';
import {ASN1ModuleFactory} from './asn1/ASN1ModuleFactory';
import {ASN1Generator} from './ASN1Generator';
import {ASN1Validator} from './ASN1Validator';
import {BERDecode} from './codec/ber/decoder/BERDecoder';
import {DEREncode} from './codec/der/encoder/DEREncoder';
import {EncodingRule} from './EncodingRule';
import {ASN1ParserOptions} from './interfaces';
import {ASN1GeneratorOptions} from './interfaces/ASN1GeneratorOptions';
import {ASN1Message} from './interfaces/ASN1Message';
import {ASN1MessageFormat} from './interfaces/ASN1MessageFormat';
import {Props} from './interfaces/Props';
import {getArrayBufferFromStr} from './misc';
 
export class ASN1 {
  static decode(
    message: string | ArrayBuffer,
    opts: Partial<ASN1ParserOptions> = {}
  ) {
    const options: ASN1ParserOptions = {
      format: ASN1MessageFormat.HEX,
      encodingRule: EncodingRule.DER,
      ...opts,
    } as ASN1ParserOptions;
 
    let input: ArrayBuffer;
    Eif (typeof message === 'string') {
      input = getArrayBufferFromStr(message, options.format);
    } else {
      input = message;
    }
 
    Eif (
      [EncodingRule.BER, EncodingRule.CER, EncodingRule.DER].includes(
        options.encodingRule
      )
    ) {
      return BERDecode(input);
    }
    throw new Error(
      'Encoding rule not yet implemented: ' + options.encodingRule
    );
  }
 
  static getModuleFromStr(definition: string): ASN1Module {
    return ASN1ModuleFactory.compile(definition);
  }
 
  static encode(
    asn1Message: ASN1Message,
    encodingRule = EncodingRule.DER
  ): Buffer {
    Eif (
      encodingRule === EncodingRule.DER ||
      encodingRule === EncodingRule.BER
    ) {
      return Buffer.from(DEREncode(asn1Message), 'hex');
    }
    throw new Error(
      'generate: encoding rule not yet implemented: ' + encodingRule
    );
  }
 
  static generate(
    module: ASN1Module,
    type: string,
    data: Props,
    opts: Partial<ASN1GeneratorOptions> = {}
  ): Buffer {
    const options = {
      encodingRule: EncodingRule.DER,
      inputFormat: 'json',
      ...opts,
    };
    const generator = new ASN1Generator(module, type);
    const asn1Message = generator.generateFromJson(data);
    return ASN1.encode(asn1Message, options.encodingRule);
  }
 
  static validate(
    module: ASN1Module,
    message: ASN1Message,
    type: string
  ): ASN1Message {
    const msg = JSON.parse(JSON.stringify(message)) as ASN1Message;
    const validator = new ASN1Validator(module);
    validator.validate(msg, type);
    return msg;
  }
}