Skip to content
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

Update grpc and protobuf #70

Merged
merged 5 commits into from
Feb 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions contrib/endpoints/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def grpc_repositories(bind=True):

native.git_repository(
name = "grpc_git",
commit = "d28417c856366df704200f544e72d31056931bce",
commit = "bb3edafea245a9780cc4c10f0b58da21e8193f38", # v1.1.1
remote = "https://github.com/grpc/grpc.git",
)

Expand All @@ -190,7 +190,7 @@ def grpc_repositories(bind=True):

native.bind(
name = "grpc_lib",
actual = "@grpc_git//:grpc++_reflection",
actual = "@grpc_git//:grpc++_codegen_proto",
)

def googleapis_repositories(protobuf_repo="@protobuf_git//", bind=True):
Expand Down Expand Up @@ -333,4 +333,3 @@ def servicecontrol_client_repositories(bind=True):
name = "servicecontrol_client",
actual = "@servicecontrol_client_git//:service_control_client_lib",
)

47 changes: 28 additions & 19 deletions contrib/endpoints/src/api_manager/auth/lib/auth_jwt_validator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ class JwtValidatorImpl : public JwtValidator {
RSA *rsa_;
EVP_PKEY *pkey_;
EVP_MD_CTX *md_ctx_;

grpc_exec_ctx exec_ctx_;
};

// Gets EVP_MD mapped from an alg (algorithm string).
Expand All @@ -159,12 +161,12 @@ const EVP_MD *EvpMdFromAlg(const char *alg);
size_t HashSizeFromAlg(const char *alg);

// Parses str into grpc_json object. Does not own buffer.
grpc_json *DecodeBase64AndParseJson(const char *str, size_t len,
gpr_slice *buffer);
grpc_json *DecodeBase64AndParseJson(grpc_exec_ctx *exec_ctx, const char *str,
size_t len, gpr_slice *buffer);

// Gets BIGNUM from b64 string, used for extracting pkey from jwk.
// Result owned by rsa_.
BIGNUM *BigNumFromBase64String(const char *b64);
BIGNUM *BigNumFromBase64String(grpc_exec_ctx *exec_ctx, const char *b64);

} // namespace

Expand All @@ -185,7 +187,8 @@ JwtValidatorImpl::JwtValidatorImpl(const char *jwt, size_t jwt_len)
x509_(nullptr),
rsa_(nullptr),
pkey_(nullptr),
md_ctx_(nullptr) {
md_ctx_(nullptr),
exec_ctx_(GRPC_EXEC_CTX_INIT) {
header_buffer_ = gpr_empty_slice();
signed_buffer_ = gpr_empty_slice();
sig_buffer_ = gpr_empty_slice();
Expand All @@ -204,7 +207,7 @@ JwtValidatorImpl::~JwtValidatorImpl() {
grpc_json_destroy(pkey_json_);
}
if (claims_ != nullptr) {
grpc_jwt_claims_destroy(claims_);
grpc_jwt_claims_destroy(&exec_ctx_, claims_);
}
if (!GPR_SLICE_IS_EMPTY(header_buffer_)) {
gpr_slice_unref(header_buffer_);
Expand Down Expand Up @@ -304,7 +307,8 @@ grpc_jwt_verifier_status JwtValidatorImpl::ParseImpl() {
if (dot == nullptr) {
return GRPC_JWT_VERIFIER_BAD_FORMAT;
}
header_json_ = DecodeBase64AndParseJson(cur, dot - cur, &header_buffer_);
header_json_ =
DecodeBase64AndParseJson(&exec_ctx_, cur, dot - cur, &header_buffer_);
CreateJoseHeader();
if (header_ == nullptr) {
return GRPC_JWT_VERIFIER_BAD_FORMAT;
Expand All @@ -323,7 +327,7 @@ grpc_jwt_verifier_status JwtValidatorImpl::ParseImpl() {
// case, and it is owned by claims_ for successful case.
gpr_slice claims_buffer = gpr_empty_slice();
grpc_json *claims_json =
DecodeBase64AndParseJson(cur, dot - cur, &claims_buffer);
DecodeBase64AndParseJson(&exec_ctx_, cur, dot - cur, &claims_buffer);
if (claims_json == nullptr) {
if (!GPR_SLICE_IS_EMPTY(claims_buffer)) {
gpr_slice_unref(claims_buffer);
Expand All @@ -332,10 +336,13 @@ grpc_jwt_verifier_status JwtValidatorImpl::ParseImpl() {
}
UpdateAudience(claims_json);
// Takes ownershp of claims_json and claims_buffer.
claims_ = grpc_jwt_claims_from_json(claims_json, claims_buffer);
if (claims_ == nullptr) {
claims_ = grpc_jwt_claims_from_json(&exec_ctx_, claims_json, claims_buffer);

// issuer is mandatory. grpc_jwt_claims_issuer checks if claims_ is nullptr.
if (grpc_jwt_claims_issuer(claims_) == nullptr) {
return GRPC_JWT_VERIFIER_BAD_FORMAT;
}

// Check timestamp.
// Passing in its own audience to skip audience check.
// Audience check should be done by the caller.
Expand All @@ -354,8 +361,8 @@ grpc_jwt_verifier_status JwtValidatorImpl::ParseImpl() {
return GRPC_JWT_VERIFIER_BAD_FORMAT;
}
cur = dot + 1;
sig_buffer_ =
grpc_base64_decode_with_len(cur, jwt_len - signed_jwt_len - 1, 1);
sig_buffer_ = grpc_base64_decode_with_len(&exec_ctx_, cur,
jwt_len - signed_jwt_len - 1, 1);
if (GPR_SLICE_IS_EMPTY(sig_buffer_)) {
return GRPC_JWT_VERIFIER_BAD_FORMAT;
}
Expand Down Expand Up @@ -576,9 +583,11 @@ bool JwtValidatorImpl::ExtractPubkeyFromJwk(const grpc_json *jkey) {
}

const char *rsa_n = GetStringValue(jkey, "n");
rsa_->n = rsa_n == nullptr ? nullptr : BigNumFromBase64String(rsa_n);
rsa_->n =
rsa_n == nullptr ? nullptr : BigNumFromBase64String(&exec_ctx_, rsa_n);
const char *rsa_e = GetStringValue(jkey, "e");
rsa_->e = rsa_e == nullptr ? nullptr : BigNumFromBase64String(rsa_e);
rsa_->e =
rsa_e == nullptr ? nullptr : BigNumFromBase64String(&exec_ctx_, rsa_e);

if (rsa_->e == nullptr || rsa_->n == nullptr) {
gpr_log(GPR_ERROR, "Missing RSA public key field.");
Expand Down Expand Up @@ -651,7 +660,7 @@ grpc_jwt_verifier_status JwtValidatorImpl::VerifyHsSignature(const char *pkey,
const EVP_MD *md = EvpMdFromAlg(header_->alg);
GPR_ASSERT(md != nullptr); // Checked before.

pkey_buffer_ = grpc_base64_decode_with_len(pkey, pkey_len, 1);
pkey_buffer_ = grpc_base64_decode_with_len(&exec_ctx_, pkey, pkey_len, 1);
if (GPR_SLICE_IS_EMPTY(pkey_buffer_)) {
gpr_log(GPR_ERROR, "Unable to decode base64 of secret");
return GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR;
Expand Down Expand Up @@ -735,11 +744,11 @@ size_t HashSizeFromAlg(const char *alg) {
}
}

grpc_json *DecodeBase64AndParseJson(const char *str, size_t len,
gpr_slice *buffer) {
grpc_json *DecodeBase64AndParseJson(grpc_exec_ctx *exec_ctx, const char *str,
size_t len, gpr_slice *buffer) {
grpc_json *json;

*buffer = grpc_base64_decode_with_len(str, len, 1);
*buffer = grpc_base64_decode_with_len(exec_ctx, str, len, 1);
if (GPR_SLICE_IS_EMPTY(*buffer)) {
gpr_log(GPR_ERROR, "Invalid base64.");
return nullptr;
Expand All @@ -753,12 +762,12 @@ grpc_json *DecodeBase64AndParseJson(const char *str, size_t len,
return json;
}

BIGNUM *BigNumFromBase64String(const char *b64) {
BIGNUM *BigNumFromBase64String(grpc_exec_ctx *exec_ctx, const char *b64) {
BIGNUM *result = nullptr;
gpr_slice bin;

if (b64 == nullptr) return nullptr;
bin = grpc_base64_decode(b64, 1);
bin = grpc_base64_decode(exec_ctx, b64, 1);
if (GPR_SLICE_IS_EMPTY(bin)) {
gpr_log(GPR_ERROR, "Invalid base64 for big num.");
return nullptr;
Expand Down
3 changes: 2 additions & 1 deletion contrib/endpoints/src/api_manager/auth/lib/auth_token.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ char *GenerateJwtClaim(const char *issuer, const char *subject,
}

char *GenerateSignatueHs256(const char *data, const char *key) {
gpr_slice key_buffer = grpc_base64_decode(key, 1);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_slice key_buffer = grpc_base64_decode(&exec_ctx, key, 1);
if (GPR_SLICE_IS_EMPTY(key_buffer)) {
gpr_log(GPR_ERROR, "Unable to decode base64 of secret");
return nullptr;
Expand Down
176 changes: 6 additions & 170 deletions contrib/endpoints/src/api_manager/auth/lib/grpc_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@
#ifndef API_MANAGER_AUTH_LIB_GRPC_INTERNALS_H_
#define API_MANAGER_AUTH_LIB_GRPC_INTERNALS_H_

// This header file contains definitions for all grpc internal
// dependencies. The code that depends on grpc internals should
// include this file instead of including the original headers
// in grpc.

// This header file is for internal use only since it declares grpc
// internals that auth depends on. A public header file should not
// include any internal grpc header files.
Expand All @@ -30,171 +25,12 @@

extern "C" {

#include <grpc/support/slice.h>
#include <openssl/rsa.h>

//////////////////////////////////////////////////////
// definitions from grpc/src/core/json/json_common.h
//////////////////////////////////////////////////////

/* The various json types. */
typedef enum {
GRPC_JSON_OBJECT,
GRPC_JSON_ARRAY,
GRPC_JSON_STRING,
GRPC_JSON_NUMBER,
GRPC_JSON_TRUE,
GRPC_JSON_FALSE,
GRPC_JSON_NULL,
GRPC_JSON_TOP_LEVEL
} grpc_json_type;

//////////////////////////////////////////////////////
// definitions from grpc/src/core/json/json.h
//////////////////////////////////////////////////////

/* A tree-like structure to hold json values. The key and value pointers
* are not owned by it.
*/
typedef struct grpc_json {
struct grpc_json *next;
struct grpc_json *prev;
struct grpc_json *child;
struct grpc_json *parent;

grpc_json_type type;
const char *key;
const char *value;
} grpc_json;

/* The next two functions are going to parse the input string, and
* modify it in the process, in order to use its space to store
* all of the keys and values for the returned object tree.
*
* They assume UTF-8 input stream, and will output UTF-8 encoded
* strings in the tree. The input stream's UTF-8 isn't validated,
* as in, what you input is what you get as an output.
*
* All the keys and values in the grpc_json objects will be strings
* pointing at your input buffer.
*
* Delete the allocated tree afterward using grpc_json_destroy().
*/
grpc_json *grpc_json_parse_string_with_len(char *input, size_t size);
grpc_json *grpc_json_parse_string(char *input);

/* Use these to create or delete a grpc_json object.
* Deletion is recursive. We will not attempt to free any of the strings
* in any of the objects of that tree.
*/
grpc_json *grpc_json_create(grpc_json_type type);
void grpc_json_destroy(grpc_json *json);

/* This function will create a new string using gpr_realloc, and will
* deserialize the grpc_json tree into it. It'll be zero-terminated,
* but will be allocated in chunks of 256 bytes.
*
* The indent parameter controls the way the output is formatted.
* If indent is 0, then newlines will be suppressed as well, and the
* output will be condensed at its maximum.
*/
char *grpc_json_dump_to_string(grpc_json *json, int indent);

//////////////////////////////////////////////////////
// definitions from grpc/src/core/security/base64
//////////////////////////////////////////////////////

/* Encodes data using base64. It is the caller's responsability to free
the returned char * using gpr_free. Returns nullptr on nullptr input. */
char *grpc_base64_encode(const void *data, size_t data_size, int url_safe,
int multiline);

/* Decodes data according to the base64 specification. Returns an empty
slice in case of failure. */
gpr_slice grpc_base64_decode(const char *b64, int url_safe);

/* Same as above except that the length is provided by the caller. */
gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
int url_safe);

//////////////////////////////////////////////////////
// definitions from grpc/src/core/auth/security/json_key.h
//////////////////////////////////////////////////////

/* --- auth_json_key parsing. --- */

typedef struct {
const char *type;
char *private_key_id;
char *client_id;
char *client_email;
RSA *private_key;
} grpc_auth_json_key;

/* Creates a json_key object from string. Returns an invalid object if a parsing
error has been encountered. */
grpc_auth_json_key grpc_auth_json_key_create_from_string(
const char *json_string);

/* Destructs the object. */
void grpc_auth_json_key_destruct(grpc_auth_json_key *json_key);

/* Caller is responsible for calling gpr_free on the returned value. May return
nullptr on invalid input. The scope parameter may be nullptr. */
char *grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key,
const char *audience,
gpr_timespec token_lifetime, const char *scope);

//////////////////////////////////////////////////////
// definitions from grpc/src/core/support/string.h
//////////////////////////////////////////////////////

/* Minimum buffer size for calling ltoa */
#define GPR_LTOA_MIN_BUFSIZE (3 * sizeof(long))

/* Convert a long to a string in base 10; returns the length of the
output string (or 0 on failure).
output must be at least GPR_LTOA_MIN_BUFSIZE bytes long. */
int gpr_ltoa(long value, char *output);

//////////////////////////////////////////////////////
// definitions from grpc/src/core/security/jwt_verifier.h
//////////////////////////////////////////////////////

/* --- grpc_jwt_verifier_status. --- */

typedef enum {
GRPC_JWT_VERIFIER_OK = 0,
GRPC_JWT_VERIFIER_BAD_SIGNATURE,
GRPC_JWT_VERIFIER_BAD_FORMAT,
GRPC_JWT_VERIFIER_BAD_AUDIENCE,
GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE,
GRPC_JWT_VERIFIER_GENERIC_ERROR
} grpc_jwt_verifier_status;

const char *grpc_jwt_verifier_status_to_string(grpc_jwt_verifier_status status);

/* --- grpc_jwt_claims. --- */

typedef struct grpc_jwt_claims grpc_jwt_claims;

void grpc_jwt_claims_destroy(grpc_jwt_claims *claims);

/* Returns the whole JSON tree of the claims. */
const grpc_json *grpc_jwt_claims_json(const grpc_jwt_claims *claims);

/* Access to registered claims in https://tools.ietf.org/html/rfc7519#page-9 */
const char *grpc_jwt_claims_subject(const grpc_jwt_claims *claims);
const char *grpc_jwt_claims_issuer(const grpc_jwt_claims *claims);
const char *grpc_jwt_claims_audience(const grpc_jwt_claims *claims);
gpr_timespec grpc_jwt_claims_expires_at(const grpc_jwt_claims *claims);

/* --- TESTING ONLY exposed functions. --- */

grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, gpr_slice buffer);
grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
const char *audience);
#include "src/core/lib/json/json.h"
#include "src/core/lib/json/json_common.h"
#include "src/core/lib/security/credentials/jwt/json_token.h"
#include "src/core/lib/security/credentials/jwt/jwt_verifier.h"
#include "src/core/lib/security/util/b64.h"
#include "src/core/lib/support/string.h"
}

#endif // API_MANAGER_AUTH_LIB_GRPC_INTERNALS_H_
4 changes: 2 additions & 2 deletions repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def boringssl_repositories(bind=True):
def protobuf_repositories(bind=True):
native.git_repository(
name = "protobuf_git",
commit = "a428e42072765993ff674fda72863c9f1aa2d268", # v3.1.0
commit = "593e917c176b5bc5aafa57bf9f6030d749d91cd5", # v3.2.0
remote = "https://github.com/google/protobuf.git",
)

Expand Down Expand Up @@ -68,7 +68,7 @@ def protobuf_repositories(bind=True):

native.bind(
name = "protobuf_clib",
actual = "@protobuf_git//:protobuf_lite",
actual = "@protobuf_git//:protoc_lib",
)


Expand Down