diff --git a/LICENSE b/LICENSE index df2bf8f..2815c82 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2022 Contributors to the Veraison project. + Copyright 2023 Contributors to the Veraison project. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 27ff962..1683cd8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,9 @@ # c-apiclient Veraison API client implementation in C + +This example makes use of curl library to make REST API invocations to the Veraison server. +It implements only Synchronous verification part of the challenge response sequence. + +Building the Client: gcc -g -o client client.c -lcurl + +Running the Client example : client -l 127.0.0.1 -t psa-evidence.cbor diff --git a/client.c b/client.c new file mode 100644 index 0000000..48edc11 --- /dev/null +++ b/client.c @@ -0,0 +1,113 @@ +// Copyright 2023 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include + +#include "curl/curl.h" +#include "curl/header.h" + +void usage_print(void) { + printf("Usage: client -l
-t \n"); + printf(" default address for -l option is 127.0.0.1\n"); +} + +int main(int argc, char *argv[]) { + CURL *curl_handle; + CURLcode res; + struct curl_header *type; + char uri[100] = {0}; + char token[1024]={0}; + int opt; + char *address="127.0.0.1"; /*default address is localhost*/ + char port[] = "8080"; + char *filename; + + if(argc == 1){ + printf("\n mention the token path using client -t \n"); + return -1; + } + + /* Parse the command line options*/ + while((opt=getopt(argc,argv,":lth"))!=-1) + { + switch(opt) + { + case 'l': + if(argv[optind] == NULL) { + usage_print(); + return -1; + } + address = argv[optind]; + break; + case 't': + if(argv[optind] == NULL) { + usage_print(); + return -1; + } + filename = argv[optind]; + break; + case 'h': + usage_print(); + return -1; + case '?': + printf("unknown option: %c\n",optopt); + break; + } + } + + sprintf(uri,"http://%s:%s/challenge-response/v1/",address,port); + + /* Initialize the curl library */ + curl_handle = curl_easy_init(); + if(curl_handle) { + /* Create new session with the veraison service */ + + char *new_session="newSession?nonceSize=32"; + char url[100]; + sprintf(url,"%s%s",uri,new_session); + curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, ""); + curl_easy_setopt(curl_handle, CURLOPT_URL, url); + res = curl_easy_perform(curl_handle); /* post away! */ + if(res != CURLE_OK) { + printf("\nerror: %s\n", curl_easy_strerror(res)); + return res; + } else { + /* Send the token for verification using the session id + returned by the previous curl_easy_perform call. + The session id is returned under Location in the header */ + + curl_easy_header(curl_handle, "Location", 0, CURLH_HEADER, -1, &type); + strcat(uri,type->value); + struct curl_slist *headers = NULL; + headers = curl_slist_append(headers, "Content-Type: application/psa-attestation-token"); + curl_slist_append(headers, "Host: veraison.example"); + curl_slist_append(headers, "Accept: application/vnd.veraison.challenge-response-session+json"); + curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); + FILE *fp=fopen(filename,"rb"); + int num; + if(fp!=NULL) { + num = fread(token, 1 ,sizeof(token),fp); + } else { + printf("\ntoken file not found\n"); + return -1; + } + curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, num); + curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, token); + curl_easy_setopt(curl_handle, CURLOPT_URL, uri); + res = curl_easy_perform(curl_handle); /* post away! */ + if(res != CURLE_OK) { + printf("\nerror: %s\n", curl_easy_strerror(res)); + } + curl_slist_free_all(headers); /* free the header list */ + curl_easy_cleanup(curl_handle); + } + } else { + printf("\nCannot initialize Curl library \n"); + return -1; + } + + return 0; +} \ No newline at end of file