示例#1
0
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);
}
示例#2
0
文件: ossl_ssl.c 项目: 2220142/ruby
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);
}
示例#3
0
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));
    }
}
示例#4
0
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);
}
示例#5
0
文件: ossl_ssl.c 项目: 2220142/ruby
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));
*/
    }
}
示例#6
0
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);
}
示例#7
0
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;
}
示例#11
0
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);
}
示例#13
0
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;
}
示例#14
0
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;
}
示例#15
0
文件: utils.c 项目: androdev4u/bud
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;
}
示例#16
0
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;
}
示例#18
0
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, &section->sessiond_addr.sa,
            addr_len(&section->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);
}
示例#19
0
/*
 * 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;
}
示例#22
0
文件: socket.c 项目: deweerdt/h2o
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());
}