1 // Copyright 2018 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/signature/rsa_ssa_pss_sign_key_manager.h"
18
19 #include <memory>
20 #include <string>
21 #include <utility>
22
23 #include "absl/memory/memory.h"
24 #include "absl/status/status.h"
25 #include "absl/strings/string_view.h"
26 #include "tink/internal/bn_util.h"
27 #include "tink/internal/rsa_util.h"
28 #include "tink/internal/ssl_unique_ptr.h"
29 #include "tink/public_key_sign.h"
30 #include "tink/signature/rsa_ssa_pss_verify_key_manager.h"
31 #include "tink/signature/sig_util.h"
32 #include "tink/subtle/rsa_ssa_pss_sign_boringssl.h"
33 #include "tink/util/enums.h"
34 #include "tink/util/errors.h"
35 #include "tink/util/protobuf_helper.h"
36 #include "tink/util/secret_data.h"
37 #include "tink/util/status.h"
38 #include "tink/util/statusor.h"
39 #include "tink/util/validation.h"
40 #include "proto/rsa_ssa_pss.pb.h"
41 #include "proto/tink.pb.h"
42
43 namespace crypto {
44 namespace tink {
45
46 using crypto::tink::util::Enums;
47 using crypto::tink::util::Status;
48 using crypto::tink::util::StatusOr;
49 using google::crypto::tink::RsaSsaPssKeyFormat;
50 using google::crypto::tink::RsaSsaPssParams;
51 using google::crypto::tink::RsaSsaPssPrivateKey;
52
53 namespace {
RsaPrivateKeySubtleToProto(const internal::RsaPrivateKey & private_key)54 std::unique_ptr<RsaSsaPssPrivateKey> RsaPrivateKeySubtleToProto(
55 const internal::RsaPrivateKey& private_key) {
56 auto key_proto = absl::make_unique<RsaSsaPssPrivateKey>();
57 key_proto->set_version(RsaSsaPssSignKeyManager().get_version());
58 key_proto->set_d(std::string(util::SecretDataAsStringView(private_key.d)));
59 key_proto->set_p(std::string(util::SecretDataAsStringView(private_key.p)));
60 key_proto->set_q(std::string(util::SecretDataAsStringView(private_key.q)));
61 key_proto->set_dp(std::string(util::SecretDataAsStringView(private_key.dp)));
62 key_proto->set_dq(std::string(util::SecretDataAsStringView(private_key.dq)));
63 key_proto->set_crt(
64 std::string(util::SecretDataAsStringView(private_key.crt)));
65 auto* public_key_proto = key_proto->mutable_public_key();
66 public_key_proto->set_version(RsaSsaPssSignKeyManager().get_version());
67 public_key_proto->set_n(private_key.n);
68 public_key_proto->set_e(private_key.e);
69 return key_proto;
70 }
71
RsaPrivateKeyProtoToSubtle(const RsaSsaPssPrivateKey & key_proto)72 internal::RsaPrivateKey RsaPrivateKeyProtoToSubtle(
73 const RsaSsaPssPrivateKey& key_proto) {
74 internal::RsaPrivateKey key;
75 key.n = key_proto.public_key().n();
76 key.e = key_proto.public_key().e();
77 key.d = util::SecretDataFromStringView(key_proto.d());
78 key.p = util::SecretDataFromStringView(key_proto.p());
79 key.q = util::SecretDataFromStringView(key_proto.q());
80 key.dp = util::SecretDataFromStringView(key_proto.dp());
81 key.dq = util::SecretDataFromStringView(key_proto.dq());
82 key.crt = util::SecretDataFromStringView(key_proto.crt());
83 return key;
84 }
85
86 } // namespace
87
CreateKey(const RsaSsaPssKeyFormat & key_format) const88 StatusOr<RsaSsaPssPrivateKey> RsaSsaPssSignKeyManager::CreateKey(
89 const RsaSsaPssKeyFormat& key_format) const {
90 util::StatusOr<internal::SslUniquePtr<BIGNUM>> e =
91 internal::StringToBignum(key_format.public_exponent());
92 if (!e.ok()) {
93 return e.status();
94 }
95
96 internal::RsaPrivateKey private_key;
97 internal::RsaPublicKey public_key;
98 util::Status status = internal::NewRsaKeyPair(
99 key_format.modulus_size_in_bits(), e->get(), &private_key, &public_key);
100 if (!status.ok()) {
101 return status;
102 }
103
104 RsaSsaPssPrivateKey key_proto =
105 std::move(*RsaPrivateKeySubtleToProto(private_key));
106 *key_proto.mutable_public_key()->mutable_params() = key_format.params();
107 return key_proto;
108 }
109
110 StatusOr<std::unique_ptr<PublicKeySign>>
Create(const RsaSsaPssPrivateKey & private_key) const111 RsaSsaPssSignKeyManager::PublicKeySignFactory::Create(
112 const RsaSsaPssPrivateKey& private_key) const {
113 auto key = RsaPrivateKeyProtoToSubtle(private_key);
114 internal::RsaSsaPssParams params;
115 const RsaSsaPssParams& params_proto = private_key.public_key().params();
116 params.sig_hash = Enums::ProtoToSubtle(params_proto.sig_hash());
117 params.mgf1_hash = Enums::ProtoToSubtle(params_proto.mgf1_hash());
118 params.salt_length = params_proto.salt_length();
119 auto signer = subtle::RsaSsaPssSignBoringSsl::New(key, params);
120 if (!signer.ok()) return signer.status();
121 // To check that the key is correct, we sign a test message with private key
122 // and verify with public key.
123 auto verifier = RsaSsaPssVerifyKeyManager().GetPrimitive<PublicKeyVerify>(
124 private_key.public_key());
125 if (!verifier.ok()) return verifier.status();
126 auto sign_verify_result =
127 SignAndVerify(signer.value().get(), verifier.value().get());
128 if (!sign_verify_result.ok()) {
129 return util::Status(absl::StatusCode::kInternal,
130 "security bug: signing with private key followed by "
131 "verifying with public key failed");
132 }
133 return signer;
134 }
135
ValidateKey(const RsaSsaPssPrivateKey & key) const136 Status RsaSsaPssSignKeyManager::ValidateKey(
137 const RsaSsaPssPrivateKey& key) const {
138 Status status = ValidateVersion(key.version(), get_version());
139 if (!status.ok()) return status;
140 return RsaSsaPssVerifyKeyManager().ValidateKey(key.public_key());
141 }
142
ValidateKeyFormat(const RsaSsaPssKeyFormat & key_format) const143 Status RsaSsaPssSignKeyManager::ValidateKeyFormat(
144 const RsaSsaPssKeyFormat& key_format) const {
145 Status modulus_status =
146 internal::ValidateRsaModulusSize(key_format.modulus_size_in_bits());
147 if (!modulus_status.ok()) {
148 return modulus_status;
149 }
150 Status exponent_status =
151 internal::ValidateRsaPublicExponent(key_format.public_exponent());
152 if (!exponent_status.ok()) {
153 return exponent_status;
154 }
155 return RsaSsaPssVerifyKeyManager().ValidateParams(key_format.params());
156 }
157
158 } // namespace tink
159 } // namespace crypto
160