mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-04 19:25:40 +00:00
feat(connect): add device identity store and registration proof (#6267)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
5133761d19d6a64c18b6b5f871d646f6a2da4ceccc998d3cf7e22f692ca2d925 accept-vectors.json
|
||||
c7da10d173e7fafa112743d9a41e2bc94df58bf88a0542d80350b74da8f382a5 error-codes.json
|
||||
e98cfbedfb385defdaa9d001c85fdebcf9df2b4d054930951ff59dfa1385e52f reject-vectors.json
|
||||
69d43c8266d7bb29b4df7105c49250293943583f2202b93d922d9a924fca0c09 trust-chain.json
|
||||
e60cfca04bf0ce2f69495c49a95e4cc42e92e8114f6ad43449084527b06a0939 trust-model.json
|
||||
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"protocolVersion": "v1",
|
||||
"fixtureSet": "offline-enrollment",
|
||||
"fixture": "accept-vectors",
|
||||
"description": "Offline enrollment artifacts that verify. evaluationTime is the verifier clock the vector is evaluated at; the artifact bytes are frozen, so a window is a property of the evaluation and not of the bytes.",
|
||||
"vectors": [
|
||||
{
|
||||
"name": "challenge signed by a chained signing key under the pinned root",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "signing",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogIlRWeDRqS2FQZ1dQbGRUU203X1N6S1BsSDVIZmhrcHFxcjlieWVDalhkSFUiLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICIwOGU3Mjk1YzhmOWQwNDNlMjJiMmI4MGZkYjE0ODBiMGJlYzA2MGRhY2JjZTdkZTlkZDJlM2Q1ODNmOTNkN2U4IiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlOMkptWm1ObU1EYzRaRGMyTkRnNU9XRTNNR1prWWpGaFpqbGlZbU5rTmpJaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3T0Mwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EZ3RNekZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiamhrZFozeWpuOC1Od0JxWjZjRUtZVlNsYV9VblVmVFJWVmNxazZJSndUTWx3S1ZyWU8xWEZSVTA1bTBWc0VNMThYM1ppOE96bGxoSVAyUjlxWUMwa0EiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"value": "jiDV4Wy81WwqQwlxVqF0eFTh9jEMnD3mkUWB5XqGmpkSw0WnTdAjuVH1wqRMeUEYkZLDTu7fB5YJRvBN2wrUtA"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"chainVerifies": true,
|
||||
"rootPinned": true,
|
||||
"withinWindow": true,
|
||||
"accepted": true,
|
||||
"reason": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "challenge evaluated 120 seconds before its issuedAt is inside the skew tolerance",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "signing",
|
||||
"evaluationTime": "2026-08-16T23:58:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogIlRWeDRqS2FQZ1dQbGRUU203X1N6S1BsSDVIZmhrcHFxcjlieWVDalhkSFUiLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICIwOGU3Mjk1YzhmOWQwNDNlMjJiMmI4MGZkYjE0ODBiMGJlYzA2MGRhY2JjZTdkZTlkZDJlM2Q1ODNmOTNkN2U4IiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlOMkptWm1ObU1EYzRaRGMyTkRnNU9XRTNNR1prWWpGaFpqbGlZbU5rTmpJaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3T0Mwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EZ3RNekZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiamhrZFozeWpuOC1Od0JxWjZjRUtZVlNsYV9VblVmVFJWVmNxazZJSndUTWx3S1ZyWU8xWEZSVTA1bTBWc0VNMThYM1ppOE96bGxoSVAyUjlxWUMwa0EiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"value": "jiDV4Wy81WwqQwlxVqF0eFTh9jEMnD3mkUWB5XqGmpkSw0WnTdAjuVH1wqRMeUEYkZLDTu7fB5YJRvBN2wrUtA"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"chainVerifies": true,
|
||||
"rootPinned": true,
|
||||
"withinWindow": true,
|
||||
"accepted": true,
|
||||
"reason": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "challenge evaluated 300 seconds after its expiresAt is still inside the skew tolerance",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "signing",
|
||||
"evaluationTime": "2026-08-24T00:05:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogIlRWeDRqS2FQZ1dQbGRUU203X1N6S1BsSDVIZmhrcHFxcjlieWVDalhkSFUiLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICIwOGU3Mjk1YzhmOWQwNDNlMjJiMmI4MGZkYjE0ODBiMGJlYzA2MGRhY2JjZTdkZTlkZDJlM2Q1ODNmOTNkN2U4IiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlOMkptWm1ObU1EYzRaRGMyTkRnNU9XRTNNR1prWWpGaFpqbGlZbU5rTmpJaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3T0Mwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EZ3RNekZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiamhrZFozeWpuOC1Od0JxWjZjRUtZVlNsYV9VblVmVFJWVmNxazZJSndUTWx3S1ZyWU8xWEZSVTA1bTBWc0VNMThYM1ppOE96bGxoSVAyUjlxWUMwa0EiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"value": "jiDV4Wy81WwqQwlxVqF0eFTh9jEMnD3mkUWB5XqGmpkSw0WnTdAjuVH1wqRMeUEYkZLDTu7fB5YJRvBN2wrUtA"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"chainVerifies": true,
|
||||
"rootPinned": true,
|
||||
"withinWindow": true,
|
||||
"accepted": true,
|
||||
"reason": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response binding the device public key and the challenge proof",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogInB3bUwxVW9jSG5NYVUwa2w2ZVc0M3BfcllOakxBOGtJaUN2TDlibktwUGMiLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "n4joB8c1KbYvw7MSjeGs1BEYeYe8dFpy47Me_iD7MO1gUSKDpGl6MyCxuZ8KWmjzNMUWz1sgREEW8HsgpNlsIQ"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"devicePublicKeyIsTheVerifyingKey": true,
|
||||
"challengeProofMatches": true,
|
||||
"organizationMatches": true,
|
||||
"clusterMatches": true,
|
||||
"withinWindow": true,
|
||||
"accepted": true,
|
||||
"reason": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response carrying an unknown optional field is accepted and the field is discarded",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogIm5fYWVJb0ZkeldyRnppWjZ4b1BManBobnhaZVB5US1YaTdQSzRYUFhDNUEiLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiLAogICAgInRlbGVtZXRyeUhpbnQiOiAiaWdub3JlZCIKfQo=",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "tdMIDSpMk2kcZKT1FC8e3TDxNwujk8CVCgw7c3Np3ols8nUMx5Hx-TuznC57lqEq0Yo08H4r4AaztSktISHbXQ"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"devicePublicKeyIsTheVerifyingKey": true,
|
||||
"challengeProofMatches": true,
|
||||
"organizationMatches": true,
|
||||
"clusterMatches": true,
|
||||
"withinWindow": true,
|
||||
"accepted": true,
|
||||
"reason": null,
|
||||
"discardedFields": [
|
||||
"telemetryHint"
|
||||
],
|
||||
"echoedBack": [],
|
||||
"stored": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"protocolVersion": "v1",
|
||||
"fixtureSet": "offline-enrollment",
|
||||
"fixture": "error-codes",
|
||||
"description": "Frozen ErrorInfo reasons for offline enrollment. Clients branch on status and reason, never on message.",
|
||||
"domain": "rustfs.connect",
|
||||
"detailType": "type.googleapis.com/google.rpc.ErrorInfo",
|
||||
"disclosureRules": [
|
||||
"A rejection never reveals whether a presented key or challenge belongs to another tenant.",
|
||||
"A rejection never contains key material, signature octets, nonces, or document bytes.",
|
||||
"A rejection never reports which of several failed checks failed first beyond the single frozen reason."
|
||||
],
|
||||
"reasons": [
|
||||
{
|
||||
"reason": "UNSUPPORTED_PROTOCOL",
|
||||
"httpStatus": 400,
|
||||
"status": "INVALID_ARGUMENT",
|
||||
"meaning": "The protocolVersion is missing, malformed, or names an unsupported major version. Identical to the rule frozen in protocol/agent/v1/authentication.md."
|
||||
},
|
||||
{
|
||||
"reason": "UNSUPPORTED_FORMAT",
|
||||
"httpStatus": 400,
|
||||
"status": "INVALID_ARGUMENT",
|
||||
"meaning": "The formatVersion is not one of the frozen supported format versions."
|
||||
},
|
||||
{
|
||||
"reason": "SIGNATURE_MALFORMED",
|
||||
"httpStatus": 400,
|
||||
"status": "INVALID_ARGUMENT",
|
||||
"meaning": "The signature is not 64 octets of fixed-width r||s in unpadded base64url, or r or s is out of range."
|
||||
},
|
||||
{
|
||||
"reason": "SIGNATURE_NOT_CANONICAL",
|
||||
"httpStatus": 400,
|
||||
"status": "INVALID_ARGUMENT",
|
||||
"meaning": "The signature is well formed and verifies, but its s exceeds half the group order. Only the low-S form is accepted."
|
||||
},
|
||||
{
|
||||
"reason": "SIGNATURE_INVALID",
|
||||
"httpStatus": 401,
|
||||
"status": "UNAUTHENTICATED",
|
||||
"meaning": "ECDSA verification over the received octets failed. The document was altered, or it was signed by another key."
|
||||
},
|
||||
{
|
||||
"reason": "ENROLLMENT_ROOT_UNKNOWN",
|
||||
"httpStatus": 401,
|
||||
"status": "UNAUTHENTICATED",
|
||||
"meaning": "The first trust link is issued by a key that is not pinned in this build. There is no path from this to acceptance: the root is never learned."
|
||||
},
|
||||
{
|
||||
"reason": "TRUST_CHAIN_INVALID",
|
||||
"httpStatus": 401,
|
||||
"status": "UNAUTHENTICATED",
|
||||
"meaning": "A trust link failed its own signature check, named the wrong issuer, carried an unknown role, or was outside its validity at the challenge issuedAt."
|
||||
},
|
||||
{
|
||||
"reason": "CONNECT_KEY_UNCHAINED",
|
||||
"httpStatus": 401,
|
||||
"status": "UNAUTHENTICATED",
|
||||
"meaning": "The challenge connectKeyId is not the subject of the last trust link, so nothing under the pinned root vouches for the signing key."
|
||||
},
|
||||
{
|
||||
"reason": "CHALLENGE_UNKNOWN",
|
||||
"httpStatus": 401,
|
||||
"status": "UNAUTHENTICATED",
|
||||
"meaning": "Connect has no issued challenge with this challengeId."
|
||||
},
|
||||
{
|
||||
"reason": "CHALLENGE_NOT_YET_VALID",
|
||||
"httpStatus": 401,
|
||||
"status": "UNAUTHENTICATED",
|
||||
"meaning": "The evaluation time is more than the skew tolerance before issuedAt."
|
||||
},
|
||||
{
|
||||
"reason": "CHALLENGE_EXPIRED",
|
||||
"httpStatus": 401,
|
||||
"status": "UNAUTHENTICATED",
|
||||
"meaning": "The evaluation time is more than the skew tolerance after expiresAt."
|
||||
},
|
||||
{
|
||||
"reason": "CHALLENGE_PROOF_INVALID",
|
||||
"httpStatus": 401,
|
||||
"status": "UNAUTHENTICATED",
|
||||
"meaning": "The response nonce or challengeProof is not the one Connect issued for this challenge."
|
||||
},
|
||||
{
|
||||
"reason": "DEVICE_PROOF_INVALID",
|
||||
"httpStatus": 401,
|
||||
"status": "UNAUTHENTICATED",
|
||||
"meaning": "The response signature does not verify under the devicePublicKey it presents, or deviceKeyId is not that key fingerprint. Proof of possession failed."
|
||||
},
|
||||
{
|
||||
"reason": "ENROLLMENT_REPLAYED",
|
||||
"httpStatus": 409,
|
||||
"status": "ABORTED",
|
||||
"meaning": "The challenge was already consumed. A challenge is single use even when the replayed response is byte identical."
|
||||
},
|
||||
{
|
||||
"reason": "ORGANIZATION_MISMATCH",
|
||||
"httpStatus": 403,
|
||||
"status": "PERMISSION_DENIED",
|
||||
"meaning": "The response names a different organization than the challenge it answers."
|
||||
},
|
||||
{
|
||||
"reason": "CLUSTER_MISMATCH",
|
||||
"httpStatus": 403,
|
||||
"status": "PERMISSION_DENIED",
|
||||
"meaning": "The response names a different cluster than the challenge it answers."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
{
|
||||
"protocolVersion": "v1",
|
||||
"fixtureSet": "offline-enrollment",
|
||||
"fixture": "reject-vectors",
|
||||
"description": "Offline enrollment artifacts that must never be accepted. signatureVerifies records whether the raw ECDSA verification over the received octets succeeds, so a vector that fails only on a rule beyond the mathematics is visibly distinct from a forgery.",
|
||||
"vectors": [
|
||||
{
|
||||
"name": "tampered challenge bytes with the original signature",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "signing",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogIkFWeDRqS2FQZ1dQbGRUU203X1N6S1BsSDVIZmhrcHFxcjlieWVDalhkSFUiLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICIwOGU3Mjk1YzhmOWQwNDNlMjJiMmI4MGZkYjE0ODBiMGJlYzA2MGRhY2JjZTdkZTlkZDJlM2Q1ODNmOTNkN2U4IiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlOMkptWm1ObU1EYzRaRGMyTkRnNU9XRTNNR1prWWpGaFpqbGlZbU5rTmpJaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3T0Mwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EZ3RNekZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiamhrZFozeWpuOC1Od0JxWjZjRUtZVlNsYV9VblVmVFJWVmNxazZJSndUTWx3S1ZyWU8xWEZSVTA1bTBWc0VNMThYM1ppOE96bGxoSVAyUjlxWUMwa0EiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"value": "jiDV4Wy81WwqQwlxVqF0eFTh9jEMnD3mkUWB5XqGmpkSw0WnTdAjuVH1wqRMeUEYkZLDTu7fB5YJRvBN2wrUtA"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": false,
|
||||
"accepted": false,
|
||||
"reason": "SIGNATURE_INVALID"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "chain rooted at a key that is not pinned in the build",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "rogueSigning",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogIjBZcVFTc2xEYlc5Nm5fcmQ4M1dKQllmX1RSWTNoZkh2WHFCRHkwWVdMY00iLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICI5MGYzOGEwZGMyYzVmOTQ4ZjQ3ODg3YTAxMGVhM2NiOWU0MjVkMDQwOWVkYjJhNDAxNGM3Zjc1MzliYzIyNDcxIiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpTVROalpHSTNORGhpTVRoak1ETmlNakEwTnpCalpqWTJZVEprWWpaaFpqZ2lMQW9nSUNBZ0luSnZiR1VpT2lBaWMybG5ibWx1WnlJc0NpQWdJQ0FpYVhOemRXVnlTMlY1U1dRaU9pQWlOV1ptTXpjNU1UQmhZVFJrTmprNU5EbGxNbU0wT0RobU9UaGtOakEzTW1ZeE1HRXpZek5sTnpOa056YzJOams0T1RZek9EY3lOVGd5TmpRMFpqY3pNU0lzQ2lBZ0lDQWljM1ZpYW1WamRFdGxlVWxrSWpvZ0lqa3daak00WVRCa1l6SmpOV1k1TkRobU5EYzRPRGRoTURFd1pXRXpZMkk1WlRReU5XUXdOREE1WldSaU1tRTBNREUwWXpkbU56VXpPV0pqTWpJME56RWlMQW9nSUNBZ0luTjFZbXBsWTNSUWRXSnNhV05MWlhraU9pQWlRa2xIVG01elQzRk5Ra2swVEZCRU9FcDVVMmMzTjBVemRrTm9TVGM0VWpSQlNHZHZiSGhHWTBwT2REbGFPVWR6VFc5V1MwbGxPVnBQWkVwUFJUTTRjMFphZEROdlJqVmpjbFV3U0hGa2VtbEhabWxGY0RsVklpd0tJQ0FnSUNKdWIzUkNaV1p2Y21VaU9pQWlNakF5Tmkwd09DMHdNVlF3TURvd01Eb3dNRm9pTEFvZ0lDQWdJbTV2ZEVGbWRHVnlJam9nSWpJd01qWXRNRGd0TXpGVU1EQTZNREE2TURCYUlncDlDZz09IiwKICAgICAgICAgICAgInNpZ25hdHVyZSI6IHsKICAgICAgICAgICAgICAgICJhbGdvcml0aG0iOiAiRVMyNTYiLAogICAgICAgICAgICAgICAgImtleUlkIjogIjVmZjM3OTEwYWE0ZDY5OTQ5ZTJjNDg4Zjk4ZDYwNzJmMTBhM2MzZTczZDc3NjY5ODk2Mzg3MjU4MjY0NGY3MzEiLAogICAgICAgICAgICAgICAgInZhbHVlIjogInN1eFViWjlJczFsaVFsaGpmd1hRb1RlemU0bWU5ZjdRZGRyMzI5OWxtenBuLThWekgya2dUQTVZdk05QmktYjRBVGVITkxQQm1rRkRoYVZveFg2NEx3IgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXQp9Cg==",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "90f38a0dc2c5f948f47887a010ea3cb9e425d0409edb2a4014c7f7539bc22471",
|
||||
"value": "WcptrTFWDSY9WhA9Lu8U-OtJZtqroeoPypZuev4S3eEvEN1L1GsAGfYAAcF9LkHUO10WI6c7NVurZdtSzoU56g"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"rootPinned": false,
|
||||
"accepted": false,
|
||||
"reason": "ENROLLMENT_ROOT_UNKNOWN"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "signing link expired before the challenge was issued",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "signing",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogIjd4UWJEQUREbTc3NGJCZzhFc2tfUnhDajFrRUdjaTJOOE8yUmVLSGdNNlUiLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICIwOGU3Mjk1YzhmOWQwNDNlMjJiMmI4MGZkYjE0ODBiMGJlYzA2MGRhY2JjZTdkZTlkZDJlM2Q1ODNmOTNkN2U4IiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlZMkV3T1dZelpUVmhaRGt4T1RFd05tUXhNalpqT0RSbFpHUmpORFZpWlRnaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3Tmkwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EY3RNREZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiU1g3NVdkT1ZMdnBoUk1jY2UweHE3VzUtRXIwSFNWaEJjc1VuZzFVdjhSQVBSMjNwckNINW9KT0YwNkFfaDd4SEFqOVhMN1lldXhSU3RQc19wa1ROckEiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"value": "xFOTJIOO0sMTsbCNGeNF31-A7R1aVyPWDx06qOuvb2BwTGNwARo95z-3zcPsZ68TSrKIocNbG5KRd3jM9zeVNQ"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"chainVerifies": false,
|
||||
"accepted": false,
|
||||
"reason": "TRUST_CHAIN_INVALID"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "challenge signed by a key the chain does not name",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "stray",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogInNXZXhMdUV5MVRtQmVydnpSX1g3SlBLa3BBdnNlM051eU10NUJIZmpqNGsiLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICJmNmZiZTA1MGRlZmRlZDE4YjUwNDc3YWNlMzhjOTUxNWZiNjFiODE1N2U1N2IyZjBlN2U4Y2E2OWM4NjJiNmNhIiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlOMkptWm1ObU1EYzRaRGMyTkRnNU9XRTNNR1prWWpGaFpqbGlZbU5rTmpJaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3T0Mwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EZ3RNekZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiamhrZFozeWpuOC1Od0JxWjZjRUtZVlNsYV9VblVmVFJWVmNxazZJSndUTWx3S1ZyWU8xWEZSVTA1bTBWc0VNMThYM1ppOE96bGxoSVAyUjlxWUMwa0EiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "f6fbe050defded18b50477ace38c9515fb61b8157e57b2f0e7e8ca69c862b6ca",
|
||||
"value": "FoWcvh5OA-_Vm7bCTf_TQuw2oGq5lOwjpVdfY45fQRAy9-TvHBCRr7Z1x4QC_5bjjt_hbled0dVm6ekfpC2dvw"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"connectKeyChained": false,
|
||||
"accepted": false,
|
||||
"reason": "CONNECT_KEY_UNCHAINED"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "challenge evaluated 301 seconds past its expiresAt",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "signing",
|
||||
"evaluationTime": "2026-08-24T00:05:01Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogIlRWeDRqS2FQZ1dQbGRUU203X1N6S1BsSDVIZmhrcHFxcjlieWVDalhkSFUiLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICIwOGU3Mjk1YzhmOWQwNDNlMjJiMmI4MGZkYjE0ODBiMGJlYzA2MGRhY2JjZTdkZTlkZDJlM2Q1ODNmOTNkN2U4IiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlOMkptWm1ObU1EYzRaRGMyTkRnNU9XRTNNR1prWWpGaFpqbGlZbU5rTmpJaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3T0Mwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EZ3RNekZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiamhrZFozeWpuOC1Od0JxWjZjRUtZVlNsYV9VblVmVFJWVmNxazZJSndUTWx3S1ZyWU8xWEZSVTA1bTBWc0VNMThYM1ppOE96bGxoSVAyUjlxWUMwa0EiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"value": "jiDV4Wy81WwqQwlxVqF0eFTh9jEMnD3mkUWB5XqGmpkSw0WnTdAjuVH1wqRMeUEYkZLDTu7fB5YJRvBN2wrUtA"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"withinWindow": false,
|
||||
"accepted": false,
|
||||
"reason": "CHALLENGE_EXPIRED"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "challenge evaluated 301 seconds before its issuedAt",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "signing",
|
||||
"evaluationTime": "2026-08-16T23:54:59Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogIlRWeDRqS2FQZ1dQbGRUU203X1N6S1BsSDVIZmhrcHFxcjlieWVDalhkSFUiLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICIwOGU3Mjk1YzhmOWQwNDNlMjJiMmI4MGZkYjE0ODBiMGJlYzA2MGRhY2JjZTdkZTlkZDJlM2Q1ODNmOTNkN2U4IiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlOMkptWm1ObU1EYzRaRGMyTkRnNU9XRTNNR1prWWpGaFpqbGlZbU5rTmpJaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3T0Mwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EZ3RNekZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiamhrZFozeWpuOC1Od0JxWjZjRUtZVlNsYV9VblVmVFJWVmNxazZJSndUTWx3S1ZyWU8xWEZSVTA1bTBWc0VNMThYM1ppOE96bGxoSVAyUjlxWUMwa0EiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"value": "jiDV4Wy81WwqQwlxVqF0eFTh9jEMnD3mkUWB5XqGmpkSw0WnTdAjuVH1wqRMeUEYkZLDTu7fB5YJRvBN2wrUtA"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"withinWindow": false,
|
||||
"accepted": false,
|
||||
"reason": "CHALLENGE_NOT_YET_VALID"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "challenge declaring an unknown formatVersion",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "signing",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzIiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MSIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogInp4Y2VGd1hVSkFlVGQyWE5yZVp6bElNVEhMX1RGa1ROd2FjUWNsaWJta0UiLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICIwOGU3Mjk1YzhmOWQwNDNlMjJiMmI4MGZkYjE0ODBiMGJlYzA2MGRhY2JjZTdkZTlkZDJlM2Q1ODNmOTNkN2U4IiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlOMkptWm1ObU1EYzRaRGMyTkRnNU9XRTNNR1prWWpGaFpqbGlZbU5rTmpJaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3T0Mwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EZ3RNekZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiamhrZFozeWpuOC1Od0JxWjZjRUtZVlNsYV9VblVmVFJWVmNxazZJSndUTWx3S1ZyWU8xWEZSVTA1bTBWc0VNMThYM1ppOE96bGxoSVAyUjlxWUMwa0EiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"value": "qfe91lyiqI8ICHxDLyGjf34dIWTD2D8xtv9SH0Najv05g8VDKHTesAsmp9wbp0RvEHRm8Zh0gylkgsZnNUM7-w"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"accepted": false,
|
||||
"reason": "UNSUPPORTED_FORMAT"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "challenge declaring an unsupported protocol major version",
|
||||
"artifact": "challenge",
|
||||
"signerKey": "signing",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50Q2hhbGxlbmdlLzEiLAogICAgInByb3RvY29sVmVyc2lvbiI6ICJ2MiIsCiAgICAiY2hhbGxlbmdlSWQiOiAiMDE5OGYzYTEtN2YwMC03ZDQwLWJlNTEtM2Y0YTViNmM3ZDgzIiwKICAgICJvcmdhbml6YXRpb25OYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwIiwKICAgICJjbHVzdGVyTmFtZSI6ICJvcmdhbml6YXRpb25zLzAxOThmM2ExLTRjMDAtN2ExMC04YjIxLTBjMWQyZTNmNGE1MC9jbHVzdGVycy8wMTk4ZjNhMS01ZDAwLTdiMjAtOWMzMS0xZDJlM2Y0YTViNjEiLAogICAgIm5vbmNlIjogIkh4WEY1b3lGR3JFdmIyRklRTUhXeXpGSVVHd3ZMeVhvYkJGOENXUnIwNnciLAogICAgImlzc3VlZEF0IjogIjIwMjYtMDgtMTdUMDA6MDA6MDBaIiwKICAgICJleHBpcmVzQXQiOiAiMjAyNi0wOC0yNFQwMDowMDowMFoiLAogICAgImNvbm5lY3RLZXlJZCI6ICIwOGU3Mjk1YzhmOWQwNDNlMjJiMmI4MGZkYjE0ODBiMGJlYzA2MGRhY2JjZTdkZTlkZDJlM2Q1ODNmOTNkN2U4IiwKICAgICJ0cnVzdENoYWluIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ5dGVzIjogImV3b2dJQ0FnSW1admNtMWhkRlpsY25OcGIyNGlPaUFpY25WemRHWnpMbU52Ym01bFkzUXViMlptYkdsdVpTNTBjblZ6ZEV4cGJtc3ZNU0lzQ2lBZ0lDQWljSEp2ZEc5amIyeFdaWEp6YVc5dUlqb2dJbll4SWl3S0lDQWdJQ0p6WlhKcFlXd2lPaUFpWXpJMU9HRTJaR1JqT1RoaVlqVmhOV1U1TkRSbU5qSmxNRFkzT1dFM05HVWlMQW9nSUNBZ0luSnZiR1VpT2lBaWFXNTBaWEp0WldScFlYUmxJaXdLSUNBZ0lDSnBjM04xWlhKTFpYbEpaQ0k2SUNKa1pqSXlaVEk0TURZeE1USmtaV0ppWlRrMU16WTNNbUZoWm1FeE9EWmtOams1WVdZd1pUazNaR1F6Wm1ReVlqQTVabUU0TXpVNU1EQTFabVV6TkRobUlpd0tJQ0FnSUNKemRXSnFaV04wUzJWNVNXUWlPaUFpTURSbFltTTNOR1F6TURBeU1HWTNNamM1T0Roak9UWmpNbVptWWpJeU9ESXhPRGd6WldVMllqSmxOR014TVRkbU5tVTVOVGxrWW1RMk0yWXpNMlE0TnlJc0NpQWdJQ0FpYzNWaWFtVmpkRkIxWW14cFkwdGxlU0k2SUNKQ1JIZzFWbk5YU1ZwS1YzcERTMkZVTURoZmVGTklhR2RoTFdsek9UVmhXVTlvTUcxa1FUVTBOMll5UVd4R1ZFeG1lV1ZhYWpBeGVtVk9hV3ROZFdSalFXWk1WSGcwUkVoWVJHRkhjM0ZRUkZSWmRGWjZSRzhpTEFvZ0lDQWdJbTV2ZEVKbFptOXlaU0k2SUNJeU1ESTJMVEF4TFRBeFZEQXdPakF3T2pBd1dpSXNDaUFnSUNBaWJtOTBRV1owWlhJaU9pQWlNakF5Tnkwd01TMHdNVlF3TURvd01Eb3dNRm9pQ24wSyIsCiAgICAgICAgICAgICJzaWduYXR1cmUiOiB7CiAgICAgICAgICAgICAgICAiYWxnb3JpdGhtIjogIkVTMjU2IiwKICAgICAgICAgICAgICAgICJrZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJsWEl4RG1rdlJYMkNLTF9OU01KX3ltLUhKWTQ4cW9VejRoM2JQUHgzM0lGRXYwRTFnblNPV2QxTTJYcHJtSVZSQ3Z4OHhONUNmWUowTDd3enNEQV9GUSIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAiYnl0ZXMiOiAiZXdvZ0lDQWdJbVp2Y20xaGRGWmxjbk5wYjI0aU9pQWljblZ6ZEdaekxtTnZibTVsWTNRdWIyWm1iR2x1WlM1MGNuVnpkRXhwYm1zdk1TSXNDaUFnSUNBaWNISnZkRzlqYjJ4V1pYSnphVzl1SWpvZ0luWXhJaXdLSUNBZ0lDSnpaWEpwWVd3aU9pQWlOMkptWm1ObU1EYzRaRGMyTkRnNU9XRTNNR1prWWpGaFpqbGlZbU5rTmpJaUxBb2dJQ0FnSW5KdmJHVWlPaUFpYzJsbmJtbHVaeUlzQ2lBZ0lDQWlhWE56ZFdWeVMyVjVTV1FpT2lBaU1EUmxZbU0zTkdRek1EQXlNR1kzTWpjNU9EaGpPVFpqTW1abVlqSXlPREl4T0RnelpXVTJZakpsTkdNeE1UZG1ObVU1TlRsa1ltUTJNMll6TTJRNE55SXNDaUFnSUNBaWMzVmlhbVZqZEV0bGVVbGtJam9nSWpBNFpUY3lPVFZqT0dZNVpEQTBNMlV5TW1JeVlqZ3dabVJpTVRRNE1HSXdZbVZqTURZd1pHRmpZbU5sTjJSbE9XUmtNbVV6WkRVNE0yWTVNMlEzWlRnaUxBb2dJQ0FnSW5OMVltcGxZM1JRZFdKc2FXTkxaWGtpT2lBaVFrZFdTVlUzZVRWU2FXZ3lhRWs0TFZCZmFXd3RSM1ZJVm5Sa1VVeEdlVEpFYUZGbFJsVTNjV2g1WW1KME1qa3hlbE5DYTE5MWVGbEtTazVoUWtSa1pEbDNUVU0wUkdac1dUVlJRbEJVT0cxU05qZEZaMk5CSWl3S0lDQWdJQ0p1YjNSQ1pXWnZjbVVpT2lBaU1qQXlOaTB3T0Mwd01WUXdNRG93TURvd01Gb2lMQW9nSUNBZ0ltNXZkRUZtZEdWeUlqb2dJakl3TWpZdE1EZ3RNekZVTURBNk1EQTZNREJhSWdwOUNnPT0iLAogICAgICAgICAgICAic2lnbmF0dXJlIjogewogICAgICAgICAgICAgICAgImFsZ29yaXRobSI6ICJFUzI1NiIsCiAgICAgICAgICAgICAgICAia2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAiamhrZFozeWpuOC1Od0JxWjZjRUtZVlNsYV9VblVmVFJWVmNxazZJSndUTWx3S1ZyWU8xWEZSVTA1bTBWc0VNMThYM1ppOE96bGxoSVAyUjlxWUMwa0EiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"value": "yR9NE0AkqEwQT23IGbGMbM377H6d7NEuLIgWSTRpsRFFKPDjZxIeMpYnSgxjAxJwSxl3CTwwfHubEti4oVaRng"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"accepted": false,
|
||||
"reason": "UNSUPPORTED_PROTOCOL"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response naming another organization than the challenge it answers",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRiNjAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogInpldXU4dVlpZDZ1cl9fa2hrMk9YNDJwaHdxUmttTXVEVXpXeUhSYkk5YW8iLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "Lgs5XNYe0XtZDTSLHpv5cxpCLzcZOgXzhJiQUMGBxb8aYng-d1B38yGJndmosm7ZWisFUW_fU7jHYRRgWroX1A"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"organizationMatches": false,
|
||||
"accepted": false,
|
||||
"reason": "ORGANIZATION_MISMATCH"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response naming another cluster than the challenge it answers",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YjYwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWM3MiIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogIlpNZkc1SUNmWkRfSnNXelVUemk2aGprTnpKRnpTV1dZeWJYNFJEMnBIRkUiLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "6sWuGJE0FXKPBhuyECUews-X6pfM9YDsTJ3ru8Pcljh5M1qPvoJBcvQ78KbwO7A-vYK4eS_s-7XFQ-YvFzCCwA"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"clusterMatches": false,
|
||||
"accepted": false,
|
||||
"reason": "CLUSTER_MISMATCH"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response echoing a nonce the challenge never carried",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiRlRpcHJ0bzF1eVpBZDJIbGV1eXFtbGtaUFpzaGJ3S3picHlqbGFuQnpBNCIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogIlA4VDhPemJzZFhTQ19RU25SaVNtU0RZakZIajMyTjVXZjJ1ZHF4ejVDakUiLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "CBOfTV8YB8DHBNLN9KOndRjRBT295jVkdaqCZUmExUEomiMRpmM24sOuOHwDNzqBH-oJioRwpDeiVxvAe8cBOg"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"challengeNonceMatches": false,
|
||||
"accepted": false,
|
||||
"reason": "CHALLENGE_PROOF_INVALID"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response carrying a proof taken from a different challenge",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiRm9XY3ZoNU9BLV9WbTdiQ1RmX1RRdXcyb0dxNWxPd2pwVmRmWTQ1ZlFSQXk5LVR2SEJDUnI3WjF4NFFDXzViamp0X2hibGVkMGRWbTZla2ZwQzJkdnciLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogIm8wdnh5Sm03cklHVjB1eGd1WGtaMmFfaHBXT1RmSEY3dlkwUVBRcTVicE0iLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "K6uiu35Fy9ImZ3LdsIHg_avCJedTk1NqsBxqcQ5q8rocD_Fx_-kzzERCtyIgxHmivljeQf5BGaevJP-BBhR_FQ"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"challengeProofMatches": false,
|
||||
"accepted": false,
|
||||
"reason": "CHALLENGE_PROOF_INVALID"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response signed by a key other than the device public key it presents",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "foreignDevice",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogIm9qUzBudHFIT3BKMzA3WUhIdlg5OUZ0U2tjb1lZR18zQVZpSldGUFZ4UzQiLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "-mAQtMW6JTIndESRTbUIYMBWIkEM_xF8EEWSHfSljXwPOgEJ_59wdsnmfCsIKmWlALjtJRjWZUsqKamERJSLdg"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": false,
|
||||
"devicePublicKeyIsTheVerifyingKey": false,
|
||||
"accepted": false,
|
||||
"reason": "DEVICE_PROOF_INVALID"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response produced 301 seconds after the challenge expiry tolerance",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-24T00:06:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogIjNwYTRMRVlFeVpSX0t2cXJ2ZndrUllWWGpDVkMzNFN6TkdiWW9rcl95aWMiLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yNFQwMDowNTowMVoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "W-CScIVVVsLmQtopMmZEYt2T0L9wwgCsdBVADpbSMPIOsKv6VwObaCTorGVWcH1rs6nvy4UTQUyNkBIIC9U8Bw"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"withinWindow": false,
|
||||
"accepted": false,
|
||||
"reason": "CHALLENGE_EXPIRED"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response declaring an unknown formatVersion",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMiIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogIlAxVWdKaUZrbXpKd1VRMzhfMmJKR2pkbC02Ri1UQ1F4akUzZzNqRDNVZzAiLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "XYPw4wwC36mBORLmzLRjRJzaY4gU7KaCJDcYY0MC6klPPX9ackSYDFEjRYo1I-qsYHAmCu3iTdbxul6CZ-CwQQ"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"accepted": false,
|
||||
"reason": "UNSUPPORTED_FORMAT"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "response declaring an unsupported protocol major version",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-20T12:00:00Z",
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYyIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogIm85U0RpUzk0YjFBdkFCNE1waTB2VnBPQnVkd054VlZlT3NBMGZCai1LdUUiLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "ypN6eGOCWi0efKh-hkv_LmwX1pU8WNG0AG8PbZFlqvhGBPO2JFxhvyLz2BlI3rH7U7FBvbebjnlNOanf1blAzQ"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"accepted": false,
|
||||
"reason": "UNSUPPORTED_PROTOCOL"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "a byte identical replay of an accepted response",
|
||||
"artifact": "response",
|
||||
"answersChallenge": "challenge signed by a chained signing key under the pinned root",
|
||||
"signerKey": "device",
|
||||
"evaluationTime": "2026-08-20T12:00:01Z",
|
||||
"challengeAlreadyConsumed": true,
|
||||
"document": {
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS5lbnJvbGxtZW50UmVzcG9uc2UvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJjaGFsbGVuZ2VJZCI6ICIwMTk4ZjNhMS03ZjAwLTdkNDAtYmU1MS0zZjRhNWI2YzdkODMiLAogICAgIm9yZ2FuaXphdGlvbk5hbWUiOiAib3JnYW5pemF0aW9ucy8wMTk4ZjNhMS00YzAwLTdhMTAtOGIyMS0wYzFkMmUzZjRhNTAiLAogICAgImNsdXN0ZXJOYW1lIjogIm9yZ2FuaXphdGlvbnMvMDE5OGYzYTEtNGMwMC03YTEwLThiMjEtMGMxZDJlM2Y0YTUwL2NsdXN0ZXJzLzAxOThmM2ExLTVkMDAtN2IyMC05YzMxLTFkMmUzZjRhNWI2MSIsCiAgICAiY2hhbGxlbmdlTm9uY2UiOiAiVFZ4NGpLYVBnV1BsZFRTbTdfU3pLUGxINUhmaGtwcXFyOWJ5ZUNqWGRIVSIsCiAgICAiY2hhbGxlbmdlUHJvb2YiOiAiamlEVjRXeTgxV3dxUXdseFZxRjBlRlRoOWpFTW5EM21rVVdCNVhxR21wa1N3MFduVGRBanVWSDF3cVJNZVVFWWtaTERUdTdmQjVZSlJ2Qk4yd3JVdEEiLAogICAgImRldmljZUtleUlkIjogIjM5Y2EyNGM4YjAyYTU1OWZkOWJlYjJiMWY1ZDE4Y2VkMjBjNGJiMjQ2NTc3YjkyOTE0YWU2ODE0YzNmNzBhY2YiLAogICAgImRldmljZVB1YmxpY0tleSI6ICJCT1R1eUp6RkhqVzQyaFJsckNZM2JtTUJLMWdmdFQzYU5MaVRnQ3NKMV9lTlNkcjFHTTlhWTh3Mzlwb3BWTG9lZHdvZUFHQUJncDYxaEVhd2tFS3FJUDAiLAogICAgImRldmljZU5vbmNlIjogInB3bUwxVW9jSG5NYVUwa2w2ZVc0M3BfcllOakxBOGtJaUN2TDlibktwUGMiLAogICAgInByb2R1Y2VkQXQiOiAiMjAyNi0wOC0yMFQxMjowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"value": "n4joB8c1KbYvw7MSjeGs1BEYeYe8dFpy47Me_iD7MO1gUSKDpGl6MyCxuZ8KWmjzNMUWz1sgREEW8HsgpNlsIQ"
|
||||
}
|
||||
},
|
||||
"expected": {
|
||||
"signatureVerifies": true,
|
||||
"accepted": false,
|
||||
"reason": "ENROLLMENT_REPLAYED"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"protocolVersion": "v1",
|
||||
"fixtureSet": "offline-enrollment",
|
||||
"fixture": "trust-chain",
|
||||
"description": "The golden trust chain. bytes fields are standard padded base64 (RFC 4648 section 4) of the exact raw octets of the signed document; signature.value is unpadded base64url (RFC 4648 section 5) of the 64 octet r||s. No private key appears here or anywhere else in this repository: the vectors are for verification conformance, and a producer proves itself with the encoding rules rather than by reproducing these bytes.",
|
||||
"pinnedRoot": {
|
||||
"keyId": "df22e2806112debbe953672aafa186d699af0e97dd3fd2b09fa8359005fe348f",
|
||||
"publicKey": "BFfx-K-FfEA5nK_Rz3IHacvRCkJyQ7JOd1geLyU6HKRZDgNezmVuKhvJ22VhemyjV__Gshk8JGGqOBzYPMD0p6s",
|
||||
"source": "compiled into official RustFS builds"
|
||||
},
|
||||
"chain": [
|
||||
{
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS50cnVzdExpbmsvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJzZXJpYWwiOiAiYzI1OGE2ZGRjOThiYjVhNWU5NDRmNjJlMDY3OWE3NGUiLAogICAgInJvbGUiOiAiaW50ZXJtZWRpYXRlIiwKICAgICJpc3N1ZXJLZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICJzdWJqZWN0S2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAic3ViamVjdFB1YmxpY0tleSI6ICJCRHg1VnNXSVpKV3pDS2FUMDhfeFNIaGdhLWlzOTVhWU9oMG1kQTU0N2YyQWxGVExmeWVaajAxemVOaWtNdWRjQWZMVHg0REhYRGFHc3FQRFRZdFZ6RG8iLAogICAgIm5vdEJlZm9yZSI6ICIyMDI2LTAxLTAxVDAwOjAwOjAwWiIsCiAgICAibm90QWZ0ZXIiOiAiMjAyNy0wMS0wMVQwMDowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "df22e2806112debbe953672aafa186d699af0e97dd3fd2b09fa8359005fe348f",
|
||||
"value": "lXIxDmkvRX2CKL_NSMJ_ym-HJY48qoUz4h3bPPx33IFEv0E1gnSOWd1M2XprmIVRCvx8xN5CfYJ0L7wzsDA_FQ"
|
||||
}
|
||||
},
|
||||
{
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS50cnVzdExpbmsvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJzZXJpYWwiOiAiN2JmZmNmMDc4ZDc2NDg5OWE3MGZkYjFhZjliYmNkNjIiLAogICAgInJvbGUiOiAic2lnbmluZyIsCiAgICAiaXNzdWVyS2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAic3ViamVjdEtleUlkIjogIjA4ZTcyOTVjOGY5ZDA0M2UyMmIyYjgwZmRiMTQ4MGIwYmVjMDYwZGFjYmNlN2RlOWRkMmUzZDU4M2Y5M2Q3ZTgiLAogICAgInN1YmplY3RQdWJsaWNLZXkiOiAiQkdWSVU3eTVSaWgyaEk4LVBfaWwtR3VIVnRkUUxGeTJEaFFlRlU3cWh5YmJ0MjkxelNCa191eFlKSk5hQkRkZDl3TUM0RGZsWTVRQlBUOG1SNjdFZ2NBIiwKICAgICJub3RCZWZvcmUiOiAiMjAyNi0wOC0wMVQwMDowMDowMFoiLAogICAgIm5vdEFmdGVyIjogIjIwMjYtMDgtMzFUMDA6MDA6MDBaIgp9Cg==",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "04ebc74d30020f727988c96c2ffb22821883ee6b2e4c117f6e959dbd63f33d87",
|
||||
"value": "jhkdZ3yjn8-NwBqZ6cEKYVSla_UnUfTRVVcqk6IJwTMlwKVrYO1XFRU05m0VsEM18X3Zi8OzllhIP2R9qYC0kA"
|
||||
}
|
||||
}
|
||||
],
|
||||
"keys": [
|
||||
{
|
||||
"role": "enrollment-root",
|
||||
"name": "root",
|
||||
"keyId": "df22e2806112debbe953672aafa186d699af0e97dd3fd2b09fa8359005fe348f",
|
||||
"publicKey": "BFfx-K-FfEA5nK_Rz3IHacvRCkJyQ7JOd1geLyU6HKRZDgNezmVuKhvJ22VhemyjV__Gshk8JGGqOBzYPMD0p6s"
|
||||
},
|
||||
{
|
||||
"role": "intermediate",
|
||||
"name": "intermediate",
|
||||
"keyId": "04ebc74d30020f727988c96c2ffb22821883ee6b2e4c117f6e959dbd63f33d87",
|
||||
"publicKey": "BDx5VsWIZJWzCKaT08_xSHhga-is95aYOh0mdA547f2AlFTLfyeZj01zeNikMudcAfLTx4DHXDaGsqPDTYtVzDo"
|
||||
},
|
||||
{
|
||||
"role": "signing",
|
||||
"name": "signing",
|
||||
"keyId": "08e7295c8f9d043e22b2b80fdb1480b0bec060dacbce7de9dd2e3d583f93d7e8",
|
||||
"publicKey": "BGVIU7y5Rih2hI8-P_il-GuHVtdQLFy2DhQeFU7qhybbt291zSBk_uxYJJNaBDdd9wMC4DflY5QBPT8mR67EgcA"
|
||||
},
|
||||
{
|
||||
"role": "unchained",
|
||||
"name": "stray",
|
||||
"keyId": "f6fbe050defded18b50477ace38c9515fb61b8157e57b2f0e7e8ca69c862b6ca",
|
||||
"publicKey": "BMDdRSCtFB2w1c3buqktv-eGgMJeck5-rYvnTlvvfTuqg2NybM5gZLrnJCasieiR48JF-Sik-4UI_HCQM12ogsA"
|
||||
},
|
||||
{
|
||||
"role": "unpinned-root",
|
||||
"name": "rogueRoot",
|
||||
"keyId": "5ff37910aa4d69949e2c488f98d6072f10a3c3e73d776698963872582644f731",
|
||||
"publicKey": "BB4ldUQqSkfBQhYa10Otr2q43Yaka53dNLVD8nDThP_fVxFH_s04p_gIds6MDef11ukjZAhdgqQu_A8JLW3SzVk"
|
||||
},
|
||||
{
|
||||
"role": "unpinned-signing",
|
||||
"name": "rogueSigning",
|
||||
"keyId": "90f38a0dc2c5f948f47887a010ea3cb9e425d0409edb2a4014c7f7539bc22471",
|
||||
"publicKey": "BIGNnsOqMBI4LPD8JySg77E3vChI78R4AHgolxFcJNt9Z9GsMoVKIe9ZOdJOE38sFZt3oF5crU0HqdziGfiEp9U"
|
||||
},
|
||||
{
|
||||
"role": "device",
|
||||
"name": "device",
|
||||
"keyId": "39ca24c8b02a559fd9beb2b1f5d18ced20c4bb246577b92914ae6814c3f70acf",
|
||||
"publicKey": "BOTuyJzFHjW42hRlrCY3bmMBK1gftT3aNLiTgCsJ1_eNSdr1GM9aY8w39popVLoedwoeAGABgp61hEawkEKqIP0"
|
||||
},
|
||||
{
|
||||
"role": "device",
|
||||
"name": "foreignDevice",
|
||||
"keyId": "63d8184f2b2ec6895bb71b999c90192d7718694ba042bad86364b27628f9cb50",
|
||||
"publicKey": "BMwdwp6a50zSVsIa3NluDPaszxyIm2EeIbdukH38O3etEhoAlHXJrRblAltumHYlku6EBa_S3IBen8T8JOrr6Nk"
|
||||
},
|
||||
{
|
||||
"role": "device",
|
||||
"name": "revokedDevice",
|
||||
"keyId": "1f6a0c684716862c2507b48e72de25fbcb7db5c7aa629ff0c17e20b8a387d7ad",
|
||||
"publicKey": "BA9MuDkIi4fZSw98wCnbuEZUxqheO5Uks4rVTZa477kg30lb-aLAk5b8xM3kgnEq6PNCkSc28x_JaBPwPkBmwYk"
|
||||
}
|
||||
],
|
||||
"alternateChains": [
|
||||
{
|
||||
"name": "chain rooted at an unpinned key",
|
||||
"chain": [
|
||||
{
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS50cnVzdExpbmsvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJzZXJpYWwiOiAiMTNjZGI3NDhiMThjMDNiMjA0NzBjZjY2YTJkYjZhZjgiLAogICAgInJvbGUiOiAic2lnbmluZyIsCiAgICAiaXNzdWVyS2V5SWQiOiAiNWZmMzc5MTBhYTRkNjk5NDllMmM0ODhmOThkNjA3MmYxMGEzYzNlNzNkNzc2Njk4OTYzODcyNTgyNjQ0ZjczMSIsCiAgICAic3ViamVjdEtleUlkIjogIjkwZjM4YTBkYzJjNWY5NDhmNDc4ODdhMDEwZWEzY2I5ZTQyNWQwNDA5ZWRiMmE0MDE0YzdmNzUzOWJjMjI0NzEiLAogICAgInN1YmplY3RQdWJsaWNLZXkiOiAiQklHTm5zT3FNQkk0TFBEOEp5U2c3N0UzdkNoSTc4UjRBSGdvbHhGY0pOdDlaOUdzTW9WS0llOVpPZEpPRTM4c0ZadDNvRjVjclUwSHFkemlHZmlFcDlVIiwKICAgICJub3RCZWZvcmUiOiAiMjAyNi0wOC0wMVQwMDowMDowMFoiLAogICAgIm5vdEFmdGVyIjogIjIwMjYtMDgtMzFUMDA6MDA6MDBaIgp9Cg==",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "5ff37910aa4d69949e2c488f98d6072f10a3c3e73d776698963872582644f731",
|
||||
"value": "suxUbZ9Is1liQlhjfwXQoTeze4me9f7Qddr3299lmzpn-8VzH2kgTA5YvM9Bi-b4ATeHNLPBmkFDhaVoxX64Lw"
|
||||
}
|
||||
}
|
||||
],
|
||||
"reason": "ENROLLMENT_ROOT_UNKNOWN",
|
||||
"note": "Internally consistent and correctly signed. It fails only because its root is not pinned, which is exactly what trust on first use would have accepted."
|
||||
},
|
||||
{
|
||||
"name": "signing link already expired when the challenge was issued",
|
||||
"chain": [
|
||||
{
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS50cnVzdExpbmsvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJzZXJpYWwiOiAiYzI1OGE2ZGRjOThiYjVhNWU5NDRmNjJlMDY3OWE3NGUiLAogICAgInJvbGUiOiAiaW50ZXJtZWRpYXRlIiwKICAgICJpc3N1ZXJLZXlJZCI6ICJkZjIyZTI4MDYxMTJkZWJiZTk1MzY3MmFhZmExODZkNjk5YWYwZTk3ZGQzZmQyYjA5ZmE4MzU5MDA1ZmUzNDhmIiwKICAgICJzdWJqZWN0S2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAic3ViamVjdFB1YmxpY0tleSI6ICJCRHg1VnNXSVpKV3pDS2FUMDhfeFNIaGdhLWlzOTVhWU9oMG1kQTU0N2YyQWxGVExmeWVaajAxemVOaWtNdWRjQWZMVHg0REhYRGFHc3FQRFRZdFZ6RG8iLAogICAgIm5vdEJlZm9yZSI6ICIyMDI2LTAxLTAxVDAwOjAwOjAwWiIsCiAgICAibm90QWZ0ZXIiOiAiMjAyNy0wMS0wMVQwMDowMDowMFoiCn0K",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "df22e2806112debbe953672aafa186d699af0e97dd3fd2b09fa8359005fe348f",
|
||||
"value": "lXIxDmkvRX2CKL_NSMJ_ym-HJY48qoUz4h3bPPx33IFEv0E1gnSOWd1M2XprmIVRCvx8xN5CfYJ0L7wzsDA_FQ"
|
||||
}
|
||||
},
|
||||
{
|
||||
"bytes": "ewogICAgImZvcm1hdFZlcnNpb24iOiAicnVzdGZzLmNvbm5lY3Qub2ZmbGluZS50cnVzdExpbmsvMSIsCiAgICAicHJvdG9jb2xWZXJzaW9uIjogInYxIiwKICAgICJzZXJpYWwiOiAiY2EwOWYzZTVhZDkxOTEwNmQxMjZjODRlZGRjNDViZTgiLAogICAgInJvbGUiOiAic2lnbmluZyIsCiAgICAiaXNzdWVyS2V5SWQiOiAiMDRlYmM3NGQzMDAyMGY3Mjc5ODhjOTZjMmZmYjIyODIxODgzZWU2YjJlNGMxMTdmNmU5NTlkYmQ2M2YzM2Q4NyIsCiAgICAic3ViamVjdEtleUlkIjogIjA4ZTcyOTVjOGY5ZDA0M2UyMmIyYjgwZmRiMTQ4MGIwYmVjMDYwZGFjYmNlN2RlOWRkMmUzZDU4M2Y5M2Q3ZTgiLAogICAgInN1YmplY3RQdWJsaWNLZXkiOiAiQkdWSVU3eTVSaWgyaEk4LVBfaWwtR3VIVnRkUUxGeTJEaFFlRlU3cWh5YmJ0MjkxelNCa191eFlKSk5hQkRkZDl3TUM0RGZsWTVRQlBUOG1SNjdFZ2NBIiwKICAgICJub3RCZWZvcmUiOiAiMjAyNi0wNi0wMVQwMDowMDowMFoiLAogICAgIm5vdEFmdGVyIjogIjIwMjYtMDctMDFUMDA6MDA6MDBaIgp9Cg==",
|
||||
"signature": {
|
||||
"algorithm": "ES256",
|
||||
"keyId": "04ebc74d30020f727988c96c2ffb22821883ee6b2e4c117f6e959dbd63f33d87",
|
||||
"value": "SX75WdOVLvphRMcce0xq7W5-Er0HSVhBcsUng1Uv8RAPR23prCH5oJOF06A_h7xHAj9XL7YeuxRStPs_pkTNrA"
|
||||
}
|
||||
}
|
||||
],
|
||||
"reason": "TRUST_CHAIN_INVALID",
|
||||
"note": "notAfter is 2026-07-01T00:00:00Z and the challenge issuedAt is 2026-08-17T00:00:00Z."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
{
|
||||
"protocolVersion": "v1",
|
||||
"fixtureSet": "offline-enrollment",
|
||||
"fixture": "trust-model",
|
||||
"description": "The frozen offline trust model: how an air-gapped device and Connect authenticate signed artifacts to each other without a network, a certificate, or trust on first use. R05 (the RustFS CLI) and R07 (the bundle writer) implement against this file; api/tests/Feature/Diagnostics/OfflineTrustFixtureTest.php replays it.",
|
||||
"signature": {
|
||||
"signatureAlgorithm": "ES256",
|
||||
"curve": "P-256",
|
||||
"hash": "SHA-256",
|
||||
"signatureEncoding": "fixed-width-r-s",
|
||||
"signatureLengthBytes": 64,
|
||||
"signatureTransferEncoding": "base64url-unpadded",
|
||||
"signatureValuePattern": "^[A-Za-z0-9_-]{86}$",
|
||||
"lowSRequired": true,
|
||||
"groupOrder": "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
|
||||
"maxS": "7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8",
|
||||
"publicKeyEncoding": "sec1-uncompressed",
|
||||
"publicKeyLengthBytes": 65,
|
||||
"publicKeyTransferEncoding": "base64url-unpadded",
|
||||
"subjectPublicKeyInfoDerPrefix": "3059301306072a8648ce3d020106082a8648ce3d030107034200",
|
||||
"keyIdAlgorithm": "SHA-256",
|
||||
"keyIdOver": "DER SubjectPublicKeyInfo",
|
||||
"keyIdEncoding": "lowercase-hex",
|
||||
"keyIdPattern": "^[0-9a-f]{64}$",
|
||||
"documentTransferEncoding": "base64-padded"
|
||||
},
|
||||
"domainSeparation": {
|
||||
"rule": "signatureInput = domainSeparationTag || 0x00 || the exact raw octets of the signed document as transmitted",
|
||||
"separatorByte": "0x00",
|
||||
"tagEncoding": "US-ASCII, no terminator beyond the single 0x00 separator",
|
||||
"reserialisationPermitted": false,
|
||||
"canonicalisationPermitted": false,
|
||||
"note": "A verifier never parses, re-encodes, re-indents, reorders, or normalises a document before verifying it. It hashes the bytes it received. Parsing happens only after the signature over those exact bytes has verified.",
|
||||
"tags": {
|
||||
"trustLink": "rustfs-offline-trust-link-v1",
|
||||
"enrollmentChallenge": "rustfs-offline-enrollment-challenge-v1",
|
||||
"enrollmentResponse": "rustfs-offline-enrollment-response-v1",
|
||||
"supportBundleManifest": "rustfs-support-bundle-v1"
|
||||
}
|
||||
},
|
||||
"verifierMustReject": [
|
||||
"A signature that is not exactly 64 octets of fixed-width r||s.",
|
||||
"A DER or any other ASN.1 encoded signature, even when it decodes to the same r and s.",
|
||||
"A signature encoded with the standard base64 alphabet or with = padding.",
|
||||
"A signature whose r or s is zero, or is greater than or equal to the group order.",
|
||||
"A signature whose s is greater than half the group order, even though such a signature verifies mathematically. ECDSA is malleable and only the low-S form is a canonical artifact identity.",
|
||||
"An algorithm value other than ES256, including a downgrade to a hash other than SHA-256.",
|
||||
"A public key that is not a 65 octet uncompressed SEC1 point on P-256, and any compressed or hybrid point form.",
|
||||
"A keyId that is not the lowercase SHA-256 hex of the DER SubjectPublicKeyInfo built from the accompanying public key.",
|
||||
"A signature checked against re-serialised, re-indented, key-reordered, or otherwise regenerated document bytes rather than the received octets.",
|
||||
"A document that verifies under one domain separation tag being accepted for another artifact type."
|
||||
],
|
||||
"rejectedSignatureEncodings": [
|
||||
{
|
||||
"name": "high-S signature over an otherwise valid challenge",
|
||||
"value": "jiDV4Wy81WwqQwlxVqF0eFTh9jEMnD3mkUWB5XqGmpntPLpXsi_cR64KPVuzhr7nK1Q3Xrg4lu7qctp1IVhQnQ",
|
||||
"acceptedByALenientVerifier": true,
|
||||
"reason": "SIGNATURE_NOT_CANONICAL",
|
||||
"note": "The malleated pair (r, n - s) of a valid signature. Every ECDSA library accepts it, which is exactly why the encoding rule and not the library has to reject it."
|
||||
},
|
||||
{
|
||||
"name": "DER encoded signature",
|
||||
"value": "MEUCIQCOINXhbLzVbCpDCXFWoXR4VOH2MQycPeaRRYHleoaamQIgEsNFp03QI7lR9cKkTHlBGJGSw07u3weWCUbwTdsK1LQ",
|
||||
"acceptedByALenientVerifier": true,
|
||||
"reason": "SIGNATURE_MALFORMED",
|
||||
"note": "The same r and s in ASN.1. A verifier that hands whatever it decoded to its library accepts it; this surface has exactly one signature encoding."
|
||||
},
|
||||
{
|
||||
"name": "padded base64url signature",
|
||||
"value": "jiDV4Wy81WwqQwlxVqF0eFTh9jEMnD3mkUWB5XqGmpkSw0WnTdAjuVH1wqRMeUEYkZLDTu7fB5YJRvBN2wrUtA==",
|
||||
"acceptedByALenientVerifier": true,
|
||||
"reason": "SIGNATURE_MALFORMED",
|
||||
"note": "The same 64 octets with = padding. Two spellings of one signature would make the signature useless as an artifact identity."
|
||||
},
|
||||
{
|
||||
"name": "truncated signature",
|
||||
"value": "jiDV4Wy81WwqQwlxVqF0eFTh9jEMnD3mkUWB5XqGmpkSw0WnTdAjuVH1wqRMeUEYkZLDTu7fB5YJRvBN",
|
||||
"acceptedByALenientVerifier": false,
|
||||
"reason": "SIGNATURE_MALFORMED",
|
||||
"note": "Sixty octets. Left-padding it back to 64 would change r, so a verifier must reject rather than repair."
|
||||
},
|
||||
{
|
||||
"name": "zero r and zero s",
|
||||
"value": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
||||
"acceptedByALenientVerifier": false,
|
||||
"reason": "SIGNATURE_MALFORMED",
|
||||
"note": "Well formed in length and alphabet, and out of range in value."
|
||||
}
|
||||
],
|
||||
"verificationOrder": {
|
||||
"principle": "Parse as late as the verification key allows, and treat anything read before the signature verified as untrusted routing information rather than as a fact.",
|
||||
"enrollmentChallenge": {
|
||||
"note": "A challenge carries its own chain, so the CLI must read structure before it can verify anything. The pre-parse yields only trustChain, connectKeyId, and issuedAt, and none of them is believed: the chain has to close on a pinned root, and the challenge signature has to verify, before any other field is used.",
|
||||
"steps": [
|
||||
"check the signature encoding",
|
||||
"pre-parse the untrusted document for trustChain, connectKeyId, and issuedAt",
|
||||
"reject unless trustChain[0].issuerKeyId is a pinned root",
|
||||
"verify every trust link against its issuer and its validity at issuedAt",
|
||||
"reject unless connectKeyId is the subject of the last link",
|
||||
"verify the challenge signature over the received octets",
|
||||
"only now read protocolVersion, then formatVersion",
|
||||
"check the freshness window"
|
||||
]
|
||||
},
|
||||
"enrollmentResponse": {
|
||||
"note": "A response presents the device key it is enrolling, so Connect necessarily reads that key from the document. Proof of possession is what makes it safe: the presented key must be the key that signed the presenting document.",
|
||||
"steps": [
|
||||
"check the signature encoding",
|
||||
"reject unless deviceKeyId is the fingerprint of devicePublicKey and the signature verifies under devicePublicKey",
|
||||
"only now read protocolVersion, then formatVersion",
|
||||
"compare organization, then cluster, against the stored challenge",
|
||||
"compare challengeId, challengeNonce, and challengeProof against the stored challenge",
|
||||
"check the freshness window against producedAt, then against the receive time",
|
||||
"reject a challenge that was already consumed"
|
||||
]
|
||||
},
|
||||
"supportBundleManifest": {
|
||||
"note": "Connect already knows which device key is effective for a bundle, so nothing has to be parsed to find the verification key. Verification comes first and the manifest is not parsed at all until it has.",
|
||||
"steps": [
|
||||
"check the signature encoding",
|
||||
"resolve the detached signature keyId against the enrolled keys of the named bundle device",
|
||||
"verify the manifest signature over the raw manifest octets",
|
||||
"only now parse the manifest, and read protocolVersion, then formatVersion",
|
||||
"reject unless the manifest deviceKeyId is the key that signed it",
|
||||
"compare organization, cluster, and device against the authorised bundle",
|
||||
"check redactionVersion, then every entry type and classification",
|
||||
"check the freshness window",
|
||||
"reject a replayed nonce"
|
||||
]
|
||||
}
|
||||
},
|
||||
"trustAnchor": {
|
||||
"trustOnFirstUse": false,
|
||||
"rootLearnedFromArtifact": false,
|
||||
"rootShippedWithArtifact": false,
|
||||
"distribution": "The hosted RustFS enrollment root public key fingerprint is compiled into official RustFS builds. It is never read from a challenge, a bundle, a configuration file, or an operator prompt.",
|
||||
"pinnedRootKeyIds": [
|
||||
"df22e2806112debbe953672aafa186d699af0e97dd3fd2b09fa8359005fe348f"
|
||||
],
|
||||
"pinnedRootPublicKeys": [
|
||||
{
|
||||
"keyId": "df22e2806112debbe953672aafa186d699af0e97dd3fd2b09fa8359005fe348f",
|
||||
"publicKey": "BFfx-K-FfEA5nK_Rz3IHacvRCkJyQ7JOd1geLyU6HKRZDgNezmVuKhvJ22VhemyjV__Gshk8JGGqOBzYPMD0p6s"
|
||||
}
|
||||
],
|
||||
"chainLinkCount": 2,
|
||||
"maxChainLinkCount": 2,
|
||||
"chainOrder": "index 0 is issued by a pinned root, index 1 is issued by the subject of index 0",
|
||||
"note": "Because no root is ever learned at runtime, an operator cannot be socially engineered into accepting an attacker root, and a stolen intermediate cannot mint its own root. The cost is that a root rollover requires redistributing the RustFS build, which is stated in rollover.root."
|
||||
},
|
||||
"keyHierarchy": [
|
||||
{
|
||||
"role": "enrollment-root",
|
||||
"holder": "RustFS",
|
||||
"algorithm": "ES256",
|
||||
"signs": [
|
||||
"intermediate trust links"
|
||||
],
|
||||
"maxValiditySeconds": null,
|
||||
"distribution": "pinned in official RustFS builds"
|
||||
},
|
||||
{
|
||||
"role": "intermediate",
|
||||
"holder": "RustFS Connect",
|
||||
"algorithm": "ES256",
|
||||
"signs": [
|
||||
"signing trust links"
|
||||
],
|
||||
"maxValiditySeconds": 31536000,
|
||||
"distribution": "carried inside every challenge as a signed trust link"
|
||||
},
|
||||
{
|
||||
"role": "signing",
|
||||
"holder": "RustFS Connect",
|
||||
"algorithm": "ES256",
|
||||
"signs": [
|
||||
"enrollment challenges"
|
||||
],
|
||||
"maxValiditySeconds": 2678400,
|
||||
"distribution": "carried inside every challenge as a signed trust link"
|
||||
},
|
||||
{
|
||||
"role": "device",
|
||||
"holder": "the air-gapped cluster device",
|
||||
"algorithm": "ES256",
|
||||
"signs": [
|
||||
"enrollment responses",
|
||||
"support bundle manifests"
|
||||
],
|
||||
"maxValiditySeconds": null,
|
||||
"distribution": "generated on the device, never transmitted; only the public point leaves it"
|
||||
}
|
||||
],
|
||||
"rollover": {
|
||||
"root": {
|
||||
"mechanism": "A new root is pinned by shipping a new official RustFS build. Both the outgoing and the incoming root stay pinned for the overlap window so a device running either build can still enroll.",
|
||||
"maxOverlapSeconds": 31536000,
|
||||
"learnedAtRuntime": false,
|
||||
"consequence": "A device that never takes a new build eventually cannot enroll. That is the accepted cost of refusing trust on first use."
|
||||
},
|
||||
"intermediate": {
|
||||
"mechanism": "Overlapping links. A challenge carries exactly the chain that validated it when it was issued, so a rolled intermediate does not invalidate challenges already in the field.",
|
||||
"maxValiditySeconds": 31536000,
|
||||
"validityEvaluatedAgainst": "the issuedAt of the challenge that carries the link, with no skew tolerance"
|
||||
},
|
||||
"signing": {
|
||||
"mechanism": "Overlapping links, rotated at least monthly.",
|
||||
"maxValiditySeconds": 2678400,
|
||||
"validityEvaluatedAgainst": "the issuedAt of the challenge that carries the link, with no skew tolerance"
|
||||
},
|
||||
"device": {
|
||||
"mechanism": "A device key is durable. Replacing it is a new enrollment: a fresh challenge, a fresh response, and a fresh device public key. There is no in-band device key rotation message.",
|
||||
"maxOverlapSeconds": 604800,
|
||||
"consequence": "The outgoing device key is revoked when the incoming one becomes effective, so a device never has more than one effective offline key."
|
||||
}
|
||||
},
|
||||
"revocation": {
|
||||
"device": {
|
||||
"effect": "immediate",
|
||||
"authority": "Connect, which holds the device key state and evaluates every artifact it receives",
|
||||
"retroactive": true,
|
||||
"note": "An artifact signed before revocation but received after it is still rejected. Revocation is not a validity window and past signatures are not grandfathered.",
|
||||
"reason": "DEVICE_KEY_REVOKED"
|
||||
},
|
||||
"signing": {
|
||||
"effect": "bounded by link validity",
|
||||
"authority": "RustFS Connect",
|
||||
"mechanism": "No CRL and no OCSP: an air-gapped device cannot fetch either, and a revocation list carried inside the artifact would simply be omitted by an attacker. Exposure is bounded by the 31 day signing link validity, and official RustFS builds additionally carry a denylist of revoked keyIds updated with each release."
|
||||
},
|
||||
"intermediate": {
|
||||
"effect": "bounded by link validity",
|
||||
"authority": "RustFS",
|
||||
"mechanism": "Same as signing, bounded by the 365 day intermediate link validity plus the build denylist."
|
||||
},
|
||||
"root": {
|
||||
"effect": "requires redistributing official RustFS builds",
|
||||
"authority": "RustFS",
|
||||
"mechanism": "There is nothing above the root to revoke it. This asymmetry is deliberate and is the reason the root signs nothing except intermediate links."
|
||||
},
|
||||
"asymmetry": "Connect can revoke a device key instantly because Connect holds that state and sees every artifact. A device cannot learn about a revoked Connect key promptly, because it has no network. Every offline-facing key therefore has a short validity instead of a revocation channel."
|
||||
},
|
||||
"clockSkew": {
|
||||
"toleranceSeconds": 300,
|
||||
"deviceClockAuthority": "advisory",
|
||||
"challengeWindow": "accepted while verifierNow is within [issuedAt - 300, expiresAt + 300]",
|
||||
"chainLinkWindow": "each link must satisfy notBefore <= challenge.issuedAt <= notAfter, evaluated with no tolerance because the issuer controls both values",
|
||||
"maxChallengeLifetimeSeconds": 604800,
|
||||
"maxManifestAgeSeconds": 2592000,
|
||||
"maxManifestFutureSkewSeconds": 300,
|
||||
"responseWindow": "producedAt must fall within [challenge.issuedAt - 300, challenge.expiresAt + 300]",
|
||||
"note": "ADR 0003 already treats client clocks as advisory for heartbeat freshness. An air-gapped device is worse: it may have no synchronised clock at all. Every window is therefore evaluated against the Connect clock for artifacts Connect receives, and against the issuer-supplied issuedAt for the chain a device validates locally."
|
||||
},
|
||||
"replay": {
|
||||
"challengeIdSingleUse": true,
|
||||
"consumedChallengeRetention": "until expiresAt + 300 seconds, so a late replay still meets a stored record rather than an empty table",
|
||||
"nonceLengthBytes": 32,
|
||||
"nonceEncoding": "base64url-unpadded",
|
||||
"noncePattern": "^[A-Za-z0-9_-]{43}$",
|
||||
"manifestNonceUniqueness": "unique per organization, cluster, and device for at least maxManifestAgeSeconds",
|
||||
"signatureCanonicality": "Low-S normalisation makes the 64 octet signature a canonical identity for the artifact, so a malleated copy is not a second distinct artifact and cannot slip past deduplication.",
|
||||
"reasons": [
|
||||
"ENROLLMENT_REPLAYED",
|
||||
"BUNDLE_REPLAYED"
|
||||
]
|
||||
},
|
||||
"versioning": {
|
||||
"protocolVersionRule": "Identical to protocol/agent/v1/authentication.md: protocolVersion is v<major> matching ^v[1-9][0-9]{0,3}$, Connect supports major 1, and anything else fails closed with UNSUPPORTED_PROTOCOL and HTTP 400. Nothing is partially processed.",
|
||||
"supportedMajorVersions": [
|
||||
1
|
||||
],
|
||||
"protocolVersionPattern": "^v[1-9][0-9]{0,3}$",
|
||||
"formatVersionRule": "formatVersion is matched exactly against the closed list below. An unknown value fails closed with UNSUPPORTED_FORMAT and is never guessed at, prefix-matched, or downgraded.",
|
||||
"supportedFormatVersions": [
|
||||
"rustfs.connect.offline.trustLink/1",
|
||||
"rustfs.connect.offline.enrollmentChallenge/1",
|
||||
"rustfs.connect.offline.enrollmentResponse/1",
|
||||
"rustfs.connect.support.bundleManifest/1"
|
||||
],
|
||||
"additive": {
|
||||
"unknownOptionalFieldPolicy": "accept-and-discard",
|
||||
"unknownOptionalEntryFieldPolicy": "accept-and-discard",
|
||||
"echoedBack": false,
|
||||
"stored": false,
|
||||
"absentOptionalFieldPolicy": "take the documented default",
|
||||
"requiredFieldsMayBeAdded": false,
|
||||
"existingFieldsMayChangeTypeOrMeaning": false,
|
||||
"signatureImpact": "None. An unknown field is inside the signed octets and is therefore authentic; discarding it after verification cannot change the signature input, because the input is the received bytes and not a projection of the parsed document."
|
||||
},
|
||||
"closedEnumerations": {
|
||||
"note": "Enumerated values are closed and are NOT additive. Only optional fields are additive. An unrecognised enumerated value is a rejection, never a discard, because silently ignoring an unknown classification or entry type would let a producer widen what it collects.",
|
||||
"enumerations": [
|
||||
"signature.algorithm",
|
||||
"trustLink.role",
|
||||
"manifest.entries[].type",
|
||||
"manifest.entries[].classification"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user