111 lines
2.9 KiB
JavaScript
111 lines
2.9 KiB
JavaScript
const { generateKeyPairSync, generateKeyPair: async } = require('crypto')
|
|
const { promisify } = require('util')
|
|
|
|
const {
|
|
THUMBPRINT_MATERIAL, JWK_MEMBERS, PUBLIC_MEMBERS,
|
|
PRIVATE_MEMBERS, KEY_MANAGEMENT_DECRYPT, KEY_MANAGEMENT_ENCRYPT
|
|
} = require('../../help/consts')
|
|
const { EC_CURVES } = require('../../registry')
|
|
const { keyObjectSupported } = require('../../help/runtime_support')
|
|
const { createPublicKey, createPrivateKey } = require('../../help/key_object')
|
|
|
|
const errors = require('../../errors')
|
|
|
|
const Key = require('./base')
|
|
|
|
const generateKeyPair = promisify(async)
|
|
|
|
const EC_PUBLIC = new Set(['crv', 'x', 'y'])
|
|
Object.freeze(EC_PUBLIC)
|
|
const EC_PRIVATE = new Set([...EC_PUBLIC, 'd'])
|
|
Object.freeze(EC_PRIVATE)
|
|
|
|
// Elliptic Curve Key Type
|
|
class ECKey extends Key {
|
|
constructor (...args) {
|
|
super(...args)
|
|
this[JWK_MEMBERS]()
|
|
Object.defineProperty(this, 'kty', { value: 'EC', enumerable: true })
|
|
if (!EC_CURVES.has(this.crv)) {
|
|
throw new errors.JOSENotSupported('unsupported EC key curve')
|
|
}
|
|
}
|
|
|
|
static get [PUBLIC_MEMBERS] () {
|
|
return EC_PUBLIC
|
|
}
|
|
|
|
static get [PRIVATE_MEMBERS] () {
|
|
return EC_PRIVATE
|
|
}
|
|
|
|
// https://tc39.github.io/ecma262/#sec-ordinaryownpropertykeys no need for any special
|
|
// JSON.stringify handling in V8
|
|
[THUMBPRINT_MATERIAL] () {
|
|
return { crv: this.crv, kty: 'EC', x: this.x, y: this.y }
|
|
}
|
|
|
|
[KEY_MANAGEMENT_ENCRYPT] () {
|
|
return this.algorithms('deriveKey')
|
|
}
|
|
|
|
[KEY_MANAGEMENT_DECRYPT] () {
|
|
if (this.public) {
|
|
return new Set()
|
|
}
|
|
return this.algorithms('deriveKey')
|
|
}
|
|
|
|
static async generate (crv = 'P-256', privat = true) {
|
|
if (!EC_CURVES.has(crv)) {
|
|
throw new errors.JOSENotSupported(`unsupported EC key curve: ${crv}`)
|
|
}
|
|
|
|
let privateKey, publicKey
|
|
|
|
if (keyObjectSupported) {
|
|
({ privateKey, publicKey } = await generateKeyPair('ec', { namedCurve: crv }))
|
|
return privat ? privateKey : publicKey
|
|
}
|
|
|
|
({ privateKey, publicKey } = await generateKeyPair('ec', {
|
|
namedCurve: crv,
|
|
publicKeyEncoding: { type: 'spki', format: 'pem' },
|
|
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
|
|
}))
|
|
|
|
if (privat) {
|
|
return createPrivateKey(privateKey)
|
|
} else {
|
|
return createPublicKey(publicKey)
|
|
}
|
|
}
|
|
|
|
static generateSync (crv = 'P-256', privat = true) {
|
|
if (!EC_CURVES.has(crv)) {
|
|
throw new errors.JOSENotSupported(`unsupported EC key curve: ${crv}`)
|
|
}
|
|
|
|
let privateKey, publicKey
|
|
|
|
if (keyObjectSupported) {
|
|
({ privateKey, publicKey } = generateKeyPairSync('ec', { namedCurve: crv }))
|
|
return privat ? privateKey : publicKey
|
|
}
|
|
|
|
({ privateKey, publicKey } = generateKeyPairSync('ec', {
|
|
namedCurve: crv,
|
|
publicKeyEncoding: { type: 'spki', format: 'pem' },
|
|
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
|
|
}))
|
|
|
|
if (privat) {
|
|
return createPrivateKey(privateKey)
|
|
} else {
|
|
return createPublicKey(publicKey)
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = ECKey
|