This commit is contained in:
Sanjana Rajan 2018-01-19 13:02:00 +01:00
parent 5cb89f4f25
commit 3ce6309788
6 changed files with 40 additions and 67 deletions

View File

@ -38,29 +38,15 @@ import type_kdf_params from '../type/kdf_params.js';
import type_mpi from '../type/mpi.js';
import type_oid from '../type/oid.js';
function createType(data, type) {
switch(type) {
case 'mpi':
return new type_mpi(data);
case 'oid':
return new type_oid(data);
case 'kdf':
if (data) {
return new type_kdf_params(data[0], data[1]);
}
return new type_kdf_params();
case 'ecdh_symkey':
return new type_ecdh_symkey(data);
default:
throw new Error('Unknown type.');
}
}
function constructParams(result, types) {
for (var i=0; i < types.length; i++) {
result[i] = createType(result[i], types[i]);
}
return result;
function constructParams(types, data) {
return types.map(function(type, i) {
if (data && data[i]) {
return new type(data[i]);
} else {
return new type();
}
});
}
export default {
@ -83,7 +69,7 @@ export default {
var n = publicParams[0].toBigInteger();
var e = publicParams[1].toBigInteger();
m = data.toBigInteger();
return constructParams([rsa.encrypt(m, e, n)], types);
return constructParams(types, [rsa.encrypt(m, e, n)]);
case 'elgamal':
var elgamal = new publicKey.elgamal();
@ -91,7 +77,7 @@ export default {
var g = publicParams[1].toBigInteger();
var y = publicParams[2].toBigInteger();
m = data.toBigInteger();
return constructParams(elgamal.encrypt(m, g, p, y), types);
return constructParams(types, elgamal.encrypt(m, g, p, y));
case 'ecdh':
var ecdh = publicKey.elliptic.ecdh;
@ -101,7 +87,7 @@ export default {
var res = await ecdh.encrypt(
curve.oid, kdf_params.cipher, kdf_params.hash, data, R, fingerprint
);
return constructParams([res.V, res.C], types);
return constructParams(types, [res.V, res.C]);
default:
return [];
@ -172,21 +158,21 @@ export default {
// - MPI of RSA secret prime value p.
// - MPI of RSA secret prime value q (p < q).
// - MPI of u, the multiplicative inverse of p, mod q.
return ['mpi', 'mpi', 'mpi', 'mpi'];
return [type_mpi, type_mpi, type_mpi, type_mpi];
case 'elgamal':
// Algorithm-Specific Fields for Elgamal secret keys:
// - MPI of Elgamal secret exponent x.
return ['mpi'];
return [type_mpi];
case 'dsa':
// Algorithm-Specific Fields for DSA secret keys:
// - MPI of DSA secret exponent x.
return ['mpi'];
return [type_mpi];
case 'ecdh':
case 'ecdsa':
case 'eddsa':
// Algorithm-Specific Fields for ECDSA or ECDH secret keys:
// - MPI of an integer representing the secret key.
return ['mpi'];
return [type_mpi];
default:
throw new Error('Unknown algorithm');
}
@ -204,32 +190,32 @@ export default {
case 'rsa_encrypt':
case 'rsa_encrypt_sign':
case 'rsa_sign':
return ['mpi', 'mpi'];
return [type_mpi, type_mpi];
// Algorithm-Specific Fields for Elgamal public keys:
// - MPI of Elgamal prime p;
// - MPI of Elgamal group generator g;
// - MPI of Elgamal public key value y (= g**x mod p where x is secret).
case 'elgamal':
return ['mpi', 'mpi', 'mpi'];
return [type_mpi, type_mpi, type_mpi];
// Algorithm-Specific Fields for DSA public keys:
// - MPI of DSA prime p;
// - MPI of DSA group order q (q is a prime divisor of p-1);
// - MPI of DSA group generator g;
// - MPI of DSA public-key value y (= g**x mod p where x is secret).
case 'dsa':
return ['mpi', 'mpi', 'mpi', 'mpi'];
return [type_mpi, type_mpi, type_mpi, type_mpi];
// Algorithm-Specific Fields for ECDSA/EdDSA public keys:
// - OID of curve;
// - MPI of EC point representing public key.
case 'ecdsa':
case 'eddsa':
return ['oid', 'mpi'];
return [type_oid, type_mpi];
// Algorithm-Specific Fields for ECDH public keys:
// - OID of curve;
// - MPI of EC point representing public key.
// - KDF: variable-length field containing KDF parameters.
case 'ecdh':
return ['oid', 'mpi', 'kdf'];
return [type_oid, type_mpi, type_kdf_params];
default:
throw new Error('Unknown algorithm.');
}
@ -245,19 +231,19 @@ export default {
// - MPI of RSA encrypted value m**e mod n.
case 'rsa_encrypt':
case 'rsa_encrypt_sign':
return ['mpi'];
return [type_mpi];
// Algorithm-Specific Fields for Elgamal encrypted session keys:
// - MPI of Elgamal value g**k mod p
// - MPI of Elgamal value m * y**k mod p
case 'elgamal':
return ['mpi', 'mpi'];
return [type_mpi, type_mpi];
// Algorithm-Specific Fields for ECDH encrypted session keys:
// - MPI containing the ephemeral key used to establish the shared secret
// - ECDH Symmetric Key
case 'ecdh':
return ['mpi', 'ecdh_symkey'];
return [type_mpi, type_ecdh_symkey];
default:
throw new Error('Unknown algorithm.');
@ -277,18 +263,18 @@ export default {
//remember "publicKey" refers to the crypto/public_key dir
var rsa = new publicKey.rsa();
return rsa.generate(bits, "10001").then(function(keyObject) {
return constructParams([keyObject.n, keyObject.ee, keyObject.d, keyObject.p, keyObject.q, keyObject.u], types);
return constructParams(types, [keyObject.n, keyObject.ee, keyObject.d, keyObject.p, keyObject.q, keyObject.u]);
});
case 'ecdsa':
case 'eddsa':
return publicKey.elliptic.generate(curve).then(function (keyObject) {
return constructParams([keyObject.oid, keyObject.Q, keyObject.d], types);
return constructParams(types, [keyObject.oid, keyObject.Q, keyObject.d]);
});
case 'ecdh':
return publicKey.elliptic.generate(curve).then(function (keyObject) {
return constructParams([keyObject.oid, keyObject.Q, [keyObject.hash, keyObject.cipher], keyObject.d], types);
return constructParams(types, [keyObject.oid, keyObject.Q, [keyObject.hash, keyObject.cipher], keyObject.d]);
});
default:
@ -296,22 +282,6 @@ export default {
}
},
getCloneFn: function(type) {
switch(type) {
case 'mpi':
return type_mpi.fromClone;
case 'oid':
return type_oid.fromClone;
case 'kdf':
return type_kdf_params.fromClone;
case 'ecdh_symkey':
return type_ecdh_symkey.fromClone;
default:
throw new Error('Unknown type.');
}
},
/**
* generate random byte prefix as string for the specified algorithm
* @param {module:enums.symmetric} algo Algorithm to use (see {@link http://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2})

View File

@ -46,7 +46,7 @@ import type_oid from '../../../type/oid.js';
// Build Param for ECDH algorithm (RFC 6637)
function buildEcdhParam(public_algo, oid, cipher_algo, hash_algo, fingerprint) {
oid = new type_oid(oid);
const kdf_params = new type_kdf_params(hash_algo, cipher_algo);
const kdf_params = new type_kdf_params([hash_algo, cipher_algo]);
return util.concatUint8Array([
oid.write(),
new Uint8Array([public_algo]),

View File

@ -94,7 +94,7 @@ PublicKey.prototype.read = function (bytes) {
this.algorithm = enums.read(enums.publicKey, bytes[pos++]);
var types = crypto.getPubKeyParamTypes(this.algorithm);
this.params = crypto.constructParams(new Array(types.length), types);
this.params = crypto.constructParams(types);
var b = bytes.subarray(pos, bytes.length);
var p = 0;
@ -214,8 +214,7 @@ PublicKey.prototype.postCloneTypeFix = function() {
const types = crypto.getPubKeyParamTypes(this.algorithm);
for (var i = 0; i < types.length; i++) {
const param = this.params[i];
const cloneFn = crypto.getCloneFn(types[i]);
this.params[i] = cloneFn(param);
this.params[i] = types[i].fromClone(param);
}
if (this.keyid) {
this.keyid = type_keyid.fromClone(this.keyid);

View File

@ -79,7 +79,7 @@ PublicKeyEncryptedSessionKey.prototype.read = function (bytes) {
var i = 10;
var types = crypto.getEncSessionKeyParamTypes(this.publicKeyAlgorithm);
this.encrypted = crypto.constructParams(new Array(types.length), types);
this.encrypted = crypto.constructParams(types);
for (var j = 0; j < types.length; j++) {
i += this.encrypted[j].read(bytes.subarray(i, bytes.length));

View File

@ -89,7 +89,7 @@ function parse_cleartext_params(hash_algorithm, cleartext, algorithm) {
}
var types = crypto.getPrivKeyParamTypes(algorithm);
var params = crypto.constructParams(new Array(types.length), types);
var params = crypto.constructParams(types);
var p = 0;
for (var i = 0; i < types.length && p < cleartext.length; i++) {
@ -298,8 +298,7 @@ SecretKey.prototype.clearPrivateParams = function () {
const types = crypto.getPubKeyParamTypes(this.algorithm).concat(crypto.getPrivKeyParamTypes(this.algorithm));
for (var i = 0; i < this.params.length; i++) {
const param = this.params[i];
const cloneFn = crypto.getCloneFn(types[i]);
this.params[i] = cloneFn(param);
this.params[i] = types[i].fromClone(param);
}
if (this.keyid) {
this.keyid = type_keyid.fromClone(this.keyid);

View File

@ -33,9 +33,14 @@ module.exports = KDFParams;
* @param {enums.hash} hash Hash algorithm
* @param {enums.symmetric} cipher Symmetric algorithm
*/
function KDFParams(hash, cipher) {
this.hash = hash || enums.hash.sha1;
this.cipher = cipher || enums.symmetric.aes128;
function KDFParams(data) {
if (data && data.length === 2) {
this.hash = data[0];
this.cipher = data[1];
} else {
this.hash = enums.hash.sha1;
this.cipher = enums.symmetric.aes128;
}
}
/**