Exemple #1
0
bool VSslServer::setKeyCrtStuff(VError& error, SSL* con, EVP_PKEY* key, X509* crt)
{
  LOG_ASSERT(key != NULL);
  LOG_ASSERT(crt != NULL);

  // LOG_DEBUG("con=%p key=%p crt=%p", con, key, crt); // gilgil temp 2014.03.14
  int res = SSL_use_certificate(con, crt);
  if (res <= 0)
  {
    error = VSslError(QString("SSL_use_certificate return %1").arg(res), VSslError::IN_SSL_CTX_USE_CERTIFICATE);
    return false;
  }

  res = SSL_use_PrivateKey(con, key);
  if (res <= 0)
  {
    error = VSslError(QString("SSL_use_PrivateKey return %1").arg(res), VSslError::SSL_CTX_USER_PRIVATEKEY);
    return false;
  }

  res = SSL_check_private_key(con);
  if (!res)
  {
    error = VSslError(QString("SSL_check_private_key return %1").arg(res), VSslError::SSL_CTX_CHECK_PRIVATEKEY);
    return false;
  }

  return true;
}
Exemple #2
0
		bool Engine::set_p12_certificate_privatekey(const Data & data, const std::string & password)
		{
			if( data.empty() ) // BIO undefined behaviour when writing 0
				return false;
			BIO *mem = BIO_new(BIO_s_mem());
			BIO_write(mem, data.getData(), data.getSize());
			PKCS12 * pkcs12 = d2i_PKCS12_bio(mem, NULL);
			BIO_free(mem);
			mem = 0;
			X509 * cax = 0;
			EVP_PKEY * pkey = 0;
//			int succ = 
			PKCS12_parse(pkcs12, password.c_str(), &pkey, &cax, NULL);
//			int err = ERR_get_error();
//			const char * err_str = ERR_error_string(err, 0);
			int cert_res = SSL_use_certificate(ssl, cax);
			if (cax)
				X509_free(cax);
			cax = 0;
			int key_res = SSL_use_PrivateKey(ssl, pkey);
			if( pkey )
				EVP_PKEY_free(pkey);
			pkey = 0;
			int check_res = SSL_check_private_key(ssl);
			return cert_res == 1 && key_res == 1 && check_res == 1;
		}
Exemple #3
0
		bool Engine::set_pem_certificate_privatekey(const Data & data, const std::string & password)
		{
			if( data.empty() ) // BIO undefined behaviour when writing 0
				return false;
			BIO *mem = BIO_new(BIO_s_mem());
			BIO_write(mem, data.getData(), data.getSize());
			X509 * cax = PEM_read_bio_X509(mem, NULL, 0, const_cast<char *>(password.c_str())); // Stupid C guys
			BIO_free(mem);
			mem = 0;
			
			mem = BIO_new(BIO_s_mem());
			BIO_write(mem, data.getData(), data.getSize());
			EVP_PKEY * pkey = PEM_read_bio_PrivateKey(mem, NULL, 0, const_cast<char *>(password.c_str())); // Stupid C guys
			BIO_free(mem);
			mem = 0;
			
			int cert_res = SSL_use_certificate(ssl, cax);
			if (cax)
				X509_free(cax);
			cax = 0;
			int key_res = SSL_use_PrivateKey(ssl, pkey);
			if( pkey )
				EVP_PKEY_free(pkey);
			pkey = 0;
			int check_res = SSL_check_private_key(ssl);
			return cert_res == 1 && key_res == 1 && check_res == 1;
		}
Exemple #4
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;
}
Exemple #5
0
static int
openssl_iostream_use_certificate(struct ssl_iostream *ssl_io, const char *cert)
{
    BIO *in;
    X509 *x;
    int ret = 0;

    in = BIO_new_mem_buf(t_strdup_noconst(cert), strlen(cert));
    if (in == NULL) {
        i_error("BIO_new_mem_buf() failed: %s", openssl_iostream_error());
        return -1;
    }

    x = PEM_read_bio_X509(in, NULL, NULL, NULL);
    if (x != NULL) {
        ret = SSL_use_certificate(ssl_io->ssl, x);
        if (ERR_peek_error() != 0)
            ret = 0;
        X509_free(x);
    }
    BIO_free(in);

    if (ret == 0) {
        i_error("%s: Can't load ssl_cert: %s", ssl_io->source,
                ssl_iostream_get_use_certificate_error(cert));
        return -1;
    }
    return 0;
}
Exemple #6
0
void SSLConnect::setToken( const QSslCertificate &cert, Qt::HANDLE key )
{
	if( !d->ssl )
		return d->setError( tr("SSL context is missing") );
	if( cert.isNull() )
		return d->setError( tr("Certificate is empty") );
	if( !SSL_use_certificate( d->ssl, X509_dup( (X509*)cert.handle() ) ) ||
		!SSL_use_PrivateKey( d->ssl, (EVP_PKEY*)key ) )
		d->setError();
}
Exemple #7
0
static void
regress_bufferevent_openssl(void *arg)
{
	struct basic_test_data *data = arg;

	struct bufferevent *bev1, *bev2;
	SSL *ssl1, *ssl2;
	X509 *cert = getcert();
	EVP_PKEY *key = getkey();
	const int start_open = strstr((char*)data->setup_data, "open")!=NULL;
	const int filter = strstr((char*)data->setup_data, "filter")!=NULL;
	int flags = BEV_OPT_DEFER_CALLBACKS;
	struct bufferevent *bev_ll[2] = { NULL, NULL };
	evutil_socket_t *fd_pair = NULL;

	tt_assert(cert);
	tt_assert(key);

	init_ssl();

	if (strstr((char*)data->setup_data, "renegotiate")) {
		if (SSLeay() >= 0x10001000 &&
		    SSLeay() <  0x1000104f) {
			/* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2
			 * can't renegotiate with themselves. Disable. */
			disable_tls_11_and_12 = 1;
		}
		renegotiate_at = 600;
	}

	ssl1 = SSL_new(get_ssl_ctx());
	ssl2 = SSL_new(get_ssl_ctx());

	SSL_use_certificate(ssl2, cert);
	SSL_use_PrivateKey(ssl2, key);

	if (! start_open)
		flags |= BEV_OPT_CLOSE_ON_FREE;

	if (!filter) {
		tt_assert(strstr((char*)data->setup_data, "socketpair"));
		fd_pair = data->pair;
	} else {
		bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0],
		    BEV_OPT_CLOSE_ON_FREE);
		bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1],
		    BEV_OPT_CLOSE_ON_FREE);
	}

	open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2,
	    fd_pair, bev_ll);

	if (!filter) {
		tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]);
	} else {
Exemple #8
0
int SSL_use_certificate_file (SSL * ssl, const char *file, int type)
{
    int j;

    BIO *in;

    int ret = 0;

    X509 *x = NULL;

    in = BIO_new (BIO_s_file_internal ());
    if (in == NULL)
    {
        SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
        goto end;
    }

    if (BIO_read_filename (in, file) <= 0)
    {
        SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
        goto end;
    }
    if (type == SSL_FILETYPE_ASN1)
    {
        j = ERR_R_ASN1_LIB;
        x = d2i_X509_bio (in, NULL);
    }
    else if (type == SSL_FILETYPE_PEM)
    {
        j = ERR_R_PEM_LIB;
        x = PEM_read_bio_X509 (in, NULL, ssl->ctx->default_passwd_callback, ssl->ctx->default_passwd_callback_userdata);
    }
    else
    {
        SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
        goto end;
    }

    if (x == NULL)
    {
        SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, j);
        goto end;
    }

    ret = SSL_use_certificate (ssl, x);
  end:
    if (x != NULL)
        X509_free (x);
    if (in != NULL)
        BIO_free (in);
    return (ret);
}
Exemple #9
0
int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d, int len) {
  X509 *x;
  int ret;

  x = d2i_X509(NULL, &d, (long)len);
  if (x == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
    return 0;
  }

  ret = SSL_use_certificate(ssl, x);
  X509_free(x);
  return ret;
}
Exemple #10
0
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
{
    X509 *x;
    int ret;

    x = d2i_X509(NULL, &d, (long)len);
    if (x == NULL) {
        SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
        return (0);
    }

    ret = SSL_use_certificate(ssl, x);
    X509_free(x);
    return (ret);
}
Exemple #11
0
static void
regress_bufferevent_openssl(void *arg)
{
	struct basic_test_data *data = arg;

	struct bufferevent *bev1, *bev2;
	SSL *ssl1, *ssl2;
	X509 *cert = getcert();
	EVP_PKEY *key = getkey();
	const int start_open = strstr((char*)data->setup_data, "open")!=NULL;
	const int filter = strstr((char*)data->setup_data, "filter")!=NULL;
	int flags = BEV_OPT_DEFER_CALLBACKS;
	struct bufferevent *bev_ll[2] = { NULL, NULL };
	int *fd_pair = NULL;

	tt_assert(cert);
	tt_assert(key);

	init_ssl();

	ssl1 = SSL_new(get_ssl_ctx());
	ssl2 = SSL_new(get_ssl_ctx());

	SSL_use_certificate(ssl2, cert);
	SSL_use_PrivateKey(ssl2, key);

	if (! start_open)
		flags |= BEV_OPT_CLOSE_ON_FREE;

	if (strstr((char*)data->setup_data, "renegotiate"))
		renegotiate_at = 600;

	if (!filter) {
		tt_assert(strstr((char*)data->setup_data, "socketpair"));
		fd_pair = data->pair;
	} else {
		bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0],
		    BEV_OPT_CLOSE_ON_FREE);
		bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1],
		    BEV_OPT_CLOSE_ON_FREE);
	}

	open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2,
	    fd_pair, bev_ll);

	if (!filter) {
		tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]);
	} else {
Exemple #12
0
int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
  if (der_len > LONG_MAX) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
    return 0;
  }

  const uint8_t *p = der;
  X509 *x509 = d2i_X509(NULL, &p, (long)der_len);
  if (x509 == NULL || p != der + der_len) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
    X509_free(x509);
    return 0;
  }

  int ret = SSL_use_certificate(ssl, x509);
  X509_free(x509);
  return ret;
}
Exemple #13
0
static int openssl_ssl_use(lua_State*L)
{
  SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl");
  X509* x = CHECK_OBJECT(2, X509, "openssl.x509");
  EVP_PKEY* pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey");
  int ret;

  luaL_argcheck(L, openssl_pkey_is_private(pkey), 3, "must be private key");
  ret = SSL_use_PrivateKey(s, pkey);
  if (ret == 1)
  {
    ret = SSL_use_certificate(s, x);
    if (ret == 1)
    {
      ret = SSL_check_private_key(s);
    }
  }
  return openssl_pushresult(L, ret);
}
Exemple #14
0
int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
  int reason_code;
  BIO *in;
  int ret = 0;
  X509 *x = NULL;

  in = BIO_new(BIO_s_file());
  if (in == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
    goto end;
  }

  if (BIO_read_filename(in, file) <= 0) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
    goto end;
  }

  if (type == SSL_FILETYPE_ASN1) {
    reason_code = ERR_R_ASN1_LIB;
    x = d2i_X509_bio(in, NULL);
  } else if (type == SSL_FILETYPE_PEM) {
    reason_code = ERR_R_PEM_LIB;
    x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
                          ssl->ctx->default_passwd_callback_userdata);
  } else {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
    goto end;
  }

  if (x == NULL) {
    OPENSSL_PUT_ERROR(SSL, reason_code);
    goto end;
  }

  ret = SSL_use_certificate(ssl, x);

end:
  X509_free(x);
  BIO_free(in);

  return ret;
}
Exemple #15
0
BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings)
{
	long options = 0;
	BIO* bio;
	RSA* rsa;
	X509* x509;
	/**
	 * SSL_OP_NO_SSLv2:
	 *
	 * We only want SSLv3 and TLSv1, so disable SSLv2.
	 * SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
	 */
	options |= SSL_OP_NO_SSLv2;
	/**
	 * SSL_OP_NO_COMPRESSION:
	 *
	 * The Microsoft RDP server does not advertise support
	 * for TLS compression, but alternative servers may support it.
	 * This was observed between early versions of the FreeRDP server
	 * and the FreeRDP client, and caused major performance issues,
	 * which is why we're disabling it.
	 */
#ifdef SSL_OP_NO_COMPRESSION
	options |= SSL_OP_NO_COMPRESSION;
#endif
	/**
	 * SSL_OP_TLS_BLOCK_PADDING_BUG:
	 *
	 * The Microsoft RDP server does *not* support TLS padding.
	 * It absolutely needs to be disabled otherwise it won't work.
	 */
	options |= SSL_OP_TLS_BLOCK_PADDING_BUG;
	/**
	 * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
	 *
	 * Just like TLS padding, the Microsoft RDP server does not
	 * support empty fragments. This needs to be disabled.
	 */
	options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;

	if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE))
		return FALSE;

	if (settings->PrivateKeyFile)
	{
		bio = BIO_new_file(settings->PrivateKeyFile, "rb+");

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new_file failed for private key %s",
			         settings->PrivateKeyFile);
			return FALSE;
		}
	}
	else if (settings->PrivateKeyContent)
	{
		bio = BIO_new_mem_buf(settings->PrivateKeyContent,
		                      strlen(settings->PrivateKeyContent));

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new_mem_buf failed for private key");
			return FALSE;
		}
	}
	else
	{
		WLog_ERR(TAG, "no private key defined");
		return FALSE;
	}

	rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
	BIO_free(bio);

	if (!rsa)
	{
		WLog_ERR(TAG, "invalid private key");
		return FALSE;
	}

	if (SSL_use_RSAPrivateKey(tls->ssl, rsa) <= 0)
	{
		WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed");
		RSA_free(rsa);
		return FALSE;
	}

	if (settings->CertificateFile)
	{
		bio = BIO_new_file(settings->CertificateFile, "rb+");

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new_file failed for certificate %s",
			         settings->CertificateFile);
			return FALSE;
		}
	}
	else if (settings->CertificateContent)
	{
		bio = BIO_new_mem_buf(settings->CertificateContent,
		                      strlen(settings->CertificateContent));

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate");
			return FALSE;
		}
	}
	else
	{
		WLog_ERR(TAG, "no certificate defined");
		return FALSE;
	}

	x509 = PEM_read_bio_X509(bio, NULL, NULL, 0);
	BIO_free(bio);

	if (!x509)
	{
		WLog_ERR(TAG, "invalid certificate");
		return FALSE;
	}

	if (SSL_use_certificate(tls->ssl, x509) <= 0)
	{
		WLog_ERR(TAG, "SSL_use_certificate_file failed");
		X509_free(x509);
		return FALSE;
	}

#ifndef OPENSSL_NO_TLSEXT
	/**
	 * The Microsoft iOS clients eventually send a null or even double null
	 * terminated hostname in the SNI TLS extension!
	 * If the length indicator does not equal the hostname strlen OpenSSL
	 * will abort (see openssl:ssl/t1_lib.c).
	 * Here is a tcpdump segment of Microsoft Remote Desktop Client Version
	 * 8.1.7 running on an iPhone 4 with iOS 7.1.2 showing the transmitted
	 * SNI hostname TLV blob when connection to server "abcd":
	 * 00                  name_type 0x00 (host_name)
	 * 00 06               length_in_bytes 0x0006
	 * 61 62 63 64 00 00   host_name "abcd\0\0"
	 *
	 * Currently the only (runtime) workaround is setting an openssl tls
	 * extension debug callback that sets the SSL context's servername_done
	 * to 1 which effectively disables the parsing of that extension type.
	 */
	SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback);
#endif
	return tls_do_handshake(tls, FALSE) > 0;
}
Exemple #16
0
BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings)
{
	long options = 0;
	BIO* bio;
	RSA* rsa;
	X509* x509;
	/**
	 * SSL_OP_NO_SSLv2:
	 *
	 * We only want SSLv3 and TLSv1, so disable SSLv2.
	 * SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
	 */
	options |= SSL_OP_NO_SSLv2;
	/**
	 * SSL_OP_NO_COMPRESSION:
	 *
	 * The Microsoft RDP server does not advertise support
	 * for TLS compression, but alternative servers may support it.
	 * This was observed between early versions of the FreeRDP server
	 * and the FreeRDP client, and caused major performance issues,
	 * which is why we're disabling it.
	 */
#ifdef SSL_OP_NO_COMPRESSION
	options |= SSL_OP_NO_COMPRESSION;
#endif
	/**
	 * SSL_OP_TLS_BLOCK_PADDING_BUG:
	 *
	 * The Microsoft RDP server does *not* support TLS padding.
	 * It absolutely needs to be disabled otherwise it won't work.
	 */
	options |= SSL_OP_TLS_BLOCK_PADDING_BUG;
	/**
	 * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
	 *
	 * Just like TLS padding, the Microsoft RDP server does not
	 * support empty fragments. This needs to be disabled.
	 */
	options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;

	if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE))
		return FALSE;

	if (settings->PrivateKeyFile)
	{
		bio = BIO_new_file(settings->PrivateKeyFile, "rb");

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new_file failed for private key %s",
			         settings->PrivateKeyFile);
			return FALSE;
		}
	}
	else if (settings->PrivateKeyContent)
	{
		bio = BIO_new_mem_buf(settings->PrivateKeyContent,
		                      strlen(settings->PrivateKeyContent));

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new_mem_buf failed for private key");
			return FALSE;
		}
	}
	else
	{
		WLog_ERR(TAG, "no private key defined");
		return FALSE;
	}

	rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
	BIO_free(bio);

	if (!rsa)
	{
		WLog_ERR(TAG, "invalid private key");
		return FALSE;
	}

	if (SSL_use_RSAPrivateKey(tls->ssl, rsa) <= 0)
	{
		WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed");
		RSA_free(rsa);
		return FALSE;
	}

	if (settings->CertificateFile)
	{
		bio = BIO_new_file(settings->CertificateFile, "rb");

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new_file failed for certificate %s",
			         settings->CertificateFile);
			return FALSE;
		}
	}
	else if (settings->CertificateContent)
	{
		bio = BIO_new_mem_buf(settings->CertificateContent,
		                      strlen(settings->CertificateContent));

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate");
			return FALSE;
		}
	}
	else
	{
		WLog_ERR(TAG, "no certificate defined");
		return FALSE;
	}

	x509 = PEM_read_bio_X509(bio, NULL, NULL, 0);
	BIO_free(bio);

	if (!x509)
	{
		WLog_ERR(TAG, "invalid certificate");
		return FALSE;
	}

	if (SSL_use_certificate(tls->ssl, x509) <= 0)
	{
		WLog_ERR(TAG, "SSL_use_certificate_file failed");
		X509_free(x509);
		return FALSE;
	}

#if defined(MICROSOFT_IOS_SNI_BUG) && !defined(OPENSSL_NO_TLSEXT)
	SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback);
#endif
	return tls_do_handshake(tls, FALSE) > 0;
}
static int
ngx_http_multiple_ssl_set_der_certificate(ngx_ssl_conn_t *ssl_conn, ngx_str_t *cert, ngx_str_t *key)
{
    BIO               *bio = NULL;
    X509              *x509 = NULL;
    u_long             n;

    bio = BIO_new_file((char *) cert->data, "r");
    if (bio == NULL) {
        return NGX_ERROR;
    }

    x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
    if (x509 == NULL) {
        BIO_free(bio);
        return NGX_ERROR;
    }

    SSL_certs_clear(ssl_conn);

    if (SSL_use_certificate(ssl_conn, x509) == 0) {
        X509_free(x509);
        BIO_free(bio);
        return NGX_ERROR;
    }

#if 0
    if (SSL_set_ex_data(ssl_conn, ngx_ssl_certificate_index, x509) == 0) {
        X509_free(x509);
        BIO_free(bio);
        return NGX_ERROR;
    }
#endif

    X509_free(x509);
    x509 = NULL;

    /* read rest of the chain */
    for ( ;; ) {
        x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
        if (x509 == NULL) {
            n = ERR_peek_last_error();

            if (ERR_GET_LIB(n) == ERR_LIB_PEM
                && ERR_GET_REASON(n) == PEM_R_NO_START_LINE)
            {
                ERR_clear_error();
                break;
            }

            BIO_free(bio);
            return NGX_ERROR;
        }

        if (SSL_add0_chain_cert(ssl_conn, x509) == 0) {
            X509_free(x509);
            BIO_free(bio);
            return NGX_ERROR;
        }
    }

    BIO_free(bio);
    bio = NULL;


    if (SSL_use_PrivateKey_file(ssl_conn, (char *) key->data,
                                        SSL_FILETYPE_PEM) != 1)
    {
        return NGX_ERROR;
    }

    return NGX_OK;
}
Exemple #18
0
tcp_stream_t *
tcp_stream_create_ssl_from_fd(int fd, const char *hostname,
                              const tcp_ssl_info_t *tsi,
                              char *errbuf, size_t errlen)
{
  char errmsg[120];

  tcp_stream_t *ts = calloc(1, sizeof(tcp_stream_t));
  ts->ts_fd = fd;

  if((ts->ts_ssl = SSL_new(ssl_ctx)) == NULL)
    goto bad_ssl;


  if(SSL_set_fd(ts->ts_ssl, fd) == 0)
    goto bad_ssl;

  if(tsi->key != NULL) {
    BIO *cbio = BIO_new_mem_buf((char *)tsi->key, -1);
    EVP_PKEY *key = PEM_read_bio_PrivateKey(cbio, NULL, NULL, NULL);
    BIO_free(cbio);
    if(key == NULL) {
      snprintf(errbuf, errlen, "Unable to load private key");
      goto bad;
    }

    SSL_use_PrivateKey(ts->ts_ssl, key);
    EVP_PKEY_free(key);
  }

  if(tsi->cert != NULL) {
    BIO *cbio = BIO_new_mem_buf((char *)tsi->cert, -1);
    X509 *cert = PEM_read_bio_X509(cbio, NULL, 0, NULL);
    BIO_free(cbio);

    if(cert == NULL) {
      snprintf(errbuf, errlen, "Unable to load certificate");
      goto bad;
    }

    SSL_use_certificate(ts->ts_ssl, cert);
    X509_free(cert);
  }

  if(SSL_connect(ts->ts_ssl) <= 0) {
    goto bad_ssl;
  }

  SSL_set_mode(ts->ts_ssl, SSL_MODE_AUTO_RETRY);

  X509 *peer = SSL_get_peer_certificate(ts->ts_ssl);
  if(peer == NULL) {
    goto bad_ssl;
  }

  int err = SSL_get_verify_result(ts->ts_ssl);
  if(err != X509_V_OK) {
    snprintf(errbuf, errlen, "Certificate error: %s",
             X509_verify_cert_error_string(err));
    X509_free(peer);
    goto bad;
  }

  if(verify_hostname(hostname, peer, errbuf, errlen)) {
    X509_free(peer);
    goto bad;
  }

  X509_free(peer);

  ts->ts_fd = fd;
  htsbuf_queue_init(&ts->ts_spill, INT32_MAX);
  htsbuf_queue_init(&ts->ts_sendq, INT32_MAX);

  ts->ts_write = ssl_write;
  ts->ts_read  = ssl_read;
  return ts;

 bad_ssl:
  ERR_error_string(ERR_get_error(), errmsg);
  snprintf(errbuf, errlen, "SSL: %s", errmsg);
 bad:
  tcp_close(ts);
  return NULL;
}
Exemple #19
0
static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key,
			   const char *passwd)
{
#ifdef PKCS12_FUNCS
	FILE *f;
	PKCS12 *p12;
	EVP_PKEY *pkey;
	X509 *cert;
	int res = 0;

	f = fopen(private_key, "r");
	if (f == NULL)
		return -1;

	p12 = d2i_PKCS12_fp(f, NULL);
	if (p12 == NULL) {
		wpa_printf(MSG_DEBUG, "TLS: Failed to read PKCS12 file '%s'",
			   private_key);
		fclose(f);
		return -1;
	}
	fclose(f);

	pkey = NULL;
	cert = NULL;
	if (!PKCS12_parse(p12, passwd, &pkey, &cert, NULL)) {
		wpa_printf(MSG_DEBUG, "TLS: Failed to parse PKCS12 file '%s': "
			   "%s", private_key,
			   ERR_error_string(ERR_get_error(), NULL));
		return -1;
	}
	wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 file '%s'",
		   private_key);

	if (cert) {
		wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12");
		if (ssl) {
			if (SSL_use_certificate(ssl, cert) != 1)
				res = -1;
		} else {
			if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1)
				res = -1;
		}
		X509_free(cert);
	}

	if (pkey) {
		wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
		if (ssl) {
			if (SSL_use_PrivateKey(ssl, pkey) != 1)
				res = -1;
		} else {
			if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1)
				res = -1;
		}
		EVP_PKEY_free(pkey);
	}

	PKCS12_free(p12);

	return res;
#else /* PKCS12_FUNCS */
	wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
		   "p12/pfx files");
	return -1;
#endif  /* PKCS12_FUNCS */
}
Exemple #20
0
/* read the data and then respond */
static int client_certificate(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p,*d;
	int i;
	unsigned int n;
	int cert_ch_len;
	unsigned char *cert_ch;

	buf=(unsigned char *)s->init_buf->data;

	/* We have a cert associated with the SSL, so attach it to
	 * the session if it does not have one */

	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A)
		{
		i=ssl2_read(s,(char *)&(buf[s->init_num]),
			SSL2_MAX_CERT_CHALLENGE_LENGTH+2-s->init_num);
		if (i<(SSL2_MIN_CERT_CHALLENGE_LENGTH+2-s->init_num))
			return(ssl2_part_read(s,SSL_F_CLIENT_CERTIFICATE,i));
		s->init_num += i;
		if (s->msg_callback)
			s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* REQUEST-CERTIFICATE */

		/* type=buf[0]; */
		/* type eq x509 */
		if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
			{
			ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_AUTHENTICATION_TYPE);
			return(-1);
			}

		if ((s->cert == NULL) ||
			(s->cert->key->x509 == NULL) ||
			(s->cert->key->privatekey == NULL))
			{
			s->state=SSL2_ST_X509_GET_CLIENT_CERTIFICATE;
			}
		else
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
		}

	cert_ch = buf + 2;
	cert_ch_len = s->init_num - 2;

	if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE)
		{
		X509 *x509=NULL;
		EVP_PKEY *pkey=NULL;

		/* If we get an error we need to
		 * ssl->rwstate=SSL_X509_LOOKUP;
		 * return(error);
		 * We should then be retried when things are ok and we
		 * can get a cert or not */

		i=0;
		if (s->ctx->client_cert_cb != NULL)
			{
			i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
			}

		if (i < 0)
			{
			s->rwstate=SSL_X509_LOOKUP;
			return(-1);
			}
		s->rwstate=SSL_NOTHING;

		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
			{
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
			if (	!SSL_use_certificate(s,x509) || 
				!SSL_use_PrivateKey(s,pkey))
				{
				i=0;
				}
			X509_free(x509);
			EVP_PKEY_free(pkey);
			}
		else if (i == 1)
			{
			if (x509 != NULL) X509_free(x509);
			if (pkey != NULL) EVP_PKEY_free(pkey);
			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
			i=0;
			}

		if (i == 0)
			{
			/* We have no client certificate to respond with
			 * so send the correct error message back */
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_B;
			p=buf;
			*(p++)=SSL2_MT_ERROR;
			s2n(SSL2_PE_NO_CERTIFICATE,p);
			s->init_off=0;
			s->init_num=3;
			/* Write is done at the end */
			}
		}

	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B)
		{
		return(ssl2_do_write(s));
		}

	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C)
		{
		EVP_MD_CTX ctx;

		/* ok, now we calculate the checksum
		 * do it first so we can reuse buf :-) */
		p=buf;
		EVP_MD_CTX_init(&ctx);
		EVP_SignInit_ex(&ctx,s->ctx->rsa_md5, NULL);
		EVP_SignUpdate(&ctx,s->s2->key_material,
			       s->s2->key_material_length);
		EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
		n=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
		EVP_SignUpdate(&ctx,buf,(unsigned int)n);

		p=buf;
		d=p+6;
		*(p++)=SSL2_MT_CLIENT_CERTIFICATE;
		*(p++)=SSL2_CT_X509_CERTIFICATE;
		n=i2d_X509(s->cert->key->x509,&d);
		s2n(n,p);

		if (!EVP_SignFinal(&ctx,d,&n,s->cert->key->privatekey))
			{
			/* this is not good.  If things have failed it
			 * means there so something wrong with the key.
			 * We will continue with a 0 length signature
			 */
			}
		EVP_MD_CTX_cleanup(&ctx);
		s2n(n,p);
		d+=n;

		s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_D;
		s->init_num=d-buf;
		s->init_off=0;
		}
	/* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */
	return(ssl2_do_write(s));
	}
Exemple #21
0
void bud_client_sni_cb(bud_http_request_t* req, bud_error_t err) {
  bud_client_t* client;
  bud_config_t* config;
  bud_client_error_t cerr;
  int r;
  STACK_OF(X509)* chain;
  SSL_CTX* ctx;
  X509* x509;
  EVP_PKEY* pkey;

  client = req->data;
  config = client->config;

  client->sni_req = NULL;
  client->async_hello = kBudProgressDone;
  if (!bud_is_ok(err)) {
    WARNING(&client->frontend, "SNI cb failed: \"%s\"", bud_error_to_str(err));
    goto fatal;
  }

  if (req->code == 404) {
    /* Not found */
    DBG(&client->frontend,
        "SNI name not found: \"%.*s\"",
        client->hello.servername_len,
        client->hello.servername);
    goto done;
  }

  /* Parse incoming JSON */
  err = bud_sni_from_json(config, req->response, &client->sni_ctx);
  if (!bud_is_ok(err)) {
    WARNING(&client->frontend,
            "SNI from json failed: \"%s\"",
            bud_error_to_str(err));
    goto fatal;
  }

  /* Success */
  DBG(&client->frontend,
      "SNI name found: \"%.*s\"",
      client->hello.servername_len,
      client->hello.servername);
  if (!SSL_set_ex_data(client->ssl, kBudSSLSNIIndex, &client->sni_ctx)) {
    err = bud_error(kBudErrClientSetExData);
    goto fatal;
  }

  /* NOTE: reference count is not increased by this API methods */
  ctx = client->sni_ctx.ctx;
  x509 = SSL_CTX_get0_certificate(ctx);
  pkey = SSL_CTX_get0_privatekey(ctx);

  r = SSL_CTX_get0_chain_certs(ctx, &chain);
  if (r == 1)
    r = SSL_use_certificate(client->ssl, x509);
  if (r == 1)
    r = SSL_use_PrivateKey(client->ssl, pkey);
  if (r == 1 && chain != NULL)
    r = SSL_set1_chain(client->ssl, chain);
  if (r != 1) {
    err = bud_error(kBudErrClientSetSNICert);
    goto fatal;
  }

  /* Update context, may be needed for early ticket key generation */
  SSL_set_SSL_CTX(client->ssl, ctx);

  /* Do not loose the cert callback! */
  SSL_set_cert_cb(client->ssl, bud_client_ssl_cert_cb, client);
  client->ssl->options = client->sni_ctx.ctx->options;

done:
  /* Request stapling info if needed */
  if (config->stapling.enabled && client->hello.ocsp_request != 0) {
    err = bud_client_ocsp_stapling(client);
    if (!bud_is_ok(err))
      goto fatal;
  }
  json_value_free(req->response);

  if (client->async_hello == kBudProgressDone) {
    cerr = bud_client_cycle(client);
    if (!bud_is_ok(cerr.err))
      bud_client_close(client, cerr);
  }
  return;

fatal:
  bud_client_close(client, bud_client_error(err, &client->frontend));
}
Exemple #22
0
static int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) {
	const char *servername;
	connection *con = (connection *) SSL_get_app_data(ssl);
	UNUSED(al);

	buffer_copy_string(con->uri.scheme, "https");

	if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
#if 0
		/* this "error" just means the client didn't support it */
		log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
				"failed to get TLS server name");
#endif
		return SSL_TLSEXT_ERR_NOACK;
	}
	buffer_copy_string(con->tlsext_server_name, servername);
	buffer_to_lower(con->tlsext_server_name);

	/* Sometimes this is still set, confusing COMP_HTTP_HOST */
	buffer_reset(con->uri.authority);

	config_cond_cache_reset(srv, con);
	config_setup_connection(srv, con);

	con->conditional_is_valid[COMP_SERVER_SOCKET] = 1;
	con->conditional_is_valid[COMP_HTTP_SCHEME] = 1;
	con->conditional_is_valid[COMP_HTTP_HOST] = 1;
	config_patch_connection(srv, con);

	if (NULL == con->conf.ssl_pemfile_x509 || NULL == con->conf.ssl_pemfile_pkey) {
		/* x509/pkey available <=> pemfile was set <=> pemfile got patched: so this should never happen, unless you nest $SERVER["socket"] */
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
			"no certificate/private key for TLS server name", con->tlsext_server_name);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	/* first set certificate! setting private key checks whether certificate matches it */
	if (!SSL_use_certificate(ssl, con->conf.ssl_pemfile_x509)) {
		log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:",
			"failed to set certificate for TLS server name", con->tlsext_server_name,
			ERR_error_string(ERR_get_error(), NULL));
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	if (!SSL_use_PrivateKey(ssl, con->conf.ssl_pemfile_pkey)) {
		log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:",
			"failed to set private key for TLS server name", con->tlsext_server_name,
			ERR_error_string(ERR_get_error(), NULL));
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	if (con->conf.ssl_verifyclient) {
		if (NULL == con->conf.ssl_ca_file_cert_names) {
			log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:",
				"can't verify client without ssl.ca-file for TLS server name", con->tlsext_server_name,
				ERR_error_string(ERR_get_error(), NULL));
			return SSL_TLSEXT_ERR_ALERT_FATAL;
		}

		SSL_set_client_CA_list(ssl, SSL_dup_CA_list(con->conf.ssl_ca_file_cert_names));
		/* forcing verification here is really not that useful - a client could just connect without SNI */
		SSL_set_verify(
			ssl,
			SSL_VERIFY_PEER | (con->conf.ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0),
			NULL
		);
		SSL_set_verify_depth(ssl, con->conf.ssl_verifyclient_depth);
	} else {
		SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
	}

	return SSL_TLSEXT_ERR_OK;
}
Exemple #23
0
MONO_API int
mono_btls_ssl_use_certificate (MonoBtlsSsl *ptr, X509 *x509)
{
	return SSL_use_certificate (ptr->ssl, x509);
}
Exemple #24
0
/*
 * Read a file that contains our certificate in "PEM" format, possibly
 * followed by a sequence of CA certificates that should be sent to the peer
 * in the Certificate message.
 */
static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
{
    BIO *in;
    int ret = 0;
    X509 *x = NULL;
    pem_password_cb *passwd_callback;
    void *passwd_callback_userdata;

    ERR_clear_error();          /* clear error stack for
                                 * SSL_CTX_use_certificate() */

    if (ctx != NULL) {
        passwd_callback = ctx->default_passwd_callback;
        passwd_callback_userdata = ctx->default_passwd_callback_userdata;
    } else {
        passwd_callback = ssl->default_passwd_callback;
        passwd_callback_userdata = ssl->default_passwd_callback_userdata;
    }

    in = BIO_new(BIO_s_file());
    if (in == NULL) {
        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
        goto end;
    }

    if (BIO_read_filename(in, file) <= 0) {
        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB);
        goto end;
    }

    x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback,
                              passwd_callback_userdata);
    if (x == NULL) {
        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
        goto end;
    }

    if (ctx)
        ret = SSL_CTX_use_certificate(ctx, x);
    else
        ret = SSL_use_certificate(ssl, x);

    if (ERR_peek_error() != 0)
        ret = 0;                /* Key/certificate mismatch doesn't imply
                                 * ret==0 ... */
    if (ret) {
        /*
         * If we could set up our certificate, now proceed to the CA
         * certificates.
         */
        X509 *ca;
        int r;
        unsigned long err;

        if (ctx)
            r = SSL_CTX_clear_chain_certs(ctx);
        else
            r = SSL_clear_chain_certs(ssl);

        if (r == 0) {
            ret = 0;
            goto end;
        }

        while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback,
                                       passwd_callback_userdata))
                != NULL) {
            if (ctx)
                r = SSL_CTX_add0_chain_cert(ctx, ca);
            else
                r = SSL_add0_chain_cert(ssl, ca);
            /*
             * Note that we must not free ca if it was successfully added to
             * the chain (while we must free the main certificate, since its
             * reference count is increased by SSL_CTX_use_certificate).
             */
            if (!r) {
                X509_free(ca);
                ret = 0;
                goto end;
            }
        }
        /* When the while loop ends, it's usually just EOF. */
        err = ERR_peek_last_error();
        if (ERR_GET_LIB(err) == ERR_LIB_PEM
            && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
            ERR_clear_error();
        else
            ret = 0;            /* some real error */
    }

 end:
    X509_free(x);
    BIO_free(in);
    return (ret);
}