xref: /aosp_15_r20/external/tink/cc/signature/signature_pem_keyset_reader.h (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 #ifndef TINK_SIGNATURE_SIGNATURE_PEM_KEYSET_READER_H_
18 #define TINK_SIGNATURE_SIGNATURE_PEM_KEYSET_READER_H_
19 
20 #include <memory>
21 #include <string>
22 #include <utility>
23 #include <vector>
24 
25 #include "tink/keyset_reader.h"
26 #include "tink/util/statusor.h"
27 #include "proto/common.pb.h"
28 #include "proto/tink.pb.h"
29 
30 namespace crypto {
31 namespace tink {
32 
33 // Type of key.
34 //
35 // Currently, PEM_EC only supports PublicKeyVerify.
36 enum PemKeyType { PEM_RSA, PEM_EC };
37 
38 // Algorithm to use with this key.
39 enum PemAlgorithm {
40   RSASSA_PSS,
41   RSASSA_PKCS1,
42   ECDSA_IEEE,  // NIST_P256 curve with IEEE_P1363 encoding
43   ECDSA_DER  // NIST_P256 curve with DER encoding
44 };
45 
46 // Common set of parameters for the PEM key.
47 struct PemKeyParams {
48   PemKeyType key_type;
49   PemAlgorithm algorithm;
50   size_t key_size_in_bits;
51   ::google::crypto::tink::HashType hash_type;
52 };
53 
54 // A PEM key consists of its serialized data `serialized_key`, and parameters
55 // `parameters`.
56 struct PemKey {
57   std::string serialized_key;
58   PemKeyParams parameters;
59 };
60 
61 // Base class for parsing PEM-encoded keys (RFC 7468) into a keyset.
62 class SignaturePemKeysetReader : public KeysetReader {
63  public:
64   util::StatusOr<std::unique_ptr<::google::crypto::tink::EncryptedKeyset>>
65   ReadEncrypted() override;
66 
67  protected:
SignaturePemKeysetReader(const std::vector<PemKey> & pem_serialized_keys)68   explicit SignaturePemKeysetReader(
69       const std::vector<PemKey>& pem_serialized_keys)
70       : pem_serialized_keys_(pem_serialized_keys) {}
71 
72   // PEM-serialized keys to parse.
73   std::vector<PemKey> pem_serialized_keys_;
74 };
75 
76 // Builder class for creating a PEM reader. Example usage:
77 //
78 // std::string some_public_key_pem = ...;
79 // PemKeyType key_type = ...;
80 // size_t key_size_in_bits = ...;
81 // HashType hash_type = ...;
82 // PemAlgorithm algorithm = ...;
83 //
84 // auto builder = SignaturePemKeysetReaderBuilder(
85 //     PemKeysetReaderBuilder::PemReaderType::PUBLIC_KEY_VERIFY);
86 // builder.Add(
87 //     {.serialized_key = some_rsa_public_key_pem,
88 //      .parameters = {
89 //          .key_type = key_type,
90 //          .algorithm = algorithm,
91 //          .key_size_in_bits = key_size_in_bits,
92 //          .hash_type = hash_type}});
93 // ...
94 // auto reader_statusor = builder.Build();
95 // if (!reader_statusor.ok()) /* handle failure */
96 //
97 // auto keyset_handle_statusor =
98 //     CleartextKeysetHandle::Read(*reader_statusor);
99 class SignaturePemKeysetReaderBuilder {
100  public:
101   // Type of reader to build. The builder type depends on the primitive
102   // supported by the keys to parse.
103   enum PemReaderType { PUBLIC_KEY_SIGN, PUBLIC_KEY_VERIFY };
104 
SignaturePemKeysetReaderBuilder(PemReaderType pem_reader_type)105   explicit SignaturePemKeysetReaderBuilder(PemReaderType pem_reader_type)
106       : pem_reader_type_(pem_reader_type) {}
107 
108   // Adds a PEM serialized key `pem_serialized_key` to the builder.
109   void Add(const PemKey& pem_serialized_key);
110 
111   // Creates an instance of keyset reader based on `pem_reader_type_`, to parse
112   // the PEM-encoded keys in `pem_serialized_keys_`.
113   util::StatusOr<std::unique_ptr<KeysetReader>> Build();
114 
115  private:
116   // List of keys as PEM serialized items.
117   std::vector<PemKey> pem_serialized_keys_;
118   // Reader type that this reader must support.
119   PemReaderType pem_reader_type_;
120 };
121 
122 // Keyset reader for PEM keys that support the PublicKeySign principal.
123 class PublicKeySignPemKeysetReader : public SignaturePemKeysetReader {
124  public:
125   util::StatusOr<std::unique_ptr<::google::crypto::tink::Keyset>> Read()
126       override;
127 
128  private:
129   // Friend builder class.
130   friend class SignaturePemKeysetReaderBuilder;
131 
PublicKeySignPemKeysetReader(const std::vector<PemKey> pem_serialized_keys)132   explicit PublicKeySignPemKeysetReader(
133       const std::vector<PemKey> pem_serialized_keys)
134       : SignaturePemKeysetReader(pem_serialized_keys) {}
135 };
136 
137 // Keyset reader for PEM keys that support the PublicKeyVerify principal.
138 class PublicKeyVerifyPemKeysetReader : public SignaturePemKeysetReader {
139  public:
140   util::StatusOr<std::unique_ptr<::google::crypto::tink::Keyset>> Read()
141       override;
142 
143  private:
144   // Friend builder class.
145   friend class SignaturePemKeysetReaderBuilder;
146 
PublicKeyVerifyPemKeysetReader(const std::vector<PemKey> pem_serialized_keys)147   explicit PublicKeyVerifyPemKeysetReader(
148       const std::vector<PemKey> pem_serialized_keys)
149       : SignaturePemKeysetReader(pem_serialized_keys) {}
150 };
151 
152 }  // namespace tink
153 }  // namespace crypto
154 
155 #endif  // TINK_SIGNATURE_SIGNATURE_PEM_KEYSET_READER_H_
156