| 314 | } |
| 315 | |
| 316 | void CompressionCodecEncrypted::Configuration::loadImpl( |
| 317 | const Poco::Util::AbstractConfiguration & config, const String & config_prefix, EncryptionMethod method, std::unique_ptr<Params> & new_params) |
| 318 | { |
| 319 | // if method is not smaller than MAX_ENCRYPTION_METHOD it is incorrect |
| 320 | if (method >= MAX_ENCRYPTION_METHOD) |
| 321 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong argument for loading configurations."); |
| 322 | |
| 323 | /// Scan all keys in config and add them into storage. If key is in hex, transform it. |
| 324 | /// Remember key ID for each key, because it will be used in encryption/decryption |
| 325 | Strings config_keys; |
| 326 | config.keys(config_prefix, config_keys); |
| 327 | for (const std::string & config_key : config_keys) |
| 328 | { |
| 329 | String key; |
| 330 | UInt64 key_id = 0; |
| 331 | |
| 332 | if ((config_key == "key") || config_key.starts_with("key[")) |
| 333 | { |
| 334 | key = config.getString(config_prefix + "." + config_key, ""); |
| 335 | key_id = config.getUInt64(config_prefix + "." + config_key + "[@id]", 0); |
| 336 | } |
| 337 | else if ((config_key == "key_hex") || config_key.starts_with("key_hex[")) |
| 338 | { |
| 339 | key = unhexKey(config.getString(config_prefix + "." + config_key, "")); |
| 340 | key_id = config.getUInt64(config_prefix + "." + config_key + "[@id]", 0); |
| 341 | } |
| 342 | else |
| 343 | continue; |
| 344 | |
| 345 | /// For each key its id should be unique. |
| 346 | if (new_params->keys_storage[method].contains(key_id)) |
| 347 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Multiple keys have the same ID {}", key_id); |
| 348 | |
| 349 | /// Check size of key. Its length depends on encryption algorithm. |
| 350 | if (key.size() != methodKeySize(method)) |
| 351 | throw Exception( |
| 352 | ErrorCodes::BAD_ARGUMENTS, |
| 353 | "Got an encryption key with unexpected size {}, the size should be {}", |
| 354 | key.size(), methodKeySize(method)); |
| 355 | |
| 356 | new_params->keys_storage[method][key_id] = key; |
| 357 | } |
| 358 | |
| 359 | /// Check that we have at least one key for this method (otherwise it is incorrect to use it). |
| 360 | if (new_params->keys_storage[method].empty()) |
| 361 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "No keys, an encryption needs keys to work"); |
| 362 | |
| 363 | if (!config.has(config_prefix + ".current_key_id")) |
| 364 | { |
| 365 | /// In case of multiple keys, current_key_id is mandatory |
| 366 | if (new_params->keys_storage[method].size() > 1) |
| 367 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "There are multiple keys in config. current_key_id is required"); |
| 368 | |
| 369 | /// If there is only one key with non zero ID, curren_key_id should be defined. |
| 370 | if (new_params->keys_storage[method].size() == 1 && !new_params->keys_storage[method].contains(0)) |
| 371 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Config has one key with non zero id. current_key_id is required"); |
| 372 | } |
| 373 | |