@noz-ele/edgca 0.1.0 → 0.3.0
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/README.md +385 -270
- package/dist/bytes.d.ts +1 -0
- package/dist/bytes.d.ts.map +1 -1
- package/dist/bytes.js +5 -0
- package/dist/ca.d.ts +2 -1
- package/dist/ca.d.ts.map +1 -1
- package/dist/ca.js +63 -34
- package/dist/crypto.d.ts +7 -7
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +98 -44
- package/dist/csr.d.ts +25 -0
- package/dist/csr.d.ts.map +1 -0
- package/dist/csr.js +266 -0
- package/dist/der.d.ts +1 -0
- package/dist/der.d.ts.map +1 -1
- package/dist/der.js +3 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/oids.d.ts +19 -0
- package/dist/oids.d.ts.map +1 -1
- package/dist/oids.js +20 -1
- package/dist/pem.d.ts +0 -2
- package/dist/pem.d.ts.map +1 -1
- package/dist/pem.js +0 -6
- package/dist/pkcs12.d.ts +11 -0
- package/dist/pkcs12.d.ts.map +1 -0
- package/dist/pkcs12.js +248 -0
- package/dist/types.d.ts +18 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/x509.d.ts +4 -2
- package/dist/x509.d.ts.map +1 -1
- package/dist/x509.js +8 -8
- package/package.json +70 -66
package/dist/csr.js
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { cloneBytes } from "./bytes.js";
|
|
2
|
+
import { importPublicKeySpki, verifyDer } from "./crypto.js";
|
|
3
|
+
import { decodeInteger, decodeOid, readChildren, readElement, readSequenceChildren, TAG } from "./der.js";
|
|
4
|
+
import { OID, SUBJECT_ATTRIBUTE_OIDS } from "./oids.js";
|
|
5
|
+
import { pemToDerWithLabel, splitPemBlocks } from "./pem.js";
|
|
6
|
+
const SHORT_NAME_BY_OID = Object.fromEntries(Object.entries(SUBJECT_ATTRIBUTE_OIDS).map(([shortName, oid]) => [oid, shortName]));
|
|
7
|
+
const VALUE_DECODERS = new Map([
|
|
8
|
+
[TAG.UTF8_STRING, (b) => new TextDecoder("utf-8", { fatal: true }).decode(b)],
|
|
9
|
+
[TAG.PRINTABLE_STRING, (b) => decodeAscii(b, "PrintableString")],
|
|
10
|
+
[TAG.IA5_STRING, (b) => decodeAscii(b, "IA5String")]
|
|
11
|
+
]);
|
|
12
|
+
const SUPPORTED_SIGNATURE_OIDS = new Set([
|
|
13
|
+
OID.ecdsaWithSha256,
|
|
14
|
+
OID.ecdsaWithSha384,
|
|
15
|
+
OID.ecdsaWithSha512
|
|
16
|
+
]);
|
|
17
|
+
export async function parseCertificateSigningRequest(input) {
|
|
18
|
+
const der = typeof input === "string" ? csrPemToDer(input) : input;
|
|
19
|
+
const root = readElement(der);
|
|
20
|
+
if (root.tag !== TAG.SEQUENCE || root.end !== der.length) {
|
|
21
|
+
throw new Error("Invalid CSR DER");
|
|
22
|
+
}
|
|
23
|
+
const [requestInfo, signatureAlgorithm, signatureValue] = readSequenceChildren(root);
|
|
24
|
+
if (!requestInfo || !signatureAlgorithm || !signatureValue) {
|
|
25
|
+
throw new Error("Invalid CSR structure");
|
|
26
|
+
}
|
|
27
|
+
if (requestInfo.tag !== TAG.SEQUENCE) {
|
|
28
|
+
throw new Error("Invalid CSR certificationRequestInfo");
|
|
29
|
+
}
|
|
30
|
+
if (signatureAlgorithm.tag !== TAG.SEQUENCE) {
|
|
31
|
+
throw new Error("Invalid CSR signatureAlgorithm");
|
|
32
|
+
}
|
|
33
|
+
if (signatureValue.tag !== TAG.BIT_STRING || signatureValue.value[0] !== 0) {
|
|
34
|
+
throw new Error("Invalid CSR signature value");
|
|
35
|
+
}
|
|
36
|
+
const signatureAlgorithmOid = readAlgorithmOid(signatureAlgorithm);
|
|
37
|
+
if (!SUPPORTED_SIGNATURE_OIDS.has(signatureAlgorithmOid)) {
|
|
38
|
+
throw new Error(`Unsupported CSR signatureAlgorithm: ${signatureAlgorithmOid}`);
|
|
39
|
+
}
|
|
40
|
+
const infoChildren = readSequenceChildren(requestInfo);
|
|
41
|
+
const versionElement = infoChildren[0];
|
|
42
|
+
const subjectElement = infoChildren[1];
|
|
43
|
+
const spkiElement = infoChildren[2];
|
|
44
|
+
const attributesElement = infoChildren[3];
|
|
45
|
+
if (!versionElement || !subjectElement || !spkiElement) {
|
|
46
|
+
throw new Error("Invalid CSR certificationRequestInfo structure");
|
|
47
|
+
}
|
|
48
|
+
if (versionElement.tag !== TAG.INTEGER || decodeInteger(versionElement.value) !== 0n) {
|
|
49
|
+
throw new Error("Unsupported CSR version (only v1 / INTEGER 0 is supported)");
|
|
50
|
+
}
|
|
51
|
+
if (spkiElement.tag !== TAG.SEQUENCE) {
|
|
52
|
+
throw new Error("Invalid CSR subjectPublicKeyInfo");
|
|
53
|
+
}
|
|
54
|
+
if (attributesElement && attributesElement.tag !== 0xa0) {
|
|
55
|
+
throw new Error("Invalid CSR attributes tag (must be IMPLICIT [0])");
|
|
56
|
+
}
|
|
57
|
+
const subject = decodeName(subjectElement);
|
|
58
|
+
const publicKey = await importPublicKeySpki(spkiElement.raw);
|
|
59
|
+
const allAttributes = attributesElement ? decodeAttributes(attributesElement.value) : [];
|
|
60
|
+
const extensionRequest = allAttributes.find((attribute) => attribute.oid === OID.extensionRequest);
|
|
61
|
+
const otherAttributes = allAttributes.filter((attribute) => attribute.oid !== OID.extensionRequest);
|
|
62
|
+
const requestedExtensions = extensionRequest
|
|
63
|
+
? decodeRequestedExtensions(extensionRequest.valuesDer)
|
|
64
|
+
: [];
|
|
65
|
+
const sanExtension = requestedExtensions.find((extension) => extension.oid === OID.subjectAltName);
|
|
66
|
+
const { dnsNames, ipAddresses } = sanExtension
|
|
67
|
+
? decodeSubjectAltName(sanExtension.valueDer)
|
|
68
|
+
: { dnsNames: [], ipAddresses: [] };
|
|
69
|
+
return {
|
|
70
|
+
subject,
|
|
71
|
+
publicKey,
|
|
72
|
+
subjectPublicKeyInfoDer: cloneBytes(spkiElement.raw),
|
|
73
|
+
requestedDnsNames: dnsNames,
|
|
74
|
+
requestedIpAddresses: ipAddresses,
|
|
75
|
+
requestedExtensions,
|
|
76
|
+
otherAttributes,
|
|
77
|
+
signatureAlgorithmOid,
|
|
78
|
+
signatureDer: cloneBytes(signatureValue.value.subarray(1)),
|
|
79
|
+
certificationRequestInfoDer: cloneBytes(requestInfo.raw)
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export async function verifyCertificateSigningRequestSignature(csr) {
|
|
83
|
+
return verifyDer(csr.publicKey, csr.signatureDer, csr.certificationRequestInfoDer);
|
|
84
|
+
}
|
|
85
|
+
function csrPemToDer(pem) {
|
|
86
|
+
// RFC 7468 §7 uses "CERTIFICATE REQUEST"; some legacy tools emit "NEW CERTIFICATE REQUEST".
|
|
87
|
+
const blocks = splitPemBlocks(pem);
|
|
88
|
+
for (const block of blocks) {
|
|
89
|
+
const labelMatch = /-----BEGIN (.+?)-----/.exec(block);
|
|
90
|
+
const label = labelMatch?.[1];
|
|
91
|
+
if (label === "CERTIFICATE REQUEST" || label === "NEW CERTIFICATE REQUEST") {
|
|
92
|
+
return pemToDerWithLabel(block, label);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
throw new Error("Invalid CSR PEM: expected CERTIFICATE REQUEST or NEW CERTIFICATE REQUEST block");
|
|
96
|
+
}
|
|
97
|
+
function readAlgorithmOid(algorithm) {
|
|
98
|
+
const children = readSequenceChildren(algorithm);
|
|
99
|
+
const oidElement = children[0];
|
|
100
|
+
if (!oidElement || oidElement.tag !== TAG.OBJECT_IDENTIFIER) {
|
|
101
|
+
throw new Error("Invalid AlgorithmIdentifier OID");
|
|
102
|
+
}
|
|
103
|
+
return decodeOid(oidElement.value);
|
|
104
|
+
}
|
|
105
|
+
function decodeName(nameElement) {
|
|
106
|
+
if (nameElement.tag !== TAG.SEQUENCE) {
|
|
107
|
+
throw new Error("Invalid Name structure");
|
|
108
|
+
}
|
|
109
|
+
const subject = [];
|
|
110
|
+
for (const rdn of readSequenceChildren(nameElement)) {
|
|
111
|
+
if (rdn.tag !== TAG.SET) {
|
|
112
|
+
throw new Error("Invalid RDN (expected SET)");
|
|
113
|
+
}
|
|
114
|
+
const attributes = readChildren(rdn.value);
|
|
115
|
+
if (attributes.length !== 1) {
|
|
116
|
+
throw new Error("Multi-valued RDNs are not supported");
|
|
117
|
+
}
|
|
118
|
+
const attribute = attributes[0];
|
|
119
|
+
if (attribute.tag !== TAG.SEQUENCE) {
|
|
120
|
+
throw new Error("Invalid AttributeTypeAndValue");
|
|
121
|
+
}
|
|
122
|
+
const [oidElement, valueElement] = readSequenceChildren(attribute);
|
|
123
|
+
if (!oidElement || !valueElement || oidElement.tag !== TAG.OBJECT_IDENTIFIER) {
|
|
124
|
+
throw new Error("Invalid AttributeTypeAndValue contents");
|
|
125
|
+
}
|
|
126
|
+
const attributeOid = decodeOid(oidElement.value);
|
|
127
|
+
const decoder = VALUE_DECODERS.get(valueElement.tag);
|
|
128
|
+
if (!decoder) {
|
|
129
|
+
throw new Error(`Unsupported AttributeValue string type: tag 0x${valueElement.tag.toString(16)}`);
|
|
130
|
+
}
|
|
131
|
+
const value = decoder(valueElement.value);
|
|
132
|
+
const shortName = SHORT_NAME_BY_OID[attributeOid];
|
|
133
|
+
subject.push({
|
|
134
|
+
type: shortName ?? attributeOid,
|
|
135
|
+
value
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return subject;
|
|
139
|
+
}
|
|
140
|
+
function decodeAttributes(value) {
|
|
141
|
+
const attributes = [];
|
|
142
|
+
for (const attribute of readChildren(value)) {
|
|
143
|
+
if (attribute.tag !== TAG.SEQUENCE) {
|
|
144
|
+
throw new Error("Invalid CSR attribute");
|
|
145
|
+
}
|
|
146
|
+
const children = readSequenceChildren(attribute);
|
|
147
|
+
const oidElement = children[0];
|
|
148
|
+
const valuesElement = children[1];
|
|
149
|
+
if (!oidElement || oidElement.tag !== TAG.OBJECT_IDENTIFIER) {
|
|
150
|
+
throw new Error("Invalid CSR attribute OID");
|
|
151
|
+
}
|
|
152
|
+
if (!valuesElement || valuesElement.tag !== TAG.SET) {
|
|
153
|
+
throw new Error("Invalid CSR attribute values (expected SET)");
|
|
154
|
+
}
|
|
155
|
+
const valuesDer = readChildren(valuesElement.value).map((value) => cloneBytes(value.raw));
|
|
156
|
+
attributes.push({
|
|
157
|
+
oid: decodeOid(oidElement.value),
|
|
158
|
+
valuesDer
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return attributes;
|
|
162
|
+
}
|
|
163
|
+
function decodeRequestedExtensions(valuesDer) {
|
|
164
|
+
if (valuesDer.length !== 1) {
|
|
165
|
+
throw new Error("extensionRequest attribute must contain exactly one SEQUENCE OF Extension");
|
|
166
|
+
}
|
|
167
|
+
const outer = readElement(valuesDer[0]);
|
|
168
|
+
if (outer.tag !== TAG.SEQUENCE) {
|
|
169
|
+
throw new Error("extensionRequest value must be a SEQUENCE OF Extension");
|
|
170
|
+
}
|
|
171
|
+
const extensions = [];
|
|
172
|
+
for (const extension of readSequenceChildren(outer)) {
|
|
173
|
+
if (extension.tag !== TAG.SEQUENCE) {
|
|
174
|
+
throw new Error("Invalid Extension");
|
|
175
|
+
}
|
|
176
|
+
const children = readSequenceChildren(extension);
|
|
177
|
+
const oidElement = children[0];
|
|
178
|
+
if (!oidElement || oidElement.tag !== TAG.OBJECT_IDENTIFIER) {
|
|
179
|
+
throw new Error("Invalid Extension OID");
|
|
180
|
+
}
|
|
181
|
+
let cursor = 1;
|
|
182
|
+
let critical = false;
|
|
183
|
+
if (children[cursor]?.tag === TAG.BOOLEAN) {
|
|
184
|
+
critical = children[cursor].value[0] !== 0;
|
|
185
|
+
cursor += 1;
|
|
186
|
+
}
|
|
187
|
+
const valueElement = children[cursor];
|
|
188
|
+
if (!valueElement || valueElement.tag !== TAG.OCTET_STRING) {
|
|
189
|
+
throw new Error("Invalid Extension value");
|
|
190
|
+
}
|
|
191
|
+
extensions.push({
|
|
192
|
+
oid: decodeOid(oidElement.value),
|
|
193
|
+
critical,
|
|
194
|
+
valueDer: cloneBytes(valueElement.value)
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return extensions;
|
|
198
|
+
}
|
|
199
|
+
function decodeSubjectAltName(value) {
|
|
200
|
+
const root = readElement(value);
|
|
201
|
+
if (root.tag !== TAG.SEQUENCE) {
|
|
202
|
+
throw new Error("Invalid SubjectAltName extension");
|
|
203
|
+
}
|
|
204
|
+
const dnsNames = [];
|
|
205
|
+
const ipAddresses = [];
|
|
206
|
+
for (const generalName of readChildren(root.value)) {
|
|
207
|
+
if (generalName.tag === 0x82) {
|
|
208
|
+
dnsNames.push(decodeAscii(generalName.value, "SAN dNSName"));
|
|
209
|
+
}
|
|
210
|
+
else if (generalName.tag === 0x87) {
|
|
211
|
+
ipAddresses.push(formatIpAddress(generalName.value));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return { dnsNames, ipAddresses };
|
|
215
|
+
}
|
|
216
|
+
function decodeAscii(bytes, label) {
|
|
217
|
+
for (const byte of bytes) {
|
|
218
|
+
if (byte > 0x7f) {
|
|
219
|
+
throw new Error(`${label} contains a non-ASCII byte`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return new TextDecoder("ascii").decode(bytes);
|
|
223
|
+
}
|
|
224
|
+
function formatIpAddress(bytes) {
|
|
225
|
+
if (bytes.length === 4) {
|
|
226
|
+
return Array.from(bytes).join(".");
|
|
227
|
+
}
|
|
228
|
+
if (bytes.length === 16) {
|
|
229
|
+
const groups = [];
|
|
230
|
+
for (let i = 0; i < 16; i += 2) {
|
|
231
|
+
groups.push(((bytes[i] << 8) | bytes[i + 1]).toString(16));
|
|
232
|
+
}
|
|
233
|
+
return compressIpv6(groups);
|
|
234
|
+
}
|
|
235
|
+
throw new Error(`Invalid SAN iPAddress length: ${bytes.length}`);
|
|
236
|
+
}
|
|
237
|
+
// RFC 5952: collapse the longest run of consecutive "0" groups (length ≥ 2) into "::".
|
|
238
|
+
function compressIpv6(groups) {
|
|
239
|
+
let bestStart = -1;
|
|
240
|
+
let bestLength = 0;
|
|
241
|
+
let currentStart = -1;
|
|
242
|
+
let currentLength = 0;
|
|
243
|
+
for (let i = 0; i < groups.length; i += 1) {
|
|
244
|
+
if (groups[i] === "0") {
|
|
245
|
+
if (currentStart === -1) {
|
|
246
|
+
currentStart = i;
|
|
247
|
+
currentLength = 0;
|
|
248
|
+
}
|
|
249
|
+
currentLength += 1;
|
|
250
|
+
if (currentLength > bestLength) {
|
|
251
|
+
bestStart = currentStart;
|
|
252
|
+
bestLength = currentLength;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
currentStart = -1;
|
|
257
|
+
currentLength = 0;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (bestLength < 2) {
|
|
261
|
+
return groups.join(":");
|
|
262
|
+
}
|
|
263
|
+
const head = groups.slice(0, bestStart).join(":");
|
|
264
|
+
const tail = groups.slice(bestStart + bestLength).join(":");
|
|
265
|
+
return `${head}::${tail}`;
|
|
266
|
+
}
|
package/dist/der.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare function boolean(value: boolean): Uint8Array;
|
|
|
31
31
|
export declare function integer(value: bigint | number | Uint8Array): Uint8Array;
|
|
32
32
|
export declare function bitString(bytes: Uint8Array, unusedBits?: number): Uint8Array;
|
|
33
33
|
export declare function octetString(bytes: Uint8Array): Uint8Array;
|
|
34
|
+
export declare function nullValue(): Uint8Array;
|
|
34
35
|
export declare function utf8String(value: string): Uint8Array;
|
|
35
36
|
export declare function printableString(value: string): Uint8Array;
|
|
36
37
|
export declare function ia5String(value: string): Uint8Array;
|
package/dist/der.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"der.d.ts","sourceRoot":"","sources":["../src/der.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG;;;;;;;;;;;;;;CAcN,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAE9D;AAED,wBAAgB,QAAQ,CAAC,GAAG,QAAQ,EAAE,UAAU,EAAE,GAAG,UAAU,CAE9D;AAED,wBAAgB,GAAG,CAAC,GAAG,QAAQ,EAAE,UAAU,EAAE,GAAG,UAAU,CAEzD;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAEzE;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAmB7C;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAElD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CA4BvE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,SAAI,GAAG,UAAU,CAMvE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEzD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAEpD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAMzD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAEjF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,CAO9C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,CAMtD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,SAAI,GAAG,UAAU,CAuBrE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,EAAE,CAMtE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,EAAE,CAW5D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CA4CnD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAevD"}
|
|
1
|
+
{"version":3,"file":"der.d.ts","sourceRoot":"","sources":["../src/der.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG;;;;;;;;;;;;;;CAcN,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAE9D;AAED,wBAAgB,QAAQ,CAAC,GAAG,QAAQ,EAAE,UAAU,EAAE,GAAG,UAAU,CAE9D;AAED,wBAAgB,GAAG,CAAC,GAAG,QAAQ,EAAE,UAAU,EAAE,GAAG,UAAU,CAEzD;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAEzE;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAmB7C;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAElD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CA4BvE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,SAAI,GAAG,UAAU,CAMvE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEzD;AAED,wBAAgB,SAAS,IAAI,UAAU,CAEtC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAEpD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAMzD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAEjF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,CAO9C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,CAMtD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,SAAI,GAAG,UAAU,CAuBrE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,EAAE,CAMtE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,EAAE,CAW5D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CA4CnD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAevD"}
|
package/dist/der.js
CHANGED
|
@@ -79,6 +79,9 @@ export function bitString(bytes, unusedBits = 0) {
|
|
|
79
79
|
export function octetString(bytes) {
|
|
80
80
|
return der(TAG.OCTET_STRING, bytes);
|
|
81
81
|
}
|
|
82
|
+
export function nullValue() {
|
|
83
|
+
return new Uint8Array([TAG.NULL, 0x00]);
|
|
84
|
+
}
|
|
82
85
|
export function utf8String(value) {
|
|
83
86
|
return der(TAG.UTF8_STRING, utf8Bytes(value));
|
|
84
87
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { createRootCA, importCertificateAuthority, issueClientCert, issueIntermediateCA } from "./ca.js";
|
|
1
|
+
export { createRootCA, importCertificateAuthority, issueClientCert, issueClientCertForPublicKey, issueIntermediateCA } from "./ca.js";
|
|
2
|
+
export { parseCertificateSigningRequest, verifyCertificateSigningRequestSignature, type ParsedCertificateSigningRequest, type CertificateSigningRequestExtension, type CertificateSigningRequestAttribute } from "./csr.js";
|
|
2
3
|
export { pemToDer, certificateToPem } from "./pem.js";
|
|
3
|
-
export {
|
|
4
|
+
export { exportPkcs12, type ExportPkcs12Input } from "./pkcs12.js";
|
|
4
5
|
export { verifyClientCertificateIssuedBy, type VerifyClientCertificateIssuedByOptions, type VerifyClientCertificateValidity } from "./verify.js";
|
|
5
|
-
export type { CertificateAuthority, CreateRootCAOptions, ImportCertificateAuthorityOptions, IssueClientCertOptions, IssueIntermediateCAOptions, IssuedClientCertificate, SerialNumber, ShortSubjectAttributeType, Subject, SubjectAttribute, SubjectAttributeType } from "./types.js";
|
|
6
|
+
export type { CertificateAuthority, CreateRootCAOptions, ImportCertificateAuthorityOptions, IssueClientCertForPublicKeyOptions, IssueClientCertOptions, IssueIntermediateCAOptions, IssuedClientCertificate, IssuedClientCertificateForPublicKey, SerialNumber, ShortSubjectAttributeType, Subject, SubjectAttribute, SubjectAttributeType } from "./types.js";
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,eAAe,EACf,mBAAmB,EACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,eAAe,EACf,2BAA2B,EAC3B,mBAAmB,EACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,8BAA8B,EAC9B,wCAAwC,EACxC,KAAK,+BAA+B,EACpC,KAAK,kCAAkC,EACvC,KAAK,kCAAkC,EACxC,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EACL,+BAA+B,EAC/B,KAAK,sCAAsC,EAC3C,KAAK,+BAA+B,EACrC,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,iCAAiC,EACjC,kCAAkC,EAClC,sBAAsB,EACtB,0BAA0B,EAC1B,uBAAuB,EACvB,mCAAmC,EACnC,YAAY,EACZ,yBAAyB,EACzB,OAAO,EACP,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { createRootCA, importCertificateAuthority, issueClientCert, issueIntermediateCA } from "./ca.js";
|
|
1
|
+
export { createRootCA, importCertificateAuthority, issueClientCert, issueClientCertForPublicKey, issueIntermediateCA } from "./ca.js";
|
|
2
|
+
export { parseCertificateSigningRequest, verifyCertificateSigningRequestSignature } from "./csr.js";
|
|
2
3
|
export { pemToDer, certificateToPem } from "./pem.js";
|
|
3
|
-
export {
|
|
4
|
+
export { exportPkcs12 } from "./pkcs12.js";
|
|
4
5
|
export { verifyClientCertificateIssuedBy } from "./verify.js";
|
package/dist/oids.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { ShortSubjectAttributeType } from "./types.js";
|
|
2
2
|
export declare const OID: {
|
|
3
|
+
readonly ecPublicKey: "1.2.840.10045.2.1";
|
|
4
|
+
readonly secp256r1: "1.2.840.10045.3.1.7";
|
|
5
|
+
readonly secp384r1: "1.3.132.0.34";
|
|
6
|
+
readonly secp521r1: "1.3.132.0.35";
|
|
3
7
|
readonly ecdsaWithSha256: "1.2.840.10045.4.3.2";
|
|
8
|
+
readonly ecdsaWithSha384: "1.2.840.10045.4.3.3";
|
|
9
|
+
readonly ecdsaWithSha512: "1.2.840.10045.4.3.4";
|
|
4
10
|
readonly basicConstraints: "2.5.29.19";
|
|
5
11
|
readonly keyUsage: "2.5.29.15";
|
|
6
12
|
readonly extendedKeyUsage: "2.5.29.37";
|
|
@@ -8,6 +14,19 @@ export declare const OID: {
|
|
|
8
14
|
readonly subjectKeyIdentifier: "2.5.29.14";
|
|
9
15
|
readonly authorityKeyIdentifier: "2.5.29.35";
|
|
10
16
|
readonly clientAuth: "1.3.6.1.5.5.7.3.2";
|
|
17
|
+
readonly extensionRequest: "1.2.840.113549.1.9.14";
|
|
18
|
+
readonly data: "1.2.840.113549.1.7.1";
|
|
19
|
+
readonly encryptedData: "1.2.840.113549.1.7.6";
|
|
20
|
+
readonly friendlyName: "1.2.840.113549.1.9.20";
|
|
21
|
+
readonly localKeyId: "1.2.840.113549.1.9.21";
|
|
22
|
+
readonly x509Certificate: "1.2.840.113549.1.9.22.1";
|
|
23
|
+
readonly certBag: "1.2.840.113549.1.12.10.1.3";
|
|
24
|
+
readonly pkcs8ShroudedKeyBag: "1.2.840.113549.1.12.10.1.2";
|
|
25
|
+
readonly pbes2: "1.2.840.113549.1.5.13";
|
|
26
|
+
readonly pbkdf2: "1.2.840.113549.1.5.12";
|
|
27
|
+
readonly hmacWithSha256: "1.2.840.113549.2.9";
|
|
28
|
+
readonly aes256Cbc: "2.16.840.1.101.3.4.1.42";
|
|
29
|
+
readonly sha256: "2.16.840.1.101.3.4.2.1";
|
|
11
30
|
};
|
|
12
31
|
export declare const SUBJECT_ATTRIBUTE_OIDS: Record<ShortSubjectAttributeType, string>;
|
|
13
32
|
export declare const SUBJECT_VALUE_LENGTH_LIMITS: Record<ShortSubjectAttributeType, number>;
|
package/dist/oids.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oids.d.ts","sourceRoot":"","sources":["../src/oids.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE5D,eAAO,MAAM,GAAG
|
|
1
|
+
{"version":3,"file":"oids.d.ts","sourceRoot":"","sources":["../src/oids.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE5D,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BN,CAAC;AAEX,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,yBAAyB,EAAE,MAAM,CAgB5E,CAAC;AAGF,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,yBAAyB,EAAE,MAAM,CAgBjF,CAAC;AAIF,eAAO,MAAM,wBAAwB,MAAM,CAAC"}
|
package/dist/oids.js
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
1
|
export const OID = {
|
|
2
|
+
ecPublicKey: "1.2.840.10045.2.1",
|
|
3
|
+
secp256r1: "1.2.840.10045.3.1.7",
|
|
4
|
+
secp384r1: "1.3.132.0.34",
|
|
5
|
+
secp521r1: "1.3.132.0.35",
|
|
2
6
|
ecdsaWithSha256: "1.2.840.10045.4.3.2",
|
|
7
|
+
ecdsaWithSha384: "1.2.840.10045.4.3.3",
|
|
8
|
+
ecdsaWithSha512: "1.2.840.10045.4.3.4",
|
|
3
9
|
basicConstraints: "2.5.29.19",
|
|
4
10
|
keyUsage: "2.5.29.15",
|
|
5
11
|
extendedKeyUsage: "2.5.29.37",
|
|
6
12
|
subjectAltName: "2.5.29.17",
|
|
7
13
|
subjectKeyIdentifier: "2.5.29.14",
|
|
8
14
|
authorityKeyIdentifier: "2.5.29.35",
|
|
9
|
-
clientAuth: "1.3.6.1.5.5.7.3.2"
|
|
15
|
+
clientAuth: "1.3.6.1.5.5.7.3.2",
|
|
16
|
+
extensionRequest: "1.2.840.113549.1.9.14",
|
|
17
|
+
data: "1.2.840.113549.1.7.1",
|
|
18
|
+
encryptedData: "1.2.840.113549.1.7.6",
|
|
19
|
+
friendlyName: "1.2.840.113549.1.9.20",
|
|
20
|
+
localKeyId: "1.2.840.113549.1.9.21",
|
|
21
|
+
x509Certificate: "1.2.840.113549.1.9.22.1",
|
|
22
|
+
certBag: "1.2.840.113549.1.12.10.1.3",
|
|
23
|
+
pkcs8ShroudedKeyBag: "1.2.840.113549.1.12.10.1.2",
|
|
24
|
+
pbes2: "1.2.840.113549.1.5.13",
|
|
25
|
+
pbkdf2: "1.2.840.113549.1.5.12",
|
|
26
|
+
hmacWithSha256: "1.2.840.113549.2.9",
|
|
27
|
+
aes256Cbc: "2.16.840.1.101.3.4.1.42",
|
|
28
|
+
sha256: "2.16.840.1.101.3.4.2.1"
|
|
10
29
|
};
|
|
11
30
|
export const SUBJECT_ATTRIBUTE_OIDS = {
|
|
12
31
|
CN: "2.5.4.3",
|
package/dist/pem.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
export declare function certificateToPem(der: Uint8Array): string;
|
|
2
|
-
export declare function privateKeyDerToPem(der: Uint8Array): string;
|
|
3
|
-
export declare function publicKeyDerToPem(der: Uint8Array): string;
|
|
4
2
|
export declare function pemToDer(pem: string): Uint8Array;
|
|
5
3
|
export declare function pemToDerWithLabel(pem: string, label: string): Uint8Array;
|
|
6
4
|
export declare function splitPemBlocks(pem: string): string[];
|
package/dist/pem.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pem.d.ts","sourceRoot":"","sources":["../src/pem.ts"],"names":[],"mappings":"AAIA,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAExD;AAED,wBAAgB,
|
|
1
|
+
{"version":3,"file":"pem.d.ts","sourceRoot":"","sources":["../src/pem.ts"],"names":[],"mappings":"AAIA,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAExD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAWhD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAaxE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAUpD"}
|
package/dist/pem.js
CHANGED
|
@@ -3,12 +3,6 @@ const PEM_LINE_LENGTH = 64;
|
|
|
3
3
|
export function certificateToPem(der) {
|
|
4
4
|
return encodePem("CERTIFICATE", der);
|
|
5
5
|
}
|
|
6
|
-
export function privateKeyDerToPem(der) {
|
|
7
|
-
return encodePem("PRIVATE KEY", der);
|
|
8
|
-
}
|
|
9
|
-
export function publicKeyDerToPem(der) {
|
|
10
|
-
return encodePem("PUBLIC KEY", der);
|
|
11
|
-
}
|
|
12
6
|
export function pemToDer(pem) {
|
|
13
7
|
const match = /-----BEGIN (.+?)-----([\s\S]*?)-----END \1-----/.exec(pem);
|
|
14
8
|
if (!match || !match[2]) {
|
package/dist/pkcs12.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ExportPkcs12Input {
|
|
2
|
+
certDer: Uint8Array;
|
|
3
|
+
chainDer?: Uint8Array[];
|
|
4
|
+
privateKey: CryptoKey;
|
|
5
|
+
password: Uint8Array;
|
|
6
|
+
friendlyName?: Uint8Array;
|
|
7
|
+
iterations?: number;
|
|
8
|
+
macIterations?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function exportPkcs12(input: ExportPkcs12Input): Promise<Uint8Array>;
|
|
11
|
+
//# sourceMappingURL=pkcs12.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkcs12.d.ts","sourceRoot":"","sources":["../src/pkcs12.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,UAAU,EAAE,SAAS,CAAC;IACtB,QAAQ,EAAE,UAAU,CAAC;IACrB,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAUD,wBAAsB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CA8FhF"}
|