@simplewebauthn/server 9.0.2 → 9.0.3

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/esm/deps.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type { AttestationConveyancePreference, AuthenticationExtensionsClientInputs, AuthenticationResponseJSON, AuthenticatorDevice, AuthenticatorSelectionCriteria, Base64URLString, COSEAlgorithmIdentifier, CredentialDeviceType, Crypto, PublicKeyCredentialCreationOptionsJSON, PublicKeyCredentialDescriptorFuture, PublicKeyCredentialParameters, PublicKeyCredentialRequestOptionsJSON, RegistrationResponseJSON, UserVerificationRequirement, } from '@simplewebauthn/types';
2
- export * as cborx from 'cbor-x/index-no-eval';
2
+ export * as tinyCbor from '@levischuck/tiny-cbor';
3
3
  export { default as base64 } from '@hexagon/base64';
4
4
  export { fetch as crossFetch } from 'cross-fetch';
5
5
  export { AsnParser, AsnSerializer } from '@peculiar/asn1-schema';
package/esm/deps.js CHANGED
@@ -1,5 +1,5 @@
1
- // cbor (a.k.a. cbor-x in Node land)
2
- export * as cborx from 'cbor-x/index-no-eval';
1
+ // tiny_cbor (a.k.a. tiny-cbor in Node land)
2
+ export * as tinyCbor from '@levischuck/tiny-cbor';
3
3
  // b64 (a.k.a. @hexagon/base64 in Node land)
4
4
  export { default as base64 } from '@hexagon/base64';
5
5
  // cross-fetch
@@ -1,3 +1,14 @@
1
+ import { tinyCbor } from '../../deps.js';
2
+ /**
3
+ * Whatever CBOR encoder is used should keep CBOR data the same length when data is re-encoded
4
+ *
5
+ * MOST CRITICALLY, this means the following needs to be true of whatever CBOR library we use:
6
+ * - CBOR Map type values MUST decode to JavaScript Maps
7
+ * - CBOR tag 64 (uint8 Typed Array) MUST NOT be used when encoding Uint8Arrays back to CBOR
8
+ *
9
+ * So long as these requirements are maintained, then CBOR sequences can be encoded and decoded
10
+ * freely while maintaining their lengths for the most accurate pointer movement across them.
11
+ */
1
12
  /**
2
13
  * Decode and return the first item in a sequence of CBOR-encoded values
3
14
  *
@@ -9,4 +20,4 @@ export declare function decodeFirst<Type>(input: Uint8Array): Type;
9
20
  /**
10
21
  * Encode data to CBOR
11
22
  */
12
- export declare function encode(input: unknown): Uint8Array;
23
+ export declare function encode(input: tinyCbor.CBORType): Uint8Array;
@@ -1,6 +1,6 @@
1
- import { cborx } from '../../deps.js';
1
+ import { tinyCbor } from '../../deps.js';
2
2
  /**
3
- * This encoder should keep CBOR data the same length when data is re-encoded
3
+ * Whatever CBOR encoder is used should keep CBOR data the same length when data is re-encoded
4
4
  *
5
5
  * MOST CRITICALLY, this means the following needs to be true of whatever CBOR library we use:
6
6
  * - CBOR Map type values MUST decode to JavaScript Maps
@@ -9,10 +9,6 @@ import { cborx } from '../../deps.js';
9
9
  * So long as these requirements are maintained, then CBOR sequences can be encoded and decoded
10
10
  * freely while maintaining their lengths for the most accurate pointer movement across them.
11
11
  */
12
- const encoder = new cborx.Encoder({
13
- mapsAsObjects: false,
14
- tagUint8Array: false,
15
- });
16
12
  /**
17
13
  * Decode and return the first item in a sequence of CBOR-encoded values
18
14
  *
@@ -23,16 +19,7 @@ const encoder = new cborx.Encoder({
23
19
  export function decodeFirst(input) {
24
20
  // Make a copy so we don't mutate the original
25
21
  const _input = new Uint8Array(input);
26
- const decoded = encoder.decodeMultiple(_input);
27
- if (decoded === undefined) {
28
- throw new Error('CBOR input data was empty');
29
- }
30
- /**
31
- * Typing on `decoded` is `void | []` which causes TypeScript to think that it's an empty array,
32
- * and thus you can't destructure it. I'm ignoring that because the code works fine in JS, and
33
- * so this should be a valid operation.
34
- */
35
- // @ts-ignore 2493
22
+ const decoded = tinyCbor.decodePartialCBOR(_input, 0);
36
23
  const [first] = decoded;
37
24
  return first;
38
25
  }
@@ -40,5 +27,5 @@ export function decodeFirst(input) {
40
27
  * Encode data to CBOR
41
28
  */
42
29
  export function encode(input) {
43
- return encoder.encode(input);
30
+ return tinyCbor.encodeCBOR(input);
44
31
  }
@@ -54,7 +54,16 @@ export function parseAuthenticatorData(authData) {
54
54
  }
55
55
  // Decode the next CBOR item in the buffer, then re-encode it back to a Buffer
56
56
  const firstDecoded = isoCBOR.decodeFirst(authData.slice(pointer));
57
- const firstEncoded = Uint8Array.from(isoCBOR.encode(firstDecoded));
57
+ const firstEncoded = Uint8Array.from(
58
+ /**
59
+ * Casting to `Map` via `as unknown` here because TS doesn't make it possible to define Maps
60
+ * with discrete keys and properties with known types per pair, and CBOR libs typically parse
61
+ * CBOR Major Type 5 to `Map` because you can have numbers for keys. A `COSEPublicKey` can be
62
+ * generalized as "a Map with numbers for keys and either numbers or bytes for values" though.
63
+ * If this presumption falls apart then other parts of verification later on will fail so we
64
+ * should be safe doing this here.
65
+ */
66
+ isoCBOR.encode(firstDecoded));
58
67
  if (foundBadCBOR) {
59
68
  // Restore the bit we changed so that `authData` is the same as it came in and won't break
60
69
  // signature verification.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "module": "./esm/index.js",
3
3
  "main": "./script/index.js",
4
4
  "name": "@simplewebauthn/server",
5
- "version": "9.0.2",
5
+ "version": "9.0.3",
6
6
  "description": "SimpleWebAuthn for Servers",
7
7
  "license": "MIT",
8
8
  "author": "Matthew Miller <matthew@millerti.me>",
@@ -50,13 +50,13 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@hexagon/base64": "^1.1.27",
53
+ "@levischuck/tiny-cbor": "^0.2.2",
53
54
  "@peculiar/asn1-android": "^2.3.10",
54
55
  "@peculiar/asn1-ecc": "^2.3.8",
55
56
  "@peculiar/asn1-rsa": "^2.3.8",
56
57
  "@peculiar/asn1-schema": "^2.3.8",
57
58
  "@peculiar/asn1-x509": "^2.3.8",
58
59
  "@simplewebauthn/types": "^9.0.1",
59
- "cbor-x": "^1.5.2",
60
60
  "cross-fetch": "^4.0.0"
61
61
  },
62
62
  "devDependencies": {
package/script/deps.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type { AttestationConveyancePreference, AuthenticationExtensionsClientInputs, AuthenticationResponseJSON, AuthenticatorDevice, AuthenticatorSelectionCriteria, Base64URLString, COSEAlgorithmIdentifier, CredentialDeviceType, Crypto, PublicKeyCredentialCreationOptionsJSON, PublicKeyCredentialDescriptorFuture, PublicKeyCredentialParameters, PublicKeyCredentialRequestOptionsJSON, RegistrationResponseJSON, UserVerificationRequirement, } from '@simplewebauthn/types';
2
- export * as cborx from 'cbor-x/index-no-eval';
2
+ export * as tinyCbor from '@levischuck/tiny-cbor';
3
3
  export { default as base64 } from '@hexagon/base64';
4
4
  export { fetch as crossFetch } from 'cross-fetch';
5
5
  export { AsnParser, AsnSerializer } from '@peculiar/asn1-schema';
package/script/deps.js CHANGED
@@ -26,9 +26,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.KeyDescription = exports.id_ce_keyDescription = exports.RSAPublicKey = exports.id_secp384r1 = exports.id_secp256r1 = exports.id_ecPublicKey = exports.ECParameters = exports.ECDSASigValue = exports.SubjectKeyIdentifier = exports.SubjectAlternativeName = exports.Name = exports.id_ce_subjectKeyIdentifier = exports.id_ce_subjectAltName = exports.id_ce_extKeyUsage = exports.id_ce_cRLDistributionPoints = exports.id_ce_basicConstraints = exports.id_ce_authorityKeyIdentifier = exports.ExtendedKeyUsage = exports.CRLDistributionPoints = exports.CertificateList = exports.Certificate = exports.BasicConstraints = exports.AuthorityKeyIdentifier = exports.AsnSerializer = exports.AsnParser = exports.crossFetch = exports.base64 = exports.cborx = void 0;
30
- // cbor (a.k.a. cbor-x in Node land)
31
- exports.cborx = __importStar(require("cbor-x/index-no-eval"));
29
+ exports.KeyDescription = exports.id_ce_keyDescription = exports.RSAPublicKey = exports.id_secp384r1 = exports.id_secp256r1 = exports.id_ecPublicKey = exports.ECParameters = exports.ECDSASigValue = exports.SubjectKeyIdentifier = exports.SubjectAlternativeName = exports.Name = exports.id_ce_subjectKeyIdentifier = exports.id_ce_subjectAltName = exports.id_ce_extKeyUsage = exports.id_ce_cRLDistributionPoints = exports.id_ce_basicConstraints = exports.id_ce_authorityKeyIdentifier = exports.ExtendedKeyUsage = exports.CRLDistributionPoints = exports.CertificateList = exports.Certificate = exports.BasicConstraints = exports.AuthorityKeyIdentifier = exports.AsnSerializer = exports.AsnParser = exports.crossFetch = exports.base64 = exports.tinyCbor = void 0;
30
+ // tiny_cbor (a.k.a. tiny-cbor in Node land)
31
+ exports.tinyCbor = __importStar(require("@levischuck/tiny-cbor"));
32
32
  // b64 (a.k.a. @hexagon/base64 in Node land)
33
33
  var base64_1 = require("@hexagon/base64");
34
34
  Object.defineProperty(exports, "base64", { enumerable: true, get: function () { return __importDefault(base64_1).default; } });
@@ -1,3 +1,14 @@
1
+ import { tinyCbor } from '../../deps.js';
2
+ /**
3
+ * Whatever CBOR encoder is used should keep CBOR data the same length when data is re-encoded
4
+ *
5
+ * MOST CRITICALLY, this means the following needs to be true of whatever CBOR library we use:
6
+ * - CBOR Map type values MUST decode to JavaScript Maps
7
+ * - CBOR tag 64 (uint8 Typed Array) MUST NOT be used when encoding Uint8Arrays back to CBOR
8
+ *
9
+ * So long as these requirements are maintained, then CBOR sequences can be encoded and decoded
10
+ * freely while maintaining their lengths for the most accurate pointer movement across them.
11
+ */
1
12
  /**
2
13
  * Decode and return the first item in a sequence of CBOR-encoded values
3
14
  *
@@ -9,4 +20,4 @@ export declare function decodeFirst<Type>(input: Uint8Array): Type;
9
20
  /**
10
21
  * Encode data to CBOR
11
22
  */
12
- export declare function encode(input: unknown): Uint8Array;
23
+ export declare function encode(input: tinyCbor.CBORType): Uint8Array;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.encode = exports.decodeFirst = void 0;
4
4
  const deps_js_1 = require("../../deps.js");
5
5
  /**
6
- * This encoder should keep CBOR data the same length when data is re-encoded
6
+ * Whatever CBOR encoder is used should keep CBOR data the same length when data is re-encoded
7
7
  *
8
8
  * MOST CRITICALLY, this means the following needs to be true of whatever CBOR library we use:
9
9
  * - CBOR Map type values MUST decode to JavaScript Maps
@@ -12,10 +12,6 @@ const deps_js_1 = require("../../deps.js");
12
12
  * So long as these requirements are maintained, then CBOR sequences can be encoded and decoded
13
13
  * freely while maintaining their lengths for the most accurate pointer movement across them.
14
14
  */
15
- const encoder = new deps_js_1.cborx.Encoder({
16
- mapsAsObjects: false,
17
- tagUint8Array: false,
18
- });
19
15
  /**
20
16
  * Decode and return the first item in a sequence of CBOR-encoded values
21
17
  *
@@ -26,16 +22,7 @@ const encoder = new deps_js_1.cborx.Encoder({
26
22
  function decodeFirst(input) {
27
23
  // Make a copy so we don't mutate the original
28
24
  const _input = new Uint8Array(input);
29
- const decoded = encoder.decodeMultiple(_input);
30
- if (decoded === undefined) {
31
- throw new Error('CBOR input data was empty');
32
- }
33
- /**
34
- * Typing on `decoded` is `void | []` which causes TypeScript to think that it's an empty array,
35
- * and thus you can't destructure it. I'm ignoring that because the code works fine in JS, and
36
- * so this should be a valid operation.
37
- */
38
- // @ts-ignore 2493
25
+ const decoded = deps_js_1.tinyCbor.decodePartialCBOR(_input, 0);
39
26
  const [first] = decoded;
40
27
  return first;
41
28
  }
@@ -44,6 +31,6 @@ exports.decodeFirst = decodeFirst;
44
31
  * Encode data to CBOR
45
32
  */
46
33
  function encode(input) {
47
- return encoder.encode(input);
34
+ return deps_js_1.tinyCbor.encodeCBOR(input);
48
35
  }
49
36
  exports.encode = encode;
@@ -57,7 +57,16 @@ function parseAuthenticatorData(authData) {
57
57
  }
58
58
  // Decode the next CBOR item in the buffer, then re-encode it back to a Buffer
59
59
  const firstDecoded = index_js_1.isoCBOR.decodeFirst(authData.slice(pointer));
60
- const firstEncoded = Uint8Array.from(index_js_1.isoCBOR.encode(firstDecoded));
60
+ const firstEncoded = Uint8Array.from(
61
+ /**
62
+ * Casting to `Map` via `as unknown` here because TS doesn't make it possible to define Maps
63
+ * with discrete keys and properties with known types per pair, and CBOR libs typically parse
64
+ * CBOR Major Type 5 to `Map` because you can have numbers for keys. A `COSEPublicKey` can be
65
+ * generalized as "a Map with numbers for keys and either numbers or bytes for values" though.
66
+ * If this presumption falls apart then other parts of verification later on will fail so we
67
+ * should be safe doing this here.
68
+ */
69
+ index_js_1.isoCBOR.encode(firstDecoded));
61
70
  if (foundBadCBOR) {
62
71
  // Restore the bit we changed so that `authData` is the same as it came in and won't break
63
72
  // signature verification.