Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ build/variables.mk: Makefile build/archive/contents/Makefile $(UI_ROOT)/Makefile
# common because both the root Makefile and protobuf.mk have C dependencies.

C_DEPS_DIR := $(abspath c-deps)
CRYPTOPP_SRC_DIR := $(C_DEPS_DIR)/cryptopp
JEMALLOC_SRC_DIR := $(C_DEPS_DIR)/jemalloc
PROTOBUF_SRC_DIR := $(C_DEPS_DIR)/protobuf
ROCKSDB_SRC_DIR := $(C_DEPS_DIR)/rocksdb
Expand Down Expand Up @@ -459,6 +460,7 @@ ifdef MINGW
BUILD_DIR := $(shell cygpath -m $(BUILD_DIR))
endif

CRYPTOPP_DIR := $(BUILD_DIR)/cryptopp
JEMALLOC_DIR := $(BUILD_DIR)/jemalloc
PROTOBUF_DIR := $(BUILD_DIR)/protobuf
ROCKSDB_DIR := $(BUILD_DIR)/rocksdb$(STDMALLOC_SUFFIX)$(if $(ENABLE_ROCKSDB_ASSERTIONS),_assert)
Expand All @@ -469,7 +471,7 @@ PROTOC_DIR := $(GOPATH)/native/$(HOST_TRIPLE)/protobuf
PROTOC := $(PROTOC_DIR)/protoc

C_LIBS_OSS = $(if $(USE_STDMALLOC),,libjemalloc) libprotobuf libsnappy librocksdb libroach
C_LIBS_CCL = $(C_LIBS_OSS) libroachccl
C_LIBS_CCL = $(C_LIBS_OSS) libcryptopp libroachccl

# Go does not permit dashes in build tags. This is undocumented. Fun!
NATIVE_SPECIFIER_TAG := $(subst -,_,$(NATIVE_SPECIFIER))$(STDMALLOC_SUFFIX)
Expand Down Expand Up @@ -510,7 +512,7 @@ $(CGO_FLAGS_FILES): Makefile
@echo 'package $(notdir $(@D))' >> $@
@echo >> $@
@echo '// #cgo CPPFLAGS: -I$(JEMALLOC_DIR)/include' >> $@
@echo '// #cgo LDFLAGS: $(addprefix -L,$(PROTOBUF_DIR) $(JEMALLOC_DIR)/lib $(SNAPPY_DIR) $(ROCKSDB_DIR) $(LIBROACH_DIR))' >> $@
@echo '// #cgo LDFLAGS: $(addprefix -L,$(CRYPTOPP_DIR) $(PROTOBUF_DIR) $(JEMALLOC_DIR)/lib $(SNAPPY_DIR) $(ROCKSDB_DIR) $(LIBROACH_DIR))' >> $@
@echo 'import "C"' >> $@

# BUILD ARTIFACT CACHING
Expand All @@ -532,6 +534,12 @@ $(CGO_FLAGS_FILES): Makefile
# only rebuild the affected objects, but in practice dependencies on configure
# flags are not tracked correctly, and these stale artifacts can cause
# particularly hard-to-debug errors.
$(CRYPTOPP_DIR)/Makefile: $(C_DEPS_DIR)/cryptopp-rebuild $(BOOTSTRAP_TARGET)
rm -rf $(CRYPTOPP_DIR)
mkdir -p $(CRYPTOPP_DIR)
@# NOTE: If you change the CMake flags below, bump the version in
@# $(C_DEPS_DIR)/cryptopp-rebuild. See above for rationale.
cd $(CRYPTOPP_DIR) && cmake $(CMAKE_FLAGS) $(CRYPTOPP_SRC_DIR)

$(JEMALLOC_SRC_DIR)/configure.ac: $(BOOTSTRAP_TARGET)

Expand Down Expand Up @@ -591,7 +599,8 @@ $(LIBROACH_DIR)/Makefile: $(C_DEPS_DIR)/libroach-rebuild $(BOOTSTRAP_TARGET)
@# $(C_DEPS_DIR)/libroach-rebuild. See above for rationale.
cd $(LIBROACH_DIR) && cmake $(CMAKE_FLAGS) $(LIBROACH_SRC_DIR) -DCMAKE_BUILD_TYPE=Release \
-DPROTOBUF_LIB=$(PROTOBUF_DIR)/libprotobuf.a -DROCKSDB_LIB=$(ROCKSDB_DIR)/librocksdb.a \
-DJEMALLOC_LIB=$(JEMALLOC_DIR)/lib/libjemalloc.a -DSNAPPY_LIB=$(SNAPPY_DIR)/libsnappy.a
-DJEMALLOC_LIB=$(JEMALLOC_DIR)/lib/libjemalloc.a -DSNAPPY_LIB=$(SNAPPY_DIR)/libsnappy.a \
-DCRYPTOPP_LIB=$(CRYPTOPP_DIR)/libcryptopp.a

# We mark C and C++ dependencies as .PHONY (or .ALWAYS_REBUILD) to avoid
# having to name the artifact (for .PHONY), which can vary by platform, and so
Expand All @@ -602,6 +611,10 @@ $(LIBROACH_DIR)/Makefile: $(C_DEPS_DIR)/libroach-rebuild $(BOOTSTRAP_TARGET)
$(PROTOC): $(PROTOC_DIR)/Makefile .ALWAYS_REBUILD | libprotobuf
@$(MAKE) --no-print-directory -C $(PROTOC_DIR) protoc

.PHONY: libcryptopp
libcryptopp: $(CRYPTOPP_DIR)/Makefile
@$(MAKE) --no-print-directory -C $(CRYPTOPP_DIR) static

.PHONY: libjemalloc
libjemalloc: $(JEMALLOC_DIR)/Makefile
@$(MAKE) --no-print-directory -C $(JEMALLOC_DIR) build_lib_static
Expand All @@ -627,7 +640,7 @@ libroachccl: $(LIBROACH_DIR)/Makefile $(CPP_PROTOS_CCL_TARGET) libroach
@$(MAKE) --no-print-directory -C $(LIBROACH_DIR) roachccl

PHONY: check-libroach
check-libroach: $(LIBROACH_DIR)/Makefile libjemalloc libprotobuf libsnappy librocksdb
check-libroach: $(LIBROACH_DIR)/Makefile libjemalloc libprotobuf libsnappy librocksdb libcryptopp
@$(MAKE) --no-print-directory -C $(LIBROACH_DIR) check

override TAGS += make $(NATIVE_SPECIFIER_TAG)
Expand Down Expand Up @@ -1143,13 +1156,15 @@ c-deps-fmt: $(shell find $(LIBROACH_SRC_DIR) \( -name '*.cc' -o -name '*.h' \) -

.PHONY: clean-c-deps
clean-c-deps:
rm -rf $(CRYPTOPP_DIR)
rm -rf $(JEMALLOC_DIR)
rm -rf $(PROTOBUF_DIR)
rm -rf $(ROCKSDB_DIR)
rm -rf $(SNAPPY_DIR)

.PHONY: unsafe-clean-c-deps
unsafe-clean-c-deps:
git -C $(CRYPTOPP_SRC_DIR) clean -dxf
git -C $(JEMALLOC_SRC_DIR) clean -dxf
git -C $(PROTOBUF_SRC_DIR) clean -dxf
git -C $(ROCKSDB_SRC_DIR) clean -dxf
Expand Down
2 changes: 2 additions & 0 deletions build/variables.mk
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ define VALID_VARS
CPP_PROTO_ROOT
CPP_SOURCES
CPP_SOURCES_CCL
CRYPTOPP_DIR
CRYPTOPP_SRC_DIR
CXX_PATH
C_DEPS_DIR
C_LIBS_CCL
Expand Down
4 changes: 4 additions & 0 deletions c-deps/cryptopp-rebuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Bump the version below when changing cryptopp configure flags. Search for "BUILD
ARTIFACT CACHING" in build/common.mk for rationale.

1
2 changes: 1 addition & 1 deletion c-deps/libroach-rebuild
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Bump the version below when changing libroach CMake flags. Search for "BUILD
ARTIFACT CACHING" in build/common.mk for rationale.

1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c-deps/cryptopp-rebuild should get this same explanatory comment (sorry, GH won't let me comment there)

Thanks for remembering to bump this one!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uh. oops. I thought I had it. Turns out mine was blank.

2
35 changes: 28 additions & 7 deletions c-deps/libroach/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,22 @@ add_library(roach
)
target_include_directories(roach
PUBLIC ./include
PRIVATE ../protobuf/src ../rocksdb/include protos
PRIVATE ../protobuf/src
PRIVATE ../rocksdb/include
PRIVATE protos
)

add_library(roachccl
ccl/db.cc
ccl/key.cc
ccl/key_manager.cc
protosccl/ccl/baseccl/encryption_options.pb.cc
)
target_include_directories(roachccl
PRIVATE .. # CryptoPP headers are directly in the directory. Include .. to be able to include <cryptopp/....h>
PRIVATE ../protobuf/src
PRIVATE ../rocksdb/include
PRIVATE ../protobuf/src protosccl
PRIVATE protosccl
)
target_link_libraries(roachccl roach)

Expand All @@ -67,6 +73,7 @@ set(tests
db_test.cc
encoding_test.cc
ccl/db_test.cc
ccl/key_manager_test.cc
)

# "test" doesn't depend on the actual tests. Let's add a "check" target
Expand All @@ -92,20 +99,34 @@ foreach(tsrc ${tests})
endif()

# Add a new executable and set includes/libraries/properties.
add_executable(${tname} ${tsrc})
add_executable(${tname} ${tsrc} testutils.cc)
target_include_directories(${tname}
PRIVATE ../googletest/googletest/include
PRIVATE ../rocksdb/include
PRIVATE ../protobuf/src
PRIVATE ../rocksdb/include
)

# Link `ccl/` tests against roachccl.
# Link `ccl/` tests against roachccl and CryptoPP.
if(${tsrc} MATCHES "^ccl/")
target_link_libraries(${tname} roachccl)
target_link_libraries(${tname}
roachccl
${CRYPTOPP_LIB}
)
target_include_directories(${tname}
PRIVATE ../cryptopp
)
endif()

# Add all other libraries.
target_link_libraries(${tname} roach ${PROTOBUF_LIB} ${ROCKSDB_LIB} ${SNAPPY_LIB} ${JEMALLOC_LIB} gtest_main pthread)
target_link_libraries(${tname}
roach
gtest_main
pthread
${ROCKSDB_LIB}
${PROTOBUF_LIB}
${JEMALLOC_LIB}
${SNAPPY_LIB}
)

set_target_properties(${tname} PROPERTIES
CXX_STANDARD 11
Expand Down
9 changes: 9 additions & 0 deletions c-deps/libroach/ccl/db.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <rocksdb/utilities/write_batch_with_index.h>
#include <rocksdb/write_batch.h>
#include "../protosccl/ccl/baseccl/encryption_options.pb.h"
#include "key_manager.h"

const DBStatus kSuccess = {NULL, 0};

Expand All @@ -37,6 +38,14 @@ rocksdb::Status parse_extra_options(const DBSlice s) {
<< " old key: " << opts.key_files().old_key() << "\n"
<< " rotation duration: " << opts.data_key_rotation_period() << "\n";

std::shared_ptr<FileKeyManager> key_manager(
new FileKeyManager(rocksdb::Env::Default(), opts.key_files().current_key(), opts.key_files().old_key()));

rocksdb::Status status = key_manager->LoadKeys();
if (!status.ok()) {
return status;
}

return rocksdb::Status::InvalidArgument("encryption is not supported");
}

Expand Down
14 changes: 11 additions & 3 deletions c-deps/libroach/ccl/db_test.cc
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
#include <gtest/gtest.h>
// Copyright 2017 The Cockroach Authors.
//
// Licensed as a CockroachDB Enterprise file under the Cockroach Community
// License (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt

#include "../db.h"
#include "../testutils.h"

TEST(LibroachCCL, DBOpenHook) {
DBOptions db_opts;

// Try an empty extra_options.
db_opts.extra_options = ToDBSlice("");
EXPECT_TRUE(DBOpenHook(db_opts).ok());
EXPECT_OK(DBOpenHook(db_opts));

// Try extra_options with bad data.
db_opts.extra_options = ToDBSlice("blah");
EXPECT_STREQ("failed to parse extra options", DBOpenHook(db_opts).getState());
EXPECT_ERR(DBOpenHook(db_opts), "failed to parse extra options");
}
23 changes: 23 additions & 0 deletions c-deps/libroach/ccl/key.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2017 The Cockroach Authors.
//
// Licensed as a CockroachDB Enterprise file under the Cockroach Community
// License (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt

#include "key.h"
#include <cryptopp/filters.h>
#include <cryptopp/hex.h>
#include <cryptopp/sha.h>

std::string KeyHash(const std::string& k) {
std::string value;
CryptoPP::SHA256 hash;

CryptoPP::StringSource ss(
k, true /* PumpAll */,
new CryptoPP::HashFilter(hash, new CryptoPP::HexEncoder(new CryptoPP::StringSink(value), false /* uppercase */)));

return value;
}
34 changes: 34 additions & 0 deletions c-deps/libroach/ccl/key.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2017 The Cockroach Authors.
//
// Licensed as a CockroachDB Enterprise file under the Cockroach Community
// License (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt

#pragma once

#include <string>

typedef std::string KeyID;
typedef std::string RawKey;

enum EncryptionType { PLAIN, AES };

// EncryptionKey represents a key: type (PLAIN or AES) and actual key contents.
// TODO(mberhault): we would like to be able to mlock and madvise(MADV_DONTDUMP) the
// memory handling keys. This includes the permanent EncryptionKey and any temporary
// buffers (eg: when reading files).
struct EncryptionKey {
EncryptionType type;
// The Key ID is a sha-256 hash of the key contents. It is lowercase, without groupings or terminator.
// **WARNING**: the key ID is persisted to disk, do not change the format.
KeyID id;
RawKey key;
// source describes the source of the key. This could be a filename or
// simply a description of the generator (eg: "data key manager").
std::string source;
};

// KeyHash returns the sha-256 hash of the string. Returned value is in hexadecimal format.
std::string KeyHash(const std::string& k);
65 changes: 65 additions & 0 deletions c-deps/libroach/ccl/key_manager.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2017 The Cockroach Authors.
//
// Licensed as a CockroachDB Enterprise file under the Cockroach Community
// License (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt

#include "key_manager.h"
#include <cryptopp/modes.h>
#include <google/protobuf/stubs/stringprintf.h>
#include "../fmt.h"

static std::string kFilenamePlain = "plain";

static rocksdb::Status KeyFromFile(rocksdb::Env* env, const std::string& path, EncryptionKey* key) {
if (path == kFilenamePlain) {
// plaintext placeholder.
key->type = PLAIN;
key->id = "";
key->key = "";
key->source = kFilenamePlain;
return rocksdb::Status::OK();
}

// Real file, try to read it.
std::string contents;
auto status = rocksdb::ReadFileToString(env, path, &contents);
if (!status.ok()) {
return status;
}

// Check that the length is valid for AES.
auto key_length = contents.size();
if (key_length != 16 && key_length != 24 && key_length != 32) {
return rocksdb::Status::InvalidArgument(fmt::StringPrintf(
"key in file %s is %llu bytes long, AES keys can be 16, 24, or 32 bytes", path.c_str(), key_length));
}

// Fill in the key.
key->type = AES;
key->id = KeyHash(contents);
key->key = contents;
key->source = path;

return rocksdb::Status::OK();
}

rocksdb::Status FileKeyManager::LoadKeys() {
std::unique_ptr<EncryptionKey> active(new EncryptionKey());
rocksdb::Status status = KeyFromFile(env_, active_key_path_, active.get());
if (!status.ok()) {
return status;
}

std::unique_ptr<EncryptionKey> old(new EncryptionKey());
status = KeyFromFile(env_, old_key_path_, old.get());
if (!status.ok()) {
return status;
}

active_key_.swap(active);
old_key_.swap(old);
return rocksdb::Status::OK();
}
Loading