Network wrapper protocol as part of the practical master thesis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

225 lines
7.2 KiB

#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 <issuer's IPv4>\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 <msg>0<signature w/o bsn>" or
//"ATTEST <msg>1<signature with bsn>"
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 = &current[ret];
bzero(chksum, MAX_CHKSUMSIZE);
ret = ecdaa_decode(current, chksum, MAX_CHKSUMSIZE);
chksum_len = strlen(chksum);
current = &current[ret];
has_nym = current[0] - '0';
current = &current[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
ecdaa_decode(current, bsn, MAX_BSNSIZE);
bsn_len = strlen(bsn);
} 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;
}