Repository: incubator-hawq
Updated Branches:
  refs/heads/master 71bb3676a -> 3bdc19464


HAWQ-1509. Support TDE read function.


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/90f1c4de
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/90f1c4de
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/90f1c4de

Branch: refs/heads/master
Commit: 90f1c4ded4321adfa98a691a0b1b47f727316738
Parents: 71bb367
Author: amyrazz44 <a...@pivotal.io>
Authored: Mon Aug 7 12:53:36 2017 +0800
Committer: amyrazz44 <a...@pivotal.io>
Committed: Mon Aug 7 12:53:36 2017 +0800

----------------------------------------------------------------------
 depends/libhdfs3/src/client/CryptoCodec.cpp     | 37 ++++++++++--------
 depends/libhdfs3/src/client/CryptoCodec.h       | 10 +++++
 depends/libhdfs3/src/client/InputStreamImpl.cpp | 41 +++++++++++++++++++-
 depends/libhdfs3/src/client/InputStreamImpl.h   | 26 +++++++++++++
 4 files changed, 97 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/90f1c4de/depends/libhdfs3/src/client/CryptoCodec.cpp
----------------------------------------------------------------------
diff --git a/depends/libhdfs3/src/client/CryptoCodec.cpp 
b/depends/libhdfs3/src/client/CryptoCodec.cpp
index 77ccf09..417f51e 100644
--- a/depends/libhdfs3/src/client/CryptoCodec.cpp
+++ b/depends/libhdfs3/src/client/CryptoCodec.cpp
@@ -101,15 +101,15 @@ namespace Hdfs {
        }
 
        int CryptoCodec::init(CryptoMethod crypto_method, int64_t 
stream_offset) {
-               //check already init
+               // Check CryptoCodec init or not.
                if (is_init)
                        return 0;
 
-               // Get decrypted key from KMS
-               std::string key = getDecryptedKeyFromKms();
+               // Get decrypted key from KMS.
+               decryptedKey = getDecryptedKeyFromKms();
 
-               // Select cipher method based on the key length
-               uint64_t AlgorithmBlockSize = key.length();
+               // Select cipher method based on the decrypted key length.
+               AlgorithmBlockSize = decryptedKey.length();
                if (AlgorithmBlockSize == KEY_LENGTH_256) {
                        cipher = EVP_aes_256_ctr();
                } else if (AlgorithmBlockSize == KEY_LENGTH_128) {
@@ -119,7 +119,17 @@ namespace Hdfs {
                        return -1;
                }
 
-               //calculate new IV when appending a existed file
+               // Calculate iv and counter in order to init cipher context 
with cipher method. Default value is 0.
+               resetStreamOffset(crypto_method, stream_offset);
+
+               LOG(DEBUG3, "CryptoCodec init success, length of the decrypted 
key is : %llu, crypto method is : %d", AlgorithmBlockSize, crypto_method);
+               is_init = true;
+               return 1;
+
+       }
+
+       int CryptoCodec::resetStreamOffset(CryptoMethod crypto_method, int64_t 
stream_offset) {
+               // Calculate new IV when appending an existed file.
                std::string iv = encryptionInfo->getIv();
                if (stream_offset > 0) {
                        counter = stream_offset / AlgorithmBlockSize;
@@ -127,25 +137,20 @@ namespace Hdfs {
                        iv = this->calculateIV(iv, counter);
                }
 
-               //judge encrypt/decrypt
-               int enc = 0;
-               method = crypto_method;
-               if (method == CryptoMethod::ENCRYPT)
-                       enc = 1;
+               // Judge the crypto method is encrypt or decrypt.
+               int enc = (method == CryptoMethod::ENCRYPT) ? 1 : 0;
 
-               // Init cipher context with cipher method
+               // Init cipher context with cipher method.
                if (!EVP_CipherInit_ex(cipherCtx, cipher, NULL,
-                               (const unsigned char *) key.c_str(), (const 
unsigned char *) iv.c_str(),
+                               (const unsigned char *) decryptedKey.c_str(), 
(const unsigned char *) iv.c_str(),
                                enc)) {
                        LOG(WARNING, "EVP_CipherInit_ex failed");
                        return -1;
                }
 
-               //AES/CTR/NoPadding 
+               // AES/CTR/NoPadding, set padding to 0.
                EVP_CIPHER_CTX_set_padding(cipherCtx, 0);
 
-               LOG(DEBUG3, "CryptoCodec init success, key_length:%llu, 
is_encode:%d", AlgorithmBlockSize, enc);
-               is_init = true;
                return 1;
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/90f1c4de/depends/libhdfs3/src/client/CryptoCodec.h
----------------------------------------------------------------------
diff --git a/depends/libhdfs3/src/client/CryptoCodec.h 
b/depends/libhdfs3/src/client/CryptoCodec.h
index 45b1088..ee68637 100644
--- a/depends/libhdfs3/src/client/CryptoCodec.h
+++ b/depends/libhdfs3/src/client/CryptoCodec.h
@@ -71,6 +71,14 @@ namespace Hdfs {
                 */
                virtual int init(CryptoMethod crypto_method, int64_t 
stream_offset = 0);
 
+               /**
+                * Reset iv and padding value when seek file.
+                * @param crypto_method do encrypt/decrypt work according to 
crypto_method.
+                * @param stream_offset the offset of the current file.
+                * @return 1 sucess; 0 already initialized; -1 failed.
+                */
+               virtual int resetStreamOffset(CryptoMethod crypto_method, 
int64_t stream_offset);
+
        private:
 
                /**
@@ -96,6 +104,8 @@ namespace Hdfs {
                int32_t bufSize;
                int64_t padding;
                int64_t counter;
+               std::string decryptedKey;
+               uint64_t AlgorithmBlockSize;
        };
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/90f1c4de/depends/libhdfs3/src/client/InputStreamImpl.cpp
----------------------------------------------------------------------
diff --git a/depends/libhdfs3/src/client/InputStreamImpl.cpp 
b/depends/libhdfs3/src/client/InputStreamImpl.cpp
index 05f27a5..c899a83 100644
--- a/depends/libhdfs3/src/client/InputStreamImpl.cpp
+++ b/depends/libhdfs3/src/client/InputStreamImpl.cpp
@@ -432,6 +432,25 @@ void 
InputStreamImpl::openInternal(shared_ptr<FileSystemInter> fs, const char *
         peerCache = &fs->getPeerCache();
         updateBlockInfos();
         closed = false;
+        /* If file is encrypted , then initialize CryptoCodec. */
+        fileStatus = fs->getFileStatus(this->path.c_str());
+        FileEncryptionInfo *fileEnInfo = fileStatus.getFileEncryption();
+        if (fileStatus.isFileEncrypted()) {
+            if (cryptoCodec == NULL) {
+                enAuth = shared_ptr<RpcAuth> (
+                        new RpcAuth(fs->getUserInfo(), 
RpcAuth::ParseMethod(conf->getKmsMethod())));
+                kcp = shared_ptr<KmsClientProvider> (
+                        new KmsClientProvider(enAuth, conf));
+                cryptoCodec = shared_ptr<CryptoCodec> (
+                        new CryptoCodec(fileEnInfo, kcp, 
conf->getCryptoBufferSize()));
+
+                int64_t file_length = 0;
+                int ret = cryptoCodec->init(CryptoMethod::DECRYPT, 
file_length);
+                if (ret < 0) {
+                    THROW(HdfsIOException, "init CryptoCodec failed, file:%s", 
this->path.c_str());
+                }
+            }
+         }
     } catch (const HdfsCanceled & e) {
         throw;
     } catch (const FileNotFoundException & e) {
@@ -626,6 +645,12 @@ int32_t InputStreamImpl::readInternal(char * buf, int32_t 
size) {
 
                 continue;
             }
+            std::string bufDecode;
+            if (fileStatus.isFileEncrypted()) {
+                /* Decrypt buffer if the file is encrypted. */
+                bufDecode = cryptoCodec->cipher_wrap(buf, size);
+                memcpy(buf, bufDecode.c_str(), size);
+            }
 
             return retval;
         } while (true);
@@ -734,9 +759,17 @@ void InputStreamImpl::seekInternal(int64_t pos) {
     }
 
     try {
-        if (blockReader && pos > cursor && pos < endOfCurBlock) {
+        if (blockReader && pos > cursor && pos < endOfCurBlock && (pos - 
cursor) < blockReader->available()) {
             blockReader->skip(pos - cursor);
             cursor = pos;
+            if (cryptoCodec) {
+                int ret = cryptoCodec->resetStreamOffset(CryptoMethod::DECRYPT,
+                        cursor);
+                if (ret < 0) {
+                    THROW(HdfsIOException, "init CryptoCodec failed, file:%s",
+                            this->path.c_str());
+                }
+            }
             return;
         }
     } catch (const HdfsIOException & e) {
@@ -758,6 +791,12 @@ void InputStreamImpl::seekInternal(int64_t pos) {
     endOfCurBlock = 0;
     blockReader.reset();
     cursor = pos;
+    if (cryptoCodec) {
+        int ret = cryptoCodec->resetStreamOffset(CryptoMethod::DECRYPT, 
cursor);
+        if (ret < 0) {
+            THROW(HdfsIOException, "init CryptoCodec failed, file:%s", 
this->path.c_str());
+        }
+    }
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/90f1c4de/depends/libhdfs3/src/client/InputStreamImpl.h
----------------------------------------------------------------------
diff --git a/depends/libhdfs3/src/client/InputStreamImpl.h 
b/depends/libhdfs3/src/client/InputStreamImpl.h
index e3c55ce..12a8e08 100644
--- a/depends/libhdfs3/src/client/InputStreamImpl.h
+++ b/depends/libhdfs3/src/client/InputStreamImpl.h
@@ -37,6 +37,8 @@
 #include "server/LocatedBlocks.h"
 #include "SessionConfig.h"
 #include "Unordered.h"
+#include "CryptoCodec.h"
+#include "KmsClientProvider.h"
 
 #ifdef MOCK
 #include "TestDatanodeStub.h"
@@ -101,6 +103,26 @@ public:
      * @return return a printable string
      */
     std::string toString();
+    
+    /**
+     * Get KmsClientProvider.
+     */
+    shared_ptr<KmsClientProvider> getKmsClientProvider();
+
+    /**
+     * Set KmsClientProvider.
+     */
+    void setKmsClientProvider(shared_ptr<KmsClientProvider> kcp);
+
+    /**
+     * Get CryptoCodec.
+     */
+    shared_ptr<CryptoCodec> getCryptoCodec();
+
+    /**
+     * Set CryptoCodec.
+     */
+    void setCryptoCodec(shared_ptr<CryptoCodec> cryptoCodec);
 
 private:
     bool choseBestNode();
@@ -141,6 +163,10 @@ private:
     std::string path;
     std::vector<DatanodeInfo> failedNodes;
     std::vector<char> localReaderBuffer;
+    shared_ptr<CryptoCodec> cryptoCodec;
+    shared_ptr<KmsClientProvider> kcp;
+    shared_ptr<RpcAuth> enAuth;
+    FileStatus fileStatus;
 
 #ifdef MOCK
 private:

Reply via email to