@reclaimprotocol/js-sdk 5.1.0 → 5.3.0-dev.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 +57 -24
- package/dist/index.d.ts +66 -17
- package/dist/index.js +363 -716
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -84,7 +84,7 @@ var require_package = __commonJS({
|
|
|
84
84
|
"package.json"(exports2, module2) {
|
|
85
85
|
module2.exports = {
|
|
86
86
|
name: "@reclaimprotocol/js-sdk",
|
|
87
|
-
version: "5.
|
|
87
|
+
version: "5.3.0-dev.1",
|
|
88
88
|
description: "Designed to request proofs from the Reclaim protocol and manage the flow of claims and witness interactions.",
|
|
89
89
|
main: "dist/index.js",
|
|
90
90
|
types: "dist/index.d.ts",
|
|
@@ -220,6 +220,7 @@ __export(index_exports, {
|
|
|
220
220
|
isHttpProviderClaimParams: () => isHttpProviderClaimParams,
|
|
221
221
|
isMobileDevice: () => isMobileDevice,
|
|
222
222
|
recoverSignersOfSignedClaim: () => recoverSignersOfSignedClaim,
|
|
223
|
+
runTeeVerification: () => runTeeVerification,
|
|
223
224
|
takePairsWhereValueIsArray: () => takePairsWhereValueIsArray,
|
|
224
225
|
takeTemplateParametersFromProofs: () => takeTemplateParametersFromProofs,
|
|
225
226
|
transformForOnchain: () => transformForOnchain,
|
|
@@ -238,7 +239,7 @@ var RECLAIM_EXTENSION_ACTIONS = {
|
|
|
238
239
|
};
|
|
239
240
|
|
|
240
241
|
// src/Reclaim.ts
|
|
241
|
-
var
|
|
242
|
+
var import_ethers6 = require("ethers");
|
|
242
243
|
var import_canonicalize3 = __toESM(require("canonicalize"));
|
|
243
244
|
|
|
244
245
|
// src/utils/errors.ts
|
|
@@ -560,19 +561,19 @@ function scheduleIntervalEndingTask(sessionId, intervals, onFailureCallback, tim
|
|
|
560
561
|
}
|
|
561
562
|
}, timeout);
|
|
562
563
|
}
|
|
563
|
-
var createVerifyProofResultSuccess = (proofs,
|
|
564
|
+
var createVerifyProofResultSuccess = (proofs, isTeeAttestationVerified) => {
|
|
564
565
|
return {
|
|
565
566
|
isVerified: true,
|
|
566
|
-
|
|
567
|
+
isTeeAttestationVerified,
|
|
567
568
|
error: void 0,
|
|
568
569
|
data: proofs.map(createTrustedDataFromProofData),
|
|
569
570
|
publicData: getPublicDataFromProofs(proofs)
|
|
570
571
|
};
|
|
571
572
|
};
|
|
572
|
-
var createVerifyProofResultFailure = (error,
|
|
573
|
+
var createVerifyProofResultFailure = (error, isTeeAttestationVerified) => {
|
|
573
574
|
return {
|
|
574
575
|
isVerified: false,
|
|
575
|
-
|
|
576
|
+
isTeeAttestationVerified,
|
|
576
577
|
error,
|
|
577
578
|
data: [],
|
|
578
579
|
publicData: []
|
|
@@ -1446,6 +1447,20 @@ function clearDeviceCache() {
|
|
|
1446
1447
|
cachedMobileType = null;
|
|
1447
1448
|
}
|
|
1448
1449
|
|
|
1450
|
+
// src/utils/attestationNonce.ts
|
|
1451
|
+
var import_ethers4 = require("ethers");
|
|
1452
|
+
var ATTESTATION_NONCE_DOMAIN = "RECLAIM_TEE_NONCE_V1";
|
|
1453
|
+
function generateAttestationNonce(appSecret, applicationId, sessionId, timestamp) {
|
|
1454
|
+
const noncePayload = [
|
|
1455
|
+
ATTESTATION_NONCE_DOMAIN,
|
|
1456
|
+
applicationId,
|
|
1457
|
+
sessionId,
|
|
1458
|
+
timestamp,
|
|
1459
|
+
appSecret
|
|
1460
|
+
].join(":");
|
|
1461
|
+
return import_ethers4.ethers.keccak256(import_ethers4.ethers.toUtf8Bytes(noncePayload)).replace(/^0x/i, "");
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1449
1464
|
// src/utils/providerUtils.ts
|
|
1450
1465
|
var logger7 = logger_default.logger;
|
|
1451
1466
|
function fetchProviderHashRequirementsBy(providerId, exactProviderVersionString, allowedTags, proofs) {
|
|
@@ -1673,309 +1688,313 @@ function assertValidateProof(proofs, config) {
|
|
|
1673
1688
|
}
|
|
1674
1689
|
|
|
1675
1690
|
// src/utils/verifyTee.ts
|
|
1676
|
-
var
|
|
1677
|
-
var import_ethers4 = require("ethers");
|
|
1678
|
-
|
|
1679
|
-
// src/utils/amdCerts.ts
|
|
1680
|
-
var AMD_CERTS = {
|
|
1681
|
-
"Milan": `-----BEGIN CERTIFICATE-----
|
|
1682
|
-
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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
56aHvNJRZgbzXDUJvnLr3dYyOvvn/DtKhCSimJynn7Len4ArDVQVwXRPe3hR/asC
|
|
1699
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
d4uQB+fggMtK0qPRthpFtc2SqVCTvHnhxyXqo7GpXMsssgLgKNwaFPe2+Ld5OwPR
|
|
1716
|
-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
|
|
1717
|
-
0YPk
|
|
1718
|
-
-----END CERTIFICATE-----
|
|
1719
|
-
-----BEGIN CERTIFICATE-----
|
|
1720
|
-
MIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC
|
|
1721
|
-
BQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS
|
|
1722
|
-
BgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg
|
|
1723
|
-
Q2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp
|
|
1724
|
-
Y2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy
|
|
1725
|
-
MTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS
|
|
1726
|
-
BgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j
|
|
1727
|
-
ZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG
|
|
1728
|
-
9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg
|
|
1729
|
-
W41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta
|
|
1730
|
-
1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2
|
|
1731
|
-
SzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0
|
|
1732
|
-
60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05
|
|
1733
|
-
gmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg
|
|
1734
|
-
bKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs
|
|
1735
|
-
+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi
|
|
1736
|
-
Qi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ
|
|
1737
|
-
eTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18
|
|
1738
|
-
fHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j
|
|
1739
|
-
WhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI
|
|
1740
|
-
rFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG
|
|
1741
|
-
KWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG
|
|
1742
|
-
SIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI
|
|
1743
|
-
AWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel
|
|
1744
|
-
ETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw
|
|
1745
|
-
STjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK
|
|
1746
|
-
dHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq
|
|
1747
|
-
zT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp
|
|
1748
|
-
KGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e
|
|
1749
|
-
pmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq
|
|
1750
|
-
HnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh
|
|
1751
|
-
3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn
|
|
1752
|
-
JZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH
|
|
1753
|
-
CViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4
|
|
1754
|
-
AFZEAwoKCQ==
|
|
1755
|
-
-----END CERTIFICATE-----`,
|
|
1756
|
-
"Genoa": `-----BEGIN CERTIFICATE-----
|
|
1757
|
-
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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
9YKSmku6JfRecY8CAwEAAaOBozCBoDAdBgNVHQ4EFgQUhEdjn8HQNI9bN2NAKL9z
|
|
1777
|
-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
-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
-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
-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
-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
-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
-
+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
-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
-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
-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
-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
-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
-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
-
xpp089vzqV8JTSJsRzTOzkujOuHUYPKswJ1TvQr5S1C0gPN2qAESnCs7Nf2x82DS
|
|
1791
|
-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
|
|
1792
|
-
2cko
|
|
1793
|
-
-----END CERTIFICATE-----
|
|
1794
|
-
-----BEGIN CERTIFICATE-----
|
|
1795
|
-
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
-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
-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
-
Q2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp
|
|
1799
|
-
Y2VzMRIwEAYDVQQDDAlBUkstR2Vub2EwHhcNMjIwMTI2MTUzNDM3WhcNNDcwMTI2
|
|
1800
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
7SgFjMC9rR07292GQCA7Z7Ulq97JQaWeD2ofGGse5swj4OQfKfVv/zaJUFjvosZO
|
|
1820
|
-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
-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
-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
-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
-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
-
dmQcYcMFQbHhgVzMiyZHGJgcCrQmA7MkTwEIds1wx/HzMcwU4qqNBAoZV7oeIIPx
|
|
1826
|
-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
-
HdS38ijiJmm9vl50RGUeOAXjSuInGR4bsRufeGPB9peTa9BcBOeTWzstqTUB/F/q
|
|
1828
|
-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
|
|
1829
|
-
/wMz1R1BHg==
|
|
1830
|
-
-----END CERTIFICATE-----`
|
|
1831
|
-
};
|
|
1832
|
-
|
|
1833
|
-
// src/utils/verifyTee.ts
|
|
1834
|
-
var crlCache = {};
|
|
1691
|
+
var import_ethers5 = require("ethers");
|
|
1835
1692
|
var logger9 = logger_default.logger;
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1693
|
+
var EXPECTED_ISSUER = "https://confidentialcomputing.googleapis.com";
|
|
1694
|
+
var EXPECTED_HW_MODEL = "GCP_AMD_SEV";
|
|
1695
|
+
var EXPECTED_TEE_PROVIDER = "gcp";
|
|
1696
|
+
var EXPECTED_TEE_TECHNOLOGY = "amd-sev";
|
|
1697
|
+
var SUPPORTED_PROOF_VERSIONS = ["v2", "v3"];
|
|
1698
|
+
var TOKEN_CLOCK_SKEW_S = 60;
|
|
1699
|
+
var NONCE_TIMESTAMP_MAX_SKEW_MS = 10 * 60 * 1e3;
|
|
1700
|
+
var BROWSER_ENVIRONMENT_ERROR = "TEE attestation verification is only supported in non-browser environments. Run verifyTeeAttestation on your server or API route.";
|
|
1701
|
+
function assert(condition, message) {
|
|
1702
|
+
if (!condition) {
|
|
1703
|
+
throw new Error(message);
|
|
1839
1704
|
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1705
|
+
}
|
|
1706
|
+
function isBrowserEnvironment() {
|
|
1707
|
+
if (typeof window !== "undefined" || typeof document !== "undefined") {
|
|
1708
|
+
return true;
|
|
1842
1709
|
}
|
|
1843
|
-
if (typeof
|
|
1844
|
-
return
|
|
1710
|
+
if (typeof navigator !== "undefined" && typeof process === "undefined") {
|
|
1711
|
+
return true;
|
|
1845
1712
|
}
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
let result = "";
|
|
1850
|
-
const chunkSize = 32768;
|
|
1851
|
-
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
1852
|
-
const chunk = bytes.subarray(i, i + chunkSize);
|
|
1853
|
-
result += String.fromCharCode(...chunk);
|
|
1713
|
+
const workerGlobalScope = globalThis.WorkerGlobalScope;
|
|
1714
|
+
if (typeof workerGlobalScope !== "undefined" && typeof self !== "undefined" && self instanceof workerGlobalScope) {
|
|
1715
|
+
return true;
|
|
1854
1716
|
}
|
|
1855
|
-
return
|
|
1717
|
+
return false;
|
|
1856
1718
|
}
|
|
1857
|
-
function
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
result[i] = binary.charCodeAt(i);
|
|
1719
|
+
function assertNonBrowserEnvironment() {
|
|
1720
|
+
if (isBrowserEnvironment()) {
|
|
1721
|
+
throw new Error(BROWSER_ENVIRONMENT_ERROR);
|
|
1861
1722
|
}
|
|
1862
|
-
return result;
|
|
1863
1723
|
}
|
|
1864
|
-
function
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1724
|
+
function normalizeHex(value) {
|
|
1725
|
+
return (value || "").trim().replace(/^0x/i, "").toLowerCase();
|
|
1726
|
+
}
|
|
1727
|
+
function isHex(value) {
|
|
1728
|
+
return /^[0-9a-f]+$/i.test(value);
|
|
1729
|
+
}
|
|
1730
|
+
function decodeBase64Url(input) {
|
|
1731
|
+
const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
1732
|
+
const padded = normalized + "=".repeat((4 - normalized.length % 4) % 4);
|
|
1869
1733
|
if (typeof Buffer !== "undefined") {
|
|
1870
|
-
return new Uint8Array(Buffer.from(
|
|
1734
|
+
return new Uint8Array(Buffer.from(padded, "base64"));
|
|
1735
|
+
}
|
|
1736
|
+
if (typeof atob === "function") {
|
|
1737
|
+
const binary = atob(padded);
|
|
1738
|
+
const bytes = new Uint8Array(binary.length);
|
|
1739
|
+
for (let i = 0; i < binary.length; i += 1) {
|
|
1740
|
+
bytes[i] = binary.charCodeAt(i);
|
|
1741
|
+
}
|
|
1742
|
+
return bytes;
|
|
1871
1743
|
}
|
|
1872
1744
|
throw new Error("Base64 decoding is not supported in this environment");
|
|
1873
1745
|
}
|
|
1874
|
-
function
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1746
|
+
function decodeUtf8(bytes) {
|
|
1747
|
+
return new TextDecoder().decode(bytes);
|
|
1748
|
+
}
|
|
1749
|
+
function decodeJwt(token) {
|
|
1750
|
+
const parts = token.split(".");
|
|
1751
|
+
assert(parts.length === 3, "attestation token is not a JWT");
|
|
1752
|
+
return {
|
|
1753
|
+
header: JSON.parse(decodeUtf8(decodeBase64Url(parts[0]))),
|
|
1754
|
+
payload: JSON.parse(decodeUtf8(decodeBase64Url(parts[1]))),
|
|
1755
|
+
signingInput: `${parts[0]}.${parts[1]}`,
|
|
1756
|
+
signature: decodeBase64Url(parts[2])
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
function getFetch() {
|
|
1760
|
+
const fetchFn = globalThis.fetch;
|
|
1761
|
+
assert(fetchFn, "fetch is not available in this environment");
|
|
1762
|
+
return fetchFn.bind(globalThis);
|
|
1763
|
+
}
|
|
1764
|
+
function getSubtleCrypto() {
|
|
1765
|
+
var _a, _b, _c;
|
|
1766
|
+
if ((_a = globalThis.crypto) == null ? void 0 : _a.subtle) {
|
|
1767
|
+
return globalThis.crypto.subtle;
|
|
1768
|
+
}
|
|
1769
|
+
const nodeCrypto = typeof process !== "undefined" && ((_b = process.versions) == null ? void 0 : _b.node) ? require("crypto") : void 0;
|
|
1770
|
+
if ((_c = nodeCrypto == null ? void 0 : nodeCrypto.webcrypto) == null ? void 0 : _c.subtle) {
|
|
1771
|
+
return nodeCrypto.webcrypto.subtle;
|
|
1772
|
+
}
|
|
1773
|
+
throw new Error("WebCrypto subtle is not available in this environment");
|
|
1774
|
+
}
|
|
1775
|
+
function fetchJson(url) {
|
|
1776
|
+
return __async(this, null, function* () {
|
|
1777
|
+
const response = yield getFetch()(url);
|
|
1778
|
+
if (!response.ok) {
|
|
1779
|
+
throw new Error(`GET ${url} returned ${response.status} ${response.statusText}`);
|
|
1780
|
+
}
|
|
1781
|
+
return response.json();
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
function sha256Hex(input) {
|
|
1785
|
+
return __async(this, null, function* () {
|
|
1786
|
+
const digest = yield getSubtleCrypto().digest("SHA-256", new TextEncoder().encode(input));
|
|
1787
|
+
return Array.from(new Uint8Array(digest), (value) => value.toString(16).padStart(2, "0")).join("");
|
|
1788
|
+
});
|
|
1789
|
+
}
|
|
1790
|
+
var JWKS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
1791
|
+
var cachedJwksUri = null;
|
|
1792
|
+
var cachedJwksKeys = null;
|
|
1793
|
+
var cachedJwksAt = 0;
|
|
1794
|
+
function verifyJwtSignature(token, issuer) {
|
|
1795
|
+
return __async(this, null, function* () {
|
|
1796
|
+
const { header, payload, signingInput, signature } = decodeJwt(token);
|
|
1797
|
+
assert(header.alg === "RS256", `unexpected attestation signing algorithm: ${header.alg}`);
|
|
1798
|
+
assert(typeof header.kid === "string" && header.kid.length > 0, "attestation token kid is missing");
|
|
1799
|
+
const isCacheFresh = cachedJwksKeys && Date.now() - cachedJwksAt < JWKS_CACHE_TTL_MS;
|
|
1800
|
+
if (!isCacheFresh) {
|
|
1801
|
+
const oidc = yield fetchJson(`${issuer}/.well-known/openid-configuration`);
|
|
1802
|
+
assert(typeof (oidc == null ? void 0 : oidc.jwks_uri) === "string" && oidc.jwks_uri.length > 0, "issuer JWKS URI is missing");
|
|
1803
|
+
cachedJwksUri = oidc.jwks_uri;
|
|
1804
|
+
const jwks = yield fetchJson(cachedJwksUri);
|
|
1805
|
+
cachedJwksKeys = (jwks == null ? void 0 : jwks.keys) || [];
|
|
1806
|
+
cachedJwksAt = Date.now();
|
|
1807
|
+
}
|
|
1808
|
+
const jwk = cachedJwksKeys.find((key) => key.kid === header.kid);
|
|
1809
|
+
assert(jwk, `no JWKS key found for kid ${header.kid}`);
|
|
1810
|
+
const cryptoKey = yield getSubtleCrypto().importKey(
|
|
1811
|
+
"jwk",
|
|
1812
|
+
jwk,
|
|
1813
|
+
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
|
|
1814
|
+
false,
|
|
1815
|
+
["verify"]
|
|
1816
|
+
);
|
|
1817
|
+
const isValid = yield getSubtleCrypto().verify(
|
|
1818
|
+
"RSASSA-PKCS1-v1_5",
|
|
1819
|
+
cryptoKey,
|
|
1820
|
+
signature,
|
|
1821
|
+
new TextEncoder().encode(signingInput)
|
|
1822
|
+
);
|
|
1823
|
+
assert(isValid, "JWT signature verification failed");
|
|
1824
|
+
return payload;
|
|
1825
|
+
});
|
|
1826
|
+
}
|
|
1827
|
+
function isNonceContextData(obj) {
|
|
1828
|
+
if (!obj || typeof obj !== "object") return false;
|
|
1829
|
+
const o = obj;
|
|
1830
|
+
return typeof o.applicationId === "string" && o.applicationId.length > 0 && typeof o.sessionId === "string" && o.sessionId.length > 0 && typeof o.timestamp === "string" && o.timestamp.length > 0;
|
|
1831
|
+
}
|
|
1832
|
+
function parseProofContext(proof) {
|
|
1833
|
+
let parsedContext;
|
|
1834
|
+
try {
|
|
1835
|
+
parsedContext = JSON.parse(proof.claimData.context);
|
|
1836
|
+
} catch (e) {
|
|
1837
|
+
throw new Error("Malformed proof: claimData.context is not valid JSON");
|
|
1838
|
+
}
|
|
1839
|
+
if (!parsedContext || typeof parsedContext !== "object") {
|
|
1840
|
+
throw new Error("Malformed proof: claimData.context is not a JSON object");
|
|
1841
|
+
}
|
|
1842
|
+
const ctx = parsedContext;
|
|
1843
|
+
const expectedNonce = ctx.attestationNonce;
|
|
1844
|
+
assert(typeof expectedNonce === "string" && expectedNonce.length > 0, "Proof context is missing attestationNonce");
|
|
1845
|
+
const nonceDataObj = ctx.attestationNonceData;
|
|
1846
|
+
assert(isNonceContextData(nonceDataObj), "Proof context is missing or has invalid attestationNonceData (requires applicationId, sessionId, timestamp)");
|
|
1847
|
+
return { parsedContext: ctx, nonceDataObj, expectedNonce };
|
|
1848
|
+
}
|
|
1849
|
+
function verifyApplicationAndSessionBinding(proof, parsedContext, nonceDataObj, expectedApplicationId) {
|
|
1850
|
+
var _a;
|
|
1851
|
+
const { applicationId, sessionId, timestamp } = nonceDataObj;
|
|
1852
|
+
if (expectedApplicationId) {
|
|
1853
|
+
assert(
|
|
1854
|
+
applicationId.toLowerCase() === expectedApplicationId.toLowerCase(),
|
|
1855
|
+
`Application ID Mismatch! Expected ${expectedApplicationId}, but proof context contains ${applicationId}`
|
|
1856
|
+
);
|
|
1857
|
+
}
|
|
1858
|
+
let parsedParameters = {};
|
|
1859
|
+
if (proof.claimData.parameters) {
|
|
1860
|
+
try {
|
|
1861
|
+
const parsed = JSON.parse(proof.claimData.parameters);
|
|
1862
|
+
parsedParameters = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
1863
|
+
} catch (e) {
|
|
1864
|
+
throw new Error("Malformed proof: claimData.parameters is not valid JSON");
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
const contextSessionId = parsedContext == null ? void 0 : parsedContext.reclaimSessionId;
|
|
1868
|
+
const parameterSessionId = (_a = parsedParameters == null ? void 0 : parsedParameters.proxySessionId) != null ? _a : parsedParameters == null ? void 0 : parsedParameters.sessionId;
|
|
1869
|
+
if (contextSessionId && contextSessionId.toString() !== sessionId.toString()) {
|
|
1870
|
+
throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof context contains reclaimSessionId=${contextSessionId}`);
|
|
1871
|
+
}
|
|
1872
|
+
if (parameterSessionId && parameterSessionId.toString() !== sessionId.toString()) {
|
|
1873
|
+
throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof parameters contain ${parameterSessionId}`);
|
|
1874
|
+
}
|
|
1875
|
+
if (!contextSessionId && !parameterSessionId) {
|
|
1876
|
+
throw new Error("Proof is missing reclaimSessionId and proxySessionId/sessionId for attestation nonce verification");
|
|
1877
|
+
}
|
|
1878
|
+
const claimTimestampMs = proof.claimData.timestampS * 1e3;
|
|
1879
|
+
const nonceTimestampMs = parseInt(timestamp, 10);
|
|
1880
|
+
const diffMs = Math.abs(claimTimestampMs - nonceTimestampMs);
|
|
1881
|
+
if (diffMs > NONCE_TIMESTAMP_MAX_SKEW_MS) {
|
|
1882
|
+
throw new Error(`Timestamp Skew Too Large! claimData.timestampS and attestationNonce timestamp differ by ${Math.round(diffMs / 1e3)}s (limit: 600s)`);
|
|
1879
1883
|
}
|
|
1880
|
-
return hex;
|
|
1881
1884
|
}
|
|
1882
|
-
function
|
|
1883
|
-
const
|
|
1884
|
-
const
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1885
|
+
function verifyNonceMaterial(expectedNonce, nonceDataObj, expectedAppSecret) {
|
|
1886
|
+
const cleanExpectedNonce = normalizeHex(expectedNonce);
|
|
1887
|
+
const { applicationId, sessionId, timestamp } = nonceDataObj;
|
|
1888
|
+
assert(cleanExpectedNonce.length > 0, "Proof context attestationNonce is empty");
|
|
1889
|
+
assert(isHex(cleanExpectedNonce), "Proof context attestationNonce is not valid hex");
|
|
1890
|
+
if (expectedAppSecret) {
|
|
1891
|
+
const recomputedNonce = generateAttestationNonce(expectedAppSecret, applicationId, sessionId, timestamp);
|
|
1892
|
+
assert(
|
|
1893
|
+
recomputedNonce === cleanExpectedNonce,
|
|
1894
|
+
"Attestation nonce verification failed: app secret, application ID, session ID, or timestamp do not match"
|
|
1895
|
+
);
|
|
1896
|
+
return;
|
|
1897
|
+
}
|
|
1898
|
+
if (cleanExpectedNonce.length > 74) {
|
|
1899
|
+
const legacyNonceData = `${applicationId}:${sessionId}:${timestamp}`;
|
|
1900
|
+
const nonceMsg = import_ethers5.ethers.getBytes(import_ethers5.ethers.keccak256(new TextEncoder().encode(legacyNonceData)));
|
|
1901
|
+
const recoveredAddress = import_ethers5.ethers.verifyMessage(
|
|
1902
|
+
nonceMsg,
|
|
1903
|
+
expectedNonce.startsWith("0x") ? expectedNonce : `0x${expectedNonce}`
|
|
1904
|
+
);
|
|
1905
|
+
assert(
|
|
1906
|
+
recoveredAddress.toLowerCase() === applicationId.toLowerCase(),
|
|
1907
|
+
`Nonce signature verification failed: recovered ${recoveredAddress}, expected ${applicationId}`
|
|
1908
|
+
);
|
|
1909
|
+
return;
|
|
1889
1910
|
}
|
|
1890
|
-
|
|
1911
|
+
throw new Error("App secret is required to verify hash-based attestation nonces");
|
|
1891
1912
|
}
|
|
1892
|
-
function
|
|
1893
|
-
const
|
|
1894
|
-
|
|
1895
|
-
|
|
1913
|
+
function assertTokenFresh(claims) {
|
|
1914
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1915
|
+
if (typeof claims.nbf === "number" && now + TOKEN_CLOCK_SKEW_S < claims.nbf) {
|
|
1916
|
+
throw new Error(`Attestation token is not valid before ${claims.nbf}`);
|
|
1917
|
+
}
|
|
1918
|
+
if (typeof claims.exp === "number" && now - TOKEN_CLOCK_SKEW_S > claims.exp) {
|
|
1919
|
+
throw new Error(`Attestation token expired at ${claims.exp}`);
|
|
1920
|
+
}
|
|
1921
|
+
if (typeof claims.iat === "number" && claims.iat > now + TOKEN_CLOCK_SKEW_S) {
|
|
1922
|
+
throw new Error(`Attestation token issued-at ${claims.iat} is in the future`);
|
|
1923
|
+
}
|
|
1896
1924
|
}
|
|
1897
|
-
function
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1925
|
+
function assertAudienceClaim(aud) {
|
|
1926
|
+
if (typeof aud === "string") {
|
|
1927
|
+
assert(aud.length > 0, "attestation token audience is empty");
|
|
1928
|
+
return;
|
|
1929
|
+
}
|
|
1930
|
+
if (Array.isArray(aud)) {
|
|
1931
|
+
assert(aud.length > 0, "attestation token audience is empty");
|
|
1932
|
+
assert(aud.every((entry) => typeof entry === "string" && entry.length > 0), "attestation token audience contains invalid entries");
|
|
1933
|
+
return;
|
|
1934
|
+
}
|
|
1935
|
+
throw new Error("attestation token audience is missing");
|
|
1901
1936
|
}
|
|
1902
|
-
|
|
1903
|
-
var getSubtleCrypto = () => {
|
|
1937
|
+
function getProofVersion(teeAttestation) {
|
|
1904
1938
|
var _a;
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
const
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
notBefore,
|
|
1943
|
-
notAfter
|
|
1944
|
-
};
|
|
1939
|
+
return (_a = teeAttestation.proof_version) != null ? _a : teeAttestation.proofVersion;
|
|
1940
|
+
}
|
|
1941
|
+
function assertProofShape(teeAttestation) {
|
|
1942
|
+
var _a, _b, _c;
|
|
1943
|
+
if (teeAttestation.error) {
|
|
1944
|
+
throw new Error(`${teeAttestation.error.code}: ${teeAttestation.error.message}`);
|
|
1945
|
+
}
|
|
1946
|
+
const proofVersion = getProofVersion(teeAttestation);
|
|
1947
|
+
assert(typeof proofVersion === "string" && SUPPORTED_PROOF_VERSIONS.includes(proofVersion), `unexpected proof version: ${proofVersion}`);
|
|
1948
|
+
assert(teeAttestation.tee_provider === EXPECTED_TEE_PROVIDER, `unexpected tee provider: ${teeAttestation.tee_provider}`);
|
|
1949
|
+
assert(teeAttestation.tee_technology === EXPECTED_TEE_TECHNOLOGY, `unexpected tee technology: ${teeAttestation.tee_technology}`);
|
|
1950
|
+
assert(typeof teeAttestation.nonce === "string" && teeAttestation.nonce.length > 0, "tee attestation nonce missing");
|
|
1951
|
+
assert(typeof teeAttestation.timestamp === "string" && teeAttestation.timestamp.length > 0, "tee attestation timestamp missing");
|
|
1952
|
+
assert(!Number.isNaN(Date.parse(teeAttestation.timestamp)), "tee attestation timestamp is invalid");
|
|
1953
|
+
assert(typeof ((_a = teeAttestation.workload) == null ? void 0 : _a.image_digest) === "string" && teeAttestation.workload.image_digest.length > 0, "workload image digest missing");
|
|
1954
|
+
assert(typeof ((_b = teeAttestation.verifier) == null ? void 0 : _b.image_digest) === "string" && teeAttestation.verifier.image_digest.length > 0, "verifier image digest missing");
|
|
1955
|
+
assert(typeof ((_c = teeAttestation.attestation) == null ? void 0 : _c.token) === "string" && teeAttestation.attestation.token.length > 0, "attestation token missing");
|
|
1956
|
+
}
|
|
1957
|
+
function computeDigestBinding(teeAttestation) {
|
|
1958
|
+
return __async(this, null, function* () {
|
|
1959
|
+
const proofVersion = getProofVersion(teeAttestation);
|
|
1960
|
+
if (proofVersion === "v3") {
|
|
1961
|
+
assert(typeof teeAttestation.workload.container_name === "string" && teeAttestation.workload.container_name.length > 0, "workload container name missing");
|
|
1962
|
+
assert(typeof teeAttestation.verifier.container_name === "string" && teeAttestation.verifier.container_name.length > 0, "verifier container name missing");
|
|
1963
|
+
return sha256Hex([
|
|
1964
|
+
"v3",
|
|
1965
|
+
`workload.container_name=${teeAttestation.workload.container_name}`,
|
|
1966
|
+
`workload.image_digest=${teeAttestation.workload.image_digest}`,
|
|
1967
|
+
`verifier.container_name=${teeAttestation.verifier.container_name}`,
|
|
1968
|
+
`verifier.image_digest=${teeAttestation.verifier.image_digest}`
|
|
1969
|
+
].join("\n"));
|
|
1970
|
+
}
|
|
1971
|
+
return sha256Hex(
|
|
1972
|
+
`${teeAttestation.workload.image_digest}
|
|
1973
|
+
${teeAttestation.verifier.image_digest}`
|
|
1974
|
+
);
|
|
1975
|
+
});
|
|
1945
1976
|
}
|
|
1946
|
-
function
|
|
1977
|
+
function verifyGcpClaims(teeAttestation, expectedNonce) {
|
|
1947
1978
|
return __async(this, null, function* () {
|
|
1948
|
-
|
|
1949
|
-
const
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
importParams = { name: "ECDSA", namedCurve: "P-384" };
|
|
1961
|
-
verifyParams = { name: "ECDSA", hash: "SHA-384" };
|
|
1962
|
-
} else {
|
|
1963
|
-
importParams = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" };
|
|
1964
|
-
verifyParams = { name: "RSASSA-PKCS1-v1_5" };
|
|
1965
|
-
}
|
|
1966
|
-
const key = yield cryptoSubtle.importKey("spki", spkiBuf, importParams, false, ["verify"]);
|
|
1967
|
-
const isValid = yield cryptoSubtle.verify(verifyParams, key, signature, data);
|
|
1968
|
-
if (!isValid) throw new Error(`Signature verification failed (OID: ${sigAlgOid}, ImportParams: ${JSON.stringify(importParams)})`);
|
|
1979
|
+
var _a;
|
|
1980
|
+
const claims = yield verifyJwtSignature(teeAttestation.attestation.token, EXPECTED_ISSUER);
|
|
1981
|
+
assert(claims.iss === EXPECTED_ISSUER, `unexpected issuer: ${claims.iss}`);
|
|
1982
|
+
assertAudienceClaim(claims.aud);
|
|
1983
|
+
assert(Array.isArray(claims.eat_nonce), "eat_nonce claim missing");
|
|
1984
|
+
const digestBinding = yield computeDigestBinding(teeAttestation);
|
|
1985
|
+
assert(claims.eat_nonce.includes(expectedNonce), "request nonce is not present in attestation token");
|
|
1986
|
+
assert(claims.eat_nonce.includes(digestBinding), "digest-binding nonce is not present in attestation token");
|
|
1987
|
+
assert(claims.hwmodel === EXPECTED_HW_MODEL, `unexpected hwmodel: ${claims.hwmodel}`);
|
|
1988
|
+
assert(claims.secboot === true, "secure boot claim is not true");
|
|
1989
|
+
assert((_a = claims.submods) == null ? void 0 : _a.gce, "gce submod claim missing");
|
|
1990
|
+
assertTokenFresh(claims);
|
|
1969
1991
|
});
|
|
1970
1992
|
}
|
|
1971
|
-
|
|
1972
|
-
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjiL30OjPuxa+GC1I7SAcBv2u2pMt
|
|
1973
|
-
h9WbP33IvB3eFww+C1hoW0fwdZPiq4FxBtKNiZuFpmYuFngW/nJteBu9kQ==
|
|
1974
|
-
-----END PUBLIC KEY-----
|
|
1975
|
-
`;
|
|
1976
|
-
function verifyTeeAttestation(proof, expectedApplicationId) {
|
|
1993
|
+
function verifyTeeAttestation(proof, appSecret) {
|
|
1977
1994
|
return __async(this, null, function* () {
|
|
1995
|
+
assertNonBrowserEnvironment();
|
|
1978
1996
|
try {
|
|
1997
|
+
const appId = new import_ethers5.ethers.Wallet(appSecret).address;
|
|
1979
1998
|
let teeAttestation = proof.teeAttestation;
|
|
1980
1999
|
if (!teeAttestation) {
|
|
1981
2000
|
throw new Error("Missing teeAttestation in proof");
|
|
@@ -1983,414 +2002,45 @@ function verifyTeeAttestation(proof, expectedApplicationId) {
|
|
|
1983
2002
|
if (typeof teeAttestation === "string") {
|
|
1984
2003
|
teeAttestation = JSON.parse(teeAttestation);
|
|
1985
2004
|
}
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
}
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
}
|
|
1998
|
-
if (teeAttestation.nonce !== expectedNonceSignature) {
|
|
1999
|
-
throw new Error(`Nonce Mismatch! Expected signature ${expectedNonceSignature}, got ${teeAttestation.nonce}`);
|
|
2000
|
-
}
|
|
2001
|
-
const { applicationId, sessionId, timestamp } = nonceDataObj;
|
|
2002
|
-
if (expectedApplicationId && applicationId.toLowerCase() !== expectedApplicationId.toLowerCase()) {
|
|
2003
|
-
throw new Error(`Application ID Mismatch! Expected ${expectedApplicationId}, but proof context contains ${applicationId}`);
|
|
2004
|
-
}
|
|
2005
|
-
const expectedNonceData = `${applicationId}:${sessionId}:${timestamp}`;
|
|
2006
|
-
const nonceMsg = import_ethers4.ethers.getBytes(import_ethers4.ethers.keccak256(new TextEncoder().encode(expectedNonceData)));
|
|
2007
|
-
const recoveredAddress = import_ethers4.ethers.verifyMessage(nonceMsg, expectedNonceSignature);
|
|
2008
|
-
if (recoveredAddress.toLowerCase() !== applicationId.toLowerCase()) {
|
|
2009
|
-
throw new Error(`Nonce signature verification failed: recovered ${recoveredAddress}, expected ${applicationId}`);
|
|
2010
|
-
}
|
|
2011
|
-
try {
|
|
2012
|
-
const context = JSON.parse(proof.claimData.context);
|
|
2013
|
-
const paramSessionId = context.attestationNonceData.sessionId;
|
|
2014
|
-
if (!paramSessionId) {
|
|
2015
|
-
throw new Error(`Proof parameters are missing proxySessionId or sessionId`);
|
|
2016
|
-
}
|
|
2017
|
-
if (paramSessionId.toString() !== sessionId.toString()) {
|
|
2018
|
-
throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof parameters contain ${paramSessionId}`);
|
|
2019
|
-
}
|
|
2020
|
-
const claimTimestampMs = proof.claimData.timestampS * 1e3;
|
|
2021
|
-
const nonceTimestampMs = parseInt(timestamp, 10);
|
|
2022
|
-
const diffMs = Math.abs(claimTimestampMs - nonceTimestampMs);
|
|
2023
|
-
const TEN_MINUTES_MS = 10 * 60 * 1e3;
|
|
2024
|
-
if (diffMs > TEN_MINUTES_MS) {
|
|
2025
|
-
throw new Error(`Timestamp Skew Too Large! claimData.timestampS and attestationNonce timestamp differ by ${Math.round(diffMs / 1e3)}s (limit: 600s)`);
|
|
2026
|
-
}
|
|
2027
|
-
} catch (e) {
|
|
2028
|
-
if (e instanceof Error && (e.message.includes("Session ID Mismatch!") || e.message.includes("Timestamp Skew"))) {
|
|
2029
|
-
throw e;
|
|
2030
|
-
}
|
|
2031
|
-
throw new Error(`Failed to cross-verify session ID: ${e.message}`);
|
|
2032
|
-
}
|
|
2033
|
-
const reportBuffer = base64ToUint8Array(teeAttestation.snp_report);
|
|
2034
|
-
const report = parseAttestationReport(reportBuffer);
|
|
2035
|
-
if (report.isDebugEnabled) {
|
|
2036
|
-
throw new Error("POLICY CHECK FAILED: Debug mode is ALLOWED. Environment is compromised.");
|
|
2037
|
-
}
|
|
2038
|
-
const certBuffer = base64ToUint8Array(teeAttestation.vlek_cert);
|
|
2039
|
-
yield verifyAMDChain(certBuffer);
|
|
2040
|
-
verifyTCB(certBuffer, report);
|
|
2041
|
-
yield verifyHardwareSignature(reportBuffer, certBuffer);
|
|
2042
|
-
yield verifyReportData(teeAttestation, proof.claimData.context, report);
|
|
2043
|
-
return true;
|
|
2005
|
+
assertProofShape(teeAttestation);
|
|
2006
|
+
const { parsedContext, nonceDataObj, expectedNonce } = parseProofContext(proof);
|
|
2007
|
+
verifyApplicationAndSessionBinding(proof, parsedContext, nonceDataObj, appId);
|
|
2008
|
+
verifyNonceMaterial(expectedNonce, nonceDataObj, appSecret);
|
|
2009
|
+
const cleanExpectedNonce = normalizeHex(expectedNonce);
|
|
2010
|
+
const cleanTeeNonce = normalizeHex(teeAttestation.nonce);
|
|
2011
|
+
assert(cleanTeeNonce.length > 0, "TEE attestation nonce is empty");
|
|
2012
|
+
assert(isHex(cleanTeeNonce), "TEE attestation nonce is not valid hex");
|
|
2013
|
+
assert(cleanTeeNonce === cleanExpectedNonce, `Nonce Mismatch! Expected ${cleanExpectedNonce}, got ${cleanTeeNonce}`);
|
|
2014
|
+
yield verifyGcpClaims(teeAttestation, cleanExpectedNonce);
|
|
2015
|
+
return { isVerified: true };
|
|
2044
2016
|
} catch (error) {
|
|
2045
2017
|
logger9.error("TEE attestation verification failed:", error);
|
|
2046
|
-
return
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
}
|
|
2050
|
-
function parseAttestationReport(buffer) {
|
|
2051
|
-
if (buffer.length < 1e3) {
|
|
2052
|
-
throw new Error(`Report buffer is too small: ${buffer.length} bytes`);
|
|
2053
|
-
}
|
|
2054
|
-
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
2055
|
-
const policy = view.getBigUint64(8, true);
|
|
2056
|
-
const isDebugEnabled = (policy & BigInt(1) << BigInt(19)) !== BigInt(0);
|
|
2057
|
-
const reported_tcb = {
|
|
2058
|
-
bootloader: buffer[56],
|
|
2059
|
-
tee: buffer[57],
|
|
2060
|
-
snp: buffer[62],
|
|
2061
|
-
microcode: buffer[63]
|
|
2062
|
-
};
|
|
2063
|
-
const reportData = arrayBufferToHex(buffer.subarray(80, 144));
|
|
2064
|
-
return { policy, isDebugEnabled, reported_tcb, reportData };
|
|
2065
|
-
}
|
|
2066
|
-
function getExtValue(certAsn1, oidString) {
|
|
2067
|
-
const tbsCert = certAsn1.value[0];
|
|
2068
|
-
if (!tbsCert || !tbsCert.value) return null;
|
|
2069
|
-
const extBlockWrapper = tbsCert.value.find((node) => node.tagClass === import_node_forge.default.asn1.Class.CONTEXT_SPECIFIC && node.type === 3);
|
|
2070
|
-
if (!extBlockWrapper || !extBlockWrapper.value || !extBlockWrapper.value.length) return null;
|
|
2071
|
-
const extSequence = extBlockWrapper.value[0];
|
|
2072
|
-
for (const ext of extSequence.value) {
|
|
2073
|
-
const extIdAsn1 = ext.value[0];
|
|
2074
|
-
const extIdStr = import_node_forge.default.asn1.derToOid(extIdAsn1.value);
|
|
2075
|
-
if (extIdStr === oidString) {
|
|
2076
|
-
const extValueAsn1 = ext.value[ext.value.length - 1];
|
|
2077
|
-
const rawOctetStringBytes = extValueAsn1.value;
|
|
2078
|
-
try {
|
|
2079
|
-
const innerAsn1 = import_node_forge.default.asn1.fromDer(import_node_forge.default.util.createBuffer(rawOctetStringBytes));
|
|
2080
|
-
if (innerAsn1.type === 2) {
|
|
2081
|
-
const bytes = innerAsn1.value;
|
|
2082
|
-
if (typeof bytes === "string" && bytes.length > 0) {
|
|
2083
|
-
return bytes.charCodeAt(bytes.length - 1);
|
|
2084
|
-
} else {
|
|
2085
|
-
throw new Error(`Extension ${oidString} INTEGER value is empty or invalid`);
|
|
2086
|
-
}
|
|
2087
|
-
} else {
|
|
2088
|
-
throw new Error(`Extension ${oidString} does not contain an INTEGER, found type ${innerAsn1.type}`);
|
|
2089
|
-
}
|
|
2090
|
-
} catch (e) {
|
|
2091
|
-
throw new Error(`Failed to strictly parse AMD TCB extension ${oidString}: ${e.message}`);
|
|
2092
|
-
}
|
|
2093
|
-
}
|
|
2094
|
-
}
|
|
2095
|
-
return null;
|
|
2096
|
-
}
|
|
2097
|
-
function verifyTCB(vlekCertBuffer, report) {
|
|
2098
|
-
const certAsn1 = import_node_forge.default.asn1.fromDer(import_node_forge.default.util.createBuffer(uint8ArrayToBinaryString(vlekCertBuffer)));
|
|
2099
|
-
const OID_BOOTLOADER = "1.3.6.1.4.1.3704.1.3.1";
|
|
2100
|
-
const OID_TEE = "1.3.6.1.4.1.3704.1.3.2";
|
|
2101
|
-
const OID_SNP = "1.3.6.1.4.1.3704.1.3.3";
|
|
2102
|
-
const OID_MICROCODE = "1.3.6.1.4.1.3704.1.3.8";
|
|
2103
|
-
const certTcb = {
|
|
2104
|
-
bootloader: getExtValue(certAsn1, OID_BOOTLOADER),
|
|
2105
|
-
tee: getExtValue(certAsn1, OID_TEE),
|
|
2106
|
-
snp: getExtValue(certAsn1, OID_SNP),
|
|
2107
|
-
microcode: getExtValue(certAsn1, OID_MICROCODE)
|
|
2108
|
-
};
|
|
2109
|
-
if (certTcb.bootloader !== null && report.reported_tcb.bootloader < certTcb.bootloader) {
|
|
2110
|
-
throw new Error(`TCB Downgrade! Bootloader reported ${report.reported_tcb.bootloader}, but certificate requires ${certTcb.bootloader}`);
|
|
2111
|
-
}
|
|
2112
|
-
if (certTcb.tee !== null && report.reported_tcb.tee < certTcb.tee) {
|
|
2113
|
-
throw new Error(`TCB Downgrade! TEE reported ${report.reported_tcb.tee}, but certificate requires ${certTcb.tee}`);
|
|
2114
|
-
}
|
|
2115
|
-
if (certTcb.snp !== null && report.reported_tcb.snp < certTcb.snp) {
|
|
2116
|
-
throw new Error(`TCB Downgrade! SNP reported ${report.reported_tcb.snp}, but certificate requires ${certTcb.snp}`);
|
|
2117
|
-
}
|
|
2118
|
-
if (certTcb.microcode !== null && report.reported_tcb.microcode < certTcb.microcode) {
|
|
2119
|
-
throw new Error(`TCB Downgrade! Microcode reported ${report.reported_tcb.microcode}, but certificate requires ${certTcb.microcode}`);
|
|
2120
|
-
}
|
|
2121
|
-
}
|
|
2122
|
-
function parseAsn1Time(node) {
|
|
2123
|
-
const s = node.value;
|
|
2124
|
-
if (node.type === import_node_forge.default.asn1.Type.UTCTIME) {
|
|
2125
|
-
const yr = parseInt(s.substring(0, 2), 10);
|
|
2126
|
-
return new Date(Date.UTC(
|
|
2127
|
-
yr >= 50 ? 1900 + yr : 2e3 + yr,
|
|
2128
|
-
parseInt(s.substring(2, 4), 10) - 1,
|
|
2129
|
-
parseInt(s.substring(4, 6), 10),
|
|
2130
|
-
parseInt(s.substring(6, 8), 10),
|
|
2131
|
-
parseInt(s.substring(8, 10), 10),
|
|
2132
|
-
parseInt(s.substring(10, 12), 10)
|
|
2133
|
-
));
|
|
2134
|
-
} else {
|
|
2135
|
-
return new Date(Date.UTC(
|
|
2136
|
-
parseInt(s.substring(0, 4), 10),
|
|
2137
|
-
parseInt(s.substring(4, 6), 10) - 1,
|
|
2138
|
-
parseInt(s.substring(6, 8), 10),
|
|
2139
|
-
parseInt(s.substring(8, 10), 10),
|
|
2140
|
-
parseInt(s.substring(10, 12), 10),
|
|
2141
|
-
parseInt(s.substring(12, 14), 10)
|
|
2142
|
-
));
|
|
2143
|
-
}
|
|
2144
|
-
}
|
|
2145
|
-
function verifyCRL(crlBuf, arkPem, vlekSerial) {
|
|
2146
|
-
return __async(this, null, function* () {
|
|
2147
|
-
const crlAsn1 = import_node_forge.default.asn1.fromDer(import_node_forge.default.util.createBuffer(uint8ArrayToBinaryString(crlBuf)));
|
|
2148
|
-
if (!Array.isArray(crlAsn1.value) || crlAsn1.value.length < 3) {
|
|
2149
|
-
throw new Error("CRL ASN.1 structure is invalid: expected SEQUENCE with TBSCertList, AlgorithmIdentifier, BIT STRING");
|
|
2150
|
-
}
|
|
2151
|
-
const tbsAsn1 = crlAsn1.value[0];
|
|
2152
|
-
const sigBitsAsn1 = crlAsn1.value[2];
|
|
2153
|
-
if (!Array.isArray(tbsAsn1.value)) {
|
|
2154
|
-
throw new Error("CRL TBSCertList is not a valid SEQUENCE");
|
|
2155
|
-
}
|
|
2156
|
-
const tbsFields = tbsAsn1.value;
|
|
2157
|
-
let fi = 0;
|
|
2158
|
-
if (fi < tbsFields.length && tbsFields[fi].tagClass === import_node_forge.default.asn1.Class.UNIVERSAL && tbsFields[fi].type === import_node_forge.default.asn1.Type.INTEGER) {
|
|
2159
|
-
fi++;
|
|
2160
|
-
}
|
|
2161
|
-
if (fi < tbsFields.length) fi++;
|
|
2162
|
-
if (fi >= tbsFields.length) throw new Error("CRL TBSCertList missing issuer");
|
|
2163
|
-
const issuerAsn1 = tbsFields[fi++];
|
|
2164
|
-
if (fi >= tbsFields.length) throw new Error("CRL TBSCertList missing thisUpdate");
|
|
2165
|
-
const thisUpdateAsn1 = tbsFields[fi++];
|
|
2166
|
-
let nextUpdateAsn1 = null;
|
|
2167
|
-
if (fi < tbsFields.length && tbsFields[fi].tagClass === import_node_forge.default.asn1.Class.UNIVERSAL && (tbsFields[fi].type === import_node_forge.default.asn1.Type.UTCTIME || tbsFields[fi].type === import_node_forge.default.asn1.Type.GENERALIZEDTIME)) {
|
|
2168
|
-
nextUpdateAsn1 = tbsFields[fi++];
|
|
2169
|
-
}
|
|
2170
|
-
let revokedSeq = null;
|
|
2171
|
-
if (fi < tbsFields.length && tbsFields[fi].tagClass === import_node_forge.default.asn1.Class.UNIVERSAL && tbsFields[fi].type === import_node_forge.default.asn1.Type.SEQUENCE) {
|
|
2172
|
-
revokedSeq = tbsFields[fi];
|
|
2173
|
-
}
|
|
2174
|
-
const now = /* @__PURE__ */ new Date();
|
|
2175
|
-
const thisUpdate = parseAsn1Time(thisUpdateAsn1);
|
|
2176
|
-
if (thisUpdate > now) {
|
|
2177
|
-
throw new Error(`CRL is not yet valid: thisUpdate is ${thisUpdate.toISOString()}`);
|
|
2178
|
-
}
|
|
2179
|
-
if (nextUpdateAsn1) {
|
|
2180
|
-
const nextUpdate = parseAsn1Time(nextUpdateAsn1);
|
|
2181
|
-
if (nextUpdate < now) {
|
|
2182
|
-
throw new Error(`CRL has expired: nextUpdate was ${nextUpdate.toISOString()}`);
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
const crlIssuerDer = import_node_forge.default.asn1.toDer(issuerAsn1).getBytes();
|
|
2186
|
-
const arkForgeCert = import_node_forge.default.pki.certificateFromPem(arkPem);
|
|
2187
|
-
const arkCertAsn1 = import_node_forge.default.pki.certificateToAsn1(arkForgeCert);
|
|
2188
|
-
const arkSubjectAsn1 = arkCertAsn1.value[0].value[5];
|
|
2189
|
-
const arkSubjectDer = import_node_forge.default.asn1.toDer(arkSubjectAsn1).getBytes();
|
|
2190
|
-
if (crlIssuerDer !== arkSubjectDer) {
|
|
2191
|
-
throw new Error("CRL issuer does not match AMD ARK certificate subject \u2014 chain mismatch");
|
|
2192
|
-
}
|
|
2193
|
-
const tbsDerBuf = binaryStringToUint8Array(import_node_forge.default.asn1.toDer(tbsAsn1).getBytes());
|
|
2194
|
-
const sigRaw = typeof sigBitsAsn1.value === "string" ? sigBitsAsn1.value : "";
|
|
2195
|
-
const sigBuf = binaryStringToUint8Array(sigRaw.substring(1));
|
|
2196
|
-
const cryptoSubtle = getSubtleCrypto();
|
|
2197
|
-
const spkiBuf = binaryStringToUint8Array(
|
|
2198
|
-
import_node_forge.default.asn1.toDer(import_node_forge.default.pki.publicKeyToAsn1(arkForgeCert.publicKey)).getBytes()
|
|
2199
|
-
);
|
|
2200
|
-
const arkCryptoKey = yield cryptoSubtle.importKey(
|
|
2201
|
-
"spki",
|
|
2202
|
-
spkiBuf,
|
|
2203
|
-
{ name: "RSA-PSS", hash: "SHA-384" },
|
|
2204
|
-
false,
|
|
2205
|
-
["verify"]
|
|
2206
|
-
);
|
|
2207
|
-
const isValid = yield cryptoSubtle.verify(
|
|
2208
|
-
{ name: "RSA-PSS", saltLength: 48 },
|
|
2209
|
-
// SHA-384 salt length is 48
|
|
2210
|
-
arkCryptoKey,
|
|
2211
|
-
sigBuf,
|
|
2212
|
-
tbsDerBuf
|
|
2213
|
-
);
|
|
2214
|
-
if (!isValid) {
|
|
2215
|
-
throw new Error("CRL signature is INVALID \u2014 the CRL may be tampered or forged");
|
|
2216
|
-
}
|
|
2217
|
-
const targetSerial = normalizeSerial(vlekSerial);
|
|
2218
|
-
if (revokedSeq && Array.isArray(revokedSeq.value)) {
|
|
2219
|
-
for (const entry of revokedSeq.value) {
|
|
2220
|
-
if (!Array.isArray(entry.value) || entry.value.length < 2) continue;
|
|
2221
|
-
const serialAsn1 = entry.value[0];
|
|
2222
|
-
if (serialAsn1.type !== import_node_forge.default.asn1.Type.INTEGER || typeof serialAsn1.value !== "string") continue;
|
|
2223
|
-
const serialHex = import_node_forge.default.util.bytesToHex(serialAsn1.value);
|
|
2224
|
-
if (normalizeSerial(serialHex) === targetSerial) {
|
|
2225
|
-
throw new Error("\u{1F6A8} VLEK Certificate is REVOKED per AMD CRL! This hardware may be compromised.");
|
|
2226
|
-
}
|
|
2227
|
-
}
|
|
2018
|
+
return {
|
|
2019
|
+
isVerified: false,
|
|
2020
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2021
|
+
};
|
|
2228
2022
|
}
|
|
2229
2023
|
});
|
|
2230
2024
|
}
|
|
2231
|
-
function
|
|
2232
|
-
const now = Date.now();
|
|
2233
|
-
if (cert.notBefore && now < cert.notBefore.getTime()) {
|
|
2234
|
-
throw new Error(`${label} certificate is not yet valid (notBefore: ${cert.notBefore.toISOString()})`);
|
|
2235
|
-
}
|
|
2236
|
-
if (cert.notAfter && now > cert.notAfter.getTime()) {
|
|
2237
|
-
throw new Error(`${label} certificate expired on ${cert.notAfter.toISOString()}`);
|
|
2238
|
-
}
|
|
2239
|
-
}
|
|
2240
|
-
function verifyAMDChain(vlekCertBuffer) {
|
|
2025
|
+
function runTeeVerification(proofs, config) {
|
|
2241
2026
|
return __async(this, null, function* () {
|
|
2242
|
-
const
|
|
2243
|
-
|
|
2244
|
-
const vlek = parseCert(vlekCertBuffer);
|
|
2245
|
-
assertCertValidity("VLEK", vlek);
|
|
2246
|
-
for (const processor of processors) {
|
|
2247
|
-
let matchedChain = false;
|
|
2027
|
+
const hasTeeData = proofs.every((proof) => {
|
|
2028
|
+
if (proof.teeAttestation) return true;
|
|
2248
2029
|
try {
|
|
2249
|
-
const
|
|
2250
|
-
|
|
2251
|
-
const certs = chainPem.split("-----END CERTIFICATE-----").map((c) => c.trim()).filter((c) => c.length > 0).map((c) => c + "\n-----END CERTIFICATE-----\n");
|
|
2252
|
-
const askCert = import_node_forge.default.pki.certificateFromPem(certs[0]);
|
|
2253
|
-
const arkCert = import_node_forge.default.pki.certificateFromPem(certs[1]);
|
|
2254
|
-
const askDer = import_node_forge.default.asn1.toDer(import_node_forge.default.pki.certificateToAsn1(askCert)).getBytes();
|
|
2255
|
-
const arkDer = import_node_forge.default.asn1.toDer(import_node_forge.default.pki.certificateToAsn1(arkCert)).getBytes();
|
|
2256
|
-
const ask = parseCert(binaryStringToUint8Array(askDer));
|
|
2257
|
-
const ark = parseCert(binaryStringToUint8Array(arkDer));
|
|
2258
|
-
assertCertValidity("ASK", ask);
|
|
2259
|
-
assertCertValidity("ARK", ark);
|
|
2260
|
-
try {
|
|
2261
|
-
yield verifySignature(certs[1], ark.tbsDer, ark.signature, ark.sigAlgOid);
|
|
2262
|
-
} catch (e) {
|
|
2263
|
-
throw new Error(`AMD ARK self-signature verification failed: ${e.message}`);
|
|
2264
|
-
}
|
|
2265
|
-
try {
|
|
2266
|
-
yield verifySignature(certs[1], ask.tbsDer, ask.signature, ask.sigAlgOid);
|
|
2267
|
-
} catch (e) {
|
|
2268
|
-
throw new Error(`AMD ASK-by-ARK signature verification failed: ${e.message}`);
|
|
2269
|
-
}
|
|
2270
|
-
try {
|
|
2271
|
-
yield verifySignature(certs[0], vlek.tbsDer, vlek.signature, vlek.sigAlgOid);
|
|
2272
|
-
} catch (e) {
|
|
2273
|
-
throw new Error(`VLEK-by-ASK signature verification failed: ${e.message}`);
|
|
2274
|
-
}
|
|
2275
|
-
matchedChain = true;
|
|
2276
|
-
let crlBuf;
|
|
2277
|
-
const now = Date.now();
|
|
2278
|
-
if (crlCache[processor] && now - crlCache[processor].fetchedAt < 36e5) {
|
|
2279
|
-
crlBuf = crlCache[processor].buffer;
|
|
2280
|
-
} else {
|
|
2281
|
-
const crlUrl = `https://kdsintf.amd.com/vlek/v1/${processor}/crl`;
|
|
2282
|
-
const controller = new AbortController();
|
|
2283
|
-
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
2284
|
-
const crlResp = yield fetch(crlUrl, { signal: controller.signal });
|
|
2285
|
-
clearTimeout(timeoutId);
|
|
2286
|
-
if (!crlResp.ok) continue;
|
|
2287
|
-
crlBuf = new Uint8Array(yield crlResp.arrayBuffer());
|
|
2288
|
-
crlCache[processor] = { buffer: crlBuf, fetchedAt: now };
|
|
2289
|
-
}
|
|
2290
|
-
if (vlek.serialNumber && crlBuf) {
|
|
2291
|
-
yield verifyCRL(crlBuf, certs[1], vlek.serialNumber);
|
|
2292
|
-
}
|
|
2293
|
-
chainVerified = true;
|
|
2294
|
-
break;
|
|
2030
|
+
const context = JSON.parse(proof.claimData.context);
|
|
2031
|
+
return !!(context == null ? void 0 : context.attestationNonce);
|
|
2295
2032
|
} catch (e) {
|
|
2296
|
-
|
|
2297
|
-
throw e;
|
|
2298
|
-
}
|
|
2299
|
-
continue;
|
|
2033
|
+
return false;
|
|
2300
2034
|
}
|
|
2035
|
+
});
|
|
2036
|
+
if (!hasTeeData) {
|
|
2037
|
+
throw new TeeVerificationError("TEE verification requested but one or more proofs are missing TEE attestation data");
|
|
2301
2038
|
}
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
}
|
|
2305
|
-
});
|
|
2306
|
-
}
|
|
2307
|
-
function verifyHardwareSignature(reportBytes, certBytes) {
|
|
2308
|
-
return __async(this, null, function* () {
|
|
2309
|
-
const vlek = parseCert(certBytes);
|
|
2310
|
-
const sigOffset = 672;
|
|
2311
|
-
const rLE = reportBytes.subarray(sigOffset, sigOffset + 72);
|
|
2312
|
-
const sLE = reportBytes.subarray(sigOffset + 72, sigOffset + 144);
|
|
2313
|
-
const rBE = reverseBytes(rLE);
|
|
2314
|
-
const sBE = reverseBytes(sLE);
|
|
2315
|
-
const signedData = reportBytes.subarray(0, 672);
|
|
2316
|
-
const cryptoSubtle = getSubtleCrypto();
|
|
2317
|
-
const importedKey = yield cryptoSubtle.importKey(
|
|
2318
|
-
"spki",
|
|
2319
|
-
vlek.spkiDer,
|
|
2320
|
-
{ name: "ECDSA", namedCurve: "P-384" },
|
|
2321
|
-
false,
|
|
2322
|
-
["verify"]
|
|
2323
|
-
);
|
|
2324
|
-
const rPadding = rBE.subarray(0, rBE.length - 48);
|
|
2325
|
-
const sPadding = sBE.subarray(0, sBE.length - 48);
|
|
2326
|
-
if (!rPadding.every((b) => b === 0) || !sPadding.every((b) => b === 0)) {
|
|
2327
|
-
throw new Error("Hardware ECDSA signature is malformed: non-zero padding bytes detected in the structural signature coordinates.");
|
|
2328
|
-
}
|
|
2329
|
-
const r48 = rBE.subarray(rBE.length - 48);
|
|
2330
|
-
const s48 = sBE.subarray(sBE.length - 48);
|
|
2331
|
-
const rawSignature = concatUint8Arrays([r48, s48]);
|
|
2332
|
-
const isValid = yield cryptoSubtle.verify(
|
|
2333
|
-
{ name: "ECDSA", hash: { name: "SHA-384" } },
|
|
2334
|
-
importedKey,
|
|
2335
|
-
rawSignature,
|
|
2336
|
-
signedData
|
|
2337
|
-
);
|
|
2338
|
-
if (!isValid) {
|
|
2339
|
-
throw new Error("Hardware ECDSA signature is completely invalid!");
|
|
2340
|
-
}
|
|
2341
|
-
});
|
|
2342
|
-
}
|
|
2343
|
-
function verifyReportData(teeAttestation, proofContext, report) {
|
|
2344
|
-
return __async(this, null, function* () {
|
|
2345
|
-
if (!teeAttestation.workload_digest || !teeAttestation.verifier_digest) {
|
|
2346
|
-
throw new Error("POLICY CHECK FAILED: Missing workload_digest or verifier_digest in TEE attestation.");
|
|
2347
|
-
}
|
|
2348
|
-
const { attestationNonce: nonce } = JSON.parse(proofContext);
|
|
2349
|
-
const cryptoSubtle = getSubtleCrypto();
|
|
2350
|
-
const extractDigestBytes = (imageRef) => {
|
|
2351
|
-
const marker = "@sha256:";
|
|
2352
|
-
const idx = imageRef.lastIndexOf(marker);
|
|
2353
|
-
if (idx < 0) throw new Error(`Image ref missing @sha256: digest: ${imageRef}`);
|
|
2354
|
-
const hexDigest = imageRef.substring(idx + marker.length);
|
|
2355
|
-
if (hexDigest.length !== 64) throw new Error(`SHA256 digest must be 64 hex chars, got ${hexDigest.length} in: ${imageRef}`);
|
|
2356
|
-
const bytes = new Uint8Array(32);
|
|
2357
|
-
for (let i = 0; i < 32; i++) bytes[i] = parseInt(hexDigest.substring(i * 2, i * 2 + 2), 16);
|
|
2358
|
-
return bytes;
|
|
2359
|
-
};
|
|
2360
|
-
const importedCosignKey = yield cryptoSubtle.importKey(
|
|
2361
|
-
"spki",
|
|
2362
|
-
base64ToUint8Array(
|
|
2363
|
-
COSIGN_PUBLIC_KEY.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").replace(/\s+/g, "")
|
|
2364
|
-
),
|
|
2365
|
-
{ name: "ECDSA", namedCurve: "P-256" },
|
|
2366
|
-
true,
|
|
2367
|
-
["verify"]
|
|
2039
|
+
const teeResults = yield Promise.all(
|
|
2040
|
+
proofs.map((proof) => verifyTeeAttestation(proof, config.appSecret))
|
|
2368
2041
|
);
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
const pubKeyHashBytes = new Uint8Array(pubKeyHashBuffer);
|
|
2372
|
-
const nonceHex = (teeAttestation.nonce || nonce).replace(/^0x/i, "");
|
|
2373
|
-
const nonceBytes = new Uint8Array(nonceHex.length / 2);
|
|
2374
|
-
for (let i = 0; i < nonceBytes.length; i++) nonceBytes[i] = parseInt(nonceHex.substring(i * 2, i * 2 + 2), 16);
|
|
2375
|
-
const workloadBytes = extractDigestBytes(teeAttestation.workload_digest);
|
|
2376
|
-
const verifierBytes = extractDigestBytes(teeAttestation.verifier_digest);
|
|
2377
|
-
const domainSep = new TextEncoder().encode("POPCORN_TEE_REPORT_DATA_V1");
|
|
2378
|
-
const version = new Uint8Array([1]);
|
|
2379
|
-
const payload = new Uint8Array(
|
|
2380
|
-
domainSep.length + version.length + workloadBytes.length + verifierBytes.length + pubKeyHashBytes.length + nonceBytes.length
|
|
2381
|
-
);
|
|
2382
|
-
let offset = 0;
|
|
2383
|
-
for (const chunk of [domainSep, version, workloadBytes, verifierBytes, pubKeyHashBytes, nonceBytes]) {
|
|
2384
|
-
payload.set(chunk, offset);
|
|
2385
|
-
offset += chunk.length;
|
|
2386
|
-
}
|
|
2387
|
-
const hashBuffer = yield cryptoSubtle.digest("SHA-256", payload);
|
|
2388
|
-
const hashHex = arrayBufferToHex(hashBuffer);
|
|
2389
|
-
const expected64ByteHex = hashHex + hashHex;
|
|
2390
|
-
if (report.reportData !== expected64ByteHex) {
|
|
2391
|
-
throw new Error(`REPORT_DATA Mismatch! Hardware report is not bound to these image digests or nonce.
|
|
2392
|
-
Expected: ${expected64ByteHex}
|
|
2393
|
-
Got: ${report.reportData}`);
|
|
2042
|
+
if (!teeResults.every((r) => r.isVerified)) {
|
|
2043
|
+
throw new TeeVerificationError("TEE attestation verification failed for one or more proofs");
|
|
2394
2044
|
}
|
|
2395
2045
|
});
|
|
2396
2046
|
}
|
|
@@ -2398,6 +2048,7 @@ Got: ${report.reportData}`);
|
|
|
2398
2048
|
// src/Reclaim.ts
|
|
2399
2049
|
var logger10 = logger_default.logger;
|
|
2400
2050
|
var sdkVersion = require_package().version;
|
|
2051
|
+
var SDK_TEE_ATTESTATION_VERSION = "v3";
|
|
2401
2052
|
function verifyProof(proofOrProofs, config) {
|
|
2402
2053
|
return __async(this, null, function* () {
|
|
2403
2054
|
const proofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];
|
|
@@ -2413,29 +2064,15 @@ function verifyProof(proofOrProofs, config) {
|
|
|
2413
2064
|
yield assertVerifiedProof(proof, attestors);
|
|
2414
2065
|
}
|
|
2415
2066
|
yield assertValidateProof(proofs, config);
|
|
2416
|
-
let
|
|
2417
|
-
if (config.
|
|
2418
|
-
|
|
2419
|
-
if (!hasTeeData) {
|
|
2420
|
-
const teeError = new TeeVerificationError("TEE verification requested but one or more proofs are missing TEE attestation data");
|
|
2421
|
-
logger10.error(teeError.message);
|
|
2422
|
-
return createVerifyProofResultFailure(teeError, false);
|
|
2423
|
-
}
|
|
2424
|
-
try {
|
|
2425
|
-
const teeResults = yield Promise.all(proofs.map((proof) => verifyTeeAttestation(proof)));
|
|
2426
|
-
isTeeVerified = teeResults.every((r) => r === true);
|
|
2427
|
-
if (!isTeeVerified) {
|
|
2428
|
-
const teeError = new TeeVerificationError("TEE attestation verification failed for one or more proofs");
|
|
2429
|
-
logger10.error(teeError.message);
|
|
2430
|
-
return createVerifyProofResultFailure(teeError, false);
|
|
2431
|
-
}
|
|
2432
|
-
} catch (error) {
|
|
2433
|
-
const teeError = new TeeVerificationError("Error verifying TEE attestation", error);
|
|
2434
|
-
logger10.error(teeError.message);
|
|
2435
|
-
return createVerifyProofResultFailure(teeError, false);
|
|
2436
|
-
}
|
|
2067
|
+
let isTeeAttestationVerified;
|
|
2068
|
+
if (config.teeAttestation && "dangerouslyDisableContentValidation" in config && config.dangerouslyDisableContentValidation) {
|
|
2069
|
+
logger10.warn("teeAttestation is enabled but content validation is disabled \u2014 TEE attestation alone does not guarantee proof contents are valid");
|
|
2437
2070
|
}
|
|
2438
|
-
|
|
2071
|
+
if (config.teeAttestation) {
|
|
2072
|
+
yield runTeeVerification(proofs, config.teeAttestation);
|
|
2073
|
+
isTeeAttestationVerified = true;
|
|
2074
|
+
}
|
|
2075
|
+
return createVerifyProofResultSuccess(proofs, isTeeAttestationVerified);
|
|
2439
2076
|
} catch (error) {
|
|
2440
2077
|
logger10.error("Error in validating proof:", error);
|
|
2441
2078
|
const _error = error instanceof Error ? error : new Error(String(error));
|
|
@@ -2498,7 +2135,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2498
2135
|
* @returns
|
|
2499
2136
|
*/
|
|
2500
2137
|
this.getTemplateData = () => {
|
|
2501
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
2138
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
2502
2139
|
if (!this.signature) {
|
|
2503
2140
|
throw new SignatureNotFoundError("Signature is not set.");
|
|
2504
2141
|
}
|
|
@@ -2538,7 +2175,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2538
2175
|
log: (_h = (_g = this.options) == null ? void 0 : _g.log) != null ? _h : false,
|
|
2539
2176
|
canAutoSubmit: (_j = (_i = this.options) == null ? void 0 : _i.canAutoSubmit) != null ? _j : true,
|
|
2540
2177
|
metadata: (_k = this.options) == null ? void 0 : _k.metadata,
|
|
2541
|
-
preferredLocale: (_l = this.options) == null ? void 0 : _l.preferredLocale
|
|
2178
|
+
preferredLocale: (_l = this.options) == null ? void 0 : _l.preferredLocale,
|
|
2179
|
+
acceptTeeAttestation: (_m = this.options) == null ? void 0 : _m.acceptTeeAttestation,
|
|
2180
|
+
teeAttestationVersion: (_o = (_n = this.context.attestationNonceData) == null ? void 0 : _n.attestationVersion) != null ? _o : SDK_TEE_ATTESTATION_VERSION
|
|
2542
2181
|
};
|
|
2543
2182
|
return templateData;
|
|
2544
2183
|
};
|
|
@@ -2609,6 +2248,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2609
2248
|
*/
|
|
2610
2249
|
static init(applicationId, appSecret, providerId, options) {
|
|
2611
2250
|
return __async(this, null, function* () {
|
|
2251
|
+
var _a;
|
|
2612
2252
|
try {
|
|
2613
2253
|
validateFunctionParams([
|
|
2614
2254
|
{ paramName: "applicationId", input: applicationId, isString: true },
|
|
@@ -2690,22 +2330,28 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2690
2330
|
}, "the constructor");
|
|
2691
2331
|
}
|
|
2692
2332
|
}
|
|
2693
|
-
const
|
|
2333
|
+
const proofRequestOptions = __spreadProps(__spreadValues({}, options), {
|
|
2334
|
+
acceptTeeAttestation: (_a = options == null ? void 0 : options.acceptTeeAttestation) != null ? _a : true
|
|
2335
|
+
});
|
|
2336
|
+
const proofRequestInstance = new _ReclaimProofRequest(applicationId, providerId, proofRequestOptions);
|
|
2694
2337
|
const signature = yield proofRequestInstance.generateSignature(appSecret);
|
|
2695
2338
|
proofRequestInstance.setSignature(signature);
|
|
2696
2339
|
const data = yield initSession(providerId, applicationId, proofRequestInstance.timeStamp, signature, options == null ? void 0 : options.providerVersion);
|
|
2697
2340
|
proofRequestInstance.sessionId = data.sessionId;
|
|
2698
2341
|
proofRequestInstance.resolvedProviderVersion = data.resolvedProviderVersion;
|
|
2699
2342
|
proofRequestInstance.context.reclaimSessionId = data.sessionId;
|
|
2700
|
-
if (
|
|
2701
|
-
const
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2343
|
+
if (proofRequestOptions.acceptTeeAttestation) {
|
|
2344
|
+
const attestationNonce = generateAttestationNonce(
|
|
2345
|
+
appSecret,
|
|
2346
|
+
applicationId,
|
|
2347
|
+
data.sessionId,
|
|
2348
|
+
proofRequestInstance.timeStamp
|
|
2349
|
+
);
|
|
2350
|
+
proofRequestInstance.setAttestationContext(attestationNonce, {
|
|
2706
2351
|
applicationId,
|
|
2707
2352
|
sessionId: data.sessionId,
|
|
2708
|
-
timestamp: proofRequestInstance.timeStamp
|
|
2353
|
+
timestamp: proofRequestInstance.timeStamp,
|
|
2354
|
+
attestationVersion: SDK_TEE_ATTESTATION_VERSION
|
|
2709
2355
|
});
|
|
2710
2356
|
}
|
|
2711
2357
|
return proofRequestInstance;
|
|
@@ -3223,13 +2869,13 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
3223
2869
|
generateSignature(applicationSecret) {
|
|
3224
2870
|
return __async(this, null, function* () {
|
|
3225
2871
|
try {
|
|
3226
|
-
const wallet = new
|
|
2872
|
+
const wallet = new import_ethers6.ethers.Wallet(applicationSecret);
|
|
3227
2873
|
const canonicalData = (0, import_canonicalize3.default)({ providerId: this.providerId, timestamp: this.timeStamp });
|
|
3228
2874
|
if (!canonicalData) {
|
|
3229
2875
|
throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
|
|
3230
2876
|
}
|
|
3231
|
-
const messageHash =
|
|
3232
|
-
return yield wallet.signMessage(
|
|
2877
|
+
const messageHash = import_ethers6.ethers.keccak256(new TextEncoder().encode(canonicalData));
|
|
2878
|
+
return yield wallet.signMessage(import_ethers6.ethers.getBytes(messageHash));
|
|
3233
2879
|
} catch (err) {
|
|
3234
2880
|
logger10.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, timeStamp: ${this.timeStamp}`);
|
|
3235
2881
|
throw new SignatureGeneratingError(`Error generating signature for applicationId: ${this.applicationId}`);
|
|
@@ -3917,6 +3563,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
3917
3563
|
isHttpProviderClaimParams,
|
|
3918
3564
|
isMobileDevice,
|
|
3919
3565
|
recoverSignersOfSignedClaim,
|
|
3566
|
+
runTeeVerification,
|
|
3920
3567
|
takePairsWhereValueIsArray,
|
|
3921
3568
|
takeTemplateParametersFromProofs,
|
|
3922
3569
|
transformForOnchain,
|