Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-17 08:28:53

0001 // Licensed to the Apache Software Foundation (ASF) under one
0002 // or more contributor license agreements.  See the NOTICE file
0003 // distributed with this work for additional information
0004 // regarding copyright ownership.  The ASF licenses this file
0005 // to you under the Apache License, Version 2.0 (the
0006 // "License"); you may not use this file except in compliance
0007 // with the License.  You may obtain a copy of the License at
0008 //
0009 //   http://www.apache.org/licenses/LICENSE-2.0
0010 //
0011 // Unless required by applicable law or agreed to in writing,
0012 // software distributed under the License is distributed on an
0013 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0014 // KIND, either express or implied.  See the License for the
0015 // specific language governing permissions and limitations
0016 // under the License.
0017 
0018 #pragma once
0019 
0020 #include <memory>
0021 #include <string>
0022 #include <unordered_map>
0023 
0024 #include "arrow/util/concurrent_map.h"
0025 
0026 #include "parquet/encryption/file_key_material_store.h"
0027 #include "parquet/encryption/key_encryption_key.h"
0028 #include "parquet/encryption/key_toolkit.h"
0029 #include "parquet/encryption/kms_client.h"
0030 #include "parquet/platform.h"
0031 
0032 namespace parquet::encryption {
0033 
0034 // This class will generate "key metadata" from "data encryption key" and "master key",
0035 // following these steps:
0036 // 1. Wrap "data encryption key". There are 2 modes:
0037 //   1.1. single wrapping: encrypt "data encryption key" directly with "master encryption
0038 //        key"
0039 //   1.2. double wrapping: 2 steps:
0040 //     1.2.1. "key encryption key" is randomized (see KeyEncryptionKey class)
0041 //     1.2.2. "data encryption key" is encrypted with the above "key encryption key"
0042 // 2. Create "key material" (see structure in KeyMaterial class)
0043 // 3. Create "key metadata" with "key material" inside or a reference to outside "key
0044 //    material" (see structure in KeyMetadata class).
0045 class PARQUET_EXPORT FileKeyWrapper {
0046  public:
0047   static constexpr int kKeyEncryptionKeyLength = 16;
0048   static constexpr int kKeyEncryptionKeyIdLength = 16;
0049 
0050   /// key_toolkit and kms_connection_config is to get KmsClient from the cache or create
0051   /// KmsClient if it's not in the cache yet. cache_entry_lifetime_seconds is life time of
0052   /// KmsClient in the cache. key_material_store is to store "key material" outside
0053   /// parquet file, NULL if "key material" is stored inside parquet file.
0054   FileKeyWrapper(KeyToolkit* key_toolkit,
0055                  const KmsConnectionConfig& kms_connection_config,
0056                  std::shared_ptr<FileKeyMaterialStore> key_material_store,
0057                  double cache_entry_lifetime_seconds, bool double_wrapping);
0058 
0059   /// Creates key_metadata field for a given data key, via wrapping the key with the
0060   /// master key.
0061   /// When external key material is used, an identifier is usually generated automatically
0062   /// but may be specified explicitly to support key rotation,
0063   /// which requires keeping the same identifiers.
0064   std::string GetEncryptionKeyMetadata(const ::arrow::util::SecureString& data_key,
0065                                        const std::string& master_key_id,
0066                                        bool is_footer_key,
0067                                        std::string key_id_in_file = "");
0068 
0069  private:
0070   KeyEncryptionKey CreateKeyEncryptionKey(const std::string& master_key_id);
0071 
0072   /// A map of Master Encryption Key ID -> KeyEncryptionKey, for the current token
0073   std::shared_ptr<::arrow::util::ConcurrentMap<std::string, KeyEncryptionKey>>
0074       kek_per_master_key_id_;
0075 
0076   std::shared_ptr<KmsClient> kms_client_;
0077   KmsConnectionConfig kms_connection_config_;
0078   std::shared_ptr<FileKeyMaterialStore> key_material_store_;
0079   const double cache_entry_lifetime_seconds_;
0080   const bool double_wrapping_;
0081   uint16_t key_counter_;
0082 };
0083 
0084 }  // namespace parquet::encryption