@noz-ele/edgca 0.2.0 → 0.4.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 +431 -351
- 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 +46 -22
- 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 +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/oids.d.ts +13 -0
- package/dist/oids.d.ts.map +1 -1
- package/dist/oids.js +14 -1
- 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 +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/x509.d.ts +2 -0
- package/dist/x509.d.ts.map +1 -1
- package/dist/x509.js +6 -3
- package/package.json +70 -66
package/dist/bytes.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export declare function bytesToBinary(bytes: Uint8Array): string;
|
|
|
6
6
|
export declare function binaryToBytes(binary: string): Uint8Array;
|
|
7
7
|
export declare function cloneBytes(bytes: Uint8Array): Uint8Array;
|
|
8
8
|
export declare function arrayBufferFromBytes(bytes: Uint8Array): ArrayBuffer;
|
|
9
|
+
export declare function randomBytes(length: number): Uint8Array;
|
|
9
10
|
//# sourceMappingURL=bytes.d.ts.map
|
package/dist/bytes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../src/bytes.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,CAWpE;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAWhE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAEnD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAYpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAUvD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAQxD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAExD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAInE"}
|
|
1
|
+
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../src/bytes.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,CAWpE;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAWhE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAEnD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAYpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAUvD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAQxD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAExD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAInE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAItD"}
|
package/dist/bytes.js
CHANGED
package/dist/ca.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { CertificateAuthority, CreateRootCAOptions, ImportCertificateAuthorityOptions, IssueClientCertForPublicKeyOptions, IssueClientCertOptions, IssueIntermediateCAOptions, IssuedClientCertificate, IssuedClientCertificateForPublicKey } from "./types.js";
|
|
1
|
+
import type { CertificateAuthority, CreateRootCAOptions, ImportCertificateAuthorityOptions, IssueClientCertForPublicKeyOptions, IssueClientCertOptions, IssueDocumentSigningCertOptions, IssueIntermediateCAOptions, IssuedClientCertificate, IssuedClientCertificateForPublicKey, IssuedDocumentSigningCertificate } from "./types.js";
|
|
2
2
|
export declare function createRootCA(options: CreateRootCAOptions): Promise<CertificateAuthority>;
|
|
3
3
|
export declare function issueIntermediateCA(options: IssueIntermediateCAOptions): Promise<CertificateAuthority>;
|
|
4
4
|
export declare function issueClientCert(options: IssueClientCertOptions): Promise<IssuedClientCertificate>;
|
|
5
5
|
export declare function issueClientCertForPublicKey(options: IssueClientCertForPublicKeyOptions): Promise<IssuedClientCertificateForPublicKey>;
|
|
6
|
+
export declare function issueDocumentSigningCert(options: IssueDocumentSigningCertOptions): Promise<IssuedDocumentSigningCertificate>;
|
|
6
7
|
export declare function importCertificateAuthority(options: ImportCertificateAuthorityOptions): Promise<CertificateAuthority>;
|
|
7
8
|
//# sourceMappingURL=ca.d.ts.map
|
package/dist/ca.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ca.d.ts","sourceRoot":"","sources":["../src/ca.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,iCAAiC,EACjC,kCAAkC,EAClC,sBAAsB,EACtB,0BAA0B,EAC1B,uBAAuB,EACvB,mCAAmC,
|
|
1
|
+
{"version":3,"file":"ca.d.ts","sourceRoot":"","sources":["../src/ca.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,iCAAiC,EACjC,kCAAkC,EAClC,sBAAsB,EACtB,+BAA+B,EAC/B,0BAA0B,EAC1B,uBAAuB,EACvB,mCAAmC,EACnC,gCAAgC,EAEjC,MAAM,YAAY,CAAC;AAcpB,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0B9F;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAgC5G;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAoBvG;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,kCAAkC,GAC1C,OAAO,CAAC,mCAAmC,CAAC,CAiB9C;AAuED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,gCAAgC,CAAC,CAoB3C;AAED,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,iCAAiC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAe1H"}
|
package/dist/ca.js
CHANGED
|
@@ -3,7 +3,7 @@ import { assertKeyPairMatches, curveOf, exportSpki, generateKeyPair, keyIdentifi
|
|
|
3
3
|
import { encodeName } from "./name.js";
|
|
4
4
|
import { certificateToPem, pemToDer, pemToDerWithLabel, splitPemBlocks } from "./pem.js";
|
|
5
5
|
import { parseCertificateDer } from "./parser.js";
|
|
6
|
-
import { authorityKeyIdentifierExtension, basicConstraintsCaExtension, basicConstraintsLeafExtension, buildCertificate, buildTbsCertificate, extendedKeyUsageClientAuthExtension, keyUsageExtension, subjectAltNameExtension, subjectKeyIdentifierExtension } from "./x509.js";
|
|
6
|
+
import { authorityKeyIdentifierExtension, basicConstraintsCaExtension, basicConstraintsLeafExtension, buildCertificate, buildTbsCertificate, extendedKeyUsageClientAuthExtension, extendedKeyUsageDocumentSigningExtension, keyUsageExtension, subjectAltNameExtension, subjectKeyIdentifierExtension } from "./x509.js";
|
|
7
7
|
export async function createRootCA(options) {
|
|
8
8
|
const keyPair = await resolveKeyPair(options.keyPair);
|
|
9
9
|
const issuerCurve = curveOf(keyPair.privateKey);
|
|
@@ -65,14 +65,12 @@ export async function issueIntermediateCA(options) {
|
|
|
65
65
|
}
|
|
66
66
|
export async function issueClientCert(options) {
|
|
67
67
|
const keyPair = await generateKeyPair();
|
|
68
|
-
const built = await
|
|
68
|
+
const built = await buildLeafCertificate(options.ca, keyPair.publicKey, {
|
|
69
69
|
subject: options.subject,
|
|
70
70
|
days: options.days,
|
|
71
71
|
notBefore: options.notBefore,
|
|
72
|
-
serialNumber: options.serialNumber
|
|
73
|
-
|
|
74
|
-
ipAddresses: options.ipAddresses
|
|
75
|
-
});
|
|
72
|
+
serialNumber: options.serialNumber
|
|
73
|
+
}, clientCertProfileExtensions(options.dnsNames, options.ipAddresses));
|
|
76
74
|
return {
|
|
77
75
|
certPem: built.certPem,
|
|
78
76
|
certDer: built.certDer,
|
|
@@ -82,42 +80,36 @@ export async function issueClientCert(options) {
|
|
|
82
80
|
};
|
|
83
81
|
}
|
|
84
82
|
export async function issueClientCertForPublicKey(options) {
|
|
85
|
-
const built = await
|
|
83
|
+
const built = await buildLeafCertificate(options.ca, options.publicKey, {
|
|
86
84
|
subject: options.subject,
|
|
87
85
|
days: options.days,
|
|
88
86
|
notBefore: options.notBefore,
|
|
89
|
-
serialNumber: options.serialNumber
|
|
90
|
-
|
|
91
|
-
ipAddresses: options.ipAddresses
|
|
92
|
-
});
|
|
87
|
+
serialNumber: options.serialNumber
|
|
88
|
+
}, clientCertProfileExtensions(options.dnsNames, options.ipAddresses));
|
|
93
89
|
return {
|
|
94
90
|
certPem: built.certPem,
|
|
95
91
|
certDer: built.certDer,
|
|
96
92
|
certChainPem: built.certChainPem
|
|
97
93
|
};
|
|
98
94
|
}
|
|
99
|
-
async function
|
|
95
|
+
async function buildLeafCertificate(ca, subjectPublicKey, identity, profileExtensions) {
|
|
100
96
|
const issuer = await parseIssuer(ca);
|
|
101
97
|
const issuerChainPem = ca.issuerChainPem;
|
|
102
98
|
assertCanIssueCertificate(issuer);
|
|
103
99
|
const issuerCurve = curveOf(ca.privateKey);
|
|
104
|
-
const subjectNameDer = encodeName(
|
|
100
|
+
const subjectNameDer = encodeName(identity.subject);
|
|
105
101
|
const spki = await exportSpki(subjectPublicKey);
|
|
106
102
|
const subjectKeyIdentifier = await keyIdentifierFromSpki(spki);
|
|
107
103
|
const authorityKeyIdentifier = issuer.subjectKeyIdentifier ?? await keyIdentifierFromSpki(issuer.subjectPublicKeyInfoDer);
|
|
108
|
-
const san = subjectAltNameExtension(content.dnsNames, content.ipAddresses);
|
|
109
104
|
const extensions = [
|
|
110
|
-
|
|
111
|
-
keyUsageExtension(["digitalSignature"]),
|
|
112
|
-
extendedKeyUsageClientAuthExtension(),
|
|
105
|
+
...profileExtensions,
|
|
113
106
|
subjectKeyIdentifierExtension(subjectKeyIdentifier),
|
|
114
|
-
authorityKeyIdentifierExtension(authorityKeyIdentifier)
|
|
115
|
-
...(san ? [san] : [])
|
|
107
|
+
authorityKeyIdentifierExtension(authorityKeyIdentifier)
|
|
116
108
|
];
|
|
117
109
|
const { tbsCertificateDer } = buildTbsCertificate({
|
|
118
|
-
serialNumber:
|
|
119
|
-
notBefore:
|
|
120
|
-
days:
|
|
110
|
+
serialNumber: identity.serialNumber,
|
|
111
|
+
notBefore: identity.notBefore,
|
|
112
|
+
days: identity.days,
|
|
121
113
|
issuerNameDer: issuer.subjectNameDer,
|
|
122
114
|
subjectNameDer,
|
|
123
115
|
subjectPublicKeyInfoDer: spki,
|
|
@@ -133,6 +125,38 @@ async function buildClientCertificate(ca, subjectPublicKey, content) {
|
|
|
133
125
|
certChainPem: joinPemChain([certPem, ca.certPem, issuerChainPem])
|
|
134
126
|
};
|
|
135
127
|
}
|
|
128
|
+
function clientCertProfileExtensions(dnsNames, ipAddresses) {
|
|
129
|
+
const san = subjectAltNameExtension(dnsNames, ipAddresses);
|
|
130
|
+
return [
|
|
131
|
+
basicConstraintsLeafExtension(),
|
|
132
|
+
keyUsageExtension(["digitalSignature"]),
|
|
133
|
+
extendedKeyUsageClientAuthExtension(),
|
|
134
|
+
...(san ? [san] : [])
|
|
135
|
+
];
|
|
136
|
+
}
|
|
137
|
+
function documentSigningProfileExtensions() {
|
|
138
|
+
return [
|
|
139
|
+
basicConstraintsLeafExtension(),
|
|
140
|
+
keyUsageExtension(["digitalSignature", "contentCommitment"]),
|
|
141
|
+
extendedKeyUsageDocumentSigningExtension()
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
export async function issueDocumentSigningCert(options) {
|
|
145
|
+
const keyPair = await generateKeyPair();
|
|
146
|
+
const built = await buildLeafCertificate(options.ca, keyPair.publicKey, {
|
|
147
|
+
subject: options.subject,
|
|
148
|
+
days: options.days,
|
|
149
|
+
notBefore: options.notBefore,
|
|
150
|
+
serialNumber: options.serialNumber
|
|
151
|
+
}, documentSigningProfileExtensions());
|
|
152
|
+
return {
|
|
153
|
+
certPem: built.certPem,
|
|
154
|
+
certDer: built.certDer,
|
|
155
|
+
privateKey: keyPair.privateKey,
|
|
156
|
+
publicKey: keyPair.publicKey,
|
|
157
|
+
certChainPem: built.certChainPem
|
|
158
|
+
};
|
|
159
|
+
}
|
|
136
160
|
export async function importCertificateAuthority(options) {
|
|
137
161
|
const issuerChainPem = options.issuerChainPem ?? "";
|
|
138
162
|
assertIssuerChainPem(issuerChainPem);
|
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, issueClientCertForPublicKey, issueIntermediateCA } from "./ca.js";
|
|
1
|
+
export { createRootCA, importCertificateAuthority, issueClientCert, issueClientCertForPublicKey, issueDocumentSigningCert, issueIntermediateCA } from "./ca.js";
|
|
2
2
|
export { parseCertificateSigningRequest, verifyCertificateSigningRequestSignature, type ParsedCertificateSigningRequest, type CertificateSigningRequestExtension, type CertificateSigningRequestAttribute } from "./csr.js";
|
|
3
3
|
export { pemToDer, certificateToPem } from "./pem.js";
|
|
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, IssueClientCertForPublicKeyOptions, IssueClientCertOptions, IssueIntermediateCAOptions, IssuedClientCertificate, IssuedClientCertificateForPublicKey, SerialNumber, ShortSubjectAttributeType, Subject, SubjectAttribute, SubjectAttributeType } from "./types.js";
|
|
6
|
+
export type { CertificateAuthority, CreateRootCAOptions, ImportCertificateAuthorityOptions, IssueClientCertForPublicKeyOptions, IssueClientCertOptions, IssueDocumentSigningCertOptions, IssueIntermediateCAOptions, IssuedClientCertificate, IssuedClientCertificateForPublicKey, IssuedDocumentSigningCertificate, 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,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,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"}
|
|
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,wBAAwB,EACxB,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,+BAA+B,EAC/B,0BAA0B,EAC1B,uBAAuB,EACvB,mCAAmC,EACnC,gCAAgC,EAChC,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, issueClientCertForPublicKey, issueIntermediateCA } from "./ca.js";
|
|
1
|
+
export { createRootCA, importCertificateAuthority, issueClientCert, issueClientCertForPublicKey, issueDocumentSigningCert, issueIntermediateCA } from "./ca.js";
|
|
2
2
|
export { parseCertificateSigningRequest, verifyCertificateSigningRequestSignature } from "./csr.js";
|
|
3
3
|
export { pemToDer, certificateToPem } from "./pem.js";
|
|
4
|
+
export { exportPkcs12 } from "./pkcs12.js";
|
|
4
5
|
export { verifyClientCertificateIssuedBy } from "./verify.js";
|
package/dist/oids.d.ts
CHANGED
|
@@ -14,7 +14,20 @@ export declare const OID: {
|
|
|
14
14
|
readonly subjectKeyIdentifier: "2.5.29.14";
|
|
15
15
|
readonly authorityKeyIdentifier: "2.5.29.35";
|
|
16
16
|
readonly clientAuth: "1.3.6.1.5.5.7.3.2";
|
|
17
|
+
readonly documentSigning: "1.3.6.1.5.5.7.3.36";
|
|
17
18
|
readonly extensionRequest: "1.2.840.113549.1.9.14";
|
|
19
|
+
readonly data: "1.2.840.113549.1.7.1";
|
|
20
|
+
readonly encryptedData: "1.2.840.113549.1.7.6";
|
|
21
|
+
readonly friendlyName: "1.2.840.113549.1.9.20";
|
|
22
|
+
readonly localKeyId: "1.2.840.113549.1.9.21";
|
|
23
|
+
readonly x509Certificate: "1.2.840.113549.1.9.22.1";
|
|
24
|
+
readonly certBag: "1.2.840.113549.1.12.10.1.3";
|
|
25
|
+
readonly pkcs8ShroudedKeyBag: "1.2.840.113549.1.12.10.1.2";
|
|
26
|
+
readonly pbes2: "1.2.840.113549.1.5.13";
|
|
27
|
+
readonly pbkdf2: "1.2.840.113549.1.5.12";
|
|
28
|
+
readonly hmacWithSha256: "1.2.840.113549.2.9";
|
|
29
|
+
readonly aes256Cbc: "2.16.840.1.101.3.4.1.42";
|
|
30
|
+
readonly sha256: "2.16.840.1.101.3.4.2.1";
|
|
18
31
|
};
|
|
19
32
|
export declare const SUBJECT_ATTRIBUTE_OIDS: Record<ShortSubjectAttributeType, string>;
|
|
20
33
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BN,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
|
@@ -13,7 +13,20 @@ export const OID = {
|
|
|
13
13
|
subjectKeyIdentifier: "2.5.29.14",
|
|
14
14
|
authorityKeyIdentifier: "2.5.29.35",
|
|
15
15
|
clientAuth: "1.3.6.1.5.5.7.3.2",
|
|
16
|
-
|
|
16
|
+
documentSigning: "1.3.6.1.5.5.7.3.36",
|
|
17
|
+
extensionRequest: "1.2.840.113549.1.9.14",
|
|
18
|
+
data: "1.2.840.113549.1.7.1",
|
|
19
|
+
encryptedData: "1.2.840.113549.1.7.6",
|
|
20
|
+
friendlyName: "1.2.840.113549.1.9.20",
|
|
21
|
+
localKeyId: "1.2.840.113549.1.9.21",
|
|
22
|
+
x509Certificate: "1.2.840.113549.1.9.22.1",
|
|
23
|
+
certBag: "1.2.840.113549.1.12.10.1.3",
|
|
24
|
+
pkcs8ShroudedKeyBag: "1.2.840.113549.1.12.10.1.2",
|
|
25
|
+
pbes2: "1.2.840.113549.1.5.13",
|
|
26
|
+
pbkdf2: "1.2.840.113549.1.5.12",
|
|
27
|
+
hmacWithSha256: "1.2.840.113549.2.9",
|
|
28
|
+
aes256Cbc: "2.16.840.1.101.3.4.1.42",
|
|
29
|
+
sha256: "2.16.840.1.101.3.4.2.1"
|
|
17
30
|
};
|
|
18
31
|
export const SUBJECT_ATTRIBUTE_OIDS = {
|
|
19
32
|
CN: "2.5.4.3",
|
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"}
|
package/dist/pkcs12.js
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { arrayBufferFromBytes, concatBytes, randomBytes } from "./bytes.js";
|
|
2
|
+
import { digestSha256, keyIdentifierFromSpki } from "./crypto.js";
|
|
3
|
+
import { contextPrimitive, der, explicit, integer, nullValue, octetString, oid, sequence, set } from "./der.js";
|
|
4
|
+
import { OID } from "./oids.js";
|
|
5
|
+
import { parseCertificateDer } from "./parser.js";
|
|
6
|
+
const DEFAULT_PBKDF2_ITERATIONS = 600_000;
|
|
7
|
+
const DEFAULT_MAC_ITERATIONS = 100_000;
|
|
8
|
+
const SALT_LENGTH = 16;
|
|
9
|
+
const IV_LENGTH = 16;
|
|
10
|
+
const MAC_KEY_LENGTH = 32;
|
|
11
|
+
const SHA256_BLOCK_SIZE = 64;
|
|
12
|
+
const PKCS12_KDF_ID_MAC = 3;
|
|
13
|
+
export async function exportPkcs12(input) {
|
|
14
|
+
const iterations = input.iterations ?? DEFAULT_PBKDF2_ITERATIONS;
|
|
15
|
+
const macIterations = input.macIterations ?? DEFAULT_MAC_ITERATIONS;
|
|
16
|
+
validateInput(input, iterations, macIterations);
|
|
17
|
+
const parsedLeaf = await parseCertificateDer(input.certDer);
|
|
18
|
+
const localKeyId = await keyIdentifierFromSpki(parsedLeaf.subjectPublicKeyInfoDer);
|
|
19
|
+
const friendlyNameAttr = input.friendlyName !== undefined && input.friendlyName.length > 0
|
|
20
|
+
? buildFriendlyNameAttr(input.friendlyName)
|
|
21
|
+
: undefined;
|
|
22
|
+
const localKeyIdAttr = buildLocalKeyIdAttr(localKeyId);
|
|
23
|
+
const leafAttrs = friendlyNameAttr ? [localKeyIdAttr, friendlyNameAttr] : [localKeyIdAttr];
|
|
24
|
+
const certBags = [buildCertSafeBag(input.certDer, leafAttrs)];
|
|
25
|
+
if (input.chainDer) {
|
|
26
|
+
for (const c of input.chainDer) {
|
|
27
|
+
certBags.push(buildCertSafeBag(c, []));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const certSafeContents = sequence(...certBags);
|
|
31
|
+
// Import the password into a non-extractable PBKDF2 baseKey once and reuse
|
|
32
|
+
// it across both cert-bag and key-bag encryption. This halves the number of
|
|
33
|
+
// password-byte ArrayBuffer copies handed to WebCrypto (which we cannot
|
|
34
|
+
// wipe) from two to one.
|
|
35
|
+
const pbkdf2BaseKey = await crypto.subtle.importKey("raw", arrayBufferFromBytes(input.password), "PBKDF2", false, ["deriveKey"]);
|
|
36
|
+
const certEncrypted = await pbes2EncryptAesCbc(certSafeContents, pbkdf2BaseKey, iterations);
|
|
37
|
+
const certContentInfo = sequence(oid(OID.encryptedData), explicit(0, sequence(integer(0n), sequence(oid(OID.data), certEncrypted.algorithm, contextPrimitive(0, certEncrypted.ciphertext)))));
|
|
38
|
+
const pkcs8 = new Uint8Array(await crypto.subtle.exportKey("pkcs8", input.privateKey));
|
|
39
|
+
const keyEncrypted = await pbes2EncryptAesCbc(pkcs8, pbkdf2BaseKey, iterations);
|
|
40
|
+
wipe(pkcs8);
|
|
41
|
+
const epki = sequence(keyEncrypted.algorithm, octetString(keyEncrypted.ciphertext));
|
|
42
|
+
const keyBag = buildKeySafeBag(epki, leafAttrs);
|
|
43
|
+
const keySafeContents = sequence(keyBag);
|
|
44
|
+
const keyContentInfo = sequence(oid(OID.data), explicit(0, octetString(keySafeContents)));
|
|
45
|
+
const authenticatedSafe = sequence(certContentInfo, keyContentInfo);
|
|
46
|
+
const macSalt = randomBytes(SALT_LENGTH);
|
|
47
|
+
const passwordUtf16 = utf8ToUtf16BeWithTerminator(input.password);
|
|
48
|
+
const macKey = await pkcs12V1KdfMacKey(passwordUtf16, macSalt, macIterations);
|
|
49
|
+
wipe(passwordUtf16);
|
|
50
|
+
const macKeyHandle = await crypto.subtle.importKey("raw", arrayBufferFromBytes(macKey), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
51
|
+
wipe(macKey);
|
|
52
|
+
const mac = new Uint8Array(await crypto.subtle.sign("HMAC", macKeyHandle, arrayBufferFromBytes(authenticatedSafe)));
|
|
53
|
+
const macData = sequence(sequence(sequence(oid(OID.sha256), nullValue()), octetString(mac)), octetString(macSalt), integer(BigInt(macIterations)));
|
|
54
|
+
const pfxAuthSafeContentInfo = sequence(oid(OID.data), explicit(0, octetString(authenticatedSafe)));
|
|
55
|
+
return sequence(integer(3n), pfxAuthSafeContentInfo, macData);
|
|
56
|
+
}
|
|
57
|
+
function validateInput(input, iterations, macIterations) {
|
|
58
|
+
if (!(input.password instanceof Uint8Array) || input.password.length === 0) {
|
|
59
|
+
throw new Error("password must be a non-empty Uint8Array of UTF-8 bytes");
|
|
60
|
+
}
|
|
61
|
+
if (!input.privateKey.extractable) {
|
|
62
|
+
throw new Error("privateKey must be extractable");
|
|
63
|
+
}
|
|
64
|
+
if (input.privateKey.algorithm.name !== "ECDSA") {
|
|
65
|
+
throw new Error("privateKey must be an ECDSA key");
|
|
66
|
+
}
|
|
67
|
+
if (!Number.isInteger(iterations) || iterations < 1) {
|
|
68
|
+
throw new Error("iterations must be a positive integer");
|
|
69
|
+
}
|
|
70
|
+
if (!Number.isInteger(macIterations) || macIterations < 1) {
|
|
71
|
+
throw new Error("macIterations must be a positive integer");
|
|
72
|
+
}
|
|
73
|
+
if (input.friendlyName !== undefined && !(input.friendlyName instanceof Uint8Array)) {
|
|
74
|
+
throw new Error("friendlyName must be a Uint8Array of UTF-8 bytes");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function buildCertSafeBag(certDer, attrs) {
|
|
78
|
+
const certBagInner = sequence(oid(OID.x509Certificate), explicit(0, octetString(certDer)));
|
|
79
|
+
return safeBag(OID.certBag, certBagInner, attrs);
|
|
80
|
+
}
|
|
81
|
+
function buildKeySafeBag(encryptedPrivateKeyInfo, attrs) {
|
|
82
|
+
return safeBag(OID.pkcs8ShroudedKeyBag, encryptedPrivateKeyInfo, attrs);
|
|
83
|
+
}
|
|
84
|
+
function safeBag(bagOid, bagValue, attrs) {
|
|
85
|
+
const parts = [oid(bagOid), explicit(0, bagValue)];
|
|
86
|
+
if (attrs.length > 0) {
|
|
87
|
+
parts.push(canonicalSetOf(attrs));
|
|
88
|
+
}
|
|
89
|
+
return sequence(...parts);
|
|
90
|
+
}
|
|
91
|
+
// X.690 §11.6: SET OF components are encoded in ascending order of their
|
|
92
|
+
// encoded octet strings, with the shorter component padded with trailing
|
|
93
|
+
// 0-octets for the comparison. Used for bagAttributes.
|
|
94
|
+
function canonicalSetOf(children) {
|
|
95
|
+
const sorted = [...children].sort(derSetCompare);
|
|
96
|
+
return set(...sorted);
|
|
97
|
+
}
|
|
98
|
+
function derSetCompare(a, b) {
|
|
99
|
+
const len = Math.max(a.length, b.length);
|
|
100
|
+
for (let i = 0; i < len; i += 1) {
|
|
101
|
+
const av = i < a.length ? a[i] : 0;
|
|
102
|
+
const bv = i < b.length ? b[i] : 0;
|
|
103
|
+
if (av !== bv)
|
|
104
|
+
return av - bv;
|
|
105
|
+
}
|
|
106
|
+
return 0;
|
|
107
|
+
}
|
|
108
|
+
function buildLocalKeyIdAttr(localKeyId) {
|
|
109
|
+
return sequence(oid(OID.localKeyId), set(octetString(localKeyId)));
|
|
110
|
+
}
|
|
111
|
+
function buildFriendlyNameAttr(friendlyNameUtf8) {
|
|
112
|
+
return sequence(oid(OID.friendlyName), set(bmpString(friendlyNameUtf8)));
|
|
113
|
+
}
|
|
114
|
+
function bmpString(utf8) {
|
|
115
|
+
const utf16 = utf8ToUtf16Be(utf8);
|
|
116
|
+
return der(0x1e, utf16);
|
|
117
|
+
}
|
|
118
|
+
async function pbes2EncryptAesCbc(plaintext, pbkdf2BaseKey, iterations) {
|
|
119
|
+
const salt = randomBytes(SALT_LENGTH);
|
|
120
|
+
const iv = randomBytes(IV_LENGTH);
|
|
121
|
+
const aesKey = await crypto.subtle.deriveKey({ name: "PBKDF2", salt: arrayBufferFromBytes(salt), iterations, hash: "SHA-256" }, pbkdf2BaseKey, { name: "AES-CBC", length: 256 }, false, ["encrypt"]);
|
|
122
|
+
const ciphertext = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-CBC", iv: arrayBufferFromBytes(iv) }, aesKey, arrayBufferFromBytes(plaintext)));
|
|
123
|
+
return {
|
|
124
|
+
algorithm: algorithmIdentifierPbes2(salt, iterations, iv),
|
|
125
|
+
ciphertext
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function algorithmIdentifierPbes2(salt, iterations, iv) {
|
|
129
|
+
const pbkdf2Params = sequence(octetString(salt), integer(BigInt(iterations)), sequence(oid(OID.hmacWithSha256), nullValue()));
|
|
130
|
+
const keyDerivationFunc = sequence(oid(OID.pbkdf2), pbkdf2Params);
|
|
131
|
+
const encryptionScheme = sequence(oid(OID.aes256Cbc), octetString(iv));
|
|
132
|
+
return sequence(oid(OID.pbes2), sequence(keyDerivationFunc, encryptionScheme));
|
|
133
|
+
}
|
|
134
|
+
// PKCS#12 v1 KDF (RFC 7292 App.B) producing an HMAC-SHA-256 key (32 bytes).
|
|
135
|
+
// Specialized for ID=3, n=u=32, v=64. Single-block output: no I update needed.
|
|
136
|
+
async function pkcs12V1KdfMacKey(passwordUtf16, salt, iterations) {
|
|
137
|
+
const v = SHA256_BLOCK_SIZE;
|
|
138
|
+
const D = new Uint8Array(v).fill(PKCS12_KDF_ID_MAC);
|
|
139
|
+
const sLen = Math.ceil(salt.length / v) * v;
|
|
140
|
+
const S2 = new Uint8Array(sLen);
|
|
141
|
+
for (let i = 0; i < sLen; i += 1) {
|
|
142
|
+
S2[i] = salt[i % salt.length];
|
|
143
|
+
}
|
|
144
|
+
const pLen = Math.ceil(passwordUtf16.length / v) * v;
|
|
145
|
+
const P2 = new Uint8Array(pLen);
|
|
146
|
+
for (let i = 0; i < pLen; i += 1) {
|
|
147
|
+
P2[i] = passwordUtf16[i % passwordUtf16.length];
|
|
148
|
+
}
|
|
149
|
+
const I = concatBytes([S2, P2]);
|
|
150
|
+
// T_0 holds D || S2 || P2 (raw password bytes embedded in P2).
|
|
151
|
+
// Each digestSha256 returns a fresh 32-byte buffer; the previous T's buffer
|
|
152
|
+
// becomes unreachable but, without an explicit wipe, would sit on the JS
|
|
153
|
+
// heap until GC. Zero it before reassigning. Successive Ts are H^j(D||I)
|
|
154
|
+
// values, which let an attacker reach H^c(D||I) = MAC key by continuing the
|
|
155
|
+
// chain — they're as sensitive as the MAC key itself.
|
|
156
|
+
let T = concatBytes([D, I]);
|
|
157
|
+
for (let j = 0; j < iterations; j += 1) {
|
|
158
|
+
const next = await digestSha256(T);
|
|
159
|
+
T.fill(0);
|
|
160
|
+
T = next;
|
|
161
|
+
}
|
|
162
|
+
wipe(D, S2, P2, I);
|
|
163
|
+
return T.subarray(0, MAC_KEY_LENGTH);
|
|
164
|
+
}
|
|
165
|
+
// Convert UTF-8 bytes to UTF-16BE bytes plus a 0x00 0x00 terminator,
|
|
166
|
+
// without going through any JavaScript string. Walks code points by hand.
|
|
167
|
+
function utf8ToUtf16BeWithTerminator(utf8) {
|
|
168
|
+
const utf16 = utf8ToUtf16Be(utf8);
|
|
169
|
+
const out = new Uint8Array(utf16.length + 2);
|
|
170
|
+
out.set(utf16, 0);
|
|
171
|
+
wipe(utf16);
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
// Two-pass to avoid an intermediate `number[]` that would retain
|
|
175
|
+
// password-derived bytes on the JS heap until GC. Pass 1 sizes the output;
|
|
176
|
+
// pass 2 writes directly into a tight Uint8Array. Both passes share the same
|
|
177
|
+
// boundary checks so an invalid leader byte fails fast in pass 1.
|
|
178
|
+
function utf8ToUtf16Be(utf8) {
|
|
179
|
+
let outLen = 0;
|
|
180
|
+
let i = 0;
|
|
181
|
+
while (i < utf8.length) {
|
|
182
|
+
const b1 = utf8[i];
|
|
183
|
+
if (b1 < 0x80) {
|
|
184
|
+
outLen += 2;
|
|
185
|
+
i += 1;
|
|
186
|
+
}
|
|
187
|
+
else if ((b1 & 0xe0) === 0xc0 && i + 1 < utf8.length) {
|
|
188
|
+
outLen += 2;
|
|
189
|
+
i += 2;
|
|
190
|
+
}
|
|
191
|
+
else if ((b1 & 0xf0) === 0xe0 && i + 2 < utf8.length) {
|
|
192
|
+
outLen += 2;
|
|
193
|
+
i += 3;
|
|
194
|
+
}
|
|
195
|
+
else if ((b1 & 0xf8) === 0xf0 && i + 3 < utf8.length) {
|
|
196
|
+
outLen += 4;
|
|
197
|
+
i += 4;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
throw new Error("Invalid UTF-8 sequence");
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const out = new Uint8Array(outLen);
|
|
204
|
+
let oi = 0;
|
|
205
|
+
i = 0;
|
|
206
|
+
while (i < utf8.length) {
|
|
207
|
+
const b1 = utf8[i];
|
|
208
|
+
let cp;
|
|
209
|
+
if (b1 < 0x80) {
|
|
210
|
+
cp = b1;
|
|
211
|
+
i += 1;
|
|
212
|
+
}
|
|
213
|
+
else if ((b1 & 0xe0) === 0xc0) {
|
|
214
|
+
cp = ((b1 & 0x1f) << 6) | (utf8[i + 1] & 0x3f);
|
|
215
|
+
i += 2;
|
|
216
|
+
}
|
|
217
|
+
else if ((b1 & 0xf0) === 0xe0) {
|
|
218
|
+
cp = ((b1 & 0x0f) << 12) | ((utf8[i + 1] & 0x3f) << 6) | (utf8[i + 2] & 0x3f);
|
|
219
|
+
i += 3;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
cp = ((b1 & 0x07) << 18)
|
|
223
|
+
| ((utf8[i + 1] & 0x3f) << 12)
|
|
224
|
+
| ((utf8[i + 2] & 0x3f) << 6)
|
|
225
|
+
| (utf8[i + 3] & 0x3f);
|
|
226
|
+
i += 4;
|
|
227
|
+
}
|
|
228
|
+
if (cp < 0x10000) {
|
|
229
|
+
out[oi++] = (cp >> 8) & 0xff;
|
|
230
|
+
out[oi++] = cp & 0xff;
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
const adj = cp - 0x10000;
|
|
234
|
+
const high = 0xd800 + ((adj >> 10) & 0x3ff);
|
|
235
|
+
const low = 0xdc00 + (adj & 0x3ff);
|
|
236
|
+
out[oi++] = (high >> 8) & 0xff;
|
|
237
|
+
out[oi++] = high & 0xff;
|
|
238
|
+
out[oi++] = (low >> 8) & 0xff;
|
|
239
|
+
out[oi++] = low & 0xff;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
function wipe(...bufs) {
|
|
245
|
+
for (const b of bufs) {
|
|
246
|
+
b.fill(0);
|
|
247
|
+
}
|
|
248
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -62,6 +62,20 @@ export interface IssuedClientCertificateForPublicKey {
|
|
|
62
62
|
certDer: Uint8Array;
|
|
63
63
|
certChainPem: string;
|
|
64
64
|
}
|
|
65
|
+
export interface IssueDocumentSigningCertOptions {
|
|
66
|
+
ca: CertificateAuthority;
|
|
67
|
+
subject: Subject;
|
|
68
|
+
days: number;
|
|
69
|
+
notBefore?: Date;
|
|
70
|
+
serialNumber?: SerialNumber;
|
|
71
|
+
}
|
|
72
|
+
export interface IssuedDocumentSigningCertificate {
|
|
73
|
+
certPem: string;
|
|
74
|
+
certDer: Uint8Array;
|
|
75
|
+
privateKey: CryptoKey;
|
|
76
|
+
publicKey: CryptoKey;
|
|
77
|
+
certChainPem: string;
|
|
78
|
+
}
|
|
65
79
|
export interface ImportCertificateAuthorityOptions {
|
|
66
80
|
certPem: string;
|
|
67
81
|
privateKey: CryptoKey;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,yBAAyB,GACjC,IAAI,GACJ,GAAG,GACH,IAAI,GACJ,GAAG,GACH,IAAI,GACJ,GAAG,GACH,GAAG,GACH,IAAI,GACJ,cAAc,GACd,QAAQ,GACR,YAAY,GACZ,OAAO,GACP,WAAW,GACX,SAAS,GACT,KAAK,CAAC;AAEV,MAAM,MAAM,SAAS,GAAG,GAAG,MAAM,IAAI,MAAM,GAAG,MAAM,EAAE,CAAC;AAEvD,MAAM,MAAM,oBAAoB,GAAG,yBAAyB,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,oBAAoB,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,oBAAoB,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,kCAAkC;IACjD,EAAE,EAAE,oBAAoB,CAAC;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,mCAAmC;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iCAAiC;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,SAAS,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,yBAAyB,GACjC,IAAI,GACJ,GAAG,GACH,IAAI,GACJ,GAAG,GACH,IAAI,GACJ,GAAG,GACH,GAAG,GACH,IAAI,GACJ,cAAc,GACd,QAAQ,GACR,YAAY,GACZ,OAAO,GACP,WAAW,GACX,SAAS,GACT,KAAK,CAAC;AAEV,MAAM,MAAM,SAAS,GAAG,GAAG,MAAM,IAAI,MAAM,GAAG,MAAM,EAAE,CAAC;AAEvD,MAAM,MAAM,oBAAoB,GAAG,yBAAyB,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,oBAAoB,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,oBAAoB,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,kCAAkC;IACjD,EAAE,EAAE,oBAAoB,CAAC;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,mCAAmC;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,+BAA+B;IAC9C,EAAE,EAAE,oBAAoB,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iCAAiC;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,SAAS,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
|
package/dist/x509.d.ts
CHANGED
|
@@ -23,11 +23,13 @@ export declare function basicConstraintsCaExtension(pathLenConstraint: number):
|
|
|
23
23
|
export declare function basicConstraintsLeafExtension(): Uint8Array;
|
|
24
24
|
export declare function keyUsageExtension(usages: readonly KeyUsageBit[]): Uint8Array;
|
|
25
25
|
export declare function extendedKeyUsageClientAuthExtension(): Uint8Array;
|
|
26
|
+
export declare function extendedKeyUsageDocumentSigningExtension(): Uint8Array;
|
|
26
27
|
export declare function subjectKeyIdentifierExtension(keyIdentifier: Uint8Array): Uint8Array;
|
|
27
28
|
export declare function authorityKeyIdentifierExtension(keyIdentifier: Uint8Array): Uint8Array;
|
|
28
29
|
export declare function subjectAltNameExtension(dnsNames?: readonly string[], ipAddresses?: readonly string[]): Uint8Array | undefined;
|
|
29
30
|
declare const KEY_USAGE_BITS: {
|
|
30
31
|
readonly digitalSignature: 0;
|
|
32
|
+
readonly contentCommitment: 1;
|
|
31
33
|
readonly keyCertSign: 5;
|
|
32
34
|
readonly cRLSign: 6;
|
|
33
35
|
};
|
package/dist/x509.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"x509.d.ts","sourceRoot":"","sources":["../src/x509.ts"],"names":[],"mappings":"AACA,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAkBjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,UAAU,CAAC;IAC3B,uBAAuB,EAAE,UAAU,CAAC;IACpC,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,WAAW,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,UAAU,CAAC;IAC9B,eAAe,EAAE,UAAU,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,IAAI,CAAC;CAChB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,qBAAqB,GAAG,oBAAoB,CAoBtF;AAED,wBAAgB,gBAAgB,CAC9B,iBAAiB,EAAE,UAAU,EAC7B,YAAY,EAAE,UAAU,EACxB,WAAW,EAAE,cAAc,GAC1B,UAAU,CAEZ;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAEnF;AAED,wBAAgB,2BAA2B,CAAC,iBAAiB,EAAE,MAAM,GAAG,UAAU,CAMjF;AAED,wBAAgB,6BAA6B,IAAI,UAAU,CAE1D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,UAAU,CAgB5E;AAED,wBAAgB,mCAAmC,IAAI,UAAU,CAEhE;AAED,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,UAAU,GAAG,UAAU,CAEnF;AAED,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,UAAU,GAAG,UAAU,CAErF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,SAAS,CAmC7H;
|
|
1
|
+
{"version":3,"file":"x509.d.ts","sourceRoot":"","sources":["../src/x509.ts"],"names":[],"mappings":"AACA,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAkBjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,UAAU,CAAC;IAC3B,uBAAuB,EAAE,UAAU,CAAC;IACpC,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,WAAW,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,UAAU,CAAC;IAC9B,eAAe,EAAE,UAAU,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,IAAI,CAAC;CAChB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,qBAAqB,GAAG,oBAAoB,CAoBtF;AAED,wBAAgB,gBAAgB,CAC9B,iBAAiB,EAAE,UAAU,EAC7B,YAAY,EAAE,UAAU,EACxB,WAAW,EAAE,cAAc,GAC1B,UAAU,CAEZ;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAEnF;AAED,wBAAgB,2BAA2B,CAAC,iBAAiB,EAAE,MAAM,GAAG,UAAU,CAMjF;AAED,wBAAgB,6BAA6B,IAAI,UAAU,CAE1D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,UAAU,CAgB5E;AAED,wBAAgB,mCAAmC,IAAI,UAAU,CAEhE;AAED,wBAAgB,wCAAwC,IAAI,UAAU,CAErE;AAED,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,UAAU,GAAG,UAAU,CAEnF;AAED,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,UAAU,GAAG,UAAU,CAErF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,SAAS,CAmC7H;AAuID,QAAA,MAAM,cAAc;;;;;CAKV,CAAC;AAEX,KAAK,WAAW,GAAG,MAAM,OAAO,cAAc,CAAC"}
|
package/dist/x509.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { asciiBytes, concatBytes } from "./bytes.js";
|
|
1
|
+
import { asciiBytes, concatBytes, randomBytes } from "./bytes.js";
|
|
2
2
|
import { signatureAlgorithmOidForCurve } from "./crypto.js";
|
|
3
3
|
import { bitString, boolean, contextPrimitive, der, explicit, generalizedTime, integer, octetString, oid, readElement, sequence, TAG, utcTime } from "./der.js";
|
|
4
4
|
import { encodeIpAddress } from "./ip.js";
|
|
@@ -43,6 +43,9 @@ export function keyUsageExtension(usages) {
|
|
|
43
43
|
export function extendedKeyUsageClientAuthExtension() {
|
|
44
44
|
return extension(OID.extendedKeyUsage, false, sequence(oid(OID.clientAuth)));
|
|
45
45
|
}
|
|
46
|
+
export function extendedKeyUsageDocumentSigningExtension() {
|
|
47
|
+
return extension(OID.extendedKeyUsage, false, sequence(oid(OID.documentSigning)));
|
|
48
|
+
}
|
|
46
49
|
export function subjectKeyIdentifierExtension(keyIdentifier) {
|
|
47
50
|
return extension(OID.subjectKeyIdentifier, false, octetString(keyIdentifier));
|
|
48
51
|
}
|
|
@@ -106,8 +109,7 @@ function encodeSerialNumber(serialNumber) {
|
|
|
106
109
|
}
|
|
107
110
|
function encodeSerialNumberDer(serialNumber) {
|
|
108
111
|
if (serialNumber === undefined) {
|
|
109
|
-
const bytes =
|
|
110
|
-
crypto.getRandomValues(bytes);
|
|
112
|
+
const bytes = randomBytes(16);
|
|
111
113
|
bytes[0] = bytes[0] & 0x7f;
|
|
112
114
|
if (bytes.every((byte) => byte === 0)) {
|
|
113
115
|
bytes[15] = 1;
|
|
@@ -193,6 +195,7 @@ function assertYearInRange(year, fieldName) {
|
|
|
193
195
|
}
|
|
194
196
|
const KEY_USAGE_BITS = {
|
|
195
197
|
digitalSignature: 0,
|
|
198
|
+
contentCommitment: 1,
|
|
196
199
|
keyCertSign: 5,
|
|
197
200
|
cRLSign: 6
|
|
198
201
|
};
|