Пример #1
0
int tls_sc_add_ca_cert(lua_State *L)
{
  tls_sc_t *ctx = getSC(L);
  X509 *x509;
  int newCAStore = FALSE;

  if (!ctx->ca_store) {
    ctx->ca_store = X509_STORE_new();
    newCAStore = TRUE;
  }

  x509 = _lua_load_x509(L, 2);
  if (!x509) {
    lua_pushboolean(L, 0);
    return 1;
  }

  X509_STORE_add_cert(ctx->ca_store, x509);
  SSL_CTX_add_client_CA(ctx->ctx, x509);
  X509_free(x509);

  if (newCAStore) {
    SSL_CTX_set_cert_store(ctx->ctx, ctx->ca_store);
  }

  lua_pushboolean(L, 1);
  return 1;
}
Пример #2
0
// XXX Clean up this function, we MUST handle all errors possible
int krypt_set_rsa(krypt_t *kconn)
{
	if (kconn->security_level == KRYPT_RSA) {
		jlog(L_NOTICE, "the security level is already set to RSA");
		return 0;
	}

	SSL_set_cipher_list(kconn->ssl, "AES256-SHA");

	// Load the trusted certificate store into our SSL_CTX
	SSL_CTX_set_cert_store(kconn->ctx, kconn->passport->trusted_authority);

	// Force the peer cert verifying + fail if no cert is sent by the peer
	SSL_set_verify(kconn->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback);

	// Set the certificate and key
	SSL_use_certificate(kconn->ssl, kconn->passport->certificate);
	SSL_use_PrivateKey(kconn->ssl, kconn->passport->keyring);

	if (kconn->conn_type == KRYPT_SERVER) {
		jlog(L_NOTICE, "set verify");

			// Change the session id to avoid resuming ADH session
		SSL_set_session_id_context(kconn->ssl, (void*)&s_server_auth_session_id_context,
							sizeof(s_server_auth_session_id_context));
	}

	kconn->security_level = KRYPT_RSA;

	return 0;
}
Пример #3
0
static int openssl_ssl_ctx_cert_store(lua_State*L)
{
  SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx");
  X509_STORE *store = NULL;
#if OPENSSL_VERSION_NUMBER >  0x10002000L
  if (lua_isnoneornil(L, 2))
  {
    store = SSL_CTX_get_cert_store(ctx);
    CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
    PUSH_OBJECT(store, "openssl.x509_store");
    return 1;
  }
  else
  {
    store = CHECK_OBJECT(2, X509_STORE, "openssl.x509_store");
    CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
    SSL_CTX_set_cert_store(ctx, store);
    X509_STORE_set_trust(store, 1);
    return 0;
  }
#else
  luaL_error(L, "NYI, openssl below 1.0.2 not fully support this feature");
  return 0;
#endif
}
Пример #4
0
void SSLContextManager::reloadTrustStore(Uint32 contextType)
{
    PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::reloadTrustStore()");

    SSL_CTX* sslContext;
    String trustStore = String::EMPTY;

    if ( contextType == SERVER_CONTEXT && _sslContext )
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
            "Context Type is Server Context.");
        sslContext = _sslContext->_rep->getContext();
        trustStore = _sslContext->getTrustStore();
    }
    else if ( contextType == EXPORT_CONTEXT && _exportSSLContext )
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
            "Context Type is Export Context.");
        sslContext = _exportSSLContext->_rep->getContext();
        trustStore = _exportSSLContext->getTrustStore();
    }
    else
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
          "Could not reload the trust store, SSL Context is not initialized.");

        MessageLoaderParms parms(
         "Pegasus.Common.SSLContextManager.COULD_NOT_RELOAD_TRUSTSTORE_SSL_CONTEXT_NOT_INITIALIZED",
         "Could not reload the trust store, SSL Context is not initialized.");
        PEG_METHOD_EXIT();
        throw SSLException(parms);
    }

    if (trustStore == String::EMPTY)
    {
        PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
            "Could not reload the trust store, the trust store is not configured.");

        MessageLoaderParms parms(
            "Pegasus.Common.SSLContextManager.TRUST_STORE_NOT_CONFIGURED",
            "Could not reload the trust store, the trust store is not configured.");
        PEG_METHOD_EXIT();
        throw SSLException(parms);
    }

    X509_STORE* newStore = _getNewX509Store(trustStore);

    //
    // acquire write lock to Context object and then overwrite the trust 
    // store cache
    //
    {
        WriteLock contextLock(_sslContextObjectLock);
        SSL_CTX_set_cert_store(sslContext, newStore);
    }
    PEG_METHOD_EXIT();
}
Пример #5
0
SSL_CTX *
evssl_init()
{
	DH		*dh;
	SSL_CTX		*ctx;

	SSL_load_error_strings();
	SSL_library_init();
	RAND_poll();

	if ((passport = pki_passport_load_from_file(cfg->cert,
	    cfg->pkey, cfg->tcert)) == NULL) {
		return NULL;
	}

	if ((ctx = SSL_CTX_new(TLSv1_2_client_method())) == NULL) {
		jlog(L_ERROR, "SSL_CTX_new failed");
		return NULL;
	}

	if ((dh = get_dh_1024()) == NULL) {
		jlog(L_ERROR, "get_dh_1024 failed");
		goto out;
	}

	if ((SSL_CTX_set_tmp_dh(ctx, dh)) == 0) {
		jlog(L_ERROR, "SSL_CTX_set_tmp_dh failed");
		goto out;
	}

	//SSL_CTX_set_cipher_list(ctx, "ECDHE-ECDSA-AES256-GCM-SHA384");
	if ((SSL_CTX_set_cipher_list(ctx, "AES256-GCM-SHA384")) == 0) {
		jlog(L_ERROR, "SSL_CTX_set_cipher failed");
		goto out;
	}

	SSL_CTX_set_cert_store(ctx, passport->cacert_store);

	if ((SSL_CTX_use_certificate(ctx, passport->certificate)) == 0) {
		jlog(L_ERROR, "SSL_CTX_use_certificate failed");
		goto out;
	}

	if ((SSL_CTX_use_PrivateKey(ctx, passport->keyring)) == 0) {
		jlog(L_ERROR, "SSL_CTX_use_PrivateKey failed");
		goto out;
	}

	DH_free(dh);
	return ctx;

out:
	DH_free(dh);
	SSL_CTX_free(ctx);
	return NULL;
}
Пример #6
0
static int
tls_sc_add_root_certs(lua_State *L) {
  int i;
  tls_sc_t *ctx = getSC(L);

  ERR_clear_error();

  if (!root_cert_store) {
    root_cert_store = X509_STORE_new();

    for (i = 0; root_certs[i]; i++) {
      BIO *bp = BIO_new(BIO_s_mem());
      X509 *x509;

      if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
        printf("error writing cert %s\n", root_certs[i]);
        BIO_free(bp);
        lua_pushboolean(L, 0);
        return 1;
      }

      x509 = PEM_read_bio_X509(bp, NULL, 0, NULL);
      if (x509 == NULL) {
        char buf[1024];
        ERR_error_string(ERR_get_error(), buf);

        printf("error writing x509 cert %s\n", buf);
        BIO_free(bp);
        lua_pushboolean(L, 0);
        return 1;
      }

      X509_STORE_add_cert(root_cert_store, x509);

      BIO_free(bp);
      X509_free(x509);
    }
  }

  ctx->ca_store = root_cert_store;
  SSL_CTX_set_cert_store(ctx->ctx, ctx->ca_store);

  lua_pushboolean(L, 1);
  return 1;
}
void ssl_clear_cert_auth_internal( int sslContextHandle )
{
    SSL *ssl = NULL;
    
    if((sslContextHandle >= ARRAYSIZE(g_SSL_Driver.m_sslContextArray)) || (sslContextHandle < 0))
    {
        return;
    }

    ssl = (SSL*)g_SSL_Driver.m_sslContextArray[sslContextHandle].SslContext;
    if (ssl == NULL)
    {
        return;
    }

    // Set a NULL cert store, SSL_CTX_set_cert_store will free the existing cert store
    SSL_CTX_set_cert_store( SSL_get_SSL_CTX(ssl), NULL );
}
Пример #8
0
/**
 * ssl_load_certificates - Load certificates and filter out the expired ones
 * @param ctx SSL context
 * @retval 1 Success
 * @retval 0 Error
 *
 * ssl certificate verification can behave strangely if there are expired certs
 * loaded into the trusted store.  This function filters out expired certs.
 *
 * Previously the code used this form:
 *     SSL_CTX_load_verify_locations (ssldata->ctx, #C_CertificateFile, NULL);
 */
static int ssl_load_certificates(SSL_CTX *ctx)
{
  FILE *fp = NULL;
  X509 *cert = NULL;
  X509_STORE *store = NULL;
  int rc = 1;
  char buf[256];

  mutt_debug(LL_DEBUG2, "loading trusted certificates\n");
  store = SSL_CTX_get_cert_store(ctx);
  if (!store)
  {
    store = X509_STORE_new();
    SSL_CTX_set_cert_store(ctx, store);
  }

  fp = fopen(C_CertificateFile, "rt");
  if (!fp)
    return 0;

  while (NULL != PEM_read_X509(fp, &cert, NULL, NULL))
  {
    if ((X509_cmp_current_time(X509_get0_notBefore(cert)) >= 0) ||
        (X509_cmp_current_time(X509_get0_notAfter(cert)) <= 0))
    {
      mutt_debug(LL_DEBUG2, "filtering expired cert: %s\n",
                 X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)));
    }
    else
    {
      X509_STORE_add_cert(store, cert);
    }
  }
  /* PEM_read_X509 sets the error NO_START_LINE on eof */
  if (ERR_GET_REASON(ERR_peek_last_error()) != PEM_R_NO_START_LINE)
    rc = 0;
  ERR_clear_error();

  X509_free(cert);
  mutt_file_fclose(&fp);

  return rc;
}
Пример #9
0
/**
 * @brief HTTPS::HTTPS
 * @param inServer
 * @param inPath
 * @param args
 * @param max_redir
 */
HTTPS::HTTPS(std::string inServer, std::string inPath, Arguments *args, int max_redir) : HTTP(inServer, inPath, max_redir)
{
    m_args = args;
    ctx = NULL;
    ssl = NULL;
    SSL_library_init();
    OpenSSL_add_all_algorithms(); // requited initialization functions

    m_port = 443; // port for SSL
    ctx = SSL_CTX_new(SSLv23_client_method()); // for better compatibility
    if (args->getCertfileUsed()) // if we are using certfile
    {
        if (!SSL_CTX_load_verify_locations(ctx, args->sCertFileName().c_str(), NULL)) // test the file
        {
            throw ISAException("Error - Loading Certificate File");
        }
    }
    else if (args->getCertfileFolderUsed()) // if we are using a folder
    {
        if (!SSL_CTX_load_verify_locations(ctx, NULL, args->sCertFilesFolder().c_str())) // test the folder
        {
            throw ISAException("Error - Loading Certificates from a folder");
        }
    }
    else
    {

        if (!SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs/")) // default folder for certs
        {
            throw ISAException("Error - Loading cerificates from /etc/ssl/certs");
        }

    }
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
    SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
    SSL_CTX_get_cert_store(ctx); // set up a store
    certstore = X509_STORE_new(); // create a new one
    if (m_args->getCertfileUsed()) X509_STORE_load_locations(certstore, m_args->sCertFileName().c_str(), NULL); // if we use file, test again
    else if (m_args->getCertfileFolderUsed()) X509_STORE_load_locations(certstore, NULL, m_args->sCertFilesFolder().c_str()); // test folder
    else X509_STORE_load_locations(certstore, NULL, "/etc/ssl/certs/"); // else load default location
    if (certstore == NULL) throw ISAException("Error - Certificate could not be loaded."); // error, throw ISAException
    SSL_CTX_set_cert_store(ctx, certstore); // set up the store with ctx
}
Пример #10
0
void TLSConnectionPrivate::OnConnect(uv_connect_t *connect, int status) {
	TLSConnectionPrivate *cp = static_cast<TLSConnectionPrivate *>(connect->data);
	assert(cp->state_ == TLS_CONNECTION_STATE_PRE_CONNECT);

	// Unable to connect.
	if (status == -1) {
		cp->ShutdownError(UVUtils::ErrorFromLastUVError(cp->loop_));
		return;
	}

	// Begin reading the incoming stream of data.
	int err = uv_read_start(connect->handle, TLSConnectionPrivate::AllocCallback, TLSConnectionPrivate::OnRead);
	if (err != UV_OK) {
		cp->ShutdownError(UVUtils::ErrorFromLastUVError(cp->loop_));
		return;
	}

	// Set up the OpenSSL context
	const SSL_METHOD *meth = TLSv1_client_method();
	cp->ctx_ = SSL_CTX_new(meth);

	SSL_CTX_set_verify(cp->ctx_, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
	SSL_CTX_set_cert_verify_callback(cp->ctx_, TLSConnectionPrivate::SSLVerifyCallback, cp);

	cp->ssl_ = SSL_new(cp->ctx_);
	SSL_set_connect_state(cp->ssl_);
	cp->bio_ = BIO_new(UVBioState::GetMethod());
	cp->biostate_ = new UVBioState(connect);
	cp->bio_->ptr = cp->biostate_;
	SSL_set_bio(cp->ssl_, cp->bio_, cp->bio_);

	// Set an empty X509_STORE as our SSL_CTX cert store.
	// The default store should be empty as well, but let's
	// make sure.
	X509_STORE *store = X509_STORE_new();
	SSL_CTX_set_cert_store(cp->ctx_, store);

	cp->state_ = TLS_CONNECTION_STATE_STARVED_SSL_CONNECT;
	cp->HandleStarvedConnectState();
}
Пример #11
0
static int
tls_sc_add_trusted_cert(lua_State *L) {
  tls_sc_t *ctx;
  BIO *bio;
  const char *certstr = NULL;
  size_t clen = 0;
  int rv;

  ctx = getSC(L);

  if (ctx->ca_store == NULL) {
    /* TODO: better handling of global CA cert list */
    ctx->ca_store = X509_STORE_new();
    SSL_CTX_set_cert_store(ctx->ctx, ctx->ca_store);
  }

  certstr = luaL_checklstring(L, 2, &clen);

  bio = str2bio(certstr, clen);

  if (!bio) {
    return luaL_error(L, "tls_sc_add_trusted_cert: Failed to convert Cert into a BIO");
  }

  ERR_clear_error();

  rv = X509_STORE_load_bio(ctx->ca_store, bio);

  if (!rv) {
    BIO_free(bio);
    return tls_fatal_error(L);
  }

  BIO_free(bio);

  return 0;
}
Пример #12
0
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server)
{
	GIOSSLChannel *chan;
	GIOChannel *gchan;
	int fd;
	SSL *ssl;
	SSL_CTX *ctx = NULL;

	const char *mycert = server->connrec->tls_cert;
	const char *mypkey = server->connrec->tls_pkey;
	const char *mypass = server->connrec->tls_pass;
	const char *cafile = server->connrec->tls_cafile;
	const char *capath = server->connrec->tls_capath;
	const char *ciphers = server->connrec->tls_ciphers;
	gboolean verify = server->connrec->tls_verify;

	g_return_val_if_fail(handle != NULL, NULL);

	if(!ssl_inited && !irssi_ssl_init())
		return NULL;

	if(!(fd = g_io_channel_unix_get_fd(handle)))
		return NULL;

	ERR_clear_error();
	ctx = SSL_CTX_new(SSLv23_client_method());
	if (ctx == NULL) {
		g_error("Could not allocate memory for SSL context");
		return NULL;
	}
	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
	SSL_CTX_set_default_passwd_cb(ctx, get_pem_password_callback);
	SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)mypass);

	if (ciphers != NULL && ciphers[0] != '\0') {
		if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1)
			g_warning("No valid SSL cipher suite could be selected");
	}

	if (mycert && *mycert) {
		char *scert = NULL, *spkey = NULL;
		FILE *fp;
		scert = convert_home(mycert);
		if (mypkey && *mypkey)
			spkey = convert_home(mypkey);

		if ((fp = fopen(scert, "r"))) {
			X509 *cert;
			/* Let's parse the certificate by hand instead of using
			 * SSL_CTX_use_certificate_file so that we can validate
			 * some parts of it. */
			cert = PEM_read_X509(fp, NULL, get_pem_password_callback, (void *)mypass);
			if (cert != NULL) {
				/* Only the expiration date is checked right now */
				if (X509_cmp_current_time(X509_get_notAfter(cert))  <= 0 ||
				    X509_cmp_current_time(X509_get_notBefore(cert)) >= 0)
					g_warning("The client certificate is expired");

				ERR_clear_error();
				if (! SSL_CTX_use_certificate(ctx, cert))
					g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error()));
				else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM))
					g_warning("Loading of private key '%s' failed: %s", mypkey ? mypkey : mycert, ERR_reason_error_string(ERR_get_error()));
				else if (! SSL_CTX_check_private_key(ctx))
					g_warning("Private key does not match the certificate");

				X509_free(cert);
			} else
				g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error()));

			fclose(fp);
		} else
			g_warning("Could not find client certificate '%s'", scert);
		g_free(scert);
		g_free(spkey);
	}

	if ((cafile && *cafile) || (capath && *capath)) {
		char *scafile = NULL;
		char *scapath = NULL;
		if (cafile && *cafile)
			scafile = convert_home(cafile);
		if (capath && *capath)
			scapath = convert_home(capath);
		if (! SSL_CTX_load_verify_locations(ctx, scafile, scapath)) {
			g_warning("Could not load CA list for verifying TLS server certificate");
			g_free(scafile);
			g_free(scapath);
			SSL_CTX_free(ctx);
			return NULL;
		}
		g_free(scafile);
		g_free(scapath);
		verify = TRUE;
	} else if (store != NULL) {
		/* Make sure to increment the refcount every time the store is
		 * used, that's essential not to get it free'd by OpenSSL when
		 * the SSL_CTX is destroyed. */
		X509_STORE_up_ref(store);
		SSL_CTX_set_cert_store(ctx, store);
	}

	if(!(ssl = SSL_new(ctx)))
	{
		g_warning("Failed to allocate SSL structure");
		SSL_CTX_free(ctx);
		return NULL;
	}

	if(!SSL_set_fd(ssl, fd))
	{
		g_warning("Failed to associate socket to SSL stream");
		SSL_free(ssl);
		SSL_CTX_free(ctx);
		return NULL;
	}

#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	SSL_set_tlsext_host_name(ssl, server->connrec->address);
#endif

	SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
			SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

	chan = g_new0(GIOSSLChannel, 1);
	chan->fd = fd;
	chan->giochan = handle;
	chan->ssl = ssl;
	chan->ctx = ctx;
	chan->server = server;
	chan->port = port;
	chan->verify = verify;

	gchan = (GIOChannel *)chan;
	gchan->funcs = &irssi_ssl_channel_funcs;
	g_io_channel_init(gchan);
	gchan->is_readable = gchan->is_writeable = TRUE;
	gchan->use_buffer = FALSE;

	return gchan;
}
Пример #13
0
static int
do_ca_cert_bootstrap(struct stream *stream)
{
    struct ssl_stream *sslv = ssl_stream_cast(stream);
    STACK_OF(X509) *chain;
    X509 *cert;
    FILE *file;
    int error;
    int fd;

    chain = SSL_get_peer_cert_chain(sslv->ssl);
    if (!chain || !sk_X509_num(chain)) {
        VLOG_ERR("could not bootstrap CA cert: no certificate presented by "
                 "peer");
        return EPROTO;
    }
    cert = sk_X509_value(chain, sk_X509_num(chain) - 1);

    /* Check that 'cert' is self-signed.  Otherwise it is not a CA
     * certificate and we should not attempt to use it as one. */
    error = X509_check_issued(cert, cert);
    if (error) {
        VLOG_ERR("could not bootstrap CA cert: obtained certificate is "
                 "not self-signed (%s)",
                 X509_verify_cert_error_string(error));
        if (sk_X509_num(chain) < 2) {
            VLOG_ERR("only one certificate was received, so probably the peer "
                     "is not configured to send its CA certificate");
        }
        return EPROTO;
    }

    fd = open(ca_cert.file_name, O_CREAT | O_EXCL | O_WRONLY, 0444);
    if (fd < 0) {
        if (errno == EEXIST) {
            VLOG_INFO_RL(&rl, "reading CA cert %s created by another process",
                         ca_cert.file_name);
            stream_ssl_set_ca_cert_file__(ca_cert.file_name, true, true);
            return EPROTO;
        } else {
            VLOG_ERR("could not bootstrap CA cert: creating %s failed: %s",
                     ca_cert.file_name, ovs_strerror(errno));
            return errno;
        }
    }

    file = fdopen(fd, "w");
    if (!file) {
        error = errno;
        VLOG_ERR("could not bootstrap CA cert: fdopen failed: %s",
                 ovs_strerror(error));
        unlink(ca_cert.file_name);
        return error;
    }

    if (!PEM_write_X509(file, cert)) {
        VLOG_ERR("could not bootstrap CA cert: PEM_write_X509 to %s failed: "
                 "%s", ca_cert.file_name,
                 ERR_error_string(ERR_get_error(), NULL));
        fclose(file);
        unlink(ca_cert.file_name);
        return EIO;
    }

    if (fclose(file)) {
        error = errno;
        VLOG_ERR("could not bootstrap CA cert: writing %s failed: %s",
                 ca_cert.file_name, ovs_strerror(error));
        unlink(ca_cert.file_name);
        return error;
    }

    VLOG_INFO("successfully bootstrapped CA cert to %s", ca_cert.file_name);
    log_ca_cert(ca_cert.file_name, cert);
    bootstrap_ca_cert = false;
    ca_cert.read = true;

    /* SSL_CTX_add_client_CA makes a copy of cert's relevant data. */
    SSL_CTX_add_client_CA(ctx, cert);

    SSL_CTX_set_cert_store(ctx, X509_STORE_new());
    if (SSL_CTX_load_verify_locations(ctx, ca_cert.file_name, NULL) != 1) {
        VLOG_ERR("SSL_CTX_load_verify_locations: %s",
                 ERR_error_string(ERR_get_error(), NULL));
        return EPROTO;
    }
    VLOG_INFO("killing successful connection to retry using CA cert");
    return EPROTO;
}
Пример #14
0
int LLVMFuzzerInitialize(int* argc, char*** argv)
{
    rand_predictable = 1;

    SSL_library_init();
    OpenSSL_add_ssl_algorithms();
    ERR_load_crypto_strings();

    if (RAND_reset_for_fuzzing)
        RAND_reset_for_fuzzing();

    ctx = SSL_CTX_new(SSLv23_method());
    const uint8_t* bufp = kRSAPrivateKeyDER;
    RSA* privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER));
    assert(privkey != NULL);
    EVP_PKEY* pkey = EVP_PKEY_new();
    EVP_PKEY_assign_RSA(pkey, privkey);
    int ret = SSL_CTX_use_PrivateKey(ctx, pkey);
    assert(ret == 1);
    EVP_PKEY_free(pkey);

    bufp = kCertificateDER;
    X509* cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER));
    assert(cert != NULL);
    ret = SSL_CTX_use_certificate(ctx, cert);
    assert(ret == 1);
    X509_free(cert);
    ret = SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:aNULL:DSS");
    assert(ret == 1);

    X509_STORE* store = X509_STORE_new();
    assert(store != NULL);

    bufp = kRSACACertDER;
    cert = d2i_X509(NULL, &bufp, sizeof(kRSACACertDER));
    assert(cert != NULL);
    ret = SSL_CTX_add_client_CA(ctx, cert);
    assert(ret == 1);
    ret = X509_STORE_add_cert(store, cert);
    assert(ret == 1);
    X509_free(cert);

    bufp = kECCACertDER;
    cert = d2i_X509(NULL, &bufp, sizeof(kECCACertDER));
    assert(cert != NULL);
    ret = SSL_CTX_add_client_CA(ctx, cert);
    assert(ret == 1);
    ret = X509_STORE_add_cert(store, cert);
    assert(ret == 1);
    X509_free(cert);

    bufp = kDSACertDER;
    cert = d2i_X509(NULL, &bufp, sizeof(kDSACertDER));
    ret = SSL_CTX_add_client_CA(ctx, cert);
    assert(ret == 1);
    ret = X509_STORE_add_cert(store, cert);
    assert(ret == 1);
    X509_free(cert);

    SSL_CTX_set_cert_store(ctx, store);
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
    SSL_CTX_set_verify_depth(ctx, 10);

#if !defined(LIBRESSL_VERSION_NUMBER)
    SSL_CTX_set_psk_server_callback(ctx, psk_callback);
    ret = SSL_CTX_use_psk_identity_hint(ctx, "ABCDEFUZZ");
    assert(ret == 1);
#endif /* !defined(LIBRESSL_VERSION_NUMBER) */

#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(BORINGSSL_API_VERSION)
    ret = SSL_CTX_set_srp_username_callback(ctx, srp_callback);
    assert(ret == 1);
    ret = SSL_CTX_set_srp_cb_arg(ctx, NULL);
    assert(ret == 1);
#endif /* !defined(LIBRESSL_VERSION_NUMBER) && !defined(BORINGSSL_API_VERSION) */

    SSL_CTX_set_alpn_select_cb(ctx, alpn_callback, NULL);
    SSL_CTX_set_next_protos_advertised_cb(ctx, npn_callback, NULL);
    SSL_CTX_set_ecdh_auto(ctx, 1);

    return 1;
}
Пример #15
0
void ContextImpl::assign(const ContextImpl& ctx)
{
    // TODO: consider to create a new SSL_CTX if required

    setProtocol(ctx._protocol);
    setVerifyMode(ctx._verify);
    setVerifyDepth(ctx._verifyDepth);

    // copy certificates presented to peer

    if(_pkey)
        EVP_PKEY_free(_pkey);
    _pkey = 0;
    
    if(_x509)
        X509_free(_x509);
    _x509 = 0;

    if( ctx._x509 )
    {
        _pkey = copyPrivateKey( ctx._pkey );  
        _x509 = copyX509( ctx._x509 );
        
        if( ! SSL_CTX_use_certificate(_ctx, _x509) )
        {
            throw InvalidCertificate("invalid certificate");
        }

        if( ! SSL_CTX_use_PrivateKey( _ctx, _pkey ) )
        {
            throw InvalidCertificate("invalid certificate");
        }
    }

    _extraCerts.clear();
    _extraCerts.reserve( ctx._extraCerts.size() );

    for(std::vector<X509*>::const_iterator it = ctx._extraCerts.begin(); it != ctx._extraCerts.end(); ++it)
    {
        // NOTE: SSL_CTX_add_extra_chain_cert does not copy the X509 certificate, 
        // or increase the refcount. We must copy it, because the SSL_CTX will
        // free it

        X509* extraX509 = copyX509(*it);
        X509AutoPtr x509Ptr(extraX509);

        if( ! SSL_CTX_add_extra_chain_cert( _ctx, extraX509 ) )
            throw InvalidCertificate("invalid extra certificate");

        _extraCerts.push_back(extraX509);
        x509Ptr.release();
    }

    // copy trusted CA certificates
    for(std::vector<X509*>::iterator it = _caCerts.begin(); it != _caCerts.end(); ++it)
    {
        X509_free(*it);
    }
    
    _caCerts.clear();
    _caCerts.reserve( ctx._caCerts.size() );

    X509_STORE* store = X509_STORE_new();
    X509StoreAutoPtr storePtr(store);

    for(std::vector<X509*>::const_iterator it = ctx._caCerts.begin(); it != ctx._caCerts.end(); ++it)
    {
        X509* x509 = copyX509(*it);
        X509AutoPtr x509Ptr(x509);

        if( ! X509_STORE_add_cert(store, x509) )
            throw InvalidCertificate("untrusted certificate");

        _caCerts.push_back(x509);
        x509Ptr.release();
    }

    SSL_CTX_set_cert_store( _ctx, store );
    storePtr.release();
}
Пример #16
0
int myproxy_ocsp_verify(X509 *cert, X509 *issuer) {
  BIO                   *bio = 0;
  int                   rc, reason, ssl, status;
  char                  *host = 0, *path = 0, *port = 0, *certdir = 0;
  char                  *aiaocspurl = 0, *chosenurl = 0;
  SSL_CTX               *ctx = 0;
  X509_LOOKUP           *lookup = NULL;
  X509_STORE            *store = 0;
  OCSP_CERTID           *id;
  OCSP_REQUEST          *req = 0;
  OCSP_RESPONSE         *resp = 0;
  OCSP_BASICRESP        *basic = 0;
  myproxy_ocspresult_t  result;
  ASN1_GENERALIZEDTIME  *producedAt, *thisUpdate, *nextUpdate;
  globus_result_t       res;

  if (!policy && !responder_url) {
      result = MYPROXY_OCSPRESULT_ERROR_NOTCONFIGURED;
      goto end;
  }

  result = MYPROXY_OCSPRESULT_ERROR_UNKNOWN;

  if (policy && strstr(policy, "aia")) {
      aiaocspurl = myproxy_get_aia_ocsp_uri(cert);
  }

  if (!responder_url && !aiaocspurl) {
      result = MYPROXY_OCSPRESULT_ERROR_NOTCONFIGURED;
      goto end;
  }

  chosenurl = aiaocspurl ? aiaocspurl : responder_url;
  if (!OCSP_parse_url(chosenurl, &host, &port, &path, &ssl)) {
    result = MYPROXY_OCSPRESULT_ERROR_BADOCSPADDRESS;
    goto end;
  }

  myproxy_log("querying OCSP responder at %s", chosenurl);

  if (!(req = OCSP_REQUEST_new())) {
    result = MYPROXY_OCSPRESULT_ERROR_OUTOFMEMORY;
    goto end;
  }

  id = OCSP_cert_to_id(0, cert, issuer);
  if (!id || !OCSP_request_add0_id(req, id)) goto end;
  if (usenonce) OCSP_request_add1_nonce(req, 0, -1);

  /* sign the request */
  if (sign_cert && sign_key &&
      !OCSP_request_sign(req, sign_cert, sign_key, EVP_sha1(), 0, 0)) {
    result = MYPROXY_OCSPRESULT_ERROR_SIGNFAILURE;
    goto end;
  }

  /* setup GSI context */
  store=X509_STORE_new();
  lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
  if (lookup == NULL) {
    result = MYPROXY_OCSPRESULT_ERROR_OUTOFMEMORY;
    goto end;
  }
  res = GLOBUS_GSI_SYSCONFIG_GET_CERT_DIR(&certdir);
  if (res != GLOBUS_SUCCESS) {
    verror_put_string("failed to find GSI CA cert directory");
    globus_error_to_verror(res);
    goto end;
  }
  X509_LOOKUP_add_dir(lookup, certdir, X509_FILETYPE_PEM);
  ctx = SSL_CTX_new(SSLv23_client_method());
  if (ctx == NULL) {
    result = MYPROXY_OCSPRESULT_ERROR_OUTOFMEMORY;
    goto end;
  }
  SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
  SSL_CTX_set_cert_store(ctx, store);
  SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);

  /* establish a connection to the OCSP responder */
  if (!(bio = my_connect(host, atoi(port), ssl, &ctx))) {
    result = MYPROXY_OCSPRESULT_ERROR_CONNECTFAILURE;
    goto end;
  }

  /* send the request and get a response */
  resp = OCSP_sendreq_bio(bio, path, req);
  if ((rc = OCSP_response_status(resp)) != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
    switch (rc) {
      case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST:
        result = MYPROXY_OCSPRESULT_ERROR_MALFORMEDREQUEST; break;
      case OCSP_RESPONSE_STATUS_INTERNALERROR:
        result = MYPROXY_OCSPRESULT_ERROR_INTERNALERROR;    break;
      case OCSP_RESPONSE_STATUS_TRYLATER:
        result = MYPROXY_OCSPRESULT_ERROR_TRYLATER;         break;
      case OCSP_RESPONSE_STATUS_SIGREQUIRED:
        result = MYPROXY_OCSPRESULT_ERROR_SIGREQUIRED;      break;
      case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
        result = MYPROXY_OCSPRESULT_ERROR_UNAUTHORIZED;     break;
    }
    goto end;
  }

  /* verify the response */
  result = MYPROXY_OCSPRESULT_ERROR_INVALIDRESPONSE;
  if (!(basic = OCSP_response_get1_basic(resp))) goto end;
  if (usenonce && OCSP_check_nonce(req, basic) <= 0) goto end;

  if (!responder_cert ||
      (rc = OCSP_basic_verify(basic, responder_cert, store,
                              OCSP_TRUSTOTHER)) <= 0)
      if ((rc = OCSP_basic_verify(basic, NULL, store, 0)) <= 0) 
          goto end;

  if (!OCSP_resp_find_status(basic, id, &status, &reason, &producedAt,
                             &thisUpdate, &nextUpdate))
    goto end;
  if (!OCSP_check_validity(thisUpdate, nextUpdate, skew, maxage))
    goto end;

  /* All done.  Set the return code based on the status from the response. */
  if (status == V_OCSP_CERTSTATUS_REVOKED) {
    result = MYPROXY_OCSPRESULT_CERTIFICATE_REVOKED;
    myproxy_log("OCSP status revoked!");
  } else {
    result = MYPROXY_OCSPRESULT_CERTIFICATE_VALID;
    myproxy_log("OCSP status valid");
  }

end:
  if (result < 0 && result != MYPROXY_OCSPRESULT_ERROR_NOTCONFIGURED) {
      ssl_error_to_verror();
      myproxy_log("OCSP check failed");
      myproxy_log_verror();
  }
  if (bio) BIO_free_all(bio);
  if (host) OPENSSL_free(host);
  if (port) OPENSSL_free(port);
  if (path) OPENSSL_free(path);
  if (req) OCSP_REQUEST_free(req);
  if (resp) OCSP_RESPONSE_free(resp);
  if (basic) OCSP_BASICRESP_free(basic);
  if (ctx) SSL_CTX_free(ctx);   /* this does X509_STORE_free(store) */
  if (certdir) free(certdir);
  if (aiaocspurl) free(aiaocspurl);

  return result;
}
Пример #17
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;

    if(OBJ_FROZEN(self)) return Qnil;
    Data_Get_Struct(self, SSL_CTX, ctx);

#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
    SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self);

    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)){
	rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_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));
    rb_obj_freeze(self);

    val = ossl_sslctx_get_sess_id_ctx(self);
    if (!NIL_P(val)){
	StringValue(val);
	if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)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");
    }

#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
    val = rb_iv_get(self, "@servername_cb");
    if (!NIL_P(val)) {
        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
	OSSL_Debug("SSL TLSEXT servername callback added");
    }
#endif

    return Qtrue;
}
Пример #18
0
void SSLContext::loadTrustedCertificates(X509_STORE* store) {
  SSL_CTX_set_cert_store(ctx_, store);
}