You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ti...@apache.org on 2016/07/04 16:42:57 UTC
[1/5] mesos git commit: Extended utilities to render certificate
extension for IP.
Repository: mesos
Updated Branches:
refs/heads/master e5f73dc7a -> 92713431c
Extended utilities to render certificate extension for IP.
Adds the ability to render a subject alternative name based on a given
IP address within a X509 certificate extension. Additionally the
libprocess test suite makes use of this feature.
Review: https://reviews.apache.org/r/49400/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/6133e72c
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/6133e72c
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/6133e72c
Branch: refs/heads/master
Commit: 6133e72ccd777c541036a2cc80487d0c842c836b
Parents: e5f73dc
Author: Till Toenshoff <to...@me.com>
Authored: Mon Jul 4 18:32:12 2016 +0200
Committer: Till Toenshoff <to...@me.com>
Committed: Mon Jul 4 18:32:12 2016 +0200
----------------------------------------------------------------------
.../libprocess/include/process/ssl/gtest.hpp | 3 +-
.../include/process/ssl/utilities.hpp | 10 ++-
3rdparty/libprocess/src/ssl/utilities.cpp | 81 +++++++++++++++++++-
3 files changed, 90 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/6133e72c/3rdparty/libprocess/include/process/ssl/gtest.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/ssl/gtest.hpp b/3rdparty/libprocess/include/process/ssl/gtest.hpp
index 5435ddd..3faf4d6 100644
--- a/3rdparty/libprocess/include/process/ssl/gtest.hpp
+++ b/3rdparty/libprocess/include/process/ssl/gtest.hpp
@@ -192,7 +192,8 @@ protected:
None(),
1,
365,
- hostname.get());
+ hostname.get(),
+ net::IP(INADDR_LOOPBACK));
if (certificate.isError()) {
cleanup("Could not generate certificate: " + certificate.error());
http://git-wip-us.apache.org/repos/asf/mesos/blob/6133e72c/3rdparty/libprocess/include/process/ssl/utilities.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/ssl/utilities.hpp b/3rdparty/libprocess/include/process/ssl/utilities.hpp
index ad9ec5d..c2f64a9 100644
--- a/3rdparty/libprocess/include/process/ssl/utilities.hpp
+++ b/3rdparty/libprocess/include/process/ssl/utilities.hpp
@@ -18,6 +18,7 @@
#include <openssl/ssl.h>
#include <openssl/x509.h>
+#include <stout/ip.hpp>
#include <stout/nothing.hpp>
#include <stout/path.hpp>
#include <stout/try.hpp>
@@ -56,7 +57,9 @@ Try<EVP_PKEY*> generate_private_rsa_key(
* @param parent_certificate. Otherwise, it is assumed this is a
* self-signed certificate in which case the @param subject_key must
* be the same as the @param sign_key, and the issuer name will be the
- * same as the subject name.
+ * same as the subject name. If @param ip is provided, then the
+ * certificate will use the ip for a subject alternative name iPAddress
+ * extension.
*
* @param subject_key The key that will be made public by the
* certificate.
@@ -68,6 +71,8 @@ Try<EVP_PKEY*> generate_private_rsa_key(
* certificate will be valid.
* @param hostname An optional hostname used to set the common name of
* the certificate.
+ * @param ip An optional IP used to set the subject alternative name
+ * iPAddress of the certificate extension.
*
* @return A pointer to an X509 certificate if successful otherwise an
* Error.
@@ -78,7 +83,8 @@ Try<X509*> generate_x509(
const Option<X509*>& parent_certificate = None(),
int serial = 1,
int days = 365,
- Option<std::string> hostname = None());
+ Option<std::string> hostname = None(),
+ const Option<net::IP>& ip = None());
/**
http://git-wip-us.apache.org/repos/asf/mesos/blob/6133e72c/3rdparty/libprocess/src/ssl/utilities.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/ssl/utilities.cpp b/3rdparty/libprocess/src/ssl/utilities.cpp
index 02bfd17..8aec613 100644
--- a/3rdparty/libprocess/src/ssl/utilities.cpp
+++ b/3rdparty/libprocess/src/ssl/utilities.cpp
@@ -88,7 +88,8 @@ Try<X509*> generate_x509(
const Option<X509*>& parent_certificate,
int serial,
int days,
- Option<std::string> hostname)
+ Option<std::string> hostname,
+ const Option<net::IP>& ip)
{
Option<X509_NAME*> issuer_name = None();
if (parent_certificate.isNone()) {
@@ -207,6 +208,84 @@ Try<X509*> generate_x509(
return Error("Failed to set issuer name: X509_set_issuer_name");
}
+ if (ip.isSome()) {
+ // Add an X509 extension with an IP for subject alternative name.
+
+ STACK_OF(GENERAL_NAME)* alt_name_stack = sk_GENERAL_NAME_new_null();
+ if (alt_name_stack == nullptr) {
+ X509_free(x509);
+ return Error("Failed to create a stack: sk_GENERAL_NAME_new_null");
+ }
+
+ GENERAL_NAME* alt_name = GENERAL_NAME_new();
+ if (alt_name == nullptr) {
+ sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
+ X509_free(x509);
+ return Error("Failed to create GENERAL_NAME: GENERAL_NAME_new");
+ }
+
+ alt_name->type = GEN_IPADD;
+
+ ASN1_STRING* alt_name_str = ASN1_STRING_new();
+ if (alt_name_str == nullptr) {
+ GENERAL_NAME_free(alt_name);
+ sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
+ X509_free(x509);
+ return Error("Failed to create alternative name: ASN1_STRING_new");
+ }
+
+ Try<in_addr> in = ip.get().in();
+
+ if (in.isError()) {
+ ASN1_STRING_free(alt_name_str);
+ GENERAL_NAME_free(alt_name);
+ sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
+ X509_free(x509);
+ return Error("Failed to get IP/4 address");
+ }
+
+ // For `iPAddress` we hand over a binary value as part of the
+ // specification.
+ if (ASN1_STRING_set(
+ alt_name_str,
+ &in.get().s_addr,
+ sizeof(in_addr_t)) == 0) {
+ ASN1_STRING_free(alt_name_str);
+ GENERAL_NAME_free(alt_name);
+ sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
+ X509_free(x509);
+ return Error("Failed to set alternative name: ASN1_STRING_set");
+ }
+
+ // We are transferring ownership of 'alt_name_str` towards the
+ // `ASN1_OCTET_STRING` here.
+ alt_name->d.iPAddress = alt_name_str;
+
+ // We try to transfer ownership of 'alt_name` towards the
+ // `STACK_OF(GENERAL_NAME)` here.
+ if (sk_GENERAL_NAME_push(alt_name_stack, alt_name) == 0) {
+ GENERAL_NAME_free(alt_name);
+ sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
+ X509_free(x509);
+ return Error("Failed to push alternative name: sk_GENERAL_NAME_push");
+ }
+
+ // We try to transfer the ownership of `alt_name_stack` towards the
+ // `X509` here.
+ if (X509_add1_ext_i2d(
+ x509,
+ NID_subject_alt_name,
+ alt_name_stack,
+ 0,
+ 0) == 0) {
+ sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
+ X509_free(x509);
+ return Error("Failed to set subject alternative name: X509_add1_ext_i2d");
+ }
+
+ sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
+ }
+
// Sign the certificate with the sign key.
if (X509_sign(x509, sign_key, EVP_sha1()) == 0) {
X509_free(x509);
[3/5] mesos git commit: Added tests for IP based certificate
validation.
Posted by ti...@apache.org.
Added tests for IP based certificate validation.
Review: https://reviews.apache.org/r/49402/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ae0504c3
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ae0504c3
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ae0504c3
Branch: refs/heads/master
Commit: ae0504c33efc126b9b19755cbc7839a38de067f5
Parents: 36a3c64
Author: Till Toenshoff <to...@me.com>
Authored: Mon Jul 4 18:34:03 2016 +0200
Committer: Till Toenshoff <to...@me.com>
Committed: Mon Jul 4 18:34:03 2016 +0200
----------------------------------------------------------------------
3rdparty/libprocess/include/process/ssl/gtest.hpp | 3 ++-
3rdparty/libprocess/src/tests/ssl_tests.cpp | 16 ++++++++++++----
2 files changed, 14 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/ae0504c3/3rdparty/libprocess/include/process/ssl/gtest.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/ssl/gtest.hpp b/3rdparty/libprocess/include/process/ssl/gtest.hpp
index 3faf4d6..a929cc9 100644
--- a/3rdparty/libprocess/include/process/ssl/gtest.hpp
+++ b/3rdparty/libprocess/include/process/ssl/gtest.hpp
@@ -267,7 +267,8 @@ protected:
* SSLTest::launch_client that factor out common behavior used in
* tests.
*/
-class SSLTest : public SSLTemporaryDirectoryTest
+class SSLTest : public SSLTemporaryDirectoryTest,
+ public ::testing::WithParamInterface<const char*>
{
protected:
SSLTest() : data("Hello World!") {}
http://git-wip-us.apache.org/repos/asf/mesos/blob/ae0504c3/3rdparty/libprocess/src/tests/ssl_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/ssl_tests.cpp b/3rdparty/libprocess/src/tests/ssl_tests.cpp
index 6fc9038..72432ec 100644
--- a/3rdparty/libprocess/src/tests/ssl_tests.cpp
+++ b/3rdparty/libprocess/src/tests/ssl_tests.cpp
@@ -102,6 +102,11 @@ Future<Nothing> await_subprocess(
}
+INSTANTIATE_TEST_CASE_P(SSLVerifyIPAdd,
+ SSLTest,
+ ::testing::Values("false", "true"));
+
+
// Ensure that we can't create an SSL socket when SSL is not enabled.
TEST(SSL, Disabled)
{
@@ -113,7 +118,7 @@ TEST(SSL, Disabled)
// Test a basic back-and-forth communication within the same OS
// process.
-TEST_F(SSLTest, BasicSameProcess)
+TEST_P(SSLTest, BasicSameProcess)
{
os::setenv("SSL_ENABLED", "true");
os::setenv("SSL_KEY_FILE", key_path().string());
@@ -121,6 +126,7 @@ TEST_F(SSLTest, BasicSameProcess)
os::setenv("SSL_REQUIRE_CERT", "true");
os::setenv("SSL_CA_DIR", os::getcwd());
os::setenv("SSL_CA_FILE", certificate_path().string());
+ os::setenv("SSL_VERIFY_IPADD", GetParam());
openssl::reinitialize();
@@ -348,20 +354,22 @@ TEST_F(SSLTest, VerifyCertificate)
// Ensure that a certificate that WAS generated using the certificate
// authority is NOT allowed to communicate when the SSL_REQUIRE_CERT
// flag is enabled.
-TEST_F(SSLTest, RequireCertificate)
+TEST_P(SSLTest, RequireCertificate)
{
Try<Socket> server = setup_server({
{"SSL_ENABLED", "true"},
{"SSL_KEY_FILE", key_path().string()},
{"SSL_CERT_FILE", certificate_path().string()},
- {"SSL_REQUIRE_CERT", "true"}});
+ {"SSL_REQUIRE_CERT", "true"},
+ {"SSL_VERIFY_IPADD", GetParam()}});
ASSERT_SOME(server);
Try<Subprocess> client = launch_client({
{"SSL_ENABLED", "true"},
{"SSL_KEY_FILE", key_path().string()},
{"SSL_CERT_FILE", certificate_path().string()},
- {"SSL_REQUIRE_CERT", "true"}},
+ {"SSL_REQUIRE_CERT", "true"},
+ {"SSL_VERIFY_IPADD", GetParam()}},
server.get(),
true);
ASSERT_SOME(client);
[2/5] mesos git commit: Updated certificate validation to check 'IP
Address' SAN.
Posted by ti...@apache.org.
Updated certificate validation to check 'IP Address' SAN.
Allows the verification of X509 certificates based on an IP address
instead of a hostname. Introduces a new environment variable;
\`SSL_VERIFY_IPADD\` which, when set to \`true\` will enable the
peer certificate verification to additionally rely on the IP
address of a connection.
Review: https://reviews.apache.org/r/49401/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/36a3c649
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/36a3c649
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/36a3c649
Branch: refs/heads/master
Commit: 36a3c6494be91e7a9b898c3c8eebe59883c050e4
Parents: 6133e72
Author: Till Toenshoff <to...@me.com>
Authored: Mon Jul 4 18:32:40 2016 +0200
Committer: Till Toenshoff <to...@me.com>
Committed: Mon Jul 4 18:32:40 2016 +0200
----------------------------------------------------------------------
3rdparty/libprocess/src/libevent_ssl_socket.cpp | 14 +-
3rdparty/libprocess/src/libevent_ssl_socket.hpp | 1 +
3rdparty/libprocess/src/openssl.cpp | 142 ++++++++++++++-----
3rdparty/libprocess/src/openssl.hpp | 8 +-
4 files changed, 125 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/36a3c649/3rdparty/libprocess/src/libevent_ssl_socket.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/libevent_ssl_socket.cpp b/3rdparty/libprocess/src/libevent_ssl_socket.cpp
index 19d9ae5..2e7f332 100644
--- a/3rdparty/libprocess/src/libevent_ssl_socket.cpp
+++ b/3rdparty/libprocess/src/libevent_ssl_socket.cpp
@@ -396,7 +396,7 @@ void LibeventSSLSocketImpl::event_callback(short events)
// Do post-validation of connection.
SSL* ssl = bufferevent_openssl_get_ssl(bev);
- Try<Nothing> verify = openssl::verify(ssl, peer_hostname);
+ Try<Nothing> verify = openssl::verify(ssl, peer_hostname, peer_ip);
if (verify.isError()) {
VLOG(1) << "Failed connect, verification error: " << verify.error();
SSL_free(ssl);
@@ -513,7 +513,7 @@ Future<Nothing> LibeventSSLSocketImpl::connect(const Address& address)
}
// Try and determine the 'peer_hostname' from the address we're
- // connecting to in order to properly verify the SSL connection later.
+ // connecting to in order to properly verify the certificate later.
const Try<string> hostname = address.hostname();
if (hostname.isError()) {
@@ -523,6 +523,10 @@ Future<Nothing> LibeventSSLSocketImpl::connect(const Address& address)
peer_hostname = hostname.get();
}
+ // Determine the 'peer_ip' from the address we're connecting to in
+ // order to properly verify the certificate later.
+ peer_ip = address.ip;
+
// Optimistically construct a 'ConnectRequest' and future.
Owned<ConnectRequest> request(new ConnectRequest());
Future<Nothing> future = request->promise.future();
@@ -1023,8 +1027,10 @@ void LibeventSSLSocketImpl::accept_SSL_callback(AcceptRequest* request)
// post-verification. First, we need to determine the peer
// hostname.
Option<string> peer_hostname = None();
+
if (request->ip.isSome()) {
Try<string> hostname = net::getHostname(request->ip.get());
+
if (hostname.isError()) {
VLOG(2) << "Could not determine hostname of peer: "
<< hostname.error();
@@ -1037,7 +1043,9 @@ void LibeventSSLSocketImpl::accept_SSL_callback(AcceptRequest* request)
SSL* ssl = bufferevent_openssl_get_ssl(bev);
CHECK_NOTNULL(ssl);
- Try<Nothing> verify = openssl::verify(ssl, peer_hostname);
+ Try<Nothing> verify =
+ openssl::verify(ssl, peer_hostname, request->ip);
+
if (verify.isError()) {
VLOG(1) << "Failed accept, verification error: " << verify.error();
request->promise.fail(verify.error());
http://git-wip-us.apache.org/repos/asf/mesos/blob/36a3c649/3rdparty/libprocess/src/libevent_ssl_socket.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/libevent_ssl_socket.hpp b/3rdparty/libprocess/src/libevent_ssl_socket.hpp
index 1dbdaa8..4d376d8 100644
--- a/3rdparty/libprocess/src/libevent_ssl_socket.hpp
+++ b/3rdparty/libprocess/src/libevent_ssl_socket.hpp
@@ -178,6 +178,7 @@ private:
Queue<Future<Socket>> accept_queue;
Option<std::string> peer_hostname;
+ Option<net::IP> peer_ip;
// Socket descriptor/handle used by libevent_ssl.
// Ownership semantics:
http://git-wip-us.apache.org/repos/asf/mesos/blob/36a3c649/3rdparty/libprocess/src/openssl.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/openssl.cpp b/3rdparty/libprocess/src/openssl.cpp
index 0f62aa6..63916ff 100644
--- a/3rdparty/libprocess/src/openssl.cpp
+++ b/3rdparty/libprocess/src/openssl.cpp
@@ -80,6 +80,12 @@ Flags::Flags()
"certificate implies verifying it.",
false);
+ add(&Flags::verify_ipadd,
+ "verify_ipadd",
+ "Enable IP address verification in subject alternative name certificate "
+ "extension.",
+ false);
+
add(&Flags::verification_depth,
"verification_depth",
"Maximum depth for the certificate chain verification that shall be "
@@ -401,6 +407,11 @@ void reinitialize()
<< "verification";
}
+ if (ssl_flags->verify_ipadd) {
+ VLOG(2) << "Will use IP address verification in subject alternative name "
+ << "certificate extension.";
+ }
+
if (ssl_flags->require_cert && !ssl_flags->verify_cert) {
// Requiring a certificate implies that is should be verified.
ssl_flags->verify_cert = true;
@@ -543,7 +554,10 @@ SSL_CTX* context()
}
-Try<Nothing> verify(const SSL* const ssl, const Option<string>& hostname)
+Try<Nothing> verify(
+ const SSL* const ssl,
+ const Option<string>& hostname,
+ const Option<net::IP>& ip)
{
// Return early if we don't need to verify.
if (!ssl_flags->verify_cert) {
@@ -565,7 +579,7 @@ Try<Nothing> verify(const SSL* const ssl, const Option<string>& hostname)
return Error("Could not verify peer certificate");
}
- if (hostname.isNone()) {
+ if (!ssl_flags->verify_ipadd && hostname.isNone()) {
X509_free(cert);
return ssl_flags->require_cert
? Error("Cannot verify peer certificate: peer hostname unknown")
@@ -589,24 +603,62 @@ Try<Nothing> verify(const SSL* const ssl, const Option<string>& hostname)
for (int i = 0; i < san_names_num; i++) {
const GENERAL_NAME* current_name = sk_GENERAL_NAME_value(san_names, i);
- if (current_name->type == GEN_DNS) {
- // Current name is a DNS name, let's check it.
- const string dns_name =
- reinterpret_cast<char*>(ASN1_STRING_data(current_name->d.dNSName));
+ switch(current_name->type) {
+ case GEN_DNS: {
+ if (hostname.isSome()) {
+ // Current name is a DNS name, let's check it.
+ const string dns_name =
+ reinterpret_cast<char*>(ASN1_STRING_data(
+ current_name->d.dNSName));
+
+ // Make sure there isn't an embedded NUL character in the DNS name.
+ const size_t length = ASN1_STRING_length(current_name->d.dNSName);
+ if (length != dns_name.length()) {
+ sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
+ X509_free(cert);
+ return Error(
+ "X509 certificate malformed: "
+ "embedded NUL character in DNS name");
+ } else {
+ VLOG(2) << "Matching dNSName(" << i << "): " << dns_name;
+
+ // Compare expected hostname with the DNS name.
+ if (hostname.get() == dns_name) {
+ sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
+ X509_free(cert);
+
+ VLOG(2) << "dNSName match found for " << hostname.get();
+
+ return Nothing();
+ }
+ }
+ }
+ break;
+ }
+ case GEN_IPADD: {
+ if (ssl_flags->verify_ipadd && ip.isSome()) {
+ // Current name is an IPAdd, let's check it.
+ const ASN1_OCTET_STRING* current_ipadd = current_name->d.iPAddress;
- // Make sure there isn't an embedded NUL character in the DNS name.
- const size_t length = ASN1_STRING_length(current_name->d.dNSName);
- if (length != dns_name.length()) {
- sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
- X509_free(cert);
- return Error(
- "X509 certificate malformed: embedded NUL character in DNS name");
- } else { // Compare expected hostname with the DNS name.
- if (hostname.get() == dns_name) {
- sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
- X509_free(cert);
- return Nothing();
+ if (current_ipadd->type == V_ASN1_OCTET_STRING &&
+ current_ipadd->data != nullptr &&
+ current_ipadd->length == sizeof(uint32_t)) {
+ const net::IP ip_add(ntohl(
+ *reinterpret_cast<uint32_t*>(current_ipadd->data)));
+
+ VLOG(2) << "Matching iPAddress(" << i << "): " << ip_add;
+
+ if (ip.get() == ip_add) {
+ sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
+ X509_free(cert);
+
+ VLOG(2) << "iPAddress match found for " << ip.get();
+
+ return Nothing();
+ }
+ }
}
+ break;
}
}
}
@@ -614,34 +666,52 @@ Try<Nothing> verify(const SSL* const ssl, const Option<string>& hostname)
sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
}
- // If we still haven't verified the hostname, try doing it via
- // the certificate subject name.
- X509_NAME* name = X509_get_subject_name(cert);
+ if (hostname.isSome()) {
+ // If we still haven't verified the hostname, try doing it via
+ // the certificate subject name.
+ X509_NAME* name = X509_get_subject_name(cert);
+
+ if (name != nullptr) {
+ char text[_POSIX_HOST_NAME_MAX] {};
- if (name != nullptr) {
- char text[_POSIX_HOST_NAME_MAX] {};
+ if (X509_NAME_get_text_by_NID(
+ name,
+ NID_commonName,
+ text,
+ sizeof(text)) > 0) {
+ VLOG(2) << "Matching common name: " << text;
+
+ if (hostname.get() != text) {
+ X509_free(cert);
+ return Error(
+ "Presented Certificate Name: " + stringify(text) +
+ " does not match peer hostname name: " + hostname.get());
+ }
+
+ VLOG(2) << "Common name match found for " << hostname.get();
- if (X509_NAME_get_text_by_NID(
- name,
- NID_commonName,
- text,
- sizeof(text)) > 0) {
- if (hostname.get() != text) {
X509_free(cert);
- return Error(
- "Presented Certificate Name: " + stringify(text) +
- " does not match peer hostname name: " + hostname.get());
+ return Nothing();
}
-
- X509_free(cert);
- return Nothing();
}
}
// If we still haven't exited, we haven't verified it, and we give up.
X509_free(cert);
+
+ std::vector<string> details;
+
+ if (hostname.isSome()) {
+ details.push_back("hostname " + hostname.get());
+ }
+
+ if (ip.isSome()) {
+ details.push_back("IP " + stringify(ip.get()));
+ }
+
return Error(
- "Could not verify presented certificate with hostname " + hostname.get());
+ "Could not verify presented certificate with " +
+ strings::join(", ", details));
}
} // namespace openssl {
http://git-wip-us.apache.org/repos/asf/mesos/blob/36a3c649/3rdparty/libprocess/src/openssl.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/openssl.hpp b/3rdparty/libprocess/src/openssl.hpp
index 7d55025..68f8897 100644
--- a/3rdparty/libprocess/src/openssl.hpp
+++ b/3rdparty/libprocess/src/openssl.hpp
@@ -18,6 +18,7 @@
#include <string>
#include <stout/flags.hpp>
+#include <stout/ip.hpp>
#include <stout/nothing.hpp>
#include <stout/option.hpp>
#include <stout/try.hpp>
@@ -39,6 +40,7 @@ public:
Option<std::string> key_file;
bool verify_cert;
bool require_cert;
+ bool verify_ipadd;
unsigned int verification_depth;
Option<std::string> ca_dir;
Option<std::string> ca_file;
@@ -61,6 +63,7 @@ const Flags& flags();
// SSL_KEY_FILE=(path to key)
// SSL_VERIFY_CERT=(false|0,true|1)
// SSL_REQUIRE_CERT=(false|0,true|1)
+// SSL_VERIFY_IPADD=(false|0,true|1)
// SSL_VERIFY_DEPTH=(4)
// SSL_CA_DIR=(path to CA directory)
// SSL_CA_FILE=(path to CA file)
@@ -82,7 +85,10 @@ SSL_CTX* context();
// Verify that the hostname is properly associated with the peer
// certificate associated with the specified SSL connection.
-Try<Nothing> verify(const SSL* const ssl, const Option<std::string>& hostname);
+Try<Nothing> verify(
+ const SSL* const ssl,
+ const Option<std::string>& hostname = None(),
+ const Option<net::IP>& ip = None());
} // namespace openssl {
} // namespace network {
[4/5] mesos git commit: Updated CHANGELOG for MESOS-5724.
Posted by ti...@apache.org.
Updated CHANGELOG for MESOS-5724.
Review: https://reviews.apache.org/r/49411/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/2585fedc
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2585fedc
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2585fedc
Branch: refs/heads/master
Commit: 2585fedca4d148508a886f7ea6391fd77fa8b308
Parents: ae0504c
Author: Till Toenshoff <to...@me.com>
Authored: Mon Jul 4 18:34:28 2016 +0200
Committer: Till Toenshoff <to...@me.com>
Committed: Mon Jul 4 18:34:28 2016 +0200
----------------------------------------------------------------------
CHANGELOG | 3 +++
1 file changed, 3 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/2585fedc/CHANGELOG
----------------------------------------------------------------------
diff --git a/CHANGELOG b/CHANGELOG
index 47a9dcb..cacfb5b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -103,6 +103,9 @@ This release contains the following new features:
resource. This initial support works when there is no container filesystem
isolation in use. Improvements to the support to come in future releases.
+ * [MESOS-5724] - SSL certificate validation allows for additional IP address
+ subject alternative name extension verification.
+
Deprecations:
* [MESOS-2281] - Deprecated the plain text format for credentials in favor of
the JSON format.
[5/5] mesos git commit: Updated SSL.md with 'SSL_VERIFY_IPADD'.
Posted by ti...@apache.org.
Updated SSL.md with 'SSL_VERIFY_IPADD'.
Review: https://reviews.apache.org/r/49412/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/92713431
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/92713431
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/92713431
Branch: refs/heads/master
Commit: 92713431c058984bc439737c647cd162ebce8836
Parents: 2585fed
Author: Till Toenshoff <to...@me.com>
Authored: Mon Jul 4 18:34:48 2016 +0200
Committer: Till Toenshoff <to...@me.com>
Committed: Mon Jul 4 18:34:48 2016 +0200
----------------------------------------------------------------------
docs/ssl.md | 3 +++
1 file changed, 3 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/92713431/docs/ssl.md
----------------------------------------------------------------------
diff --git a/docs/ssl.md b/docs/ssl.md
index 5eef9fd..64f63b7 100644
--- a/docs/ssl.md
+++ b/docs/ssl.md
@@ -52,6 +52,9 @@ Enforce that certificates must be presented by connecting clients. This means al
#### SSL_VERIFY_DEPTH=(N) [default=4]
The maximum depth used to verify certificates. The default is 4. See the OpenSSL documentation or contact your system administrator to learn why you may want to change this.
+#### SSL_VERIFY_IPADD=(false|0,true|1) [default=false|0]
+Enable IP address verification in the certificate subject alternative name extension. When set to `true` the peer certificate verification will additionally use the IP address of a peer connection. When a hostname of the peer as well as its IP address are available, the validation will succeed when either the hostname or the IP match.
+
#### SSL_CA_DIR=(path to CA directory)
The directory used to find the certificate authority / authorities. You can specify `SSL_CA_DIR` or `SSL_CA_FILE` depending on how you want to restrict your certificate authorization.