UAF: Conformance Testing API - fido-alliance/conformance-test-tools-resources GitHub Wiki
To perform conformance testing, server vendor must implement standardised API adapter. This document describes all API endpoints and their behaviour. This document is based and fully compliant with Client and API specification.
If you have any question, issue or suggestions regarding this document, please email to [email protected]
-
Contents
-
IDL Definitions
-
8.3.3 GetUAFRequest dictionary
dictionary GetUAFRequest { Operation op; DOMString previousRequest; DOMString context; };
-
GetUAFRequestContext
dictionary GetUAFRequestContext { required DOMString username; DOMString transaction; DOMString deregisterAAID; boolean deregisterAll; };
- required DOMString
username
- a mandatory username - DOMString
transaction
- Only applies to Authentication requests(op isAuth
). If set, server must return transaction with the value of the field. - DOMString
deregisterAAID
- Only applies to Deregistration requests(op isDereg
). If set, server must return a deregistration request for the given AAID. Server must validate AAID before sending deregistration request. - boolean
deregisterAll
- Only applies to Deregistration requests(op isDereg
). If set to true, server must return a deregistration request, to deregister all authenticators for the given user.
- required DOMString
-
8.3.4 ReturnUAFRequest dictionary
dictionary ReturnUAFRequest { required unsigned long statusCode; DOMString uafRequest; Operation op; long lifetimeMillis; };
-
8.3.5 SendUAFResponse dictionary
dictionary ReturnUAFRequest { required unsigned long statusCode; DOMString uafRequest; Operation op; long lifetimeMillis; };
-
8.3.7 ServerResponse Interface
dictionary ServerResponse { int statusCode; DOMString description; Token[] additionalTokens; DOMString location; DOMString postData; DOMString newUAFRequest; };
-
Getting registration request
-
URL
- /get
-
Method:
POST
-
URL Params
- None
-
Data Params
- Example request
{ "op" : "Reg", "context" : "{\"username\" : \"alice\"}" }
-
Success Response:
- Code: 200 OK
{ "statusCode" : 1200, "uafRequest" : "[{\"header\":{\"upv\":{\"major\":1,\"minor\":1},\"op\":\"Auth\",\"appID\":\"https://uaf.example.com\",\"serverData\":\"5s7n8-7_LDAtRIKKYqbAtTTOezVKCjl2mPorYzbpxRrZ-_3wWroMXsF_pLYjNVm_l7bplAx4bkEwK6ibil9EHGfdfKOQ1q0tyEkNJFOgqdjVmLioroxgThlj8Istpt7q\"},\"challenge\":\"HQ1VkTUQC1NJDOo6OOWdxewrb9i5WthjfKIehFxpeuU\",\"policy\":{\"accepted\":[{\"aaid\":[\"FFFF#FFFF\"]}](/fido-alliance/conformance-test-tools-resources/wiki/{\"aaid\":[\"FFFF#FFFF\"]})}}]"} }
-
Error Response:
-
Example
Unauthorized
{ "statusCode" : 1401 }
-
-
Sample Call:
fetch('/get', { method : 'POST', credentials : 'same-origin', headers : { 'Content-Type' : 'application/json' }, body: JSON.stringify({ "op" : "Reg", "context" : "{\"username\" : \"alice\"}" }) }).then(function (response) { return response.json(); }).then(function (json) { console.log(json); }).catch(function (err) { console.log({ 'status': 'failed', 'error': err }); })
Sending registration response
-
URL
- /respond
-
Method:
POST
-
URL Params
- None
-
Data Params
- Example response
{ "uafResponse" : "[{\"header\":{\"upv\":{\"major\":1,\"minor\":1},\"op\":\"Reg\",\"appID\":\"https://uaf.example.com/facets.json\",\"serverData\":\"ZQ_fRGDH2ar_LvrTM8JnQcl-wfnaOutiyCmpBgmMcuE\"},\"fcParams\":\"eyJmYWNldElEIjoiaHR0cHM6Ly91YWYuZXhhbXBsZS5jb20vaW5kZXguaHRtbCIsImFwcElEIjoiaHR0cHM6Ly91YWYuZXhhbXBsZS5jb20vZmFjZXRzLmpzb24iLCJjaGFsbGVuZ2UiOiJZYjM5U2RVaFUyQjAwODlwUzVMN1ZCVzhhZmRscGxudlI0QjFBbmE1dms0IiwiY2hhbm5lbEJpbmRpbmciOnt9fQ\",\"assertions\":[{\"assertionScheme\":\"UAFV1TLV\",\"assertion\":\"AT73AgM-sQALLgkARkZGRiNGQzAzDi4HAAEAAQIAAAEKLiAAbkZZjz4ysihP9vVgevgoH8SEV2JITkTxKFfsKbAiofQJLiAA2onnfjAyZ0Uc3GL4VyOEdRgIkz7q...-i2wq1FnD_svIyTyEYm_QbOYJC0GUVE-L6V7OiD8K9Z4PfiBFRO-qMdMBswDAYDVR0TBAUwAwEB_zALBgNVHQ8EBAMCBsAwCgYIKoZIzj0EAwIDSAAwRQIgWDy1Oxu8PT6diGXycY0rxb1e16omexfQ-Iv9KOg5p9cCIQCFPPCArmDh3-EyxI_OaZFPvW2kG2hQBmi9PnC-bBrfYQ\"}]}]", "context" : "{\"username\" : \"alice\"}" }
-
Success Response:
- Code: 200 OK
{ "statusCode" : 1200 }
-
Error Response:
-
Example
Bad response
{ "statusCode" : 1400 }
-
-
Sample Call:
fetch('/get', { method : 'POST', credentials : 'same-origin', headers : { 'Content-Type' : 'application/json' }, body: JSON.stringify({ "uafResponse" : "[{\"header\":{\"upv\":{\"major\":1,\"minor\":1},\"op\":\"Reg\",\"appID\":\"https://uaf.example.com/facets.json\",\"serverData\":\"ZQ_fRGDH2ar_LvrTM8JnQcl-wfnaOutiyCmpBgmMcuE\"},\"fcParams\":\"eyJmYWNldElEIjoiaHR0cHM6Ly91YWYuZXhhbXBsZS5jb20vaW5kZXguaHRtbCIsImFwcElEIjoiaHR0cHM6Ly91YWYuZXhhbXBsZS5jb20vZmFjZXRzLmpzb24iLCJjaGFsbGVuZ2UiOiJZYjM5U2RVaFUyQjAwODlwUzVMN1ZCVzhhZmRscGxudlI0QjFBbmE1dms0IiwiY2hhbm5lbEJpbmRpbmciOnt9fQ\",\"assertions\":[{\"assertionScheme\":\"UAFV1TLV\",\"assertion\":\"AT73AgM-sQALLgkARkZGRiNGQzAzDi4HAAEAAQIAAAEKLiAAbkZZjz4ysihP9vVgevgoH8SEV2JITkTxKFfsKbAiofQJLiAA2onnfjAyZ0Uc3GL4VyOEdRgIkz7q...-i2wq1FnD_svIyTyEYm_QbOYJC0GUVE-L6V7OiD8K9Z4PfiBFRO-qMdMBswDAYDVR0TBAUwAwEB_zALBgNVHQ8EBAMCBsAwCgYIKoZIzj0EAwIDSAAwRQIgWDy1Oxu8PT6diGXycY0rxb1e16omexfQ-Iv9KOg5p9cCIQCFPPCArmDh3-EyxI_OaZFPvW2kG2hQBmi9PnC-bBrfYQ\"}]}]", "context" : "{\"username\" : \"alice\"}" }) }).then(function (response) { return response.json(); }).then(function (json) { console.log(json); }).catch(function (err) { console.log({ 'status': 'failed', 'error': err }); })
Getting authentication request
-
URL
- /get
-
Method:
POST
-
URL Params
- None
-
Data Params
- Example request
{ "op" : "Auth", "context" : "{\"username\" : \"alice\"}" }
- Example request with transaction confirmation
{ "op" : "Auth", "context" : "{\"username\" : \"alice\", \"transaction\":\"Transfer 1000$ to Bob?\"}" }
-
Success Response:
- Code: 200 OK
{ "statusCode" : 1200, "uafRequest" : "[{\"header\":{\"upv\":{\"major\":1,\"minor\":1},\"op\":\"Auth\",\"appID\":\"https://uaf.example.com\",\"serverData\":\"5s7n8-7_LDAtRIKKYqbAtTTOezVKCjl2mPorYzbpxRrZ-_3wWroMXsF_pLYjNVm_l7bplAx4bkEwK6ibil9EHGfdfKOQ1q0tyEkNJFOgqdjVmLioroxgThlj8Istpt7q\"},\"challenge\":\"HQ1VkTUQC1NJDOo6OOWdxewrb9i5WthjfKIehFxpeuU\",\"policy\":{\"accepted\":[{\"aaid\":[\"FFFF#FFFF\"]}](/fido-alliance/conformance-test-tools-resources/wiki/{\"aaid\":[\"FFFF#FFFF\"]})}}]"} }
-
Error Response:
-
Example
Unauthorized
{ "statusCode" : 1401 }
-
-
Sample Call:
fetch('/get', { method : 'POST', credentials : 'same-origin', headers : { 'Content-Type' : 'application/json' }, body: JSON.stringify({ "op" : "Auth", "context" : "{\"username\" : \"alice\"}" }) }).then(function (response) { return response.json(); }).then(function (json) { console.log(json); }).catch(function (err) { console.log({ 'status': 'failed', 'error': err }); })
Sending authentication response
-
URL
- /respond
-
Method:
POST
-
URL Params
- None
-
Data Params
- Example response
{ "uafResponse" : "[{\"header\":{\"upv\":{\"major\":1,\"minor\":1},\"op\":\"Auth\",\"appID\":\"https://uaf.example.com/facets.json\",\"serverData\":\"mz0YSKHLXDd_StbbDINZaRvW3Pa6sxrNMPYp2gOs3-Y\"},\"fcParams\":\"eyJmYWNldElEIjoiaHR0cHM6Ly91YWYuZXhhbXBsZS5jb20vaW5kZXguaHRtbCIsImFwcElEIjoiaHR0cHM6Ly91YWYuZXhhbXBsZS5jb20vZmFjZXRzLmpzb24iLCJjaGFsbGVuZ2UiOiI0RDhlVXhkU3pRX1JiazdHZjBTb29LN1hyOU8yTFUtZzE1MHN0T3BLMGdvIiwiY2hhbm5lbEJpbmRpbmciOnt9fQ\",\"assertions\":[{\"assertionScheme\":\"UAFV1TLV\",\"assertion\":\"Aj7EAAQ-dgALLgkARkZGRiNGQzAzDi4FAAEAAQIADy4IAB4gsCir67EvCi4gAMYR1ZSqYuPLiNpYlomDJYGZZGQRGSlLlThqf8ZzF-k2EC4AAAkuIADaied-MDJnRRzcYvhXI4R1GAiTPuqiCrOYhNwQ8ui8_Q0uBAABAAAABi5GADBEAiDDt4-pzmEWZyakWcWGdtBQLIXSf75wL3tEjiCIry_QtQIgjw0oMlQqKOHdG2M26e1Z0bG4wGjfow_vu5zp-VkALFo\"}]}]", "context" : "{\"username\" : \"alice\"}" }
-
Success Response:
- Code: 200 OK
{ "statusCode" : 1200 }
-
Error Response:
-
Example
Bad response
{ "statusCode" : 1400 }
-
-
Sample Call:
fetch('/respond', { method : 'POST', credentials : 'same-origin', headers : { 'Content-Type' : 'application/json' }, body: JSON.stringify({ "uafResponse" : "[{\"header\":{\"upv\":{\"major\":1,\"minor\":1},\"op\":\"Auth\",\"appID\":\"https://uaf.example.com/facets.json\",\"serverData\":\"mz0YSKHLXDd_StbbDINZaRvW3Pa6sxrNMPYp2gOs3-Y\"},\"fcParams\":\"eyJmYWNldElEIjoiaHR0cHM6Ly91YWYuZXhhbXBsZS5jb20vaW5kZXguaHRtbCIsImFwcElEIjoiaHR0cHM6Ly91YWYuZXhhbXBsZS5jb20vZmFjZXRzLmpzb24iLCJjaGFsbGVuZ2UiOiI0RDhlVXhkU3pRX1JiazdHZjBTb29LN1hyOU8yTFUtZzE1MHN0T3BLMGdvIiwiY2hhbm5lbEJpbmRpbmciOnt9fQ\",\"assertions\":[{\"assertionScheme\":\"UAFV1TLV\",\"assertion\":\"Aj7EAAQ-dgALLgkARkZGRiNGQzAzDi4FAAEAAQIADy4IAB4gsCir67EvCi4gAMYR1ZSqYuPLiNpYlomDJYGZZGQRGSlLlThqf8ZzF-k2EC4AAAkuIADaied-MDJnRRzcYvhXI4R1GAiTPuqiCrOYhNwQ8ui8_Q0uBAABAAAABi5GADBEAiDDt4-pzmEWZyakWcWGdtBQLIXSf75wL3tEjiCIry_QtQIgjw0oMlQqKOHdG2M26e1Z0bG4wGjfow_vu5zp-VkALFo\"}]}]", "context" : "{\"username\" : \"alice\"}" }) }).then(function (response) { return response.json(); }).then(function (json) { console.log(json); }).catch(function (err) { console.log({ 'status': 'failed', 'error': err }); })
Getting deregistration request
-
URL
- /get
-
Method:
POST
-
URL Params
- None
-
Data Params
- Example request
{ "op" : "Dereg", "context" : "{\"username\" : \"alice\"}" }
- Example request to deregister all users for specific authenticator
{ "op" : "Dereg", "context" : "{\"username\" : \"alice\", \"deregisterAAID\" : \"FFFF#FFFF\"}" }
- Example request to deregister all authenticators
{ "op" : "Dereg", "context" : "{\"username\" : \"alice\", \"deregisterAll\" : true}" }
-
Success Response:
- Code: 200 OK
{ "statusCode" : 1200, "uafRequest" : "[{\"header\":{\"op\":\"Dereg\",\"upv\":{\"major\":1,\"minor\":1},\"appID\":\"https://uaf.example.com\"},\"authenticators\":[{\"aaid\":\"ABCD#ABCD\",\"keyID\":\"ZMCPn92yHv1Ip-iCiBb6i4ADq6ZOv569KFQCvYSJfNg\"}]}]"} }
-
Error Response:
-
Example
Unauthorized
{ "statusCode" : 1401 }
-
-
Sample Call:
fetch('/get', { method : 'POST', credentials : 'same-origin', headers : { 'Content-Type' : 'application/json' }, body: JSON.stringify({ "op" : "Dereg", "context" : "{\"username\" : \"alice\"}" }) }).then(function (response) { return response.json(); }).then(function (json) { console.log(json); }).catch(function (err) { console.log({ 'status': 'failed', 'error': err }); })