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