sm-crypto-wasm 0.7.0 → 0.7.1
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 +41 -876
- package/dist/asn1/decode.d.ts +103 -12
- package/dist/asn1/decode.js +129 -10
- package/dist/asn1/encode.d.ts +120 -19
- package/dist/asn1/encode.js +158 -19
- package/dist/asn1/index.d.ts +6 -0
- package/dist/asn1/index.js +6 -0
- package/dist/asn1/oid.d.ts +18 -0
- package/dist/asn1/oid.js +30 -1
- package/dist/asn1/time.d.ts +32 -0
- package/dist/asn1/time.js +55 -1
- package/dist/asn1/types.d.ts +100 -16
- package/dist/asn1/types.js +47 -6
- package/dist/cms/errors.d.ts +12 -2
- package/dist/cms/errors.js +7 -1
- package/dist/cms/index.d.ts +5 -0
- package/dist/cms/index.js +5 -0
- package/dist/cms/oids.d.ts +37 -7
- package/dist/cms/oids.js +37 -7
- package/dist/cms/parse.d.ts +155 -13
- package/dist/cms/parse.js +98 -4
- package/dist/cms/sign.d.ts +80 -10
- package/dist/cms/sign.js +54 -2
- package/dist/cms/verify.d.ts +84 -9
- package/dist/cms/verify.js +54 -5
- package/dist/common/hybrid.d.ts +25 -0
- package/dist/common/hybrid.js +25 -0
- package/dist/common/sealed.d.ts +119 -15
- package/dist/common/sealed.js +67 -9
- package/dist/esbuild-plugin.d.ts +74 -5
- package/dist/esbuild-plugin.js +69 -4
- package/dist/index.d.ts +19 -0
- package/dist/index.js +22 -0
- package/dist/pem/asn1.d.ts +13 -0
- package/dist/pem/asn1.js +13 -0
- package/dist/pem/index.d.ts +2 -0
- package/dist/pem/index.js +2 -0
- package/dist/pem/pkcs8.d.ts +64 -8
- package/dist/pem/pkcs8.js +66 -6
- package/dist/pem/sm2.d.ts +76 -4
- package/dist/pem/sm2.js +169 -12
- package/dist/pem/sm9.d.ts +42 -2
- package/dist/pem/sm9.js +42 -2
- package/dist/runtime/base64.core.d.ts +25 -1
- package/dist/runtime/base64.core.js +31 -1
- package/dist/runtime/convert.d.ts +70 -7
- package/dist/runtime/convert.js +129 -9
- package/dist/runtime/errors.d.ts +64 -8
- package/dist/runtime/errors.js +64 -8
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/loadWasm.browser.d.ts +33 -0
- package/dist/runtime/loadWasm.browser.js +46 -0
- package/dist/runtime/loadWasm.core.d.ts +59 -3
- package/dist/runtime/loadWasm.core.js +53 -3
- package/dist/runtime/loadWasm.d.ts +44 -0
- package/dist/runtime/loadWasm.js +79 -4
- package/dist/runtime/random.browser.d.ts +24 -0
- package/dist/runtime/random.browser.js +31 -1
- package/dist/runtime/random.core.d.ts +21 -0
- package/dist/runtime/random.core.js +27 -0
- package/dist/runtime/random.d.ts +28 -0
- package/dist/runtime/random.js +40 -1
- package/dist/sm2/exchange.d.ts +132 -16
- package/dist/sm2/exchange.js +120 -9
- package/dist/sm2/hybrid.d.ts +65 -3
- package/dist/sm2/hybrid.js +53 -1
- package/dist/sm2/index.d.ts +260 -21
- package/dist/sm2/index.js +346 -23
- package/dist/sm2/kem.d.ts +62 -5
- package/dist/sm2/kem.js +37 -2
- package/dist/sm2/keyInput.d.ts +36 -3
- package/dist/sm2/keyInput.js +36 -3
- package/dist/sm3/index.d.ts +30 -0
- package/dist/sm3/index.js +55 -1
- package/dist/sm4/index.d.ts +125 -17
- package/dist/sm4/index.js +201 -14
- package/dist/sm9/core.d.ts +58 -8
- package/dist/sm9/core.js +36 -5
- package/dist/sm9/hybrid.d.ts +66 -3
- package/dist/sm9/hybrid.js +46 -1
- package/dist/sm9/index.d.ts +265 -19
- package/dist/sm9/index.js +175 -5
- package/dist/sm9/input.d.ts +37 -2
- package/dist/sm9/input.js +50 -1
- package/dist/sm9/kem.d.ts +57 -4
- package/dist/sm9/kem.js +47 -1
- package/dist/webcrypto/algorithms.d.ts +58 -12
- package/dist/webcrypto/algorithms.js +58 -10
- package/dist/webcrypto/cryptoKey.d.ts +81 -15
- package/dist/webcrypto/cryptoKey.js +69 -11
- package/dist/webcrypto/errors.d.ts +29 -5
- package/dist/webcrypto/errors.js +29 -5
- package/dist/webcrypto/index.d.ts +10 -0
- package/dist/webcrypto/index.js +10 -0
- package/dist/webcrypto/subtle.d.ts +53 -3
- package/dist/webcrypto/subtle.js +69 -1
- package/dist/x509/encode.d.ts +86 -16
- package/dist/x509/encode.js +89 -16
- package/dist/x509/errors.d.ts +16 -1
- package/dist/x509/errors.js +16 -1
- package/dist/x509/extensions.d.ts +46 -7
- package/dist/x509/extensions.js +67 -9
- package/dist/x509/index.d.ts +7 -0
- package/dist/x509/index.js +19 -0
- package/dist/x509/ip.d.ts +9 -0
- package/dist/x509/ip.js +21 -0
- package/dist/x509/issue.d.ts +45 -2
- package/dist/x509/issue.js +107 -0
- package/dist/x509/oids.d.ts +41 -7
- package/dist/x509/oids.js +58 -7
- package/dist/x509/parse.d.ts +21 -0
- package/dist/x509/parse.js +115 -1
- package/dist/x509/sha1.d.ts +12 -1
- package/dist/x509/sha1.js +18 -1
- package/dist/x509/sha256.d.ts +12 -1
- package/dist/x509/sha256.js +31 -1
- package/dist/x509/sig.d.ts +15 -0
- package/dist/x509/sig.js +28 -1
- package/dist/x509/types.d.ts +312 -57
- package/dist/x509/types.js +6 -0
- package/dist/x509/verify.d.ts +51 -4
- package/dist/x509/verify.js +42 -3
- package/dist/zuc/index.d.ts +128 -10
- package/dist/zuc/index.js +136 -7
- package/package.json +53 -36
package/dist/asn1/decode.d.ts
CHANGED
|
@@ -13,62 +13,153 @@
|
|
|
13
13
|
* - 单对象解析一律拒绝尾部多余字节(红线 #3)。
|
|
14
14
|
*
|
|
15
15
|
* 每个节点保留 `raw`(输入缓冲上的视图),供 CMS 验签与证书 TBS 直接使用。
|
|
16
|
+
*
|
|
17
|
+
* ASN.1 DER/BER parser.
|
|
18
|
+
*
|
|
19
|
+
* Covers the BER/DER subset needed by X.509 and CMS:
|
|
20
|
+
* - definite-length (short and long form);
|
|
21
|
+
* - BER indefinite-length (`0x80` + EOC `00 00`), allowed **only in `parseBer`**;
|
|
22
|
+
* - high tag numbers (`0x1f` + base128);
|
|
23
|
+
* - recursive constructed / primitive handling.
|
|
24
|
+
*
|
|
25
|
+
* Strictness:
|
|
26
|
+
* - `parseDer` rejects indefinite length, non-minimal length encodings, EOC and
|
|
27
|
+
* trailing bytes;
|
|
28
|
+
* - `parseBer` relaxes length encoding and allows indefinite length, but still
|
|
29
|
+
* rejects truncation and trailing bytes;
|
|
30
|
+
* - single-object parsing always rejects trailing bytes (red line #3).
|
|
31
|
+
*
|
|
32
|
+
* Every node keeps `raw` (a view onto the input buffer) so that CMS signature
|
|
33
|
+
* verification and certificate TBS hashing can use it directly.
|
|
16
34
|
*/
|
|
17
35
|
import { type Asn1Node } from './types.js';
|
|
18
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* 解析选项。
|
|
38
|
+
*
|
|
39
|
+
* Parse options.
|
|
40
|
+
*/
|
|
19
41
|
export interface ParseOptions {
|
|
20
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* 允许 BER indefinite-length。仅 CMS 路径应开启。
|
|
44
|
+
*
|
|
45
|
+
* Allow BER indefinite-length; only the CMS path should enable this.
|
|
46
|
+
*/
|
|
21
47
|
allowIndefinite?: boolean;
|
|
22
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* 是否严格校验长度编码的最小形式(DER 默认开启)。
|
|
50
|
+
*
|
|
51
|
+
* Whether to enforce minimal length encoding (on by default for DER).
|
|
52
|
+
*/
|
|
23
53
|
strictLength?: boolean;
|
|
24
54
|
}
|
|
25
55
|
/**
|
|
26
56
|
* 解析单个 DER 对象。
|
|
27
57
|
*
|
|
28
58
|
* @throws Asn1Error 截断、超出深度、非 DER 编码、或根节点后有多余字节。
|
|
59
|
+
*
|
|
60
|
+
* Parses a single DER object.
|
|
61
|
+
*
|
|
62
|
+
* @throws Asn1Error On truncation, excessive depth, non-DER encoding, or trailing
|
|
63
|
+
* bytes after the root node.
|
|
29
64
|
*/
|
|
30
65
|
export declare function parseDer(buf: Uint8Array): Asn1Node;
|
|
31
66
|
/**
|
|
32
67
|
* 解析单个 BER 对象(允许 indefinite-length)。
|
|
33
68
|
*
|
|
34
69
|
* @throws Asn1Error 截断、超出深度、或根节点后有多余字节。
|
|
70
|
+
*
|
|
71
|
+
* Parses a single BER object (indefinite-length allowed).
|
|
72
|
+
*
|
|
73
|
+
* @throws Asn1Error On truncation, excessive depth, or trailing bytes after the
|
|
74
|
+
* root node.
|
|
35
75
|
*/
|
|
36
76
|
export declare function parseBer(buf: Uint8Array): Asn1Node;
|
|
37
77
|
/**
|
|
38
78
|
* 解析连续的多个 DER 对象(证书 bundle / CMS 文件)。
|
|
39
79
|
*
|
|
40
80
|
* 返回按出现顺序排列的节点;允许空输入并返回空数组。
|
|
81
|
+
*
|
|
82
|
+
* Parses a sequence of consecutive DER objects (a certificate bundle or a CMS file).
|
|
83
|
+
*
|
|
84
|
+
* Returns the nodes in order of appearance; empty input is allowed and yields an
|
|
85
|
+
* empty array.
|
|
41
86
|
*/
|
|
42
87
|
export declare function parseDerAll(buf: Uint8Array): Asn1Node[];
|
|
43
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* 解析连续的多个 BER 对象(允许 indefinite-length)。
|
|
90
|
+
*
|
|
91
|
+
* Parses a sequence of consecutive BER objects (indefinite-length allowed).
|
|
92
|
+
*/
|
|
44
93
|
export declare function parseBerAll(buf: Uint8Array): Asn1Node[];
|
|
45
94
|
/**
|
|
46
95
|
* 读取 INTEGER(二进制补码,支持负数)。
|
|
47
96
|
*
|
|
48
97
|
* @throws Asn1Error 节点不是 INTEGER。
|
|
98
|
+
*
|
|
99
|
+
* Reads an INTEGER (two's complement, negative values supported).
|
|
100
|
+
*
|
|
101
|
+
* @throws Asn1Error When the node is not an INTEGER.
|
|
49
102
|
*/
|
|
50
103
|
export declare function readInteger(node: Asn1Node, what?: string): bigint;
|
|
51
|
-
/**
|
|
104
|
+
/**
|
|
105
|
+
* 读取 BOOLEAN(DER 中 TRUE 必须为 0xFF)。
|
|
106
|
+
*
|
|
107
|
+
* Reads a BOOLEAN (DER requires TRUE to be 0xFF).
|
|
108
|
+
*/
|
|
52
109
|
export declare function readBoolean(node: Asn1Node, what?: string): boolean;
|
|
53
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* BIT STRING 内容。
|
|
112
|
+
*
|
|
113
|
+
* Contents of a BIT STRING.
|
|
114
|
+
*/
|
|
54
115
|
export interface BitString {
|
|
55
|
-
/**
|
|
116
|
+
/**
|
|
117
|
+
* 去掉 unused bits 后的有效字节(尾部未用位保留,由调用方屏蔽)。
|
|
118
|
+
*
|
|
119
|
+
* The payload bytes, with the unused-bits header removed (the trailing unused
|
|
120
|
+
* bits stay in place and must be masked by the caller).
|
|
121
|
+
*/
|
|
56
122
|
readonly bytes: Uint8Array;
|
|
57
|
-
/**
|
|
123
|
+
/**
|
|
124
|
+
* 末尾未使用位数(0..7)。
|
|
125
|
+
*
|
|
126
|
+
* Number of unused trailing bits (0..7).
|
|
127
|
+
*/
|
|
58
128
|
readonly unusedBits: number;
|
|
59
129
|
}
|
|
60
|
-
/**
|
|
130
|
+
/**
|
|
131
|
+
* 读取 BIT STRING。
|
|
132
|
+
*
|
|
133
|
+
* Reads a BIT STRING.
|
|
134
|
+
*/
|
|
61
135
|
export declare function readBitString(node: Asn1Node, what?: string): BitString;
|
|
62
|
-
/**
|
|
136
|
+
/**
|
|
137
|
+
* 读取 OCTET STRING。
|
|
138
|
+
*
|
|
139
|
+
* Reads an OCTET STRING.
|
|
140
|
+
*/
|
|
63
141
|
export declare function readOctetString(node: Asn1Node, what?: string): Uint8Array;
|
|
64
|
-
/**
|
|
142
|
+
/**
|
|
143
|
+
* 读取 OBJECT IDENTIFIER。
|
|
144
|
+
*
|
|
145
|
+
* Reads an OBJECT IDENTIFIER.
|
|
146
|
+
*/
|
|
65
147
|
export declare function readOid(node: Asn1Node, what?: string): string;
|
|
66
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* 读取 UTCTime / GeneralizedTime。
|
|
150
|
+
*
|
|
151
|
+
* Reads a UTCTime / GeneralizedTime.
|
|
152
|
+
*/
|
|
67
153
|
export declare function readTime(node: Asn1Node, what?: string): Date;
|
|
68
154
|
/**
|
|
69
155
|
* 读取 ASN.1 字符串。
|
|
70
156
|
*
|
|
71
157
|
* 支持 UTF8String / PrintableString / IA5String / NumericString /
|
|
72
158
|
* TeletexString / BMPString / UniversalString;其他类型抛 `Asn1Error`。
|
|
159
|
+
*
|
|
160
|
+
* Reads an ASN.1 string.
|
|
161
|
+
*
|
|
162
|
+
* Supports UTF8String / PrintableString / IA5String / NumericString /
|
|
163
|
+
* TeletexString / BMPString / UniversalString; other types throw `Asn1Error`.
|
|
73
164
|
*/
|
|
74
165
|
export declare function readString(node: Asn1Node, what?: string): string;
|
package/dist/asn1/decode.js
CHANGED
|
@@ -13,16 +13,44 @@
|
|
|
13
13
|
* - 单对象解析一律拒绝尾部多余字节(红线 #3)。
|
|
14
14
|
*
|
|
15
15
|
* 每个节点保留 `raw`(输入缓冲上的视图),供 CMS 验签与证书 TBS 直接使用。
|
|
16
|
+
*
|
|
17
|
+
* ASN.1 DER/BER parser.
|
|
18
|
+
*
|
|
19
|
+
* Covers the BER/DER subset needed by X.509 and CMS:
|
|
20
|
+
* - definite-length (short and long form);
|
|
21
|
+
* - BER indefinite-length (`0x80` + EOC `00 00`), allowed **only in `parseBer`**;
|
|
22
|
+
* - high tag numbers (`0x1f` + base128);
|
|
23
|
+
* - recursive constructed / primitive handling.
|
|
24
|
+
*
|
|
25
|
+
* Strictness:
|
|
26
|
+
* - `parseDer` rejects indefinite length, non-minimal length encodings, EOC and
|
|
27
|
+
* trailing bytes;
|
|
28
|
+
* - `parseBer` relaxes length encoding and allows indefinite length, but still
|
|
29
|
+
* rejects truncation and trailing bytes;
|
|
30
|
+
* - single-object parsing always rejects trailing bytes (red line #3).
|
|
31
|
+
*
|
|
32
|
+
* Every node keeps `raw` (a view onto the input buffer) so that CMS signature
|
|
33
|
+
* verification and certificate TBS hashing can use it directly.
|
|
16
34
|
*/
|
|
17
35
|
import { decodeOid } from './oid.js';
|
|
18
36
|
import { parseTime } from './time.js';
|
|
19
37
|
import { Asn1Class, Asn1Error, UniversalTag } from './types.js';
|
|
20
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* constructed 嵌套深度上限,防栈溢出与恶意深嵌套。
|
|
40
|
+
*
|
|
41
|
+
* Upper bound on constructed nesting depth, to avoid stack overflow and hostile
|
|
42
|
+
* deeply nested input.
|
|
43
|
+
*/
|
|
21
44
|
const MAX_DEPTH = 64;
|
|
22
45
|
/**
|
|
23
46
|
* 解析单个 DER 对象。
|
|
24
47
|
*
|
|
25
48
|
* @throws Asn1Error 截断、超出深度、非 DER 编码、或根节点后有多余字节。
|
|
49
|
+
*
|
|
50
|
+
* Parses a single DER object.
|
|
51
|
+
*
|
|
52
|
+
* @throws Asn1Error On truncation, excessive depth, non-DER encoding, or trailing
|
|
53
|
+
* bytes after the root node.
|
|
26
54
|
*/
|
|
27
55
|
export function parseDer(buf) {
|
|
28
56
|
return parseSingle(buf, { allowIndefinite: false, strictLength: true }, 'parseDer');
|
|
@@ -31,6 +59,11 @@ export function parseDer(buf) {
|
|
|
31
59
|
* 解析单个 BER 对象(允许 indefinite-length)。
|
|
32
60
|
*
|
|
33
61
|
* @throws Asn1Error 截断、超出深度、或根节点后有多余字节。
|
|
62
|
+
*
|
|
63
|
+
* Parses a single BER object (indefinite-length allowed).
|
|
64
|
+
*
|
|
65
|
+
* @throws Asn1Error On truncation, excessive depth, or trailing bytes after the
|
|
66
|
+
* root node.
|
|
34
67
|
*/
|
|
35
68
|
export function parseBer(buf) {
|
|
36
69
|
return parseSingle(buf, { allowIndefinite: true, strictLength: false }, 'parseBer');
|
|
@@ -39,14 +72,28 @@ export function parseBer(buf) {
|
|
|
39
72
|
* 解析连续的多个 DER 对象(证书 bundle / CMS 文件)。
|
|
40
73
|
*
|
|
41
74
|
* 返回按出现顺序排列的节点;允许空输入并返回空数组。
|
|
75
|
+
*
|
|
76
|
+
* Parses a sequence of consecutive DER objects (a certificate bundle or a CMS file).
|
|
77
|
+
*
|
|
78
|
+
* Returns the nodes in order of appearance; empty input is allowed and yields an
|
|
79
|
+
* empty array.
|
|
42
80
|
*/
|
|
43
81
|
export function parseDerAll(buf) {
|
|
44
82
|
return parseAll(buf, { allowIndefinite: false, strictLength: true }, 'parseDerAll');
|
|
45
83
|
}
|
|
46
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* 解析连续的多个 BER 对象(允许 indefinite-length)。
|
|
86
|
+
*
|
|
87
|
+
* Parses a sequence of consecutive BER objects (indefinite-length allowed).
|
|
88
|
+
*/
|
|
47
89
|
export function parseBerAll(buf) {
|
|
48
90
|
return parseAll(buf, { allowIndefinite: true, strictLength: false }, 'parseBerAll');
|
|
49
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* 解析根节点,并要求输入完全被消费。
|
|
94
|
+
*
|
|
95
|
+
* Parses the root node and requires the whole input to be consumed.
|
|
96
|
+
*/
|
|
50
97
|
function parseSingle(buf, opts, where) {
|
|
51
98
|
const reader = new Reader(buf, opts, where);
|
|
52
99
|
const node = reader.readNode(0);
|
|
@@ -55,6 +102,11 @@ function parseSingle(buf, opts, where) {
|
|
|
55
102
|
}
|
|
56
103
|
return node;
|
|
57
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* 解析所有顶层对象,直到输入耗尽。
|
|
107
|
+
*
|
|
108
|
+
* Parses every top-level object until the input is exhausted.
|
|
109
|
+
*/
|
|
58
110
|
function parseAll(buf, opts, where) {
|
|
59
111
|
const reader = new Reader(buf, opts, where);
|
|
60
112
|
const nodes = [];
|
|
@@ -63,6 +115,11 @@ function parseAll(buf, opts, where) {
|
|
|
63
115
|
}
|
|
64
116
|
return nodes;
|
|
65
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* 游标式 TLV 读取器(持有单一输入缓冲与位置)。
|
|
120
|
+
*
|
|
121
|
+
* Cursor-style TLV reader over a single input buffer.
|
|
122
|
+
*/
|
|
66
123
|
class Reader {
|
|
67
124
|
buf;
|
|
68
125
|
opts;
|
|
@@ -73,16 +130,30 @@ class Reader {
|
|
|
73
130
|
this.opts = opts;
|
|
74
131
|
this.where = where;
|
|
75
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* 距输入末尾还剩多少字节。
|
|
135
|
+
*
|
|
136
|
+
* Number of bytes left before the end of the input.
|
|
137
|
+
*/
|
|
76
138
|
remaining() {
|
|
77
139
|
return this.buf.length - this.pos;
|
|
78
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* 读取一个字节,越界则报错。
|
|
143
|
+
*
|
|
144
|
+
* Reads one byte, throwing on out-of-bounds.
|
|
145
|
+
*/
|
|
79
146
|
byte() {
|
|
80
147
|
if (this.pos >= this.buf.length) {
|
|
81
148
|
throw new Asn1Error(`${this.where}: truncated at offset ${this.pos}`);
|
|
82
149
|
}
|
|
83
150
|
return this.buf[this.pos++];
|
|
84
151
|
}
|
|
85
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* 读取一个完整 TLV。
|
|
154
|
+
*
|
|
155
|
+
* Reads one complete TLV.
|
|
156
|
+
*/
|
|
86
157
|
readNode(depth) {
|
|
87
158
|
if (depth > MAX_DEPTH) {
|
|
88
159
|
throw new Asn1Error(`${this.where}: nesting deeper than ${MAX_DEPTH}`);
|
|
@@ -93,6 +164,8 @@ class Reader {
|
|
|
93
164
|
const constructed = (first & 0x20) !== 0;
|
|
94
165
|
const tag = (first & 0x1f) === 0x1f ? this.readHighTag() : first & 0x1f;
|
|
95
166
|
// EndOfContent 只能作为 indefinite-length 的结束标记出现。
|
|
167
|
+
//
|
|
168
|
+
// EndOfContent may only appear as the terminator of an indefinite-length value.
|
|
96
169
|
if (cls === Asn1Class.Universal && tag === UniversalTag.EndOfContent && !constructed) {
|
|
97
170
|
const lb = this.byte();
|
|
98
171
|
if (lb !== 0)
|
|
@@ -120,6 +193,8 @@ class Reader {
|
|
|
120
193
|
const contentStart = this.pos;
|
|
121
194
|
if (indefinite) {
|
|
122
195
|
// indefinite:一直读到 EOC(00 00)。
|
|
196
|
+
//
|
|
197
|
+
// Indefinite: keep reading until the EOC (00 00).
|
|
123
198
|
const children = [];
|
|
124
199
|
for (;;) {
|
|
125
200
|
if (this.remaining() < 2) {
|
|
@@ -176,7 +251,11 @@ class Reader {
|
|
|
176
251
|
raw: this.buf.subarray(start, this.pos),
|
|
177
252
|
};
|
|
178
253
|
}
|
|
179
|
-
/**
|
|
254
|
+
/**
|
|
255
|
+
* 高 tag number:后续字节 base128。
|
|
256
|
+
*
|
|
257
|
+
* High tag number: subsequent bytes are base128.
|
|
258
|
+
*/
|
|
180
259
|
readHighTag() {
|
|
181
260
|
let value = 0;
|
|
182
261
|
let count = 0;
|
|
@@ -194,7 +273,11 @@ class Reader {
|
|
|
194
273
|
return value;
|
|
195
274
|
}
|
|
196
275
|
}
|
|
197
|
-
/**
|
|
276
|
+
/**
|
|
277
|
+
* 长格式长度(`n` 为 1..4)。
|
|
278
|
+
*
|
|
279
|
+
* Long-form length (`n` is 1..4).
|
|
280
|
+
*/
|
|
198
281
|
readLongLength(n) {
|
|
199
282
|
if (n === 0)
|
|
200
283
|
throw new Asn1Error(`${this.where}: reserved length encoding 0x80`);
|
|
@@ -220,10 +303,16 @@ class Reader {
|
|
|
220
303
|
}
|
|
221
304
|
}
|
|
222
305
|
// ----------------- 常用值读取 -----------------
|
|
306
|
+
//
|
|
307
|
+
// ----------------- Common value readers -----------------
|
|
223
308
|
/**
|
|
224
309
|
* 读取 INTEGER(二进制补码,支持负数)。
|
|
225
310
|
*
|
|
226
311
|
* @throws Asn1Error 节点不是 INTEGER。
|
|
312
|
+
*
|
|
313
|
+
* Reads an INTEGER (two's complement, negative values supported).
|
|
314
|
+
*
|
|
315
|
+
* @throws Asn1Error When the node is not an INTEGER.
|
|
227
316
|
*/
|
|
228
317
|
export function readInteger(node, what = 'INTEGER') {
|
|
229
318
|
if (node.cls !== Asn1Class.Universal || node.tag !== UniversalTag.Integer) {
|
|
@@ -240,7 +329,11 @@ export function readInteger(node, what = 'INTEGER') {
|
|
|
240
329
|
}
|
|
241
330
|
return value;
|
|
242
331
|
}
|
|
243
|
-
/**
|
|
332
|
+
/**
|
|
333
|
+
* 读取 BOOLEAN(DER 中 TRUE 必须为 0xFF)。
|
|
334
|
+
*
|
|
335
|
+
* Reads a BOOLEAN (DER requires TRUE to be 0xFF).
|
|
336
|
+
*/
|
|
244
337
|
export function readBoolean(node, what = 'BOOLEAN') {
|
|
245
338
|
if (node.cls !== Asn1Class.Universal || node.tag !== UniversalTag.Boolean) {
|
|
246
339
|
throw new Asn1Error(`${what}: expected BOOLEAN`);
|
|
@@ -249,7 +342,11 @@ export function readBoolean(node, what = 'BOOLEAN') {
|
|
|
249
342
|
throw new Asn1Error(`${what}: BOOLEAN must be 1 byte`);
|
|
250
343
|
return node.value[0] !== 0;
|
|
251
344
|
}
|
|
252
|
-
/**
|
|
345
|
+
/**
|
|
346
|
+
* 读取 BIT STRING。
|
|
347
|
+
*
|
|
348
|
+
* Reads a BIT STRING.
|
|
349
|
+
*/
|
|
253
350
|
export function readBitString(node, what = 'BIT STRING') {
|
|
254
351
|
if (node.cls !== Asn1Class.Universal || node.tag !== UniversalTag.BitString) {
|
|
255
352
|
throw new Asn1Error(`${what}: expected BIT STRING`);
|
|
@@ -261,21 +358,33 @@ export function readBitString(node, what = 'BIT STRING') {
|
|
|
261
358
|
throw new Asn1Error(`${what}: invalid unused-bit count ${unusedBits}`);
|
|
262
359
|
return { bytes: node.value.subarray(1), unusedBits };
|
|
263
360
|
}
|
|
264
|
-
/**
|
|
361
|
+
/**
|
|
362
|
+
* 读取 OCTET STRING。
|
|
363
|
+
*
|
|
364
|
+
* Reads an OCTET STRING.
|
|
365
|
+
*/
|
|
265
366
|
export function readOctetString(node, what = 'OCTET STRING') {
|
|
266
367
|
if (node.cls !== Asn1Class.Universal || node.tag !== UniversalTag.OctetString) {
|
|
267
368
|
throw new Asn1Error(`${what}: expected OCTET STRING`);
|
|
268
369
|
}
|
|
269
370
|
return node.value;
|
|
270
371
|
}
|
|
271
|
-
/**
|
|
372
|
+
/**
|
|
373
|
+
* 读取 OBJECT IDENTIFIER。
|
|
374
|
+
*
|
|
375
|
+
* Reads an OBJECT IDENTIFIER.
|
|
376
|
+
*/
|
|
272
377
|
export function readOid(node, what = 'OBJECT IDENTIFIER') {
|
|
273
378
|
if (node.cls !== Asn1Class.Universal || node.tag !== UniversalTag.ObjectIdentifier) {
|
|
274
379
|
throw new Asn1Error(`${what}: expected OBJECT IDENTIFIER`);
|
|
275
380
|
}
|
|
276
381
|
return decodeOid(node.value);
|
|
277
382
|
}
|
|
278
|
-
/**
|
|
383
|
+
/**
|
|
384
|
+
* 读取 UTCTime / GeneralizedTime。
|
|
385
|
+
*
|
|
386
|
+
* Reads a UTCTime / GeneralizedTime.
|
|
387
|
+
*/
|
|
279
388
|
export function readTime(node, what = 'Time') {
|
|
280
389
|
if (node.cls !== Asn1Class.Universal) {
|
|
281
390
|
throw new Asn1Error(`${what}: expected UTCTime or GeneralizedTime`);
|
|
@@ -291,6 +400,11 @@ export function readTime(node, what = 'Time') {
|
|
|
291
400
|
*
|
|
292
401
|
* 支持 UTF8String / PrintableString / IA5String / NumericString /
|
|
293
402
|
* TeletexString / BMPString / UniversalString;其他类型抛 `Asn1Error`。
|
|
403
|
+
*
|
|
404
|
+
* Reads an ASN.1 string.
|
|
405
|
+
*
|
|
406
|
+
* Supports UTF8String / PrintableString / IA5String / NumericString /
|
|
407
|
+
* TeletexString / BMPString / UniversalString; other types throw `Asn1Error`.
|
|
294
408
|
*/
|
|
295
409
|
export function readString(node, what = 'string') {
|
|
296
410
|
if (node.cls !== Asn1Class.Universal) {
|
|
@@ -330,6 +444,11 @@ export function readString(node, what = 'string') {
|
|
|
330
444
|
throw new Asn1Error(`${what}: unsupported string tag ${node.tag}`);
|
|
331
445
|
}
|
|
332
446
|
}
|
|
447
|
+
/**
|
|
448
|
+
* 字节 → 单字节字符(低 8 位),用于 ASCII 类字符串。
|
|
449
|
+
*
|
|
450
|
+
* Bytes to one-code-unit string, used for ASCII-like string types.
|
|
451
|
+
*/
|
|
333
452
|
function latin1(bytes) {
|
|
334
453
|
let out = '';
|
|
335
454
|
for (let i = 0; i < bytes.length; i++)
|
package/dist/asn1/encode.d.ts
CHANGED
|
@@ -8,55 +8,149 @@
|
|
|
8
8
|
* - BOOLEAN TRUE 编码为 0xFF;
|
|
9
9
|
* - INTEGER 使用最小补码编码;
|
|
10
10
|
* - 输出始终是 definite-length(BER indefinite 只在解析侧接受)。
|
|
11
|
+
*
|
|
12
|
+
* ASN.1 DER encoder and builders.
|
|
13
|
+
*
|
|
14
|
+
* Rules:
|
|
15
|
+
* - `encode()` rebuilds the leading byte from `cls + constructed + tag` (fixing the
|
|
16
|
+
* legacy implementation dropping the constructed bit) and recurses into children
|
|
17
|
+
* of constructed nodes;
|
|
18
|
+
* - SET OF is sorted by encoded bytes (a DER requirement);
|
|
19
|
+
* - BOOLEAN TRUE is encoded as 0xFF;
|
|
20
|
+
* - INTEGER uses minimal two's-complement encoding;
|
|
21
|
+
* - output is always definite-length (BER indefinite is only accepted when parsing).
|
|
11
22
|
*/
|
|
12
23
|
import { Asn1Class, type Asn1Node } from './types.js';
|
|
13
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* 编码单个节点为 DER 字节。
|
|
26
|
+
*
|
|
27
|
+
* Encodes a single node to DER bytes.
|
|
28
|
+
*/
|
|
14
29
|
export declare function encode(node: Asn1Node): Uint8Array;
|
|
15
30
|
/**
|
|
16
31
|
* `encode` 的旧名(兼容 `src/pem/asn1.ts` 的历史导出)。
|
|
17
32
|
*
|
|
18
33
|
* @deprecated 使用 `encode`。
|
|
34
|
+
*
|
|
35
|
+
* Legacy alias of `encode` (kept for the historical exports of `src/pem/asn1.ts`).
|
|
36
|
+
*
|
|
37
|
+
* @deprecated Use `encode`.
|
|
19
38
|
*/
|
|
20
39
|
export declare const encodeDer: typeof encode;
|
|
21
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* 编码 tag 首字节(含高 tag number 的 base128 展开)。
|
|
42
|
+
*
|
|
43
|
+
* Encodes the tag's leading byte (including base128 expansion of high tag numbers).
|
|
44
|
+
*/
|
|
22
45
|
export declare function encodeTag(cls: Asn1Class, constructed: boolean, tag: number): Uint8Array;
|
|
23
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* 编码 definite-length。
|
|
48
|
+
*
|
|
49
|
+
* Encodes a definite length.
|
|
50
|
+
*/
|
|
24
51
|
export declare function encodeLength(length: number): Uint8Array;
|
|
25
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* 构造 SEQUENCE。
|
|
54
|
+
*
|
|
55
|
+
* Builds a SEQUENCE.
|
|
56
|
+
*/
|
|
26
57
|
export declare function seq(children: readonly Asn1Node[]): Asn1Node;
|
|
27
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* 构造 SET(保持给定顺序;ASN.1 SET 的排序语义由调用方负责)。
|
|
60
|
+
*
|
|
61
|
+
* Builds a SET, keeping the given order; ordering semantics are the caller's job.
|
|
62
|
+
*/
|
|
28
63
|
export declare function set(children: readonly Asn1Node[]): Asn1Node;
|
|
29
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* 构造 SET OF(按 DER 编码字节排序)。
|
|
66
|
+
*
|
|
67
|
+
* Builds a SET OF, sorted by encoded DER bytes.
|
|
68
|
+
*/
|
|
30
69
|
export declare function setOf(children: readonly Asn1Node[]): Asn1Node;
|
|
31
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* 构造 `[tag] EXPLICIT` 包装。
|
|
72
|
+
*
|
|
73
|
+
* Builds a `[tag] EXPLICIT` wrapper.
|
|
74
|
+
*/
|
|
32
75
|
export declare function explicit(tag: number, inner: Asn1Node): Asn1Node;
|
|
33
76
|
/**
|
|
34
77
|
* 构造 `[tag] IMPLICIT` 包装:只替换外层标签,内容保持不变。
|
|
78
|
+
*
|
|
79
|
+
* Builds a `[tag] IMPLICIT` wrapper: only the outer tag is replaced, the content is
|
|
80
|
+
* kept unchanged.
|
|
35
81
|
*/
|
|
36
82
|
export declare function implicit(tag: number, inner: Asn1Node, cls?: Asn1Class): Asn1Node;
|
|
37
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* 构造 BIT STRING。`unusedBits` 为末尾未使用位数(0..7)。
|
|
85
|
+
*
|
|
86
|
+
* Builds a BIT STRING; `unusedBits` is the number of unused trailing bits (0..7).
|
|
87
|
+
*/
|
|
38
88
|
export declare function bitString(bytes: Uint8Array, unusedBits?: number): Asn1Node;
|
|
39
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* 构造 OCTET STRING。
|
|
91
|
+
*
|
|
92
|
+
* Builds an OCTET STRING.
|
|
93
|
+
*/
|
|
40
94
|
export declare function octetString(bytes: Uint8Array): Asn1Node;
|
|
41
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* 构造 BOOLEAN。
|
|
97
|
+
*
|
|
98
|
+
* Builds a BOOLEAN.
|
|
99
|
+
*/
|
|
42
100
|
export declare function boolean(value: boolean): Asn1Node;
|
|
43
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* 构造 NULL。
|
|
103
|
+
*
|
|
104
|
+
* Builds a NULL.
|
|
105
|
+
*/
|
|
44
106
|
export declare function nullValue(): Asn1Node;
|
|
45
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* 构造 INTEGER(最小补码编码)。
|
|
109
|
+
*
|
|
110
|
+
* Builds an INTEGER (minimal two's-complement encoding).
|
|
111
|
+
*/
|
|
46
112
|
export declare function integer(value: bigint | number): Asn1Node;
|
|
47
|
-
/**
|
|
113
|
+
/**
|
|
114
|
+
* 构造 OBJECT IDENTIFIER。
|
|
115
|
+
*
|
|
116
|
+
* Builds an OBJECT IDENTIFIER.
|
|
117
|
+
*/
|
|
48
118
|
export declare function oid(value: string): Asn1Node;
|
|
49
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* 构造 UTF8String。
|
|
121
|
+
*
|
|
122
|
+
* Builds a UTF8String.
|
|
123
|
+
*/
|
|
50
124
|
export declare function utf8String(value: string): Asn1Node;
|
|
51
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* 构造 PrintableString(仅允许 A-Z a-z 0-9 与 `'()+,-./:=?` 和空格)。
|
|
127
|
+
*
|
|
128
|
+
* Builds a PrintableString (only A-Z a-z 0-9 and `'()+,-./:=?` plus space allowed).
|
|
129
|
+
*/
|
|
52
130
|
export declare function printableString(value: string): Asn1Node;
|
|
53
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* 构造 IA5String(仅 ASCII)。
|
|
133
|
+
*
|
|
134
|
+
* Builds an IA5String (ASCII only).
|
|
135
|
+
*/
|
|
54
136
|
export declare function ia5String(value: string): Asn1Node;
|
|
55
|
-
/**
|
|
137
|
+
/**
|
|
138
|
+
* 构造 UTCTime(1950–2049)。
|
|
139
|
+
*
|
|
140
|
+
* Builds a UTCTime (years 1950–2049).
|
|
141
|
+
*/
|
|
56
142
|
export declare function utcTime(date: Date): Asn1Node;
|
|
57
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* 构造 GeneralizedTime。
|
|
145
|
+
*
|
|
146
|
+
* Builds a GeneralizedTime.
|
|
147
|
+
*/
|
|
58
148
|
export declare function generalizedTime(date: Date): Asn1Node;
|
|
59
|
-
/**
|
|
149
|
+
/**
|
|
150
|
+
* 按 RFC 5280 自动选择 UTCTime / GeneralizedTime。
|
|
151
|
+
*
|
|
152
|
+
* Picks UTCTime / GeneralizedTime automatically as RFC 5280 requires.
|
|
153
|
+
*/
|
|
60
154
|
export declare function time(date: Date): Asn1Node;
|
|
61
155
|
/**
|
|
62
156
|
* INTEGER 最小补码编码。
|
|
@@ -64,5 +158,12 @@ export declare function time(date: Date): Asn1Node;
|
|
|
64
158
|
* - 0 → `00`;
|
|
65
159
|
* - 正数:最高位为 1 时前置 `00`;
|
|
66
160
|
* - 负数:选择最少字节数 n 使 `-2^(8n-1) <= v`,按 2^(8n) 取模。
|
|
161
|
+
*
|
|
162
|
+
* Minimal two's-complement INTEGER encoding.
|
|
163
|
+
*
|
|
164
|
+
* - 0 → `00`;
|
|
165
|
+
* - positive: prepend `00` when the top bit would otherwise be set;
|
|
166
|
+
* - negative: pick the fewest bytes n such that `-2^(8n-1) <= v`, then reduce modulo
|
|
167
|
+
* 2^(8n).
|
|
67
168
|
*/
|
|
68
169
|
export declare function encodeIntegerValue(v: bigint): Uint8Array;
|