@freedomofpress/sigstore-browser 0.1.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.
Files changed (193) hide show
  1. package/.github/workflows/conformance.yml +29 -0
  2. package/.github/workflows/publish.yml +45 -0
  3. package/README.md +10 -0
  4. package/dist/asn1/error.d.ts +5 -0
  5. package/dist/asn1/error.d.ts.map +1 -0
  6. package/dist/asn1/error.js +20 -0
  7. package/dist/asn1/error.js.map +1 -0
  8. package/dist/asn1/index.d.ts +2 -0
  9. package/dist/asn1/index.d.ts.map +1 -0
  10. package/dist/asn1/index.js +17 -0
  11. package/dist/asn1/index.js.map +1 -0
  12. package/dist/asn1/length.d.ts +4 -0
  13. package/dist/asn1/length.d.ts.map +1 -0
  14. package/dist/asn1/length.js +59 -0
  15. package/dist/asn1/length.js.map +1 -0
  16. package/dist/asn1/obj.d.ts +15 -0
  17. package/dist/asn1/obj.d.ts.map +1 -0
  18. package/dist/asn1/obj.js +153 -0
  19. package/dist/asn1/obj.js.map +1 -0
  20. package/dist/asn1/parse.d.ts +7 -0
  21. package/dist/asn1/parse.d.ts.map +1 -0
  22. package/dist/asn1/parse.js +118 -0
  23. package/dist/asn1/parse.js.map +1 -0
  24. package/dist/asn1/tag.d.ts +17 -0
  25. package/dist/asn1/tag.d.ts.map +1 -0
  26. package/dist/asn1/tag.js +86 -0
  27. package/dist/asn1/tag.js.map +1 -0
  28. package/dist/bundle.d.ts +87 -0
  29. package/dist/bundle.d.ts.map +1 -0
  30. package/dist/bundle.js +2 -0
  31. package/dist/bundle.js.map +1 -0
  32. package/dist/canonicalize.d.ts +2 -0
  33. package/dist/canonicalize.d.ts.map +1 -0
  34. package/dist/canonicalize.js +64 -0
  35. package/dist/canonicalize.js.map +1 -0
  36. package/dist/cli.d.ts +3 -0
  37. package/dist/cli.d.ts.map +1 -0
  38. package/dist/cli.js +217 -0
  39. package/dist/cli.js.map +1 -0
  40. package/dist/crypto.d.ts +5 -0
  41. package/dist/crypto.d.ts.map +1 -0
  42. package/dist/crypto.js +260 -0
  43. package/dist/crypto.js.map +1 -0
  44. package/dist/dsse.d.ts +2 -0
  45. package/dist/dsse.d.ts.map +1 -0
  46. package/dist/dsse.js +42 -0
  47. package/dist/dsse.js.map +1 -0
  48. package/dist/encoding.d.ts +17 -0
  49. package/dist/encoding.d.ts.map +1 -0
  50. package/dist/encoding.js +112 -0
  51. package/dist/encoding.js.map +1 -0
  52. package/dist/errors.d.ts +39 -0
  53. package/dist/errors.d.ts.map +1 -0
  54. package/dist/errors.js +79 -0
  55. package/dist/errors.js.map +1 -0
  56. package/dist/index.d.ts +8 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +5 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/interfaces.d.ts +104 -0
  61. package/dist/interfaces.d.ts.map +1 -0
  62. package/dist/interfaces.js +26 -0
  63. package/dist/interfaces.js.map +1 -0
  64. package/dist/oid.d.ts +5 -0
  65. package/dist/oid.d.ts.map +1 -0
  66. package/dist/oid.js +25 -0
  67. package/dist/oid.js.map +1 -0
  68. package/dist/pem.d.ts +3 -0
  69. package/dist/pem.d.ts.map +1 -0
  70. package/dist/pem.js +41 -0
  71. package/dist/pem.js.map +1 -0
  72. package/dist/rfc3161/error.d.ts +3 -0
  73. package/dist/rfc3161/error.d.ts.map +1 -0
  74. package/dist/rfc3161/error.js +18 -0
  75. package/dist/rfc3161/error.js.map +1 -0
  76. package/dist/rfc3161/index.d.ts +2 -0
  77. package/dist/rfc3161/index.d.ts.map +1 -0
  78. package/dist/rfc3161/index.js +17 -0
  79. package/dist/rfc3161/index.js.map +1 -0
  80. package/dist/rfc3161/timestamp.d.ts +36 -0
  81. package/dist/rfc3161/timestamp.d.ts.map +1 -0
  82. package/dist/rfc3161/timestamp.js +203 -0
  83. package/dist/rfc3161/timestamp.js.map +1 -0
  84. package/dist/rfc3161/tstinfo.d.ts +13 -0
  85. package/dist/rfc3161/tstinfo.d.ts.map +1 -0
  86. package/dist/rfc3161/tstinfo.js +47 -0
  87. package/dist/rfc3161/tstinfo.js.map +1 -0
  88. package/dist/sigstore.d.ts +33 -0
  89. package/dist/sigstore.d.ts.map +1 -0
  90. package/dist/sigstore.js +531 -0
  91. package/dist/sigstore.js.map +1 -0
  92. package/dist/stream.d.ts +22 -0
  93. package/dist/stream.d.ts.map +1 -0
  94. package/dist/stream.js +114 -0
  95. package/dist/stream.js.map +1 -0
  96. package/dist/timestamp/tsa.d.ts +24 -0
  97. package/dist/timestamp/tsa.d.ts.map +1 -0
  98. package/dist/timestamp/tsa.js +150 -0
  99. package/dist/timestamp/tsa.js.map +1 -0
  100. package/dist/tlog/body.d.ts +8 -0
  101. package/dist/tlog/body.d.ts.map +1 -0
  102. package/dist/tlog/body.js +45 -0
  103. package/dist/tlog/body.js.map +1 -0
  104. package/dist/tlog/checkpoint.d.ts +23 -0
  105. package/dist/tlog/checkpoint.d.ts.map +1 -0
  106. package/dist/tlog/checkpoint.js +187 -0
  107. package/dist/tlog/checkpoint.js.map +1 -0
  108. package/dist/tlog/dsse.d.ts +4 -0
  109. package/dist/tlog/dsse.d.ts.map +1 -0
  110. package/dist/tlog/dsse.js +85 -0
  111. package/dist/tlog/dsse.js.map +1 -0
  112. package/dist/tlog/hashedrekord.d.ts +4 -0
  113. package/dist/tlog/hashedrekord.d.ts.map +1 -0
  114. package/dist/tlog/hashedrekord.js +63 -0
  115. package/dist/tlog/hashedrekord.js.map +1 -0
  116. package/dist/tlog/intoto.d.ts +4 -0
  117. package/dist/tlog/intoto.d.ts.map +1 -0
  118. package/dist/tlog/intoto.js +50 -0
  119. package/dist/tlog/intoto.js.map +1 -0
  120. package/dist/tlog/merkle.d.ts +3 -0
  121. package/dist/tlog/merkle.d.ts.map +1 -0
  122. package/dist/tlog/merkle.js +112 -0
  123. package/dist/tlog/merkle.js.map +1 -0
  124. package/dist/trust/tuf-root.json +1 -0
  125. package/dist/trust/tuf.d.ts +95 -0
  126. package/dist/trust/tuf.d.ts.map +1 -0
  127. package/dist/trust/tuf.js +150 -0
  128. package/dist/trust/tuf.js.map +1 -0
  129. package/dist/x509/cert.d.ts +52 -0
  130. package/dist/x509/cert.d.ts.map +1 -0
  131. package/dist/x509/cert.js +256 -0
  132. package/dist/x509/cert.js.map +1 -0
  133. package/dist/x509/chain.d.ts +20 -0
  134. package/dist/x509/chain.d.ts.map +1 -0
  135. package/dist/x509/chain.js +141 -0
  136. package/dist/x509/chain.js.map +1 -0
  137. package/dist/x509/ext.d.ts +48 -0
  138. package/dist/x509/ext.d.ts.map +1 -0
  139. package/dist/x509/ext.js +164 -0
  140. package/dist/x509/ext.js.map +1 -0
  141. package/dist/x509/index.d.ts +4 -0
  142. package/dist/x509/index.d.ts.map +1 -0
  143. package/dist/x509/index.js +19 -0
  144. package/dist/x509/index.js.map +1 -0
  145. package/dist/x509/sct.d.ts +25 -0
  146. package/dist/x509/sct.d.ts.map +1 -0
  147. package/dist/x509/sct.js +123 -0
  148. package/dist/x509/sct.js.map +1 -0
  149. package/eslint.config.mjs +31 -0
  150. package/package.json +39 -0
  151. package/src/asn1/error.ts +18 -0
  152. package/src/asn1/index.ts +16 -0
  153. package/src/asn1/length.ts +71 -0
  154. package/src/asn1/obj.ts +184 -0
  155. package/src/asn1/parse.ts +146 -0
  156. package/src/asn1/tag.ts +105 -0
  157. package/src/bundle.ts +99 -0
  158. package/src/canonicalize.ts +61 -0
  159. package/src/cli.ts +285 -0
  160. package/src/crypto.ts +310 -0
  161. package/src/dsse.ts +49 -0
  162. package/src/encoding.ts +141 -0
  163. package/src/errors.ts +82 -0
  164. package/src/index.browser.test.ts +219 -0
  165. package/src/index.ts +14 -0
  166. package/src/interfaces.ts +118 -0
  167. package/src/oid.ts +28 -0
  168. package/src/pem.ts +48 -0
  169. package/src/rfc3161/error.ts +16 -0
  170. package/src/rfc3161/index.ts +17 -0
  171. package/src/rfc3161/timestamp.ts +270 -0
  172. package/src/rfc3161/tstinfo.ts +80 -0
  173. package/src/sigstore.ts +728 -0
  174. package/src/stream.ts +141 -0
  175. package/src/timestamp/tsa.ts +205 -0
  176. package/src/tlog/body.ts +65 -0
  177. package/src/tlog/checkpoint.ts +248 -0
  178. package/src/tlog/dsse.ts +147 -0
  179. package/src/tlog/hashedrekord.ts +130 -0
  180. package/src/tlog/intoto.ts +102 -0
  181. package/src/tlog/merkle.ts +152 -0
  182. package/src/trust/README.md +38 -0
  183. package/src/trust/tuf-root.json +1 -0
  184. package/src/trust/tuf.ts +223 -0
  185. package/src/types/tuf-browser.d.ts +13 -0
  186. package/src/x509/cert.ts +319 -0
  187. package/src/x509/chain.ts +212 -0
  188. package/src/x509/ext.ts +212 -0
  189. package/src/x509/index.ts +19 -0
  190. package/src/x509/sct.ts +154 -0
  191. package/tsconfig.json +18 -0
  192. package/vite.config.playwright.ts +26 -0
  193. package/vite.config.ts +18 -0
@@ -0,0 +1,29 @@
1
+ # .github/workflows/conformance.yml
2
+ name: sigstore-conformance
3
+
4
+ on:
5
+ push:
6
+ branches: [ main ]
7
+ pull_request:
8
+ workflow_dispatch:
9
+ workflow_call:
10
+
11
+ jobs:
12
+ conformance:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Install Node
18
+ uses: actions/setup-node@v4
19
+ with:
20
+ node-version: '20'
21
+
22
+ - run: npm ci
23
+ - run: npm run build
24
+ - run: chmod +x dist/cli.js
25
+
26
+ - uses: sigstore/sigstore-conformance@v0.0.21
27
+ with:
28
+ entrypoint: dist/cli.js
29
+ skip-signing: true
@@ -0,0 +1,45 @@
1
+ # .github/workflows/publish.yml
2
+ name: publish
3
+
4
+ on:
5
+ push:
6
+ tags:
7
+ - "v*.*.*"
8
+
9
+ jobs:
10
+ run-conformance:
11
+ uses: ./.github/workflows/conformance.yml
12
+
13
+ publish:
14
+ needs: run-conformance
15
+ runs-on: ubuntu-latest
16
+
17
+ if: startsWith(github.ref, 'refs/tags/v')
18
+
19
+ permissions:
20
+ contents: read
21
+ packages: write
22
+ id-token: write
23
+
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+
27
+ - uses: actions/setup-node@v4
28
+ with:
29
+ node-version: 20
30
+ registry-url: "https://registry.npmjs.org"
31
+
32
+ - run: npm ci
33
+ - run: npm run build
34
+
35
+ - name: Dry-run publish
36
+ env:
37
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
38
+ run: npm publish --dry-run
39
+
40
+ - name: Publish to npm
41
+ env:
42
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
43
+ run: npm publish --access public
44
+
45
+
package/README.md ADDED
@@ -0,0 +1,10 @@
1
+ # Minimal Browser-Compatible Implementation of a Sgistore verifier
2
+
3
+ [![Conformance](https://github.com/freedomofpress/sigstore-browser/actions/workflows/conformance.yml/badge.svg)](https://github.com/freedomofpress/sigstore-browser/actions/workflows/conformance.yml)
4
+
5
+ A minimal TypeScript implementation of [Sigstore](https://sigstore.dev/) specification for verification, optimized for browser compatibility.
6
+
7
+ This is a lightweight alternative to [sigstore-js](github.com/sigstore/sigstore-js) that focuses on verification functionality needed for secure software updates in browser environments.
8
+
9
+ > [!CAUTION]
10
+ > This library has not received an independent security audit. Maintenance is performed by volunteers, and the project is not officially supported or endorsed by the Freedom of the Press Foundation.
@@ -0,0 +1,5 @@
1
+ export declare class ASN1ParseError extends Error {
2
+ }
3
+ export declare class ASN1TypeError extends Error {
4
+ }
5
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/asn1/error.ts"],"names":[],"mappings":"AAeA,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAE5C,qBAAa,aAAc,SAAQ,KAAK;CAAG"}
@@ -0,0 +1,20 @@
1
+ /*
2
+ Copyright 2023 The Sigstore Authors.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ export class ASN1ParseError extends Error {
17
+ }
18
+ export class ASN1TypeError extends Error {
19
+ }
20
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/asn1/error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;EAcE;AACF,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAE5C,MAAM,OAAO,aAAc,SAAQ,KAAK;CAAG"}
@@ -0,0 +1,2 @@
1
+ export { ASN1Obj } from "./obj.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/asn1/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,17 @@
1
+ /*
2
+ Copyright 2023 The Sigstore Authors.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ export { ASN1Obj } from "./obj.js";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/asn1/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;EAcE;AACF,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { ByteStream } from "../stream.js";
2
+ export declare function decodeLength(stream: ByteStream): number;
3
+ export declare function encodeLength(len: number): Uint8Array;
4
+ //# sourceMappingURL=length.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"length.d.ts","sourceRoot":"","sources":["../../src/asn1/length.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK1C,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA8BvD;AAGD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAgBpD"}
@@ -0,0 +1,59 @@
1
+ /*
2
+ Copyright 2023 The Sigstore Authors.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ import { ASN1ParseError } from "./error.js";
17
+ // Decodes the length of a DER-encoded ANS.1 element from the supplied stream.
18
+ // https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-encoded-length-and-value-bytes
19
+ export function decodeLength(stream) {
20
+ const buf = stream.getUint8();
21
+ // If the most significant bit is UNSET the length is just the value of the
22
+ // byte.
23
+ if ((buf & 0x80) === 0x00) {
24
+ return buf;
25
+ }
26
+ // Otherwise, the lower 7 bits of the first byte indicate the number of bytes
27
+ // that follow to encode the length.
28
+ const byteCount = buf & 0x7f;
29
+ // Ensure the encoded length can safely fit in a JS number.
30
+ if (byteCount > 6) {
31
+ throw new ASN1ParseError("length exceeds 6 byte limit");
32
+ }
33
+ // Iterate over the bytes that encode the length.
34
+ let len = 0;
35
+ for (let i = 0; i < byteCount; i++) {
36
+ len = len * 256 + stream.getUint8();
37
+ }
38
+ // This is a valid ASN.1 length encoding, but we don't support it.
39
+ if (len === 0) {
40
+ throw new ASN1ParseError("indefinite length encoding not supported");
41
+ }
42
+ return len;
43
+ }
44
+ // Translates the supplied value to a DER-encoded length.
45
+ export function encodeLength(len) {
46
+ if (len < 128) {
47
+ return new Uint8Array([len]);
48
+ }
49
+ // Bitwise operations on large numbers are not supported in JS, so we need to
50
+ // use BigInts.
51
+ let val = BigInt(len);
52
+ const bytes = [];
53
+ while (val > 0n) {
54
+ bytes.unshift(Number(val & 255n));
55
+ val = val >> 8n;
56
+ }
57
+ return new Uint8Array([0x80 | bytes.length, ...bytes]);
58
+ }
59
+ //# sourceMappingURL=length.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"length.js","sourceRoot":"","sources":["../../src/asn1/length.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;EAcE;AAGF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,8EAA8E;AAC9E,qGAAqG;AACrG,MAAM,UAAU,YAAY,CAAC,MAAkB;IAC7C,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAE9B,2EAA2E;IAC3E,QAAQ;IACR,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,6EAA6E;IAC7E,oCAAoC;IACpC,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC;IAE7B,2DAA2D;IAC3D,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,cAAc,CAAC,6BAA6B,CAAC,CAAC;IAC1D,CAAC;IAED,iDAAiD;IACjD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IACtC,CAAC;IAED,kEAAkE;IAClE,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACd,MAAM,IAAI,cAAc,CAAC,0CAA0C,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACd,OAAO,IAAI,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,6EAA6E;IAC7E,eAAe;IACf,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,MAAM,KAAK,GAAG,EAAE,CAAC;IAEjB,OAAO,GAAG,GAAG,EAAE,EAAE,CAAC;QAChB,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC;QAClC,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;IAClB,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { ASN1Tag } from "./tag.js";
2
+ export declare class ASN1Obj {
3
+ readonly tag: ASN1Tag;
4
+ readonly subs: ASN1Obj[];
5
+ readonly value: Uint8Array;
6
+ constructor(tag: ASN1Tag, value: Uint8Array, subs: ASN1Obj[]);
7
+ static parseBuffer(buf: Uint8Array): ASN1Obj;
8
+ toDER(): Uint8Array;
9
+ toBoolean(): boolean;
10
+ toInteger(): bigint;
11
+ toOID(): string;
12
+ toDate(): Date;
13
+ toBitString(): number[];
14
+ }
15
+ //# sourceMappingURL=obj.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obj.d.ts","sourceRoot":"","sources":["../../src/asn1/obj.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,qBAAa,OAAO;IAClB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;gBAEf,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE;WAO9C,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAI5C,KAAK,IAAI,UAAU;IA2BnB,SAAS,IAAI,OAAO;IAUpB,SAAS,IAAI,MAAM;IAUnB,KAAK,IAAI,MAAM;IAUf,MAAM,IAAI,IAAI;IAcd,WAAW,IAAI,MAAM,EAAE;CAO/B"}
@@ -0,0 +1,153 @@
1
+ /*
2
+ Copyright 2023 The Sigstore Authors.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ import { toArrayBuffer } from "../encoding.js";
17
+ import { ByteStream } from "../stream.js";
18
+ import { ASN1ParseError, ASN1TypeError } from "./error.js";
19
+ import { decodeLength, encodeLength } from "./length.js";
20
+ import { parseBitString, parseBoolean, parseInteger, parseOID, parseTime, } from "./parse.js";
21
+ import { ASN1Tag } from "./tag.js";
22
+ export class ASN1Obj {
23
+ tag;
24
+ subs;
25
+ value;
26
+ constructor(tag, value, subs) {
27
+ this.tag = tag;
28
+ this.value = value;
29
+ this.subs = subs;
30
+ }
31
+ // Constructs an ASN.1 object from a Buffer of DER-encoded bytes.
32
+ static parseBuffer(buf) {
33
+ return parseStream(new ByteStream(toArrayBuffer(buf)));
34
+ }
35
+ toDER() {
36
+ const valueStream = new ByteStream();
37
+ if (this.subs.length > 0) {
38
+ for (const sub of this.subs) {
39
+ valueStream.appendView(sub.toDER());
40
+ }
41
+ }
42
+ else {
43
+ valueStream.appendView(this.value);
44
+ }
45
+ const value = valueStream.buffer;
46
+ // Concat tag/length/value
47
+ const obj = new ByteStream();
48
+ obj.appendChar(this.tag.toDER());
49
+ obj.appendView(encodeLength(value.length));
50
+ obj.appendView(value);
51
+ return obj.buffer;
52
+ }
53
+ /////////////////////////////////////////////////////////////////////////////
54
+ // Convenience methods for parsing ASN.1 primitives into JS types
55
+ // Returns the ASN.1 object's value as a boolean. Throws an error if the
56
+ // object is not a boolean.
57
+ toBoolean() {
58
+ if (!this.tag.isBoolean()) {
59
+ throw new ASN1TypeError("not a boolean");
60
+ }
61
+ return parseBoolean(this.value);
62
+ }
63
+ // Returns the ASN.1 object's value as a BigInt. Throws an error if the
64
+ // object is not an integer.
65
+ toInteger() {
66
+ if (!this.tag.isInteger()) {
67
+ throw new ASN1TypeError("not an integer");
68
+ }
69
+ return parseInteger(this.value);
70
+ }
71
+ // Returns the ASN.1 object's value as an OID string. Throws an error if the
72
+ // object is not an OID.
73
+ toOID() {
74
+ if (!this.tag.isOID()) {
75
+ throw new ASN1TypeError("not an OID");
76
+ }
77
+ return parseOID(this.value);
78
+ }
79
+ // Returns the ASN.1 object's value as a Date. Throws an error if the object
80
+ // is not either a UTCTime or a GeneralizedTime.
81
+ toDate() {
82
+ switch (true) {
83
+ case this.tag.isUTCTime():
84
+ return parseTime(this.value, true);
85
+ case this.tag.isGeneralizedTime():
86
+ return parseTime(this.value, false);
87
+ default:
88
+ throw new ASN1TypeError("not a date");
89
+ }
90
+ }
91
+ // Returns the ASN.1 object's value as a number[] where each number is the
92
+ // value of a bit in the bit string. Throws an error if the object is not a
93
+ // bit string.
94
+ toBitString() {
95
+ if (!this.tag.isBitString()) {
96
+ throw new ASN1TypeError("not a bit string");
97
+ }
98
+ return parseBitString(this.value);
99
+ }
100
+ }
101
+ /////////////////////////////////////////////////////////////////////////////
102
+ // Internal stream parsing functions
103
+ function parseStream(stream) {
104
+ // Parse tag, length, and value from stream
105
+ const tag = new ASN1Tag(stream.getUint8());
106
+ const len = decodeLength(stream);
107
+ const value = stream.slice(stream.position, len);
108
+ const start = stream.position;
109
+ let subs = [];
110
+ // If the object is constructed, parse its children. Sometimes, children
111
+ // are embedded in OCTESTRING objects, so we need to check those
112
+ // for children as well.
113
+ if (tag.constructed) {
114
+ subs = collectSubs(stream, len);
115
+ }
116
+ else if (tag.isOctetString()) {
117
+ // Attempt to parse children of OCTETSTRING objects. If anything fails,
118
+ // assume the object is not constructed and treat as primitive.
119
+ try {
120
+ subs = collectSubs(stream, len);
121
+ }
122
+ catch {
123
+ // Fail silently and treat as primitive
124
+ }
125
+ }
126
+ // If there are no children, move stream cursor to the end of the object
127
+ if (subs.length === 0) {
128
+ stream.seek(start + len);
129
+ }
130
+ return new ASN1Obj(tag, value, subs);
131
+ }
132
+ function collectSubs(stream, len) {
133
+ // Calculate end of object content
134
+ const end = stream.position + len;
135
+ // Make sure there are enough bytes left in the stream. This should never
136
+ // happen, cause it'll get caught when the stream is sliced in parseStream.
137
+ // Leaving as an extra check just in case.
138
+ /* istanbul ignore if */
139
+ if (end > stream.length) {
140
+ throw new ASN1ParseError("invalid length");
141
+ }
142
+ // Parse all children
143
+ const subs = [];
144
+ while (stream.position < end) {
145
+ subs.push(parseStream(stream));
146
+ }
147
+ // When we're done parsing children, we should be at the end of the object
148
+ if (stream.position !== end) {
149
+ throw new ASN1ParseError("invalid length");
150
+ }
151
+ return subs;
152
+ }
153
+ //# sourceMappingURL=obj.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obj.js","sourceRoot":"","sources":["../../src/asn1/obj.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function parseInteger(buf: Uint8Array): bigint;
2
+ export declare function parseStringASCII(buf: Uint8Array): string;
3
+ export declare function parseTime(buf: Uint8Array, shortYear: boolean): Date;
4
+ export declare function parseOID(buf: Uint8Array): string;
5
+ export declare function parseBoolean(buf: Uint8Array): boolean;
6
+ export declare function parseBitString(buf: Uint8Array): number[];
7
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/asn1/parse.ts"],"names":[],"mappings":"AAyBA,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CA2BpD;AAID,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAExD;AAID,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CAqBnE;AAID,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CA0BhD;AAID,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAErD;AAID,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,EAAE,CAsBxD"}
@@ -0,0 +1,118 @@
1
+ /*
2
+ Copyright 2023 The Sigstore Authors.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ import { Uint8ArrayToString } from "../encoding.js";
17
+ const RE_TIME_SHORT_YEAR = /^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\.\d{3})?Z$/;
18
+ const RE_TIME_LONG_YEAR = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\.\d{3})?Z$/;
19
+ // Parse a BigInt from the DER-encoded buffer
20
+ // https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-integer
21
+ export function parseInteger(buf) {
22
+ let pos = 0;
23
+ const end = buf.length;
24
+ let val = buf[pos];
25
+ const neg = val > 0x7f;
26
+ // Consume any padding bytes
27
+ const pad = neg ? 0xff : 0x00;
28
+ while (val == pad && ++pos < end) {
29
+ val = buf[pos];
30
+ }
31
+ // Calculate remaining bytes to read
32
+ const len = end - pos;
33
+ if (len === 0)
34
+ return BigInt(neg ? -1 : 0);
35
+ // Handle two's complement for negative numbers
36
+ val = neg ? val - 256 : val;
37
+ // Parse remaining bytes
38
+ let n = BigInt(val);
39
+ for (let i = pos + 1; i < end; ++i) {
40
+ n = n * BigInt(256) + BigInt(buf[i]);
41
+ }
42
+ return n;
43
+ }
44
+ // Parse an ASCII string from the DER-encoded buffer
45
+ // https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-basic-types#boolean
46
+ export function parseStringASCII(buf) {
47
+ return Uint8ArrayToString(buf);
48
+ }
49
+ // Parse a Date from the DER-encoded buffer
50
+ // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.5.1
51
+ export function parseTime(buf, shortYear) {
52
+ const timeStr = parseStringASCII(buf);
53
+ // Parse the time string into matches - captured groups start at index 1
54
+ const m = shortYear
55
+ ? RE_TIME_SHORT_YEAR.exec(timeStr)
56
+ : RE_TIME_LONG_YEAR.exec(timeStr);
57
+ if (!m) {
58
+ throw new Error("invalid time");
59
+ }
60
+ // Translate dates with a 2-digit year to 4 digits per the spec
61
+ if (shortYear) {
62
+ let year = Number(m[1]);
63
+ year += year >= 50 ? 1900 : 2000;
64
+ m[1] = year.toString();
65
+ }
66
+ // Translate to ISO8601 format and parse
67
+ return new Date(`${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}Z`);
68
+ }
69
+ // Parse an OID from the DER-encoded buffer
70
+ // https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-object-identifier
71
+ export function parseOID(buf) {
72
+ let pos = 0;
73
+ const end = buf.length;
74
+ // Consume first byte which encodes the first two OID components
75
+ let n = buf[pos++];
76
+ const first = Math.floor(n / 40);
77
+ const second = n % 40;
78
+ let oid = `${first}.${second}`;
79
+ // Consume remaining bytes
80
+ let val = 0;
81
+ for (; pos < end; ++pos) {
82
+ n = buf[pos];
83
+ val = (val << 7) + (n & 0x7f);
84
+ // If the left-most bit is NOT set, then this is the last byte in the
85
+ // sequence and we can add the value to the OID and reset the accumulator
86
+ if ((n & 0x80) === 0) {
87
+ oid += `.${val}`;
88
+ val = 0;
89
+ }
90
+ }
91
+ return oid;
92
+ }
93
+ // Parse a boolean from the DER-encoded buffer
94
+ // https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-basic-types#boolean
95
+ export function parseBoolean(buf) {
96
+ return buf[0] !== 0;
97
+ }
98
+ // Parse a bit string from the DER-encoded buffer
99
+ // https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-bit-string
100
+ export function parseBitString(buf) {
101
+ // First byte tell us how many unused bits are in the last byte
102
+ const unused = buf[0];
103
+ const start = 1;
104
+ const end = buf.length;
105
+ const bits = [];
106
+ for (let i = start; i < end; ++i) {
107
+ const byte = buf[i];
108
+ // The skip value is only used for the last byte
109
+ const skip = i === end - 1 ? unused : 0;
110
+ // Iterate over each bit in the byte (most significant first)
111
+ for (let j = 7; j >= skip; --j) {
112
+ // Read the bit and add it to the bit string
113
+ bits.push((byte >> j) & 0x01);
114
+ }
115
+ }
116
+ return bits;
117
+ }
118
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/asn1/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export declare class ASN1Tag {
2
+ readonly number: number;
3
+ readonly constructed: boolean;
4
+ readonly class: number;
5
+ constructor(enc: number);
6
+ isUniversal(): boolean;
7
+ isContextSpecific(num?: number): boolean;
8
+ isBoolean(): boolean;
9
+ isInteger(): boolean;
10
+ isBitString(): boolean;
11
+ isOctetString(): boolean;
12
+ isOID(): boolean;
13
+ isUTCTime(): boolean;
14
+ isGeneralizedTime(): boolean;
15
+ toDER(): number;
16
+ }
17
+ //# sourceMappingURL=tag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../src/asn1/tag.ts"],"names":[],"mappings":"AAsCA,qBAAa,OAAO;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,GAAG,EAAE,MAAM;IAmBhB,WAAW,IAAI,OAAO;IAItB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO;IAKxC,SAAS,IAAI,OAAO;IAIpB,SAAS,IAAI,OAAO;IAIpB,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,OAAO;IAIxB,KAAK,IAAI,OAAO;IAMhB,SAAS,IAAI,OAAO;IAIpB,iBAAiB,IAAI,OAAO;IAI5B,KAAK,IAAI,MAAM;CAGvB"}
@@ -0,0 +1,86 @@
1
+ /*
2
+ Copyright 2023 The Sigstore Authors.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ import { ASN1ParseError } from "./error.js";
17
+ const UNIVERSAL_TAG = {
18
+ BOOLEAN: 0x01,
19
+ INTEGER: 0x02,
20
+ BIT_STRING: 0x03,
21
+ OCTET_STRING: 0x04,
22
+ OBJECT_IDENTIFIER: 0x06,
23
+ SEQUENCE: 0x10,
24
+ SET: 0x11,
25
+ PRINTABLE_STRING: 0x13,
26
+ UTC_TIME: 0x17,
27
+ GENERALIZED_TIME: 0x18,
28
+ };
29
+ const TAG_CLASS = {
30
+ UNIVERSAL: 0x00,
31
+ APPLICATION: 0x01,
32
+ CONTEXT_SPECIFIC: 0x02,
33
+ PRIVATE: 0x03,
34
+ };
35
+ // https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-encoded-tag-bytes
36
+ export class ASN1Tag {
37
+ number;
38
+ constructed;
39
+ class;
40
+ constructor(enc) {
41
+ // Bits 0 through 4 are the tag number
42
+ this.number = enc & 0x1f;
43
+ // Bit 5 is the constructed bit
44
+ this.constructed = (enc & 0x20) === 0x20;
45
+ // Bit 6 & 7 are the class
46
+ this.class = enc >> 6;
47
+ if (this.number === 0x1f) {
48
+ throw new ASN1ParseError("long form tags not supported");
49
+ }
50
+ if (this.class === TAG_CLASS.UNIVERSAL && this.number === 0x00) {
51
+ throw new ASN1ParseError("unsupported tag 0x00");
52
+ }
53
+ }
54
+ isUniversal() {
55
+ return this.class === TAG_CLASS.UNIVERSAL;
56
+ }
57
+ isContextSpecific(num) {
58
+ const res = this.class === TAG_CLASS.CONTEXT_SPECIFIC;
59
+ return num !== undefined ? res && this.number === num : res;
60
+ }
61
+ isBoolean() {
62
+ return this.isUniversal() && this.number === UNIVERSAL_TAG.BOOLEAN;
63
+ }
64
+ isInteger() {
65
+ return this.isUniversal() && this.number === UNIVERSAL_TAG.INTEGER;
66
+ }
67
+ isBitString() {
68
+ return this.isUniversal() && this.number === UNIVERSAL_TAG.BIT_STRING;
69
+ }
70
+ isOctetString() {
71
+ return this.isUniversal() && this.number === UNIVERSAL_TAG.OCTET_STRING;
72
+ }
73
+ isOID() {
74
+ return (this.isUniversal() && this.number === UNIVERSAL_TAG.OBJECT_IDENTIFIER);
75
+ }
76
+ isUTCTime() {
77
+ return this.isUniversal() && this.number === UNIVERSAL_TAG.UTC_TIME;
78
+ }
79
+ isGeneralizedTime() {
80
+ return this.isUniversal() && this.number === UNIVERSAL_TAG.GENERALIZED_TIME;
81
+ }
82
+ toDER() {
83
+ return this.number | (this.constructed ? 0x20 : 0x00) | (this.class << 6);
84
+ }
85
+ }
86
+ //# sourceMappingURL=tag.js.map