void lws_ssl_info_callback(const SSL *ssl, int where, int ret) { struct lws *wsi; struct lws_context *context; struct lws_ssl_info si; #ifndef USE_WOLFSSL context = (struct lws_context *)SSL_CTX_get_ex_data( SSL_get_SSL_CTX(ssl), openssl_SSL_CTX_private_data_index); #else context = (struct lws_context *)SSL_CTX_get_ex_data( SSL_get_SSL_CTX((SSL*) ssl), openssl_SSL_CTX_private_data_index); #endif if (!context) return; wsi = wsi_from_fd(context, SSL_get_fd(ssl)); if (!wsi) return; if (!(where & wsi->vhost->tls.ssl_info_event_mask)) return; si.where = where; si.ret = ret; if (user_callback_handle_rxflow(wsi->protocol->callback, wsi, LWS_CALLBACK_SSL_INFO, wsi->user_space, &si, 0)) lws_set_timeout(wsi, PENDING_TIMEOUT_KILLED_BY_SSL_INFO, -1); }
static void ossl_sslctx_free(SSL_CTX *ctx) { if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1) ctx->cert_store = NULL; SSL_CTX_free(ctx); }
static void __apn_ssl_info_callback(const SSL *ssl, int where, int ret) { apn_ctx_t *ctx = SSL_CTX_get_ex_data(ssl->ctx, 0); if (!ctx) { return; } if (where & SSL_CB_LOOP) { apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: %s:%s:%s", (where & SSL_ST_CONNECT) ? "connect" : "undef", SSL_state_string_long(ssl), SSL_get_cipher_name(ssl)); } else if (where & SSL_CB_EXIT) { apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: %s:%s", (where & SSL_ST_CONNECT) ? "connect" : "undef", SSL_state_string_long(ssl)); } else if (where & SSL_CB_ALERT) { apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: alert %s:%s", (where & SSL_CB_READ) ? "read" : "write", SSL_state_string_long(ssl), SSL_alert_desc_string_long(ret)); } else if (where & SSL_CB_HANDSHAKE_START) { apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: handshake started %s:%s:%s", (where & SSL_CB_READ) ? "read" : "write", SSL_state_string_long(ssl), SSL_alert_desc_string_long(ret)); } else if (where & SSL_CB_HANDSHAKE_DONE) { apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: handshake done %s:%s:%s", (where & SSL_CB_READ) ? "read" : "write", SSL_state_string_long(ssl), SSL_alert_desc_string_long(ret)); } else { apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: state %s:%s:%s", SSL_state_string_long(ssl), SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret)); } }
int verify_cb(int ok, X509_STORE_CTX* store) { SSL* ssl = (SSL *)X509_STORE_CTX_get_app_data(store); SSL_CTX* ssl_ctx = ssl_ctx = SSL_get_SSL_CTX(ssl); void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); // get the pointer to the go Ctx object and pass it back into the thunk return verify_cb_thunk(p, ok, store); }
static void ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) { VALUE ary, sslctx_obj, sess_obj, ret_obj; void *ptr; int state = 0; OSSL_Debug("SSL SESSION remove callback entered"); if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL) return; sslctx_obj = (VALUE)ptr; sess_obj = rb_obj_alloc(cSSLSession); CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); DATA_PTR(sess_obj) = sess; ary = rb_ary_new2(2); rb_ary_push(ary, sslctx_obj); rb_ary_push(ary, sess_obj); ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state); if (state) { /* the SSL_CTX is frozen, nowhere to save state. there is no common accessor method to check it either. rb_ivar_set(sslctx_obj, ID_callback_state, INT2NUM(state)); */ } }
NOEXPORT void sess_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) { SERVICE_OPTIONS *opt; s_log(LOG_DEBUG, "Remove session callback"); opt=SSL_CTX_get_ex_data(ctx, index_opt); if(opt->option.sessiond) cache_remove(ctx, sess); }
int _qvd_verify_cert_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { SSL *ssl; SSL_CTX *sslctx; qvdclient *qvd ; ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); sslctx = SSL_get_SSL_CTX(ssl); qvd = SSL_CTX_get_ex_data(sslctx, _qvd_ssl_index); X509 *cert = X509_STORE_CTX_get_current_cert(x509_ctx); int depth = X509_STORE_CTX_get_error_depth(x509_ctx); int err = X509_STORE_CTX_get_error(x509_ctx); /* save the certificate by incrementing the reference count and * keeping a pointer */ if (depth < MAX_CERTS && !certificate[depth]) { certificate[depth] = cert; certificate_error[depth] = err; cert->references++; } /* See http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html# */ if (preverify_ok) { qvd_printf("_qvd_verify_cert_callback: Certificate was validated\n"); return preverify_ok; } if (qvd->ssl_verify_callback == NULL) { qvd_printf("_qvd_verify_cert_callback: No callback specified returning false (specify if you wissh callbacks for unknown certs with qvd_set_unknown_cert_callback)\n"); return 0; } BIO *bio_out = BIO_new(BIO_s_mem()); BUF_MEM *biomem; int result; PEM_write_bio_X509(bio_out, certificate[depth]); BIO_get_mem_ptr(bio_out, &biomem); char cert_info[1024]; char issuer[256], subject[256]; X509_NAME_oneline(X509_get_issuer_name(certificate[depth]), issuer, 256); X509_NAME_oneline(X509_get_subject_name(certificate[depth]), subject, 256); snprintf(cert_info, 1023, "Serial: %lu\n\nIssuer: %s\n\nValidity:\n\tNot before: %s\n\tNot after: %s\n\nSubject: %s\n", ASN1_INTEGER_get(X509_get_serialNumber(certificate[depth])), issuer, X509_get_notBefore(certificate[depth])->data, X509_get_notAfter(cert)->data, subject); cert_info[1023] = '\0'; result = qvd->ssl_verify_callback(qvd, cert_info, biomem->data); if (result) { _qvd_save_certificate(qvd, certificate[depth], depth, biomem); } BIO_free(bio_out); return result; }
int SSLSessionCacheManager::newSessionCallback(SSL* ssl, SSL_SESSION* session) { SSLSessionCacheManager* manager = nullptr; SSL_CTX* ctx = SSL_get_SSL_CTX(ssl); manager = (SSLSessionCacheManager *)SSL_CTX_get_ex_data(ctx, sExDataIndex_); if (manager == nullptr) { LOG(FATAL) << "Null SSLSessionCacheManager in callback"; return -1; } return manager->newSession(ssl, session); }
void SSLSessionCacheManager::removeSessionCallback(SSL_CTX* ctx, SSL_SESSION* session) { SSLSessionCacheManager* manager = nullptr; manager = (SSLSessionCacheManager *)SSL_CTX_get_ex_data(ctx, sExDataIndex_); if (manager == nullptr) { LOG(FATAL) << "Null SSLSessionCacheManager in callback"; return; } return manager->removeSession(ctx, session); }
ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_resolver_t *resolver, ngx_msec_t resolver_timeout) { ngx_ssl_stapling_t *staple; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); staple->resolver = resolver; staple->resolver_timeout = resolver_timeout; return NGX_OK; }
SSL_SESSION* SSLSessionCacheManager::getSessionCallback(SSL* ssl, unsigned char* sess_id, int id_len, int* copyflag) { SSLSessionCacheManager* manager = nullptr; SSL_CTX* ctx = SSL_get_SSL_CTX(ssl); manager = (SSLSessionCacheManager *)SSL_CTX_get_ex_data(ctx, sExDataIndex_); if (manager == nullptr) { LOG(FATAL) << "Null SSLSessionCacheManager in callback"; return nullptr; } return manager->getSession(ssl, sess_id, id_len, copyflag); }
int TLSTicketKeyManager::callback(SSL* ssl, unsigned char* keyName, unsigned char* iv, EVP_CIPHER_CTX* cipherCtx, HMAC_CTX* hmacCtx, int encrypt) { TLSTicketKeyManager* manager = nullptr; SSL_CTX* ctx = SSL_get_SSL_CTX(ssl); manager = (TLSTicketKeyManager *)SSL_CTX_get_ex_data(ctx, sExDataIndex_); if (manager == nullptr) { LOG(FATAL) << "Null TLSTicketKeyManager in callback" ; } return manager->processTicket(ssl, keyName, iv, cipherCtx, hmacCtx, encrypt); }
static int lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg) { struct lws_context *context; struct lws_vhost *vhost, *vh; const char *servername; int port; if (!ssl) return SSL_TLSEXT_ERR_NOACK; context = (struct lws_context *)SSL_CTX_get_ex_data( SSL_get_SSL_CTX(ssl), openssl_SSL_CTX_private_data_index); /* * We can only get ssl accepted connections by using a vhost's ssl_ctx * find out which listening one took us and only match vhosts on the * same port. */ vh = context->vhost_list; while (vh) { if (!vh->being_destroyed && vh->ssl_ctx == SSL_get_SSL_CTX(ssl)) break; vh = vh->vhost_next; } assert(vh); /* we cannot get an ssl without using a vhost ssl_ctx */ port = vh->listen_port; servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); if (servername) { vhost = lws_select_vhost(context, port, servername); if (vhost) { lwsl_debug("SNI: Found: %s (port %d)\n", servername, port); SSL_set_SSL_CTX(ssl, vhost->ssl_ctx); return SSL_TLSEXT_ERR_OK; } lwsl_err("SNI: Unknown ServerName: %s\n", servername); } return SSL_TLSEXT_ERR_OK; }
ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_resolver_t *resolver, ngx_msec_t resolver_timeout) { X509 *cert; ngx_ssl_stapling_t *staple; for (cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); cert; cert = X509_get_ex_data(cert, ngx_ssl_next_certificate_index)) { staple = X509_get_ex_data(cert, ngx_ssl_stapling_index); staple->resolver = resolver; staple->resolver_timeout = resolver_timeout; } return NGX_OK; }
int bud_config_verify_cert(int status, X509_STORE_CTX* s) { bud_config_t* config; bud_context_t* ctx; X509_STORE_CTX store_ctx; X509* cert; X509_STORE* store; SSL* ssl; int r; ssl = X509_STORE_CTX_get_ex_data(s, SSL_get_ex_data_X509_STORE_CTX_idx()); ASSERT(ssl != NULL, "STORE_CTX without associated ssl"); cert = s->cert; ctx = SSL_get_ex_data(ssl, kBudSSLSNIIndex); config = SSL_CTX_get_ex_data(ssl->ctx, kBudSSLConfigIndex); ASSERT(config != NULL, "Config not present in SSL"); if (ctx != NULL && ctx->ca_store != NULL) store = ctx->ca_store; else if (config->contexts[0].ca_store != NULL) store = config->contexts[0].ca_store; else store = NULL; /* No certificate store, validate cert if present */ if (store == NULL) { if (cert != NULL) return SSL_get_verify_result(ssl) == X509_V_OK ? 1 : 0; else if (config->contexts[0].optional_cert) return 1; else return config->contexts[0].request_cert ? 1 : 0; } if (!X509_STORE_CTX_init(&store_ctx, store, cert, NULL)) return 0; r = X509_verify_cert(&store_ctx); X509_STORE_CTX_cleanup(&store_ctx); return r; }
ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify) { X509 *cert; for (cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); cert; cert = X509_get_ex_data(cert, ngx_ssl_next_certificate_index)) { if (ngx_ssl_stapling_certificate(cf, ssl, cert, file, responder, verify) != NGX_OK) { return NGX_ERROR; } } SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback); return NGX_OK; }
static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file) { BIO *bio; int len; u_char *p, *buf; OCSP_RESPONSE *response; ngx_ssl_stapling_t *staple; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) { return NGX_ERROR; } bio = BIO_new_file((char *) file->data, "r"); if (bio == NULL) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "BIO_new_file(\"%s\") failed", file->data); return NGX_ERROR; } response = d2i_OCSP_RESPONSE_bio(bio, NULL); if (response == NULL) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "d2i_OCSP_RESPONSE_bio(\"%s\") failed", file->data); BIO_free(bio); return NGX_ERROR; } len = i2d_OCSP_RESPONSE(response, NULL); if (len <= 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "i2d_OCSP_RESPONSE(\"%s\") failed", file->data); goto failed; } buf = ngx_alloc(len, ssl->log); if (buf == NULL) { goto failed; } p = buf; len = i2d_OCSP_RESPONSE(response, &p); if (len <= 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "i2d_OCSP_RESPONSE(\"%s\") failed", file->data); ngx_free(buf); goto failed; } OCSP_RESPONSE_free(response); BIO_free(bio); staple->staple.data = buf; staple->staple.len = len; staple->valid = NGX_MAX_TIME_T_VALUE; return NGX_OK; failed: OCSP_RESPONSE_free(response); BIO_free(bio); return NGX_ERROR; }
NOEXPORT void cache_transfer(SSL_CTX *ctx, const u_char type, const long timeout, const u_char *key, const size_t key_len, const u_char *val, const size_t val_len, unsigned char **ret, size_t *ret_len) { char session_id_txt[2*SSL_MAX_SSL_SESSION_ID_LENGTH+1]; const char hex[16]="0123456789ABCDEF"; const char *type_description[]={"new", "get", "remove"}; unsigned i; SOCKET s; ssize_t len; struct timeval t; CACHE_PACKET *packet; SERVICE_OPTIONS *section; if(ret) /* set error as the default result if required */ *ret=NULL; /* log the request information */ for(i=0; i<key_len && i<SSL_MAX_SSL_SESSION_ID_LENGTH; ++i) { session_id_txt[2*i]=hex[key[i]>>4]; session_id_txt[2*i+1]=hex[key[i]&0x0f]; } session_id_txt[2*i]='\0'; s_log(LOG_INFO, "cache_transfer: request=%s, timeout=%ld, id=%s, length=%lu", type_description[type], timeout, session_id_txt, (long unsigned)val_len); /* allocate UDP packet buffer */ if(key_len>SSL_MAX_SSL_SESSION_ID_LENGTH) { s_log(LOG_ERR, "cache_transfer: session id too big (%lu bytes)", (unsigned long)key_len); return; } if(val_len>MAX_VAL_LEN) { s_log(LOG_ERR, "cache_transfer: encoded session too big (%lu bytes)", (unsigned long)key_len); return; } packet=str_alloc(sizeof(CACHE_PACKET)); /* setup packet */ packet->version=1; packet->type=type; packet->timeout=htons((u_short)(timeout<64800?timeout:64800));/* 18 hours */ memcpy(packet->key, key, key_len); memcpy(packet->val, val, val_len); /* create the socket */ s=s_socket(AF_INET, SOCK_DGRAM, 0, 0, "cache_transfer: socket"); if(s==INVALID_SOCKET) { str_free(packet); return; } /* retrieve pointer to the section structure of this ctx */ section=SSL_CTX_get_ex_data(ctx, index_opt); if(sendto(s, (void *)packet, #ifdef USE_WIN32 (int) #endif (sizeof(CACHE_PACKET)-MAX_VAL_LEN+val_len), 0, §ion->sessiond_addr.sa, addr_len(§ion->sessiond_addr))<0) { sockerror("cache_transfer: sendto"); closesocket(s); str_free(packet); return; } if(!ret || !ret_len) { /* no response is required */ closesocket(s); str_free(packet); return; } /* set recvfrom timeout to 200ms */ t.tv_sec=0; t.tv_usec=200; if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (void *)&t, sizeof t)<0) { sockerror("cache_transfer: setsockopt SO_RCVTIMEO"); closesocket(s); str_free(packet); return; } /* retrieve response */ len=recv(s, (void *)packet, sizeof(CACHE_PACKET), 0); closesocket(s); if(len<0) { if(get_last_socket_error()==S_EWOULDBLOCK || get_last_socket_error()==S_EAGAIN) s_log(LOG_INFO, "cache_transfer: recv timeout"); else sockerror("cache_transfer: recv"); str_free(packet); return; } /* parse results */ if(len<(int)sizeof(CACHE_PACKET)-MAX_VAL_LEN || /* too short */ packet->version!=1 || /* wrong version */ safe_memcmp(packet->key, key, key_len)) { /* wrong session id */ s_log(LOG_DEBUG, "cache_transfer: malformed packet received"); str_free(packet); return; } if(packet->type!=CACHE_RESP_OK) { s_log(LOG_INFO, "cache_transfer: session not found"); str_free(packet); return; } *ret_len=(size_t)len-(sizeof(CACHE_PACKET)-MAX_VAL_LEN); *ret=str_alloc(*ret_len); s_log(LOG_INFO, "cache_transfer: session found"); memcpy(*ret, packet->val, *ret_len); str_free(packet); }
/* * call-seq: * ctx.setup => Qtrue # first time * ctx.setup => nil # thereafter * * This method is called automatically when a new SSLSocket is created. * Normally you do not need to call this method (unless you are writing an extension in C). */ static VALUE ossl_sslctx_setup(VALUE self) { SSL_CTX *ctx; X509 *cert = NULL, *client_ca = NULL; X509_STORE *store; EVP_PKEY *key = NULL; char *ca_path = NULL, *ca_file = NULL; int i, verify_mode; VALUE val; Data_Get_Struct(self, SSL_CTX, ctx); if(SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx) == (void*)self) return Qnil; SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self); #if !defined(OPENSSL_NO_DH) if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){ SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); } else{ SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback); } #endif val = ossl_sslctx_get_cert_store(self); if(!NIL_P(val)){ /* * WORKAROUND: * X509_STORE can count references, but * X509_STORE_free() doesn't care it. * So we won't increment it but mark it by ex_data. */ store = GetX509StorePtr(val); /* NO NEED TO DUP */ SSL_CTX_set_cert_store(ctx, store); SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1); } val = ossl_sslctx_get_extra_cert(self); if(!NIL_P(val)){ size_t i; for(i = 0; i < rb_ary_size(val); i++) { ossl_sslctx_add_extra_chain_cert_i(rb_ary_entry(val, i), self); } } /* private key may be bundled in certificate file. */ val = ossl_sslctx_get_cert(self); cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */ val = ossl_sslctx_get_key(self); key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */ if (cert && key) { if (!SSL_CTX_use_certificate(ctx, cert)) { /* Adds a ref => Safe to FREE */ ossl_raise(eSSLError, "SSL_CTX_use_certificate:"); } if (!SSL_CTX_use_PrivateKey(ctx, key)) { /* Adds a ref => Safe to FREE */ ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey:"); } if (!SSL_CTX_check_private_key(ctx)) { ossl_raise(eSSLError, "SSL_CTX_check_private_key:"); } } val = ossl_sslctx_get_client_ca(self); if(!NIL_P(val)){ if(TYPE(val) == T_ARRAY){ for(i = 0; i < RARRAY_LEN(val); i++){ client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]); if (!SSL_CTX_add_client_CA(ctx, client_ca)){ /* Copies X509_NAME => FREE it. */ ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); } } } else{ client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ if (!SSL_CTX_add_client_CA(ctx, client_ca)){ /* Copies X509_NAME => FREE it. */ ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); } } } val = ossl_sslctx_get_ca_file(self); ca_file = NIL_P(val) ? NULL : StringValuePtr(val); val = ossl_sslctx_get_ca_path(self); ca_path = NIL_P(val) ? NULL : StringValuePtr(val); if(ca_file || ca_path){ if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) rb_warning("can't set verify locations"); } val = ossl_sslctx_get_verify_mode(self); verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val); SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback); if (RTEST(ossl_sslctx_get_client_cert_cb(self))) SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); val = ossl_sslctx_get_timeout(self); if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val)); val = ossl_sslctx_get_verify_dep(self); if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val)); val = ossl_sslctx_get_options(self); if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val)); val = ossl_sslctx_get_sess_id_ctx(self); if (!NIL_P(val)){ StringValue(val); if (!SSL_CTX_set_session_id_context(ctx, RSTRING_PTR(val), RSTRING_LEN(val))){ ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:"); } } if (RTEST(rb_iv_get(self, "@session_get_cb"))) { SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); OSSL_Debug("SSL SESSION get callback added"); } if (RTEST(rb_iv_get(self, "@session_new_cb"))) { SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); OSSL_Debug("SSL SESSION new callback added"); } if (RTEST(rb_iv_get(self, "@session_remove_cb"))) { SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); OSSL_Debug("SSL SESSION remove callback added"); } return Qtrue; }
static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder) { ngx_url_t u; char *s; ngx_ssl_stapling_t *staple; STACK_OF(OPENSSL_STRING) *aia; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); if (responder->len == 0) { /* extract OCSP responder URL from certificate */ aia = X509_get1_ocsp(staple->cert); if (aia == NULL) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " "no OCSP responder URL in the certificate"); return NGX_DECLINED; } #if OPENSSL_VERSION_NUMBER >= 0x10000000L s = sk_OPENSSL_STRING_value(aia, 0); #else s = sk_value(aia, 0); #endif if (s == NULL) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " "no OCSP responder URL in the certificate"); X509_email_free(aia); return NGX_DECLINED; } responder->len = ngx_strlen(s); responder->data = ngx_palloc(cf->pool, responder->len); if (responder->data == NULL) { X509_email_free(aia); return NGX_ERROR; } ngx_memcpy(responder->data, s, responder->len); X509_email_free(aia); } ngx_memzero(&u, sizeof(ngx_url_t)); u.url = *responder; u.default_port = 80; u.uri_part = 1; if (u.url.len > 7 && ngx_strncasecmp(u.url.data, (u_char *) "http://", 7) == 0) { u.url.len -= 7; u.url.data += 7; } else { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " "invalid URL prefix in OCSP responder \"%V\"", &u.url); return NGX_DECLINED; } if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " "%s in OCSP responder \"%V\"", u.err, &u.url); return NGX_DECLINED; } return NGX_ERROR; } staple->addrs = u.addrs; staple->host = u.host; staple->uri = u.uri; staple->port = u.port; if (staple->uri.len == 0) { ngx_str_set(&staple->uri, "/"); } return NGX_OK; }
static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl) { int i, n, rc; X509 *cert, *issuer; X509_STORE *store; X509_STORE_CTX *store_ctx; STACK_OF(X509) *chain; ngx_ssl_stapling_t *staple; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); #if OPENSSL_VERSION_NUMBER >= 0x10001000L SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain); #else chain = ssl->ctx->extra_certs; #endif n = sk_X509_num(chain); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: %d extra certs", n); for (i = 0; i < n; i++) { issuer = sk_X509_value(chain, i); if (X509_check_issued(issuer, cert) == X509_V_OK) { #if OPENSSL_VERSION_NUMBER >= 0x10100001L X509_up_ref(issuer); #else CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509); #endif ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: found %p in extra certs", issuer); staple->cert = cert; staple->issuer = issuer; return NGX_OK; } } store = SSL_CTX_get_cert_store(ssl->ctx); if (store == NULL) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_get_cert_store() failed"); return NGX_ERROR; } store_ctx = X509_STORE_CTX_new(); if (store_ctx == NULL) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_STORE_CTX_new() failed"); return NGX_ERROR; } if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_STORE_CTX_init() failed"); X509_STORE_CTX_free(store_ctx); return NGX_ERROR; } rc = X509_STORE_CTX_get1_issuer(&issuer, store_ctx, cert); if (rc == -1) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_STORE_CTX_get1_issuer() failed"); X509_STORE_CTX_free(store_ctx); return NGX_ERROR; } if (rc == 0) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, issuer certificate not found"); X509_STORE_CTX_free(store_ctx); return NGX_DECLINED; } X509_STORE_CTX_free(store_ctx); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: found %p in cert store", issuer); staple->cert = cert; staple->issuer = issuer; return NGX_OK; }
h2o_cache_t *h2o_socket_ssl_get_session_cache(SSL_CTX *ctx) { return (h2o_cache_t *)SSL_CTX_get_ex_data(ctx, get_ssl_session_cache_index()); }