@blamejs/pki 0.8.58 → 0.8.60
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 +50 -0
- package/lib/acme.js +53 -30
- package/lib/alt-sig.js +3 -1
- package/lib/asn1-der.js +98 -39
- package/lib/attrcert-sign.js +19 -16
- package/lib/byte-writer.js +63 -13
- package/lib/cbor-det.js +9 -3
- package/lib/cmc-build.js +16 -10
- package/lib/cmp-build.js +45 -34
- package/lib/cmp-session.js +19 -9
- package/lib/cms-decrypt.js +28 -10
- package/lib/cms-encrypt.js +23 -17
- package/lib/cms-sign.js +65 -43
- package/lib/cms-verify.js +11 -7
- package/lib/crl-sign.js +27 -20
- package/lib/csr-sign.js +5 -2
- package/lib/ct.js +37 -17
- package/lib/est.js +55 -32
- package/lib/guard-bytes.js +5 -1
- package/lib/guard-der.js +6 -1
- package/lib/guard-identifier.js +1 -1
- package/lib/guard-intrinsic.js +12 -4
- package/lib/guard-list.js +64 -0
- package/lib/guard-name.js +1 -1
- package/lib/hpke.js +10 -3
- package/lib/http-transport.js +12 -3
- package/lib/inspect.js +10 -2
- package/lib/jose.js +3 -1
- package/lib/key.js +11 -7
- package/lib/lint.js +236 -152
- package/lib/mime.js +9 -5
- package/lib/ocsp.js +25 -22
- package/lib/path-validate.js +48 -18
- package/lib/pbes2.js +6 -2
- package/lib/pkcs11-uri.js +3 -1
- package/lib/pkcs12-build.js +14 -11
- package/lib/pki-build.js +18 -14
- package/lib/possession.js +3 -1
- package/lib/rc2.js +6 -2
- package/lib/revocation-fetch.js +78 -19
- package/lib/scep.js +14 -6
- package/lib/schema-attrcert.js +4 -2
- package/lib/schema-c509.js +94 -78
- package/lib/schema-cmc.js +5 -2
- package/lib/schema-cmp.js +6 -3
- package/lib/schema-cms.js +7 -4
- package/lib/schema-crl.js +1 -1
- package/lib/schema-crmf.js +1 -1
- package/lib/schema-csr.js +3 -3
- package/lib/schema-engine.js +36 -18
- package/lib/schema-pkcs1.js +7 -3
- package/lib/schema-pkcs12.js +9 -6
- package/lib/schema-pkix.js +19 -3
- package/lib/schema-sec1.js +4 -1
- package/lib/schema-tsp.js +4 -1
- package/lib/shbs.js +7 -3
- package/lib/sign-scheme.js +4 -4
- package/lib/smime.js +18 -14
- package/lib/tlog.js +17 -11
- package/lib/tuf.js +3 -1
- package/lib/validator-keydesc.js +4 -1
- package/lib/validator-tls.js +7 -2
- package/lib/webcrypto.js +14 -8
- package/lib/x509-sign.js +20 -15
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/attrcert-sign.js
CHANGED
|
@@ -24,6 +24,9 @@ var x509 = require("./schema-x509");
|
|
|
24
24
|
var signScheme = require("./sign-scheme");
|
|
25
25
|
var guard = require("./guard-all");
|
|
26
26
|
var intrinsic = require("./guard-intrinsic");
|
|
27
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
28
|
+
* consults a setter inherited there, and these lists become the bytes that get signed. */
|
|
29
|
+
var _push = intrinsic.append;
|
|
27
30
|
/** @internal The promise a signature verdict is awaited through, built from the constructor captured at
|
|
28
31
|
* load. `Promise.resolve` builds from its RECEIVER, so reading the global binding at the call hands the
|
|
29
32
|
* construction to whatever that binding holds: one settling without awaiting its argument drops the
|
|
@@ -195,7 +198,7 @@ function _issuerSerialContent(is) {
|
|
|
195
198
|
var parts = [_b.encodeGeneralNames(_gnList(is.issuer)), _b.serialInteger(is.serial)];
|
|
196
199
|
if (is.issuerUID != null) {
|
|
197
200
|
if (!Buffer.isBuffer(is.issuerUID)) throw _err("attrcert/bad-input", "baseCertificateID.issuerUID must be a Buffer");
|
|
198
|
-
parts
|
|
201
|
+
_push(parts,b.bitString(is.issuerUID, 0));
|
|
199
202
|
}
|
|
200
203
|
return Buffer.concat(parts);
|
|
201
204
|
}
|
|
@@ -251,8 +254,8 @@ function _encodeRole(role) {
|
|
|
251
254
|
_assertFields(role, KNOWN_ROLE_KEYS, "role");
|
|
252
255
|
if (role.roleName == null) throw _err("attrcert/bad-input", "role must be an object with a roleName GeneralName");
|
|
253
256
|
var parts = [];
|
|
254
|
-
if (role.roleAuthority != null) parts
|
|
255
|
-
parts
|
|
257
|
+
if (role.roleAuthority != null) _push(parts,_b.encodeGeneralNames(_gnList(role.roleAuthority), 0));
|
|
258
|
+
_push(parts,b.explicit(1, _b.encodeGeneralName(role.roleName)));
|
|
256
259
|
return b.sequence(parts);
|
|
257
260
|
}
|
|
258
261
|
function _encodeClearance(cl) {
|
|
@@ -269,11 +272,11 @@ function _encodeClearance(cl) {
|
|
|
269
272
|
return pos;
|
|
270
273
|
});
|
|
271
274
|
var isDefault = positions.length === 1 && positions[0] === CLASSLIST_BIT.unclassified;
|
|
272
|
-
if (!isDefault) parts
|
|
275
|
+
if (!isDefault) _push(parts,b.namedBitString(positions));
|
|
273
276
|
}
|
|
274
277
|
if (cl.securityCategories != null) {
|
|
275
278
|
if (!Array.isArray(cl.securityCategories) || !cl.securityCategories.length) throw _err("attrcert/bad-input", "clearance.securityCategories must be a non-empty array");
|
|
276
|
-
parts
|
|
279
|
+
_push(parts,b.set(guard.list.copyMap(cl.securityCategories, _encodeSecurityCategory)));
|
|
277
280
|
}
|
|
278
281
|
return b.sequence(parts);
|
|
279
282
|
}
|
|
@@ -291,8 +294,8 @@ function _encodeIetfAttrSyntax(ia) {
|
|
|
291
294
|
_assertFields(ia, KNOWN_IETF_ATTR_KEYS, "IetfAttrSyntax");
|
|
292
295
|
if (!Array.isArray(ia.values) || !ia.values.length) throw _err("attrcert/bad-input", "an IetfAttrSyntax attribute must be an object with a non-empty values array");
|
|
293
296
|
var parts = [];
|
|
294
|
-
if (ia.policyAuthority != null) parts
|
|
295
|
-
parts
|
|
297
|
+
if (ia.policyAuthority != null) _push(parts,_b.encodeGeneralNames(_gnList(ia.policyAuthority), 0));
|
|
298
|
+
_push(parts,b.sequence(guard.list.copyMap(ia.values, function (v) {
|
|
296
299
|
if (v == null || typeof v !== "object") throw _err("attrcert/bad-input", "each IetfAttrSyntax value must be { octets }, { oid }, or { string }");
|
|
297
300
|
_assertFields(v, KNOWN_IETF_ATTR_VALUE_KEYS, "IetfAttrSyntax value");
|
|
298
301
|
if (v.octets != null) { if (!Buffer.isBuffer(v.octets)) throw _err("attrcert/bad-input", "IetfAttrSyntax octets must be a Buffer"); return b.octetString(v.octets); }
|
|
@@ -310,7 +313,7 @@ function _encodeSvceAuthInfo(sai, authInfoAllowed, label) {
|
|
|
310
313
|
if (sai.authInfo != null) {
|
|
311
314
|
if (!authInfoAllowed) throw _err("attrcert/bad-input", "accessIdentity must not carry authInfo (RFC 5755 sec. 4.4.2)");
|
|
312
315
|
if (!Buffer.isBuffer(sai.authInfo)) throw _err("attrcert/bad-input", label + " authInfo must be a Buffer");
|
|
313
|
-
parts
|
|
316
|
+
_push(parts,b.octetString(sai.authInfo));
|
|
314
317
|
}
|
|
315
318
|
return b.sequence(parts);
|
|
316
319
|
}
|
|
@@ -349,11 +352,11 @@ function _encodeAAControls(aac) {
|
|
|
349
352
|
var parts = [];
|
|
350
353
|
if (aac.pathLenConstraint != null) {
|
|
351
354
|
if (typeof aac.pathLenConstraint !== "number" || !Number.isInteger(aac.pathLenConstraint) || aac.pathLenConstraint < 0 || aac.pathLenConstraint > 0x7fffffff) throw _err("attrcert/bad-input", "aaControls.pathLenConstraint must be an integer in 0..2147483647 (RFC 5755 sec. 7.4)");
|
|
352
|
-
parts
|
|
355
|
+
_push(parts,b.integer(BigInt(aac.pathLenConstraint)));
|
|
353
356
|
}
|
|
354
|
-
if (aac.permittedAttrs != null) parts
|
|
355
|
-
if (aac.excludedAttrs != null) parts
|
|
356
|
-
if (aac.permitUnSpecified === false) parts
|
|
357
|
+
if (aac.permittedAttrs != null) _push(parts,_attrSpec(aac.permittedAttrs, 0, "permittedAttrs"));
|
|
358
|
+
if (aac.excludedAttrs != null) _push(parts,_attrSpec(aac.excludedAttrs, 1, "excludedAttrs"));
|
|
359
|
+
if (aac.permitUnSpecified === false) _push(parts,b.boolean(false));
|
|
357
360
|
else if (aac.permitUnSpecified != null && aac.permitUnSpecified !== true) throw _err("attrcert/bad-input", "aaControls.permitUnSpecified must be a boolean");
|
|
358
361
|
return b.sequence(parts);
|
|
359
362
|
}
|
|
@@ -388,7 +391,7 @@ function _buildAttributes(attrSpec) {
|
|
|
388
391
|
if (seen[type]) throw _err("attrcert/duplicate-attribute", "duplicate " + (oid.name(type) || type) + " attribute (RFC 5755 sec. 4.2.7)");
|
|
389
392
|
seen[type] = true;
|
|
390
393
|
_assertAttributeProfile(type, attrcert.validateAttributeValue(type, valueTlv));
|
|
391
|
-
attrs
|
|
394
|
+
_push(attrs,b.sequence([b.oid(type), b.set([valueTlv])]));
|
|
392
395
|
}
|
|
393
396
|
if (Array.isArray(attrSpec)) {
|
|
394
397
|
/** @internal Through the captured walk, never the caller's own `forEach`: these attributes are the
|
|
@@ -409,7 +412,7 @@ function _buildAttributes(attrSpec) {
|
|
|
409
412
|
catch (err) { if (err instanceof AttrCertError) throw err; throw _err("attrcert/bad-input", "pre-encoded " + (oid.name(at) || at) + " attribute value is malformed", err); }
|
|
410
413
|
_assertAttributeProfile(at, decoded);
|
|
411
414
|
});
|
|
412
|
-
attrs
|
|
415
|
+
_push(attrs,b.raw(der));
|
|
413
416
|
});
|
|
414
417
|
if (!attrs.length) throw _err("attrcert/bad-attributes", "attributes must carry at least one Attribute (RFC 5755 sec. 4.2.7)");
|
|
415
418
|
return b.sequence(attrs);
|
|
@@ -442,7 +445,7 @@ function _emitNamedExtension(out, seen, k, val, ctx) {
|
|
|
442
445
|
seen[eOid] = true;
|
|
443
446
|
var valueDer = _extensionValue(k, val, ctx);
|
|
444
447
|
_assertExtensionProfile(eOid, _decodeExtensionValue(eOid, valueDer), ctx);
|
|
445
|
-
out
|
|
448
|
+
_push(out,_b.ext(eOid, meta.critical, valueDer));
|
|
446
449
|
}
|
|
447
450
|
function _buildExtensions(extSpec, ctx) {
|
|
448
451
|
if (extSpec == null) extSpec = {};
|
|
@@ -593,7 +596,7 @@ function _sign(spec, issuer, opts) {
|
|
|
593
596
|
b.integer(1n), holderDer, issuerDer, scheme.sigAlgId,
|
|
594
597
|
_b.serialInteger(spec.serialNumber), validityDer, attributesDer,
|
|
595
598
|
];
|
|
596
|
-
if (extsDer) acinfoChildren
|
|
599
|
+
if (extsDer) _push(acinfoChildren,extsDer);
|
|
597
600
|
var acinfoDer = b.sequence(acinfoChildren);
|
|
598
601
|
|
|
599
602
|
return signScheme.signOverTbs(scheme, issuer.key, acinfoDer, _signE).then(function (sig) {
|
package/lib/byte-writer.js
CHANGED
|
@@ -18,20 +18,58 @@
|
|
|
18
18
|
* in a format module.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
var intrinsic = require("./guard-intrinsic");
|
|
22
|
+
/** @internal Every operation this writer decides a field's width, range or bytes with is bound at
|
|
23
|
+
* load. Each one participates in what gets emitted: the integer tests decide whether a value fits
|
|
24
|
+
* the field, the allocation decides how wide the field is, and the concatenation decides the byte
|
|
25
|
+
* string a caller signs or sends. */
|
|
26
|
+
var _isInteger = intrinsic.isInteger;
|
|
27
|
+
var _isSafeInteger = intrinsic.isSafeInteger;
|
|
28
|
+
var _bufferAlloc = intrinsic.bufferAlloc;
|
|
29
|
+
var _isBuffer = intrinsic.isBuffer;
|
|
30
|
+
var _bufferConcat = intrinsic.bufferConcat;
|
|
31
|
+
var _BigInt = intrinsic.BigInt;
|
|
32
|
+
var _taSet = intrinsic.typedArraySet;
|
|
33
|
+
/** @internal The two writes that place an integer into its field, bound at load. A bound's own
|
|
34
|
+
* `valueOf` runs inside the comparison the length is checked by, which is a window to replace a
|
|
35
|
+
* method the write that follows would otherwise read off the prototype: measured, a vector declared
|
|
36
|
+
* a length of 0 over a payload of two bytes that way. */
|
|
37
|
+
var _writeUIntBE = intrinsic.uncurry(Buffer.prototype.writeUIntBE);
|
|
38
|
+
var _writeBigUInt64BE = intrinsic.uncurry(Buffer.prototype.writeBigUInt64BE);
|
|
39
|
+
|
|
40
|
+
/** @internal A real copy of the bytes, in this writer's own allocation. A slice of a view shares the
|
|
41
|
+
* backing buffer, so a buffer that can be resized takes the slice out of bounds with it, and the
|
|
42
|
+
* copy has to be taken before anything else in the call can run code. */
|
|
43
|
+
function _copyOf(view) {
|
|
44
|
+
var n = intrinsic.sizeOf(view);
|
|
45
|
+
var out = _bufferAlloc(n);
|
|
46
|
+
if (n !== 0) _taSet(out, view, 0);
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
|
|
21
50
|
function ByteWriter(E, defaultCode) {
|
|
22
51
|
this.parts = [];
|
|
23
52
|
this.len = 0;
|
|
24
53
|
this.E = E;
|
|
25
54
|
this.defaultCode = defaultCode || "byte-writer/bad-value";
|
|
26
55
|
}
|
|
27
|
-
|
|
56
|
+
/** @internal The piece is APPENDED by defining its index, not stored by `push`. A store walks the
|
|
57
|
+
* prototype chain for a setter, so an accessor installed at an array index receives each piece as it
|
|
58
|
+
* is added and can define something else in its place, and these pieces are the bytes this writer
|
|
59
|
+
* emits. The length is accumulated from the buffer's own byte length rather than a `length`
|
|
60
|
+
* property, so a view that overstates itself cannot make the declared length disagree with the
|
|
61
|
+
* bytes. */
|
|
62
|
+
ByteWriter.prototype._push = function (buf) {
|
|
63
|
+
intrinsic.append(this.parts, buf);
|
|
64
|
+
this.len += intrinsic.sizeOf(buf);
|
|
65
|
+
};
|
|
28
66
|
ByteWriter.prototype._uint = function (v, width, code) {
|
|
29
|
-
if (!
|
|
67
|
+
if (!_isInteger(width) || width < 1 || width > 4) throw new this.E(code || this.defaultCode, "an integer width must be 1..4, got " + width);
|
|
30
68
|
var max = width === 4 ? 0xffffffff : (1 << (8 * width)) - 1;
|
|
31
|
-
if (typeof v !== "number" || !
|
|
69
|
+
if (typeof v !== "number" || !_isSafeInteger(v) || v < 0 || v > max) {
|
|
32
70
|
throw new this.E(code || this.defaultCode, "a uint" + (8 * width) + " must be an integer in 0.." + max + ", got " + v);
|
|
33
71
|
}
|
|
34
|
-
var b =
|
|
72
|
+
var b = _bufferAlloc(width); _writeUIntBE(b, v, 0, width); this._push(b);
|
|
35
73
|
};
|
|
36
74
|
ByteWriter.prototype.u8 = function (v, code) { this._uint(v, 1, code); return this; };
|
|
37
75
|
ByteWriter.prototype.u16 = function (v, code) { this._uint(v, 2, code); return this; };
|
|
@@ -40,25 +78,37 @@ ByteWriter.prototype.u32 = function (v, code) { this._uint(v, 4, code); return t
|
|
|
40
78
|
ByteWriter.prototype.u64 = function (v, code) {
|
|
41
79
|
var big;
|
|
42
80
|
if (typeof v === "bigint") big = v;
|
|
43
|
-
else if (typeof v === "number" &&
|
|
81
|
+
else if (typeof v === "number" && _isSafeInteger(v) && v >= 0) big = _BigInt(v);
|
|
44
82
|
else throw new this.E(code || this.defaultCode, "a uint64 must be a non-negative integer or BigInt, got " + v);
|
|
45
83
|
if (big < 0n || big > 0xffffffffffffffffn) throw new this.E(code || this.defaultCode, "a uint64 must be in 0..2^64-1");
|
|
46
|
-
var b =
|
|
84
|
+
var b = _bufferAlloc(8); _writeBigUInt64BE(b, big); this._push(b);
|
|
47
85
|
return this;
|
|
48
86
|
};
|
|
49
87
|
ByteWriter.prototype.bytes = function (buf, code) {
|
|
50
|
-
if (!
|
|
88
|
+
if (!_isBuffer(buf)) throw new this.E(code || this.defaultCode, "bytes() requires a Buffer");
|
|
51
89
|
this._push(buf); return this;
|
|
52
90
|
};
|
|
53
91
|
ByteWriter.prototype.vector = function (lenWidth, min, max, body, code) {
|
|
54
|
-
if (!
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
92
|
+
if (!_isBuffer(body)) throw new this.E(code || this.defaultCode, "vector() body must be a Buffer");
|
|
93
|
+
/** @internal The body is COPIED before it is measured, and the copy is what gets written. The
|
|
94
|
+
* bounds, the length prefix and the bytes then all describe one byte string that nothing else
|
|
95
|
+
* holds. Measuring the caller's view instead left a window: a resizable backing buffer shrunk
|
|
96
|
+
* between the measurement and the write (a `min` whose `valueOf` resizes it is enough) and the
|
|
97
|
+
* vector declared two bytes over a payload of one. The bounds are converted to numbers up front
|
|
98
|
+
* for the same reason, so a bound cannot run code in the middle of the comparison it is part of. */
|
|
99
|
+
var bytes = _copyOf(body);
|
|
100
|
+
var bodyLen = intrinsic.sizeOf(bytes);
|
|
101
|
+
var lo = intrinsic.Number(min);
|
|
102
|
+
if (!_isSafeInteger(lo) || lo < 0) throw new this.E(code || this.defaultCode, "a vector minimum must be a non-negative integer, got " + lo);
|
|
103
|
+
var hi = max == null ? null : intrinsic.Number(max);
|
|
104
|
+
if (hi !== null && (!_isSafeInteger(hi) || hi < lo)) throw new this.E(code || this.defaultCode, "a vector maximum must be an integer not below the minimum, got " + hi);
|
|
105
|
+
if (bodyLen < lo) throw new this.E(code || this.defaultCode, "vector body " + bodyLen + " below minimum " + lo);
|
|
106
|
+
if (hi !== null && bodyLen > hi) throw new this.E(code || this.defaultCode, "vector body " + bodyLen + " above maximum " + hi);
|
|
107
|
+
this._uint(bodyLen, lenWidth, code);
|
|
108
|
+
this._push(bytes);
|
|
59
109
|
return this;
|
|
60
110
|
};
|
|
61
111
|
ByteWriter.prototype.length = function () { return this.len; };
|
|
62
|
-
ByteWriter.prototype.build = function () { return
|
|
112
|
+
ByteWriter.prototype.build = function () { return _bufferConcat(this.parts, this.len); };
|
|
63
113
|
|
|
64
114
|
module.exports = ByteWriter;
|
package/lib/cbor-det.js
CHANGED
|
@@ -40,6 +40,12 @@ var constants = require("./constants");
|
|
|
40
40
|
var frameworkError = require("./framework-error");
|
|
41
41
|
var asn1 = require("./asn1-der");
|
|
42
42
|
var guard = require("./guard-all");
|
|
43
|
+
/** @internal The append every list in this module is built with. `push` STORES at the index, and a
|
|
44
|
+
* store walks the prototype chain for a setter, so an accessor inherited at an array index receives
|
|
45
|
+
* each element as it is appended and the index then reads back whatever its getter answers. The
|
|
46
|
+
* decoded children below are what every C509 field is read out of, so a replaced element there is a
|
|
47
|
+
* field this codec never decoded. */
|
|
48
|
+
var _push = guard.list.append;
|
|
43
49
|
|
|
44
50
|
var CborError = frameworkError.CborError;
|
|
45
51
|
|
|
@@ -141,7 +147,7 @@ function _decodeItem(buf, start, limit, depth, maxD, rules, state) {
|
|
|
141
147
|
var cp = contentStart;
|
|
142
148
|
for (var i = 0n; i < argument; i++) {
|
|
143
149
|
var el = _decodeItem(buf, cp, limit, depth + 1, maxD, rules, state);
|
|
144
|
-
children
|
|
150
|
+
_push(children, el.node);
|
|
145
151
|
cp = el.end;
|
|
146
152
|
}
|
|
147
153
|
end = cp;
|
|
@@ -158,7 +164,7 @@ function _decodeItem(buf, start, limit, depth, maxD, rules, state) {
|
|
|
158
164
|
if (cmp > 0) throw new CborError("cbor/unsorted-map-keys", "map keys are not in bytewise-ascending order");
|
|
159
165
|
if (cmp === 0) throw new CborError("cbor/duplicate-map-key", "duplicate map key");
|
|
160
166
|
}
|
|
161
|
-
children
|
|
167
|
+
_push(children, [k.node, v.node]);
|
|
162
168
|
}
|
|
163
169
|
end = mp;
|
|
164
170
|
} else if (mt === 6) {
|
|
@@ -682,7 +688,7 @@ var build = Object.assign(Object.create(null), {
|
|
|
682
688
|
enc = guard.list.sortedCopy(enc, function (a, b) { return guard.bytes.compare(a[0], b[0]); });
|
|
683
689
|
for (var i = 1; i < enc.length; i++) { if (guard.bytes.compare(enc[i - 1][0], enc[i][0]) === 0) throw new CborError("cbor/duplicate-map-key", "build.map: duplicate map key"); }
|
|
684
690
|
var flat = [_head(5, pairs.length, "build.map")];
|
|
685
|
-
enc.forEach(function (p) { flat
|
|
691
|
+
enc.forEach(function (p) { _push(flat, p[0]); _push(flat, p[1]); });
|
|
686
692
|
return _assertDecodes(Buffer.concat(flat), "build.map");
|
|
687
693
|
},
|
|
688
694
|
tag: function (tagNum, inner) { return _assertDecodes(Buffer.concat([_head(6, tagNum, "build.tag"), _cbItem(inner, "build.tag content")]), "build.tag"); },
|
package/lib/cmc-build.js
CHANGED
|
@@ -22,6 +22,9 @@ var key = require("./key");
|
|
|
22
22
|
var _createPublicKey = nodeCrypto.createPublicKey;
|
|
23
23
|
var guard = require("./guard-all");
|
|
24
24
|
var intrinsic = require("./guard-intrinsic");
|
|
25
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
26
|
+
* consults a setter inherited there, and these lists become the controls a request carries. */
|
|
27
|
+
var _push = intrinsic.append;
|
|
25
28
|
var _hasOwn = intrinsic.hasOwn;
|
|
26
29
|
var _isArray = intrinsic.isArray;
|
|
27
30
|
var _isBuffer = intrinsic.isBuffer;
|
|
@@ -173,7 +176,10 @@ function fixedRequestId(req, index) {
|
|
|
173
176
|
return "unknown field " + JSON.stringify(k) + " on request " + index +
|
|
174
177
|
" -- a request names one of tcr / crm / orm, and optionally bodyPartID";
|
|
175
178
|
});
|
|
176
|
-
|
|
179
|
+
/** @internal `selectList`, not the live `filter`: the selection decides which request arm this
|
|
180
|
+
* message carries, and `Array.prototype.filter` is both read off the prototype and specified to
|
|
181
|
+
* build its result through the species constructor. */
|
|
182
|
+
var arms = intrinsic.selectList(["tcr", "crm", "orm"], function (k) { return req[k] != null; });
|
|
177
183
|
if (arms.length !== 1) {
|
|
178
184
|
throw E("cmc/bad-input",
|
|
179
185
|
"each request names exactly one of tcr / crm / orm, got " + (arms.length ? arms.join(" + ") : "none") +
|
|
@@ -446,7 +452,7 @@ function _assertSecret(secret, what) {
|
|
|
446
452
|
}
|
|
447
453
|
|
|
448
454
|
function _ownSecret(buf, owned) {
|
|
449
|
-
owned
|
|
455
|
+
_push(owned,buf);
|
|
450
456
|
return buf;
|
|
451
457
|
}
|
|
452
458
|
|
|
@@ -801,15 +807,15 @@ async function _build(spec, signer, opts) {
|
|
|
801
807
|
|
|
802
808
|
_assertNoDuplicateBinding(callerControls, spec);
|
|
803
809
|
if (spec.transactionId != null) {
|
|
804
|
-
controls
|
|
810
|
+
_push(controls,encodeControl(OID_TRANSACTION_ID,
|
|
805
811
|
[b.integer(_asBigInt(spec.transactionId, "spec.transactionId"))], ids));
|
|
806
812
|
}
|
|
807
813
|
if (spec.senderNonce != null) {
|
|
808
|
-
controls
|
|
814
|
+
_push(controls,encodeControl(OID_SENDER_NONCE,
|
|
809
815
|
[b.octetString(_der(spec.senderNonce, "spec.senderNonce"))], ids));
|
|
810
816
|
}
|
|
811
817
|
if (spec.dataReturn != null) {
|
|
812
|
-
controls
|
|
818
|
+
_push(controls,encodeControl(OID_DATA_RETURN,
|
|
813
819
|
[b.octetString(_der(spec.dataReturn, "spec.dataReturn"))], ids));
|
|
814
820
|
}
|
|
815
821
|
|
|
@@ -836,8 +842,8 @@ async function _build(spec, signer, opts) {
|
|
|
836
842
|
if (identity != null && typeof identity !== "string") {
|
|
837
843
|
throw E("cmc/bad-input", "identityProof.identity is the UTF8String the Identification control carries");
|
|
838
844
|
}
|
|
839
|
-
if (identity != null) controls
|
|
840
|
-
controls
|
|
845
|
+
if (identity != null) _push(controls,encodeControl(OID_IDENTIFICATION, [b.utf8(identity)], ids));
|
|
846
|
+
_push(controls,encodeControl(OID_IDENTITY_PROOF_V2,
|
|
841
847
|
[identityProofV2(spec.identityProof.secret, reqSequenceBytes, carriedIdentity)], ids));
|
|
842
848
|
}
|
|
843
849
|
|
|
@@ -930,8 +936,8 @@ async function _build(spec, signer, opts) {
|
|
|
930
936
|
throw E("cmc/bad-input", "popLinkRandomBytes must be a positive integer");
|
|
931
937
|
}
|
|
932
938
|
var R = nodeCrypto.randomBytes(rBytes);
|
|
933
|
-
controls
|
|
934
|
-
controls
|
|
939
|
+
_push(controls,encodeControl(OID_POP_LINK_RANDOM, [b.octetString(R)], ids));
|
|
940
|
+
_push(controls,encodeControl(O("id-cmc-popLinkWitnessV2"),
|
|
935
941
|
[popLinkWitnessV2(spec.popLink.secret, R)], ids));
|
|
936
942
|
}
|
|
937
943
|
|
|
@@ -1013,7 +1019,7 @@ function _copySigners(signer, owned) {
|
|
|
1013
1019
|
return c;
|
|
1014
1020
|
}
|
|
1015
1021
|
function _own(buf, isSecret) {
|
|
1016
|
-
if (isSecret && owned) owned
|
|
1022
|
+
if (isSecret && owned) _push(owned,buf);
|
|
1017
1023
|
return buf;
|
|
1018
1024
|
}
|
|
1019
1025
|
return Array.isArray(signer) ? guard.list.copyMap(signer, one) : one(signer);
|
package/lib/cmp-build.js
CHANGED
|
@@ -29,6 +29,7 @@ var cmp = require("./schema-cmp");
|
|
|
29
29
|
var crmf = require("./crmf-sign");
|
|
30
30
|
var schemaCrmf = require("./schema-crmf");
|
|
31
31
|
var intrinsic = require("./guard-intrinsic");
|
|
32
|
+
var _strTrim = intrinsic.uncurry(String.prototype.trim);
|
|
32
33
|
/** @internal The promise a signature self-check is awaited through, built from the constructor captured
|
|
33
34
|
* at load. `Promise.resolve` builds from its RECEIVER, so reading the global binding at the call hands
|
|
34
35
|
* the construction to whatever that binding holds, and one settling without awaiting its argument runs
|
|
@@ -55,7 +56,9 @@ var _bufferConcat = intrinsic.bufferConcat;
|
|
|
55
56
|
var _map = intrinsic.map;
|
|
56
57
|
var _keys = intrinsic.keys;
|
|
57
58
|
var _forEach = intrinsic.forEach;
|
|
58
|
-
|
|
59
|
+
/** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
|
|
60
|
+
* setter, so an accessor there takes the element being appended. `append` defines it. */
|
|
61
|
+
var _push = intrinsic.append;
|
|
59
62
|
var _stringify = intrinsic.stringify;
|
|
60
63
|
var _bigInt = intrinsic.BigInt;
|
|
61
64
|
var _Date = intrinsic.Date;
|
|
@@ -166,7 +169,7 @@ function _encodeInfoTypeAndValue(itav) {
|
|
|
166
169
|
if (typeof itav.infoType !== "string" || O(itav.infoType) == null) throw _err("cmp/bad-name", "unknown infoType " + guard.text.showValue(itav.infoType));
|
|
167
170
|
var children = [b.oid(O(itav.infoType))];
|
|
168
171
|
var val = _encodeInfoValue(itav);
|
|
169
|
-
if (val != null) children
|
|
172
|
+
if (val != null) _push(children,val);
|
|
170
173
|
return b.sequence(children);
|
|
171
174
|
}
|
|
172
175
|
|
|
@@ -237,16 +240,16 @@ function _encodeHeader(headerSpec, protectionAlgDer, pvno) {
|
|
|
237
240
|
];
|
|
238
241
|
if (headerSpec.messageTime != null) {
|
|
239
242
|
guard.time.assertEncodable(headerSpec.messageTime, _err, "cmp/bad-input", "header.messageTime");
|
|
240
|
-
children
|
|
243
|
+
_push(children,b.explicit(0, b.generalizedTime(headerSpec.messageTime)));
|
|
241
244
|
}
|
|
242
|
-
if (protectionAlgDer != null) children
|
|
243
|
-
if (headerSpec.senderKID != null) children
|
|
244
|
-
if (headerSpec.recipKID != null) children
|
|
245
|
-
if (headerSpec.transactionID != null) children
|
|
246
|
-
if (headerSpec.senderNonce != null) children
|
|
247
|
-
if (headerSpec.recipNonce != null) children
|
|
248
|
-
if (headerSpec.freeText != null) children
|
|
249
|
-
if (headerSpec.generalInfo != null) children
|
|
245
|
+
if (protectionAlgDer != null) _push(children,b.explicit(1, b.raw(protectionAlgDer)));
|
|
246
|
+
if (headerSpec.senderKID != null) _push(children,b.explicit(2, _reqOctets(headerSpec.senderKID, "header.senderKID")));
|
|
247
|
+
if (headerSpec.recipKID != null) _push(children,b.explicit(3, _reqOctets(headerSpec.recipKID, "header.recipKID")));
|
|
248
|
+
if (headerSpec.transactionID != null) _push(children,b.explicit(4, _reqOctets(headerSpec.transactionID, "header.transactionID")));
|
|
249
|
+
if (headerSpec.senderNonce != null) _push(children,b.explicit(5, _reqOctets(headerSpec.senderNonce, "header.senderNonce")));
|
|
250
|
+
if (headerSpec.recipNonce != null) _push(children,b.explicit(6, _reqOctets(headerSpec.recipNonce, "header.recipNonce")));
|
|
251
|
+
if (headerSpec.freeText != null) _push(children,b.explicit(7, _encodePkiFreeText(headerSpec.freeText, "cmp/bad-freetext", "header.freeText")));
|
|
252
|
+
if (headerSpec.generalInfo != null) _push(children,b.explicit(8, _encodeGeneralInfo(headerSpec.generalInfo, "cmp/bad-general-info", "header.generalInfo")));
|
|
250
253
|
return b.sequence(children);
|
|
251
254
|
}
|
|
252
255
|
|
|
@@ -266,8 +269,8 @@ function _encodePkiStatusInfo(si, code) {
|
|
|
266
269
|
if (!si || typeof si !== "object" || Buffer.isBuffer(si)) throw _err(code, "a PKIStatusInfo must be an object { status, statusString?, failInfo? }");
|
|
267
270
|
if (typeof si.status !== "number" || !Number.isInteger(si.status) || si.status < 0 || si.status > 6) throw _err(code, "statusInfo.status must be a PKIStatus 0..6 (RFC 9810 sec. 5.2.3)");
|
|
268
271
|
var children = [b.integer(BigInt(si.status))];
|
|
269
|
-
if (si.statusString != null) children
|
|
270
|
-
if (si.failInfo != null) children
|
|
272
|
+
if (si.statusString != null) _push(children,_encodePkiFreeText(si.statusString, code, "statusInfo.statusString"));
|
|
273
|
+
if (si.failInfo != null) _push(children,_encodeFailInfo(si.failInfo, code));
|
|
271
274
|
return b.sequence(children);
|
|
272
275
|
}
|
|
273
276
|
|
|
@@ -277,10 +280,10 @@ function _encodeCertStatus(cs, state) {
|
|
|
277
280
|
_reqOctets(cs.certHash, "certConf certHash"),
|
|
278
281
|
b.integer(_reqIdInt(cs.certReqId, "cmp/bad-cert-status", "CertStatus certReqId")),
|
|
279
282
|
];
|
|
280
|
-
if (cs.statusInfo != null) children
|
|
283
|
+
if (cs.statusInfo != null) _push(children,_encodePkiStatusInfo(cs.statusInfo, "cmp/bad-cert-status"));
|
|
281
284
|
if (cs.hashAlg != null) {
|
|
282
285
|
if (typeof cs.hashAlg !== "string" || !CERT_CONF_HASH_ALGS[cs.hashAlg]) throw _err("cmp/bad-name", "certConf hashAlg must be a hash algorithm (sha256 / sha384 / sha512 / sha3-256 / sha3-512 / sha1); got " + guard.text.showValue(cs.hashAlg));
|
|
283
|
-
children
|
|
286
|
+
_push(children,b.explicit(0, _algIdNoParams(cs.hashAlg)));
|
|
284
287
|
state.usesCmp2021 = true;
|
|
285
288
|
}
|
|
286
289
|
return b.sequence(children);
|
|
@@ -316,7 +319,7 @@ function _encodeRevDetails(rd) {
|
|
|
316
319
|
certDetails = b.raw(crmf.buildCertTemplate(rd.certDetails));
|
|
317
320
|
}
|
|
318
321
|
var children = [certDetails];
|
|
319
|
-
if (rd.crlEntryDetails != null) children
|
|
322
|
+
if (rd.crlEntryDetails != null) _push(children,b.raw(_encodeCrlEntryDetails(rd.crlEntryDetails)));
|
|
320
323
|
return b.sequence(children);
|
|
321
324
|
}
|
|
322
325
|
|
|
@@ -418,12 +421,12 @@ function _encodeCertifiedKeyPair(ckp, state) {
|
|
|
418
421
|
var children = [_encodeCertOrEncCert(ckp, state)];
|
|
419
422
|
if (ckp.privateKey != null) {
|
|
420
423
|
var pk = _b.reqDer(ckp.privateKey, "certifiedKeyPair.privateKey (a pre-encoded EncryptedKey DER)");
|
|
421
|
-
children
|
|
424
|
+
_push(children,b.explicit(0, b.raw(pk)));
|
|
422
425
|
var pkNode;
|
|
423
426
|
try { pkNode = asn1.decode(pk); } catch (e) { throw _err("cmp/bad-cert-response", "certifiedKeyPair.privateKey is not valid DER", e); }
|
|
424
427
|
if (pkNode.tagClass === "context" && pkNode.tagNumber === 0) state.usesCmp2021 = true;
|
|
425
428
|
}
|
|
426
|
-
if (ckp.publicationInfo != null) children
|
|
429
|
+
if (ckp.publicationInfo != null) _push(children,b.explicit(1, b.raw(_b.reqDer(ckp.publicationInfo, "certifiedKeyPair.publicationInfo (a pre-encoded DER)"))));
|
|
427
430
|
return b.sequence(children);
|
|
428
431
|
}
|
|
429
432
|
|
|
@@ -434,8 +437,8 @@ function _encodeCertResponse(cr, state) {
|
|
|
434
437
|
if (hasCkp && cr.status.failInfo != null) throw _err("cmp/bad-cert-response", "a CertResponse must not carry both failInfo and certifiedKeyPair");
|
|
435
438
|
if (hasCkp && cr.status.status !== 0 && cr.status.status !== 1) throw _err("cmp/bad-cert-response", "a CertResponse certifiedKeyPair is allowed only under a granting status (accepted / grantedWithMods)");
|
|
436
439
|
var children = [b.integer(_reqIdInt(cr.certReqId, "cmp/bad-cert-response", "CertResponse certReqId")), _encodePkiStatusInfo(cr.status, "cmp/bad-cert-response")];
|
|
437
|
-
if (hasCkp) children
|
|
438
|
-
if (cr.rspInfo != null) children
|
|
440
|
+
if (hasCkp) _push(children,_encodeCertifiedKeyPair(cr.certifiedKeyPair, state));
|
|
441
|
+
if (cr.rspInfo != null) _push(children,_reqOctets(cr.rspInfo, "CertResponse.rspInfo"));
|
|
439
442
|
return b.sequence(children);
|
|
440
443
|
}
|
|
441
444
|
|
|
@@ -445,9 +448,9 @@ function _encodeCertRepMessage(spec, state, arm) {
|
|
|
445
448
|
var children = [];
|
|
446
449
|
if (spec.caPubs != null) {
|
|
447
450
|
if (!Array.isArray(spec.caPubs) || !spec.caPubs.length) throw _err("cmp/bad-cert-rep", arm + ".caPubs must be a non-empty array of certificate DERs");
|
|
448
|
-
children
|
|
451
|
+
_push(children,b.explicit(1, b.sequence(spec.caPubs.map(function (c) { return _certRaw(c, "cmp/bad-cert-rep", "a caPubs entry"); }))));
|
|
449
452
|
}
|
|
450
|
-
children
|
|
453
|
+
_push(children,b.sequence(spec.response.map(function (cr) { return _encodeCertResponse(cr, state); })));
|
|
451
454
|
return b.sequence(children);
|
|
452
455
|
}
|
|
453
456
|
|
|
@@ -467,11 +470,11 @@ function _encodeRevRepContent(spec) {
|
|
|
467
470
|
var children = [b.sequence(spec.status.map(function (si) { return _encodePkiStatusInfo(si, "cmp/bad-rev-rep"); }))];
|
|
468
471
|
if (spec.revCerts != null) {
|
|
469
472
|
if (!Array.isArray(spec.revCerts) || !spec.revCerts.length) throw _err("cmp/bad-rev-rep", "rp.revCerts must be a non-empty array of CertId");
|
|
470
|
-
children
|
|
473
|
+
_push(children,b.explicit(0, b.sequence(spec.revCerts.map(_encodeCertIdRr))));
|
|
471
474
|
}
|
|
472
475
|
if (spec.crls != null) {
|
|
473
476
|
if (!Array.isArray(spec.crls) || !spec.crls.length) throw _err("cmp/bad-rev-rep", "rp.crls must be a non-empty array of CertificateList DERs");
|
|
474
|
-
children
|
|
477
|
+
_push(children,b.explicit(1, b.sequence(spec.crls.map(function (c) {
|
|
475
478
|
var der = _b.reqDerSequence(c, "crls entry (a CertificateList DER)");
|
|
476
479
|
try { crl.parse(der); }
|
|
477
480
|
catch (e) { if (e instanceof CmpError) throw e; throw _err("cmp/bad-rev-rep", "a crls entry is not a valid CRL (CertificateList)", e); }
|
|
@@ -485,8 +488,8 @@ function _encodeErrorMsgContent(spec) {
|
|
|
485
488
|
if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("cmp/bad-error", "error must be an object { pKIStatusInfo, errorCode?, errorDetails? }");
|
|
486
489
|
if (spec.pKIStatusInfo == null) throw _err("cmp/bad-error", "error.pKIStatusInfo is required");
|
|
487
490
|
var children = [_encodePkiStatusInfo(spec.pKIStatusInfo, "cmp/bad-error")];
|
|
488
|
-
if (spec.errorCode != null) children
|
|
489
|
-
if (spec.errorDetails != null) children
|
|
491
|
+
if (spec.errorCode != null) _push(children,b.integer(_reqIdInt(spec.errorCode, "cmp/bad-error", "error.errorCode")));
|
|
492
|
+
if (spec.errorDetails != null) _push(children,_encodePkiFreeText(spec.errorDetails, "cmp/bad-error", "error.errorDetails"));
|
|
490
493
|
return b.sequence(children);
|
|
491
494
|
}
|
|
492
495
|
|
|
@@ -496,7 +499,7 @@ function _encodePollRepContent(list) {
|
|
|
496
499
|
if (!pr || typeof pr !== "object" || Buffer.isBuffer(pr)) throw _err("cmp/bad-poll-rep", "each pollRep entry must be an object");
|
|
497
500
|
if (typeof pr.checkAfter !== "number" || !Number.isInteger(pr.checkAfter) || pr.checkAfter < 0 || pr.checkAfter > 0x7fffffff) throw _err("cmp/bad-poll-rep", "pollRep checkAfter must be a non-negative uint31 delay in seconds (RFC 9810 sec. 5.3.22)");
|
|
498
501
|
var kids = [b.integer(_reqIdInt(pr.certReqId, "cmp/bad-poll-rep", "pollRep certReqId")), b.integer(BigInt(pr.checkAfter))];
|
|
499
|
-
if (pr.reason != null) kids
|
|
502
|
+
if (pr.reason != null) _push(kids,_encodePkiFreeText(pr.reason, "cmp/bad-poll-rep", "pollRep reason"));
|
|
500
503
|
return b.sequence(kids);
|
|
501
504
|
}));
|
|
502
505
|
}
|
|
@@ -505,14 +508,14 @@ function _encodeKeyRecRepContent(spec, state) {
|
|
|
505
508
|
if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("cmp/bad-key-rec-rep", "krp must be an object { status, newSigCert?, caCerts?, keyPairHist? }");
|
|
506
509
|
if (spec.status == null) throw _err("cmp/bad-key-rec-rep", "krp.status is required");
|
|
507
510
|
var children = [_encodePkiStatusInfo(spec.status, "cmp/bad-key-rec-rep")];
|
|
508
|
-
if (spec.newSigCert != null) children
|
|
511
|
+
if (spec.newSigCert != null) _push(children,b.explicit(0, _certRaw(spec.newSigCert, "cmp/bad-key-rec-rep", "krp.newSigCert")));
|
|
509
512
|
if (spec.caCerts != null) {
|
|
510
513
|
if (!Array.isArray(spec.caCerts) || !spec.caCerts.length) throw _err("cmp/bad-key-rec-rep", "krp.caCerts must be a non-empty array of certificate DERs");
|
|
511
|
-
children
|
|
514
|
+
_push(children,b.explicit(1, b.sequence(spec.caCerts.map(function (c) { return _certRaw(c, "cmp/bad-key-rec-rep", "a krp.caCerts entry"); }))));
|
|
512
515
|
}
|
|
513
516
|
if (spec.keyPairHist != null) {
|
|
514
517
|
if (!Array.isArray(spec.keyPairHist) || !spec.keyPairHist.length) throw _err("cmp/bad-key-rec-rep", "krp.keyPairHist must be a non-empty array of CertifiedKeyPair");
|
|
515
|
-
children
|
|
518
|
+
_push(children,b.explicit(2, b.sequence(spec.keyPairHist.map(function (ckp) { return _encodeCertifiedKeyPair(ckp, state); }))));
|
|
516
519
|
}
|
|
517
520
|
return b.sequence(children);
|
|
518
521
|
}
|
|
@@ -890,7 +893,7 @@ async function _build(message, opts) {
|
|
|
890
893
|
var protectionBits = await prot.computeBits(protectedPartDer);
|
|
891
894
|
var msgChildren = [headerTLV, bodyTLV, b.explicit(0, protectionBits)];
|
|
892
895
|
var extraCertsDers = _collectExtraCerts(opts, prot.certDer);
|
|
893
|
-
if (extraCertsDers.length) msgChildren
|
|
896
|
+
if (extraCertsDers.length) _push(msgChildren,b.explicit(1, b.sequence(extraCertsDers)));
|
|
894
897
|
var der = b.sequence(msgChildren);
|
|
895
898
|
|
|
896
899
|
cmp.parse(der);
|
|
@@ -904,14 +907,14 @@ async function _build(message, opts) {
|
|
|
904
907
|
|
|
905
908
|
function _collectExtraCerts(opts, protCertDer) {
|
|
906
909
|
var out = [];
|
|
907
|
-
if (protCertDer != null) out
|
|
910
|
+
if (protCertDer != null) _push(out,b.raw(protCertDer));
|
|
908
911
|
if (opts.extraCerts != null) {
|
|
909
912
|
if (!Array.isArray(opts.extraCerts)) throw _err("cmp/bad-extra-certs", "opts.extraCerts must be an array of certificate DERs");
|
|
910
913
|
opts.extraCerts.forEach(function (c) {
|
|
911
914
|
var der = _b.reqDerSequence(c, "extraCerts entry (a Certificate DER)");
|
|
912
915
|
try { x509.parse(der); }
|
|
913
916
|
catch (e) { if (e instanceof CmpError) throw e; throw _err("cmp/bad-extra-certs", "an extraCerts entry is not a valid X.509 certificate", e); }
|
|
914
|
-
out
|
|
917
|
+
_push(out,b.raw(der));
|
|
915
918
|
});
|
|
916
919
|
}
|
|
917
920
|
return out;
|
|
@@ -1012,7 +1015,15 @@ function _tlsForTransfer(opts) {
|
|
|
1012
1015
|
return guard.identifier.pickSettings(opts.tls, TLS_SETTINGS);
|
|
1013
1016
|
}
|
|
1014
1017
|
|
|
1015
|
-
|
|
1018
|
+
/** @internal The media type is read through the captured operations, and on the delimiter CHARACTER
|
|
1019
|
+
* rather than through `split`, which hard rule 11 bans in lib/ because the separator's own
|
|
1020
|
+
* `Symbol.split` is part of that operation. The token decides which parser a response body is
|
|
1021
|
+
* handed to. */
|
|
1022
|
+
function _ctypeToken(headers) {
|
|
1023
|
+
var raw = intrinsic.String((headers || {})["content-type"] || "");
|
|
1024
|
+
var parts = intrinsic.splitChar(raw, 59);
|
|
1025
|
+
return intrinsic.toLowerCase(_strTrim(parts.length ? parts[0] : ""));
|
|
1026
|
+
}
|
|
1016
1027
|
function _isPkixcmp(headers) { var t = _ctypeToken(headers); return t === PKIXCMP || t === PKIXCMP_POLL; }
|
|
1017
1028
|
|
|
1018
1029
|
/** @internal The sentinel is added at the one exit rather than at each `return`, so a branch added
|