Fixes ECDH with Curve25519 and key import/export problems

This commit is contained in:
Mahrud Sayrafi 2018-01-04 01:44:50 -08:00 committed by Sanjana Rajan
parent 35f18444b0
commit 3e1d9c4d0d
3 changed files with 31 additions and 19 deletions

View File

@ -60,6 +60,7 @@ if (webCrypto && config.use_native) {
const curves = { const curves = {
p256: { p256: {
oid: util.bin2str([0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07]), oid: util.bin2str([0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07]),
keyType: enums.publicKey.ecdsa,
hash: enums.hash.sha256, hash: enums.hash.sha256,
cipher: enums.symmetric.aes128, cipher: enums.symmetric.aes128,
node: nodeCurves.secp256r1, node: nodeCurves.secp256r1,
@ -68,6 +69,7 @@ const curves = {
}, },
p384: { p384: {
oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x22]), oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x22]),
keyType: enums.publicKey.ecdsa,
hash: enums.hash.sha384, hash: enums.hash.sha384,
cipher: enums.symmetric.aes192, cipher: enums.symmetric.aes192,
node: nodeCurves.secp384r1, node: nodeCurves.secp384r1,
@ -76,6 +78,7 @@ const curves = {
}, },
p521: { p521: {
oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x23]), oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x23]),
keyType: enums.publicKey.ecdsa,
hash: enums.hash.sha512, hash: enums.hash.sha512,
cipher: enums.symmetric.aes256, cipher: enums.symmetric.aes256,
node: nodeCurves.secp521r1, node: nodeCurves.secp521r1,
@ -84,17 +87,19 @@ const curves = {
}, },
secp256k1: { secp256k1: {
oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x0A]), oid: util.bin2str([0x2B, 0x81, 0x04, 0x00, 0x0A]),
keyType: enums.publicKey.ecdsa,
hash: enums.hash.sha256, hash: enums.hash.sha256,
cipher: enums.symmetric.aes128, cipher: enums.symmetric.aes128,
node: false // FIXME when we replace jwk-to-pem or it supports this curve node: false // FIXME when we replace jwk-to-pem or it supports this curve
}, },
ed25519: { ed25519: {
oid: util.bin2str([0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01]), oid: util.bin2str([0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01]),
hash: enums.hash.sha512, keyType: enums.publicKey.eddsa,
keyType: enums.publicKey.eddsa hash: enums.hash.sha512
}, },
curve25519: { curve25519: {
oid: util.bin2str([0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01]), oid: util.bin2str([0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01]),
keyType: enums.publicKey.ecdh,
hash: enums.hash.sha256, hash: enums.hash.sha256,
cipher: enums.symmetric.aes128 cipher: enums.symmetric.aes128
}, },
@ -107,12 +112,17 @@ const curves = {
}; };
function Curve(name, params) { function Curve(name, params) {
if (params.keyType === enums.publicKey.eddsa) { this.keyType = params.keyType;
this.curve = new EdDSA(name); switch (this.keyType) {
this.keyType = enums.publicKey.eddsa; case enums.publicKey.eddsa:
} else { this.curve = new EdDSA(name);
this.curve = new EC(name); break;
this.keyType = enums.publicKey.ecdsa; case enums.publicKey.ecdsa:
case enums.publicKey.ecdh:
this.curve = new EC(name);
break;
default:
throw new Error('Unknown elliptic key type;');
} }
this.oid = curves[name].oid; this.oid = curves[name].oid;
this.hash = params.hash; this.hash = params.hash;
@ -141,16 +151,12 @@ Curve.prototype.genKeyPair = async function () {
} else if (nodeCrypto && config.use_native && this.node) { } else if (nodeCrypto && config.use_native && this.node) {
keyPair = await nodeGenKeyPair(this.name); keyPair = await nodeGenKeyPair(this.name);
} else { } else {
var compact = this.curve.curve.type === 'edwards' || this.curve.curve.type === 'mont';
r = await this.curve.genKeyPair();
if (this.keyType === enums.publicKey.eddsa) { if (this.keyType === enums.publicKey.eddsa) {
keyPair = { keyPair = { secret: r.getSecret() };
secret: util.hexidump(random.getRandomBytes(32))
};
} else { } else {
r = this.curve.genKeyPair(); keyPair = { pub: r.getPublic('array', compact), priv: r.getPrivate().toArray() };
keyPair = {
pub: r.getPublic().encode(),
priv: r.getPrivate().toArray()
};
} }
} }
return new KeyPair(this.curve, keyPair); return new KeyPair(this.curve, keyPair);

View File

@ -118,6 +118,8 @@ async function decrypt(oid, cipher_algo, hash_algo, V, C, d, fingerprint) {
} }
module.exports = { module.exports = {
buildEcdhParam: buildEcdhParam,
kdf: kdf,
encrypt: encrypt, encrypt: encrypt,
decrypt: decrypt decrypt: decrypt
}; };

View File

@ -55,11 +55,12 @@ KeyPair.prototype.derive = function (pub) {
if (this.keyType === enums.publicKey.eddsa) { if (this.keyType === enums.publicKey.eddsa) {
throw new Error('Key can only be used for EdDSA'); throw new Error('Key can only be used for EdDSA');
} }
return this.keyPair.derive(pub.keyPair.getPublic()).toArray(); return this.keyPair.derive(pub.keyPair.getPublic());
}; };
KeyPair.prototype.getPublic = function () { KeyPair.prototype.getPublic = function () {
return this.keyPair.getPublic('array'); var compact = (this.curve.curve.type === 'edwards' || this.curve.curve.type === 'mont');
return this.keyPair.getPublic('array', compact);
}; };
KeyPair.prototype.getPrivate = function () { KeyPair.prototype.getPrivate = function () {
@ -70,7 +71,10 @@ KeyPair.prototype.getPrivate = function () {
} }
}; };
KeyPair.prototype.isValid = function () { // FIXME KeyPair.prototype.isValid = function () {
if (this.curve.curve.type === 'edwards' || this.curve.curve.type === 'mont') {
throw new Error('Validation is not Implemented for this curve.');
}
return this.keyPair.validate().result; return this.keyPair.validate().result;
}; };