summaryrefslogtreecommitdiffstats
path: root/third_party/js/PKI.js/src/SignerInfo.ts
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/js/PKI.js/src/SignerInfo.ts')
-rw-r--r--third_party/js/PKI.js/src/SignerInfo.ts352
1 files changed, 352 insertions, 0 deletions
diff --git a/third_party/js/PKI.js/src/SignerInfo.ts b/third_party/js/PKI.js/src/SignerInfo.ts
new file mode 100644
index 0000000000..a6f59805dd
--- /dev/null
+++ b/third_party/js/PKI.js/src/SignerInfo.ts
@@ -0,0 +1,352 @@
+import * as asn1js from "asn1js";
+import * as pvutils from "pvutils";
+import { AlgorithmIdentifier, AlgorithmIdentifierJson, AlgorithmIdentifierSchema } from "./AlgorithmIdentifier";
+import { SignedAndUnsignedAttributes, SignedAndUnsignedAttributesJson, SignedAndUnsignedAttributesSchema } from "./SignedAndUnsignedAttributes";
+import { IssuerAndSerialNumber, IssuerAndSerialNumberSchema } from "./IssuerAndSerialNumber";
+import * as Schema from "./Schema";
+import { PkiObject, PkiObjectParameters } from "./PkiObject";
+import { AsnError } from "./errors";
+
+const VERSION = "version";
+const SID = "sid";
+const DIGEST_ALGORITHM = "digestAlgorithm";
+const SIGNED_ATTRS = "signedAttrs";
+const SIGNATURE_ALGORITHM = "signatureAlgorithm";
+const SIGNATURE = "signature";
+const UNSIGNED_ATTRS = "unsignedAttrs";
+const SIGNER_INFO = "SignerInfo";
+const SIGNER_INFO_VERSION = `${SIGNER_INFO}.${VERSION}`;
+const SIGNER_INFO_SID = `${SIGNER_INFO}.${SID}`;
+const SIGNER_INFO_DIGEST_ALGORITHM = `${SIGNER_INFO}.${DIGEST_ALGORITHM}`;
+const SIGNER_INFO_SIGNED_ATTRS = `${SIGNER_INFO}.${SIGNED_ATTRS}`;
+const SIGNER_INFO_SIGNATURE_ALGORITHM = `${SIGNER_INFO}.${SIGNATURE_ALGORITHM}`;
+const SIGNER_INFO_SIGNATURE = `${SIGNER_INFO}.${SIGNATURE}`;
+const SIGNER_INFO_UNSIGNED_ATTRS = `${SIGNER_INFO}.${UNSIGNED_ATTRS}`;
+const CLEAR_PROPS = [
+ SIGNER_INFO_VERSION,
+ SIGNER_INFO_SID,
+ SIGNER_INFO_DIGEST_ALGORITHM,
+ SIGNER_INFO_SIGNED_ATTRS,
+ SIGNER_INFO_SIGNATURE_ALGORITHM,
+ SIGNER_INFO_SIGNATURE,
+ SIGNER_INFO_UNSIGNED_ATTRS
+];
+
+export interface ISignerInfo {
+ version: number;
+ sid: Schema.SchemaType;
+ digestAlgorithm: AlgorithmIdentifier;
+ signedAttrs?: SignedAndUnsignedAttributes;
+ signatureAlgorithm: AlgorithmIdentifier;
+ signature: asn1js.OctetString;
+ unsignedAttrs?: SignedAndUnsignedAttributes;
+}
+
+export interface SignerInfoJson {
+ version: number;
+ sid?: Schema.SchemaType;
+ digestAlgorithm: AlgorithmIdentifierJson;
+ signedAttrs?: SignedAndUnsignedAttributesJson;
+ signatureAlgorithm: AlgorithmIdentifierJson;
+ signature: asn1js.OctetStringJson;
+ unsignedAttrs?: SignedAndUnsignedAttributesJson;
+}
+
+export type SignerInfoParameters = PkiObjectParameters & Partial<ISignerInfo>;
+
+/**
+ * Represents the SignerInfo structure described in [RFC5652](https://datatracker.ietf.org/doc/html/rfc5652)
+ */
+export class SignerInfo extends PkiObject implements ISignerInfo {
+
+ public static override CLASS_NAME = "SignerInfo";
+
+ public version!: number;
+ public sid: Schema.SchemaType;
+ public digestAlgorithm!: AlgorithmIdentifier;
+ public signedAttrs?: SignedAndUnsignedAttributes;
+ public signatureAlgorithm!: AlgorithmIdentifier;
+ public signature!: asn1js.OctetString;
+ public unsignedAttrs?: SignedAndUnsignedAttributes;
+
+ /**
+ * Initializes a new instance of the {@link SignerInfo} class
+ * @param parameters Initialization parameters
+ */
+ constructor(parameters: SignerInfoParameters = {}) {
+ super();
+
+ this.version = pvutils.getParametersValue(parameters, VERSION, SignerInfo.defaultValues(VERSION));
+ this.sid = pvutils.getParametersValue(parameters, SID, SignerInfo.defaultValues(SID));
+ this.digestAlgorithm = pvutils.getParametersValue(parameters, DIGEST_ALGORITHM, SignerInfo.defaultValues(DIGEST_ALGORITHM));
+ if (SIGNED_ATTRS in parameters) {
+ this.signedAttrs = pvutils.getParametersValue(parameters, SIGNED_ATTRS, SignerInfo.defaultValues(SIGNED_ATTRS));
+ }
+ this.signatureAlgorithm = pvutils.getParametersValue(parameters, SIGNATURE_ALGORITHM, SignerInfo.defaultValues(SIGNATURE_ALGORITHM));
+ this.signature = pvutils.getParametersValue(parameters, SIGNATURE, SignerInfo.defaultValues(SIGNATURE));
+ if (UNSIGNED_ATTRS in parameters) {
+ this.unsignedAttrs = pvutils.getParametersValue(parameters, UNSIGNED_ATTRS, SignerInfo.defaultValues(UNSIGNED_ATTRS));
+ }
+
+ 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
+ */
+ public static override defaultValues(memberName: typeof VERSION): number;
+ public static override defaultValues(memberName: typeof SID): Schema.SchemaType;
+ public static override defaultValues(memberName: typeof DIGEST_ALGORITHM): AlgorithmIdentifier;
+ public static override defaultValues(memberName: typeof SIGNED_ATTRS): SignedAndUnsignedAttributes;
+ public static override defaultValues(memberName: typeof SIGNATURE_ALGORITHM): AlgorithmIdentifier;
+ public static override defaultValues(memberName: typeof SIGNATURE): asn1js.OctetString;
+ public static override defaultValues(memberName: typeof UNSIGNED_ATTRS): SignedAndUnsignedAttributes;
+ public static override defaultValues(memberName: string): any {
+ switch (memberName) {
+ case VERSION:
+ return 0;
+ case SID:
+ return new asn1js.Any();
+ case DIGEST_ALGORITHM:
+ return new AlgorithmIdentifier();
+ case SIGNED_ATTRS:
+ return new SignedAndUnsignedAttributes({ type: 0 });
+ case SIGNATURE_ALGORITHM:
+ return new AlgorithmIdentifier();
+ case SIGNATURE:
+ return new asn1js.OctetString();
+ case UNSIGNED_ATTRS:
+ return new SignedAndUnsignedAttributes({ type: 1 });
+ default:
+ return super.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
+ */
+ public static compareWithDefault(memberName: string, memberValue: any): boolean {
+ switch (memberName) {
+ case VERSION:
+ return (SignerInfo.defaultValues(VERSION) === memberValue);
+ case SID:
+ return (memberValue instanceof asn1js.Any);
+ case DIGEST_ALGORITHM:
+ if ((memberValue instanceof AlgorithmIdentifier) === false)
+ return false;
+
+ return memberValue.isEqual(SignerInfo.defaultValues(DIGEST_ALGORITHM));
+ case SIGNED_ATTRS:
+ return ((SignedAndUnsignedAttributes.compareWithDefault("type", memberValue.type))
+ && (SignedAndUnsignedAttributes.compareWithDefault("attributes", memberValue.attributes))
+ && (SignedAndUnsignedAttributes.compareWithDefault("encodedValue", memberValue.encodedValue)));
+ case SIGNATURE_ALGORITHM:
+ if ((memberValue instanceof AlgorithmIdentifier) === false)
+ return false;
+
+ return memberValue.isEqual(SignerInfo.defaultValues(SIGNATURE_ALGORITHM));
+ case SIGNATURE:
+ case UNSIGNED_ATTRS:
+ return ((SignedAndUnsignedAttributes.compareWithDefault("type", memberValue.type))
+ && (SignedAndUnsignedAttributes.compareWithDefault("attributes", memberValue.attributes))
+ && (SignedAndUnsignedAttributes.compareWithDefault("encodedValue", memberValue.encodedValue)));
+ default:
+ return super.defaultValues(memberName);
+ }
+ }
+
+ /**
+ * @inheritdoc
+ * @asn ASN.1 schema
+ * ```asn
+ * SignerInfo ::= SEQUENCE {
+ * version CMSVersion,
+ * sid SignerIdentifier,
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
+ * signatureAlgorithm SignatureAlgorithmIdentifier,
+ * signature SignatureValue,
+ * unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
+ *
+ * SignerIdentifier ::= CHOICE {
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * subjectKeyIdentifier [0] SubjectKeyIdentifier }
+ *
+ * SubjectKeyIdentifier ::= OCTET STRING
+ *```
+ */
+ public static override schema(parameters: Schema.SchemaParameters<{
+ version?: string;
+ sidSchema?: IssuerAndSerialNumberSchema;
+ sid?: string;
+ digestAlgorithm?: AlgorithmIdentifierSchema;
+ signedAttrs?: SignedAndUnsignedAttributesSchema;
+ signatureAlgorithm?: AlgorithmIdentifierSchema;
+ signature?: string;
+ unsignedAttrs?: SignedAndUnsignedAttributesSchema;
+ }> = {}): Schema.SchemaType {
+ const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
+
+ return (
+ new asn1js.Sequence({
+ name: SIGNER_INFO,
+ value: [
+ new asn1js.Integer({ name: (names.version || SIGNER_INFO_VERSION) }),
+ new asn1js.Choice({
+ value: [
+ IssuerAndSerialNumber.schema(names.sidSchema || {
+ names: {
+ blockName: SIGNER_INFO_SID
+ }
+ }),
+ new asn1js.Choice({
+ value: [
+ new asn1js.Constructed({
+ optional: true,
+ name: (names.sid || SIGNER_INFO_SID),
+ idBlock: {
+ tagClass: 3, // CONTEXT-SPECIFIC
+ tagNumber: 0 // [0]
+ },
+ value: [new asn1js.OctetString()]
+ }),
+ new asn1js.Primitive({
+ optional: true,
+ name: (names.sid || SIGNER_INFO_SID),
+ idBlock: {
+ tagClass: 3, // CONTEXT-SPECIFIC
+ tagNumber: 0 // [0]
+ }
+ }),
+ ]
+ }),
+ ]
+ }),
+ AlgorithmIdentifier.schema(names.digestAlgorithm || {
+ names: {
+ blockName: SIGNER_INFO_DIGEST_ALGORITHM
+ }
+ }),
+ SignedAndUnsignedAttributes.schema(names.signedAttrs || {
+ names: {
+ blockName: SIGNER_INFO_SIGNED_ATTRS,
+ tagNumber: 0
+ }
+ }),
+ AlgorithmIdentifier.schema(names.signatureAlgorithm || {
+ names: {
+ blockName: SIGNER_INFO_SIGNATURE_ALGORITHM
+ }
+ }),
+ new asn1js.OctetString({ name: (names.signature || SIGNER_INFO_SIGNATURE) }),
+ SignedAndUnsignedAttributes.schema(names.unsignedAttrs || {
+ names: {
+ blockName: SIGNER_INFO_UNSIGNED_ATTRS,
+ tagNumber: 1
+ }
+ })
+ ]
+ })
+ );
+ }
+
+ public fromSchema(schema: Schema.SchemaType): void {
+ // Clear input data first
+ pvutils.clearProps(schema, CLEAR_PROPS);
+
+ // Check the schema is valid
+ const asn1 = asn1js.compareSchema(schema,
+ schema,
+ SignerInfo.schema()
+ );
+ AsnError.assertSchema(asn1, this.className);
+
+ // Get internal properties from parsed schema
+ this.version = asn1.result[SIGNER_INFO_VERSION].valueBlock.valueDec;
+
+ const currentSid = asn1.result[SIGNER_INFO_SID];
+ if (currentSid.idBlock.tagClass === 1)
+ this.sid = new IssuerAndSerialNumber({ schema: currentSid });
+ else
+ this.sid = currentSid;
+
+ this.digestAlgorithm = new AlgorithmIdentifier({ schema: asn1.result[SIGNER_INFO_DIGEST_ALGORITHM] });
+ if (SIGNER_INFO_SIGNED_ATTRS in asn1.result)
+ this.signedAttrs = new SignedAndUnsignedAttributes({ type: 0, schema: asn1.result[SIGNER_INFO_SIGNED_ATTRS] });
+
+ this.signatureAlgorithm = new AlgorithmIdentifier({ schema: asn1.result[SIGNER_INFO_SIGNATURE_ALGORITHM] });
+ this.signature = asn1.result[SIGNER_INFO_SIGNATURE];
+ if (SIGNER_INFO_UNSIGNED_ATTRS in asn1.result)
+ this.unsignedAttrs = new SignedAndUnsignedAttributes({ type: 1, schema: asn1.result[SIGNER_INFO_UNSIGNED_ATTRS] });
+ }
+
+ public toSchema(): asn1js.Sequence {
+ if (SignerInfo.compareWithDefault(SID, this.sid))
+ throw new Error("Incorrectly initialized \"SignerInfo\" class");
+
+ //#region Create array for output sequence
+ const outputArray = [];
+
+ outputArray.push(new asn1js.Integer({ value: this.version }));
+
+ if (this.sid instanceof IssuerAndSerialNumber)
+ outputArray.push(this.sid.toSchema());
+ else
+ outputArray.push(this.sid);
+
+ outputArray.push(this.digestAlgorithm.toSchema());
+
+ if (this.signedAttrs) {
+ if (SignerInfo.compareWithDefault(SIGNED_ATTRS, this.signedAttrs) === false)
+ outputArray.push(this.signedAttrs.toSchema());
+ }
+
+ outputArray.push(this.signatureAlgorithm.toSchema());
+ outputArray.push(this.signature);
+
+ if (this.unsignedAttrs) {
+ if (SignerInfo.compareWithDefault(UNSIGNED_ATTRS, this.unsignedAttrs) === false)
+ outputArray.push(this.unsignedAttrs.toSchema());
+ }
+ //#endregion
+
+ //#region Construct and return new ASN.1 schema for this object
+ return (new asn1js.Sequence({
+ value: outputArray
+ }));
+ //#endregion
+ }
+
+ public toJSON(): SignerInfoJson {
+ if (SignerInfo.compareWithDefault(SID, this.sid)) {
+ throw new Error("Incorrectly initialized \"SignerInfo\" class");
+ }
+
+ const res: SignerInfoJson = {
+ version: this.version,
+ digestAlgorithm: this.digestAlgorithm.toJSON(),
+ signatureAlgorithm: this.signatureAlgorithm.toJSON(),
+ signature: this.signature.toJSON(),
+ };
+
+ if (!(this.sid instanceof asn1js.Any))
+ res.sid = this.sid.toJSON();
+
+ if (this.signedAttrs && SignerInfo.compareWithDefault(SIGNED_ATTRS, this.signedAttrs) === false) {
+ res.signedAttrs = this.signedAttrs.toJSON();
+ }
+
+ if (this.unsignedAttrs && SignerInfo.compareWithDefault(UNSIGNED_ATTRS, this.unsignedAttrs) === false) {
+ res.unsignedAttrs = this.unsignedAttrs.toJSON();
+ }
+
+ return res;
+ }
+
+}