Read and write ECDSA packets

This commit is contained in:
Ismael Bejarano 2016-08-12 00:24:49 -03:00 committed by Sanjana Rajan
parent ba2f49234e
commit 673151ec87
6 changed files with 42 additions and 6 deletions

View File

@ -144,6 +144,10 @@ export default {
// Algorithm-Specific Fields for DSA secret keys:
// - MPI of DSA secret exponent x.
return 1;
case 'ecdsa':
// Algorithm-Specific Fields for ECDSA secret keys:
// - MPI of an integer representing the secret key.
return 1;
default:
throw new Error('Unknown algorithm');
}
@ -175,6 +179,12 @@ export default {
case 'dsa':
return 4;
// Algorithm-Specific Fields for ECDSA public keys:
// - OID of curve;
// - MPI of EC point representing public key.
case 'ecdsa':
return 2;
default:
throw new Error('Unknown algorithm.');
}

View File

@ -56,6 +56,15 @@ export default {
m = data;
var dopublic = dsa.verify(hash_algo, s1, s2, m, p, q, g, y);
return dopublic.compareTo(s1) === 0;
case 19:
// ECDSA
const ecdsa = publicKey.elliptic.ecdsa;
const curve = publickey_MPIs[0];
const r = msg_MPIs[0].toBigInteger();
const s = msg_MPIs[1].toBigInteger();
m = data;
const gw = publickey_MPIs[1].toBigInteger();
return ecdsa.verify(curve.oid, hash_algo, {r: r, s: s}, m, gw);
default:
throw new Error('Invalid signature algorithm.');
}
@ -107,6 +116,16 @@ export default {
case 16:
// Elgamal (Encrypt-Only) [ELGAMAL] [HAC]
throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.');
case 19:
// ECDSA
const ecdsa = publicKey.elliptic.ecdsa;
const curve = keyIntegers[0];
const w = keyIntegers[2].toBigInteger();
m = data;
const signature = ecdsa.sign(curve.oid, hash_algo, m, w);
return util.str2Uint8Array(signature.r.toMPI() + signature.s.toMPI());
default:
throw new Error('Invalid signature algorithm.');
}

View File

@ -26,7 +26,8 @@ export default {
rsa_encrypt: 2,
rsa_sign: 3,
elgamal: 16,
dsa: 17
dsa: 17,
ecdsa: 19
},
/** {@link http://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}

View File

@ -339,7 +339,8 @@ function isValidEncryptionKeyPacket(keyPacket, signature) {
function isValidSigningKeyPacket(keyPacket, signature) {
return (keyPacket.algorithm === enums.read(enums.publicKey, enums.publicKey.dsa) ||
keyPacket.algorithm === enums.read(enums.publicKey, enums.publicKey.rsa_sign) ||
keyPacket.algorithm === enums.read(enums.publicKey, enums.publicKey.rsa_encrypt_sign)) &&
keyPacket.algorithm === enums.read(enums.publicKey, enums.publicKey.rsa_encrypt_sign) ||
keyPacket.algorithm === enums.read(enums.publicKey, enums.publicKey.ecdsa)) &&
(!signature.keyFlags ||
(signature.keyFlags[0] & enums.keyFlags.sign_data) !== 0);
}

View File

@ -26,6 +26,7 @@
* @requires enums
* @requires type/keyid
* @requires type/mpi
* @requires type/oid
* @requires util
* @module packet/public_key
*/
@ -35,6 +36,7 @@
import util from '../util.js';
import type_mpi from '../type/mpi.js';
import type_keyid from '../type/keyid.js';
import type_oid from '../type/oid.js';
import enums from '../enums.js';
import crypto from '../crypto';
@ -100,8 +102,11 @@ PublicKey.prototype.read = function (bytes) {
var p = 0;
for (var i = 0; i < mpicount && p < bmpi.length; i++) {
this.mpi[i] = new type_mpi();
if (this.algorithm === 'ecdsa' && i === 0) {
this.mpi[i] = new type_oid();
} else {
this.mpi[i] = new type_mpi();
}
p += this.mpi[i].read(bmpi.subarray(p, bmpi.length));

View File

@ -629,10 +629,10 @@ Signature.prototype.verify = function (key, data) {
if (publicKeyAlgorithm > 0 && publicKeyAlgorithm < 4) {
mpicount = 1;
}
// Algorithm-Specific Fields for DSA signatures:
// Algorithm-Specific Fields for DSA and ECDSA signatures:
// - MPI of DSA value r.
// - MPI of DSA value s.
else if (publicKeyAlgorithm === 17) {
else if (publicKeyAlgorithm === 17 || publicKeyAlgorithm === 19) {
mpicount = 2;
}