-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Private key filename #44
base: main
Are you sure you want to change the base?
Changes from all commits
96628d4
e253f66
3b030cb
e8d239c
960d1e1
f227c31
ef43c38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// Taken with modifications from https://gist.github.com/niuk/6365b819a86a7e0b92d82328fcf87da5 | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
|
||
#include <openssl/ssl.h> | ||
#include <openssl/err.h> | ||
|
||
#define CPPHTTPLIB_OPENSSL_SUPPORT | ||
#ifndef NOMINMAX | ||
#define NOMINMAX | ||
#endif | ||
#include <httplib.hpp> | ||
|
||
#include <json.hpp> | ||
using json = nlohmann::json; | ||
namespace duckdb | ||
{ | ||
|
||
char get_base64_char(char byte) { | ||
if (byte < 26) { | ||
return 'A' + byte; | ||
} else if (byte < 52) { | ||
return 'a' + byte - 26; | ||
} else if (byte < 62) { | ||
return '0' + byte - 52; | ||
} else if (byte == 62) { | ||
return '-'; | ||
} else if (byte == 63) { | ||
return '_'; | ||
} else { | ||
fprintf(stderr, "BAD BYTE: %02x\n", byte); | ||
exit(1); | ||
return 0; | ||
} | ||
} | ||
|
||
// To execute C, please define "int main()" | ||
void base64encode(char *output, const char *input, size_t input_length) { | ||
size_t input_index = 0; | ||
size_t output_index = 0; | ||
for (; input_index < input_length; ++output_index) { | ||
switch (output_index % 4) { | ||
case 0: | ||
output[output_index] = get_base64_char((0xfc & input[input_index]) >> 2); | ||
break; | ||
case 1: | ||
output[output_index] = get_base64_char(((0x03 & input[input_index]) << 4) | ((0xf0 & input[input_index + 1]) >> 4)); | ||
++input_index; | ||
break; | ||
case 2: | ||
output[output_index] = get_base64_char(((0x0f & input[input_index]) << 2) | ((0xc0 & input[input_index + 1]) >> 6)); | ||
++input_index; | ||
break; | ||
case 3: | ||
output[output_index] = get_base64_char(0x3f & input[input_index]); | ||
++input_index; | ||
break; | ||
default: | ||
exit(1); | ||
} | ||
} | ||
|
||
output[output_index] = '\0'; | ||
} | ||
|
||
std::string get_token(const std::string& filename) { | ||
const char *header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"; | ||
|
||
/* Create jwt claim set */ | ||
json jwt_claim_set; | ||
std::time_t t = std::time(NULL); | ||
std::ifstream ifs(filename); | ||
json credentials_file = json::parse(ifs); | ||
std::string email = credentials_file["client_email"].get<std::string>(); | ||
|
||
jwt_claim_set["iss"] = email; /* service account email address */ | ||
jwt_claim_set["scope"] = "https://www.googleapis.com/auth/spreadsheets" /* scope of requested access token */; | ||
jwt_claim_set["aud"] = "https://accounts.google.com/o/oauth2/token"; /* intended target of the assertion for an access token */ | ||
jwt_claim_set["iat"] = std::to_string(t); /* issued time */ | ||
// Since we get a new token on every request (and max request time is 3 minutes), | ||
// set the limit to 10 minutes. (Max that Google allows is 1 hour) | ||
jwt_claim_set["exp"] = std::to_string(t+600); /* expire time*/ | ||
|
||
char header_64[1024]; | ||
base64encode(header_64, header, strlen(header)); | ||
|
||
char claim_set_64[1024]; | ||
base64encode(claim_set_64, jwt_claim_set.dump().c_str(), strlen(jwt_claim_set.dump().c_str())); | ||
|
||
char input[1024]; | ||
int input_length = sprintf(input, "%s.%s", header_64, claim_set_64); | ||
Check warning on line 92 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 92 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 92 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 92 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 92 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 92 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 92 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 92 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
|
||
|
||
unsigned char *digest = SHA256((const unsigned char *)input, input_length, NULL); | ||
char digest_str[1024]; | ||
for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) { | ||
sprintf(digest_str + i * 2, "%02x", digest[i]); | ||
Check warning on line 97 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 97 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 97 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 97 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 97 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 97 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 97 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 97 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
|
||
} | ||
|
||
digest_str[SHA256_DIGEST_LENGTH * 2] = '\0'; | ||
|
||
std::string private_key_string = credentials_file["private_key"].get<std::string>(); | ||
|
||
BIO* bio = BIO_new(BIO_s_mem()); | ||
const void * private_key_pointer = private_key_string.c_str(); | ||
int private_key_length = std::strlen(private_key_string.c_str()); | ||
BIO_write(bio, private_key_pointer, private_key_length); | ||
EVP_PKEY* evp_key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); | ||
RSA* rsa = EVP_PKEY_get1_RSA(evp_key); | ||
Check warning on line 109 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_mvp, wasm32-emscripten)
Check warning on line 109 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_threads, wasm32-emscripten)
Check warning on line 109 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_eh, wasm32-emscripten)
Check warning on line 109 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 109 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_mvp, wasm32-emscripten)
Check warning on line 109 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 109 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
|
||
|
||
if (rsa != NULL) { | ||
unsigned char sigret[4096] = {}; | ||
unsigned int siglen; | ||
if (RSA_sign(NID_sha256, digest, SHA256_DIGEST_LENGTH, sigret, &siglen, rsa)) { | ||
Check warning on line 114 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_mvp, wasm32-emscripten)
Check warning on line 114 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_threads, wasm32-emscripten)
Check warning on line 114 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_eh, wasm32-emscripten)
Check warning on line 114 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 114 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_mvp, wasm32-emscripten)
Check warning on line 114 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 114 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
|
||
if (RSA_verify(NID_sha256, digest, SHA256_DIGEST_LENGTH, sigret, siglen, rsa)) { | ||
Check warning on line 115 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_mvp, wasm32-emscripten)
Check warning on line 115 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_threads, wasm32-emscripten)
Check warning on line 115 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_eh, wasm32-emscripten)
Check warning on line 115 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 115 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_mvp, wasm32-emscripten)
Check warning on line 115 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 115 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
|
||
char signature_64[1024]; | ||
base64encode(signature_64, (const char *)sigret, siglen); | ||
|
||
char jwt[1024]; | ||
sprintf(jwt, "%s.%s", input, signature_64); | ||
Check warning on line 120 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 120 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 120 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 120 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
|
||
|
||
duckdb_httplib_openssl::Client cli("https://oauth2.googleapis.com"); | ||
duckdb_httplib_openssl::Params params; | ||
params.emplace("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"); | ||
params.emplace("assertion", jwt); | ||
auto result = cli.Post("/token", params); | ||
return (result -> body); | ||
} else { | ||
printf("Could not verify RSA signature."); | ||
} | ||
} else { | ||
unsigned long err = ERR_get_error(); | ||
printf("RSA_sign failed: %lu, %s\n", err, ERR_error_string(err, NULL)); | ||
} | ||
|
||
RSA_free(rsa); | ||
Check warning on line 136 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_mvp, wasm32-emscripten)
Check warning on line 136 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_threads, wasm32-emscripten)
Check warning on line 136 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_eh, wasm32-emscripten)
Check warning on line 136 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
Check warning on line 136 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / DuckDB-Wasm (wasm_mvp, wasm32-emscripten)
Check warning on line 136 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_amd64, x86_64, x64-osx)
Check warning on line 136 in src/gsheets_get_token.cpp GitHub Actions / Build extension binaries / MacOS (osx_arm64, arm64, arm64-osx)
|
||
} | ||
std::string failure_message = "{\"status\":\"failed\"}"; | ||
|
||
return failure_message; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
#include <stdlib.h> | ||
|
||
namespace duckdb { | ||
|
||
char get_base64_char(char byte); | ||
|
||
void base64encode(char *output, const char *input, size_t input_length) ; | ||
|
||
std::string get_token(const std::string& filename) ; | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2017 yhirose | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think google would normally refer to this as key_file