public version!: number; public authSafe!: ContentInfo; public macData?: MacData; public parsedValue?: PFXParsedValue;
/** * Initializes a new instance of the {@link PFX} class * @param parameters Initialization parameters
*/
constructor(parameters: PFXParameters = {}) { super();
this.version = pvutils.getParametersValue(parameters, VERSION, PFX.defaultValues(VERSION)); this.authSafe = pvutils.getParametersValue(parameters, AUTH_SAFE, PFX.defaultValues(AUTH_SAFE)); if (MAC_DATA in parameters) { this.macData = pvutils.getParametersValue(parameters, MAC_DATA, PFX.defaultValues(MAC_DATA));
} if (PARSED_VALUE in parameters) { this.parsedValue = pvutils.getParametersValue(parameters, PARSED_VALUE, PFX.defaultValues(PARSED_VALUE));
}
if (parameters.schema) { this.fromSchema(parameters.schema);
}
}
/** * Returns default values for all class members * @param memberName String name for a class member * @returns Default value
*/ publicstatic override defaultValues(memberName: typeof VERSION): number; publicstatic override defaultValues(memberName: typeof AUTH_SAFE): ContentInfo; publicstatic override defaultValues(memberName: typeof MAC_DATA): MacData; publicstatic override defaultValues(memberName: typeof PARSED_VALUE): PFXParsedValue; publicstatic override defaultValues(memberName: string): any { switch (memberName) { case VERSION: return3; case AUTH_SAFE: return (new ContentInfo()); case MAC_DATA: return (new MacData()); case PARSED_VALUE: return {}; default: returnsuper.defaultValues(memberName);
}
}
/** * Compare values with default values for all class members * @param memberName String name for a class member * @param memberValue Value to compare with default value
*/ publicstatic compareWithDefault(memberName: string, memberValue: any): boolean { switch (memberName) { case VERSION: return (memberValue === PFX.defaultValues(memberName)); case AUTH_SAFE: return ((ContentInfo.compareWithDefault("contentType", memberValue.contentType)) &&
(ContentInfo.compareWithDefault("content", memberValue.content))); case MAC_DATA: return ((MacData.compareWithDefault("mac", memberValue.mac)) &&
(MacData.compareWithDefault("macSalt", memberValue.macSalt)) &&
(MacData.compareWithDefault("iterations", memberValue.iterations))); case PARSED_VALUE: return ((memberValue instanceof Object) && (Object.keys(memberValue).length === 0)); default: returnsuper.defaultValues(memberName);
}
}
// Get internal properties from parsed schema this.version = asn1.result.version.valueBlock.valueDec; this.authSafe = new ContentInfo({ schema: asn1.result.authSafe }); if (MAC_DATA in asn1.result) this.macData = new MacData({ schema: asn1.result.macData });
}
public toSchema(): asn1js.Sequence { //#region Construct and return new ASN.1 schema for this object const outputArray = [ new asn1js.Integer({ value: this.version }), this.authSafe.toSchema()
];
if (this.macData) {
outputArray.push(this.macData.toSchema());
}
return (new asn1js.Sequence({
value: outputArray
})); //#endregion
}
if (this.macData) {
output.macData = this.macData.toJSON();
}
return output;
}
/** * Making ContentInfo from PARSED_VALUE object * @param parameters Parameters, specific to each "integrity mode" * @param crypto Crypto engine
*/ public async makeInternalValues(parameters: MakeInternalValuesParams = {}, crypto = common.getCrypto(true)) { //#region Check mandatory parameter
ArgumentError.assert(parameters, "parameters", "object"); if (!this.parsedValue) { thrownew Error("Please call \"parseValues\" function first in order to make \"parsedValue\" data");
}
ParameterError.assertEmpty(this.parsedValue.integrityMode, "integrityMode", "parsedValue");
ParameterError.assertEmpty(this.parsedValue.authenticatedSafe, "authenticatedSafe", "parsedValue"); //#endregion
//#region Makes values for each particular integrity mode switch (this.parsedValue.integrityMode) { //#region HMAC-based integrity case0:
{ //#region Check additional mandatory parameters if (!("iterations" in parameters)) thrownew ParameterError("iterations");
ParameterError.assertEmpty(parameters.pbkdf2HashAlgorithm, "pbkdf2HashAlgorithm");
ParameterError.assertEmpty(parameters.hmacHashAlgorithm, "hmacHashAlgorithm");
ParameterError.assertEmpty(parameters.password, "password"); //#endregion
//#region Initial variables const saltBuffer = new ArrayBuffer(64); const saltView = new Uint8Array(saltBuffer);
crypto.getRandomValues(saltView);
const data = this.parsedValue.authenticatedSafe.toSchema().toBER(false);
this.authSafe = new ContentInfo({
contentType: ContentInfo.DATA,
content: new asn1js.OctetString({ valueHex: data })
}); //#endregion
//#region Call current crypto engine for making HMAC-based data stamp const result = await crypto.stampDataWithPassword({
password: parameters.password,
hashAlgorithm: parameters.hmacHashAlgorithm,
salt: saltBuffer,
iterationCount: parameters.iterations,
contentToStamp: data
}); //#endregion
//#region Make MAC_DATA values this.macData = new MacData({
mac: new DigestInfo({
digestAlgorithm: new AlgorithmIdentifier({
algorithmId: crypto.getOIDByAlgorithm({ name: parameters.hmacHashAlgorithm }, true, "hmacHashAlgorithm"),
}),
digest: new asn1js.OctetString({ valueHex: result })
}),
macSalt: new asn1js.OctetString({ valueHex: saltBuffer }),
iterations: parameters.iterations
}); //#endregion //#endregion
} break; //#endregion //#region publicKey-based integrity case1:
{ //#region Check additional mandatory parameters if (!("signingCertificate" in parameters)) { thrownew ParameterError("signingCertificate");
}
ParameterError.assertEmpty(parameters.privateKey, "privateKey");
ParameterError.assertEmpty(parameters.hashAlgorithm, "hashAlgorithm"); //#endregion
//#region Making data to be signed // NOTE: all internal data for "authenticatedSafe" must be already prepared. // Thus user must call "makeValues" for all internal "SafeContent" value with appropriate parameters. // Or user can choose to use values from initial parsing of existing PKCS#12 data.
//#region Initial variables const cmsSigned = new SignedData({
version: 1,
encapContentInfo: new EncapsulatedContentInfo({
eContentType: "1.2.840.113549.1.7.1", // "data" content type
eContent: new asn1js.OctetString({ valueHex: toBeSigned })
}),
certificates: [parameters.signingCertificate]
}); //#endregion
//#region Making additional attributes for CMS Signed Data //#region Create a message digest const result = await crypto.digest({ name: parameters.hashAlgorithm }, new Uint8Array(toBeSigned)); //#endregion
//#region Combine all signed extensions //#region Initial variables const signedAttr: Attribute[] = []; //#endregion
//#region contentType
signedAttr.push(new Attribute({
type: "1.2.840.113549.1.9.3",
values: [ new asn1js.ObjectIdentifier({ value: "1.2.840.113549.1.7.1" })
]
})); //#endregion //#region signingTime
signedAttr.push(new Attribute({
type: "1.2.840.113549.1.9.5",
values: [ new asn1js.UTCTime({ valueDate: new Date() })
]
})); //#endregion //#region messageDigest
signedAttr.push(new Attribute({
type: "1.2.840.113549.1.9.4",
values: [ new asn1js.OctetString({ valueHex: result })
]
})); //#endregion
//#region Making final value for "SignerInfo" type
cmsSigned.signerInfos.push(new SignerInfo({
version: 1,
sid: new IssuerAndSerialNumber({
issuer: parameters.signingCertificate.issuer,
serialNumber: parameters.signingCertificate.serialNumber
}),
signedAttrs: new SignedAndUnsignedAttributes({
type: 0,
attributes: signedAttr
})
})); //#endregion //#endregion //#endregion
//#region Signing CMS Signed Data
await cmsSigned.sign(parameters.privateKey, 0, parameters.hashAlgorithm, undefined, crypto); //#endregion
//#region Making final CMS_CONTENT_INFO type this.authSafe = new ContentInfo({
contentType: "1.2.840.113549.1.7.2",
content: cmsSigned.toSchema(true)
}); //#endregion
} break; //#endregion //#region default default: thrownew Error(`Parameter "integrityMode" has unknown value: ${this.parsedValue.integrityMode}`); //#endregion
} //#endregion
}
public async parseInternalValues(parameters: {
checkIntegrity?: boolean;
password?: ArrayBuffer;
}, crypto = common.getCrypto(true)) { //#region Check input data from "parameters"
ArgumentError.assert(parameters, "parameters", "object");
if (parameters.checkIntegrity === undefined) {
parameters.checkIntegrity = true;
} //#endregion
//#region Create value for "this.parsedValue.authenticatedSafe" and check integrity this.parsedValue = {};
switch (this.authSafe.contentType) { //#region data case ContentInfo.DATA:
{ //#region Check additional mandatory parameters
ParameterError.assertEmpty(parameters.password, "password"); //#endregion
//#region Integrity based on HMAC this.parsedValue.integrityMode = 0; //#endregion
//#region Check that we do have OCTETSTRING as "content"
ArgumentError.assert(this.authSafe.content, "authSafe.content", asn1js.OctetString); //#endregion
//#region Check we have "constructive encoding" for AuthSafe content const authSafeContent = this.authSafe.content.getValue(); //#endregion
//#region Set "authenticatedSafe" value this.parsedValue.authenticatedSafe = AuthenticatedSafe.fromBER(authSafeContent); //#endregion
//#region Check integrity if (parameters.checkIntegrity) { //#region Check that MAC_DATA exists if (!this.macData) { thrownew Error("Absent \"macData\" value, can not check PKCS#12 data integrity");
} //#endregion
//#region Call current crypto engine for verifying HMAC-based data stamp const result = await crypto.verifyDataStampedWithPassword({
password: parameters.password,
hashAlgorithm: hashAlgorithm.name,
salt: BufferSourceConverter.toArrayBuffer(this.macData.macSalt.valueBlock.valueHexView),
iterationCount: this.macData.iterations || 1,
contentToVerify: authSafeContent,
signatureToVerify: BufferSourceConverter.toArrayBuffer(this.macData.mac.digest.valueBlock.valueHexView),
}); //#endregion
//#region Verify HMAC signature if (!result) { thrownew Error("Integrity for the PKCS#12 data is broken!");
} //#endregion
} //#endregion
} break; //#endregion //#region signedData case ContentInfo.SIGNED_DATA:
{ //#region Integrity based on signature using public key this.parsedValue.integrityMode = 1; //#endregion
//#region Parse CMS Signed Data const cmsSigned = new SignedData({ schema: this.authSafe.content }); //#endregion
//#region Check that we do have OCTET STRING as "content" const eContent = cmsSigned.encapContentInfo.eContent;
ParameterError.assert(eContent, "eContent", "cmsSigned.encapContentInfo");
ArgumentError.assert(eContent, "eContent", asn1js.OctetString); //#endregion
//#region Create correct data block for verification const data = eContent.getValue(); //#endregion
//#region Set "authenticatedSafe" value this.parsedValue.authenticatedSafe = AuthenticatedSafe.fromBER(data); //#endregion
//#region Check integrity const ok = await cmsSigned.verify({ signer: 0, checkChain: false }, crypto); if (!ok) { thrownew Error("Integrity for the PKCS#12 data is broken!");
} //#endregion
} break; //#endregion //#region default default: thrownew Error(`Incorrect value for"this.authSafe.contentType": ${this.authSafe.contentType}`); //#endregion
} //#endregion
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-05)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.