UNPKG

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.

85 lines 12.8 kB
/** * @license * Copyright 2020 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import { SecurityException } from '../exception/security_exception'; import { PbEcdsaPrivateKey, PbEcdsaSignatureEncoding as PbEcdsaSignatureEncodingType } from '../internal/proto'; import { bytesAsU8, bytesLength } from '../internal/proto_shims'; import * as Util from '../internal/util'; import * as EllipticCurves from '../subtle/elliptic_curves'; import * as Validators from '../subtle/validators'; export function validateKeyFormat(keyFormat) { const params = keyFormat.getParams(); if (!params) { throw new SecurityException('Invalid key format - missing params.'); } validateParams(params); } export function validatePrivateKey(key, privateKeyManagerVersion, publicKeyManagerVersion) { Validators.validateVersion(key.getVersion(), privateKeyManagerVersion); if (!key.getKeyValue()) { throw new SecurityException('Invalid private key - missing private key value.'); } const publicKey = key.getPublicKey(); if (!publicKey) { throw new SecurityException('Invalid private key - missing public key information.'); } validatePublicKey(publicKey, publicKeyManagerVersion); } export function validatePublicKey(key, publicKeyManagerVersion) { Validators.validateVersion(key.getVersion(), publicKeyManagerVersion); const params = key.getParams(); if (!params) { throw new SecurityException('Invalid public key - missing params.'); } validateParams(params); if (!bytesLength(key.getX()) || !bytesLength(key.getY())) { throw new SecurityException('Invalid public key - missing value of X or Y.'); } } export function validateParams(params) { if (params.getEncoding() === PbEcdsaSignatureEncodingType.UNKNOWN_ENCODING) { throw new SecurityException('Invalid public key - missing signature encoding.'); } const hash = Util.hashTypeProtoToString(params.getHashType()); const curve = EllipticCurves.curveToString(Util.curveTypeProtoToSubtle(params.getCurve())); Validators.validateEcdsaParams(curve, hash); } export function encodingTypeProtoToEnum(encodingTypeProto) { switch (encodingTypeProto) { case PbEcdsaSignatureEncodingType.DER: return EllipticCurves.EcdsaSignatureEncodingType.DER; case PbEcdsaSignatureEncodingType.IEEE_P1363: return EllipticCurves.EcdsaSignatureEncodingType.IEEE_P1363; default: throw new SecurityException('Unknown ECDSA signature encoding type.'); } } /** * WARNING: This method assumes that the given key proto is valid. * */ export function getJsonWebKeyFromProto(key) { let publicKey; let d = null; if (key instanceof PbEcdsaPrivateKey) { publicKey = key.getPublicKey(); } else { publicKey = key; } const params = publicKey.getParams(); if (!params) { throw new SecurityException('Params not set'); } const curveType = Util.curveTypeProtoToSubtle(params.getCurve()); const expectedLength = EllipticCurves.fieldSizeInBytes(curveType); const x = Util.bigEndianNumberToCorrectLength(bytesAsU8(publicKey.getX()), expectedLength); const y = Util.bigEndianNumberToCorrectLength(bytesAsU8(publicKey.getY()), expectedLength); if (key instanceof PbEcdsaPrivateKey) { d = Util.bigEndianNumberToCorrectLength(bytesAsU8(key.getKeyValue()), expectedLength); } return EllipticCurves.getJsonWebKey(curveType, x, y, d); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNkc2FfdXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NpZ25hdHVyZS9lY2RzYV91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxpQ0FBaUMsQ0FBQztBQUNsRSxPQUFPLEVBQWtDLGlCQUFpQixFQUFvQix3QkFBd0IsSUFBSSw0QkFBNEIsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2pLLE9BQU8sRUFBQyxTQUFTLEVBQUUsV0FBVyxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFDL0QsT0FBTyxLQUFLLElBQUksTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEtBQUssY0FBYyxNQUFNLDJCQUEyQixDQUFDO0FBQzVELE9BQU8sS0FBSyxVQUFVLE1BQU0sc0JBQXNCLENBQUM7QUFFbkQsTUFBTSxVQUFVLGlCQUFpQixDQUFDLFNBQTJCO0lBQzNELE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNyQyxJQUFJLENBQUMsTUFBTSxFQUFFO1FBQ1gsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7S0FDckU7SUFDRCxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDekIsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FDOUIsR0FBc0IsRUFBRSx3QkFBZ0MsRUFDeEQsdUJBQStCO0lBQ2pDLFVBQVUsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxFQUFFLHdCQUF3QixDQUFDLENBQUM7SUFDdkUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsRUFBRTtRQUN0QixNQUFNLElBQUksaUJBQWlCLENBQ3ZCLGtEQUFrRCxDQUFDLENBQUM7S0FDekQ7SUFDRCxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDckMsSUFBSSxDQUFDLFNB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UyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ2pELElBQUksR0FBRyxZQUFZLGlCQUFpQixFQUFFO1FBQ3BDLENBQUMsR0FBRyxJQUFJLENBQUMsOEJBQThCLENBQ25DLFNBQVMsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztLQUNuRDtJQUNELE9BQU8sY0FBYyxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMxRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuXG5pbXBvcnQge1NlY3VyaXR5RXhjZXB0aW9ufSBmcm9tICcuLi9leGNlcHRpb24vc2VjdXJpdHlfZXhjZXB0aW9uJztcbmltcG9ydCB7UGJFY2RzYUtleUZvcm1hdCwgUGJFY2RzYVBhcmFtcywgUGJFY2RzYVByaXZhdGVLZXksIFBiRWNkc2FQdWJsaWNLZXksIFBiRWNkc2FTaWduYXR1cmVFbmNvZGluZyBhcyBQYkVjZHNhU2lnbmF0dXJlRW5jb2RpbmdUeXBlfSBmcm9tICcuLi9pbnRlcm5hbC9wcm90byc7XG5pbXBvcnQge2J5dGVzQXNVOCwgYnl0ZXNMZW5ndGh9IGZyb20gJy4uL2ludGVybmFsL3Byb3RvX3NoaW1zJztcbmltcG9ydCAqIGFzIFV0aWwgZnJvbSAnLi4vaW50ZXJuYWwvdXRpbCc7XG5pbXBvcnQgKiBhcyBFbGxpcHRpY0N1cnZlcyBmcm9tICcuLi9zdWJ0bGUvZWxsaXB0aWNfY3VydmVzJztcbmltcG9ydCAqIGFzIFZhbGlkYXRvcnMgZnJvbSAnLi4vc3VidGxlL3ZhbGlkYXRvcnMnO1xuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVLZXlGb3JtYXQoa2V5Rm9ybWF0OiBQYkVjZHNhS2V5Rm9ybWF0KSB7XG4gIGNvbnN0IHBhcmFtcyA9IGtleUZvcm1hdC5nZXRQYXJhbXMoKTtcbiAgaWYgKCFwYXJhbXMpIHtcbiAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oJ0ludmFsaWQga2V5IGZvcm1hdCAtIG1pc3NpbmcgcGFyYW1zLicpO1xuICB9XG4gIHZhbGlkYXRlUGFyYW1zKHBhcmFtcyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVByaXZhdGVLZXkoXG4gICAga2V5OiBQYkVjZHNhUHJpdmF0ZUtleSwgcHJpdmF0ZUtleU1hbmFnZXJWZXJzaW9uOiBudW1iZXIsXG4gICAgcHVibGljS2V5TWFuYWdlclZlcnNpb246IG51bWJlcikge1xuICBWYWxpZGF0b3JzLnZhbGlkYXRlVmVyc2lvbihrZXkuZ2V0VmVyc2lvbigpLCBwcml2YXRlS2V5TWFuYWdlclZlcnNpb24pO1xuICBpZiAoIWtleS5nZXRLZXlWYWx1ZSgpKSB7XG4gICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAnSW52YWxpZCBwcml2YXRlIGtleSAtIG1pc3NpbmcgcHJpdmF0ZSBrZXkgdmFsdWUuJyk7XG4gIH1cbiAgY29uc3QgcHVibGljS2V5ID0ga2V5LmdldFB1YmxpY0tleSgpO1xuICBpZiAoIXB1YmxpY0tleSkge1xuICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbihcbiAgICAgICAgJ0ludmFsaWQgcHJpdmF0ZSBrZXkgLSBtaXNzaW5nIHB1YmxpYyBrZXkgaW5mb3JtYXRpb24uJyk7XG4gIH1cbiAgdmFsaWRhdGVQdWJsaWNLZXkocHVibGljS2V5LCBwdWJsaWNLZXlNYW5hZ2VyVmVyc2lvbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVB1YmxpY0tleShcbiAgICBrZXk6IFBiRWNkc2FQdWJsaWNLZXksIHB1YmxpY0tleU1hbmFnZXJWZXJzaW9uOiBudW1iZXIpIHtcbiAgVmFsaWRhdG9ycy52YWxpZGF0ZVZlcnNpb24oa2V5LmdldFZlcnNpb24oKSwgcHVibGljS2V5TWFuYWdlclZlcnNpb24pO1xuICBjb25zdCBwYXJhbXMgPSBrZXkuZ2V0UGFyYW1zKCk7XG4gIGlmICghcGFyYW1zKSB7XG4gICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCdJbnZhbGlkIHB1YmxpYyBrZXkgLSBtaXNzaW5nIHBhcmFtcy4nKTtcbiAgfVxuICB2YWxpZGF0ZVBhcmFtcyhwYXJhbXMpO1xuICBpZiAoIWJ5dGVzTGVuZ3RoKGtleS5nZXRYKCkpIHx8ICFieXRlc0xlbmd0aChrZXkuZ2V0WSgpKSkge1xuICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbihcbiAgICAgICAgJ0ludmFsaWQgcHVibGljIGtleSAtIG1pc3NpbmcgdmFsdWUgb2YgWCBvciBZLicpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVBhcmFtcyhwYXJhbXM6IFBiRWNkc2FQYXJhbXMpIHtcbiAgaWYgKHBhcmFtcy5nZXRFbmNvZGluZygpID09PSBQYkVjZHNhU2lnbmF0dXJlRW5jb2RpbmdUeXBlLlVOS05PV05fRU5DT0RJTkcpIHtcbiAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oXG4gICAgICAgICdJbnZhbGlkIHB1YmxpYyBrZXkgLSBtaXNzaW5nIHNpZ25hdHVyZSBlbmNvZGluZy4nKTtcbiAgfVxuICBjb25zdCBoYXNoID0gVXRpbC5oYXNoVHlwZVByb3RvVG9TdHJpbmcocGFyYW1zLmdldEhhc2hUeXBlKCkpO1xuICBjb25zdCBjdXJ2ZSA9IEVsbGlwdGljQ3VydmVzLmN1cnZlVG9TdHJpbmcoXG4gICAgICBVdGlsLmN1cnZlVHlwZVByb3RvVG9TdWJ0bGUocGFyYW1zLmdldEN1cnZlKCkpKTtcbiAgVmFsaWRhdG9ycy52YWxpZGF0ZUVjZHNhUGFyYW1zKGN1cnZlLCBoYXNoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVuY29kaW5nVHlwZVByb3RvVG9FbnVtKFxuICAgIGVuY29kaW5nVHlwZVByb3RvOiBQYkVjZHNhU2lnbmF0dXJlRW5jb2RpbmdUeXBlKTpcbiAgICBFbGxpcHRpY0N1cnZlcy5FY2RzYVNpZ25hdHVyZUVuY29kaW5nVHlwZSB7XG4gIHN3aXRjaCAoZW5jb2RpbmdUeXBlUHJvdG8pIHtcbiAgICBjYXNlIFBiRWNkc2FTaWduYXR1cmVFbmNvZGluZ1R5cGUuREVSOlxuICAgICAgcmV0dXJuIEVsbGlwdGljQ3VydmVzLkVjZHNhU2lnbmF0dXJlRW5jb2RpbmdUeXBlLkRFUjtcbiAgICBjYXNlIFBiRWNkc2FTaWduYXR1cmVFbmNvZGluZ1R5cGUuSUVFRV9QMTM2MzpcbiAgICAgIHJldHVybiBFbGxpcHRpY0N1cnZlcy5FY2RzYVNpZ25hdHVyZUVuY29kaW5nVHlwZS5JRUVFX1AxMzYzO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oJ1Vua25vd24gRUNEU0Egc2lnbmF0dXJlIGVuY29kaW5nIHR5cGUuJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBXQVJOSU5HOiBUaGlzIG1ldGhvZCBhc3N1bWVzIHRoYXQgdGhlIGdpdmVuIGtleSBwcm90byBpcyB2YWxpZC5cbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRKc29uV2ViS2V5RnJvbVByb3RvKGtleTogUGJFY2RzYVByaXZhdGVLZXl8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYkVjZHNhUHVibGljS2V5KTogSnNvbldlYktleSB7XG4gIGxldCBwdWJsaWNLZXk6IFBiRWNkc2FQdWJsaWNLZXk7XG4gIGxldCBkOiBVaW50OEFycmF5fG51bGwgPSBudWxsO1xuICBpZiAoa2V5IGluc3RhbmNlb2YgUGJFY2RzYVByaXZhdGVLZXkpIHtcbiAgICBwdWJsaWNLZXkgPSAoa2V5LmdldFB1YmxpY0tleSgpIGFzIFBiRWNkc2FQdWJsaWNLZXkpO1xuICB9IGVsc2Uge1xuICAgIHB1YmxpY0tleSA9IGtleTtcbiAgfVxuICBjb25zdCBwYXJhbXMgPSBwdWJsaWNLZXkuZ2V0UGFyYW1zKCk7XG4gIGlmICghcGFyYW1zKSB7XG4gICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCdQYXJhbXMgbm90IHNldCcpO1xuICB9XG4gIGNvbnN0IGN1cnZlVHlwZSA9IFV0aWwuY3VydmVUeXBlUHJvdG9Ub1N1YnRsZShwYXJhbXMuZ2V0Q3VydmUoKSk7XG4gIGNvbnN0IGV4cGVjdGVkTGVuZ3RoID0gRWxsaXB0aWNDdXJ2ZXMuZmllbGRTaXplSW5CeXRlcyhjdXJ2ZVR5cGUpO1xuICBjb25zdCB4ID0gVXRpbC5iaWdFbmRpYW5OdW1iZXJUb0NvcnJlY3RMZW5ndGgoXG4gICAgICBieXRlc0FzVTgocHVibGljS2V5LmdldFgoKSksIGV4cGVjdGVkTGVuZ3RoKTtcbiAgY29uc3QgeSA9IFV0aWwuYmlnRW5kaWFuTnVtYmVyVG9Db3JyZWN0TGVuZ3RoKFxuICAgICAgYnl0ZXNBc1U4KHB1YmxpY0tleS5nZXRZKCkpLCBleHBlY3RlZExlbmd0aCk7XG4gIGlmIChrZXkgaW5zdGFuY2VvZiBQYkVjZHNhUHJpdmF0ZUtleSkge1xuICAgIGQgPSBVdGlsLmJpZ0VuZGlhbk51bWJlclRvQ29ycmVjdExlbmd0aChcbiAgICAgICAgYnl0ZXNBc1U4KGtleS5nZXRLZXlWYWx1ZSgpKSwgZXhwZWN0ZWRMZW5ndGgpO1xuICB9XG4gIHJldHVybiBFbGxpcHRpY0N1cnZlcy5nZXRKc29uV2ViS2V5KGN1cnZlVHlwZSwgeCwgeSwgZCk7XG59XG4iXX0=