1 // Copyright 2021 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 /////////////////////////////////////////////////////////////////////////////// 16 17 #ifndef TINK_JWT_RAW_JWT_H_ 18 #define TINK_JWT_RAW_JWT_H_ 19 20 #include <string> 21 #include <vector> 22 23 #include "google/protobuf/struct.pb.h" 24 #include "absl/strings/string_view.h" 25 #include "absl/time/clock.h" 26 #include "absl/time/time.h" 27 #include "tink/util/status.h" 28 #include "tink/util/statusor.h" 29 30 namespace crypto { 31 namespace tink { 32 33 namespace jwt_internal { 34 35 // For friend declaration 36 class RawJwtParser; 37 38 } // namespace jwt_internal 39 40 /////////////////////////////////////////////////////////////////////////////// 41 // An unsigned JSON Web Token (JWT), https://tools.ietf.org/html/rfc7519. 42 // 43 // It contains all payload claims and a subset of the headers. It does not 44 // contain any headers that depend on the key, such as "alg" or "kid", because 45 // these headers are chosen when the token is signed and encoded, and should not 46 // be chosen by the user. This ensures that the key can be changed without any 47 // changes to the user code. 48 class RawJwt { 49 public: 50 RawJwt(); 51 52 bool HasTypeHeader() const; 53 util::StatusOr<std::string> GetTypeHeader() const; 54 bool HasIssuer() const; 55 util::StatusOr<std::string> GetIssuer() const; 56 bool HasSubject() const; 57 util::StatusOr<std::string> GetSubject() const; 58 bool HasAudiences() const; 59 util::StatusOr<std::vector<std::string>> GetAudiences() const; 60 bool HasJwtId() const; 61 util::StatusOr<std::string> GetJwtId() const; 62 bool HasExpiration() const; 63 util::StatusOr<absl::Time> GetExpiration() const; 64 bool HasNotBefore() const; 65 util::StatusOr<absl::Time> GetNotBefore() const; 66 bool HasIssuedAt() const; 67 util::StatusOr<absl::Time> GetIssuedAt() const; 68 bool IsNullClaim(absl::string_view name) const; 69 bool HasBooleanClaim(absl::string_view name) const; 70 util::StatusOr<bool> GetBooleanClaim(absl::string_view name) const; 71 bool HasStringClaim(absl::string_view name) const; 72 util::StatusOr<std::string> GetStringClaim(absl::string_view name) const; 73 bool HasNumberClaim(absl::string_view name) const; 74 util::StatusOr<double> GetNumberClaim(absl::string_view name) const; 75 bool HasJsonObjectClaim(absl::string_view name) const; 76 util::StatusOr<std::string> GetJsonObjectClaim(absl::string_view name) const; 77 bool HasJsonArrayClaim(absl::string_view name) const; 78 util::StatusOr<std::string> GetJsonArrayClaim(absl::string_view name) const; 79 std::vector<std::string> CustomClaimNames() const; 80 81 util::StatusOr<std::string> GetJsonPayload() const; 82 83 // RawJwt objects are copiable and movable. 84 RawJwt(const RawJwt&) = default; 85 RawJwt& operator=(const RawJwt&) = default; 86 RawJwt(RawJwt&& other) = default; 87 RawJwt& operator=(RawJwt&& other) = default; 88 89 private: 90 static util::StatusOr<RawJwt> FromJson( 91 absl::optional<std::string> type_header, absl::string_view json_payload); 92 explicit RawJwt(absl::optional<std::string> type_header, 93 google::protobuf::Struct json_proto); 94 friend class RawJwtBuilder; 95 friend class jwt_internal::RawJwtParser; 96 absl::optional<std::string> type_header_; 97 google::protobuf::Struct json_proto_; 98 }; 99 100 class RawJwtBuilder { 101 public: 102 RawJwtBuilder(); 103 104 RawJwtBuilder& SetTypeHeader(absl::string_view type_header); 105 RawJwtBuilder& SetIssuer(absl::string_view issuer); 106 RawJwtBuilder& SetSubject(absl::string_view subject); 107 RawJwtBuilder& SetAudience(absl::string_view audience); 108 RawJwtBuilder& SetAudiences(std::vector<std::string> audience); 109 RawJwtBuilder& AddAudience(absl::string_view audience); 110 RawJwtBuilder& SetJwtId(absl::string_view jwid); 111 RawJwtBuilder& WithoutExpiration(); 112 RawJwtBuilder& SetExpiration(absl::Time expiration); 113 RawJwtBuilder& SetNotBefore(absl::Time not_before); 114 RawJwtBuilder& SetIssuedAt(absl::Time issued_at); 115 RawJwtBuilder& AddNullClaim(absl::string_view name); 116 RawJwtBuilder& AddBooleanClaim(absl::string_view name, bool bool_value); 117 RawJwtBuilder& AddStringClaim(absl::string_view name, 118 absl::string_view string_value); 119 RawJwtBuilder& AddNumberClaim(absl::string_view name, double double_value); 120 RawJwtBuilder& AddJsonObjectClaim(absl::string_view name, 121 absl::string_view object_value); 122 RawJwtBuilder& AddJsonArrayClaim(absl::string_view name, 123 absl::string_view array_value); 124 125 util::StatusOr<RawJwt> Build(); 126 127 // RawJwtBuilder objects are copiable and movable. 128 RawJwtBuilder(const RawJwtBuilder&) = default; 129 RawJwtBuilder& operator=(const RawJwtBuilder&) = default; 130 RawJwtBuilder(RawJwtBuilder&& other) = default; 131 RawJwtBuilder& operator=(RawJwtBuilder&& other) = default; 132 133 private: 134 absl::optional<util::Status> error_; 135 absl::optional<std::string> type_header_; 136 bool without_expiration_; 137 google::protobuf::Struct json_proto_; 138 }; 139 140 } // namespace tink 141 } // namespace crypto 142 143 #endif // TINK_JWT_RAW_JWT_H_ 144