| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you 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. |
| |
| #include "kudu/ranger-kms/ranger_kms_client.h" |
| |
| #include <string> |
| #include <vector> |
| |
| #include <glog/logging.h> |
| #include <rapidjson/document.h> |
| |
| #include "kudu/gutil/strings/escaping.h" |
| #include "kudu/gutil/strings/substitute.h" |
| #include "kudu/util/curl_util.h" |
| #include "kudu/util/easy_json.h" |
| #include "kudu/util/faststring.h" |
| #include "kudu/util/jsonreader.h" |
| |
| using rapidjson::Value; |
| using std::string; |
| using std::vector; |
| using strings::a2b_hex; |
| using strings::b2a_hex; |
| using strings::Substitute; |
| using strings::WebSafeBase64Escape; |
| using strings::WebSafeBase64Unescape; |
| |
| namespace kudu { |
| namespace security { |
| |
| Status RangerKMSClient::DecryptKey(const string& encrypted_key, |
| const string& iv, |
| const string& key_version, |
| string* decrypted_key) { |
| EasyJson payload; |
| payload.Set("name", cluster_key_name_); |
| string iv_plain = a2b_hex(iv); |
| string iv_b64; |
| WebSafeBase64Escape(iv_plain, &iv_b64); |
| payload.Set("iv", iv_b64); |
| string eek_plain = a2b_hex(encrypted_key); |
| string eek_b64; |
| WebSafeBase64Escape(eek_plain, &eek_b64); |
| payload.Set("material", eek_b64); |
| EasyCurl curl; |
| curl.set_auth(CurlAuthType::SPNEGO); |
| string url = Substitute("$0/v1/keyversion/$1/_eek?eek_op=decrypt", |
| kms_url_, key_version); |
| faststring resp; |
| RETURN_NOT_OK_PREPEND( |
| curl.PostToURL(url, payload.ToString(), &resp, {"Content-Type: application/json"}), |
| "failed to decrypt server key"); |
| JsonReader r(resp.ToString()); |
| RETURN_NOT_OK(r.Init()); |
| string dek_b64; |
| RETURN_NOT_OK(r.ExtractString(r.root(), "material", &dek_b64)); |
| string dek_plain; |
| WebSafeBase64Unescape(dek_b64, &dek_plain); |
| *decrypted_key = b2a_hex(dek_plain); |
| return Status::OK(); |
| } |
| |
| Status RangerKMSClient::GenerateEncryptedServerKey(string* encrypted_key, |
| string* iv, |
| string* key_version) { |
| EasyCurl curl; |
| curl.set_auth(CurlAuthType::SPNEGO); |
| string url = Substitute("$0/v1/key/$1/_eek?eek_op=generate&num_keys=1", |
| kms_url_, cluster_key_name_); |
| faststring resp; |
| RETURN_NOT_OK_PREPEND(curl.FetchURL(url, &resp), "failed to generate server key"); |
| JsonReader r(resp.ToString()); |
| RETURN_NOT_OK(r.Init()); |
| vector<const Value*> keys; |
| RETURN_NOT_OK(r.ExtractObjectArray(r.root(), nullptr, &keys)); |
| string iv_b64; |
| DCHECK_GT(keys.size(), 0); |
| const Value* key = keys[0]; |
| RETURN_NOT_OK(r.ExtractString(key, "iv", &iv_b64)); |
| string iv_plain; |
| if (!WebSafeBase64Unescape(iv_b64, &iv_plain)) { |
| return Status::Corruption("Invalid IV received"); |
| } |
| *iv = b2a_hex(iv_plain); |
| RETURN_NOT_OK(r.ExtractString(key, "versionName", key_version)); |
| const Value* ekv = nullptr; |
| RETURN_NOT_OK(r.ExtractObject(key, "encryptedKeyVersion", &ekv)); |
| string key_b64; |
| RETURN_NOT_OK(r.ExtractString(ekv, "material", &key_b64)); |
| string key_plain; |
| if (!WebSafeBase64Unescape(key_b64, &key_plain)) { |
| return Status::Corruption("Invalid encryption key received"); |
| } |
| *encrypted_key = b2a_hex(key_plain); |
| return Status::OK(); |
| } |
| |
| } // namespace security |
| } // namespace kudu |