Merge pull request #361 from etschannen/master

merge release 5.2 into master
This commit is contained in:
Evan Tschannen 2018-05-10 15:02:19 -07:00 committed by GitHub
commit a799d2a08c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
74 changed files with 2904 additions and 2203 deletions

View File

@ -15,6 +15,8 @@
<ClCompile Include="FDBLibTLSPlugin.cpp" />
<ClInclude Include="FDBLibTLSPolicy.h" />
<ClCompile Include="FDBLibTLSPolicy.cpp" />
<ClInclude Include="FDBLibTLSVerify.h" />
<ClCompile Include="FDBLibTLSVerify.cpp" />
<ClInclude Include="FDBLibTLSSession.h" />
<ClCompile Include="FDBLibTLSSession.cpp" />
</ItemGroup>

View File

@ -23,8 +23,7 @@
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/obj_mac.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
@ -34,10 +33,12 @@
#include <string>
#include <vector>
#include <string.h>
#include <limits.h>
FDBLibTLSPolicy::FDBLibTLSPolicy(Reference<FDBLibTLSPlugin> plugin, ITLSLogFunc logf):
plugin(plugin), logf(logf), tls_cfg(NULL), session_created(false), cert_data_set(false),
key_data_set(false), verify_peers_set(false), verify_cert(true), verify_time(true) {
plugin(plugin), logf(logf), tls_cfg(NULL), roots(NULL), session_created(false), ca_data_set(false),
cert_data_set(false), key_data_set(false), verify_peers_set(false) {
if ((tls_cfg = tls_config_new()) == NULL) {
logf("FDBLibTLSConfigError", NULL, true, NULL);
@ -46,251 +47,73 @@ FDBLibTLSPolicy::FDBLibTLSPolicy(Reference<FDBLibTLSPlugin> plugin, ITLSLogFunc
// Require client certificates for authentication.
tls_config_verify_client(tls_cfg);
// Name verification is always manually handled (if requested via configuration).
tls_config_insecure_noverifyname(tls_cfg);
}
FDBLibTLSPolicy::~FDBLibTLSPolicy() {
sk_X509_pop_free(roots, X509_free);
tls_config_free(tls_cfg);
}
ITLSSession* FDBLibTLSPolicy::create_session(bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid) {
ITLSSession* FDBLibTLSPolicy::create_session(bool is_client, const char* servername, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid) {
if (is_client) {
// If verify peers has been set then there is no point specifying a
// servername, since this will be ignored - the servername should be
// matched by the verify criteria instead.
if (verify_peers_set && servername != NULL) {
logf("FDBLibTLSVerifyPeersWithServerName", NULL, true, NULL);
return NULL;
}
// If verify peers has not been set, then require a server name to
// avoid an accidental lack of name validation.
if (!verify_peers_set && servername == NULL) {
logf("FDBLibTLSNoServerName", NULL, true, NULL);
return NULL;
}
}
session_created = true;
try {
return new FDBLibTLSSession(Reference<FDBLibTLSPolicy>::addRef(this), is_client, send_func, send_ctx, recv_func, recv_ctx, uid);
return new FDBLibTLSSession(Reference<FDBLibTLSPolicy>::addRef(this), is_client, servername, send_func, send_ctx, recv_func, recv_ctx, uid);
} catch ( ... ) {
return NULL;
}
}
static int hexValue(char c) {
static char const digits[] = "0123456789ABCDEF";
static int password_cb(char *buf, int size, int rwflag, void *u) {
const char *password = (const char *)u;
int plen;
if (c >= 'a' && c <= 'f')
c -= ('a' - 'A');
if (size < 0)
return 0;
if (u == NULL)
return 0;
int value = std::find(digits, digits + 16, c) - digits;
if (value >= 16) {
throw std::runtime_error("hexValue");
}
return value;
plen = strlen(password);
if (plen > size)
return 0;
// Note: buf does not need to be NUL-terminated since
// we return an explicit length.
strncpy(buf, password, size);
return plen;
}
// Does not handle "raw" form (e.g. #28C4D1), only escaped text
static std::string de4514(std::string const& input, int start, int& out_end) {
std::string output;
if(input[start] == '#' || input[start] == ' ') {
out_end = start;
return output;
}
int space_count = 0;
for(int p = start; p < input.size();) {
switch(input[p]) {
case '\\': // Handle escaped sequence
// Backslash escaping nothing!
if(p == input.size() - 1) {
out_end = p;
goto FIN;
}
switch(input[p+1]) {
case ' ':
case '"':
case '#':
case '+':
case ',':
case ';':
case '<':
case '=':
case '>':
case '\\':
output += input[p+1];
p += 2;
space_count = 0;
continue;
default:
// Backslash escaping pair of hex digits requires two characters
if(p == input.size() - 2) {
out_end = p;
goto FIN;
}
try {
output += hexValue(input[p+1]) * 16 + hexValue(input[p+2]);
p += 3;
space_count = 0;
continue;
} catch( ... ) {
out_end = p;
goto FIN;
}
}
case '"':
case '+':
case ',':
case ';':
case '<':
case '>':
case 0:
// All of these must have been escaped
out_end = p;
goto FIN;
default:
// Character is what it is
output += input[p];
if(input[p] == ' ')
space_count++;
else
space_count = 0;
p++;
}
}
out_end = input.size();
FIN:
out_end -= space_count;
output.resize(output.size() - space_count);
return output;
}
static std::pair<std::string, std::string> splitPair(std::string const& input, char c) {
int p = input.find_first_of(c);
if(p == input.npos) {
throw std::runtime_error("splitPair");
}
return std::make_pair(input.substr(0, p), input.substr(p+1, input.size()));
}
static int abbrevToNID(std::string const& sn) {
int nid = NID_undef;
if (sn == "C" || sn == "CN" || sn == "L" || sn == "ST" || sn == "O" || sn == "OU")
nid = OBJ_sn2nid(sn.c_str());
if (nid == NID_undef)
throw std::runtime_error("abbrevToNID");
return nid;
}
void FDBLibTLSPolicy::parse_verify(std::string input) {
int s = 0;
while (s < input.size()) {
int eq = input.find('=', s);
if (eq == input.npos)
throw std::runtime_error("parse_verify");
std::string term = input.substr(s, eq - s);
if (term.find("Check.") == 0) {
if (eq + 2 > input.size())
throw std::runtime_error("parse_verify");
if (eq + 2 != input.size() && input[eq + 2] != ',')
throw std::runtime_error("parse_verify");
bool* flag;
if (term == "Check.Valid")
flag = &verify_cert;
else if (term == "Check.Unexpired")
flag = &verify_time;
else
throw std::runtime_error("parse_verify");
if (input[eq + 1] == '0')
*flag = false;
else if (input[eq + 1] == '1')
*flag = true;
else
throw std::runtime_error("parse_verify");
s = eq + 3;
} else {
std::map<int, std::string>* criteria = &subject_criteria;
if (term.find('.') != term.npos) {
auto scoped = splitPair(term, '.');
if (scoped.first == "S" || scoped.first == "Subject")
criteria = &subject_criteria;
else if (scoped.first == "I" || scoped.first == "Issuer")
criteria = &issuer_criteria;
else
throw std::runtime_error("parse_verify");
term = scoped.second;
}
int remain;
auto unesc = de4514(input, eq + 1, remain);
if (remain == eq + 1)
throw std::runtime_error("parse_verify");
criteria->insert(std::make_pair(abbrevToNID(term), unesc));
if (remain != input.size() && input[remain] != ',')
throw std::runtime_error("parse_verify");
s = remain + 1;
}
}
}
void FDBLibTLSPolicy::reset_verify() {
verify_cert = true;
verify_time = true;
subject_criteria = {};
issuer_criteria = {};
}
int password_cb(char *buf, int size, int rwflag, void *u) {
// A no-op password callback is provided simply to stop libcrypto
// from trying to use its own password reading functionality.
return 0;
}
bool FDBLibTLSPolicy::set_cert_data(const uint8_t* cert_data, int cert_len) {
struct stack_st_X509* FDBLibTLSPolicy::parse_cert_pem(const uint8_t* cert_pem, size_t cert_pem_len) {
struct stack_st_X509 *certs = NULL;
unsigned long errnum;
X509 *cert = NULL;
BIO *bio = NULL;
long data_len;
char *data;
int errnum;
bool rc = false;
// The cert data contains one or more PEM encoded certificates - the
// first certificate is for this host, with any additional certificates
// being the full certificate chain. As such, the last certificate
// is the trusted root certificate. If only one certificate is provided
// then it is required to be a self-signed certificate, which is also
// treated as the trusted root.
if (cert_data_set) {
logf("FDBLibTLSCertAlreadySet", NULL, true, NULL);
if (cert_pem_len > INT_MAX)
goto err;
}
if (session_created) {
logf("FDBLibTLSPolicyAlreadyActive", NULL, true, NULL);
goto err;
}
if ((certs = sk_X509_new_null()) == NULL) {
if ((bio = BIO_new_mem_buf((void *)cert_pem, cert_pem_len)) == NULL) {
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
goto err;
}
if ((bio = BIO_new_mem_buf((void *)cert_data, cert_len)) == NULL) {
if ((certs = sk_X509_new_null()) == NULL) {
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
goto err;
}
@ -318,61 +141,21 @@ bool FDBLibTLSPolicy::set_cert_data(const uint8_t* cert_data, int cert_len) {
goto err;
}
BIO_free_all(bio);
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
goto err;
}
if (!PEM_write_bio_X509(bio, sk_X509_value(certs, sk_X509_num(certs) - 1))) {
logf("FDBLibTLSCertWriteError", NULL, true, NULL);
goto err;
}
if ((data_len = BIO_get_mem_data(bio, &data)) <= 0) {
logf("FDBLibTLSCertError", NULL, true, NULL);
goto err;
}
BIO_free(bio);
if (tls_config_set_ca_mem(tls_cfg, (const uint8_t *)data, data_len) == -1) {
logf("FDBLibTLSSetCAError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
goto err;
}
if (sk_X509_num(certs) > 1) {
BIO_free_all(bio);
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
goto err;
}
for (int i = 0; i < sk_X509_num(certs) - 1; i++) {
if (!PEM_write_bio_X509(bio, sk_X509_value(certs, i))) {
logf("FDBLibTLSCertWriteError", NULL, true, NULL);
goto err;
}
}
if ((data_len = BIO_get_mem_data(bio, &data)) <= 0) {
logf("FDBLibTLSCertError", NULL, true, NULL);
goto err;
}
}
if (tls_config_set_cert_mem(tls_cfg, (const uint8_t *)data, data_len) == -1) {
logf("FDBLibTLSSetCertError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
goto err;
}
rc = true;
return certs;
err:
sk_X509_pop_free(certs, X509_free);
X509_free(cert);
BIO_free_all(bio);
BIO_free(bio);
return rc;
return NULL;
}
bool FDBLibTLSPolicy::set_key_data(const uint8_t* key_data, int key_len) {
if (key_data_set) {
logf("FDBLibTLSKeyAlreadySet", NULL, true, NULL);
bool FDBLibTLSPolicy::set_ca_data(const uint8_t* ca_data, int ca_len) {
if (ca_data_set) {
logf("FDBLibTLSCAAlreadySet", NULL, true, NULL);
return false;
}
if (session_created) {
@ -380,17 +163,112 @@ bool FDBLibTLSPolicy::set_key_data(const uint8_t* key_data, int key_len) {
return false;
}
if (tls_config_set_key_mem(tls_cfg, key_data, key_len) == -1) {
logf("FDBLibTLSKeyError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
if (ca_len < 0)
return false;
sk_X509_pop_free(roots, X509_free);
if ((roots = parse_cert_pem(ca_data, ca_len)) == NULL)
return false;
if (tls_config_set_ca_mem(tls_cfg, ca_data, ca_len) == -1) {
logf("FDBLibTLSCAError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
return false;
}
key_data_set = true;
ca_data_set = true;
return true;
}
bool FDBLibTLSPolicy::set_verify_peers(const uint8_t* verify_peers, int verify_peers_len) {
bool FDBLibTLSPolicy::set_cert_data(const uint8_t* cert_data, int cert_len) {
if (cert_data_set) {
logf("FDBLibTLSCertAlreadySet", NULL, true, NULL);
return false;
}
if (session_created) {
logf("FDBLibTLSPolicyAlreadyActive", NULL, true, NULL);
return false;
}
if (tls_config_set_cert_mem(tls_cfg, cert_data, cert_len) == -1) {
logf("FDBLibTLSCertError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
return false;
}
cert_data_set = true;
return true;
}
bool FDBLibTLSPolicy::set_key_data(const uint8_t* key_data, int key_len, const char* password) {
EVP_PKEY *key = NULL;
BIO *bio = NULL;
bool rc = false;
if (key_data_set) {
logf("FDBLibTLSKeyAlreadySet", NULL, true, NULL);
goto err;
}
if (session_created) {
logf("FDBLibTLSPolicyAlreadyActive", NULL, true, NULL);
goto err;
}
if (password != NULL) {
char *data;
long len;
if ((bio = BIO_new_mem_buf((void *)key_data, key_len)) == NULL) {
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
goto err;
}
ERR_clear_error();
if ((key = PEM_read_bio_PrivateKey(bio, NULL, password_cb, (void *)password)) == NULL) {
int errnum = ERR_peek_error();
char errbuf[256];
if ((ERR_GET_LIB(errnum) == ERR_LIB_PEM && ERR_GET_REASON(errnum) == PEM_R_BAD_DECRYPT) ||
(ERR_GET_LIB(errnum) == ERR_LIB_EVP && ERR_GET_REASON(errnum) == EVP_R_BAD_DECRYPT)) {
logf("FDBLibTLSIncorrectPassword", NULL, true, NULL);
} else {
ERR_error_string_n(errnum, errbuf, sizeof(errbuf));
logf("FDBLibTLSPrivateKeyError", NULL, true, "LibcryptoErrorMessage", errbuf, NULL);
}
goto err;
}
BIO_free(bio);
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
goto err;
}
if (!PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) {
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
goto err;
}
if ((len = BIO_get_mem_data(bio, &data)) <= 0) {
logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
goto err;
}
if (tls_config_set_key_mem(tls_cfg, (const uint8_t *)data, len) == -1) {
logf("FDBLibTLSKeyError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
goto err;
}
} else {
if (tls_config_set_key_mem(tls_cfg, key_data, key_len) == -1) {
logf("FDBLibTLSKeyError", NULL, true, "LibTLSErrorMessage", tls_config_error(tls_cfg), NULL);
goto err;
}
}
key_data_set = true;
rc = true;
err:
BIO_free(bio);
EVP_PKEY_free(key);
return rc;
}
bool FDBLibTLSPolicy::set_verify_peers(int count, const uint8_t* verify_peers[], int verify_peers_len[]) {
if (verify_peers_set) {
logf("FDBLibTLSVerifyPeersAlreadySet", NULL, true, NULL);
return false;
@ -400,19 +278,26 @@ bool FDBLibTLSPolicy::set_verify_peers(const uint8_t* verify_peers, int verify_p
return false;
}
try {
parse_verify(std::string((const char*)verify_peers, verify_peers_len));
} catch ( const std::runtime_error& e ) {
reset_verify();
logf("FDBLibTLSVerifyPeersParseError", NULL, true, "Config", verify_peers, NULL);
if (count < 1) {
logf("FDBLibTLSNoVerifyPeers", NULL, true, NULL);
return false;
}
if (!verify_cert)
tls_config_insecure_noverifycert(tls_cfg);
for (int i = 0; i < count; i++) {
try {
Reference<FDBLibTLSVerify> verify = Reference<FDBLibTLSVerify>(new FDBLibTLSVerify(std::string((const char*)verify_peers[i], verify_peers_len[i])));
verify_rules.push_back(verify);
} catch ( const std::runtime_error& e ) {
verify_rules.clear();
logf("FDBLibTLSVerifyPeersParseError", NULL, true, "Config", verify_peers[i], NULL);
return false;
}
}
if (!verify_time)
tls_config_insecure_noverifytime(tls_cfg);
// All verification is manually handled (as requested via configuration).
tls_config_insecure_noverifycert(tls_cfg);
tls_config_insecure_noverifyname(tls_cfg);
tls_config_insecure_noverifytime(tls_cfg);
verify_peers_set = true;

View File

@ -23,12 +23,14 @@
#pragma once
#include "FDBLibTLSPlugin.h"
#include "ITLSPlugin.h"
#include "ReferenceCounted.h"
#include <map>
#include "FDBLibTLSPlugin.h"
#include "FDBLibTLSVerify.h"
#include <string>
#include <vector>
struct FDBLibTLSPolicy: ITLSPolicy, ReferenceCounted<FDBLibTLSPolicy> {
FDBLibTLSPolicy(Reference<FDBLibTLSPlugin> plugin, ITLSLogFunc logf);
@ -40,28 +42,29 @@ struct FDBLibTLSPolicy: ITLSPolicy, ReferenceCounted<FDBLibTLSPolicy> {
Reference<FDBLibTLSPlugin> plugin;
ITLSLogFunc logf;
virtual ITLSSession* create_session(bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid);
virtual ITLSSession* create_session(bool is_client, const char* servername, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid);
struct stack_st_X509* parse_cert_pem(const uint8_t* cert_pem, size_t cert_pem_len);
void parse_verify(std::string input);
void reset_verify(void);
virtual bool set_ca_data(const uint8_t* ca_data, int ca_len);
virtual bool set_cert_data(const uint8_t* cert_data, int cert_len);
virtual bool set_key_data(const uint8_t* key_data, int key_len);
virtual bool set_verify_peers(const uint8_t* verify_peers, int verify_peers_len);
virtual bool set_key_data(const uint8_t* key_data, int key_len, const char* password);
virtual bool set_verify_peers(int count, const uint8_t* verify_peers[], int verify_peers_len[]);
struct tls_config *tls_cfg;
struct tls_config* tls_cfg;
bool session_created;
bool ca_data_set;
bool cert_data_set;
bool key_data_set;
bool verify_peers_set;
bool verify_cert;
bool verify_time;
struct stack_st_X509* roots;
std::map<int, std::string> subject_criteria;
std::map<int, std::string> issuer_criteria;
std::vector<Reference<FDBLibTLSVerify>> verify_rules;
};
#endif /* FDB_LIBTLS_POLICY_H */

View File

@ -21,11 +21,12 @@
#include "FDBLibTLSSession.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <exception>
#include <iostream>
#include <string.h>
#include <limits.h>
@ -54,8 +55,9 @@ static ssize_t tls_write_func(struct tls *ctx, const void *buf, size_t buflen, v
return (ssize_t)rv;
}
FDBLibTLSSession::FDBLibTLSSession(Reference<FDBLibTLSPolicy> policy, bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid) :
tls_ctx(NULL), tls_sctx(NULL), policy(policy), send_func(send_func), send_ctx(send_ctx), recv_func(recv_func), recv_ctx(recv_ctx), handshake_completed(false), uid(uid) {
FDBLibTLSSession::FDBLibTLSSession(Reference<FDBLibTLSPolicy> policy, bool is_client, const char* servername, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid) :
tls_ctx(NULL), tls_sctx(NULL), is_client(is_client), policy(policy), send_func(send_func), send_ctx(send_ctx),
recv_func(recv_func), recv_ctx(recv_ctx), handshake_completed(false), uid(uid) {
if (is_client) {
if ((tls_ctx = tls_client()) == NULL) {
@ -67,7 +69,7 @@ FDBLibTLSSession::FDBLibTLSSession(Reference<FDBLibTLSPolicy> policy, bool is_cl
tls_free(tls_ctx);
throw std::runtime_error("FDBLibTLSConfigureError");
}
if (tls_connect_cbs(tls_ctx, tls_read_func, tls_write_func, this, NULL) == -1) {
if (tls_connect_cbs(tls_ctx, tls_read_func, tls_write_func, this, servername) == -1) {
policy->logf("FDBLibTLSConnectError", uid, true, "LibTLSErrorMessage", tls_error(tls_ctx), NULL);
tls_free(tls_ctx);
throw std::runtime_error("FDBLibTLSConnectError");
@ -97,8 +99,6 @@ FDBLibTLSSession::~FDBLibTLSSession() {
tls_free(tls_sctx);
}
int password_cb(char *buf, int size, int rwflag, void *u);
bool match_criteria(X509_NAME *name, int nid, const char *value, size_t len) {
unsigned char *name_entry_utf8 = NULL, *criteria_utf8 = NULL;
int name_entry_utf8_len, criteria_utf8_len;
@ -138,65 +138,108 @@ bool match_criteria(X509_NAME *name, int nid, const char *value, size_t len) {
return rc;
}
bool FDBLibTLSSession::check_criteria() {
bool FDBLibTLSSession::check_verify(Reference<FDBLibTLSVerify> verify, struct stack_st_X509 *certs) {
X509_STORE_CTX *store_ctx = NULL;
X509_NAME *subject, *issuer;
const uint8_t *cert_pem;
size_t cert_pem_len;
X509 *cert = NULL;
BIO *bio = NULL;
bool rc = false;
// If certificate verification is disabled, there's nothing more to do.
if (!policy->verify_cert)
if (!verify->verify_cert)
return true;
// If no criteria have been specified, then we're done.
if (policy->subject_criteria.size() == 0 && policy->issuer_criteria.size() == 0)
// Verify the certificate.
if ((store_ctx = X509_STORE_CTX_new()) == NULL) {
policy->logf("FDBLibTLSOutOfMemory", uid, true, NULL);
goto err;
}
if (!X509_STORE_CTX_init(store_ctx, NULL, sk_X509_value(certs, 0), certs)) {
policy->logf("FDBLibTLSStoreCtxInit", uid, true, NULL);
goto err;
}
X509_STORE_CTX_trusted_stack(store_ctx, policy->roots);
X509_STORE_CTX_set_default(store_ctx, is_client ? "ssl_client" : "ssl_server");
if (!verify->verify_time)
X509_VERIFY_PARAM_set_flags(X509_STORE_CTX_get0_param(store_ctx), X509_V_FLAG_NO_CHECK_TIME);
if (X509_verify_cert(store_ctx) <= 0) {
const char *errstr = X509_verify_cert_error_string(X509_STORE_CTX_get_error(store_ctx));
policy->logf("FDBLibTLSVerifyCert", uid, true, "VerifyError", errstr, NULL);
goto err;
}
// Check subject criteria.
if ((subject = X509_get_subject_name(sk_X509_value(store_ctx->chain, 0))) == NULL) {
policy->logf("FDBLibTLSCertSubjectError", uid, true, NULL);
goto err;
}
for (auto &pair: verify->subject_criteria) {
if (!match_criteria(subject, pair.first, pair.second.c_str(), pair.second.size())) {
policy->logf("FDBLibTLSCertSubjectMatchFailure", uid, true, NULL);
goto err;
}
}
// Check issuer criteria.
if ((issuer = X509_get_issuer_name(sk_X509_value(store_ctx->chain, 0))) == NULL) {
policy->logf("FDBLibTLSCertIssuerError", uid, true, NULL);
goto err;
}
for (auto &pair: verify->issuer_criteria) {
if (!match_criteria(issuer, pair.first, pair.second.c_str(), pair.second.size())) {
policy->logf("FDBLibTLSCertIssuerMatchFailure", uid, true, NULL);
goto err;
}
}
// Check root criteria - this is the subject of the final certificate in the stack.
if ((subject = X509_get_subject_name(sk_X509_value(store_ctx->chain, sk_X509_num(store_ctx->chain) - 1))) == NULL) {
policy->logf("FDBLibTLSRootSubjectError", uid, true, NULL);
goto err;
}
for (auto &pair: verify->root_criteria) {
if (!match_criteria(subject, pair.first, pair.second.c_str(), pair.second.size())) {
policy->logf("FDBLibTLSRootSubjectMatchFailure", uid, true, NULL);
goto err;
}
}
// If we got this far, everything checked out...
rc = true;
err:
X509_STORE_CTX_free(store_ctx);
return rc;
}
bool FDBLibTLSSession::verify_peer() {
struct stack_st_X509 *certs = NULL;
const uint8_t *cert_pem;
size_t cert_pem_len;
bool rc = false;
// If no verify peer rules have been set, we are relying on standard
// libtls verification.
if (policy->verify_rules.empty())
return true;
if ((cert_pem = tls_peer_cert_chain_pem(tls_ctx, &cert_pem_len)) == NULL) {
policy->logf("FDBLibTLSNoCertError", uid, true, NULL);
goto err;
}
if ((bio = BIO_new_mem_buf((void *)cert_pem, cert_pem_len)) == NULL) {
policy->logf("FDBLibTLSOutOfMemory", NULL, true, NULL);
if ((certs = policy->parse_cert_pem(cert_pem, cert_pem_len)) == NULL)
goto err;
}
if ((cert = PEM_read_bio_X509(bio, NULL, password_cb, NULL)) == NULL) {
policy->logf("FDBLibTLSCertPEMError", uid, true, NULL);
goto err;
}
// Check subject criteria.
if ((subject = X509_get_subject_name(cert)) == NULL) {
policy->logf("FDBLibTLSCertSubjectError", uid, true, NULL);
goto err;
}
for (auto &pair: policy->subject_criteria) {
if (!match_criteria(subject, pair.first, pair.second.c_str(), pair.second.size())) {
policy->logf("FDBLibTLSCertSubjectMatchFailure", uid, true, NULL);
goto err;
// Any matching rule is sufficient.
for (auto &verify_rule: policy->verify_rules) {
if (check_verify(verify_rule, certs)) {
rc = true;
break;
}
}
// Check issuer criteria.
if ((issuer = X509_get_issuer_name(cert)) == NULL) {
policy->logf("FDBLibTLSCertIssuerError", uid, true, NULL);
goto err;
}
for (auto &pair: policy->issuer_criteria) {
if (!match_criteria(issuer, pair.first, pair.second.c_str(), pair.second.size())) {
policy->logf("FDBLibTLSCertIssuerMatchFailure", uid, true, NULL);
goto err;
}
}
// If we got this far, everything checked out...
rc = true;
err:
BIO_free_all(bio);
X509_free(cert);
sk_X509_pop_free(certs, X509_free);
return rc;
}
@ -206,7 +249,7 @@ int FDBLibTLSSession::handshake() {
switch (rv) {
case 0:
if (!check_criteria())
if (!verify_peer())
return FAILED;
handshake_completed = true;
return SUCCESS;

View File

@ -27,17 +27,19 @@
#include "ReferenceCounted.h"
#include "FDBLibTLSPolicy.h"
#include "FDBLibTLSVerify.h"
#include <tls.h>
struct FDBLibTLSSession : ITLSSession, ReferenceCounted<FDBLibTLSSession> {
FDBLibTLSSession(Reference<FDBLibTLSPolicy> policy, bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid);
FDBLibTLSSession(Reference<FDBLibTLSPolicy> policy, bool is_client, const char* servername, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid);
virtual ~FDBLibTLSSession();
virtual void addref() { ReferenceCounted<FDBLibTLSSession>::addref(); }
virtual void delref() { ReferenceCounted<FDBLibTLSSession>::delref(); }
bool check_criteria();
bool verify_peer();
bool check_verify(Reference<FDBLibTLSVerify> verify, struct stack_st_X509 *certs);
virtual int handshake();
virtual int read(uint8_t* data, int length);
@ -45,6 +47,8 @@ struct FDBLibTLSSession : ITLSSession, ReferenceCounted<FDBLibTLSSession> {
Reference<FDBLibTLSPolicy> policy;
bool is_client;
struct tls *tls_ctx;
struct tls *tls_sctx;

View File

@ -0,0 +1,220 @@
/*
* FDBLibTLSVerify.cpp
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
*
* Licensed 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 "FDBLibTLSVerify.h"
#include <openssl/objects.h>
#include <algorithm>
#include <exception>
static int hexValue(char c) {
static char const digits[] = "0123456789ABCDEF";
if (c >= 'a' && c <= 'f')
c -= ('a' - 'A');
int value = std::find(digits, digits + 16, c) - digits;
if (value >= 16) {
throw std::runtime_error("hexValue");
}
return value;
}
// Does not handle "raw" form (e.g. #28C4D1), only escaped text
static std::string de4514(std::string const& input, int start, int& out_end) {
std::string output;
if(input[start] == '#' || input[start] == ' ') {
out_end = start;
return output;
}
int space_count = 0;
for(int p = start; p < input.size();) {
switch(input[p]) {
case '\\': // Handle escaped sequence
// Backslash escaping nothing!
if(p == input.size() - 1) {
out_end = p;
goto FIN;
}
switch(input[p+1]) {
case ' ':
case '"':
case '#':
case '+':
case ',':
case ';':
case '<':
case '=':
case '>':
case '\\':
output += input[p+1];
p += 2;
space_count = 0;
continue;
default:
// Backslash escaping pair of hex digits requires two characters
if(p == input.size() - 2) {
out_end = p;
goto FIN;
}
try {
output += hexValue(input[p+1]) * 16 + hexValue(input[p+2]);
p += 3;
space_count = 0;
continue;
} catch( ... ) {
out_end = p;
goto FIN;
}
}
case '"':
case '+':
case ',':
case ';':
case '<':
case '>':
case 0:
// All of these must have been escaped
out_end = p;
goto FIN;
default:
// Character is what it is
output += input[p];
if(input[p] == ' ')
space_count++;
else
space_count = 0;
p++;
}
}
out_end = input.size();
FIN:
out_end -= space_count;
output.resize(output.size() - space_count);
return output;
}
static std::pair<std::string, std::string> splitPair(std::string const& input, char c) {
int p = input.find_first_of(c);
if(p == input.npos) {
throw std::runtime_error("splitPair");
}
return std::make_pair(input.substr(0, p), input.substr(p+1, input.size()));
}
static int abbrevToNID(std::string const& sn) {
int nid = NID_undef;
if (sn == "C" || sn == "CN" || sn == "L" || sn == "ST" || sn == "O" || sn == "OU")
nid = OBJ_sn2nid(sn.c_str());
if (nid == NID_undef)
throw std::runtime_error("abbrevToNID");
return nid;
}
FDBLibTLSVerify::FDBLibTLSVerify(std::string verify_config):
verify_cert(true), verify_time(true) {
parse_verify(verify_config);
}
FDBLibTLSVerify::~FDBLibTLSVerify() {
}
void FDBLibTLSVerify::parse_verify(std::string input) {
int s = 0;
while (s < input.size()) {
int eq = input.find('=', s);
if (eq == input.npos)
throw std::runtime_error("parse_verify");
std::string term = input.substr(s, eq - s);
if (term.find("Check.") == 0) {
if (eq + 2 > input.size())
throw std::runtime_error("parse_verify");
if (eq + 2 != input.size() && input[eq + 2] != ',')
throw std::runtime_error("parse_verify");
bool* flag;
if (term == "Check.Valid")
flag = &verify_cert;
else if (term == "Check.Unexpired")
flag = &verify_time;
else
throw std::runtime_error("parse_verify");
if (input[eq + 1] == '0')
*flag = false;
else if (input[eq + 1] == '1')
*flag = true;
else
throw std::runtime_error("parse_verify");
s = eq + 3;
} else {
std::map<int, std::string>* criteria = &subject_criteria;
if (term.find('.') != term.npos) {
auto scoped = splitPair(term, '.');
if (scoped.first == "S" || scoped.first == "Subject")
criteria = &subject_criteria;
else if (scoped.first == "I" || scoped.first == "Issuer")
criteria = &issuer_criteria;
else if (scoped.first == "R" || scoped.first == "Root")
criteria = &root_criteria;
else
throw std::runtime_error("parse_verify");
term = scoped.second;
}
int remain;
auto unesc = de4514(input, eq + 1, remain);
if (remain == eq + 1)
throw std::runtime_error("parse_verify");
criteria->insert(std::make_pair(abbrevToNID(term), unesc));
if (remain != input.size() && input[remain] != ',')
throw std::runtime_error("parse_verify");
s = remain + 1;
}
}
}

View File

@ -0,0 +1,50 @@
/*
* FDBLibTLSVerify.h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
*
* Licensed 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.
*/
#ifndef FDB_LIBTLS_VERIFY_H
#define FDB_LIBTLS_VERIFY_H
#pragma once
#include <stdint.h>
#include "ReferenceCounted.h"
#include <map>
#include <string>
struct FDBLibTLSVerify: ReferenceCounted<FDBLibTLSVerify> {
FDBLibTLSVerify(std::string verify);
virtual ~FDBLibTLSVerify();
virtual void addref() { ReferenceCounted<FDBLibTLSVerify>::addref(); }
virtual void delref() { ReferenceCounted<FDBLibTLSVerify>::delref(); }
void parse_verify(std::string input);
bool verify_cert;
bool verify_time;
std::map<int, std::string> subject_criteria;
std::map<int, std::string> issuer_criteria;
std::map<int, std::string> root_criteria;
};
#endif /* FDB_LIBTLS_VERIFY_H */

View File

@ -1,140 +0,0 @@
/*
* ITLSPlugin.h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
*
* Licensed 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.
*/
#ifndef FDB_ITLSPLUGIN_H
#define FDB_ITLSPLUGIN_H
#pragma once
#include <stdint.h>
struct ITLSSession {
enum { SUCCESS = 0, WANT_READ = -1, WANT_WRITE = -2, FAILED = -3 };
virtual void addref() = 0;
virtual void delref() = 0;
// handshake should return SUCCESS if the handshake is complete,
// FAILED on fatal error, or one of WANT_READ or WANT_WRITE if the
// handshake should be reattempted after more data can be
// read/written on the underlying connection.
virtual int handshake() = 0;
// read should return the (non-zero) number of bytes read,
// WANT_READ or WANT_WRITE if the operation is blocked by the
// underlying stream, or FAILED if there is an error (including a
// closed connection).
virtual int read(uint8_t* data, int length) = 0;
// write should return the (non-zero) number of bytes written, or
// WANT_READ or WANT_WRITE if the operation is blocked by the
// underlying stream, or FAILED if there is an error.
virtual int write(const uint8_t* data, int length) = 0;
};
// Returns the number of bytes sent (possibly 0), or -1 on error
// (including connection close)
typedef int (*TLSSendCallbackFunc)(void* ctx, const uint8_t* buf, int len);
// Returns the number of bytes read (possibly 0), or -1 on error
// (including connection close)
typedef int (*TLSRecvCallbackFunc)(void* ctx, uint8_t* buf, int len);
struct ITLSPolicy {
virtual void addref() = 0;
virtual void delref() = 0;
// set_cert_data should import the provided certificate list and
// associate it with this policy. cert_data will point to a PEM
// encoded certificate list, ordered such that each certificate
// certifies the one before it.
//
// cert_data may additionally contain key information, which must
// be ignored.
//
// set_cert_data should return true if the operation succeeded,
// and false otherwise. After the first call to create_session for
// a given policy, set_cert_data should immediately return false
// if called.
virtual bool set_cert_data(const uint8_t* cert_data, int cert_len) = 0;
// set_key_data should import the provided private key and
// associate it with this policy. key_data will point to a PEM
// encoded key.
//
// key_data may additionally contain certificate information,
// which must be ignored.
//
// set_key_data should return true if the operation succeeded, and
// false otherwise. After the first call to create_session for a
// given policy, set_key_data should immediately return false if
// called.
virtual bool set_key_data(const uint8_t* key_data, int key_len) = 0;
// set_verify_peers should modify the validation rules for
// verifying a peer during connection handshake. The format of
// verify_peers is implementation specific.
//
// set_verify_peers should return true if the operation succeed,
// and false otherwise. After the first call to create_session for
// a given policy, set_verify_peers should immediately return
// false if called.
virtual bool set_verify_peers(const uint8_t* verify_peers, int verify_peers_len) = 0;
// create_session should return a new object that implements
// ITLSSession, associated with this policy. After the first call
// to create_session for a given policy, further calls to
// ITLSPolicy::set_* will fail and return false.
//
// The newly created session should use send_func and recv_func to
// send and receive data on the underlying transport, and must
// provide send_ctx/recv_ctx to the callbacks.
//
// uid should only be provided when invoking an ITLSLogFunc, which
// will use it to identify this session.
virtual ITLSSession* create_session(bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid ) = 0;
};
// Logs a message/error to the appropriate trace log.
//
// event must be a valid XML attribute value. uid may be NULL or the
// uid provided to ITLSPolicy::create_session by the caller. is_error
// should be true for errors and false for informational messages. The
// remaining arguments must be pairs of (const char*); the first of
// each pair must be a valid XML attribute name, and the second a
// valid XML attribute value. The final parameter must be NULL.
typedef void (*ITLSLogFunc)(const char* event, void* uid, bool is_error, ...);
struct ITLSPlugin {
virtual void addref() = 0;
virtual void delref() = 0;
// create_policy should return a new object that implements
// ITLSPolicy.
//
// The newly created policy, and any session further created from
// the policy, should use logf to log any messages or errors that
// occur.
virtual ITLSPolicy* create_policy( ITLSLogFunc logf ) = 0;
static inline const char* get_plugin_type_name_and_version() { return "ITLSPlugin"; }
};
#endif /* FDB_ITLSPLUGIN_H */

View File

@ -69,7 +69,7 @@ $(error Unknown platform $(PLATFORM))
endif
PLUGIN := FDBLibTLS.$(DYEXT)
OBJECTS := FDBLibTLSPlugin.o FDBLibTLSPolicy.o FDBLibTLSSession.o
OBJECTS := FDBLibTLSPlugin.o FDBLibTLSPolicy.o FDBLibTLSSession.o FDBLibTLSVerify.o
LINKLINE := $(CXXFLAGS) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $(LINK_LDFLAGS) -o $(PLUGIN)
all: $(PLUGIN)

View File

@ -1,4 +1,4 @@
FDBLibTLS_CFLAGS := -fPIC -I/usr/local/include -I$(BOOSTDIR)
FDBLibTLS_CFLAGS := -fPIC -I/usr/local/include -I$(BOOSTDIR) -Ifdbrpc
FDBLibTLS_STATIC_LIBS := -ltls -lssl -lcrypto
FDBLibTLS_LDFLAGS := -L/usr/local/lib -static-libstdc++ -static-libgcc -lrt
FDBLibTLS_LDFLAGS += -Wl,-soname,FDBLibTLS.so -Wl,--version-script=FDBLibTLS/FDBLibTLS.map

View File

@ -48,29 +48,27 @@ static std::string load_file(std::string path)
return ss.str();
}
struct FDBLibTLSClientServerTest {
FDBLibTLSClientServerTest(bool client_success, bool server_success, std::string client_path, std::string server_path, std::string client_verify, std::string server_verify):
client_success(client_success), server_success(server_success), client_verify(client_verify), server_verify(server_verify) {
client_data = load_file(TESTDATA + client_path);
server_data = load_file(TESTDATA + server_path);
}
~FDBLibTLSClientServerTest() {}
struct client_server_test {
std::string ca_path;
bool client_success;
bool server_success;
std::string client_path;
const char* client_password;
std::vector<std::string> client_verify;
const char* servername;
std::string client_data;
std::string client_verify;
std::string server_data;
std::string server_verify;
bool server_success;
std::string server_path;
const char* server_password;
std::vector<std::string> server_verify;
};
struct FDBLibTLSPluginTest {
FDBLibTLSPluginTest(Reference<ITLSPlugin> plugin, ITLSLogFunc logf);
~FDBLibTLSPluginTest();
FDBLibTLSPluginTest(Reference<ITLSPlugin> plugin, ITLSLogFunc logf);
~FDBLibTLSPluginTest();
Reference<ITLSPlugin> plugin;
ITLSLogFunc logf;
Reference<ITLSPlugin> plugin;
ITLSLogFunc logf;
boost::circular_buffer<uint8_t> client_buffer;
boost::circular_buffer<uint8_t> server_buffer;
@ -83,13 +81,13 @@ struct FDBLibTLSPluginTest {
int server_write(const uint8_t* buf, int len);
Reference<ITLSPolicy> create_policy(void);
Reference<ITLSSession> create_client_session(Reference<ITLSPolicy> policy);
Reference<ITLSSession> create_client_session(Reference<ITLSPolicy> policy, const char* servername);
Reference<ITLSSession> create_server_session(Reference<ITLSPolicy> policy);
void circular_reset(void);
void circular_self_test(void);
int client_server_test(FDBLibTLSClientServerTest const& cst);
int client_server_test(const struct client_server_test *cst);
int set_cert_data_test(void);
};
@ -225,9 +223,9 @@ static int client_recv_func(void* ctx, uint8_t* buf, int len) {
}
}
Reference<ITLSSession> FDBLibTLSPluginTest::create_client_session(Reference<ITLSPolicy> policy)
Reference<ITLSSession> FDBLibTLSPluginTest::create_client_session(Reference<ITLSPolicy> policy, const char* servername)
{
return Reference<ITLSSession>(policy->create_session(true, client_send_func, this, client_recv_func, this, NULL));
return Reference<ITLSSession>(policy->create_session(true, servername, client_send_func, this, client_recv_func, this, NULL));
}
static int server_send_func(void* ctx, const uint8_t* buf, int len) {
@ -250,42 +248,74 @@ static int server_recv_func(void* ctx, uint8_t* buf, int len) {
Reference<ITLSSession> FDBLibTLSPluginTest::create_server_session(Reference<ITLSPolicy> policy)
{
return Reference<ITLSSession>(policy->create_session(false, server_send_func, this, server_recv_func, this, NULL));
return Reference<ITLSSession>(policy->create_session(false, NULL, server_send_func, this, server_recv_func, this, NULL));
}
int FDBLibTLSPluginTest::client_server_test(FDBLibTLSClientServerTest const& cst)
#define MAX_VERIFY_RULES 5
static void convert_verify_peers(const std::vector<std::string> *verify_rules, const uint8_t *verify_peers[], int verify_peers_len[]) {
if (verify_rules->size() > MAX_VERIFY_RULES)
throw std::runtime_error("verify");
int i = 0;
for (auto &verify_rule: *verify_rules) {
verify_peers[i] = (const uint8_t *)&verify_rule[0];
verify_peers_len[i] = verify_rule.size();
i++;
}
}
int FDBLibTLSPluginTest::client_server_test(const struct client_server_test* cst)
{
const uint8_t *verify_peers[MAX_VERIFY_RULES];
int verify_peers_len[MAX_VERIFY_RULES];
circular_reset();
std::string ca_data = load_file(TESTDATA + cst->ca_path);
std::string client_data = load_file(TESTDATA + cst->client_path);
std::string server_data = load_file(TESTDATA + cst->server_path);
Reference<ITLSPolicy> client_policy = create_policy();
if (!client_policy->set_cert_data((const uint8_t*)&cst.client_data[0], cst.client_data.size())) {
if (!client_policy->set_ca_data((const uint8_t*)&ca_data[0], ca_data.size())) {
std::cerr << "FAIL: failed to set client ca data\n";
return 1;
}
if (!client_policy->set_cert_data((const uint8_t*)&client_data[0], client_data.size())) {
std::cerr << "FAIL: failed to set client cert data\n";
return 1;
}
if (!client_policy->set_key_data((const uint8_t*)&cst.client_data[0], cst.client_data.size())) {
if (!client_policy->set_key_data((const uint8_t*)&client_data[0], client_data.size(), cst->client_password)) {
std::cerr << "FAIL: failed to set client key data\n";
return 1;
}
if (!client_policy->set_verify_peers((const uint8_t*)&cst.client_verify[0], cst.client_verify.size())) {
std::cerr << "FAIL: failed to set client key data\n";
return 1;
if (!cst->client_verify.empty()) {
convert_verify_peers(&cst->client_verify, verify_peers, verify_peers_len);
if (!client_policy->set_verify_peers(cst->client_verify.size(), verify_peers, verify_peers_len)) {
std::cerr << "FAIL: failed to set client verify peers\n";
return 1;
}
}
Reference<ITLSPolicy> server_policy = create_policy();
if (!server_policy->set_cert_data((const uint8_t*)&cst.server_data[0], cst.server_data.size())) {
if (!server_policy->set_ca_data((const uint8_t*)&ca_data[0], ca_data.size())) {
std::cerr << "FAIL: failed to set server ca data\n";
return 1;
}
if (!server_policy->set_cert_data((const uint8_t*)&server_data[0], server_data.size())) {
std::cerr << "FAIL: failed to set server cert data\n";
return 1;
}
if (!server_policy->set_key_data((const uint8_t*)&cst.server_data[0], cst.server_data.size())) {
if (!server_policy->set_key_data((const uint8_t*)&server_data[0], server_data.size(), cst->server_password)) {
std::cerr << "FAIL: failed to set server key data\n";
return 1;
}
if (!server_policy->set_verify_peers((const uint8_t*)&cst.server_verify[0], cst.server_verify.size())) {
std::cerr << "FAIL: failed to set client key data\n";
convert_verify_peers(&cst->server_verify, verify_peers, verify_peers_len);
if (!server_policy->set_verify_peers(cst->server_verify.size(), verify_peers, verify_peers_len)) {
std::cerr << "FAIL: failed to set server verify peers\n";
return 1;
}
Reference<ITLSSession> client_session = create_client_session(client_policy);
Reference<ITLSSession> client_session = create_client_session(client_policy, cst->servername);
Reference<ITLSSession> server_session = create_server_session(server_policy);
if (client_session.getPtr() == NULL || server_session.getPtr() == NULL)
@ -302,7 +332,7 @@ int FDBLibTLSPluginTest::client_server_test(FDBLibTLSClientServerTest const& cst
if (rc == ITLSSession::SUCCESS) {
client_done = true;
} else if (rc == ITLSSession::FAILED) {
if (cst.client_success) {
if (cst->client_success) {
std::cerr << "FAIL: failed to complete client handshake\n";
return 1;
} else {
@ -320,7 +350,7 @@ int FDBLibTLSPluginTest::client_server_test(FDBLibTLSClientServerTest const& cst
if (rc == ITLSSession::SUCCESS) {
server_done = true;
} else if (rc == ITLSSession::FAILED) {
if (cst.server_success) {
if (cst->server_success) {
std::cerr << "FAIL: failed to complete server handshake\n";
return 1;
} else {
@ -340,11 +370,15 @@ int FDBLibTLSPluginTest::client_server_test(FDBLibTLSClientServerTest const& cst
return 1;
}
if (!cst.client_success && !client_failed)
if (!cst->client_success && !client_failed) {
std::cerr << "FAIL: client handshake succeeded when it should have failed\n";
if (!cst.server_success && !server_failed)
return 1;
}
if (!cst->server_success && !server_failed) {
std::cerr << "FAIL: server handshake succeeded when it should have failed\n";
if (!cst.client_success || !cst.server_success)
return 1;
}
if (!cst->client_success || !cst->server_success)
return 0;
std::cerr << "INFO: handshake completed successfully\n";
@ -477,6 +511,546 @@ static void logf(const char* event, void* uid, int is_error, ...) {
va_end(args);
}
const struct client_server_test client_server_tests[] = {
// Single root CA.
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-2.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-2.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
// Multiple root CAs.
{
.ca_path = "test-ca-all.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-4.pem",
.server_password = "fdb123",
.server_verify = {""},
},
{
.ca_path = "test-ca-all.pem",
.client_success = true,
.client_path = "test-client-4.pem",
.client_password = "fdb321",
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = "fdb123",
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-4.pem",
.server_password = "fdb123",
.server_verify = {""},
},
{
.ca_path = "test-ca-2.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = false,
.server_path = "test-server-4.pem",
.server_password = "fdb123",
.server_verify = {""},
},
// Expired certificates.
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-3.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-3.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = false,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"Check.Unexpired=0"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-3.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-3.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"Check.Unexpired=0"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"Check.Valid=0"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-3.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-3.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"Check.Valid=0"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 1", "I.CN=FDB LibTLS Plugin Test Intermediate CA 2,Check.Unexpired=0"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-3.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 1,Check.Unexpired=0", "I.CN=FDB LibTLS Plugin Test Intermediate CA 2"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-3.pem",
.server_password = NULL,
.server_verify = {""},
},
// Match on specific subject and/or issuer.
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"C=US"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"C=US"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"C=AU"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"C=US", "C=AU"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"C=US", "C=JP"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\04\\>"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"CN=FDB LibTLS Plugin Test Server 2\\, \\81 \\<\\01\\+\\02=\\04\\>"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\04"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {"CN=FDB LibTLS Plugin Test Client 1"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"CN=FDB LibTLS Plugin Test Client 1"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-2.pem",
.client_password = NULL,
.client_verify = {""},
.servername = NULL,
.server_success = false,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"O=Apple Pty Limited,OU=FDC Team"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-2.pem",
.client_password = NULL,
.client_verify = {"O=Apple Inc.,OU=FDB Team"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"O=Apple Pty Limited,OU=FDB Team"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-2.pem",
.client_password = NULL,
.client_verify = {"O=Apple Inc.,OU=FDC Team"},
.servername = NULL,
.server_success = false,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"O=Apple Pty Limited,OU=FDC Team"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDB Team"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDB Team"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDC Team"},
.servername = NULL,
.server_success = false,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDC Team"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 2"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 2"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>,I.CN=FDB LibTLS Plugin Test Intermediate CA 2"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 1,O=Apple Inc.,I.C=US,S.C=US"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>,I.CN=FDB LibTLS Plugin Test Intermediate CA 1"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {"I.CN=FDB LibTLS Plugin Test Intermediate CA 1,O=Apple Inc.,I.C=US,S.C=US"},
},
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"R.CN=FDB LibTLS Plugin Test Root CA 1"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-2.pem",
.server_password = NULL,
.server_verify = {"R.CN=FDB LibTLS Plugin Test Root CA 1"},
},
{
.ca_path = "test-ca-all.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"R.CN=FDB LibTLS Plugin Test Root CA 1"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-4.pem",
.server_password = "fdb123",
.server_verify = {"R.CN=FDB LibTLS Plugin Test Root CA 1"},
},
{
.ca_path = "test-ca-all.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"R.CN=FDB LibTLS Plugin Test Root CA 1", "R.CN=FDB LibTLS Plugin Test Root CA 2"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-4.pem",
.server_password = "fdb123",
.server_verify = {"R.CN=FDB LibTLS Plugin Test Root CA 1"},
},
{
.ca_path = "test-ca-all.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"R.CN=FDB LibTLS Plugin Test Root CA 2"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-4.pem",
.server_password = "fdb123",
.server_verify = {"R.CN=FDB LibTLS Plugin Test Root CA 1"},
},
{
.ca_path = "test-ca-all.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {"R.OU=FDB Team"},
.servername = NULL,
.server_success = true,
.server_path = "test-server-4.pem",
.server_password = "fdb123",
.server_verify = {"R.OU=FDB Team"},
},
// Client performing name validation via servername.
{
.ca_path = "test-ca-1.pem",
.client_success = true,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {},
.servername = "test.foundationdb.org",
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {""},
},
{
.ca_path = "test-ca-1.pem",
.client_success = false,
.client_path = "test-client-1.pem",
.client_password = NULL,
.client_verify = {},
.servername = "www.foundationdb.org",
.server_success = true,
.server_path = "test-server-1.pem",
.server_password = NULL,
.server_verify = {""},
},
};
int main(int argc, char **argv)
{
void *pluginSO = NULL;
@ -502,81 +1076,12 @@ int main(int argc, char **argv)
Reference<ITLSPlugin> plugin = Reference<ITLSPlugin>((ITLSPlugin *)getPlugin(ITLSPlugin::get_plugin_type_name_and_version()));
std::vector<FDBLibTLSClientServerTest> tests = {
// Valid - all use single root CA.
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem", "", ""),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem", "", ""),
FDBLibTLSClientServerTest(true, true, "test-2-client.pem", "test-2-server.pem", "", ""),
FDBLibTLSClientServerTest(true, true, "test-2-client.pem", "test-1-server.pem", "", ""),
// Certificates terminate at different intermediate CAs.
FDBLibTLSClientServerTest(false, false, "test-4-client.pem", "test-5-server.pem", "", ""),
FDBLibTLSClientServerTest(false, false, "test-5-client.pem", "test-4-server.pem", "", ""),
FDBLibTLSClientServerTest(true, true, "test-4-client.pem", "test-5-server.pem",
"Check.Valid=0", "Check.Valid=0"),
FDBLibTLSClientServerTest(true, true, "test-5-client.pem", "test-4-server.pem",
"Check.Valid=0", "Check.Valid=0"),
// Expired certificates.
FDBLibTLSClientServerTest(false, false, "test-1-client.pem", "test-3-server.pem", "", ""),
FDBLibTLSClientServerTest(false, false, "test-3-client.pem", "test-1-server.pem", "", ""),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-3-server.pem", "Check.Unexpired=0", ""),
FDBLibTLSClientServerTest(true, true, "test-3-client.pem", "test-1-server.pem", "", "Check.Unexpired=0"),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-3-server.pem", "Check.Valid=0", ""),
FDBLibTLSClientServerTest(true, true, "test-3-client.pem", "test-1-server.pem", "", "Check.Valid=0"),
// Match on specific subject and/or issuer.
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem", "C=US", ""),
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem", "C=US", ""),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem", "C=AU", ""),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem",
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>", ""),
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem",
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\04\\>", ""),
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem",
"CN=FDB LibTLS Plugin Test Server 2\\, \\81 \\<\\01\\+\\02=\\04\\>", ""),
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem",
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\04", ""),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem",
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>",
"CN=FDB LibTLS Plugin Test Client 1"),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem",
"", "CN=FDB LibTLS Plugin Test Client 1"),
FDBLibTLSClientServerTest(true, false, "test-2-client.pem", "test-1-server.pem",
"", "O=Apple Pty Limited,OU=FDC Team"),
FDBLibTLSClientServerTest(true, true, "test-2-client.pem", "test-1-server.pem",
"O=Apple Inc.,OU=FDB Team", "O=Apple Pty Limited,OU=FDB Team"),
FDBLibTLSClientServerTest(false, false, "test-2-client.pem", "test-1-server.pem",
"O=Apple Inc.,OU=FDC Team", "O=Apple Pty Limited,OU=FDC Team"),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem",
"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDB Team",
"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDB Team"),
FDBLibTLSClientServerTest(false, false, "test-1-client.pem", "test-1-server.pem",
"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDC Team",
"I.C=US,I.ST=California,I.L=Cupertino,I.O=Apple Inc.,I.OU=FDC Team"),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-1-server.pem",
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1",
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"),
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-1-server.pem",
"I.CN=FDB LibTLS Plugin Test Intermediate CA 2",
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem",
"I.CN=FDB LibTLS Plugin Test Intermediate CA 2",
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1"),
FDBLibTLSClientServerTest(true, true, "test-1-client.pem", "test-2-server.pem",
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>,I.CN=FDB LibTLS Plugin Test Intermediate CA 2",
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1,O=Apple Inc.,I.C=US,S.C=US"),
FDBLibTLSClientServerTest(false, true, "test-1-client.pem", "test-2-server.pem",
"CN=FDB LibTLS Plugin Test Server 2\\, \\80 \\<\\01\\+\\02=\\03\\>,I.CN=FDB LibTLS Plugin Test Intermediate CA 1",
"I.CN=FDB LibTLS Plugin Test Intermediate CA 1,O=Apple Inc.,I.C=US,S.C=US"),
};
FDBLibTLSPluginTest *pt = new FDBLibTLSPluginTest(plugin, (ITLSLogFunc)logf);
int test_num = 1;
for (auto &test: tests) {
for (auto &cst: client_server_tests) {
std::cerr << "== Test " << test_num++ << " ==\n";
failed |= pt->client_server_test(test);
failed |= pt->client_server_test(&cst);
}
delete pt;

View File

@ -1,6 +1,6 @@
#!/bin/sh
#
# make-tests-certs.sh
# make-test-certs.sh
#
# This source file is part of the FoundationDB open source project
#
@ -33,6 +33,17 @@ cleanup() {
trap cleanup EXIT INT
make_ca_bundle() {
local bundle_file=$1;
shift 1;
printf '' > "${bundle_file}"
for f in $@; do
openssl x509 -nameopt oneline -subject -issuer -noout -in "${TMPDIR}/${f}" >> "${bundle_file}"
cat "${TMPDIR}/${f}" >> "${bundle_file}"
done
}
make_bundle() {
local bundle_file=$1;
local key_file=$2;
@ -80,36 +91,60 @@ subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:false
keyUsage = critical, digitalSignature
[fdb_v3_server_san]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:false
keyUsage = critical, digitalSignature
subjectAltName = @fdb_v3_server_alt_names
[fdb_v3_server_alt_names]
DNS.1 = test.foundationdb.org
EOF
# Root CA.
# Root CA 1.
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 -x509 \
-subj "${SUBJECT} Root CA" -keyout "${TMPDIR}/ca-root.key" \
-subj "${SUBJECT} Root CA 1" -keyout "${TMPDIR}/ca-root-1.key" \
-config "${TMPDIR}/openssl.cnf" -extensions fdb_v3_ca \
-out "${TMPDIR}/ca-root.crt"
-out "${TMPDIR}/ca-root-1.crt"
# Intermediate CA 1.
# Root CA 2.
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 -x509 \
-subj "${SUBJECT_ALT} Root CA 2" -keyout "${TMPDIR}/ca-root-2.key" \
-config "${TMPDIR}/openssl.cnf" -extensions fdb_v3_ca \
-out "${TMPDIR}/ca-root-2.crt"
# Intermediate CA 1 (from CA 1).
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
-subj "${SUBJECT} Intermediate CA 1" -keyout "${TMPDIR}/ca-int-1.key" \
-out "${TMPDIR}/ca-int-1.csr"
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-root.crt" -CAkey "${TMPDIR}/ca-root.key" \
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-root-1.crt" -CAkey "${TMPDIR}/ca-root-1.key" \
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_ca -days 3650 \
-CAcreateserial -in "${TMPDIR}/ca-int-1.csr" -out "${TMPDIR}/ca-int-1.crt"
# Intermediate CA 2.
# Intermediate CA 2 (from CA 1).
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
-subj "${SUBJECT} Intermediate CA 2" -keyout "${TMPDIR}/ca-int-2.key" \
-out "${TMPDIR}/ca-int-2.csr"
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-root.crt" -CAkey "${TMPDIR}/ca-root.key" \
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-root-1.crt" -CAkey "${TMPDIR}/ca-root-1.key" \
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_ca -days 3650 \
-CAcreateserial -in "${TMPDIR}/ca-int-2.csr" -out "${TMPDIR}/ca-int-2.crt"
# Intermediate CA 3 (from CA 2).
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
-subj "${SUBJECT} Intermediate CA 3" -keyout "${TMPDIR}/ca-int-3.key" \
-out "${TMPDIR}/ca-int-3.csr"
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-root-2.crt" -CAkey "${TMPDIR}/ca-root-2.key" \
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_ca -days 3650 \
-CAcreateserial -in "${TMPDIR}/ca-int-3.csr" -out "${TMPDIR}/ca-int-3.crt"
# Server 1.
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
-subj "${SUBJECT} Server 1" -keyout "${TMPDIR}/server-1.key" \
-out "${TMPDIR}/server-1.csr"
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-int-1.crt" -CAkey "${TMPDIR}/ca-int-1.key" \
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_other -days 3650 \
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_server_san -days 3650 \
-CAcreateserial -in "${TMPDIR}/server-1.csr" -out "${TMPDIR}/server-1.crt"
# Server 2.
@ -130,6 +165,15 @@ printf "y\ny\n" | openssl ca -cert "${TMPDIR}/ca-int-1.crt" -keyfile "${TMPDIR}/
-config "${TMPDIR}/openssl.cnf" -notext \
-in "${TMPDIR}/server-3.csr" -out "${TMPDIR}/server-3.crt"
# Server 4.
openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -aes128 -pass pass:fdb123 \
-out "${TMPDIR}/server-4.key"
openssl req -new -days 3650 -sha256 -key "${TMPDIR}/server-4.key" -passin pass:fdb123 \
-subj "${SUBJECT} Server 4" -out "${TMPDIR}/server-4.csr"
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-int-3.crt" -CAkey "${TMPDIR}/ca-int-3.key" \
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_other -days 3650 \
-CAcreateserial -in "${TMPDIR}/server-4.csr" -out "${TMPDIR}/server-4.crt"
# Client 1.
openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \
-subj "${SUBJECT} Client 1" -keyout "${TMPDIR}/client-1.key" \
@ -156,23 +200,35 @@ printf "y\ny\n" | openssl ca -cert "${TMPDIR}/ca-int-1.crt" -keyfile "${TMPDIR}/
-config "${TMPDIR}/openssl.cnf" \
-in "${TMPDIR}/client-3.csr" -out "${TMPDIR}/client-3.crt"
# Client 4.
openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -aes128 -pass pass:fdb321 \
-out "${TMPDIR}/client-4.key"
openssl req -new -days 3650 -sha256 -key "${TMPDIR}/client-4.key" -passin pass:fdb321 \
-subj "${SUBJECT} Client 4" -out "${TMPDIR}/client-4.csr"
openssl x509 -req -days 3650 -CA "${TMPDIR}/ca-int-3.crt" -CAkey "${TMPDIR}/ca-int-3.key" \
-extfile "${TMPDIR}/openssl.cnf" -extensions fdb_v3_other \
-CAcreateserial -in "${TMPDIR}/client-4.csr" -out "${TMPDIR}/client-4.crt"
#
# Test Bundles
#
make_bundle 'test-1-server.pem' 'server-1.key' 'server-1.crt' 'ca-int-1.crt' 'ca-root.crt'
make_bundle 'test-1-client.pem' 'client-1.key' 'client-1.crt' 'ca-int-1.crt' 'ca-root.crt'
make_bundle 'test-2-server.pem' 'server-2.key' 'server-2.crt' 'ca-int-2.crt' 'ca-root.crt'
make_bundle 'test-2-client.pem' 'client-2.key' 'client-2.crt' 'ca-int-2.crt' 'ca-root.crt'
make_ca_bundle 'test-ca-1.pem' 'ca-root-1.crt'
make_ca_bundle 'test-ca-2.pem' 'ca-root-2.crt'
make_ca_bundle 'test-ca-all.pem' 'ca-root-1.crt' 'ca-root-2.crt'
# Expired client/server.
make_bundle 'test-3-client.pem' 'client-3.key' 'client-3.crt' 'ca-int-1.crt' 'ca-root.crt'
make_bundle 'test-3-server.pem' 'server-3.key' 'server-3.crt' 'ca-int-1.crt' 'ca-root.crt'
# Valid client/server from intermediate CA 1.
make_bundle 'test-client-1.pem' 'client-1.key' 'client-1.crt' 'ca-int-1.crt'
make_bundle 'test-server-1.pem' 'server-1.key' 'server-1.crt' 'ca-int-1.crt'
# Bundles that terminate at intermediate 1.
make_bundle 'test-4-server.pem' 'server-1.key' 'server-1.crt' 'ca-int-1.crt'
make_bundle 'test-4-client.pem' 'client-1.key' 'client-1.crt' 'ca-int-1.crt'
# Valid client/server from intermediate CA 2.
make_bundle 'test-client-2.pem' 'client-2.key' 'client-2.crt' 'ca-int-2.crt'
make_bundle 'test-server-2.pem' 'server-2.key' 'server-2.crt' 'ca-int-2.crt'
# Bundles that terminate at intermediate 2.
make_bundle 'test-5-server.pem' 'server-2.key' 'server-2.crt' 'ca-int-2.crt'
make_bundle 'test-5-client.pem' 'client-2.key' 'client-2.crt' 'ca-int-2.crt'
# Expired client/server from intermediate CA 1.
make_bundle 'test-client-3.pem' 'client-3.key' 'client-3.crt' 'ca-int-1.crt'
make_bundle 'test-server-3.pem' 'server-3.key' 'server-3.crt' 'ca-int-1.crt'
# Valid client/server from intermediate CA 3.
make_bundle 'test-client-4.pem' 'client-4.key' 'client-4.crt' 'ca-int-3.crt'
make_bundle 'test-server-4.pem' 'server-4.key' 'server-4.crt' 'ca-int-3.crt'

View File

@ -1,106 +0,0 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Client 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIJALOPTrQGpeslMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGIMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
UyBQbHVnaW4gVGVzdCBDbGllbnQgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALVkdxOmWcd959NyirJ1iz7q5fkjdRUV+88KMMehQWc3f50GJIQ+eZo+
7RhwVE+n8nd0i5iGfyY6LRuupdwoQUxoZ/5rUIDGKspNO62DVRW+tZqzpEa1+ub5
75BMoc7I7l9sXDkuiMu1OYcPNKMv4F3mf+B3ourLqjUekKlUv8XIZXAvN+R19HlR
FM8vs8rnhQXx7iWVP91frDvyD8G7lOf6R7R4homnB37kLom8WU+fCmcyA6em0qX0
JeVP6xk2qXU1cMs7DL8WftdrWHv+a73/l4hytQHo5OvtGaLZhpPYpC/FMSaFHVSM
irWSFK+ZtvaLi3LXc2HGANMokjPoRf8CAwEAAaNgMF4wHQYDVR0OBBYEFPtTL9KZ
jn49cLediy1ixz7AXOI3MB8GA1UdIwQYMBaAFCXTF7f83Hd7xm9gR+O4QrvjNo8Q
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
AQA17a4d/tSWIlTkIfkrXziD21+1OsN6/dUrWQK7kxtEe21QXIutccW4bwpM0JDB
M+bZiWkdgQ15+ZotX5UXlBcx9WWDU5RqSO06hhXu5b8gZwfVF4Od6tBdVxkn4KbU
0YujOZrL8fDOrQHqCO7nhNlYgcEn7bKF5wjtOoiKhtA9sLSIZQR5g32kkJXXGvcY
lLWMXygEg9FMQoldW9RHq4GbUiYEeqEq6k4S7cE03R1lvmQEOOAJ2S7LnaS4UHQT
GmW6uvLnJJrG4HB9JGE+y1e9M+C7Enzhi39RGd8ylignGimkdw/1UEWnvKGCqoU7
ufWGF7eUV8dCqO+jYghIY8rA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
XvmR6B5iRkDVpw==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1ZHcTplnHfefT
coqydYs+6uX5I3UVFfvPCjDHoUFnN3+dBiSEPnmaPu0YcFRPp/J3dIuYhn8mOi0b
rqXcKEFMaGf+a1CAxirKTTutg1UVvrWas6RGtfrm+e+QTKHOyO5fbFw5LojLtTmH
DzSjL+Bd5n/gd6Lqy6o1HpCpVL/FyGVwLzfkdfR5URTPL7PK54UF8e4llT/dX6w7
8g/Bu5Tn+ke0eIaJpwd+5C6JvFlPnwpnMgOnptKl9CXlT+sZNql1NXDLOwy/Fn7X
a1h7/mu9/5eIcrUB6OTr7Rmi2YaT2KQvxTEmhR1UjIq1khSvmbb2i4ty13NhxgDT
KJIz6EX/AgMBAAECggEAEm2Mc2CZCl1OKfsfABZU+SVgC7mAcY30MQp1/jHxtQy8
WDWBjDXUoMj3yV3QEu+bAGvEqtAvJrEOWBucGgu05pBM0FoSqaJ4QmkqQOxwvm7L
gFXzwINIZCLMJbrDTYC4RtV5YQ3LM/bLS19OF64Lez6piyJcWMIsHo1mYO2NNgiD
7f1x1uQw46Q0YHWeoHY58MPfmgfKsqnJDWc8cCuU9fJOWeU4dVrfW8dh9WVAoLZ7
qAM5vvap11Qk8RXaRnmLjxN6H1M7iVNfcLVNKfG6XOBBepYjZr/qMkuN3ONuqBHl
fC3Zia2zQZRfiuPspX0KhjCfYAKbIZC6oyrQM2uXgQKBgQDoD5voZiCOeGXJEMUk
9JV4V8A96aE0xxy+OHMogVpysxBO4V0Nh0krSLTt9NXnpjawZQ+3pLQ4+2J2XM2e
fJuJJ7Z+Mhjv6epnMM7FoxK1VF7oe+LE7Yk/kg/moCuVS/XhLdQrhZVBJhfEADS3
oFybf7Q6rJYtN3OYsiFymyneHwKBgQDIGsY5kGdmx27LS5rPMwdw632TF8G5BGbu
C3ty7LYkOWb/9/V4cuWjW4eLJQqCWbJQrzOvg0coxwXLUuEQik+IP2IkF0YlRS43
VJuULwOxi3Cbj51RoapHhmYTO9fe2A1N9oJMAqEUHY1q/r9txPcguRWyuH2Yv9Ih
OzHnc2DcIQKBgQCGW0MxMq/2zM5hs0vxMYq4ulWbgwDKxd1mZNiHwxzS+8mdYe22
P3WlkdrvSqnuDNXtGxYWhU2zEBjZ3rFN6WdD6bJHLkox3YTRafjNhLT4N3kbsV6C
FeU44SBDrsiNEAWz8gy9hgH8TknEOTpMdpQnk7CNqA7q7wgGiFvFNwDukQKBgG7i
R03Gs0XE5aRJtPN0N39fPyqvU24O/mqSekno2dWg6W6WHLQuFwo6whVc5UHuKl2D
eISdnmT+RDuzJXxg6El7tgqByyEEAOQwQjYPB2Du/+tz3Z1KlG0mEJI/6xNVbany
G6m7Gz9mUOMlXzaYmsjLRzbN/OsUAIDhqHm0+cuBAoGAZCND80akS3xr3yC87GyX
aA0RoHXbdB6dbP8Y6XYDXR4QFIA4kXwY5cCLaZA/0hP5FOzDhORmaoaPM8vUdNyb
IYvbw2H6tODiU5oICWY6+HQQ2nXikucI4HDYDLbsiV2htZkEmBYWLilYq0Tb8jC5
u+ehIIvZYLqKaY1GaKmF86A=
-----END PRIVATE KEY-----

View File

@ -1,106 +0,0 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Server 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIJALOPTrQGpesjMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGIMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
UyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAJp26QAmlMusO7C8Py/I117r3kHvB+My5kIrj8g9sKpktwTzmsJGpvJU
EaKISEdBsJHLGnZJhwIhr/+MG4WDEM4oFNCtBQZznV3wjIQWq1w4IO8/f3+nBPpW
f14fjs1E911Uo/ZOL9bxvh1SIHkS6itgJi+tgVPx7C3s3W3mC5nU3omsE+Rx4DDm
KUq1kyN1ELBIAceQ4wTmQ5B8dv6MSW7zt8Jdrhfhg2GJIPPB6XUZJ2yIOvgu55GW
J5sMPa0uNDfCsWJ37fzFm+XJ/D96t7x8I49IyfzbIgcU9JYFlcqkryvKh5IpQGGm
H/I6adIWa5xWpMhB2PA6kgtDD07Hu2sCAwEAAaNgMF4wHQYDVR0OBBYEFJ7S+FUz
9ngzH/TNPVeM/cE7LeBGMB8GA1UdIwQYMBaAFCXTF7f83Hd7xm9gR+O4QrvjNo8Q
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
AQAx6WHwikVFAH0TRYCznwO6He+0t2pnlyfrI+24N28tzupMSrRPs086UbLgHLz1
lbkYdheeOkLPzjWi5vfymL1Oua3E2iAXWEpMb4Sg7E5SVHp9yt6gZ0DTVwR+Gcu7
uooroidAG3OFeOXL5ivU5J5ipaoEAiLprpKxtPzo4z/TxIqw3kJISC56qw9VTJNQ
TQZvneUecykdIZuH61ih0cJLe5WRkEs/63Dgl8TBYiVDbvBSGRbsXoAXcspVlc2x
XOLey5IVJ4/TH5ZBobShC6J1KrjZTNYvUgc44CocOgrc0ePPiQzB7JXxR1H8ATGl
yKjWqT2PkrfHmjdcmsi2GIVt
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
XvmR6B5iRkDVpw==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCadukAJpTLrDuw
vD8vyNde695B7wfjMuZCK4/IPbCqZLcE85rCRqbyVBGiiEhHQbCRyxp2SYcCIa//
jBuFgxDOKBTQrQUGc51d8IyEFqtcOCDvP39/pwT6Vn9eH47NRPddVKP2Ti/W8b4d
UiB5EuorYCYvrYFT8ewt7N1t5guZ1N6JrBPkceAw5ilKtZMjdRCwSAHHkOME5kOQ
fHb+jElu87fCXa4X4YNhiSDzwel1GSdsiDr4LueRliebDD2tLjQ3wrFid+38xZvl
yfw/ere8fCOPSMn82yIHFPSWBZXKpK8ryoeSKUBhph/yOmnSFmucVqTIQdjwOpIL
Qw9Ox7trAgMBAAECggEAOZAMvsCh/NDfobpVddJL6JTPzBRvBQ1H3+rp9z5+ItHL
nq3Fw5aeynnn5IETJnLlgT+GSgSWqoWxV/N3oia40YsATs/bqo7VW1e0ldj43TIR
m/c25XRxl3U6m/H4vqhv4rkTLUvv6hNGvRiI/3W8DJQVRvlK0+S5FlhKIJV1R0sH
tp5vmaPp09Ln+NVno3u3iaYkVgVME4Ukul2i03sQ9OgvZSBCaVr//fMpiPdBeeN6
QY6XHjeGQRnP/UdzMYJ4Qz1yovL1ntneaTMdz/GkKuAFoNNh8Vr2kiEskW17OWPB
ZGcIT6YpBEPo34xXUhUQt7ylFPxGH+zZyHZ3vb8j6QKBgQDJPeu/iPg+M5nz5gO5
ge9gzYrhxK/1mwbFlD7qt1NjOSm6xWxUcss3STjuG7jB0c+NopIUoq/egsUnxrRm
4l17uOCYNLbhTJ2ynfv6QnUMxW5Xkve3DkLa2bze/fhMUywTy8N4A7z0+y35qzm3
lY4rLmQOQKPkmqWRnxU1u8fjFQKBgQDEfpOZ0fp2D/1gTG+D+/zrMEbjnNn3ZO8I
wrjoXwRxcRggt7lJhxgQpwtDr98IqYkDzX7bvyMFJuyTii3NM6NYycpA1pHX70B/
xMvOcrgJnIUAoJ7nl43Or7s8bFTPDLaD9PNGHjrlkF3JOXqSKEbw367jHVOa4SYr
OjrogjrEfwKBgQDHU2a7ax5+9btqggx0ZQfGOTBzmM60lZ3qe4CqGXUl1YvIrB01
tBImq4cRCTJB/9/1qO3KNK2/1oUTddRgB5ySnDcRaz0tASc9sQ/Q/JxVTwSRB0gG
78A2Zu6VbLbQWp1Q6kWtDP7PJC+QmRFtDlwn1yZRm6L6HlcaWpi2hU1iVQKBgCEu
ashv8Aad3qCzZ6V3GReyOFZZd2lSjxcAou8ClKJ/gZ6Mx+pFuOee/cT5XwV8c5nD
yuda2JQXJZ4omGFtlej5coEOeuRnD5JD7lK3hqKA3ujjNtJPAnBjto+Wj5/DOtL/
u1Ec6782aNABN9SUnp4wd7z8h9DAsoxcMfRvgXMLAoGBAJ9gGttfqZbuPz9V0rAo
p05SPPado1i5+2dUOScIbNB6+vQij9IlR2Tzu1T9DwzrBqTDPPmSggeA/JXeTvh6
Skb9fDukizeDfwPYUN2gljhiJEqFdpRBr5vP0lFi291+a0jMW1zldrumxCcGKMyU
D5ReKLp/zSQSQi/Wt4FF1II7
-----END PRIVATE KEY-----

View File

@ -1,106 +0,0 @@
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Client 2, \C2\80 <\01+\02=\03>"
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
-----BEGIN CERTIFICATE-----
MIIEEzCCAvugAwIBAgIJALOPTrQGpesmMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGdMQswCQYDVQQGEwJBVTEYMBYG
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBDbGllbnQgMiwgwoAgPAErAj0DPjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALanLExQi/yK2PRyu6Mvdw2MRxUs
26kJftYuK7KtYyltTO3vtj4kNKg1vZI1eezhqr2Ta/1DzE76eLVs8EOW0LAb5oWM
zXdYBXBX4vG+K7pYfjuvZUd6jfX2bHW10xC96HgDTfRn6dof8GR0fILJ6DoEcyI3
82xnKKxTsgAuXU4uvcsl0g0F78nXuIbk8ZktTV3LIdbOCIcLQfG7DdDyAfEA0T7Q
Vg6eeLknIUvPePxyWkUdYeSCDP2d+3NIlHMxNPmH1q3+fCsEsy/kqdVO9e6KrZla
CKqnc6yYTXvTffpPepC3Igz678iGg3dv9rLj0i4fyTr4tEOTJebO9Ka3TbMCAwEA
AaNgMF4wHQYDVR0OBBYEFKO2/D1IhG8KWFwR6OdyoFqEzIWAMB8GA1UdIwQYMBaA
FJFP+HFpDrD0BRU0yE606s6xkqFBMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQAQV3FjsvZvwi5Oi/oSc7Du/BQS9nQ/D4j6
IeYpd3M0y50awZB83BReYrhdC907xKkLRD0R8oEPDEg5SaSj3vRML4kaUUqnEINW
4JQtv4wNO9CagYriGg8ygQa0xd683svHeXDet3ov11XN/Ms8lfDiOUp2291HgeTW
8hqn1DaNfZrCb3EkdoNThwVKIUzQtEPBuPkLE+XT8kZP5d8KHmv8/9L39NdZY32d
fzKGBeCxZ34pQS0cTap3rZ02nDfV2vNevODRyuqdhs7EQps2Oe1IfPB9GSE0OFUQ
tdphxSjsv1BcHpTwBDpIITKarnceMIKxQjcZU3yPv5ibIaGCgZOt
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpesiMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEApTSBCiUb0amf+QRV2WY6b3bK93D/PSrm4KR/2m2V0lciU1DAk00/kZ52
ZIZmq8g9EaE2+CaDtU0fMvDZpaZD+vTFRwsx4varehq0ZwX9Wt25i/3G/eGLNlD3
9E4tDNruK5UQjum4nJ0SV+AdFEGkSfeU3ZJEHYH0NrcbyAUbh0KeWCSwHiYiFJJf
gBYwRq/HdKNoS/4YvLXzTLR7BSm3YcqWlO5tdkJ2lcT/7Th/Hq1TCW/FKwdQJJBq
JrbOYGlMrf1pLO7Drei/xhsYkwTQ899MhSjkBRhc+401p41Mky0n8wLkuPJGhoY3
9QUOjT+Rmvq5yryg0eWGiFquk6Ru5QIDAQABo2MwYTAdBgNVHQ4EFgQUkU/4cWkO
sPQFFTTITrTqzrGSoUEwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAJfCHU7dm2/2ASyt3wyxivQLxlV6FsEZcF7HcpbbxuB73frGOL4kEoOxvr2X
fBGyjlPMotbc1MeAalAv+hVHdcAcBFPF7lxtYiV6D7YI5T5yVbWSASG3+DMAiW6S
GdQi2eyeh00nH7Y1IkW+yaky0enBtWLzrw+XzHl6xT6DIEJnir//PNxvgXTJ5sjk
6eFAm8HJIqkNQmgfChMQfUH6nm66WwULW6I117RCSkXhIgxZ7wzDq8bXcEdXCrZk
yy5ket9OiVpbd38JgdYirBLmCQVq0uDOOPLz4ZJmNCzQzEt+38AAK2azAk/eb8W9
JaKWH+5V8lhlyGw1zQKdNEP/wg8=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
XvmR6B5iRkDVpw==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC2pyxMUIv8itj0
crujL3cNjEcVLNupCX7WLiuyrWMpbUzt77Y+JDSoNb2SNXns4aq9k2v9Q8xO+ni1
bPBDltCwG+aFjM13WAVwV+Lxviu6WH47r2VHeo319mx1tdMQveh4A030Z+naH/Bk
dHyCyeg6BHMiN/NsZyisU7IALl1OLr3LJdINBe/J17iG5PGZLU1dyyHWzgiHC0Hx
uw3Q8gHxANE+0FYOnni5JyFLz3j8clpFHWHkggz9nftzSJRzMTT5h9at/nwrBLMv
5KnVTvXuiq2ZWgiqp3OsmE170336T3qQtyIM+u/IhoN3b/ay49IuH8k6+LRDkyXm
zvSmt02zAgMBAAECggEAU2sYHSZwOH+FRGcd8RJdcg+N60rYa2QNzG27wVfUwPfN
OaHP/qN0dRpOIPdRXvFVlE0+9aVAKxXTiTBers+zMascZgP/VrEZksxgtn1e5TVD
OakKPVHogdvwfvXylmPVRvJjaOsIb3lExew5bVYfPFgJ6Sfagbi/Z6y1z8VdEbYb
mI34KSZA4bBAMAHPZLa9TGEx/vbPsBlqpU6k8lcoy3cTkO5fCZW4ZZIpwBwef4uJ
UozhRgtTtRBiUpk0F9IoOXonZY1Dtpg+HcDMti/FYgahBVe1hadJ+lbVTxH6GxyI
NJYvptdq5S99UOoJDmCCih0v0ZCUNYWoO0I0vzNncQKBgQDemN7es2fIBstiPjOf
p103DF5j9Uxq5YH9B3wli0CXf6Z2w5uosONoJWgJZKsHJ6f+YSuHsoE/eCrFF3U9
lxT9Nie/wYYIGedly/VR143aCdiTXI44m5gxXgwaUcjvY1DpWyEAAmr5XNdoyZ5n
LNTvOTb4vVo9SgDU7II7rdpRmwKBgQDSD9aBtIy/650suQK/9RiXRU0Kg7LXXVM5
lavPgLvH55lufJeGSa8+ofCNeo31N4AaVuU4lkGeny9tLNBQbYAoyAz0lf51qK7B
1u5JqBDyRrIpdkqwbT0FT1pu1LA3+Qg0KQBrTCnOx+YyyVSivR4YMZzJjmwZGKMg
BWOi0PzhyQKBgGR44dfpaIWbs39zjf+ZHnTza0N4+/YgA60/DKUxloULRArFPeRF
e0+N2siqnJvNJYGnQGuugbIxPjTZ4rxbDklAgW6HHkVX099Z0TAQuGFbIltZYoRg
jrBxv8q9cZHD5Uh/LoT/kmNdqYkNwCbX0IDt9UcOyMVzOq7g1eO0FB/TAoGBAMaG
tWIsMwGHOip0SAcHKtB8bI1NXo5v4yH/NDuOHOqXFcj383S02uzEu8XaV6Ozalx6
V3SdfTLem0IBIneApajlOGlIAQ9N9qu358ixECMJcYQCCiCnfQ4xqvQoCss7judN
ANpnRvPotMS2xkhvl6uh594NvlgRksnGjh3oibcRAoGBAJKiu5ajmIkelzAhFMEC
Slxhg/E+djJ1/SG/FaF8zIyTOxre/QUvmTwFKtHe6A5EfKQo9GCTuHuAcJ1U7eQP
l2BoY0POqJFpw3s/QOt4g/pOz0YjD9GD6awL5WDfO++s4mnI1Snc3wcu99N4Klax
htsaEUECJBUF0ZpIFad73s2f
-----END PRIVATE KEY-----

View File

@ -1,106 +0,0 @@
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Server 2, \C2\80 <\01+\02=\03>"
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
-----BEGIN CERTIFICATE-----
MIIEEzCCAvugAwIBAgIJALOPTrQGpeskMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGdMQswCQYDVQQGEwJBVTEYMBYG
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMiwgwoAgPAErAj0DPjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALAolQZIGMeL5w/Bu2X6lHWjO58u
+HUDtBmr37So4jazhZBSFDBg+QlRMiYGLev9EhvCrUsVcRwtvtcuMI3wfKl7qgbi
ZX8zmrzZ3YJo9U47NzCa05faOl8uSBvuXuXUBLU342WFP8XDB1W8yOBQMK73xoFv
DkcxURx9ZtOhdC3EgYKrFqOB1Azl1DB4gLV3h9rHW5QpQ8SqD9CyggcDBpDeZQIP
+4l5YFE9Nb4kEUTscz2wGn4TdHMmcnVpfUxp1Y2o8Umvh4llXHIPhximGb3JJ4QQ
Sir4ZXeeoooWoJG0sdlqVLroKav/VMGtEu9LyfbrNdKnTJq3ceVQ+HJ2hlMCAwEA
AaNgMF4wHQYDVR0OBBYEFH61Z8O9vFsVdhM4MBU3poX2UMTEMB8GA1UdIwQYMBaA
FJFP+HFpDrD0BRU0yE606s6xkqFBMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQCVbxlLGIBCo6/XXjqoMyZc7uQZJj7pGnwh
nIMs2izCLfax8j+QrThO2Qjn03zT/WF8eG6ibPbjgnw3VFwCkV6oQ+BXG6Yt0xqP
4rz1LzxSio6HSm26gSk4SQUsVoAtz3OImoTCFVfz+Mixe87pyVXXEEtCYvfU74H9
I1WGyNkWAxiJbqeIxF5PKoc3EdnT5mfdC6sdeGm7t2neeS8PDFQtJ4UfVIEK5z1C
MOfQILNkLX2nBYxNqKpV66zf68VZNN9002ZH2FITGqImpj74BEws3sheiuZySdoI
wnAwRnymIMfAmkf9C7Q2ugId0YMMyesaWrIwSlXlJOHGsA1VrBRD
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpesiMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEApTSBCiUb0amf+QRV2WY6b3bK93D/PSrm4KR/2m2V0lciU1DAk00/kZ52
ZIZmq8g9EaE2+CaDtU0fMvDZpaZD+vTFRwsx4varehq0ZwX9Wt25i/3G/eGLNlD3
9E4tDNruK5UQjum4nJ0SV+AdFEGkSfeU3ZJEHYH0NrcbyAUbh0KeWCSwHiYiFJJf
gBYwRq/HdKNoS/4YvLXzTLR7BSm3YcqWlO5tdkJ2lcT/7Th/Hq1TCW/FKwdQJJBq
JrbOYGlMrf1pLO7Drei/xhsYkwTQ899MhSjkBRhc+401p41Mky0n8wLkuPJGhoY3
9QUOjT+Rmvq5yryg0eWGiFquk6Ru5QIDAQABo2MwYTAdBgNVHQ4EFgQUkU/4cWkO
sPQFFTTITrTqzrGSoUEwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAJfCHU7dm2/2ASyt3wyxivQLxlV6FsEZcF7HcpbbxuB73frGOL4kEoOxvr2X
fBGyjlPMotbc1MeAalAv+hVHdcAcBFPF7lxtYiV6D7YI5T5yVbWSASG3+DMAiW6S
GdQi2eyeh00nH7Y1IkW+yaky0enBtWLzrw+XzHl6xT6DIEJnir//PNxvgXTJ5sjk
6eFAm8HJIqkNQmgfChMQfUH6nm66WwULW6I117RCSkXhIgxZ7wzDq8bXcEdXCrZk
yy5ket9OiVpbd38JgdYirBLmCQVq0uDOOPLz4ZJmNCzQzEt+38AAK2azAk/eb8W9
JaKWH+5V8lhlyGw1zQKdNEP/wg8=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
XvmR6B5iRkDVpw==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCwKJUGSBjHi+cP
wbtl+pR1ozufLvh1A7QZq9+0qOI2s4WQUhQwYPkJUTImBi3r/RIbwq1LFXEcLb7X
LjCN8Hype6oG4mV/M5q82d2CaPVOOzcwmtOX2jpfLkgb7l7l1AS1N+NlhT/FwwdV
vMjgUDCu98aBbw5HMVEcfWbToXQtxIGCqxajgdQM5dQweIC1d4fax1uUKUPEqg/Q
soIHAwaQ3mUCD/uJeWBRPTW+JBFE7HM9sBp+E3RzJnJ1aX1MadWNqPFJr4eJZVxy
D4cYphm9ySeEEEoq+GV3nqKKFqCRtLHZalS66Cmr/1TBrRLvS8n26zXSp0yat3Hl
UPhydoZTAgMBAAECggEAVD60NlLYduXzVNfDtVuHEFNGOjSOYfepc/V8gLubo6lr
IMAAI7rcnpYUM5cU8x0OQfRyR8wzUdSWxfWzBs6R78PSZoRzIcgeIl7Wzn0/g3BS
To5czuxwqgBKQAFZpPQmZDwcJfr5qqxAn8IvFweCoMqiRlhELcvqDIP0XxWBqDjc
TNJ988XzZXQmJbjjpWOkUBy2Uqz8lZt8MmxKFpW7SW4tBJwPphnorgjWfjCV/VEh
ORio0rG74NHFo4f1TSrdU2BcB2cbVJ4B+bcUYRdvYmS5bmokhGF8vir0l43gUEdz
Fyk6MaPrTI6cinqzenm3q/0eRvNhBE56U0tiGLn14QKBgQDkCkt1Y4LEboSwsVYl
IXriStqj9p9MOizihh0enhzRXTTQuLX82fNi+bh1LAluwv290Q57pvKa+hB/YciB
o4s7QfSojxQY9DxqvXN7CvxPWXHTyFY5sL4Rm807+C/a9rd39MxBynz9u/7YRvsA
s8v8Y/01qIHnTo+mpDvu6HttWwKBgQDFwdRkgstuE+dXZZe8g1ivh3RNPa968TE3
b8rzF9/nOJV7f6B/n6YEmHD/cHF5mm1bR+zt/jtf1NCRMpazchw3vT3JzQZYMDnM
SD6vxTs5rG47QLiNyTIRmmD4gsEWBpyvoyP8E/9QdfDT1bWI5zZnky9CquRlN+cu
J1bTsefEaQKBgGJsRxFNd91MThztDV9NSfptkFyAT1TZLxI+DEdwusNqVSdY8cNG
VpP7cC+yaAfURSwuFPAtqDxXfdNc4uuBKNDUsMInrubuUz1Gs5cBsNCWrFhZ+U1B
CWgUNMqTXiRFo/40PAyRVs003NOAH0m4UGyIw3rrVdX9xGaKMAv3b35NAoGATkkl
I4UDs1f9xQNaxi3Y9ePRjqJUzX6d1SxUU1eoM4ia5IDpsJwqxLb0RKrmwRT5JaGb
kbuLFazRxCkar38E3Kv1weWAFXlB6DTRXBPgFjzEhoBgjwCO6ZkLulVIysdjT8Rt
gmUINXn7FGENtFyTlP0XQHUWZVt0ETlRjgxni8ECgYBYv6MoSr0iPjQpxeKvwFDz
d9zE+ZXN+3GwtkI340lKRSc/f0Uq1TlC2w+DzjyyXcrBwubMQKTKcQQSH9f3YbMu
DuxVE9AXdlQ1gSQHGjS0qUWwsS/8Xcjk8ZuduAXPGr/MsvsW+FbbZqG8qdZTeMHu
MSTpOxu9HXC8SHML+y0cpw==
-----END PRIVATE KEY-----

View File

@ -1,150 +0,0 @@
subject=
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 1048578 (0x100002)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, L=Cupertino, O=Apple Inc., OU=FDB Team, CN=FDB LibTLS Plugin Test Intermediate CA 1
Validity
Not Before: Jan 1 00:00:00 2017 GMT
Not After : Dec 31 00:00:00 2017 GMT
Subject:
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:e4:6f:67:4b:e7:d2:1b:0a:ec:f8:92:ae:1e:d4:
e9:00:6b:47:83:ad:4e:9e:e2:cc:52:b0:8a:04:46:
57:1f:f7:32:37:cc:f0:cd:ec:c0:b9:b9:27:b4:19:
33:a1:21:a7:4c:a2:6c:c7:56:31:c4:6a:4f:5f:fb:
92:6c:22:8f:c4:eb:3f:d1:2b:06:c7:7b:6b:90:83:
37:d3:59:1c:c0:da:de:85:a1:dc:e6:9d:e1:d8:fc:
6f:d4:c0:b4:6e:37:3d:d2:d7:4e:4e:04:09:6a:fb:
9f:d3:cf:b1:80:db:7a:78:97:65:e1:bc:8d:5a:fa:
ec:b1:b6:ee:3f:c9:03:83:ab:0a:9a:8e:03:29:88:
42:14:50:80:11:a7:d5:2d:87:c8:bd:25:32:9e:55:
fb:22:ef:9c:64:a8:a4:62:3b:d6:86:43:1a:22:a3:
1c:4b:ee:af:30:70:d3:9c:aa:da:b6:87:61:78:87:
32:0c:0b:b7:44:16:9b:44:1b:4e:6d:f3:98:99:f8:
ed:ae:41:02:5d:52:9a:98:49:c3:24:24:0b:18:7b:
bf:40:ce:37:65:0f:32:0c:1c:5a:47:4b:b0:3f:db:
17:b6:89:68:99:3c:0e:70:84:92:5c:33:cb:6d:2e:
67:c8:af:47:41:87:bd:37:87:88:00:65:1f:7e:7b:
d9:09
Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption
0b:5a:f7:7e:e5:93:4b:25:dc:01:eb:20:37:cb:bd:a9:71:3a:
af:6d:73:d9:9e:3c:8b:5c:6d:74:45:76:72:02:64:7e:e6:41:
bf:29:d7:cd:f8:a7:2d:87:32:6d:25:3f:14:11:2b:95:5a:2e:
a8:8b:ba:b1:f9:52:79:b4:5b:ea:fe:b0:ee:b0:9c:14:53:ba:
5d:64:aa:b9:d9:ca:17:b2:99:da:34:18:31:56:83:d9:21:8f:
20:9e:6a:7f:09:41:2f:36:fa:ab:e7:d1:6c:76:50:d4:51:69:
b9:93:ae:9a:eb:8a:6f:a9:91:21:58:a9:3d:53:e8:c1:2c:6f:
88:25:65:03:8a:90:9c:8e:58:5d:9a:e2:67:8e:6a:f6:11:19:
24:8d:89:b7:11:5e:a8:dc:21:35:7a:9a:78:8a:94:c2:29:84:
bb:b7:a5:8e:04:79:dc:db:9d:d7:a7:a3:b7:39:e6:c3:a5:be:
83:ad:59:3a:ee:ea:4a:8a:bd:6e:71:c9:e4:a7:46:d5:a3:fd:
a0:b1:a3:54:8d:bc:01:fb:68:4c:5a:a2:f5:79:44:f7:b9:e9:
7b:db:91:91:74:5b:68:f6:3a:b2:70:ee:e6:49:f4:f1:a6:53:
66:13:ce:2f:9e:88:45:66:34:ae:fc:0d:14:02:6f:6a:c9:ac:
b5:3f:89:bc
-----BEGIN CERTIFICATE-----
MIIDCDCCAfACAxAAAjANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMCVVMxEzAR
BgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwK
QXBwbGUgSW5jLjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJU
TFMgUGx1Z2luIFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwHhcNMTcwMTAxMDAwMDAw
WhcNMTcxMjMxMDAwMDAwWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEA5G9nS+fSGwrs+JKuHtTpAGtHg61OnuLMUrCKBEZXH/cyN8zwzezAubkntBkz
oSGnTKJsx1YxxGpPX/uSbCKPxOs/0SsGx3trkIM301kcwNrehaHc5p3h2Pxv1MC0
bjc90tdOTgQJavuf08+xgNt6eJdl4byNWvrssbbuP8kDg6sKmo4DKYhCFFCAEafV
LYfIvSUynlX7Iu+cZKikYjvWhkMaIqMcS+6vMHDTnKratodheIcyDAu3RBabRBtO
bfOYmfjtrkECXVKamEnDJCQLGHu/QM43ZQ8yDBxaR0uwP9sXtolomTwOcISSXDPL
bS5nyK9HQYe9N4eIAGUffnvZCQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQALWvd+
5ZNLJdwB6yA3y72pcTqvbXPZnjyLXG10RXZyAmR+5kG/KdfN+KcthzJtJT8UESuV
Wi6oi7qx+VJ5tFvq/rDusJwUU7pdZKq52coXspnaNBgxVoPZIY8gnmp/CUEvNvqr
59FsdlDUUWm5k66a64pvqZEhWKk9U+jBLG+IJWUDipCcjlhdmuJnjmr2ERkkjYm3
EV6o3CE1epp4ipTCKYS7t6WOBHnc253Xp6O3OebDpb6DrVk67upKir1uccnkp0bV
o/2gsaNUjbwB+2hMWqL1eUT3uel725GRdFto9jqycO7mSfTxplNmE84vnohFZjSu
/A0UAm9qyay1P4m8
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
XvmR6B5iRkDVpw==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDkb2dL59IbCuz4
kq4e1OkAa0eDrU6e4sxSsIoERlcf9zI3zPDN7MC5uSe0GTOhIadMomzHVjHEak9f
+5JsIo/E6z/RKwbHe2uQgzfTWRzA2t6FodzmneHY/G/UwLRuNz3S105OBAlq+5/T
z7GA23p4l2XhvI1a+uyxtu4/yQODqwqajgMpiEIUUIARp9Uth8i9JTKeVfsi75xk
qKRiO9aGQxoioxxL7q8wcNOcqtq2h2F4hzIMC7dEFptEG05t85iZ+O2uQQJdUpqY
ScMkJAsYe79AzjdlDzIMHFpHS7A/2xe2iWiZPA5whJJcM8ttLmfIr0dBh703h4gA
ZR9+e9kJAgMBAAECggEBAKC87x+PQN18g6CpfdH+GPINiuXR9ieBCSsKRCOb50R7
6Z8wGyWbeUV2TsTAkv7HsnQPOqHNOfmuoKm2WKK0cxuqOV6SexO0+cxXONoDs2LU
342ChvDTmY7YmkxHSO7g+iS5EcV9u67G3gDp/Unhpjzis3Ly/ThOpmyqftztMgbb
6KKfgGi3VL+fZ2x8gQt0II2QcO6GIzrPcn9ruEM6tXJhQ50YaSCeCmseKBvKuWPW
b/Gj7wgYhsiMW+nt8QjVam99eCQ6Q94CsapWRdGpj1Nrd4ISREbqr8x4fmcbiSO6
6HZyUidxZIxr2Y4/BTd/BiIqXXdKAMoCVElmyE09P4ECgYEA9IkOkHq1jDLAmppd
fNSC/ndmITS0imvwzTTubXKOTn3yZHVxk2/ld83aauGA3UwAueW4Hh0hJdIWqC0d
IyaNj3EhcVbidyYwvXdChlPuQ1uccu/earhzsbaFwqNoLVgMrPcB5QcMKUs2/s4Q
tBXOqNlFjDZ+bkHQyGXtFYJzknECgYEA7yUcJqf2jB5e4LWG4Se4zD1E/ccZH3t8
nhuXa6nDsx2trZBknHpQmc85WzbBITD+LRaamlYpnB1Ueiyr7/Efamtls7NvnoQN
14cNFnnj5HooTHJHgNBuL/M3hr/q8uK4lR6bu/DOfzUfRGowX3pj+POB01ObPdm8
BUTFwmfJTBkCgYEAkakqccmGZxK8Q9t7oKX9uZJp1ZHNkT6m27WR6MP6HKtNPaXv
l4Fp0KlgV5Yn6qohLJq3x8hWPG8ea+MjnhKS9ETRRPAaShsHoXRuvhE0tg7V7GkR
tcRVtiAhIUWxAoGWW1lvWXuPNPHGupUIwhzTUyTJFrJHMWom8Zg1V0CzkyECgYEA
0JpPXwzejEUlv9+4owhyM34ygyg8KvEduBEbWWfBdKmryR2OFczAKBrRzlYJy3kg
DpaMD5qfOzV+bgAvjuKG496A3WrlL6HDLUD50qRKfQ9tvZll8+BcbWk8A0e/m1TX
bARCFoOsrNvaxWPXhEGPmSZYFc31OdOHJhViZ/z+Y2kCgYEAphx6cPXLMcgv0ivj
SgIG09vo3hGA5r06FkLtGL677CTvYsk/Equ5TkG0AIJ0acY9wiabk6zyM/9XjRAp
Nf8qYzhaMxJiyw+JEXmud4Dc41DqjGm9bLV4tKSR+7xzPBP9Q/QLxfRvArBOKhiX
L5fWmM5SQAoHsf124DTKckNirLI=
-----END PRIVATE KEY-----

View File

@ -1,101 +0,0 @@
subject=
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
-----BEGIN CERTIFICATE-----
MIIDCDCCAfACAxAAATANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMCVVMxEzAR
BgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwK
QXBwbGUgSW5jLjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJU
TFMgUGx1Z2luIFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwHhcNMTcwMTAxMDAwMDAw
WhcNMTcxMjMxMDAwMDAwWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEA43+uFNDYKXQQ4fmSencxdm/mfM6FAlGwRBWotptutznfH0N+ulp5RhjRcbGb
AHwPOBBNEBSIV3LhdPXep3NcmSkfaMdnPEgrurI0DLYbxZryEXdJZyoueT+w4TNx
I5mNlZDKD5bH5rhV/dUAmK/+LpWuxWraWYaHBZBsuqpb0MF6IZJAN9Ve9JiKHeiY
6ecz/o9XIrFFeWKMncHwBV1taPPoG2Ksjv8UlqqehrYXG+md958MXf69dkuQJLCS
rojPOkhUroixvGiXJBRSFCyVhQxPCLyASsEv8qPEKMUiW4oY3w5R9RQmw97AHlA1
7xB4mGZTZEjUIOYDdd8LyuRpawIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAHMAsm
zLtFnDaYaOgJdPpi9VAUkZpbSXcA3a02PzOvLN9VV1Fogf1+F0zYFlWbiYGIwcI4
3YfuFr97/e0uEQd6pwGc8/a63q+CunGz+HPStWZm+2ZgmJhBH6i1RwmhA9rH6rGK
j2UghYIYT83gn6S2XSfUwzV8gCw+JjJwczcjGpOf9dRCAEsRDcRwUX7rI16cE2tZ
SLzYB/Kg3wSnUXTKXRJfg6VbVRPFXHQlRYpOxe2z5LWoTEo2uYuHgYO+DzSO9pEj
WgyKBwcc+L3zIZFYCqc9EN//QrLlXsiwSDVMvtzVnzvIQKcGF7OE22NyojTaMzQL
2h8UA9W0Mew5PTSl
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID9jCCAt6gAwIBAgIJALfRa36cuemYMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMScwJQYDVQQDDB5GREIgTGliVExTIFBsdWdpbiBU
ZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/J+sL
7POoXNdzYRsMZCI5juxMPOVue5vU2QPU9z/PHBsBICX6tVsCnkzk5CLdM6TxofgX
F+MqRKxtcIqxBcKjjVecJlqHuNY+jS2r8UjcoQm+EQ5RsBWu8yaSnXIiZTccQNjB
5T2awwt9Ptbn946MZfq6oEnn4ZPByu9/nCrlk7QXTkuGdpTnC6paQWt/lVxZfELM
i0g76/K/f3e2Lv9UCvlxKOwFMye9XjwF3ekEmUuio5JZEdn+LIs9zB1zehFhGlYB
TUXnkZ0LTOPbH9OxsOli04n31/n7UbYq1BSuoiXx5A2eHOunMppa0NDg7oXmDSKE
A1zo+QtIu1YPXaLdAgMBAAGjYzBhMB0GA1UdDgQWBBSeq0aNrc7mMaWHm8eCndN/
w0I8qTAfBgNVHSMEGDAWgBSeq0aNrc7mMaWHm8eCndN/w0I8qTAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIOw1jC39
VW+1fqGT+n44Y6Oh66lAowIvi/BEOW1I4iPAjkr0g6FbbdKeq0VLL7aMMu+q/AOv
UETv7MdVh9xjTLqWZGN0R3Lr/n6ButI3E7MLKL5ByLNCoOhF42aBLINkpKSNFRrQ
40iNoHm3BaNRLKS7poCk5HFkEMjvxdQ1AenNbUa21DTh7y9arHF4CPfi8Ity29jW
ED8jYK/+bWIaO+YhGkRh8UuD3o5WnOti+9QK56qxkPtkqVTh9vMVHfD0DgVeLvMN
nZpTplLTfhjzyFJELwE/U+HJ6KIslmqwarJ1Sla+1gHCmJEbzbsrnb6bLtrHtXCZ
XvmR6B5iRkDVpw==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDjf64U0NgpdBDh
+ZJ6dzF2b+Z8zoUCUbBEFai2m263Od8fQ366WnlGGNFxsZsAfA84EE0QFIhXcuF0
9d6nc1yZKR9ox2c8SCu6sjQMthvFmvIRd0lnKi55P7DhM3EjmY2VkMoPlsfmuFX9
1QCYr/4ula7FatpZhocFkGy6qlvQwXohkkA31V70mIod6Jjp5zP+j1cisUV5Yoyd
wfAFXW1o8+gbYqyO/xSWqp6Gthcb6Z33nwxd/r12S5AksJKuiM86SFSuiLG8aJck
FFIULJWFDE8IvIBKwS/yo8QoxSJbihjfDlH1FCbD3sAeUDXvEHiYZlNkSNQg5gN1
3wvK5GlrAgMBAAECggEAAVjMKwthfD1XrD7SAy+Zd14KO0rttqnNJVoLealJ6oPJ
MmIv6eKHPUcAVm/6vvH9FRPjoOi+NeZUN2ENRGiGb9GygehMUCsNNzm+3SRm3bCh
JkFSie3SAJ3D6lFnphJOqEgHKjh2ToNg3vPX4Q+JrbTtJ/YN/OGzAvFr81721DGO
L7Hs6foBHKrLeibbguVRdc5zc/WtWjGPFhNAmR9qincM3Q9DrUUHjbJzTS1UXDVT
zssTUTZe9TLd4buqHjLLfmiPoTV8qzv5l4RwkmuuLIT+5mO7X41glwdOkBfk+Cum
BZjrjgTDXbqLNXjMsvXkG1hCZQ6qwdT4GINYlYSiQQKBgQD4pJf7xLaX53rj+LDc
HY3TbWDdyS7h7cq4ZoKa1xPt4Va3xIAIst20edTr6tBYtNygjFZwIkPFYGwdGKVK
CqbpzTxVl8p5I3uoUmIFDo8hX7ChLC928K9lfD62agU85ZfP9Vly4zvDG2sIvxpw
HUY/96VhdSG3fssWYvg3dYUGCQKBgQDqOuyrcTHaZujFMN+MIuUExgYOMS0R0O4T
zCMtWIEkjntSk4CBMsHSb/dZH3CbFB90GjS+WklfTBd6kZ8tBO35vtM6nz5NPCEr
2umqJR5hijHV2tB98qV9qJttJrH/z0VKuuZBa14S1rJwGpX9ZoOULwcOGK3VC9pQ
YnH7Wdjw0wKBgFtBZXqE7xL/ZS4IVzjiK+xeJ4Ae13MaKB3XmbWknG7hFkep+ee3
ZgFX+ZqAeukjsBnIh+zt1nu5cNSY+Akdsbb7mVo8tJYTPM5BNjJu7n8sNJJiuiTo
HyebGxUuAjAgf8BWZvbwiT2JcZYrNVPSmrbdeDg1miNTiMv1lO4d1q2pAoGBANq8
oFwSX24IAIR1+a2SwLDOhMUoI2Cp7ktKrecg6alL7drVqIH+9oYgzarK84u/JQh1
mJ/TDQYTtzFdYHrYSaybCgOKxtG1v3yG+QNNmquYNKXzrBSSTv2kQVGTe1LbK2h4
VaLuM3IAUa7jBQMZgvMVX89IOL3mTcAXzz3dT/zFAoGBAI/pVbABfPihWZ1MrmTN
pnRmQ0461J0WGT+fIgAPR+R+umckHaOVAGiSQomfNrUBbsydoZYu/by7GhIGsDeO
8XKwEP/HLRrABvZu4KLTxa+qTnW/t6BSIfFwQmrNMofxcFRbdzNAODKjyaJG2dqT
ksg9s2SxReRrGOeb43CAw5SC
-----END PRIVATE KEY-----

View File

@ -1,80 +0,0 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Client 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIJALOPTrQGpeslMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGIMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
UyBQbHVnaW4gVGVzdCBDbGllbnQgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALVkdxOmWcd959NyirJ1iz7q5fkjdRUV+88KMMehQWc3f50GJIQ+eZo+
7RhwVE+n8nd0i5iGfyY6LRuupdwoQUxoZ/5rUIDGKspNO62DVRW+tZqzpEa1+ub5
75BMoc7I7l9sXDkuiMu1OYcPNKMv4F3mf+B3ourLqjUekKlUv8XIZXAvN+R19HlR
FM8vs8rnhQXx7iWVP91frDvyD8G7lOf6R7R4homnB37kLom8WU+fCmcyA6em0qX0
JeVP6xk2qXU1cMs7DL8WftdrWHv+a73/l4hytQHo5OvtGaLZhpPYpC/FMSaFHVSM
irWSFK+ZtvaLi3LXc2HGANMokjPoRf8CAwEAAaNgMF4wHQYDVR0OBBYEFPtTL9KZ
jn49cLediy1ixz7AXOI3MB8GA1UdIwQYMBaAFCXTF7f83Hd7xm9gR+O4QrvjNo8Q
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
AQA17a4d/tSWIlTkIfkrXziD21+1OsN6/dUrWQK7kxtEe21QXIutccW4bwpM0JDB
M+bZiWkdgQ15+ZotX5UXlBcx9WWDU5RqSO06hhXu5b8gZwfVF4Od6tBdVxkn4KbU
0YujOZrL8fDOrQHqCO7nhNlYgcEn7bKF5wjtOoiKhtA9sLSIZQR5g32kkJXXGvcY
lLWMXygEg9FMQoldW9RHq4GbUiYEeqEq6k4S7cE03R1lvmQEOOAJ2S7LnaS4UHQT
GmW6uvLnJJrG4HB9JGE+y1e9M+C7Enzhi39RGd8ylignGimkdw/1UEWnvKGCqoU7
ufWGF7eUV8dCqO+jYghIY8rA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1ZHcTplnHfefT
coqydYs+6uX5I3UVFfvPCjDHoUFnN3+dBiSEPnmaPu0YcFRPp/J3dIuYhn8mOi0b
rqXcKEFMaGf+a1CAxirKTTutg1UVvrWas6RGtfrm+e+QTKHOyO5fbFw5LojLtTmH
DzSjL+Bd5n/gd6Lqy6o1HpCpVL/FyGVwLzfkdfR5URTPL7PK54UF8e4llT/dX6w7
8g/Bu5Tn+ke0eIaJpwd+5C6JvFlPnwpnMgOnptKl9CXlT+sZNql1NXDLOwy/Fn7X
a1h7/mu9/5eIcrUB6OTr7Rmi2YaT2KQvxTEmhR1UjIq1khSvmbb2i4ty13NhxgDT
KJIz6EX/AgMBAAECggEAEm2Mc2CZCl1OKfsfABZU+SVgC7mAcY30MQp1/jHxtQy8
WDWBjDXUoMj3yV3QEu+bAGvEqtAvJrEOWBucGgu05pBM0FoSqaJ4QmkqQOxwvm7L
gFXzwINIZCLMJbrDTYC4RtV5YQ3LM/bLS19OF64Lez6piyJcWMIsHo1mYO2NNgiD
7f1x1uQw46Q0YHWeoHY58MPfmgfKsqnJDWc8cCuU9fJOWeU4dVrfW8dh9WVAoLZ7
qAM5vvap11Qk8RXaRnmLjxN6H1M7iVNfcLVNKfG6XOBBepYjZr/qMkuN3ONuqBHl
fC3Zia2zQZRfiuPspX0KhjCfYAKbIZC6oyrQM2uXgQKBgQDoD5voZiCOeGXJEMUk
9JV4V8A96aE0xxy+OHMogVpysxBO4V0Nh0krSLTt9NXnpjawZQ+3pLQ4+2J2XM2e
fJuJJ7Z+Mhjv6epnMM7FoxK1VF7oe+LE7Yk/kg/moCuVS/XhLdQrhZVBJhfEADS3
oFybf7Q6rJYtN3OYsiFymyneHwKBgQDIGsY5kGdmx27LS5rPMwdw632TF8G5BGbu
C3ty7LYkOWb/9/V4cuWjW4eLJQqCWbJQrzOvg0coxwXLUuEQik+IP2IkF0YlRS43
VJuULwOxi3Cbj51RoapHhmYTO9fe2A1N9oJMAqEUHY1q/r9txPcguRWyuH2Yv9Ih
OzHnc2DcIQKBgQCGW0MxMq/2zM5hs0vxMYq4ulWbgwDKxd1mZNiHwxzS+8mdYe22
P3WlkdrvSqnuDNXtGxYWhU2zEBjZ3rFN6WdD6bJHLkox3YTRafjNhLT4N3kbsV6C
FeU44SBDrsiNEAWz8gy9hgH8TknEOTpMdpQnk7CNqA7q7wgGiFvFNwDukQKBgG7i
R03Gs0XE5aRJtPN0N39fPyqvU24O/mqSekno2dWg6W6WHLQuFwo6whVc5UHuKl2D
eISdnmT+RDuzJXxg6El7tgqByyEEAOQwQjYPB2Du/+tz3Z1KlG0mEJI/6xNVbany
G6m7Gz9mUOMlXzaYmsjLRzbN/OsUAIDhqHm0+cuBAoGAZCND80akS3xr3yC87GyX
aA0RoHXbdB6dbP8Y6XYDXR4QFIA4kXwY5cCLaZA/0hP5FOzDhORmaoaPM8vUdNyb
IYvbw2H6tODiU5oICWY6+HQQ2nXikucI4HDYDLbsiV2htZkEmBYWLilYq0Tb8jC5
u+ehIIvZYLqKaY1GaKmF86A=
-----END PRIVATE KEY-----

View File

@ -1,80 +0,0 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Server 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIJALOPTrQGpesjMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGIMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
UyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAJp26QAmlMusO7C8Py/I117r3kHvB+My5kIrj8g9sKpktwTzmsJGpvJU
EaKISEdBsJHLGnZJhwIhr/+MG4WDEM4oFNCtBQZznV3wjIQWq1w4IO8/f3+nBPpW
f14fjs1E911Uo/ZOL9bxvh1SIHkS6itgJi+tgVPx7C3s3W3mC5nU3omsE+Rx4DDm
KUq1kyN1ELBIAceQ4wTmQ5B8dv6MSW7zt8Jdrhfhg2GJIPPB6XUZJ2yIOvgu55GW
J5sMPa0uNDfCsWJ37fzFm+XJ/D96t7x8I49IyfzbIgcU9JYFlcqkryvKh5IpQGGm
H/I6adIWa5xWpMhB2PA6kgtDD07Hu2sCAwEAAaNgMF4wHQYDVR0OBBYEFJ7S+FUz
9ngzH/TNPVeM/cE7LeBGMB8GA1UdIwQYMBaAFCXTF7f83Hd7xm9gR+O4QrvjNo8Q
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
AQAx6WHwikVFAH0TRYCznwO6He+0t2pnlyfrI+24N28tzupMSrRPs086UbLgHLz1
lbkYdheeOkLPzjWi5vfymL1Oua3E2iAXWEpMb4Sg7E5SVHp9yt6gZ0DTVwR+Gcu7
uooroidAG3OFeOXL5ivU5J5ipaoEAiLprpKxtPzo4z/TxIqw3kJISC56qw9VTJNQ
TQZvneUecykdIZuH61ih0cJLe5WRkEs/63Dgl8TBYiVDbvBSGRbsXoAXcspVlc2x
XOLey5IVJ4/TH5ZBobShC6J1KrjZTNYvUgc44CocOgrc0ePPiQzB7JXxR1H8ATGl
yKjWqT2PkrfHmjdcmsi2GIVt
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpeshMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAyOwdOcYcH3wYou13CchsXh3lLWA85E550tT6/WwDnslQjiMZHFrKvUT2
B8CUOR3Fr+4RG+cdw80rgojYEUuHKwmIGyjo5IotdaYbWzf6mvYThlIPPudCCkSU
CTtqPv8Oq4QdIpCxHdix0MINKu7c+qt1rUwnDFQSv/gHhVnNxT4r8pwVp6T4hwka
2YQaRNjzUuuFinMub0UtxnUX0rH8X5STlOSVn4Ksjo0OhQzsGEYDx86jVAXjgGcb
2CgGGctgq04hVrngP5ahT1Xeh9YycMlQJXsckJJBxfUJebIjANSRyzxI5fYt+ZkY
qoG5VLPREUQknxcpbT7Rsj0n+k0RhwIDAQABo2MwYTAdBgNVHQ4EFgQUJdMXt/zc
d3vGb2BH47hCu+M2jxAwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAGwW7bRqB7aYUGsD1MOE9d5slp6Iw6wKyNLdg+mzoV+iCV2ZM7ejNRButiAy
vPOxSQwXcibLm/g599e+LY1TiI1XXPbL2bFnTcnThqpHHFe+eRrDgqxO8qJyrcBp
EfyMCJWq7jFg4bWoYTpLeC/RAKyi9fxlqY1NzQCp1bG3LiaDJ5VJd4uwkgX2a0yN
3e0XEFNi7r4u4IHejwFjKWrDg8sstjbY+XOYC4EVQyUsbzeKZKSqnOdR2Jv1QZHH
5O24G/efIFpsA6MVUOfRk0eq0RfKX7CdHn2a5p8aC6E6YMDhXL6xo146n49t9sYD
HMUnfG6AEboTBa/l+zwCG/u4f/Y=
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCadukAJpTLrDuw
vD8vyNde695B7wfjMuZCK4/IPbCqZLcE85rCRqbyVBGiiEhHQbCRyxp2SYcCIa//
jBuFgxDOKBTQrQUGc51d8IyEFqtcOCDvP39/pwT6Vn9eH47NRPddVKP2Ti/W8b4d
UiB5EuorYCYvrYFT8ewt7N1t5guZ1N6JrBPkceAw5ilKtZMjdRCwSAHHkOME5kOQ
fHb+jElu87fCXa4X4YNhiSDzwel1GSdsiDr4LueRliebDD2tLjQ3wrFid+38xZvl
yfw/ere8fCOPSMn82yIHFPSWBZXKpK8ryoeSKUBhph/yOmnSFmucVqTIQdjwOpIL
Qw9Ox7trAgMBAAECggEAOZAMvsCh/NDfobpVddJL6JTPzBRvBQ1H3+rp9z5+ItHL
nq3Fw5aeynnn5IETJnLlgT+GSgSWqoWxV/N3oia40YsATs/bqo7VW1e0ldj43TIR
m/c25XRxl3U6m/H4vqhv4rkTLUvv6hNGvRiI/3W8DJQVRvlK0+S5FlhKIJV1R0sH
tp5vmaPp09Ln+NVno3u3iaYkVgVME4Ukul2i03sQ9OgvZSBCaVr//fMpiPdBeeN6
QY6XHjeGQRnP/UdzMYJ4Qz1yovL1ntneaTMdz/GkKuAFoNNh8Vr2kiEskW17OWPB
ZGcIT6YpBEPo34xXUhUQt7ylFPxGH+zZyHZ3vb8j6QKBgQDJPeu/iPg+M5nz5gO5
ge9gzYrhxK/1mwbFlD7qt1NjOSm6xWxUcss3STjuG7jB0c+NopIUoq/egsUnxrRm
4l17uOCYNLbhTJ2ynfv6QnUMxW5Xkve3DkLa2bze/fhMUywTy8N4A7z0+y35qzm3
lY4rLmQOQKPkmqWRnxU1u8fjFQKBgQDEfpOZ0fp2D/1gTG+D+/zrMEbjnNn3ZO8I
wrjoXwRxcRggt7lJhxgQpwtDr98IqYkDzX7bvyMFJuyTii3NM6NYycpA1pHX70B/
xMvOcrgJnIUAoJ7nl43Or7s8bFTPDLaD9PNGHjrlkF3JOXqSKEbw367jHVOa4SYr
OjrogjrEfwKBgQDHU2a7ax5+9btqggx0ZQfGOTBzmM60lZ3qe4CqGXUl1YvIrB01
tBImq4cRCTJB/9/1qO3KNK2/1oUTddRgB5ySnDcRaz0tASc9sQ/Q/JxVTwSRB0gG
78A2Zu6VbLbQWp1Q6kWtDP7PJC+QmRFtDlwn1yZRm6L6HlcaWpi2hU1iVQKBgCEu
ashv8Aad3qCzZ6V3GReyOFZZd2lSjxcAou8ClKJ/gZ6Mx+pFuOee/cT5XwV8c5nD
yuda2JQXJZ4omGFtlej5coEOeuRnD5JD7lK3hqKA3ujjNtJPAnBjto+Wj5/DOtL/
u1Ec6782aNABN9SUnp4wd7z8h9DAsoxcMfRvgXMLAoGBAJ9gGttfqZbuPz9V0rAo
p05SPPado1i5+2dUOScIbNB6+vQij9IlR2Tzu1T9DwzrBqTDPPmSggeA/JXeTvh6
Skb9fDukizeDfwPYUN2gljhiJEqFdpRBr5vP0lFi291+a0jMW1zldrumxCcGKMyU
D5ReKLp/zSQSQi/Wt4FF1II7
-----END PRIVATE KEY-----

View File

@ -1,80 +0,0 @@
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Client 2, \C2\80 <\01+\02=\03>"
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
-----BEGIN CERTIFICATE-----
MIIEEzCCAvugAwIBAgIJALOPTrQGpesmMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGdMQswCQYDVQQGEwJBVTEYMBYG
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBDbGllbnQgMiwgwoAgPAErAj0DPjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALanLExQi/yK2PRyu6Mvdw2MRxUs
26kJftYuK7KtYyltTO3vtj4kNKg1vZI1eezhqr2Ta/1DzE76eLVs8EOW0LAb5oWM
zXdYBXBX4vG+K7pYfjuvZUd6jfX2bHW10xC96HgDTfRn6dof8GR0fILJ6DoEcyI3
82xnKKxTsgAuXU4uvcsl0g0F78nXuIbk8ZktTV3LIdbOCIcLQfG7DdDyAfEA0T7Q
Vg6eeLknIUvPePxyWkUdYeSCDP2d+3NIlHMxNPmH1q3+fCsEsy/kqdVO9e6KrZla
CKqnc6yYTXvTffpPepC3Igz678iGg3dv9rLj0i4fyTr4tEOTJebO9Ka3TbMCAwEA
AaNgMF4wHQYDVR0OBBYEFKO2/D1IhG8KWFwR6OdyoFqEzIWAMB8GA1UdIwQYMBaA
FJFP+HFpDrD0BRU0yE606s6xkqFBMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQAQV3FjsvZvwi5Oi/oSc7Du/BQS9nQ/D4j6
IeYpd3M0y50awZB83BReYrhdC907xKkLRD0R8oEPDEg5SaSj3vRML4kaUUqnEINW
4JQtv4wNO9CagYriGg8ygQa0xd683svHeXDet3ov11XN/Ms8lfDiOUp2291HgeTW
8hqn1DaNfZrCb3EkdoNThwVKIUzQtEPBuPkLE+XT8kZP5d8KHmv8/9L39NdZY32d
fzKGBeCxZ34pQS0cTap3rZ02nDfV2vNevODRyuqdhs7EQps2Oe1IfPB9GSE0OFUQ
tdphxSjsv1BcHpTwBDpIITKarnceMIKxQjcZU3yPv5ibIaGCgZOt
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpesiMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEApTSBCiUb0amf+QRV2WY6b3bK93D/PSrm4KR/2m2V0lciU1DAk00/kZ52
ZIZmq8g9EaE2+CaDtU0fMvDZpaZD+vTFRwsx4varehq0ZwX9Wt25i/3G/eGLNlD3
9E4tDNruK5UQjum4nJ0SV+AdFEGkSfeU3ZJEHYH0NrcbyAUbh0KeWCSwHiYiFJJf
gBYwRq/HdKNoS/4YvLXzTLR7BSm3YcqWlO5tdkJ2lcT/7Th/Hq1TCW/FKwdQJJBq
JrbOYGlMrf1pLO7Drei/xhsYkwTQ899MhSjkBRhc+401p41Mky0n8wLkuPJGhoY3
9QUOjT+Rmvq5yryg0eWGiFquk6Ru5QIDAQABo2MwYTAdBgNVHQ4EFgQUkU/4cWkO
sPQFFTTITrTqzrGSoUEwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAJfCHU7dm2/2ASyt3wyxivQLxlV6FsEZcF7HcpbbxuB73frGOL4kEoOxvr2X
fBGyjlPMotbc1MeAalAv+hVHdcAcBFPF7lxtYiV6D7YI5T5yVbWSASG3+DMAiW6S
GdQi2eyeh00nH7Y1IkW+yaky0enBtWLzrw+XzHl6xT6DIEJnir//PNxvgXTJ5sjk
6eFAm8HJIqkNQmgfChMQfUH6nm66WwULW6I117RCSkXhIgxZ7wzDq8bXcEdXCrZk
yy5ket9OiVpbd38JgdYirBLmCQVq0uDOOPLz4ZJmNCzQzEt+38AAK2azAk/eb8W9
JaKWH+5V8lhlyGw1zQKdNEP/wg8=
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC2pyxMUIv8itj0
crujL3cNjEcVLNupCX7WLiuyrWMpbUzt77Y+JDSoNb2SNXns4aq9k2v9Q8xO+ni1
bPBDltCwG+aFjM13WAVwV+Lxviu6WH47r2VHeo319mx1tdMQveh4A030Z+naH/Bk
dHyCyeg6BHMiN/NsZyisU7IALl1OLr3LJdINBe/J17iG5PGZLU1dyyHWzgiHC0Hx
uw3Q8gHxANE+0FYOnni5JyFLz3j8clpFHWHkggz9nftzSJRzMTT5h9at/nwrBLMv
5KnVTvXuiq2ZWgiqp3OsmE170336T3qQtyIM+u/IhoN3b/ay49IuH8k6+LRDkyXm
zvSmt02zAgMBAAECggEAU2sYHSZwOH+FRGcd8RJdcg+N60rYa2QNzG27wVfUwPfN
OaHP/qN0dRpOIPdRXvFVlE0+9aVAKxXTiTBers+zMascZgP/VrEZksxgtn1e5TVD
OakKPVHogdvwfvXylmPVRvJjaOsIb3lExew5bVYfPFgJ6Sfagbi/Z6y1z8VdEbYb
mI34KSZA4bBAMAHPZLa9TGEx/vbPsBlqpU6k8lcoy3cTkO5fCZW4ZZIpwBwef4uJ
UozhRgtTtRBiUpk0F9IoOXonZY1Dtpg+HcDMti/FYgahBVe1hadJ+lbVTxH6GxyI
NJYvptdq5S99UOoJDmCCih0v0ZCUNYWoO0I0vzNncQKBgQDemN7es2fIBstiPjOf
p103DF5j9Uxq5YH9B3wli0CXf6Z2w5uosONoJWgJZKsHJ6f+YSuHsoE/eCrFF3U9
lxT9Nie/wYYIGedly/VR143aCdiTXI44m5gxXgwaUcjvY1DpWyEAAmr5XNdoyZ5n
LNTvOTb4vVo9SgDU7II7rdpRmwKBgQDSD9aBtIy/650suQK/9RiXRU0Kg7LXXVM5
lavPgLvH55lufJeGSa8+ofCNeo31N4AaVuU4lkGeny9tLNBQbYAoyAz0lf51qK7B
1u5JqBDyRrIpdkqwbT0FT1pu1LA3+Qg0KQBrTCnOx+YyyVSivR4YMZzJjmwZGKMg
BWOi0PzhyQKBgGR44dfpaIWbs39zjf+ZHnTza0N4+/YgA60/DKUxloULRArFPeRF
e0+N2siqnJvNJYGnQGuugbIxPjTZ4rxbDklAgW6HHkVX099Z0TAQuGFbIltZYoRg
jrBxv8q9cZHD5Uh/LoT/kmNdqYkNwCbX0IDt9UcOyMVzOq7g1eO0FB/TAoGBAMaG
tWIsMwGHOip0SAcHKtB8bI1NXo5v4yH/NDuOHOqXFcj383S02uzEu8XaV6Ozalx6
V3SdfTLem0IBIneApajlOGlIAQ9N9qu358ixECMJcYQCCiCnfQ4xqvQoCss7judN
ANpnRvPotMS2xkhvl6uh594NvlgRksnGjh3oibcRAoGBAJKiu5ajmIkelzAhFMEC
Slxhg/E+djJ1/SG/FaF8zIyTOxre/QUvmTwFKtHe6A5EfKQo9GCTuHuAcJ1U7eQP
l2BoY0POqJFpw3s/QOt4g/pOz0YjD9GD6awL5WDfO++s4mnI1Snc3wcu99N4Klax
htsaEUECJBUF0ZpIFad73s2f
-----END PRIVATE KEY-----

View File

@ -1,80 +0,0 @@
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Server 2, \C2\80 <\01+\02=\03>"
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA
-----BEGIN CERTIFICATE-----
MIIEEzCCAvugAwIBAgIJALOPTrQGpeskMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
ODA0MDcxNDE2MDJaFw0yODA0MDQxNDE2MDJaMIGdMQswCQYDVQQGEwJBVTEYMBYG
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMiwgwoAgPAErAj0DPjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALAolQZIGMeL5w/Bu2X6lHWjO58u
+HUDtBmr37So4jazhZBSFDBg+QlRMiYGLev9EhvCrUsVcRwtvtcuMI3wfKl7qgbi
ZX8zmrzZ3YJo9U47NzCa05faOl8uSBvuXuXUBLU342WFP8XDB1W8yOBQMK73xoFv
DkcxURx9ZtOhdC3EgYKrFqOB1Azl1DB4gLV3h9rHW5QpQ8SqD9CyggcDBpDeZQIP
+4l5YFE9Nb4kEUTscz2wGn4TdHMmcnVpfUxp1Y2o8Umvh4llXHIPhximGb3JJ4QQ
Sir4ZXeeoooWoJG0sdlqVLroKav/VMGtEu9LyfbrNdKnTJq3ceVQ+HJ2hlMCAwEA
AaNgMF4wHQYDVR0OBBYEFH61Z8O9vFsVdhM4MBU3poX2UMTEMB8GA1UdIwQYMBaA
FJFP+HFpDrD0BRU0yE606s6xkqFBMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQCVbxlLGIBCo6/XXjqoMyZc7uQZJj7pGnwh
nIMs2izCLfax8j+QrThO2Qjn03zT/WF8eG6ibPbjgnw3VFwCkV6oQ+BXG6Yt0xqP
4rz1LzxSio6HSm26gSk4SQUsVoAtz3OImoTCFVfz+Mixe87pyVXXEEtCYvfU74H9
I1WGyNkWAxiJbqeIxF5PKoc3EdnT5mfdC6sdeGm7t2neeS8PDFQtJ4UfVIEK5z1C
MOfQILNkLX2nBYxNqKpV66zf68VZNN9002ZH2FITGqImpj74BEws3sheiuZySdoI
wnAwRnymIMfAmkf9C7Q2ugId0YMMyesaWrIwSlXlJOHGsA1VrBRD
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIJALOPTrQGpesiMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEnMCUGA1UE
AwweRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBMB4XDTE4MDQwNzE0MTYw
MVoXDTI4MDQwNDE0MTYwMVowgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
Zm9ybmlhMRIwEAYDVQQHDAlDdXBlcnRpbm8xEzARBgNVBAoMCkFwcGxlIEluYy4x
ETAPBgNVBAsMCEZEQiBUZWFtMTEwLwYDVQQDDChGREIgTGliVExTIFBsdWdpbiBU
ZXN0IEludGVybWVkaWF0ZSBDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEApTSBCiUb0amf+QRV2WY6b3bK93D/PSrm4KR/2m2V0lciU1DAk00/kZ52
ZIZmq8g9EaE2+CaDtU0fMvDZpaZD+vTFRwsx4varehq0ZwX9Wt25i/3G/eGLNlD3
9E4tDNruK5UQjum4nJ0SV+AdFEGkSfeU3ZJEHYH0NrcbyAUbh0KeWCSwHiYiFJJf
gBYwRq/HdKNoS/4YvLXzTLR7BSm3YcqWlO5tdkJ2lcT/7Th/Hq1TCW/FKwdQJJBq
JrbOYGlMrf1pLO7Drei/xhsYkwTQ899MhSjkBRhc+401p41Mky0n8wLkuPJGhoY3
9QUOjT+Rmvq5yryg0eWGiFquk6Ru5QIDAQABo2MwYTAdBgNVHQ4EFgQUkU/4cWkO
sPQFFTTITrTqzrGSoUEwHwYDVR0jBBgwFoAUnqtGja3O5jGlh5vHgp3Tf8NCPKkw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
ggEBAJfCHU7dm2/2ASyt3wyxivQLxlV6FsEZcF7HcpbbxuB73frGOL4kEoOxvr2X
fBGyjlPMotbc1MeAalAv+hVHdcAcBFPF7lxtYiV6D7YI5T5yVbWSASG3+DMAiW6S
GdQi2eyeh00nH7Y1IkW+yaky0enBtWLzrw+XzHl6xT6DIEJnir//PNxvgXTJ5sjk
6eFAm8HJIqkNQmgfChMQfUH6nm66WwULW6I117RCSkXhIgxZ7wzDq8bXcEdXCrZk
yy5ket9OiVpbd38JgdYirBLmCQVq0uDOOPLz4ZJmNCzQzEt+38AAK2azAk/eb8W9
JaKWH+5V8lhlyGw1zQKdNEP/wg8=
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCwKJUGSBjHi+cP
wbtl+pR1ozufLvh1A7QZq9+0qOI2s4WQUhQwYPkJUTImBi3r/RIbwq1LFXEcLb7X
LjCN8Hype6oG4mV/M5q82d2CaPVOOzcwmtOX2jpfLkgb7l7l1AS1N+NlhT/FwwdV
vMjgUDCu98aBbw5HMVEcfWbToXQtxIGCqxajgdQM5dQweIC1d4fax1uUKUPEqg/Q
soIHAwaQ3mUCD/uJeWBRPTW+JBFE7HM9sBp+E3RzJnJ1aX1MadWNqPFJr4eJZVxy
D4cYphm9ySeEEEoq+GV3nqKKFqCRtLHZalS66Cmr/1TBrRLvS8n26zXSp0yat3Hl
UPhydoZTAgMBAAECggEAVD60NlLYduXzVNfDtVuHEFNGOjSOYfepc/V8gLubo6lr
IMAAI7rcnpYUM5cU8x0OQfRyR8wzUdSWxfWzBs6R78PSZoRzIcgeIl7Wzn0/g3BS
To5czuxwqgBKQAFZpPQmZDwcJfr5qqxAn8IvFweCoMqiRlhELcvqDIP0XxWBqDjc
TNJ988XzZXQmJbjjpWOkUBy2Uqz8lZt8MmxKFpW7SW4tBJwPphnorgjWfjCV/VEh
ORio0rG74NHFo4f1TSrdU2BcB2cbVJ4B+bcUYRdvYmS5bmokhGF8vir0l43gUEdz
Fyk6MaPrTI6cinqzenm3q/0eRvNhBE56U0tiGLn14QKBgQDkCkt1Y4LEboSwsVYl
IXriStqj9p9MOizihh0enhzRXTTQuLX82fNi+bh1LAluwv290Q57pvKa+hB/YciB
o4s7QfSojxQY9DxqvXN7CvxPWXHTyFY5sL4Rm807+C/a9rd39MxBynz9u/7YRvsA
s8v8Y/01qIHnTo+mpDvu6HttWwKBgQDFwdRkgstuE+dXZZe8g1ivh3RNPa968TE3
b8rzF9/nOJV7f6B/n6YEmHD/cHF5mm1bR+zt/jtf1NCRMpazchw3vT3JzQZYMDnM
SD6vxTs5rG47QLiNyTIRmmD4gsEWBpyvoyP8E/9QdfDT1bWI5zZnky9CquRlN+cu
J1bTsefEaQKBgGJsRxFNd91MThztDV9NSfptkFyAT1TZLxI+DEdwusNqVSdY8cNG
VpP7cC+yaAfURSwuFPAtqDxXfdNc4uuBKNDUsMInrubuUz1Gs5cBsNCWrFhZ+U1B
CWgUNMqTXiRFo/40PAyRVs003NOAH0m4UGyIw3rrVdX9xGaKMAv3b35NAoGATkkl
I4UDs1f9xQNaxi3Y9ePRjqJUzX6d1SxUU1eoM4ia5IDpsJwqxLb0RKrmwRT5JaGb
kbuLFazRxCkar38E3Kv1weWAFXlB6DTRXBPgFjzEhoBgjwCO6ZkLulVIysdjT8Rt
gmUINXn7FGENtFyTlP0XQHUWZVt0ETlRjgxni8ECgYBYv6MoSr0iPjQpxeKvwFDz
d9zE+ZXN+3GwtkI340lKRSc/f0Uq1TlC2w+DzjyyXcrBwubMQKTKcQQSH9f3YbMu
DuxVE9AXdlQ1gSQHGjS0qUWwsS/8Xcjk8ZuduAXPGr/MsvsW+FbbZqG8qdZTeMHu
MSTpOxu9HXC8SHML+y0cpw==
-----END PRIVATE KEY-----

26
FDBLibTLS/testdata/test-ca-1.pem vendored Normal file
View File

@ -0,0 +1,26 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
-----BEGIN CERTIFICATE-----
MIID+jCCAuKgAwIBAgIJAJkdwMd9MHxpMA0GCSqGSIb3DQEBCwUAMIGJMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEpMCcGA1UE
AwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDEwHhcNMTgwNDI2MTYz
NTU0WhcNMjgwNDIzMTYzNTU0WjCBiTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
bGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwKQXBwbGUgSW5j
LjERMA8GA1UECwwIRkRCIFRlYW0xKTAnBgNVBAMMIEZEQiBMaWJUTFMgUGx1Z2lu
IFRlc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
vfuzumqT8vHWNOwLPnXLJitIJ7vH9leTcWq05/PfeUUyaPDbt1u9ZRFyexew+q3A
DUNKKOrbo53B+aVipxmqmfo8w6jWzv90MpnCOTEQOHeJyiBTUG99yafy9PCE2KDg
T0dXayOeKPjAoTrHDYkZmd2lA7+V+upz7R7bNDjotLW/BctVllc5fw+ky1hWAKqj
Buda0ZNElCI78U9f2aMK41/J5vLaQzQvZ68m5cgKUQ6TwWZ0ZX4p9w5aqiLRlvK+
Wo+lYe0IFXShX73QIAlcFo+apOZG652VmMXk7vzo8llbxC6s93bwm/WxZ7K3St3O
ttcIiE6mIoG94V0Xzby/fQIDAQABo2MwYTAdBgNVHQ4EFgQUCFkAB0WIBjGP84hL
whmqKiBbyXgwHwYDVR0jBBgwFoAUCFkAB0WIBjGP84hLwhmqKiBbyXgwDwYDVR0T
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABLO
dQJuW85pcOhvMf1eaMfNGaKraX/r/+a0TsbbbSDqOKhytqk7JQkGEEzyBuJhfRmG
/jXkikWAId4SBBR67FVcwyqnegzY4ObFeH22hAjfGqL1HDDu+bcpPIJzGN1CqOXB
DVjAo1tKILP2fAVHyFNGKCk60zECtXv7QfkqjMu29kMgkK0dofGIAQeYpJP1WBtH
DUTvzdjv6nBBYMLtJV1TexcSMPn4fAKDfD6uWYSeGhP6J0mfYNHOE2Sn0MuM3+yE
vrPLiCmNctnnWfcIWiUOXA9BF84MWwglK0UETR1CEONvvdpqlmvGf3G8S1r8P0MF
B8mQBTsexWGMb2NTeaY=
-----END CERTIFICATE-----

26
FDBLibTLS/testdata/test-ca-2.pem vendored Normal file
View File

@ -0,0 +1,26 @@
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 2
issuer= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 2
-----BEGIN CERTIFICATE-----
MIIEDDCCAvSgAwIBAgIJAOikTZQKEq0VMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD
VQQGEwJBVTEYMBYGA1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRu
ZXkxGjAYBgNVBAoMEUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVh
bTEpMCcGA1UEAwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDIwHhcN
MTgwNDI2MTYzNTU0WhcNMjgwNDIzMTYzNTU0WjCBkjELMAkGA1UEBhMCQVUxGDAW
BgNVBAgMD05ldyBTb3V0aCBXYWxlczEPMA0GA1UEBwwGU3lkbmV5MRowGAYDVQQK
DBFBcHBsZSBQdHkgTGltaXRlZDERMA8GA1UECwwIRkRCIFRlYW0xKTAnBgNVBAMM
IEZEQiBMaWJUTFMgUGx1Z2luIFRlc3QgUm9vdCBDQSAyMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAlZBDX6/eZDsu8JrEE3rgBcq8qRSAAhcI3B4PRz8K
NgwRGGq+8BrjsTRMqFdl8GpUDbzFKzpZ3I849GwkK+S0YU86dAQa0aORL5oEBisM
wjxDSRe3qyFZBnyJJkVo9BqF3wJhGCnWYNtFQ5OWnBKS3ZPf9jUGGL1q8ZFMoK/T
z5o0KmjH2VIAIW/Jz8Ouf3XQUHG3qC1C6l//BPqKWhxE0dYcDKBTSNMeI/NOsJ2X
PJn4g4NG+SYurQwTFYuFUTIig4p7Zu68VvgyNK/sgWoiR47AyyC9Lc5/Ojr0GMUp
zOhPEUba7ZnSgSlQLFdOyuKPO9LnaRLZ2C0uaW7ZHcXVMwIDAQABo2MwYTAdBgNV
HQ4EFgQU/DxpqnpxElyiZZHTJBmO7bTajGcwHwYDVR0jBBgwFoAU/DxpqnpxElyi
ZZHTJBmO7bTajGcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
KoZIhvcNAQELBQADggEBAE7VijzPBR7ouPkAQI6OEe8iWiaNE2OziZhOofai84ky
ExhGrd5NAC7eSLiIe/iXL1T0XobMwxh+hglz9zqCQ8xOLtH2z3xH97KSehnb/psM
Zz/7fOyHlj3MorRl9xpi7ncz9IY60hKAeYQ8JxSz5Wp/9KyXP+JPGCcnDal7AphW
adesPBGh6eGeAY0EDstETBsm1uMg99ABWeJk/moOlK/8F05lHUa15Pkyxx//S/cf
tKJUUcj8COm8vXvEFIBPi2FH8DKZMLFG8Ld/9N+lfDgp0r1yERxdWK4aB22iRoTL
LX97Vky4ozfdldIFBi2tzYggraPlgVn+Rxza6XXc2xA=
-----END CERTIFICATE-----

52
FDBLibTLS/testdata/test-ca-all.pem vendored Normal file
View File

@ -0,0 +1,52 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
-----BEGIN CERTIFICATE-----
MIID+jCCAuKgAwIBAgIJAJkdwMd9MHxpMA0GCSqGSIb3DQEBCwUAMIGJMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEpMCcGA1UE
AwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDEwHhcNMTgwNDI2MTYz
NTU0WhcNMjgwNDIzMTYzNTU0WjCBiTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
bGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwKQXBwbGUgSW5j
LjERMA8GA1UECwwIRkRCIFRlYW0xKTAnBgNVBAMMIEZEQiBMaWJUTFMgUGx1Z2lu
IFRlc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
vfuzumqT8vHWNOwLPnXLJitIJ7vH9leTcWq05/PfeUUyaPDbt1u9ZRFyexew+q3A
DUNKKOrbo53B+aVipxmqmfo8w6jWzv90MpnCOTEQOHeJyiBTUG99yafy9PCE2KDg
T0dXayOeKPjAoTrHDYkZmd2lA7+V+upz7R7bNDjotLW/BctVllc5fw+ky1hWAKqj
Buda0ZNElCI78U9f2aMK41/J5vLaQzQvZ68m5cgKUQ6TwWZ0ZX4p9w5aqiLRlvK+
Wo+lYe0IFXShX73QIAlcFo+apOZG652VmMXk7vzo8llbxC6s93bwm/WxZ7K3St3O
ttcIiE6mIoG94V0Xzby/fQIDAQABo2MwYTAdBgNVHQ4EFgQUCFkAB0WIBjGP84hL
whmqKiBbyXgwHwYDVR0jBBgwFoAUCFkAB0WIBjGP84hLwhmqKiBbyXgwDwYDVR0T
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABLO
dQJuW85pcOhvMf1eaMfNGaKraX/r/+a0TsbbbSDqOKhytqk7JQkGEEzyBuJhfRmG
/jXkikWAId4SBBR67FVcwyqnegzY4ObFeH22hAjfGqL1HDDu+bcpPIJzGN1CqOXB
DVjAo1tKILP2fAVHyFNGKCk60zECtXv7QfkqjMu29kMgkK0dofGIAQeYpJP1WBtH
DUTvzdjv6nBBYMLtJV1TexcSMPn4fAKDfD6uWYSeGhP6J0mfYNHOE2Sn0MuM3+yE
vrPLiCmNctnnWfcIWiUOXA9BF84MWwglK0UETR1CEONvvdpqlmvGf3G8S1r8P0MF
B8mQBTsexWGMb2NTeaY=
-----END CERTIFICATE-----
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 2
issuer= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 2
-----BEGIN CERTIFICATE-----
MIIEDDCCAvSgAwIBAgIJAOikTZQKEq0VMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD
VQQGEwJBVTEYMBYGA1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRu
ZXkxGjAYBgNVBAoMEUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVh
bTEpMCcGA1UEAwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDIwHhcN
MTgwNDI2MTYzNTU0WhcNMjgwNDIzMTYzNTU0WjCBkjELMAkGA1UEBhMCQVUxGDAW
BgNVBAgMD05ldyBTb3V0aCBXYWxlczEPMA0GA1UEBwwGU3lkbmV5MRowGAYDVQQK
DBFBcHBsZSBQdHkgTGltaXRlZDERMA8GA1UECwwIRkRCIFRlYW0xKTAnBgNVBAMM
IEZEQiBMaWJUTFMgUGx1Z2luIFRlc3QgUm9vdCBDQSAyMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAlZBDX6/eZDsu8JrEE3rgBcq8qRSAAhcI3B4PRz8K
NgwRGGq+8BrjsTRMqFdl8GpUDbzFKzpZ3I849GwkK+S0YU86dAQa0aORL5oEBisM
wjxDSRe3qyFZBnyJJkVo9BqF3wJhGCnWYNtFQ5OWnBKS3ZPf9jUGGL1q8ZFMoK/T
z5o0KmjH2VIAIW/Jz8Ouf3XQUHG3qC1C6l//BPqKWhxE0dYcDKBTSNMeI/NOsJ2X
PJn4g4NG+SYurQwTFYuFUTIig4p7Zu68VvgyNK/sgWoiR47AyyC9Lc5/Ojr0GMUp
zOhPEUba7ZnSgSlQLFdOyuKPO9LnaRLZ2C0uaW7ZHcXVMwIDAQABo2MwYTAdBgNV
HQ4EFgQU/DxpqnpxElyiZZHTJBmO7bTajGcwHwYDVR0jBBgwFoAU/DxpqnpxElyi
ZZHTJBmO7bTajGcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
KoZIhvcNAQELBQADggEBAE7VijzPBR7ouPkAQI6OEe8iWiaNE2OziZhOofai84ky
ExhGrd5NAC7eSLiIe/iXL1T0XobMwxh+hglz9zqCQ8xOLtH2z3xH97KSehnb/psM
Zz/7fOyHlj3MorRl9xpi7ncz9IY60hKAeYQ8JxSz5Wp/9KyXP+JPGCcnDal7AphW
adesPBGh6eGeAY0EDstETBsm1uMg99ABWeJk/moOlK/8F05lHUa15Pkyxx//S/cf
tKJUUcj8COm8vXvEFIBPi2FH8DKZMLFG8Ld/9N+lfDgp0r1yERxdWK4aB22iRoTL
LX97Vky4ozfdldIFBi2tzYggraPlgVn+Rxza6XXc2xA=
-----END CERTIFICATE-----

80
FDBLibTLS/testdata/test-client-1.pem vendored Normal file
View File

@ -0,0 +1,80 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Client 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIJALOPTrQGpet4MA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
ODA0MjYxNjM1NTVaFw0yODA0MjMxNjM1NTVaMIGIMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
UyBQbHVnaW4gVGVzdCBDbGllbnQgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBANj3q3KYExHaOLkrzc+rAHl90pc8/msBoc5CZ+nVHBfyCNkOllNtUh8+
sSzpkfWJB+XqQhFCj5T9nudwnaTYHASfd9QJ/sf5ImlzP1WiKJFMbxyDMtaRkHkS
KvnMhSquZHdy3UBMKTzUBbSAMHa1YB69BmWYnaUMo6tMyURWMVYIiIR6hP/JOQEi
69iK4IHyCkZBIBim0YFaTm//DD9wMpPQ9WKQCLVvOWXkKzC46onT1B0hQqURab4Y
Tx4lbL+Ux9SfPMchw+q61H6NKDyjy+65YASXW+70WVyuAstISrrjwDVjCZ6wTmMj
KdkPrP6n40NA4s80oT8pTHGj5Qyk9nECAwEAAaNgMF4wHQYDVR0OBBYEFPN0PhhZ
LtP5w/UG720qW63BdUUxMB8GA1UdIwQYMBaAFE5kWrQCBzHu7qG5gMdamzZ0lHpS
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
AQB2+Wcc48txPQygh//2nxzxTCUiDhKnxXaOqJawJ1sKwLVhGYvlJQMVBWUUKr46
xsiYl9AnQu0J0ARHDZKwYvUieaG7wVd4lnsDCifRwyUoML4lETVBucK/oTVt5Kde
hEd6VR8fnS5P5hjnfCZ9XB5EwqRk+nyQO3XFBQLjYBeCqhA9vRnIuE6xYTC20Dss
/zl4SJQRC1WQ0C1+O0719yHgujjsai9jlxLppnxZz12ZfQy7XmXJFCpkMsmI95+e
M4O/7p7RObtlVJCEhleJbc8N8aZ2JYuRENwyuvaG5z2fpK9chrP7YkwE2PMTOGsL
DS21pfxrLCsPWGFe9tLAPauc
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEAjCCAuqgAwIBAgIJALOPTrQGpetyMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEpMCcGA1UE
AwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDEwHhcNMTgwNDI2MTYz
NTU0WhcNMjgwNDIzMTYzNTU0WjCBkTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
bGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwKQXBwbGUgSW5j
LjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJUTFMgUGx1Z2lu
IFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCqE74CmPzqGMCmWWTrCDBOShmiOcu266V0+upPBn3aEo3ZUevdRDIZ
R5waXh8sVmxoUfQdwxOBZPZFSLULPU9vQDny2DsbYfJ1MLNzEH9W5gHc5YzpvtuE
6cZvaCb8PLGcGOesACwJ2tpc+lI9ZxfB/vIO/ZUcg0mHfhcaE1bHRVrj0yZTkPe/
yhQWWQshS6locyn+LbvayB72uaC4OeCbucGOH6B4SU1pBpG8OPMD3ktES8nIjDdj
RnuiPestjt7VIB6u37CsTSupK9Gxgyi7U9JI7kwCnRinZmHygDzLzlQ8Awksg/Qb
NuSfV0OcNG3O/Xal4OWhS1AMpayPMxXFAgMBAAGjYzBhMB0GA1UdDgQWBBROZFq0
Agcx7u6huYDHWps2dJR6UjAfBgNVHSMEGDAWgBQIWQAHRYgGMY/ziEvCGaoqIFvJ
eDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUF
AAOCAQEApoV9izIHMB4418NP8FTdsToMwemxIs/ASoURGPnXnDG3EG9R8E8h64bg
38fddyaOR4AkWyn1DELzlp2vdlA4v8xY5Fu4au5MSvpxzf8H2ia3QUP/xEGj70Vg
6BJhRWQ/iOALVLVsTvJmhXQBlhIsFZMi0eIcr8CqpZ6x80SuLgl67omBvqpoVNuA
Y0FKgva+bNcEDhPur7LYAiTT+0ykgKFMR2/KnPDJOh12lYMw2ILQIQXuYCJJOXNy
nXDXa7l8vxywxMtdk5jqAB8Jct+9gV69F5uW+VuP9CEfHXpOZmDsxbFzsQbU+5mD
xj4rdSXEuk8h9bOBuqUBR9opl7jw9Q==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDY96tymBMR2ji5
K83PqwB5fdKXPP5rAaHOQmfp1RwX8gjZDpZTbVIfPrEs6ZH1iQfl6kIRQo+U/Z7n
cJ2k2BwEn3fUCf7H+SJpcz9VoiiRTG8cgzLWkZB5Eir5zIUqrmR3ct1ATCk81AW0
gDB2tWAevQZlmJ2lDKOrTMlEVjFWCIiEeoT/yTkBIuvYiuCB8gpGQSAYptGBWk5v
/ww/cDKT0PVikAi1bzll5CswuOqJ09QdIUKlEWm+GE8eJWy/lMfUnzzHIcPqutR+
jSg8o8vuuWAEl1vu9FlcrgLLSEq648A1YwmesE5jIynZD6z+p+NDQOLPNKE/KUxx
o+UMpPZxAgMBAAECggEAYhz9hsCGPxhzdij81N/7QvVG+eU3F6SRSvh0jSU1ow5s
OduC1w8kh8SN0kV9H49r5uhcH/n9e96EsRwX7adcZCrIwTYT5NIgYZcgGNVPiwUJ
addacfU5Y8Z3cKavwXFDNVDYBG9sZnlqawlc4RF7+ep4rhCpmS1yBdCfYyum+8Pi
1dQsE3whxDYf+P/f/9Cjlm3UIo8hrYTOr/zq8EushX6cf67q9CxAMCHGxHDONMOX
hAv35vhOHm5WYGuuD9IitEyPFIL9F06/vU+k4uVA8Oo0/8nhl6YTHgLYZoM0dqFm
/ofz4UhDAyyMWE9nHYpXoiSIfpyC3K91ahWdpxXpAQKBgQDzTzxoLQlXyBXDouS7
zMw/nkqDZ1oy9iOghYSrhiAmyRTFuUzGpjAVdlMaHr0QdrOVS3kEJneDciPe1Uil
Uo6LyN7Y+ePid744gQBj26vznQKe1Q1YXQ3kRVIvV6kHAgFhVMv/x5YV5JsSDtya
FRHavzDlQRjMRKxB1lnjgO51eQKBgQDkSLRM7GK/8h2r7njWGmprDqQums/ZEftQ
9m/HiraXThyJPHYzR2bE4N1nHx4SEiSYulazU3F2s+tp1YIXdDWnRquGhI9OpmcB
Q3R+Af/LIsyBl3ugzjKErHh72WIC/UhAimzLW8h3fQy1uOQOnqnbNpga1BqBl8Bv
c8TyRHgiuQKBgHXqE5tlIB8Dn9CVFAcTpHS8cN4n62XBNdjofDhoIxLI5qFAQT4Q
ckMkefexp+zfqf6Teg2R2t/AJDQs5yz/yodiDOXYjSFG6NAXbKn4XugMUqXJGNOX
HVFgawj4kbkMtsCFyOunvUvU43Yn769YwLNjbv3bw3nTWiv6Bswjwuz5AoGAZfPG
elhUHe9uqvudAdnYTynBz4KacxKhz93PvClKNLbQ7cWP8ITh8+mNV+HA10c9Cuyl
jf8lPGNMLv8I05q135gjQLdxHSoZ9KmAnEoeSEWpWfMiZoXQcApq4L0MFdOycgig
YA4EsMCrbXk+eP0JVPrD4a96iwgQDHaCrcRAdxkCgYEApyJ789WE2tQylL/1vhE6
cu4iXMYbYTp9w3FaNZF4/yh3AT6VGyU2x28Z3PuZcWFFeZSRYuRhMNglAgSwJgXV
qJdtdKz0gscvDQxT9luqMBNKdh5u8UvwwIxoozbDH6MJ5gchk7h7mB/O/wtaE/7K
EYPR6QVzl4Mv0M2WGZ7kzlg=
-----END PRIVATE KEY-----

80
FDBLibTLS/testdata/test-client-2.pem vendored Normal file
View File

@ -0,0 +1,80 @@
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Client 2, \C2\80 <\01+\02=\03>"
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
-----BEGIN CERTIFICATE-----
MIIEEzCCAvugAwIBAgIJALOPTrQGpet5MA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
ODA0MjYxNjM1NTVaFw0yODA0MjMxNjM1NTVaMIGdMQswCQYDVQQGEwJBVTEYMBYG
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBDbGllbnQgMiwgwoAgPAErAj0DPjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMECQvC15g9BhmNov+0Wr/lRCPR9
shOuuxR2Q5DnFHbef3ZD3wD8B6eZHJMYFXXPFI5+I7Pa37ej1iPtJZLbVM0SzrPw
B5/maTbOTIe5nkmBYe81YnE7dcDCncMlHnUqXZP7ZY14PwxA0c60dky6UYeFkQqJ
H2uzh9siX7qJKdGm5/MlK+wLEsHqg6rHYPEe0o1NHmHvwVVZTGw3DAq5z0fmbWQD
PrTUOzn/4b0bV7zZjy7tBAp65b6bOGfOccF+lvgLEhooMYaoQxYMzOIx0091cClV
FnDTdG9ThANQRp6CshOHDO1kemsdHZkFQbwn5dCWe1I0wwb7RiyNKSKyPhUCAwEA
AaNgMF4wHQYDVR0OBBYEFOQwxEN04ikMQ9IO2+SkTYwy8xMyMB8GA1UdIwQYMBaA
FI3qUMbfoAWLeyNOiULqI+o1FAmMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQAzj35V+V7j8ScwMgPt1f5O1dkw3bVKDtPJ
10b52pXBCelNi/WNY0PTp5vOOQo5n3Cmnte6O5BBZhvRqAhoztMEhe8oxExr6dcj
dGkgXbLDhMeHJNb+qh5wezaiFH7C0cNgLEHHv6fvGIrCKJ4lqdQs+4rmDRynXBSx
Zjt18ciFDgZeCGlU869Le3C3URERGGl/whEHPyknaaJVF0mhqhYXioP83ilh/6Av
2ct9zscavCfmDGa91lDsybJqyndXmtsvFVQy+EVg3vzamx1wMNCCBCXhWv9hGNex
WJplxBSZTNbzH7g06lTcd2m98KFEu25bpyUGeaAIzOT6PtcDeef+
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEAjCCAuqgAwIBAgIJALOPTrQGpetzMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEpMCcGA1UE
AwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDEwHhcNMTgwNDI2MTYz
NTU0WhcNMjgwNDIzMTYzNTU0WjCBkTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
bGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwKQXBwbGUgSW5j
LjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJUTFMgUGx1Z2lu
IFRlc3QgSW50ZXJtZWRpYXRlIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCrmd2lnZGJt04Zn7ToQBf4zaBNe87YlMGc7gkA9P1fT3QBuT9K5x21
P3SZQJj9KQ8LQwLYTUTPaJDPQ+rgZrFU9e8lTrKtjD4uPafzSDXLBDz4sDrj26hd
jh7ldMh0qMb+pvzMI+/R1oULQH0+45oweFeEfdrXeMOgITJXtNd4lPB6ezkkIE++
xbeao2bnTfFVwCsSDuk67tEPce2CKt0jI1/8nLcs4qd3uM0bRWyPd+i6rDQckW/3
rapPqCiGZoYLwMMVKfZMtLRftx8JQsvK+7vwU+SgOSI9Of8KYkz1nykKEUA0U2Pk
8MxOQ2SFC23ChcZMNaTWxfUQT0Enab4xAgMBAAGjYzBhMB0GA1UdDgQWBBSN6lDG
36AFi3sjTolC6iPqNRQJjDAfBgNVHSMEGDAWgBQIWQAHRYgGMY/ziEvCGaoqIFvJ
eDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUF
AAOCAQEAMHVjMu0aJnfmj44CLsdBVzJSFSg2ibvyRLbIEL22i5HnfAnl4uCW5ms9
/pYIaOqw0r5av2WfeKBzarGfBC0vnMGUog7rjv6CFDT52o/w5w9ScNAE2m85Ibt4
q9rlFSh2zOYUCfG5F+7cGHHYrWNvQ4X8p2qziUHZEl3i9hCr9edt+XnVj6Oelb9q
3zDdqOwSklJ4DzcauZORv/FwRggqZlp6upuIdVC5lIygd92k6RugQOwrWhLlaAi+
OC6Sw45W0RG0K4WqLBrErmqH3OmV8O1xNIAFjADR70AgKYAO9mOobTRx+iD/me5R
0t0M0NLKAVEGiOTvznu/yxnNkDTpsQ==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDBAkLwteYPQYZj
aL/tFq/5UQj0fbITrrsUdkOQ5xR23n92Q98A/AenmRyTGBV1zxSOfiOz2t+3o9Yj
7SWS21TNEs6z8Aef5mk2zkyHuZ5JgWHvNWJxO3XAwp3DJR51Kl2T+2WNeD8MQNHO
tHZMulGHhZEKiR9rs4fbIl+6iSnRpufzJSvsCxLB6oOqx2DxHtKNTR5h78FVWUxs
NwwKuc9H5m1kAz601Ds5/+G9G1e82Y8u7QQKeuW+mzhnznHBfpb4CxIaKDGGqEMW
DMziMdNPdXApVRZw03RvU4QDUEaegrIThwztZHprHR2ZBUG8J+XQlntSNMMG+0Ys
jSkisj4VAgMBAAECggEASkMUfol+e2A61QT408Bm9Qa461lxqyEP2k+mr5o5xYLW
iCqVI0vVpibDV9VsbGfBARKHqiwM6BuhyTD1xAugFUenQJSaWmvND8lQqOhCfwXJ
KMDhn6/BHunCydL+ZRZn6whPip85ov1NvLqyydLmi75YkDUyYb4yB56yNpOQA5oJ
lsJVKDNwSZHk2wcrZZOf9xgBWtBvdwMy8/dpIrGi/zIVLVk8F/L/OhcKULz3xQu9
j81AU6SiT6tYGuDaM+plUtnUvaBm8BTgk5F6ghOGnN6AmS6FNtM1v4Z3MaP8yYGu
BaUxC15RbuZZkT0d+FNqFpk5/HKKXZV4jOB/bn6eAQKBgQDfEZWGhub7NrptMhr2
3Wq16JeO9WyWlEHhCYgRaP3LjY4JCCQKbhWkBiukxtOqOqYQ2YlKoPr6EcQHKz3C
CtMMtmBs9sSgtUeIqch7VfmgJMLBi2ONTdCDmOhw3R9oL00L3crWorHme2ZabhCU
RYUKhKQ91V/FaRlrteQHFA1PgwKBgQDdgKC+Tamw6gdVCmtf4GIwBucEgxKoFGT2
hVb3xIyGexsb6v6e/DICmkNMzUWkZEb1m3PN3rp/76A1uLz6346x60JIotlywyA7
9ieWOOjXtgRAPpopPrPedFhTjd/UOfIpYl9klJzYBonYC4mj0wxqdsu8niqwIht0
wSCPtkxwhwKBgQDDrPgebx4VhheZDBftL6OY+PRh+lYL7PexQRw0MYZYVc8fix2a
bKDdJnCIdcVdEV91bm3pojcmwAjWRQ9CtR4Xi7AgRYOMehjLACyWTH/SBA03nF9y
p6zek3Zq8v3G9Z8/Zoq1JzipNtw9PUmb1zPyWxJ8Dz2YvS4IdyEVOHjIowKBgQC3
pFAg1wTMP4tqryPMrpzZUq+v5vfN0HLQjEZJT3RufpxALjmCGHdh/wGzKDEIFXdb
Y9HEKlgXf9UlFQ/hMv38dp9S12lPI4WTEQdLHc22IhsuJHjtnyXDVlRwmZysOIqU
UxHhsvDCjdE1BIPOBkkx72IE9GFR/EUlLIVRgQOo+wKBgQCD5Hyn1vYxKZ0y4sBi
s2y1joxTZ8thkWs95HzHpv0v0mAzSU4aYdkGzoZI9edBUlutOPutPqyEjCTS+e4X
ruA9d/0zg0sqvzcC074+8LdTR8Vut8QA6Nqve0XpzxZxyQOqfouXRELUBS63uECY
XUDGwPu1yucaorm4BXqdn05Iqg==
-----END PRIVATE KEY-----

124
FDBLibTLS/testdata/test-client-3.pem vendored Normal file
View File

@ -0,0 +1,124 @@
subject=
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 1048578 (0x100002)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, L=Cupertino, O=Apple Inc., OU=FDB Team, CN=FDB LibTLS Plugin Test Intermediate CA 1
Validity
Not Before: Jan 1 00:00:00 2017 GMT
Not After : Dec 31 00:00:00 2017 GMT
Subject:
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:eb:56:4c:da:09:7f:4c:b7:7e:83:a4:25:12:d3:
a2:ba:73:38:51:6f:e0:7c:7c:87:e6:94:c9:3e:f0:
b2:31:09:90:fc:c7:b4:64:c9:a9:28:89:6e:6a:a1:
23:41:70:36:6c:13:01:06:40:14:f6:c2:f6:3c:d6:
8d:9b:42:0f:83:b7:75:9b:05:27:86:55:a0:8b:11:
7e:f2:43:f2:d8:ae:27:e2:a9:ec:80:55:39:4a:24:
b0:9d:f8:33:ed:d4:ca:41:e9:e6:00:81:d5:ed:47:
7c:da:33:2b:5a:a7:e0:4c:77:b3:a3:b0:dc:77:3e:
44:71:57:ba:0e:9f:73:d2:c5:cd:a3:78:37:00:cc:
55:1a:1c:50:45:37:f5:15:cb:b6:42:44:99:fa:13:
bf:d8:56:c2:39:7d:94:cb:1b:d7:04:98:13:8c:e5:
52:95:a7:40:2a:da:2b:36:c1:a9:01:7f:08:5c:86:
e6:a6:86:ea:a4:29:ee:9d:e4:4b:86:d0:4d:b8:e1:
5d:37:df:42:87:66:d2:31:d4:25:0a:5d:6f:60:bd:
53:2c:95:ea:db:f9:d0:b6:a7:4f:9e:80:0f:54:41:
93:a6:6c:9c:e9:bb:36:c6:cd:17:b7:20:ba:56:99:
87:b2:86:47:f3:94:8a:34:66:dd:f4:cc:a7:c4:d1:
c9:71
Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption
99:42:4d:71:3b:5c:70:1f:1a:c5:3b:6a:6a:4a:fe:10:93:6d:
ce:dd:d6:2f:9e:75:0a:27:44:a3:06:96:d9:bd:e3:33:2a:3d:
14:80:e1:d3:f0:4a:24:f4:30:08:74:8d:b3:1d:78:d8:be:b9:
f2:fa:de:1b:a0:fa:51:d2:c3:ea:47:4a:21:16:21:b9:97:bd:
e7:72:26:ae:42:20:ea:09:2f:34:0b:3e:1f:77:ec:63:a4:10:
34:b9:3e:9e:22:06:b3:28:c6:e3:d0:ee:7c:64:1c:3c:0f:6c:
c1:9c:b9:84:62:fb:04:8f:2c:49:a6:e8:bb:11:46:30:06:08:
17:e7:4d:8b:c9:1a:12:74:49:c0:9d:e6:fc:89:c8:b6:81:19:
dc:1d:59:10:5f:2c:d2:c6:e4:73:29:03:8c:7a:c3:41:7c:28:
88:97:c7:31:6c:78:18:b1:8d:cf:5a:35:de:9b:89:a3:48:9f:
eb:0d:57:8a:d1:be:a0:d6:42:71:8f:7f:1c:f5:ef:d4:00:7d:
a8:7d:e7:03:2b:3f:bf:50:63:e5:72:57:38:ae:50:5f:94:42:
ea:4c:f8:02:b4:33:67:e8:09:bf:9e:21:01:48:63:d4:cf:29:
da:c7:8e:21:a6:ae:1f:e4:56:03:74:c8:2e:3e:77:9d:60:e5:
53:4c:14:87
-----BEGIN CERTIFICATE-----
MIIDCDCCAfACAxAAAjANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMCVVMxEzAR
BgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwK
QXBwbGUgSW5jLjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJU
TFMgUGx1Z2luIFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwHhcNMTcwMTAxMDAwMDAw
WhcNMTcxMjMxMDAwMDAwWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEA61ZM2gl/TLd+g6QlEtOiunM4UW/gfHyH5pTJPvCyMQmQ/Me0ZMmpKIluaqEj
QXA2bBMBBkAU9sL2PNaNm0IPg7d1mwUnhlWgixF+8kPy2K4n4qnsgFU5SiSwnfgz
7dTKQenmAIHV7Ud82jMrWqfgTHezo7Dcdz5EcVe6Dp9z0sXNo3g3AMxVGhxQRTf1
Fcu2QkSZ+hO/2FbCOX2UyxvXBJgTjOVSladAKtorNsGpAX8IXIbmpobqpCnuneRL
htBNuOFdN99Ch2bSMdQlCl1vYL1TLJXq2/nQtqdPnoAPVEGTpmyc6bs2xs0XtyC6
VpmHsoZH85SKNGbd9MynxNHJcQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCZQk1x
O1xwHxrFO2pqSv4Qk23O3dYvnnUKJ0SjBpbZveMzKj0UgOHT8Eok9DAIdI2zHXjY
vrny+t4boPpR0sPqR0ohFiG5l73nciauQiDqCS80Cz4fd+xjpBA0uT6eIgazKMbj
0O58ZBw8D2zBnLmEYvsEjyxJpui7EUYwBggX502LyRoSdEnAneb8ici2gRncHVkQ
XyzSxuRzKQOMesNBfCiIl8cxbHgYsY3PWjXem4mjSJ/rDVeK0b6g1kJxj38c9e/U
AH2ofecDKz+/UGPlclc4rlBflELqTPgCtDNn6Am/niEBSGPUzynax44hpq4f5FYD
dMguPnedYOVTTBSH
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEAjCCAuqgAwIBAgIJALOPTrQGpetyMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEpMCcGA1UE
AwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDEwHhcNMTgwNDI2MTYz
NTU0WhcNMjgwNDIzMTYzNTU0WjCBkTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
bGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwKQXBwbGUgSW5j
LjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJUTFMgUGx1Z2lu
IFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCqE74CmPzqGMCmWWTrCDBOShmiOcu266V0+upPBn3aEo3ZUevdRDIZ
R5waXh8sVmxoUfQdwxOBZPZFSLULPU9vQDny2DsbYfJ1MLNzEH9W5gHc5YzpvtuE
6cZvaCb8PLGcGOesACwJ2tpc+lI9ZxfB/vIO/ZUcg0mHfhcaE1bHRVrj0yZTkPe/
yhQWWQshS6locyn+LbvayB72uaC4OeCbucGOH6B4SU1pBpG8OPMD3ktES8nIjDdj
RnuiPestjt7VIB6u37CsTSupK9Gxgyi7U9JI7kwCnRinZmHygDzLzlQ8Awksg/Qb
NuSfV0OcNG3O/Xal4OWhS1AMpayPMxXFAgMBAAGjYzBhMB0GA1UdDgQWBBROZFq0
Agcx7u6huYDHWps2dJR6UjAfBgNVHSMEGDAWgBQIWQAHRYgGMY/ziEvCGaoqIFvJ
eDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUF
AAOCAQEApoV9izIHMB4418NP8FTdsToMwemxIs/ASoURGPnXnDG3EG9R8E8h64bg
38fddyaOR4AkWyn1DELzlp2vdlA4v8xY5Fu4au5MSvpxzf8H2ia3QUP/xEGj70Vg
6BJhRWQ/iOALVLVsTvJmhXQBlhIsFZMi0eIcr8CqpZ6x80SuLgl67omBvqpoVNuA
Y0FKgva+bNcEDhPur7LYAiTT+0ykgKFMR2/KnPDJOh12lYMw2ILQIQXuYCJJOXNy
nXDXa7l8vxywxMtdk5jqAB8Jct+9gV69F5uW+VuP9CEfHXpOZmDsxbFzsQbU+5mD
xj4rdSXEuk8h9bOBuqUBR9opl7jw9Q==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDrVkzaCX9Mt36D
pCUS06K6czhRb+B8fIfmlMk+8LIxCZD8x7RkyakoiW5qoSNBcDZsEwEGQBT2wvY8
1o2bQg+Dt3WbBSeGVaCLEX7yQ/LYrifiqeyAVTlKJLCd+DPt1MpB6eYAgdXtR3za
Mytap+BMd7OjsNx3PkRxV7oOn3PSxc2jeDcAzFUaHFBFN/UVy7ZCRJn6E7/YVsI5
fZTLG9cEmBOM5VKVp0Aq2is2wakBfwhchuamhuqkKe6d5EuG0E244V0330KHZtIx
1CUKXW9gvVMslerb+dC2p0+egA9UQZOmbJzpuzbGzRe3ILpWmYeyhkfzlIo0Zt30
zKfE0clxAgMBAAECggEAKZNTfGmVHb6FEUicbBkLdJkKaAi1xghSEgBTFVV8hYFF
JgM58VxXEBxHb3sMOXFTjABHfA0yJu4GhnT5C2a+SuzMUBi3BNp3xFnQ7YfnjTQn
Q7n1WC62Mk0NDrtcoTWojcB+q7REUOkCO6IylI935sp26AJE0KQlf0iaTB8LXT7R
/IeZgUs0qoY+LVa+bsCgXvvFqtf1U3GHgW6R6vNksWAL/hDewJPAo4pzoZYRc1No
TJ8lP2fBNTzn+8zkaoHJ6awT9T0TMlwq0uruDr0wGeSTYpuwP9IuwDdByiJO6EQs
7XNTUlEr5yjfIpR5pnKRxFwlrvPl8xpW32gQgZYoYQKBgQD39P5NEquNM+CNM9EB
381du6bk3kFB2bn49U9jGbU1kcMJekJ6cOsGQgZvtmh7GWkGdey8icjOCxx/rmQ8
Yk05XD1/qPk1H1EQ0xjJ0NheHSq1eT3L4ZAR9hvCZa7Kn882VgKTAHAnp0XxoIse
mF5TVCPTxHzl1hd9V5ocRinXBQKBgQDy+IM+axVIuTIP2KUs19JooZaSx2k9k575
7utNCFsvYjA9Gi3QufkBGZ+zoQjwJGKyQbYdldgObMivhylhL/YAsfG0OdZYEMLQ
NF9xHy4nLI/6ikhb7Tm1Ja4iCrEj7H78TLz7U3V2gaOTrpVWg/x+SXg1wz6gMH1p
r2Vm4wZcfQKBgAMD8rfDO1zbPabZ83e/XgL+zjfIUCjZ2f4iFZYR8Pc2z5Vk7DwK
9YC8+tEO+dRNac6PTpK4Zj3DOtR+rW9ijqfc7E6KIoW33MeEma+Sn579YdCVKeA5
3QOq54mErQx/xwhVIXDiN3rz+NDIcAiuN69xvYHMyOwOn3iBwTkIzWd1AoGAaDUF
tSOgQUyMmBdG4HDAIXgMaG92R56ktHUwHh3TXgMyxUIRHFBm533h7NzIRJaWbfWY
8h9uRuGJQR8rNC+pxqqLC80yjRrDMyEDPjUtSkfmiIH+fs7DzVmX0ancR5gK7pLL
Cs/EtUrsqU5bZnu9Mzy3ffd7SKEDaOx9BR+hftECgYEAs0wGUVW5oZoaHzHorHfG
W4dOwvmcT5Y2uHP8JBiOr3l6NHzdbOhN9DmEo62sf4rIrz+h1TIkLCS36Agm28JL
ptTfVAaB6ufGwBh8uMtzL5cd6gZgG2g9SKEdHCIQ9eQajuepWEgtMJda5e1+zLfB
Na5+X0YtsCTXKtqSMSO0Zy4=
-----END PRIVATE KEY-----

82
FDBLibTLS/testdata/test-client-4.pem vendored Normal file
View File

@ -0,0 +1,82 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Client 4
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 3
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 3
issuer= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 2
-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIJALOPTrQGpet6MA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMzAeFw0x
ODA0MjYxNjM1NTZaFw0yODA0MjMxNjM1NTZaMIGIMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
UyBQbHVnaW4gVGVzdCBDbGllbnQgNDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALhJzjx42rEMT6JQC2Dq/A2/iHWyNCW6h6PqLE6JsKsHiUIHLQWbE766
Pskwg1RpXkfMONyOYVpGSos8jDdxNGbpyCsRFsMcmG/oiGKUY+OCW7S0l5lvSQqX
j18LOTAThSXWZoMvimMMNFivH356GIxR0mTFdv308JR3GgI1dZvvIKvNQUjs/bvG
UUw8Gq9PxbHGLjQFLFYaCPUs8OaO2nTEurM5JpDlEKaqL2usOJgjhvvtlJ4oo+10
aYNUlIotYxbJsxnAIciR6FjNfUz9z4mrYG62iR6OD4bI3OP74nOv6poim1tze7DP
93E/GEHso+Pfj37m53r50TD+GUHwRJkCAwEAAaNgMF4wHQYDVR0OBBYEFFRemg/3
R1b0u9qfeB6LQFAc23awMB8GA1UdIwQYMBaAFNJkFNeVtJApFs//7Jvd5R/+BJ0Z
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
AQBHrHzTOjZTjWnmTCmUwtDfSXEVQia9DtoaI1dVUDNbANFvMQuAe+ReuEicWmxQ
mhCXkFBgQr56g5QOY1e5ncBpjSqs9GYfheW0L2dTYFvVp+yXAaAVW0sY56dFnrKx
rYiPYO6ssMElGQPUQs8q/Mup/JMvkv3B4fNi+COPy+KNV6t7pzIEydg5uurOkK8J
kwIvyFlit1W+KXIzZlKHCzv4jF0Q3lDXQXjNoLORCAxSgyJVVcxvLzPTtCtKM0XC
0uMc29N61aTmzTonxdoAlxhRhohCfYohTvUg/2JjbUb1U/+VRRkTDl/4H4DegfBm
igvwRnL+koW3Bp8ZdmRfTO88
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIECzCCAvOgAwIBAgIJALOPTrQGpet0MA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD
VQQGEwJBVTEYMBYGA1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRu
ZXkxGjAYBgNVBAoMEUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVh
bTEpMCcGA1UEAwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDIwHhcN
MTgwNDI2MTYzNTU0WhcNMjgwNDIzMTYzNTU0WjCBkTELMAkGA1UEBhMCVVMxEzAR
BgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwK
QXBwbGUgSW5jLjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJU
TFMgUGx1Z2luIFRlc3QgSW50ZXJtZWRpYXRlIENBIDMwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCZ3UPCarKiS+IqK2VvB0lVQ3L0TPuNUov54L7ELFnB
1lijZWX2wX3Vi0uAyvwmLi+PYkUkzhaNhGWbVPHEFqsOzwMbifGLfdxjetZD0kOr
ZuARithrDXVWZegIXEFDUdnpz74TKG6rCQ6o4WMIFUV/j9770iMtrMABr/BwASrE
sVqAqNe4bOqHJyxyeTxF/vCRme3PVf+u06mM9OLxVVaPRK+tiysdKprjs6oyFoxT
S/Cl+vv7Lnt5Yth0F7YJGMrIKDPuSWCqAfKWAc+b73XPQ14coIczVzQAikyRFmGa
9aaw0aWYI2gjTkuah0c5fboZAuHT0Z7nQVtYUyIYRY8BAgMBAAGjYzBhMB0GA1Ud
DgQWBBTSZBTXlbSQKRbP/+yb3eUf/gSdGTAfBgNVHSMEGDAWgBT8PGmqenESXKJl
kdMkGY7ttNqMZzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkq
hkiG9w0BAQUFAAOCAQEAdoyvb/2+r587RMar6+/OauAVXWwnNEI8hhUvxiTnDq/M
TKu+okSAHSbGvYp5yGD2IXlEZHjtKnMapsih7tvm2VboM7U5Zi3aK7hjvk6Kxs5B
eynHP9dDnUWG/qRbAF83B3mK7ymmrZvJIDwHZEtY9Gmmmb9ty9aK2ywmYtlYgIS8
FSh/qwzvThIiMuCQma9JJOx6ZDXV2YwCxYtIRAuTvIWuOckb608fPi812k0zYILG
q4VLhZTc2AM8H/629RBRV5zC/tqySLb3VgpWQ2vZSzUwuKIdIPs4lsbNqmsdWIyR
hHnl8610t/JAUdCPHDd1bBlYNgLhMKJTM8fGu9Ux/Q==
-----END CERTIFICATE-----
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIin+Bh1kSGiQCAggA
MB0GCWCGSAFlAwQBAgQQecgfNmQfm8gVISC1QceptQSCBNA3fAw+SiU1l/j+Pc05
2i1VzOkDKQGTSVtpO6tV67p7uWaUS2oCpx36eE1LfJgWOxsk+gizPsH1kFrKlqfl
6SmeVp17dogeBX/uf9bGqyqEO4GXEmxhajMFpE8mmQJ4aSLGuSN2sh1YkI/QrX/v
y6QsJi0hsd/xxjPORoZxhtgRwRaiw2hUF9Al/ipusoRQ+x4of6j6hpVLxAn6yKIk
l6fk+HDlGaEBLZjbTQd/Usx6AlQo5ydEPKdftKx6uHltkt0hrnIJC6pc1w6O3Ndh
An/lagHxNSGfAFNkEH3YCFYtRzAR19a879LKVFqaKfVgfhwv8e0x06GaIfvyaGiY
KbzRkjIUp+Z/0SB8hZVzOTNYcW/0cXRNH498Vv5L4j0irqTyf7yxwiPuWZieBGpa
sLo9gE3Ap0XahS6//G2ZIXAwXN9nVPN4QjyKh4iXmYO0arNiIYZwtHJ77E/O62x7
cKQA5y4Fsgft0wWUfAi5nZ16qwleXpSMBfnvHMz5RJWIGjpiQ67Mf9u9svudXR0h
5TQaViQLDUVs6kAhulTQvdifPCsIbpLlJ2YxH2L9BsTPnU5oHBU+veFA6zagjh0G
UtyaQWKe8iC7cjeEXRL5s32bfaG4x5FMnNJbU6Sd5qGbFHPJyGorKOCFh8RbTlZV
pXbnYFm8KX1hRu3BbCKxHUVypqyYj7SIOe5ihWkudDq1qDS+ugzMhAdZK+WF+euv
Hzf/HYI3zLKeiZmhmG1ysfs4SRd2K++dYIbmWcFDcNLogsYt4BidH/8VZdxsmd0C
vjt1mY3W3QvV7gWr2ZeMWalmrS+OuTR2jcJPxrqqm8Iz4rGOi/yRrp4i9F3lNuGB
TMo1RP8SFFh9wXvwxRqh8/uWKdeytgqgNbXAA9Lu93IDniGH3ELM655mxbEHFR5W
omCVKu7LTNCgCx1gJDd4zb9cNz0Fmn8dFbdHcmMecil01sDITq6pJRp/niB8MFx9
Fp8t1wf9FrPVbZ5+yKTVfAms3xgj9NmEs5pBZNbz/z4PKW5WY/fObSAiIwNp+17S
mkFE65YPa93DXjs4u62rP21i5L6e5u7rE/hpw0DbWLpkcYrVUrzoEfWXLnBpcCam
OexWbAZMmp2MWF9YOVsGmAfgmPpE57SPvmuh48vFZfnx58hz/Ejg0MUrtvgRzy0X
RcaSX1AJUJ/+M/qsMNR6AX5z2Ofal1nZj5/lfq/OS2lakn2SbZPczuFb87QjXTuj
GXARzXVlnj4CFHO8mep5Z8SsLHOj2Fdljk3EWoNvm2yE+7nbKHVAeDaEqA3lf1Qw
jZsUX3Smc7jc0hRccvwsaNLDST4H1uorCIqGgtqRhH/FsH7jlmqLi2+CaLLd/KwA
VOJoSLaZP3pWJcF2r+sNfrgsFkK3Pog9BRVt45QCarnnmFKu5PmtGnXDw4kc7eVG
z7on+oRURza5mo0HNZTe+JaJO3FdO5fULxn8kk2JpEGqqSbpT1PUCjAc9oShvV7b
qtYMyFLHn5KBJ64HUdQkeDq7o1s2rmQwbIt48xGRYbUuINFBC2KS4oTPlI8jPuzp
KKWC5TGywFtdiIJTWKyPFiHsOM9nAFv+t/rFVkzThrTPlg0W75TQWcK588Id2yzL
bzKKwKV8N3LcIgVcr+bZHooJbA==
-----END ENCRYPTED PRIVATE KEY-----

81
FDBLibTLS/testdata/test-server-1.pem vendored Normal file
View File

@ -0,0 +1,81 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Server 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
-----BEGIN CERTIFICATE-----
MIIEIjCCAwqgAwIBAgIJALOPTrQGpet1MA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMTAeFw0x
ODA0MjYxNjM1NTRaFw0yODA0MjMxNjM1NTRaMIGIMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
UyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBANlALdHnBWuhYm5bsginazmSRHO0l0lpyjbG6EdlPFLg/Xb7Q3tILGRd
J585iqhCLRRx/HZ0j+yv1WZ3ZFcOEZMessw32kt0LN1fbYPrKkHVkQtZjorxnHWa
IW/JMBvMCZHag9vLI87TRtjMicB9ZxIl4Sppal7FZ0ggYBlOZ+T5G3j08y4tszrr
3Xg4BOuKziSmgQrTBObOG6IvsxZZv/MtwnvPeIowBUOGaux5CIjyotmaUxxaRlH9
jbVpojtYCDskwSOq5faqPSpaoOKyXLQ87ayAL6nAP2dXvcv44kaaZbZ5lSyrAW3P
hMsGEhhhkdHfrG6ACwHV45k/m2r4kUkCAwEAAaOBgzCBgDAdBgNVHQ4EFgQUw4g/
xtD1EMkhSpS8jqKa/15emtcwHwYDVR0jBBgwFoAUTmRatAIHMe7uobmAx1qbNnSU
elIwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwIAYDVR0RBBkwF4IVdGVz
dC5mb3VuZGF0aW9uZGIub3JnMA0GCSqGSIb3DQEBBQUAA4IBAQCbNF+pt4RdLkyd
fC0mNxctQeCTIWfoazpZxNrku0gmQmlWnsY8J9TMhF0Mfd3tePXGTsPRyybWObIw
6IKvYCvK8mgz/BlB4RSWs/evVuy+z5hFeBQJJ66dPhfb4gnLw9qnmpXrgudvZkMM
F6pjsNAXxj7yXX5PvgLg+0VysElquwviuQl4AQ4Lit57U+TlLlkRFcTxbb1pZAAK
4q9SWf6rTqwBW6qr8YMbInRZ//cUfprAbDJ2rS6bP+X2S8Qftl66iNOJkhkbRosy
NVn44DGUw5UHL2T4g6FhziisHoga7rMRqMT4Kmo/xcFzRPbP7jggqV485JyLmxXw
vfypbIxc
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEAjCCAuqgAwIBAgIJALOPTrQGpetyMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEpMCcGA1UE
AwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDEwHhcNMTgwNDI2MTYz
NTU0WhcNMjgwNDIzMTYzNTU0WjCBkTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
bGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwKQXBwbGUgSW5j
LjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJUTFMgUGx1Z2lu
IFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCqE74CmPzqGMCmWWTrCDBOShmiOcu266V0+upPBn3aEo3ZUevdRDIZ
R5waXh8sVmxoUfQdwxOBZPZFSLULPU9vQDny2DsbYfJ1MLNzEH9W5gHc5YzpvtuE
6cZvaCb8PLGcGOesACwJ2tpc+lI9ZxfB/vIO/ZUcg0mHfhcaE1bHRVrj0yZTkPe/
yhQWWQshS6locyn+LbvayB72uaC4OeCbucGOH6B4SU1pBpG8OPMD3ktES8nIjDdj
RnuiPestjt7VIB6u37CsTSupK9Gxgyi7U9JI7kwCnRinZmHygDzLzlQ8Awksg/Qb
NuSfV0OcNG3O/Xal4OWhS1AMpayPMxXFAgMBAAGjYzBhMB0GA1UdDgQWBBROZFq0
Agcx7u6huYDHWps2dJR6UjAfBgNVHSMEGDAWgBQIWQAHRYgGMY/ziEvCGaoqIFvJ
eDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUF
AAOCAQEApoV9izIHMB4418NP8FTdsToMwemxIs/ASoURGPnXnDG3EG9R8E8h64bg
38fddyaOR4AkWyn1DELzlp2vdlA4v8xY5Fu4au5MSvpxzf8H2ia3QUP/xEGj70Vg
6BJhRWQ/iOALVLVsTvJmhXQBlhIsFZMi0eIcr8CqpZ6x80SuLgl67omBvqpoVNuA
Y0FKgva+bNcEDhPur7LYAiTT+0ykgKFMR2/KnPDJOh12lYMw2ILQIQXuYCJJOXNy
nXDXa7l8vxywxMtdk5jqAB8Jct+9gV69F5uW+VuP9CEfHXpOZmDsxbFzsQbU+5mD
xj4rdSXEuk8h9bOBuqUBR9opl7jw9Q==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDZQC3R5wVroWJu
W7IIp2s5kkRztJdJaco2xuhHZTxS4P12+0N7SCxkXSefOYqoQi0Ucfx2dI/sr9Vm
d2RXDhGTHrLMN9pLdCzdX22D6ypB1ZELWY6K8Zx1miFvyTAbzAmR2oPbyyPO00bY
zInAfWcSJeEqaWpexWdIIGAZTmfk+Rt49PMuLbM66914OATris4kpoEK0wTmzhui
L7MWWb/zLcJ7z3iKMAVDhmrseQiI8qLZmlMcWkZR/Y21aaI7WAg7JMEjquX2qj0q
WqDisly0PO2sgC+pwD9nV73L+OJGmmW2eZUsqwFtz4TLBhIYYZHR36xugAsB1eOZ
P5tq+JFJAgMBAAECggEBANOvV3Y5tuxi+jgyHM2V5ELapNxhUTB1ZlXthpNar2bK
V+9BcUWE08yPgHYDaXn90VMkpiz98udbhYIsP5cb3EAQH4QhwBDZiIXD4EA0Op6f
bI80mlIEjsGAh6gWz0umioSV+PmHfMKg112UH31yM6ZZRoc+5CioDLUY5sqBvXY7
AGnxMslXEesIP9VLzautKJJGoCXyZgoEiOpUn1N69BcupipekFNlsIANwqkktE+i
gfq6xC4pxUx8w9wkStVg0DPiasl8cOvD4Cle4Sk30itWhIzQnB0uoUcfVsjiuiuT
kGt0pboQyGrezSsbyjh4vo6kAABc1oxeeNIVh+BHeqECgYEA9illuy5qwcxaHdb5
g06WIpFk+HsX2yN8wH3FRoDwU2YfOWSP4+bsyCD6KRzfm+Diyucb7B9aLq+k4FvZ
rRhgVvoaGLzLwqU1ue5EQHcmcNabGhJ2kzp9/MeyWa+zxe1l9ugjdgIQt8HA75xI
dMFSPCfCFmXQVP761y5lWSFTOFUCgYEA4e76jMsFY7WEoMNgmiIzN0uk8b6Z1U9W
kmW7ARrRlbjIaBHJCvblakCIir7BqO7Qyw7E/ssbGTBG7KN+ZxhB17RgAzQla5b3
VtXQ+wTLbsaL0XSjTvGJcseKRGpLA/9JT6krcDUWgWWp9Za+XOqE6138A1S7Uzom
d5Kq4clMuSUCgYBk7e5XRB3jnh0o9PbTHsqyG7kxpI7QfAlvh2H2mXFwUIPm7VOO
FyXonJTVfJA2gouatA2fz+8TC1Nn5mEm9sKxhtRiZi6JfWG8/XOglvn89BEeLInP
rgDwPxTibwcf1UmkZeP8Q7aFEX1BAWw36vgD0C1lL5Ou9ej1h4FofSB5DQKBgQCB
d8OFuLVO7O6ifTM3QA/fSO6tRQ68KKmwXLFrsaWWSXw1/rMZIGBYocBc2XD6UFe/
dKg4ZcUSixKpegruIv1gEVHPpCspWypDTWVi4t18jjQDA/atP0YHSwcVq19vW/Pz
vTpSI2nRHqPlQsu1TQJ8KbBHbF+oErOGY7qehg78LQKBgQDl3/srSZihKYwva8a+
FQrZ0978WwD9JsUOFuHp8gQzdArFiK4VCCv57VTL/4cqdVOwW9eDhgeP5cKnAQ99
5HZzLl+L0b0QfGcerPn4002Us09g7eAh5vHHY7BpdXOU9a9lgfOVWEIMWp1NSGEc
vd2TbSD8vDjbd9hZYh+pqkddCw==
-----END PRIVATE KEY-----

80
FDBLibTLS/testdata/test-server-2.pem vendored Normal file
View File

@ -0,0 +1,80 @@
subject= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = "FDB LibTLS Plugin Test Server 2, \C2\80 <\01+\02=\03>"
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 2
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
-----BEGIN CERTIFICATE-----
MIIEEzCCAvugAwIBAgIJALOPTrQGpet2MA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMjAeFw0x
ODA0MjYxNjM1NTRaFw0yODA0MjMxNjM1NTRaMIGdMQswCQYDVQQGEwJBVTEYMBYG
A1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRuZXkxGjAYBgNVBAoM
EUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVhbTE0MDIGA1UEAwwr
RkRCIExpYlRMUyBQbHVnaW4gVGVzdCBTZXJ2ZXIgMiwgwoAgPAErAj0DPjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO6tYgoMCdvU9QQT556tSgaAGtkf
u2IMZZxoqXqK1Qpfmgg+PkG8+5Dzf+ExdjQUUSS8fPf8AMFx/ZIAMZeNEOnHYPLH
p8iWbIDYyoqqI089WQ5yZ5lypqLvdiTt9HfgaL+rI7fIPNlcGiwdDNq4I9r7rtGv
SoY2ZajgR5hVMessAhVEgb/ahUXlnF2qpuzaSKJMpJU+eCpWO629nNnDCWbJpinB
B5xqhXLdf+clHqdwWtGQVdWTxFOLgy3KAw947FY15hwhZvPSAC1zV/bgaKdh5Tn2
hXCG4mLQUj/vIX0j285zl0B1i+1tkw+2saUZq+gwvRkV9y2kXNFBlPEcZasCAwEA
AaNgMF4wHQYDVR0OBBYEFFItD8P8VeKOiRbgLBAIROtUHTOnMB8GA1UdIwQYMBaA
FI3qUMbfoAWLeyNOiULqI+o1FAmMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
AgeAMA0GCSqGSIb3DQEBBQUAA4IBAQAnVKze/bSM5Azr5Ig/QfpLTEMSiZJ/A8cM
99EnThay2ZuF+1hUA3JMldI7pgOqCtuTp7BOI1UsMs+KdtJh1eMx+HQ632gf3Hv8
9k5Q1cONV/mxZywwfBItFf1i49Tj0NXZZKiSyoiUoDaiWMHdpXTdWSu05lpx8rDJ
tcQrrxRFSc3togqvs1+PW+F10s3x0uv5ocHLZ889vx6P8gVleKKP/O8vGOBc44AO
SS/oBHDwY8Q+1blG3tCbSgVpZ1SF6njnMff4fO+LGS8W5aCcHaqne+CeqH+b/GxZ
NUr9Xwh/OjDE8/REGkOwxywvMJEhI9aLxgW7a6yjcMG7HH94pZ4f
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEAjCCAuqgAwIBAgIJALOPTrQGpetzMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEpMCcGA1UE
AwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDEwHhcNMTgwNDI2MTYz
NTU0WhcNMjgwNDIzMTYzNTU0WjCBkTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
bGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwKQXBwbGUgSW5j
LjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJUTFMgUGx1Z2lu
IFRlc3QgSW50ZXJtZWRpYXRlIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCrmd2lnZGJt04Zn7ToQBf4zaBNe87YlMGc7gkA9P1fT3QBuT9K5x21
P3SZQJj9KQ8LQwLYTUTPaJDPQ+rgZrFU9e8lTrKtjD4uPafzSDXLBDz4sDrj26hd
jh7ldMh0qMb+pvzMI+/R1oULQH0+45oweFeEfdrXeMOgITJXtNd4lPB6ezkkIE++
xbeao2bnTfFVwCsSDuk67tEPce2CKt0jI1/8nLcs4qd3uM0bRWyPd+i6rDQckW/3
rapPqCiGZoYLwMMVKfZMtLRftx8JQsvK+7vwU+SgOSI9Of8KYkz1nykKEUA0U2Pk
8MxOQ2SFC23ChcZMNaTWxfUQT0Enab4xAgMBAAGjYzBhMB0GA1UdDgQWBBSN6lDG
36AFi3sjTolC6iPqNRQJjDAfBgNVHSMEGDAWgBQIWQAHRYgGMY/ziEvCGaoqIFvJ
eDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUF
AAOCAQEAMHVjMu0aJnfmj44CLsdBVzJSFSg2ibvyRLbIEL22i5HnfAnl4uCW5ms9
/pYIaOqw0r5av2WfeKBzarGfBC0vnMGUog7rjv6CFDT52o/w5w9ScNAE2m85Ibt4
q9rlFSh2zOYUCfG5F+7cGHHYrWNvQ4X8p2qziUHZEl3i9hCr9edt+XnVj6Oelb9q
3zDdqOwSklJ4DzcauZORv/FwRggqZlp6upuIdVC5lIygd92k6RugQOwrWhLlaAi+
OC6Sw45W0RG0K4WqLBrErmqH3OmV8O1xNIAFjADR70AgKYAO9mOobTRx+iD/me5R
0t0M0NLKAVEGiOTvznu/yxnNkDTpsQ==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDurWIKDAnb1PUE
E+eerUoGgBrZH7tiDGWcaKl6itUKX5oIPj5BvPuQ83/hMXY0FFEkvHz3/ADBcf2S
ADGXjRDpx2Dyx6fIlmyA2MqKqiNPPVkOcmeZcqai73Yk7fR34Gi/qyO3yDzZXBos
HQzauCPa+67Rr0qGNmWo4EeYVTHrLAIVRIG/2oVF5Zxdqqbs2kiiTKSVPngqVjut
vZzZwwlmyaYpwQecaoVy3X/nJR6ncFrRkFXVk8RTi4MtygMPeOxWNeYcIWbz0gAt
c1f24GinYeU59oVwhuJi0FI/7yF9I9vOc5dAdYvtbZMPtrGlGavoML0ZFfctpFzR
QZTxHGWrAgMBAAECggEAKgnBxdE+/0gv64rx9cHB0wlHMUzkfS1/zB+nEh1Xzp7u
C1ujLYLysCIjOO+0SRH3BMhqHmd1Xp0MM2XzViUTgImMatZ9l9fevobwjaHP3EoK
4H+H/b/y16njnjeHIoIVEQU8okcTaJlPRsvLEs7yCcTgkrAUKTV1jFwMYClJRIlB
tH3IwlTc4X4ISLs8jU5TbDwbX/vsfOL9dbhnI0pRJYbjx0A6bPeIwPcBv9MrJ0zC
J08v6CtBtfhg/rr0Il3Shhr+he74R6r9C82095XtdPgV2RdXrwD3VZfJ1N+VE2g4
xdIQI4TybL7olsduwDz4EDcAkLLQNuMQIJrvmYtDMQKBgQD5dp7whs70bagEIhNc
sviVpOzbwzpB4jjOaJuS+SpTYy6xiZ1GSXokjAlGnx27YJx2F0XsGNbD8YEJplrW
pl6xxxJJ76ClpLMJ4dOaUZICaOUJlvFs/a/eq1DPzm/8de8VnJPxV8NHURGoItjD
Cp5J5Hfs09pAoGed41OU4H1VaQKBgQD07mjzDBOiRMgIyoQqkO7KSUy4VxPWRw/e
UURwkWlDPyb69x8VMlaaVNvtA+C7bHGGNCxQEcl9hy/eFNeLvxZZnB+3CG5BBIfT
ZFXwDLlt4Cck7lT8RmGCHmD7uEeLsKlFXLmdIsGdy4vb5UJoluU1lonYdfMmF1r5
Wn1D5Yhb8wKBgQDxyxnvBJtfq1Go/+ZIeWgck4jI0YeMCFsLJbV1VXDC9mVxy3LX
h6yN8/Whr+Q/lDrS82fgmYrAzTpHQijV2Nf79Hozk8HgC61FrM9OyjV9hHJLQzSq
cZGff+mKIgvFZgHgrq1uxaQPYfJ9R5lWItqdwIbE0+q9rTwBey+uI5EX0QKBgCQA
WxrGfqhOVdy877pV/VNsfMNnwTmwzktORLILHZ7NzIv9AOubr5EVwhHPjRvfb7xb
NNw8ERLLaSTKiXg4CS/4u8yqh5I0+UYALIWRSTw2Q2qxQXqnWbPHhVfamWGWAPt6
CqpnLnBkN9WFmEJJU72RuAdCJxBFRJD8VQdC2M0zAoGBAOpbXf1MPtwQIOrBsKiw
pvlRzVKuW4fo8LNqkk/m5f+hR7kptfc2uDU1HiyOjsrsh1AnYD+sg3bH1XGs5Ai7
y5+C0hQHQln+HWpe/5Pw6IPRsgTHRRkKYtS13QyDGHybU+Pq8ZnY20POOBZyMLqo
jKg/enqxtKZ6M+U4HcjKbewH
-----END PRIVATE KEY-----

75
FDBLibTLS/testdata/test-server-3.pem vendored Normal file
View File

@ -0,0 +1,75 @@
subject=
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 1
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 1
-----BEGIN CERTIFICATE-----
MIIDCDCCAfACAxAAATANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMCVVMxEzAR
BgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwK
QXBwbGUgSW5jLjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJU
TFMgUGx1Z2luIFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwHhcNMTcwMTAxMDAwMDAw
WhcNMTcxMjMxMDAwMDAwWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAqMXM+ZMsh7LrUrGS1Kw6z4eTccaITGxJ2bdPpPrerwQG/2lj5N9kl/YUAUwY
d/iCmc2ZiZ0xf12R39yDiZrzn+QSArmgKpXRoGStleTRw3Zr5KMO9PhCrDrNTP05
a95y6Pi+GFn/xG74P7dg9JVcmKZ5DS9LKheLzR8wbYNQ28BEq4ljVJ5FCXrSqO1v
tQZ/dK8ThZw64ODFhKNFTTspk6VAecnIG6ABU3E9EZ038423q6OZERBXlHU93Y8F
IGlzaD4zKEGhzbmAdG1+Z9xq6DcuQkrIUzUgHVljIpMGCXzNe7tkXYw29lAapiIK
bcH9GBM6hg3p18SZBsUmYkslhwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBohEcs
wqGHDfn756yZTwX8415Xm4qC9MqcA50I4JGk9KqeUxLCytultTvNIkFMm12TyqAK
lMFK/GFvwJwlz+dBrsraaosw2HVZs9e/kHJA70R/iNwhXb0RUIJrBxzE4M9gQ4I5
I9DBo8hoaaPU2awHE2Y694qW4dEdFXz2637Afnb/euJ2zm3nhrV05pKu/Wer9cjF
W8Opx2AjgB+/ixftVQuGr3fys0tvhpZlC7MYnFvKFlh6QFvFCSa9M5ESHrnuRg2g
sqDTqdWab1drQvWZyiIBATErMlgQxsAQMT8YH4U4qbGcicYh8Zw4ZIRyHZndMHIU
wgO+WZp3DVHg6Y81
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEAjCCAuqgAwIBAgIJALOPTrQGpetyMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEpMCcGA1UE
AwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDEwHhcNMTgwNDI2MTYz
NTU0WhcNMjgwNDIzMTYzNTU0WjCBkTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
bGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwKQXBwbGUgSW5j
LjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJUTFMgUGx1Z2lu
IFRlc3QgSW50ZXJtZWRpYXRlIENBIDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCqE74CmPzqGMCmWWTrCDBOShmiOcu266V0+upPBn3aEo3ZUevdRDIZ
R5waXh8sVmxoUfQdwxOBZPZFSLULPU9vQDny2DsbYfJ1MLNzEH9W5gHc5YzpvtuE
6cZvaCb8PLGcGOesACwJ2tpc+lI9ZxfB/vIO/ZUcg0mHfhcaE1bHRVrj0yZTkPe/
yhQWWQshS6locyn+LbvayB72uaC4OeCbucGOH6B4SU1pBpG8OPMD3ktES8nIjDdj
RnuiPestjt7VIB6u37CsTSupK9Gxgyi7U9JI7kwCnRinZmHygDzLzlQ8Awksg/Qb
NuSfV0OcNG3O/Xal4OWhS1AMpayPMxXFAgMBAAGjYzBhMB0GA1UdDgQWBBROZFq0
Agcx7u6huYDHWps2dJR6UjAfBgNVHSMEGDAWgBQIWQAHRYgGMY/ziEvCGaoqIFvJ
eDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUF
AAOCAQEApoV9izIHMB4418NP8FTdsToMwemxIs/ASoURGPnXnDG3EG9R8E8h64bg
38fddyaOR4AkWyn1DELzlp2vdlA4v8xY5Fu4au5MSvpxzf8H2ia3QUP/xEGj70Vg
6BJhRWQ/iOALVLVsTvJmhXQBlhIsFZMi0eIcr8CqpZ6x80SuLgl67omBvqpoVNuA
Y0FKgva+bNcEDhPur7LYAiTT+0ykgKFMR2/KnPDJOh12lYMw2ILQIQXuYCJJOXNy
nXDXa7l8vxywxMtdk5jqAB8Jct+9gV69F5uW+VuP9CEfHXpOZmDsxbFzsQbU+5mD
xj4rdSXEuk8h9bOBuqUBR9opl7jw9Q==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCoxcz5kyyHsutS
sZLUrDrPh5NxxohMbEnZt0+k+t6vBAb/aWPk32SX9hQBTBh3+IKZzZmJnTF/XZHf
3IOJmvOf5BICuaAqldGgZK2V5NHDdmvkow70+EKsOs1M/Tlr3nLo+L4YWf/Ebvg/
t2D0lVyYpnkNL0sqF4vNHzBtg1DbwESriWNUnkUJetKo7W+1Bn90rxOFnDrg4MWE
o0VNOymTpUB5ycgboAFTcT0RnTfzjbero5kREFeUdT3djwUgaXNoPjMoQaHNuYB0
bX5n3GroNy5CSshTNSAdWWMikwYJfM17u2RdjDb2UBqmIgptwf0YEzqGDenXxJkG
xSZiSyWHAgMBAAECggEBAJi3/EXuVkIoteZrRulpPAJktRgkRVuaNa1rwgcQ94Y5
R7fA/yKwvs7/XpTZ7d5JoqxYLlInSw3sdr6yRNi0vTV25JFQtU0zqq/Pyn+zwdh0
hScsIbGsIHDG+NVs4pPog+SqiSFx9w4iOEM3xeUsbtC2+xziKcrZ6ahgS6sdQ4LE
3Wh6MfQTg36GWIhM4FgMiDVWOVV5lXjeRYtNWygfcr7dSDR4LTkUYFXOw/Y2r7gj
U/iWKGXv0VCb5fuzuDSyri2yfOFk73MxknSGseVF9ovUdxZVPaXGhKUt1687yB0o
k5vs6h1bHfutr/YyY8onp1k9teVMFdK1PTbwCKGcCokCgYEA0oF/pCd/5HPDbG6U
a1Yyl9pTWR/+BD7jy0cI39FM6hvNvGuoSaIJNjq1wlTA+HYPKD7WXdnInKQIZhhW
beNP3K+6lbMWa3vu3OlghlwbCymVH43mtWShsoJAACSsH+cjSJUKqxGRbebG2lJb
WFkCxPuGkOeMi3cY1mB+m6Aadz0CgYEAzT9cS5wSW1gTyrZAX7kgnQWdxttIIc53
JnJXkNt9Re3WZ/d958hTO8GKeL5TRGUWP5B3depiRNedkqNq2Pb03/H7IdeIUnx0
XDYy34Aq4LFuoss3gMBpQntxHi1ZsK8Dr0OhCmiXKRbOnG+DtRZnFtnWUMHsxT1T
GP97P3QKPBMCgYAt+GnPh3C+iylaPKvc5O4Xi244QGxQsQs+ET0245ZQadH8G+ac
be5lEV0wGyIpIF8fAtn9lNnim0/aO+ZkCQgfwaCVoI582ovHYo/Zx7OANIyEX5DK
fDdzrE4dueR88xUZfLLfuO5xebxjYSjhmk6oheVVL7vZmSCrcFc11TjyYQKBgEEj
TahVVOIWdtmLs6xtdXM/+A3HRAIuo1PZT/8SGZTa4YPHYPbxdbDuQIMHbCe1qTTt
JWyPwTY187U5Fczbu2VjR5865vG+u7MUJFsYMwNybDlQI0JCTmWiBYldPSy8rn+u
B+rkvKx2p4WwQm1zOa5f3gttMDZ8uuWhFz1RF3pvAoGBALEhLdvVbUVjWJzjQOep
hKdWXuo8hWd29XaxYrZkz0BatOxcPVK4PnaTH+dt31vhiE1EpYBFxb6ZsHu+g6NT
x1tsPWY+weGDpIdkvaQt9zrqLh7QaHpvu+S/2tV7DKpx9Qu+NlUsD/Vi12LnRxPU
0Kbv5wbAtjOuAoYMgcb19P1e
-----END PRIVATE KEY-----

82
FDBLibTLS/testdata/test-server-4.pem vendored Normal file
View File

@ -0,0 +1,82 @@
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Server 4
issuer= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 3
subject= C = US, ST = California, L = Cupertino, O = Apple Inc., OU = FDB Team, CN = FDB LibTLS Plugin Test Intermediate CA 3
issuer= C = AU, ST = New South Wales, L = Sydney, O = Apple Pty Limited, OU = FDB Team, CN = FDB LibTLS Plugin Test Root CA 2
-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIJALOPTrQGpet3MA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5v
MRMwEQYDVQQKDApBcHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTExMC8GA1UE
AwwoRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMzAeFw0x
ODA0MjYxNjM1NTVaFw0yODA0MjMxNjM1NTVaMIGIMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ3VwZXJ0aW5vMRMwEQYDVQQKDApB
cHBsZSBJbmMuMREwDwYDVQQLDAhGREIgVGVhbTEoMCYGA1UEAwwfRkRCIExpYlRM
UyBQbHVnaW4gVGVzdCBTZXJ2ZXIgNDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBANkcEPk77yl3JC11UYMR4IWtK4GZpZQ3QOMAD5UHM/naEOQ+tOcbU+C9
WV+1AnPdmjdMgTuoPg4enJHJKqL/RcBdBfidOmlvgkXJsK22VAGX2vc2kl3KbM2O
8wdW0Wg1+1X6PsLl1agVuqA35BTtKliFGq2kWn/GD7g6Cr5cCcGCBh9SJo2WsCJB
S1NDeq/p0yST4C60pLpLC+nWerzclgZhtWE2rTQyPieAzMbK6BLI80fkyPnUjFLM
q8PZaZUHE3Vfb1GR5cQ2Xo9X433g68BzmPEkwrXi7Kz0clGQkihorlZcwKcBJtmw
sQr4Cj5THn939NDJLjrTTeBLsC1vhk0CAwEAAaNgMF4wHQYDVR0OBBYEFJEzltQT
5y5gQwKRibK7NAjfvJcfMB8GA1UdIwQYMBaAFNJkFNeVtJApFs//7Jvd5R/+BJ0Z
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBBQUAA4IB
AQCD1/J06qb2mCcU2+nHKnSfuEg0lqyFiPm/MW+Mti0tqU49QtGzPTqECYIPgGgI
RbiWU/+lvTwShF6TnSynnvFAXpiqzogxgTD5AZAFaatDj07TZpeL3+15JZQRAA1c
JTGSiYbmEBR6H71aXVgUuIbiYp14Q63RX3OcOD65Yycn3jKOfUrHgfPn84+HDusW
2BscBu5fWmH0iNUxblVIihS5XRGoKnjcYAfBSuZ6T/0EOVEITV11Zd8cum97C9xO
a+ZJlwIPd8pM310DsulBC7EaQJNmlEaGrYHsBfjUZe93BsPfA/SK2iBDotuiSfoA
ZQslO1EMS1zORQb3LXDFZBuJ
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIECzCCAvOgAwIBAgIJALOPTrQGpet0MA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD
VQQGEwJBVTEYMBYGA1UECAwPTmV3IFNvdXRoIFdhbGVzMQ8wDQYDVQQHDAZTeWRu
ZXkxGjAYBgNVBAoMEUFwcGxlIFB0eSBMaW1pdGVkMREwDwYDVQQLDAhGREIgVGVh
bTEpMCcGA1UEAwwgRkRCIExpYlRMUyBQbHVnaW4gVGVzdCBSb290IENBIDIwHhcN
MTgwNDI2MTYzNTU0WhcNMjgwNDIzMTYzNTU0WjCBkTELMAkGA1UEBhMCVVMxEzAR
BgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUN1cGVydGlubzETMBEGA1UECgwK
QXBwbGUgSW5jLjERMA8GA1UECwwIRkRCIFRlYW0xMTAvBgNVBAMMKEZEQiBMaWJU
TFMgUGx1Z2luIFRlc3QgSW50ZXJtZWRpYXRlIENBIDMwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCZ3UPCarKiS+IqK2VvB0lVQ3L0TPuNUov54L7ELFnB
1lijZWX2wX3Vi0uAyvwmLi+PYkUkzhaNhGWbVPHEFqsOzwMbifGLfdxjetZD0kOr
ZuARithrDXVWZegIXEFDUdnpz74TKG6rCQ6o4WMIFUV/j9770iMtrMABr/BwASrE
sVqAqNe4bOqHJyxyeTxF/vCRme3PVf+u06mM9OLxVVaPRK+tiysdKprjs6oyFoxT
S/Cl+vv7Lnt5Yth0F7YJGMrIKDPuSWCqAfKWAc+b73XPQ14coIczVzQAikyRFmGa
9aaw0aWYI2gjTkuah0c5fboZAuHT0Z7nQVtYUyIYRY8BAgMBAAGjYzBhMB0GA1Ud
DgQWBBTSZBTXlbSQKRbP/+yb3eUf/gSdGTAfBgNVHSMEGDAWgBT8PGmqenESXKJl
kdMkGY7ttNqMZzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkq
hkiG9w0BAQUFAAOCAQEAdoyvb/2+r587RMar6+/OauAVXWwnNEI8hhUvxiTnDq/M
TKu+okSAHSbGvYp5yGD2IXlEZHjtKnMapsih7tvm2VboM7U5Zi3aK7hjvk6Kxs5B
eynHP9dDnUWG/qRbAF83B3mK7ymmrZvJIDwHZEtY9Gmmmb9ty9aK2ywmYtlYgIS8
FSh/qwzvThIiMuCQma9JJOx6ZDXV2YwCxYtIRAuTvIWuOckb608fPi812k0zYILG
q4VLhZTc2AM8H/629RBRV5zC/tqySLb3VgpWQ2vZSzUwuKIdIPs4lsbNqmsdWIyR
hHnl8610t/JAUdCPHDd1bBlYNgLhMKJTM8fGu9Ux/Q==
-----END CERTIFICATE-----
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIx3nCjm2zsV8CAggA
MB0GCWCGSAFlAwQBAgQQK7Wa4+IkQwAbbEqowS8e8QSCBNAiqELNOXJ1yLnkuHku
+qMycK8XJQ/zqyQ2dikHzHX3i90OwHSdZp13i1uHe7nguq8Tz6NQqnEtcLevECz3
EnEcAZK5Ipmonqn6QWZn6Lglh9mOv0Ykfdpiz2CKkJDwVzoWDPb/fOea0zlPNZAj
w8A+xsGA0Z2NkuBUpYFQgR6WtBKqndi0p6MRWG6aH21p3WCQ37jb0pzQTo3Ki53P
pq84JaphfSvj/DO7Cy0CfWHroAoODCxmjV8oPiddyLqk/Q3kv/nwHIqIKZN5s0OY
wSqkKJO4PkUqPPIa4QatKj7T6uZujRCEZIJPWfW/b9Om9CXdUpsvXEaZu41kAawC
jYyOqQ9CfCSC481R/LGtLOY/7vBiwUTRRLsrGeZkbmWMrK3spbsZqgTI5sl7Ya1C
tDOF7SUqauIdLLhK86jHwjLzebqv/qZ4W/zoOSFNlvsQCF4qRjLMlgA2JzOHtmAW
bYotgN+aOhQmxnrBJVBJChFE1vmsr+hpctJ0U62qtfD29yLO3q4xqbkg239lQEH1
LtygB2mMJPtL3u+8K2ZNo2cZlNJFeDzNyPhB9+gT5Iil7OW897e9LJl5O/gCbgcS
IgDGY6vgLf64v5MjAbCTSmfX05biP9y1vgXqXT3YtXFqgCjsMZAKVibyXtq9DWUc
b6g1qX+RPBIGxHwCDQPoP/rdQF5WSWN/V6BYr2An9jLL2jRwQuvIG0hw8dtJWr45
yGXP8A9QD6tL6rY9Bwzd0QjoH9HuQj9DwM6MRx0o2GG8lYJ5l70ZCHrHEO/3mKV0
RvZBVCYm2wNRnrcmcfjdncMt2AF24Mk4CFcUgOUj8reK+Pg1+o5uThQwsPY7ttwq
rrm8/0Z9MIjPR/lKKunJU+SapULakhIsiSxuLP8R/G//wfjdZPO8T3AMlsyFglA+
Tdq6b+ji2itL0foiUnaoJUVlH2aO6GteHxj8H4hfeF0IReYzfEiVjcew29sxY+MW
inLp0fcnAQqfk0rsA8agOIq/b/5PMpDvC1XM4MuRW7iLCydUTVENYYWNhIHffOy8
fIQBTtqsHIEcytehZ6BjNIwr4JsdmcmUWiWveYIqdEv9ayIzuFQh5ZzAD/YemlXh
tCkKjoda+GKSdO5yUlZLRhkbmz/VSYXOLCYOo2nO0zNqyL/kMqQPjMNh6dxIKKTN
XXQjPUHDAjHWlBeXntM/Xqgl35QmzWb3gQU1xMEYqBDHkkc+lnhO/oSWBHaX43ov
+qnvcUaFGlDQexvFVO5AWujv4+Cx9eTukWjjMSKQ3RFsj8akPoKkl0Y+jONI4nR/
WeSVSz7OFAT16Td8peVPnPCuz1bprmtBLJPSXTNgZNqDeudD9HnV2K0Rrg1D9rwy
NJyOERnw+9goVVqTcOTKON4FqqZM//aS2yrgnxLMjVb4bb69xgtBUjpoWHho9D1b
Aa88mrm8NsCIO8OxLrH9ZX4+CRpJa/SEmxPDQd/Z5qV1uMr7uRI3AlRkpqc3Ui8e
9qobzTd/VnIVMQK8JTW01/hwoK1mccEJPyF7phs22LpXZqKSU2oJ84NzfCLBvfyt
mipPVbuRblbmgRQiF0UhAzJO2JzeMbgY4M/zSXuet+YHYt0y1FrEUFh8dc9TXY8n
Rfsap1higlUefD6p/qj/E8KfVw==
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -22,7 +22,9 @@
#include <string>
#include <vector>
#include <openssl/obj_mac.h>
#include <string.h>
#include <openssl/objects.h>
#include "ITLSPlugin.h"
#include "ReferenceCounted.h"
@ -32,10 +34,10 @@
struct FDBLibTLSVerifyTest {
FDBLibTLSVerifyTest(std::string input):
input(input), valid(false), verify_cert(true), verify_time(true), subject_criteria({}), issuer_criteria({}) {};
FDBLibTLSVerifyTest(std::string input, bool verify_cert, bool verify_time, std::map<int, std::string> subject, std::map<int, std::string> issuer):
input(input), valid(true), verify_cert(verify_cert), verify_time(verify_time), subject_criteria(subject), issuer_criteria(issuer) {};
~FDBLibTLSVerifyTest() {};
input(input), valid(false), verify_cert(true), verify_time(true), subject_criteria({}), issuer_criteria({}), root_criteria({}) {};
FDBLibTLSVerifyTest(std::string input, bool verify_cert, bool verify_time, std::map<int, std::string> subject, std::map<int, std::string> issuer, std::map<int, std::string> root):
input(input), valid(true), verify_cert(verify_cert), verify_time(verify_time), subject_criteria(subject), issuer_criteria(issuer), root_criteria(root) {};
~FDBLibTLSVerifyTest() {};
int run();
@ -47,6 +49,7 @@ struct FDBLibTLSVerifyTest {
std::map<int, std::string> subject_criteria;
std::map<int, std::string> issuer_criteria;
std::map<int, std::string> root_criteria;
};
static std::string printable( std::string const& val ) {
@ -80,34 +83,95 @@ static void logf(const char* event, void* uid, int is_error, ...) {
}
int FDBLibTLSVerifyTest::run() {
FDBLibTLSPlugin *plugin = new FDBLibTLSPlugin();
FDBLibTLSPolicy *policy = new FDBLibTLSPolicy(Reference<FDBLibTLSPlugin>::addRef(plugin), (ITLSLogFunc)logf);
bool rc = policy->set_verify_peers((const uint8_t *)input.c_str(), input.size());
if (rc != valid) {
Reference<FDBLibTLSVerify> verify;
try {
verify = Reference<FDBLibTLSVerify>(new FDBLibTLSVerify(input));
} catch ( const std::runtime_error& e ) {
if (valid) {
std::cerr << "FAIL: Verify test failed, but should have succeeded - '" << input << "'\n";
return 1;
} else {
std::cerr << "FAIL: Verify test should have failed, but succeeded - '" << input << "'\n";
}
return 0;
}
if (!valid) {
std::cerr << "FAIL: Verify test should have failed, but succeeded - '" << input << "'\n";
return 1;
}
if (verify->verify_cert != verify_cert) {
std::cerr << "FAIL: Got verify cert " << verify->verify_cert << ", want " << verify_cert << "\n";
return 1;
}
if (verify->verify_time != verify_time) {
std::cerr << "FAIL: Got verify time " << verify->verify_time << ", want " << verify_time << "\n";
return 1;
}
if (verify->subject_criteria != subject_criteria) {
std::cerr << "FAIL: Got subject criteria " << criteriaToString(verify->subject_criteria) << ", want " << criteriaToString(subject_criteria) << "\n";
return 1;
}
if (verify->issuer_criteria != issuer_criteria) {
std::cerr << "FAIL: Got issuer criteria " << criteriaToString(verify->issuer_criteria) << ", want " << criteriaToString(issuer_criteria) << "\n";
return 1;
}
if (verify->root_criteria != root_criteria) {
std::cerr << "FAIL: Got root criteria " << criteriaToString(verify->root_criteria) << ", want " << criteriaToString(root_criteria) << "\n";
return 1;
}
return 0;
}
static int policy_verify_test() {
Reference<FDBLibTLSPlugin> plugin = Reference<FDBLibTLSPlugin>(new FDBLibTLSPlugin());
Reference<FDBLibTLSPolicy> policy = Reference<FDBLibTLSPolicy>(new FDBLibTLSPolicy(plugin, (ITLSLogFunc)logf));
const char *verify_peers[] = {
"S.CN=abc",
"I.CN=def",
"R.CN=xyz,Check.Unexpired=0",
};
int verify_peers_len[] = {
(int)strlen(verify_peers[0]),
(int)strlen(verify_peers[1]),
(int)strlen(verify_peers[2]),
};
Reference<FDBLibTLSVerify> verify_rules[] = {
Reference<FDBLibTLSVerify>(new FDBLibTLSVerify(std::string(verify_peers[0], verify_peers_len[0]))),
Reference<FDBLibTLSVerify>(new FDBLibTLSVerify(std::string(verify_peers[1], verify_peers_len[1]))),
Reference<FDBLibTLSVerify>(new FDBLibTLSVerify(std::string(verify_peers[2], verify_peers_len[2]))),
};
if (!policy->set_verify_peers(3, (const uint8_t **)verify_peers, verify_peers_len)) {
std::cerr << "FAIL: Policy verify test failed, but should have succeeded\n";
return 1;
}
if (policy->verify_rules.size() != 3) {
std::cerr << "FAIL: Got " << policy->verify_rules.size() << " verify rule, want 3\n";
return 1;
}
int i = 0;
for (auto &verify_rule: policy->verify_rules) {
if (verify_rule->verify_cert != verify_rules[i]->verify_cert) {
std::cerr << "FAIL: Got verify cert " << verify_rule->verify_cert << ", want " << verify_rules[i]->verify_cert << "\n";
return 1;
}
}
if (policy->verify_cert != verify_cert) {
std::cerr << "FAIL: Got verify cert " << policy->verify_cert << ", want " << verify_cert << "\n";
return 1;
}
if (policy->verify_time != verify_time) {
std::cerr << "FAIL: Got verify time " << policy->verify_time << ", want " << verify_time << "\n";
return 1;
}
if (policy->subject_criteria != subject_criteria) {
std::cerr << "FAIL: Got subject criteria " << criteriaToString(policy->subject_criteria) << ", want " << criteriaToString(subject_criteria) << "\n";
return 1;
}
if (policy->issuer_criteria != issuer_criteria) {
std::cerr << "FAIL: Got issuer criteria " << criteriaToString(policy->issuer_criteria) << ", want " << criteriaToString(issuer_criteria) << "\n";
return 1;
if (verify_rule->verify_time != verify_rules[i]->verify_time) {
std::cerr << "FAIL: Got verify time " << verify_rule->verify_time << ", want " << verify_rules[i]->verify_time << "\n";
return 1;
}
if (verify_rule->subject_criteria != verify_rules[i]->subject_criteria) {
std::cerr << "FAIL: Got subject criteria " << criteriaToString(verify_rule->subject_criteria) << ", want " << criteriaToString(verify_rules[i]->subject_criteria) << "\n";
return 1;
}
if (verify_rule->issuer_criteria != verify_rules[i]->issuer_criteria) {
std::cerr << "FAIL: Got issuer criteria " << criteriaToString(verify_rule->issuer_criteria) << ", want " << criteriaToString(verify_rules[i]->issuer_criteria) << "\n";
return 1;
}
if (verify_rule->root_criteria != verify_rules[i]->root_criteria) {
std::cerr << "FAIL: Got root criteria " << criteriaToString(verify_rule->root_criteria) << ", want " << criteriaToString(verify_rules[i]->root_criteria) << "\n";
return 1;
}
i++;
}
return 0;
}
@ -117,27 +181,33 @@ int main(int argc, char **argv)
int failed = 0;
std::vector<FDBLibTLSVerifyTest> tests = {
FDBLibTLSVerifyTest("", true, true, {}, {}),
FDBLibTLSVerifyTest("Check.Valid=1", true, true, {}, {}),
FDBLibTLSVerifyTest("Check.Valid=0", false, true, {}, {}),
FDBLibTLSVerifyTest("Check.Unexpired=1", true, true, {}, {}),
FDBLibTLSVerifyTest("Check.Unexpired=0", true, false, {}, {}),
FDBLibTLSVerifyTest("Check.Valid=1,Check.Unexpired=0", true, false, {}, {}),
FDBLibTLSVerifyTest("Check.Unexpired=0,Check.Valid=0", false, false, {}, {}),
FDBLibTLSVerifyTest("", true, true, {}, {}, {}),
FDBLibTLSVerifyTest("Check.Valid=1", true, true, {}, {}, {}),
FDBLibTLSVerifyTest("Check.Valid=0", false, true, {}, {}, {}),
FDBLibTLSVerifyTest("Check.Unexpired=1", true, true, {}, {}, {}),
FDBLibTLSVerifyTest("Check.Unexpired=0", true, false, {}, {}, {}),
FDBLibTLSVerifyTest("Check.Valid=1,Check.Unexpired=0", true, false, {}, {}, {}),
FDBLibTLSVerifyTest("Check.Unexpired=0,Check.Valid=0", false, false, {}, {}, {}),
FDBLibTLSVerifyTest("Check.Unexpired=0,I.C=US,C=US,S.O=XYZCorp\\, LLC", true, false,
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp, LLC"}}, {{NID_countryName, "US"}}),
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp, LLC"}}, {{NID_countryName, "US"}}, {}),
FDBLibTLSVerifyTest("Check.Unexpired=0,I.C=US,C=US,S.O=XYZCorp\\= LLC", true, false,
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp= LLC"}}, {{NID_countryName, "US"}}),
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp= LLC"}}, {{NID_countryName, "US"}}, {}),
FDBLibTLSVerifyTest("Check.Unexpired=0,R.C=US,C=US,S.O=XYZCorp\\= LLC", true, false,
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp= LLC"}}, {}, {{NID_countryName, "US"}}),
FDBLibTLSVerifyTest("Check.Unexpired=0,I.C=US,C=US,S.O=XYZCorp=LLC", true, false,
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp=LLC"}}, {{NID_countryName, "US"}}),
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp=LLC"}}, {{NID_countryName, "US"}}, {}),
FDBLibTLSVerifyTest("I.C=US,C=US,Check.Unexpired=0,S.O=XYZCorp=LLC", true, false,
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp=LLC"}}, {{NID_countryName, "US"}}),
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp=LLC"}}, {{NID_countryName, "US"}}, {}),
FDBLibTLSVerifyTest("I.C=US,C=US,S.O=XYZCorp\\, LLC", true, true,
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp, LLC"}}, {{NID_countryName, "US"}}),
FDBLibTLSVerifyTest("C=\\,S=abc", true, true, {{NID_countryName, ",S=abc"}}, {}),
FDBLibTLSVerifyTest("CN=\\61\\62\\63", true, true, {{NID_commonName, "abc"}}, {}),
FDBLibTLSVerifyTest("CN=a\\62c", true, true, {{NID_commonName, "abc"}}, {}),
FDBLibTLSVerifyTest("CN=a\\01c", true, true, {{NID_commonName, "a\001c"}}, {}),
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp, LLC"}}, {{NID_countryName, "US"}}, {}),
FDBLibTLSVerifyTest("I.C=US,C=US,S.O=XYZCorp\\, LLC,R.CN=abc", true, true,
{{NID_countryName, "US"}, {NID_organizationName, "XYZCorp, LLC"}},
{{NID_countryName, "US"}},
{{NID_commonName, "abc"}}),
FDBLibTLSVerifyTest("C=\\,S=abc", true, true, {{NID_countryName, ",S=abc"}}, {}, {}),
FDBLibTLSVerifyTest("CN=\\61\\62\\63", true, true, {{NID_commonName, "abc"}}, {}, {}),
FDBLibTLSVerifyTest("CN=a\\62c", true, true, {{NID_commonName, "abc"}}, {}, {}),
FDBLibTLSVerifyTest("CN=a\\01c", true, true, {{NID_commonName, "a\001c"}}, {}, {}),
// Invalid cases.
FDBLibTLSVerifyTest("Check.Invalid=0"),
@ -153,5 +223,7 @@ int main(int argc, char **argv)
for (auto &test: tests)
failed |= test.run();
failed |= policy_verify_test();
return (failed);
}

View File

@ -20,6 +20,7 @@
import math
import re
import struct
import fdb
@ -80,6 +81,20 @@ class Test(object):
def validate(self, db, args):
return []
def versionstamp_key(self, raw_bytes, version_pos):
if hasattr(self, 'api_version') and self.api_version < 520:
return raw_bytes + struct.pack('<H', version_pos)
else:
return raw_bytes + struct.pack('<L', version_pos)
def versionstamp_value(self, raw_bytes, version_pos=0):
if hasattr(self, 'api_version') and self.api_version < 520:
if version_pos != 0:
raise ValueError("unable to set non-zero version position before 520 in values")
return raw_bytes
else:
return raw_bytes + struct.pack('<L', version_pos)
@classmethod
def create_test(cls, name, subspace):
target = 'bindingtester.tests.%s' % name

View File

@ -40,6 +40,7 @@ class ApiTest(Test):
self.stack_subspace = self.subspace['stack']
self.versionstamped_values = self.scratch['versionstamped_values']
self.versionstamped_values_2 = self.scratch['versionstamped_values_2']
self.versionstamped_keys = self.scratch['versionstamped_keys']
def setup(self, args):
@ -56,6 +57,7 @@ class ApiTest(Test):
self.generated_keys = []
self.outstanding_ops = []
self.random = test_util.RandomGenerator(args.max_int_bits, args.api_version, args.types)
self.api_version = args.api_version
def add_stack_items(self, num):
self.stack_size += num
@ -349,17 +351,30 @@ class ApiTest(Test):
elif op == 'VERSIONSTAMP':
rand_str1 = self.random.random_string(100)
key1 = self.versionstamped_values.pack((rand_str1,))
key2 = self.versionstamped_values_2.pack((rand_str1,))
split = random.randint(0, 70)
rand_str2 = self.random.random_string(20 + split) + fdb.tuple.Versionstamp._UNSET_TR_VERSION + self.random.random_string(70 - split)
key2 = self.versionstamped_keys.pack() + rand_str2
index = key2.find(fdb.tuple.Versionstamp._UNSET_TR_VERSION)
key2 += chr(index % 256) + chr(index / 256)
prefix = self.random.random_string(20 + split)
if prefix.endswith('\xff'):
# Necessary to make sure that the SET_VERSIONSTAMPED_VALUE check
# correctly finds where the version is supposed to fit in.
prefix += '\x00'
suffix = self.random.random_string(70 - split)
rand_str2 = prefix + fdb.tuple.Versionstamp._UNSET_TR_VERSION + suffix
key3 = self.versionstamped_keys.pack() + rand_str2
index = len(self.versionstamped_keys.pack()) + len(prefix)
key3 = self.versionstamp_key(key3, index)
instructions.push_args(u'SET_VERSIONSTAMPED_VALUE', key1, fdb.tuple.Versionstamp._UNSET_TR_VERSION + rand_str2)
instructions.push_args(u'SET_VERSIONSTAMPED_VALUE',
key1,
self.versionstamp_value(fdb.tuple.Versionstamp._UNSET_TR_VERSION + rand_str2))
instructions.append('ATOMIC_OP')
instructions.push_args(u'SET_VERSIONSTAMPED_KEY', key2, rand_str1)
if args.api_version >= 520:
instructions.push_args(u'SET_VERSIONSTAMPED_VALUE', key2, self.versionstamp_value(rand_str2, len(prefix)))
instructions.append('ATOMIC_OP')
instructions.push_args(u'SET_VERSIONSTAMPED_KEY', key3, rand_str1)
instructions.append('ATOMIC_OP')
self.can_use_key_selectors = False
@ -430,16 +445,17 @@ class ApiTest(Test):
elif op == 'TUPLE_PACK_WITH_VERSIONSTAMP':
tup = (self.random.random_string(20),) + self.random.random_tuple(10, incomplete_versionstamps=True)
instructions.push_args(self.versionstamped_keys.pack(), len(tup), *tup)
prefix = self.versionstamped_keys.pack()
instructions.push_args(prefix, len(tup), *tup)
instructions.append(op)
self.add_strings(1)
version_key = self.versionstamped_keys.pack(tup)
first_incomplete = version_key.find(fdb.tuple.Versionstamp._UNSET_TR_VERSION)
versionstamp_param = prefix + fdb.tuple.pack(tup)
first_incomplete = versionstamp_param.find(fdb.tuple.Versionstamp._UNSET_TR_VERSION)
second_incomplete = -1 if first_incomplete < 0 else \
version_key.find(fdb.tuple.Versionstamp._UNSET_TR_VERSION, first_incomplete + len(fdb.tuple.Versionstamp._UNSET_TR_VERSION) + 1)
versionstamp_param.find(fdb.tuple.Versionstamp._UNSET_TR_VERSION, first_incomplete + len(fdb.tuple.Versionstamp._UNSET_TR_VERSION) + 1)
# If there is exactly one incomplete versionstamp, perform the versionstamped key operation.
# If there is exactly one incomplete versionstamp, perform the versionstamp operation.
if first_incomplete >= 0 and second_incomplete < 0:
rand_str = self.random.random_string(100)
@ -448,9 +464,15 @@ class ApiTest(Test):
instructions.push_args(u'SET_VERSIONSTAMPED_KEY')
instructions.append('ATOMIC_OP')
if self.api_version >= 520:
version_value_key_2 = self.versionstamped_values_2.pack((rand_str,))
versionstamped_value = self.versionstamp_value(fdb.tuple.pack(tup), first_incomplete - len(prefix))
instructions.push_args(u'SET_VERSIONSTAMPED_VALUE', version_value_key_2, versionstamped_value)
instructions.append('ATOMIC_OP')
version_value_key = self.versionstamped_values.pack((rand_str,))
instructions.push_args(u'SET_VERSIONSTAMPED_VALUE', version_value_key,
fdb.tuple.Versionstamp._UNSET_TR_VERSION + fdb.tuple.pack(tup))
self.versionstamp_value(fdb.tuple.Versionstamp._UNSET_TR_VERSION + fdb.tuple.pack(tup)))
instructions.append('ATOMIC_OP')
self.can_use_key_selectors = False
@ -510,7 +532,7 @@ class ApiTest(Test):
self.add_strings(1)
else:
assert False
assert False, 'Unknown operation: ' + op
if read_performed and op not in database_reads:
self.outstanding_ops.append((self.stack_size, len(instructions) - 1))
@ -539,13 +561,22 @@ class ApiTest(Test):
incorrect_versionstamps = 0
for k, v in tr.get_range(begin_key, self.versionstamped_values.range().stop, limit=limit):
next_begin = k + '\x00'
tup = fdb.tuple.unpack(k)
key = self.versionstamped_keys.pack() + v[10:].replace(fdb.tuple.Versionstamp._UNSET_TR_VERSION, v[:10], 1)
if tr[key] != tup[-1]:
random_id = self.versionstamped_values.unpack(k)[0]
versioned_value = v[10:].replace(fdb.tuple.Versionstamp._UNSET_TR_VERSION, v[:10], 1)
versioned_key = self.versionstamped_keys.pack() + versioned_value
if tr[versioned_key] != random_id:
util.get_logger().error(' INCORRECT VERSIONSTAMP:')
util.get_logger().error(' %s != %s', repr(tr[key]), repr(tup[-1]))
util.get_logger().error(' %s != %s', repr(tr[versioned_key]), repr(random_id))
incorrect_versionstamps += 1
if self.api_version >= 520:
k2 = self.versionstamped_values_2.pack((random_id,))
if tr[k2] != versioned_value:
util.get_logger().error(' INCORRECT VERSIONSTAMP:')
util.get_logger().error(' %s != %s', repr(tr[k2]), repr(versioned_value))
incorrect_versionstamps += 1
return (next_begin, incorrect_versionstamps)
def validate(self, db, args):

View File

@ -54,6 +54,8 @@ class ScriptedTest(Test):
if args.bisect:
raise Exception('Scripted tests cannot be bisected')
self.api_version = args.api_version
def generate(self, args, thread_number):
self.results = []
@ -272,12 +274,17 @@ class ScriptedTest(Test):
stampKey = 'stampedXXXXXXXXXXsuffix'
stampKeyIndex = stampKey.find('XXXXXXXXXX')
stampKeyStr = chr(stampKeyIndex % 256) + chr(stampKeyIndex / 256)
main_thread.push_args(u'SET_VERSIONSTAMPED_KEY', stampKey + stampKeyStr, 'stampedBar')
main_thread.push_args(u'SET_VERSIONSTAMPED_KEY', self.versionstamp_key(stampKey, stampKeyIndex), 'stampedBar')
main_thread.append('ATOMIC_OP')
main_thread.push_args(u'SET_VERSIONSTAMPED_VALUE', 'stampedValue', 'XXXXXXXXXX')
main_thread.push_args(u'SET_VERSIONSTAMPED_VALUE', 'stampedValue', self.versionstamp_value('XXXXXXXXXX'))
main_thread.append('ATOMIC_OP')
if self.api_version >= 520:
stampValue = 'stampedXXXXXXXXXXsuffix'
stampValueIndex = stampValue.find('XXXXXXXXXX')
main_thread.push_args(u'SET_VERSIONSTAMPED_VALUE', 'stampedValue2', self.versionstamp_value(stampValue, stampValueIndex))
main_thread.append('ATOMIC_OP')
main_thread.push_args('suffix')
main_thread.append('GET_VERSIONSTAMP')
test_util.blocking_commit(main_thread)
@ -296,6 +303,12 @@ class ScriptedTest(Test):
main_thread.append('GET')
self.add_result(main_thread, args, 'stampedBar')
if self.api_version >= 520:
main_thread.push_args('stampedValue2')
main_thread.append('GET')
main_thread.append('GET')
self.add_result(main_thread, args, 'stampedBar')
main_thread.append('GET_VERSIONSTAMP')
test_util.blocking_commit(main_thread)
self.add_result(main_thread, args, 'RESULT_NOT_PRESENT')

View File

@ -42,7 +42,10 @@ int g_api_version = 0;
#define CLUSTER(c) ((ICluster*)c)
#define TXN(t) ((ITransaction*)t)
#define API (MultiVersionApi::api)
/*
* While we could just use the MultiVersionApi instance directly, this #define allows us to swap in any other IClientApi instance (e.g. from ThreadSafeApi)
*/
#define API ((IClientApi*)MultiVersionApi::api)
/* This must be true so that we can return the data pointer of a
Standalone<RangeResultRef> as an array of FDBKeyValue. */

View File

@ -450,12 +450,12 @@ func (t Transaction) Min(key KeyConvertible, param []byte) {
t.atomicOp(key.FDBKey(), param, 13)
}
// SetVersionstampedKey transforms ``key`` using a versionstamp for the transaction. Sets the transformed key in the database to ``param``. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database. The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time versionstamps are compatible with the Tuple layer only in the Java and Python bindings. Note that this implies versionstamped keys may not be used with the Subspace and Directory layers except in those languages.
// SetVersionstampedKey transforms ``key`` using a versionstamp for the transaction. Sets the transformed key in the database to ``param``. The key is transformed by removing the final four bytes from the key and reading those as a little-Endian 32-bit integer to get a position ``pos``. The 10 bytes of the key from ``pos`` to ``pos + 10`` are replaced with the versionstamp of the transaction used. The first byte of the key is position 0. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database (serialized in big-Endian order). The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time, versionstamps are compatible with the Tuple layer only in the Java and Python bindings. Also, note that prior to API version 520, the offset was computed from only the final two bytes rather than the final four bytes.
func (t Transaction) SetVersionstampedKey(key KeyConvertible, param []byte) {
t.atomicOp(key.FDBKey(), param, 14)
}
// SetVersionstampedValue transforms ``param`` using a versionstamp for the transaction. Sets ``key`` in the database to the transformed parameter. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database. The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time versionstamped values are not compatible with the Tuple layer.
// SetVersionstampedValue transforms ``param`` using a versionstamp for the transaction. Sets the ``key`` given to the transformed ``param``. The parameter is transformed by removing the final four bytes from ``param`` and reading those as a little-Endian 32-bit integer to get a position ``pos``. The 10 bytes of the parameter from ``pos`` to ``pos + 10`` are replaced with the versionstamp of the transaction used. The first byte of the parameter is position 0. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database (serialized in big-Endian order). The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time, versionstamps are compatible with the Tuple layer only in the Java and Python bindings. Also, note that prior to API version 520, the versionstamp was always placed at the beginning of the parameter rather than computing an offset.
func (t Transaction) SetVersionstampedValue(key KeyConvertible, param []byte) {
t.atomicOp(key.FDBKey(), param, 15)
}

View File

@ -33,6 +33,8 @@ import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;
import com.apple.foundationdb.FDB;
class TupleUtil {
private static final byte nil = 0x00;
private static final BigInteger[] size_limits;
@ -569,7 +571,7 @@ class TupleUtil {
}
static byte[] pack(List<Object> items, byte[] prefix) {
List<byte[]> encoded = new ArrayList<byte[]>(2 * items.size() + (prefix == null ? 0 : 1));
List<byte[]> encoded = new ArrayList<>(2 * items.size() + (prefix == null ? 0 : 1));
EncodeResult result = encodeAll(items, prefix, encoded);
if(result.versionPos > 0) {
throw new IllegalArgumentException("Incomplete Versionstamp included in vanilla tuple pack");
@ -579,7 +581,7 @@ class TupleUtil {
}
static byte[] packWithVersionstamp(List<Object> items, byte[] prefix) {
List<byte[]> encoded = new ArrayList<byte[]>(2 * items.size() + (prefix == null ? 1 : 2));
List<byte[]> encoded = new ArrayList<>(2 * items.size() + (prefix == null ? 1 : 2));
EncodeResult result = encodeAll(items, prefix, encoded);
if(result.versionPos < 0) {
throw new IllegalArgumentException("No incomplete Versionstamp included in tuple pack with versionstamp");
@ -587,7 +589,11 @@ class TupleUtil {
if(result.versionPos > 0xffff) {
throw new IllegalArgumentException("Tuple has incomplete version at position " + result.versionPos + " which is greater than the maximum " + 0xffff);
}
encoded.add(ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort((short)result.versionPos).array());
if (FDB.instance().getAPIVersion() < 520) {
encoded.add(ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort((short)result.versionPos).array());
} else {
encoded.add(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(result.versionPos).array());
}
return ByteArrayUtil.join(null, encoded);
}
}

View File

@ -384,7 +384,10 @@ def _pack_maybe_with_versionstamp(t, prefix=None):
if version_pos >= 0:
version_pos += len(prefix) if prefix is not None else 0
bytes_list.extend(child_bytes)
bytes_list.append(struct.pack('<H', version_pos))
if fdb.is_api_version_selected() and fdb.get_api_version() < 520:
bytes_list.append(struct.pack('<H', version_pos))
else:
bytes_list.append(struct.pack('<L', version_pos))
else:
bytes_list.extend(child_bytes)

View File

@ -32,14 +32,7 @@ import traceback
sys.path[:0] = [os.path.join(os.path.dirname(__file__), '..')]
import fdb
assert not fdb.is_api_version_selected()
try:
fdb.get_api_version()
except RuntimeError as e:
assert str(e) == 'API version is not set'
fdb.api_version(int(sys.argv[2]))
assert int(sys.argv[2]) == fdb.get_api_version()
from fdb import six
from fdb.impl import strinc
@ -528,19 +521,6 @@ class Tester:
Tester.wait_empty(self.db, prefix)
inst.push(b"WAITED_FOR_EMPTY")
elif inst.op == six.u("UNIT_TESTS"):
assert fdb.is_api_version_selected()
api_version = fdb.get_api_version()
try:
fdb.api_version(api_version + 1)
raise RuntimeError('Was not stopped from selecting two API versions')
except RuntimeError as e:
assert str(e) == 'FDB API already loaded at version {}'.format(api_version)
try:
fdb.api_version(api_version - 1)
raise RuntimeError('Was not stopped from selecting two API versions')
except RuntimeError as e:
assert str(e) == 'FDB API already loaded at version {}'.format(api_version)
fdb.api_version(api_version)
try:
db.options.set_location_cache_size(100001)

View File

@ -1,214 +1,63 @@
#############
Release Notes
#############
5.1.7
=====
Fixes
-----
* fdbdr switch could take a long time to complete if the two clusters were not created at the same time. <rdar://problem/37551521>
5.1.6
=====
Fixes
-----
* Expiring a backup could cause the fdbbackup process to hang indefinitely. <rdar://problem/39382121>
5.1.5
=====
Fixes
-----
* The consistency check calculated the size of the database inefficiently. <rdar://problem/38385230>
* Could not create new directories with the Python and Ruby implementations of the directory layer. <rdar://problem/38911902> <rdar://problem/38477474>
* fdbcli could erroneously report that it was incompatible with some processes in the cluster. <rdar://problem/39353867>
* The commit commmand in fdbcli did not wait for the result of the commit before continuing to the next command.
Other Changes
-------------
* renamed the ``multi_dc`` replication mode to ``three_datacenter``.
5.1.4
=====
Fixes
-----
* The master would recover twice when a new cluster controller was elected. <rdar://problem/38305649>
* The cluster controller could be elected on a storage process after restarting all processes in a cluster. <rdar://problem/37946424>
* Allow backup expiration to succeed if the backup is too new to be restorable. <rdar://problem/38237313>
* Process metric collection in status could sometimes fail. <rdar://problem/38311829>
5.1.3
=====
Fixes
-----
* The backup agents ran out of memory when heavily loaded. <rdar://problem/37509745>
* Storage servers were not marked as failed until after their files were deleted. <rdar://problem/38266562>
* The consistency check requested too many shards in the same request from the proxy. <rdar://problem/37326268>
* Client knobs for blob send/receive were reversed in meaning. <rdar://problem/37945529>
* fdbbackup status provides more information on reported errors. <rdar://problem/36200858> <rdar://problem/37461836>
5.1.2
=====
Fixes
-----
* Backup did not incrementally delete mutations from the mutation log. <rdar://problem/37609229>
* fdbcli status misreported completed backup/DR as running. <rdar://problem/37608661>
* Stopped producing the "fdbblob" alias for fdbbackup. <rdar://problem/37244632>
5.1.1
=====
Fixes
-----
* Bindings: Disposing a transaction during a commit resulted in a broken promise from ``get_versionstamp``. <rdar://problem/35835272>
* Bindings: Calling ``create_cluster`` before initializing the network would result in a crash. <rdar://problem/35563243>
* Latest restorable version of a running backup was not being updated in backup layer status.<rdar://problem/37288715>
* Backup layer status would sometimes show an error or an incorrect value for the recent blob bandwidth metric. <rdar://problem/37288943>
* Backup deletions were not deleting all of the files related to the backup. <rdar://problem/37756550>
* The cluster controller was sharing a process with the master even when better locations existed. <rdar://problem/37318611>
* Blob credentials files were being opened in read-write mode.
* Sometimes fdbbackup did not write log files even when ``--log`` was passed on the command line. <rdar://problem/36259384>
Performance
-----------
* Backup file uploads will respond to server-side throttling in the middle of a chunk upload rather than only between chunks. <rdar://problem/37245992>
5.1.0
=====
Features
--------
* Backups continually write snapshots at a configured interval, reducing restore times for long running backups. <rdar://problem/25512772>
* Old backup snapshots and associated logs can be deleted from a backup. <rdar://problem/25512772>
* Backup files are stored in a deep folder structure. <rdar://problem/27723412>
* Restore allows you to specify an approximate time instead of a version. <rdar://problem/34557380>
* Backup and DR agents can be paused from ``fdbbackup`` and ``fdbdr`` respectively. <rdar://problem/34776039>
* Added byte min and byte max atomic operations. <rdar://problem/29255441>
* The behavior of atomic "and" and "min" operations has changed when the key doesn't exist in the database. If the key is not present, then an "and" or "min" is now equivalent to a set. <rdar://problem/29255441>
* Exception messages are more descriptive. <rdar://problem/33665340>
* Clients can view a sample of committed mutations. <rdar://problem/33324935>
* When switching to a DR cluster, the commit versions on that cluster will be higher than the versions on the primary cluster. <rdar://problem/33572665>
* Added a read-only lock aware transaction option. <rdar://problem/34579176>
* Automatically suppress trace log events which occur too frequently. <rdar://problem/33764208>
* Added a new ``multi_dc`` replication mode designed for cross data center deployments. <rdar://problem/36489132>
Performance
-----------
* The data distribution algorithm can split the system keyspace. <rdar://problem/29932360>
* Improved load balancing when servers are located across multiple data centers. <rdar://problem/34213649>
* Improved read latencies after recoveries by only making servers responsible for keys if they have finished copying the data from other servers. <rdar://problem/34697182>
* Improved recovery times by waiting until a process has finished recovering its data from disk before letting it be recruited for new roles. <rdar://problem/32000146> <rdar://problem/34212951>
* Improved 95% read version latencies by reducing the number of logs required to confirm that a proxy has not been replaced. <rdar://problem/33196298>
* Stopped the transaction logs from copying unneeded data after multiple successive recoveries. <rdar://problem/36488946>
* Significantly improved the performance of range reads. <rdar://problem/33926224>
* The cluster controller prefers to be recruited on stateless class processes and will not put other stateless roles on the same process. <rdar://problem/35155324>
* Excluded servers no longer take on stateless roles. <rdar://problem/27110802>
* Stateless roles will be proactively moved off of excluded processes. <rdar://problem/27110802> <rdar://problem/35155044>
* Dramatically improved restore speeds of large disk queue files. <rdar://problem/35567320>
* Clients get key location information directly from the proxies, significantly reducing the latency of worst case read patterns. <rdar://problem/35953920>
* Reduced the amount of work incompatible clients generate for coordinators and the cluster controller. In particular, this reduces the load on the cluster caused by using the multi-version client. <rdar://problem/30897631>
* Pop partially recovered mutations from the transaction log to save disk space after multiple successive recoveries. <rdar://problem/33755270>
* Stopped using network checksums when also using TLS. <rdar://problem/32157852>
* Improved cluster performance after recoveries by prioritizing processing new mutations on the logs over copying data from the previous logs. <rdar://problem/36489337>
* Backup agents prefer reading from servers in the same data center. <rdar://problem/34213617>
Fixes
-----
* New databases immediately configured into ``three_data_hall`` would not respect the ``three_data_hall`` constraint. <rdar://problem/34415440>
* Exclude considered the free space of non-storage processes when determining if an exclude was safe.
* ``fdbmonitor`` failed to start processes after fork failure. <rdar://problem/34743257>
* ``fdbmonitor`` will only stop processes when the configuration file is deleted if ``kill_on_configuration_change`` is set. <rdar://problem/35497412>
* The data distribution algorithm would hang indefinitely when asked to build storage teams with more than three servers.
* Mutations from a restore could continue to be applied for a very short amount of time after a restore was successfully aborted.
Extremely Rare Bug Fixes
------------------------
* Storage servers did not properly handle rollbacks to versions before their restored version.
* A newly recruited transaction log configured with the memory storage engine could crash on startup.
* The data distribution algorithm could split a key range so that one part did not have any data.
* Storage servers could update to an incorrect version after a master failure.
* The disk queue could report a commit as successful before the sync of the disk queue files completed.
* A disk queue which was shutdown before completing its first commit could become unrecoverable.
Status
------
* If a cluster cannot recover because too many transaction logs are missing, status lists the missing logs. <rdar://problem/34965531>
* The list of connected clients includes their trace log groups. <rdar://problem/33779874>
* Status reports if a cluster is being used as a DR destination. <rdar://problem/34971187>
Bindings
--------
* API version updated to 510.
* Add versionstamp support to the Tuple layer in Java and Python. <rdar://problem/25560444>
Java
----
* API versions prior to 510 are no longer supported.
* The bindings have been moved to the package ``com.apple.foundationdb`` from ``com.apple.cie.foundationdb``. <rdar://problem/33271641>
* We no longer offer a version of the Java bindings with our custom futures library or support Java versions less than 8. The bindings that use completable futures have been renamed to ``fdb-java``. <rdar://problem/35029630>
* Finalizers now log a warning to stderr if an object with native resources is not closed. This can be disabled by calling ``FDB.setUnclosedWarning()``. <rdar://problem/35421530>
* Implementers of the ``Disposable`` interface now implement ``AutoCloseable`` instead, with ``close()`` replacing ``dispose()``.
* ``AutoCloseable`` objects will continue to be closed in object finalizers, but this behavior is being deprecated. All ``AutoCloseable`` objects should be explicitly closed. <rdar://problem/35421530>
* ``AsyncIterator`` is no longer closeable. <rdar://problem/35595971>
* ``getBoundaryKeys()`` now returns a ``CloseableAsyncIterable`` rather than an ``AsyncIterator``. <rdar://problem/35421530>
* ``Transaction.getRange()`` no longer initiates a range read immediately. Instead, the read is issued by a call to ``AsyncIterable.asList()`` or ``AsyncIterable.iterator()``. <rdar://problem/35595971>
* Added ``hashCode()`` method to ``Subspace``. <rdar://problem/35125601>
* Added thread names to threads created by our default executor. <rdar://problem/36077166>
* The network thread by default will be named ``fdb-network-thread``. <rdar://problem/36077166>
* Added an overload of ``whileTrue()`` which takes a ``Supplier``. <rdar://problem/35096338>
* Added experimental support for enabling native callbacks from external threads. <rdar://problem/33300740>
* Fix: Converting the result of ``Transaction.getRange()`` to a list would issue an unneeded range read. <rdar://problem/35325444>
* Fix: range iterators failed to close underlying native resources. <rdar://problem/35595971>
* Fix: various objects internal to the bindings were not properly closed. <rdar://problem/35541447>
Other Changes
-------------
* Backups made prior to 5.1 can no longer be restored. <rdar://problem/25512772>
* Backup now uses a hostname in the connection string instead of a list of IPs when backing up to blob storage. This hostname is resolved using DNS. <rdar://problem/34093405>
* ``fdbblob`` functionality has been moved to ``fdbbackup``. <rdar://problem/25512772>
* ``fdbcli`` will warn the user if it is used to connect to an incompatible cluster. <rdar://problem/33363571>
* Cluster files that do not match the current connection string are no longer corrected automatically. <rdar://problem/35129575>
* Improved computation of available memory on pre-3.14 kernels. <rdar://problem/35336487>
* Stopped reporting blob storage connection credentials in ``fdbbackup`` status output. <rdar://problem/31483629>
Earlier release notes
---------------------
* :doc:`5.0 (API Version 500) </old-release-notes/release-notes-500>`
* :doc:`4.6 (API Version 460) </old-release-notes/release-notes-460>`
* :doc:`4.5 (API Version 450) </old-release-notes/release-notes-450>`
* :doc:`4.4 (API Version 440) </old-release-notes/release-notes-440>`
* :doc:`4.3 (API Version 430) </old-release-notes/release-notes-430>`
* :doc:`4.2 (API Version 420) </old-release-notes/release-notes-420>`
* :doc:`4.1 (API Version 410) </old-release-notes/release-notes-410>`
* :doc:`4.0 (API Version 400) </old-release-notes/release-notes-400>`
* :doc:`3.0 (API Version 300) </old-release-notes/release-notes-300>`
* :doc:`2.0 (API Version 200) </old-release-notes/release-notes-200>`
* :doc:`1.0 (API Version 100) </old-release-notes/release-notes-100>`
* :doc:`Beta 3 (API Version 23) </old-release-notes/release-notes-023>`
* :doc:`Beta 2 (API Version 22) </old-release-notes/release-notes-022>`
* :doc:`Beta 1 (API Version 21) </old-release-notes/release-notes-021>`
* :doc:`Alpha 6 (API Version 16) </old-release-notes/release-notes-016>`
* :doc:`Alpha 5 (API Version 14) </old-release-notes/release-notes-014>`
#############
Release Notes
#############
5.2.0
=====
Features
--------
* Backup and DR share a single mutation log when both are being used on the same cluster. Ongoing backups will be aborted when upgrading to 5.2. `(PR #3) <https://github.com/apple/foundationdb/pull/3>`_
* Added a TLS plugin implementation. `(PR #343) <https://github.com/apple/foundationdb/pull/343>`_
* Backup supports HTTPS for blobstore connections. `(PR #343) <https://github.com/apple/foundationdb/pull/343>`_
* Added the APPEND_IF_FITS atomic operation. `(PR #22) <https://github.com/apple/foundationdb/pull/22>`_
* Updated the SET_VERSIONSTAMPED_VALUE atomic operation to place the versionstamp at a specified offset in a value. `(Issue #148) <https://github.com/apple/foundationdb/issues/148>`_
Performance
-----------
* Improved backup task prioritization. `(PR #71) <https://github.com/apple/foundationdb/pull/71>`_
Fixes
-----
* The client did not clear the storage server interface cache on endpoint failure for all request types. This causes up to one second of additional latency on the first get range request to a rebooted storage server. `(Issue #351) <https://github.com/apple/foundationdb/issues/351>`_
Status
------
* Available space metrics for the memory storage engine take into account both memory and disk. `(PR #41) <https://github.com/apple/foundationdb/pull/41>`_
* Added metrics for read bytes per second and read keys per second. `(PR #303) <https://github.com/apple/foundationdb/pull/303>`_
Bindings
--------
* API version updated to 520.
* Added convenience methods to determine if an API version has been set. `(PR #72) <https://github.com/apple/foundationdb/pull/72>`_
* Go: Reduce memory allocations when packing tuples. `(PR #278) <https://github.com/apple/foundationdb/pull/278>`_
Other Changes
-------------
* Deprecated the read_ahead_disable option. The commit_on_first_proxy, debug_dump, and check_writes_enable options are no longer exposed through the bindings. `(PR #134) <https://github.com/apple/foundationdb/pull/134>`_
Earlier release notes
---------------------
* :doc:`5.1 (API Version 510) </old-release-notes/release-notes-510>`
* :doc:`5.0 (API Version 500) </old-release-notes/release-notes-500>`
* :doc:`4.6 (API Version 460) </old-release-notes/release-notes-460>`
* :doc:`4.5 (API Version 450) </old-release-notes/release-notes-450>`
* :doc:`4.4 (API Version 440) </old-release-notes/release-notes-440>`
* :doc:`4.3 (API Version 430) </old-release-notes/release-notes-430>`
* :doc:`4.2 (API Version 420) </old-release-notes/release-notes-420>`
* :doc:`4.1 (API Version 410) </old-release-notes/release-notes-410>`
* :doc:`4.0 (API Version 400) </old-release-notes/release-notes-400>`
* :doc:`3.0 (API Version 300) </old-release-notes/release-notes-300>`
* :doc:`2.0 (API Version 200) </old-release-notes/release-notes-200>`
* :doc:`1.0 (API Version 100) </old-release-notes/release-notes-100>`
* :doc:`Beta 3 (API Version 23) </old-release-notes/release-notes-023>`
* :doc:`Beta 2 (API Version 22) </old-release-notes/release-notes-022>`
* :doc:`Beta 1 (API Version 21) </old-release-notes/release-notes-021>`
* :doc:`Alpha 6 (API Version 16) </old-release-notes/release-notes-016>`
* :doc:`Alpha 5 (API Version 14) </old-release-notes/release-notes-014>`

View File

@ -2078,6 +2078,8 @@ struct CLIOptions {
std::string tlsCertPath;
std::string tlsKeyPath;
std::string tlsVerifyPeers;
std::string tlsCAPath;
std::string tlsPassword;
CLIOptions( int argc, char* argv[] )
: trace(false),
@ -2151,9 +2153,15 @@ struct CLIOptions {
case TLSOptions::OPT_TLS_CERTIFICATES:
tlsCertPath = args.OptionArg();
break;
case TLSOptions::OPT_TLS_CA_FILE:
tlsCAPath = args.OptionArg();
break;
case TLSOptions::OPT_TLS_KEY:
tlsKeyPath = args.OptionArg();
break;
case TLSOptions::OPT_TLS_PASSWORD:
tlsPassword = args.OptionArg();
break;
case TLSOptions::OPT_TLS_VERIFY_PEERS:
tlsVerifyPeers = args.OptionArg();
break;
@ -3177,8 +3185,20 @@ int main(int argc, char **argv) {
return 1;
}
}
if (opt.tlsCAPath.size()) {
try {
setNetworkOption(FDBNetworkOptions::TLS_CA_PATH, opt.tlsCAPath);
}
catch (Error& e) {
fprintf(stderr, "ERROR: cannot set TLS CA path to `%s' (%s)\n", opt.tlsCAPath.c_str(), e.what());
return 1;
}
}
if ( opt.tlsKeyPath.size() ) {
try {
if (opt.tlsPassword.size())
setNetworkOption(FDBNetworkOptions::TLS_PASSWORD);
setNetworkOption(FDBNetworkOptions::TLS_KEY_PATH, opt.tlsKeyPath);
} catch( Error& e ) {
fprintf(stderr, "ERROR: cannot set TLS key path to `%s' (%s)\n", opt.tlsKeyPath.c_str(), e.what());

View File

@ -227,14 +227,14 @@ static KeyRangeRef getVersionstampKeyRange(Arena& arena, const KeyRef &key, cons
KeyRef begin(arena, key);
KeyRef end(arena, key);
if (begin.size() < 2)
if (begin.size() < 4)
throw client_invalid_operation();
int16_t pos;
memcpy(&pos, begin.end() - sizeof(int16_t), sizeof(int16_t));
pos = littleEndian16(pos);
begin = begin.substr(0, begin.size() - 2);
end = end.substr(0, end.size() - 1);
int32_t pos;
memcpy(&pos, begin.end() - sizeof(int32_t), sizeof(int32_t));
pos = littleEndian32(pos);
begin = begin.substr(0, begin.size() - 4);
end = end.substr(0, end.size() - 3);
mutateString(end)[end.size()-1] = 0;
if (pos < 0 || pos + 10 > begin.size())
@ -255,28 +255,19 @@ static void placeVersionstamp( uint8_t* destination, Version version, uint16_t t
memcpy( destination + sizeof(version), &transactionNumber, sizeof(transactionNumber) );
}
static void transformSetVersionstampedKey( MutationRef& mutation, Version version, uint16_t transactionNumber ) {
// This transforms a SetVersionstampedKey mutation into a SetValue mutation.
// It is the responsibility of the caller to also add a write conflict range for the new mutation's key.
if (mutation.param1.size() >= 2) {
int16_t pos;
memcpy(&pos, mutation.param1.end() - sizeof(int16_t), sizeof(int16_t));
pos = littleEndian16(pos);
mutation.param1 = mutation.param1.substr(0, mutation.param1.size() - 2);
static void transformVersionstampMutation( MutationRef& mutation, StringRef MutationRef::* param, Version version, uint16_t transactionNumber ) {
if ((mutation.*param).size() >= 4) {
int32_t pos;
memcpy(&pos, (mutation.*param).end() - sizeof(int32_t), sizeof(int32_t));
pos = littleEndian32(pos);
mutation.*param = (mutation.*param).substr(0, (mutation.*param).size() - 4);
if (pos >= 0 && pos + 10 <= mutation.param1.size()) {
placeVersionstamp( mutateString(mutation.param1) + pos, version, transactionNumber );
if (pos >= 0 && pos + 10 <= (mutation.*param).size()) {
placeVersionstamp( mutateString(mutation.*param) + pos, version, transactionNumber );
}
}
mutation.type = MutationRef::SetValue;
}
static void transformSetVersionstampedValue( MutationRef& mutation, Version version, uint16_t transactionNumber ) {
if (mutation.param2.size() >= 10)
placeVersionstamp( mutateString(mutation.param2), version, transactionNumber );
mutation.type = MutationRef::SetValue;
}
#endif
#endif

View File

@ -1645,6 +1645,7 @@ public:
tr->setOption(FDBTransactionOptions::LOCK_AWARE);
Optional<Value> drVersion = wait(tr->get(drVersionKey));
TraceEvent("DRU_versionCheck").detail("current", drVersion.present() ? BinaryReader::fromStringRef<int>(drVersion.get(), Unversioned()) : -1).detail("expected", DatabaseBackupAgent::LATEST_DR_VERSION).detail("logUid", BinaryWriter::toValue(logUid, Unversioned()).printable());
if (drVersion.present() && BinaryReader::fromStringRef<int>(drVersion.get(), Unversioned()) == DatabaseBackupAgent::LATEST_DR_VERSION) {
return Void();
}

View File

@ -104,6 +104,8 @@ public:
virtual void stopNetwork() = 0;
virtual ThreadFuture<Reference<ICluster>> createCluster(const char *clusterFilePath) = 0;
virtual void addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter) = 0;
};
#endif

View File

@ -1196,7 +1196,7 @@ ACTOR Future<Void> lockDatabase( Transaction* tr, UID id ) {
}
}
tr->atomicOp(databaseLockedKey, BinaryWriter::toValue(id, Unversioned()).withPrefix(LiteralStringRef("0123456789")), MutationRef::SetVersionstampedValue);
tr->atomicOp(databaseLockedKey, BinaryWriter::toValue(id, Unversioned()).withPrefix(LiteralStringRef("0123456789")).withSuffix(LiteralStringRef("\x00\x00\x00\x00")), MutationRef::SetVersionstampedValue);
tr->addWriteConflictRange(normalKeys);
return Void();
}
@ -1215,7 +1215,7 @@ ACTOR Future<Void> lockDatabase( Reference<ReadYourWritesTransaction> tr, UID id
}
}
tr->atomicOp(databaseLockedKey, BinaryWriter::toValue(id, Unversioned()).withPrefix(LiteralStringRef("0123456789")), MutationRef::SetVersionstampedValue);
tr->atomicOp(databaseLockedKey, BinaryWriter::toValue(id, Unversioned()).withPrefix(LiteralStringRef("0123456789")).withSuffix(LiteralStringRef("\x00\x00\x00\x00")), MutationRef::SetVersionstampedValue);
tr->addWriteConflictRange(normalKeys);
return Void();
}

View File

@ -336,7 +336,21 @@ void DLApi::setupNetwork() {
}
void DLApi::runNetwork() {
throwIfError(api->runNetwork());
auto e = api->runNetwork();
for(auto &hook : threadCompletionHooks) {
try {
hook.first(hook.second);
}
catch(Error &e) {
TraceEvent(SevError, "NetworkShutdownHookError").error(e);
}
catch(...) {
TraceEvent(SevError, "NetworkShutdownHookError").error(unknown_error());
}
}
throwIfError(e);
}
void DLApi::stopNetwork() {
@ -355,6 +369,11 @@ ThreadFuture<Reference<ICluster>> DLApi::createCluster(const char *clusterFilePa
});
}
void DLApi::addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter) {
MutexHolder holder(lock);
threadCompletionHooks.push_back(std::make_pair(hook, hookParameter));
}
// MultiVersionTransaction
MultiVersionTransaction::MultiVersionTransaction(Reference<MultiVersionDatabase> db) : db(db) {
updateTransaction();
@ -1140,19 +1159,6 @@ THREAD_FUNC_RETURN runNetworkThread(void *param) {
TraceEvent(SevError, "RunNetworkError").error(e);
}
std::vector<std::pair<void (*)(void*), void*>> &hooks = ((ClientInfo*)param)->threadCompletionHooks;
for(auto &hook : hooks) {
try {
hook.first(hook.second);
}
catch(Error &e) {
TraceEvent(SevError, "NetworkShutdownHookError").error(e);
}
catch(...) {
TraceEvent(SevError, "NetworkShutdownHookError").error(unknown_error());
}
}
THREAD_RETURN;
}
@ -1174,29 +1180,7 @@ void MultiVersionApi::runNetwork() {
});
}
Error *runErr = NULL;
try {
localClient->api->runNetwork();
}
catch(Error &e) {
runErr = &e;
}
for(auto &hook : localClient->threadCompletionHooks) {
try {
hook.first(hook.second);
}
catch(Error &e) {
TraceEvent(SevError, "NetworkShutdownHookError").error(e);
}
catch(...) {
TraceEvent(SevError, "NetworkShutdownHookError").error(unknown_error());
}
}
if(runErr != NULL) {
throw *runErr;
}
localClient->api->runNetwork();
for(auto h : handles) {
waitThread(h);
@ -1220,7 +1204,7 @@ void MultiVersionApi::stopNetwork() {
}
}
void MultiVersionApi::addNetworkThreadCompletionHook(void (*hook)(void*), void *hook_parameter) {
void MultiVersionApi::addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter) {
lock.enter();
if(!networkSetup) {
lock.leave();
@ -1228,13 +1212,12 @@ void MultiVersionApi::addNetworkThreadCompletionHook(void (*hook)(void*), void *
}
lock.leave();
auto hookPair = std::pair<void (*)(void*), void*>(hook, hook_parameter);
threadCompletionHooks.push_back(hookPair);
localClient->api->addNetworkThreadCompletionHook(hook, hookParameter);
if(!bypassMultiClientApi) {
for( auto it : externalClients ) {
it.second->threadCompletionHooks.push_back(hookPair);
}
runOnExternalClients([hook, hookParameter](Reference<ClientInfo> client) {
client->api->addNetworkThreadCompletionHook(hook, hookParameter);
});
}
}

View File

@ -203,12 +203,17 @@ public:
ThreadFuture<Reference<ICluster>> createCluster(const char *clusterFilePath);
void addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter);
private:
const std::string fdbCPath;
const Reference<FdbCApi> api;
int headerVersion;
bool networkSetup;
Mutex lock;
std::vector<std::pair<void (*)(void*), void*>> threadCompletionHooks;
void init();
};
@ -403,7 +408,7 @@ public:
void setupNetwork();
void runNetwork();
void stopNetwork();
void addNetworkThreadCompletionHook(void (*hook)(void*), void *hook_parameter);
void addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter);
ThreadFuture<Reference<ICluster>> createCluster(const char *clusterFilePath);
static MultiVersionApi* api;
@ -443,7 +448,6 @@ private:
std::vector<std::pair<FDBNetworkOptions::Option, Optional<Standalone<StringRef>>>> options;
std::map<FDBNetworkOptions::Option, std::set<Standalone<StringRef>>> setEnvOptions;
volatile bool envOptionsLoaded;
std::vector<std::pair<void (*)(void*), void*>> threadCompletionHooks;
};

View File

@ -285,7 +285,7 @@ ACTOR static Future<Void> transactionInfoCommitActor(Transaction *tr, std::vecto
int64_t numCommitBytes = 0;
for (auto &chunk : *chunks) {
tr->atomicOp(chunk.key, chunk.value, MutationRef::SetVersionstampedKey);
numCommitBytes += chunk.key.size() + chunk.value.size() - 2; // subtract last 2 bytes of key that denotes verstion stamp index
numCommitBytes += chunk.key.size() + chunk.value.size() - 4; // subtract number of bytes of key that denotes verstion stamp index
}
tr->atomicOp(clientLatencyAtomicCtr, StringRef((uint8_t*)&numCommitBytes, 8), MutationRef::AddValue);
Void _ = wait(tr->commit());
@ -369,9 +369,9 @@ ACTOR static Future<Void> clientStatusUpdateActor(DatabaseContext *cx) {
TrInfoChunk chunk;
BinaryWriter chunkBW(Unversioned());
chunkBW << bigEndian32(i+1) << bigEndian32(num_chunks);
chunk.key = KeyRef(clientLatencyName + std::string(10, '\x00') + "/" + random_id + "/" + chunkBW.toStringRef().toString() + "/" + std::string(2, '\x00'));
int16_t pos = littleEndian16(clientLatencyName.size());
memcpy(mutateString(chunk.key) + chunk.key.size() - sizeof(int16_t), &pos, sizeof(int16_t));
chunk.key = KeyRef(clientLatencyName + std::string(10, '\x00') + "/" + random_id + "/" + chunkBW.toStringRef().toString() + "/" + std::string(4, '\x00'));
int32_t pos = littleEndian32(clientLatencyName.size());
memcpy(mutateString(chunk.key) + chunk.key.size() - sizeof(int32_t), &pos, sizeof(int32_t));
if (i == num_chunks - 1) {
chunk.value = ValueRef(static_cast<uint8_t *>(bw.getData()) + (i * value_size_limit), bw.getLength() - (i * value_size_limit));
}
@ -790,6 +790,18 @@ void setNetworkOption(FDBNetworkOptions::Option option, Optional<StringRef> valu
case FDBNetworkOptions::TLS_CERT_BYTES:
tlsOptions->set_cert_data( value.get().toString() );
break;
case FDBNetworkOptions::TLS_CA_PATH:
validateOptionValue(value, true);
tlsOptions->set_ca_file( value.get().toString() );
break;
case FDBNetworkOptions::TLS_CA_BYTES:
validateOptionValue(value, true);
tlsOptions->set_ca_data(value.get().toString());
break;
case FDBNetworkOptions::TLS_PASSWORD:
validateOptionValue(value, true);
tlsOptions->set_key_password(value.get().toString());
break;
case FDBNetworkOptions::TLS_KEY_PATH:
validateOptionValue(value, true);
tlsOptions->set_key_file( value.get().toString() );
@ -801,7 +813,7 @@ void setNetworkOption(FDBNetworkOptions::Option option, Optional<StringRef> valu
case FDBNetworkOptions::TLS_VERIFY_PEERS:
validateOptionValue(value, true);
try {
tlsOptions->set_verify_peers( value.get().toString() );
tlsOptions->set_verify_peers({ value.get().toString() });
} catch( Error& e ) {
TraceEvent(SevWarnAlways, "TLSValidationSetError")
.detail("Input", value.get().toString() )
@ -1010,57 +1022,8 @@ ACTOR Future<Optional<vector<StorageServerInterface>>> transactionalGetServerInt
return serverInterfaces;
}
template <class F>
pair<KeyRange, Reference<LocationInfo>> getCachedKeyLocation( Database cx, Key key, F StorageServerInterface::*member, bool isBackward = false ) {
auto ssi = cx->getCachedLocation( key, isBackward );
if (!ssi.second) {
return ssi;
}
for(int i = 0; i < ssi.second->size(); i++) {
if( IFailureMonitor::failureMonitor().onlyEndpointFailed(ssi.second->get(i, member).getEndpoint()) ) {
cx->invalidateCache( key );
ssi.second.clear();
return ssi;
}
}
return ssi;
}
template <class F>
vector< pair<KeyRange,Reference<LocationInfo>> > getCachedKeyRangeLocations( Database cx, KeyRange keys, int limit, bool reverse, F StorageServerInterface::*member ) {
ASSERT (!keys.empty());
vector< pair<KeyRange,Reference<LocationInfo>> > locations;
if (!cx->getCachedLocations(keys, locations, limit, reverse))
return vector< pair<KeyRange,Reference<LocationInfo>> >();
bool foundFailed = false;
for(auto& it : locations) {
bool onlyEndpointFailed = false;
for(int i = 0; i < it.second->size(); i++) {
if( IFailureMonitor::failureMonitor().onlyEndpointFailed(it.second->get(i, member).getEndpoint()) ) {
onlyEndpointFailed = true;
break;
}
}
if( onlyEndpointFailed ) {
cx->invalidateCache( it.first.begin );
foundFailed = true;
}
}
if(foundFailed) {
return vector< pair<KeyRange,Reference<LocationInfo>> >();
}
return locations;
}
//If isBackward == true, returns the shard containing the key before 'key' (an infinitely long, inexpressible key). Otherwise returns the shard containing key
ACTOR Future< pair<KeyRange,Reference<LocationInfo>> > getKeyLocation( Database cx, Key key, TransactionInfo info, bool isBackward = false ) {
ACTOR Future< pair<KeyRange,Reference<LocationInfo>> > getKeyLocation_internal( Database cx, Key key, TransactionInfo info, bool isBackward = false ) {
if (isBackward) {
ASSERT( key != allKeys.begin && key <= allKeys.end );
} else {
@ -1085,7 +1048,25 @@ ACTOR Future< pair<KeyRange,Reference<LocationInfo>> > getKeyLocation( Database
}
}
ACTOR Future< vector< pair<KeyRange,Reference<LocationInfo>> > > getKeyRangeLocations( Database cx, KeyRange keys, int limit, bool reverse, TransactionInfo info ) {
template <class F>
Future<pair<KeyRange, Reference<LocationInfo>>> getKeyLocation( Database const& cx, Key const& key, F StorageServerInterface::*member, TransactionInfo const& info, bool isBackward = false ) {
auto ssi = cx->getCachedLocation( key, isBackward );
if (!ssi.second) {
return getKeyLocation_internal( cx, key, info, isBackward );
}
for(int i = 0; i < ssi.second->size(); i++) {
if( IFailureMonitor::failureMonitor().onlyEndpointFailed(ssi.second->get(i, member).getEndpoint()) ) {
cx->invalidateCache( key );
ssi.second.clear();
return getKeyLocation_internal( cx, key, info, isBackward );
}
}
return ssi;
}
ACTOR Future< vector< pair<KeyRange,Reference<LocationInfo>> > > getKeyRangeLocations_internal( Database cx, KeyRange keys, int limit, bool reverse, TransactionInfo info ) {
if( info.debugID.present() )
g_traceBatch.addEvent("TransactionDebug", info.debugID.get().first(), "NativeAPI.getKeyLocations.Before");
@ -1112,11 +1093,43 @@ ACTOR Future< vector< pair<KeyRange,Reference<LocationInfo>> > > getKeyRangeLoca
}
}
template <class F>
Future< vector< pair<KeyRange,Reference<LocationInfo>> > > getKeyRangeLocations( Database const& cx, KeyRange const& keys, int limit, bool reverse, F StorageServerInterface::*member, TransactionInfo const& info ) {
ASSERT (!keys.empty());
vector< pair<KeyRange,Reference<LocationInfo>> > locations;
if (!cx->getCachedLocations(keys, locations, limit, reverse)) {
return getKeyRangeLocations_internal( cx, keys, limit, reverse, info );
}
bool foundFailed = false;
for(auto& it : locations) {
bool onlyEndpointFailed = false;
for(int i = 0; i < it.second->size(); i++) {
if( IFailureMonitor::failureMonitor().onlyEndpointFailed(it.second->get(i, member).getEndpoint()) ) {
onlyEndpointFailed = true;
break;
}
}
if( onlyEndpointFailed ) {
cx->invalidateCache( it.first.begin );
foundFailed = true;
}
}
if(foundFailed) {
return getKeyRangeLocations_internal( cx, keys, limit, reverse, info );
}
return locations;
}
ACTOR Future<Void> warmRange_impl( Transaction *self, Database cx, KeyRange keys ) {
state int totalRanges = 0;
state int totalRequests = 0;
loop {
vector<pair<KeyRange, Reference<LocationInfo>>> locations = wait(getKeyRangeLocations(cx, keys, CLIENT_KNOBS->WARM_RANGE_SHARD_LIMIT, false, self->info));
vector<pair<KeyRange, Reference<LocationInfo>>> locations = wait(getKeyRangeLocations_internal(cx, keys, CLIENT_KNOBS->WARM_RANGE_SHARD_LIMIT, false, self->info));
totalRanges += CLIENT_KNOBS->WARM_RANGE_SHARD_LIMIT;
totalRequests++;
if(locations.size() == 0 || totalRanges >= cx->locationCacheSize || locations[locations.size()-1].first.end >= keys.end)
@ -1153,12 +1166,7 @@ ACTOR Future<Optional<Value>> getValue( Future<Version> version, Key key, Databa
validateVersion(ver);
loop {
state pair<KeyRange, Reference<LocationInfo>> ssi = getCachedKeyLocation(cx, key, &StorageServerInterface::getValue);
if (!ssi.second) {
pair<KeyRange, Reference<LocationInfo>> ssi2 = wait( getKeyLocation( cx, key, info ) );
ssi = std::move(ssi2);
}
state pair<KeyRange, Reference<LocationInfo>> ssi = wait( getKeyLocation(cx, key, &StorageServerInterface::getValue, info) );
state Optional<UID> getValueID = Optional<UID>();
state uint64_t startTime;
state double startTimeD;
@ -1237,11 +1245,7 @@ ACTOR Future<Key> getKey( Database cx, KeySelector k, Future<Version> version, T
}
Key locationKey(k.getKey(), k.arena());
state pair<KeyRange, Reference<LocationInfo>> ssi = getCachedKeyLocation(cx, locationKey, &StorageServerInterface::getKey, k.isBackward());
if(!ssi.second) {
pair<KeyRange, Reference<LocationInfo>> ssi2 = wait( getKeyLocation(cx, locationKey, info, k.isBackward()) );
ssi = std::move(ssi2);
}
state pair<KeyRange, Reference<LocationInfo>> ssi = wait( getKeyLocation(cx, locationKey, &StorageServerInterface::getKey, info, k.isBackward()) );
try {
if( info.debugID.present() )
@ -1300,11 +1304,7 @@ ACTOR Future< Void > watchValue( Future<Version> version, Key key, Optional<Valu
ASSERT(ver != latestVersion);
loop {
state pair<KeyRange, Reference<LocationInfo>> ssi = getCachedKeyLocation(cx, key, &StorageServerInterface::watchValue );
if (!ssi.second) {
pair<KeyRange, Reference<LocationInfo>> ssi2 = wait( getKeyLocation( cx, key, info ) );
ssi = std::move(ssi2);
}
state pair<KeyRange, Reference<LocationInfo>> ssi = wait( getKeyLocation(cx, key, &StorageServerInterface::watchValue, info ) );
try {
state Optional<UID> watchValueID = Optional<UID>();
@ -1375,12 +1375,7 @@ ACTOR Future<Standalone<RangeResultRef>> getExactRange( Database cx, Version ver
//printf("getExactRange( '%s', '%s' )\n", keys.begin.toString().c_str(), keys.end.toString().c_str());
loop {
state vector< pair<KeyRange, Reference<LocationInfo>> > locations = getCachedKeyRangeLocations( cx, keys, CLIENT_KNOBS->GET_RANGE_SHARD_LIMIT, reverse, &StorageServerInterface::getKeyValues);
if (!locations.size()) {
vector< pair<KeyRange, Reference<LocationInfo>> > _locations = wait( getKeyRangeLocations( cx, keys, CLIENT_KNOBS->GET_RANGE_SHARD_LIMIT, reverse, info ) );
locations = std::move(_locations);
}
state vector< pair<KeyRange, Reference<LocationInfo>> > locations = wait( getKeyRangeLocations( cx, keys, CLIENT_KNOBS->GET_RANGE_SHARD_LIMIT, reverse, &StorageServerInterface::getKeyValues, info ) );
ASSERT( locations.size() );
state int shard = 0;
loop {
@ -1637,12 +1632,7 @@ ACTOR Future<Standalone<RangeResultRef>> getRange( Database cx, Reference<Transa
Key locationKey = reverse ? Key(end.getKey(), end.arena()) : Key(begin.getKey(), begin.arena());
bool locationBackward = reverse ? (end-1).isBackward() : begin.isBackward();
state pair<KeyRange, Reference<LocationInfo>> beginServer = getCachedKeyLocation( cx, locationKey, &StorageServerInterface::getKeyValues, locationBackward );
if (!beginServer.second) {
pair<KeyRange, Reference<LocationInfo>> ssi2 = wait( getKeyLocation( cx, locationKey, info, locationBackward ) );
beginServer = std::move(ssi2);
}
state pair<KeyRange, Reference<LocationInfo>> beginServer = wait( getKeyLocation( cx, locationKey, &StorageServerInterface::getKeyValues, info, locationBackward ) );
state KeyRange shard = beginServer.first;
state bool modifiedSelectors = false;
state GetKeyValuesRequest req;
@ -2097,10 +2087,12 @@ void Transaction::atomicOp(const KeyRef& key, const ValueRef& operand, MutationR
else if (operationType == MutationRef::And)
operationType = MutationRef::AndV2;
}
auto &req = tr;
auto &t = req.transaction;
auto r = singleKeyRange( key, req.arena );
auto v = ValueRef( req.arena, operand );
t.mutations.push_back( req.arena, MutationRef( operationType, r.begin, v ) );
if( addConflictRange )
@ -2905,11 +2897,7 @@ ACTOR Future< StorageMetrics > waitStorageMetrics(
{
state int tooManyShardsCount = 0;
loop {
state vector< pair<KeyRange, Reference<LocationInfo>> > locations = getCachedKeyRangeLocations( cx, keys, shardLimit, false, &StorageServerInterface::waitMetrics);
if (!locations.size()) {
vector< pair<KeyRange, Reference<LocationInfo>> > _locations = wait( getKeyRangeLocations( cx, keys, shardLimit, false, TransactionInfo(TaskDataDistribution) ) );
locations = std::move(_locations);
}
state vector< pair<KeyRange, Reference<LocationInfo>> > locations = wait( getKeyRangeLocations( cx, keys, shardLimit, false, &StorageServerInterface::waitMetrics, TransactionInfo(TaskDataDistribution) ) );
if( locations.size() == shardLimit ) {
TraceEvent(!g_network->isSimulated() && ++tooManyShardsCount >= 15 ? SevWarnAlways : SevWarn, "WaitStorageMetricsPenalty")
@ -2963,11 +2951,7 @@ Future< StorageMetrics > Transaction::getStorageMetrics( KeyRange const& keys, i
ACTOR Future< Standalone<VectorRef<KeyRef>> > splitStorageMetrics( Database cx, KeyRange keys, StorageMetrics limit, StorageMetrics estimated )
{
loop {
state vector< pair<KeyRange, Reference<LocationInfo>> > locations = getCachedKeyRangeLocations( cx, keys, CLIENT_KNOBS->STORAGE_METRICS_SHARD_LIMIT, false, &StorageServerInterface::splitMetrics);
if (!locations.size()) {
vector< pair<KeyRange, Reference<LocationInfo>> > _locations = wait( getKeyRangeLocations( cx, keys, CLIENT_KNOBS->STORAGE_METRICS_SHARD_LIMIT, false, TransactionInfo(TaskDataDistribution) ) );
locations = std::move(_locations);
}
state vector< pair<KeyRange, Reference<LocationInfo>> > locations = wait( getKeyRangeLocations( cx, keys, CLIENT_KNOBS->STORAGE_METRICS_SHARD_LIMIT, false, &StorageServerInterface::splitMetrics, TransactionInfo(TaskDataDistribution) ) );
state StorageMetrics used;
state Standalone<VectorRef<KeyRef>> results;

View File

@ -386,7 +386,7 @@ TEST_CASE("fdbclient/WriteMap/setVersionstampedKey") {
ASSERT(writes.empty());
ASSERT(getWriteMapCount(&writes) == 1);
writes.mutate(LiteralStringRef("stamp:XXXXXXXX\x06\x00"), MutationRef::SetVersionstampedKey, LiteralStringRef("1"), true);
writes.mutate(LiteralStringRef("stamp:XXXXXXXX\x06\x00\x00\x00"), MutationRef::SetVersionstampedKey, LiteralStringRef("1"), true);
ASSERT(!writes.empty());
ASSERT(getWriteMapCount(&writes) == 3);
@ -398,7 +398,7 @@ TEST_CASE("fdbclient/WriteMap/setVersionstampedKey") {
ASSERT(it.beginKey() < allKeys.end);
ASSERT(it.beginKey().cmp(LiteralStringRef("")) == 0);
ASSERT(it.endKey().cmp(LiteralStringRef("stamp:XXXXXXXX\x06\x00")) == 0);
ASSERT(it.endKey().cmp(LiteralStringRef("stamp:XXXXXXXX\x06\x00\x00\x00")) == 0);
ASSERT(!it.is_cleared_range());
ASSERT(!it.is_conflict_range());
ASSERT(!it.is_operation());
@ -407,8 +407,8 @@ TEST_CASE("fdbclient/WriteMap/setVersionstampedKey") {
++it;
ASSERT(it.beginKey() < allKeys.end);
ASSERT(it.beginKey().cmp(LiteralStringRef("stamp:XXXXXXXX\x06\x00")) == 0);
ASSERT(it.endKey().cmp(LiteralStringRef("stamp:XXXXXXXX\x06\x00\x00")) == 0);
ASSERT(it.beginKey().cmp(LiteralStringRef("stamp:XXXXXXXX\x06\x00\x00\x00")) == 0);
ASSERT(it.endKey().cmp(LiteralStringRef("stamp:XXXXXXXX\x06\x00\x00\x00\x00")) == 0);
ASSERT(!it.is_cleared_range());
ASSERT(it.is_conflict_range());
ASSERT(it.is_operation());
@ -418,7 +418,7 @@ TEST_CASE("fdbclient/WriteMap/setVersionstampedKey") {
++it;
ASSERT(it.beginKey() < allKeys.end);
ASSERT(it.beginKey().cmp(LiteralStringRef("stamp:XXXXXXXX\x06\x00\x00")) == 0);
ASSERT(it.beginKey().cmp(LiteralStringRef("stamp:XXXXXXXX\x06\x00\x00\x00\x00")) == 0);
ASSERT(it.endKey().cmp(LiteralStringRef("stamp:ZZZZZZZZZZ")) == 0);
ASSERT(!it.is_cleared_range());
ASSERT(!it.is_conflict_range());
@ -459,7 +459,7 @@ TEST_CASE("fdbclient/WriteMap/setVersionstampedValue") {
ASSERT(writes.empty());
ASSERT(getWriteMapCount(&writes) == 1);
writes.mutate(LiteralStringRef("stamp"), MutationRef::SetVersionstampedValue, LiteralStringRef("XXXXXXXX\x00\x00"), true);
writes.mutate(LiteralStringRef("stamp"), MutationRef::SetVersionstampedValue, LiteralStringRef("XXXXXXXX\x00\x00\x00\x00\x00\x00"), true);
ASSERT(!writes.empty());
ASSERT(getWriteMapCount(&writes) == 3);

View File

@ -82,6 +82,12 @@ public:
static ValueRef getRandomVersionstampValue(Arena& arena) {
int len = g_random->randomInt(10, 98);
std::string value = std::string(len, 'x');
int32_t pos = g_random->randomInt(0, len - 9);
if (g_random->random01() < 0.01) {
pos = value.size() - 10;
}
pos = littleEndian32(pos);
value += std::string((const char*)&pos, sizeof(int32_t));
return ValueRef(arena, value);
}
@ -92,15 +98,15 @@ public:
key += '\x00';
if (idx % 3 >= 2)
key += '\x00';
int pos = key.size() - g_random->randomInt(0, 3);
int32_t pos = key.size() - g_random->randomInt(0, 3);
if (g_random->random01() < 0.01) {
pos = 0;
}
key = key.substr(0, pos);
key += "XXXXXXXXYY";
key += std::string(g_random->randomInt(0, 3), 'z');
key += (char)(pos & 0xFF);
key += (char)((pos >> 8) & 0xFF);
pos = littleEndian32(pos);
key += std::string((const char*)&pos, sizeof(int32_t));
return ValueRef(arena, key);
}
@ -132,4 +138,4 @@ public:
void testESR();
void testSnapshotCache();
#endif
#endif

View File

@ -940,8 +940,8 @@ public:
std::swap(itCopy->value[i--], itCopy->value.back());
itCopy->value.pop_back();
} else if( !valueKnown ||
(itCopy->value[i]->setPresent && (itCopy->value[i]->setValue.present() != val.present() || (val.present() && itCopy->value[i]->setValue.get() != val.get()))) ||
(itCopy->value[i]->valuePresent && (itCopy->value[i]->value.present() != val.present() || (val.present() && itCopy->value[i]->value.get() != val.get()))) ) {
(itCopy->value[i]->setPresent && (itCopy->value[i]->setValue.present() != val.present() || (val.present() && itCopy->value[i]->setValue.get() != val.get()))) ||
(itCopy->value[i]->valuePresent && (itCopy->value[i]->value.present() != val.present() || (val.present() && itCopy->value[i]->value.get() != val.get()))) ) {
itCopy->value[i]->onChangeTrigger.send(Void());
if( i < itCopy->value.size() - 1 )
std::swap(itCopy->value[i--], itCopy->value.back());
@ -1487,6 +1487,26 @@ void ReadYourWritesTransaction::atomicOp( const KeyRef& key, const ValueRef& ope
if(operand.size() > CLIENT_KNOBS->VALUE_SIZE_LIMIT)
throw value_too_large();
if (tr.apiVersionAtLeast(510)) {
if (operationType == MutationRef::Min)
operationType = MutationRef::MinV2;
else if (operationType == MutationRef::And)
operationType = MutationRef::AndV2;
}
KeyRef k;
if(!tr.apiVersionAtLeast(520) && operationType == MutationRef::SetVersionstampedKey) {
k = key.withSuffix( LiteralStringRef("\x00\x00"), arena );
} else {
k = KeyRef( arena, key );
}
ValueRef v;
if(!tr.apiVersionAtLeast(520) && operationType == MutationRef::SetVersionstampedValue) {
v = operand.withSuffix( LiteralStringRef("\x00\x00\x00\x00"), arena );
} else {
v = ValueRef( arena, operand );
}
if(operationType == MutationRef::SetVersionstampedKey) {
KeyRangeRef range = getVersionstampKeyRange(arena, key, getMaxReadKey()); // this does validation of the key and needs to be performed before the readYourWritesDisabled path
if(!options.readYourWritesDisabled) {
@ -1495,23 +1515,20 @@ void ReadYourWritesTransaction::atomicOp( const KeyRef& key, const ValueRef& ope
}
}
if (operationType == MutationRef::SetVersionstampedValue && operand.size() < 10)
throw client_invalid_operation();
if (tr.apiVersionAtLeast(510)) {
if (operationType == MutationRef::Min)
operationType = MutationRef::MinV2;
else if (operationType == MutationRef::And)
operationType = MutationRef::AndV2;
if(operationType == MutationRef::SetVersionstampedValue) {
if(operand.size() < 4)
throw client_invalid_operation();
int32_t pos;
memcpy(&pos, operand.end() - sizeof(int32_t), sizeof(int32_t));
pos = littleEndian32(pos);
if (pos < 0 || pos + 10 > operand.size() - 4)
throw client_invalid_operation();
}
if(options.readYourWritesDisabled) {
return tr.atomicOp(key, operand, (MutationRef::Type) operationType, addWriteConflict);
return tr.atomicOp(k, v, (MutationRef::Type) operationType, addWriteConflict);
}
KeyRef k = KeyRef( arena, key );
ValueRef v = ValueRef( arena, operand );
writes.mutate(k, (MutationRef::Type) operationType, v, addWriteConflict);
RYWImpl::triggerWatches(this, key, Optional<ValueRef>(), false);
}

View File

@ -357,7 +357,30 @@ void ThreadSafeApi::setupNetwork() {
}
void ThreadSafeApi::runNetwork() {
::runNetwork();
Optional<Error> runErr;
try {
::runNetwork();
}
catch(Error &e) {
runErr = e;
}
for(auto &hook : threadCompletionHooks) {
try {
hook.first(hook.second);
}
catch(Error &e) {
TraceEvent(SevError, "NetworkShutdownHookError").error(e);
}
catch(...) {
TraceEvent(SevError, "NetworkShutdownHookError").error(unknown_error());
}
}
if(runErr.present()) {
throw runErr.get();
}
}
void ThreadSafeApi::stopNetwork() {
@ -368,4 +391,14 @@ ThreadFuture<Reference<ICluster>> ThreadSafeApi::createCluster(const char *clust
return ThreadSafeCluster::create(clusterFilePath, apiVersion);
}
void ThreadSafeApi::addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter) {
if (!g_network) {
throw network_not_setup();
}
MutexHolder holder(lock); // We could use the network thread to protect this action, but then we can't guarantee upon return that the hook is set.
threadCompletionHooks.push_back(std::make_pair(hook, hookParameter));
}
IClientApi* ThreadSafeApi::api = new ThreadSafeApi();

View File

@ -140,6 +140,8 @@ public:
ThreadFuture<Reference<ICluster>> createCluster(const char *clusterFilePath);
void addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter);
static IClientApi* api;
private:
@ -148,6 +150,9 @@ private:
int apiVersion;
const std::string clientVersion;
uint64_t transportId;
Mutex lock;
std::vector<std::pair<void (*)(void*), void*>> threadCompletionHooks;
};
#endif

View File

@ -142,7 +142,7 @@ public:
bool following_conflict = it.entry().following_keys_conflict;
bool is_conflict = addConflict || it.is_conflict_range();
bool following_unreadable = it.entry().following_keys_unreadable;
bool is_unreadable = it.is_unreadable() || operation == MutationRef::SetVersionstampedValue || operation == MutationRef::SetVersionstampedKey;
bool is_unreadable = it.is_unreadable() || operation == MutationRef::SetVersionstampedValue || operation == MutationRef::SetVersionstampedKey;
bool is_dependent = operation != MutationRef::SetValue && operation != MutationRef::SetVersionstampedValue && operation != MutationRef::SetVersionstampedKey;
if (it.entry().key != key) {
@ -630,4 +630,4 @@ private:
*/
#endif
#endif

View File

@ -79,6 +79,15 @@ description is not currently required but encouraged.
<Option name="Buggify_section_fired_probability" code="51"
paramType="Int" paramDescription="probability expressed as a percentage between 0 and 100"
description="Set the probability of an active BUGGIFY section being fired" />
<Option name="TLS_ca_bytes" code="52"
paramType="Bytes" paramDescription="ca bundle"
description="Set the ca bundle" />
<Option name="TLS_ca_path" code="53"
paramType="String" paramDescription="file path"
description="Set the file from which to load the certificate authority bundle" />
<Option name="TLS_password" code="54"
paramType="String" paramDescription="key passphrase"
description="Set the passphrase for encrypted private key. Password should be set before setting the key for the password to be used." />
<Option name="disable_multi_version_client_api" code="60"
description="Disables the multi-version client API and instead uses the local client directly. Must be set before setting up the network." />
<Option name="callbacks_on_external_threads" code="61"
@ -234,10 +243,10 @@ description is not currently required but encouraged.
description="Performs a little-endian comparison of byte strings. If the existing value in the database is not present, then ``param`` is stored in the database. If the existing value in the database is shorter than ``param``, it is first extended to the length of ``param`` with zero bytes. If ``param`` is shorter than the existing value in the database, the existing value is truncated to match the length of ``param``. The smaller of the two values is then stored in the database."/>
<Option name="set_versionstamped_key" code="14"
paramType="Bytes" paramDescription="value to which to set the transformed key"
description="Transforms ``key`` using a versionstamp for the transaction. Sets the transformed key in the database to ``param``. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database. The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time versionstamps are compatible with the Tuple layer only in the Java and Python bindings. Note that this implies versionstamped keys may not be used with the Subspace and Directory layers except in those languages." />
description="Transforms ``key`` using a versionstamp for the transaction. Sets the transformed key in the database to ``param``. The key is transformed by removing the final four bytes from the key and reading those as a little-Endian 32-bit integer to get a position ``pos``. The 10 bytes of the key from ``pos`` to ``pos + 10`` are replaced with the versionstamp of the transaction used. The first byte of the key is position 0. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database (serialized in big-Endian order). The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time, versionstamps are compatible with the Tuple layer only in the Java and Python bindings. Also, note that prior to API version 520, the offset was computed from only the final two bytes rather than the final four bytes." />
<Option name="set_versionstamped_value" code="15"
paramType="Bytes" paramDescription="value to versionstamp and set"
description="Transforms ``param`` using a versionstamp for the transaction. Sets ``key`` in the database to the transformed parameter. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database. The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time versionstamped values are not compatible with the Tuple layer." />
description="Transforms ``param`` using a versionstamp for the transaction. Sets the ``key`` given to the transformed ``param``. The parameter is transformed by removing the final four bytes from ``param`` and reading those as a little-Endian 32-bit integer to get a position ``pos``. The 10 bytes of the parameter from ``pos`` to ``pos + 10`` are replaced with the versionstamp of the transaction used. The first byte of the parameter is position 0. A versionstamp is a 10 byte, unique, monotonically (but not sequentially) increasing value for each committed transaction. The first 8 bytes are the committed version of the database (serialized in big-Endian order). The last 2 bytes are monotonic in the serialization order for transactions. WARNING: At this time, versionstamps are compatible with the Tuple layer only in the Java and Python bindings. Also, note that prior to API version 520, the versionstamp was always placed at the beginning of the parameter rather than computing an offset." />
<Option name="byte_min" code="16"
paramType="Bytes" paramDescription="value to check against database value"
description="Performs lexicographic comparison of byte strings. If the existing value in the database is not present, then ``param`` is stored. Otherwise the smaller of the two values is then stored in the database."/>

View File

@ -49,6 +49,7 @@ BlobStoreEndpoint::Stats BlobStoreEndpoint::Stats::operator-(const Stats &rhs) {
BlobStoreEndpoint::Stats BlobStoreEndpoint::s_stats;
BlobStoreEndpoint::BlobKnobs::BlobKnobs() {
secure_connection = 1;
connect_tries = CLIENT_KNOBS->BLOBSTORE_CONNECT_TRIES;
connect_timeout = CLIENT_KNOBS->BLOBSTORE_CONNECT_TIMEOUT;
max_connection_life = CLIENT_KNOBS->BLOBSTORE_MAX_CONNECTION_LIFE;
@ -71,6 +72,7 @@ BlobStoreEndpoint::BlobKnobs::BlobKnobs() {
bool BlobStoreEndpoint::BlobKnobs::set(StringRef name, int value) {
#define TRY_PARAM(n, sn) if(name == LiteralStringRef(#n) || name == LiteralStringRef(#sn)) { n = value; return true; }
TRY_PARAM(secure_connection, sc)
TRY_PARAM(connect_tries, ct);
TRY_PARAM(connect_timeout, cto);
TRY_PARAM(max_connection_life, mcl);
@ -98,6 +100,7 @@ std::string BlobStoreEndpoint::BlobKnobs::getURLParameters() const {
static BlobKnobs defaults;
std::string r;
#define _CHECK_PARAM(n, sn) if(n != defaults. n) { r += format("%s%s=%d", r.empty() ? "" : "&", #sn, n); }
_CHECK_PARAM(secure_connection, sc);
_CHECK_PARAM(connect_tries, ct);
_CHECK_PARAM(connect_timeout, cto);
_CHECK_PARAM(max_connection_life, mcl);
@ -149,7 +152,7 @@ Reference<BlobStoreEndpoint> BlobStoreEndpoint::fromString(std::string const &ur
StringRef value = t.eat("&");
char *valueEnd;
int ivalue = strtol(value.toString().c_str(), &valueEnd, 10);
if(*valueEnd || ivalue == 0)
if(*valueEnd || (ivalue == 0 && value.toString() != "0"))
throw format("%s is not a valid value for %s", value.toString().c_str(), name.toString().c_str());
if(!knobs.set(name, ivalue))
throw format("%s is not a valid parameter name", name.toString().c_str());
@ -393,8 +396,10 @@ ACTOR Future<BlobStoreEndpoint::ReusableConnection> connect_impl(Reference<BlobS
return rconn;
}
}
state Reference<IConnection> conn = wait(INetworkConnections::net()->connect(b->host, b->service.empty() ? "http" : b->service));
std::string service = b->service;
if (service.empty())
service = b->knobs.secure_connection ? "https" : "http";
state Reference<IConnection> conn = wait(INetworkConnections::net()->connect(b->host, service, b->knobs.secure_connection ? true : false));
TraceEvent("BlobStoreEndpointNewConnection")
.detail("RemoteEndpoint", conn->getPeerAddress())

View File

@ -48,7 +48,8 @@ public:
struct BlobKnobs {
BlobKnobs();
int connect_tries,
int secure_connection,
connect_tries,
connect_timeout,
max_connection_life,
request_tries,
@ -70,6 +71,7 @@ public:
std::string getURLParameters() const;
static std::vector<std::string> getKnobDescriptions() {
return {
"secure_connection (or sc) Set 1 for secure connection and 0 for insecure connection.",
"connect_tries (or ct) Number of times to try to connect for each request.",
"connect_timeout (or cto) Number of seconds to wait for a connect request to succeed.",
"max_connection_life (or mcl) Maximum number of seconds to use a single TCP connection.",

View File

@ -1,22 +1,22 @@
/*
* ITLSPlugin.h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
*
* Licensed 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.
*/
* ITLSPlugin.h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
*
* Licensed 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.
*/
#ifndef FDB_ITLSPLUGIN_H
#define FDB_ITLSPLUGIN_H
@ -51,20 +51,30 @@ struct ITLSSession {
// Returns the number of bytes sent (possibly 0), or -1 on error
// (including connection close)
typedef int (*TLSSendCallbackFunc)(void* ctx, const uint8_t* buf, int len);
typedef int(*TLSSendCallbackFunc)(void* ctx, const uint8_t* buf, int len);
// Returns the number of bytes read (possibly 0), or -1 on error
// (including connection close)
typedef int (*TLSRecvCallbackFunc)(void* ctx, uint8_t* buf, int len);
typedef int(*TLSRecvCallbackFunc)(void* ctx, uint8_t* buf, int len);
struct ITLSPolicy {
virtual void addref() = 0;
virtual void delref() = 0;
// set_ca_data should import the provided certificate list and
// associate it with this policy. cert_data will point to a PEM
// encoded certificate list of trust roots.
//
// set_ca_data should return true if the operation succeeded,
// and false otherwise. After the first call to create_session for
// a given policy, set_ca_data should immediately return false
// if called.
virtual bool set_ca_data(const uint8_t* ca_data, int ca_len) = 0;
// set_cert_data should import the provided certificate list and
// associate it with this policy. cert_data will point to a PEM
// encoded certificate list, ordered such that each certificate
// certifies the one befor it.
// certifies the one before it.
//
// cert_data may additionally contain key information, which must
// be ignored.
@ -77,7 +87,8 @@ struct ITLSPolicy {
// set_key_data should import the provided private key and
// associate it with this policy. key_data will point to a PEM
// encoded key.
// encoded key, which may be encrypted. If encrypted the password
// argument should be specified, otherwise it may be NULL.
//
// key_data may additionally contain certificate information,
// which must be ignored.
@ -86,7 +97,7 @@ struct ITLSPolicy {
// false otherwise. After the first call to create_session for a
// given policy, set_key_data should immediately return false if
// called.
virtual bool set_key_data(const uint8_t* key_data, int key_len) = 0;
virtual bool set_key_data(const uint8_t* key_data, int key_len, const char* password) = 0;
// set_verify_peers should modify the validation rules for
// verifying a peer during connection handshake. The format of
@ -96,7 +107,7 @@ struct ITLSPolicy {
// and false otherwise. After the first call to create_session for
// a given policy, set_verify_peers should immediately return
// false if called.
virtual bool set_verify_peers(const uint8_t* verify_peers, int verify_peers_len) = 0;
virtual bool set_verify_peers(int count, const uint8_t* verify_peers[], int verify_peers_len[]) = 0;
// create_session should return a new object that implements
// ITLSSession, associated with this policy. After the first call
@ -109,7 +120,7 @@ struct ITLSPolicy {
//
// uid should only be provided when invoking an ITLSLogFunc, which
// will use it to identify this session.
virtual ITLSSession* create_session(bool is_client, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid ) = 0;
virtual ITLSSession* create_session(bool is_client, const char *servername, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid) = 0;
};
// Logs a message/error to the appropriate trace log.
@ -120,7 +131,7 @@ struct ITLSPolicy {
// remaining arguments must be pairs of (const char*); the first of
// each pair must be a valid XML attribute name, and the second a
// valid XML attribute value. The final parameter must be NULL.
typedef void (*ITLSLogFunc)(const char* event, void* uid, int is_error, ...);
typedef void(*ITLSLogFunc)(const char* event, void* uid, bool is_error, ...);
struct ITLSPlugin {
virtual void addref() = 0;
@ -132,7 +143,7 @@ struct ITLSPlugin {
// The newly created policy, and any session further created from
// the policy, should use logf to log any messages or errors that
// occur.
virtual ITLSPolicy* create_policy( ITLSLogFunc logf ) = 0;
virtual ITLSPolicy* create_policy(ITLSLogFunc logf) = 0;
static inline const char* get_plugin_type_name_and_version() { return "ITLSPlugin"; }
};

View File

@ -26,6 +26,7 @@
#include "ITLSPlugin.h"
#include "LoadPlugin.h"
#include "Platform.h"
#include <memory>
// Must not throw an exception from this function!
static int send_func(void* ctx, const uint8_t* buf, int len) {
@ -83,8 +84,9 @@ ACTOR static Future<Void> handshake( TLSConnection* self ) {
return Void();
}
TLSConnection::TLSConnection( Reference<IConnection> const& conn, Reference<ITLSPolicy> const& policy, bool is_client ) : conn(conn), write_wants(0), read_wants(0), uid(conn->getDebugID()) {
session = Reference<ITLSSession>( policy->create_session(is_client, send_func, this, recv_func, this, (void*)&uid) );
TLSConnection::TLSConnection( Reference<IConnection> const& conn, Reference<ITLSPolicy> const& policy, bool is_client, std::string host) : conn(conn), write_wants(0), read_wants(0), uid(conn->getDebugID()) {
const char * serverName = host.empty() ? NULL : host.c_str();
session = Reference<ITLSSession>( policy->create_session(is_client, serverName, send_func, this, recv_func, this, (void*)&uid) );
if ( !session ) {
// If session is NULL, we're trusting policy->create_session
// to have used its provided logging function to have logged
@ -150,13 +152,13 @@ int TLSConnection::write( SendBuffer const* buffer, int limit ) {
return 0;
}
ACTOR Future<Reference<IConnection>> wrap( Reference<ITLSPolicy> policy, bool is_client, Future<Reference<IConnection>> c ) {
ACTOR Future<Reference<IConnection>> wrap( Reference<ITLSPolicy> policy, bool is_client, Future<Reference<IConnection>> c, std::string host) {
Reference<IConnection> conn = wait(c);
return Reference<IConnection>(new TLSConnection( conn, policy, is_client ));
return Reference<IConnection>(new TLSConnection( conn, policy, is_client, host ));
}
Future<Reference<IConnection>> TLSListener::accept() {
return wrap( policy, false, listener->accept() );
return wrap( policy, false, listener->accept(), "");
}
TLSNetworkConnections::TLSNetworkConnections( Reference<TLSOptions> options ) : options(options) {
@ -164,11 +166,14 @@ TLSNetworkConnections::TLSNetworkConnections( Reference<TLSOptions> options ) :
g_network->setGlobal(INetwork::enumGlobal::enNetworkConnections, (flowGlobalType) this);
}
Future<Reference<IConnection>> TLSNetworkConnections::connect( NetworkAddress toAddr ) {
Future<Reference<IConnection>> TLSNetworkConnections::connect( NetworkAddress toAddr, std::string host) {
if ( toAddr.isTLS() ) {
NetworkAddress clearAddr( toAddr.ip, toAddr.port, toAddr.isPublic(), false );
TraceEvent("TLSConnectionConnecting").detail("ToAddr", toAddr);
return wrap( options->get_policy(), true, network->connect( clearAddr ) );
if (host.empty() || host == toIPString(toAddr.ip))
return wrap(options->get_policy(TLSOptions::POLICY_VERIFY_PEERS), true, network->connect(clearAddr), std::string(""));
else
return wrap( options->get_policy(TLSOptions::POLICY_NO_VERIFY_PEERS), true, network->connect( clearAddr ), host );
}
return network->connect( toAddr );
}
@ -181,7 +186,7 @@ Reference<IListener> TLSNetworkConnections::listen( NetworkAddress localAddr ) {
if ( localAddr.isTLS() ) {
NetworkAddress clearAddr( localAddr.ip, localAddr.port, localAddr.isPublic(), false );
TraceEvent("TLSConnectionListening").detail("OnAddr", localAddr);
return Reference<IListener>(new TLSListener( options->get_policy(), network->listen( clearAddr ) ));
return Reference<IListener>(new TLSListener( options->get_policy(TLSOptions::POLICY_VERIFY_PEERS), network->listen( clearAddr ) ));
}
return network->listen( localAddr );
}
@ -206,17 +211,48 @@ void TLSOptions::set_cert_file( std::string const& cert_file ) {
}
}
void TLSOptions::set_ca_file(std::string const& ca_file) {
try {
TraceEvent("TLSConnectionSettingCAFile").detail("CAPath", ca_file);
set_ca_data(readFileBytes(ca_file, CERT_FILE_MAX_SIZE));
}
catch (Error&) {
TraceEvent(SevError, "TLSOptionsSetCertAError").detail("Filename", ca_file);
throw;
}
}
void TLSOptions::set_ca_data(std::string const& ca_data) {
if (!policyVerifyPeersSet || !policyVerifyPeersNotSet)
init_plugin();
TraceEvent("TLSConnectionSettingCAData").detail("CADataSize", ca_data.size());
if (!policyVerifyPeersSet->set_ca_data((const uint8_t*)&ca_data[0], ca_data.size()))
throw tls_error();
if (!policyVerifyPeersNotSet->set_ca_data((const uint8_t*)&ca_data[0], ca_data.size()))
throw tls_error();
ca_set = true;
}
void TLSOptions::set_cert_data( std::string const& cert_data ) {
if ( !policy )
if (!policyVerifyPeersSet || !policyVerifyPeersNotSet)
init_plugin();
TraceEvent("TLSConnectionSettingCertData").detail("CertDataSize", cert_data.size());
if ( !policy->set_cert_data( (const uint8_t*)&cert_data[0], cert_data.size() ) )
if ( !policyVerifyPeersSet->set_cert_data( (const uint8_t*)&cert_data[0], cert_data.size() ) )
throw tls_error();
if (!policyVerifyPeersNotSet->set_cert_data((const uint8_t*)&cert_data[0], cert_data.size()))
throw tls_error();
certs_set = true;
}
void TLSOptions::set_key_password(std::string const& password) {
TraceEvent("TLSConnectionSettingPassword");
keyPassword = password;
}
void TLSOptions::set_key_file( std::string const& key_file ) {
try {
TraceEvent("TLSConnectionSettingKeyFile").detail("KeyFilePath", key_file);
@ -228,22 +264,34 @@ void TLSOptions::set_key_file( std::string const& key_file ) {
}
void TLSOptions::set_key_data( std::string const& key_data ) {
if ( !policy )
if (!policyVerifyPeersSet || !policyVerifyPeersNotSet)
init_plugin();
const char *passphrase = keyPassword.empty() ? NULL : keyPassword.c_str();
TraceEvent("TLSConnectionSettingKeyData").detail("KeyDataSize", key_data.size());
if ( !policy->set_key_data( (const uint8_t*)&key_data[0], key_data.size() ) )
if ( !policyVerifyPeersSet->set_key_data( (const uint8_t*)&key_data[0], key_data.size(), passphrase) )
throw tls_error();
if (!policyVerifyPeersNotSet->set_key_data((const uint8_t*)&key_data[0], key_data.size(), passphrase))
throw tls_error();
key_set = true;
}
void TLSOptions::set_verify_peers( std::string const& verify_peers ) {
if ( !policy )
void TLSOptions::set_verify_peers( std::vector<std::string> const& verify_peers ) {
if (!policyVerifyPeersSet)
init_plugin();
{
TraceEvent e("TLSConnectionSettingVerifyPeers");
for (int i = 0; i < verify_peers.size(); i++)
e.detail(std::string("Value" + std::to_string(i)).c_str(), verify_peers[i].c_str());
}
std::unique_ptr<const uint8_t *[]> verify_peers_arr(new const uint8_t*[verify_peers.size()]);
std::unique_ptr<int[]> verify_peers_len(new int[verify_peers.size()]);
for (int i = 0; i < verify_peers.size(); i++) {
verify_peers_arr[i] = (const uint8_t *)&verify_peers[i][0];
verify_peers_len[i] = verify_peers[i].size();
}
TraceEvent("TLSConnectionSettingVerifyPeers").detail("Value", verify_peers);
if ( !policy->set_verify_peers( (const uint8_t*)&verify_peers[0], verify_peers.size() ) )
if (!policyVerifyPeersSet->set_verify_peers(verify_peers.size(), verify_peers_arr.get(), verify_peers_len.get()))
throw tls_error();
verify_peers_set = true;
@ -257,7 +305,7 @@ void TLSOptions::register_network() {
const char *defaultCertFileName = "fdb.pem";
Reference<ITLSPolicy> TLSOptions::get_policy() {
Reference<ITLSPolicy> TLSOptions::get_policy(PolicyType type) {
if ( !certs_set ) {
std::string certFile;
if ( !platform::getEnvironmentVar( "FDB_TLS_CERTIFICATE_FILE", certFile ) )
@ -272,14 +320,32 @@ Reference<ITLSPolicy> TLSOptions::get_policy() {
}
if( !verify_peers_set ) {
std::string verifyPeerString;
if ( platform::getEnvironmentVar( "FDB_TLS_VERIFY_PEERS", verifyPeerString ) )
set_verify_peers( verifyPeerString );
if (platform::getEnvironmentVar("FDB_TLS_VERIFY_PEERS", verifyPeerString))
set_verify_peers({ verifyPeerString });
else
set_verify_peers({ std::string("Check.Valid=0")});
}
if (!ca_set) {
std::string caFile;
if (platform::getEnvironmentVar("FDB_TLS_CA_FILE", caFile))
set_ca_file(caFile);
}
Reference<ITLSPolicy> policy;
switch (type) {
case POLICY_VERIFY_PEERS:
policy = policyVerifyPeersSet;
break;
case POLICY_NO_VERIFY_PEERS:
policy = policyVerifyPeersNotSet;
break;
default:
ASSERT_ABORT(0);
}
return policy;
}
static void TLSConnectionLogFunc( const char* event, void* uid_ptr, int is_error, ... ) {
static void TLSConnectionLogFunc( const char* event, void* uid_ptr, bool is_error, ... ) {
UID uid;
if ( uid_ptr )
@ -320,14 +386,21 @@ void TLSOptions::init_plugin( std::string const& plugin_path ) {
throw tls_error();
}
policy = Reference<ITLSPolicy>( plugin->create_policy( TLSConnectionLogFunc ) );
if ( !policy ) {
policyVerifyPeersSet = Reference<ITLSPolicy>( plugin->create_policy( TLSConnectionLogFunc ) );
if ( !policyVerifyPeersSet) {
// Hopefully create_policy logged something with the log func
TraceEvent(SevError, "TLSConnectionCreatePolicyError");
TraceEvent(SevError, "TLSConnectionCreatePolicyVerifyPeersSetError");
throw tls_error();
}
policyVerifyPeersNotSet = Reference<ITLSPolicy>(plugin->create_policy(TLSConnectionLogFunc));
if (!policyVerifyPeersNotSet) {
// Hopefully create_policy logged something with the log func
TraceEvent(SevError, "TLSConnectionCreatePolicyVerifyPeersNotSetError");
throw tls_error();
}
}
bool TLSOptions::enabled() {
return !!policy;
return !!policyVerifyPeersSet && !!policyVerifyPeersNotSet;
}

View File

@ -40,7 +40,7 @@ struct TLSConnection : IConnection, ReferenceCounted<TLSConnection> {
virtual void addref() { ReferenceCounted<TLSConnection>::addref(); }
virtual void delref() { ReferenceCounted<TLSConnection>::delref(); }
TLSConnection( Reference<IConnection> const& conn, Reference<ITLSPolicy> const& policy, bool is_client );
TLSConnection( Reference<IConnection> const& conn, Reference<ITLSPolicy> const& policy, bool is_client, std::string host);
~TLSConnection() {
// Here for ordering to make sure we delref the ITLSSession
// which has a pointer to this object
@ -80,28 +80,34 @@ struct TLSListener : IListener, ReferenceCounted<TLSListener> {
};
struct TLSOptions : ReferenceCounted<TLSOptions> {
enum { OPT_TLS = 100000, OPT_TLS_PLUGIN, OPT_TLS_CERTIFICATES, OPT_TLS_KEY, OPT_TLS_VERIFY_PEERS };
TLSOptions() : certs_set(false), key_set(false), verify_peers_set(false) {}
enum { OPT_TLS = 100000, OPT_TLS_PLUGIN, OPT_TLS_CERTIFICATES, OPT_TLS_KEY, OPT_TLS_VERIFY_PEERS, OPT_TLS_CA_FILE, OPT_TLS_PASSWORD };
enum PolicyType { POLICY_VERIFY_PEERS = 1, POLICY_NO_VERIFY_PEERS };
TLSOptions() : certs_set(false), key_set(false), verify_peers_set(false), ca_set(false) {}
void set_plugin_name_or_path( std::string const& plugin_name_or_path );
void set_cert_file( std::string const& cert_file );
void set_cert_data( std::string const& cert_data );
void set_ca_file(std::string const& ca_file);
void set_ca_data(std::string const& ca_data);
// If there is a passphrase, this api should be called prior to setting key for the passphrase to be used
void set_key_password( std::string const& password );
void set_key_file( std::string const& key_file );
void set_key_data( std::string const& key_data );
void set_verify_peers( std::string const& verify_peers );
void set_verify_peers( std::vector<std::string> const& verify_peers );
void register_network();
Reference<ITLSPolicy> get_policy();
Reference<ITLSPolicy> get_policy(PolicyType type);
bool enabled();
private:
void init_plugin( std::string const& plugin_path = "" );
Reference<ITLSPlugin> plugin;
Reference<ITLSPolicy> policy;
bool certs_set, key_set, verify_peers_set;
Reference<ITLSPolicy> policyVerifyPeersSet;
Reference<ITLSPolicy> policyVerifyPeersNotSet;
bool certs_set, key_set, verify_peers_set, ca_set;
std::string keyPassword;
};
struct TLSNetworkConnections : INetworkConnections {
@ -109,7 +115,7 @@ struct TLSNetworkConnections : INetworkConnections {
explicit TLSNetworkConnections( Reference<TLSOptions> options );
virtual Future<Reference<IConnection>> connect( NetworkAddress toAddr );
virtual Future<Reference<IConnection>> connect( NetworkAddress toAddr, std::string host );
virtual Future<std::vector<NetworkAddress>> resolveTCPEndpoint( std::string host, std::string service);
virtual Reference<IListener> listen( NetworkAddress localAddr );
@ -122,12 +128,16 @@ private:
#define TLS_CERTIFICATE_FILE_FLAG "--tls_certificate_file"
#define TLS_KEY_FILE_FLAG "--tls_key_file"
#define TLS_VERIFY_PEERS_FLAG "--tls_verify_peers"
#define TLS_CA_FILE_FLAG "--tls_ca_file"
#define TLS_PASSWORD_FLAG "--tls_password"
#define TLS_OPTION_FLAGS \
{ TLSOptions::OPT_TLS_PLUGIN, TLS_PLUGIN_FLAG, SO_OPT }, \
{ TLSOptions::OPT_TLS_CERTIFICATES, TLS_CERTIFICATE_FILE_FLAG, SO_REQ_SEP }, \
{ TLSOptions::OPT_TLS_KEY, TLS_KEY_FILE_FLAG, SO_REQ_SEP }, \
{ TLSOptions::OPT_TLS_VERIFY_PEERS, TLS_VERIFY_PEERS_FLAG, SO_REQ_SEP },
{ TLSOptions::OPT_TLS_VERIFY_PEERS, TLS_VERIFY_PEERS_FLAG, SO_REQ_SEP }, \
{ TLSOptions::OPT_TLS_PASSWORD, TLS_PASSWORD_FLAG, SO_REQ_SEP }, \
{ TLSOptions::OPT_TLS_CA_FILE, TLS_CA_FILE_FLAG, SO_REQ_SEP },
#define TLS_HELP \
" " TLS_PLUGIN_FLAG " PLUGIN\n" \
@ -138,9 +148,13 @@ private:
" " TLS_CERTIFICATE_FILE_FLAG " CERTFILE\n" \
" The path of a file containing the TLS certificate and CA\n" \
" chain.\n" \
" " TLS_CA_FILE_FLAG " CERTAUTHFILE\n" \
" The path of a file containing the CA certificates chain.\n" \
" " TLS_KEY_FILE_FLAG " KEYFILE\n" \
" The path of a file containing the private key corresponding\n" \
" to the TLS certificate.\n" \
" " TLS_PASSWORD_FLAG " PASSCODE\n" \
" The passphrase of encrypted private key\n" \
" " TLS_VERIFY_PEERS_FLAG " CONSTRAINTS\n" \
" The constraints by which to validate TLS peers. The contents\n" \
" and format of CONSTRAINTS are plugin-specific.\n"

View File

@ -772,8 +772,8 @@ public:
currentTaskID = taskID;
}
// Sets the taskID/priority of the current task, without yielding
virtual Future<Reference<IConnection>> connect( NetworkAddress toAddr ) {
ASSERT( !toAddr.isTLS() );
virtual Future<Reference<IConnection>> connect( NetworkAddress toAddr, std::string host ) {
ASSERT( !toAddr.isTLS() && host.empty());
if (!addressMap.count( toAddr )) {
return waitForProcessAndConnect( toAddr, this );
}

View File

@ -263,10 +263,10 @@ struct ResolutionRequestBuilder {
bool isTXNStateTransaction = false;
for (auto & m : trIn.mutations) {
if (m.type == MutationRef::SetVersionstampedKey) {
transformSetVersionstampedKey( m, requests[0].version, transactionNumberInBatch );
transformVersionstampMutation( m, &MutationRef::param1, requests[0].version, transactionNumberInBatch );
trIn.write_conflict_ranges.push_back( requests[0].arena, singleKeyRange( m.param1, requests[0].arena ) );
} else if (m.type == MutationRef::SetVersionstampedValue ) {
transformSetVersionstampedValue( m, requests[0].version, transactionNumberInBatch );
} else if (m.type == MutationRef::SetVersionstampedValue) {
transformVersionstampMutation( m, &MutationRef::param2, requests[0].version, transactionNumberInBatch );
}
if (isMetadataMutation(m)) {
isTXNStateTransaction = true;

View File

@ -868,7 +868,8 @@ int main(int argc, char* argv[]) {
bool testOnServers = false;
Reference<TLSOptions> tlsOptions = Reference<TLSOptions>( new TLSOptions );
std::string tlsCertPath, tlsKeyPath, tlsVerifyPeers;
std::string tlsCertPath, tlsKeyPath, tlsCAPath, tlsPassword;
std::vector<std::string> tlsVerifyPeers;
double fileIoTimeout = 0.0;
bool fileIoWarnOnly = false;
@ -1203,11 +1204,17 @@ int main(int argc, char* argv[]) {
case TLSOptions::OPT_TLS_CERTIFICATES:
tlsCertPath = args.OptionArg();
break;
case TLSOptions::OPT_TLS_PASSWORD:
tlsPassword = args.OptionArg();
break;
case TLSOptions::OPT_TLS_CA_FILE:
tlsCAPath = args.OptionArg();
break;
case TLSOptions::OPT_TLS_KEY:
tlsKeyPath = args.OptionArg();
break;
case TLSOptions::OPT_TLS_VERIFY_PEERS:
tlsVerifyPeers = args.OptionArg();
tlsVerifyPeers.push_back(args.OptionArg());
break;
}
}
@ -1467,8 +1474,14 @@ int main(int argc, char* argv[]) {
if ( tlsCertPath.size() )
tlsOptions->set_cert_file( tlsCertPath );
if ( tlsKeyPath.size() )
tlsOptions->set_key_file( tlsKeyPath );
if (tlsCAPath.size())
tlsOptions->set_ca_file(tlsCAPath);
if (tlsKeyPath.size()) {
if (tlsPassword.size())
tlsOptions->set_key_password(tlsPassword);
tlsOptions->set_key_file(tlsKeyPath);
}
if ( tlsVerifyPeers.size() )
tlsOptions->set_verify_peers( tlsVerifyPeers );

View File

@ -23,6 +23,7 @@
#include "fdbclient/BackupAgent.h"
#include "workloads.h"
#include "BulkSetup.actor.h"
#include "fdbclient/ManagementAPI.h"
//A workload which test the correctness of upgrading DR from 5.1 to 5.2
struct BackupToDBUpgradeWorkload : TestWorkload {
@ -266,12 +267,87 @@ struct BackupToDBUpgradeWorkload : TestWorkload {
return Void();
}
ACTOR static Future<Void> diffRanges(Standalone<VectorRef<KeyRangeRef>> ranges, StringRef backupPrefix, Database src, Database dest) {
state int rangeIndex;
for (rangeIndex = 0; rangeIndex < ranges.size(); ++rangeIndex) {
state KeyRangeRef range = ranges[rangeIndex];
state Key begin = range.begin;
if(range.empty()) {
continue;
}
loop {
state Transaction tr(src);
state Transaction tr2(dest);
try {
loop {
tr.setOption(FDBTransactionOptions::LOCK_AWARE);
tr2.setOption(FDBTransactionOptions::LOCK_AWARE);
state Future<Standalone<RangeResultRef>> srcFuture = tr.getRange(KeyRangeRef(begin, range.end), 1000);
state Future<Standalone<RangeResultRef>> bkpFuture = tr2.getRange(KeyRangeRef(begin, range.end).withPrefix(backupPrefix), 1000);
Void _ = wait(success(srcFuture) && success(bkpFuture));
auto src = srcFuture.get().begin();
auto bkp = bkpFuture.get().begin();
while (src != srcFuture.get().end() && bkp != bkpFuture.get().end()) {
KeyRef bkpKey = bkp->key.substr(backupPrefix.size());
if (src->key != bkpKey && src->value != bkp->value) {
TraceEvent(SevError, "MismatchKeyAndValue").detail("srcKey", printable(src->key)).detail("srcVal", printable(src->value)).detail("bkpKey", printable(bkpKey)).detail("bkpVal", printable(bkp->value));
}
else if (src->key != bkpKey) {
TraceEvent(SevError, "MismatchKey").detail("srcKey", printable(src->key)).detail("srcVal", printable(src->value)).detail("bkpKey", printable(bkpKey)).detail("bkpVal", printable(bkp->value));
}
else if (src->value != bkp->value) {
TraceEvent(SevError, "MismatchValue").detail("srcKey", printable(src->key)).detail("srcVal", printable(src->value)).detail("bkpKey", printable(bkpKey)).detail("bkpVal", printable(bkp->value));
}
begin = std::min(src->key, bkpKey);
if (src->key == bkpKey) {
++src;
++bkp;
}
else if (src->key < bkpKey) {
++src;
}
else {
++bkp;
}
}
while (src != srcFuture.get().end() && !bkpFuture.get().more) {
TraceEvent(SevError, "MissingBkpKey").detail("srcKey", printable(src->key)).detail("srcVal", printable(src->value));
begin = src->key;
++src;
}
while (bkp != bkpFuture.get().end() && !srcFuture.get().more) {
TraceEvent(SevError, "MissingSrcKey").detail("bkpKey", printable(bkp->key.substr(backupPrefix.size()))).detail("bkpVal", printable(bkp->value));
begin = bkp->key;
++bkp;
}
if (!srcFuture.get().more && !bkpFuture.get().more) {
break;
}
begin = keyAfter(begin);
}
break;
}
catch (Error &e) {
Void _ = wait(tr.onError(e));
}
}
}
return Void();
}
ACTOR static Future<Void> _start(Database cx, BackupToDBUpgradeWorkload* self) {
state DatabaseBackupAgent backupAgent(cx);
state DatabaseBackupAgent restoreAgent(self->extraDB);
state Future<Void> disabler = disableConnectionFailuresAfter(300, "BackupToDBUpgradeStart");
state Standalone<VectorRef<KeyRangeRef>> prevBackupRanges;
state UID logUid;
state Version commitVersion;
state Future<Void> stopDifferential = delay(self->stopDifferentialAfter);
state Future<Void> waitUpgrade = backupAgent.waitUpgradeToLatestDrVersion(self->extraDB, self->backupTag);
@ -292,16 +368,47 @@ struct BackupToDBUpgradeWorkload : TestWorkload {
ASSERT(backupKeysPacked.present());
BinaryReader br(backupKeysPacked.get(), IncludeVersion());
prevBackupRanges = Standalone<VectorRef<KeyRangeRef>>();
br >> prevBackupRanges;
Void _ = wait( lockDatabase(tr, logUid) );
tr->addWriteConflictRange(singleKeyRange(StringRef()));
Void _ = wait( tr->commit() );
commitVersion = tr->getCommittedVersion();
break;
} catch( Error &e ) {
Void _ = wait( tr->onError(e) );
}
}
TraceEvent("DRU_locked").detail("lockedVersion", commitVersion);
// Wait for the destination to apply mutations up to the lock commit before switching over.
state ReadYourWritesTransaction versionCheckTr(self->extraDB);
loop {
try {
versionCheckTr.setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS);
versionCheckTr.setOption(FDBTransactionOptions::LOCK_AWARE);
Optional<Value> v = wait(versionCheckTr.get(BinaryWriter::toValue(logUid, Unversioned()).withPrefix(applyMutationsBeginRange.begin)));
TraceEvent("DRU_applied").detail("appliedVersion", v.present() ? BinaryReader::fromStringRef<Version>(v.get(), Unversioned()) : -1);
if( v.present() && BinaryReader::fromStringRef<Version>(v.get(), Unversioned()) >= commitVersion)
break;
state Future<Void> versionWatch = versionCheckTr.watch(BinaryWriter::toValue(logUid, Unversioned()).withPrefix(applyMutationsBeginRange.begin));
Void _ = wait(versionCheckTr.commit());
Void _ = wait(versionWatch);
versionCheckTr.reset();
} catch( Error &e ) {
Void _ = wait(versionCheckTr.onError(e));
}
}
TraceEvent("DRU_diffRanges");
Void _ = wait( diffRanges(prevBackupRanges, self->backupPrefix, cx, self->extraDB ) );
// abort backup
TraceEvent("DRU_abortBackup").detail("tag", printable(self->backupTag));
Void _ = wait(backupAgent.abortBackup(self->extraDB, self->backupTag));
Void _ = wait( unlockDatabase(self->extraDB, logUid) );
// restore database
TraceEvent("DRU_prepareRestore").detail("restoreTag", printable(self->restoreTag));

View File

@ -820,7 +820,7 @@ struct FuzzApiCorrectnessWorkload : TestWorkload {
Key key;
Value value;
uint8_t op;
int16_t pos;
int32_t pos;
TestAtomicOp(unsigned int id, FuzzApiCorrectnessWorkload *workload) : BaseTestCallback(id, workload, "TestAtomicOp") {
key = makeKey();
@ -853,8 +853,11 @@ struct FuzzApiCorrectnessWorkload : TestWorkload {
}
pos = -1;
if(op == MutationRef::SetVersionstampedKey && key.size() >= 2) {
pos = littleEndian16(*(int16_t*)&key.end()[-2]);
if(op == MutationRef::SetVersionstampedKey && key.size() >= 4) {
pos = littleEndian32(*(int32_t*)&key.end()[-4]);
}
if(op == MutationRef::SetVersionstampedValue && value.size() >= 4) {
pos = littleEndian32(*(int32_t*)&value.end()[-4]);
}
contract = {
@ -865,8 +868,8 @@ struct FuzzApiCorrectnessWorkload : TestWorkload {
std::make_pair( error_code_key_outside_legal_range, ExceptionContract::requiredIf(
(key >= (workload->useSystemKeys ? systemKeys.end : normalKeys.end))) ),
std::make_pair( error_code_client_invalid_operation, ExceptionContract::requiredIf(
(op == MutationRef::SetVersionstampedValue && value.size() < 10) ||
(op == MutationRef::SetVersionstampedKey && (pos < 0 || pos + 10 > key.size() - 2))) )
(op == MutationRef::SetVersionstampedKey && (pos < 0 || pos + 10 > key.size() - 4)) ||
(op == MutationRef::SetVersionstampedValue && (pos < 0 || pos + 10 > value.size() - 4))) )
};
}

View File

@ -76,15 +76,17 @@ struct VersionStampWorkload : TestWorkload {
}
Key versionStampKeyForIndex(uint64_t index) {
Key result = makeString(38);
Key result = makeString(40);
uint8_t* data = mutateString(result);
memset(&data[0], 'V', 38);
memset(&data[0], 'V', 40);
double d = double(index) / nodeCount;
emplaceIndex(data, 4, *(int64_t*)&d);
data[38 - 2] = 24 + vsKeyPrefix.size();
data[38 - 1] = 0;
data[40 - 4] = 24 + vsKeyPrefix.size();
data[40 - 3] = 0;
data[40 - 2] = 0;
data[40 - 1] = 0;
return result.withPrefix(vsKeyPrefix);
}
@ -232,11 +234,15 @@ struct VersionStampWorkload : TestWorkload {
state KeyRangeRef range(prefix, endOfRange);
state Standalone<StringRef> committedVersionStamp;
state Version committedVersion;
bool useVersionstampPos = (g_random->random01() < 0.5);
state Value versionStampValue = value.withSuffix(LiteralStringRef("\x00\x00\x00\x00"));
loop{
state bool error = false;
//TraceEvent("VST_commit_begin").detail("key", printable(key)).detail("vsKey", printable(versionStampKey)).detail("clear", printable(range));
try {
tr.atomicOp(key, value, MutationRef::SetVersionstampedValue);
tr.atomicOp(key, versionStampValue, MutationRef::SetVersionstampedValue);
tr.clear(range);
tr.atomicOp(versionStampKey, value, MutationRef::SetVersionstampedKey);
state Future<Standalone<StringRef>> fTrVs = tr.getVersionstamp();

View File

@ -512,11 +512,11 @@ struct WriteDuringReadWorkload : TestWorkload {
}
Key versionStampKeyForIndex( int idx ) {
Key result = KeyRef( getKeyForIndex(idx).toString() + std::string(12,'\x00') );
int16_t pos = g_random->randomInt(0, result.size() - 11);
pos = littleEndian16(pos);
Key result = KeyRef( getKeyForIndex(idx).toString() + std::string(14,'\x00') );
int32_t pos = g_random->randomInt(0, result.size() - 13);
pos = littleEndian32(pos);
uint8_t* data = mutateString(result);
memcpy(data+result.size()-sizeof(int16_t), &pos, sizeof(int16_t));
memcpy(data+result.size()-sizeof(int32_t), &pos, sizeof(int32_t));
return result;
}

View File

@ -429,9 +429,22 @@ public:
return StringRef(s,prefix.size() + size());
}
StringRef withSuffix( const StringRef& suffix, Arena& arena ) const {
uint8_t* s = new (arena) uint8_t[ suffix.size() + size() ];
memcpy(s, begin(), size());
memcpy(s+size(), suffix.begin(), suffix.size());
return StringRef(s,suffix.size() + size());
}
Standalone<StringRef> withPrefix( const StringRef& prefix ) const {
Standalone<StringRef> r;
((StringRef &)r) = withPrefix(prefix, r.arena());
r.contents() = withPrefix(prefix, r.arena());
return r;
}
Standalone<StringRef> withSuffix( const StringRef& suffix ) const {
Standalone<StringRef> r;
r.contents() = withSuffix(suffix, r.arena());
return r;
}
@ -441,6 +454,12 @@ public:
return substr( s.size() );
}
StringRef removeSuffix( const StringRef& s ) const {
// pre: endsWith(s)
UNSTOPPABLE_ASSERT( s.size() <= size() ); //< In debug mode, we could check endsWith()
return substr( 0, size() - s.size() );
}
std::string toString() const { return std::string( (const char*)data, length ); }
std::string printable() const {
std::string s;

View File

@ -122,7 +122,7 @@ public:
void initMetrics();
// INetworkConnections interface
virtual Future<Reference<IConnection>> connect( NetworkAddress toAddr );
virtual Future<Reference<IConnection>> connect( NetworkAddress toAddr, std::string host );
virtual Future<std::vector<NetworkAddress>> resolveTCPEndpoint( std::string host, std::string service);
virtual Reference<IListener> listen( NetworkAddress localAddr );
@ -829,7 +829,7 @@ THREAD_HANDLE Net2::startThread( THREAD_FUNC_RETURN (*func) (void*), void *arg )
}
Future< Reference<IConnection> > Net2::connect( NetworkAddress toAddr ) {
Future< Reference<IConnection> > Net2::connect( NetworkAddress toAddr, std::string host ) {
return Connection::connect(&this->reactor.ios, toAddr);
}

View File

@ -79,6 +79,6 @@ Future<Reference<IConnection>> INetworkConnections::connect( std::string host, s
// Template types are being provided explicitly because they can't be automatically deduced for some reason.
return mapAsync<NetworkAddress, std::function<Future<Reference<IConnection>>(NetworkAddress const &)>, Reference<IConnection> >
(pickEndpoint, [=](NetworkAddress const &addr) -> Future<Reference<IConnection>> {
return connect(addr);
return connect(addr, host);
});
}

View File

@ -270,7 +270,7 @@ public:
// security to override only these operations without having to delegate everything in INetwork.
// Make an outgoing connection to the given address. May return an error or block indefinitely in case of connection problems!
virtual Future<Reference<IConnection>> connect( NetworkAddress toAddr ) = 0;
virtual Future<Reference<IConnection>> connect( NetworkAddress toAddr, std::string host = "") = 0;
// Resolve host name and service name (such as "http" or can be a plain number like "80") to a list of 1 or more NetworkAddresses
virtual Future<std::vector<NetworkAddress>> resolveTCPEndpoint( std::string host, std::string service ) = 0;