xref: /aosp_15_r20/external/tink/cc/signature/signature_pem_keyset_reader.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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/signature_pem_keyset_reader.h"
18 
19 #include <cstddef>
20 #include <memory>
21 #include <random>
22 #include <string>
23 #include <utility>
24 
25 #include "absl/memory/memory.h"
26 #include "absl/status/status.h"
27 #include "absl/strings/str_cat.h"
28 #include "absl/strings/string_view.h"
29 #include "tink/internal/ec_util.h"
30 #include "tink/internal/rsa_util.h"
31 #include "tink/keyset_reader.h"
32 #include "tink/signature/ecdsa_verify_key_manager.h"
33 #include "tink/signature/rsa_ssa_pkcs1_sign_key_manager.h"
34 #include "tink/signature/rsa_ssa_pkcs1_verify_key_manager.h"
35 #include "tink/signature/rsa_ssa_pss_sign_key_manager.h"
36 #include "tink/signature/rsa_ssa_pss_verify_key_manager.h"
37 #include "tink/subtle/pem_parser_boringssl.h"
38 #include "tink/util/enums.h"
39 #include "tink/util/keyset_util.h"
40 #include "tink/util/secret_data.h"
41 #include "tink/util/status.h"
42 #include "tink/util/statusor.h"
43 #include "proto/common.pb.h"
44 #include "proto/ecdsa.pb.h"
45 #include "proto/rsa_ssa_pkcs1.pb.h"
46 #include "proto/rsa_ssa_pss.pb.h"
47 #include "proto/tink.pb.h"
48 
49 namespace crypto {
50 namespace tink {
51 
52 using ::google::crypto::tink::EcdsaParams;
53 using ::google::crypto::tink::EcdsaPublicKey;
54 using ::google::crypto::tink::EllipticCurveType;
55 using ::google::crypto::tink::EncryptedKeyset;
56 using ::google::crypto::tink::HashType;
57 using ::google::crypto::tink::KeyData;
58 using ::google::crypto::tink::Keyset;
59 using ::google::crypto::tink::KeyStatusType;
60 using ::google::crypto::tink::OutputPrefixType;
61 using ::google::crypto::tink::RsaSsaPkcs1PrivateKey;
62 using ::google::crypto::tink::RsaSsaPkcs1PublicKey;
63 using ::google::crypto::tink::RsaSsaPssParams;
64 using ::google::crypto::tink::RsaSsaPssPrivateKey;
65 using ::google::crypto::tink::RsaSsaPssPublicKey;
66 
67 namespace {
68 
69 // Sets the parameters for an RSASSA-PSS key `parameters` given the PEM
70 // parameters `pem_parameters`.
SetRsaSsaPssParameters(const PemKeyParams & pem_parameters,RsaSsaPssParams * parameters)71 util::Status SetRsaSsaPssParameters(const PemKeyParams& pem_parameters,
72                                     RsaSsaPssParams* parameters) {
73   if (parameters == nullptr) {
74     return util::Status(absl::StatusCode::kInvalidArgument,
75                         "Null parameters provided");
76   }
77   parameters->set_mgf1_hash(pem_parameters.hash_type);
78   parameters->set_sig_hash(pem_parameters.hash_type);
79   auto salt_len_or = util::Enums::HashLength(pem_parameters.hash_type);
80   if (!salt_len_or.ok()) return salt_len_or.status();
81   parameters->set_salt_length(salt_len_or.value());
82 
83   return util::OkStatus();
84 }
85 
86 // Sets the parameters for an ECDSA key `parameters` given the PEM
87 // parameters `pem_parameters`.
SetEcdsaParameters(const PemKeyParams & pem_parameters,EcdsaParams * parameters)88 util::Status SetEcdsaParameters(const PemKeyParams& pem_parameters,
89                                 EcdsaParams* parameters) {
90   if (parameters == nullptr) {
91     return util::Status(absl::StatusCode::kInvalidArgument,
92                         "Null parameters provided");
93   }
94 
95   if (pem_parameters.hash_type != HashType::SHA256 ||
96       pem_parameters.key_size_in_bits != 256) {
97     return util::Status(
98         absl::StatusCode::kInvalidArgument,
99         "Only NIST_P256 ECDSA supported. Parameters should contain "
100         "SHA256 and 256 bit key size.");
101   }
102 
103   parameters->set_hash_type(pem_parameters.hash_type);
104   parameters->set_curve(EllipticCurveType::NIST_P256);
105 
106   switch (pem_parameters.algorithm) {
107     case PemAlgorithm::ECDSA_IEEE: {
108       parameters->set_encoding(
109           google::crypto::tink::EcdsaSignatureEncoding::IEEE_P1363);
110       break;
111     }
112     case PemAlgorithm::ECDSA_DER: {
113       parameters->set_encoding(
114           google::crypto::tink::EcdsaSignatureEncoding::DER);
115       break;
116     }
117     default: {
118       return util::Status(
119           absl::StatusCode::kInvalidArgument,
120           "Only ECDSA supported. The algorithm parameter should be "
121           "ECDSA_IEEE or ECDSA_DER.");
122     }
123   }
124 
125   return util::OkStatus();
126 }
127 
128 // Creates a new Keyset::Key with ID `key_id`. The key has key data
129 // `key_data`, key type `key_type`, and key material type
130 // `key_material_type`.
NewKeysetKey(uint32_t key_id,absl::string_view key_type,const KeyData::KeyMaterialType & key_material_type,const std::string & key_data)131 Keyset::Key NewKeysetKey(uint32_t key_id, absl::string_view key_type,
132                          const KeyData::KeyMaterialType& key_material_type,
133                          const std::string& key_data) {
134   Keyset::Key key;
135   // Populate KeyData for the new key.
136   key.set_key_id(key_id);
137   key.set_status(KeyStatusType::ENABLED);
138   // PEM keys don't add any prefix to signatures
139   key.set_output_prefix_type(OutputPrefixType::RAW);
140   KeyData* key_data_proto = key.mutable_key_data();
141   key_data_proto->set_type_url(key_type.data(), key_type.size());
142   key_data_proto->set_value(key_data);
143   key_data_proto->set_key_material_type(key_material_type);
144   return key;
145 }
146 
147 // Construct a new RSASSA-PSS key proto from a subtle RSA private key
148 // `private_key_subtle`; the key is assigned version `key_version` and
149 // key paramters `parameters`.
NewRsaSsaPrivateKey(const internal::RsaPrivateKey & private_key_subtle,uint32_t key_version,const PemKeyParams & parameters)150 util::StatusOr<RsaSsaPssPrivateKey> NewRsaSsaPrivateKey(
151     const internal::RsaPrivateKey& private_key_subtle, uint32_t key_version,
152     const PemKeyParams& parameters) {
153   RsaSsaPssPrivateKey private_key_proto;
154 
155   // RSA Private key parameters.
156   private_key_proto.set_version(key_version);
157   private_key_proto.set_d(
158       std::string(util::SecretDataAsStringView(private_key_subtle.d)));
159   private_key_proto.set_p(
160       std::string(util::SecretDataAsStringView(private_key_subtle.p)));
161   private_key_proto.set_q(
162       std::string(util::SecretDataAsStringView(private_key_subtle.q)));
163   private_key_proto.set_dp(
164       std::string(util::SecretDataAsStringView(private_key_subtle.dp)));
165   private_key_proto.set_dq(
166       std::string(util::SecretDataAsStringView(private_key_subtle.dq)));
167   private_key_proto.set_crt(
168       std::string(util::SecretDataAsStringView(private_key_subtle.crt)));
169 
170   // Inner RSA public key.
171   RsaSsaPssPublicKey* public_key_proto = private_key_proto.mutable_public_key();
172   public_key_proto->set_version(key_version);
173   public_key_proto->set_n(private_key_subtle.n);
174   public_key_proto->set_e(private_key_subtle.e);
175 
176   // RSASSA-PSS public key parameters.
177   auto set_parameter_status =
178       SetRsaSsaPssParameters(parameters, public_key_proto->mutable_params());
179   if (!set_parameter_status.ok()) {
180     return set_parameter_status;
181   }
182 
183   return private_key_proto;
184 }
185 
186 // Construct a new RSASSA-PKCS1 key proto from a subtle RSA private key
187 // `private_key_subtle`; the key is assigned version `key_version` and
188 // key paramters `parameters`.
NewRsaSsaPkcs1PrivateKey(const internal::RsaPrivateKey & private_key_subtle,uint32_t key_version,const PemKeyParams & parameters)189 RsaSsaPkcs1PrivateKey NewRsaSsaPkcs1PrivateKey(
190     const internal::RsaPrivateKey& private_key_subtle, uint32_t key_version,
191     const PemKeyParams& parameters) {
192   RsaSsaPkcs1PrivateKey private_key_proto;
193 
194   // RSA Private key parameters.
195   private_key_proto.set_version(key_version);
196   private_key_proto.set_d(
197       std::string(util::SecretDataAsStringView(private_key_subtle.d)));
198   private_key_proto.set_p(
199       std::string(util::SecretDataAsStringView(private_key_subtle.p)));
200   private_key_proto.set_q(
201       std::string(util::SecretDataAsStringView(private_key_subtle.q)));
202   private_key_proto.set_dp(
203       std::string(util::SecretDataAsStringView(private_key_subtle.dp)));
204   private_key_proto.set_dq(
205       std::string(util::SecretDataAsStringView(private_key_subtle.dq)));
206   private_key_proto.set_crt(
207       std::string(util::SecretDataAsStringView(private_key_subtle.crt)));
208 
209   // Inner RSA Public key parameters.
210   RsaSsaPkcs1PublicKey* public_key_proto =
211       private_key_proto.mutable_public_key();
212   public_key_proto->set_version(key_version);
213   public_key_proto->set_n(private_key_subtle.n);
214   public_key_proto->set_e(private_key_subtle.e);
215 
216   // RSASSA-PKCS1 Public key parameters.
217   public_key_proto->mutable_params()->set_hash_type(parameters.hash_type);
218 
219   return private_key_proto;
220 }
221 
222 // Adds the PEM-encoded private key `pem_key` to `keyset`.
AddRsaSsaPrivateKey(const PemKey & pem_key,Keyset * keyset)223 util::Status AddRsaSsaPrivateKey(const PemKey& pem_key, Keyset* keyset) {
224   // Try to parse the PEM RSA private key.
225   auto private_key_subtle_or =
226       subtle::PemParser::ParseRsaPrivateKey(pem_key.serialized_key);
227   if (!private_key_subtle_or.ok()) return private_key_subtle_or.status();
228 
229   std::unique_ptr<internal::RsaPrivateKey> private_key_subtle =
230       std::move(private_key_subtle_or).value();
231 
232   size_t modulus_size = private_key_subtle->n.length() * 8;
233   if (pem_key.parameters.key_size_in_bits != modulus_size) {
234     return util::Status(
235         absl::StatusCode::kInvalidArgument,
236         absl::StrCat("Invalid RSA Key modulus size; found: ", modulus_size,
237                      ", expected: ", pem_key.parameters.key_size_in_bits));
238   }
239 
240   switch (pem_key.parameters.algorithm) {
241     case PemAlgorithm::RSASSA_PSS: {
242       RsaSsaPssSignKeyManager key_manager;
243       auto private_key_proto_or = NewRsaSsaPrivateKey(
244           *private_key_subtle, key_manager.get_version(), pem_key.parameters);
245       if (!private_key_proto_or.ok()) return private_key_proto_or.status();
246       RsaSsaPssPrivateKey private_key_proto = private_key_proto_or.value();
247 
248       // Validate the key.
249       auto key_validation_status = key_manager.ValidateKey(private_key_proto);
250       if (!key_validation_status.ok()) return key_validation_status;
251 
252       *keyset->add_key() =
253           NewKeysetKey(GenerateUnusedKeyId(*keyset), key_manager.get_key_type(),
254                        key_manager.key_material_type(),
255                        private_key_proto.SerializeAsString());
256       break;
257     }
258     case PemAlgorithm::RSASSA_PKCS1: {
259       RsaSsaPkcs1SignKeyManager key_manager;
260       RsaSsaPkcs1PrivateKey private_key_proto = NewRsaSsaPkcs1PrivateKey(
261           *private_key_subtle, key_manager.get_version(), pem_key.parameters);
262 
263       // Validate the key.
264       auto key_validation_status = key_manager.ValidateKey(private_key_proto);
265       if (!key_validation_status.ok()) return key_validation_status;
266 
267       *keyset->add_key() =
268           NewKeysetKey(GenerateUnusedKeyId(*keyset), key_manager.get_key_type(),
269                        key_manager.key_material_type(),
270                        private_key_proto.SerializeAsString());
271 
272       break;
273     }
274     default:
275       return util::Status(
276           absl::StatusCode::kInvalidArgument,
277           absl::StrCat("Invalid RSA algorithm ", pem_key.parameters.algorithm));
278   }
279 
280   return util::OkStatus();
281 }
282 // Parses a given PEM-encoded ECDSA public key `pem_key`, and adds it to the
283 // keyset `keyset`.
AddEcdsaPublicKey(const PemKey & pem_key,Keyset * keyset)284 util::Status AddEcdsaPublicKey(const PemKey& pem_key, Keyset* keyset) {
285   // Parse the PEM string into a ECDSA public key.
286   auto public_key_subtle_or =
287       subtle::PemParser::ParseEcPublicKey(pem_key.serialized_key);
288   if (!public_key_subtle_or.ok()) return public_key_subtle_or.status();
289 
290   std::unique_ptr<internal::EcKey> public_key_subtle =
291       std::move(public_key_subtle_or).value();
292 
293   EcdsaPublicKey ecdsa_key;
294   EcdsaVerifyKeyManager key_manager;
295 
296   // ECDSA Public Key Parameters
297   ecdsa_key.set_x(public_key_subtle->pub_x);
298   ecdsa_key.set_y(public_key_subtle->pub_y);
299   auto set_parameter_status =
300       SetEcdsaParameters(pem_key.parameters, ecdsa_key.mutable_params());
301   if (!set_parameter_status.ok()) return set_parameter_status;
302 
303   ecdsa_key.set_version(key_manager.get_version());
304 
305   // Validate the key.
306   auto key_validation_status = key_manager.ValidateKey(ecdsa_key);
307   if (!key_validation_status.ok()) return key_validation_status;
308 
309   *keyset->add_key() = NewKeysetKey(
310       GenerateUnusedKeyId(*keyset), key_manager.get_key_type(),
311       key_manager.key_material_type(), ecdsa_key.SerializeAsString());
312 
313   return util::OkStatus();
314 }
315 
316 // Parses a given PEM-encoded RSA public key `pem_key`, and adds it to the
317 // keyset `keyset`.
AddRsaSsaPublicKey(const PemKey & pem_key,Keyset * keyset)318 util::Status AddRsaSsaPublicKey(const PemKey& pem_key, Keyset* keyset) {
319   // Parse the PEM string into a RSA public key.
320   auto public_key_subtle_or =
321       subtle::PemParser::ParseRsaPublicKey(pem_key.serialized_key);
322   if (!public_key_subtle_or.ok()) return public_key_subtle_or.status();
323 
324   std::unique_ptr<internal::RsaPublicKey> public_key_subtle =
325       std::move(public_key_subtle_or).value();
326 
327   // Check key length is as expected.
328   size_t modulus_size = public_key_subtle->n.length() * 8;
329   if (pem_key.parameters.key_size_in_bits != modulus_size) {
330     return util::Status(
331         absl::StatusCode::kInvalidArgument,
332         absl::StrCat("Invalid RSA Key modulus size; found ", modulus_size,
333                      ", expected ", pem_key.parameters.key_size_in_bits));
334   }
335 
336   switch (pem_key.parameters.algorithm) {
337     case PemAlgorithm::RSASSA_PSS: {
338       RsaSsaPssPublicKey public_key_proto;
339       RsaSsaPssVerifyKeyManager key_manager;
340 
341       // RSA Public key paramters.
342       public_key_proto.set_e(public_key_subtle->e);
343       public_key_proto.set_n(public_key_subtle->n);
344 
345       // RSASSA-PSS Public key parameters.
346       auto set_parameter_status = SetRsaSsaPssParameters(
347           pem_key.parameters, public_key_proto.mutable_params());
348       if (!set_parameter_status.ok()) return set_parameter_status;
349       public_key_proto.set_version(key_manager.get_version());
350 
351       // Validate the key.
352       auto key_validation_status = key_manager.ValidateKey(public_key_proto);
353       if (!key_validation_status.ok()) return key_validation_status;
354 
355       *keyset->add_key() =
356           NewKeysetKey(GenerateUnusedKeyId(*keyset), key_manager.get_key_type(),
357                        key_manager.key_material_type(),
358                        public_key_proto.SerializeAsString());
359 
360       break;
361     }
362     case PemAlgorithm::RSASSA_PKCS1: {
363       RsaSsaPkcs1PublicKey public_key_proto;
364       RsaSsaPkcs1VerifyKeyManager key_manager;
365 
366       // RSA Public key paramters.
367       public_key_proto.set_e(public_key_subtle->e);
368       public_key_proto.set_n(public_key_subtle->n);
369 
370       // RSASSA-PKCS1 Public key parameters.
371       public_key_proto.mutable_params()->set_hash_type(
372           pem_key.parameters.hash_type);
373       public_key_proto.set_version(key_manager.get_version());
374 
375       // Validate the key.
376       auto key_validation_status = key_manager.ValidateKey(public_key_proto);
377       if (!key_validation_status.ok()) return key_validation_status;
378 
379       *keyset->add_key() =
380           NewKeysetKey(GenerateUnusedKeyId(*keyset), key_manager.get_key_type(),
381                        key_manager.key_material_type(),
382                        public_key_proto.SerializeAsString());
383       break;
384     }
385     default:
386       return util::Status(
387           absl::StatusCode::kInvalidArgument,
388           absl::StrCat("Invalid RSA algorithm ", pem_key.parameters.algorithm));
389   }
390   return util::OkStatus();
391 }
392 
393 }  // namespace
394 
Add(const PemKey & pem_serialized_key)395 void SignaturePemKeysetReaderBuilder::Add(const PemKey& pem_serialized_key) {
396   pem_serialized_keys_.push_back(pem_serialized_key);
397 }
398 
399 util::StatusOr<std::unique_ptr<KeysetReader>>
Build()400 SignaturePemKeysetReaderBuilder::Build() {
401   if (pem_serialized_keys_.empty()) {
402     return util::Status(absl::StatusCode::kInvalidArgument,
403                         "Empty array of PEM-encoded keys");
404   }
405 
406   switch (pem_reader_type_) {
407     case PUBLIC_KEY_SIGN: {
408       return absl::WrapUnique<KeysetReader>(
409           new PublicKeySignPemKeysetReader(pem_serialized_keys_));
410     }
411     case PUBLIC_KEY_VERIFY: {
412       return absl::WrapUnique<KeysetReader>(
413           new PublicKeyVerifyPemKeysetReader(pem_serialized_keys_));
414     }
415   }
416   return util::Status(absl::StatusCode::kInvalidArgument,
417                       "Unknown pem_reader_type_");
418 }
419 
Read()420 util::StatusOr<std::unique_ptr<Keyset>> PublicKeySignPemKeysetReader::Read() {
421   if (pem_serialized_keys_.empty()) {
422     return util::Status(absl::StatusCode::kInvalidArgument,
423                         "Empty array of PEM-encoded keys");
424   }
425 
426   auto keyset = absl::make_unique<Keyset>();
427   for (const PemKey& pem_key : pem_serialized_keys_) {
428     // Parse and add the new key to the keyset.
429     switch (pem_key.parameters.key_type) {
430       case PemKeyType::PEM_RSA: {
431         auto add_rsassa_pss_status = AddRsaSsaPrivateKey(pem_key, keyset.get());
432         if (!add_rsassa_pss_status.ok()) return add_rsassa_pss_status;
433         break;
434       }
435       default:
436         return util::Status(absl::StatusCode::kUnimplemented,
437                             "EC Keys Parsing unimplemented");
438     }
439   }
440 
441   // Set the 1st key as primary.
442   keyset->set_primary_key_id(keyset->key(0).key_id());
443 
444   return std::move(keyset);
445 }
446 
Read()447 util::StatusOr<std::unique_ptr<Keyset>> PublicKeyVerifyPemKeysetReader::Read() {
448   if (pem_serialized_keys_.empty()) {
449     return util::Status(absl::StatusCode::kInvalidArgument,
450                         "Empty array of PEM-encoded keys");
451   }
452 
453   auto keyset = absl::make_unique<Keyset>();
454   for (const PemKey& pem_key : pem_serialized_keys_) {
455     // Parse and add the new key to the keyset.
456     switch (pem_key.parameters.key_type) {
457       case PemKeyType::PEM_RSA: {
458         auto add_rsassa_pss_status = AddRsaSsaPublicKey(pem_key, keyset.get());
459         if (!add_rsassa_pss_status.ok()) return add_rsassa_pss_status;
460         break;
461       }
462       case PemKeyType::PEM_EC:
463         auto add_ecdsa_status = AddEcdsaPublicKey(pem_key, keyset.get());
464         if (!add_ecdsa_status.ok()) return add_ecdsa_status;
465     }
466   }
467 
468   // Set the 1st key as primary.
469   keyset->set_primary_key_id(keyset->key(0).key_id());
470 
471   return std::move(keyset);
472 }
473 
474 util::StatusOr<std::unique_ptr<EncryptedKeyset>>
ReadEncrypted()475 SignaturePemKeysetReader::ReadEncrypted() {
476   return util::Status(absl::StatusCode::kUnimplemented,
477                       "Reading Encrypted PEM is not supported");
478 }
479 
480 }  // namespace tink
481 }  // namespace crypto
482