| // Copyright 2018 Google Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #ifndef TINK_SIGNATURE_SIGNATURE_PEM_KEYSET_READER_H_ |
| #define TINK_SIGNATURE_SIGNATURE_PEM_KEYSET_READER_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "tink/keyset_reader.h" |
| #include "tink/util/statusor.h" |
| #include "proto/common.pb.h" |
| #include "proto/tink.pb.h" |
| |
| namespace crypto { |
| namespace tink { |
| |
| // Type of key. |
| // |
| // Currently, PEM_EC only supports PublicKeyVerify. |
| enum PemKeyType { PEM_RSA, PEM_EC }; |
| |
| // Algorithm to use with this key. |
| enum PemAlgorithm { |
| RSASSA_PSS, |
| RSASSA_PKCS1, |
| ECDSA_IEEE, // NIST_P256 curve with IEEE_P1363 encoding |
| ECDSA_DER // NIST_P256 curve with DER encoding |
| }; |
| |
| // Common set of parameters for the PEM key. |
| struct PemKeyParams { |
| PemKeyType key_type; |
| PemAlgorithm algorithm; |
| size_t key_size_in_bits; |
| ::google::crypto::tink::HashType hash_type; |
| }; |
| |
| // A PEM key consists of its serialized data `serialized_key`, and parameters |
| // `parameters`. |
| struct PemKey { |
| std::string serialized_key; |
| PemKeyParams parameters; |
| }; |
| |
| // Base class for parsing PEM-encoded keys (RFC 7468) into a keyset. |
| class SignaturePemKeysetReader : public KeysetReader { |
| public: |
| util::StatusOr<std::unique_ptr<::google::crypto::tink::EncryptedKeyset>> |
| ReadEncrypted() override; |
| |
| protected: |
| explicit SignaturePemKeysetReader( |
| const std::vector<PemKey>& pem_serialized_keys) |
| : pem_serialized_keys_(pem_serialized_keys) {} |
| |
| // PEM-serialized keys to parse. |
| std::vector<PemKey> pem_serialized_keys_; |
| }; |
| |
| // Builder class for creating a PEM reader. Example usage: |
| // |
| // std::string some_public_key_pem = ...; |
| // PemKeyType key_type = ...; |
| // size_t key_size_in_bits = ...; |
| // HashType hash_type = ...; |
| // PemAlgorithm algorithm = ...; |
| // |
| // auto builder = SignaturePemKeysetReaderBuilder( |
| // PemKeysetReaderBuilder::PemReaderType::PUBLIC_KEY_VERIFY); |
| // builder.Add( |
| // {.serialized_key = some_rsa_public_key_pem, |
| // .parameters = { |
| // .key_type = key_type, |
| // .algorithm = algorithm, |
| // .key_size_in_bits = key_size_in_bits, |
| // .hash_type = hash_type}}); |
| // ... |
| // auto reader_statusor = builder.Build(); |
| // if (!reader_statusor.ok()) /* handle failure */ |
| // |
| // auto keyset_handle_statusor = |
| // CleartextKeysetHandle::Read(*reader_statusor); |
| class SignaturePemKeysetReaderBuilder { |
| public: |
| // Type of reader to build. The builder type depends on the primitive |
| // supported by the keys to parse. |
| enum PemReaderType { PUBLIC_KEY_SIGN, PUBLIC_KEY_VERIFY }; |
| |
| explicit SignaturePemKeysetReaderBuilder(PemReaderType pem_reader_type) |
| : pem_reader_type_(pem_reader_type) {} |
| |
| // Adds a PEM serialized key `pem_serialized_key` to the builder. |
| void Add(const PemKey& pem_serialized_key); |
| |
| // Creates an instance of keyset reader based on `pem_reader_type_`, to parse |
| // the PEM-encoded keys in `pem_serialized_keys_`. |
| util::StatusOr<std::unique_ptr<KeysetReader>> Build(); |
| |
| private: |
| // List of keys as PEM serialized items. |
| std::vector<PemKey> pem_serialized_keys_; |
| // Reader type that this reader must support. |
| PemReaderType pem_reader_type_; |
| }; |
| |
| // Keyset reader for PEM keys that support the PublicKeySign principal. |
| class PublicKeySignPemKeysetReader : public SignaturePemKeysetReader { |
| public: |
| util::StatusOr<std::unique_ptr<::google::crypto::tink::Keyset>> Read() |
| override; |
| |
| private: |
| // Friend builder class. |
| friend class SignaturePemKeysetReaderBuilder; |
| |
| explicit PublicKeySignPemKeysetReader( |
| const std::vector<PemKey> pem_serialized_keys) |
| : SignaturePemKeysetReader(pem_serialized_keys) {} |
| }; |
| |
| // Keyset reader for PEM keys that support the PublicKeyVerify principal. |
| class PublicKeyVerifyPemKeysetReader : public SignaturePemKeysetReader { |
| public: |
| util::StatusOr<std::unique_ptr<::google::crypto::tink::Keyset>> Read() |
| override; |
| |
| private: |
| // Friend builder class. |
| friend class SignaturePemKeysetReaderBuilder; |
| |
| explicit PublicKeyVerifyPemKeysetReader( |
| const std::vector<PemKey> pem_serialized_keys) |
| : SignaturePemKeysetReader(pem_serialized_keys) {} |
| }; |
| |
| } // namespace tink |
| } // namespace crypto |
| |
| #endif // TINK_SIGNATURE_SIGNATURE_PEM_KEYSET_READER_H_ |