@motebit/crypto-android-keystore 1.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.
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Pinned Google Hardware Attestation root certificates.
3
+ *
4
+ * Every `platform: "android_keystore"` hardware-attestation claim must
5
+ * chain to one of the root CAs listed here. Pinning is the
6
+ * self-attesting contract — a verifier that dynamically fetched
7
+ * Google's attestation roots could not be reproduced by a third-party
8
+ * audit. By committing the exact bytes of the CAs we accept, anyone
9
+ * can audit this file, pin the same bytes in their own verifier, and
10
+ * reach the same yes/no answer.
11
+ *
12
+ * Two roots are pinned, covering the in-flight rotation Google
13
+ * announced for early 2026:
14
+ *
15
+ * - **Legacy RSA-4096 root** — covers all factory-provisioned
16
+ * Android devices since 2014. Cannot be rotated on those devices,
17
+ * so it stays valid indefinitely for that fleet.
18
+ *
19
+ * - **ECDSA P-384 root** — issued 2025-07-17. Covers RKP-provisioned
20
+ * devices (Remote Key Provisioning, the modern flow). Devices
21
+ * began emitting chains rooted here on 2026-02-01; switched
22
+ * exclusively after 2026-04-10.
23
+ *
24
+ * Verifiers MUST pin both. Source of truth: `roots.json` in the
25
+ * `android/keyattestation` repository (Google's canonical Kotlin
26
+ * reference verifier), mirrored from Android's published attestation
27
+ * trust anchor list.
28
+ *
29
+ * Operator note — runtime fetching is forbidden. The Android docs are
30
+ * explicit: "Don't query for roots at runtime. Use formal
31
+ * configuration updates." A new Google root cert lands here as an
32
+ * additive constant, never via dynamic fetch — any other path
33
+ * sacrifices the sovereign-verifier story.
34
+ *
35
+ * Each constant ships its real Google-published bytes. Each comment
36
+ * names: source URL, subject DN, SHA-256 fingerprint, public-key
37
+ * algorithm, validity window. The fingerprint is the audit anchor — a
38
+ * third party that fetches the same source and computes its own
39
+ * SHA-256 should reach the byte-identical value below.
40
+ */
41
+ /**
42
+ * Google Hardware Attestation Root — RSA-4096 (legacy / factory-provisioned).
43
+ *
44
+ * Source: https://github.com/android/keyattestation (roots.json[0])
45
+ * Subject: serialNumber=f92009e853b6b045
46
+ * Issuer: same (self-signed)
47
+ * Serial: 0xf1c172a699eaf51d
48
+ * SHA-256: cedb1cb6dc896ae5ec797348bce9286753c2b38ee71ce0fbe34a9a1248800dfc
49
+ * Public key: RSA-4096
50
+ * Validity: 2022-03-20 → 2042-03-15
51
+ */
52
+ export declare const GOOGLE_ANDROID_KEYSTORE_ROOT_RSA_PEM = "-----BEGIN CERTIFICATE-----\nMIIFHDCCAwSgAwIBAgIJAPHBcqaZ6vUdMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\nBAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMjIwMzIwMTgwNzQ4WhcNNDIwMzE1MTgw\nNzQ4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS\nSxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7\ntv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj\nnar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq\nC4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ\noVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O\nJtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg\nsTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi\nigHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M\nRPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E\naDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um\nAGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud\nIwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD\nVR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQB8cMqTllHc8U+qCrOlg3H7\n174lmaCsbo/bJ0C17JEgMLb4kvrqsXZs01U3mB/qABg/1t5Pd5AORHARs1hhqGIC\nW/nKMav574f9rZN4PC2ZlufGXb7sIdJpGiO9ctRhiLuYuly10JccUZGEHpHSYM2G\ntkgYbZba6lsCPYAAP83cyDV+1aOkTf1RCp/lM0PKvmxYN10RYsK631jrleGdcdkx\noSK//mSQbgcWnmAEZrzHoF1/0gso1HZgIn0YLzVhLSA/iXCX4QT2h3J5z3znluKG\n1nv8NQdxei2DIIhASWfu804CA96cQKTTlaae2fweqXjdN1/v2nqOhngNyz1361mF\nmr4XmaKH/ItTwOe72NI9ZcwS1lVaCvsIkTDCEXdm9rCNPAY10iTunIHFXRh+7KPz\nlHGewCq/8TOohBRn0/NNfh7uRslOSZ/xKbN9tMBtw37Z8d2vvnXq/YWdsm1+JLVw\nn6yYD/yacNJBlwpddla8eaVMjsF6nBnIgQOf9zKSe06nSTqvgwUHosgOECZJZ1Eu\nzbH4yswbt02tKtKEFhx+v+OTge/06V+jGsqTWLsfrOCNLuA8H++z+pUENmpqnnHo\nvaI47gC+TNpkgYGkkBT6B/m/U01BuOBBTzhIlMEZq9qkDWuM2cA5kW5V3FJUcfHn\nw1IdYIg2Wxg7yHcQZemFQg==\n-----END CERTIFICATE-----\n";
53
+ /**
54
+ * Google Hardware Attestation Root — ECDSA P-384 (modern / RKP).
55
+ *
56
+ * Source: https://github.com/android/keyattestation (roots.json[1])
57
+ * Subject: CN=Key Attestation CA1, OU=Android, O=Google LLC, C=US
58
+ * Issuer: same (self-signed)
59
+ * Serial: 0x84a9d0297b0eb58ae7ff0e80de760605
60
+ * SHA-256: 6d9db4ce6c5c0b293166d08986e05774a8776ceb525d9e4329520de12ba4bcc0
61
+ * Public key: ECDSA P-384
62
+ * Validity: 2025-07-17 → 2035-07-15
63
+ *
64
+ * Rotation timeline (Google-published, motebit-recorded):
65
+ * - 2026-02-01: RKP-enabled devices begin emitting chains rooted here
66
+ * - 2026-03-31: target deadline for verifiers to pin both anchors
67
+ * - 2026-04-10: RKP-enabled devices switch exclusively to this root
68
+ */
69
+ export declare const GOOGLE_ANDROID_KEYSTORE_ROOT_ECDSA_PEM = "-----BEGIN CERTIFICATE-----\nMIICIjCCAaigAwIBAgIRAISp0Cl7DrWK5/8OgN52BgUwCgYIKoZIzj0EAwMwUjEc\nMBoGA1UEAwwTS2V5IEF0dGVzdGF0aW9uIENBMTEQMA4GA1UECwwHQW5kcm9pZDET\nMBEGA1UECgwKR29vZ2xlIExMQzELMAkGA1UEBhMCVVMwHhcNMjUwNzE3MjIzMjE4\nWhcNMzUwNzE1MjIzMjE4WjBSMRwwGgYDVQQDDBNLZXkgQXR0ZXN0YXRpb24gQ0Ex\nMRAwDgYDVQQLDAdBbmRyb2lkMRMwEQYDVQQKDApHb29nbGUgTExDMQswCQYDVQQG\nEwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABCPaI3FO3z5bBQo8cuiEas4HjqCt\nG/mLFfRT0MsIssPBEEU5Cfbt6sH5yOAxqEi5QagpU1yX4HwnGb7OtBYpDTB57uH5\nEczm34A5FNijV3s0/f0UPl7zbJcTx6xwqMIRq6NCMEAwDwYDVR0TAQH/BAUwAwEB\n/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFIyuyz7RkOb3NaBqQ5lZuA0QepA\nMAoGCCqGSM49BAMDA2gAMGUCMETfjPO/HwqReR2CS7p0ZWoD/LHs6hDi422opifH\nEUaYLxwGlT9SLdjkVpz0UUOR5wIxAIoGyxGKRHVTpqpGRFiJtQEOOTp/+s1GcxeY\nuR2zh/80lQyu9vAFCj6E4AXc+osmRg==\n-----END CERTIFICATE-----\n";
70
+ /**
71
+ * Default pinned-root set returned when a caller passes no `rootPems`
72
+ * override. Both Google attestation roots — pin order is irrelevant
73
+ * to chain validation but is documented for audit-readability.
74
+ */
75
+ export declare const DEFAULT_ANDROID_KEYSTORE_TRUST_ANCHORS: readonly string[];
76
+ /**
77
+ * Sentinel value the consumer-facing verifier emits on a mint path
78
+ * where the Kotlin bridge returns a `not_supported` failure envelope.
79
+ * Exposed as a constant so call sites match on a named token rather
80
+ * than a raw string literal.
81
+ */
82
+ export declare const ANDROID_KEYSTORE_PLATFORM: "android_keystore";
83
+ /**
84
+ * The OID Google uses for the Android Key Attestation extension on
85
+ * the leaf certificate. Defined in the Android security docs:
86
+ * https://source.android.com/docs/security/features/keystore/attestation
87
+ */
88
+ export declare const ANDROID_KEY_ATTESTATION_OID = "1.3.6.1.4.1.11129.2.1.17";
89
+ //# sourceMappingURL=google-roots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-roots.d.ts","sourceRoot":"","sources":["../src/google-roots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oCAAoC,60DA8BhD,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sCAAsC,qzBAclD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sCAAsC,EAAE,SAAS,MAAM,EAGnE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAG,kBAA2B,CAAC;AAErE;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,6BAA6B,CAAC"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Pinned Google Hardware Attestation root certificates.
3
+ *
4
+ * Every `platform: "android_keystore"` hardware-attestation claim must
5
+ * chain to one of the root CAs listed here. Pinning is the
6
+ * self-attesting contract — a verifier that dynamically fetched
7
+ * Google's attestation roots could not be reproduced by a third-party
8
+ * audit. By committing the exact bytes of the CAs we accept, anyone
9
+ * can audit this file, pin the same bytes in their own verifier, and
10
+ * reach the same yes/no answer.
11
+ *
12
+ * Two roots are pinned, covering the in-flight rotation Google
13
+ * announced for early 2026:
14
+ *
15
+ * - **Legacy RSA-4096 root** — covers all factory-provisioned
16
+ * Android devices since 2014. Cannot be rotated on those devices,
17
+ * so it stays valid indefinitely for that fleet.
18
+ *
19
+ * - **ECDSA P-384 root** — issued 2025-07-17. Covers RKP-provisioned
20
+ * devices (Remote Key Provisioning, the modern flow). Devices
21
+ * began emitting chains rooted here on 2026-02-01; switched
22
+ * exclusively after 2026-04-10.
23
+ *
24
+ * Verifiers MUST pin both. Source of truth: `roots.json` in the
25
+ * `android/keyattestation` repository (Google's canonical Kotlin
26
+ * reference verifier), mirrored from Android's published attestation
27
+ * trust anchor list.
28
+ *
29
+ * Operator note — runtime fetching is forbidden. The Android docs are
30
+ * explicit: "Don't query for roots at runtime. Use formal
31
+ * configuration updates." A new Google root cert lands here as an
32
+ * additive constant, never via dynamic fetch — any other path
33
+ * sacrifices the sovereign-verifier story.
34
+ *
35
+ * Each constant ships its real Google-published bytes. Each comment
36
+ * names: source URL, subject DN, SHA-256 fingerprint, public-key
37
+ * algorithm, validity window. The fingerprint is the audit anchor — a
38
+ * third party that fetches the same source and computes its own
39
+ * SHA-256 should reach the byte-identical value below.
40
+ */
41
+ /**
42
+ * Google Hardware Attestation Root — RSA-4096 (legacy / factory-provisioned).
43
+ *
44
+ * Source: https://github.com/android/keyattestation (roots.json[0])
45
+ * Subject: serialNumber=f92009e853b6b045
46
+ * Issuer: same (self-signed)
47
+ * Serial: 0xf1c172a699eaf51d
48
+ * SHA-256: cedb1cb6dc896ae5ec797348bce9286753c2b38ee71ce0fbe34a9a1248800dfc
49
+ * Public key: RSA-4096
50
+ * Validity: 2022-03-20 → 2042-03-15
51
+ */
52
+ export const GOOGLE_ANDROID_KEYSTORE_ROOT_RSA_PEM = `-----BEGIN CERTIFICATE-----
53
+ MIIFHDCCAwSgAwIBAgIJAPHBcqaZ6vUdMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
54
+ BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMjIwMzIwMTgwNzQ4WhcNNDIwMzE1MTgw
55
+ NzQ4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
56
+ AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS
57
+ Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7
58
+ tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj
59
+ nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq
60
+ C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ
61
+ oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O
62
+ JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg
63
+ sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi
64
+ igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M
65
+ RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E
66
+ aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um
67
+ AGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud
68
+ IwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD
69
+ VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQB8cMqTllHc8U+qCrOlg3H7
70
+ 174lmaCsbo/bJ0C17JEgMLb4kvrqsXZs01U3mB/qABg/1t5Pd5AORHARs1hhqGIC
71
+ W/nKMav574f9rZN4PC2ZlufGXb7sIdJpGiO9ctRhiLuYuly10JccUZGEHpHSYM2G
72
+ tkgYbZba6lsCPYAAP83cyDV+1aOkTf1RCp/lM0PKvmxYN10RYsK631jrleGdcdkx
73
+ oSK//mSQbgcWnmAEZrzHoF1/0gso1HZgIn0YLzVhLSA/iXCX4QT2h3J5z3znluKG
74
+ 1nv8NQdxei2DIIhASWfu804CA96cQKTTlaae2fweqXjdN1/v2nqOhngNyz1361mF
75
+ mr4XmaKH/ItTwOe72NI9ZcwS1lVaCvsIkTDCEXdm9rCNPAY10iTunIHFXRh+7KPz
76
+ lHGewCq/8TOohBRn0/NNfh7uRslOSZ/xKbN9tMBtw37Z8d2vvnXq/YWdsm1+JLVw
77
+ n6yYD/yacNJBlwpddla8eaVMjsF6nBnIgQOf9zKSe06nSTqvgwUHosgOECZJZ1Eu
78
+ zbH4yswbt02tKtKEFhx+v+OTge/06V+jGsqTWLsfrOCNLuA8H++z+pUENmpqnnHo
79
+ vaI47gC+TNpkgYGkkBT6B/m/U01BuOBBTzhIlMEZq9qkDWuM2cA5kW5V3FJUcfHn
80
+ w1IdYIg2Wxg7yHcQZemFQg==
81
+ -----END CERTIFICATE-----
82
+ `;
83
+ /**
84
+ * Google Hardware Attestation Root — ECDSA P-384 (modern / RKP).
85
+ *
86
+ * Source: https://github.com/android/keyattestation (roots.json[1])
87
+ * Subject: CN=Key Attestation CA1, OU=Android, O=Google LLC, C=US
88
+ * Issuer: same (self-signed)
89
+ * Serial: 0x84a9d0297b0eb58ae7ff0e80de760605
90
+ * SHA-256: 6d9db4ce6c5c0b293166d08986e05774a8776ceb525d9e4329520de12ba4bcc0
91
+ * Public key: ECDSA P-384
92
+ * Validity: 2025-07-17 → 2035-07-15
93
+ *
94
+ * Rotation timeline (Google-published, motebit-recorded):
95
+ * - 2026-02-01: RKP-enabled devices begin emitting chains rooted here
96
+ * - 2026-03-31: target deadline for verifiers to pin both anchors
97
+ * - 2026-04-10: RKP-enabled devices switch exclusively to this root
98
+ */
99
+ export const GOOGLE_ANDROID_KEYSTORE_ROOT_ECDSA_PEM = `-----BEGIN CERTIFICATE-----
100
+ MIICIjCCAaigAwIBAgIRAISp0Cl7DrWK5/8OgN52BgUwCgYIKoZIzj0EAwMwUjEc
101
+ MBoGA1UEAwwTS2V5IEF0dGVzdGF0aW9uIENBMTEQMA4GA1UECwwHQW5kcm9pZDET
102
+ MBEGA1UECgwKR29vZ2xlIExMQzELMAkGA1UEBhMCVVMwHhcNMjUwNzE3MjIzMjE4
103
+ WhcNMzUwNzE1MjIzMjE4WjBSMRwwGgYDVQQDDBNLZXkgQXR0ZXN0YXRpb24gQ0Ex
104
+ MRAwDgYDVQQLDAdBbmRyb2lkMRMwEQYDVQQKDApHb29nbGUgTExDMQswCQYDVQQG
105
+ EwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABCPaI3FO3z5bBQo8cuiEas4HjqCt
106
+ G/mLFfRT0MsIssPBEEU5Cfbt6sH5yOAxqEi5QagpU1yX4HwnGb7OtBYpDTB57uH5
107
+ Eczm34A5FNijV3s0/f0UPl7zbJcTx6xwqMIRq6NCMEAwDwYDVR0TAQH/BAUwAwEB
108
+ /zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFIyuyz7RkOb3NaBqQ5lZuA0QepA
109
+ MAoGCCqGSM49BAMDA2gAMGUCMETfjPO/HwqReR2CS7p0ZWoD/LHs6hDi422opifH
110
+ EUaYLxwGlT9SLdjkVpz0UUOR5wIxAIoGyxGKRHVTpqpGRFiJtQEOOTp/+s1GcxeY
111
+ uR2zh/80lQyu9vAFCj6E4AXc+osmRg==
112
+ -----END CERTIFICATE-----
113
+ `;
114
+ /**
115
+ * Default pinned-root set returned when a caller passes no `rootPems`
116
+ * override. Both Google attestation roots — pin order is irrelevant
117
+ * to chain validation but is documented for audit-readability.
118
+ */
119
+ export const DEFAULT_ANDROID_KEYSTORE_TRUST_ANCHORS = [
120
+ GOOGLE_ANDROID_KEYSTORE_ROOT_RSA_PEM,
121
+ GOOGLE_ANDROID_KEYSTORE_ROOT_ECDSA_PEM,
122
+ ];
123
+ /**
124
+ * Sentinel value the consumer-facing verifier emits on a mint path
125
+ * where the Kotlin bridge returns a `not_supported` failure envelope.
126
+ * Exposed as a constant so call sites match on a named token rather
127
+ * than a raw string literal.
128
+ */
129
+ export const ANDROID_KEYSTORE_PLATFORM = "android_keystore";
130
+ /**
131
+ * The OID Google uses for the Android Key Attestation extension on
132
+ * the leaf certificate. Defined in the Android security docs:
133
+ * https://source.android.com/docs/security/features/keystore/attestation
134
+ */
135
+ export const ANDROID_KEY_ATTESTATION_OID = "1.3.6.1.4.1.11129.2.1.17";
136
+ //# sourceMappingURL=google-roots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-roots.js","sourceRoot":"","sources":["../src/google-roots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BnD,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,sCAAsC,GAAG;;;;;;;;;;;;;;CAcrD,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,sCAAsC,GAAsB;IACvE,oCAAoC;IACpC,sCAAsC;CACvC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,kBAA2B,CAAC;AAErE;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,0BAA0B,CAAC"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @motebit/crypto-android-keystore — Android Hardware-Backed Keystore
3
+ * Attestation adapter for motebit hardware-attestation claims.
4
+ *
5
+ * The metabolic leaf `@motebit/crypto` delegates to when a
6
+ * `HardwareAttestationClaim` declares `platform: "android_keystore"`.
7
+ * Dep-thin `@motebit/crypto` stays permissive-floor-pure; this
8
+ * package, also on the permissive floor (Apache-2.0), metabolizes
9
+ * `@peculiar/x509` plus a hand-rolled DER walker for the AOSP Key
10
+ * Attestation extension to judge whether a Google-published
11
+ * Hardware Attestation root signed the leaf that the device's
12
+ * Trusted-Environment / StrongBox-backed key signed.
13
+ *
14
+ * Wiring from a consumer:
15
+ *
16
+ * ```ts
17
+ * import { verify } from "@motebit/crypto";
18
+ * import { androidKeystoreVerifier } from "@motebit/crypto-android-keystore";
19
+ *
20
+ * const result = await verify(credential, {
21
+ * hardwareAttestation: {
22
+ * android_keystore: androidKeystoreVerifier({
23
+ * expectedAttestationApplicationId,
24
+ * }),
25
+ * },
26
+ * });
27
+ * ```
28
+ *
29
+ * This package exports no global state, no side-effect registrations;
30
+ * the injection is call-site only. Pinned Google attestation roots
31
+ * live in `./google-roots.ts` and are the self-attesting audit
32
+ * surface — a third party that fetches the same roots.json and
33
+ * computes its own SHA-256 should reach the byte-identical
34
+ * fingerprints documented inline.
35
+ */
36
+ import type { HardwareAttestationClaim } from "@motebit/protocol";
37
+ import type { AndroidKeystoreRevocationSnapshot, AndroidKeystoreVerifyResult } from "./verify.js";
38
+ export { parseKeyDescription, SECURITY_LEVEL_SOFTWARE, SECURITY_LEVEL_TRUSTED_ENVIRONMENT, SECURITY_LEVEL_STRONG_BOX, VERIFIED_BOOT_STATE_VERIFIED, VERIFIED_BOOT_STATE_SELF_SIGNED, VERIFIED_BOOT_STATE_UNVERIFIED, VERIFIED_BOOT_STATE_FAILED, type RootOfTrust, type AuthorizationList, type KeyDescription, } from "./asn1.js";
39
+ export { ANDROID_KEYSTORE_PLATFORM, ANDROID_KEY_ATTESTATION_OID, GOOGLE_ANDROID_KEYSTORE_ROOT_RSA_PEM, GOOGLE_ANDROID_KEYSTORE_ROOT_ECDSA_PEM, DEFAULT_ANDROID_KEYSTORE_TRUST_ANCHORS, } from "./google-roots.js";
40
+ export { verifyAndroidKeystoreAttestation, EMPTY_REVOCATION_SNAPSHOT } from "./verify.js";
41
+ export type { AndroidKeystoreVerifyOptions, AndroidKeystoreVerifyResult, AndroidKeystoreVerifyError, AndroidKeystoreRevocationSnapshot, } from "./verify.js";
42
+ /**
43
+ * Shape the optional verifier injected into `@motebit/crypto`'s
44
+ * `HardwareAttestationVerifiers.android_keystore` slot carries.
45
+ * Mirrors the sync-or-async return shape the dispatcher supports
46
+ * and extends the canonical shape with `attestation_detail` so
47
+ * callers can introspect chain / extension / binding independently.
48
+ */
49
+ export interface AndroidKeystoreVerifierResult {
50
+ readonly valid: boolean;
51
+ readonly platform: "android_keystore";
52
+ readonly errors: ReadonlyArray<{
53
+ readonly message: string;
54
+ }>;
55
+ readonly attestation_detail?: AndroidKeystoreVerifyResult;
56
+ }
57
+ /**
58
+ * VC-subject fields the dispatcher lifts out of the credential and
59
+ * threads through to the verifier. All three participate in the JCS
60
+ * canonical body that derives the attestation challenge; without them
61
+ * the verifier reports the missing channel explicitly rather than
62
+ * silently passing.
63
+ */
64
+ export interface AndroidKeystoreVerifierContext {
65
+ readonly expectedMotebitId?: string;
66
+ readonly expectedDeviceId?: string;
67
+ readonly expectedAttestedAt?: number;
68
+ }
69
+ export interface AndroidKeystoreVerifierConfig {
70
+ /**
71
+ * Bound to the registered Android package's
72
+ * `attestationApplicationId` byte representation (raw OCTET STRING
73
+ * captured at registration time). Required at wiring time so the
74
+ * package binding constraint fires on every claim.
75
+ */
76
+ readonly expectedAttestationApplicationId: Uint8Array;
77
+ /** Optional: override the pinned Google attestation roots. */
78
+ readonly rootPems?: readonly string[];
79
+ /** Optional: caller-supplied revocation snapshot. */
80
+ readonly revocationSnapshot?: AndroidKeystoreRevocationSnapshot;
81
+ /** Optional: allowlist of `verifiedBootState` ENUMERATED values. */
82
+ readonly verifiedBootStateAllowlist?: readonly number[];
83
+ /** Optional: minimum `attestationSecurityLevel` (default TRUSTED_ENVIRONMENT). */
84
+ readonly minSecurityLevel?: number;
85
+ /** Optional: minimum `attestationVersion` (default 3 / Keymaster 3). */
86
+ readonly minAttestationVersion?: number;
87
+ /** Optional: inject a fixed clock for deterministic chain validity. */
88
+ readonly now?: () => number;
89
+ }
90
+ /**
91
+ * Factory — build an `android_keystore` verifier bound to a registered
92
+ * package. The returned function matches the
93
+ * `HardwareAttestationVerifiers.android_keystore` three-arg signature
94
+ * the `@motebit/crypto` dispatcher calls.
95
+ */
96
+ export declare function androidKeystoreVerifier(config: AndroidKeystoreVerifierConfig): (claim: HardwareAttestationClaim, expectedIdentityHex: string, context?: AndroidKeystoreVerifierContext) => Promise<AndroidKeystoreVerifierResult>;
97
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAGlE,OAAO,KAAK,EACV,iCAAiC,EAEjC,2BAA2B,EAC5B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,kCAAkC,EAClC,yBAAyB,EACzB,4BAA4B,EAC5B,+BAA+B,EAC/B,8BAA8B,EAC9B,0BAA0B,EAC1B,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,oCAAoC,EACpC,sCAAsC,EACtC,sCAAsC,GACvC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAC1F,YAAY,EACV,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,iCAAiC,GAClC,MAAM,aAAa,CAAC;AAErB;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,2BAA2B,CAAC;CAC3D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,6BAA6B;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,gCAAgC,EAAE,UAAU,CAAC;IACtD,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,qDAAqD;IACrD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,iCAAiC,CAAC;IAChE,oEAAoE;IACpE,QAAQ,CAAC,0BAA0B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxD,kFAAkF;IAClF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,wEAAwE;IACxE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,uEAAuE;IACvE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,6BAA6B,GACpC,CACD,KAAK,EAAE,wBAAwB,EAC/B,mBAAmB,EAAE,MAAM,EAC3B,OAAO,CAAC,EAAE,8BAA8B,KACrC,OAAO,CAAC,6BAA6B,CAAC,CAqC1C"}
package/dist/index.js ADDED
@@ -0,0 +1,84 @@
1
+ /**
2
+ * @motebit/crypto-android-keystore — Android Hardware-Backed Keystore
3
+ * Attestation adapter for motebit hardware-attestation claims.
4
+ *
5
+ * The metabolic leaf `@motebit/crypto` delegates to when a
6
+ * `HardwareAttestationClaim` declares `platform: "android_keystore"`.
7
+ * Dep-thin `@motebit/crypto` stays permissive-floor-pure; this
8
+ * package, also on the permissive floor (Apache-2.0), metabolizes
9
+ * `@peculiar/x509` plus a hand-rolled DER walker for the AOSP Key
10
+ * Attestation extension to judge whether a Google-published
11
+ * Hardware Attestation root signed the leaf that the device's
12
+ * Trusted-Environment / StrongBox-backed key signed.
13
+ *
14
+ * Wiring from a consumer:
15
+ *
16
+ * ```ts
17
+ * import { verify } from "@motebit/crypto";
18
+ * import { androidKeystoreVerifier } from "@motebit/crypto-android-keystore";
19
+ *
20
+ * const result = await verify(credential, {
21
+ * hardwareAttestation: {
22
+ * android_keystore: androidKeystoreVerifier({
23
+ * expectedAttestationApplicationId,
24
+ * }),
25
+ * },
26
+ * });
27
+ * ```
28
+ *
29
+ * This package exports no global state, no side-effect registrations;
30
+ * the injection is call-site only. Pinned Google attestation roots
31
+ * live in `./google-roots.ts` and are the self-attesting audit
32
+ * surface — a third party that fetches the same roots.json and
33
+ * computes its own SHA-256 should reach the byte-identical
34
+ * fingerprints documented inline.
35
+ */
36
+ import { verifyAndroidKeystoreAttestation } from "./verify.js";
37
+ export { parseKeyDescription, SECURITY_LEVEL_SOFTWARE, SECURITY_LEVEL_TRUSTED_ENVIRONMENT, SECURITY_LEVEL_STRONG_BOX, VERIFIED_BOOT_STATE_VERIFIED, VERIFIED_BOOT_STATE_SELF_SIGNED, VERIFIED_BOOT_STATE_UNVERIFIED, VERIFIED_BOOT_STATE_FAILED, } from "./asn1.js";
38
+ export { ANDROID_KEYSTORE_PLATFORM, ANDROID_KEY_ATTESTATION_OID, GOOGLE_ANDROID_KEYSTORE_ROOT_RSA_PEM, GOOGLE_ANDROID_KEYSTORE_ROOT_ECDSA_PEM, DEFAULT_ANDROID_KEYSTORE_TRUST_ANCHORS, } from "./google-roots.js";
39
+ export { verifyAndroidKeystoreAttestation, EMPTY_REVOCATION_SNAPSHOT } from "./verify.js";
40
+ /**
41
+ * Factory — build an `android_keystore` verifier bound to a registered
42
+ * package. The returned function matches the
43
+ * `HardwareAttestationVerifiers.android_keystore` three-arg signature
44
+ * the `@motebit/crypto` dispatcher calls.
45
+ */
46
+ export function androidKeystoreVerifier(config) {
47
+ return async (claim, expectedIdentityHex, context) => {
48
+ const opts = {
49
+ expectedAttestationApplicationId: config.expectedAttestationApplicationId,
50
+ expectedIdentityPublicKeyHex: expectedIdentityHex,
51
+ ...(config.rootPems !== undefined ? { rootPems: config.rootPems } : {}),
52
+ ...(config.revocationSnapshot !== undefined
53
+ ? { revocationSnapshot: config.revocationSnapshot }
54
+ : {}),
55
+ ...(config.verifiedBootStateAllowlist !== undefined
56
+ ? { verifiedBootStateAllowlist: config.verifiedBootStateAllowlist }
57
+ : {}),
58
+ ...(config.minSecurityLevel !== undefined
59
+ ? { minSecurityLevel: config.minSecurityLevel }
60
+ : {}),
61
+ ...(config.minAttestationVersion !== undefined
62
+ ? { minAttestationVersion: config.minAttestationVersion }
63
+ : {}),
64
+ ...(config.now !== undefined ? { now: config.now } : {}),
65
+ ...(context?.expectedMotebitId !== undefined
66
+ ? { expectedMotebitId: context.expectedMotebitId }
67
+ : {}),
68
+ ...(context?.expectedDeviceId !== undefined
69
+ ? { expectedDeviceId: context.expectedDeviceId }
70
+ : {}),
71
+ ...(context?.expectedAttestedAt !== undefined
72
+ ? { expectedAttestedAt: context.expectedAttestedAt }
73
+ : {}),
74
+ };
75
+ const detail = await verifyAndroidKeystoreAttestation(claim, opts);
76
+ return {
77
+ valid: detail.valid,
78
+ platform: "android_keystore",
79
+ errors: detail.errors,
80
+ attestation_detail: detail,
81
+ };
82
+ };
83
+ }
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH,OAAO,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAC;AAO/D,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,kCAAkC,EAClC,yBAAyB,EACzB,4BAA4B,EAC5B,+BAA+B,EAC/B,8BAA8B,EAC9B,0BAA0B,GAI3B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,oCAAoC,EACpC,sCAAsC,EACtC,sCAAsC,GACvC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAyD1F;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAqC;IAMrC,OAAO,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE;QACnD,MAAM,IAAI,GAAiC;YACzC,gCAAgC,EAAE,MAAM,CAAC,gCAAgC;YACzE,4BAA4B,EAAE,mBAAmB;YACjD,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,MAAM,CAAC,kBAAkB,KAAK,SAAS;gBACzC,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,EAAE;gBACnD,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,0BAA0B,KAAK,SAAS;gBACjD,CAAC,CAAC,EAAE,0BAA0B,EAAE,MAAM,CAAC,0BAA0B,EAAE;gBACnE,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS;gBACvC,CAAC,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE;gBAC/C,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,qBAAqB,KAAK,SAAS;gBAC5C,CAAC,CAAC,EAAE,qBAAqB,EAAE,MAAM,CAAC,qBAAqB,EAAE;gBACzD,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,SAAS;gBAC1C,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE;gBAClD,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,SAAS;gBACzC,CAAC,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE;gBAChD,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,SAAS;gBAC3C,CAAC,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE;gBACpD,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,gCAAgC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACnE,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,kBAAkB,EAAE,MAAM;SAC3B,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Android Hardware-Backed Keystore Attestation verifier — the core
3
+ * judgment function this package exports.
4
+ *
5
+ * Flow (matches Google's published verification recipe at
6
+ * https://source.android.com/docs/security/features/keystore/attestation,
7
+ * plus the motebit-specific identity-key binding step):
8
+ *
9
+ * 1. Split the receipt into the leaf cert plus the rest of the chain
10
+ * (`{leafCertB64}.{intermediatesJoinedB64}` — comma-joined leaf-
11
+ * proximal-first base64url DER blobs in the second segment).
12
+ * 2. Parse the chain as X.509 certificates. Walk the chain leaf →
13
+ * intermediates → terminal anchor with `@peculiar/x509`'s
14
+ * `X509ChainBuilder`. Every non-leaf must carry
15
+ * `basicConstraints.cA === true`. Every signature must verify
16
+ * under its issuer's public key. Every cert must be within its
17
+ * validity window. The terminal cert's DER must equal one of the
18
+ * pinned Google attestation roots.
19
+ * 3. Read the Android Key Attestation extension (OID
20
+ * `1.3.6.1.4.1.11129.2.1.17`) from the LEAF cert only. The AOSP
21
+ * spec is explicit that later occurrences of this extension up
22
+ * the chain MUST be ignored — only the leaf's copy carries
23
+ * trustworthy data, because only the leaf is signed by the
24
+ * device's secure-hardware key.
25
+ * 4. Constrain the parsed `KeyDescription`:
26
+ * - `attestationSecurityLevel ≥ TRUSTED_ENVIRONMENT` (rejects
27
+ * software-only fallback, which is structurally not
28
+ * third-party meaningful)
29
+ * - `attestationVersion ≥ 3` (rejects pre-Android-7 / Keymaster
30
+ * v2; current production is 4 / Keymaster 4 through 400 /
31
+ * KeyMint 4.0)
32
+ * - `hardwareEnforced.rootOfTrust.verifiedBootState` is in the
33
+ * caller's allowlist (default: VERIFIED only)
34
+ * - `hardwareEnforced.attestationApplicationId` byte-equals
35
+ * the caller's expected package binding
36
+ * - leaf's serial number is not in the caller-supplied
37
+ * revocation snapshot
38
+ * 5. Cryptographically bind the leaf's `attestationChallenge` field
39
+ * to the motebit Ed25519 identity: re-derive
40
+ * `SHA-256(canonicalJson({ attested_at, device_id,
41
+ * identity_public_key, motebit_id, platform: "android_keystore",
42
+ * version: "1" }))` and byte-compare against the transmitted
43
+ * challenge. A malicious client that substitutes any other body
44
+ * fails here.
45
+ *
46
+ * Pure. No network. No filesystem. Deterministic given `now()` and
47
+ * the caller-supplied revocation snapshot.
48
+ */
49
+ import type { HardwareAttestationClaim } from "@motebit/protocol";
50
+ /**
51
+ * Caller-supplied revocation snapshot keyed by lowercase-hex serial
52
+ * number — mirrors Google's published shape at
53
+ * https://android.googleapis.com/attestation/status. The motebit
54
+ * verifier never fetches this at runtime; the canonical CLI in
55
+ * `@motebit/verify` ships an embedded snapshot at release time and
56
+ * accepts an override path. Empty snapshot is the no-revocation-data
57
+ * default and means every leaf passes the revocation check.
58
+ */
59
+ export interface AndroidKeystoreRevocationSnapshot {
60
+ readonly entries: Readonly<Record<string, {
61
+ readonly status: "REVOKED" | "SUSPENDED";
62
+ readonly reason?: string;
63
+ }>>;
64
+ }
65
+ /** Empty revocation snapshot — every leaf passes the revocation check. */
66
+ export declare const EMPTY_REVOCATION_SNAPSHOT: AndroidKeystoreRevocationSnapshot;
67
+ export interface AndroidKeystoreVerifyOptions {
68
+ /**
69
+ * Android package name + signing-cert SHA-256 hash binding the
70
+ * leaf's `attestationApplicationId` MUST match. The expected value
71
+ * is the byte-identical encoding the Kotlin mint path produces —
72
+ * either a raw OCTET STRING capture or a wrapped representation,
73
+ * depending on the surface. Implementations typically supply the
74
+ * raw bytes captured at registration time.
75
+ */
76
+ readonly expectedAttestationApplicationId: Uint8Array;
77
+ /**
78
+ * Ed25519 identity key (lowercase hex) the motebit VC claims. The
79
+ * leaf's `attestationChallenge` MUST bind this key (via the
80
+ * canonical-body re-derivation).
81
+ */
82
+ readonly expectedIdentityPublicKeyHex: string;
83
+ /**
84
+ * motebit_id from the credential subject. Participates in the JCS
85
+ * canonical body re-derived here and byte-compared against the
86
+ * transmitted challenge.
87
+ */
88
+ readonly expectedMotebitId?: string;
89
+ /** device_id from the credential subject. Same binding role. */
90
+ readonly expectedDeviceId?: string;
91
+ /** `attested_at` (unix ms) from the credential subject. Same binding role. */
92
+ readonly expectedAttestedAt?: number;
93
+ /**
94
+ * Override the pinned trust anchors. Tests fabricate their own root
95
+ * so chain verification exercises the same code path without needing
96
+ * a real device-signed leaf. Defaults to
97
+ * `DEFAULT_ANDROID_KEYSTORE_TRUST_ANCHORS` (RSA + ECDSA P-384).
98
+ */
99
+ readonly rootPems?: readonly string[];
100
+ /**
101
+ * Allowlist of `verifiedBootState` ENUMERATED values the verifier
102
+ * accepts. Default = `[VERIFIED]` (Google-signed bootloader). Set
103
+ * to `[VERIFIED, SELF_SIGNED]` to allow GrapheneOS-style
104
+ * user-installed roots-of-trust per their published attestation
105
+ * compatibility model. Empty array = accept any state (NOT
106
+ * recommended — leaks the boot-image guarantee).
107
+ */
108
+ readonly verifiedBootStateAllowlist?: readonly number[];
109
+ /**
110
+ * Minimum `attestationSecurityLevel` the verifier accepts. Default =
111
+ * `TRUSTED_ENVIRONMENT` (1). Software-only attestations (level 0)
112
+ * are structurally not third-party meaningful and are rejected.
113
+ * StrongBox (2) is a higher score in the semiring, not an admission
114
+ * gate — pass `TRUSTED_ENVIRONMENT` here and let the score-side
115
+ * code differentiate.
116
+ */
117
+ readonly minSecurityLevel?: number;
118
+ /**
119
+ * Minimum `attestationVersion` the verifier accepts. Default = 3
120
+ * (Keymaster 3 / Android 7 — earliest version with the modern chain
121
+ * shape). Anything below this is rejected.
122
+ */
123
+ readonly minAttestationVersion?: number;
124
+ /**
125
+ * Caller-supplied revocation snapshot. Defaults to empty (no
126
+ * revocation enforcement). Production callers should supply
127
+ * Google's status-list shape; `@motebit/verify` ships an embedded
128
+ * snapshot at release time.
129
+ */
130
+ readonly revocationSnapshot?: AndroidKeystoreRevocationSnapshot;
131
+ /** Clock for chain-validity checks. Defaults to `Date.now`. */
132
+ readonly now?: () => number;
133
+ }
134
+ export interface AndroidKeystoreVerifyError {
135
+ readonly message: string;
136
+ }
137
+ export interface AndroidKeystoreVerifyResult {
138
+ readonly valid: boolean;
139
+ readonly cert_chain_valid: boolean;
140
+ /**
141
+ * True when the leaf carried a parseable Key Attestation extension
142
+ * AND every constraint check (security level, attestation version,
143
+ * verified-boot state, application-ID match, revocation lookup)
144
+ * passed.
145
+ */
146
+ readonly attestation_extension_valid: boolean;
147
+ /**
148
+ * True when `attestationChallenge` byte-equals
149
+ * `SHA256(canonical body)` for the caller-supplied identity.
150
+ */
151
+ readonly identity_bound: boolean;
152
+ /**
153
+ * The `attestationSecurityLevel` parsed off the leaf (or null if
154
+ * the extension wasn't parseable). Exposed so callers can surface
155
+ * `TRUSTED_ENVIRONMENT` vs `STRONG_BOX` in an audit UI alongside
156
+ * the pass/fail verdict — and so a routing semiring can score
157
+ * StrongBox higher than plain TEE.
158
+ */
159
+ readonly attestation_security_level: number | null;
160
+ /**
161
+ * The `verifiedBootState` parsed off the leaf's `rootOfTrust` (or
162
+ * null if absent / extension unparseable). Same audit-surface
163
+ * rationale as `attestation_security_level`.
164
+ */
165
+ readonly verified_boot_state: number | null;
166
+ readonly errors: readonly AndroidKeystoreVerifyError[];
167
+ }
168
+ /**
169
+ * Android Hardware-Backed Keystore Attestation verifier.
170
+ *
171
+ * `claim.attestation_receipt` is the cert chain encoded as
172
+ * `{leafCertB64}.{intermediatesJoinedB64}` — leaf-first DER chain
173
+ * matching the wire format the Kotlin `expo-android-keystore` mint
174
+ * path emits. The intermediates segment is a comma-joined list of
175
+ * base64url-encoded DERs in leaf-proximal-first order; an empty
176
+ * second segment means the leaf chains directly to a pinned root.
177
+ */
178
+ export declare function verifyAndroidKeystoreAttestation(claim: HardwareAttestationClaim, opts: AndroidKeystoreVerifyOptions): Promise<AndroidKeystoreVerifyResult>;
179
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAIH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAalE;;;;;;;;GAQG;AACH,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,OAAO,EAAE,QAAQ,CACxB,MAAM,CACJ,MAAM,EACN;QACE,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,WAAW,CAAC;QACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,CACF,CACF,CAAC;CACH;AAED,0EAA0E;AAC1E,eAAO,MAAM,yBAAyB,EAAE,iCAAmD,CAAC;AAE5F,MAAM,WAAW,4BAA4B;IAC3C;;;;;;;OAOG;IACH,QAAQ,CAAC,gCAAgC,EAAE,UAAU,CAAC;IACtD;;;;OAIG;IACH,QAAQ,CAAC,4BAA4B,EAAE,MAAM,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,gEAAgE;IAChE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC;;;;;;;OAOG;IACH,QAAQ,CAAC,0BAA0B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxD;;;;;;;OAOG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,iCAAiC,CAAC;IAChE,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,2BAA2B,EAAE,OAAO,CAAC;IAC9C;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,SAAS,0BAA0B,EAAE,CAAC;CACxD;AAED;;;;;;;;;GASG;AACH,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,wBAAwB,EAC/B,IAAI,EAAE,4BAA4B,GACjC,OAAO,CAAC,2BAA2B,CAAC,CAiHtC"}