simplify packet parsing using type maps

This commit is contained in:
Sanjana Rajan 2017-07-27 00:59:21 +02:00
parent cdc7004b96
commit b718cf359d
9 changed files with 58 additions and 74 deletions

View File

@ -53,8 +53,8 @@ function createType(data, type) {
}
}
function mapResult(result, types) {
for (var i=0; i < result.length; i++) {
function constructParams(result, types) {
for (var i=0; i < types.length; i++) {
result[i] = createType(result[i], types[i]);
}
return result;
@ -81,7 +81,7 @@ export default {
var n = publicParams[0].toBigInteger();
var e = publicParams[1].toBigInteger();
m = data.toBigInteger();
return mapResult([rsa.encrypt(m, e, n)], types);
return constructParams([rsa.encrypt(m, e, n)], types);
case 'elgamal':
var elgamal = new publicKey.elgamal();
@ -89,7 +89,7 @@ export default {
var g = publicParams[1].toBigInteger();
var y = publicParams[2].toBigInteger();
m = data.toBigInteger();
return mapResult(elgamal.encrypt(m, g, p, y), types);
return constructParams(elgamal.encrypt(m, g, p, y), types);
case 'ecdh':
var ecdh = publicKey.elliptic.ecdh;
@ -97,7 +97,7 @@ export default {
var kdf_params = publicParams[2];
var R = publicParams[1].toBigInteger();
var res = ecdh.encrypt(curve.oid, kdf_params.cipher, kdf_params.hash, data, R, fingerprint);
return mapResult([res.V, res.C], types);
return constructParams([res.V, res.C], types);
default:
return [];
@ -258,7 +258,7 @@ export default {
// Algorithm-Specific Fields for ECDH encrypted session keys:
// - MPI containing the ephemeral key used to establish the shared secret
// - EcdhSymmetricKey
// - ECDHSymmetricKey
case 'ecdh':
return ['mpi', 'ecdh_symkey'];
@ -280,17 +280,17 @@ 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 mapResult([keyObject.n, keyObject.ee, keyObject.d, keyObject.p, keyObject.q, keyObject.u], types);
return constructParams([keyObject.n, keyObject.ee, keyObject.d, keyObject.p, keyObject.q, keyObject.u], types);
});
case 'ecdsa':
return publicKey.elliptic.generate(curve).then(function (keyObject) {
return mapResult([keyObject.oid, keyObject.R, keyObject.r], types);
return constructParams([keyObject.oid, keyObject.R, keyObject.r], types);
});
case 'ecdh':
return publicKey.elliptic.generate(curve).then(function (keyObject) {
return mapResult([keyObject.oid, keyObject.R, [keyObject.hash, keyObject.cipher], keyObject.r], types);
return constructParams([keyObject.oid, keyObject.R, [keyObject.hash, keyObject.cipher], keyObject.r], types);
});
default:
@ -316,5 +316,7 @@ export default {
*/
generateSessionKey: function(algo) {
return random.getRandomBytes(cipher[algo].keySize);
}
},
constructParams: constructParams
};

View File

@ -69,7 +69,7 @@ function kdf(hash_algo, X, length, param) {
/**
* Encrypt and wrap a session key
*
* @param {String} oid Oid of the curve to use
* @param {String} oid OID of the curve to use
* @param {Enums} cipher_algo Symmetric cipher to use
* @param {Enums} hash_algo Hash to use
* @param {Uint8Array} m Value derived from session key (RFC 6637)
@ -96,7 +96,7 @@ function encrypt(oid, cipher_algo, hash_algo, m, R, fingerprint) {
/**
* Decrypt and unwrap the value derived from session key
*
* @param {String} oid Curve oid
* @param {String} oid Curve OID
* @param {Enums} cipher_algo Symmetric cipher to use
* @param {Enums} hash_algo Hash algorithm to use
* @param {BigInteger} V Public part of ephemeral key

View File

@ -79,21 +79,21 @@ export { default as Keyid } from './type/keyid';
/**
* @see module:type/ecdh_symkey
* @name module:openpgp.EcdhSymmetricKey
* @name module:openpgp.ECDHSymmetricKey
*/
export { default as EcdhSymmetricKey } from './type/ecdh_symkey';
export { default as ECDHSymmetricKey } from './type/ecdh_symkey';
/**
* @see module:type/kdf_params
* @name module:openpgp.KdfParams
* @name module:openpgp.KDFParams
*/
export { default as KdfParams } from './type/kdf_params';
export { default as KDFParams } from './type/kdf_params';
/**
* @see module:type/oid
* @name module:openpgp.Oid
* @name module:openpgp.OID
*/
export { default as Oid } from './type/oid';
export { default as OID } from './type/oid';
/**
* @see module:encoding/armor

View File

@ -93,24 +93,15 @@ PublicKey.prototype.read = function (bytes) {
// - A one-octet number denoting the public-key algorithm of this key.
this.algorithm = enums.read(enums.publicKey, bytes[pos++]);
var param_count = crypto.getPubKeyParamCount(this.algorithm);
this.params = [];
var types = crypto.getPubKeyParamTypes(this.algorithm);
this.params = crypto.constructParams(new Array(types.length), types);
var bmpi = bytes.subarray(pos, bytes.length);
var b = bytes.subarray(pos, bytes.length);
var p = 0;
for (var i = 0; i < param_count && p < bmpi.length; i++) {
if ((this.algorithm === 'ecdsa' || this.algorithm === 'ecdh') && i === 0) {
this.params[i] = new type_oid();
} else if (this.algorithm === 'ecdh' && i === 2) {
this.params[i] = new type_kdf_params();
} else {
this.params[i] = new type_mpi();
}
p += this.params[i].read(bmpi.subarray(p, bmpi.length));
if (p > bmpi.length) {
for (var i = 0; i < types.length && p < b.length; i++) {
p += this.params[i].read(b.subarray(p, b.length));
if (p > b.length) {
throw new Error('Error reading MPI @:' + p);
}
}

View File

@ -78,20 +78,11 @@ PublicKeyEncryptedSessionKey.prototype.read = function (bytes) {
var i = 10;
var integerCount = crypto.getEncSessionKeyParamCount(this.publicKeyAlgorithm);
var types = crypto.getEncSessionKeyParamTypes(this.publicKeyAlgorithm);
this.encrypted = crypto.constructParams(new Array(types.length), types);
this.encrypted = [];
for (var j = 0; j < integerCount; j++) {
var param;
if (this.publicKeyAlgorithm === 'ecdh' && j === 1) {
param = new type_ecdh_symkey();
} else {
param = new type_mpi();
}
i += param.read(bytes.subarray(i, bytes.length));
this.encrypted.push(param);
for (var j = 0; j < types.length; j++) {
i += this.encrypted[j].read(bytes.subarray(i, bytes.length));
}
};

View File

@ -26,12 +26,12 @@
import util from '../util.js';
module.exports = EcdhSymmetricKey;
module.exports = ECDHSymmetricKey;
/**
* @constructor
*/
function EcdhSymmetricKey(data) {
function ECDHSymmetricKey(data) {
if (typeof data === 'undefined') {
data = new Uint8Array([]);
} else if (typeof data === 'string') {
@ -43,11 +43,11 @@ function EcdhSymmetricKey(data) {
}
/**
* Read an EcdhSymmetricKey from an Uint8Array
* Read an ECDHSymmetricKey from an Uint8Array
* @param {Uint8Array} input Where to read the encoded symmetric key from
* @return {Number} Number of read bytes
*/
EcdhSymmetricKey.prototype.read = function (input) {
ECDHSymmetricKey.prototype.read = function (input) {
if (input.length >= 1)
{
var length = input[0];
@ -61,10 +61,10 @@ EcdhSymmetricKey.prototype.read = function (input) {
};
/**
* Write an EcdhSymmetricKey as an Uint8Array
* Write an ECDHSymmetricKey as an Uint8Array
* @return {Uint8Array} An array containing the value
*/
EcdhSymmetricKey.prototype.write = function () {
ECDHSymmetricKey.prototype.write = function () {
return util.concatUint8Array([
new Uint8Array([this.data.length]),
this.data]);

View File

@ -26,26 +26,26 @@
import enums from '../enums.js';
module.exports = KdfParams;
module.exports = KDFParams;
/**
* @constructor
* @param {enums.hash} hash Hash algorithm
* @param {enums.symmetric} cipher Symmetric algorithm
*/
function KdfParams(hash, cipher) {
function KDFParams(hash, cipher) {
this.hash = hash || enums.hash.sha1;
this.cipher = cipher || enums.symmetric.aes128;
}
/**
* Read KdfParams from an Uint8Array
* @param {Uint8Array} input Where to read the KdfParams from
* Read KDFParams from an Uint8Array
* @param {Uint8Array} input Where to read the KDFParams from
* @return {Number} Number of read bytes
*/
KdfParams.prototype.read = function (input) {
KDFParams.prototype.read = function (input) {
if (input.length < 4 || input[0] !== 3 || input[1] !== 1) {
throw new Error('Cannot read KdfParams');
throw new Error('Cannot read KDFParams');
}
this.hash = input[2];
this.cipher = input[3];
@ -53,9 +53,9 @@ KdfParams.prototype.read = function (input) {
};
/**
* Write KdfParams to an Uint8Array
* @return {Uint8Array} Array with the KdfParams value
* Write KDFParams to an Uint8Array
* @return {Uint8Array} Array with the KDFParams value
*/
KdfParams.prototype.write = function () {
KDFParams.prototype.write = function () {
return new Uint8Array([3, 1, this.hash, this.cipher]);
};

View File

@ -16,7 +16,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* Wrapper to an Oid value<br/>
* Wrapper to an OID value<br/>
* <br/>
* An object identifier type from {@link https://tools.ietf.org/html/rfc6637#section-11|RFC6637, section 11}.
* @requires util
@ -27,12 +27,12 @@
import util from '../util.js';
module.exports = Oid;
module.exports = OID;
/**
* @constructor
*/
function Oid(oid) {
function OID(oid) {
if (typeof oid === 'undefined') {
oid = '';
} else if (util.isArray(oid)) {
@ -44,11 +44,11 @@ function Oid(oid) {
}
/**
* Method to read an Oid object
* @param {Uint8Array} input Where to read the Oid from
* Method to read an OID object
* @param {Uint8Array} input Where to read the OID from
* @return {Number} Number of read bytes
*/
Oid.prototype.read = function (input) {
OID.prototype.read = function (input) {
if (input.length >= 1) {
var length = input[0];
if (input.length >= 1+length) {
@ -60,10 +60,10 @@ Oid.prototype.read = function (input) {
};
/**
* Serialize an Oid object
* @return {Uint8Array} Array with the serialized value the Oid
* Serialize an OID object
* @return {Uint8Array} Array with the serialized value the OID
*/
Oid.prototype.write = function () {
OID.prototype.write = function () {
return util.str2Uint8Array(
String.fromCharCode(this.oid.length)+this.oid);
};

View File

@ -5,14 +5,14 @@ var openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp :
var expect = require('chai').expect;
describe('Oid tests', function() {
var Oid = openpgp.Oid;
var OID = openpgp.OID;
var p256_oid = new Uint8Array([0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07]);
var p384_oid = new Uint8Array([0x2B, 0x81, 0x04, 0x00, 0x22]);
var p521_oid = new Uint8Array([0x2B, 0x81, 0x04, 0x00, 0x23]);
it('Constructing', function() {
var oids = [p256_oid, p384_oid, p521_oid];
oids.forEach(function (data) {
var oid = new Oid(data);
var oid = new OID(data);
expect(oid).to.exist;
expect(oid.oid).to.exist;
expect(oid.oid).to.have.length(data.length);
@ -22,8 +22,8 @@ describe('Oid tests', function() {
it('Reading and writing', function() {
var oids = [p256_oid, p384_oid, p521_oid];
oids.forEach(function (data) {
data = openpgp.util.concatUint8Array([new Uint8Array([data.length]), data]);
var oid = new Oid();
data = openpgp.util.concatUint8Array([new Uint8Array([data.length]), data]);
var oid = new OID();
expect(oid.read(data)).to.equal(data.length);
expect(oid.oid).to.exist;
expect(oid.oid).to.have.length(data.length-1);