@blamejs/pki 0.1.22 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/README.md +18 -6
- package/index.js +22 -12
- package/lib/asn1-der.js +126 -68
- package/lib/constants.js +46 -21
- package/lib/ct.js +54 -39
- package/lib/est.js +717 -0
- package/lib/framework-error.js +74 -34
- package/lib/oid.js +116 -60
- package/lib/path-validate.js +302 -135
- package/lib/schema-all.js +65 -41
- package/lib/schema-attrcert.js +101 -64
- package/lib/schema-cmp.js +152 -131
- package/lib/schema-cms.js +621 -163
- package/lib/schema-crl.js +43 -21
- package/lib/schema-crmf.js +136 -79
- package/lib/schema-csr.js +78 -15
- package/lib/schema-csrattrs.js +371 -0
- package/lib/schema-engine.js +92 -43
- package/lib/schema-ocsp.js +101 -55
- package/lib/schema-pkcs12.js +80 -64
- package/lib/schema-pkcs8.js +12 -12
- package/lib/schema-pkix.js +295 -105
- package/lib/schema-smime.js +39 -39
- package/lib/schema-tsp.js +108 -59
- package/lib/schema-x509.js +36 -25
- package/lib/webcrypto.js +161 -26
- package/package.json +3 -2
- package/sbom.cdx.json +6 -6
package/lib/oid.js
CHANGED
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
* OID strings and their human names, plus arc conversion and DER
|
|
14
14
|
* encode/decode convenience. Every algorithm, attribute type, and
|
|
15
15
|
* extension in PKI is named by an OID, and resolving them through one
|
|
16
|
-
* registry
|
|
17
|
-
* codebase
|
|
16
|
+
* registry -- rather than scattering magic dotted strings across the
|
|
17
|
+
* codebase -- is what lets a new algorithm be a data entry instead of a
|
|
18
18
|
* code change.
|
|
19
19
|
*
|
|
20
20
|
* The seed set is declared by FAMILY: an OID belongs to a class with a
|
|
21
|
-
* shared base arc (the "starting variable"
|
|
21
|
+
* shared base arc (the "starting variable" -- `2.5.4` for the RFC 5280
|
|
22
22
|
* attribute types, `2.5.29` for the extensions, `2.16.840.1.101.3.4` for
|
|
23
23
|
* the NIST algorithms), and each member names only its trailing arc. The
|
|
24
24
|
* full OID is derived from base + leaf at load, so the arc hierarchy that
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* extend it with `register` (one OID) or `registerFamily` (a whole arc).
|
|
30
30
|
*
|
|
31
31
|
* @card
|
|
32
|
-
* Two-way OID
|
|
32
|
+
* Two-way OID <-> name registry with arc conversion, seeded by family from
|
|
33
33
|
* the RFC 5280 and NIST post-quantum object identifiers.
|
|
34
34
|
*/
|
|
35
35
|
|
|
@@ -38,72 +38,72 @@ var frameworkError = require("./framework-error");
|
|
|
38
38
|
|
|
39
39
|
var OidError = frameworkError.OidError;
|
|
40
40
|
|
|
41
|
-
// FAMILIES
|
|
41
|
+
// FAMILIES -- OIDs grouped by their shared base arc (the "similar starting
|
|
42
42
|
// variable" that defines a class). A member is `name: leaf`, where leaf is a
|
|
43
43
|
// trailing arc (number) or a short arc array for a multi-level leaf; the full
|
|
44
44
|
// arc is derived at load via base.concat(leaf). Declaring by family means no
|
|
45
45
|
// dotted-decimal OID literal appears in this source at all, and adding a
|
|
46
|
-
// member is one `name: leaf` line under its class
|
|
46
|
+
// member is one `name: leaf` line under its class -- no base to re-type.
|
|
47
47
|
var FAMILIES = {
|
|
48
48
|
// RFC 5280 attribute types.
|
|
49
49
|
attributeType: { base: [2, 5, 4], of: {
|
|
50
50
|
commonName: 3, surname: 4, serialNumber: 5, countryName: 6,
|
|
51
51
|
localityName: 7, stateOrProvinceName: 8, streetAddress: 9,
|
|
52
52
|
organizationName: 10, organizationalUnitName: 11, title: 12, givenName: 42,
|
|
53
|
-
// RFC 5755
|
|
53
|
+
// RFC 5755 sec. 4.4 attribute-certificate attribute types.
|
|
54
54
|
clearance: 55, role: 72 } },
|
|
55
55
|
|
|
56
56
|
// RFC 5280 certificate extensions.
|
|
57
57
|
certExtension: { base: [2, 5, 29], of: {
|
|
58
58
|
subjectKeyIdentifier: 14, keyUsage: 15, subjectAltName: 17, issuerAltName: 18,
|
|
59
59
|
basicConstraints: 19,
|
|
60
|
-
// CRL + CRL-entry extensions (RFC 5280
|
|
60
|
+
// CRL + CRL-entry extensions (RFC 5280 sec. 5.2, sec. 5.3)
|
|
61
61
|
cRLNumber: 20, reasonCode: 21, invalidityDate: 24, deltaCRLIndicator: 27,
|
|
62
62
|
issuingDistributionPoint: 28, certificateIssuer: 29,
|
|
63
63
|
nameConstraints: 30, cRLDistributionPoints: 31,
|
|
64
64
|
certificatePolicies: 32, policyMappings: 33, authorityKeyIdentifier: 35,
|
|
65
65
|
policyConstraints: 36, extKeyUsage: 37, freshestCRL: 46,
|
|
66
66
|
inhibitAnyPolicy: 54,
|
|
67
|
-
// The two special-OID leaves under extension arcs (RFC 5280
|
|
68
|
-
//
|
|
67
|
+
// The two special-OID leaves under extension arcs (RFC 5280 sec. 4.2.1.4 /
|
|
68
|
+
// sec. 4.2.1.12): the certificate-policies wildcard and the EKU wildcard.
|
|
69
69
|
anyPolicy: [32, 0], anyExtendedKeyUsage: [37, 0],
|
|
70
|
-
// RFC 5755 attribute-certificate extensions (
|
|
70
|
+
// RFC 5755 attribute-certificate extensions (sec. 4.3.2, sec. 4.3.6).
|
|
71
71
|
targetInformation: 55, noRevAvail: 56 } },
|
|
72
72
|
|
|
73
73
|
// PKIX private extensions on the id-pe arc (authorityInfoAccess et al, plus the
|
|
74
|
-
// RFC 5755 attribute-certificate id-pe extensions: ac-auditIdentity
|
|
75
|
-
// aaControls
|
|
74
|
+
// RFC 5755 attribute-certificate id-pe extensions: ac-auditIdentity sec. 4.3.1,
|
|
75
|
+
// aaControls sec. 7.4, ac-proxying sec. 7.2).
|
|
76
76
|
pkixAccess: { base: [1, 3, 6, 1, 5, 5, 7, 1], of: {
|
|
77
77
|
authorityInfoAccess: 1, acAuditIdentity: 4, aaControls: 6, acProxying: 10 } },
|
|
78
78
|
|
|
79
|
-
// id-aca
|
|
80
|
-
// authenticationInfo
|
|
79
|
+
// id-aca -- RFC 5755 attribute-certificate attribute types on the id-pkix 10 arc:
|
|
80
|
+
// authenticationInfo sec. 4.4.1 .. group sec. 4.4.4, plus encAttrs sec. 7.1 (the encrypted-
|
|
81
81
|
// attribute wrapper, syntax ContentInfo). { id-aca 5 } is reserved.
|
|
82
82
|
idAca: { base: [1, 3, 6, 1, 5, 5, 7, 10], of: {
|
|
83
83
|
authenticationInfo: 1, accessIdentity: 2, chargingIdentity: 3, group: 4, encAttrs: 6 } },
|
|
84
84
|
|
|
85
85
|
// The legacy RFC 3281 id-at-clearance on the X.501 selected-attribute-types arc.
|
|
86
|
-
// RFC 5755
|
|
86
|
+
// RFC 5755 sec. 4.4.6 says implementations MUST NOT OUTPUT this form but SHOULD ACCEPT
|
|
87
87
|
// it for decoding, so it is registered as an alias of "clearance". The canonical
|
|
88
88
|
// name -> OID reverse stays the RFC 5755 attributeType-arc 2.5.4.55 (registered
|
|
89
89
|
// first under attributeType, so it wins the reverse mapping).
|
|
90
90
|
selectedAttrType: { base: [2, 5, 1, 5], of: { clearance: 55 } },
|
|
91
91
|
|
|
92
|
-
// PKIX Access Descriptor methods (id-ad, RFC 5280
|
|
92
|
+
// PKIX Access Descriptor methods (id-ad, RFC 5280 sec. 4.2.2.1/sec. 4.2.2.2). id-ad-ocsp
|
|
93
93
|
// is the arc the OCSP responder OIDs hang under; id-ad-caIssuers names the AIA
|
|
94
94
|
// CA-issuers access method.
|
|
95
95
|
adAccess: { base: [1, 3, 6, 1, 5, 5, 7, 48], of: { ocsp: 1, caIssuers: 2 } },
|
|
96
96
|
|
|
97
97
|
// OCSP (RFC 6960) on the id-pkix-ocsp arc (= id-ad-ocsp). id-pkix-ocsp-basic is
|
|
98
|
-
// the ResponseBytes.responseType this build decodes; id-pkix-ocsp-nonce (
|
|
98
|
+
// the ResponseBytes.responseType this build decodes; id-pkix-ocsp-nonce (sec. 4.4.1)
|
|
99
99
|
// names the nonce extension; the remaining members name the other OCSP extensions
|
|
100
100
|
// (CRL references, acceptable-response-types, archive-cutoff, service-locator,
|
|
101
|
-
// preferred-signature-algorithms, extended-revoke
|
|
101
|
+
// preferred-signature-algorithms, extended-revoke -- RFC 6960 sec. 4.4, RFC 9654).
|
|
102
102
|
ocsp: { base: [1, 3, 6, 1, 5, 5, 7, 48, 1], of: {
|
|
103
103
|
ocspBasic: 1, ocspNonce: 2, ocspCrl: 3, ocspResponse: 4, ocspNoCheck: 5,
|
|
104
104
|
ocspArchiveCutoff: 6, ocspServiceLocator: 7, ocspPrefSigAlgs: 8, ocspExtendedRevoke: 9 } },
|
|
105
105
|
|
|
106
|
-
// CRMF (RFC 4211) registration controls (
|
|
106
|
+
// CRMF (RFC 4211) registration controls (sec. 6) and registration info (sec. 7) on the
|
|
107
107
|
// id-pkip arc (id-pkix 5). id-regCtrl (id-pkip 1) names the control types a
|
|
108
108
|
// CertRequest carries; id-regInfo (id-pkip 2) names the registration-info types.
|
|
109
109
|
// The parser surfaces each control/info value RAW keyed by these names.
|
|
@@ -111,15 +111,15 @@ var FAMILIES = {
|
|
|
111
111
|
regToken: 1, authenticator: 2, pkiPublicationInfo: 3, pkiArchiveOptions: 4, oldCertID: 5, protocolEncrKey: 6 } },
|
|
112
112
|
regInfo: { base: [1, 3, 6, 1, 5, 5, 7, 5, 2], of: { utf8Pairs: 1, certReq: 2 } },
|
|
113
113
|
|
|
114
|
-
// PKIX extended key purposes (id-kp, RFC 5280
|
|
115
|
-
//
|
|
114
|
+
// PKIX extended key purposes (id-kp, RFC 5280 sec. 4.2.1.12). timeStamping is required
|
|
115
|
+
// -- critical and sole -- on an RFC 3161 TSA signing certificate (sec. 2.3).
|
|
116
116
|
pkixKp: { base: [1, 3, 6, 1, 5, 5, 7, 3], of: {
|
|
117
117
|
serverAuth: 1, clientAuth: 2, codeSigning: 3, emailProtection: 4, timeStamping: 8, ocspSigning: 9 } },
|
|
118
118
|
|
|
119
119
|
// Google Certificate Transparency (RFC 6962) on the 1.3.6.1.4.1.11129.2.4 arc:
|
|
120
|
-
// the SCT-list X.509 extension (
|
|
121
|
-
// precert-signing EKU (
|
|
122
|
-
// (
|
|
120
|
+
// the SCT-list X.509 extension (sec. 3.3), the precertificate poison (sec. 3.1), the
|
|
121
|
+
// precert-signing EKU (sec. 3.1, naming only), and the OCSP-delivered SCT list
|
|
122
|
+
// (sec. 3.3). The SCT payload itself is TLS presentation language, not DER -- it is
|
|
123
123
|
// parsed by lib/ct.js (pki.ct), never routed through the DER schema engine.
|
|
124
124
|
ct: { base: [1, 3, 6, 1, 4, 1, 11129, 2, 4], of: {
|
|
125
125
|
signedCertificateTimestampList: 2, precertificatePoison: 3,
|
|
@@ -131,27 +131,27 @@ var FAMILIES = {
|
|
|
131
131
|
sha256WithRSAEncryption: 11,
|
|
132
132
|
sha384WithRSAEncryption: 12, sha512WithRSAEncryption: 13 } },
|
|
133
133
|
|
|
134
|
-
// PKCS#7 / CMS content types (RFC 5652
|
|
134
|
+
// PKCS#7 / CMS content types (RFC 5652 sec. 4, RFC 2315). id-signedData is the one
|
|
135
135
|
// this toolkit structurally decodes; the rest are recognized-and-deferred.
|
|
136
136
|
pkcs7: { base: [1, 2, 840, 113549, 1, 7], of: {
|
|
137
137
|
data: 1, signedData: 2, envelopedData: 3, signedAndEnvelopedData: 4,
|
|
138
138
|
digestedData: 5, encryptedData: 6 } },
|
|
139
139
|
|
|
140
|
-
// PKCS#9 attribute types
|
|
141
|
-
// and the PKCS#12 bag attributes friendlyName / localKeyId (RFC 7292
|
|
140
|
+
// PKCS#9 attribute types -- incl. the CMS signed-attribute OIDs (RFC 5652 sec. 11)
|
|
141
|
+
// and the PKCS#12 bag attributes friendlyName / localKeyId (RFC 7292 sec. 4.2).
|
|
142
142
|
pkcs9: { base: [1, 2, 840, 113549, 1, 9], of: {
|
|
143
143
|
emailAddress: 1, contentType: 3, messageDigest: 4, signingTime: 5,
|
|
144
|
-
challengePassword: 7, extensionRequest: 14,
|
|
145
|
-
friendlyName: 20, localKeyId: 21 } },
|
|
144
|
+
countersignature: 6, challengePassword: 7, extensionRequest: 14,
|
|
145
|
+
smimeCapabilities: 15, friendlyName: 20, localKeyId: 21 } },
|
|
146
146
|
|
|
147
|
-
// PKCS#9 CertBag / CRLBag value discriminators (RFC 7292
|
|
147
|
+
// PKCS#9 CertBag / CRLBag value discriminators (RFC 7292 sec. 4.2.3-sec. 4.2.4).
|
|
148
148
|
pkcs9CertTypes: { base: [1, 2, 840, 113549, 1, 9, 22], of: { x509Certificate: 1, sdsiCertificate: 2 } },
|
|
149
149
|
pkcs9CrlTypes: { base: [1, 2, 840, 113549, 1, 9, 23], of: { x509CRL: 1 } },
|
|
150
150
|
|
|
151
151
|
// PKCS#5 password-based schemes (RFC 8018) + the PBMAC1 MacData arm (RFC 9579).
|
|
152
152
|
pkcs5: { base: [1, 2, 840, 113549, 1, 5], of: { pbkdf2: 12, pbes2: 13, pbmac1: 14 } },
|
|
153
153
|
|
|
154
|
-
// CMP InfoTypeAndValue types
|
|
154
|
+
// CMP InfoTypeAndValue types -- id-it under id-pkix (RFC 9810 sec. 5.3.19; the
|
|
155
155
|
// PKIXCMP-2023 module assigns these leaves, 8/9 unassigned).
|
|
156
156
|
idIt: { base: [1, 3, 6, 1, 5, 5, 7, 4], of: {
|
|
157
157
|
caProtEncCert: 1, signKeyPairTypes: 2, encKeyPairTypes: 3, preferredSymmAlg: 4,
|
|
@@ -162,15 +162,15 @@ var FAMILIES = {
|
|
|
162
162
|
crls: 23, kemCiphertextInfo: 24 } },
|
|
163
163
|
|
|
164
164
|
// CMP message-protection MAC algorithms on the Entrust arc (RFC 9810
|
|
165
|
-
//
|
|
165
|
+
// sec. 5.1.3.1/.2/.4; RFC 9481 sec. 6.1.1).
|
|
166
166
|
entrustAlg: { base: [1, 2, 840, 113533, 7, 66], of: {
|
|
167
167
|
passwordBasedMac: 13, kemBasedMac: 16, dhBasedMac: 30 } },
|
|
168
168
|
|
|
169
|
-
// PKCS#12 bag types (RFC 7292
|
|
169
|
+
// PKCS#12 bag types (RFC 7292 sec. 4.2, Appendix D).
|
|
170
170
|
pkcs12BagTypes: { base: [1, 2, 840, 113549, 1, 12, 10, 1], of: {
|
|
171
171
|
keyBag: 1, pkcs8ShroudedKeyBag: 2, certBag: 3, crlBag: 4, secretBag: 5, safeContentsBag: 6 } },
|
|
172
172
|
|
|
173
|
-
// PKCS#12 password-based encryption schemes (RFC 7292 Appendix C)
|
|
173
|
+
// PKCS#12 password-based encryption schemes (RFC 7292 Appendix C) -- legacy
|
|
174
174
|
// PBE identifiers still emitted by deployed exporters; recognized so a
|
|
175
175
|
// shrouded bag's algorithm resolves to a name, never decrypted here.
|
|
176
176
|
pkcs12Pbe: { base: [1, 2, 840, 113549, 1, 12, 1], of: {
|
|
@@ -178,23 +178,48 @@ var FAMILIES = {
|
|
|
178
178
|
"pbeWithSHAAnd3-KeyTripleDES-CBC": 3, "pbeWithSHAAnd2-KeyTripleDES-CBC": 4,
|
|
179
179
|
"pbeWithSHAAnd128BitRC2-CBC": 5, "pbeWithSHAAnd40BitRC2-CBC": 6 } },
|
|
180
180
|
|
|
181
|
-
// RSADSI digest / HMAC algorithms (RFC 8018
|
|
181
|
+
// RSADSI digest / HMAC algorithms (RFC 8018 sec. B.1) -- the PBKDF2 / PBMAC1 PRFs.
|
|
182
182
|
rsadsiDigest: { base: [1, 2, 840, 113549, 2], of: {
|
|
183
183
|
hmacWithSHA1: 7, hmacWithSHA224: 8, hmacWithSHA256: 9,
|
|
184
184
|
hmacWithSHA384: 10, hmacWithSHA512: 11 } },
|
|
185
185
|
|
|
186
186
|
// S/MIME content types on the PKCS#9 smime arc (RFC 5652, RFC 3161): id-ct.
|
|
187
|
-
|
|
187
|
+
// authData is RFC 5652 sec. 9 AuthenticatedData; authEnvelopedData is RFC 5083.
|
|
188
|
+
smimeCt: { base: [1, 2, 840, 113549, 1, 9, 16, 1], of: { authData: 2, tSTInfo: 4, authEnvelopedData: 23, encKeyWithID: 21 } },
|
|
189
|
+
|
|
190
|
+
// S/MIME other-recipient-info types (id-ori, RFC 5652 sec. 6.2.5). id-ori-kem
|
|
191
|
+
// carries a KEMRecipientInfo (RFC 9629) inside the ori [4] RecipientInfo arm.
|
|
192
|
+
smimeOri: { base: [1, 2, 840, 113549, 1, 9, 16, 13], of: { kem: 3 } },
|
|
193
|
+
|
|
194
|
+
// S/MIME algorithm identifiers (id-alg). The HKDF KDFs (RFC 8619) and the
|
|
195
|
+
// CEK-HKDF content-encryption wrapper (RFC 9709) a KEMRecipientInfo names, plus
|
|
196
|
+
// the RSA-KEM SPKI algorithm (RFC 9690). Parameters are absent for the HKDFs.
|
|
197
|
+
smimeAlg: { base: [1, 2, 840, 113549, 1, 9, 16, 3], of: {
|
|
198
|
+
"id-rsa-kem": 14, hkdfWithSha256: 28, hkdfWithSha384: 29, hkdfWithSha512: 30, cekHkdfSha256: 31 } },
|
|
199
|
+
|
|
200
|
+
// RSA-KEM key-transport algorithm (RFC 9690, obsoletes RFC 5990) on the ISO
|
|
201
|
+
// 18033-2 arc -- the kem OID an RSA KEMRecipientInfo carries (distinct from the
|
|
202
|
+
// id-rsa-kem SPKI algorithm above).
|
|
203
|
+
iso18033: { base: [1, 0, 18033, 2, 2], of: { "id-kem-rsa": 4 } },
|
|
204
|
+
|
|
205
|
+
// RFC 3370 HMAC-SHA-1 MAC algorithm (the AuthenticatedData macAlgorithm on the
|
|
206
|
+
// PKIX arc, distinct from the RSADSI hmacWithSHA1).
|
|
207
|
+
pkixHmac: { base: [1, 3, 6, 1, 5, 5, 8, 1], of: { "hmac-SHA1": 2 } },
|
|
188
208
|
|
|
189
209
|
// S/MIME authenticated attributes (id-aa, RFC 2634 / RFC 5035 / RFC 5816). The ESS
|
|
190
210
|
// signing-certificate attributes bind a CMS / TSP SignerInfo to its signing cert;
|
|
191
|
-
// signingCertificateV2 (ESSCertIDv2) carries a non-SHA-1 cert hash (RFC 5816
|
|
211
|
+
// signingCertificateV2 (ESSCertIDv2) carries a non-SHA-1 cert hash (RFC 5816 sec. 2.2.1).
|
|
192
212
|
// The RFC 2634 originals (receiptRequest .. contentReference) are name-only: they
|
|
193
213
|
// resolve to a name so an unsupported-attribute diagnostic is legible, not decoded.
|
|
214
|
+
// decryptKeyID / asymmDecryptKeyID name the out-of-band key-encryption key a
|
|
215
|
+
// /serverkeygen client references (RFC 4108 sec. 2.2.5 / RFC 7030 sec. 4.4.1);
|
|
216
|
+
// certificationRequestInfoTemplate / extensionReqTemplate are the RFC 9908
|
|
217
|
+
// CSR-attributes template carriers.
|
|
194
218
|
smimeAa: { base: [1, 2, 840, 113549, 1, 9, 16, 2], of: {
|
|
195
219
|
receiptRequest: 1, eSSSecurityLabel: 2, mlExpansionHistory: 3, contentHints: 4,
|
|
196
220
|
msgSigDigest: 5, contentIdentifier: 7, equivalentLabels: 9, contentReference: 10,
|
|
197
|
-
signingCertificate: 12, timeStampToken: 14, signingCertificateV2: 47
|
|
221
|
+
signingCertificate: 12, timeStampToken: 14, decryptKeyID: 37, signingCertificateV2: 47,
|
|
222
|
+
asymmDecryptKeyID: 54, certificationRequestInfoTemplate: 61, extensionReqTemplate: 62 } },
|
|
198
223
|
|
|
199
224
|
// ANSI X9.62 EC public key, named curve, and ECDSA signatures.
|
|
200
225
|
ansiX962: { base: [1, 2, 840, 10045], of: {
|
|
@@ -207,22 +232,23 @@ var FAMILIES = {
|
|
|
207
232
|
// Edwards / Montgomery curves (RFC 8410).
|
|
208
233
|
edwards: { base: [1, 3, 101], of: { X25519: 110, X448: 111, Ed25519: 112, Ed448: 113 } },
|
|
209
234
|
|
|
210
|
-
// OIW Secsig SHA-1 (1.3.14.3.2.26)
|
|
235
|
+
// OIW Secsig SHA-1 (1.3.14.3.2.26) -- the most common OCSP CertID hashAlgorithm;
|
|
211
236
|
// nistHash covers only SHA-256 and above.
|
|
212
237
|
oiwSecsig: { base: [1, 3, 14, 3, 2], of: { sha1: 26 } },
|
|
213
238
|
|
|
214
|
-
// NIST AES content-encryption algorithms (arc 2.16.840.1.101.3.4.1)
|
|
239
|
+
// NIST AES content-encryption algorithms (arc 2.16.840.1.101.3.4.1) -- the
|
|
215
240
|
// modern PBES2 / CMS content ciphers a PKCS#12 or EnvelopedData names.
|
|
216
241
|
nistAes: { base: [2, 16, 840, 1, 101, 3, 4, 1], of: {
|
|
217
|
-
"aes128-CBC": 2, "aes128-
|
|
218
|
-
"
|
|
242
|
+
"aes128-CBC": 2, "aes128-wrap": 5, "aes128-GCM": 6, "aes128-CCM": 7,
|
|
243
|
+
"aes192-CBC": 22, "aes192-wrap": 25, "aes192-GCM": 26, "aes192-CCM": 27,
|
|
244
|
+
"aes256-CBC": 42, "aes256-wrap": 45, "aes256-GCM": 46, "aes256-CCM": 47 } },
|
|
219
245
|
|
|
220
246
|
// NIST hash functions (SHA-2, SHA-3, SHAKE).
|
|
221
247
|
nistHash: { base: [2, 16, 840, 1, 101, 3, 4, 2], of: {
|
|
222
248
|
sha256: 1, sha384: 2, sha512: 3, "sha3-256": 8, "sha3-512": 10, shake256: 12 } },
|
|
223
249
|
|
|
224
|
-
// NIST signature algorithms
|
|
225
|
-
// signature arc 2.16.840.1.101.3.4.3. RFC 9909
|
|
250
|
+
// NIST signature algorithms -- FIPS 204 ML-DSA + FIPS 205 SLH-DSA share the
|
|
251
|
+
// signature arc 2.16.840.1.101.3.4.3. RFC 9909 sec. 3 assigns the 12 Pure SLH-DSA
|
|
226
252
|
// sets .20-.31 (SHA-2 .20-.25, SHAKE .26-.31) and the 12 pre-hash HashSLH-DSA
|
|
227
253
|
// sets .35-.46, each pairing a parameter set with its message-digest hash. The
|
|
228
254
|
// parameters MUST be absent for every one of them (enforced via paramsMustBeAbsent).
|
|
@@ -241,7 +267,7 @@ var FAMILIES = {
|
|
|
241
267
|
"id-hash-slh-dsa-shake-192s-with-shake256": 43, "id-hash-slh-dsa-shake-192f-with-shake256": 44,
|
|
242
268
|
"id-hash-slh-dsa-shake-256s-with-shake256": 45, "id-hash-slh-dsa-shake-256f-with-shake256": 46 } },
|
|
243
269
|
|
|
244
|
-
// NIST KEM
|
|
270
|
+
// NIST KEM -- FIPS 203 ML-KEM (arc 2.16.840.1.101.3.4.4).
|
|
245
271
|
nistKem: { base: [2, 16, 840, 1, 101, 3, 4, 4], of: {
|
|
246
272
|
"id-ml-kem-512": 1, "id-ml-kem-768": 2, "id-ml-kem-1024": 3 } },
|
|
247
273
|
|
|
@@ -266,7 +292,7 @@ function _isArc(a) {
|
|
|
266
292
|
return typeof a === "number" && Number.isSafeInteger(a) && a >= 0;
|
|
267
293
|
}
|
|
268
294
|
|
|
269
|
-
// Seed the registry family by family
|
|
295
|
+
// Seed the registry family by family -- the built-in set is registered through
|
|
270
296
|
// the exact same primitive an operator uses (registerFamily), so there is one
|
|
271
297
|
// path from a declared family to indexed OIDs and no dotted literals anywhere.
|
|
272
298
|
Object.keys(FAMILIES).forEach(function (fam) {
|
|
@@ -274,11 +300,27 @@ Object.keys(FAMILIES).forEach(function (fam) {
|
|
|
274
300
|
});
|
|
275
301
|
|
|
276
302
|
function _assertDotted(dotted, who) {
|
|
277
|
-
|
|
278
|
-
|
|
303
|
+
// No leading-zero components: "01.2.840" is a key no decoded OID can match,
|
|
304
|
+
// and the arc converters round-trip it to a DIFFERENT OID ("1.2.840").
|
|
305
|
+
if (typeof dotted !== "string" || !/^(0|[1-9]\d*)(\.(0|[1-9]\d*))+$/.test(dotted)) {
|
|
306
|
+
throw new OidError("oid/bad-input", who + ": expected a dotted-decimal OID string (no leading-zero components)");
|
|
279
307
|
}
|
|
280
308
|
}
|
|
281
309
|
|
|
310
|
+
// X.660 encodability: the root arc is 0..2 and, under roots 0 and 1, the
|
|
311
|
+
// second arc is 0..39 (the first two arcs pack into a single octet as
|
|
312
|
+
// 40*X+Y). An OID outside these bounds can never be DER-encoded, so a
|
|
313
|
+
// registration carrying one fails at config time rather than at first use.
|
|
314
|
+
function _assertEncodableArcs(arcs, who) {
|
|
315
|
+
if (arcs.length < 2) {
|
|
316
|
+
throw new OidError("oid/bad-input", who + ": an OID must have at least 2 arcs");
|
|
317
|
+
}
|
|
318
|
+
var root = typeof arcs[0] === "bigint" ? arcs[0] : BigInt(arcs[0]);
|
|
319
|
+
var second = typeof arcs[1] === "bigint" ? arcs[1] : BigInt(arcs[1]);
|
|
320
|
+
if (root > 2n) throw new OidError("oid/bad-arc", who + ": the root arc must be 0, 1, or 2 (X.660)");
|
|
321
|
+
if (root < 2n && second > 39n) throw new OidError("oid/bad-arc", who + ": the second arc must be 0..39 under roots 0 and 1 (X.660)");
|
|
322
|
+
}
|
|
323
|
+
|
|
282
324
|
/**
|
|
283
325
|
* @primitive pki.oid.name
|
|
284
326
|
* @signature pki.oid.name(dotted) -> string | undefined
|
|
@@ -317,10 +359,10 @@ function has(dotted) {
|
|
|
317
359
|
* @spec X.660, RFC 5280
|
|
318
360
|
* @related pki.oid.registerFamily, pki.oid.name
|
|
319
361
|
*
|
|
320
|
-
* Add (or override) an OID
|
|
362
|
+
* Add (or override) an OID -> name mapping so an operator's private or
|
|
321
363
|
* newly-standardized arc resolves through the same registry as the seed
|
|
322
364
|
* set. A later registration of the same OID replaces the forward name;
|
|
323
|
-
* the reverse (name
|
|
365
|
+
* the reverse (name -> OID) keeps the first registration as canonical.
|
|
324
366
|
*
|
|
325
367
|
* @example
|
|
326
368
|
* pki.oid.register("1.3.6.1.4.1.99999.1", "acmeWidgetPolicy");
|
|
@@ -328,6 +370,7 @@ function has(dotted) {
|
|
|
328
370
|
function register(dotted, n) {
|
|
329
371
|
_assertDotted(dotted, "register");
|
|
330
372
|
if (typeof n !== "string" || n.length === 0) throw new OidError("oid/bad-input", "register: name must be a non-empty string");
|
|
373
|
+
_assertEncodableArcs(dotted.split(".").map(BigInt), "register");
|
|
331
374
|
_index(dotted, n);
|
|
332
375
|
}
|
|
333
376
|
|
|
@@ -341,7 +384,7 @@ function register(dotted, n) {
|
|
|
341
384
|
*
|
|
342
385
|
* Register a whole OID family in one call. `base` is the shared arc prefix
|
|
343
386
|
* (the starting variable a class of OIDs has in common) and `members` maps
|
|
344
|
-
* each name to its trailing arc
|
|
387
|
+
* each name to its trailing arc -- a number, or a short arc array for a
|
|
345
388
|
* multi-level leaf. Each full OID is derived as `base` followed by the leaf,
|
|
346
389
|
* so a family is declared as its hierarchy rather than as re-spelled full
|
|
347
390
|
* paths. This is the primitive the built-in seed set itself is built from.
|
|
@@ -372,6 +415,7 @@ function registerFamily(base, members) {
|
|
|
372
415
|
if (!arcs.every(_isArc)) {
|
|
373
416
|
throw new OidError("oid/bad-arc", "registerFamily: member " + JSON.stringify(nm) + " has a non-arc leaf");
|
|
374
417
|
}
|
|
418
|
+
_assertEncodableArcs(arcs, "registerFamily");
|
|
375
419
|
_index(arcs.join("."), nm);
|
|
376
420
|
});
|
|
377
421
|
}
|
|
@@ -382,7 +426,7 @@ function all() {
|
|
|
382
426
|
return out;
|
|
383
427
|
}
|
|
384
428
|
|
|
385
|
-
// toArcs / fromArcs
|
|
429
|
+
// toArcs / fromArcs -- dotted <-> numeric arc array. Arcs come back as
|
|
386
430
|
// Number where safe and BigInt where an arc exceeds 2^53 (rare, but a
|
|
387
431
|
// UUID-based OID arc can), so the round-trip never loses precision.
|
|
388
432
|
function toArcs(dotted) {
|
|
@@ -405,7 +449,7 @@ function fromArcs(arcs) {
|
|
|
405
449
|
}).join(".");
|
|
406
450
|
}
|
|
407
451
|
|
|
408
|
-
// DER convenience
|
|
452
|
+
// DER convenience -- thin pass-throughs to the codec so callers reach for
|
|
409
453
|
// one namespace when they have a dotted string in hand.
|
|
410
454
|
function toDER(dotted) { _assertDotted(dotted, "toDER"); return asn1.build.oid(dotted); }
|
|
411
455
|
function fromDER(input) {
|
|
@@ -414,11 +458,11 @@ function fromDER(input) {
|
|
|
414
458
|
return asn1.read.oid(node);
|
|
415
459
|
}
|
|
416
460
|
|
|
417
|
-
// Algorithm identifiers whose `parameters` field MUST be absent
|
|
461
|
+
// Algorithm identifiers whose `parameters` field MUST be absent -- no explicit
|
|
418
462
|
// NULL, no bytes. The FIPS 204 ML-DSA and FIPS 205 SLH-DSA signature families
|
|
419
|
-
// and the RFC 8410 Edwards / Montgomery curves each carry this MUST: RFC 9909
|
|
420
|
-
// (SLH-DSA in X.509), RFC 9814
|
|
421
|
-
// RFC 8410
|
|
463
|
+
// and the RFC 8410 Edwards / Montgomery curves each carry this MUST: RFC 9909 sec. 3
|
|
464
|
+
// (SLH-DSA in X.509), RFC 9814 sec. 4 (SLH-DSA in CMS), RFC 9881 sec. 2 (ML-DSA in X.509),
|
|
465
|
+
// RFC 8410 sec. 3 (Ed25519 / Ed448 / X25519 / X448). Built by NAME through the same
|
|
422
466
|
// registry every caller uses, so a typo fails closed at load rather than silently
|
|
423
467
|
// dropping a member. One set drives the single shared AlgorithmIdentifier reject
|
|
424
468
|
// (schema-pkix), so every format consumer inherits the rule with no per-format code.
|
|
@@ -429,7 +473,7 @@ var _PARAMS_ABSENT = new Set();
|
|
|
429
473
|
"id-slh-dsa-sha2-192f", "id-slh-dsa-sha2-256s", "id-slh-dsa-sha2-256f",
|
|
430
474
|
"id-slh-dsa-shake-128s", "id-slh-dsa-shake-128f", "id-slh-dsa-shake-192s",
|
|
431
475
|
"id-slh-dsa-shake-192f", "id-slh-dsa-shake-256s", "id-slh-dsa-shake-256f",
|
|
432
|
-
// Pre-hash HashSLH-DSA sets (RFC 9909
|
|
476
|
+
// Pre-hash HashSLH-DSA sets (RFC 9909 sec. 3) -- parameters MUST be absent too.
|
|
433
477
|
"id-hash-slh-dsa-sha2-128s-with-sha256", "id-hash-slh-dsa-sha2-128f-with-sha256",
|
|
434
478
|
"id-hash-slh-dsa-sha2-192s-with-sha512", "id-hash-slh-dsa-sha2-192f-with-sha512",
|
|
435
479
|
"id-hash-slh-dsa-sha2-256s-with-sha512", "id-hash-slh-dsa-sha2-256f-with-sha512",
|
|
@@ -437,7 +481,19 @@ var _PARAMS_ABSENT = new Set();
|
|
|
437
481
|
"id-hash-slh-dsa-shake-192s-with-shake256", "id-hash-slh-dsa-shake-192f-with-shake256",
|
|
438
482
|
"id-hash-slh-dsa-shake-256s-with-shake256", "id-hash-slh-dsa-shake-256f-with-shake256",
|
|
439
483
|
"Ed25519", "Ed448", "X25519", "X448",
|
|
440
|
-
|
|
484
|
+
// FIPS 203 ML-KEM (RFC 9936 sec. 3: PARAMS ARE absent).
|
|
485
|
+
"id-ml-kem-512", "id-ml-kem-768", "id-ml-kem-1024",
|
|
486
|
+
// HKDF key-derivation identifiers (RFC 8619 sec. 2: when any of these appear
|
|
487
|
+
// within AlgorithmIdentifier, the parameters component SHALL be absent).
|
|
488
|
+
"hkdfWithSha256", "hkdfWithSha384", "hkdfWithSha512",
|
|
489
|
+
].forEach(function (nm) {
|
|
490
|
+
var d = byName(nm);
|
|
491
|
+
// A seed-list typo must fail at module load -- admitting undefined would
|
|
492
|
+
// make paramsMustBeAbsent(byName(sameTypo)) return TRUE for every other
|
|
493
|
+
// unregistered name (Set.has(undefined)), a fail-open guard.
|
|
494
|
+
if (typeof d !== "string") throw new OidError("oid/unknown-name", "paramsMustBeAbsent seed: " + JSON.stringify(nm) + " is not a registered name");
|
|
495
|
+
_PARAMS_ABSENT.add(d);
|
|
496
|
+
});
|
|
441
497
|
|
|
442
498
|
/**
|
|
443
499
|
* @primitive pki.oid.paramsMustBeAbsent
|