Using Google Service Account key file

Viewed 54

I maintain a 3rd party app that accesses Google data. We tell our customers to create a service account, download a .p12 file (which has the password "notasecret") then allow our app to read the .p12 file. In my code, I call the OpenSSL routine PKCS12_parse() with that password, and from there other routines which result in a JWT that I can use to obtain a Google authorization code. This has worked fine in many projects.

Now we have one customer who has some corporate restrictions that require him to create a service account within the Marketplace SDK of a Google Cloud Platform project. I don't really know anything about that. The customer says it generates a .p12 file for him, but at no point tells him that the password is "notasecret" nor allows him to set one. In my code, the PKCS12_parse routine fails with error "Mac verify failure" (which supposedly means the password is incorrect). I have tried setting the password to null but the result is the same.

I'm hoping somebody can recognize what exactly this customer is doing to generate the .p12 file, and why it doesn't work with my code? Any help is appreciated, thanks. (Note I am not using any API, just C++ and direct http calls via libcurl).

Further clarification: I am trying to implement creating a JWT from this documentation: https://developers.google.com/identity/protocols/oauth2/service-account#httprest

The critical part is signing the JWT. I am using the following code, which uses routines from OpenSSL (most error checking removed here for clarity):

   wsprintf(JWT,"%s.%s", JWTHeader64, ClaimSet64);
   SHA256((unsigned char*)JWT, strlen(JWT), (unsigned char*)digest);
   d2i_PKCS12(&p12_cert, &pkdata2, flen); // pkdata2 contains bytes from the .p12 file
   ret=PKCS12_parse(p12_cert, "notasecret", &pkey, &x509_cert, NULL);
   pkerr = ERR_get_error();
   if (!ret) {
       ERR_error_string(pkerr, ScratchBuf);
       printf("PKCS12_parse error: %ld (%s)", pkerr, ScratchBuf);
       return(2);
   }
   rsa_key = EVP_PKEY_get1_RSA(pkey);
   if (rsa_key == NULL) {
       printf("rsa_key is null");
       return(3);
   }

   ret=RSA_sign(NID_sha256, (unsigned char *)digest, SHA256_DIGEST_LENGTH, (unsigned char *)sigret, &siglen, rsa_key);
   if (!ret) {
       printf("RSA-sign return: %d", ret);
       return(4);
   }

   com_Base64Encode((char *)sigret, siglen, TRUE, Signature64);
   wsprintf(JWT,"%s.%s.", JWTHeader64, ClaimSet64);
   strcat(JWT, Signature64);

This code works with all the other .p12 files generated by our customers, but in this one case, the PKCS12_parse() routine fails with the error "error:23076071:PKCS12 routines:PKCS12_parse:mac verify failure".

Is there something I should be doing differently for a private key obtained from the Google API console?

0 Answers
Related