Skip to content

Commit

Permalink
Update grpc and protobuf (envoyproxy#70)
Browse files Browse the repository at this point in the history
* protobuf v3.2.0
* grpc v1.1.1
* Align auth lib with grpc 1.1.1
  • Loading branch information
lizan authored Feb 9, 2017
1 parent fdac61b commit 6e372fc
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 195 deletions.
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

0 comments on commit 6e372fc

Please sign in to comment.