• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google Inc.
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 #include "tink/jwt/internal/raw_jwt_hmac_key_manager.h"
18 
19 #include <map>
20 
21 #include "absl/status/status.h"
22 #include "absl/strings/string_view.h"
23 #include "tink/mac.h"
24 #include "tink/subtle/hmac_boringssl.h"
25 #include "tink/subtle/random.h"
26 #include "tink/util/enums.h"
27 #include "tink/util/errors.h"
28 #include "tink/util/input_stream_util.h"
29 #include "tink/util/protobuf_helper.h"
30 #include "tink/util/status.h"
31 #include "tink/util/statusor.h"
32 #include "tink/util/validation.h"
33 #include "proto/common.pb.h"
34 #include "proto/jwt_hmac.pb.h"
35 #include "proto/tink.pb.h"
36 
37 namespace crypto {
38 namespace tink {
39 namespace jwt_internal {
40 
41 using crypto::tink::util::Status;
42 using crypto::tink::util::StatusOr;
43 using google::crypto::tink::JwtHmacAlgorithm;
44 using google::crypto::tink::JwtHmacKey;
45 using google::crypto::tink::JwtHmacKeyFormat;
46 
47 namespace {
48 
MinimumKeySize(const JwtHmacAlgorithm & algorithm)49 StatusOr<int> MinimumKeySize(const JwtHmacAlgorithm& algorithm) {
50   switch (algorithm) {
51     case JwtHmacAlgorithm::HS256:
52       return 32;
53     case JwtHmacAlgorithm::HS384:
54       return 48;
55     case JwtHmacAlgorithm::HS512:
56       return 64;
57     default:
58       return Status(absl::StatusCode::kInvalidArgument,
59                     "Unsupported algorithm.");
60   }
61 }
62 
63 }  // namespace
64 
CreateKey(const JwtHmacKeyFormat & jwt_hmac_key_format) const65 StatusOr<JwtHmacKey> RawJwtHmacKeyManager::CreateKey(
66     const JwtHmacKeyFormat& jwt_hmac_key_format) const {
67   JwtHmacKey jwt_hmac_key;
68   jwt_hmac_key.set_version(get_version());
69   jwt_hmac_key.set_algorithm(jwt_hmac_key_format.algorithm());
70   jwt_hmac_key.set_key_value(
71       subtle::Random::GetRandomBytes(jwt_hmac_key_format.key_size()));
72   return jwt_hmac_key;
73 }
74 
DeriveKey(const JwtHmacKeyFormat & jwt_hmac_key_format,InputStream * input_stream) const75 StatusOr<JwtHmacKey> RawJwtHmacKeyManager::DeriveKey(
76     const JwtHmacKeyFormat& jwt_hmac_key_format,
77     InputStream* input_stream) const {
78   return util::Status(absl::StatusCode::kUnimplemented,
79                       "RawJwtHmacKeyManager::DeriveKey is not implemented");
80 }
81 
ValidateKey(const JwtHmacKey & key) const82 Status RawJwtHmacKeyManager::ValidateKey(const JwtHmacKey& key) const {
83   Status status = ValidateVersion(key.version(), get_version());
84   if (!status.ok()) return status;
85   StatusOr<int> min_key_size = MinimumKeySize(key.algorithm());
86   if (!min_key_size.ok()) {
87     return min_key_size.status();
88   }
89   if (key.key_value().size() < *min_key_size) {
90     return util::Status(absl::StatusCode::kInvalidArgument,
91                         "Invalid JwtHmacKey: key_value is too short.");
92   }
93   return util::OkStatus();
94 }
95 
96 // static
ValidateKeyFormat(const JwtHmacKeyFormat & key_format) const97 Status RawJwtHmacKeyManager::ValidateKeyFormat(
98     const JwtHmacKeyFormat& key_format) const {
99   StatusOr<int> min_key_size = MinimumKeySize(key_format.algorithm());
100   if (!min_key_size.ok()) {
101     return min_key_size.status();
102   }
103   if (key_format.key_size() < *min_key_size) {
104     return util::Status(absl::StatusCode::kInvalidArgument,
105                         "Invalid HmacKeyFormat: key_size is too small.");
106   }
107   return util::OkStatus();
108 }
109 
110 }  // namespace jwt_internal
111 }  // namespace tink
112 }  // namespace crypto
113