blob: 366317f4d963a2d23a9a6598107e72b1e0257f07 [file] [log] [blame]
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {SecurityException} from '../exception/security_exception';
import {PbEcdsaKeyFormat, PbEcdsaParams, PbEcdsaPrivateKey, PbEcdsaPublicKey, PbEcdsaSignatureEncoding as PbEcdsaSignatureEncodingType} from '../internal/proto';
import * as Util from '../internal/util';
import * as EllipticCurves from '../subtle/elliptic_curves';
import * as Validators from '../subtle/validators';
export function validateKeyFormat(keyFormat: PbEcdsaKeyFormat) {
const params = keyFormat.getParams();
if (!params) {
throw new SecurityException('Invalid key format - missing params.');
}
validateParams(params);
}
export function validatePrivateKey(
key: PbEcdsaPrivateKey, privateKeyManagerVersion: number,
publicKeyManagerVersion: number) {
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: PbEcdsaPublicKey, publicKeyManagerVersion: number) {
Validators.validateVersion(key.getVersion(), publicKeyManagerVersion);
const params = key.getParams();
if (!params) {
throw new SecurityException('Invalid public key - missing params.');
}
validateParams(params);
if (!key.getX() || !key.getY()) {
throw new SecurityException(
'Invalid public key - missing value of X or Y.');
}
}
export function validateParams(params: PbEcdsaParams) {
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: PbEcdsaSignatureEncodingType):
EllipticCurves.EcdsaSignatureEncodingType {
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: PbEcdsaPrivateKey|
PbEcdsaPublicKey): JsonWebKey {
let publicKey: PbEcdsaPublicKey;
let d: Uint8Array|null = null;
if (key instanceof PbEcdsaPrivateKey) {
publicKey = (key.getPublicKey() as PbEcdsaPublicKey);
} 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(
publicKey.getX_asU8(), expectedLength);
const y = Util.bigEndianNumberToCorrectLength(
publicKey.getY_asU8(), expectedLength);
if (key instanceof PbEcdsaPrivateKey) {
d = Util.bigEndianNumberToCorrectLength(
key.getKeyValue_asU8(), expectedLength);
}
return EllipticCurves.getJsonWebKey(curveType, x, y, d);
}