jose 6.0.11 → 6.0.12
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/dist/types/jwe/compact/encrypt.d.ts +4 -3
- package/dist/types/jwe/flattened/encrypt.d.ts +3 -3
- package/dist/types/jwks/local.d.ts +3 -2
- package/dist/types/jwks/remote.d.ts +11 -5
- package/dist/types/jwt/encrypt.d.ts +3 -3
- package/dist/types/key/generate_key_pair.d.ts +3 -2
- package/dist/types/key/generate_secret.d.ts +8 -5
- package/dist/types/key/import.d.ts +18 -13
- package/dist/types/types.d.ts +2 -1
- package/dist/webapi/jwks/remote.js +1 -1
- package/dist/webapi/lib/asn1.js +74 -118
- package/package.json +1 -1
|
@@ -46,9 +46,10 @@ export declare class CompactEncrypt {
|
|
|
46
46
|
*/
|
|
47
47
|
setProtectedHeader(protectedHeader: types.CompactJWEHeaderParameters): this;
|
|
48
48
|
/**
|
|
49
|
-
* Sets the JWE Key Management parameters to be used when encrypting
|
|
50
|
-
*
|
|
51
|
-
*
|
|
49
|
+
* Sets the JWE Key Management parameters to be used when encrypting. Use of this is method is
|
|
50
|
+
* really only needed for ECDH based algorithms when utilizing the Agreement PartyUInfo or
|
|
51
|
+
* Agreement PartyVInfo parameters. Other parameters will always be randomly generated when needed
|
|
52
|
+
* and missing.
|
|
52
53
|
*
|
|
53
54
|
* @param parameters JWE Key Management parameters.
|
|
54
55
|
*/
|
|
@@ -21,9 +21,9 @@ export declare class FlattenedEncrypt {
|
|
|
21
21
|
constructor(plaintext: Uint8Array);
|
|
22
22
|
/**
|
|
23
23
|
* Sets the JWE Key Management parameters to be used when encrypting. Use of this is method is
|
|
24
|
-
* really only needed for ECDH based algorithms when utilizing the Agreement PartyUInfo or
|
|
25
|
-
* Agreement PartyVInfo parameters. Other parameters will always be randomly generated
|
|
26
|
-
* and missing.
|
|
24
|
+
* really only needed for ECDH based algorithms when utilizing the "apu" (Agreement PartyUInfo) or
|
|
25
|
+
* "apv" (Agreement PartyVInfo) parameters. Other parameters will always be randomly generated
|
|
26
|
+
* when needed and missing.
|
|
27
27
|
*
|
|
28
28
|
* @param parameters JWE Key Management parameters.
|
|
29
29
|
*/
|
|
@@ -17,8 +17,9 @@ import type * as types from '../types.d.ts';
|
|
|
17
17
|
* multiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt
|
|
18
18
|
* verification in an iterative manner.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* > [!NOTE]\
|
|
21
|
+
* > The function's purpose is to resolve public keys used for verifying signatures and will not work
|
|
22
|
+
* > for public encryption keys.
|
|
22
23
|
*
|
|
23
24
|
* This function is exported (as a named export) from the main `'jose'` module entry point as well
|
|
24
25
|
* as from its subpath export `'jose/jwks/local'`.
|
|
@@ -8,6 +8,10 @@ import type * as types from '../types.d.ts';
|
|
|
8
8
|
* When passed to {@link jwks/remote.createRemoteJWKSet createRemoteJWKSet} this allows the resolver
|
|
9
9
|
* to make use of advanced fetch configurations, HTTP Proxies, retry on network errors, etc.
|
|
10
10
|
*
|
|
11
|
+
* > [!NOTE]\
|
|
12
|
+
* > Known caveat: Expect Type-related issues when passing the inputs through to fetch-like modules,
|
|
13
|
+
* > they hardly ever get their typings inline with actual fetch, you should `@ts-expect-error` them.
|
|
14
|
+
*
|
|
11
15
|
* import ky from 'ky'
|
|
12
16
|
*
|
|
13
17
|
* let logRequest!: (request: Request) => void
|
|
@@ -109,9 +113,10 @@ options: {
|
|
|
109
113
|
signal: AbortSignal;
|
|
110
114
|
}) => Promise<Response>;
|
|
111
115
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* writable by your own
|
|
116
|
+
* > [!WARNING]\
|
|
117
|
+
* > This option has security implications that must be understood, assessed for applicability, and
|
|
118
|
+
* > accepted before use. It is critical that the JSON Web Key Set cache only be writable by your own
|
|
119
|
+
* > code.
|
|
115
120
|
*
|
|
116
121
|
* This option is intended for cloud computing runtimes that cannot keep an in memory cache between
|
|
117
122
|
* their code's invocations. Use in runtimes where an in memory cache between requests is available
|
|
@@ -207,8 +212,9 @@ export type JWKSCacheInput = ExportedJWKSCache | Record<string, never>;
|
|
|
207
212
|
* multiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt
|
|
208
213
|
* verification in an iterative manner.
|
|
209
214
|
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
215
|
+
* > [!NOTE]\
|
|
216
|
+
* > The function's purpose is to resolve public keys used for verifying signatures and will not work
|
|
217
|
+
* > for public encryption keys.
|
|
212
218
|
*
|
|
213
219
|
* This function is exported (as a named export) from the main `'jose'` module entry point as well
|
|
214
220
|
* as from its subpath export `'jose/jwks/remote'`.
|
|
@@ -35,9 +35,9 @@ export declare class EncryptJWT implements types.ProduceJWT {
|
|
|
35
35
|
setProtectedHeader(protectedHeader: types.CompactJWEHeaderParameters): this;
|
|
36
36
|
/**
|
|
37
37
|
* Sets the JWE Key Management parameters to be used when encrypting. Use of this is method is
|
|
38
|
-
* really only needed for ECDH based algorithms when utilizing the Agreement PartyUInfo or
|
|
39
|
-
* Agreement PartyVInfo parameters. Other parameters will always be randomly generated
|
|
40
|
-
* and missing.
|
|
38
|
+
* really only needed for ECDH based algorithms when utilizing the "apu" (Agreement PartyUInfo) or
|
|
39
|
+
* "apv" (Agreement PartyVInfo) parameters. Other parameters will always be randomly generated
|
|
40
|
+
* when needed and missing.
|
|
41
41
|
*
|
|
42
42
|
* @param parameters JWE Key Management parameters.
|
|
43
43
|
*/
|
|
@@ -33,8 +33,9 @@ export interface GenerateKeyPairOptions {
|
|
|
33
33
|
* Generates a private and a public key for a given JWA algorithm identifier. This can only generate
|
|
34
34
|
* asymmetric key pairs. For symmetric secrets use the `generateSecret` function.
|
|
35
35
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
36
|
+
* > [!NOTE]\
|
|
37
|
+
* > The `privateKey` is generated with `extractable` set to `false` by default. See
|
|
38
|
+
* > {@link GenerateKeyPairOptions.extractable} to generate an extractable `privateKey`.
|
|
38
39
|
*
|
|
39
40
|
* This function is exported (as a named export) from the main `'jose'` module entry point as well
|
|
40
41
|
* as from its subpath export `'jose/generate/keypair'`.
|
|
@@ -9,18 +9,21 @@ export interface GenerateSecretOptions {
|
|
|
9
9
|
/**
|
|
10
10
|
* The value to use as {@link !SubtleCrypto.generateKey} `extractable` argument. Default is false.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* > [!NOTE]\
|
|
13
|
+
* > Because A128CBC-HS256, A192CBC-HS384, and A256CBC-HS512 secrets cannot be represented as
|
|
14
|
+
* > {@link !CryptoKey} this option has no effect for them.
|
|
14
15
|
*/
|
|
15
16
|
extractable?: boolean;
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
18
19
|
* Generates a symmetric secret key for a given JWA algorithm identifier.
|
|
19
20
|
*
|
|
20
|
-
*
|
|
21
|
+
* > [!NOTE]\
|
|
22
|
+
* > The secret key is generated with `extractable` set to `false` by default.
|
|
21
23
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
+
* > [!NOTE]\
|
|
25
|
+
* > Because A128CBC-HS256, A192CBC-HS384, and A256CBC-HS512 secrets cannot be represented as
|
|
26
|
+
* > {@link !CryptoKey} this method yields a {@link !Uint8Array} for them instead.
|
|
24
27
|
*
|
|
25
28
|
* This function is exported (as a named export) from the main `'jose'` module entry point as well
|
|
26
29
|
* as from its subpath export `'jose/generate/secret'`.
|
|
@@ -15,9 +15,10 @@ export interface KeyImportOptions {
|
|
|
15
15
|
/**
|
|
16
16
|
* Imports a PEM-encoded SPKI string as a {@link !CryptoKey}.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* > [!NOTE]\
|
|
19
|
+
* > The OID id-RSASSA-PSS (1.2.840.113549.1.1.10) is not supported in
|
|
20
|
+
* > {@link https://w3c.github.io/webcrypto/ Web Cryptography API}, use the OID rsaEncryption
|
|
21
|
+
* > (1.2.840.113549.1.1.1) instead for all RSA algorithms.
|
|
21
22
|
*
|
|
22
23
|
* This function is exported (as a named export) from the main `'jose'` module entry point as well
|
|
23
24
|
* as from its subpath export `'jose/key/import'`.
|
|
@@ -30,9 +31,10 @@ export declare function importSPKI(spki: string, alg: string, options?: KeyImpor
|
|
|
30
31
|
/**
|
|
31
32
|
* Imports the SPKI from an X.509 string certificate as a {@link !CryptoKey}.
|
|
32
33
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* > [!NOTE]\
|
|
35
|
+
* > The OID id-RSASSA-PSS (1.2.840.113549.1.1.10) is not supported in
|
|
36
|
+
* > {@link https://w3c.github.io/webcrypto/ Web Cryptography API}, use the OID rsaEncryption
|
|
37
|
+
* > (1.2.840.113549.1.1.1) instead for all RSA algorithms.
|
|
36
38
|
*
|
|
37
39
|
* This function is exported (as a named export) from the main `'jose'` module entry point as well
|
|
38
40
|
* as from its subpath export `'jose/key/import'`.
|
|
@@ -45,9 +47,10 @@ export declare function importX509(x509: string, alg: string, options?: KeyImpor
|
|
|
45
47
|
/**
|
|
46
48
|
* Imports a PEM-encoded PKCS#8 string as a {@link !CryptoKey}.
|
|
47
49
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
50
|
+
* > [!NOTE]\
|
|
51
|
+
* > The OID id-RSASSA-PSS (1.2.840.113549.1.1.10) is not supported in
|
|
52
|
+
* > {@link https://w3c.github.io/webcrypto/ Web Cryptography API}, use the OID rsaEncryption
|
|
53
|
+
* > (1.2.840.113549.1.1.1) instead for all RSA algorithms.
|
|
51
54
|
*
|
|
52
55
|
* This function is exported (as a named export) from the main `'jose'` module entry point as well
|
|
53
56
|
* as from its subpath export `'jose/key/import'`.
|
|
@@ -61,11 +64,13 @@ export declare function importPKCS8(pkcs8: string, alg: string, options?: KeyImp
|
|
|
61
64
|
* Imports a JWK to a {@link !CryptoKey}. Either the JWK "alg" (Algorithm) Parameter, or the optional
|
|
62
65
|
* "alg" argument, must be present for asymmetric JSON Web Key imports.
|
|
63
66
|
*
|
|
64
|
-
*
|
|
65
|
-
* {@link !CryptoKey}
|
|
67
|
+
* > [!NOTE]\
|
|
68
|
+
* > The JSON Web Key parameters "use", "key_ops", and "ext" are also used in the {@link !CryptoKey}
|
|
69
|
+
* > import process.
|
|
66
70
|
*
|
|
67
|
-
*
|
|
68
|
-
* {@link !
|
|
71
|
+
* > [!NOTE]\
|
|
72
|
+
* > Symmetric JSON Web Keys (i.e. `kty: "oct"`) yield back an {@link !Uint8Array} instead of a
|
|
73
|
+
* > {@link !CryptoKey}.
|
|
69
74
|
*
|
|
70
75
|
* This function is exported (as a named export) from the main `'jose'` module entry point as well
|
|
71
76
|
* as from its subpath export `'jose/key/import'`.
|
package/dist/types/types.d.ts
CHANGED
|
@@ -522,7 +522,8 @@ export interface VerifyOptions extends CritOption {
|
|
|
522
522
|
* A list of accepted JWS "alg" (Algorithm) Header Parameter values. By default all "alg"
|
|
523
523
|
* (Algorithm) values applicable for the used key/secret are allowed.
|
|
524
524
|
*
|
|
525
|
-
*
|
|
525
|
+
* > [!NOTE]\
|
|
526
|
+
* > Unsecured JWTs (`{ "alg": "none" }`) are never accepted by this API.
|
|
526
527
|
*/
|
|
527
528
|
algorithms?: string[]
|
|
528
529
|
}
|
|
@@ -9,7 +9,7 @@ function isCloudflareWorkers() {
|
|
|
9
9
|
let USER_AGENT;
|
|
10
10
|
if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
|
|
11
11
|
const NAME = 'jose';
|
|
12
|
-
const VERSION = 'v6.0.
|
|
12
|
+
const VERSION = 'v6.0.12';
|
|
13
13
|
USER_AGENT = `${NAME}/${VERSION}`;
|
|
14
14
|
}
|
|
15
15
|
export const customFetch = Symbol();
|
package/dist/webapi/lib/asn1.js
CHANGED
|
@@ -30,50 +30,42 @@ export const toSPKI = (key) => {
|
|
|
30
30
|
export const toPKCS8 = (key) => {
|
|
31
31
|
return genericExport('private', 'pkcs8', key);
|
|
32
32
|
};
|
|
33
|
-
const findOid = (keyData, oid, from = 0) => {
|
|
34
|
-
if (from === 0) {
|
|
35
|
-
oid.unshift(oid.length);
|
|
36
|
-
oid.unshift(0x06);
|
|
37
|
-
}
|
|
38
|
-
const i = keyData.indexOf(oid[0], from);
|
|
39
|
-
if (i === -1)
|
|
40
|
-
return false;
|
|
41
|
-
const sub = keyData.subarray(i, i + oid.length);
|
|
42
|
-
if (sub.length !== oid.length)
|
|
43
|
-
return false;
|
|
44
|
-
return sub.every((value, index) => value === oid[index]) || findOid(keyData, oid, i + 1);
|
|
45
|
-
};
|
|
46
33
|
const getNamedCurve = (keyData) => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
34
|
+
const patterns = Object.entries({
|
|
35
|
+
'P-256': [0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07],
|
|
36
|
+
'P-384': [0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22],
|
|
37
|
+
'P-521': [0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23],
|
|
38
|
+
});
|
|
39
|
+
const maxPatternLen = Math.max(...patterns.map(([, bytes]) => bytes.length));
|
|
40
|
+
for (let i = 0; i <= keyData.byteLength - maxPatternLen; i++) {
|
|
41
|
+
for (const [curve, bytes] of patterns) {
|
|
42
|
+
if (i <= keyData.byteLength - bytes.length) {
|
|
43
|
+
if (keyData.subarray(i, i + bytes.length).every((byte, idx) => byte === bytes[idx])) {
|
|
44
|
+
return curve;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
56
48
|
}
|
|
49
|
+
return undefined;
|
|
57
50
|
};
|
|
58
|
-
const genericImport = async (
|
|
51
|
+
const genericImport = async (keyFormat, keyData, alg, options) => {
|
|
59
52
|
let algorithm;
|
|
60
53
|
let keyUsages;
|
|
61
|
-
const keyData = new Uint8Array(atob(pem.replace(replace, ''))
|
|
62
|
-
.split('')
|
|
63
|
-
.map((c) => c.charCodeAt(0)));
|
|
64
54
|
const isPublic = keyFormat === 'spki';
|
|
55
|
+
const getSignatureUsages = () => (isPublic ? ['verify'] : ['sign']);
|
|
56
|
+
const getEncryptionUsages = () => isPublic ? ['encrypt', 'wrapKey'] : ['decrypt', 'unwrapKey'];
|
|
65
57
|
switch (alg) {
|
|
66
58
|
case 'PS256':
|
|
67
59
|
case 'PS384':
|
|
68
60
|
case 'PS512':
|
|
69
61
|
algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };
|
|
70
|
-
keyUsages =
|
|
62
|
+
keyUsages = getSignatureUsages();
|
|
71
63
|
break;
|
|
72
64
|
case 'RS256':
|
|
73
65
|
case 'RS384':
|
|
74
66
|
case 'RS512':
|
|
75
67
|
algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };
|
|
76
|
-
keyUsages =
|
|
68
|
+
keyUsages = getSignatureUsages();
|
|
77
69
|
break;
|
|
78
70
|
case 'RSA-OAEP':
|
|
79
71
|
case 'RSA-OAEP-256':
|
|
@@ -83,33 +75,29 @@ const genericImport = async (replace, keyFormat, pem, alg, options) => {
|
|
|
83
75
|
name: 'RSA-OAEP',
|
|
84
76
|
hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`,
|
|
85
77
|
};
|
|
86
|
-
keyUsages =
|
|
78
|
+
keyUsages = getEncryptionUsages();
|
|
87
79
|
break;
|
|
88
80
|
case 'ES256':
|
|
89
|
-
algorithm = { name: 'ECDSA', namedCurve: 'P-256' };
|
|
90
|
-
keyUsages = isPublic ? ['verify'] : ['sign'];
|
|
91
|
-
break;
|
|
92
81
|
case 'ES384':
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
algorithm = { name: 'ECDSA', namedCurve: 'P-521' };
|
|
98
|
-
keyUsages = isPublic ? ['verify'] : ['sign'];
|
|
82
|
+
case 'ES512': {
|
|
83
|
+
const curveMap = { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' };
|
|
84
|
+
algorithm = { name: 'ECDSA', namedCurve: curveMap[alg] };
|
|
85
|
+
keyUsages = getSignatureUsages();
|
|
99
86
|
break;
|
|
87
|
+
}
|
|
100
88
|
case 'ECDH-ES':
|
|
101
89
|
case 'ECDH-ES+A128KW':
|
|
102
90
|
case 'ECDH-ES+A192KW':
|
|
103
91
|
case 'ECDH-ES+A256KW': {
|
|
104
92
|
const namedCurve = getNamedCurve(keyData);
|
|
105
|
-
algorithm = namedCurve
|
|
93
|
+
algorithm = namedCurve ? { name: 'ECDH', namedCurve } : { name: 'X25519' };
|
|
106
94
|
keyUsages = isPublic ? [] : ['deriveBits'];
|
|
107
95
|
break;
|
|
108
96
|
}
|
|
109
97
|
case 'Ed25519':
|
|
110
98
|
case 'EdDSA':
|
|
111
99
|
algorithm = { name: 'Ed25519' };
|
|
112
|
-
keyUsages =
|
|
100
|
+
keyUsages = getSignatureUsages();
|
|
113
101
|
break;
|
|
114
102
|
default:
|
|
115
103
|
throw new JOSENotSupported('Invalid or unsupported "alg" (Algorithm) value');
|
|
@@ -117,99 +105,67 @@ const genericImport = async (replace, keyFormat, pem, alg, options) => {
|
|
|
117
105
|
return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? (isPublic ? true : false), keyUsages);
|
|
118
106
|
};
|
|
119
107
|
export const fromPKCS8 = (pem, alg, options) => {
|
|
120
|
-
|
|
108
|
+
const keyData = decodeBase64(pem.replace(/(?:-----(?:BEGIN|END) PRIVATE KEY-----|\s)/g, ''));
|
|
109
|
+
return genericImport('pkcs8', keyData, alg, options);
|
|
121
110
|
};
|
|
122
111
|
export const fromSPKI = (pem, alg, options) => {
|
|
123
|
-
|
|
112
|
+
const keyData = decodeBase64(pem.replace(/(?:-----(?:BEGIN|END) PUBLIC KEY-----|\s)/g, ''));
|
|
113
|
+
return genericImport('spki', keyData, alg, options);
|
|
124
114
|
};
|
|
125
|
-
function
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
function parseElement(bytes) {
|
|
136
|
-
let position = 0;
|
|
137
|
-
let tag = bytes[0] & 0x1f;
|
|
138
|
-
position++;
|
|
139
|
-
if (tag === 0x1f) {
|
|
140
|
-
tag = 0;
|
|
141
|
-
while (bytes[position] >= 0x80) {
|
|
142
|
-
tag = tag * 128 + bytes[position] - 0x80;
|
|
143
|
-
position++;
|
|
144
|
-
}
|
|
145
|
-
tag = tag * 128 + bytes[position] - 0x80;
|
|
146
|
-
position++;
|
|
147
|
-
}
|
|
148
|
-
let length = 0;
|
|
149
|
-
if (bytes[position] < 0x80) {
|
|
150
|
-
length = bytes[position];
|
|
151
|
-
position++;
|
|
152
|
-
}
|
|
153
|
-
else if (length === 0x80) {
|
|
154
|
-
length = 0;
|
|
155
|
-
while (bytes[position + length] !== 0 || bytes[position + length + 1] !== 0) {
|
|
156
|
-
if (length > bytes.byteLength) {
|
|
157
|
-
throw new TypeError('invalid indefinite form length');
|
|
115
|
+
function spkiFromX509(buf) {
|
|
116
|
+
let pos = 0;
|
|
117
|
+
const parseLength = () => {
|
|
118
|
+
const first = buf[pos++];
|
|
119
|
+
if (first & 0x80) {
|
|
120
|
+
const lengthOfLength = first & 0x7f;
|
|
121
|
+
let length = 0;
|
|
122
|
+
for (let i = 0; i < lengthOfLength; i++) {
|
|
123
|
+
length = (length << 8) | buf[pos++];
|
|
158
124
|
}
|
|
159
|
-
length
|
|
125
|
+
return length;
|
|
160
126
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
length = 0;
|
|
172
|
-
for (let i = 0; i < numberOfDigits; i++) {
|
|
173
|
-
length = length * 256 + bytes[position];
|
|
174
|
-
position++;
|
|
127
|
+
return first;
|
|
128
|
+
};
|
|
129
|
+
const skipElement = (count = 1) => {
|
|
130
|
+
if (count <= 0)
|
|
131
|
+
return;
|
|
132
|
+
pos++;
|
|
133
|
+
const length = parseLength();
|
|
134
|
+
pos += length;
|
|
135
|
+
if (count > 1) {
|
|
136
|
+
skipElement(count - 1);
|
|
175
137
|
}
|
|
176
|
-
}
|
|
177
|
-
const byteLength = position + length;
|
|
178
|
-
return {
|
|
179
|
-
byteLength,
|
|
180
|
-
contents: bytes.subarray(position, byteLength),
|
|
181
|
-
raw: bytes.subarray(0, byteLength),
|
|
182
138
|
};
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
createPublicKey ??= globalThis.process?.getBuiltinModule?.('node:crypto')?.createPublicKey;
|
|
192
|
-
}
|
|
193
|
-
catch {
|
|
194
|
-
createPublicKey = 0;
|
|
139
|
+
if (buf[pos++] !== 0x30)
|
|
140
|
+
throw new Error('Invalid certificate structure');
|
|
141
|
+
parseLength();
|
|
142
|
+
if (buf[pos++] !== 0x30)
|
|
143
|
+
throw new Error('Invalid tbsCertificate structure');
|
|
144
|
+
parseLength();
|
|
145
|
+
if (buf[pos] === 0xa0) {
|
|
146
|
+
skipElement(6);
|
|
195
147
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
return new createPublicKey(x509).export({ format: 'pem', type: 'spki' });
|
|
199
|
-
}
|
|
200
|
-
catch { }
|
|
148
|
+
else {
|
|
149
|
+
skipElement(5);
|
|
201
150
|
}
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
151
|
+
const spkiStart = pos;
|
|
152
|
+
if (buf[pos++] !== 0x30)
|
|
153
|
+
throw new Error('Invalid SPKI structure');
|
|
154
|
+
const spkiContentLength = parseLength();
|
|
155
|
+
return buf.subarray(spkiStart, spkiStart + spkiContentLength + (pos - spkiStart));
|
|
156
|
+
}
|
|
157
|
+
function extractX509SPKI(x509) {
|
|
158
|
+
const base64Content = x509.replace(/(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g, '');
|
|
159
|
+
const derBytes = decodeBase64(base64Content);
|
|
160
|
+
return spkiFromX509(derBytes);
|
|
205
161
|
}
|
|
206
162
|
export const fromX509 = (pem, alg, options) => {
|
|
207
163
|
let spki;
|
|
208
164
|
try {
|
|
209
|
-
spki =
|
|
165
|
+
spki = extractX509SPKI(pem);
|
|
210
166
|
}
|
|
211
167
|
catch (cause) {
|
|
212
168
|
throw new TypeError('Failed to parse the X.509 certificate', { cause });
|
|
213
169
|
}
|
|
214
|
-
return
|
|
170
|
+
return genericImport('spki', spki, alg, options);
|
|
215
171
|
};
|