Subject: | Doesn't handle public keys with null chars in them |
A public key can have a null char in it. In that case, u2fclib_verifyRegistration will fail to return them properly.
There's two bugs here. In u2fclib_verifyRegistration, you write out the delimiter and the handle after the first null, which may be part-way through the key. A fix to that is attached.
(I note that I am very uneasy about the use of a fixed-length buffer and strcat in security-sensitive code, especially when the length of the key handle is unknown. ~20K bytes is probably enough, but still).
The thing I don't know how to do right now is change the XS to return a SV with a set length. I expect u2fclib_verifyRegistration will need to be changed to take output parameters, and then something extra done in the return to get this back to Perl sanely. I'll investigate further tomorrow, but hopefully you'll know how to do this easily.
For testing, here's a sample challenge and response that result in a public key value with a null:
{ "challenge": "gbB-YfEXqCOHqXDFsNEn4n7JWhZ6ZI_bzY7X3x1ToG0", "version": "U2F_V2", "appId": "test" }
{ "registrationData": "BQQLxnimZma_IY-6RNeytXH1E0KyMPI1obSJ4LdYbnPjin6oeCPKlF_VvKtB71gANN4JIGYnnxF4YpBXuWi88GeKQGx8W8CVVj2ETebp7OmXc7ZQl1HwVh72xVLwb4V67mj2626ES__A82sOKtVgxFx1EwJ1lLdeMVtvDnx2HptgL9wwggIaMIIBBKADAgECAgQuQunNMAsGCSqGSIb3DQEBCzAuMSwwKgYDVQQDEyNZdWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwMDYzMTAgFw0xNDA4MDEwMDAwMDBaGA8yMDUwMDkwNDAwMDAwMFowKTEnMCUGA1UEAwweWXViaWNvIFUyRiBFRSBTZXJpYWwgNzc2MTM3MTY1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESbo91Jw7oVvVuHWN79tJLiqMPj9wAsRNXdSDP5_AzkCdkTdK8FF68gBqujnC-3MbNnGgzlzp2sGEtWGVuXDNTKMSMBAwDgYKKwYBBAGCxAoBAwQAMAsGCSqGSIb3DQEBCwOCAQEDdg42lWXviOkEKATYj_pfvVuZk6MSRo-xdJYSlqU5zGWwYv0AfZmKqqlMymsD-atC0hC2VSV-2LfV-0cUbMQVkXST1f0RqwIglE6eu6ai_DhKcEbYJb3WECKgnAu4BSPnn1lkOdsL-U9VivlM4VHbel1I7qN_KJS_ZhcdDhQC9U5EZhRdShpwAd1lCpIMt-RtlvFFIh5xwlcO_8G7ekx0rm9fCbZcOoQDUpTi6UjlYyFQpRzrfAF1C1kuHxEg-2tpXdJqnmVXtxP1SN-u21LfFf2JUmkkfTu0rBCi2Qi2BiBcShTUGyni33XEcm0bdJ45d1P5csCf4N3tmUWm1Fj-2DBEAiAVNs2fBsPLeYN8iApIxJ_oRKjt0hZzQ9owxRmIwjx48gIgCbgXitkcSCmyZrB2cH3SDfPjUf3ZwomlD3-tSPZpk6w", "clientData": "eyAiY2hhbGxlbmdlIjogImdiQi1ZZkVYcUNPSHFYREZzTkVuNG43SldoWjZaSV9ielk3WDN4MVRvRzAiLCAib3JpZ2luIjogInRlc3QiLCAidHlwIjogIm5hdmlnYXRvci5pZC5maW5pc2hFbnJvbGxtZW50IiB9" }
Rob N.
Subject: | 0001-handle-key-nulls.diff |
diff --git a/u2f.c b/u2f.c
index 045df96..a342c17 100644
--- a/u2f.c
+++ b/u2f.c
@@ -52,6 +52,8 @@
//#include <stdbool.h>
#include <string.h>
+#define DELIMITER "##DELIMITER##"
+
char *p;
char errorstring[10000];
char regdata[20000];
@@ -180,12 +182,13 @@ char* u2fclib_verifyRegistration(void* ctx, char* buf) {
sprintf(errorstring, "error (%d): %s", rc, u2fs_strerror(rc));
return 0;
}
+ char *out = regdata;
+
const char *k = u2fs_get_registration_publicKey(reg_result);
- memcpy(regdata, k, U2FS_PUBLIC_KEY_LEN);
- regdata[U2FS_PUBLIC_KEY_LEN] = 0;
+ memcpy(out, k, U2FS_PUBLIC_KEY_LEN); out += U2FS_PUBLIC_KEY_LEN;
- strcat(regdata, "##DELIMITER##");
- strcat(regdata, u2fs_get_registration_keyHandle(reg_result));
+ strcat(out, DELIMITER); out += strlen(DELIMITER);
+ strcat(out, u2fs_get_registration_keyHandle(reg_result));
//sprintf(regdata.keyHandle, "%s", u2fs_get_registration_keyHandle(reg_result));