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