diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ac977d..33cda34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,15 @@ target_include_directories(ecdaa_member PUBLIC target_link_libraries(ecdaa_member /usr/local/lib/libecdaa.so) target_link_libraries(ecdaa_member /usr/local/lib/libecdaa-tpm.so) +add_executable(ecdaa_member_tpm member-tpm.c common.h common.c client.h client.c server.h server.c) +target_include_directories(ecdaa_member_tpm PUBLIC + ${ECDAA_AMCL} + ) +target_link_libraries(ecdaa_member_tpm /usr/local/lib/libecdaa.so) +target_link_libraries(ecdaa_member_tpm /usr/local/lib/libecdaa-tpm.so) +target_link_libraries(ecdaa_member_tpm /usr/local/lib/libxaptum-tpm.so) +target_link_libraries(ecdaa_member_tpm /usr/lib/x86_64-linux-gnu/libtss2-esys.so) + add_executable(ecdaa_verifier verifier.c common.h common.c server.h server.c client.h client.c) target_include_directories(ecdaa_verifier PUBLIC ${ECDAA_AMCL} diff --git a/common.h b/common.h index 073d270..77dca49 100644 --- a/common.h +++ b/common.h @@ -18,7 +18,9 @@ #define VERIFIERPORT 6592 #define MAX_CLIENTS 10 -#define MAX_BUFSIZE 1024 +#define MAX_BUFSIZE 2048 +#define MAX_MSGSIZE (MAX_BUFSIZE / 8) +#define MAX_BSNSIZE (MAX_BUFSIZE / 16) #define NONCE_SIZE 384 typedef int (*conn_handler)(char *buffer); diff --git a/member-tpm.c b/member-tpm.c new file mode 100644 index 0000000..329a8bc --- /dev/null +++ b/member-tpm.c @@ -0,0 +1,318 @@ +#include "member-tpm.h" + +typedef enum memberstate { + ON, + ISSUERPUB, + RCVPUBLIC, + JOIN, + APPEND, + JOINPROCEED, + JOINED, +} memberstate_e; + +typedef struct member { + struct ecdaa_member_public_key_FP256BN mpk; + memberstate_e state; + uint8_t nonce[NONCE_SIZE]; + struct ecdaa_credential_FP256BN cred; + struct ecdaa_issuer_public_key_FP256BN ipk; + uint8_t bsn[MAX_BSNSIZE]; + size_t bsn_len; + struct ecdaa_tpm_context ctx; +} member_t; + +member_t member; + +int init_tpm(); +int free_tpm(); +int member_join(char *buffer); +int member_attest(char *buffer); +int member_publish(char *buffer); +int member_getpublic(char *buffer); +int member_joinappend(char *buffer); +int member_joinfinish(char *buffer); + +int main() { + + init_tpm(); + if (2 != server_start(&process_member, MEMBERPORT)) { + printf("server failed\n"); + } + free_tpm(); + return 0; +} + +int init_tpm() { + TSS2_TCTI_CONTEXT *tctiContext = NULL; + TPM_HANDLE handle = 0; + const char* passwd = "1234"; + uint16_t passwdlen = strlen(passwd); + TSS2_RC retval = 0; + size_t bufsize = tss2_tcti_getsize_device(); + uint8_t tctiBuffer[bufsize]; + bzero(tctiBuffer, bufsize); + const char* devicePath = "/dev/tpm0"; + + tctiContext = tctiBuffer; + retval = tss2_tcti_init_device(devicePath, strlen(devicePath), tctiContext); + switch (retval & 0xFF) { + case TSS2_RC_SUCCESS: + printf("tcti context established\n"); + break; + default: + printf("tcti context failed\n"); + break; + } + //initialize ecdaa tpm context + if(0 != ecdaa_tpm_context_init(&member.ctx, handle, NULL, 0, tctiContext)) { + printf("\necdaa context failed\n"); + return -1; + } + printf("\necdaa context initialized\n"); + return 0; +} + +int free_tpm() { + ecdaa_tpm_context_free(&member.ctx); + return 0; +} + +int process_member(char *buffer) { + int ret = 0; + + bzero(member.bsn, MAX_BSNSIZE); + strncpy((char *) member.bsn, "Biometric Sensor", 16); + member.bsn_len = 16; + + printf("> MEMBER: %s\n", buffer); + + if (member.state == JOINED && 0 == strncasecmp("ATTEST", buffer, 6)) { + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "ATTEST ", 7); + member_attest(buffer); + } else if (member.state == ON && 0 == strncasecmp("GETPUBLIC", buffer, 9)) { + bzero(buffer, MAX_BUFSIZE); + ret = client_connect(&member_getpublic, ISSUERIP, ISSUERPORT); + if (0 >= ret || RCVPUBLIC != member.state) { + printf("process_member: issuer connection failed\n"); + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "ERR\n", 4); + } else { + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "OK\n", 3); + } + ret = 0; + } else if (0 == strncasecmp("PUBLISH", buffer, 7)) { + bzero(buffer, MAX_BUFSIZE); + member_publish(buffer); + } else if (member.state == RCVPUBLIC && 0 == strncasecmp("JOIN", buffer, 4)) { + member.state = JOIN; + ret = client_connect(&member_join, ISSUERIP, ISSUERPORT); + if (0 >= ret || JOINED != member.state) { + printf("process_member: issuer connection failed\n"); + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "ERR\n", 4); + } else { + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "OK\n", 3); + } + ret = 0; + } else if (0 == strncasecmp("EXIT", buffer, 4)) { + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "OK\n", 3); + ret = 1; + } else if (0 == strncasecmp("SHUTDOWN", buffer, 8)) { + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "OK\n", 3); + ret = 2; + } else { + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "ERR\n", 4); + ret = 0; + } + + printf("< MEMBER: %s\n", buffer); + return ret; +} + +int member_join(char *buffer) { + int ret = 0; + + switch (member.state) { + case JOIN: + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "JOIN\n", 5); + member.state = APPEND; + break; + case APPEND: + if (0 == strncasecmp("JOINSTART", buffer, 9)) { + printf("ISSUER > MEMBER: %s", buffer); + member_joinappend(buffer); + member.state = JOINPROCEED; + } else { + printf("member_join: did not get nonce from issuer\n"); + member.state = RCVPUBLIC; + ret = -1; + } + break; + case JOINPROCEED: + if (0 == strncasecmp("JOINPROCEED", buffer, 11)) { + printf("ISSUER > MEMBER: %s", buffer); + member_joinfinish(buffer); + member.state = JOINED; + ret = 1; + } else { + printf("member_getpublic: did not get credentials from issuer\n"); + member.state = RCVPUBLIC; + ret = -1; + } + break; + default: + ret = -1; + } + if (0 == ret) { + printf("ISSUER < MEMBER: %s", buffer); + } + return ret; +} + +int member_getpublic(char *buffer) { + int ret = 0; + + switch (member.state) { + case ON: + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "PUBLISH\n", 8); + member.state = ISSUERPUB; + break; + case ISSUERPUB: + if (0 == strncasecmp("PUBLISH", buffer, 7)) { + printf("ISSUER > MEMBER: %s", buffer); + uint8_t binbuf[MAX_BUFSIZE]; + char *current = &buffer[8]; + ecdaa_hextobin(current, binbuf, ECDAA_ISSUER_PUBLIC_KEY_FP256BN_LENGTH); + ret = ecdaa_issuer_public_key_FP256BN_deserialize(&member.ipk, binbuf); + if (-1 == ret) { + printf("member_getpublic: issuer public key is malformed!\n"); + ret = -1; + } else if (-2 == ret) { + printf("member_getpublic: signature of issuer public key is invalid\n"); + ret = -1; + } else { + member.state = RCVPUBLIC; + ret = 1; + } + } else { + printf("member_getpublic: did not get public key from issuer\n"); + member.state = ON; + ret = -1; + } + break; + default: + printf("member_getpublic: did not get public key from issuer\n"); + member.state = ON; + ret = -1; + break; + } + if (0 == ret) { + printf("ISSUER < MEMBER: %s", buffer); + } + return ret; +} + +//"ATTEST" > "ATTEST " +int member_attest(char *buffer) { + char *current = buffer; + uint8_t binbuf[MAX_BUFSIZE]; + uint8_t msg[MAX_MSGSIZE] = "I am the real host"; + size_t msg_len = strlen((char*)msg); + uint8_t has_nym = member.bsn_len != 0 ? 1 : 0; + struct ecdaa_signature_FP256BN sig; + size_t sig_len = has_nym ? ECDAA_SIGNATURE_FP256BN_WITH_NYM_LENGTH : ECDAA_SIGNATURE_FP256BN_LENGTH; + + ecdaa_signature_TPM_FP256BN_sign(&sig, msg, msg_len, member.bsn, member.bsn_len, &member.cred, ecdaa_rand, &member.ctx); + bzero(buffer, MAX_BUFSIZE); + bzero(binbuf, MAX_BUFSIZE); + strncpy(current, "ATTEST ", 7); + current = ¤t[7]; + + strncpy(current, (char*) msg, MAX_MSGSIZE); + current[MAX_MSGSIZE] = has_nym == 1 ? '1' : '0'; + current = ¤t[MAX_MSGSIZE + 1]; + if(has_nym) { + strncpy(current, (char *)member.bsn, MAX_BSNSIZE); + current = ¤t[MAX_BSNSIZE]; + } + + ecdaa_signature_FP256BN_serialize(binbuf, &sig, has_nym); + ecdaa_bintohex(binbuf, sig_len, current); + current[2 * sig_len] = '\n'; + return 0; +} + +//"PUBLISH" > "PUBLISH " +int member_publish(char *buffer) { + char *current; + uint8_t binbuf[MAX_BUFSIZE]; + bzero(buffer, MAX_BUFSIZE); + + strncpy(buffer, "PUBLISH ", 8); + + current = &buffer[8]; + bzero(binbuf, MAX_BUFSIZE); + ecdaa_member_public_key_FP256BN_serialize(binbuf, &member.mpk); + ecdaa_bintohex(binbuf, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH, current); + + current[2 * ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH] = '\n'; + + return 0; +} + +//"JOINSTART " > "APPEND " +int member_joinappend(char *buffer) { + char *current = &buffer[10]; + uint8_t binbuf[MAX_BUFSIZE]; + ecdaa_hextobin(current, member.nonce, NONCE_SIZE); + + uint8_t serial_gpk[ECDAA_GROUP_PUBLIC_KEY_FP256BN_LENGTH]; + bzero(serial_gpk, ECDAA_GROUP_PUBLIC_KEY_FP256BN_LENGTH); + ecdaa_issuer_public_key_FP256BN_serialize(serial_gpk, &member.ipk); + + if (0 != ecdaa_member_key_pair_TPM_FP256BN_generate(&member.mpk, serial_gpk, member.nonce, NONCE_SIZE, &member.ctx)) { + fprintf(stderr, "Error generating member key-pair\n"); + return -1; + } + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "APPEND ", 7); + + current = &buffer[7]; + bzero(binbuf, MAX_BUFSIZE); + ecdaa_member_public_key_FP256BN_serialize(binbuf, &member.mpk); + ecdaa_bintohex(binbuf, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH, current); + current[2 * ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH] = '\n'; + return 0; +} + +//"JOINPROCEED " > "" +int member_joinfinish(char *buffer) { + char *current = &buffer[12]; + uint8_t *bincur; + uint8_t binbuf[MAX_BUFSIZE]; + int ret = 0; + bzero(binbuf, MAX_BUFSIZE); + ecdaa_hextobin(current, binbuf, ECDAA_CREDENTIAL_FP256BN_LENGTH); + + current = &buffer[12 + 2 * ECDAA_CREDENTIAL_FP256BN_LENGTH + 1]; + bincur = &binbuf[ECDAA_CREDENTIAL_FP256BN_LENGTH]; + ecdaa_hextobin(current, bincur, ECDAA_CREDENTIAL_FP256BN_SIGNATURE_LENGTH); + ret = ecdaa_credential_FP256BN_deserialize_with_signature(&member.cred, &member.mpk, &member.ipk.gpk, binbuf, bincur); + if(-1 == ret) { + printf("member_joinfinish: credential is malformed!\n"); + ret = -1; + } else if(-2 == ret) { + printf("member_joinfinish: siganture of credential is invalid"); + ret = -1; + } + + return ret; +} \ No newline at end of file diff --git a/member-tpm.h b/member-tpm.h new file mode 100644 index 0000000..ffea763 --- /dev/null +++ b/member-tpm.h @@ -0,0 +1,19 @@ +// +// Created by root on 11/5/19. +// + +#ifndef ECDAA_ISSUER_MEMBER_H +#define ECDAA_ISSUER_MEMBER_H +#include +#include +#include +#include +#include +#include +#include "server.h" +#include "client.h" +#include "common.h" + +int process_member(char *buffer); + +#endif //ECDAA_ISSUER_ISSUER_H diff --git a/member.c b/member.c index 75a971e..55f10a2 100644 --- a/member.c +++ b/member.c @@ -8,8 +8,6 @@ typedef enum memberstate { APPEND, JOINPROCEED, JOINED, - ATTEST, - PUBLISH } memberstate_e; typedef struct member { @@ -18,8 +16,9 @@ typedef struct member { memberstate_e state; uint8_t nonce[NONCE_SIZE]; struct ecdaa_credential_FP256BN cred; - struct ecdaa_credential_FP256BN_signature cred_sig; struct ecdaa_issuer_public_key_FP256BN ipk; + uint8_t bsn[MAX_BSNSIZE]; + size_t bsn_len; } member_t; member_t member; @@ -47,6 +46,10 @@ int main() { int process_member(char *buffer) { int ret = 0; + bzero(member.bsn, MAX_BSNSIZE); + strncpy((char *) member.bsn, "Biometric Sensor", 16); + member.bsn_len = 16; + printf("> MEMBER: %s\n", buffer); if (member.state == JOINED && 0 == strncasecmp("ATTEST", buffer, 6)) { @@ -112,6 +115,10 @@ int member_join(char *buffer) { printf("ISSUER > MEMBER: %s", buffer); member_joinappend(buffer); member.state = JOINPROCEED; + } else { + printf("member_join: did not get nonce from issuer\n"); + member.state = RCVPUBLIC; + ret = -1; } break; case JOINPROCEED: @@ -120,10 +127,14 @@ int member_join(char *buffer) { member_joinfinish(buffer); member.state = JOINED; ret = 1; + } else { + printf("member_getpublic: did not get credentials from issuer\n"); + member.state = RCVPUBLIC; + ret = -1; } break; default: - ret - 1; + ret = -1; } if (0 == ret) { printf("ISSUER < MEMBER: %s", buffer); @@ -157,9 +168,15 @@ int member_getpublic(char *buffer) { member.state = RCVPUBLIC; ret = 1; } + } else { + printf("member_getpublic: did not get public key from issuer\n"); + member.state = ON; + ret = -1; } break; default: + printf("member_getpublic: did not get public key from issuer\n"); + member.state = ON; ret = -1; break; } @@ -171,7 +188,32 @@ int member_getpublic(char *buffer) { //"ATTEST" > "ATTEST " int member_attest(char *buffer) { - strncat(buffer, "\n", 13); + char *current = buffer; + uint8_t binbuf[MAX_BUFSIZE]; + uint8_t msg[MAX_MSGSIZE] = "I am the real host"; + size_t msg_len = strlen((char*)msg); + uint8_t has_nym = member.bsn_len != 0 ? 1 : 0; + struct ecdaa_signature_FP256BN sig; + size_t sig_len = has_nym ? ECDAA_SIGNATURE_FP256BN_WITH_NYM_LENGTH : ECDAA_SIGNATURE_FP256BN_LENGTH; + + ecdaa_signature_FP256BN_sign(&sig, msg, msg_len, member.bsn, member.bsn_len, &member.msk, &member.cred, ecdaa_rand); + + bzero(buffer, MAX_BUFSIZE); + bzero(binbuf, MAX_BUFSIZE); + strncpy(current, "ATTEST ", 7); + current = ¤t[7]; + + strncpy(current, (char*) msg, MAX_MSGSIZE); + current[MAX_MSGSIZE] = has_nym == 1 ? '1' : '0'; + current = ¤t[MAX_MSGSIZE + 1]; + if(has_nym) { + strncpy(current, (char *)member.bsn, MAX_BSNSIZE); + current = ¤t[MAX_BSNSIZE]; + } + + ecdaa_signature_FP256BN_serialize(binbuf, &sig, has_nym); + ecdaa_bintohex(binbuf, sig_len, current); + current[2 * sig_len] = '\n'; return 0; } @@ -188,7 +230,7 @@ int member_publish(char *buffer) { ecdaa_member_public_key_FP256BN_serialize(binbuf, &member.mpk); ecdaa_bintohex(binbuf, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH, current); - buffer[2 * ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH + 8] = '\n'; + current[2 * ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH] = '\n'; return 0; } @@ -199,6 +241,7 @@ int member_joinappend(char *buffer) { uint8_t binbuf[MAX_BUFSIZE]; ecdaa_hextobin(current, member.nonce, NONCE_SIZE); +// if (0 != ecdaa_member_key_pair_TPM_FP256BN_generate(&member.mpk, member.nonce, NONCE_SIZE)) { if (0 != ecdaa_member_key_pair_FP256BN_generate(&member.mpk, &member.msk, member.nonce, NONCE_SIZE, ecdaa_rand)) { fprintf(stderr, "Error generating member key-pair\n"); return -1; @@ -210,6 +253,7 @@ int member_joinappend(char *buffer) { bzero(binbuf, MAX_BUFSIZE); ecdaa_member_public_key_FP256BN_serialize(binbuf, &member.mpk); ecdaa_bintohex(binbuf, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH, current); + current[2 * ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH] = '\n'; return 0; } diff --git a/member.h b/member.h index 10ff17e..5b78c8f 100644 --- a/member.h +++ b/member.h @@ -5,7 +5,6 @@ #ifndef ECDAA_ISSUER_MEMBER_H #define ECDAA_ISSUER_MEMBER_H #include -#include #include #include "server.h" #include "client.h" diff --git a/verifier.c b/verifier.c index f26d8e5..6693ad9 100644 --- a/verifier.c +++ b/verifier.c @@ -4,14 +4,12 @@ typedef enum verifierstate { ON, ASKISSUER, GOTISSUER, - ASKMEMBER, - GOTMEMBER, ASKATTEST, } verifierstate_e; typedef struct verifier { struct ecdaa_issuer_public_key_FP256BN ipk; - struct ecdaa_member_public_key_FP256BN mpk; +// struct ecdaa_member_public_key_FP256BN mpk; struct ecdaa_revocations_FP256BN revocations; verifierstate_e state; } verifier_t; @@ -20,10 +18,13 @@ verifier_t verifier; int verifier_getissuer(char *buffer); -int verifier_getmember(char *buffer); +//int verifier_getmember(char *buffer); int verifier_attestmember(char *buffer); + int verifier_checklink(char *buffer); +int verifier_checkattest(char *buffer); + int main() { verifier.revocations.sk_list = NULL; verifier.revocations.bsn_list = NULL; @@ -41,7 +42,7 @@ int process_verifier(char *buffer) { if (0 == strncasecmp("VERIFY", buffer, 6)) { switch (verifier.state) { - case GOTMEMBER: + case GOTISSUER: bzero(buffer, MAX_BUFSIZE); strncpy(buffer, "OK\n", 3); break; @@ -49,11 +50,21 @@ int process_verifier(char *buffer) { bzero(buffer, MAX_BUFSIZE); strncpy(buffer, "ERR\n", 4); } - } else if (0 == strncasecmp("LINk", buffer, 4)) { + } else if (0 == strncasecmp("ATTEST", buffer, 4)) { + ret = client_connect(&verifier_attestmember, MEMBERIP, MEMBERPORT); + if (0 >= ret) { + printf("process_verifier: member verification failed\n"); + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "ERR\n", 4); + } else { + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "OK\n", 3); + } + ret = 0; + } else if (0 == strncasecmp("LINK", buffer, 4)) { bzero(buffer, MAX_BUFSIZE); verifier_checklink(buffer); - } else if (0 == strncasecmp("GETPUBLISHED", buffer, 12)) { - printf("link()\n"); + } else if (0 == strncasecmp("GETPUBLIC", buffer, 9)) { verifier.state = ON; ret = client_connect(&verifier_getissuer, ISSUERIP, ISSUERPORT); if (0 >= ret || GOTISSUER != verifier.state) { @@ -61,17 +72,10 @@ int process_verifier(char *buffer) { bzero(buffer, MAX_BUFSIZE); strncpy(buffer, "ERR\n", 4); } else { - ret = client_connect(&verifier_getmember, MEMBERIP, MEMBERPORT); - if (0 >= ret || GOTMEMBER != verifier.state) { - printf("process_verifier: issuer connection failed\n"); - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "ERR\n", 4); - } else { - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "OK\n", 3); - } - ret = 0; + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "OK\n", 3); } + ret = 0; } else if (0 == strncasecmp("EXIT", buffer, 4)) { printf("exit()\n"); bzero(buffer, MAX_BUFSIZE); @@ -118,6 +122,10 @@ int verifier_getissuer(char *buffer) { verifier.state = GOTISSUER; ret = 1; } + } else { + printf("verifier_getpublic: did not get public key from issuer\n"); + verifier.state = ON; + ret = -1; } break; default: @@ -129,60 +137,21 @@ int verifier_getissuer(char *buffer) { return ret; } -int verifier_getmember(char *buffer) { - int ret = 0; - - switch (verifier.state) { - case GOTISSUER: - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "PUBLISH\n", 8); - verifier.state = ASKMEMBER; - break; - case ASKMEMBER: - if (0 == strncasecmp("PUBLISH", buffer, 7)) { - printf("MEMBER > VERIFIER: %s", buffer); - uint8_t binbuf[MAX_BUFSIZE]; - char *current = &buffer[8]; - ecdaa_hextobin(current, binbuf, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH); - ret = ecdaa_member_public_key_FP256BN_deserialize_no_check(&verifier.mpk, binbuf); - if (-1 == ret) { - printf("verifier_getmember: member public key is malformed!\n"); - ret = -1; - } else if (-2 == ret) { - printf("verifier_getmember: signature of member public key is invalid\n"); - ret = -1; - } else { - verifier.state = GOTMEMBER; - ret = 1; - } - } - break; - default: - ret = -1; - } - if (0 == ret) { - printf("MEMBER < VERIFIER: %s", buffer); - } - return ret; -} //"ATTEST" > "OK" int verifier_attestmember(char *buffer) { int ret = 0; switch (verifier.state) { - case GOTMEMBER: + case GOTISSUER: bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "ATTEST\n", 8); + strncpy(buffer, "ATTEST\n", 7); verifier.state = ASKATTEST; break; case ASKATTEST: - if (0 == strncasecmp("ATTEST", buffer, 7)) { + if (0 == strncasecmp("ATTEST", buffer, 6)) { printf("MEMBER > VERIFIER: %s", buffer); - uint8_t binbuf[MAX_BUFSIZE]; - char *current = &buffer[8]; - ecdaa_hextobin(current, binbuf, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH); - ret = ecdaa_member_public_key_FP256BN_deserialize_no_check(&verifier.mpk, binbuf); + ret = verifier_checkattest(buffer); if (-1 == ret) { printf("verifier_attestmember: member public key is malformed!\n"); ret = -1; @@ -190,9 +159,12 @@ int verifier_attestmember(char *buffer) { printf("verifier_attestmember: signature of member public key is invalid\n"); ret = -1; } else { - verifier.state = GOTMEMBER; + verifier.state = GOTISSUER; ret = 1; } + } else { + printf("verifier_attestmember: did not get correct message from member\n"); + ret = -1; } break; default: @@ -204,8 +176,53 @@ int verifier_attestmember(char *buffer) { return ret; } +//"ATTEST 0" or +//"ATTEST 1" +int verifier_checkattest(char *buffer) { + char *current = &buffer[7]; //"ATTEST " + + char msg[MAX_MSGSIZE]; + strncpy(msg, buffer, MAX_MSGSIZE); + size_t msg_len = strlen(msg); + current = ¤t[MAX_MSGSIZE]; + + int has_nym = current[0] - '0'; + current = ¤t[1]; + + char bsn[MAX_BSNSIZE]; + bzero(bsn, MAX_BSNSIZE); + size_t bsn_len = 0; + + uint8_t binbuf[MAX_BUFSIZE]; + bzero(binbuf, MAX_BUFSIZE); + + if (has_nym) { + strncpy(bsn, current, MAX_BSNSIZE); + bsn_len = strlen(bsn); + current = ¤t[MAX_BSNSIZE]; + } + int sig_len = has_nym ? ECDAA_SIGNATURE_FP256BN_WITH_NYM_LENGTH : ECDAA_SIGNATURE_FP256BN_LENGTH; + ecdaa_hextobin(current, binbuf, sig_len); + + struct ecdaa_signature_FP256BN sig; + int ret = ecdaa_signature_FP256BN_deserialize(&sig, binbuf, has_nym); + if (0 != ret) { + printf("verifier_checkattest: error reading signature"); + return -1; + } + + ret = ecdaa_signature_FP256BN_verify(&sig, &verifier.ipk.gpk, &verifier.revocations, (uint8_t *) msg, msg_len, + (uint8_t *) bsn, bsn_len); + if (0 == ret) { + printf("verifier_checkattest: signature not valid"); + return -1; + } + + return 0; +} + //"LINK" > "NOT IMPLEMENTED" int verifier_checklink(char *buffer) { - strncat(buffer, "NOT_IMPLEMENTED\n", 16); + strncat(buffer, "NOT_IMPLEMENTED\n", 17); return 0; }