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.35 to 2.1.36

2

package.json

@@ -84,4 +84,4 @@ {

"name": "pkijs",
"version": "2.1.35",
"version": "2.1.36",
"license": "MIT"
}

@@ -372,729 +372,2 @@ import * as asn1js from "asn1js";

*/
verify_old({
signer = (-1),
data = (new ArrayBuffer(0)),
trustedCerts = [],
checkDate = (new Date()),
checkChain = false,
includeSignerCertificate = false,
extendedMode = false,
findOrigin = null,
findIssuer = null
} = {})
{
//region Global variables
let sequence = Promise.resolve();
let messageDigestValue = new ArrayBuffer(0);
let publicKey;
let shaAlgorithm = "";
let signerCertificate = {};
let timestampSerial = null;
let certificatePath = [];
//endregion
//region Get a "crypto" extension
const crypto = getCrypto();
if(typeof crypto === "undefined")
return Promise.reject("Unable to create WebCrypto object");
//endregion
//region Get a signer number
if(signer === (-1))
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 1,
message: "Unable to get signer index from input parameters",
signatureVerified: null,
signerCertificate: null,
signerCertificateVerified: null
});
}
return Promise.reject("Unable to get signer index from input parameters");
}
//endregion
//region Check that certificates field was included in signed data
if(("certificates" in this) === false)
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 2,
message: "No certificates attached to this signed data",
signatureVerified: null,
signerCertificate: null,
signerCertificateVerified: null
});
}
return Promise.reject("No certificates attached to this signed data");
}
//endregion
//region Find a certificate for specified signer
if(this.signerInfos[signer].sid instanceof IssuerAndSerialNumber)
{
sequence = sequence.then(() =>
{
for(const certificate of this.certificates)
{
if((certificate instanceof Certificate) === false)
continue;
if((certificate.issuer.isEqual(this.signerInfos[signer].sid.issuer)) &&
(certificate.serialNumber.isEqual(this.signerInfos[signer].sid.serialNumber)))
{
signerCertificate = certificate;
return Promise.resolve();
}
}
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 3,
message: "Unable to find signer certificate",
signatureVerified: null,
signerCertificate: null,
signerCertificateVerified: null
});
}
return Promise.reject("Unable to find signer certificate");
});
}
else // Find by SubjectKeyIdentifier
{
sequence = sequence.then(() =>
Promise.all(Array.from(this.certificates.filter(certificate => (certificate instanceof Certificate)), certificate =>
crypto.digest({ name: "sha-1" }, new Uint8Array(certificate.subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHex)))
).then(results =>
{
for(const [index, certificate] of this.certificates.entries())
{
if((certificate instanceof Certificate) === false)
continue;
if(isEqualBuffer(results[index], this.signerInfos[signer].sid.valueBlock.valueHex))
{
signerCertificate = certificate;
return Promise.resolve();
}
}
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 3,
message: "Unable to find signer certificate",
signatureVerified: null,
signerCertificate: null,
signerCertificateVerified: null
});
}
return Promise.reject("Unable to find signer certificate");
}, () =>
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 3,
message: "Unable to find signer certificate",
signatureVerified: null,
signerCertificate: null,
signerCertificateVerified: null
});
}
return Promise.reject("Unable to find signer certificate");
})
);
}
//endregion
//region Verify internal digest in case of "tSTInfo" content type
sequence = sequence.then(() =>
{
if(this.encapContentInfo.eContentType === "1.2.840.113549.1.9.16.1.4")
{
//region Check "eContent" precense
if(("eContent" in this.encapContentInfo) === false)
return false;
//endregion
//region Initialize TST_INFO value
const asn1 = asn1js.fromBER(this.encapContentInfo.eContent.valueBlock.valueHex);
let tstInfo;
try
{
tstInfo = new TSTInfo({ schema: asn1.result });
}
catch(ex)
{
return false;
}
//endregion
//region Change "checkDate" and append "timestampSerial"
checkDate = tstInfo.genTime;
timestampSerial = tstInfo.serialNumber.valueBlock.valueHex;
//endregion
//region Check that we do have detached data content
if(data.byteLength === 0)
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 4,
message: "Missed detached data input array",
signatureVerified: null,
signerCertificate,
signerCertificateVerified: null
});
}
return Promise.reject("Missed detached data input array");
}
//endregion
return tstInfo.verify({ data });
}
return true;
});
//endregion
//region Make additional verification for signer's certificate
function checkCA(cert)
{
/// <param name="cert" type="in_window.org.pkijs.simpl.CERT">Certificate to find CA flag for</param>
//region Do not include signer's certificate
if((cert.issuer.isEqual(signerCertificate.issuer) === true) && (cert.serialNumber.isEqual(signerCertificate.serialNumber) === true))
return null;
//endregion
let isCA = false;
if("extensions" in cert)
{
for(const extension of cert.extensions)
{
if(extension.extnID === "2.5.29.19") // BasicConstraints
{
if("cA" in extension.parsedValue)
{
if(extension.parsedValue.cA === true)
isCA = true;
}
}
}
}
if(isCA)
return cert;
return null;
}
if(checkChain)
{
sequence = sequence.then(result =>
{
//region Verify result of previous operation
if(result === false)
return false;
//endregion
const promiseResults = Array.from(this.certificates.filter(certificate => (certificate instanceof Certificate)), certificate => checkCA(certificate));
const certificateChainValidationEngineParameters = {
checkDate,
certs: Array.from(promiseResults.filter(_result => (_result !== null))),
trustedCerts
};
if(findIssuer !== null)
certificateChainValidationEngineParameters.findIssuer = findIssuer;
if(findOrigin !== null)
certificateChainValidationEngineParameters.findOrigin = findOrigin;
const certificateChainEngine = new CertificateChainValidationEngine(certificateChainValidationEngineParameters);
certificateChainEngine.certs.push(signerCertificate);
if("crls" in this)
{
for(const crl of this.crls)
{
if(crl instanceof CertificateRevocationList)
certificateChainEngine.crls.push(crl);
else // Assumed "revocation value" has "OtherRevocationInfoFormat"
{
if(crl.otherRevInfoFormat === "1.3.6.1.5.5.7.48.1.1") // Basic OCSP response
certificateChainEngine.ocsps.push(new BasicOCSPResponse({ schema: crl.otherRevInfo }));
}
}
}
if("ocsps" in this)
certificateChainEngine.ocsps.push(...(this.ocsps));
return certificateChainEngine.verify().then(verificationResult =>
{
if("certificatePath" in verificationResult)
certificatePath = verificationResult.certificatePath;
if(verificationResult.result === true)
return Promise.resolve(true);
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 5,
message: `Validation of signer's certificate failed: ${verificationResult.resultMessage}`,
signatureVerified: null,
signerCertificate,
signerCertificateVerified: false
});
}
return Promise.reject("Validation of signer's certificate failed");
}, error =>
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 5,
message: `Validation of signer's certificate failed with error: ${((error instanceof Object) ? error.resultMessage : error)}`,
signatureVerified: null,
signerCertificate,
signerCertificateVerified: false
});
}
return Promise.reject(`Validation of signer's certificate failed with error: ${((error instanceof Object) ? error.resultMessage : error)}`);
});
});
}
//endregion
//region Find signer's hashing algorithm
sequence = sequence.then(result =>
{
//region Verify result of previous operation
if(result === false)
return false;
//endregion
const signerInfoHashAlgorithm = getAlgorithmByOID(this.signerInfos[signer].digestAlgorithm.algorithmId);
if(("name" in signerInfoHashAlgorithm) === false)
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 7,
message: `Unsupported signature algorithm: ${this.signerInfos[signer].digestAlgorithm.algorithmId}`,
signatureVerified: null,
signerCertificate,
signerCertificateVerified: true
});
}
return Promise.reject(`Unsupported signature algorithm: ${this.signerInfos[signer].digestAlgorithm.algorithmId}`);
}
shaAlgorithm = signerInfoHashAlgorithm.name;
return true;
});
//endregion
//region Create correct data block for verification
sequence = sequence.then(result =>
{
//region Verify result of previous operation
if(result === false)
return false;
//endregion
if("eContent" in this.encapContentInfo) // Attached data
{
if((this.encapContentInfo.eContent.idBlock.tagClass === 1) &&
(this.encapContentInfo.eContent.idBlock.tagNumber === 4))
{
if(this.encapContentInfo.eContent.idBlock.isConstructed === false)
data = this.encapContentInfo.eContent.valueBlock.valueHex;
else
{
for(const contentValue of this.encapContentInfo.eContent.valueBlock.value)
data = utilConcatBuf(data, contentValue.valueBlock.valueHex);
}
}
else
data = this.encapContentInfo.eContent.valueBlock.valueBeforeDecode;
}
else // Detached data
{
if(data.byteLength === 0) // Check that "data" already provided by function parameter
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 8,
message: "Missed detached data input array",
signatureVerified: null,
signerCertificate,
signerCertificateVerified: true
});
}
return Promise.reject("Missed detached data input array");
}
}
if("signedAttrs" in this.signerInfos[signer])
{
//region Check mandatory attributes
let foundContentType = false;
let foundMessageDigest = false;
for(const attribute of this.signerInfos[signer].signedAttrs.attributes)
{
//region Check that "content-type" attribute exists
if(attribute.type === "1.2.840.113549.1.9.3")
foundContentType = true;
//endregion
//region Check that "message-digest" attribute exists
if(attribute.type === "1.2.840.113549.1.9.4")
{
foundMessageDigest = true;
messageDigestValue = attribute.values[0].valueBlock.valueHex;
}
//endregion
//region Speed-up searching
if(foundContentType && foundMessageDigest)
break;
//endregion
}
if(foundContentType === false)
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 9,
message: "Attribute \"content-type\" is a mandatory attribute for \"signed attributes\"",
signatureVerified: null,
signerCertificate,
signerCertificateVerified: true
});
}
return Promise.reject("Attribute \"content-type\" is a mandatory attribute for \"signed attributes\"");
}
if(foundMessageDigest === false)
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 10,
message: "Attribute \"message-digest\" is a mandatory attribute for \"signed attributes\"",
signatureVerified: null,
signerCertificate,
signerCertificateVerified: true
});
}
return Promise.reject("Attribute \"message-digest\" is a mandatory attribute for \"signed attributes\"");
}
//endregion
}
return true;
});
//endregion
//region Import public key from signer's certificate
sequence = sequence.then(result =>
{
//region Verify result of previous operation
if(result === false)
return false;
//endregion
//region Get information about public key algorithm and default parameters for import
let algorithmId;
if(signerCertificate.signatureAlgorithm.algorithmId === "1.2.840.113549.1.1.10")
algorithmId = signerCertificate.signatureAlgorithm.algorithmId;
else
algorithmId = signerCertificate.subjectPublicKeyInfo.algorithm.algorithmId;
const algorithmObject = getAlgorithmByOID(algorithmId);
if(("name" in algorithmObject) === false)
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 11,
message: `Unsupported public key algorithm: ${algorithmId}`,
signatureVerified: null,
signerCertificate,
signerCertificateVerified: true
});
}
return Promise.reject(`Unsupported public key algorithm: ${algorithmId}`);
}
const algorithm = getAlgorithmParameters(algorithmObject.name, "importkey");
if("hash" in algorithm.algorithm)
algorithm.algorithm.hash.name = shaAlgorithm;
//region Special case for ECDSA
if(algorithmObject.name === "ECDSA")
{
//region Get information about named curve
let algorithmParamsChecked = false;
if(("algorithmParams" in signerCertificate.subjectPublicKeyInfo.algorithm) === true)
{
if("idBlock" in signerCertificate.subjectPublicKeyInfo.algorithm.algorithmParams)
{
if((signerCertificate.subjectPublicKeyInfo.algorithm.algorithmParams.idBlock.tagClass === 1) && (signerCertificate.subjectPublicKeyInfo.algorithm.algorithmParams.idBlock.tagNumber === 6))
algorithmParamsChecked = true;
}
}
if(algorithmParamsChecked === false)
return Promise.reject("Incorrect type for ECDSA public key parameters");
const curveObject = getAlgorithmByOID(signerCertificate.subjectPublicKeyInfo.algorithm.algorithmParams.valueBlock.toString());
if(("name" in curveObject) === false)
return Promise.reject(`Unsupported named curve algorithm: ${signerCertificate.subjectPublicKeyInfo.algorithm.algorithmParams.valueBlock.toString()}`);
//endregion
algorithm.algorithm.namedCurve = curveObject.name;
}
//endregion
//endregion
const publicKeyInfoSchema = signerCertificate.subjectPublicKeyInfo.toSchema();
const publicKeyInfoBuffer = publicKeyInfoSchema.toBER(false);
const publicKeyInfoView = new Uint8Array(publicKeyInfoBuffer);
return crypto.importKey("spki", publicKeyInfoView, algorithm.algorithm, true, algorithm.usages);
});
//endregion
//region Verify signer's signature
sequence = sequence.then(result =>
{
//region Verify result of previous operation
if(typeof result === "boolean")
return false;
//endregion
publicKey = result;
//region Verify "message-digest" attribute in case of "signedAttrs"
if("signedAttrs" in this.signerInfos[signer])
return crypto.digest(shaAlgorithm, new Uint8Array(data));
return true;
//endregion
}).then(result =>
{
//region Verify result of previous operation
if(result === false)
return false;
//endregion
if("signedAttrs" in this.signerInfos[signer])
{
if(isEqualBuffer(result, messageDigestValue))
{
data = this.signerInfos[signer].signedAttrs.encodedValue;
return true;
}
return false;
}
return true;
}).then(result =>
{
//region Check result of previous operation
if(result === false)
return false;
//endregion
//region Get default algorithm parameters for verification
const algorithm = getAlgorithmParameters(publicKey.algorithm.name, "verify");
if("hash" in algorithm.algorithm)
algorithm.algorithm.hash.name = shaAlgorithm;
//endregion
//region Special case for RSA-PSS
if(publicKey.algorithm.name === "RSA-PSS")
{
let pssParameters;
try
{
pssParameters = new RSASSAPSSParams({ schema: this.signerInfos[signer].signatureAlgorithm.algorithmParams });
}
catch(ex)
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 12,
message: ex,
signatureVerified: null,
signerCertificate,
signerCertificateVerified: true
});
}
return Promise.reject(ex);
}
if("saltLength" in pssParameters)
algorithm.algorithm.saltLength = pssParameters.saltLength;
else
algorithm.algorithm.saltLength = 20;
let hashName = "SHA-1";
if("hashAlgorithm" in pssParameters)
{
const hashAlgorithm = getAlgorithmByOID(pssParameters.hashAlgorithm.algorithmId);
if(("name" in hashAlgorithm) === false)
{
if(extendedMode)
{
return Promise.reject({
date: checkDate,
code: 13,
message: `Unrecognized hash algorithm: ${pssParameters.hashAlgorithm.algorithmId}`,
signatureVerified: null,
signerCertificate,
signerCertificateVerified: true
});
}
return Promise.reject(`Unrecognized hash algorithm: ${pssParameters.hashAlgorithm.algorithmId}`);
}
hashName = hashAlgorithm.name;
}
algorithm.algorithm.hash.name = hashName;
}
//endregion
//region Special case for ECDSA signatures
let signatureValue = this.signerInfos[signer].signature.valueBlock.valueHex;
if(publicKey.algorithm.name === "ECDSA")
{
const asn1 = asn1js.fromBER(signatureValue);
signatureValue = createECDSASignatureFromCMS(asn1.result);
}
//endregion
return crypto.verify(algorithm.algorithm,
publicKey,
new Uint8Array(signatureValue),
new Uint8Array(data));
});
//endregion
//region Make a final result
sequence = sequence.then(result =>
{
if(extendedMode)
{
return {
date: checkDate,
code: 14,
message: "",
signatureVerified: result,
signerCertificate,
timestampSerial,
signerCertificateVerified: true,
certificatePath
};
}
return result;
}, error =>
{
if(extendedMode)
{
if("code" in error)
return Promise.reject(error);
return Promise.reject({
date: checkDate,
code: 15,
message: `Error during verification: ${error.message}`,
signatureVerified: null,
signerCertificate,
timestampSerial,
signerCertificateVerified: true
});
}
return Promise.reject(error);
});
//endregion
return sequence;
}
//**********************************************************************************
/**
* Verify current SignedData value
* @param signer
* @param data
* @param trustedCerts
* @param checkDate
* @param checkChain
* @param includeSignerCertificate
* @param extendedMode
* @param findOrigin
* @param findIssuer
* @returns {*}
*/
verify({

@@ -1101,0 +374,0 @@ signer = (-1),

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

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