UNPKG

@small-tech/auto-encrypt

Version:

Automatically provisions and renews Let’s Encrypt TLS certificates on Node.js https servers (including Kitten, Polka, Express.js, etc.)

815 lines (730 loc) 29 kB
// Require @panva’s fork of ASN1 that’s already included as part of the Jose library. // https://github.com/panva/asn1.js/ import asn1 from '@panva/asn1.js'; /** * RFC5280 X509 and Extension Definitions * From: https://github.com/indutny/asn1.js * * (Including this directly as the Jose library we use in Auto Encrypt * already includes a fork of ASN1.js but with this RFC implementation * stripped. There’s no reason to include the whole library again.) */ // OIDs const x509OIDs = { '2 5 29 9': 'subjectDirectoryAttributes', '2 5 29 14': 'subjectKeyIdentifier', '2 5 29 15': 'keyUsage', '2 5 29 17': 'subjectAlternativeName', '2 5 29 18': 'issuerAlternativeName', '2 5 29 19': 'basicConstraints', '2 5 29 20': 'cRLNumber', '2 5 29 21': 'reasonCode', '2 5 29 24': 'invalidityDate', '2 5 29 27': 'deltaCRLIndicator', '2 5 29 28': 'issuingDistributionPoint', '2 5 29 29': 'certificateIssuer', '2 5 29 30': 'nameConstraints', '2 5 29 31': 'cRLDistributionPoints', '2 5 29 32': 'certificatePolicies', '2 5 29 33': 'policyMappings', '2 5 29 35': 'authorityKeyIdentifier', '2 5 29 36': 'policyConstraints', '2 5 29 37': 'extendedKeyUsage', '2 5 29 46': 'freshestCRL', '2 5 29 54': 'inhibitAnyPolicy', '1 3 6 1 5 5 7 1 1': 'authorityInformationAccess', '1 3 6 1 5 5 7 11': 'subjectInformationAccess' }; // CertificateList ::= SEQUENCE { // tbsCertList TBSCertList, // signatureAlgorithm AlgorithmIdentifier, // signature BIT STRING } export const CertificateList = asn1.define('CertificateList', function() { this.seq().obj( this.key('tbsCertList').use(TBSCertList), this.key('signatureAlgorithm').use(AlgorithmIdentifier), this.key('signature').bitstr() ); }); // AlgorithmIdentifier ::= SEQUENCE { // algorithm OBJECT IDENTIFIER, // parameters ANY DEFINED BY algorithm OPTIONAL } export const AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function() { this.seq().obj( this.key('algorithm').objid(), this.key('parameters').optional().any() ); }); // Certificate ::= SEQUENCE { // tbsCertificate TBSCertificate, // signatureAlgorithm AlgorithmIdentifier, // signature BIT STRING } export const Certificate = asn1.define('Certificate', function() { this.seq().obj( this.key('tbsCertificate').use(TBSCertificate), this.key('signatureAlgorithm').use(AlgorithmIdentifier), this.key('signature').bitstr() ); }); // TBSCertificate ::= SEQUENCE { // version [0] Version DEFAULT v1, // serialNumber CertificateSerialNumber, // signature AlgorithmIdentifier, // issuer Name, // validity Validity, // subject Name, // subjectPublicKeyInfo SubjectPublicKeyInfo, // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, // extensions [3] Extensions OPTIONAL export const TBSCertificate = asn1.define('TBSCertificate', function() { this.seq().obj( this.key('version').def('v1').explicit(0).use(Version), this.key('serialNumber').int(), this.key('signature').use(AlgorithmIdentifier), this.key('issuer').use(Name), this.key('validity').use(Validity), this.key('subject').use(Name), this.key('subjectPublicKeyInfo').use(SubjectPublicKeyInfo), this.key('issuerUniqueID').optional().implicit(1).bitstr(), this.key('subjectUniqueID').optional().implicit(2).bitstr(), this.key('extensions').optional().explicit(3).seqof(Extension) ); }); // Version ::= INTEGER { v1(0), v2(1), v3(2) } export const Version = asn1.define('Version', function() { this.int({ 0: 'v1', 1: 'v2', 2: 'v3' }); }); // Validity ::= SEQUENCE { // notBefore Time, // notAfter Time } export const Validity = asn1.define('Validity', function() { this.seq().obj( this.key('notBefore').use(Time), this.key('notAfter').use(Time) ); }); // Time ::= CHOICE { // utcTime UTCTime, // generalTime GeneralizedTime } export const Time = asn1.define('Time', function() { this.choice({ utcTime: this.utctime(), genTime: this.gentime() }); }); // SubjectPublicKeyInfo ::= SEQUENCE { // algorithm AlgorithmIdentifier, // subjectPublicKey BIT STRING } export const SubjectPublicKeyInfo = asn1.define('SubjectPublicKeyInfo', function() { this.seq().obj( this.key('algorithm').use(AlgorithmIdentifier), this.key('subjectPublicKey').bitstr() ); }); // TBSCertList ::= SEQUENCE { // version Version OPTIONAL, // signature AlgorithmIdentifier, // issuer Name, // thisUpdate Time, // nextUpdate Time OPTIONAL, // revokedCertificates SEQUENCE OF SEQUENCE { // userCertificate CertificateSerialNumber, // revocationDate Time, // crlEntryExtensions Extensions OPTIONAL // } OPTIONAL, // crlExtensions [0] Extensions OPTIONAL } export const TBSCertList = asn1.define('TBSCertList', function() { this.seq().obj( this.key('version').optional().int(), this.key('signature').use(AlgorithmIdentifier), this.key('issuer').use(Name), this.key('thisUpdate').use(Time), this.key('nextUpdate').use(Time), this.key('revokedCertificates').optional().seqof(RevokedCertificate), this.key('crlExtensions').explicit(0).optional().seqof(Extension) ); }); const RevokedCertificate = asn1.define('RevokedCertificate', function() { this.seq().obj( this.key('userCertificate').use(CertificateSerialNumber), this.key('revocationDate').use(Time), this.key('crlEntryExtensions').optional().seqof(Extension) ); }); // Extension ::= SEQUENCE { // extnID OBJECT IDENTIFIER, // critical BOOLEAN DEFAULT FALSE, // extnValue OCTET STRING } export const Extension = asn1.define('Extension', function() { this.seq().obj( this.key('extnID').objid(x509OIDs), this.key('critical').bool().def(false), this.key('extnValue').octstr().contains(function(obj) { const out = x509Extensions[obj.extnID]; // Cope with unknown extensions return out ? out : asn1.define('OctString', function() { this.any(); }); }) ); }); // Name ::= CHOICE { -- only one possibility for now -- // rdnSequence RDNSequence } export const Name = asn1.define('Name', function() { this.choice({ rdnSequence: this.use(RDNSequence) }); }); // GeneralName ::= CHOICE { // otherName [0] AnotherName, // rfc822Name [1] IA5String, // dNSName [2] IA5String, // x400Address [3] ORAddress, // directoryName [4] Name, // ediPartyName [5] EDIPartyName, // uniformResourceIdentifier [6] IA5String, // iPAddress [7] OCTET STRING, // registeredID [8] OBJECT IDENTIFIER } export const GeneralName = asn1.define('GeneralName', function() { this.choice({ otherName: this.implicit(0).use(AnotherName), rfc822Name: this.implicit(1).ia5str(), dNSName: this.implicit(2).ia5str(), directoryName: this.explicit(4).use(Name), ediPartyName: this.implicit(5).use(EDIPartyName), uniformResourceIdentifier: this.implicit(6).ia5str(), iPAddress: this.implicit(7).octstr(), registeredID: this.implicit(8).objid() }); }); // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName export const GeneralNames = asn1.define('GeneralNames', function() { this.seqof(GeneralName); }); // AnotherName ::= SEQUENCE { // type-id OBJECT IDENTIFIER, // value [0] EXPLICIT ANY DEFINED BY type-id } export const AnotherName = asn1.define('AnotherName', function() { this.seq().obj( this.key('type-id').objid(), this.key('value').explicit(0).any() ); }); // EDIPartyName ::= SEQUENCE { // nameAssigner [0] DirectoryString OPTIONAL, // partyName [1] DirectoryString } export const EDIPartyName = asn1.define('EDIPartyName', function() { this.seq().obj( this.key('nameAssigner').implicit(0).optional().use(DirectoryString), this.key('partyName').implicit(1).use(DirectoryString) ); }); // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName export const RDNSequence = asn1.define('RDNSequence', function() { this.seqof(RelativeDistinguishedName); }); // RelativeDistinguishedName ::= // SET SIZE (1..MAX) OF AttributeTypeAndValue export const RelativeDistinguishedName = asn1.define('RelativeDistinguishedName', function() { this.setof(AttributeTypeAndValue); }); // AttributeTypeAndValue ::= SEQUENCE { // type AttributeType, // value AttributeValue } export const AttributeTypeAndValue = asn1.define('AttributeTypeAndValue', function() { this.seq().obj( this.key('type').use(AttributeType), this.key('value').use(AttributeValue) ); }); // Attribute ::= SEQUENCE { // type AttributeType, // values SET OF AttributeValue } export const Attribute = asn1.define('Attribute', function() { this.seq().obj( this.key('type').use(AttributeType), this.key('values').setof(AttributeValue) ); }); // AttributeType ::= OBJECT IDENTIFIER export const AttributeType = asn1.define('AttributeType', function() { this.objid(); }); // AttributeValue ::= ANY -- DEFINED BY AttributeType export const AttributeValue = asn1.define('AttributeValue', function() { this.any(); }); // DirectoryString ::= CHOICE { // teletexString TeletexString (SIZE (1..MAX)), // printableString PrintableString (SIZE (1..MAX)), // universalString UniversalString (SIZE (1..MAX)), // utf8String UTF8String (SIZE (1..MAX)), // bmpString BMPString (SIZE (1..MAX)) } export const DirectoryString = asn1.define('DirectoryString', function() { this.choice({ teletexString: this.t61str(), printableString: this.printstr(), universalString: this.unistr(), utf8String: this.utf8str(), bmpString: this.bmpstr() }); }); // AuthorityKeyIdentifier ::= SEQUENCE { // keyIdentifier [0] KeyIdentifier OPTIONAL, // authorityCertIssuer [1] GeneralNames OPTIONAL, // authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } export const AuthorityKeyIdentifier = asn1.define('AuthorityKeyIdentifier', function() { this.seq().obj( this.key('keyIdentifier').implicit(0).optional().use(KeyIdentifier), this.key('authorityCertIssuer').implicit(1).optional().use(GeneralNames), this.key('authorityCertSerialNumber').implicit(2).optional() .use(CertificateSerialNumber) ); }); // KeyIdentifier ::= OCTET STRING export const KeyIdentifier = asn1.define('KeyIdentifier', function() { this.octstr(); }); // CertificateSerialNumber ::= INTEGER export const CertificateSerialNumber = asn1.define('CertificateSerialNumber', function() { this.int(); }); // ORAddress ::= SEQUENCE { // built-in-standard-attributes BuiltInStandardAttributes, // built-in-domain-defined-attributes BuiltInDomainDefinedAttributes // OPTIONAL, // extension-attributes ExtensionAttributes OPTIONAL } export const ORAddress = asn1.define('ORAddress', function() { this.seq().obj( this.key('builtInStandardAttributes').use(BuiltInStandardAttributes), this.key('builtInDomainDefinedAttributes').optional() .use(BuiltInDomainDefinedAttributes), this.key('extensionAttributes').optional().use(ExtensionAttributes) ); }); // BuiltInStandardAttributes ::= SEQUENCE { // country-name CountryName OPTIONAL, // administration-domain-name AdministrationDomainName OPTIONAL, // network-address [0] IMPLICIT NetworkAddress OPTIONAL, // terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL, // private-domain-name [2] PrivateDomainName OPTIONAL, // organization-name [3] IMPLICIT OrganizationName OPTIONAL, // numeric-user-identifier [4] IMPLICIT NumericUserIdentifier OPTIONAL, // personal-name [5] IMPLICIT PersonalName OPTIONAL, // organizational-unit-names [6] IMPLICIT OrganizationalUnitNames OPTIONAL } export const BuiltInStandardAttributes = asn1.define('BuiltInStandardAttributes', function() { this.seq().obj( this.key('countryName').optional().use(CountryName), this.key('administrationDomainName').optional() .use(AdministrationDomainName), this.key('networkAddress').implicit(0).optional().use(NetworkAddress), this.key('terminalIdentifier').implicit(1).optional() .use(TerminalIdentifier), this.key('privateDomainName').explicit(2).optional().use(PrivateDomainName), this.key('organizationName').implicit(3).optional().use(OrganizationName), this.key('numericUserIdentifier').implicit(4).optional() .use(NumericUserIdentifier), this.key('personalName').implicit(5).optional().use(PersonalName), this.key('organizationalUnitNames').implicit(6).optional() .use(OrganizationalUnitNames) ); }); // CountryName ::= CHOICE { // x121-dcc-code NumericString, // iso-3166-alpha2-code PrintableString } export const CountryName = asn1.define('CountryName', function() { this.choice({ x121DccCode: this.numstr(), iso3166Alpha2Code: this.printstr() }); }); // AdministrationDomainName ::= CHOICE { // numeric NumericString, // printable PrintableString } export const AdministrationDomainName = asn1.define('AdministrationDomainName', function() { this.choice({ numeric: this.numstr(), printable: this.printstr() }); }); // NetworkAddress ::= X121Address export const NetworkAddress = asn1.define('NetworkAddress', function() { this.use(X121Address); }); // X121Address ::= NumericString export const X121Address = asn1.define('X121Address', function() { this.numstr(); }); // TerminalIdentifier ::= PrintableString export const TerminalIdentifier = asn1.define('TerminalIdentifier', function() { this.printstr(); }); // PrivateDomainName ::= CHOICE { // numeric NumericString, // printable PrintableString } export const PrivateDomainName = asn1.define('PrivateDomainName', function() { this.choice({ numeric: this.numstr(), printable: this.printstr() }); }); // OrganizationName ::= PrintableString export const OrganizationName = asn1.define('OrganizationName', function() { this.printstr(); }); // NumericUserIdentifier ::= NumericString export const NumericUserIdentifier = asn1.define('NumericUserIdentifier', function() { this.numstr(); }); // PersonalName ::= SET { // surname [0] IMPLICIT PrintableString, // given-name [1] IMPLICIT PrintableString OPTIONAL, // initials [2] IMPLICIT PrintableString OPTIONAL, // generation-qualifier [3] IMPLICIT PrintableString OPTIONAL } export const PersonalName = asn1.define('PersonalName', function() { this.set().obj( this.key('surname').implicit(0).printstr(), this.key('givenName').implicit(1).printstr(), this.key('initials').implicit(2).printstr(), this.key('generationQualifier').implicit(3).printstr() ); }); // OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) // OF OrganizationalUnitName export const OrganizationalUnitNames = asn1.define('OrganizationalUnitNames', function() { this.seqof(OrganizationalUnitName); }); // OrganizationalUnitName ::= PrintableString (SIZE // (1..ub-organizational-unit-name-length)) export const OrganizationalUnitName = asn1.define('OrganizationalUnitName', function() { this.printstr(); }); // uiltInDomainDefinedAttributes ::= SEQUENCE SIZE // (1..ub-domain-defined-attributes) // OF BuiltInDomainDefinedAttribute export const BuiltInDomainDefinedAttributes = asn1.define( 'BuiltInDomainDefinedAttributes', function() { this.seqof(BuiltInDomainDefinedAttribute); }); // BuiltInDomainDefinedAttribute ::= SEQUENCE { // type PrintableString (SIZE (1..ub-domain-defined-attribute-type-length)), // value PrintableString (SIZE (1..ub-domain-defined-attribute-value-length)) //} export const BuiltInDomainDefinedAttribute = asn1.define('BuiltInDomainDefinedAttribute', function() { this.seq().obj( this.key('type').printstr(), this.key('value').printstr() ); }); // ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF // ExtensionAttribute export const ExtensionAttributes = asn1.define('ExtensionAttributes', function() { this.seqof(ExtensionAttribute); }); // ExtensionAttribute ::= SEQUENCE { // extension-attribute-type [0] IMPLICIT INTEGER, // extension-attribute-value [1] ANY DEFINED BY extension-attribute-type } export const ExtensionAttribute = asn1.define('ExtensionAttribute', function() { this.seq().obj( this.key('extensionAttributeType').implicit(0).int(), this.key('extensionAttributeValue').any().explicit(1).int() ); }); // SubjectKeyIdentifier ::= KeyIdentifier export const SubjectKeyIdentifier = asn1.define('SubjectKeyIdentifier', function() { this.use(KeyIdentifier); }); // KeyUsage ::= BIT STRING { // digitalSignature (0), // nonRepudiation (1), -- recent editions of X.509 have // -- renamed this bit to contentCommitment // keyEncipherment (2), // dataEncipherment (3), // keyAgreement (4), // keyCertSign (5), // cRLSign (6), // encipherOnly (7), // decipherOnly (8) } export const KeyUsage = asn1.define('KeyUsage', function() { this.bitstr(); }); // CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation export const CertificatePolicies = asn1.define('CertificatePolicies', function() { this.seqof(PolicyInformation); }); // PolicyInformation ::= SEQUENCE { // policyIdentifier CertPolicyId, // policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo // OPTIONAL } export const PolicyInformation = asn1.define('PolicyInformation', function() { this.seq().obj( this.key('policyIdentifier').use(CertPolicyId), this.key('policyQualifiers').optional().use(PolicyQualifiers) ); }); // CertPolicyId ::= OBJECT IDENTIFIER export const CertPolicyId = asn1.define('CertPolicyId', function() { this.objid(); }); export const PolicyQualifiers = asn1.define('PolicyQualifiers', function() { this.seqof(PolicyQualifierInfo); }); // PolicyQualifierInfo ::= SEQUENCE { // policyQualifierId PolicyQualifierId, // qualifier ANY DEFINED BY policyQualifierId } export const PolicyQualifierInfo = asn1.define('PolicyQualifierInfo', function() { this.seq().obj( this.key('policyQualifierId').use(PolicyQualifierId), this.key('qualifier').any() ); }); // PolicyQualifierId ::= OBJECT IDENTIFIER export const PolicyQualifierId = asn1.define('PolicyQualifierId', function() { this.objid(); }); // PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { // issuerDomainPolicy CertPolicyId, // subjectDomainPolicy CertPolicyId } export const PolicyMappings = asn1.define('PolicyMappings', function() { this.seqof(PolicyMapping); }); export const PolicyMapping = asn1.define('PolicyMapping', function() { this.seq().obj( this.key('issuerDomainPolicy').use(CertPolicyId), this.key('subjectDomainPolicy').use(CertPolicyId) ); }); // SubjectAltName ::= GeneralNames export const SubjectAlternativeName = asn1.define('SubjectAlternativeName', function() { this.use(GeneralNames); }); // IssuerAltName ::= GeneralNames export const IssuerAlternativeName = asn1.define('IssuerAlternativeName', function() { this.use(GeneralNames); }); // SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute export const SubjectDirectoryAttributes = asn1.define('SubjectDirectoryAttributes', function() { this.seqof(Attribute); }); // BasicConstraints ::= SEQUENCE { // cA BOOLEAN DEFAULT FALSE, // pathLenConstraint INTEGER (0..MAX) OPTIONAL } export const BasicConstraints = asn1.define('BasicConstraints', function() { this.seq().obj( this.key('cA').bool().def(false), this.key('pathLenConstraint').optional().int() ); }); // NameConstraints ::= SEQUENCE { // permittedSubtrees [0] GeneralSubtrees OPTIONAL, // excludedSubtrees [1] GeneralSubtrees OPTIONAL } export const NameConstraints = asn1.define('NameConstraints', function() { this.seq().obj( this.key('permittedSubtrees').implicit(0).optional().use(GeneralSubtrees), this.key('excludedSubtrees').implicit(1).optional().use(GeneralSubtrees) ); }); // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree export const GeneralSubtrees = asn1.define('GeneralSubtrees', function() { this.seqof(GeneralSubtree); }); // GeneralSubtree ::= SEQUENCE { // base GeneralName, // minimum [0] BaseDistance DEFAULT 0, // maximum [1] BaseDistance OPTIONAL } export const GeneralSubtree = asn1.define('GeneralSubtree', function() { this.seq().obj( this.key('base').use(GeneralName), this.key('minimum').implicit(0).def(0).use(BaseDistance), this.key('maximum').implicit(0).optional().use(BaseDistance) ); }); // BaseDistance ::= INTEGER export const BaseDistance = asn1.define('BaseDistance', function() { this.int(); }); // PolicyConstraints ::= SEQUENCE { // requireExplicitPolicy [0] SkipCerts OPTIONAL, // inhibitPolicyMapping [1] SkipCerts OPTIONAL } export const PolicyConstraints = asn1.define('PolicyConstraints', function() { this.seq().obj( this.key('requireExplicitPolicy').implicit(0).optional().use(SkipCerts), this.key('inhibitPolicyMapping').implicit(1).optional().use(SkipCerts) ); }); // SkipCerts ::= INTEGER export const SkipCerts = asn1.define('SkipCerts', function() { this.int(); }); // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId export const ExtendedKeyUsage = asn1.define('ExtendedKeyUsage', function() { this.seqof(KeyPurposeId); }); // KeyPurposeId ::= OBJECT IDENTIFIER export const KeyPurposeId = asn1.define('KeyPurposeId', function() { this.objid(); }); // RLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint export const CRLDistributionPoints = asn1.define('CRLDistributionPoints', function() { this.seqof(DistributionPoint); }); // DistributionPoint ::= SEQUENCE { // distributionPoint [0] DistributionPointName OPTIONAL, // reasons [1] ReasonFlags OPTIONAL, // cRLIssuer [2] GeneralNames OPTIONAL } export const DistributionPoint = asn1.define('DistributionPoint', function() { this.seq().obj( this.key('distributionPoint').optional().explicit(0) .use(DistributionPointName), this.key('reasons').optional().implicit(1).use(ReasonFlags), this.key('cRLIssuer').optional().implicit(2).use(GeneralNames) ); }); // DistributionPointName ::= CHOICE { // fullName [0] GeneralNames, // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } export const DistributionPointName = asn1.define('DistributionPointName', function() { this.choice({ fullName: this.implicit(0).use(GeneralNames), nameRelativeToCRLIssuer: this.implicit(1).use(RelativeDistinguishedName) }); }); // ReasonFlags ::= BIT STRING { // unused (0), // keyCompromise (1), // cACompromise (2), // affiliationChanged (3), // superseded (4), // cessationOfOperation (5), // certificateHold (6), // privilegeWithdrawn (7), // aACompromise (8) } export const ReasonFlags = asn1.define('ReasonFlags', function() { this.bitstr(); }); // InhibitAnyPolicy ::= SkipCerts export const InhibitAnyPolicy = asn1.define('InhibitAnyPolicy', function() { this.use(SkipCerts); }); // FreshestCRL ::= CRLDistributionPoints export const FreshestCRL = asn1.define('FreshestCRL', function() { this.use(CRLDistributionPoints); }); // AuthorityInfoAccessSyntax ::= // SEQUENCE SIZE (1..MAX) OF AccessDescription export const AuthorityInfoAccessSyntax = asn1.define('AuthorityInfoAccessSyntax', function() { this.seqof(AccessDescription); }); // AccessDescription ::= SEQUENCE { // accessMethod OBJECT IDENTIFIER, // accessLocation GeneralName } export const AccessDescription = asn1.define('AccessDescription', function() { this.seq().obj( this.key('accessMethod').objid(), this.key('accessLocation').use(GeneralName) ); }); // SubjectInfoAccessSyntax ::= // SEQUENCE SIZE (1..MAX) OF AccessDescription export const SubjectInformationAccess = asn1.define('SubjectInformationAccess', function() { this.seqof(AccessDescription); }); /** * CRL Extensions */ // CRLNumber ::= INTEGER export const CRLNumber = asn1.define('CRLNumber', function() { this.int(); }); export const DeltaCRLIndicator = asn1.define('DeltaCRLIndicator', function() { this.use(CRLNumber); }); // IssuingDistributionPoint ::= SEQUENCE { // distributionPoint [0] DistributionPointName OPTIONAL, // onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, // onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, // onlySomeReasons [3] ReasonFlags OPTIONAL, // indirectCRL [4] BOOLEAN DEFAULT FALSE, // onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE } export const IssuingDistributionPoint = asn1.define('IssuingDistributionPoint', function() { this.seq().obj( this.key('distributionPoint').explicit(0).optional() .use(DistributionPointName), this.key('onlyContainsUserCerts').implicit(1).def(false).bool(), this.key('onlyContainsCACerts').implicit(2).def(false).bool(), this.key('onlySomeReasons').implicit(3).optional().use(ReasonFlags), this.key('indirectCRL').implicit(4).def(false).bool(), this.key('onlyContainsAttributeCerts').implicit(5).def(false).bool() ); }); // CRLReason ::= ENUMERATED { // unspecified (0), // keyCompromise (1), // cACompromise (2), // affiliationChanged (3), // superseded (4), // cessationOfOperation (5), // certificateHold (6), // -- value 7 is not used // removeFromCRL (8), // privilegeWithdrawn (9), // aACompromise (10) } export const ReasonCode = asn1.define('ReasonCode', function() { this.enum({ 0: 'unspecified', 1: 'keyCompromise', 2: 'cACompromise', 3: 'affiliationChanged', 4: 'superseded', 5: 'cessationOfOperation', 6: 'certificateHold', 8: 'removeFromCRL', 9: 'privilegeWithdrawn', 10: 'aACompromise' }); }); // InvalidityDate ::= GeneralizedTime export const InvalidityDate = asn1.define('InvalidityDate', function() { this.gentime(); }); // CertificateIssuer ::= GeneralNames export const CertificateIssuer = asn1.define('CertificateIssuer', function() { this.use(GeneralNames); }); // OID label to extension model mapping const x509Extensions = { subjectDirectoryAttributes: SubjectDirectoryAttributes, subjectKeyIdentifier: SubjectKeyIdentifier, keyUsage: KeyUsage, subjectAlternativeName: SubjectAlternativeName, issuerAlternativeName: IssuerAlternativeName, basicConstraints: BasicConstraints, cRLNumber: CRLNumber, reasonCode: ReasonCode, invalidityDate: InvalidityDate, deltaCRLIndicator: DeltaCRLIndicator, issuingDistributionPoint: IssuingDistributionPoint, certificateIssuer: CertificateIssuer, nameConstraints: NameConstraints, cRLDistributionPoints: CRLDistributionPoints, certificatePolicies: CertificatePolicies, policyMappings: PolicyMappings, authorityKeyIdentifier: AuthorityKeyIdentifier, policyConstraints: PolicyConstraints, extendedKeyUsage: ExtendedKeyUsage, freshestCRL: FreshestCRL, inhibitAnyPolicy: InhibitAnyPolicy, authorityInformationAccess: AuthorityInfoAccessSyntax, subjectInformationAccess: SubjectInformationAccess };