Example #1
1
BIO *Connect_SSL(char *hostname, int port)
{
	//BIO *bio = NULL;
	char bio_addr[BUF_MAX] = { 0 };
	
	snprintf(bio_addr, sizeof(bio_addr), "%s:%d", hostname, port);
	
	SSL_library_init();
	
	SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
	SSL *ssl = NULL;
	
	bio = BIO_new_ssl_connect(ctx);
	if (bio == NULL)
	{
		Error("BIO_new_ssl_connect");
	}
	
	BIO_get_ssl(bio, &ssl);
	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
	BIO_set_conn_hostname(bio, bio_addr);
	
	if (BIO_do_connect(bio) <= 0)
	{
		Error("SSL Unable to connect");
	}

	return bio;
}
Example #2
0
BIO* connect_encrypted(char* host_and_port, char* store_path, char store_type, SSL_CTX** ctx, SSL** ssl) {
  BIO* bio = NULL;
  int r = 0;

  *ctx = SSL_CTX_new(SSLv23_client_method());
  *ssl = NULL;

  if (store_type == 'f')
    r = SSL_CTX_load_verify_locations(*ctx, store_path, NULL);
  else
    r = SSL_CTX_load_verify_locations(*ctx, NULL, store_path);
  if (r == 0) {
    return NULL;
  }

  bio = BIO_new_ssl_connect(*ctx);
  BIO_get_ssl(bio, ssl);
  if (!(*ssl)) {
    return NULL;
  }
  SSL_set_mode(*ssl, SSL_MODE_AUTO_RETRY);

  BIO_set_conn_hostname(bio, host_and_port);

  if (BIO_do_connect(bio) < 1) {
    return NULL;
  }

  return bio;
}
Example #3
0
static Pfd*
opensslconnect(char *host)
{
	Pfd *pfd;
	BIO *sbio;
	SSL_CTX *ctx;
	SSL *ssl;
	static int didinit;
	char buf[1024];

	if(!didinit){
		httpsinit();
		didinit = 1;
	}

	ctx = SSL_CTX_new(SSLv23_client_method());
	sbio = BIO_new_ssl_connect(ctx);
	BIO_get_ssl(sbio, &ssl);
	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
	
	snprint(buf, sizeof buf, "%s:https", host);
	BIO_set_conn_hostname(sbio, buf);
	
	if(BIO_do_connect(sbio) <= 0 || BIO_do_handshake(sbio) <= 0){
		ERR_error_string_n(ERR_get_error(), buf, sizeof buf);
		BIO_free_all(sbio);
		werrstr("openssl: %s", buf);
		return nil;
	}

	pfd = emalloc(sizeof *pfd);
	pfd->sbio = sbio;
	return pfd;
}
Example #4
0
int main() 
{
    SSL_load_error_strings();
    ERR_load_BIO_strings();
    OpenSSL_add_all_algorithms();
    
    SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
    if (ctx == NULL) {
        printf("SSL_CTX_new err func:%s\n reaseon:%s", ERR_func_error_string(ERR_get_error()),
               ERR_reason_error_string(ERR_get_error()));
        exit(1);
    }

    //加载可信任证书库
    if (0 == SSL_CTX_load_verify_locations(ctx, "./push_cer.pem", NULL)) {
        printf("err func:%s\n reaseon:%s", ERR_func_error_string(ERR_get_error()),
               ERR_reason_error_string(ERR_get_error()));
        ERR_print_errors_fp(stdout);
        exit(1);
    }

    //set BIO
    BIO *bio = BIO_new_ssl_connect(ctx);
    if (bio == NULL) {
        printf("err func:%s\n", ERR_func_error_string(ERR_get_error()));
        ERR_print_errors_fp(stdout);
        exit(1);
    }

    SSL *ssl;
    BIO_get_ssl(bio, &ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    //open safe connect
    BIO_set_conn_hostname(bio, "gateway.sandbox.push.apple.com:2195");

    //verify connect ok
    if (BIO_do_connect(bio) <= 0) {
        ERR_print_errors_fp(stdout);
        exit(1);
    }

    if (SSL_get_verify_result(ssl) != X509_V_OK) {
        printf("SSL_get_verify_result not success\n");
    }

    char buf[MAXBUF];
    char *json = "{\"aps\":{\"badge\":123}}";
    sendPayload(bio, token, json, strlen(json));
    int ret = BIO_read(bio, buf, MAXBUF);
    if (ret <= 0) {
        printf("BIO_read return 0\n");
    }

    SSL_CTX_free(ctx);
    BIO_free_all(bio);
    return 0;
}
Example #5
0
bool Email::sendCode(std::string user, std::string code)
{
    std::string msg,to;
    
    msg = m_m1 + code + m_m2;
    to = m_to1 + user + m_to3;
    
    SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method());
    SSL* ssl;
    
    BIO* bio = BIO_new_ssl_connect(ctx);
    BIO_get_ssl(bio, &ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    BIO_set_conn_hostname(bio, m_amazonHostname.c_str());
    
    if(BIO_do_connect(bio) <= 0){
        BIO_free_all(bio);
        SSL_CTX_free(ctx);
        return false;
    }
    
    if(BIO_do_handshake(bio) <= 0){
        BIO_free_all(bio);
        SSL_CTX_free(ctx);
        return false;
    }

    m_len = BIO_read(bio, m_buf, BUF_LEN) - 1;
    BIO_puts(bio, "HELO localhost\r\n");
    m_len = BIO_read(bio, m_buf, BUF_LEN) - 1;
    BIO_puts(bio,"AUTH LOGIN\r\n");
    m_len = BIO_read(bio,m_buf,BUF_LEN) - 1;
    BIO_puts(bio,"QUtJQUlFVzJDMlU3RUZYTU5PUVE=\r\n"); 
    m_len = BIO_read(bio,m_buf,BUF_LEN) - 1;
    BIO_puts(bio,"QWd3TkZSOUJyb2dUTUkxYlJHeXh4dHZMYm4reldGZCtYSFJMbnJpNzZ5RC8=\r\n"); 
    m_len = BIO_read(bio,m_buf,BUF_LEN) - 1;
    BIO_puts(bio,"MAIL FROM:[email protected]\r\n"); 
    m_len = BIO_read(bio,m_buf,BUF_LEN) - 1;
    BIO_puts(bio,to.c_str()); 
    m_len = BIO_read(bio,m_buf,BUF_LEN) - 1;
    BIO_puts(bio,"DATA\r\n"); 
    m_len = BIO_read(bio,m_buf,BUF_LEN) - 1;
    BIO_puts(bio,"Subject:OneBrown Verification\r\n\r\n"); 
    BIO_puts(bio,msg.c_str()); 
    BIO_puts(bio,"\r\n.\r\n"); 
    m_len = BIO_read(bio,m_buf,BUF_LEN) - 1;
    BIO_puts(bio,"QUIT\r\n"); 
    m_len = BIO_read(bio,m_buf,BUF_LEN) - 1;
    
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    
    return true;
}
Example #6
0
const char *dbapi_lookup(const char *key) {
	long res = 1;
	SSL_CTX* ctx = NULL;
	BIO *web = NULL, *out = NULL;
	SSL *ssl = NULL;
	const SSL_METHOD* method;
	char *token, *tmpout, *buf;
	int hlen=0, len=0, maxlen=2048;
	(void)SSL_library_init();
	SSL_load_error_strings();
	OPENSSL_config(NULL);
	method = SSLv23_method(); if(method==NULL) return NULL;
	ctx = SSL_CTX_new(method); if(ctx==NULL) return NULL;
	SSL_CTX_set_verify_depth(ctx, 4);
	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|
		SSL_OP_NO_COMPRESSION);
	web = BIO_new_ssl_connect(ctx); if(web==NULL) return NULL;
	res = BIO_set_conn_hostname(web, DB_API_SERVER); if(res!=1) return NULL;
	BIO_get_ssl(web, &ssl); if(ssl==NULL) return NULL;
	res = SSL_set_cipher_list(ssl, SECURE_CIPHER_LIST); if(res!=1) return NULL;
	res = SSL_set_tlsext_host_name(ssl, DB_API_HOST); if(res!=1) return NULL;
	out = BIO_new_fp(stdout, BIO_NOCLOSE); if(NULL==out) return NULL;
	res = BIO_do_connect(web); if(res!=1) return NULL;
	res = BIO_do_handshake(web); if(res!=1) return NULL;
	len=(60+strlen(key)+strlen(DB_API_HOST)+strlen(DB_API_AUTH));
	char *request=malloc(sizeof(char)*(len+1));
	snprintf(request,len,
		"GET %s HTTP/1.1\nHost: %s\nx-api-key: %s\nConnection: close\n\n",
		key, DB_API_HOST, DB_API_AUTH);
	request[len]='\0';
	BIO_puts(web, request);
	BIO_puts(out, "\n");
	buf = malloc(sizeof(char)*maxlen);
	do {
		char buff[1536] = {};
		len=BIO_read(web, buff, sizeof(buff));
		hlen+=len;
		if(hlen<maxlen&&len>0) strncat(buf,buff,len);
	} while (len>0 || BIO_should_retry(web));
	buf[maxlen]='\0';
	tmpout = malloc(sizeof(char)*(HASH_MAXLENGTH+1));
	token = strtok(buf, "\n");
	while (token) {
		snprintf(tmpout,HASH_MAXLENGTH,"%s",token);
		token = strtok(NULL, "\n");
	}
	tmpout[strlen(tmpout)]='\0';
	free(buf);
	free(request);
	if(out) BIO_free(out);
	if(web != NULL) BIO_free_all(web);
	if(NULL != ctx) SSL_CTX_free(ctx);
	return tmpout;
}
Example #7
0
static BIO *
my_connect_ssl(char *host, int port, SSL_CTX **ctx) {
  BIO *conn = 0;

  if (!(conn = BIO_new_ssl_connect(*ctx))) goto error_exit;
  BIO_set_conn_hostname(conn, host);
  BIO_set_conn_int_port(conn, &port);

  if (BIO_do_connect(conn) <= 0) goto error_exit;
  return conn;

error_exit:
  if (conn) BIO_free_all(conn);
  return 0;
}
Example #8
0
/**
 * Connect to a host using an encrypted stream
 */
BIO* connect_encrypted(char* host_and_port, char* store_path, char store_type, SSL_CTX** ctx, SSL** ssl) {

    BIO* bio = NULL;
    int r = 0;

    /* Set up the SSL pointers */
    *ctx = SSL_CTX_new(SSLv23_client_method());
    *ssl = NULL;

    /* Load the trust store from the pem location in argv[2] */
    if (store_type == 'f')
        r = SSL_CTX_load_verify_locations(*ctx, store_path, NULL);
    else
        r = SSL_CTX_load_verify_locations(*ctx, NULL, store_path);
    if (r == 0) {

        print_ssl_error_2("Unable to load the trust store from %s.\n", store_path, stdout);
        return NULL;
    }

    /* Setting up the BIO SSL object */
    bio = BIO_new_ssl_connect(*ctx);
    BIO_get_ssl(bio, ssl);
    if (!(*ssl)) {

        print_ssl_error("Unable to allocate SSL pointer.\n", stdout);
        return NULL;
    }
    SSL_set_mode(*ssl, SSL_MODE_AUTO_RETRY);

    /* Attempt to connect */
    BIO_set_conn_hostname(bio, host_and_port);

    /* Verify the connection opened and perform the handshake */
    if (BIO_do_connect(bio) < 1) {

        print_ssl_error_2("Unable to connect BIO.%s\n", host_and_port, stdout);
        return NULL;
    }

    if (SSL_get_verify_result(*ssl) != X509_V_OK) {

        print_ssl_error("Unable to verify connection result.\n", stdout);
    }

    return bio;
}
Example #9
0
bool tls_socket::set_hostname(const char* sAddr)
{
	sock_closed = false;
	if(ctx == nullptr)
	{
		init_ctx();
		if(ctx == nullptr)
		{
			print_error();
			return false;
		}
	}

	if((bio = BIO_new_ssl_connect(ctx)) == nullptr)
	{
		print_error();
		return false;
	}

	int flag = 1;
	/* If it fails, it fails, we won't loose too much sleep over it */
	setsockopt(BIO_get_fd(bio, nullptr), IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));

	if(BIO_set_conn_hostname(bio, sAddr) != 1)
	{
		print_error();
		return false;
	}

	BIO_get_ssl(bio, &ssl);
	if(ssl == nullptr)
	{
		print_error();
		return false;
	}

	if(jconf::inst()->TlsSecureAlgos())
	{
		if(SSL_set_cipher_list(ssl, "HIGH:!aNULL:!PSK:!SRP:!MD5:!RC4:!SHA1") != 1)
		{
			print_error();
			return false;
		}
	}

	return true;
}
Example #10
0
BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
	{
#ifndef OPENSSL_NO_SOCK
	BIO *ret=NULL,*buf=NULL,*ssl=NULL;

	if ((buf=BIO_new(BIO_f_buffer())) == NULL)
		return(NULL);
	if ((ssl=BIO_new_ssl_connect(ctx)) == NULL)
		goto err;
	if ((ret=BIO_push(buf,ssl)) == NULL)
		goto err;
	return(ret);
err:
	if (buf != NULL) BIO_free(buf);
	if (ssl != NULL) BIO_free(ssl);
#endif
	return(NULL);
	}
Example #11
0
static int openssl_ssl_ctx_new_bio(lua_State*L)
{
  SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx");
  const char* host_addr = luaL_checkstring(L, 2);
  int server = lua_isnoneornil(L, 3) ? 0 : auxiliar_checkboolean(L, 3);
  int autoretry = lua_isnoneornil(L, 4) ? 1 : auxiliar_checkboolean(L, 4);

  SSL *ssl = NULL;
  BIO *bio = server ? BIO_new_ssl(ctx, 0) : BIO_new_ssl_connect(ctx);
  int ret = BIO_get_ssl(bio, &ssl);
  if (ret == 1 && ssl)
  {
    if (autoretry)
      SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    if (server)
    {
      BIO* acpt = BIO_new_accept((char*)host_addr);
      BIO_set_accept_bios(acpt, bio);
      bio = acpt;
    }
    else
    {
      ret = BIO_set_conn_hostname(bio, host_addr);
    }
    if (ret == 1)
    {
      PUSH_OBJECT(bio, "openssl.bio");
      openssl_newvalue(L, bio);

      lua_pushboolean(L, 1);
      openssl_setvalue(L, bio, "free_all");

      return 1;
    }
    else
      return openssl_pushresult(L, ret);
  }
  else
  {
    BIO_free(bio);
    bio = NULL;
    return 0;
  }
}
Example #12
0
bool tls_socket::set_hostname(const char* sAddr)
{
	if(ctx == nullptr)
	{
		init_ctx();
		if(ctx == nullptr)
		{
			print_error();
			return false;
		}
	}

	if((bio = BIO_new_ssl_connect(ctx)) == nullptr)
	{
		print_error();
		return false;
	}

	if(BIO_set_conn_hostname(bio, sAddr) != 1)
	{
		print_error();
		return false;
	}

	BIO_get_ssl(bio, &ssl);
	if(ssl == nullptr)
	{
		print_error();
		return false;
	}

	if(jconf::inst()->TlsSecureAlgos())
	{
		if(SSL_set_cipher_list(ssl, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4:!SHA1") != 1)
		{
			print_error();
			return false;
		}
	}

	return true;
}
Example #13
0
// ----------------------------------------------------------------------------
void SecureClient::init() {
  SSL_load_error_strings();
  ERR_load_BIO_strings();
  OpenSSL_add_all_algorithms();

  m_ssl_context = SSL_CTX_new(SSLv23_client_method());

  // loading the Trust Store
  if(!SSL_CTX_load_verify_locations(m_ssl_context, "../client/certs/TrustStore.pem", nullptr)) {
    ERR("Failed to load the Trust Store of certificates: %s", ERR_reason_error_string(ERR_get_error()));
    throw ClientException();
  }

  m_bio = BIO_new_ssl_connect(m_ssl_context);
  if (m_bio == nullptr) {
    ERR("Failed to prepare new secure connection: %s", ERR_reason_error_string(ERR_get_error()));
    throw ClientException();
  }
  BIO_get_ssl(m_bio, &m_ssl);
  SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY);  // retry handshake transparently if Server suddenly wants

  // establish secure connection
  BIO_set_conn_hostname(m_bio, m_ip_address.c_str());
  BIO_set_conn_port(m_bio, m_port.c_str());
  if (BIO_do_connect(m_bio) <= 0) {
    ERR("Failed to securely connect to [%s:%s]: %s", m_ip_address.c_str(), m_port.c_str(), ERR_reason_error_string(ERR_get_error()));
    m_is_connected = false;
  } else {
    m_is_connected = true;
  }

  // checking certificate from Server
  if (SSL_get_verify_result(m_ssl) != X509_V_OK) {
    WRN("Certificate verification has failed: %s", ERR_reason_error_string(ERR_get_error()));
    // TODO: probably, proceed further
  }

  INF("Secure connection has been established");
  m_api_impl = new SecureClientApiImpl(m_bio, m_ip_address, m_port);
}
Example #14
0
/*
  Connect to host on the given port using tls and return the BIO object
  representing the connection.
*/
BIO* connect_tls(const char *host, const char *port){
  init_ssl_lib();
  //the assignment is redundant, but it's weird not having it
  ctx = init_ssl_ctx();
  if(!ctx){return NULL;}

  BIO *bio = BIO_new_ssl_connect(ctx);
  if(!bio){goto err;}

  if(BIO_set_conn_hostname(bio, host) == 0){
    goto err;
  }
  if(BIO_set_conn_port(bio, port) == 0){
    goto err;
  }

  SSL *ssl;
  BIO_get_ssl(bio, &ssl);
  //Handle renegotiation transparently
  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
  //this is to let the server know what name we used to connect to it
  SSL_set_tlsext_host_name(ssl, host);
  if(BIO_do_connect(bio) == 0){
    goto err;
  }
  if(BIO_do_handshake(bio) == 0){
    goto err;
  }
  //make sure that the certificate was valid
  if(SSL_get_verify_result(ssl) != X509_V_OK){
    goto err;
  }

  return bio;
 err:
  print_errors();
  BIO_free_all(bio);
  SSL_CTX_free(ctx);
  return NULL;
}
Example #15
0
bool ClientSSLSocket::Connect(std::string hostAndPort) {
  SSL_library_init();
  _ctx.Reset(SSL_CTX_new(SSLv23_client_method()));
  if (!_ctx.Get()) {
    ERR_print_errors_fp(stderr);
    return false;
  }

  _bio.Reset(BIO_new_ssl_connect(_ctx.Get()));

  SSL* ssl = nullptr;

  // Set some flags.
  BIO_get_ssl(_bio.Get(), &ssl);
  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

  // Create and setup the connection.
  BIO_set_conn_hostname(_bio.Get(), hostAndPort.c_str());
  
  if (BIO_do_connect(_bio.Get()) <= 0) {
    std::cerr << "ERROR: Could not connect to \"" << hostAndPort << "\""
              << std::endl;
    ERR_print_errors_fp(stderr);
    return false;
  }

#if 0  // We don't care about the certificate validity at the moment.
  // Check the certificate.
  if (SSL_get_verify_result(ssl) != X509_V_OK) {
    std::cerr << "ERROR: Certificate verification error ("
              << SSL_get_verify_result(ssl) << ")" << std::endl;
    ERR_print_errors_fp(stderr);
    return false;
  }
#endif  // 0

  return true;
}
Example #16
0
File: _ssl.c Project: judu/hxssl
//BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
value _BIO_new_ssl_connect(value ctx) {
	return alloc_abstract(k_ssl_ctx_pointer, BIO_new_ssl_connect(
			(SSL_CTX*) val_data(ctx)));
}
Example #17
0
int anetSSLGenericConnect( char* err, char* addr, int port, int flags, anetSSLConnection* sslctn, char* certFilePath, char* certDirPath, char* checkCommonName ) {
  sslctn->sd = -1;
  sslctn->ctx = NULL;
  sslctn->ssl = NULL;
  sslctn->bio = NULL;
  sslctn->conn_str = NULL;

  // Set up a SSL_CTX object, which will tell our BIO object how to do its work
  SSL_CTX* ctx = SSL_CTX_new(TLSv1_1_client_method());
  sslctn->ctx = ctx;

  // Create a SSL object pointer, which our BIO object will provide.
  SSL* ssl;

  // Create our BIO object for SSL connections.
  BIO* bio = BIO_new_ssl_connect(ctx);
  sslctn->bio = bio;

  // Failure?
  if (bio == NULL) {
     char errorbuf[1024];

     ERR_error_string(1024,errorbuf);
     anetSetError(err, "SSL Error: Error creating BIO: %s\n", errorbuf);

     // We need to free up the SSL_CTX before we leave.
     anetCleanupSSL( sslctn );
     return ANET_ERR;
  }

  // Makes ssl point to bio's SSL object.
  BIO_get_ssl(bio, &ssl);
  sslctn->ssl = ssl;

  // Set the SSL to automatically retry on failure.
  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

  char* connect_str = (char *)calloc( 1, strlen( addr ) + 10 );
  sprintf( connect_str, "%s:%d", addr, port );
  sslctn->conn_str = connect_str;

  // We're connection to to the redis server at IP:port.
  BIO_set_conn_hostname(bio, connect_str);

  SSL_CTX_load_verify_locations(ctx, certFilePath, certDirPath);

  // Same as before, try to connect.
  if (BIO_do_connect(bio) <= 0) {
    char errorbuf[1024];
    ERR_error_string(1024,errorbuf);
    anetSetError(err, "SSL Error: Failed to connect: %s\n", errorbuf);
    anetCleanupSSL( sslctn );
    return ANET_ERR;
  }

  // Now we need to do the SSL handshake, so we can communicate.
  if (BIO_do_handshake(bio) <= 0) {
    char errorbuf[1024];
    ERR_error_string(1024,errorbuf);
    anetSetError(err, "SSL Error: handshake failure: %s\n", errorbuf);
    anetCleanupSSL( sslctn );
    return ANET_ERR;
  }

  long verify_result = SSL_get_verify_result(ssl);
  if( verify_result == X509_V_OK) {
    X509* peerCertificate = SSL_get_peer_certificate(ssl);

    char commonName [512];
    X509_NAME * name = X509_get_subject_name(peerCertificate);
    X509_NAME_get_text_by_NID(name, NID_commonName, commonName, 512);
    if( checkCommonName != NULL && strlen( checkCommonName ) > 0 ) {
      if(wildcmp(commonName, checkCommonName, strlen(checkCommonName)) == 0) {
        anetSetError(err, "SSL Error: Error validating peer common name: %s\n", commonName);
        anetCleanupSSL( sslctn );
        return ANET_ERR;
      }
    }
  } else {
     char errorbuf[1024];
     ERR_error_string(1024,errorbuf);
     anetSetError(err, "SSL Error: Error retrieving peer certificate: %s\n", errorbuf);
     anetCleanupSSL( sslctn );
     return ANET_ERR;
  }

  int s = BIO_get_fd( bio, NULL );

  if (flags & ANET_CONNECT_NONBLOCK) {
       if (anetNonBlock(err,s) != ANET_OK)
         return ANET_ERR;
  }

  return s;
}
Example #18
0
/** Returns status of ticket by filling 'buf' with a NetID if the ticket
 *  is valid and buf is large enough and returning 1.  If not, 0 is
 *  returned.
 */
int cas_validate(
    char *ticket, char *service, char *outbuf, int outbuflen, pam_cas_config_t *config)
{
  int b, ret, total;
  SSL_CTX *ctx = NULL;
  BIO * bio = NULL;
  SSL *ssl = NULL;
  char buf[4096];
  char *full_request = NULL, *str;
  char netid[CAS_LEN_NETID];
  char parsebuf[128];

  debug = config->debug;

  if (config->ssl)
  {
    DEBUG_LOG("We use SSL as configured\n", "");
    /* Set up the SSL library */
    ERR_load_BIO_strings();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();
#if defined(OpenSSL_add_ssl_algorithms)
    OpenSSL_add_ssl_algorithms();
#endif

    /* Set up the SSL context */
    ctx = SSL_CTX_new(SSLv23_client_method());
    if ( ! ctx ) 
    {
      DEBUG_LOG("Cannot create SSL context", "");
      END(CAS_SSL_ERROR_INIT);
    }

    /* Load the trust store */
    if(! SSL_CTX_load_verify_locations(ctx, config->trusted_ca, NULL))
    {
      DEBUG_LOG("Error loading certificate store : %s\n", ERR_reason_error_string(ERR_get_error()));
      END(CAS_SSL_ERROR_CERT_LOAD);
    }

    /* Setup the connection */
    bio = BIO_new_ssl_connect(ctx);

    /* Set the SSL_MODE_AUTO_RETRY flag :
       if the server suddenly wants a new handshake, OpenSSL handles it in the background */
    BIO_get_ssl(bio, & ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    /* Create and setup the connection */
    DEBUG_LOG("We connect to host %s\n", config->host);
    BIO_set_conn_hostname(bio, config->host);
    BIO_set_conn_port(bio, config->port);
    if(BIO_do_connect(bio) <= 0)
    {
      DEBUG_LOG("Error attempting to connect : %s\n", ERR_reason_error_string(ERR_get_error()));
      END(CAS_SSL_ERROR_CONN);
    }

    /* Check the certificate */
    if (SSL_get_verify_result(ssl) != X509_V_OK)
    {
      DEBUG_LOG("Certificate verification error: %ld\n", SSL_get_verify_result(ssl));
      END(CAS_SSL_ERROR_CERT_VALID);
    }
  }
  else  /* no ssl */
  {    
    bio = BIO_new_connect(config->host);
    BIO_set_conn_port(bio, config->port);
    if(BIO_do_connect(bio) <= 0)
    {
      DEBUG_LOG("Error attempting to connect : %s\n", config->host);
      END(CAS_ERROR_CONN);
    }
  }

  /* build request */
  full_request = malloc(strlen(CAS_METHOD) + strlen(" ")
    + strlen(config->uriValidate) + strlen("?ticket=") + strlen(ticket) + 
    + strlen("&service=") + strlen(service) + strlen(" ") 
    + strlen(GENERIC_HEADERS) + strlen ("\r\n")
#ifdef HEADER_HOST_NAME
    + strlen(HEADER_HOST_NAME) + strlen (": ") + strlen (config->host)
#endif
    + strlen("\r\n\r\n") + 1);
  if (full_request == NULL)
  {
      DEBUG_LOG("Error memory allocation%s\n", "");
      END(CAS_ERROR_MEMORY_ALLOC);
  }
#ifdef HEADER_HOST_NAME
  sprintf(full_request, "%s %s?ticket=%s&service=%s %s\r\n%s: %s\r\n\r\n",
	  CAS_METHOD, config->uriValidate, ticket, service, GENERIC_HEADERS,
          HEADER_HOST_NAME,config->host);
#else
  sprintf(full_request, "%s %s?ticket=%s&service=%s %s\r\n\r\n",
	  CAS_METHOD, config->uriValidate, ticket, service, GENERIC_HEADERS);
#endif

  /* send request */
  DEBUG_LOG("---- request :\n%s\n", full_request);
  if (BIO_write(bio, full_request, strlen(full_request)) != strlen(full_request))
  {
    DEBUG_LOG("Unable to correctly send request to %s\n", config->host);
    END(CAS_ERROR_HTTP);
  }

  /* Read the response */
  total = 0;
  b = 0;
  do 
  {
    b = BIO_read(bio, buf + total, (sizeof(buf) - 1) - total);
    total += b;
  } while (b > 0);
  buf[total] = '\0';

  if (b != 0 || total >= sizeof(buf) - 1)
  {
    DEBUG_LOG("Unexpected read error or response too large from %s\n", config->host);
    DEBUG_LOG("b = %d\n", b);
    DEBUG_LOG("total = %d\n", total);
    DEBUG_LOG("buf = %s\n", buf);
    END(CAS_ERROR_HTTP);		// unexpected read error or response too large
  }

  DEBUG_LOG("---- response :\n%s\n", buf);
  str = (char *)strstr(buf, "\r\n\r\n");  // find the end of the header

  if (!str)
  {
    DEBUG_LOG("no header in response%s\n", "");
    END(CAS_ERROR_HTTP);			  // no header
  }

  /*
   * 'str' now points to the beginning of the body, which should be an
   * XML document
   */

  // make sure that the authentication succeeded
  
  if (!element_body(
    str, "cas:authenticationSuccess", 1, parsebuf, sizeof(parsebuf))) {
    END(CAS_BAD_TICKET);
  }

  // retrieve the NetID
  if (!element_body(str, "cas:user", 1, netid, sizeof(netid))) {
    DEBUG_LOG("unable to determine username%s\n", "");
    END(CAS_PROTOCOL_FAILURE);
  }


  // check the first proxy (if present)
  if ((config->proxies) && (config->proxies[0]))
    if (element_body(str, "cas:proxies", 1, parsebuf, sizeof(parsebuf)))
      if (element_body(str, "cas:proxy", 1, parsebuf, sizeof(parsebuf)))
        if (!arrayContains(config->proxies, parsebuf)) {
          DEBUG_LOG("bad proxy: %s\n", parsebuf);
          END(CAS_BAD_PROXY);
        }

  /*
   * without enough space, fail entirely, since a partial NetID could
   * be dangerous
   */
  if (outbuflen < strlen(netid) + 1) 
  {
    syslog(LOG_ERR, "output buffer too short");
    DEBUG_LOG("output buffer too short%s\n", "");
    END(CAS_PROTOCOL_FAILURE);
  }

  strcpy(outbuf, netid);
  SUCCEED;

   /* cleanup and return */

end:
  if (ctx)
    SSL_CTX_free(ctx);
  if (bio)
    BIO_free_all(bio);
  if (full_request)
    free(full_request);
  return ret;
}
Example #19
0
int main(int argc, char **argv)
{
    BIO *sbio = NULL, *out = NULL;
    int i, len, rv;
    char tmpbuf[1024];
    SSL_CTX *ctx = NULL;
    SSL_CONF_CTX *cctx = NULL;
    SSL *ssl = NULL;
    CONF *conf = NULL;
    STACK_OF(CONF_VALUE) *sect = NULL;
    CONF_VALUE *cnf;
    const char *connect_str = "localhost:4433";
    long errline = -1;

    ERR_load_crypto_strings();
    ERR_load_SSL_strings();
    SSL_library_init();

    conf = NCONF_new(NULL);

    if (NCONF_load(conf, "connect.cnf", &errline) <= 0) {
        if (errline <= 0)
            fprintf(stderr, "Error processing config file\n");
        else
            fprintf(stderr, "Error on line %ld\n", errline);
        goto end;
    }

    sect = NCONF_get_section(conf, "default");

    if (sect == NULL) {
        fprintf(stderr, "Error retrieving default section\n");
        goto end;
    }

    ctx = SSL_CTX_new(SSLv3_client_method());
    cctx = SSL_CONF_CTX_new();
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
    for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
        cnf = sk_CONF_VALUE_value(sect, i);
        rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value);
        if (rv > 0)
            continue;
        if (rv != -2) {
            fprintf(stderr, "Error processing %s = %s\n",
                    cnf->name, cnf->value);
            ERR_print_errors_fp(stderr);
            goto end;
        }
        if (!strcmp(cnf->name, "Connect")) {
            connect_str = cnf->value;
        } else {
            fprintf(stderr, "Unknown configuration option %s\n", cnf->name);
            goto end;
        }
    }

    if (!SSL_CONF_CTX_finish(cctx)) {
        fprintf(stderr, "Finish error\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }

    /*
     * We'd normally set some stuff like the verify paths and * mode here
     * because as things stand this will connect to * any server whose
     * certificate is signed by any CA.
     */

    sbio = BIO_new_ssl_connect(ctx);

    BIO_get_ssl(sbio, &ssl);

    if (!ssl) {
        fprintf(stderr, "Can't locate SSL pointer\n");
        goto end;
    }

    /* Don't want any retries */
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    /* We might want to do other things with ssl here */

    BIO_set_conn_hostname(sbio, connect_str);

    out = BIO_new_fp(stdout, BIO_NOCLOSE);
    if (BIO_do_connect(sbio) <= 0) {
        fprintf(stderr, "Error connecting to server\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    if (BIO_do_handshake(sbio) <= 0) {
        fprintf(stderr, "Error establishing SSL connection\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    /* Could examine ssl here to get connection info */

    BIO_puts(sbio, "GET / HTTP/1.0\n\n");
    for (;;) {
        len = BIO_read(sbio, tmpbuf, 1024);
        if (len <= 0)
            break;
        BIO_write(out, tmpbuf, len);
    }
 end:
    SSL_CONF_CTX_free(cctx);
    BIO_free_all(sbio);
    BIO_free(out);
    NCONF_free(conf);
    return 0;
}
Example #20
0
int main(int argc, char *argv[]) {
	BIO *sbio;
	SSL_CTX *ssl_ctx;
	SSL *ssl;
	X509 *server_cert;

	// Initialize OpenSSL
	OpenSSL_add_all_algorithms();
	SSL_library_init();
	SSL_load_error_strings();

 	// Check OpenSSL PRNG
	if(RAND_status() != 1) {
		fprintf(stderr, "OpenSSL PRNG not seeded with enough data.");
		goto error_1;
	}

	ssl_ctx = SSL_CTX_new(TLSv1_client_method());
	
	// Enable certificate validation
	SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
	// Configure the CA trust store to be used
	if (SSL_CTX_load_verify_locations(ssl_ctx, TRUSTED_CA_PATHNAME, NULL) != 1) {
		fprintf(stderr, "Couldn't load certificate trust store.\n");
		goto error_2;
	}

	// Only support secure cipher suites
	if (SSL_CTX_set_cipher_list(ssl_ctx, SECURE_CIPHER_LIST) != 1)
		goto error_2;

	// Create the SSL connection
	sbio = BIO_new_ssl_connect(ssl_ctx);
	BIO_get_ssl(sbio, &ssl); 
	if(!ssl) {
	  fprintf(stderr, "Can't locate SSL pointer\n");
		goto error_3;
	}

	// Do the SSL handshake
	BIO_set_conn_hostname(sbio, TARGET_SERVER);
	if(SSL_do_handshake(ssl) <= 0) {
		// SSL Handshake failed
		long verify_err = SSL_get_verify_result(ssl);
		if (verify_err != X509_V_OK) { 
			// It failed because the certificate chain validation failed
			fprintf(stderr, "Certificate chain validation failed: %s\n", X509_verify_cert_error_string(verify_err));
		}
		else {
			// It failed for another reason
			ERR_print_errors_fp(stderr);
		}
		goto error_3;
	}

	// Recover the server's certificate
	server_cert =  SSL_get_peer_certificate(ssl);
	if (server_cert == NULL) {
		// The handshake was successful although the server did not provide a certificate
		// Most likely using an insecure anonymous cipher suite... get out!
		goto error_4;
	}

	// Validate the hostname
	if (validate_hostname(TARGET_HOST, server_cert) != MatchFound) {
		fprintf(stderr, "Hostname validation failed.\n");
		goto error_5;
	}

	// Hostname validation succeeded; we can start sending data
	send_http_get_and_print(sbio);


error_5:
	X509_free(server_cert);

error_4:
	BIO_ssl_shutdown(sbio);

error_3:
	BIO_free_all(sbio);

error_2:
	SSL_CTX_free(ssl_ctx);

error_1: // OpenSSL cleanup
    EVP_cleanup();
    ERR_free_strings();

	return 0;
}
Example #21
0
int test_ssl_certificate() {

  init_openssl();

  SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method());
  SSL * ssl;

  if (NULL == ctx) {
    DEBUG_PRINT("%s\n", "Failed to init SSL_CTX");
    exit(1);
  }

  if(!SSL_CTX_load_verify_locations(ctx, NULL ,"/etc/ssl/certs")) {
    DEBUG_PRINT("%s\n", "Failed to load certs from /etc/ssl/certs");
    exit(1);
  }

  BIO *bio;

  // Create secure BIO object
  bio = BIO_new_ssl_connect(ctx);

  if (NULL == bio) {
    DEBUG_PRINT("%s\n", "Failed to create the BIO object");
    exit(1);
  }

  // Get the SSL connection from bio struct to ssl
  BIO_get_ssl(bio, &ssl);

  // Set SSL_MODE_AUTO_RETRY flag to allow retrying ssl handshake
  // int the background
  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

  DEBUG_PRINT("%s\n", "Performing SSL handshake with the host www.verisign.com");

  // Set up connection hostname and port
  BIO_set_conn_hostname(bio, "www.verisign.com:https");

  // Verify the connection opened and perform the handshake
  if (BIO_do_connect(bio) <= 0) {
    // Connection failed
    DEBUG_PRINT("%s\n", "Failed to open connection to host");
    ERR_print_errors_fp(stderr);
    BIO_free_all(bio);
    exit(1);
  }

  // Verify certificate
  if(SSL_get_verify_result(ssl) != X509_V_OK) {
    // Problem in certificate
    DEBUG_PRINT("%s\n", "Failed to verify host certificate");
  } else {
    DEBUG_PRINT("%s\n", "Verified host certificate");
  }

  // Clean context structure
  SSL_CTX_free(ctx);

  /* To reuse the connection, use this line */
  /*BIO_reset(bio);*/

  /* To free it from memory, use this line */
  BIO_free_all(bio);

  return 0;
}
Example #22
0
void *netConnectHttpsThread(void *threadParam)
/* use a thread to run socket back to user */
{
/* child */

struct netConnectHttpsParams *params = threadParam;

pthread_detach(params->thread);  // this thread will never join back with it's progenitor

int fd=0;

char hostnameProto[256];

BIO *sbio;
SSL_CTX *ctx;
SSL *ssl;

openSslInit();

ctx = SSL_CTX_new(SSLv23_client_method());

fd_set readfds;
fd_set writefds;
int err;
struct timeval tv;


/* TODO checking certificates 

char *certFile = NULL;
char *certPath = NULL;
if (certFile || certPath)
    {
    SSL_CTX_load_verify_locations(ctx,certFile,certPath);
#if (OPENSSL_VERSION_NUMBER < 0x0090600fL)
    SSL_CTX_set_verify_depth(ctx,1);
#endif
    }

// verify paths and mode.

*/


sbio = BIO_new_ssl_connect(ctx);

BIO_get_ssl(sbio, &ssl);
if(!ssl) 
    {
    xerr("Can't locate SSL pointer");
    goto cleanup;
    }

/* Don't want any retries since we are non-blocking bio now */
//SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);


safef(hostnameProto,sizeof(hostnameProto),"%s:%d",params->hostName,params->port);
BIO_set_conn_hostname(sbio, hostnameProto);

BIO_set_nbio(sbio, 1);     /* non-blocking mode */

while (1) 
    {
    if (BIO_do_connect(sbio) == 1) 
	{
	break;  /* Connected */
	}
    if (! BIO_should_retry(sbio)) 
	{
	xerr("BIO_do_connect() failed");
	char s[256];	
	safef(s, sizeof s, "SSL error: %s", ERR_reason_error_string(ERR_get_error()));
	xerr(s);
	goto cleanup;
	}

    fd = BIO_get_fd(sbio, NULL);
    if (fd == -1) 
	{
	xerr("unable to get BIO descriptor");
	goto cleanup;
	}
    FD_ZERO(&readfds);
    FD_ZERO(&writefds);
    if (BIO_should_read(sbio)) 
	{
	FD_SET(fd, &readfds);
	}
    else if (BIO_should_write(sbio)) 
	{
	FD_SET(fd, &writefds);
	}
    else 
	{  /* BIO_should_io_special() */
	FD_SET(fd, &readfds);
	FD_SET(fd, &writefds);
	}
    tv.tv_sec = 10;  // timeout
    tv.tv_usec = 0;

    err = select(fd + 1, &readfds, &writefds, NULL, &tv);
    if (err < 0) 
	{
	xerr("select() error");
	goto cleanup;
	}

    if (err == 0) 
	{
	char s[256];	
	safef(s, sizeof s, "connection timeout to %s", params->hostName);
	xerr(s);
	goto cleanup;
	}
    }


/* TODO checking certificates 

if (certFile || certPath)
    if (!check_cert(ssl, host))
	return -1;

*/

/* we need to wait on both the user's socket and the BIO SSL socket 
 * to see if we need to ferry data from one to the other */


char sbuf[32768];  // socket buffer sv[1] to user
char bbuf[32768];  // bio buffer
int srd = 0;
int swt = 0;
int brd = 0;
int bwt = 0;
while (1) 
    {

    // Do NOT move this outside the while loop. 
    /* Get underlying file descriptor, needed for select call */
    fd = BIO_get_fd(sbio, NULL);
    if (fd == -1) 
	{
	xerr("BIO doesn't seem to be initialized in https, unable to get descriptor.");
	goto cleanup;
	}


    FD_ZERO(&readfds);
    FD_ZERO(&writefds);

    if (brd == 0)
	FD_SET(fd, &readfds);
    if (swt < srd)
	FD_SET(fd, &writefds);
    if (srd == 0)
	FD_SET(params->sv[1], &readfds);

    tv.tv_sec = 10;   // timeout
    tv.tv_usec = 0;

    err = select(max(fd,params->sv[1]) + 1, &readfds, &writefds, NULL, &tv);

    /* Evaluate select() return code */
    if (err < 0) 
	{
	xerr("error during select()");
	goto cleanup;
	}
    else if (err == 0) 
	{
	/* Timed out - just quit */
	xerr("https timeout expired");
	goto cleanup;
	}

    else 
	{
	if (FD_ISSET(params->sv[1], &readfds))
	    {
	    swt = 0;
	    srd = read(params->sv[1], sbuf, 32768);
	    if (srd == -1)
		{
		if (errno != 104) // udcCache often closes causing "Connection reset by peer"
		    xerrno("error reading https socket");
		goto cleanup;
		}
	    if (srd == 0) 
		break;  // user closed socket, we are done
	    }

	if (FD_ISSET(fd, &writefds))
	    {
	    int swtx = BIO_write(sbio, sbuf+swt, srd-swt);
	    if (swtx <= 0)
		{
		if (!BIO_should_write(sbio))
		    {
		    ERR_print_errors_fp(stderr);
		    xerr("Error writing SSL connection");
		    goto cleanup;
		    }
		}
	    else
		{
		swt += swtx;
		if (swt >= srd)
		    {
		    swt = 0;
		    srd = 0;
		    }
		}
	    }

	if (FD_ISSET(fd, &readfds))
	    {
	    bwt = 0;
	    brd = BIO_read(sbio, bbuf, 32768);

	    if (brd <= 0)
		{
		if (BIO_should_read(sbio))
		    {
		    brd = 0;
		    continue;
		    }
		else
		    {
		    if (brd == 0) break;
		    ERR_print_errors_fp(stderr);
		    xerr("Error reading SSL connection");
		    goto cleanup;
		    }
		}
	    // write the https data received immediately back on socket to user, and it's ok if it blocks.
	    while(bwt < brd)
		{
		int bwtx = write(params->sv[1], bbuf+bwt, brd-bwt);
		if (bwtx == -1)
		    {
		    if ((errno != 104)  // udcCache often closes causing "Connection reset by peer"
		     && (errno !=  32)) // udcCache often closes causing "Broken pipe"
			xerrno("error writing https data back to user socket");
		    goto cleanup;
		    }
		bwt += bwtx;
		}
	    brd = 0;
	    bwt = 0;
	    }
	}
    }

cleanup:

BIO_free_all(sbio);
close(params->sv[1]);  /* we are done with it */

return NULL;
}
Example #23
0
/**
 * Run SSL handshake and store the resulting time value in the
 * 'time_map'.
 *
 * @param time_map where to store the current time
 */
static void
run_ssl (uint32_t *time_map)
{
  BIO *s_bio;
  BIO *c_bio;
  SSL_CTX *ctx;
  SSL *ssl;

  SSL_load_error_strings();
  SSL_library_init();

  ctx = NULL;
  if (0 == strcmp("sslv23", protocol))
  {
    verb ("V: using SSLv23_client_method()\n");
    ctx = SSL_CTX_new(SSLv23_client_method());
  } else if (0 == strcmp("sslv3", protocol))
  {
    verb ("V: using SSLv3_client_method()\n");
    ctx = SSL_CTX_new(SSLv3_client_method());
  } else if (0 == strcmp("tlsv1", protocol))
  {
    verb ("V: using TLSv1_client_method()\n");
    ctx = SSL_CTX_new(TLSv1_client_method());
  } else
    die("Unsupported protocol `%s'\n", protocol);

  if (ctx == NULL)
    die("OpenSSL failed to support protocol `%s'\n", protocol);

  if (ca_racket)
  {
    // For google specifically:
    // SSL_CTX_load_verify_locations(ctx, "/etc/ssl/certs/Equifax_Secure_CA.pem", NULL);
    if (1 != SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs/"))
      fprintf(stderr, "SSL_CTX_load_verify_locations failed\n");
  }

  if (NULL == (s_bio = BIO_new_ssl_connect(ctx)))
    die ("SSL BIO setup failed\n");
  BIO_get_ssl(s_bio, &ssl);
  if (NULL == ssl)
    die ("SSL setup failed\n");
  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
  if ( (1 != BIO_set_conn_hostname(s_bio, host)) ||
       (1 != BIO_set_conn_port(s_bio, port)) )
    die ("Failed to initialize connection to `%s:%s'\n", host, port);

  if (NULL == (c_bio = BIO_new_fp(stdout, BIO_NOCLOSE)))
    die ("FIXME: error message");

  // This should run in seccomp
  // eg:     prctl(PR_SET_SECCOMP, 1);
  if (1 != BIO_do_connect(s_bio)) // XXX TODO: BIO_should_retry() later?
    die ("SSL connection failed\n");    
  if (1 != BIO_do_handshake(s_bio))
    die ("SSL handshake failed\n");
  // Verify the peer certificate against the CA certs on the local system
  if (ca_racket) {
    X509 *x509;
    long ssl_verify_result;

    if (NULL == (x509 = SSL_get_peer_certificate(ssl)) )
      die ("Getting SSL certificate failed\n");

    // In theory, we verify that the cert is valid
    ssl_verify_result = SSL_get_verify_result(ssl);
    switch (ssl_verify_result)
    {
    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
      die ("SSL certificate is self signed\n");
    case X509_V_OK:
      verb ("V: SSL certificate verification passed\n");
      break;
    default:
      die ("SSL certification verification error: %ld\n", 
	   ssl_verify_result);
    }
  } else {
    verb ("V: Certificate verification skipped!\n");
  }

  // from /usr/include/openssl/ssl3.h
  //  ssl->s3->server_random is an unsigned char of 32 bytes
  memcpy(time_map, ssl->s3->server_random, sizeof (uint32_t));  
}
Example #24
0
Status getTLSCertificate(std::string hostname, QueryData& results) {
  SSL_library_init();

  const auto method = TLSv1_method();
  if (method == nullptr) {
    return Status(1, "Failed to create OpenSSL method object");
  }

  auto delCTX = [](SSL_CTX* ctx) { SSL_CTX_free(ctx); };
  auto ctx =
      std::unique_ptr<SSL_CTX, decltype(delCTX)>(SSL_CTX_new(method), delCTX);
  if (ctx == nullptr) {
    return Status(1, "Failed to create OpenSSL CTX object");
  }

  auto delBIO = [](BIO* bio) { BIO_free_all(bio); };
  auto server = std::unique_ptr<BIO, decltype(delBIO)>(
      BIO_new_ssl_connect(ctx.get()), delBIO);
  if (server == nullptr) {
    return Status(1, "Failed to create OpenSSL BIO object");
  }

  std::string port = ":443";
  auto ext_hostname = hostname;
  auto conn_hostname = hostname;
  auto delim = hostname.find(":");
  if (delim == std::string::npos) {
    conn_hostname += ":443";
  } else {
    ext_hostname = hostname.substr(0, delim);
  }

  auto ret = BIO_set_conn_hostname(server.get(), conn_hostname.c_str());
  if (ret != 1) {
    return Status(1, "Failed to set OpenSSL hostname: " + std::to_string(ret));
  }

  SSL* ssl = nullptr;
  BIO_get_ssl(server.get(), &ssl);
  if (ssl == nullptr) {
    return Status(1, "Failed to retrieve OpenSSL object");
  }

  ret = SSL_set_tlsext_host_name(ssl, ext_hostname.c_str());
  if (ret != 1) {
    return Status(1,
                  "Failed to set OpenSSL server name: " + std::to_string(ret));
  }

  ret = BIO_do_connect(server.get());
  if (ret != 1) {
    return Status(1,
                  "Failed to establish TLS connection: " + std::to_string(ret));
  }

  ret = BIO_do_handshake(server.get());
  if (ret != 1) {
    return Status(1,
                  "Failed to complete TLS handshake: " + std::to_string(ret));
  }

  auto delX509 = [](X509* cert) { X509_free(cert); };
  auto cert = std::unique_ptr<X509, decltype(delX509)>(
      SSL_get_peer_certificate(ssl), delX509);
  if (cert == nullptr) {
    return Status(1, "No certificate");
  }

  Row r;
  r["hostname"] = hostname;
  fillRow(r, cert.get());
  results.push_back(r);
  return Status();
}
Example #25
0
int main(int argc, char *argv[]) {

  if (argc < 4) {
    printf("UNSUPPORTED");  //for now at least
    return 3;
  }

  BIO *sbio;
	SSL_CTX *ssl_ctx;
	SSL *ssl;
	X509 *cert;

  int returncode = 0;

  char url[256]; sprintf(url, "%s:%s", argv[1], argv[2]);
  char ca_bundle[256]; strcpy(ca_bundle, argv[3]);

//init:

  SSL_library_init();
  SSL_load_error_strings();

  ssl_ctx = SSL_CTX_new(TLSv1_client_method());
  SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
  if (SSL_CTX_load_verify_locations(ssl_ctx, ca_bundle, NULL) != 1) {
    printf("Couldn't load certificate trust store.");
    returncode=1;
    goto end;
  } else {
    goto connect;
  }

connect:

  sbio = BIO_new_ssl_connect(ssl_ctx);
  BIO_get_ssl(sbio, &ssl);
  if (!ssl) {
    printf("Connection failed");
    returncode=2;
    goto connect_end;
  }

  SSL_set_tlsext_host_name(ssl, url);
  BIO_set_conn_hostname(sbio, url);

  if(SSL_do_handshake(ssl) <= 0 || !verify_cert_hostname(SSL_get_peer_certificate(ssl), argv[1])) {
    printf ("VERIFY FAILURE");
  } else {
    printf ("VERIFY SUCCESS");
  }

  X509_free(cert);
	BIO_ssl_shutdown(sbio);

connect_end:

  BIO_free_all(sbio);

end:

  SSL_CTX_free(ssl_ctx);
  EVP_cleanup();
  ERR_free_strings();

	return returncode;
}
Example #26
0
int main(int argc, char **argv) {
  SSL_load_error_strings();
  ERR_load_BIO_strings();
  SSL_library_init();

  /*BIO *SSLout = BIO_new_connect(BROKER_CONN);
  if (!SSLout) {
    fprintf(stderr, "Error creating BIO\n");
    exit(EXIT_FAILURE);
  }
  if (BIO_do_connect(SSLout) <= 0) {
    fprintf(stderr,"Error connecting BIO\n");
    exit(EXIT_FAILURE);
  }
  char buf[BUFSIZ];
  */

  printf("HERE\n");

  SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
  if (!SSL_CTX_load_verify_locations(ctx,BROKER_CERT,NULL)) {
    fprintf(stderr,"Failed to load broker cert\n");
    exit(EXIT_FAILURE);
  }
  printf("HERE\n");
  SSL *ssl = SSL_new(ctx);
  SSL_set_mode(ssl,SSL_MODE_AUTO_RETRY);
  BIO *sslconn = BIO_new_ssl_connect(ctx);
  BIO_get_ssl(sslconn, &ssl);
 
  printf("HERE\n"); 

  // Do connection
  BIO_set_conn_hostname(sslconn,BROKER_CONN);
  BIO_set_conn_port(sslconn,BROKER_PORT);
  if (BIO_do_connect(sslconn) < 0) {
    fprintf(stderr,"Failed to make ssl connection\n");
    fprintf(stderr,"Error description: %s\n", ERR_reason_error_string(ERR_get_error()));
    exit(EXIT_FAILURE);
  }

  int err; 
  if((err = SSL_connect(ssl)) < 1)
  {
      fprintf(stderr, "Failed to initiate handshake:%s\n", ERR_reason_error_string(ERR_get_error()));
  }
  printf("HERE\n"); 
 
  char buf[BUFSIZ];  

  strcpy(buf,"OHAITHAR!\n");

  if( BIO_write(sslconn,buf,strlen(buf)) <= 0 ) {
    if(! BIO_should_retry(sslconn)) {
      
    }
  }
  
  
  /*if we want to reuse, start fresh
  BIO_reset(sslconn);
  */
  BIO_free_all(sslconn);
  
  return 0;
}
Example #27
0
void secure_and_send(int client_fd, char* read_pipe, char* write_pipe, int index, FILE* d_out){
	BIO* bio;
	SSL* ssl;
	SSL_CTX* ctx;
	
	/*init ssl library*/
	SSL_library_init();
	ERR_load_BIO_strings();
	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();
	
	/* Set up the SSL context */

    ctx = SSL_CTX_new(SSLv23_client_method());

    /* Load the trust store */

    if(! SSL_CTX_load_verify_locations(ctx, "cacerts.pem", NULL))
    {
        fprintf(stderr, "Error loading trust store\n");
        ERR_print_errors_fp(stderr);
        SSL_CTX_free(ctx);
        return;
    }
    /* Setup the connection */

    bio = BIO_new_ssl_connect(ctx);

    /* Set the SSL_MODE_AUTO_RETRY flag */

    BIO_get_ssl(bio, & ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    
    /* Create and setup the connection */
	char host[LINE];
	sprintf(host,"%s:%s",safe_host[index],safe_port[index]);
    BIO_set_conn_hostname(bio, safe_host[index]);
    BIO_set_conn_port(bio,safe_port[index]);

    if(BIO_do_connect(bio) <= 0)
    {
        fprintf(stderr, "Error attempting to connect\n");
        ERR_print_errors_fp(stderr);
        BIO_free_all(bio);
        SSL_CTX_free(ctx);
        return;
    }

    /* Check the certificate */

    if(SSL_get_verify_result(ssl) != X509_V_OK)
    {
        fprintf(stderr, "Certificate verification error: %lu\n", SSL_get_verify_result(ssl));
        BIO_free_all(bio);
        SSL_CTX_free(ctx);
        return;
    }
    /* Send the request */

    BIO_write(bio, read_pipe, strlen(read_pipe));

    /* Read in the response */

    for(;;)
    {
        int p = BIO_read(bio, write_pipe, PIPE_MAX);
        if(p <= 0) break;
        p = write(client_fd,write_pipe,p);
    }

    /* Close the connection and free the context */
	
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    close(client_fd);
    fclose(d_out);
    return;
}
Example #28
0
File: run.c Project: ouspg/trytls
int main(int argc, char *argv[]) {

  unsigned int bundleLength=0, urlLength=0;

  if (argc == 3) {
    printf("UNSUPPORTED\n");  //for now at least
    return EXIT_SUCCESS;
  } else if (argc != 4) {
    printf("usage: %s <host> <port> <ca-bundle>\n", argv[0]);
    return EXIT_FAILURE;
  } else if ((urlLength = strlen(argv[1]) + strlen(argv[2]) + 2) > MAX_LENGTH) {
    printf("Too long URL: %d characters, max: %d\n", urlLength, MAX_LENGTH);
    return EXIT_FAILURE;
  } else if ((bundleLength = strlen(argv[3]) + 1) > MAX_LENGTH) {
    printf("Too long ca-bundle filepath: %d characters, max: %d\n", bundleLength, MAX_LENGTH);
    return EXIT_FAILURE;
  }

  char url[1024];       snprintf(url, sizeof(url), "%s:%s", argv[1], argv[2]);
  char ca_bundle[1024]; memcpy(ca_bundle, argv[3], bundleLength);
  int exitvalue = 0;

  BIO *sbio;
  SSL_CTX *ssl_ctx;
  SSL *ssl;
  X509 *cert;

  const char *servername = NULL;
  X509_VERIFY_PARAM *param = NULL;

  SSL_load_error_strings();
  SSL_library_init();

  ssl_ctx = SSL_CTX_new(TLS_method());  //if you are using an older version of openssl, you may need to change this into for example: TLSv1_2_client_method
  param = SSL_CTX_get0_param(ssl_ctx);

  //set certificate verify
  //https://wiki.openssl.org/index.php/Hostname_validation
  X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
  X509_VERIFY_PARAM_set1_host(param, argv[1], 0);
  SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
  if (SSL_CTX_load_verify_locations(ssl_ctx, ca_bundle, NULL) != 1) {
    printf("Couldn't load certificate trust store\n");
    printf("%s\n", ERR_reason_error_string(ERR_get_error()));
    exitvalue=EXIT_FAILURE;
    goto end;
  }

  sbio = BIO_new_ssl_connect(ssl_ctx);
  BIO_get_ssl(sbio, &ssl);
  if (!ssl) {
    printf("Connection failed\n");
    printf("%s\n", ERR_reason_error_string(ERR_get_error()));
    exitvalue=EXIT_FAILURE;
    goto connect_end;
  }

  //handshake
  SSL_set_tlsext_host_name(ssl, url);
  BIO_set_conn_hostname(sbio, url);
  if(SSL_do_handshake(ssl) <= 0) {
    unsigned long int error = ERR_get_error();
    printf("%s\n", ERR_reason_error_string(error));
    printf("REJECT\n");
  } else {
    printf ("ACCEPT\n");
  }

connect_end:

  BIO_free_all(sbio);

end:

  SSL_CTX_free(ssl_ctx);
  EVP_cleanup();
  ERR_free_strings();

  return exitvalue;
}
Example #29
0
int crashreport_send(char *fname)
{
	char buf[1024];
	char header[512], footer[512];
	char delimiter[41];
	int filesize;
	int n;
	FILE *fd;
	SSL_CTX *ctx_client;
	BIO *socket = NULL;
	
	filesize = getfilesize(fname);
	if (filesize < 0)
		return 0;
	
	for (n = 0; n < sizeof(delimiter); n++)
		delimiter[n] = getrandom8()%26 + 'a';
	delimiter[sizeof(delimiter)-1] = '\0';
	
	snprintf(header, sizeof(header), "--%s\r\n"
	                           "Content-Disposition: form-data; name=\"upload\"; filename=\"crash.txt\"\r\n"
	                           "Content-Type: text/plain\r\n"
	                           "\r\n",
	                           delimiter);
	snprintf(footer, sizeof(footer), "\r\n--%s--\r\n", delimiter);

	ctx_client = crashreport_init_ssl();
	if (!ctx_client)
	{
		printf("ERROR: SSL initalization failure (I)\n");
		return 0;
	}
	
	socket = BIO_new_ssl_connect(ctx_client);
	if (!socket)
	{
		printf("ERROR: SSL initalization failure (II)\n");
		return 0;
	}
	
	BIO_set_conn_hostname(socket, CRASH_REPORT_HOST ":443");

	if (BIO_do_connect(socket) != 1)
	{
		printf("ERROR: Could not connect to %s\n", CRASH_REPORT_HOST);
		return 0;
	}
	
	if (BIO_do_handshake(socket) != 1)
	{
		printf("ERROR: Could not connect to %s (SSL handshake failed)\n", CRASH_REPORT_HOST);
		return 0;
	}
	
	snprintf(buf, sizeof(buf), "POST /crash.php HTTP/1.1\r\n"
	                    "User-Agent: UnrealIRCd %s\r\n"
	                    "Host: %s\r\n"
	                    "Accept: */*\r\n"
	                    "Content-Length: %d\r\n"
	                    "Expect: 100-continue\r\n"
	                    "Content-Type: multipart/form-data; boundary=%s\r\n"
	                    "\r\n",
	                    VERSIONONLY,
	                    CRASH_REPORT_HOST,
	                    (int)(filesize+strlen(header)+strlen(footer)),
	                    delimiter);
	
	BIO_puts(socket, buf);
	
	memset(buf, 0, sizeof(buf));
	n = BIO_read(socket, buf, 255);
	if ((n < 0) || strncmp(buf, "HTTP/1.1 100", 12))
	{
		printf("Error transmitting bug report (stage II, n=%d)\n", n);
		return 0;
	}
	
	fd = fopen(fname, "rb");
	if (!fd)
		return 0;

	BIO_puts(socket, header);
	
	while ((fgets(buf, sizeof(buf), fd)))
	{
		BIO_puts(socket, buf);
	}
	fclose(fd);

	BIO_puts(socket, footer);

	do { } while(BIO_should_retry(socket)); /* make sure we are really finished (you never know with SSL) */
	
	BIO_free_all(socket);
	
	SSL_CTX_free(ctx_client);
	
	return 1;
}
Example #30
0
/**
 * oh_ssl_connect
 * @hostname:   Name of target host.  Format:
 *                  "hostname:port" or "IPaddress:port"
 * @ctx:        pointer to SSL_CTX as returned by oh_ssl_ctx_init()
 * @timeout:    maximum number of seconds to wait for a connection to
 *              hostname, or zero to wait forever
 *
 * Create and open a new ssl conection to the specified host.
 *
 * Return value: pointer to BIO, or NULL for failure
 **/
BIO             *oh_ssl_connect(char *hostname, SSL_CTX *ctx, long timeout)
{
        BIO             *bio;
        SSL             *ssl;
        fd_set          readfds;
        fd_set          writefds;
        struct timeval  tv;
        int             fd;
        int             err;

        if (hostname == NULL) {
                err("NULL hostname in oh_ssl_connect()");
                return(NULL);
        }
        if (ctx == NULL) {
                err("NULL ctx in oh_ssl_connect()");
                return(NULL);
        }
        if (timeout < 0) {
                err("inappropriate timeout in oh_ssl_connect()");
                return(NULL);
        }

        /* Start with a new SSL BIO */
        bio = BIO_new_ssl_connect(ctx);
        if (bio == NULL) {
                err("BIO_new_ssl_connect() failed");
                return(NULL);
        }

        /* Set up connection parameters for this BIO */
        BIO_set_conn_hostname(bio, hostname);
        BIO_set_nbio(bio, 1);           /* Set underlying socket to
                                         * non-blocking mode
                                         */

        /* Set up SSL session parameters */
        BIO_get_ssl(bio, &ssl);
        if (ssl == NULL) {
                err("BIO_get_ssl() failed");
                BIO_free_all(bio);
                return(NULL);
        }
        SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);

        /* Ready to open the connection.  Note that this call will probably
         * take a while, so we need to retry it, watching for a timeout.
         */
        while (1) {
                if (BIO_do_connect(bio) == 1) {
                        break;          /* Connection established */
                }
                if (! BIO_should_retry(bio)) { /* Hard error? */
                        err("BIO_do_connect() failed");
                        err("SSL error: %s",
                            ERR_reason_error_string(ERR_get_error()));
                        BIO_free_all(bio);
                        return(NULL);
                }

                /* Wait until there's a change in the socket's status or until
                 * the timeout period.
                 *
                 * Get underlying file descriptor, needed for the select call.
                 */
                fd = BIO_get_fd(bio, NULL);
                if (fd == -1) {
                        err("BIO isn't initialized in oh_ssl_connect()");
                        BIO_free_all(bio);
                        return(NULL);
                }

                FD_ZERO(&readfds);
                FD_ZERO(&writefds);
                if (BIO_should_read(bio)) {
                        FD_SET(fd, &readfds);
                }
                else if (BIO_should_write(bio)) {
                        FD_SET(fd, &writefds);
                }
                else {                  /* This is BIO_should_io_special().
                                         * Not sure what "special" needs to
                                         * wait for, but both read and write
                                         * seems to work without unnecessary
                                         * retries.
                                         */
                        FD_SET(fd, &readfds);
                        FD_SET(fd, &writefds);
                }
                if (timeout) {
                        tv.tv_sec = timeout;
                        tv.tv_usec = 0;
                        err = select(fd + 1, &readfds, &writefds, NULL, &tv);
                }
                else {                  /* No timeout */
                        err = select(fd + 1, &readfds, &writefds, NULL, NULL);
                }

                /* Evaluate select() return code */
                if (err < 0) {
                        err("error during select()");
                        BIO_free_all(bio);
                        return(NULL);
                }
                if (err == 0) {
                        err("connection timeout to %s", hostname);
                        BIO_free_all(bio);
                        return(NULL);   /* Timeout */
                }
        }

        /* TODO: Do I need to set the client or server mode here?  I don't
         * think so.
         */

        return(bio);
}