UNPKG

pooja-docucomb-tink-crypto

Version:

A multi-language, cross-platform library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.

148 lines (136 loc) 5.04 kB
/** * @license * Copyright 2020 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import {SecurityException} from '../exception/security_exception'; import * as Bytes from '../subtle/bytes'; import * as EllipticCurves from '../subtle/elliptic_curves'; import {PbEllipticCurveType, PbHashType, PbKeyset, PbKeysetKey, PbKeyStatusType, PbOutputPrefixType, PbPointFormat} from './proto'; /** * A type representing the constructor function for a given class. Unlike * TypeScript's built-in `new` types, this works with abstract classes. It is * used to describe the relationship between a primitive type object and its * instances. */ export type Constructor<T> = Function&{prototype: T}; /** Like the `instanceof` operator, but works with `Constructor`. */ export function isInstanceOf<T>( value: unknown, ctor: Constructor<T>): value is T { return value instanceof ctor; } /** * Validates the given key and throws SecurityException if it is invalid. * */ export function validateKey(key: PbKeysetKey) { if (!key) { throw new SecurityException('Key should be non null.'); } if (!key.getKeyData()) { throw new SecurityException( 'Key data are missing for key ' + key.getKeyId() + '.'); } if (key.getOutputPrefixType() === PbOutputPrefixType.UNKNOWN_PREFIX) { throw new SecurityException( 'Key ' + key.getKeyId() + ' has unknown output prefix type.'); } if (key.getStatus() === PbKeyStatusType.UNKNOWN_STATUS) { throw new SecurityException( 'Key ' + key.getKeyId() + ' has unknown status.'); } } /** * Validates the given keyset and throws SecurityException if it is invalid. * */ export function validateKeyset(keyset: PbKeyset) { if (!keyset || !keyset.getKeyList() || keyset.getKeyList().length < 1) { throw new SecurityException( 'Keyset should be non null and must contain at least one key.'); } let hasPrimary = false; const numberOfKeys = keyset.getKeyList().length; for (let i = 0; i < numberOfKeys; i++) { const key = keyset.getKeyList()[i]; validateKey(key); if (keyset.getPrimaryKeyId() === key.getKeyId() && key.getStatus() === PbKeyStatusType.ENABLED) { if (hasPrimary) { throw new SecurityException('Primary key has to be unique.'); } hasPrimary = true; } } if (!hasPrimary) { throw new SecurityException( 'Primary key has to be in the keyset and ' + 'has to be enabled.'); } } // Functions which are useful for implementation of // private and public EC keys. /** * Either prolong or shrinks the array representing number in BigEndian encoding * to have the specified size. As webcrypto API assumes that x, y and d values * has exactly the supposed number of bytes, whereas corresponding x, y and * keyValue values in proto might either have some leading zeros or the leading * zeros might be missing. * */ export function bigEndianNumberToCorrectLength( bigEndianNumber: Uint8Array, sizeInBytes: number): Uint8Array { const numberLen = bigEndianNumber.length; if (numberLen < sizeInBytes) { const zeros = new Uint8Array(sizeInBytes - numberLen); return Bytes.concat(zeros, bigEndianNumber); } if (numberLen > sizeInBytes) { for (let i = 0; i < numberLen - sizeInBytes; i++) { if (bigEndianNumber[i] != 0) { throw new SecurityException( 'Number needs more bytes to be represented.'); } } return bigEndianNumber.slice(numberLen - sizeInBytes, numberLen); } return bigEndianNumber; } export function curveTypeProtoToSubtle(curveTypeProto: PbEllipticCurveType): EllipticCurves.CurveType { switch (curveTypeProto) { case PbEllipticCurveType.NIST_P256: return EllipticCurves.CurveType.P256; case PbEllipticCurveType.NIST_P384: return EllipticCurves.CurveType.P384; case PbEllipticCurveType.NIST_P521: return EllipticCurves.CurveType.P521; default: throw new SecurityException('Unknown curve type.'); } } export function hashTypeProtoToString(hashTypeProto: PbHashType): string { switch (hashTypeProto) { case PbHashType.SHA1: return 'SHA-1'; case PbHashType.SHA256: return 'SHA-256'; case PbHashType.SHA512: return 'SHA-512'; default: throw new SecurityException('Unknown hash type.'); } } export function pointFormatProtoToSubtle(pointFormatProto: PbPointFormat): EllipticCurves.PointFormatType { switch (pointFormatProto) { case PbPointFormat.UNCOMPRESSED: return EllipticCurves.PointFormatType.UNCOMPRESSED; case PbPointFormat.COMPRESSED: return EllipticCurves.PointFormatType.COMPRESSED; case PbPointFormat.DO_NOT_USE_CRUNCHY_UNCOMPRESSED: return EllipticCurves.PointFormatType.DO_NOT_USE_CRUNCHY_UNCOMPRESSED; default: throw new SecurityException('Unknown point format.'); } }