xref: /aosp_15_r20/external/tink/cc/jwt/internal/jwt_public_key_sign_impl.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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 #include "tink/jwt/internal/jwt_public_key_sign_impl.h"
18 
19 #include <string>
20 
21 #include "absl/status/status.h"
22 #include "absl/strings/escaping.h"
23 #include "absl/strings/str_split.h"
24 #include "tink/jwt/internal/jwt_format.h"
25 
26 namespace crypto {
27 namespace tink {
28 namespace jwt_internal {
29 
SignAndEncodeWithKid(const RawJwt & token,absl::optional<absl::string_view> kid) const30 util::StatusOr<std::string> JwtPublicKeySignImpl::SignAndEncodeWithKid(
31     const RawJwt& token, absl::optional<absl::string_view> kid) const {
32   absl::optional<std::string> type_header;
33   if (token.HasTypeHeader()) {
34     util::StatusOr<std::string> type = token.GetTypeHeader();
35     if (!type.ok()) {
36       return type.status();
37     }
38     type_header = *type;
39   }
40   if (custom_kid_.has_value()) {
41     if (kid.has_value()) {
42       return util::Status(absl::StatusCode::kInvalidArgument,
43                           "TINK keys are not allowed to have a kid value set.");
44     }
45     kid = *custom_kid_;
46   }
47   util::StatusOr<std::string> encoded_header =
48       CreateHeader(algorithm_, type_header, kid);
49   if (!encoded_header.ok()) {
50     return encoded_header.status();
51   }
52   util::StatusOr<std::string> payload = token.GetJsonPayload();
53   if (!payload.ok()) {
54     return payload.status();
55   }
56   std::string encoded_payload = EncodePayload(*payload);
57   std::string unsigned_token =
58       absl::StrCat(*encoded_header, ".", encoded_payload);
59   util::StatusOr<std::string> tag = sign_->Sign(unsigned_token);
60   if (!tag.ok()) {
61     return tag.status();
62   }
63   std::string encoded_tag = EncodeSignature(*tag);
64   return absl::StrCat(unsigned_token, ".", encoded_tag);
65 }
66 
67 }  // namespace jwt_internal
68 }  // namespace tink
69 }  // namespace crypto
70