UNPKG

@dfinity/identity

Version:

JavaScript and TypeScript library to manage identity with the Internet Computer

117 lines 4.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ECDSAKeyIdentity = exports.CryptoError = void 0; const agent_1 = require("@dfinity/agent"); const candid_1 = require("@dfinity/candid"); class CryptoError extends Error { constructor(message) { super(message); this.message = message; Object.setPrototypeOf(this, CryptoError.prototype); } } exports.CryptoError = CryptoError; /** * Utility method to ensure that a subtleCrypto implementation is provided or is available in the global context * @param subtleCrypto SubtleCrypto implementation * @returns subleCrypto */ function _getEffectiveCrypto(subtleCrypto) { if (typeof global !== 'undefined' && global['crypto'] && global['crypto']['subtle']) { return global['crypto']['subtle']; } if (subtleCrypto) { return subtleCrypto; } else if (typeof crypto !== 'undefined' && crypto['subtle']) { return crypto.subtle; } else { throw new CryptoError('Global crypto was not available and none was provided. Please inlcude a SubtleCrypto implementation. See https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto'); } } /** * An identity interface that wraps an ECDSA keypair using the P-256 named curve. Supports DER-encoding and decoding for agent calls */ class ECDSAKeyIdentity extends agent_1.SignIdentity { /** * Generates a randomly generated identity for use in calls to the Internet Computer. * @param {CryptoKeyOptions} options optional settings * @param {CryptoKeyOptions['extractable']} options.extractable - whether the key should allow itself to be used. Set to false for maximum security. * @param {CryptoKeyOptions['keyUsages']} options.keyUsages - a list of key usages that the key can be used for * @param {CryptoKeyOptions['subtleCrypto']} options.subtleCrypto interface * @returns a {@link ECDSAKeyIdentity} */ static async generate(options) { const { extractable = false, keyUsages = ['sign', 'verify'], subtleCrypto } = options ?? {}; const effectiveCrypto = _getEffectiveCrypto(subtleCrypto); const keyPair = await effectiveCrypto.generateKey({ name: 'ECDSA', namedCurve: 'P-256', }, extractable, keyUsages); const derKey = (0, candid_1.uint8FromBufLike)(await effectiveCrypto.exportKey('spki', keyPair.publicKey)); Object.assign(derKey, { __derEncodedPublicKey__: undefined, }); return new this(keyPair, derKey, effectiveCrypto); } /** * generates an identity from a public and private key. Please ensure that you are generating these keys securely and protect the user's private key * @param keyPair a CryptoKeyPair * @param subtleCrypto - a SubtleCrypto interface in case one is not available globally * @returns an {@link ECDSAKeyIdentity} */ static async fromKeyPair(keyPair, subtleCrypto) { const effectiveCrypto = _getEffectiveCrypto(subtleCrypto); const derKey = (0, candid_1.uint8FromBufLike)(await effectiveCrypto.exportKey('spki', keyPair.publicKey)); Object.assign(derKey, { __derEncodedPublicKey__: undefined, }); return new ECDSAKeyIdentity(keyPair, derKey, effectiveCrypto); } // `fromKeyPair` and `generate` should be used for instantiation, not this constructor. constructor(keyPair, derKey, subtleCrypto) { super(); this._keyPair = keyPair; this._derKey = derKey; this._subtleCrypto = subtleCrypto; } /** * Return the internally-used key pair. * @returns a CryptoKeyPair */ getKeyPair() { return this._keyPair; } /** * Return the public key. * @returns an {@link PublicKey & DerCryptoKey} */ getPublicKey() { const derKey = this._derKey; const key = Object.create(this._keyPair.publicKey); key.toDer = function () { return derKey; }; return key; } /** * Signs a blob of data, with this identity's private key. * @param {Uint8Array} challenge - challenge to sign with this identity's secretKey, producing a signature * @returns {Promise<Signature>} signature */ async sign(challenge) { const params = { name: 'ECDSA', hash: { name: 'SHA-256' }, }; const signature = (0, candid_1.uint8FromBufLike)(await this._subtleCrypto.sign(params, this._keyPair.privateKey, challenge)); Object.assign(signature, { __signature__: undefined, }); return signature; } } exports.ECDSAKeyIdentity = ECDSAKeyIdentity; exports.default = ECDSAKeyIdentity; //# sourceMappingURL=ecdsa.js.map