Store named session key parameters (#1157)
Change session key parameter handling to mirror key parameters. Parameters are stored as an object rather than an array. MPIs are always stored as Uint8Arrays.
This commit is contained in:
parent
400ae63c5e
commit
d5dd247b2c
|
@ -25,7 +25,6 @@
|
||||||
* @requires crypto/random
|
* @requires crypto/random
|
||||||
* @requires type/ecdh_symkey
|
* @requires type/ecdh_symkey
|
||||||
* @requires type/kdf_params
|
* @requires type/kdf_params
|
||||||
* @requires type/mpi
|
|
||||||
* @requires type/oid
|
* @requires type/oid
|
||||||
* @requires enums
|
* @requires enums
|
||||||
* @requires util
|
* @requires util
|
||||||
|
@ -35,23 +34,13 @@
|
||||||
import publicKey from './public_key';
|
import publicKey from './public_key';
|
||||||
import * as cipher from './cipher';
|
import * as cipher from './cipher';
|
||||||
import { getRandomBytes } from './random';
|
import { getRandomBytes } from './random';
|
||||||
import type_ecdh_symkey from '../type/ecdh_symkey';
|
import ECDHSymkey from '../type/ecdh_symkey';
|
||||||
import KDFParams from '../type/kdf_params';
|
import KDFParams from '../type/kdf_params';
|
||||||
import type_mpi from '../type/mpi';
|
|
||||||
import enums from '../enums';
|
import enums from '../enums';
|
||||||
import util from '../util';
|
import util from '../util';
|
||||||
import OID from '../type/oid';
|
import OID from '../type/oid';
|
||||||
import { Curve } from './public_key/elliptic/curves';
|
import { Curve } from './public_key/elliptic/curves';
|
||||||
|
|
||||||
export function constructParams(types, data) {
|
|
||||||
return types.map(function(type, i) {
|
|
||||||
if (data && data[i]) {
|
|
||||||
return new type(data[i]);
|
|
||||||
}
|
|
||||||
return new type();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypts data using specified algorithm and public key parameters.
|
* Encrypts data using specified algorithm and public key parameters.
|
||||||
* See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1} for public key algorithms.
|
* See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1} for public key algorithms.
|
||||||
|
@ -59,29 +48,26 @@ export function constructParams(types, data) {
|
||||||
* @param {Object} publicParams Algorithm-specific public key parameters
|
* @param {Object} publicParams Algorithm-specific public key parameters
|
||||||
* @param {Uint8Array} data Data to be encrypted
|
* @param {Uint8Array} data Data to be encrypted
|
||||||
* @param {Uint8Array} fingerprint Recipient fingerprint
|
* @param {Uint8Array} fingerprint Recipient fingerprint
|
||||||
* @returns {Array<module:type/mpi|
|
* @returns {Object} Encrypted session key parameters
|
||||||
* module:type/ecdh_symkey>} Encrypted session key parameters
|
|
||||||
* @async
|
* @async
|
||||||
*/
|
*/
|
||||||
export async function publicKeyEncrypt(algo, publicParams, data, fingerprint) {
|
export async function publicKeyEncrypt(algo, publicParams, data, fingerprint) {
|
||||||
const types = getEncSessionKeyParamTypes(algo);
|
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
case enums.publicKey.rsaEncrypt:
|
case enums.publicKey.rsaEncrypt:
|
||||||
case enums.publicKey.rsaEncryptSign: {
|
case enums.publicKey.rsaEncryptSign: {
|
||||||
const { n, e } = publicParams;
|
const { n, e } = publicParams;
|
||||||
const res = await publicKey.rsa.encrypt(data, n, e);
|
const c = await publicKey.rsa.encrypt(data, n, e);
|
||||||
return constructParams(types, [res]);
|
return { c };
|
||||||
}
|
}
|
||||||
case enums.publicKey.elgamal: {
|
case enums.publicKey.elgamal: {
|
||||||
const { p, g, y } = publicParams;
|
const { p, g, y } = publicParams;
|
||||||
const res = await publicKey.elgamal.encrypt(data, p, g, y);
|
return publicKey.elgamal.encrypt(data, p, g, y);
|
||||||
return constructParams(types, [res.c1, res.c2]);
|
|
||||||
}
|
}
|
||||||
case enums.publicKey.ecdh: {
|
case enums.publicKey.ecdh: {
|
||||||
const { oid, Q, kdfParams } = publicParams;
|
const { oid, Q, kdfParams } = publicParams;
|
||||||
const { publicKey: V, wrappedKey: C } = await publicKey.elliptic.ecdh.encrypt(
|
const { publicKey: V, wrappedKey: C } = await publicKey.elliptic.ecdh.encrypt(
|
||||||
oid, kdfParams, data, Q, fingerprint);
|
oid, kdfParams, data, Q, fingerprint);
|
||||||
return constructParams(types, [V, C]);
|
return { V, C: new ECDHSymkey(C) };
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return [];
|
return [];
|
||||||
|
@ -94,24 +80,22 @@ export async function publicKeyEncrypt(algo, publicParams, data, fingerprint) {
|
||||||
* @param {module:enums.publicKey} algo Public key algorithm
|
* @param {module:enums.publicKey} algo Public key algorithm
|
||||||
* @param {Object} publicKeyParams Algorithm-specific public key parameters
|
* @param {Object} publicKeyParams Algorithm-specific public key parameters
|
||||||
* @param {Object} privateKeyParams Algorithm-specific private key parameters
|
* @param {Object} privateKeyParams Algorithm-specific private key parameters
|
||||||
* @param {Array<module:type/mpi|
|
* @param {Object} sessionKeyParams Encrypted session key parameters
|
||||||
module:type/ecdh_symkey>} data_params Encrypted session key parameters
|
|
||||||
* @param {Uint8Array} fingerprint Recipient fingerprint
|
* @param {Uint8Array} fingerprint Recipient fingerprint
|
||||||
* @returns {Uint8Array} Decrypted data
|
* @returns {Uint8Array} Decrypted data
|
||||||
* @async
|
* @async
|
||||||
*/
|
*/
|
||||||
export async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, data_params, fingerprint) {
|
export async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, sessionKeyParams, fingerprint) {
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
case enums.publicKey.rsaEncryptSign:
|
case enums.publicKey.rsaEncryptSign:
|
||||||
case enums.publicKey.rsaEncrypt: {
|
case enums.publicKey.rsaEncrypt: {
|
||||||
const c = data_params[0].toUint8Array();
|
const { c } = sessionKeyParams;
|
||||||
const { n, e } = publicKeyParams;
|
const { n, e } = publicKeyParams;
|
||||||
const { d, p, q, u } = privateKeyParams;
|
const { d, p, q, u } = privateKeyParams;
|
||||||
return publicKey.rsa.decrypt(c, n, e, d, p, q, u);
|
return publicKey.rsa.decrypt(c, n, e, d, p, q, u);
|
||||||
}
|
}
|
||||||
case enums.publicKey.elgamal: {
|
case enums.publicKey.elgamal: {
|
||||||
const c1 = data_params[0].toUint8Array();
|
const { c1, c2 } = sessionKeyParams;
|
||||||
const c2 = data_params[1].toUint8Array();
|
|
||||||
const p = publicKeyParams.p;
|
const p = publicKeyParams.p;
|
||||||
const x = privateKeyParams.x;
|
const x = privateKeyParams.x;
|
||||||
return publicKey.elgamal.decrypt(c1, c2, p, x);
|
return publicKey.elgamal.decrypt(c1, c2, p, x);
|
||||||
|
@ -119,10 +103,9 @@ export async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams,
|
||||||
case enums.publicKey.ecdh: {
|
case enums.publicKey.ecdh: {
|
||||||
const { oid, Q, kdfParams } = publicKeyParams;
|
const { oid, Q, kdfParams } = publicKeyParams;
|
||||||
const { d } = privateKeyParams;
|
const { d } = privateKeyParams;
|
||||||
const V = data_params[0].toUint8Array();
|
const { V, C } = sessionKeyParams;
|
||||||
const C = data_params[1].data;
|
|
||||||
return publicKey.elliptic.ecdh.decrypt(
|
return publicKey.elliptic.ecdh.decrypt(
|
||||||
oid, kdfParams, V, C, Q, d, fingerprint);
|
oid, kdfParams, V, C.data, Q, d, fingerprint);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid public key encryption algorithm.');
|
throw new Error('Invalid public key encryption algorithm.');
|
||||||
|
@ -222,27 +205,37 @@ export function parsePrivateKeyParams(algo, bytes, publicParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the types comprising the encrypted session key of an algorithm
|
/** Returns the types comprising the encrypted session key of an algorithm
|
||||||
* @param {module:enums.publicKey} algo The public key algorithm
|
* @param {module:enums.publicKey} algo The key algorithm
|
||||||
* @returns {Array<Object>} The array of types
|
* @param {Uint8Array} bytes The key material to parse
|
||||||
|
* @returns {Object} The session key parameters referenced by name
|
||||||
*/
|
*/
|
||||||
export function getEncSessionKeyParamTypes(algo) {
|
export function parseEncSessionKeyParams(algo, bytes) {
|
||||||
|
let read = 0;
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
// Algorithm-Specific Fields for RSA encrypted session keys:
|
// Algorithm-Specific Fields for RSA encrypted session keys:
|
||||||
// - MPI of RSA encrypted value m**e mod n.
|
// - MPI of RSA encrypted value m**e mod n.
|
||||||
case enums.publicKey.rsaEncrypt:
|
case enums.publicKey.rsaEncrypt:
|
||||||
case enums.publicKey.rsaEncryptSign:
|
case enums.publicKey.rsaEncryptSign: {
|
||||||
return [type_mpi];
|
const c = util.readMPI(bytes.subarray(read));
|
||||||
|
return { c };
|
||||||
|
}
|
||||||
|
|
||||||
// Algorithm-Specific Fields for Elgamal encrypted session keys:
|
// Algorithm-Specific Fields for Elgamal encrypted session keys:
|
||||||
// - MPI of Elgamal value g**k mod p
|
// - MPI of Elgamal value g**k mod p
|
||||||
// - MPI of Elgamal value m * y**k mod p
|
// - MPI of Elgamal value m * y**k mod p
|
||||||
case enums.publicKey.elgamal:
|
case enums.publicKey.elgamal: {
|
||||||
return [type_mpi, type_mpi];
|
const c1 = util.readMPI(bytes.subarray(read)); read += c1.length + 2;
|
||||||
|
const c2 = util.readMPI(bytes.subarray(read));
|
||||||
|
return { c1, c2 };
|
||||||
|
}
|
||||||
// Algorithm-Specific Fields for ECDH encrypted session keys:
|
// Algorithm-Specific Fields for ECDH encrypted session keys:
|
||||||
// - MPI containing the ephemeral key used to establish the shared secret
|
// - MPI containing the ephemeral key used to establish the shared secret
|
||||||
// - ECDH Symmetric Key
|
// - ECDH Symmetric Key
|
||||||
case enums.publicKey.ecdh:
|
case enums.publicKey.ecdh: {
|
||||||
return [type_mpi, type_ecdh_symkey];
|
const V = util.readMPI(bytes.subarray(read)); read += V.length + 2;
|
||||||
|
const C = new ECDHSymkey(); C.read(bytes.subarray(read));
|
||||||
|
return { V, C };
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid public key encryption algorithm.');
|
throw new Error('Invalid public key encryption algorithm.');
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,15 +70,8 @@ class PublicKeyEncryptedSessionKeyPacket {
|
||||||
this.publicKeyId.read(bytes.subarray(1, bytes.length));
|
this.publicKeyId.read(bytes.subarray(1, bytes.length));
|
||||||
this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes[9]);
|
this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes[9]);
|
||||||
|
|
||||||
let i = 10;
|
|
||||||
|
|
||||||
const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
|
const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
|
||||||
const types = crypto.getEncSessionKeyParamTypes(algo);
|
this.encrypted = crypto.parseEncSessionKeyParams(algo, bytes.subarray(10));
|
||||||
this.encrypted = crypto.constructParams(types);
|
|
||||||
|
|
||||||
for (let j = 0; j < types.length; j++) {
|
|
||||||
i += this.encrypted[j].read(bytes.subarray(i, bytes.length));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,11 +80,14 @@ class PublicKeyEncryptedSessionKeyPacket {
|
||||||
* @returns {Uint8Array} The Uint8Array representation
|
* @returns {Uint8Array} The Uint8Array representation
|
||||||
*/
|
*/
|
||||||
write() {
|
write() {
|
||||||
const arr = [new Uint8Array([this.version]), this.publicKeyId.write(), new Uint8Array([enums.write(enums.publicKey, this.publicKeyAlgorithm)])];
|
const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
|
||||||
|
|
||||||
for (let i = 0; i < this.encrypted.length; i++) {
|
const arr = [
|
||||||
arr.push(this.encrypted[i].write());
|
new Uint8Array([this.version]),
|
||||||
}
|
this.publicKeyId.write(),
|
||||||
|
new Uint8Array([enums.write(enums.publicKey, this.publicKeyAlgorithm)]),
|
||||||
|
crypto.serializeKeyParams(algo, this.encrypted)
|
||||||
|
];
|
||||||
|
|
||||||
return util.concatUint8Array(arr);
|
return util.concatUint8Array(arr);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user