Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pkijs

Package Overview
Dependencies
Maintainers
2
Versions
151
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pkijs - npm Package Compare versions

Comparing version 2.1.97 to 2.2.0

13

build/KeyAgreeRecipientInfo.js

@@ -77,2 +77,9 @@ "use strict";

this.recipientCertificate = (0, _pvutils.getParametersValue)(parameters, "recipientCertificate", KeyAgreeRecipientInfo.defaultValues("recipientCertificate")); //endregion
/**
* @type {CryptoKey}
* @desc recipientPublicKey
*/
this.recipientPublicKey = (0, _pvutils.getParametersValue)(parameters, "recipientPublicKey", KeyAgreeRecipientInfo.defaultValues("recipientPublicKey")); //endregion
//region If input argument array contains "schema" for this object

@@ -109,2 +116,5 @@

case "recipientPublicKey":
return null;
default:

@@ -143,2 +153,5 @@ throw new Error(`Invalid member name for KeyAgreeRecipientInfo class: ${memberName}`);

case "recipientPublicKey":
return false;
default:

@@ -145,0 +158,0 @@ throw new Error(`Invalid member name for KeyAgreeRecipientInfo class: ${memberName}`);

8

package.json

@@ -82,4 +82,6 @@ {

"ex18:es5": "cd examples/OpenSSLPrivateKeyEncryption && npm run build:es5 && cd ../..",
"build:examples": "npm run ex1 && npm run ex2 && npm run ex3 && npm run ex4 && npm run ex5 && npm run ex6 && npm run ex7 && npm run ex8 && npm run ex9 && npm run ex10 && npm run ex11 && npm run ex12 && npm run ex13 && npm run ex14 && npm run ex15 && npm run ex16 && npm run ex17 && npm run ex18",
"build:examples:es5": "npm run ex1:es5 && npm run ex2:es5 && npm run ex3 && npm run ex4:es5 && npm run ex5:es5 && npm run ex6:es5 && npm run ex7:es5 && npm run ex8:es5 && npm run ex9:es5 && npm run ex10:es5 && npm run ex11:es5 && npm run ex12:es5 && npm run ex13:es5 && npm run ex14:es5 && npm run ex15:es5 && npm run ex16:es5 && npm run ex18:es5",
"ex19": "cd examples/HowToEncryptCMSviaKey && npm run build && cd ../..",
"ex19:es5": "cd examples/HowToEncryptCMSviaKey && npm run build:es5 && cd ../..",
"build:examples": "npm run ex1 && npm run ex2 && npm run ex3 && npm run ex4 && npm run ex5 && npm run ex6 && npm run ex7 && npm run ex8 && npm run ex9 && npm run ex10 && npm run ex11 && npm run ex12 && npm run ex13 && npm run ex14 && npm run ex15 && npm run ex16 && npm run ex17 && npm run ex18 && npm run ex19",
"build:examples:es5": "npm run ex1:es5 && npm run ex2:es5 && npm run ex3 && npm run ex4:es5 && npm run ex5:es5 && npm run ex6:es5 && npm run ex7:es5 && npm run ex8:es5 && npm run ex9:es5 && npm run ex10:es5 && npm run ex11:es5 && npm run ex12:es5 && npm run ex13:es5 && npm run ex14:es5 && npm run ex15:es5 && npm run ex16:es5 && npm run ex18:es5 && npm run ex19:es5",
"build:tests": "npm run build:examples",

@@ -109,3 +111,3 @@ "build:docs": "esdoc",

"name": "pkijs",
"version": "2.1.97",
"version": "2.2.0",
"license": "BSD-3-Clause",

@@ -112,0 +114,0 @@ "esdoc": {

@@ -12,2 +12,3 @@ import * as asn1js from "asn1js";

import IssuerAndSerialNumber from "./IssuerAndSerialNumber.js";
import RecipientKeyIdentifier from "./RecipientKeyIdentifier.js";
import RecipientEncryptedKey from "./RecipientEncryptedKey.js";

@@ -25,2 +26,12 @@ import KeyAgreeRecipientIdentifier from "./KeyAgreeRecipientIdentifier.js";

//**************************************************************************************
const defaultEncryptionParams = {
kdfAlgorithm: "SHA-512",
kekEncryptionLength: 256
};
const curveLengthByName = {
"P-256": 256,
"P-384": 384,
"P-521": 528
};
//**************************************************************************************
/**

@@ -334,6 +345,10 @@ * Class from RFC5652

{
//region Initial variables
const encryptionParameters = parameters || {};
//endregion
//region Initialize encryption parameters
const encryptionParameters = Object.assign(
{ useOAEP: true, oaepHashAlgorithm: "SHA-512" },
defaultEncryptionParams,
parameters || {}
);
//endregion
//region Check type of certificate

@@ -349,16 +364,2 @@ if(certificate.subjectPublicKeyInfo.algorithm.algorithmId.indexOf("1.2.840.113549") !== (-1))

}
//endregion
//region Initialize encryption parameters
if(("oaepHashAlgorithm" in encryptionParameters) === false)
encryptionParameters.oaepHashAlgorithm = "SHA-512";
if(("kdfAlgorithm" in encryptionParameters) === false)
encryptionParameters.kdfAlgorithm = "SHA-512";
if(("kekEncryptionLength" in encryptionParameters) === false)
encryptionParameters.kekEncryptionLength = 256;
if(("useOAEP" in encryptionParameters) === false)
encryptionParameters.useOAEP = true;
//endregion

@@ -446,64 +447,14 @@

{
//region RecipientEncryptedKey
const encryptedKey = new RecipientEncryptedKey({
rid: new KeyAgreeRecipientIdentifier({
variant: 1,
value: new IssuerAndSerialNumber({
issuer: certificate.issuer,
serialNumber: certificate.serialNumber
})
const recipientIdentifier = new KeyAgreeRecipientIdentifier({
variant: 1,
value: new IssuerAndSerialNumber({
issuer: certificate.issuer,
serialNumber: certificate.serialNumber
})
// "encryptedKey" will be calculated in "encrypt" function
});
//endregion
//region keyEncryptionAlgorithm
const aesKWoid = getOIDByAlgorithm({
name: "AES-KW",
length: encryptionParameters.kekEncryptionLength
});
if(aesKWoid === "")
throw new Error(`Unknown length for key encryption algorithm: ${encryptionParameters.kekEncryptionLength}`);
const aesKW = new AlgorithmIdentifier({
algorithmId: aesKWoid,
algorithmParams: new asn1js.Null()
});
//endregion
//region KeyAgreeRecipientInfo
const ecdhOID = getOIDByAlgorithm({
name: "ECDH",
kdf: encryptionParameters.kdfAlgorithm
});
if(ecdhOID === "")
throw new Error(`Unknown KDF algorithm: ${encryptionParameters.kdfAlgorithm}`);
// In fact there is no need in so long UKM, but RFC2631
// has requirement that "UserKeyMaterial" must be 512 bits long
const ukmBuffer = new ArrayBuffer(64);
const ukmView = new Uint8Array(ukmBuffer);
getRandomValues(ukmView); // Generate random values in 64 bytes long buffer
const keyInfo = new KeyAgreeRecipientInfo({
version: 3,
// "originator" will be calculated in "encrypt" function because ephemeral key would be generated there
ukm: new asn1js.OctetString({ valueHex: ukmBuffer }),
keyEncryptionAlgorithm: new AlgorithmIdentifier({
algorithmId: ecdhOID,
algorithmParams: aesKW.toSchema()
}),
recipientEncryptedKeys: new RecipientEncryptedKeys({
encryptedKeys: [encryptedKey]
}),
recipientCertificate: certificate
});
//endregion
//region Final values for "CMS_ENVELOPED_DATA"
this.recipientInfos.push(new RecipientInfo({
variant: 2,
value: keyInfo
}));
//endregion
this._addKeyAgreeRecipientInfo(
recipientIdentifier,
encryptionParameters,
{recipientCertificate: certificate}
);
}

@@ -682,2 +633,93 @@ break;

/**
* Add a "RecipientInfo" using a KeyAgreeRecipientInfo of type RecipientKeyIdentifier.
* @param {CryptoKey} [key] Recipient's public key
* @param {ArrayBuffer} [keyId] The id for the recipient's public key
* @param {Object} [parameters] Additional parameters for "fine tuning" the encryption process
*/
addRecipientByKeyIdentifier(key, keyId, parameters)
{
//region Initialize encryption parameters
const encryptionParameters = Object.assign({}, defaultEncryptionParams, parameters || {});
//endregion
const recipientIdentifier = new KeyAgreeRecipientIdentifier({
variant: 2,
value: new RecipientKeyIdentifier({
subjectKeyIdentifier: new asn1js.OctetString({valueHex: keyId}),
})
});
this._addKeyAgreeRecipientInfo(
recipientIdentifier,
encryptionParameters,
{recipientPublicKey: key}
);
}
//**********************************************************************************
/**
* Add a "RecipientInfo" using a KeyAgreeRecipientInfo of type RecipientKeyIdentifier.
* @param {KeyAgreeRecipientIdentifier} [recipientIdentifier] Recipient identifier
* @param {Object} [encryptionParameters] Additional parameters for "fine tuning" the encryption process
* @param {Object} [extraRecipientInfoParams] Additional params for KeyAgreeRecipientInfo
*/
_addKeyAgreeRecipientInfo(recipientIdentifier, encryptionParameters, extraRecipientInfoParams)
{
//region RecipientEncryptedKey
const encryptedKey = new RecipientEncryptedKey({
rid: recipientIdentifier
// "encryptedKey" will be calculated in "encrypt" function
});
//endregion
//region keyEncryptionAlgorithm
const aesKWoid = getOIDByAlgorithm({
name: "AES-KW",
length: encryptionParameters.kekEncryptionLength
});
if (aesKWoid === "")
throw new Error(`Unknown length for key encryption algorithm: ${encryptionParameters.kekEncryptionLength}`);
const aesKW = new AlgorithmIdentifier({
algorithmId: aesKWoid,
algorithmParams: new asn1js.Null()
});
//endregion
//region KeyAgreeRecipientInfo
const ecdhOID = getOIDByAlgorithm({
name: "ECDH",
kdf: encryptionParameters.kdfAlgorithm
});
if (ecdhOID === "")
throw new Error(`Unknown KDF algorithm: ${encryptionParameters.kdfAlgorithm}`);
// In fact there is no need in so long UKM, but RFC2631
// has requirement that "UserKeyMaterial" must be 512 bits long
const ukmBuffer = new ArrayBuffer(64);
const ukmView = new Uint8Array(ukmBuffer);
getRandomValues(ukmView); // Generate random values in 64 bytes long buffer
const recipientInfoParams = {
version: 3,
// "originator" will be calculated in "encrypt" function because ephemeral key would be generated there
ukm: new asn1js.OctetString({valueHex: ukmBuffer}),
keyEncryptionAlgorithm: new AlgorithmIdentifier({
algorithmId: ecdhOID,
algorithmParams: aesKW.toSchema()
}),
recipientEncryptedKeys: new RecipientEncryptedKeys({
encryptedKeys: [encryptedKey]
})
};
const keyInfo = new KeyAgreeRecipientInfo(Object.assign(recipientInfoParams, extraRecipientInfoParams));
//endregion
//region Final values for "CMS_ENVELOPED_DATA"
this.recipientInfos.push(new RecipientInfo({
variant: 2,
value: keyInfo
}));
//endregion
}
//**********************************************************************************
/**
* Create a new CMS Enveloped Data content with encrypted data

@@ -777,6 +819,9 @@ * @param {Object} contentEncryptionAlgorithm WebCrypto algorithm. For the moment here could be only "AES-CBC" or "AES-GCM" algorithms.

let currentSequence = Promise.resolve();
const recipientInfo = _this.recipientInfos[index];
let ecdhPublicKey;
let ecdhPrivateKey;
let recipientPublicKey;
let recipientCurve;

@@ -787,32 +832,42 @@ let recipientCurveLength;

//endregion
//region Get "namedCurve" parameter from recipient's certificate
//region Get public key and named curve from recipient's certificate or public key
currentSequence = currentSequence.then(() =>
{
const curveObject = _this.recipientInfos[index].value.recipientCertificate.subjectPublicKeyInfo.algorithm.algorithmParams;
if(curveObject.constructor.blockName() !== asn1js.ObjectIdentifier.blockName())
return Promise.reject(`Incorrect "recipientCertificate" for index ${index}`);
const curveOID = curveObject.valueBlock.toString();
switch(curveOID)
{
case "1.2.840.10045.3.1.7":
recipientCurve = "P-256";
recipientCurveLength = 256;
break;
case "1.3.132.0.34":
recipientCurve = "P-384";
recipientCurveLength = 384;
break;
case "1.3.132.0.35":
recipientCurve = "P-521";
recipientCurveLength = 528;
break;
default:
return Promise.reject(`Incorrect curve OID for index ${index}`);
if (recipientInfo.value.recipientPublicKey) {
recipientCurve = recipientInfo.value.recipientPublicKey.algorithm.namedCurve;
return recipientInfo.value.recipientPublicKey;
} else {
const curveObject = recipientInfo.value.recipientCertificate.subjectPublicKeyInfo.algorithm.algorithmParams;
if (curveObject.constructor.blockName() !== asn1js.ObjectIdentifier.blockName())
return Promise.reject(`Incorrect "recipientCertificate" for index ${index}`);
const curveOID = curveObject.valueBlock.toString();
switch (curveOID) {
case "1.2.840.10045.3.1.7":
recipientCurve = "P-256";
break;
case "1.3.132.0.34":
recipientCurve = "P-384";
break;
case "1.3.132.0.35":
recipientCurve = "P-521";
break;
default:
return Promise.reject(`Incorrect curve OID for index ${index}`);
}
return recipientInfo.value.recipientCertificate.getPublicKey({
algorithm: {
algorithm: {
name: "ECDH",
namedCurve: recipientCurve
},
usages: []
}
});
}
return recipientCurve;
}, error =>

@@ -823,9 +878,12 @@ Promise.reject(error));

//region Generate ephemeral ECDH key
currentSequence = currentSequence.then(result =>
crypto.generateKey({
name: "ECDH",
namedCurve: result
},
true,
["deriveBits"]),
currentSequence = currentSequence.then(result => {
recipientPublicKey = result;
recipientCurveLength = curveLengthByName[recipientCurve];
return crypto.generateKey(
{name: "ECDH", namedCurve: recipientCurve},
true,
["deriveBits"]
);
},
error =>

@@ -846,17 +904,7 @@ Promise.reject(error)

//endregion
//region Import recipient's public key
//region Save public key of ephemeral ECDH key pair
currentSequence = currentSequence.then(result =>
{
exportedECDHPublicKey = result;
return _this.recipientInfos[index].value.recipientCertificate.getPublicKey({
algorithm: {
algorithm: {
name: "ECDH",
namedCurve: recipientCurve
},
usages: []
}
});
}, error =>

@@ -866,5 +914,5 @@ Promise.reject(error));

//region Create shared secret
currentSequence = currentSequence.then(result => crypto.deriveBits({
currentSequence = currentSequence.then(() => crypto.deriveBits({
name: "ECDH",
public: result
public: recipientPublicKey
},

@@ -885,4 +933,4 @@ ecdhPrivateKey,

//region Get length of used AES-KW algorithm
const aesKWAlgorithm = new AlgorithmIdentifier({ schema: _this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmParams });
const aesKWAlgorithm = new AlgorithmIdentifier({ schema: recipientInfo.value.keyEncryptionAlgorithm.algorithmParams });
const KWalgorithm = getAlgorithmByOID(aesKWAlgorithm.algorithmId);

@@ -917,3 +965,3 @@ if(("name" in KWalgorithm) === false)

}),
entityUInfo: _this.recipientInfos[index].value.ukm,
entityUInfo: recipientInfo.value.ukm,
suppPubInfo: new asn1js.OctetString({ valueHex: kwLengthBuffer })

@@ -926,5 +974,5 @@ });

//region Get SHA algorithm used together with ECDH
const ecdhAlgorithm = getAlgorithmByOID(_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId);
const ecdhAlgorithm = getAlgorithmByOID(recipientInfo.value.keyEncryptionAlgorithm.algorithmId);
if(("name" in ecdhAlgorithm) === false)
return Promise.reject(`Incorrect OID for key encryption algorithm: ${_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId}`);
return Promise.reject(`Incorrect OID for key encryption algorithm: ${recipientInfo.value.keyEncryptionAlgorithm.algorithmId}`);
//endregion

@@ -959,7 +1007,4 @@

originator.value = new OriginatorPublicKey({ schema: asn1.result });
// There is option when we can stay with ECParameters, but here index prefer to avoid the params
if("algorithmParams" in originator.value.algorithm)
delete originator.value.algorithm.algorithmParams;
_this.recipientInfos[index].value.originator = originator;
recipientInfo.value.originator = originator;
//endregion

@@ -971,3 +1016,3 @@

*/
_this.recipientInfos[index].value.recipientEncryptedKeys.encryptedKeys[0].encryptedKey = new asn1js.OctetString({ valueHex: result });
recipientInfo.value.recipientEncryptedKeys.encryptedKeys[0].encryptedKey = new asn1js.OctetString({ valueHex: result });
//endregion

@@ -1263,19 +1308,27 @@

//endregion
const originator = _this.recipientInfos[index].value.originator;
//region Get "namedCurve" parameter from recipient's certificate
currentSequence = currentSequence.then(() =>
{
if(("recipientCertificate" in decryptionParameters) === false)
return Promise.reject("Parameter \"recipientCertificate\" is mandatory for \"KeyAgreeRecipientInfo\"");
if ("recipientCertificate" in decryptionParameters) {
const curveObject = decryptionParameters.recipientCertificate.subjectPublicKeyInfo.algorithm.algorithmParams;
if(curveObject.constructor.blockName() !== asn1js.ObjectIdentifier.blockName()) {
return Promise.reject(`Incorrect "recipientCertificate" for index ${index}`);
}
curveOID = curveObject.valueBlock.toString();
} else if ("algorithmParams" in originator.value.algorithm) {
const curveObject = originator.value.algorithm.algorithmParams;
if(curveObject.constructor.blockName() !== asn1js.ObjectIdentifier.blockName()) {
return Promise.reject(`Incorrect originator for index ${index}`);
}
curveOID = curveObject.valueBlock.toString();
} else {
return Promise.reject("Parameter \"recipientCertificate\" is mandatory for \"KeyAgreeRecipientInfo\" if algorithm params are missing from originator");
}
if(("recipientPrivateKey" in decryptionParameters) === false)
return Promise.reject("Parameter \"recipientPrivateKey\" is mandatory for \"KeyAgreeRecipientInfo\"");
const curveObject = decryptionParameters.recipientCertificate.subjectPublicKeyInfo.algorithm.algorithmParams;
if(curveObject.constructor.blockName() !== asn1js.ObjectIdentifier.blockName())
return Promise.reject(`Incorrect "recipientCertificate" for index ${index}`);
curveOID = curveObject.valueBlock.toString();
switch(curveOID)

@@ -1318,8 +1371,8 @@ {

//region Change "OriginatorPublicKey" if "curve" parameter absent
if(("algorithmParams" in _this.recipientInfos[index].value.originator.value.algorithm) === false)
_this.recipientInfos[index].value.originator.value.algorithm.algorithmParams = new asn1js.ObjectIdentifier({ value: curveOID });
if(("algorithmParams" in originator.value.algorithm) === false)
originator.value.algorithm.algorithmParams = new asn1js.ObjectIdentifier({ value: curveOID });
//endregion
//region Create ArrayBuffer with sender's public key
const buffer = _this.recipientInfos[index].value.originator.value.toSchema().toBER(false);
const buffer = originator.value.toSchema().toBER(false);
//endregion

@@ -1326,0 +1379,0 @@

@@ -56,2 +56,8 @@ import * as asn1js from "asn1js";

//endregion
/**
* @type {CryptoKey}
* @desc recipientPublicKey
*/
this.recipientPublicKey = getParametersValue(parameters, "recipientPublicKey", KeyAgreeRecipientInfo.defaultValues("recipientPublicKey"));
//endregion

@@ -84,2 +90,4 @@ //region If input argument array contains "schema" for this object

return new Certificate();
case "recipientPublicKey":
return null;
default:

@@ -111,2 +119,4 @@ throw new Error(`Invalid member name for KeyAgreeRecipientInfo class: ${memberName}`);

return false; // For now leave it as is
case "recipientPublicKey":
return false;
default:

@@ -113,0 +123,0 @@ throw new Error(`Invalid member name for KeyAgreeRecipientInfo class: ${memberName}`);

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc