UNPKG

@microsoft/useragent-sdk

Version:

SDK for building decentralized identity wallets and enterprise agents.

94 lines (81 loc) 3.77 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import CryptoFactory from "../plugin/CryptoFactory"; import { CryptoAlgorithm } from "../keyStore/IKeyStore"; import KeyTypeFactory, { KeyType } from "./KeyTypeFactory"; import W3cCryptoApiConstants from "../utilities/W3cCryptoApiConstants"; import EcPairwiseKey from "./ec/EcPairwiseKey"; import CryptoError from "../CryptoError"; import RsaPairwiseKey from "./rsa/RsaPairwiseKey"; import PrivateKey from "./PrivateKey"; import { SubtleCrypto } from 'webcrypto-core'; import JoseConstants from "../protocols/jose/JoseConstants"; import OctKey from "./Oct/OctKey"; import IKeyContainer from "./IKeyContainer"; /** * Class to model pairwise keys */ export default class PairwiseKey { /** * Get or set the crypto factory to use, containing the crypto suite and the key store. */ private cryptoFactory: CryptoFactory; // Set of master keys for the different persona's private masterKeys: Map<string, Buffer> = new Map<string, Buffer>(); /** * Create an instance of @class PairwiseKey. * @param cryptoFactory The crypto factory object. */ public constructor (cryptoFactory: CryptoFactory) { this.cryptoFactory = cryptoFactory; } /** * Generate a pairwise key for the specified algorithms * @param algorithm for the key * @param seedReference Reference to the seed * @param personaId Id for the persona * @param peerId Id for the peer */ public async generatePairwiseKey(algorithm: EcKeyGenParams | RsaHashedKeyGenParams, seedReference: string, personaId: string, peerId: string): Promise<PrivateKey> { const personaMasterKey: Buffer = await this.generatePersonaMasterKey(seedReference, personaId); const keyType = KeyTypeFactory.createViaWebCrypto(algorithm); switch (keyType) { case KeyType.EC: case KeyType.OKP: return EcPairwiseKey.generate(this.cryptoFactory, personaMasterKey, <EcKeyGenParams>algorithm, peerId); case KeyType.RSA: return RsaPairwiseKey.generate(this.cryptoFactory, personaMasterKey, <RsaHashedKeyGenParams>algorithm, peerId); default: throw new CryptoError(algorithm, `Pairwise key for type '${keyType}' is not supported.`); } } /** * Generate a pairwise master key. * @param seedReference The master seed for generating pairwise keys * @param personaId The owner DID */ private async generatePersonaMasterKey (seedReference: string, personaId: string): Promise<Buffer> { let mk: Buffer | undefined = this.masterKeys.get(personaId); if (mk) { return mk; } // Get the seed const jwk = <OctKey>(<IKeyContainer> await this.cryptoFactory.keyStore.get(seedReference, false)).getKey(); // Get the subtle crypto const crypto: SubtleCrypto = this.cryptoFactory.getMessageAuthenticationCodeSigners(W3cCryptoApiConstants.Hmac); // Generate the master key const alg: CryptoAlgorithm = { name: W3cCryptoApiConstants.Hmac, hash: W3cCryptoApiConstants.Sha512 }; const masterJwk = { kty: 'oct', alg: JoseConstants.Hs512, k: jwk.k }; let key = await crypto.importKey('jwk', masterJwk, alg, false, ['sign']); const masterKey = await crypto.sign(alg, key, Buffer.from(personaId)); mk = Buffer.from(masterKey); this.masterKeys.set(personaId, mk); return mk; } }