google drive sdk - trouble getting JWT for a server to server application in C -


i have trouble getting jwt server server application. following command

openssl pkcs12 -in mypkcs12-private.p12 -out privatekey.pem. 

following doc /docs/oauth2serviceaccount, encoded header

{"alg":"rs256","typ":"jwt"} 

and claim

{"iss":"******@developer.gserviceaccount.com","scope":"https://www.googleapis.com/auth/drive.file,"aud":"https://accounts.google.com/o/oauth2/token","exp":1401710837,"iat":1401707237}  

in base64. created base64 encoded signature using (b64header.b64claim), private key , hmac function. when request token using curl, invalid_grant error. tried many things don't know issue is.

here code

static size_t writememorycallback(void *contents, size_t size, size_t nmemb, void *userp) {    size_t realsize = size * nmemb;   memorystruct *mem = (memorystruct *)userp;    mem->memory = realloc(mem->memory, mem->size + realsize + 1);   if(mem->memory == null) {     /* out of memory! */      printf("not enough memory (realloc returned null)\n");     return 0;   }    memcpy(&(mem->memory[mem->size]), contents, realsize);   mem->size += realsize;   mem->memory[mem->size] = 0;     return realsize; }   char *base64encode(const char *normal, size_t length)  {     bio *bmem, *b64;     buf_mem *bptr;     char *buff = null;     b64 = bio_new(bio_f_base64());     bmem = bio_new(bio_s_mem());     b64 = bio_push(b64, bmem);     bio_write(b64, normal, (int) length);     if (bio_flush(b64) != 1) {         return null;     }      bio_get_mem_ptr(b64, &bptr);      buff = (char *) malloc(bptr->length);     memcpy(buff, bptr->data, bptr->length-1);     buff[bptr->length - 1] = 0;      bio_free_all(b64);     b64 = null;     return buff; }  char * createclaimset(char * address) {     char * output = null;     char claim_format[] =  "{\"iss\":\"%s\",\"scope\":\"https://www.googleapis.com/auth/drive.file\",\"aud\":\"https://accounts.google.com/o/oauth2/token\",\"exp\":%ld,\"iat\":%ld}";     size_t len_address = 0;     size_t size = 0;     time_t iat;     time_t exp;      time(&iat);     exp = iat + 3600;      if (address) len_address = strlen(address);     size = strlen(claim_format);     output = (char*) calloc(len_address + size - 8 + 20 + 1, sizeof(char));     sprintf(output,claim_format, address, exp, iat);     printf(output);      return output; }   char *b64hmacsha256fct(char *line, char * keyp12, size_t size) {     char *hmac64 = "";     const evp_md *evp_md = evp_sha256();     unsigned char md[evp_max_md_size];     unsigned int md_len;       // hmac     hmac(evp_md, keyp12, (int)size, (const unsigned char*) line, strlen(line), md, &md_len);      hmac64=base64encode(md, md_len);      return hmac64; }  int authserviceaccount(curl *curl) {     char * b64_claim_set = null;     char * claim_set = null;     char * header64 = null;     char * jwt = null;     char * tosign = null;     char * sig64 = null;     char * str = null;     char * data = null;     char * privatekey = null;     char grant[] = "grant_type=urn%3aietf%3aparams%3aoauth%3agrant-type%3ajwt-bearer";     char uri[] = "https://accounts.google.com/o/oauth2/token";     char header[] = "{\"alg\":\"rs256\",\"typ\":\"jwt\"}";     char emailaddress[] = "xxxxxx@developer.gserviceaccount.com";     char pkcs12_file_path[] = "c:\\temp\\mykey.key";     file * pinputp12name = null;     int = 0;     int j = 0;     memorystruct writememory;     size_t filep12size = 0;     size_t lclaim64 = 0;     size_t lclaimset = 0;     size_t lheader64 = 0;     size_t lstr = 0;     size_t resultat;      header64 = base64encode(header, strlen(header));     if (header64) lheader64 = strlen(header64);      claim_set = createclaimset(emailaddress);     if (claim_set) lclaimset = strlen(claim_set);     b64_claim_set = base64encode(claim_set, lclaimset);     if (b64_claim_set) lclaim64 = strlen(b64_claim_set);     str = (char*) calloc(lclaim64+1, sizeof(char));     if (!str) return 1;     (i=0; i<lclaim64; i++) {         if (isprint(b64_claim_set[i])) {             str[j] = b64_claim_set[i];             j++;         }     }     str[j] = '\0';      if (str) lstr = strlen(str);     tosign = (char*) calloc(lheader64 + 1 + lstr + 1, sizeof(char));     if (!tosign) return 1;     sprintf(tosign,"%s.%s",header64,str);      pinputp12name = fopen (pkcs12_file_path,"rb");     if (pinputp12name==null) {         perror ("error opening file");         return (-1);     }     else     {         resultat = _fseeki64(pinputp12name, 0, seek_end);         filep12size= (size_t) ftell(pinputp12name);         rewind(pinputp12name);         privatekey = (char *) calloc(filep12size+1, sizeof(char));         resultat = fread (privatekey,sizeof(char),filep12size,pinputp12name);         fclose (pinputp12name);     }      sig64 = b64hmacsha256fct(tosign,privatekey,filep12size);     if (!sig64) return 1;      jwt = (char *) calloc(strlen(tosign) + 1 + strlen(sig64) + 1, sizeof(char));     sprintf(jwt,"%s.%s", tosign, sig64);       if (curl) {         file* pfile = null;         size_t size = 0;          memset(&writememory,'\0',sizeof(memorystruct));          size = strlen(grant)+strlen("&assertion=")+strlen(jwt);         data = (char *) calloc(size+1, sizeof(char));         if (!data) return 1;         sprintf(data,"%s&assertion=%s", grant, jwt);          curl_easy_reset(curl);         curl_easy_setopt( curl, curlopt_url, uri );         curl_easy_setopt( curl, curlopt_port , 443 );         curl_easy_setopt( curl, curlopt_post, 1 );         curl_easy_setopt( curl, curlopt_postfields, data);         curl_easy_setopt( curl, curlopt_postfieldsize, strlen(data));         curl_easy_setopt( curl, curlopt_header, 1 );         curl_easy_setopt( curl, curlopt_verbose, 1);         curl_easy_setopt( curl, curlopt_writedata, &writememory);         curl_easy_setopt( curl, curlopt_writefunction, writememorycallback);         curl_easy_setopt( curl, curlopt_ssl_verifypeer, 0l);         curl_easy_setopt( curl, curlopt_ssl_verifyhost, 0l);          curl_easy_perform(curl);         printf("%s",writememory.memory);     }      return 0; }  int main(void) {     curl *curl;     curl_version_info_data *curlvers;      curlvers = curl_version_info( curlversion_now );     curl_global_init(curl_global_all);      curl = curl_easy_init();      authserviceaccount(curl);      /* cleanup */      curl_easy_cleanup(curl);     curl_global_cleanup();  exit(0);  } 

the documentation states must use base64url encoding, variant of base64 encoded uses url-safe characters.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -