#include "verifier.h" typedef enum verifierstate { ON, ASKISSUER, GOTISSUER, } verifierstate_e; typedef struct verifier { struct ecdaa_issuer_public_key_FP256BN ipk; // struct ecdaa_member_public_key_FP256BN mpk; struct ecdaa_revocations_FP256BN revocations; verifierstate_e state; } verifier_t; verifier_t verifier; uint8_t msg[MAX_MSGSIZE]; size_t msg_len; uint8_t chksum[MAX_CHKSUMSIZE]; size_t chksum_len; int verifier_getissuer(char *buffer); int verifier_attestmember(char *buffer); int verifier_checklink(char *buffer); int verifier_verifymsg(char *buffer); int main(int argc, char **argv) { verifier.revocations.sk_list = NULL; verifier.revocations.bsn_list = NULL; char *remote_ip; int ret = 0; switch(argc) { case 1: if (0 != ecdaa_issuer_public_key_FP256BN_deserialize_file(&verifier.ipk, VERIFIER_GROUP_PK_FILE)) { printf("Could not import key file. Importing from %s was not successful.\n",VERIFIER_GROUP_PK_FILE); return 1; } printf("verifier_setup: loaded keys from disk.\n"); verifier.state = GOTISSUER; break; case 3: if( 0 == strncasecmp("--public", argv[1], 6) || 0 == strncasecmp("-p", argv[1], 2)) { verifier.state = ON; remote_ip = argv[2]; ret = client_connect(&verifier_getissuer, remote_ip, ISSUERPORT); if (0 >= ret || GOTISSUER != verifier.state) { printf("Error: connection to issuer failed.\n"); } if(0 != ecdaa_issuer_public_key_FP256BN_serialize_file(VERIFIER_GROUP_PK_FILE, &verifier.ipk)) { printf("Error saving key-pair to disk.\n"); return -1; } printf("verifier_setup: wrote new issuer's public key to %s.\n", VERIFIER_GROUP_PK_FILE); } else { printf("Error: Arguments invalid.\n"); } break; default: printf("Usage: \n Get issuer's public key: %s --public \n", argv[0]); printf("If the public key is already saved, no arguments are needed.\n"); break; } if (GOTISSUER == verifier.state && 2 != server_start(&process_verifier, VERIFIERPORT)) { printf("Error: Server failed.\n"); } return 0; } int process_verifier(char *buffer) { int ret = 0; char remote_ip[16]; printf("> VERIFIER: %s\n", buffer); if (0 == strncasecmp("VERIFYMSG", buffer, 9)) { ret = verifier_verifymsg(&buffer[10]); bzero(buffer, MAX_BUFSIZE); if (-1 == ret) { printf("process_verifier: Member public key is malformed!\n"); } else if (-2 == ret) { printf("process_verifier: Signature of member public key is invalid.\n"); } else { printf("process_verifier: Received message with valid DAA signature.\n"); } printf("closing client session.\n"); ret = 1; } else if (0 == strncasecmp("EXIT", buffer, 4)) { printf("closing client session.\n"); bzero(buffer, MAX_BUFSIZE); ret = 1; } else if (0 == strncasecmp("SHUTDOWN", buffer, 8)) { bzero(buffer, MAX_BUFSIZE); ret = 2; } else { printf("unknown command.\n"); bzero(buffer, MAX_BUFSIZE); strncpy(buffer, "ERR\n", 4); ret = 0; } if (0 == ret) { printf("< VERIFIER: %s\n", buffer); } return ret; } int verifier_getissuer(char *buffer) { int ret = 0; switch (verifier.state) { case ON: bzero(buffer, MAX_BUFSIZE); strncpy(buffer, "PUBLISH\n", 8); verifier.state = ASKISSUER; break; case ASKISSUER: if (0 == strncasecmp("PUBLISH", buffer, 7)) { #ifdef DEBUG printf("ISSUER > VERIFIER: %s", buffer); #endif uint8_t binbuf[MAX_BUFSIZE]; char *current = &buffer[8]; ecdaa_decode(current, binbuf, ECDAA_ISSUER_PUBLIC_KEY_FP256BN_LENGTH); ret = ecdaa_issuer_public_key_FP256BN_deserialize(&verifier.ipk, binbuf); if (-1 == ret) { printf("verifier_getpublic: issuer public key is malformed!\n"); ret = -1; } else if (-2 == ret) { printf("verifier_getpublic: signature of issuer public key is invalid.\n"); ret = -1; } else { verifier.state = GOTISSUER; ret = 1; } } else { printf("verifier_getpublic: did not get public key from issuer.\n"); verifier.state = ON; ret = -1; } break; default: ret = -1; } if (0 == ret) { #ifdef DEBUG printf("ISSUER < VERIFIER: %s", buffer); #endif } return ret; } //"ATTEST 0" or //"ATTEST 1" int verifier_verifymsg(char *buffer) { char *current = buffer; int has_nym = 0; char bsn[MAX_BSNSIZE]; size_t bsn_len = 0; uint8_t binbuf[MAX_BUFSIZE]; size_t sig_len = 0; struct ecdaa_signature_FP256BN sig; int ret = 0; bzero(msg, MAX_MSGSIZE); ret = ecdaa_decode(current, msg, MAX_MSGSIZE); msg_len = strlen(msg); current = ¤t[ret]; bzero(chksum, MAX_CHKSUMSIZE); ret = ecdaa_decode(current, chksum, MAX_CHKSUMSIZE); chksum_len = strlen(chksum); current = ¤t[ret]; has_nym = current[0] - '0'; current = ¤t[1]; bzero(bsn, MAX_BSNSIZE); if (has_nym) { sig_len = ecdaa_signature_FP256BN_with_nym_length(); #ifdef DEBUG printf("verifier_verifymsg: nym detected, signature length = %ld.\n",sig_len); #endif } else { sig_len = ecdaa_signature_FP256BN_length(); } bzero(binbuf, MAX_BUFSIZE); ecdaa_decode(current, binbuf, sig_len); #ifdef DEBUG printf("verifier_verifymsg: Signature decoded.\n"); #endif ret = ecdaa_signature_FP256BN_deserialize(&sig, binbuf, has_nym); if (0 != ret) { printf("verifier_verifymsg: error reading signature.\n"); return -1; } #ifdef DEBUG printf("verifier_verifymsg: Signature deserialized.\n"); #endif #ifdef DEBUG printf("verifier_verifymsg: has_nym: %u, sig_len: %lu\n", has_nym, sig_len); printf("verifier_verifymsg: msg: %s, len: %lu\n", msg, msg_len); printf("verifier_verifymsg: chksum: %s, len: %lu\n", chksum, chksum_len); printf("verifier_verifymsg: bsn: %s, len: %lu\n", bsn, bsn_len); printf("verifier_verifymsg: sig: %s, len: %lu\n", current, sig_len); #endif ret = ecdaa_signature_FP256BN_verify(&sig, &verifier.ipk.gpk, &verifier.revocations, (uint8_t *) chksum, chksum_len, (uint8_t *) bsn, bsn_len); if (0 != ret) { printf("verifier_verifymsg: signature not valid, ret = %i\n", ret); return -1; } printf("writing message to %s\n", MESSAGE_FILE); ecdaa_write_buffer_to_file(MESSAGE_FILE, msg, msg_len); printf("writing checksum to %s\n", CHECKSUM_FILE); ecdaa_write_buffer_to_file(CHECKSUM_FILE, chksum, chksum_len); return 0; }