You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by to...@apache.org on 2017/02/01 21:25:44 UTC
[3/3] kudu git commit: Extract a static function to generate a
self-signed CA
Extract a static function to generate a self-signed CA
We had some similar code in a test case and in MasterCertAuthority. This
extracts a function to create a self-signed CA, as well as a test
utility function which creates both a self-signed CA and private key.
Currently the test utility is only used from one test case, but I have
plans to use it elsewhere.
Change-Id: Ib40add99ed96e4753a3810709c66d07c96ab70bd
Reviewed-on: http://gerrit.cloudera.org:8080/5844
Tested-by: Kudu Jenkins
Reviewed-by: Alexey Serbin <as...@cloudera.com>
Reviewed-by: Dan Burkert <da...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/86714152
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/86714152
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/86714152
Branch: refs/heads/master
Commit: 86714152d3122580984a28ad0fc46ed942d5020c
Parents: 431aee5
Author: Todd Lipcon <to...@apache.org>
Authored: Tue Jan 31 14:52:37 2017 -0800
Committer: Todd Lipcon <to...@apache.org>
Committed: Wed Feb 1 21:24:31 2017 +0000
----------------------------------------------------------------------
src/kudu/master/master_cert_authority.cc | 21 ++-------
src/kudu/security/CMakeLists.txt | 1 +
src/kudu/security/ca/cert_management-test.cc | 27 +++---------
src/kudu/security/ca/cert_management.cc | 20 +++++++++
src/kudu/security/ca/cert_management.h | 34 +++++++++------
src/kudu/security/security-test-util.cc | 52 +++++++++++++++++++++++
src/kudu/security/security-test-util.h | 11 ++++-
7 files changed, 112 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kudu/blob/86714152/src/kudu/master/master_cert_authority.cc
----------------------------------------------------------------------
diff --git a/src/kudu/master/master_cert_authority.cc b/src/kudu/master/master_cert_authority.cc
index 8b33991..45190a1 100644
--- a/src/kudu/master/master_cert_authority.cc
+++ b/src/kudu/master/master_cert_authority.cc
@@ -75,26 +75,13 @@ MasterCertAuthority::~MasterCertAuthority() {
Status MasterCertAuthority::Init() {
CHECK(!ca_private_key_);
- // Create a key for the self-signed CA.
- shared_ptr<PrivateKey> key(make_shared<PrivateKey>());
+ // Create a key and cert for the self-signed CA.
+ auto key = make_shared<PrivateKey>();
+ auto ca_cert = make_shared<Cert>();
RETURN_NOT_OK(GeneratePrivateKey(FLAGS_master_ca_rsa_key_length_bits,
key.get()));
- // Generate a CSR for the CA.
- CertSignRequest ca_csr;
- {
- CaCertRequestGenerator gen(PrepareCaConfig(server_uuid_));
- RETURN_NOT_OK(gen.Init());
- RETURN_NOT_OK(gen.GenerateRequest(*key, &ca_csr));
- }
-
- // Self-sign the CA's CSR.
- auto ca_cert = make_shared<Cert>();
- {
- CertSigner ca_signer;
- RETURN_NOT_OK(ca_signer.InitForSelfSigning(key));
- RETURN_NOT_OK(ca_signer.Sign(ca_csr, ca_cert.get()));
- }
+ RETURN_NOT_OK(CertSigner::SelfSignCA(key, PrepareCaConfig(server_uuid_), ca_cert.get()));
// Initialize our signer with the new CA.
auto signer = make_shared<CertSigner>();
http://git-wip-us.apache.org/repos/asf/kudu/blob/86714152/src/kudu/security/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/security/CMakeLists.txt b/src/kudu/security/CMakeLists.txt
index 2627b77..4a4501f 100644
--- a/src/kudu/security/CMakeLists.txt
+++ b/src/kudu/security/CMakeLists.txt
@@ -90,6 +90,7 @@ ADD_EXPORTABLE_LIBRARY(security
if (NOT NO_TESTS)
set(SECURITY_TEST_SRCS
+ security-test-util.cc
test/mini_kdc.cc
test/test_certs.cc)
http://git-wip-us.apache.org/repos/asf/kudu/blob/86714152/src/kudu/security/ca/cert_management-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/security/ca/cert_management-test.cc b/src/kudu/security/ca/cert_management-test.cc
index c4d9084..39dfec8 100644
--- a/src/kudu/security/ca/cert_management-test.cc
+++ b/src/kudu/security/ca/cert_management-test.cc
@@ -17,6 +17,7 @@
#include "kudu/security/ca/cert_management.h"
+#include <memory>
#include <thread>
#include <utility>
#include <vector>
@@ -26,6 +27,7 @@
#include "kudu/gutil/strings/util.h"
#include "kudu/security/cert.h"
#include "kudu/security/openssl_util.h"
+#include "kudu/security/security-test-util.h"
#include "kudu/security/test/test_certs.h"
#include "kudu/util/env.h"
#include "kudu/util/path_util.h"
@@ -33,6 +35,7 @@
#include "kudu/util/test_macros.h"
#include "kudu/util/test_util.h"
+using std::shared_ptr;
using std::string;
using std::vector;
using std::thread;
@@ -372,27 +375,9 @@ TEST_F(CertManagementTest, SignCaCert) {
// Test the creation and use of a CA which uses a self-signed CA cert
// generated on the fly.
TEST_F(CertManagementTest, TestSelfSignedCA) {
- // Create a key for the self-signed CA.
- auto ca_key = std::make_shared<PrivateKey>();
- ASSERT_OK(GeneratePrivateKey(2048, ca_key.get()));
-
- // Generate a CSR for the CA.
- CertSignRequest ca_csr;
- {
- const CertRequestGenerator::Config gen_config(
- PrepareConfig("8C084CF6-A30B-4F5B-9673-A73E62E29A9D"));
- CaCertRequestGenerator gen(gen_config);
- ASSERT_OK(gen.Init());
- ASSERT_OK(gen.GenerateRequest(*ca_key, &ca_csr));
- }
-
- // Self-sign the CA's CSR.
- auto ca_cert = std::make_shared<Cert>();
- {
- CertSigner ca_signer;
- ASSERT_OK(ca_signer.InitForSelfSigning(ca_key));
- ASSERT_OK(ca_signer.Sign(ca_csr, ca_cert.get()));
- }
+ shared_ptr<PrivateKey> ca_key;
+ shared_ptr<Cert> ca_cert;
+ ASSERT_OK(GenerateSelfSignedCAForTests(&ca_key, &ca_cert));
// Create a key for the tablet server.
auto ts_key = std::make_shared<PrivateKey>();
http://git-wip-us.apache.org/repos/asf/kudu/blob/86714152/src/kudu/security/ca/cert_management.cc
----------------------------------------------------------------------
diff --git a/src/kudu/security/ca/cert_management.cc b/src/kudu/security/ca/cert_management.cc
index 8de37dd..710b23e 100644
--- a/src/kudu/security/ca/cert_management.cc
+++ b/src/kudu/security/ca/cert_management.cc
@@ -281,6 +281,26 @@ Status CaCertRequestGenerator::SetExtensions(X509_REQ* req) const {
return Status::OK();
}
+Status CertSigner::SelfSignCA(const shared_ptr<PrivateKey>& key,
+ CaCertRequestGenerator::Config config,
+ Cert* cert) {
+ // Generate a CSR for the CA.
+ CertSignRequest ca_csr;
+ {
+ CaCertRequestGenerator gen(std::move(config));
+ RETURN_NOT_OK(gen.Init());
+ RETURN_NOT_OK(gen.GenerateRequest(*key, &ca_csr));
+ }
+
+ // Self-sign the CA's CSR.
+ {
+ CertSigner ca_signer;
+ RETURN_NOT_OK(ca_signer.InitForSelfSigning(key));
+ RETURN_NOT_OK(ca_signer.Sign(ca_csr, cert));
+ }
+ return Status::OK();
+}
+
CertSigner::CertSigner()
: is_initialized_(false) {
}
http://git-wip-us.apache.org/repos/asf/kudu/blob/86714152/src/kudu/security/ca/cert_management.h
----------------------------------------------------------------------
diff --git a/src/kudu/security/ca/cert_management.h b/src/kudu/security/ca/cert_management.h
index 4974983..7a2887a 100644
--- a/src/kudu/security/ca/cert_management.h
+++ b/src/kudu/security/ca/cert_management.h
@@ -54,15 +54,15 @@ class CertRequestGeneratorBase {
// Properties for the generated X509 CSR. Using server UUID for the common
// name field.
struct Config {
- const std::string country; // subject field: C
- const std::string state; // subject field: ST
- const std::string locality; // subject field: L
- const std::string org; // subject field: O
- const std::string unit; // subject field: OU
- const std::string uuid; // subject field: CN
- const std::string comment; // custom extension: Netscape Comment
- const std::vector<std::string> hostnames; // subjectAltName extension (DNS:)
- const std::vector<std::string> ips; // subjectAltName extension (IP:)
+ std::string country; // subject field: C
+ std::string state; // subject field: ST
+ std::string locality; // subject field: L
+ std::string org; // subject field: O
+ std::string unit; // subject field: OU
+ std::string uuid; // subject field: CN
+ std::string comment; // custom extension: Netscape Comment
+ std::vector<std::string> hostnames; // subjectAltName extension (DNS:)
+ std::vector<std::string> ips; // subjectAltName extension (IP:)
};
explicit CertRequestGeneratorBase(Config config);
@@ -134,6 +134,11 @@ class CaCertRequestGenerator : public CertRequestGeneratorBase {
// An utility class for issuing and signing certificates.
class CertSigner {
public:
+ // Generate a self-signed certificate authority using the given key
+ // and CSR configuration.
+ static Status SelfSignCA(const std::shared_ptr<PrivateKey>& key,
+ CaCertRequestGenerator::Config config,
+ Cert* cert);
// Create a CertSigner.
// Exactly one of the following Init*() methods must be called
// exactly once before the instance may be used.
@@ -149,11 +154,6 @@ class CertSigner {
// on disk.
Status InitFromFiles(const std::string& ca_cert_path,
const std::string& ca_private_key_path);
- // Initialize the signer for self-signing using the given private key.
- //
- // Any certificates signed by this CertSigner will have the 'issuer' equal
- // to the signed cert's subject.
- Status InitForSelfSigning(std::shared_ptr<PrivateKey> private_key);
// Set the expiration interval for certs signed by this signer.
// This may be changed at any point.
@@ -175,6 +175,12 @@ class CertSigner {
static Status DigestSign(const EVP_MD* md, EVP_PKEY* pkey, X509* x);
static Status GenerateSerial(c_unique_ptr<ASN1_INTEGER>* ret);
+ // Initialize the signer for self-signing using the given private key.
+ //
+ // Any certificates signed by this CertSigner will have the 'issuer' equal
+ // to the signed cert's subject.
+ Status InitForSelfSigning(std::shared_ptr<PrivateKey> private_key);
+
Status DoSign(const EVP_MD* digest, int32_t exp_seconds, X509 *ret) const;
mutable simple_spinlock lock_;
http://git-wip-us.apache.org/repos/asf/kudu/blob/86714152/src/kudu/security/security-test-util.cc
----------------------------------------------------------------------
diff --git a/src/kudu/security/security-test-util.cc b/src/kudu/security/security-test-util.cc
new file mode 100644
index 0000000..2fa8b1f
--- /dev/null
+++ b/src/kudu/security/security-test-util.cc
@@ -0,0 +1,52 @@
+// 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/security/security-test-util.h"
+
+#include <memory>
+
+#include <glog/logging.h>
+
+#include "kudu/security/ca/cert_management.h"
+#include "kudu/security/cert.h"
+#include "kudu/security/crypto.h"
+
+namespace kudu {
+namespace security {
+
+using ca::CaCertRequestGenerator;
+using ca::CertSigner;
+
+Status GenerateSelfSignedCAForTests(std::shared_ptr<PrivateKey>* ca_key,
+ std::shared_ptr<Cert>* ca_cert) {
+ // Create a key for the self-signed CA.
+ auto ret_ca_key = std::make_shared<PrivateKey>();
+ auto ret_ca_cert = std::make_shared<Cert>();
+ RETURN_NOT_OK(GeneratePrivateKey(512, ret_ca_key.get()));
+
+ CaCertRequestGenerator::Config config;
+ config.uuid = "test-ca-uuid";
+ RETURN_NOT_OK(CertSigner::SelfSignCA(ret_ca_key, config, ret_ca_cert.get()));
+
+ *ca_key = std::move(ret_ca_key);
+ *ca_cert = std::move(ret_ca_cert);
+ return Status::OK();
+}
+
+
+} // namespace security
+} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/86714152/src/kudu/security/security-test-util.h
----------------------------------------------------------------------
diff --git a/src/kudu/security/security-test-util.h b/src/kudu/security/security-test-util.h
index 76853d4..17c5375 100644
--- a/src/kudu/security/security-test-util.h
+++ b/src/kudu/security/security-test-util.h
@@ -25,10 +25,13 @@
namespace kudu {
namespace security {
+class Cert;
+class PrivateKey;
+
// TODO(todd): consolidate these certs with those in
// security/test/test_certs.h once we support configuring a password
// for the RPC cert.
-static Status CreateSSLServerCert(const std::string& file_path) {
+inline static Status CreateSSLServerCert(const std::string& file_path) {
static const char* test_server_cert = R"(
-----BEGIN CERTIFICATE-----
MIIEejCCA2KgAwIBAgIJAKMdvDR5PL82MA0GCSqGSIb3DQEBBQUAMIGEMQswCQYD
@@ -62,7 +65,7 @@ seCrQwgi1Fer9Ekd5XNjWjigC3VC3SjMqWaxeKbZ2/AuABJMz5xSiRkgwphXEQ==
}
// Writes the test SSL private key into a temporary file.
-static Status CreateSSLPrivateKey(const std::string& file_path) {
+inline static Status CreateSSLPrivateKey(const std::string& file_path) {
static const char* test_private_key = R"(
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqFI96TENhC5K886vpKIsZY1RQQBBKsFFkowPhhCsHxW/1D0Y
@@ -96,5 +99,9 @@ dc+JVPKL8Fe4a8fmsI6ndcZQ9qpOdZM5WOD0ldKRc+SsrYKkTmOOJQ==
return Status::OK();
}
+// TODO(todd): change these from shared_ptrs to unique_ptrs
+Status GenerateSelfSignedCAForTests(std::shared_ptr<PrivateKey>* ca_key,
+ std::shared_ptr<Cert>* ca_cert);
+
} // namespace security
} // namespace kudu