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

View File

@ -56,6 +56,15 @@ export default {
m = data; m = data;
var dopublic = dsa.verify(hash_algo, s1, s2, m, p, q, g, y); var dopublic = dsa.verify(hash_algo, s1, s2, m, p, q, g, y);
return dopublic.compareTo(s1) === 0; 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: default:
throw new Error('Invalid signature algorithm.'); throw new Error('Invalid signature algorithm.');
} }
@ -107,6 +116,16 @@ export default {
case 16: case 16:
// Elgamal (Encrypt-Only) [ELGAMAL] [HAC] // Elgamal (Encrypt-Only) [ELGAMAL] [HAC]
throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.'); 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: default:
throw new Error('Invalid signature algorithm.'); throw new Error('Invalid signature algorithm.');
} }

View File

@ -26,7 +26,8 @@ export default {
rsa_encrypt: 2, rsa_encrypt: 2,
rsa_sign: 3, rsa_sign: 3,
elgamal: 16, elgamal: 16,
dsa: 17 dsa: 17,
ecdsa: 19
}, },
/** {@link http://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2} /** {@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) { function isValidSigningKeyPacket(keyPacket, signature) {
return (keyPacket.algorithm === enums.read(enums.publicKey, enums.publicKey.dsa) || 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_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 ||
(signature.keyFlags[0] & enums.keyFlags.sign_data) !== 0); (signature.keyFlags[0] & enums.keyFlags.sign_data) !== 0);
} }

View File

@ -26,6 +26,7 @@
* @requires enums * @requires enums
* @requires type/keyid * @requires type/keyid
* @requires type/mpi * @requires type/mpi
* @requires type/oid
* @requires util * @requires util
* @module packet/public_key * @module packet/public_key
*/ */
@ -35,6 +36,7 @@
import util from '../util.js'; import util from '../util.js';
import type_mpi from '../type/mpi.js'; import type_mpi from '../type/mpi.js';
import type_keyid from '../type/keyid.js'; import type_keyid from '../type/keyid.js';
import type_oid from '../type/oid.js';
import enums from '../enums.js'; import enums from '../enums.js';
import crypto from '../crypto'; import crypto from '../crypto';
@ -100,8 +102,11 @@ PublicKey.prototype.read = function (bytes) {
var p = 0; var p = 0;
for (var i = 0; i < mpicount && p < bmpi.length; i++) { for (var i = 0; i < mpicount && p < bmpi.length; i++) {
if (this.algorithm === 'ecdsa' && i === 0) {
this.mpi[i] = new type_mpi(); this.mpi[i] = new type_oid();
} else {
this.mpi[i] = new type_mpi();
}
p += this.mpi[i].read(bmpi.subarray(p, bmpi.length)); 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) { if (publicKeyAlgorithm > 0 && publicKeyAlgorithm < 4) {
mpicount = 1; 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 r.
// - MPI of DSA value s. // - MPI of DSA value s.
else if (publicKeyAlgorithm === 17) { else if (publicKeyAlgorithm === 17 || publicKeyAlgorithm === 19) {
mpicount = 2; mpicount = 2;
} }