refactor mpi, generalize mpi to params to account for non-mpi algorithm-specific data
This commit is contained in:
parent
840c0229f8
commit
cdc7004b96
|
@ -38,14 +38,26 @@ import type_kdf_params from '../type/kdf_params.js';
|
|||
import type_mpi from '../type/mpi.js';
|
||||
import type_oid from '../type/oid.js';
|
||||
|
||||
function BigInteger2mpi(bn) {
|
||||
var mpi = new type_mpi();
|
||||
mpi.fromBigInteger(bn);
|
||||
return mpi;
|
||||
function createType(data, type) {
|
||||
switch(type) {
|
||||
case 'mpi':
|
||||
return new type_mpi(data);
|
||||
case 'oid':
|
||||
return new type_oid(data);
|
||||
case 'kdf':
|
||||
return new type_kdf_params(data);
|
||||
case 'ecdh_symkey':
|
||||
return new type_ecdh_symkey(data);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function mapResult(result) {
|
||||
return result.map(BigInteger2mpi);
|
||||
function mapResult(result, types) {
|
||||
for (var i=0; i < result.length; i++) {
|
||||
result[i] = createType(result[i], types[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export default {
|
||||
|
@ -53,38 +65,39 @@ export default {
|
|||
* Encrypts data using the specified public key multiprecision integers
|
||||
* and the specified algorithm.
|
||||
* @param {module:enums.publicKey} algo Algorithm to be used (See {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1})
|
||||
* @param {Array<module:type/mpi>} publicMPIs Algorithm dependent multiprecision integers
|
||||
* @param {Array<module:type/mpi>} publicParams Algorithm dependent multiprecision integers
|
||||
* @param {module:type/mpi} data Data to be encrypted as MPI
|
||||
* @return {Array<module:type/mpi>} if RSA an module:type/mpi;
|
||||
* if elgamal encryption an array of two module:type/mpi is returned; otherwise null
|
||||
*/
|
||||
publicKeyEncrypt: function(algo, publicMPIs, data, fingerprint) {
|
||||
publicKeyEncrypt: function(algo, publicParams, data, fingerprint) {
|
||||
var types = this.getEncSessionKeyParamTypes(algo);
|
||||
var result = (function() {
|
||||
var m;
|
||||
switch (algo) {
|
||||
case 'rsa_encrypt':
|
||||
case 'rsa_encrypt_sign':
|
||||
var rsa = new publicKey.rsa();
|
||||
var n = publicMPIs[0].toBigInteger();
|
||||
var e = publicMPIs[1].toBigInteger();
|
||||
var n = publicParams[0].toBigInteger();
|
||||
var e = publicParams[1].toBigInteger();
|
||||
m = data.toBigInteger();
|
||||
return mapResult([rsa.encrypt(m, e, n)]);
|
||||
return mapResult([rsa.encrypt(m, e, n)], types);
|
||||
|
||||
case 'elgamal':
|
||||
var elgamal = new publicKey.elgamal();
|
||||
var p = publicMPIs[0].toBigInteger();
|
||||
var g = publicMPIs[1].toBigInteger();
|
||||
var y = publicMPIs[2].toBigInteger();
|
||||
var p = publicParams[0].toBigInteger();
|
||||
var g = publicParams[1].toBigInteger();
|
||||
var y = publicParams[2].toBigInteger();
|
||||
m = data.toBigInteger();
|
||||
return mapResult(elgamal.encrypt(m, g, p, y));
|
||||
return mapResult(elgamal.encrypt(m, g, p, y), types);
|
||||
|
||||
case 'ecdh':
|
||||
var ecdh = publicKey.elliptic.ecdh;
|
||||
var curve = publicMPIs[0];
|
||||
var kdf_params = publicMPIs[2];
|
||||
var R = publicMPIs[1].toBigInteger();
|
||||
var curve = publicParams[0];
|
||||
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 [BigInteger2mpi(res.V), new type_ecdh_symkey(res.C)];
|
||||
return mapResult([res.V, res.C], types);
|
||||
|
||||
default:
|
||||
return [];
|
||||
|
@ -98,7 +111,7 @@ export default {
|
|||
* Decrypts data using the specified public key multiprecision integers of the private key,
|
||||
* the specified secretMPIs of the private key and the specified algorithm.
|
||||
* @param {module:enums.publicKey} algo Algorithm to be used (See {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1})
|
||||
* @param {Array<module:type/mpi>} publicMPIs Algorithm dependent multiprecision integers
|
||||
* @param {Array<module:type/mpi>} publicParams Algorithm dependent multiprecision integers
|
||||
* of the public key part of the private key
|
||||
* @param {Array<module:type/mpi>} secretMPIs Algorithm dependent multiprecision integers
|
||||
* of the private key used
|
||||
|
@ -146,8 +159,7 @@ export default {
|
|||
}
|
||||
})();
|
||||
|
||||
var result = new type_mpi();
|
||||
result.fromBigInteger(bn);
|
||||
var result = new type_mpi(bn);
|
||||
return result;
|
||||
},
|
||||
|
||||
|
@ -155,7 +167,7 @@ export default {
|
|||
* @param {String} algo The public key algorithm
|
||||
* @return {Integer} The number of integers.
|
||||
*/
|
||||
getPrivateMpiCount: function(algo) {
|
||||
getPrivKeyParamTypes: function(algo) {
|
||||
switch (algo) {
|
||||
case 'rsa_encrypt':
|
||||
case 'rsa_encrypt_sign':
|
||||
|
@ -165,27 +177,30 @@ 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 4;
|
||||
return ['mpi', 'mpi', 'mpi', 'mpi'];
|
||||
case 'elgamal':
|
||||
// Algorithm-Specific Fields for Elgamal secret keys:
|
||||
// - MPI of Elgamal secret exponent x.
|
||||
return 1;
|
||||
return ['mpi'];
|
||||
case 'dsa':
|
||||
// Algorithm-Specific Fields for DSA secret keys:
|
||||
// - MPI of DSA secret exponent x.
|
||||
return 1;
|
||||
return ['mpi'];
|
||||
case 'ecdh':
|
||||
case 'ecdsa':
|
||||
// Algorithm-Specific Fields for ECDSA or ECDH secret keys:
|
||||
// - MPI of an integer representing the secret key.
|
||||
return 1;
|
||||
return ['mpi'];
|
||||
default:
|
||||
throw new Error('Unknown algorithm');
|
||||
}
|
||||
},
|
||||
|
||||
getPublicMpiCount: function(algo) {
|
||||
// - A series of multiprecision integers comprising the key material:
|
||||
getPrivKeyParamCount: function(algo) {
|
||||
return this.getPrivKeyParamTypes(algo).length;
|
||||
},
|
||||
|
||||
getPubKeyParamTypes: function(algo) {
|
||||
// Algorithm-Specific Fields for RSA public keys:
|
||||
// - a multiprecision integer (MPI) of RSA public modulus n;
|
||||
// - an MPI of RSA public encryption exponent e.
|
||||
|
@ -193,42 +208,71 @@ export default {
|
|||
case 'rsa_encrypt':
|
||||
case 'rsa_encrypt_sign':
|
||||
case 'rsa_sign':
|
||||
return 2;
|
||||
|
||||
return ['mpi', '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 3;
|
||||
|
||||
return ['mpi', 'mpi', '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 4;
|
||||
|
||||
return ['mpi', 'mpi', 'mpi', 'mpi'];
|
||||
// Algorithm-Specific Fields for ECDSA public keys:
|
||||
// - OID of curve;
|
||||
// - MPI of EC point representing public key.
|
||||
case 'ecdsa':
|
||||
return 2;
|
||||
|
||||
return ['oid', 'mpi'];
|
||||
// Algorithm-Specific Fields for ECDH public keys:
|
||||
// - OID of curve;
|
||||
// - MPI of EC point representing public key.
|
||||
// - variable-length field containing KDF parameters.
|
||||
case 'ecdh':
|
||||
return 3;
|
||||
return ['oid', 'mpi', 'kdf'];
|
||||
default:
|
||||
throw new Error('Unknown algorithm.');
|
||||
}
|
||||
},
|
||||
|
||||
getPubKeyParamCount: function(algo) {
|
||||
return this.getPubKeyParamTypes(algo).length;
|
||||
},
|
||||
|
||||
getEncSessionKeyParamTypes: function(algo) {
|
||||
switch (algo) {
|
||||
// Algorithm-Specific Fields for RSA encrypted session keys:
|
||||
// - MPI of RSA encrypted value m**e mod n.
|
||||
case 'rsa_encrypt':
|
||||
case 'rsa_encrypt_sign':
|
||||
return ['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'];
|
||||
|
||||
// Algorithm-Specific Fields for ECDH encrypted session keys:
|
||||
// - MPI containing the ephemeral key used to establish the shared secret
|
||||
// - EcdhSymmetricKey
|
||||
case 'ecdh':
|
||||
return ['mpi', 'ecdh_symkey'];
|
||||
|
||||
default:
|
||||
throw new Error('Unknown algorithm.');
|
||||
}
|
||||
},
|
||||
|
||||
generateMpi: function(algo, bits, curve) {
|
||||
getEncSessionKeyParamCount: function(algo) {
|
||||
return this.getEncSessionKeyParamTypes(algo).length;
|
||||
},
|
||||
|
||||
generateParams: function(algo, bits, curve) {
|
||||
var types = this.getPubKeyParamTypes(algo).concat(this.getPrivKeyParamTypes(algo));
|
||||
switch (algo) {
|
||||
case 'rsa_encrypt':
|
||||
case 'rsa_encrypt_sign':
|
||||
|
@ -236,33 +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) {
|
||||
var output = [];
|
||||
output.push(keyObject.n);
|
||||
output.push(keyObject.ee);
|
||||
output.push(keyObject.d);
|
||||
output.push(keyObject.p);
|
||||
output.push(keyObject.q);
|
||||
output.push(keyObject.u);
|
||||
return mapResult(output);
|
||||
return mapResult([keyObject.n, keyObject.ee, keyObject.d, keyObject.p, keyObject.q, keyObject.u], types);
|
||||
});
|
||||
|
||||
case 'ecdsa':
|
||||
return publicKey.elliptic.generate(curve).then(function (keyObject) {
|
||||
return [
|
||||
new type_oid(keyObject.oid),
|
||||
BigInteger2mpi(keyObject.R),
|
||||
BigInteger2mpi(keyObject.r)
|
||||
];
|
||||
return mapResult([keyObject.oid, keyObject.R, keyObject.r], types);
|
||||
});
|
||||
|
||||
case 'ecdh':
|
||||
return publicKey.elliptic.generate(curve).then(function (keyObject) {
|
||||
return [
|
||||
new type_oid(keyObject.oid),
|
||||
BigInteger2mpi(keyObject.R),
|
||||
new type_kdf_params(keyObject.hash, keyObject.cipher),
|
||||
BigInteger2mpi(keyObject.r)
|
||||
];
|
||||
return mapResult([keyObject.oid, keyObject.R, [keyObject.hash, keyObject.cipher], keyObject.r], types);
|
||||
});
|
||||
|
||||
default:
|
||||
|
|
|
@ -113,8 +113,7 @@ export default {
|
|||
randomBits.charCodeAt(0)) +
|
||||
randomBits.substring(1);
|
||||
}
|
||||
var mpi = new type_mpi();
|
||||
mpi.fromBytes(randomBits);
|
||||
var mpi = new type_mpi(randomBits);
|
||||
return mpi.toBigInteger();
|
||||
},
|
||||
|
||||
|
|
|
@ -380,7 +380,7 @@ Key.prototype.encrypt = function(passphrase) {
|
|||
var keys = this.getAllKeyPackets();
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
keys[i].encrypt(passphrase);
|
||||
keys[i].clearPrivateMPIs();
|
||||
keys[i].clearPrivateParams();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1279,8 +1279,8 @@ function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) {
|
|||
packetlist.push(subkeySignaturePacket);
|
||||
|
||||
if (!options.unlocked) {
|
||||
secretKeyPacket.clearPrivateMPIs();
|
||||
secretSubkeyPacket.clearPrivateMPIs();
|
||||
secretKeyPacket.clearPrivateParams();
|
||||
secretSubkeyPacket.clearPrivateParams();
|
||||
}
|
||||
|
||||
return new Key(packetlist);
|
||||
|
|
|
@ -51,12 +51,8 @@ export default function PublicKey() {
|
|||
/** Key creation date.
|
||||
* @type {Date} */
|
||||
this.created = new Date();
|
||||
/** A list of multiprecision integers
|
||||
* @type {module:type/mpi} */
|
||||
this.mpi = [];
|
||||
/** Public key algorithm
|
||||
* @type {module:enums.publicKey} */
|
||||
this.algorithm = 'rsa_sign';
|
||||
/* Algorithm specific params */
|
||||
this.params = [];
|
||||
// time in days (V3 only)
|
||||
this.expirationTimeV3 = 0;
|
||||
/**
|
||||
|
@ -97,22 +93,22 @@ 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 mpicount = crypto.getPublicMpiCount(this.algorithm);
|
||||
this.mpi = [];
|
||||
var param_count = crypto.getPubKeyParamCount(this.algorithm);
|
||||
this.params = [];
|
||||
|
||||
var bmpi = bytes.subarray(pos, bytes.length);
|
||||
var p = 0;
|
||||
|
||||
for (var i = 0; i < mpicount && p < bmpi.length; i++) {
|
||||
for (var i = 0; i < param_count && p < bmpi.length; i++) {
|
||||
if ((this.algorithm === 'ecdsa' || this.algorithm === 'ecdh') && i === 0) {
|
||||
this.mpi[i] = new type_oid();
|
||||
this.params[i] = new type_oid();
|
||||
} else if (this.algorithm === 'ecdh' && i === 2) {
|
||||
this.mpi[i] = new type_kdf_params();
|
||||
this.params[i] = new type_kdf_params();
|
||||
} else {
|
||||
this.mpi[i] = new type_mpi();
|
||||
this.params[i] = new type_mpi();
|
||||
}
|
||||
|
||||
p += this.mpi[i].read(bmpi.subarray(p, bmpi.length));
|
||||
p += this.params[i].read(bmpi.subarray(p, bmpi.length));
|
||||
|
||||
if (p > bmpi.length) {
|
||||
throw new Error('Error reading MPI @:' + p);
|
||||
|
@ -147,10 +143,10 @@ PublicKey.prototype.write = function () {
|
|||
}
|
||||
arr.push(new Uint8Array([enums.write(enums.publicKey, this.algorithm)]));
|
||||
|
||||
var mpicount = crypto.getPublicMpiCount(this.algorithm);
|
||||
var param_count = crypto.getPubKeyParamCount(this.algorithm);
|
||||
|
||||
for (var i = 0; i < mpicount; i++) {
|
||||
arr.push(this.mpi[i].write());
|
||||
for (var i = 0; i < param_count; i++) {
|
||||
arr.push(this.params[i].write());
|
||||
}
|
||||
|
||||
return util.concatUint8Array(arr);
|
||||
|
@ -183,7 +179,7 @@ PublicKey.prototype.getKeyId = function () {
|
|||
if (this.version === 4) {
|
||||
this.keyid.read(util.str2Uint8Array(util.hex2bin(this.getFingerprint()).substr(12, 8)));
|
||||
} else if (this.version === 3) {
|
||||
var arr = this.mpi[0].write();
|
||||
var arr = this.params[0].write();
|
||||
this.keyid.read(arr.subarray(arr.length - 8, arr.length));
|
||||
}
|
||||
return this.keyid;
|
||||
|
@ -202,9 +198,9 @@ PublicKey.prototype.getFingerprint = function () {
|
|||
toHash = this.writeOld();
|
||||
this.fingerprint = util.Uint8Array2str(crypto.hash.sha1(toHash));
|
||||
} else if (this.version === 3) {
|
||||
var mpicount = crypto.getPublicMpiCount(this.algorithm);
|
||||
for (var i = 0; i < mpicount; i++) {
|
||||
toHash += this.mpi[i].toBytes();
|
||||
var param_count = crypto.getPubKeyParamCount(this.algorithm);
|
||||
for (var i = 0; i < param_count; i++) {
|
||||
toHash += this.params[i].toBytes();
|
||||
}
|
||||
this.fingerprint = util.Uint8Array2str(crypto.hash.md5(util.str2Uint8Array(toHash)));
|
||||
}
|
||||
|
@ -217,15 +213,15 @@ PublicKey.prototype.getFingerprint = function () {
|
|||
* @return {int} Number of bits
|
||||
*/
|
||||
PublicKey.prototype.getBitSize = function () {
|
||||
return this.mpi[0].byteLength() * 8;
|
||||
return this.params[0].byteLength() * 8;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fix custom types after cloning
|
||||
*/
|
||||
PublicKey.prototype.postCloneTypeFix = function() {
|
||||
for (var i = 0; i < this.mpi.length; i++) {
|
||||
this.mpi[i] = type_mpi.fromClone(this.mpi[i]);
|
||||
for (var i = 0; i < this.params.length; i++) {
|
||||
this.params[i] = type_mpi.fromClone(this.params[i]);
|
||||
}
|
||||
if (this.keyid) {
|
||||
this.keyid = type_keyid.fromClone(this.keyid);
|
||||
|
|
|
@ -55,10 +55,7 @@ export default function PublicKeyEncryptedSessionKey() {
|
|||
this.version = 3;
|
||||
|
||||
this.publicKeyId = new type_keyid();
|
||||
this.publicKeyAlgorithm = 'rsa_encrypt';
|
||||
|
||||
this.sessionKey = null;
|
||||
this.sessionKeyAlgorithm = 'aes256';
|
||||
|
||||
/** @type {Array<module:type/mpi>} */
|
||||
this.encrypted = [];
|
||||
|
@ -81,34 +78,20 @@ PublicKeyEncryptedSessionKey.prototype.read = function (bytes) {
|
|||
|
||||
var i = 10;
|
||||
|
||||
var integerCount = (function(algo) {
|
||||
switch (algo) {
|
||||
case 'rsa_encrypt':
|
||||
case 'rsa_encrypt_sign':
|
||||
return 1;
|
||||
var integerCount = crypto.getEncSessionKeyParamCount(this.publicKeyAlgorithm);
|
||||
|
||||
case 'elgamal':
|
||||
return 2;
|
||||
|
||||
case 'ecdh':
|
||||
return 2;
|
||||
|
||||
default:
|
||||
throw new Error("Invalid algorithm.");
|
||||
}
|
||||
})(this.publicKeyAlgorithm);
|
||||
|
||||
this.encrypted = [];
|
||||
|
||||
for (var j = 0; j < integerCount; j++) {
|
||||
var mpi;
|
||||
var param;
|
||||
if (this.publicKeyAlgorithm === 'ecdh' && j === 1) {
|
||||
mpi = new type_ecdh_symkey();
|
||||
param = new type_ecdh_symkey();
|
||||
} else {
|
||||
mpi = new type_mpi();
|
||||
param = new type_mpi();
|
||||
}
|
||||
i += mpi.read(bytes.subarray(i, bytes.length));
|
||||
this.encrypted.push(mpi);
|
||||
i += param.read(bytes.subarray(i, bytes.length));
|
||||
this.encrypted.push(param);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -136,20 +119,20 @@ PublicKeyEncryptedSessionKey.prototype.encrypt = function (key) {
|
|||
var checksum = util.calc_checksum(this.sessionKey);
|
||||
data += util.Uint8Array2str(util.writeNumber(checksum, 2));
|
||||
|
||||
var mpi;
|
||||
var param;
|
||||
if (this.publicKeyAlgorithm === 'ecdh') {
|
||||
mpi = util.str2Uint8Array(crypto.pkcs5.addPadding(data));
|
||||
param = util.str2Uint8Array(crypto.pkcs5.addPadding(data));
|
||||
} else {
|
||||
mpi = new type_mpi();
|
||||
mpi.fromBytes(crypto.pkcs1.eme.encode(
|
||||
param = new type_mpi();
|
||||
param.fromBytes(crypto.pkcs1.eme.encode(
|
||||
data,
|
||||
key.mpi[0].byteLength()));
|
||||
key.params[0].byteLength()));
|
||||
}
|
||||
|
||||
this.encrypted = crypto.publicKeyEncrypt(
|
||||
this.publicKeyAlgorithm,
|
||||
key.mpi,
|
||||
mpi,
|
||||
key.params,
|
||||
param,
|
||||
key.fingerprint);
|
||||
};
|
||||
|
||||
|
@ -164,7 +147,7 @@ PublicKeyEncryptedSessionKey.prototype.encrypt = function (key) {
|
|||
PublicKeyEncryptedSessionKey.prototype.decrypt = function (key) {
|
||||
var result = crypto.publicKeyDecrypt(
|
||||
this.publicKeyAlgorithm,
|
||||
key.mpi,
|
||||
key.params,
|
||||
this.encrypted,
|
||||
key.fingerprint).toBytes();
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ function parse_cleartext_mpi(hash_algorithm, cleartext, algorithm) {
|
|||
return new Error("Hash mismatch.");
|
||||
}
|
||||
|
||||
var mpis = crypto.getPrivateMpiCount(algorithm);
|
||||
var mpis = crypto.getPrivKeyParamCount(algorithm);
|
||||
|
||||
var j = 0;
|
||||
var mpi = [];
|
||||
|
@ -104,7 +104,7 @@ function parse_cleartext_mpi(hash_algorithm, cleartext, algorithm) {
|
|||
|
||||
function write_cleartext_mpi(hash_algorithm, algorithm, mpi) {
|
||||
var arr = [];
|
||||
var discard = crypto.getPublicMpiCount(algorithm);
|
||||
var discard = crypto.getPubKeyParamCount(algorithm);
|
||||
|
||||
for (var i = discard; i < mpi.length; i++) {
|
||||
arr.push(mpi[i].write());
|
||||
|
@ -147,7 +147,7 @@ SecretKey.prototype.read = function (bytes) {
|
|||
if (parsedMPI instanceof Error) {
|
||||
throw parsedMPI;
|
||||
}
|
||||
this.mpi = this.mpi.concat(parsedMPI);
|
||||
this.params = this.params.concat(parsedMPI);
|
||||
this.isDecrypted = true;
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ SecretKey.prototype.write = function () {
|
|||
|
||||
if (!this.encrypted) {
|
||||
arr.push(new Uint8Array([0]));
|
||||
arr.push(write_cleartext_mpi('mod', this.algorithm, this.mpi));
|
||||
arr.push(write_cleartext_mpi('mod', this.algorithm, this.params));
|
||||
} else {
|
||||
arr.push(this.encrypted);
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ SecretKey.prototype.encrypt = function (passphrase) {
|
|||
|
||||
var s2k = new type_s2k(),
|
||||
symmetric = 'aes256',
|
||||
cleartext = write_cleartext_mpi('sha1', this.algorithm, this.mpi),
|
||||
cleartext = write_cleartext_mpi('sha1', this.algorithm, this.params),
|
||||
key = produceEncryptionKey(s2k, passphrase, symmetric),
|
||||
blockLen = crypto.cipher[symmetric].blockSize,
|
||||
iv = crypto.random.getRandomBytes(blockLen);
|
||||
|
@ -267,7 +267,7 @@ SecretKey.prototype.decrypt = function (passphrase) {
|
|||
if (parsedMPI instanceof Error) {
|
||||
return false;
|
||||
}
|
||||
this.mpi = this.mpi.concat(parsedMPI);
|
||||
this.params = this.params.concat(parsedMPI);
|
||||
this.isDecrypted = true;
|
||||
this.encrypted = null;
|
||||
return true;
|
||||
|
@ -276,8 +276,8 @@ SecretKey.prototype.decrypt = function (passphrase) {
|
|||
SecretKey.prototype.generate = function (bits, curve) {
|
||||
var self = this;
|
||||
|
||||
return crypto.generateMpi(self.algorithm, bits, curve).then(function(mpi) {
|
||||
self.mpi = mpi;
|
||||
return crypto.generateParams(self.algorithm, bits, curve).then(function(params) {
|
||||
self.params = params;
|
||||
self.isDecrypted = true;
|
||||
});
|
||||
};
|
||||
|
@ -285,10 +285,10 @@ SecretKey.prototype.generate = function (bits, curve) {
|
|||
/**
|
||||
* Clear private MPIs, return to initial state
|
||||
*/
|
||||
SecretKey.prototype.clearPrivateMPIs = function () {
|
||||
SecretKey.prototype.clearPrivateParams = function () {
|
||||
if (!this.encrypted) {
|
||||
throw new Error('If secret key is not encrypted, clearing private MPIs is irreversible.');
|
||||
}
|
||||
this.mpi = this.mpi.slice(0, crypto.getPublicMpiCount(this.algorithm));
|
||||
this.params = this.params.slice(0, crypto.getPubKeyParamCount(this.algorithm));
|
||||
this.isDecrypted = false;
|
||||
};
|
||||
|
|
|
@ -243,7 +243,7 @@ Signature.prototype.sign = function (key, data) {
|
|||
this.signedHashValue = hash.subarray(0, 2);
|
||||
|
||||
this.signature = crypto.signature.sign(hashAlgorithm,
|
||||
publicKeyAlgorithm, key.mpi, toHash);
|
||||
publicKeyAlgorithm, key.params, toHash);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -644,7 +644,7 @@ Signature.prototype.verify = function (key, data) {
|
|||
}
|
||||
|
||||
this.verified = crypto.signature.verify(publicKeyAlgorithm,
|
||||
hashAlgorithm, mpi, key.mpi,
|
||||
hashAlgorithm, mpi, key.params,
|
||||
util.concatUint8Array([bytes, this.signatureData, trailer]));
|
||||
|
||||
return this.verified;
|
||||
|
|
|
@ -42,9 +42,15 @@ import util from '../util.js';
|
|||
/**
|
||||
* @constructor
|
||||
*/
|
||||
export default function MPI() {
|
||||
export default function MPI(data) {
|
||||
/** An implementation dependent integer */
|
||||
this.data = null;
|
||||
if (data instanceof BigInteger) {
|
||||
this.fromBigInteger(data);
|
||||
} else if (typeof data === 'string') {
|
||||
this.fromBytes(data);
|
||||
} else {
|
||||
this.data = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -191,13 +191,13 @@ describe("Packet", function() {
|
|||
enc.publicKeyAlgorithm = 'rsa_encrypt';
|
||||
enc.sessionKeyAlgorithm = 'aes256';
|
||||
enc.publicKeyId.bytes = '12345678';
|
||||
enc.encrypt({ mpi: mpi });
|
||||
enc.encrypt({ params: mpi });
|
||||
|
||||
msg.push(enc);
|
||||
|
||||
msg2.read(msg.write());
|
||||
|
||||
msg2[0].decrypt({ mpi: mpi });
|
||||
msg2[0].decrypt({ params: mpi });
|
||||
|
||||
expect(stringify(msg2[0].sessionKey)).to.equal(stringify(enc.sessionKey));
|
||||
expect(msg2[0].sessionKeyAlgorithm).to.equal(enc.sessionKeyAlgorithm);
|
||||
|
@ -445,8 +445,8 @@ describe("Packet", function() {
|
|||
return mpi;
|
||||
});
|
||||
|
||||
key[0].mpi = mpi;
|
||||
|
||||
key[0].params = mpi;
|
||||
key[0].algorithm = "rsa_sign";
|
||||
key[0].encrypt('hello');
|
||||
|
||||
var raw = key.write();
|
||||
|
@ -455,7 +455,7 @@ describe("Packet", function() {
|
|||
key2.read(raw);
|
||||
key2[0].decrypt('hello');
|
||||
|
||||
expect(key[0].mpi.toString()).to.equal(key2[0].mpi.toString());
|
||||
expect(key[0].params.toString()).to.equal(key2[0].params.toString());
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -473,7 +473,8 @@ describe("Packet", function() {
|
|||
return mpi;
|
||||
});
|
||||
|
||||
key.mpi = mpi;
|
||||
key.params = mpi;
|
||||
key.algorithm = "rsa_sign";
|
||||
|
||||
var signed = new openpgp.packet.List(),
|
||||
literal = new openpgp.packet.Literal(),
|
||||
|
|
Loading…
Reference in New Issue
Block a user