src/AttributeCertificateV1.js
import * as asn1js from "asn1js";
import { getParametersValue, clearProps } from "pvutils";
import GeneralNames from "./GeneralNames.js";
import AlgorithmIdentifier from "./AlgorithmIdentifier.js";
import Attribute from "./Attribute.js";
import Extensions from "./Extensions.js";
//**************************************************************************************
/**
* Class from RFC5755
*/
export class AttCertValidityPeriod
{
//**********************************************************************************
/**
* Constructor for AttCertValidityPeriod class
* @param {Object} [parameters={}]
* @property {Object} [schema] asn1js parsed value
*/
constructor(parameters = {})
{
//region Internal properties of the object
/**
* @type {GeneralizedTime}
* @description notBeforeTime
*/
this.notBeforeTime = getParametersValue(parameters, "notBeforeTime", AttCertValidityPeriod.defaultValues("notBeforeTime"));
/**
* @type {GeneralizedTime}
* @description notAfterTime
*/
this.notAfterTime = getParametersValue(parameters, "notAfterTime", AttCertValidityPeriod.defaultValues("notAfterTime"));
//endregion
//region If input argument array contains "schema" for this object
if("schema" in parameters)
this.fromSchema(parameters.schema);
//endregion
}
//**********************************************************************************
/**
* Return default values for all class members
* @param {string} memberName String name for a class member
*/
static defaultValues(memberName)
{
switch(memberName)
{
case "notBeforeTime":
case "notAfterTime":
return new Date(0, 0, 0);
default:
throw new Error(`Invalid member name for AttCertValidityPeriod class: ${memberName}`);
}
}
//**********************************************************************************
/**
* Return value of asn1js schema for current class
* @param {Object} parameters Input parameters for the schema
* @returns {Object} asn1js schema object
*/
static schema(parameters = {})
{
// AttCertValidityPeriod ::= SEQUENCE {
// notBeforeTime GeneralizedTime,
// notAfterTime GeneralizedTime
// }
/**
* @type {Object}
* @property {string} [blockName]
* @property {string} [notBeforeTime]
* @property {string} [notAfterTime]
*/
const names = getParametersValue(parameters, "names", {});
return (new asn1js.Sequence({
name: (names.blockName || ""),
value: [
new asn1js.GeneralizedTime({ name: (names.notBeforeTime || "") }),
new asn1js.GeneralizedTime({ name: (names.notAfterTime || "") })
]
}));
}
//**********************************************************************************
/**
* Convert parsed asn1js object into current class
* @param {!Object} schema
*/
fromSchema(schema)
{
//region Clear input data first
clearProps(schema, [
"notBeforeTime",
"notAfterTime"
]);
//endregion
//region Check the schema is valid
const asn1 = asn1js.compareSchema(schema,
schema,
AttCertValidityPeriod.schema({
names: {
notBeforeTime: "notBeforeTime",
notAfterTime: "notAfterTime"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for AttCertValidityPeriod");
//endregion
//region Get internal properties from parsed schema
this.notBeforeTime = asn1.result.notBeforeTime.toDate();
this.notAfterTime = asn1.result.notAfterTime.toDate();
//endregion
}
//**********************************************************************************
/**
* Convert current object to asn1js object and set correct values
* @returns {Object} asn1js object
*/
toSchema()
{
//region Construct and return new ASN.1 schema for this object
return (new asn1js.Sequence({
value: [
new asn1js.GeneralizedTime({ valueDate: this.notBeforeTime }),
new asn1js.GeneralizedTime({ valueDate: this.notAfterTime }),
]
}));
//endregion
}
//**********************************************************************************
/**
* Convertion for the class to JSON object
* @returns {Object}
*/
toJSON()
{
return {
notBeforeTime: this.notBeforeTime,
notAfterTime: this.notAfterTime
};
}
//**********************************************************************************
}
//**************************************************************************************
/**
* Class from RFC5755
*/
export class IssuerSerial
{
//**********************************************************************************
/**
* Constructor for IssuerSerial class
* @param {Object} [parameters={}]
* @property {Object} [schema] asn1js parsed value
*/
constructor(parameters = {})
{
//region Internal properties of the object
/**
* @type {RelativeDistinguishedNames}
* @description issuer
*/
this.issuer = getParametersValue(parameters, "issuer", IssuerSerial.defaultValues("issuer"));
/**
* @type {Integer}
* @description serialNumber
*/
this.serialNumber = getParametersValue(parameters, "serialNumber", IssuerSerial.defaultValues("serialNumber"));
if("issuerUID" in parameters)
/**
* @type {BitString}
* @description issuerUID
*/
this.issuerUID = getParametersValue(parameters, "issuerUID", IssuerSerial.defaultValues("issuerUID"));
//endregion
//region If input argument array contains "schema" for this object
if("schema" in parameters)
this.fromSchema(parameters.schema);
//endregion
}
//**********************************************************************************
/**
* Return default values for all class members
* @param {string} memberName String name for a class member
*/
static defaultValues(memberName)
{
switch(memberName)
{
case "issuer":
return new GeneralNames();
case "serialNumber":
return new asn1js.Integer();
case "issuerUID":
return new asn1js.BitString();
default:
throw new Error(`Invalid member name for IssuerSerial class: ${memberName}`);
}
}
//**********************************************************************************
/**
* Return value of asn1js schema for current class
* @param {Object} parameters Input parameters for the schema
* @returns {Object} asn1js schema object
*/
static schema(parameters = {})
{
// IssuerSerial ::= SEQUENCE {
// issuer GeneralNames,
// serial CertificateSerialNumber,
// issuerUID UniqueIdentifier OPTIONAL
// }
//
// CertificateSerialNumber ::= INTEGER
// UniqueIdentifier ::= BIT STRING
/**
* @type {Object}
* @property {string} [blockName]
* @property {string} [issuer]
* @property {string} [serialNumber]
* @property {string} [issuerUID]
*/
const names = getParametersValue(parameters, "names", {});
return (new asn1js.Sequence({
name: (names.blockName || ""),
value: [
GeneralNames.schema(names.issuer || {}),
new asn1js.Integer({ name: (names.serialNumber || "") }),
new asn1js.BitString({
optional: true,
name: (names.issuerUID || "")
})
]
}));
}
//**********************************************************************************
/**
* Convert parsed asn1js object into current class
* @param {!Object} schema
*/
fromSchema(schema)
{
//region Clear input data first
clearProps(schema, [
"issuer",
"serialNumber",
"issuerUID"
]);
//endregion
//region Check the schema is valid
const asn1 = asn1js.compareSchema(schema,
schema,
IssuerSerial.schema({
names: {
issuer: {
names: {
blockName: "issuer"
}
},
serialNumber: "serialNumber",
issuerUID: "issuerUID"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for IssuerSerial");
//endregion
//region Get internal properties from parsed schema
this.issuer = new GeneralNames({ schema: asn1.result.issuer });
this.serialNumber = asn1.result.serialNumber;
if("issuerUID" in asn1.result)
this.issuerUID = asn1.result.issuerUID;
//endregion
}
//**********************************************************************************
/**
* Convert current object to asn1js object and set correct values
* @returns {Object} asn1js object
*/
toSchema()
{
const result = new asn1js.Sequence({
value: [
this.issuer.toSchema(),
this.serialNumber
]
});
if("issuerUID" in this)
result.valueBlock.value.push(this.issuerUID);
//region Construct and return new ASN.1 schema for this object
return result;
//endregion
}
//**********************************************************************************
/**
* Convertion for the class to JSON object
* @returns {Object}
*/
toJSON()
{
const result = {
issuer: this.issuer.toJSON(),
serialNumber: this.serialNumber.toJSON()
};
if("issuerUID" in this)
result.issuerUID = this.issuerUID.toJSON();
return result;
}
//**********************************************************************************
}
//**************************************************************************************
/**
* Class from RFC5755
*/
export class AttributeCertificateInfoV1
{
//**********************************************************************************
/**
* Constructor for AttributeCertificateInfoV1 class
* @param {Object} [parameters={}]
* @property {Object} [schema] asn1js parsed value
*/
constructor(parameters = {})
{
//region Internal properties of the object
/**
* @type {Number}
* @description version
*/
this.version = getParametersValue(parameters, "version", AttributeCertificateInfoV1.defaultValues("version"));
if("baseCertificateID" in parameters)
/**
* @type {IssuerSerial}
* @description baseCertificateID
*/
this.baseCertificateID = getParametersValue(parameters, "baseCertificateID", AttributeCertificateInfoV1.defaultValues("baseCertificateID"));
if("subjectName" in parameters)
/**
* @type {GeneralNames}
* @description subjectName
*/
this.subjectName = getParametersValue(parameters, "subjectName", AttributeCertificateInfoV1.defaultValues("subjectName"));
/**
* @type {GeneralNames}
* @description issuer
*/
this.issuer = getParametersValue(parameters, "issuer", AttributeCertificateInfoV1.defaultValues("issuer"));
/**
* @type {AlgorithmIdentifier}
* @description signature
*/
this.signature = getParametersValue(parameters, "signature", AttributeCertificateInfoV1.defaultValues("signature"));
/**
* @type {Integer}
* @description serialNumber
*/
this.serialNumber = getParametersValue(parameters, "serialNumber", AttributeCertificateInfoV1.defaultValues("serialNumber"));
/**
* @type {AttCertValidityPeriod}
* @description attrCertValidityPeriod
*/
this.attrCertValidityPeriod = getParametersValue(parameters, "attrCertValidityPeriod", AttributeCertificateInfoV1.defaultValues("attrCertValidityPeriod"));
/**
* @type {Array.<Attribute>}
* @description attributes
*/
this.attributes = getParametersValue(parameters, "attributes", AttributeCertificateInfoV1.defaultValues("attributes"));
if("issuerUniqueID" in parameters)
/**
* @type {BitString}
* @description issuerUniqueID
*/
this.issuerUniqueID = getParametersValue(parameters, "issuerUniqueID", AttributeCertificateInfoV1.defaultValues("issuerUniqueID"));
if("extensions" in parameters)
/**
* @type {Extensions}
* @description extensions
*/
this.extensions = getParametersValue(parameters, "extensions", AttributeCertificateInfoV1.defaultValues("extensions"));
//endregion
//region If input argument array contains "schema" for this object
if("schema" in parameters)
this.fromSchema(parameters.schema);
//endregion
}
//**********************************************************************************
/**
* Return default values for all class members
* @param {string} memberName String name for a class member
*/
static defaultValues(memberName)
{
switch(memberName)
{
case "version":
return 0;
case "baseCertificateID":
return new IssuerSerial();
case "subjectName":
return new GeneralNames();
case "issuer":
return {};
case "signature":
return new AlgorithmIdentifier();
case "serialNumber":
return new asn1js.Integer();
case "attrCertValidityPeriod":
return new AttCertValidityPeriod();
case "attributes":
return [];
case "issuerUniqueID":
return new asn1js.BitString();
case "extensions":
return new Extensions();
default:
throw new Error(`Invalid member name for AttributeCertificateInfoV1 class: ${memberName}`);
}
}
//**********************************************************************************
/**
* Return value of asn1js schema for current class
* @param {Object} parameters Input parameters for the schema
* @returns {Object} asn1js schema object
*/
static schema(parameters = {})
{
// AttributeCertificateInfo ::= SEQUENCE {
// version Version DEFAULT v1,
// subject CHOICE {
// baseCertificateID [0] IssuerSerial, -- associated with a Public Key Certificate
// subjectName [1] GeneralNames }, -- associated with a name
// issuer GeneralNames, -- CA issuing the attribute certificate
// signature AlgorithmIdentifier,
// serialNumber CertificateSerialNumber,
// attrCertValidityPeriod AttCertValidityPeriod,
// attributes SEQUENCE OF Attribute,
// issuerUniqueID UniqueIdentifier OPTIONAL,
// extensions Extensions OPTIONAL
// }
/**
* @type {Object}
* @property {string} [blockName]
* @property {string} [issuer]
* @property {string} [serialNumber]
*/
const names = getParametersValue(parameters, "names", {});
return (new asn1js.Sequence({
name: (names.blockName || ""),
value: [
new asn1js.Integer({ name: (names.version || "") }),
new asn1js.Choice({
value: [
new asn1js.Constructed({
name: (names.baseCertificateID || ""),
idBlock: {
tagClass: 3,
tagNumber: 0 // [0]
},
value: IssuerSerial.schema().valueBlock.value
}),
new asn1js.Constructed({
name: (names.subjectName || ""),
idBlock: {
tagClass: 3,
tagNumber: 1 // [2]
},
value: GeneralNames.schema().valueBlock.value
}),
]
}),
GeneralNames.schema({
names: {
blockName: (names.issuer || "")
}
}),
AlgorithmIdentifier.schema(names.signature || {}),
new asn1js.Integer({ name: (names.serialNumber || "") }),
AttCertValidityPeriod.schema(names.attrCertValidityPeriod || {}),
new asn1js.Sequence({
name: (names.attributes || ""),
value: [
new asn1js.Repeated({
value: Attribute.schema()
})
]
}),
new asn1js.BitString({
optional: true,
name: (names.issuerUniqueID || "")
}),
Extensions.schema(names.extensions || {}, true)
]
}));
}
//**********************************************************************************
/**
* Convert parsed asn1js object into current class
* @param {!Object} schema
*/
fromSchema(schema)
{
//region Clear input data first
clearProps(schema, [
"version",
"baseCertificateID",
"subjectName",
"issuer",
"signature",
"serialNumber",
"attrCertValidityPeriod",
"attributes",
"issuerUniqueID",
"extensions"
]);
//endregion
//region Check the schema is valid
const asn1 = asn1js.compareSchema(schema,
schema,
AttributeCertificateInfoV1.schema({
names: {
version: "version",
baseCertificateID: "baseCertificateID",
subjectName: "subjectName",
issuer: "issuer",
signature: {
names: {
blockName: "signature"
}
},
serialNumber: "serialNumber",
attrCertValidityPeriod: {
names: {
blockName: "attrCertValidityPeriod"
}
},
attributes: "attributes",
issuerUniqueID: "issuerUniqueID",
extensions: {
names: {
blockName: "extensions"
}
}
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for AttributeCertificateInfoV1");
//endregion
//region Get internal properties from parsed schema
this.version = asn1.result.version.valueBlock.valueDec;
if("baseCertificateID" in asn1.result)
{
this.baseCertificateID = new IssuerSerial({
schema: new asn1js.Sequence({
value: asn1.result.baseCertificateID.valueBlock.value
})
});
}
if("subjectName" in asn1.result)
{
this.subjectName = new GeneralNames({
schema: new asn1js.Sequence({
value: asn1.result.subjectName.valueBlock.value
})
});
}
this.issuer = asn1.result.issuer;
this.signature = new AlgorithmIdentifier({ schema: asn1.result.signature });
this.serialNumber = asn1.result.serialNumber;
this.attrCertValidityPeriod = new AttCertValidityPeriod({ schema: asn1.result.attrCertValidityPeriod });
this.attributes = Array.from(asn1.result.attributes.valueBlock.value, element => new Attribute({ schema: element }));
if("issuerUniqueID" in asn1.result)
this.issuerUniqueID = asn1.result.issuerUniqueID;
if("extensions" in asn1.result)
this.extensions = new Extensions({ schema: asn1.result.extensions });
//endregion
}
//**********************************************************************************
/**
* Convert current object to asn1js object and set correct values
* @returns {Object} asn1js object
*/
toSchema()
{
const result = new asn1js.Sequence({
value: [new asn1js.Integer({ value: this.version })]
});
if("baseCertificateID" in this)
{
result.valueBlock.value.push(new asn1js.Constructed({
idBlock: {
tagClass: 3,
tagNumber: 0 // [0]
},
value: this.baseCertificateID.toSchema().valueBlock.value
}));
}
if("subjectName" in this)
{
result.valueBlock.value.push(new asn1js.Constructed({
idBlock: {
tagClass: 3,
tagNumber: 1 // [1]
},
value: this.subjectName.toSchema().valueBlock.value
}));
}
result.valueBlock.value.push(this.issuer.toSchema());
result.valueBlock.value.push(this.signature.toSchema());
result.valueBlock.value.push(this.serialNumber);
result.valueBlock.value.push(this.attrCertValidityPeriod.toSchema());
result.valueBlock.value.push(new asn1js.Sequence({
value: Array.from(this.attributes, element => element.toSchema())
}));
if("issuerUniqueID" in this)
result.valueBlock.value.push(this.issuerUniqueID);
if("extensions" in this)
result.valueBlock.value.push(this.extensions.toSchema());
return result;
}
//**********************************************************************************
/**
* Convertion for the class to JSON object
* @returns {Object}
*/
toJSON()
{
const result = {
version: this.version
};
if("baseCertificateID" in this)
result.baseCertificateID = this.baseCertificateID.toJSON();
if("subjectName" in this)
result.subjectName = this.subjectName.toJSON();
result.issuer = this.issuer.toJSON();
result.signature = this.signature.toJSON();
result.serialNumber = this.serialNumber.toJSON();
result.attrCertValidityPeriod = this.attrCertValidityPeriod.toJSON();
result.attributes = Array.from(this.attributes, element => element.toJSON());
if("issuerUniqueID" in this)
result.issuerUniqueID = this.issuerUniqueID.toJSON();
if("extensions" in this)
result.extensions = this.extensions.toJSON();
return result;
}
//**********************************************************************************
}
//**************************************************************************************
/**
* Class from X.509:1997
*/
export default class AttributeCertificateV1
{
//**********************************************************************************
/**
* Constructor for AttributeCertificateV1 class
* @param {Object} [parameters={}]
* @property {Object} [schema] asn1js parsed value
*/
constructor(parameters = {})
{
//region Internal properties of the object
/**
* @type {AttributeCertificateInfoV1}
* @description acinfo
*/
this.acinfo = getParametersValue(parameters, "acinfo", AttributeCertificateV1.defaultValues("acinfo"));
/**
* @type {AlgorithmIdentifier}
* @description signatureAlgorithm
*/
this.signatureAlgorithm = getParametersValue(parameters, "signatureAlgorithm", AttributeCertificateV1.defaultValues("signatureAlgorithm"));
/**
* @type {BitString}
* @description signatureValue
*/
this.signatureValue = getParametersValue(parameters, "signatureValue", AttributeCertificateV1.defaultValues("signatureValue"));
//endregion
//region If input argument array contains "schema" for this object
if("schema" in parameters)
this.fromSchema(parameters.schema);
//endregion
}
//**********************************************************************************
/**
* Return default values for all class members
* @param {string} memberName String name for a class member
*/
static defaultValues(memberName)
{
switch(memberName)
{
case "acinfo":
return new AttributeCertificateInfoV1();
case "signatureAlgorithm":
return new AlgorithmIdentifier();
case "signatureValue":
return new asn1js.BitString();
default:
throw new Error(`Invalid member name for AttributeCertificateV1 class: ${memberName}`);
}
}
//**********************************************************************************
/**
* Return value of asn1js schema for current class
* @param {Object} parameters Input parameters for the schema
* @returns {Object} asn1js schema object
*/
static schema(parameters = {})
{
// AttributeCertificate ::= SEQUENCE {
// acinfo AttributeCertificateInfoV1,
// signatureAlgorithm AlgorithmIdentifier,
// signatureValue BIT STRING
// }
/**
* @type {Object}
* @property {string} [blockName]
* @property {Object} [acinfo]
* @property {Object} [signatureAlgorithm]
* @property {string} [signatureValue]
*/
const names = getParametersValue(parameters, "names", {});
return (new asn1js.Sequence({
name: (names.blockName || ""),
value: [
AttributeCertificateInfoV1.schema(names.acinfo || {}),
AlgorithmIdentifier.schema(names.signatureAlgorithm || {}),
new asn1js.BitString({ name: (names.signatureValue || "") })
]
}));
}
//**********************************************************************************
/**
* Convert parsed asn1js object into current class
* @param {!Object} schema
*/
fromSchema(schema)
{
//region Clear input data first
clearProps(schema, [
"acinfo",
"signatureValue",
"signatureAlgorithm"
]);
//endregion
//region Check the schema is valid
const asn1 = asn1js.compareSchema(schema,
schema,
AttributeCertificateV1.schema({
names: {
acinfo: {
names: {
blockName: "acinfo"
}
},
signatureAlgorithm: {
names: {
blockName: "signatureAlgorithm"
}
},
signatureValue: "signatureValue"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for AttributeCertificateV1");
//endregion
//region Get internal properties from parsed schema
this.acinfo = new AttributeCertificateInfoV1({ schema: asn1.result.acinfo });
this.signatureAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.signatureAlgorithm });
this.signatureValue = asn1.result.signatureValue;
//endregion
}
//**********************************************************************************
/**
* Convert current object to asn1js object and set correct values
* @returns {Object} asn1js object
*/
toSchema()
{
return (new asn1js.Sequence({
value: [
this.acinfo.toSchema(),
this.signatureAlgorithm.toSchema(),
this.signatureValue
]
}));
}
//**********************************************************************************
/**
* Convertion for the class to JSON object
* @returns {Object}
*/
toJSON()
{
return {
acinfo: this.acinfo.toJSON(),
signatureAlgorithm: this.signatureAlgorithm.toJSON(),
signatureValue: this.signatureValue.toJSON()
};
}
//**********************************************************************************
}
//**************************************************************************************