• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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