aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar jboeuf <jboeuf@google.com>2014-12-12 15:39:47 -0800
committerGravatar Nicolas Noble <nnoble@google.com>2014-12-12 16:36:06 -0800
commitbefd26501a6dbc0dca9d12444b4d245fa5560db0 (patch)
tree1891340ab73ce69fb66e08ab09b1540526098ce7 /test
parent993dfcef3ea9c511a47c8d7caed8b52e9584abb9 (diff)
Adding base utils for JWT service account workflow. OpenSSL base64 decoding is
a disaster and does not support url_safe which we need for the JWT. Change on 2014/12/12 by jboeuf <jboeuf@google.com> ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=82020601
Diffstat (limited to 'test')
-rw-r--r--test/core/security/base64_test.c185
-rw-r--r--test/core/security/json_token_test.c210
2 files changed, 395 insertions, 0 deletions
diff --git a/test/core/security/base64_test.c b/test/core/security/base64_test.c
new file mode 100644
index 0000000000..b3ba491a34
--- /dev/null
+++ b/test/core/security/base64_test.c
@@ -0,0 +1,185 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/security/base64.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+#include "test/core/util/test_config.h"
+
+static int buffers_are_equal(const unsigned char *buf1,
+ const unsigned char *buf2, size_t size) {
+ size_t i;
+ for (i = 0; i < size; i++) {
+ if (buf1[i] != buf2[i]) {
+ gpr_log(GPR_ERROR, "buf1 and buf2 differ: buf1[%d] = %x vs buf2[%d] = %x",
+ (int)i, buf1[i], (int)i, buf2[i]);
+ return 0;
+ }
+ }
+ return 1;
+}
+static void test_simple_encode_decode_b64(int url_safe, int multiline) {
+ const char *hello = "hello";
+ char *hello_b64 =
+ grpc_base64_encode(hello, strlen(hello), url_safe, multiline);
+ gpr_slice hello_slice = grpc_base64_decode(hello_b64, url_safe);
+ GPR_ASSERT(GPR_SLICE_LENGTH(hello_slice) == strlen(hello));
+ GPR_ASSERT(!strncmp((const char *)GPR_SLICE_START_PTR(hello_slice), hello,
+ GPR_SLICE_LENGTH(hello_slice)));
+
+ gpr_slice_unref(hello_slice);
+ gpr_free(hello_b64);
+}
+
+static void test_full_range_encode_decode_b64(int url_safe, int multiline) {
+ unsigned char orig[256];
+ size_t i;
+ char *b64;
+ gpr_slice orig_decoded;
+ for (i = 0; i < sizeof(orig); i++) orig[i] = (char)i;
+
+ /* Try all the different paddings. */
+ for (i = 0; i < 3; i++) {
+ b64 = grpc_base64_encode(orig, sizeof(orig) - i, url_safe, multiline);
+ orig_decoded = grpc_base64_decode(b64, url_safe);
+ GPR_ASSERT(GPR_SLICE_LENGTH(orig_decoded) == (sizeof(orig) - i));
+ GPR_ASSERT(buffers_are_equal(orig, GPR_SLICE_START_PTR(orig_decoded),
+ sizeof(orig) - i));
+ gpr_slice_unref(orig_decoded);
+ gpr_free(b64);
+ }
+}
+
+static void test_simple_encode_decode_b64_no_multiline(void) {
+ test_simple_encode_decode_b64(0, 0);
+}
+
+static void test_simple_encode_decode_b64_multiline(void) {
+ test_simple_encode_decode_b64(0, 1);
+}
+
+static void test_simple_encode_decode_b64_urlsafe_no_multiline(void) {
+ test_simple_encode_decode_b64(1, 0);
+}
+
+static void test_simple_encode_decode_b64_urlsafe_multiline(void) {
+ test_simple_encode_decode_b64(1, 1);
+}
+
+static void test_full_range_encode_decode_b64_no_multiline(void) {
+ test_full_range_encode_decode_b64(0, 0);
+}
+
+static void test_full_range_encode_decode_b64_multiline(void) {
+ test_full_range_encode_decode_b64(0, 1);
+}
+
+static void test_full_range_encode_decode_b64_urlsafe_no_multiline(void) {
+ test_full_range_encode_decode_b64(1, 0);
+}
+
+static void test_full_range_encode_decode_b64_urlsafe_multiline(void) {
+ test_full_range_encode_decode_b64(1, 1);
+}
+
+static void test_url_safe_unsafe_mismtach_failure(void) {
+ unsigned char orig[256];
+ size_t i;
+ char *b64;
+ gpr_slice orig_decoded;
+ int url_safe = 1;
+ for (i = 0; i < sizeof(orig); i++) orig[i] = (char)i;
+
+ b64 = grpc_base64_encode(orig, sizeof(orig), url_safe, 0);
+ orig_decoded = grpc_base64_decode(b64, !url_safe);
+ GPR_ASSERT(GPR_SLICE_IS_EMPTY(orig_decoded));
+ gpr_free(b64);
+ gpr_slice_unref(orig_decoded);
+
+ b64 = grpc_base64_encode(orig, sizeof(orig), !url_safe, 0);
+ orig_decoded = grpc_base64_decode(b64, url_safe);
+ GPR_ASSERT(GPR_SLICE_IS_EMPTY(orig_decoded));
+ gpr_free(b64);
+ gpr_slice_unref(orig_decoded);
+}
+
+static void test_rfc4648_test_vectors(void) {
+ char *b64;
+
+ b64 = grpc_base64_encode("", 0, 0, 0);
+ GPR_ASSERT(!strcmp("", b64));
+ gpr_free(b64);
+
+ b64 = grpc_base64_encode("f", 1, 0, 0);
+ GPR_ASSERT(!strcmp("Zg==", b64));
+ gpr_free(b64);
+
+ b64 = grpc_base64_encode("fo", 2, 0, 0);
+ GPR_ASSERT(!strcmp("Zm8=", b64));
+ gpr_free(b64);
+
+ b64 = grpc_base64_encode("foo", 3, 0, 0);
+ GPR_ASSERT(!strcmp("Zm9v", b64));
+ gpr_free(b64);
+
+ b64 = grpc_base64_encode("foob", 4, 0, 0);
+ GPR_ASSERT(!strcmp("Zm9vYg==", b64));
+ gpr_free(b64);
+
+ b64 = grpc_base64_encode("fooba", 5, 0, 0);
+ GPR_ASSERT(!strcmp("Zm9vYmE=", b64));
+ gpr_free(b64);
+
+ b64 = grpc_base64_encode("foobar", 6, 0, 0);
+ GPR_ASSERT(!strcmp("Zm9vYmFy", b64));
+ gpr_free(b64);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ test_simple_encode_decode_b64_no_multiline();
+ test_simple_encode_decode_b64_multiline();
+ test_simple_encode_decode_b64_urlsafe_no_multiline();
+ test_simple_encode_decode_b64_urlsafe_multiline();
+ test_full_range_encode_decode_b64_no_multiline();
+ test_full_range_encode_decode_b64_multiline();
+ test_full_range_encode_decode_b64_urlsafe_no_multiline();
+ test_full_range_encode_decode_b64_urlsafe_multiline();
+ test_url_safe_unsafe_mismtach_failure();
+ test_rfc4648_test_vectors();
+ return 0;
+}
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
new file mode 100644
index 0000000000..bb36f786c4
--- /dev/null
+++ b/test/core/security/json_token_test.c
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/security/json_token.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+#include "test/core/util/test_config.h"
+
+/* This JSON key was generated with the GCE console and revoked immediately.
+ The identifiers have been changed as well.
+ Maximum size for a string literal is 509 chars in C89, yay! */
+static const char test_json_key_str_part1[] =
+ "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----"
+ "\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\n7mJEqg"
+ "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\nyjSeg/"
+ "rWBQvS4hle4LfijkP3J5BG+"
+ "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\nOnVF6N7dL3nTYZg+"
+ "uQrNsMTz9UxVAgMBAAECgYEAzbLewe1xe9vy+2GoSsfib+28\nDZgSE6Bu/"
+ "zuFoPrRc6qL9p2SsnV7txrunTyJkkOnPLND9ABAXybRTlcVKP/sGgza\n/"
+ "8HpCqFYM9V8f34SBWfD4fRFT+n/"
+ "73cfRUtGXdXpseva2lh8RilIQfPhNZAncenU\ngqXjDvpkypEusgXAykECQQD+";
+static const char test_json_key_str_part2[] =
+ "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\nCslxoHQM8s+"
+ "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\nEkoy2L/"
+ "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\nAARh2QJBAMKeDAG"
+ "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\n8FZi5c8idxiwC36kbAL6HzA"
+ "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\n6z8RJm0+"
+ "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/"
+ "5nZ68ECQQDvYuI3\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZY"
+ "Ap6LI9W\nIqv4vr6y38N79TTC\n-----END PRIVATE KEY-----\n\", ";
+static const char test_json_key_str_part3[] =
+ "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
+ "\"client_email\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
+ "com\", \"client_id\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
+ "com\", \"type\": \"service_account\" }";
+
+static char *test_json_key_str(const char *bad_part3) {
+ const char *part3 = bad_part3 != NULL ? bad_part3 : test_json_key_str_part3;
+ size_t result_len = strlen(test_json_key_str_part1) +
+ strlen(test_json_key_str_part2) + strlen(part3);
+ char *result = gpr_malloc(result_len + 1);
+ char *current = result;
+ strcpy(result, test_json_key_str_part1);
+ current += strlen(test_json_key_str_part1);
+ strcpy(current, test_json_key_str_part2);
+ current += strlen(test_json_key_str_part2);
+ strcpy(current, part3);
+ return result;
+}
+
+static void test_parse_json_key_success() {
+ char *json_string = test_json_key_str(NULL);
+ grpc_auth_json_key json_key =
+ grpc_auth_json_key_create_from_string(json_string);
+ GPR_ASSERT(grpc_auth_json_key_is_valid(&json_key));
+ GPR_ASSERT(json_key.type != NULL &&
+ !(strcmp(json_key.type, "service_account")));
+ GPR_ASSERT(json_key.private_key_id != NULL &&
+ !strcmp(json_key.private_key_id,
+ "e6b5137873db8d2ef81e06a47289e6434ec8a165"));
+ GPR_ASSERT(json_key.client_id != NULL &&
+ !strcmp(json_key.client_id,
+ "777-abaslkan11hlb6nmim3bpspl31ud.apps."
+ "googleusercontent.com"));
+ GPR_ASSERT(json_key.client_email != NULL &&
+ !strcmp(json_key.client_email,
+ "777-abaslkan11hlb6nmim3bpspl31ud@developer."
+ "gserviceaccount.com"));
+ GPR_ASSERT(json_key.private_key != NULL);
+ gpr_free(json_string);
+ grpc_auth_json_key_destruct(&json_key);
+}
+
+static void test_parse_json_key_failure_bad_json() {
+ const char non_closing_part3[] =
+ "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
+ "\"client_email\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
+ "com\", \"client_id\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
+ "com\", \"type\": \"service_account\" ";
+ char *json_string = test_json_key_str(non_closing_part3);
+ grpc_auth_json_key json_key =
+ grpc_auth_json_key_create_from_string(json_string);
+ GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key));
+ gpr_free(json_string);
+ grpc_auth_json_key_destruct(&json_key);
+}
+
+static void test_parse_json_key_failure_no_type() {
+ const char no_type_part3[] =
+ "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
+ "\"client_email\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
+ "com\", \"client_id\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
+ "com\" }";
+ char *json_string = test_json_key_str(no_type_part3);
+ grpc_auth_json_key json_key =
+ grpc_auth_json_key_create_from_string(json_string);
+ GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key));
+ gpr_free(json_string);
+ grpc_auth_json_key_destruct(&json_key);
+}
+
+static void test_parse_json_key_failure_no_client_id() {
+ const char no_client_id_part3[] =
+ "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
+ "\"client_email\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
+ "com\", "
+ "\"type\": \"service_account\" }";
+ char *json_string = test_json_key_str(no_client_id_part3);
+ grpc_auth_json_key json_key =
+ grpc_auth_json_key_create_from_string(json_string);
+ GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key));
+ gpr_free(json_string);
+ grpc_auth_json_key_destruct(&json_key);
+}
+
+static void test_parse_json_key_failure_no_client_email() {
+ const char no_client_email_part3[] =
+ "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
+ "\"client_id\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
+ "com\", \"type\": \"service_account\" }";
+ char *json_string = test_json_key_str(no_client_email_part3);
+ grpc_auth_json_key json_key =
+ grpc_auth_json_key_create_from_string(json_string);
+ GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key));
+ gpr_free(json_string);
+ grpc_auth_json_key_destruct(&json_key);
+}
+
+static void test_parse_json_key_failure_no_private_key_id() {
+ const char no_private_key_id_part3[] =
+ "\"client_email\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
+ "com\", \"client_id\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
+ "com\", \"type\": \"service_account\" }";
+ char *json_string = test_json_key_str(no_private_key_id_part3);
+ grpc_auth_json_key json_key =
+ grpc_auth_json_key_create_from_string(json_string);
+ GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key));
+ gpr_free(json_string);
+ grpc_auth_json_key_destruct(&json_key);
+}
+
+static void test_parse_json_key_failure_no_private_key() {
+ const char no_private_key_json_string[] =
+ "{ \"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
+ "\"client_email\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
+ "com\", \"client_id\": "
+ "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
+ "com\", \"type\": \"service_account\" }";
+ grpc_auth_json_key json_key =
+ grpc_auth_json_key_create_from_string(no_private_key_json_string);
+ GPR_ASSERT(!grpc_auth_json_key_is_valid(&json_key));
+ grpc_auth_json_key_destruct(&json_key);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ test_parse_json_key_success();
+ test_parse_json_key_failure_bad_json();
+ test_parse_json_key_failure_no_type();
+ test_parse_json_key_failure_no_client_id();
+ test_parse_json_key_failure_no_client_email();
+ test_parse_json_key_failure_no_private_key_id();
+ test_parse_json_key_failure_no_private_key();
+ return 0;
+}