Hello community,

here is the log from the commit of package jwt_verify_lib for openSUSE:Factory 
checked in at 2019-08-06 17:27:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/jwt_verify_lib (Old)
 and      /work/SRC/openSUSE:Factory/.jwt_verify_lib.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "jwt_verify_lib"

Tue Aug  6 17:27:18 2019 rev:4 rq:721261 version:20190708

Changes:
--------
--- /work/SRC/openSUSE:Factory/jwt_verify_lib/jwt_verify_lib.changes    
2019-07-23 22:42:22.502796497 +0200
+++ /work/SRC/openSUSE:Factory/.jwt_verify_lib.new.4126/jwt_verify_lib.changes  
2019-08-06 17:27:21.520687502 +0200
@@ -1,0 +2,24 @@
+Thu Aug 01 11:20:17 UTC 2019 - [email protected]
+
+- Use OpenSSL instead of BoringSSL.
+- Update to version 20190708:
+  * Implement RS384/RS512 token verification
+  * Add tests for RS384 and RS512 tokens
+  * Harden JwkRSA verification code
+  * Reduce fuzz truncate case
+  * Fix verify_time_test
+  * one more uint64
+  * one more uint64_t
+  * change to unsigned
+  * clean struct_utils
+  * clean protobuf binding
+  * remove rapidjson
+  * fix jwks
+  * 3rd draft
+  * second draft
+  * first draft
+  * Clear SSL errors for failed verification
+- Remove patch:
+  * bazel-unbundle-dependencies.patch
+
+-------------------------------------------------------------------

Old:
----
  bazel-unbundle-dependencies.patch
  jwt_verify_lib-20181125.tar.xz

New:
----
  BUILD
  WORKSPACE
  abseil_strings.BUILD
  abseil_time.BUILD
  bsslwrapper.BUILD
  googletest.BUILD
  jwt-verify-lib-openssl-20190723.tar.xz
  jwt_verify_lib-20190708.tar.xz
  opensslcbs.BUILD
  zlib.BUILD

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ jwt_verify_lib.spec ++++++
--- /var/tmp/diff_new_pack.iuQUpj/_old  2019-08-06 17:27:22.404687310 +0200
+++ /var/tmp/diff_new_pack.iuQUpj/_new  2019-08-06 17:27:22.408687308 +0200
@@ -18,21 +18,37 @@
 
 %define sover 0
 %define libname lib%{name}%{sover}
+%define maistra_name jwt-verify-lib-openssl
+%define maistra_version 20190723
 
 Name:           jwt_verify_lib
-Version:        20181125
+Version:        20190708
 Release:        0
 Summary:        JSON Web Tokens verification library for C++
 License:        Apache-2.0
 Group:          Development/Libraries/C and C++
 Url:            https://github.com/google/%{name}
-Source:         %{name}-%{version}.tar.xz
-Patch0:         bazel-unbundle-dependencies.patch
+Source0:        %{name}-%{version}.tar.xz
+Source1:        %{maistra_name}-%{maistra_version}.tar.xz
+Source100:      WORKSPACE
+Source101:      BUILD
+Source200:      abseil_strings.BUILD
+Source201:      abseil_time.BUILD
+Source202:      bsslwrapper.BUILD
+Source203:      googletest.BUILD
+Source204:      opensslcbs.BUILD
+Source205:      zlib.BUILD
 BuildRequires:  abseil-cpp-devel
+BuildRequires:  bazel-skylib-source
 BuildRequires:  bazel0.19
-BuildRequires:  boringssl-devel
+BuildRequires:  bssl_wrapper-devel
 BuildRequires:  gcc-c++
+BuildRequires:  gmock
 BuildRequires:  gtest
+BuildRequires:  openssl-cbs-devel
+BuildRequires:  openssl-devel
+BuildRequires:  protobuf-devel
+BuildRequires:  protobuf-source
 BuildRequires:  rapidjson-devel
 ExcludeArch:    %ix86
 
@@ -62,11 +78,20 @@
 This package contains development files for jwt_verify_lib.
 
 %prep
+%setup -q -D -b 1 -n %{maistra_name}-%{maistra_version}
+
 %setup -q
-%patch0 -p1
-# BoringSSL headers are installed in /usr/include/boringssl directory to avoid
-# conflict with openssl-devel.
-find . -type f \( -name "*.h" -o -name "*.cc" \) -exec sed -i 
's/openssl/boringssl/' "{}" +
+pushd ../%{maistra_name}-%{maistra_version}
+./openssl.sh ../%{name}-%{version} SSL
+popd
+cp %{SOURCE100} .
+cp %{SOURCE101} .
+cp %{SOURCE200} .
+cp %{SOURCE201} .
+cp %{SOURCE202} .
+cp %{SOURCE203} .
+cp %{SOURCE204} .
+cp %{SOURCE205} .
 
 %build
 # TODO(mrostecki): Create a macro in bazel package.

++++++ BUILD ++++++
licenses(["notice"])  # Apache 2

package(default_visibility = ["//visibility:public"])

exports_files(["LICENSE"])

cc_library(
    name = "jwt_verify_lib",
    srcs = [
        "src/check_audience.cc",
        "src/jwks.cc",
        "src/jwt.cc",
        "src/status.cc",
        "src/struct_utils.h",
        "src/verify.cc",
    ],
    hdrs = [
        "jwt_verify_lib/check_audience.h",
        "jwt_verify_lib/jwks.h",
        "jwt_verify_lib/jwt.h",
        "jwt_verify_lib/status.h",
        "jwt_verify_lib/verify.h",
    ],
    deps = [
        "@abseil_strings//:abseil_strings",
        "@abseil_time//:abseil_time",
        "@openssl//:openssl-lib",
        "//external:protobuf",
    ],
)
++++++ WORKSPACE ++++++
local_repository(
    name = "com_google_protobuf",
    path = "/usr/src/protobuf",
)
bind(
    name = "protobuf",
    actual = "@com_google_protobuf//:protobuf",
)

local_repository(
    name = "bazel_skylib",
    path = "/usr/src/bazel-skylib",
)

new_local_repository(
    name = "openssl",
    path = "/usr/lib64/",
    build_file = "openssl.BUILD",
)

new_local_repository(
    name = "abseil_strings",
    path = "/usr/lib64/",
    build_file = "abseil_strings.BUILD",
)

new_local_repository(
    name = "abseil_time",
    path = "/usr/lib64/",
    build_file = "abseil_time.BUILD",
)

new_local_repository(
    name = "bssl_wrapper_lib",
    path = "/usr/lib64/",
    build_file = "bsslwrapper.BUILD",
)

new_local_repository(
    name = "googletest",
    path = "/usr/lib64/",
    build_file = "googletest.BUILD",
)

new_local_repository(
    name = "opensslcbs",
    path = "/usr/lib64/",
    build_file = "opensslcbs.BUILD",
)

new_local_repository(
    name = "zlib",
    path = "/usr/lib64",
    build_file = "zlib.BUILD",
)
++++++ _service ++++++
--- /var/tmp/diff_new_pack.iuQUpj/_old  2019-08-06 17:27:22.460687298 +0200
+++ /var/tmp/diff_new_pack.iuQUpj/_new  2019-08-06 17:27:22.460687298 +0200
@@ -5,7 +5,15 @@
     <param name="changesgenerate">enable</param>
     <param name="filename">jwt_verify_lib</param>
     <param name="versionformat">%cd</param>
-    <param name="revision">a1298efde49c8f2329e8c124a2389c37845cacf5</param>
+    <param name="revision">0f14d43f20381cfae0469cb2309b2e220c0f0ea3</param>
+  </service>
+  <service mode="disabled" name="tar_scm">
+    <param name="url">https://github.com/Maistra/jwt-verify-lib-openssl</param>
+    <param name="scm">git</param>
+    <param name="changesgenerate">disable</param>
+    <param name="filename">jwt-verify-lib-openssl</param>
+    <param name="versionformat">%cd</param>
+    <param name="revision">55dba200857b7c50d82336d38d556be5807d39b6</param>
   </service>
   <service mode="disabled" name="recompress">
     <param name="file">*.tar</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.iuQUpj/_old  2019-08-06 17:27:22.476687294 +0200
+++ /var/tmp/diff_new_pack.iuQUpj/_new  2019-08-06 17:27:22.480687294 +0200
@@ -1,4 +1,4 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/google/jwt_verify_lib</param>
-              <param 
name="changesrevision">0dd668acc4ebd8af9a83172464432ebe466ba5a1</param></service></servicedata>
\ No newline at end of file
+              <param 
name="changesrevision">c2a793f4c5c019199dbd7902a48fee07c252664b</param></service></servicedata>
\ No newline at end of file

++++++ abseil_strings.BUILD ++++++
licenses(["notice"])  # Apache 2

cc_library(
    name = "abseil_strings",
    hdrs = glob(["thirdparty_build/include/absl/**/*.h"]),
    copts = ["-I/usr/include/absl"],
    linkopts = [
        "-labsl_base_libbase",
        "-labsl_base_libthrow_delegate",
        "-labsl_strings_libinternal",
        "-labsl_strings_libstr_format_internal",
        "-labsl_strings_libstrings",
    ],
    visibility = ["//visibility:public"],
    linkstatic=False,
)
++++++ abseil_time.BUILD ++++++
licenses(["notice"])  # Apache 2

cc_library(
    name = "abseil_time",
    hdrs = glob(["thirdparty_build/include/absl/**/*.h"]),
    copts = ["-I/usr/include/absl"],
    linkopts = [
        "-labsl_base_libbase",
        "-labsl_base_libspinlock_wait",
        "-labsl_numeric_libint128",
        "-labsl_time_internal_cctz_libcivil_time",
        "-labsl_time_internal_cctz_libtime_zone",
        "-labsl_time_libtest_util",
        "-labsl_time_libtime",
    ],
    visibility = ["//visibility:public"],
    linkstatic=False,
)
++++++ bsslwrapper.BUILD ++++++
licenses(["notice"])  # Apache 2

cc_library(
    name = "bssl_wrapper_lib",
    hdrs = glob(["thirdparty_build/include/bssl_wrapper/**/*.h"]),
    copts = ["-I/usr/include/bssl_wrapper"],
    linkopts = [
        "-lbssl_wrapper_lib",
    ],
    visibility = ["//visibility:public"],
    linkstatic=False,
)
++++++ googletest.BUILD ++++++
licenses(["notice"])  # Apache 2

cc_library(
    name = "googletest",
    hdrs = glob([
        "thirdparty_build/include/gmock/**/*.h",
        "thirdparty_build/include/gtest/**/*.h",
    ]),
    copts = ["-I/usr/include/gtest"],
    linkopts = [
        "-lgmock",
        "-lgmock_main",
        "-lgtest",
        "-lgtest_main",
    ],
    visibility = ["//visibility:public"],
    linkstatic=False,
)
++++++ jwt_verify_lib-20181125.tar.xz -> jwt_verify_lib-20190708.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/BUILD 
new/jwt_verify_lib-20190708/BUILD
--- old/jwt_verify_lib-20181125/BUILD   2018-11-25 02:41:06.000000000 +0100
+++ new/jwt_verify_lib-20190708/BUILD   2019-07-08 18:31:22.000000000 +0200
@@ -11,6 +11,7 @@
         "src/jwks.cc",
         "src/jwt.cc",
         "src/status.cc",
+        "src/struct_utils.h",
         "src/verify.cc",
     ],
     hdrs = [
@@ -23,7 +24,7 @@
     deps = [
         "//external:abseil_strings",
         "//external:abseil_time",
-        "//external:rapidjson",
+        "//external:protobuf",
         "//external:ssl",
     ],
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/WORKSPACE 
new/jwt_verify_lib-20190708/WORKSPACE
--- old/jwt_verify_lib-20181125/WORKSPACE       2018-11-25 02:41:06.000000000 
+0100
+++ new/jwt_verify_lib-20190708/WORKSPACE       2019-07-08 18:31:22.000000000 
+0200
@@ -2,12 +2,12 @@
     "//:repositories.bzl",
     "boringssl_repositories",
     "googletest_repositories",
-    "rapidjson_repositories",
     "abseil_repositories",
+    "protobuf_repositories",
 )
 
 boringssl_repositories()
 googletest_repositories()
-rapidjson_repositories()
 abseil_repositories()
+protobuf_repositories()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/jwt_verify_lib/jwt.h 
new/jwt_verify_lib-20190708/jwt_verify_lib/jwt.h
--- old/jwt_verify_lib-20181125/jwt_verify_lib/jwt.h    2018-11-25 
02:41:06.000000000 +0100
+++ new/jwt_verify_lib-20190708/jwt_verify_lib/jwt.h    2019-07-08 
18:31:22.000000000 +0200
@@ -17,7 +17,7 @@
 #include <string>
 #include <vector>
 
-#include "rapidjson/document.h"
+#include "google/protobuf/struct.pb.h"
 
 #include "jwt_verify_lib/status.h"
 
@@ -35,15 +35,15 @@
   std::string header_str_;
   // header base64_url encoded
   std::string header_str_base64url_;
-  // header JSON object
-  rapidjson::Document header_json_;
+  // header in Struct protobuf
+  ::google::protobuf::Struct header_pb_;
 
   // payload string
   std::string payload_str_;
   // payload base64_url encoded
   std::string payload_str_base64url_;
-  // payload JSON object
-  rapidjson::Document payload_json_;
+  // payload in Struct protobuf
+  ::google::protobuf::Struct payload_pb_;
   // signature string
   std::string signature_;
   // alg
@@ -57,11 +57,11 @@
   // sub
   std::string sub_;
   // issued at
-  int64_t iat_ = 0;
+  uint64_t iat_ = 0;
   // not before
-  int64_t nbf_ = 0;
+  uint64_t nbf_ = 0;
   // expiration
-  int64_t exp_ = 0;
+  uint64_t exp_ = 0;
   // JWT ID
   std::string jti_;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/jwt_verify_lib/verify.h 
new/jwt_verify_lib-20190708/jwt_verify_lib/verify.h
--- old/jwt_verify_lib-20181125/jwt_verify_lib/verify.h 2018-11-25 
02:41:06.000000000 +0100
+++ new/jwt_verify_lib-20190708/jwt_verify_lib/verify.h 2019-07-08 
18:31:22.000000000 +0200
@@ -42,7 +42,7 @@
  * @param now is the number of seconds since the unix epoch
  * @return the verification status
  */
-Status verifyJwt(const Jwt& jwt, const Jwks& jwks, int64_t now);
+Status verifyJwt(const Jwt& jwt, const Jwks& jwks, uint64_t now);
 
 /**
  * This function verifies JWT signature is valid, that it has not expired
@@ -74,7 +74,7 @@
  * @return the verification status
  */
 Status verifyJwt(const Jwt& jwt, const Jwks& jwks,
-                 const std::vector<std::string>& audiences, int64_t now);
+                 const std::vector<std::string>& audiences, uint64_t now);
 
 }  // namespace jwt_verify
 }  // namespace google
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/repositories.bzl 
new/jwt_verify_lib-20190708/repositories.bzl
--- old/jwt_verify_lib-20181125/repositories.bzl        2018-11-25 
02:41:06.000000000 +0100
+++ new/jwt_verify_lib-20190708/repositories.bzl        2019-07-08 
18:31:22.000000000 +0200
@@ -3,7 +3,7 @@
 BORINGSSL_COMMIT = "9df0c47bc034d60d73d216cd0e090707b3fbea58"  # same as Envoy
 BORINGSSL_SHA256 = 
"86d0614bb9e6cb4e6444b83bb1f031755eff4bbe52cd8f4cd5720bb84a7ea9f5"
 
-def boringssl_repositories(bind=True):
+def boringssl_repositories(bind = True):
     http_archive(
         name = "boringssl",
         strip_prefix = "boringssl-" + BORINGSSL_COMMIT,
@@ -20,7 +20,7 @@
 GOOGLETEST_COMMIT = "43863938377a9ea1399c0596269e0890b5c5515a"
 GOOGLETEST_SHA256 = 
"7c8ece456ad588c30160429498e108e2df6f42a30888b3ec0abf5d9792d9d3a0"
 
-def googletest_repositories(bind=True):
+def googletest_repositories(bind = True):
     http_archive(
         name = "googletest_git",
         build_file = "//:googletest.BUILD",
@@ -45,28 +45,10 @@
             actual = "@googletest_git//:googletest_prod",
         )
 
-RAPIDJSON_COMMIT = "f54b0e47a08782a6131cc3d60f94d038fa6e0a51"
-RAPIDJSON_SHA256 = 
"4a76453d36770c9628d7d175a2e9baccbfbd2169ced44f0cb72e86c5f5f2f7cd"
-
-def rapidjson_repositories(bind=True):
-    http_archive(
-        name = "com_github_tencent_rapidjson",
-        build_file = "//:rapidjson.BUILD",
-        strip_prefix = "rapidjson-" + RAPIDJSON_COMMIT,
-        url = "https://github.com/tencent/rapidjson/archive/"; + 
RAPIDJSON_COMMIT + ".tar.gz",
-        sha256 = RAPIDJSON_SHA256,
-    )
-
-    if bind:
-        native.bind(
-            name = "rapidjson",
-            actual = "@com_github_tencent_rapidjson//:rapidjson",
-        )
-
 ABSEIL_COMMIT = "cc8dcd307b76a575d2e3e0958a4fe4c7193c2f68"  # same as Envoy
 ABSEIL_SHA256 = 
"e35082e88b9da04f4d68094c05ba112502a5063712f3021adfa465306d238c76"
 
-def abseil_repositories(bind=True):
+def abseil_repositories(bind = True):
     http_archive(
         name = "com_google_absl",
         strip_prefix = "abseil-cpp-" + ABSEIL_COMMIT,
@@ -88,9 +70,38 @@
 CCTZ_COMMIT = "e19879df3a14791b7d483c359c4acd6b2a1cd96b"
 CCTZ_SHA256 = 
"35d2c6cf7ddef1cf7c1bb054bdf2e8d7778242f6d199591a834c14d224b80c39"
 
-def _cctz_repositories(bind=True):
+def _cctz_repositories(bind = True):
     http_archive(
         name = "com_googlesource_code_cctz",
         url = "https://github.com/google/cctz/archive/"; + CCTZ_COMMIT + 
".tar.gz",
         sha256 = CCTZ_SHA256,
-    )
\ No newline at end of file
+    )
+
+BAZEL_SKYLIB_RELEASE = "0.5.0"
+BAZEL_SKYLIB_SHA256 = 
"b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f"
+
+def _bazel_skylib_repositories():
+    http_archive(
+        name = "bazel_skylib",
+        sha256 = BAZEL_SKYLIB_SHA256,
+        strip_prefix = "bazel-skylib-" + BAZEL_SKYLIB_RELEASE,
+        url = "https://github.com/bazelbuild/bazel-skylib/archive/"; + 
BAZEL_SKYLIB_RELEASE + ".tar.gz",
+    )
+
+PROTOBUF_COMMIT = "fa252ec2a54acb24ddc87d48fed1ecfd458445fd"
+PROTOBUF_SHA256 = 
"3d610ac90f8fa16e12490088605c248b85fdaf23114ce4b3605cdf81f7823604"
+
+def protobuf_repositories(bind = True):
+    _bazel_skylib_repositories()
+    http_archive(
+        name = "com_google_protobuf",
+        strip_prefix = "protobuf-" + PROTOBUF_COMMIT,
+        url = "https://github.com/protocolbuffers/protobuf/archive/"; + 
PROTOBUF_COMMIT + ".tar.gz",
+        sha256 = PROTOBUF_SHA256,
+    )
+
+    if bind:
+        native.bind(
+            name = "protobuf",
+            actual = "@com_google_protobuf//:protobuf",
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/src/jwks.cc 
new/jwt_verify_lib-20190708/src/jwks.cc
--- old/jwt_verify_lib-20181125/src/jwks.cc     2018-11-25 02:41:06.000000000 
+0100
+++ new/jwt_verify_lib-20190708/src/jwks.cc     2019-07-08 18:31:22.000000000 
+0200
@@ -15,10 +15,11 @@
 #include <assert.h>
 #include <iostream>
 
-#include "jwt_verify_lib/jwks.h"
-
 #include "absl/strings/escaping.h"
-#include "rapidjson/document.h"
+#include "google/protobuf/struct.pb.h"
+#include "google/protobuf/util/json_util.h"
+#include "jwt_verify_lib/jwks.h"
+#include "src/struct_utils.h"
 
 #include "openssl/bn.h"
 #include "openssl/ecdsa.h"
@@ -134,100 +135,96 @@
   }
 };
 
-Status extractJwkFromJwkRSA(const rapidjson::Value& jwk_json,
+Status extractJwkFromJwkRSA(const ::google::protobuf::Struct& jwk_pb,
                             Jwks::Pubkey* jwk) {
   if (jwk->alg_specified_ &&
       (jwk->alg_.size() < 2 || jwk->alg_.compare(0, 2, "RS") != 0)) {
     return Status::JwksRSAKeyBadAlg;
   }
 
-  if (!jwk_json.HasMember("n")) {
+  StructUtils jwk_getter(jwk_pb);
+  std::string n_str;
+  auto code = jwk_getter.GetString("n", &n_str);
+  if (code == StructUtils::MISSING) {
     return Status::JwksRSAKeyMissingN;
   }
-  const auto& n_value = jwk_json["n"];
-  if (!n_value.IsString()) {
+  if (code == StructUtils::WRONG_TYPE) {
     return Status::JwksRSAKeyBadN;
   }
-  std::string n_str = n_value.GetString();
 
-  if (!jwk_json.HasMember("e")) {
+  std::string e_str;
+  code = jwk_getter.GetString("e", &e_str);
+  if (code == StructUtils::MISSING) {
     return Status::JwksRSAKeyMissingE;
   }
-  const auto& e_value = jwk_json["e"];
-  if (!e_value.IsString()) {
+  if (code == StructUtils::WRONG_TYPE) {
     return Status::JwksRSAKeyBadE;
   }
-  std::string e_str = e_value.GetString();
 
   EvpPkeyGetter e;
   jwk->evp_pkey_ = e.createEvpPkeyFromJwkRSA(n_str, e_str);
   return e.getStatus();
 }
 
-Status extractJwkFromJwkEC(const rapidjson::Value& jwk_json,
+Status extractJwkFromJwkEC(const ::google::protobuf::Struct& jwk_pb,
                            Jwks::Pubkey* jwk) {
   if (jwk->alg_specified_ && jwk->alg_ != "ES256") {
     return Status::JwksECKeyBadAlg;
   }
 
-  if (!jwk_json.HasMember("x")) {
+  StructUtils jwk_getter(jwk_pb);
+  std::string x_str;
+  auto code = jwk_getter.GetString("x", &x_str);
+  if (code == StructUtils::MISSING) {
     return Status::JwksECKeyMissingX;
   }
-  const auto& x_value = jwk_json["x"];
-  if (!x_value.IsString()) {
+  if (code == StructUtils::WRONG_TYPE) {
     return Status::JwksECKeyBadX;
   }
-  std::string x_str = x_value.GetString();
 
-  if (!jwk_json.HasMember("y")) {
+  std::string y_str;
+  code = jwk_getter.GetString("y", &y_str);
+  if (code == StructUtils::MISSING) {
     return Status::JwksECKeyMissingY;
   }
-  const auto& y_value = jwk_json["y"];
-  if (!y_value.IsString()) {
+  if (code == StructUtils::WRONG_TYPE) {
     return Status::JwksECKeyBadY;
   }
-  std::string y_str = y_value.GetString();
 
   EvpPkeyGetter e;
   jwk->ec_key_ = e.createEcKeyFromJwkEC(x_str, y_str);
   return e.getStatus();
 }
 
-Status extractJwk(const rapidjson::Value& jwk_json, Jwks::Pubkey* jwk) {
+Status extractJwk(const ::google::protobuf::Struct& jwk_pb, Jwks::Pubkey* jwk) 
{
+  StructUtils jwk_getter(jwk_pb);
   // Check "kty" parameter, it should exist.
   // https://tools.ietf.org/html/rfc7517#section-4.1
-  if (!jwk_json.HasMember("kty")) {
+  auto code = jwk_getter.GetString("kty", &jwk->kty_);
+  if (code == StructUtils::MISSING) {
     return Status::JwksMissingKty;
   }
-  const auto& kty_value = jwk_json["kty"];
-  if (!kty_value.IsString()) {
+  if (code == StructUtils::WRONG_TYPE) {
     return Status::JwksBadKty;
   }
-  jwk->kty_ = kty_value.GetString();
 
   // "kid" and "alg" are optional, if they do not exist, set them to empty.
   // https://tools.ietf.org/html/rfc7517#page-8
-  if (jwk_json.HasMember("kid")) {
-    const auto& kid_value = jwk_json["kid"];
-    if (kid_value.IsString()) {
-      jwk->kid_ = kid_value.GetString();
-      jwk->kid_specified_ = true;
-    }
-  }
-  if (jwk_json.HasMember("alg")) {
-    const auto& alg_value = jwk_json["alg"];
-    if (alg_value.IsString()) {
-      jwk->alg_ = alg_value.GetString();
-      jwk->alg_specified_ = true;
-    }
+  code = jwk_getter.GetString("kid", &jwk->kid_);
+  if (code == StructUtils::OK) {
+    jwk->kid_specified_ = true;
+  }
+  code = jwk_getter.GetString("alg", &jwk->alg_);
+  if (code == StructUtils::OK) {
+    jwk->alg_specified_ = true;
   }
 
   // Extract public key according to "kty" value.
   // https://tools.ietf.org/html/rfc7518#section-6.1
   if (jwk->kty_ == "EC") {
-    return extractJwkFromJwkEC(jwk_json, jwk);
+    return extractJwkFromJwkEC(jwk_pb, jwk);
   } else if (jwk->kty_ == "RSA") {
-    return extractJwkFromJwkRSA(jwk_json, jwk);
+    return extractJwkFromJwkRSA(jwk_pb, jwk);
   }
   return Status::JwksNotImplementedKty;
 }
@@ -262,28 +259,35 @@
   }
 }
 
-void Jwks::createFromJwksCore(const std::string& pkey_jwks) {
+void Jwks::createFromJwksCore(const std::string& jwks_json) {
   keys_.clear();
 
-  rapidjson::Document jwks_json;
-  if (jwks_json.Parse(pkey_jwks.c_str()).HasParseError()) {
+  ::google::protobuf::util::JsonParseOptions options;
+  ::google::protobuf::Struct jwks_pb;
+  const auto status = ::google::protobuf::util::JsonStringToMessage(
+      jwks_json, &jwks_pb, options);
+  if (!status.ok()) {
     updateStatus(Status::JwksParseError);
     return;
   }
 
-  if (!jwks_json.HasMember("keys")) {
+  const auto& fields = jwks_pb.fields();
+  const auto keys_it = fields.find("keys");
+  if (keys_it == fields.end()) {
     updateStatus(Status::JwksNoKeys);
     return;
   }
-  const auto& keys_value = jwks_json["keys"];
-  if (!keys_value.IsArray()) {
+  if (keys_it->second.kind_case() != google::protobuf::Value::kListValue) {
     updateStatus(Status::JwksBadKeys);
     return;
   }
 
-  for (auto key_it = keys_value.Begin(); key_it != keys_value.End(); ++key_it) 
{
+  for (const auto& key_value : keys_it->second.list_value().values()) {
+    if (key_value.kind_case() != ::google::protobuf::Value::kStructValue) {
+      continue;
+    }
     PubkeyPtr key_ptr(new Pubkey());
-    Status status = extractJwk(*key_it, key_ptr.get());
+    Status status = extractJwk(key_value.struct_value(), key_ptr.get());
     if (status == Status::Ok) {
       keys_.push_back(std::move(key_ptr));
     } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/src/jwks_test.cc 
new/jwt_verify_lib-20190708/src/jwks_test.cc
--- old/jwt_verify_lib-20181125/src/jwks_test.cc        2018-11-25 
02:41:06.000000000 +0100
+++ new/jwt_verify_lib-20190708/src/jwks_test.cc        2019-07-08 
18:31:22.000000000 +0200
@@ -267,6 +267,55 @@
   EXPECT_EQ(jwks->getStatus(), Status::JwksRsaParseError);
 }
 
+TEST(JwksParseTest, JwksRSAInvalidN) {
+  const std::string BadPublicKeyRSA =
+      "{\n"
+      " \"keys\": [\n"
+      " {\n"
+      " \"alg\": \"RS256\",\n"
+      " \"kty\": \"RSA\",\n"
+      " \"use\": \"sig\",\n"
+      " \"x5c\": "
+      
"[\"MIIDjjCCAnYCCQDM2dGMrJDL3TANBgkqhkiG9w0BAQUFADCBiDEVMBMGA1UEAwwMd3d3L"
+      
"mRlbGwuY29tMQ0wCwYDVQQKDARkZWxsMQ0wCwYDVQQLDARkZWxsMRIwEAYDVQQHDAlCYW5nY"
+      
"WxvcmUxEjAQBgNVBAgMCUthcm5hdGFrYTELMAkGA1UEBhMCSU4xHDAaBgkqhkiG9w0BCQEWD"
+      
"WFiaGlAZGVsbC5jb20wHhcNMTkwNjI1MDcwNjM1WhcNMjAwNjI0MDcwNjM1WjCBiDEVMBMGA"
+      
"1UEAwwMd3d3LmRlbGwuY29tMQ0wCwYDVQQKDARkZWxsMQ0wCwYDVQQLDARkZWxsMRIwEAYDV"
+      
"QQHDAlCYW5nYWxvcmUxEjAQBgNVBAgMCUthcm5hdGFrYTELMAkGA1UEBhMCSU4xHDAaBgkqh"
+      
"kiG9w0BCQEWDWFiaGlAZGVsbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBA"
+      "QDlE7W15NCXoIZX+"
+      
"uE7HF0LTnfgBpaqoYyQFDmVUNEd0WWV9nX04c3iyxZSpoTsoUZktNd0CUyC8oVRg2xxdPxA2"
+      
"aRVpNMwsDkuDnOZPNZZCS64QmMD7V5ebSAi4vQ7LH6zo9DCVwjzW10ZOZ3WHAyoKuNVGeb5w"
+      "2+xDQM1mFqApy6KB7M/b3KG7cqpZfPn9Ebd1Uyk+8WY/"
+      "IxJvb7EHt06Z+8b3F+LkRp7UI4ykkVkl3XaiBlG56ZyHfvH6R5Jy+"
+      
"8P0vl4wtX86N6MS48TZPhGAoo2KwWsOEGxve005ZK6LkHwxMsOD98yvLM7AG0SBxVF8O8KeZ"
+      "/nbTP1oVSq6aEFAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAGEhT6xuZqyZb/"
+      "K6aI61RYy4tnR92d97H+zcL9t9/"
+      "8FyH3qIAjIM9+qdr7dLLnVcNMmwiKzZpsBywno72z5gG4l6/TicBIJfI2BaG9JVdU3/"
+      "wscPlqazwI/"
+      "d1LvIkWSzrFQ2VdTPSYactPzGWddlx9QKU9cIKcNPcWdg0S0q1Khu8kejpJ+"
+      "EUtSMc8OonFV99r1juFzVPtwGihuc6R7T/"
+      "GnWgYLmhoCCaQKdLWn7FIyQH2WZ10CI6as+"
+      
"zKkylDkVnbsJYFabvbgRrNNl4RGXXm5D0lk9cwo1Srd28wEhi35b8zb1p0eTamS6qTpjHtc6"
+      "DpgZK3MavFVdaFfR9bEYpHc=\"],\n"
+      " \"n\": "
+      "\"5RO1teTQl6CGV/"
+      
"rhOxxdC0534AaWqqGMkBQ5lVDRHdFllfZ19OHN4ssWUqaE7KFGZLTXdAlMgvKFUYNscXT8QN"
+      "mkVaTTMLA5Lg5zmTzWWQkuuEJjA+1eXm0gIuL0Oyx+s6PQwlcI81tdGTmd1hwMqCrjVRnm+"
+      "cNvsQ0DNZhagKcuigezP29yhu3KqWXz5/"
+      "RG3dVMpPvFmPyMSb2+xB7dOmfvG9xfi5Eae1COMpJFZJd12ogZRuemch37x+"
+      "keScvvD9L5eMLV/OjejEuPE2T4RgKKNisFrDhBsb3tNOWSui5B8MTLDg/"
+      "fMryzOwBtEgcVRfDvCnmf520z9aFUqumhBQ\",\n"
+      " \"e\": \"AQAB\",\n"
+      " \"kid\": \"F46BB2F600BF3BBB53A324F12B290846\",\n"
+      " \"x5t\": \"F46BB2F600BF3BBB53A324F12B290846\"\n"
+      " }\n"
+      " ]\n"
+      "}";
+  auto jwks = Jwks::createFrom(BadPublicKeyRSA, Jwks::JWKS);
+  EXPECT_EQ(jwks->getStatus(), Status::JwksRsaParseError);
+}
+
 }  // namespace
 }  // namespace jwt_verify
 }  // namespace google
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/src/jwt.cc 
new/jwt_verify_lib-20190708/src/jwt.cc
--- old/jwt_verify_lib-20181125/src/jwt.cc      2018-11-25 02:41:06.000000000 
+0100
+++ new/jwt_verify_lib-20190708/src/jwt.cc      2019-07-08 18:31:22.000000000 
+0200
@@ -16,16 +16,13 @@
 
 #include "absl/strings/escaping.h"
 #include "absl/strings/str_split.h"
+#include "google/protobuf/util/json_util.h"
 #include "jwt_verify_lib/jwt.h"
+#include "src/struct_utils.h"
 
 namespace google {
 namespace jwt_verify {
 
-// Maximum Jwt size to prevent JSON parser attack:
-// stack overflow crash if a document contains heavily nested arrays.
-// [[... repeat 100,000 times ... [[[0]]]]]]]]]]]]]]]]]]]]]]]]]]]..
-const size_t kMaxJwtSize = 8096;
-
 Jwt::Jwt(const Jwt& instance) { *this = instance; }
 
 Jwt& Jwt::operator=(const Jwt& rhs) {
@@ -34,9 +31,6 @@
 }
 
 Status Jwt::parseFromString(const std::string& jwt) {
-  if (jwt.size() >= kMaxJwtSize) {
-    return Status::JwtBadFormat;
-  }
   // jwt must have exactly 2 dots
   if (std::count(jwt.begin(), jwt.end(), '.') != 2) {
     return Status::JwtBadFormat;
@@ -54,26 +48,27 @@
     return Status::JwtHeaderParseError;
   }
 
-  if (header_json_.Parse(header_str_.c_str()).HasParseError()) {
+  ::google::protobuf::util::JsonParseOptions options;
+  const auto header_status = ::google::protobuf::util::JsonStringToMessage(
+      header_str_, &header_pb_, options);
+  if (!header_status.ok()) {
     return Status::JwtHeaderParseError;
   }
 
+  StructUtils header_getter(header_pb_);
   // Header should contain "alg" and should be a string.
-  if (!header_json_.HasMember("alg") || !header_json_["alg"].IsString()) {
+  if (header_getter.GetString("alg", &alg_) != StructUtils::OK) {
     return Status::JwtHeaderBadAlg;
   }
-  alg_ = header_json_["alg"].GetString();
 
-  if (alg_ != "RS256" && alg_ != "ES256") {
+  if (alg_ != "RS256" && alg_ != "ES256" && alg_ != "RS384" &&
+      alg_ != "RS512") {
     return Status::JwtHeaderNotImplementedAlg;
   }
 
   // Header may contain "kid", should be a string if exists.
-  if (header_json_.HasMember("kid")) {
-    if (!header_json_["kid"].IsString()) {
-      return Status::JwtHeaderBadKid;
-    }
-    kid_ = header_json_["kid"].GetString();
+  if (header_getter.GetString("kid", &kid_) == StructUtils::WRONG_TYPE) {
+    return Status::JwtHeaderBadKid;
   }
 
   // Parse payload json
@@ -82,76 +77,39 @@
     return Status::JwtPayloadParseError;
   }
 
-  if (payload_json_.Parse(payload_str_.c_str()).HasParseError()) {
+  const auto payload_status = ::google::protobuf::util::JsonStringToMessage(
+      payload_str_, &payload_pb_, options);
+  if (!payload_status.ok()) {
     return Status::JwtPayloadParseError;
   }
 
-  if (payload_json_.HasMember("iss")) {
-    if (payload_json_["iss"].IsString()) {
-      iss_ = payload_json_["iss"].GetString();
-    } else {
-      return Status::JwtPayloadParseError;
-    }
-  }
-  if (payload_json_.HasMember("sub")) {
-    if (payload_json_["sub"].IsString()) {
-      sub_ = payload_json_["sub"].GetString();
-    } else {
-      return Status::JwtPayloadParseError;
-    }
-  }
-  if (payload_json_.HasMember("iat")) {
-    if (payload_json_["iat"].IsInt64()) {
-      iat_ = payload_json_["iat"].GetInt64();
-    } else {
-      return Status::JwtPayloadParseError;
-    }
-  } else {
-    iat_ = 0;
-  }
-  if (payload_json_.HasMember("nbf")) {
-    if (payload_json_["nbf"].IsInt64()) {
-      nbf_ = payload_json_["nbf"].GetInt64();
-    } else {
-      return Status::JwtPayloadParseError;
-    }
-  } else {
-    nbf_ = 0;
-  }
-  if (payload_json_.HasMember("exp")) {
-    if (payload_json_["exp"].IsInt64()) {
-      exp_ = payload_json_["exp"].GetInt64();
-    } else {
-      return Status::JwtPayloadParseError;
-    }
-  } else {
-    exp_ = 0;
-  }
-  if (payload_json_.HasMember("jti")) {
-    if (payload_json_["jti"].IsString()) {
-      jti_ = payload_json_["jti"].GetString();
-    } else {
-      return Status::JwtPayloadParseError;
-    }
+  StructUtils payload_getter(payload_pb_);
+  if (payload_getter.GetString("iss", &iss_) == StructUtils::WRONG_TYPE) {
+    return Status::JwtPayloadParseError;
+  }
+  if (payload_getter.GetString("sub", &sub_) == StructUtils::WRONG_TYPE) {
+    return Status::JwtPayloadParseError;
+  }
+
+  if (payload_getter.GetInt64("iat", &iat_) == StructUtils::WRONG_TYPE) {
+    return Status::JwtPayloadParseError;
+  }
+  if (payload_getter.GetInt64("nbf", &nbf_) == StructUtils::WRONG_TYPE) {
+    return Status::JwtPayloadParseError;
+  }
+  if (payload_getter.GetInt64("exp", &exp_) == StructUtils::WRONG_TYPE) {
+    return Status::JwtPayloadParseError;
+  }
+
+  if (payload_getter.GetString("jti", &jti_) == StructUtils::WRONG_TYPE) {
+    return Status::JwtPayloadParseError;
   }
 
   // "aud" can be either string array or string.
   // Try as string array, read it as empty array if doesn't exist.
-  if (payload_json_.HasMember("aud")) {
-    const auto& aud_value = payload_json_["aud"];
-    if (aud_value.IsArray()) {
-      for (auto it = aud_value.Begin(); it != aud_value.End(); ++it) {
-        if (it->IsString()) {
-          audiences_.push_back(it->GetString());
-        } else {
-          return Status::JwtPayloadParseError;
-        }
-      }
-    } else if (aud_value.IsString()) {
-      audiences_.push_back(aud_value.GetString());
-    } else {
-      return Status::JwtPayloadParseError;
-    }
+  if (payload_getter.GetStringList("aud", &audiences_) ==
+      StructUtils::WRONG_TYPE) {
+    return Status::JwtPayloadParseError;
   }
 
   // Set up signature
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/src/jwt_test.cc 
new/jwt_verify_lib-20190708/src/jwt_test.cc
--- old/jwt_verify_lib-20181125/src/jwt_test.cc 2018-11-25 02:41:06.000000000 
+0100
+++ new/jwt_verify_lib-20190708/src/jwt_test.cc 2019-07-08 18:31:22.000000000 
+0200
@@ -13,7 +13,11 @@
 // limitations under the License.
 
 #include "jwt_verify_lib/jwt.h"
+#include "google/protobuf/util/message_differencer.h"
 #include "gtest/gtest.h"
+#include "src/struct_utils.h"
+
+using google::protobuf::util::MessageDifferencer;
 
 #include <functional>
 #include <vector>
@@ -43,19 +47,25 @@
   EXPECT_EQ(jwt.alg_, "RS256");
   EXPECT_EQ(jwt.kid_, "");
   EXPECT_EQ(jwt.iss_, "https://example.com";);
-  EXPECT_TRUE(jwt.header_json_.HasMember("customheader"));
-  EXPECT_TRUE(jwt.header_json_["customheader"].IsString());
-  EXPECT_EQ(jwt.header_json_["customheader"].GetString(), std::string("abc"));
   EXPECT_EQ(jwt.sub_, "[email protected]");
   EXPECT_EQ(jwt.audiences_, std::vector<std::string>());
   EXPECT_EQ(jwt.iat_, 1501281000);
   EXPECT_EQ(jwt.nbf_, 1501281000);
   EXPECT_EQ(jwt.exp_, 1501281058);
   EXPECT_EQ(jwt.jti_, std::string("identity"));
-  EXPECT_TRUE(jwt.payload_json_.HasMember("custompayload"));
-  EXPECT_TRUE(jwt.payload_json_["custompayload"].IsInt());
-  EXPECT_EQ(jwt.payload_json_["custompayload"].GetInt(), 1234);
   EXPECT_EQ(jwt.signature_, "Signature");
+
+  StructUtils header_getter(jwt.header_pb_);
+  std::string str_value;
+  EXPECT_EQ(header_getter.GetString("customheader", &str_value),
+            StructUtils::OK);
+  EXPECT_EQ(str_value, std::string("abc"));
+
+  StructUtils payload_getter(jwt.payload_pb_);
+  uint64_t int_value;
+  EXPECT_EQ(payload_getter.GetInt64("custompayload", &int_value),
+            StructUtils::OK);
+  EXPECT_EQ(int_value, 1234);
 }
 
 TEST(JwtParseTest, Copy) {
@@ -81,8 +91,10 @@
     EXPECT_EQ(ref.exp_, original.exp_);
     EXPECT_EQ(ref.jti_, original.jti_);
     EXPECT_EQ(ref.signature_, original.signature_);
-    EXPECT_EQ(ref.header_json_, original.header_json_);
-    EXPECT_EQ(ref.payload_json_, original.payload_json_);
+    EXPECT_TRUE(
+        MessageDifferencer::Equals(ref.header_pb_, original.header_pb_));
+    EXPECT_TRUE(
+        MessageDifferencer::Equals(ref.payload_pb_, original.payload_pb_));
   }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/src/struct_utils.h 
new/jwt_verify_lib-20190708/src/struct_utils.h
--- old/jwt_verify_lib-20181125/src/struct_utils.h      1970-01-01 
01:00:00.000000000 +0100
+++ new/jwt_verify_lib-20190708/src/struct_utils.h      2019-07-08 
18:31:22.000000000 +0200
@@ -0,0 +1,90 @@
+// Copyright 2018 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.#pragma once
+
+#pragma once
+
+#include "google/protobuf/struct.pb.h"
+
+namespace google {
+namespace jwt_verify {
+
+class StructUtils {
+ public:
+  StructUtils(const ::google::protobuf::Struct& struct_pb)
+      : struct_pb_(struct_pb) {}
+
+  enum FindResult {
+    OK = 0,
+    MISSING,
+    WRONG_TYPE,
+  };
+
+  FindResult GetString(const std::string& name, std::string* value) {
+    const auto& fields = struct_pb_.fields();
+    const auto it = fields.find(name);
+    if (it == fields.end()) {
+      return MISSING;
+    }
+    if (it->second.kind_case() != google::protobuf::Value::kStringValue) {
+      return WRONG_TYPE;
+    }
+    *value = it->second.string_value();
+    return OK;
+  }
+
+  FindResult GetInt64(const std::string& name, uint64_t* value) {
+    const auto& fields = struct_pb_.fields();
+    const auto it = fields.find(name);
+    if (it == fields.end()) {
+      return MISSING;
+    }
+    if (it->second.kind_case() != google::protobuf::Value::kNumberValue) {
+      return WRONG_TYPE;
+    }
+    *value = static_cast<uint64_t>(it->second.number_value());
+    return OK;
+  }
+
+  // Get string or list of string, designed to get "aud" field
+  // "aud" can be either string array or string.
+  // Try as string array, read it as empty array if doesn't exist.
+  FindResult GetStringList(const std::string& name,
+                           std::vector<std::string>* list) {
+    const auto& fields = struct_pb_.fields();
+    const auto it = fields.find(name);
+    if (it == fields.end()) {
+      return MISSING;
+    }
+    if (it->second.kind_case() == google::protobuf::Value::kStringValue) {
+      list->push_back(it->second.string_value());
+      return OK;
+    }
+    if (it->second.kind_case() == google::protobuf::Value::kListValue) {
+      for (const auto& v : it->second.list_value().values()) {
+        if (v.kind_case() != google::protobuf::Value::kStringValue) {
+          return WRONG_TYPE;
+        }
+        list->push_back(v.string_value());
+      }
+      return OK;
+    }
+    return WRONG_TYPE;
+  }
+
+ private:
+  const ::google::protobuf::Struct& struct_pb_;
+};
+
+}  // namespace jwt_verify
+}  // namespace google
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/src/test_common.h 
new/jwt_verify_lib-20190708/src/test_common.h
--- old/jwt_verify_lib-20181125/src/test_common.h       2018-11-25 
02:41:06.000000000 +0100
+++ new/jwt_verify_lib-20190708/src/test_common.h       2019-07-08 
18:31:22.000000000 +0200
@@ -37,12 +37,10 @@
   }
 
   // truncate bytes
-  for (size_t pos = 0; pos < jwt.signature_.size(); ++pos) {
-    for (size_t count = 1; count < jwt.signature_.size() - pos; ++count) {
-      Jwt fuzz_jwt(jwt);
-      fuzz_jwt.signature_ = jwt.signature_.substr(pos, count);
-      test_fn(fuzz_jwt);
-    }
+  for (size_t count = 1; count < jwt.signature_.size(); ++count) {
+    Jwt fuzz_jwt(jwt);
+    fuzz_jwt.signature_ = jwt.signature_.substr(0, count);
+    test_fn(fuzz_jwt);
   }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/src/verify.cc 
new/jwt_verify_lib-20190708/src/verify.cc
--- old/jwt_verify_lib-20181125/src/verify.cc   2018-11-25 02:41:06.000000000 
+0100
+++ new/jwt_verify_lib-20190708/src/verify.cc   2019-07-08 18:31:22.000000000 
+0200
@@ -19,6 +19,7 @@
 
 #include "openssl/bn.h"
 #include "openssl/ecdsa.h"
+#include "openssl/err.h"
 #include "openssl/evp.h"
 #include "openssl/rsa.h"
 #include "openssl/sha.h"
@@ -41,9 +42,16 @@
   }
   bssl::UniquePtr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_create());
 
-  EVP_DigestVerifyInit(md_ctx.get(), nullptr, md, nullptr, key);
-  EVP_DigestVerifyUpdate(md_ctx.get(), signed_data, signed_data_len);
-  return (EVP_DigestVerifyFinal(md_ctx.get(), signature, signature_len) == 1);
+  if (EVP_DigestVerifyInit(md_ctx.get(), nullptr, md, nullptr, key) == 1) {
+    if (EVP_DigestVerifyUpdate(md_ctx.get(), signed_data, signed_data_len) ==
+        1) {
+      if (EVP_DigestVerifyFinal(md_ctx.get(), signature, signature_len) == 1) {
+        return true;
+      }
+    }
+  }
+  ERR_clear_error();
+  return false;
 }
 
 bool verifySignatureRSA(EVP_PKEY* key, const EVP_MD* md,
@@ -76,8 +84,12 @@
       BN_bin2bn(signature + 32, 32, ecdsa_sig->s) == nullptr) {
     return false;
   }
-  return (ECDSA_do_verify(digest, SHA256_DIGEST_LENGTH, ecdsa_sig.get(), key) 
==
-          1);
+  if (ECDSA_do_verify(digest, SHA256_DIGEST_LENGTH, ecdsa_sig.get(), key) ==
+      1) {
+    return true;
+  }
+  ERR_clear_error();
+  return false;
 }
 
 bool verifySignatureEC(EC_KEY* key, absl::string_view signature,
@@ -92,7 +104,7 @@
   return verifyJwt(jwt, jwks, absl::ToUnixSeconds(absl::Now()));
 }
 
-Status verifyJwt(const Jwt& jwt, const Jwks& jwks, int64_t now) {
+Status verifyJwt(const Jwt& jwt, const Jwks& jwks, uint64_t now) {
   // First check that the JWT has not expired (exp) and is active (nbf).
   if (now < jwt.nbf_) {
     return Status::JwtNotYetValid;
@@ -123,11 +135,22 @@
         verifySignatureEC(jwk->ec_key_.get(), jwt.signature_, signed_data)) {
       // Verification succeeded.
       return Status::Ok;
-    } else if ((jwk->pem_format_ || jwk->kty_ == "RSA") &&
-               verifySignatureRSA(jwk->evp_pkey_.get(), EVP_sha256(),
-                                  jwt.signature_, signed_data)) {
-      // Verification succeeded.
-      return Status::Ok;
+    } else if (jwk->pem_format_ || jwk->kty_ == "RSA") {
+      const EVP_MD* md;
+      if (jwt.alg_ == "RS384") {
+        md = EVP_sha384();
+      } else if (jwt.alg_ == "RS512") {
+        md = EVP_sha512();
+      } else {
+        // default to SHA256
+        md = EVP_sha256();
+      }
+
+      if (verifySignatureRSA(jwk->evp_pkey_.get(), md, jwt.signature_,
+                             signed_data)) {
+        // Verification succeeded.
+        return Status::Ok;
+      }
     }
   }
 
@@ -142,7 +165,7 @@
 }
 
 Status verifyJwt(const Jwt& jwt, const Jwks& jwks,
-                 const std::vector<std::string>& audiences, int64_t now) {
+                 const std::vector<std::string>& audiences, uint64_t now) {
   CheckAudience checker(audiences);
   if (!checker.areAudiencesAllowed(jwt.audiences_)) {
     return Status::JwtAudienceNotAllowed;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/src/verify_pem_test.cc 
new/jwt_verify_lib-20190708/src/verify_pem_test.cc
--- old/jwt_verify_lib-20181125/src/verify_pem_test.cc  2018-11-25 
02:41:06.000000000 +0100
+++ new/jwt_verify_lib-20190708/src/verify_pem_test.cc  2019-07-08 
18:31:22.000000000 +0200
@@ -24,7 +24,7 @@
 // Header:  {"alg":"RS256","typ":"JWT"}
 // Payload:
 // {"iss":"https://example.com","sub":"[email protected]","exp":1501281058}
-const std::string JwtPem =
+const std::string JwtPemRs256 =
     "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9."
     "eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwic3ViIjoidGVzdEBleGFtcGxlLmNvbSIs"
     "ImV4cCI6MTUwMTI4MTA1OH0.FxT92eaBr9thDpeWaQh0YFhblVggn86DBpnTa_"
@@ -34,6 +34,34 @@
     "N09hdvlCtAF87Fu1qqfwEQ93A-J7m08bZJoyIPcNmTcYGHwfMR4-lcI5cC_93C_"
     "5BGE1FHPLOHpNghLuM6-rhOtgwZc9ywupn_bBK3QzuAoDnYwpqQhgQL_CdUD_bSHcmWFkw";
 
+// JWT with
+// Header:  {"alg":"RS384","typ":"JWT"}
+// Payload:
+// {"iss":"https://example.com","sub":"[email protected]","exp":1501281058}
+const std::string JwtPemRs384 =
+    "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9."
+    "eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwic3ViIjoidGVzdEBleGFtcGxlLmNvbSIs"
+    "ImV4cCI6MTUwMTI4MTA1OH0.NvinWcCVmBAmbK5FnAPt8gMBSWOU9kjTEIxcDqJBzjB6nKGj"
+    "sUYF05RC69F4POrJKLl3ak9LQUFPAwn732xEavbQunl-MreZCtRKrTX2xdwod0_u3gvSakcc"
+    "N9kEkbXMqJ5DhFUH0Viv7oVQtbRzwB7hr0ip-Yi8RAbrKfk8qDX0bT2TOlqzbLDnIp3M5btX"
+    "vO1GfOirIiz0YDfzEmSbkhZAnz4D062LWwyfIfM1ZhFusSyYBaNjib1vBfjIGsiYW-ot9dRY"
+    "X0YZP1YF-XxalyUGalD6pn-5nOkd86KL8ch0OkxBpHc1XqBrrsw0Pjax6Sv-nYYUb9qN6p69"
+    "q9YstA";
+
+// JWT with
+// Header:  {"alg":"RS512","typ":"JWT"}
+// Payload:
+// {"iss":"https://example.com","sub":"[email protected]","exp":1501281058}
+const std::string JwtPemRs512 =
+    "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9."
+    "eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwic3ViIjoidGVzdEBleGFtcGxlLmNvbSIs"
+    "ImV4cCI6MTUwMTI4MTA1OH0.BaBGWBS5ZhOX7o0LlAYqnnS-rME0E_eAjnCzPolSY5oh-Mic"
+    "WFN3B1AW-iCeAW3fHf7GhlbshKoybLaj7Cj87m9T-w015WGyIBIwWKQVjfT62RJ1hrKzoyM5"
+    "flVbwMPG70vqV9xfOTpZ4iZ9QomAut4yMDSBTINeeQLRVckYUN-IQVLU-bMnnvabsIQeNxhs"
+    "sG6S61cOD234mGdgkxoaZhHDprvEtAaYAuuKsIlaNIbp8r5hYFv09SMjAELlneObiMI3m5IG"
+    "yx3cF3odgb8PPLRBEOxD6HwJzmvbYmkjmgLuE5vb5lLEacyn2I1ko7e-Hlzvp_ezST0wknz5"
+    "wadrCQ";
+
 const std::string PublicKeyPem =
     "MIIBCgKCAQEAtw7MNxUTxmzWROCD5BqJxmzT7xqc9KsnAjbXCoqEEHDx4WBlfcwk"
     "XHt9e/2+Uwi3Arz3FOMNKwGGlbr7clBY3utsjUs8BTF0kO/poAmSTdSuGeh2mSbc"
@@ -42,9 +70,37 @@
     "+hHYL6nqwOR3ej0VqCTLS0OloC0LuCpLV7CnSpwbp2Qg/c+MDzQ0TH8g8drIzR5h"
     "Fe9a3NlNRMXgUU5RqbLnR9zfXr7b9oEszQIDAQAB";
 
-TEST(VerifyPemTest, OKPem) {
+TEST(VerifyPemTestRs256, OKPem) {
+  Jwt jwt;
+  EXPECT_EQ(jwt.parseFromString(JwtPemRs256), Status::Ok);
+
+  auto jwks = Jwks::createFrom(PublicKeyPem, Jwks::Type::PEM);
+  EXPECT_EQ(jwks->getStatus(), Status::Ok);
+
+  EXPECT_EQ(verifyJwt(jwt, *jwks, 1), Status::Ok);
+
+  fuzzJwtSignature(jwt, [&jwks](const Jwt& jwt) {
+    EXPECT_EQ(verifyJwt(jwt, *jwks, 1), Status::JwtVerificationFail);
+  });
+}
+
+TEST(VerifyPemTestRs384, OKPem) {
+  Jwt jwt;
+  EXPECT_EQ(jwt.parseFromString(JwtPemRs384), Status::Ok);
+
+  auto jwks = Jwks::createFrom(PublicKeyPem, Jwks::Type::PEM);
+  EXPECT_EQ(jwks->getStatus(), Status::Ok);
+
+  EXPECT_EQ(verifyJwt(jwt, *jwks, 1), Status::Ok);
+
+  fuzzJwtSignature(jwt, [&jwks](const Jwt& jwt) {
+    EXPECT_EQ(verifyJwt(jwt, *jwks, 1), Status::JwtVerificationFail);
+  });
+}
+
+TEST(VerifyPemTestRs512, OKPem) {
   Jwt jwt;
-  EXPECT_EQ(jwt.parseFromString(JwtPem), Status::Ok);
+  EXPECT_EQ(jwt.parseFromString(JwtPemRs512), Status::Ok);
 
   auto jwks = Jwks::createFrom(PublicKeyPem, Jwks::Type::PEM);
   EXPECT_EQ(jwks->getStatus(), Status::Ok);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jwt_verify_lib-20181125/src/verify_time_test.cc 
new/jwt_verify_lib-20190708/src/verify_time_test.cc
--- old/jwt_verify_lib-20181125/src/verify_time_test.cc 2018-11-25 
02:41:06.000000000 +0100
+++ new/jwt_verify_lib-20190708/src/verify_time_test.cc 2019-07-08 
18:31:22.000000000 +0200
@@ -41,7 +41,11 @@
   Jwt jwt;
   Jwks jwks;
   EXPECT_EQ(jwt.parseFromString(JwtText), Status::Ok);
-  EXPECT_EQ(verifyJwt(jwt, jwks, 9223372036854775807), Status::JwtExpired);
+  // proto.Struct is using "double" for number_value. A big integer has been
+  // casted to double and back may not be the same.
+  // In this case, 9223372036854775806 become 9223372036854775808
+  // so using 9223372036854775807 for the test will not work.
+  EXPECT_EQ(verifyJwt(jwt, jwks, 9223372036854775810U), Status::JwtExpired);
 }
 
 TEST(VerifyExpTest, NotBefore) {

++++++ opensslcbs.BUILD ++++++
licenses(["notice"])  # Apache 2

cc_library(
    name = "bssl_wrapper_lib",
    hdrs = glob(["thirdparty_build/include/opensslcbs/**/*.h"]),
    copts = ["-I/usr/include/opensslcbs"],
    linkopts = [
        "-lopenssl_cbs_lib",
    ],
    visibility = ["//visibility:public"],
    linkstatic=False,
)
++++++ zlib.BUILD ++++++
licenses(["notice"])  # Apache 2

cc_library(
    name = "zlib",
    hdrs = glob([
        "thirdparty_build/include/zconf.h",
        "thirdparty_build/include/zlib.h",
    ]),
    copts = [],
    linkopts = ["-lz"],
    visibility = ["//visibility:public"],
    linkstatic=False,
)

Reply via email to