| 37 | } |
| 38 | |
| 39 | std::shared_ptr<FileEncryptionProperties> CryptoFactory::GetFileEncryptionProperties( |
| 40 | const KmsConnectionConfig& kms_connection_config, |
| 41 | const EncryptionConfiguration& encryption_config, const std::string& file_path, |
| 42 | const std::shared_ptr<::arrow::fs::FileSystem>& file_system) { |
| 43 | if (!encryption_config.uniform_encryption && encryption_config.column_keys.empty()) { |
| 44 | throw ParquetException("Either column_keys or uniform_encryption must be set"); |
| 45 | } else if (encryption_config.uniform_encryption && |
| 46 | !encryption_config.column_keys.empty()) { |
| 47 | throw ParquetException("Cannot set both column_keys and uniform_encryption"); |
| 48 | } |
| 49 | const std::string& footer_key_id = encryption_config.footer_key; |
| 50 | const std::string& column_key_str = encryption_config.column_keys; |
| 51 | |
| 52 | std::shared_ptr<FileKeyMaterialStore> key_material_store = nullptr; |
| 53 | if (!encryption_config.internal_key_material) { |
| 54 | try { |
| 55 | key_material_store = |
| 56 | FileSystemKeyMaterialStore::Make(file_path, file_system, false); |
| 57 | } catch (ParquetException& e) { |
| 58 | std::stringstream ss; |
| 59 | ss << "Failed to get key material store.\n" << e.what() << "\n"; |
| 60 | throw ParquetException(ss.str()); |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | FileKeyWrapper key_wrapper(key_toolkit_.get(), kms_connection_config, |
| 65 | key_material_store, encryption_config.cache_lifetime_seconds, |
| 66 | encryption_config.double_wrapping); |
| 67 | |
| 68 | int32_t dek_length_bits = encryption_config.data_key_length_bits; |
| 69 | if (!internal::ValidateKeyLength(dek_length_bits)) { |
| 70 | std::ostringstream ss; |
| 71 | ss << "Wrong data key length : " << dek_length_bits; |
| 72 | throw ParquetException(ss.str()); |
| 73 | } |
| 74 | |
| 75 | int dek_length = dek_length_bits / 8; |
| 76 | |
| 77 | SecureString footer_key(dek_length, '\0'); |
| 78 | RandBytes(footer_key.as_span().data(), footer_key.size()); |
| 79 | |
| 80 | std::string footer_key_metadata = |
| 81 | key_wrapper.GetEncryptionKeyMetadata(footer_key, footer_key_id, true); |
| 82 | |
| 83 | FileEncryptionProperties::Builder properties_builder = |
| 84 | FileEncryptionProperties::Builder(footer_key); |
| 85 | properties_builder.footer_key_metadata(std::move(footer_key_metadata)); |
| 86 | properties_builder.algorithm(encryption_config.encryption_algorithm); |
| 87 | |
| 88 | if (!encryption_config.uniform_encryption) { |
| 89 | ColumnPathToEncryptionPropertiesMap encrypted_columns = |
| 90 | GetColumnEncryptionProperties(dek_length, column_key_str, &key_wrapper); |
| 91 | properties_builder.encrypted_columns(std::move(encrypted_columns)); |
| 92 | |
| 93 | if (encryption_config.plaintext_footer) { |
| 94 | properties_builder.set_plaintext_footer(); |
| 95 | } |
| 96 | } |