tls: use SSL_set_cert_cb
for async SNI/OCSP
Do not enable ClientHello parser for async SNI/OCSP. Use new OpenSSL-1.0.2's API `SSL_set_cert_cb` to pause the handshake process and load the cert/OCSP response asynchronously. Hopefuly this will make whole async SNI/OCSP process much faster and will eventually let us remove the ClientHello parser itself (which is currently used only for async session, see #1462 for the discussion of removing it). NOTE: Ported our code to `SSL_CTX_add1_chain_cert` to use `SSL_CTX_get0_chain_certs` in `CertCbDone`. Test provided for this feature. Fix: https://github.com/iojs/io.js/issues/1423 PR-URL: https://github.com/iojs/io.js/pull/1464 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
This commit is contained in:
parent
30b7349176
commit
550c2638c0
@ -141,29 +141,23 @@ function onclienthello(hello) {
|
||||
if (err)
|
||||
return self.destroy(err);
|
||||
|
||||
// Servername came from SSL session
|
||||
// NOTE: TLS Session ticket doesn't include servername information
|
||||
//
|
||||
// Another note, From RFC3546:
|
||||
//
|
||||
// If, on the other hand, the older
|
||||
// session is resumed, then the server MUST ignore extensions appearing
|
||||
// in the client hello, and send a server hello containing no
|
||||
// extensions; in this case the extension functionality negotiated
|
||||
// during the original session initiation is applied to the resumed
|
||||
// session.
|
||||
//
|
||||
// Therefore we should account session loading when dealing with servername
|
||||
var servername = session && session.servername || hello.servername;
|
||||
loadSNI(self, servername, function(err, ctx) {
|
||||
self._handle.endParser();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function oncertcb(info) {
|
||||
var self = this;
|
||||
var servername = info.servername;
|
||||
|
||||
loadSNI(self, servername, function(err, ctx) {
|
||||
if (err)
|
||||
return self.destroy(err);
|
||||
requestOCSP(self, info, ctx, function(err) {
|
||||
if (err)
|
||||
return self.destroy(err);
|
||||
requestOCSP(self, hello, ctx, function(err) {
|
||||
if (err)
|
||||
return self.destroy(err);
|
||||
|
||||
self._handle.endParser();
|
||||
});
|
||||
self._handle.certCbDone();
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -333,15 +327,18 @@ TLSSocket.prototype._init = function(socket, wrap) {
|
||||
ssl.onhandshakestart = onhandshakestart.bind(this);
|
||||
ssl.onhandshakedone = onhandshakedone.bind(this);
|
||||
ssl.onclienthello = onclienthello.bind(this);
|
||||
ssl.oncertcb = oncertcb.bind(this);
|
||||
ssl.onnewsession = onnewsession.bind(this);
|
||||
ssl.lastHandshakeTime = 0;
|
||||
ssl.handshakes = 0;
|
||||
|
||||
if (this.server &&
|
||||
(listenerCount(this.server, 'resumeSession') > 0 ||
|
||||
listenerCount(this.server, 'newSession') > 0 ||
|
||||
listenerCount(this.server, 'OCSPRequest') > 0)) {
|
||||
ssl.enableSessionCallbacks();
|
||||
if (this.server) {
|
||||
if (listenerCount(this.server, 'resumeSession') > 0 ||
|
||||
listenerCount(this.server, 'newSession') > 0) {
|
||||
ssl.enableSessionCallbacks();
|
||||
}
|
||||
if (listenerCount(this.server, 'OCSPRequest') > 0)
|
||||
ssl.enableCertCb();
|
||||
}
|
||||
} else {
|
||||
ssl.onhandshakestart = function() {};
|
||||
@ -382,7 +379,7 @@ TLSSocket.prototype._init = function(socket, wrap) {
|
||||
options.server._contexts.length)) {
|
||||
assert(typeof options.SNICallback === 'function');
|
||||
this._SNICallback = options.SNICallback;
|
||||
ssl.enableHelloParser();
|
||||
ssl.enableCertCb();
|
||||
}
|
||||
|
||||
if (process.features.tls_npn && options.NPNProtocols)
|
||||
|
@ -55,6 +55,7 @@ namespace node {
|
||||
V(bytes_parsed_string, "bytesParsed") \
|
||||
V(callback_string, "callback") \
|
||||
V(change_string, "change") \
|
||||
V(oncertcb_string, "oncertcb") \
|
||||
V(onclose_string, "_onclose") \
|
||||
V(code_string, "code") \
|
||||
V(compare_string, "compare") \
|
||||
|
@ -132,6 +132,8 @@ template int SSLWrap<TLSWrap>::SelectNextProtoCallback(
|
||||
#endif
|
||||
template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void* arg);
|
||||
template void SSLWrap<TLSWrap>::DestroySSL();
|
||||
template int SSLWrap<TLSWrap>::SSLCertCallback(SSL* s, void* arg);
|
||||
template void SSLWrap<TLSWrap>::WaitForCertCb(CertCb cb, void* arg);
|
||||
|
||||
|
||||
static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
|
||||
@ -511,7 +513,8 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
|
||||
}
|
||||
|
||||
while ((ca = PEM_read_bio_X509(in, nullptr, CryptoPemCallback, nullptr))) {
|
||||
r = SSL_CTX_add_extra_chain_cert(ctx, ca);
|
||||
// NOTE: Increments reference count on `ca`
|
||||
r = SSL_CTX_add1_chain_cert(ctx, ca);
|
||||
|
||||
if (!r) {
|
||||
X509_free(ca);
|
||||
@ -987,6 +990,7 @@ void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
|
||||
env->SetProtoMethod(t, "verifyError", VerifyError);
|
||||
env->SetProtoMethod(t, "getCurrentCipher", GetCurrentCipher);
|
||||
env->SetProtoMethod(t, "endParser", EndParser);
|
||||
env->SetProtoMethod(t, "certCbDone", CertCbDone);
|
||||
env->SetProtoMethod(t, "renegotiate", Renegotiate);
|
||||
env->SetProtoMethod(t, "shutdownSSL", Shutdown);
|
||||
env->SetProtoMethod(t, "getTLSTicket", GetTLSTicket);
|
||||
@ -1869,6 +1873,122 @@ int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
|
||||
#endif // NODE__HAVE_TLSEXT_STATUS_CB
|
||||
|
||||
|
||||
template <class Base>
|
||||
void SSLWrap<Base>::WaitForCertCb(CertCb cb, void* arg) {
|
||||
cert_cb_ = cb;
|
||||
cert_cb_arg_ = arg;
|
||||
}
|
||||
|
||||
|
||||
template <class Base>
|
||||
int SSLWrap<Base>::SSLCertCallback(SSL* s, void* arg) {
|
||||
Base* w = static_cast<Base*>(SSL_get_app_data(s));
|
||||
|
||||
if (!w->is_server())
|
||||
return 1;
|
||||
|
||||
if (!w->is_waiting_cert_cb())
|
||||
return 1;
|
||||
|
||||
if (w->cert_cb_running_)
|
||||
return -1;
|
||||
|
||||
Environment* env = w->env();
|
||||
HandleScope handle_scope(env->isolate());
|
||||
Context::Scope context_scope(env->context());
|
||||
w->cert_cb_running_ = true;
|
||||
|
||||
Local<Object> info = Object::New(env->isolate());
|
||||
|
||||
SSL_SESSION* sess = SSL_get_session(s);
|
||||
if (sess != nullptr) {
|
||||
if (sess->tlsext_hostname == nullptr) {
|
||||
info->Set(env->servername_string(), String::Empty(env->isolate()));
|
||||
} else {
|
||||
Local<String> servername = OneByteString(env->isolate(),
|
||||
sess->tlsext_hostname,
|
||||
strlen(sess->tlsext_hostname));
|
||||
info->Set(env->servername_string(), servername);
|
||||
}
|
||||
info->Set(env->tls_ticket_string(),
|
||||
Boolean::New(env->isolate(), sess->tlsext_ticklen != 0));
|
||||
}
|
||||
bool ocsp = s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp;
|
||||
info->Set(env->ocsp_request_string(), Boolean::New(env->isolate(), ocsp));
|
||||
|
||||
Local<Value> argv[] = { info };
|
||||
w->MakeCallback(env->oncertcb_string(), ARRAY_SIZE(argv), argv);
|
||||
|
||||
if (!w->cert_cb_running_)
|
||||
return 1;
|
||||
|
||||
// Performing async action, wait...
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
template <class Base>
|
||||
void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
|
||||
Base* w = Unwrap<Base>(args.Holder());
|
||||
Environment* env = w->env();
|
||||
|
||||
CHECK(w->is_waiting_cert_cb() && w->cert_cb_running_);
|
||||
|
||||
Local<Object> object = w->object();
|
||||
Local<Value> ctx = object->Get(env->sni_context_string());
|
||||
Local<FunctionTemplate> cons = env->secure_context_constructor_template();
|
||||
|
||||
// Not an object, probably undefined or null
|
||||
if (!ctx->IsObject())
|
||||
goto fire_cb;
|
||||
|
||||
if (cons->HasInstance(ctx)) {
|
||||
SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
|
||||
w->sni_context_.Reset();
|
||||
w->sni_context_.Reset(env->isolate(), ctx);
|
||||
|
||||
int rv;
|
||||
|
||||
// NOTE: reference count is not increased by this API methods
|
||||
X509* x509 = SSL_CTX_get0_certificate(sc->ctx_);
|
||||
EVP_PKEY* pkey = SSL_CTX_get0_privatekey(sc->ctx_);
|
||||
STACK_OF(X509)* chain;
|
||||
|
||||
rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain);
|
||||
if (rv)
|
||||
rv = SSL_use_certificate(w->ssl_, x509);
|
||||
if (rv)
|
||||
rv = SSL_use_PrivateKey(w->ssl_, pkey);
|
||||
if (rv && chain != nullptr)
|
||||
rv = SSL_set1_chain(w->ssl_, chain);
|
||||
if (!rv) {
|
||||
unsigned long err = ERR_get_error();
|
||||
if (!err)
|
||||
return env->ThrowError("CertCbDone");
|
||||
return ThrowCryptoError(env, err);
|
||||
}
|
||||
} else {
|
||||
// Failure: incorrect SNI context object
|
||||
Local<Value> err = Exception::TypeError(env->sni_context_err_string());
|
||||
w->MakeCallback(env->onerror_string(), 1, &err);
|
||||
return;
|
||||
}
|
||||
|
||||
fire_cb:
|
||||
CertCb cb;
|
||||
void* arg;
|
||||
|
||||
cb = w->cert_cb_;
|
||||
arg = w->cert_cb_arg_;
|
||||
|
||||
w->cert_cb_running_ = false;
|
||||
w->cert_cb_ = nullptr;
|
||||
w->cert_cb_arg_ = nullptr;
|
||||
|
||||
cb(arg);
|
||||
}
|
||||
|
||||
|
||||
template <class Base>
|
||||
void SSLWrap<Base>::SSLGetter(Local<String> property,
|
||||
const PropertyCallbackInfo<Value>& info) {
|
||||
@ -1975,6 +2095,10 @@ int Connection::HandleSSLError(const char* func,
|
||||
DEBUG_PRINT("[%p] SSL: %s want read\n", ssl_, func);
|
||||
return 0;
|
||||
|
||||
} else if (err == SSL_ERROR_WANT_X509_LOOKUP) {
|
||||
DEBUG_PRINT("[%p] SSL: %s want x509 lookup\n", ssl_, func);
|
||||
return 0;
|
||||
|
||||
} else if (err == SSL_ERROR_ZERO_RETURN) {
|
||||
HandleScope scope(ssl_env()->isolate());
|
||||
|
||||
@ -2140,7 +2264,7 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
|
||||
|
||||
// Call the SNI callback and use its return value as context
|
||||
if (!conn->sniObject_.IsEmpty()) {
|
||||
conn->sniContext_.Reset();
|
||||
conn->sni_context_.Reset();
|
||||
|
||||
Local<Value> arg = PersistentToLocal(env->isolate(), conn->servername_);
|
||||
Local<Value> ret = conn->MakeCallback(env->onselect_string(), 1, &arg);
|
||||
@ -2149,7 +2273,7 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
|
||||
Local<FunctionTemplate> secure_context_constructor_template =
|
||||
env->secure_context_constructor_template();
|
||||
if (secure_context_constructor_template->HasInstance(ret)) {
|
||||
conn->sniContext_.Reset(env->isolate(), ret);
|
||||
conn->sni_context_.Reset(env->isolate(), ret);
|
||||
SecureContext* sc = Unwrap<SecureContext>(ret.As<Object>());
|
||||
InitNPN(sc);
|
||||
SSL_set_SSL_CTX(s, sc->ctx_);
|
||||
@ -2188,6 +2312,8 @@ void Connection::New(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
InitNPN(sc);
|
||||
|
||||
SSL_set_cert_cb(conn->ssl_, SSLWrap<Connection>::SSLCertCallback, conn);
|
||||
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
|
||||
if (is_server) {
|
||||
SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
|
||||
|
@ -143,7 +143,10 @@ class SSLWrap {
|
||||
kind_(kind),
|
||||
next_sess_(nullptr),
|
||||
session_callbacks_(false),
|
||||
new_session_wait_(false) {
|
||||
new_session_wait_(false),
|
||||
cert_cb_(nullptr),
|
||||
cert_cb_arg_(nullptr),
|
||||
cert_cb_running_(false) {
|
||||
ssl_ = SSL_new(sc->ctx_);
|
||||
env_->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
|
||||
CHECK_NE(ssl_, nullptr);
|
||||
@ -160,6 +163,9 @@ class SSLWrap {
|
||||
npn_protos_.Reset();
|
||||
selected_npn_proto_.Reset();
|
||||
#endif
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
|
||||
sni_context_.Reset();
|
||||
#endif
|
||||
#ifdef NODE__HAVE_TLSEXT_STATUS_CB
|
||||
ocsp_response_.Reset();
|
||||
#endif // NODE__HAVE_TLSEXT_STATUS_CB
|
||||
@ -170,8 +176,11 @@ class SSLWrap {
|
||||
inline bool is_server() const { return kind_ == kServer; }
|
||||
inline bool is_client() const { return kind_ == kClient; }
|
||||
inline bool is_waiting_new_session() const { return new_session_wait_; }
|
||||
inline bool is_waiting_cert_cb() const { return cert_cb_ != nullptr; }
|
||||
|
||||
protected:
|
||||
typedef void (*CertCb)(void* arg);
|
||||
|
||||
// Size allocated by OpenSSL: one for SSL structure, one for SSL3_STATE and
|
||||
// some for buffers.
|
||||
// NOTE: Actually it is much more than this
|
||||
@ -199,6 +208,7 @@ class SSLWrap {
|
||||
static void VerifyError(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void GetCurrentCipher(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void EndParser(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void CertCbDone(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void Renegotiate(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void Shutdown(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void GetTLSTicket(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
@ -227,10 +237,12 @@ class SSLWrap {
|
||||
void* arg);
|
||||
#endif // OPENSSL_NPN_NEGOTIATED
|
||||
static int TLSExtStatusCallback(SSL* s, void* arg);
|
||||
static int SSLCertCallback(SSL* s, void* arg);
|
||||
static void SSLGetter(v8::Local<v8::String> property,
|
||||
const v8::PropertyCallbackInfo<v8::Value>& info);
|
||||
|
||||
void DestroySSL();
|
||||
void WaitForCertCb(CertCb cb, void* arg);
|
||||
|
||||
inline Environment* ssl_env() const {
|
||||
return env_;
|
||||
@ -242,6 +254,12 @@ class SSLWrap {
|
||||
SSL* ssl_;
|
||||
bool session_callbacks_;
|
||||
bool new_session_wait_;
|
||||
|
||||
// SSL_set_cert_cb
|
||||
CertCb cert_cb_;
|
||||
void* cert_cb_arg_;
|
||||
bool cert_cb_running_;
|
||||
|
||||
ClientHelloParser hello_parser_;
|
||||
|
||||
#ifdef NODE__HAVE_TLSEXT_STATUS_CB
|
||||
@ -253,6 +271,10 @@ class SSLWrap {
|
||||
v8::Persistent<v8::Value> selected_npn_proto_;
|
||||
#endif // OPENSSL_NPN_NEGOTIATED
|
||||
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
|
||||
v8::Persistent<v8::Value> sni_context_;
|
||||
#endif
|
||||
|
||||
friend class SecureContext;
|
||||
};
|
||||
|
||||
@ -264,7 +286,6 @@ class Connection : public SSLWrap<Connection>, public AsyncWrap {
|
||||
~Connection() override {
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
|
||||
sniObject_.Reset();
|
||||
sniContext_.Reset();
|
||||
servername_.Reset();
|
||||
#endif
|
||||
}
|
||||
@ -279,7 +300,6 @@ class Connection : public SSLWrap<Connection>, public AsyncWrap {
|
||||
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
|
||||
v8::Persistent<v8::Object> sniObject_;
|
||||
v8::Persistent<v8::Value> sniContext_;
|
||||
v8::Persistent<v8::String> servername_;
|
||||
#endif
|
||||
|
||||
|
@ -150,6 +150,8 @@ void TLSWrap::InitSSL() {
|
||||
|
||||
InitNPN(sc_);
|
||||
|
||||
SSL_set_cert_cb(ssl_, SSLWrap<TLSWrap>::SSLCertCallback, this);
|
||||
|
||||
if (is_server()) {
|
||||
SSL_set_accept_state(ssl_);
|
||||
} else if (is_client()) {
|
||||
@ -355,6 +357,7 @@ Local<Value> TLSWrap::GetSSLError(int status, int* err, const char** msg) {
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
break;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
return scope.Escape(env()->zero_return_string());
|
||||
@ -738,12 +741,6 @@ void TLSWrap::EnableSessionCallbacks(
|
||||
const FunctionCallbackInfo<Value>& args) {
|
||||
TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
|
||||
wrap->enable_session_callbacks();
|
||||
EnableHelloParser(args);
|
||||
}
|
||||
|
||||
|
||||
void TLSWrap::EnableHelloParser(const FunctionCallbackInfo<Value>& args) {
|
||||
TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
|
||||
NodeBIO::FromBIO(wrap->enc_in_)->set_initial(kMaxHelloLength);
|
||||
wrap->hello_parser_.Start(SSLWrap<TLSWrap>::OnClientHello,
|
||||
OnClientHelloParseEnd,
|
||||
@ -759,6 +756,12 @@ void TLSWrap::DestroySSL(const FunctionCallbackInfo<Value>& args) {
|
||||
}
|
||||
|
||||
|
||||
void TLSWrap::EnableCertCb(const FunctionCallbackInfo<Value>& args) {
|
||||
TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
|
||||
wrap->WaitForCertCb(OnClientHelloParseEnd, wrap);
|
||||
}
|
||||
|
||||
|
||||
void TLSWrap::OnClientHelloParseEnd(void* arg) {
|
||||
TLSWrap* c = static_cast<TLSWrap*>(arg);
|
||||
c->Cycle();
|
||||
@ -857,8 +860,8 @@ void TLSWrap::Initialize(Handle<Object> target,
|
||||
env->SetProtoMethod(t, "start", Start);
|
||||
env->SetProtoMethod(t, "setVerifyMode", SetVerifyMode);
|
||||
env->SetProtoMethod(t, "enableSessionCallbacks", EnableSessionCallbacks);
|
||||
env->SetProtoMethod(t, "enableHelloParser", EnableHelloParser);
|
||||
env->SetProtoMethod(t, "destroySSL", DestroySSL);
|
||||
env->SetProtoMethod(t, "enableCertCb", EnableCertCb);
|
||||
|
||||
StreamBase::AddMethods<TLSWrap>(env, t, StreamBase::kFlagHasWritev);
|
||||
SSLWrap<TLSWrap>::AddMethods(env, t);
|
||||
|
@ -130,7 +130,7 @@ class TLSWrap : public crypto::SSLWrap<TLSWrap>,
|
||||
static void SetVerifyMode(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void EnableSessionCallbacks(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void EnableHelloParser(
|
||||
static void EnableCertCb(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void DestroySSL(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
@ -159,10 +159,6 @@ class TLSWrap : public crypto::SSLWrap<TLSWrap>,
|
||||
// If true - delivered EOF to the js-land, either after `close_notify`, or
|
||||
// after the `UV_EOF` on socket.
|
||||
bool eof_;
|
||||
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
|
||||
v8::Persistent<v8::Value> sni_context_;
|
||||
#endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
|
||||
};
|
||||
|
||||
} // namespace node
|
||||
|
47
test/fixtures/keys/Makefile
vendored
47
test/fixtures/keys/Makefile
vendored
@ -17,6 +17,28 @@ ca2-cert.pem: ca2.cnf
|
||||
echo '01' > ca2-serial
|
||||
touch ca2-database.txt
|
||||
|
||||
#
|
||||
# Create Subordinate Certificate Authority: ca3
|
||||
# ('password' is used for the CA password.)
|
||||
#
|
||||
ca3-key.pem:
|
||||
openssl genrsa -out ca3-key.pem 1024
|
||||
|
||||
ca3-csr.pem: ca3.cnf ca3-key.pem
|
||||
openssl req -new \
|
||||
-extensions v3_ca -config ca3.cnf -key ca3-key.pem -out ca3-csr.pem
|
||||
|
||||
ca3-cert.pem: ca3-csr.pem ca3-key.pem ca3.cnf ca1-cert.pem ca1-key.pem
|
||||
openssl x509 -req \
|
||||
-extfile ca3.cnf \
|
||||
-extensions v3_ca \
|
||||
-days 9999 \
|
||||
-passin "pass:password" \
|
||||
-in ca3-csr.pem \
|
||||
-CA ca1-cert.pem \
|
||||
-CAkey ca1-key.pem \
|
||||
-CAcreateserial \
|
||||
-out ca3-cert.pem
|
||||
|
||||
#
|
||||
# agent1 is signed by ca1.
|
||||
@ -157,6 +179,31 @@ agent5-cert.pem: agent5-csr.pem ca2-cert.pem ca2-key.pem
|
||||
agent5-verify: agent5-cert.pem ca2-cert.pem
|
||||
openssl verify -CAfile ca2-cert.pem agent5-cert.pem
|
||||
|
||||
#
|
||||
# agent6 is signed by ca3
|
||||
#
|
||||
|
||||
agent6-key.pem:
|
||||
openssl genrsa -out agent6-key.pem 1024
|
||||
|
||||
agent6-csr.pem: agent6.cnf agent6-key.pem
|
||||
openssl req -new -config agent6.cnf -key agent6-key.pem -out agent6-csr.pem
|
||||
|
||||
agent6-cert.pem: agent6-csr.pem ca3-cert.pem ca3-key.pem
|
||||
openssl x509 -req \
|
||||
-days 9999 \
|
||||
-passin "pass:password" \
|
||||
-in agent6-csr.pem \
|
||||
-CA ca3-cert.pem \
|
||||
-CAkey ca3-key.pem \
|
||||
-CAcreateserial \
|
||||
-extfile agent6.cnf \
|
||||
-out agent6-cert.pem
|
||||
cat ca3-cert.pem >> agent6-cert.pem
|
||||
|
||||
agent6-verify: agent6-cert.pem ca3-cert.pem
|
||||
openssl verify -CAfile ca3-cert.pem agent6-cert.pem
|
||||
|
||||
ec-key.pem:
|
||||
openssl ecparam -genkey -out ec-key.pem -name prime256v1
|
||||
|
||||
|
18
test/fixtures/keys/agent1-cert.pem
vendored
18
test/fixtures/keys/agent1-cert.pem
vendored
@ -1,9 +1,9 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC1jCCAj+gAwIBAgIJAJqEq8+4pyq+MA0GCSqGSIb3DQEBBQUAMHoxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIEwJDQTELMAkGA1UEBxMCU0YxDzANBgNVBAoTBkpveWVu
|
||||
dDEQMA4GA1UECxMHTm9kZS5qczEMMAoGA1UEAxMDY2ExMSAwHgYJKoZIhvcNAQkB
|
||||
FhFyeUB0aW55Y2xvdWRzLm9yZzAeFw0xNDA0MTUyMTMxMzFaFw00MTA4MzAyMTMx
|
||||
MzFaMH0xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTELMAkGA1UEBxMCU0YxDzAN
|
||||
MIIC1jCCAj+gAwIBAgIJAJqEq8+4pyrAMA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzANBgNVBAoMBkpveWVu
|
||||
dDEQMA4GA1UECwwHTm9kZS5qczEMMAoGA1UEAwwDY2ExMSAwHgYJKoZIhvcNAQkB
|
||||
FhFyeUB0aW55Y2xvdWRzLm9yZzAeFw0xNTA0MTgxMzI5MDhaFw00MjA5MDIxMzI5
|
||||
MDhaMH0xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTELMAkGA1UEBxMCU0YxDzAN
|
||||
BgNVBAoTBkpveWVudDEQMA4GA1UECxMHTm9kZS5qczEPMA0GA1UEAxMGYWdlbnQx
|
||||
MSAwHgYJKoZIhvcNAQkBFhFyeUB0aW55Y2xvdWRzLm9yZzCBnzANBgkqhkiG9w0B
|
||||
AQEFAAOBjQAwgYkCgYEAuOs3hW8rF+7xx5iB9wjmIgd+HTqRFUeKxG+mWV35Hl6A
|
||||
@ -11,8 +11,8 @@ AQEFAAOBjQAwgYkCgYEAuOs3hW8rF+7xx5iB9wjmIgd+HTqRFUeKxG+mWV35Hl6A
|
||||
lRxqJGXTjx+vG/0nDCXLBhoDKO00zEccdjGS8xEjjieQQr+KeASmIm0kQmuN5YcC
|
||||
AwEAAaNhMF8wXQYIKwYBBQUHAQEEUTBPMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz
|
||||
cC5ub2RlanMub3JnLzAoBggrBgEFBQcwAoYcaHR0cDovL2NhLm5vZGVqcy5vcmcv
|
||||
Y2EuY2VydDANBgkqhkiG9w0BAQUFAAOBgQAx6rhnYbPygJwIm6nidyx+ydJQC4Gk
|
||||
JD+pzbdJkTS+01r+xjVY/Wckn4JAsIlo/MMn055rs2cfdjoQtlj6yjEU6AP/7bfr
|
||||
Mju4lBxDLACJ2y5/rfj3wO4q4Knd4Q4mPWjlS2SwmkHZ21QOqJ6Ig9ps6HPM7syw
|
||||
ZYQ3WQ1LOPAxMg==
|
||||
Y2EuY2VydDANBgkqhkiG9w0BAQsFAAOBgQA45MmH28Gns+1yu9w9MR/oR8hKDMnG
|
||||
E4yDZ+9SofWdqRsGe5MNeMbp9c+FxIxODcNmdhV5Ao6+ZCRX4N9GjLqUL1jQoFAs
|
||||
pT/U80ZU+4bz2EwGMBQt7CJZb/u+j8/vXheyGFZkCWEQj6AgZQFTniRRQJLwbiy5
|
||||
uDktGqnhvamyrg==
|
||||
-----END CERTIFICATE-----
|
||||
|
31
test/fixtures/keys/agent6-cert.pem
vendored
Normal file
31
test/fixtures/keys/agent6-cert.pem
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICajCCAdOgAwIBAgIJAMTNiT75p13MMA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzANBgNVBAoMBkpveWVu
|
||||
dDEQMA4GA1UECwwHTm9kZS5qczEMMAoGA1UEAwwDY2EzMSAwHgYJKoZIhvcNAQkB
|
||||
FhFyeUB0aW55Y2xvdWRzLm9yZzAeFw0xNTA0MTgxMzI4NDFaFw00MjA5MDIxMzI4
|
||||
NDFaMHQxCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDERMA8GA1UECgwI
|
||||
VHJlc29yaXQxFjAUBgNVBAMMDcOBZMOhbSBMaXBwYWkxJzAlBgkqhkiG9w0BCQEW
|
||||
GGFkYW0ubGlwcGFpQHRyZXNvcml0LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
|
||||
gYkCgYEA3Iwmwd6gdWH1AlSFeuVsEY/2MQm3XluOyHR9HNtXkWqwcQqVL8FX3NHt
|
||||
//1jaSTMJjkR4FhC9R0hX6wyUuBp11J4GzoDqd02JUkCeUISq/3/2G+ynaZCx5Eo
|
||||
GNHhcN0gALTCET/1QMD9h4aBjRbij3iHUghcbgverfkasp59WWcCAwEAATANBgkq
|
||||
hkiG9w0BAQsFAAOBgQAmfrCJY+FPeOraPTUQTYf9rXqfVRQEVc/yyVygPbtg3gtA
|
||||
yST0wI/g6sBjQ6Mm39yMf4rkWmwOKGtrKcqs9o9NdM5g5QQSWeg925Ex6aB+REgz
|
||||
qjaAsLM88BJ0QU76VPi6K0hDSpeuQ6Zrcp93VkdGdVZzna3FSCMTNRnSq/GuMQ==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICgjCCAeugAwIBAgIJAJqEq8+4pyq/MA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzANBgNVBAoMBkpveWVu
|
||||
dDEQMA4GA1UECwwHTm9kZS5qczEMMAoGA1UEAwwDY2ExMSAwHgYJKoZIhvcNAQkB
|
||||
FhFyeUB0aW55Y2xvdWRzLm9yZzAeFw0xNTA0MTgxMzI4NDFaFw00MjA5MDIxMzI4
|
||||
NDFaMHoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzAN
|
||||
BgNVBAoMBkpveWVudDEQMA4GA1UECwwHTm9kZS5qczEMMAoGA1UEAwwDY2EzMSAw
|
||||
HgYJKoZIhvcNAQkBFhFyeUB0aW55Y2xvdWRzLm9yZzCBnzANBgkqhkiG9w0BAQEF
|
||||
AAOBjQAwgYkCgYEAqs4MKn9saUIu/9EfHQPouC3kL9Mo5sd1WR6RBeSd8cqeFxXW
|
||||
EWEq/P0hUeAH1sY0u8RFOccJmSJg8KTyRGc+VZzWimopz17mTuQY4hPW4bFzqmQm
|
||||
7STfJz5eHzynBTU8jk5omi8hjbnRA38jOm4D7rN/vqtB+RG+vEhxONnq4DMCAwEA
|
||||
AaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQBo8rX1uZWHvKHG
|
||||
gWw+LXrY24Pkg8NdDRmfqEVyuaR4GoGGOXCqlVaFa6x+4/eqOUzHoC9uGfPtjrvW
|
||||
BYQ1o/l0JZWW4KZYuXoVuMUSj+sel82mf9zLDeq5WYTPECgJDMfgVpXOmhHfyezn
|
||||
SkUTX7XJUohjET+X5BqTFlqRT/RfIw==
|
||||
-----END CERTIFICATE-----
|
12
test/fixtures/keys/agent6-csr.pem
vendored
Normal file
12
test/fixtures/keys/agent6-csr.pem
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIB2TCCAUICAQAwdDELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MREw
|
||||
DwYDVQQKDAhUcmVzb3JpdDEWMBQGA1UEAwwNw4Fkw6FtIExpcHBhaTEnMCUGCSqG
|
||||
SIb3DQEJARYYYWRhbS5saXBwYWlAdHJlc29yaXQuY29tMIGfMA0GCSqGSIb3DQEB
|
||||
AQUAA4GNADCBiQKBgQDcjCbB3qB1YfUCVIV65WwRj/YxCbdeW47IdH0c21eRarBx
|
||||
CpUvwVfc0e3//WNpJMwmORHgWEL1HSFfrDJS4GnXUngbOgOp3TYlSQJ5QhKr/f/Y
|
||||
b7KdpkLHkSgY0eFw3SAAtMIRP/VAwP2HhoGNFuKPeIdSCFxuC96t+Rqynn1ZZwID
|
||||
AQABoCUwIwYJKoZIhvcNAQkHMRYMFEEgY2hhbGxlbmdlIHBhc3N3b3JkMA0GCSqG
|
||||
SIb3DQEBCwUAA4GBAEU4gmRyeeh5TMYG3bI0biXr+9CvkYBaHwZD5o4TUo8AenIR
|
||||
NTrJdy9Pg9B23eOnEnCDB+KMfl08UuaPxbKRXRtYm1rTC8v5wmJEpZdWxum4c3hL
|
||||
3o7J8/LmjRGQImr5vnS5zmsVrBLtjW+jVpSg5xnXFKQmpXPfgRwhvbu0lXf7
|
||||
-----END CERTIFICATE REQUEST-----
|
15
test/fixtures/keys/agent6-key.pem
vendored
Normal file
15
test/fixtures/keys/agent6-key.pem
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXgIBAAKBgQDcjCbB3qB1YfUCVIV65WwRj/YxCbdeW47IdH0c21eRarBxCpUv
|
||||
wVfc0e3//WNpJMwmORHgWEL1HSFfrDJS4GnXUngbOgOp3TYlSQJ5QhKr/f/Yb7Kd
|
||||
pkLHkSgY0eFw3SAAtMIRP/VAwP2HhoGNFuKPeIdSCFxuC96t+Rqynn1ZZwIDAQAB
|
||||
AoGBAIL3AsjbL8OksL56fG0XMY5YQ6SpFWeFzQsCCY2KPrzOcwodc6vRDyDE1KTP
|
||||
zimQvV3xQ8lKADDX5IqQka2fL5mgF+LighVvGHDm6M4ILJb46SDbuINwnqqvVuye
|
||||
+OwjHBGEmKu18K+eL/YoCh3+sFTKP/18F7c7DGskCyzyub5RAkEA+Fs1ROx5w8AH
|
||||
cbIH4fMU/QBGQVnuKgNXGSPcT6NHqFLbrhvNn5HwoF1SiJKkML1h3gVpj3T8kquw
|
||||
Y1FcTVB9eQJBAONV1qXFo7i5gl2FyPuXvpgdzIXxzzr6q3seDkCR7q/vfBo+kKAx
|
||||
zyG2xjJrCc9+ox4Vh257qK9b57W6R6sWNd8CQQCeAHjNVpzI2nxh6t908k8h/nCz
|
||||
1uDcPa/FwLjCuaA3CC/Wfr28jP5HJ9gAJzrp/zIqK8tShxzAuxXGudY9Ib4RAkEA
|
||||
v+3elIIx4WktOQwUTOUmEoNGAufOD3tGf2E2oykRnRPRcM7Vh4nF2C7ZUgOweq/t
|
||||
wx5mAs7/8VzkWTb1/ul3fQJACLBXTChgyA77i5C/035tLwQbeLOjexLblEI0dgkW
|
||||
HIa8q4ZL0M7L+/oziQ8zIT0bTAqEG1Q00PgFLl3m8gDuNg==
|
||||
-----END RSA PRIVATE KEY-----
|
18
test/fixtures/keys/agent6.cnf
vendored
Normal file
18
test/fixtures/keys/agent6.cnf
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
[ req ]
|
||||
string_mask = utf8only
|
||||
utf8 = yes
|
||||
default_bits = 1024
|
||||
days = 999
|
||||
distinguished_name = req_distinguished_name
|
||||
attributes = req_attributes
|
||||
prompt = no
|
||||
|
||||
[ req_distinguished_name ]
|
||||
C = HU
|
||||
L = Budapest
|
||||
O = Tresorit
|
||||
CN = Ádám Lippai
|
||||
emailAddress = adam.lippai@tresorit.com
|
||||
|
||||
[ req_attributes ]
|
||||
challengePassword = A challenge password
|
27
test/fixtures/keys/ca1-cert.pem
vendored
27
test/fixtures/keys/ca1-cert.pem
vendored
@ -1,15 +1,16 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICazCCAdQCCQC1CQyJn8L/kzANBgkqhkiG9w0BAQUFADB6MQswCQYDVQQGEwJV
|
||||
UzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQKEwZKb3llbnQxEDAO
|
||||
BgNVBAsTB05vZGUuanMxDDAKBgNVBAMTA2NhMTEgMB4GCSqGSIb3DQEJARYRcnlA
|
||||
dGlueWNsb3Vkcy5vcmcwHhcNMTQwNDE1MjEzMTMxWhcNNDEwODMwMjEzMTMxWjB6
|
||||
MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExCzAJBgNVBAcTAlNGMQ8wDQYDVQQK
|
||||
EwZKb3llbnQxEDAOBgNVBAsTB05vZGUuanMxDDAKBgNVBAMTA2NhMTEgMB4GCSqG
|
||||
SIb3DQEJARYRcnlAdGlueWNsb3Vkcy5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
|
||||
MIGJAoGBALBXMk/xFR2GN2v/wKreZKyIitGphxYGoJ2d//s/wM6qqyIW94aiq3sm
|
||||
1zpmOTPTorT9Pk32A7uKKHfrafB+yA07QXgCYXgzcn17nfFInncDyGdggNFGAO13
|
||||
5JuC3JC8pRJpEokkMszpHJxPdR6gKXIT05blUnpwGT/AmYJ8S59lAgMBAAEwDQYJ
|
||||
KoZIhvcNAQEFBQADgYEAAb+Pye0I+k927Qi2+cUowLS5MtmrEosUbTYwI4rqYSR2
|
||||
aiibqmC3Z55N72ktQ2pJKP8I1t3Rk+j8/yIKWzSn5Jd2GT4ZzqbANrdLKeAsfVDK
|
||||
pnsUR1IV/sdIvuELm+P4kyK5wafJytUjD+A4SH2oWN4EozDR1OidAhJrraXQksw=
|
||||
MIICgjCCAeugAwIBAgIJAI3yHAFGivOTMA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzANBgNVBAoMBkpveWVu
|
||||
dDEQMA4GA1UECwwHTm9kZS5qczEMMAoGA1UEAwwDY2ExMSAwHgYJKoZIhvcNAQkB
|
||||
FhFyeUB0aW55Y2xvdWRzLm9yZzAeFw0xNTA0MTgxMzI4NDFaFw00MjA5MDIxMzI4
|
||||
NDFaMHoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzAN
|
||||
BgNVBAoMBkpveWVudDEQMA4GA1UECwwHTm9kZS5qczEMMAoGA1UEAwwDY2ExMSAw
|
||||
HgYJKoZIhvcNAQkBFhFyeUB0aW55Y2xvdWRzLm9yZzCBnzANBgkqhkiG9w0BAQEF
|
||||
AAOBjQAwgYkCgYEAwbF7gKfk7nGLcH0lbok1UJEBpMiQ49YxUqT/oIfXBaRjMODX
|
||||
RknQxpARWw4R8qj+Zeu9zZZ8Hzv3dAxtcpnMTgeoPUL3HCStk0bK8QrFdkFrBxQD
|
||||
mF92r9Mgr/fz+x7rSZuCIKhATwB5iJOz63fRctTL5tBmzG15JUG1GN5HPZECAwEA
|
||||
AaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAnAHtchz5FGqod
|
||||
8twiFF3yQdGN3WE3VC3A6VrcmjKUp+M7f0uRDYw4uKUhadyZdYhMn39fe9DVN6rC
|
||||
6wUUoe4hSs+0SWi6Ora7DFpCbm6fNpooSr0K0OUMZ2opwDmAEPdVOSPRhzQJ/cNp
|
||||
s3mxIrkAQ5kgJSSGlPETMEumQmXDfA==
|
||||
-----END CERTIFICATE-----
|
||||
|
2
test/fixtures/keys/ca1-cert.srl
vendored
2
test/fixtures/keys/ca1-cert.srl
vendored
@ -1 +1 @@
|
||||
9A84ABCFB8A72ABE
|
||||
9A84ABCFB8A72AC0
|
||||
|
30
test/fixtures/keys/ca1-key.pem
vendored
30
test/fixtures/keys/ca1-key.pem
vendored
@ -1,17 +1,17 @@
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIJ36Z9tFiv2oCAggA
|
||||
MBQGCCqGSIb3DQMHBAjCAyUwdFh+7gSCAoD9Sv9009MmLb8+wHhYhxmrPrpeYZOt
|
||||
W8xfELfal/2XWFe41WV41Qsa2HyN03VeyQjb+cnKvZX6HUCe5zVMUsf+B91yQBqR
|
||||
jOZgsgoflEC3tFrhW5ogmRnjuok3CbTYLx0f8GMucSRNa9ZPhpfUjrVcCUrKKRJ+
|
||||
owk0VxWQkRqMF/8WJJgHxnm8/jLbNKuHbwY8SSQO/pStyKxqx5rBXAA/YCrAx7EZ
|
||||
aDvc2q9EwRHX+hWIhpIkYna7PwnNAX03Ghv4iiwUlwHoomvgxExdUc9T8HBQu/xP
|
||||
2pmUqwTglAdRb0tNiYrF+yIesAlqBc1qoi7tv2SM3gTowdw2PeHq5MA/ShV21oC8
|
||||
51bc0OxRkEFsHGLIs1v5qzs21JhX0IKvb5LDHAaze2RwODfnCTcQb8jYaFZNmwpt
|
||||
ZrHgBQBwOHSvZ9CCqInDDtGBhYRlQIQRGgj9Ju5fruRYycn8vE58OcIfF52dwLKB
|
||||
7sjTFX0O0b58wpiQSJzbHGbjNlQNRXxdk9v1qfP8vx8rFHLoFSScaZomavp4uijU
|
||||
yLKVwquzEOVOMP8cC+yRk+zkcb9EE2pE1CqG0Mj6MHH1Lha98kakTIAS/VG59/Mp
|
||||
EqZoRtJ6n/DzscrRpHIm+170ufLGmivmTeOXcMyHv1pGp35c5VbmUTZCxcE7A/0f
|
||||
WPLVB3lBPgsvR/4NVx9A6mvXbkp2yngdfbvQgzRDG6pfrE1xeiUAyRCts7dR3Q9/
|
||||
dNHIM2wsiO3A/8Up1vrY6d/dcJt7cwjHRkx2eQFbpeE+a4CCNZ7gXFcwHLigBH8G
|
||||
uTTVZf4HJavjXiYlkY3OFnPuz4KzanJzuqluKeIdJwSEkp9Kra/Id0eO
|
||||
MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI4tZeEUDNwLoCAggA
|
||||
MBQGCCqGSIb3DQMHBAglCttpxF+UrASCAoCOiXoMG1+CJFtRnovzp0wSCeEtieI3
|
||||
jntJkCBF+NNUZrbWaQqWO+Id8KjXNFQdUo7lYT0d0w5lf52OHTyswjN0ILCOp/WN
|
||||
eVMDfgmaJXtaah2l++hDFhcbGsOdRcwM0+yComF02Qxr13ftYnIPzUH4+Ix1i1Tr
|
||||
6eBGDBJv0eXDZj/dLrploA7/pepKlytRw2stIL99TSICR54UQ7fyZ/oS6NvoQU7U
|
||||
iBCVsrkjyE6jHJZ6vNe/ZjM8ZdLM9K2inoldpFaavDTh6GwHC6e3e9FJuJk6X30e
|
||||
s2lhrVLOmxLuFS168iApyA8XvVTg/RG08DvkzUUFv8+HNETH0Qkb5kpJM+pPzwyu
|
||||
c5et2fX8YuQRc8SdIdd+Z0lZJga1IciEXlsfzGeUtcZKUjBZ5yPTx+1InfcNFDKR
|
||||
wCU2p0Haj9OCcvSBzU53I57RYXkENMEHQ46/FytGULXHimIoIR/SEbrqbKX0xDmT
|
||||
rc/4c4vI5+tQPYMjo0rqydLAb5YjWCivrXDVXVHrG0YFsAoJkvTBLXlPiqTcnkea
|
||||
KACuq7B+ymdVmpjV891OLuN3Yah+HgrvTkMlNexsFWvGpis03UYwpI6bppe4dHtt
|
||||
rLBlgtyxFLJ9hu/YnkR6HcrjKaW5kGFDX06elAZBdPD/6foghzTb4jw3OK6a4ue0
|
||||
PE/zF6d7QWW+w5xKtNO62WWKABi9OtLhdUNVAFyBlaA43zYbnXkyfmv0l7LXPZ9t
|
||||
Ps+BmG4r/gxO6GmZZ40sRXFjpkj230bTjbN6sUrU3WgOszMy0uFAph+zBUIMZWSP
|
||||
wqZWmQi8MHQ4+Qm8N5GdXUTXw32eZ60bj82QGPso/NNxzDQsk5wd+bR3
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
|
3
test/fixtures/keys/ca1.cnf
vendored
3
test/fixtures/keys/ca1.cnf
vendored
@ -5,6 +5,7 @@ distinguished_name = req_distinguished_name
|
||||
attributes = req_attributes
|
||||
prompt = no
|
||||
output_password = password
|
||||
x509_extensions = v3_ca
|
||||
|
||||
[ req_distinguished_name ]
|
||||
C = US
|
||||
@ -18,3 +19,5 @@ emailAddress = ry@tinyclouds.org
|
||||
[ req_attributes ]
|
||||
challengePassword = A challenge password
|
||||
|
||||
[ v3_ca ]
|
||||
basicConstraints = CA:TRUE
|
||||
|
16
test/fixtures/keys/ca3-cert.pem
vendored
Normal file
16
test/fixtures/keys/ca3-cert.pem
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICgjCCAeugAwIBAgIJAJqEq8+4pyq/MA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzANBgNVBAoMBkpveWVu
|
||||
dDEQMA4GA1UECwwHTm9kZS5qczEMMAoGA1UEAwwDY2ExMSAwHgYJKoZIhvcNAQkB
|
||||
FhFyeUB0aW55Y2xvdWRzLm9yZzAeFw0xNTA0MTgxMzI4NDFaFw00MjA5MDIxMzI4
|
||||
NDFaMHoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDzAN
|
||||
BgNVBAoMBkpveWVudDEQMA4GA1UECwwHTm9kZS5qczEMMAoGA1UEAwwDY2EzMSAw
|
||||
HgYJKoZIhvcNAQkBFhFyeUB0aW55Y2xvdWRzLm9yZzCBnzANBgkqhkiG9w0BAQEF
|
||||
AAOBjQAwgYkCgYEAqs4MKn9saUIu/9EfHQPouC3kL9Mo5sd1WR6RBeSd8cqeFxXW
|
||||
EWEq/P0hUeAH1sY0u8RFOccJmSJg8KTyRGc+VZzWimopz17mTuQY4hPW4bFzqmQm
|
||||
7STfJz5eHzynBTU8jk5omi8hjbnRA38jOm4D7rN/vqtB+RG+vEhxONnq4DMCAwEA
|
||||
AaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQBo8rX1uZWHvKHG
|
||||
gWw+LXrY24Pkg8NdDRmfqEVyuaR4GoGGOXCqlVaFa6x+4/eqOUzHoC9uGfPtjrvW
|
||||
BYQ1o/l0JZWW4KZYuXoVuMUSj+sel82mf9zLDeq5WYTPECgJDMfgVpXOmhHfyezn
|
||||
SkUTX7XJUohjET+X5BqTFlqRT/RfIw==
|
||||
-----END CERTIFICATE-----
|
1
test/fixtures/keys/ca3-cert.srl
vendored
Normal file
1
test/fixtures/keys/ca3-cert.srl
vendored
Normal file
@ -0,0 +1 @@
|
||||
C4CD893EF9A75DCC
|
13
test/fixtures/keys/ca3-csr.pem
vendored
Normal file
13
test/fixtures/keys/ca3-csr.pem
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIB3zCCAUgCAQAwejELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQswCQYDVQQH
|
||||
DAJTRjEPMA0GA1UECgwGSm95ZW50MRAwDgYDVQQLDAdOb2RlLmpzMQwwCgYDVQQD
|
||||
DANjYTMxIDAeBgkqhkiG9w0BCQEWEXJ5QHRpbnljbG91ZHMub3JnMIGfMA0GCSqG
|
||||
SIb3DQEBAQUAA4GNADCBiQKBgQCqzgwqf2xpQi7/0R8dA+i4LeQv0yjmx3VZHpEF
|
||||
5J3xyp4XFdYRYSr8/SFR4AfWxjS7xEU5xwmZImDwpPJEZz5VnNaKainPXuZO5Bji
|
||||
E9bhsXOqZCbtJN8nPl4fPKcFNTyOTmiaLyGNudEDfyM6bgPus3++q0H5Eb68SHE4
|
||||
2ergMwIDAQABoCUwIwYJKoZIhvcNAQkHMRYMFEEgY2hhbGxlbmdlIHBhc3N3b3Jk
|
||||
MA0GCSqGSIb3DQEBCwUAA4GBABMaKC7NVVdfoQeKwIy5lYo17mOr4WcWHPNRcoIy
|
||||
rAHLcAzFOp0RCSZ7ROVRR6O/QIBYapUmPmdYRhKfz1g35xCX3+T28cWXngALV5v0
|
||||
XzMYJiew+97/LlNnBwoTRafAorviugdbFgJeMpYHRkG7/zXQsBz+hwgymKZnHW9D
|
||||
Dl4h
|
||||
-----END CERTIFICATE REQUEST-----
|
15
test/fixtures/keys/ca3-key.pem
vendored
Normal file
15
test/fixtures/keys/ca3-key.pem
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqzgwqf2xpQi7/0R8dA+i4LeQv0yjmx3VZHpEF5J3xyp4XFdYR
|
||||
YSr8/SFR4AfWxjS7xEU5xwmZImDwpPJEZz5VnNaKainPXuZO5BjiE9bhsXOqZCbt
|
||||
JN8nPl4fPKcFNTyOTmiaLyGNudEDfyM6bgPus3++q0H5Eb68SHE42ergMwIDAQAB
|
||||
AoGBAJkcc5N0/j2s8mynjXh5FJhlqvOkGjol+m+VEvNxaJRiySxwiqCxtdNrJf87
|
||||
EEvbCVJ4MoYEgfof8z5E3lerJRgqrhY2RSfiQrSUA89Lw9uYzcx28zhWpwwmuLHY
|
||||
5gjz+LCDDS5okLsXnl2awHXADEmcx29sZnRS6dGRFcf8F0FhAkEA1c7HrW8Vghu2
|
||||
FlRaY6LOuoFNAHM++ugoWrC85/moYevLG8wAJCuSIp/RuWrx1FdJoa7rfhyS649v
|
||||
cMGN0m1yHwJBAMyC1S1QoqXSdoqN8OrXyHJmaSbWG8IMLcT2FXA8Mk3Tk0zWSjiz
|
||||
sk/O85NsmUQQnkRgbtSS+w0Kc0OMWXbfl20CQH+igFsNjEZuaoXr90WxhD2cQK57
|
||||
HebEvopdJXhJ9nX2P/qpDpCJHiTjSVyp9hFvxjnp5RUU07QhnUIvmY073rsCQFMN
|
||||
ovNHNvZutVNpd3h372B+NJ/f/d/dQE0nvucYmzk9/ikLMZM7buO4YPTy+n9I3G1a
|
||||
WEgd9LSEFPFOsxpyjTUCQGn9XTyeSo1EoVuV21DE0Cnx30YsnPKMT1YRS7QgjDPK
|
||||
RA3fSsvnhtTzT53kfJ/ZurBV+RKbePL1JVqDtGvJVeE=
|
||||
-----END RSA PRIVATE KEY-----
|
23
test/fixtures/keys/ca3.cnf
vendored
Normal file
23
test/fixtures/keys/ca3.cnf
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
[ req ]
|
||||
default_bits = 1024
|
||||
days = 999
|
||||
distinguished_name = req_distinguished_name
|
||||
attributes = req_attributes
|
||||
prompt = no
|
||||
output_password = password
|
||||
x509_extensions = v3_ca
|
||||
|
||||
[ req_distinguished_name ]
|
||||
C = US
|
||||
ST = CA
|
||||
L = SF
|
||||
O = Joyent
|
||||
OU = Node.js
|
||||
CN = ca3
|
||||
emailAddress = ry@tinyclouds.org
|
||||
|
||||
[ req_attributes ]
|
||||
challengePassword = A challenge password
|
||||
|
||||
[ v3_ca ]
|
||||
basicConstraints = CA:TRUE
|
@ -36,13 +36,13 @@ server.listen(common.PORT, function() {
|
||||
|
||||
common.debug(util.inspect(peerCert));
|
||||
assert.equal(peerCert.subject.emailAddress, 'ry@tinyclouds.org');
|
||||
assert.equal(peerCert.serialNumber, '9A84ABCFB8A72ABE');
|
||||
assert.equal(peerCert.serialNumber, '9A84ABCFB8A72AC0');
|
||||
assert.deepEqual(peerCert.infoAccess['OCSP - URI'],
|
||||
[ 'http://ocsp.nodejs.org/' ]);
|
||||
|
||||
var issuer = peerCert.issuerCertificate;
|
||||
assert.ok(issuer.issuerCertificate === issuer);
|
||||
assert.equal(issuer.serialNumber, 'B5090C899FC2FF93');
|
||||
assert.equal(issuer.serialNumber, '8DF21C01468AF393');
|
||||
verified = true;
|
||||
server.close();
|
||||
});
|
||||
|
@ -35,6 +35,11 @@ var SNIContexts = {
|
||||
'asterisk.test.com': {
|
||||
key: loadPEM('agent3-key'),
|
||||
cert: loadPEM('agent3-cert')
|
||||
},
|
||||
'chain.example.com': {
|
||||
key: loadPEM('agent6-key'),
|
||||
// NOTE: Contains ca3 chain cert
|
||||
cert: loadPEM('agent6-cert')
|
||||
}
|
||||
};
|
||||
|
||||
@ -42,32 +47,29 @@ var serverPort = common.PORT;
|
||||
|
||||
var clientsOptions = [{
|
||||
port: serverPort,
|
||||
key: loadPEM('agent1-key'),
|
||||
cert: loadPEM('agent1-cert'),
|
||||
ca: [loadPEM('ca1-cert')],
|
||||
servername: 'a.example.com',
|
||||
rejectUnauthorized: false
|
||||
}, {
|
||||
port: serverPort,
|
||||
key: loadPEM('agent2-key'),
|
||||
cert: loadPEM('agent2-cert'),
|
||||
ca: [loadPEM('ca2-cert')],
|
||||
servername: 'b.test.com',
|
||||
rejectUnauthorized: false
|
||||
}, {
|
||||
port: serverPort,
|
||||
key: loadPEM('agent2-key'),
|
||||
cert: loadPEM('agent2-cert'),
|
||||
ca: [loadPEM('ca2-cert')],
|
||||
servername: 'a.b.test.com',
|
||||
rejectUnauthorized: false
|
||||
}, {
|
||||
port: serverPort,
|
||||
key: loadPEM('agent3-key'),
|
||||
cert: loadPEM('agent3-cert'),
|
||||
ca: [loadPEM('ca1-cert')],
|
||||
servername: 'c.wrong.com',
|
||||
rejectUnauthorized: false
|
||||
}, {
|
||||
port: serverPort,
|
||||
ca: [loadPEM('ca1-cert')],
|
||||
servername: 'chain.example.com',
|
||||
rejectUnauthorized: false
|
||||
}];
|
||||
|
||||
var serverResults = [],
|
||||
@ -79,6 +81,7 @@ var server = tls.createServer(serverOptions, function(c) {
|
||||
|
||||
server.addContext('a.example.com', SNIContexts['a.example.com']);
|
||||
server.addContext('*.test.com', SNIContexts['asterisk.test.com']);
|
||||
server.addContext('chain.example.com', SNIContexts['chain.example.com']);
|
||||
|
||||
server.listen(serverPort, startTest);
|
||||
|
||||
@ -105,7 +108,9 @@ function startTest() {
|
||||
}
|
||||
|
||||
process.on('exit', function() {
|
||||
assert.deepEqual(serverResults, ['a.example.com', 'b.test.com',
|
||||
'a.b.test.com', 'c.wrong.com']);
|
||||
assert.deepEqual(clientResults, [true, true, false, false]);
|
||||
assert.deepEqual(serverResults, [
|
||||
'a.example.com', 'b.test.com', 'a.b.test.com', 'c.wrong.com',
|
||||
'chain.example.com'
|
||||
]);
|
||||
assert.deepEqual(clientResults, [true, true, false, false, true]);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user