示例#1
0
int load_private_key(SSL_CTX *ctx, const neo4j_config_t *config,
        neo4j_logger_t *logger)
{
    const char *private_key = config->tls_private_key_file;
    if (private_key == NULL)
    {
        return 0;
    }

    if (SSL_CTX_use_certificate_chain_file(ctx, private_key) != 1)
    {
        errno = openssl_error(logger, NEO4J_LOG_ERROR, __FILE__, __LINE__);
        return -1;
    }

    if (config->tls_pem_pw_callback != NULL)
    {
        SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)(intptr_t)config);
        SSL_CTX_set_default_passwd_cb(ctx, pem_pw_callback);
    }

    return 0;
}
示例#2
0
DskSslContext    *
dsk_ssl_context_new   (DskSslContextOptions *options,
                       DskError            **error)
{
  const SSL_METHOD *method = SSLv3_method ();
  SSL_CTX *ctx = SSL_CTX_new (method);
  DskSslContext *rv = dsk_object_new (&dsk_ssl_context_class);
  rv->ctx = ctx;
  if (options->password)
    {
      rv->password = dsk_strdup (options->password);
      SSL_CTX_set_default_passwd_cb (ctx, set_password_cb);
      SSL_CTX_set_default_passwd_cb_userdata (ctx, rv);
    }
  if (options->cert_filename)
    {
      if (SSL_CTX_use_certificate_file (ctx, options->cert_filename,
                                        SSL_FILETYPE_PEM) != 1)
        {
          dsk_set_error (error, "error using certificate file %s",
                         options->cert_filename);
          dsk_object_unref (rv);
          return NULL;
        }
    }
  if (options->key_filename)
    {
      if (SSL_CTX_use_PrivateKey_file (ctx, options->key_filename, SSL_FILETYPE_PEM) != 1)
        {
          dsk_set_error (error, "error using key file %s",
                         options->key_filename);
          dsk_object_unref (rv);
          return NULL;
        }
    }
  return rv;
}
示例#3
0
void
tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
{
  ASSERT(NULL != ctx);

  SSL_CTX_set_session_cache_mode (ctx->ctx, SSL_SESS_CACHE_OFF);
  SSL_CTX_set_options (ctx->ctx, SSL_OP_SINGLE_DH_USE);
  SSL_CTX_set_default_passwd_cb (ctx->ctx, pem_password_callback);

  /* Require peer certificate verification */
#if P2MP_SERVER
  if (ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)
    {
      msg (M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION "
	  "--client-cert-not-required may accept clients which do not present "
	  "a certificate");
    }
  else
#endif
  SSL_CTX_set_verify (ctx->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
		      verify_callback);

  SSL_CTX_set_info_callback (ctx->ctx, info_callback);
}
示例#4
0
/*
 * load a private key from a file
 */
static int
load_private_key(SSL_CTX * ctx, char *filename)
{
	int idx, ret_pwd;
	LM_DBG("entered\n");

	SSL_CTX_set_default_passwd_cb(ctx, passwd_cb);
	SSL_CTX_set_default_passwd_cb_userdata(ctx, filename);

	for(idx = 0, ret_pwd = 0; idx < NUM_RETRIES; idx++ ) {
		ret_pwd = SSL_CTX_use_PrivateKey_file(ctx, filename, SSL_FILETYPE_PEM);
		if ( ret_pwd ) {
			break;
		} else {
			LM_ERR("unable to load private key file '%s'. \n"
				"Retry (%d left) (check password case)\n",
				filename, (NUM_RETRIES - idx -1) );
			continue;
		}
	}

	if( ! ret_pwd ) {
		LM_ERR("unable to load private key file '%s'\n",
			filename);
		return -1;
	}

	if (!SSL_CTX_check_private_key(ctx)) {
		LM_ERR("key '%s' does not match the public key of the certificate\n",
			filename);
		return -1;
	}

	LM_DBG("key '%s' successfuly loaded\n", filename);
	return 0;
}
示例#5
0
static bool
_mongoc_ssl_setup_pem_file (SSL_CTX    *ctx,
                            const char *pem_file,
                            const char *password)
{
   if (!SSL_CTX_use_certificate_chain_file (ctx, pem_file)) {
      return 0;
   }

   if (password) {
      SSL_CTX_set_default_passwd_cb_userdata (ctx, (void *)password);
      SSL_CTX_set_default_passwd_cb (ctx, _mongoc_ssl_password_cb);
   }

   if (!(SSL_CTX_use_PrivateKey_file (ctx, pem_file, SSL_FILETYPE_PEM))) {
      return 0;
   }

   if (!(SSL_CTX_check_private_key (ctx))) {
      return 0;
   }

   return 1;
}
/*
 *	Create Global context SSL and use it in every new session
 *
 *	- Load the trusted CAs
 *	- Load the Private key & the certificate
 *	- Set the Context options & Verify options
 */
static SSL_CTX *init_tls_ctx(EAP_TLS_CONF *conf)
{
	SSL_METHOD *meth;
	SSL_CTX *ctx;
	X509_STORE *certstore;
	int verify_mode = SSL_VERIFY_NONE;
	int ctx_options = 0;
	int type;

	/*
	 *	Add all the default ciphers and message digests
	 *	Create our context.
	 */
	SSL_library_init();
	SSL_load_error_strings();

	/*
	 *	SHA256 is in all versions of OpenSSL, but isn't
	 *	initialized by default.  It's needed for WiMAX
	 *	certificates.
	 */
#ifdef HAVE_OPENSSL_EVP_SHA256
	EVP_add_digest(EVP_sha256());
#endif

	meth = TLSv1_method();
	ctx = SSL_CTX_new(meth);

	/*
	 * Identify the type of certificates that needs to be loaded
	 */
	if (conf->file_type) {
		type = SSL_FILETYPE_PEM;
	} else {
		type = SSL_FILETYPE_ASN1;
	}

	/*
	 * Set the password to load private key
	 */
	if (conf->private_key_password) {
#ifdef __APPLE__
		/*
		 * We don't want to put the private key password in eap.conf, so  check
		 * for our special string which indicates we should get the password
		 * programmatically. 
		 */
		const char* special_string = "Apple:UseCertAdmin";
		if (strncmp(conf->private_key_password,
					special_string,
					strlen(special_string)) == 0)
		{
			char cmd[256];
			const long max_password_len = 128;
			snprintf(cmd, sizeof(cmd) - 1,
					 "/usr/sbin/certadmin --get-private-key-passphrase \"%s\"",
					 conf->private_key_file);

			DEBUG2("rlm_eap: Getting private key passphrase using command \"%s\"", cmd);

			FILE* cmd_pipe = popen(cmd, "r");
			if (!cmd_pipe) {
				radlog(L_ERR, "rlm_eap: %s command failed.	Unable to get private_key_password", cmd);
				radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file);
				return NULL;
			}

			free(conf->private_key_password);
			conf->private_key_password = malloc(max_password_len * sizeof(char));
			if (!conf->private_key_password) {
				radlog(L_ERR, "rlm_eap: Can't malloc space for private_key_password");
				radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file);
				pclose(cmd_pipe);
				return NULL;
			}

			fgets(conf->private_key_password, max_password_len, cmd_pipe);
			pclose(cmd_pipe);

			/* Get rid of newline at end of password. */
			conf->private_key_password[strlen(conf->private_key_password) - 1] = '\0';
			DEBUG2("rlm_eap:  Password from command = \"%s\"", conf->private_key_password);
		}
#endif
		SSL_CTX_set_default_passwd_cb_userdata(ctx, conf->private_key_password);
		SSL_CTX_set_default_passwd_cb(ctx, cbtls_password);
	}

	/*
	 *	Load our keys and certificates
	 *
	 *	If certificates are of type PEM then we can make use
	 *	of cert chain authentication using openssl api call
	 *	SSL_CTX_use_certificate_chain_file.  Please see how
	 *	the cert chain needs to be given in PEM from
	 *	openSSL.org
	 */
	if (type == SSL_FILETYPE_PEM) {
		if (!(SSL_CTX_use_certificate_chain_file(ctx, conf->certificate_file))) {
			radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
			radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
			return NULL;
		}

	} else if (!(SSL_CTX_use_certificate_file(ctx, conf->certificate_file, type))) {
		radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
		radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
		return NULL;
	}

	/* Load the CAs we trust */
	if (conf->ca_file || conf->ca_path) {
		if (!SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) {
			radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
			radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list %s",conf->ca_file );
			return NULL;
		}
	}
	if (conf->ca_file && *conf->ca_file) SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file));
	if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) {
		radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
		radlog(L_ERR, "rlm_eap_tls: Error reading private key file %s", conf->private_key_file);
		return NULL;
	}

	/*
	 * Check if the loaded private key is the right one
	 */
	if (!SSL_CTX_check_private_key(ctx)) {
		radlog(L_ERR, "rlm_eap_tls: Private key does not match the certificate public key");
		return NULL;
	}

	/*
	 *	Set ctx_options
	 */
	ctx_options |= SSL_OP_NO_SSLv2;
   	ctx_options |= SSL_OP_NO_SSLv3;
#ifdef SSL_OP_NO_TICKET
	ctx_options |= SSL_OP_NO_TICKET ;
#endif

	/*
	 *	SSL_OP_SINGLE_DH_USE must be used in order to prevent
	 *	small subgroup attacks and forward secrecy. Always
	 *	using
	 *
	 *	SSL_OP_SINGLE_DH_USE has an impact on the computer
	 *	time needed during negotiation, but it is not very
	 *	large.
	 */
   	ctx_options |= SSL_OP_SINGLE_DH_USE;

	/*
	 *	SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS to work around issues
	 *	in Windows Vista client.
	 *	http://www.openssl.org/~bodo/tls-cbc.txt
	 *	http://www.nabble.com/(RADIATOR)-Radiator-Version-3.16-released-t2600070.html
	 */
   	ctx_options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;

	SSL_CTX_set_options(ctx, ctx_options);

	/*
	 *	TODO: Set the RSA & DH
	 *	SSL_CTX_set_tmp_rsa_callback(ctx, cbtls_rsa);
	 *	SSL_CTX_set_tmp_dh_callback(ctx, cbtls_dh);
	 */

	/*
	 *	set the message callback to identify the type of
	 *	message.  For every new session, there can be a
	 *	different callback argument.
	 *
	 *	SSL_CTX_set_msg_callback(ctx, cbtls_msg);
	 */

	/* Set Info callback */
	SSL_CTX_set_info_callback(ctx, cbtls_info);

	/*
	 *	Callbacks, etc. for session resumption.
	 */						      
	if (conf->session_cache_enable) {
		SSL_CTX_sess_set_new_cb(ctx, cbtls_new_session);
		SSL_CTX_sess_set_get_cb(ctx, cbtls_get_session);
		SSL_CTX_sess_set_remove_cb(ctx, cbtls_remove_session);

		SSL_CTX_set_quiet_shutdown(ctx, 1);
	}

	/*
	 *	Check the certificates for revocation.
	 */
#ifdef X509_V_FLAG_CRL_CHECK
	if (conf->check_crl) {
	  certstore = SSL_CTX_get_cert_store(ctx);
	  if (certstore == NULL) {
	    radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
	    radlog(L_ERR, "rlm_eap_tls: Error reading Certificate Store");
	    return NULL;
	  }
	  X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
	}
#endif

	/*
	 *	Set verify modes
	 *	Always verify the peer certificate
	 */
	verify_mode |= SSL_VERIFY_PEER;
	verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
	verify_mode |= SSL_VERIFY_CLIENT_ONCE;
	SSL_CTX_set_verify(ctx, verify_mode, cbtls_verify);

	if (conf->verify_depth) {
		SSL_CTX_set_verify_depth(ctx, conf->verify_depth);
	}

	/* Load randomness */
	if (!(RAND_load_file(conf->random_file, 1024*1024))) {
		radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
		radlog(L_ERR, "rlm_eap_tls: Error loading randomness");
		return NULL;
	}

	/*
	 * Set the cipher list if we were told to
	 */
	if (conf->cipher_list) {
		if (!SSL_CTX_set_cipher_list(ctx, conf->cipher_list)) {
			radlog(L_ERR, "rlm_eap_tls: Error setting cipher list");
			return NULL;
		}
	}

	/*
	 *	Setup session caching
	 */
	if (conf->session_cache_enable) {
		/*
		 *	Create a unique context Id per EAP-TLS configuration.
		 */
		if (conf->session_id_name) {
			snprintf(conf->session_context_id,
				 sizeof(conf->session_context_id),
				 "FreeRADIUS EAP-TLS %s",
				 conf->session_id_name);
		} else {
			snprintf(conf->session_context_id,
				 sizeof(conf->session_context_id),
				 "FreeRADIUS EAP-TLS %p", conf);
		}

		/*
		 *	Cache it, and DON'T auto-clear it.
		 */
		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR);
					       
		SSL_CTX_set_session_id_context(ctx,
					       (unsigned char *) conf->session_context_id,
					       (unsigned int) strlen(conf->session_context_id));

		/*
		 *	Our timeout is in hours, this is in seconds.
		 */
		SSL_CTX_set_timeout(ctx, conf->session_timeout * 3600);
		
		/*
		 *	Set the maximum number of entries in the
		 *	session cache.
		 */
		SSL_CTX_sess_set_cache_size(ctx, conf->session_cache_size);

	} else {
		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
	}

	/*
	 *	Register the application indices.  We can't use
	 *	hard-coded "0" and "1" as before, because we need to
	 *	set up a "free" handler for the cached session
	 *	information.
	 */
	if (eaptls_handle_idx < 0) {
		eaptls_handle_idx = SSL_get_ex_new_index(0, &eaptls_handle_idx,
							 NULL, NULL, NULL);
	}
	
	if (eaptls_conf_idx < 0) {
		eaptls_conf_idx = SSL_get_ex_new_index(0, &eaptls_conf_idx,
							  NULL, NULL, NULL);
	}

	if (eaptls_store_idx < 0) {
		eaptls_store_idx = SSL_get_ex_new_index(0, "eaptls_store_idx",
							  NULL, NULL, NULL);
	}

	if (eaptls_session_idx < 0) {
		eaptls_session_idx = SSL_get_ex_new_index(0, &eaptls_session_idx,
							  NULL, NULL,
							  eaptls_session_free);
	}

	return ctx;
}
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = 0;
    int      clientfd = 0;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    char   msg[] = "I hear you fa shizzle!";
    char   input[1024];
    int    idx;
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    int    port = yasslPort;
    int    usePsk = 0;
    int    doDTLS = 0;
    int    useNtruKey = 0;
    char*  cipherList = NULL;
    char*  verifyCert = (char*)cliCert;
    char*  ourCert    = (char*)svrCert;
    char*  ourKey     = (char*)svrKey;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

    ((func_args*)args)->return_code = -1; /* error state */

    while ((ch = mygetopt(argc, argv, "?dbsnup:v:l:A:c:k:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                version = -1;  /* DTLS flag */
                break;

            case 'p' :
                port = atoi(myoptarg);
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                if (doDTLS)
                    version = -1;  /* stay with DTLS */
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    argc -= myoptind;
    argv += myoptind;
    myoptind = 0;      /* reset for test cases */

    switch (version) {
        case 0:
            method = SSLv3_server_method();
            break;

        case 1:
            method = TLSv1_server_method();
            break;

        case 2:
            method = TLSv1_1_server_method();
            break;

        case 3:
            method = TLSv1_2_server_method();
            break;

#ifdef CYASSL_DTLS
        case -1:
            method = DTLSv1_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("can't set cipher list");

    if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                     != SSL_SUCCESS)
        err_sys("can't load server cert file, check file and run from"
                " CyaSSL home dir");


#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                               != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from CyaSSL home dir");
    }
#endif

    if (!useNtruKey) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                " CyaSSL home dir");
    }

#ifndef NO_PSK
    if (usePsk) {
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
        SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
        if (cipherList == NULL)
            if (SSL_CTX_set_cipher_list(ctx,"PSK-AES256-CBC-SHA") !=SSL_SUCCESS)
                err_sys("can't set cipher list");
    }
#endif

    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    }

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS)
        err_sys("can't set cipher list");
#endif

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL");

#ifdef HAVE_CRL
    CyaSSL_EnableCRL(ssl, 0);
    CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                     CYASSL_CRL_START_MON);
    CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS);
    if (!doDTLS) 
        CloseSocket(sockfd);

    SSL_set_fd(ssl, clientfd);
#ifdef NO_PSK
    #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
        CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
    #else
        SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
    #endif
#endif

#ifdef NON_BLOCKING
    tcp_set_nonblocking(&clientfd);
    NonBlockingSSL_Accept(ssl);
#else
    #ifndef CYASSL_CALLBACKS
        if (SSL_accept(ssl) != SSL_SUCCESS) {
            int err = SSL_get_error(ssl, 0);
            char buffer[80];
            printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
            err_sys("SSL_accept failed");
        }
    #else
        NonBlockingSSL_Accept(ssl);
    #endif
#endif
    showPeer(ssl);

    idx = SSL_read(ssl, input, sizeof(input));
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);
    }
    
    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
        err_sys("SSL_write failed");

    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = 0;
    return 0;
}
示例#8
0
int anetSSLAccept( char *err, int fd, struct redisServer server, anetSSLConnection *ctn) {

  ctn->sd = -1;
  ctn->ctx = NULL;
  ctn->ssl = NULL;
  ctn->bio = NULL;
  ctn->conn_str = NULL;

  if( fd == -1 ) {
    return ANET_ERR;
  }
  ctn->sd = fd;

  // Create the SSL Context ( server method )
  SSL_CTX* ctx = SSL_CTX_new(TLSv1_1_server_method());
  ctn->ctx = ctx;

   /*
     You will need to generate certificates, the root certificate authority file, the private key file, and the random file yourself.
     Google will help. The openssl executable created when you compiled OpenSSL can do all this.
   */

    // Load trusted root authorities
    SSL_CTX_load_verify_locations(ctx, server.ssl_root_file, server.ssl_root_dir);

    // Sets the default certificate password callback function. Read more under the Certificate Verification section.
    if( NULL != server.ssl_srvr_cert_passwd ) {
      global_ssl_cert_password = server.ssl_srvr_cert_passwd;
      SSL_CTX_set_default_passwd_cb(ctx, password_callback);
    }

    // Sets the certificate file to be used.
    SSL_CTX_use_certificate_file(ctx, server.ssl_cert_file, SSL_FILETYPE_PEM);

    // Sets the private key file to be used.
    SSL_CTX_use_PrivateKey_file(ctx, server.ssl_pk_file, SSL_FILETYPE_PEM);

    // Set the maximum depth to be used verifying certificates
    // Due to a bug, this is not enforced. The verify callback must enforce it.
    SSL_CTX_set_verify_depth(ctx, 1);

    // Set the certificate verification callback.
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER /* | SSL_VERIFY_FAIL_IF_NO_PEER_CERT */, verify_callback);

    /*
      End certificate verification setup.
    */

    // We need to load the Diffie-Hellman key exchange parameters.
    // First load dh1024.pem (you DID create it, didn't you?)
    BIO* bio = BIO_new_file(server.ssl_dhk_file, "r");

    // Did we get a handle to the file?
    if (bio == NULL) {
      anetSetError(err, "SSL Accept: Couldn't open DH param file");
      anetCleanupSSL( ctn);
      return ANET_ERR;
    }

    // Read in the DH params.
    DH* ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);

    // Free up the BIO object.
    BIO_free(bio);

    // Set up our SSL_CTX to use the DH parameters.
    if (SSL_CTX_set_tmp_dh(ctx, ret) < 0) {
      anetSetError(err, "SSL Accept: Couldn't set DH parameters");
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    // Now we need to generate a RSA key for use.
    // 1024-bit key. If you want to use something stronger, go ahead but it must be a power of 2. Upper limit should be 4096.
    RSA* rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);

    // Set up our SSL_CTX to use the generated RSA key.
    if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
      anetSetError(err, "SSL Accept: Couldn't set RSA Key");
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    // Free up the RSA structure.
    RSA_free(rsa);

    /*
      For some reason many tutorials don't include this...

      Servers must specify the ciphers they can use, to verify that both the client and the server can use the same cipher.
      If you don't do this, you'll get errors relating to "no shared ciphers" or "no common ciphers".

      Use all ciphers with the exception of: ones with anonymous Diffie-Hellman, low-strength ciphers, export ciphers, md5 hashing. Ordered from strongest to weakest.
      Note that as ciphers become broken, it will be necessary to change the available cipher list to remain secure.
    */

    if( NULL == server.ssl_srvr_cipher_list || 0 == strlen(server.ssl_srvr_cipher_list) )
        SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
    else
    	SSL_CTX_set_cipher_list(ctx, server.ssl_srvr_cipher_list);

    // Set up our SSL object as before
    SSL* ssl = SSL_new(ctx);
    ctn->ssl = ssl;
    
    // Set up our BIO object to use the client socket
    BIO* sslclient = BIO_new_socket(fd, BIO_NOCLOSE);
    ctn->bio = sslclient;

    // Set up our SSL object to use the BIO.
    SSL_set_bio(ssl, sslclient, sslclient);

    // Do SSL handshaking.
    int r = SSL_accept(ssl);

    // Something failed. Print out all the error information, since all of it may be relevant to the problem.
    if (r != 1) {
      char error[65535];

      ERR_error_string_n(ERR_get_error(), error, 65535);

      anetSetError(err, "SSL Accept: Error %d - %s ", SSL_get_error(ssl, r), error );

      // We failed to accept this client connection.
      // Ideally here you'll drop the connection and continue on.
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    /* Verify certificate */
    if (SSL_get_verify_result(ssl) != X509_V_OK) {
      anetSetError(err, "SSL Accept: Certificate failed verification!");
      // Ideally here you'll close this connection and continue on.
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    return ANET_OK;
}
示例#9
0
void echoclient_test(void* args)
{
    SOCKET_T sockfd = 0;

    FILE* fin  = stdin;
    FILE* fout = stdout;

    int inCreated  = 0;
    int outCreated = 0;

    char send[1024];
    char reply[1024];

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    int sendSz;
    int argc    = 0;
    char** argv = 0;

    ((func_args*)args)->return_code = -1; /* error state */
    argc = ((func_args*)args)->argc;
    argv = ((func_args*)args)->argv;

    if (argc >= 2) {
        fin  = fopen(argv[1], "r"); 
        inCreated = 1;
    }
    if (argc >= 3) {
        fout = fopen(argv[2], "w");
        outCreated = 1;
    }

    if (!fin)  err_sys("can't open input file");
    if (!fout) err_sys("can't open output file");

    tcp_connect(&sockfd, yasslIP, yasslPort);

#if defined(CYASSL_DTLS)
    method  = DTLSv1_client_method();
#elif  !defined(NO_TLS)
    method = TLSv1_client_method();
#else
    method = SSLv3_client_method();
#endif
    ctx    = SSL_CTX_new(method);

#ifndef NO_FILESYSTEM
    if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
        err_sys("can't load ca file");
    #ifdef HAVE_ECC
        if (SSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file");
    #endif
#else
    load_buffer(ctx, caCert, CYASSL_CA);
#endif

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
    ssl = SSL_new(ctx);

    SSL_set_fd(ssl, sockfd);
#if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER)
    /* let echoserver bind first, TODO: add Windows signal like pthreads does */
    Sleep(100);
#endif
    if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");

    while (fgets(send, sizeof(send), fin)) {

        sendSz = (int)strlen(send) + 1;

        if (SSL_write(ssl, send, sendSz) != sendSz)
            err_sys("SSL_write failed");

        if (strncmp(send, "quit", 4) == 0) {
            fputs("sending server shutdown command: quit!\n", fout);
            break;
        }

        if (strncmp(send, "break", 4) == 0) {
            fputs("sending server session close: break!\n", fout);
            break;
        }

        while (sendSz) {
            int got;
            if ( (got = SSL_read(ssl, reply, sizeof(reply))) > 0) {
                fputs(reply, fout);
                sendSz -= got;
            }
            else
                break;
        }
    }

#ifdef CYASSL_DTLS
    strncpy(send, "break", 6);
    sendSz = (int)strlen(send);
    /* try to tell server done */
    SSL_write(ssl, send, sendSz);
#else
    SSL_shutdown(ssl);
#endif

    SSL_free(ssl);
    SSL_CTX_free(ctx);

    fflush(fout);
    if (inCreated)  fclose(fin);
    if (outCreated) fclose(fout);

    CloseSocket(sockfd);
    ((func_args*)args)->return_code = 0; 
}
示例#10
0
void SSLHandler::init(const SecurityProperties& securityProperties) {
	if(isSSLEnabled)
	{
		this->securityProperties = securityProperties;
		if(securityProperties.alpnEnabled && securityProperties.alpnProtoList.size()>0)
		{
			for(int pn=0;pn<(int)securityProperties.alpnProtoList.size();pn++)
			{
				string protoname = securityProperties.alpnProtoList.at(pn);
				vector<unsigned char> res = vector<unsigned char>(1 + protoname.length());
				unsigned char* p = res.data();
				*p++ = protoname.length();
				memcpy(p, protoname.c_str(), protoname.length());
				advertisedProtos.push_back(res);
			}
		}

		string sslConfsettings = "Server setup with SSL enabled, CERTFILE = ";
		sslConfsettings.append(securityProperties.cert_file);
		sslConfsettings.append(", KEYFILE = ");
		sslConfsettings.append(securityProperties.key_file);
		sslConfsettings.append(", PASSWORD = "******", DHFILE = ");
		sslConfsettings.append(securityProperties.dh_file);
		sslConfsettings.append(", CA_LIST = ");
		sslConfsettings.append(securityProperties.ca_list);
		sslConfsettings.append(", ISDH_PARAMS = ");
		//sslConfsettings.append(CastUtil::lexical_cast<string>(securityProperties.isDHParams));
		//sslConfsettings.append(", CLIENT_SEC_LEVEL = ");
		//sslConfsettings.append(CastUtil::lexical_cast<string>(securityProperties.client_auth));
		logger << sslConfsettings << endl;

		/* Build our SSL context*/
		ctx = SSLCommon::initialize_ctx(true);

		pass = (char*)securityProperties.sec_password.c_str();
		SSL_CTX_set_default_passwd_cb(ctx, SSLHandler::password_cb);

		SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
							SSL_OP_NO_COMPRESSION | SSL_OP_SINGLE_DH_USE |
							SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
							SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_TICKET |
							SSL_OP_CIPHER_SERVER_PREFERENCE);
		SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
		SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);

		if(securityProperties.isDHParams)
		{
			SSLCommon::load_dh_params(ctx,(char*)securityProperties.dh_file.c_str());
		}
		else
		{
			SSLCommon::load_ecdh_params(ctx);
		}

		const unsigned char sid_ctx[] = "Ffead";
		SSL_CTX_set_session_id_context(ctx, sid_ctx, sizeof(sid_ctx) - 1);
		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
		/*SSL_CTX_set_session_id_context(ctx,
				(const unsigned char*)&s_server_session_id_context,
				sizeof s_server_session_id_context);
		 */

		/* Set our cipher list */
		if(SSLCommon::ciphers!=""){
			SSL_CTX_set_cipher_list(ctx, SSLCommon::ciphers.c_str());
		}

		SSLCommon::loadCerts(ctx, (char*)securityProperties.cert_file.c_str(),
				(char*)securityProperties.key_file.c_str(),
				securityProperties.ca_list, true);


		if(securityProperties.client_auth==2)
		{
			/* Set to require peer (client) certificate verification */
			SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
			/* Set the verification depth to 1 */
			#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
            	SSL_CTX_set_verify_depth(ctx,1);
			#endif
		}
		else if(securityProperties.client_auth==1)
		{
			/* Set to require peer (client) certificate verification */
			SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
			/* Set the verification depth to 1 */
			#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
            	SSL_CTX_set_verify_depth(ctx,1);
			#endif
		}
		else
		{
			SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
		}

#if OPENSSL_VERSION_NUMBER >= 0x10002000L
		if(securityProperties.alpnEnabled)
		{
			for (int var = 0; var < (int)advertisedProtos.size(); ++var) {
				SSL_CTX_set_next_protos_advertised_cb(ctx, SSLHandler::next_proto_cb, &(advertisedProtos.at(var)));
			}


			// ALPN selection callback
			SSL_CTX_set_alpn_select_cb(ctx, SSLHandler::alpn_select_proto_cb, NULL);
		}
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
	}
}
示例#11
0
static
int cert_stuff(struct connectdata *conn,
               SSL_CTX* ctx,
               char *cert_file,
               const char *cert_type,
               char *key_file,
               const char *key_type)
{
  struct SessionHandle *data = conn->data;
  int file_type;

  if(cert_file != NULL) {
    SSL *ssl;
    X509 *x509;

    if(data->set.key_passwd) {
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
      /*
       * If password has been given, we store that in the global
       * area (*shudder*) for a while:
       */
      size_t len = strlen(data->set.key_passwd);
      if(len < sizeof(global_passwd))
        memcpy(global_passwd, data->set.key_passwd, len+1);
#else
      /*
       * We set the password in the callback userdata
       */
      SSL_CTX_set_default_passwd_cb_userdata(ctx,
                                             data->set.key_passwd);
#endif
      /* Set passwd callback: */
      SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
    }

    file_type = do_file_type(cert_type);

    switch(file_type) {
    case SSL_FILETYPE_PEM:
      /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
      if(SSL_CTX_use_certificate_chain_file(ctx,
                                            cert_file) != 1) {
        failf(data, "unable to set certificate file (wrong password?)");
        return 0;
      }
      break;

    case SSL_FILETYPE_ASN1:
      /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
         we use the case above for PEM so this can only be performed with
         ASN1 files. */
      if(SSL_CTX_use_certificate_file(ctx,
                                      cert_file,
                                      file_type) != 1) {
        failf(data, "unable to set certificate file (wrong password?)");
        return 0;
      }
      break;
    case SSL_FILETYPE_ENGINE:
      failf(data, "file type ENG for certificate not implemented");
      return 0;

    default:
      failf(data, "not supported file type '%s' for certificate", cert_type);
      return 0;
    }

    file_type = do_file_type(key_type);

    switch(file_type) {
    case SSL_FILETYPE_PEM:
      if(key_file == NULL)
        /* cert & key can only be in PEM case in the same file */
        key_file=cert_file;
    case SSL_FILETYPE_ASN1:
      if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
        failf(data, "unable to set private key file: '%s' type %s\n",
              key_file, key_type?key_type:"PEM");
        return 0;
      }
      break;
    case SSL_FILETYPE_ENGINE:
#ifdef HAVE_OPENSSL_ENGINE_H
      {                         /* XXXX still needs some work */
        EVP_PKEY *priv_key = NULL;
        if(conn && conn->data && conn->data->engine) {
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
          UI_METHOD *ui_method = UI_OpenSSL();
#endif
          if(!key_file || !key_file[0]) {
            failf(data, "no key set to load from crypto engine\n");
            return 0;
          }
          /* the typecast below was added to please mingw32 */
          priv_key = (EVP_PKEY *)
            ENGINE_load_private_key(conn->data->engine,key_file,
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
                                    ui_method,
#endif
                                    data->set.key_passwd);
          if(!priv_key) {
            failf(data, "failed to load private key from crypto engine\n");
            return 0;
          }
          if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
            failf(data, "unable to set private key\n");
            EVP_PKEY_free(priv_key);
            return 0;
          }
          EVP_PKEY_free(priv_key);  /* we don't need the handle any more... */
        }
        else {
          failf(data, "crypto engine not set, can't load private key\n");
          return 0;
        }
      }
      break;
#else
      failf(data, "file type ENG for private key not supported\n");
      return 0;
#endif
    default:
      failf(data, "not supported file type for private key\n");
      return 0;
    }

    ssl=SSL_new(ctx);
    x509=SSL_get_certificate(ssl);

    /* This version was provided by Evan Jordan and is supposed to not
       leak memory as the previous version: */
    if(x509 != NULL) {
      EVP_PKEY *pktmp = X509_get_pubkey(x509);
      EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));
      EVP_PKEY_free(pktmp);
    }

    SSL_free(ssl);

    /* If we are using DSA, we can copy the parameters from
     * the private key */


    /* Now we know that a key and cert have been set against
     * the SSL context */
    if(!SSL_CTX_check_private_key(ctx)) {
      failf(data, "Private key does not match the certificate public key");
      return(0);
    }
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
    /* erase it now */
    memset(global_passwd, 0, sizeof(global_passwd));
#endif
  }
  return(1);
}
示例#12
0
bool
SSLClient::sslSetupCTX(std::string &keyspec, std::string &caspec)
{
    GNASH_REPORT_FUNCTION;
//     SSL_METHOD *meth;
    int ret;
    string keyfile;
    string cafile;

#if 1
    if (keyspec.find('/', 0) != string::npos) {
	keyfile = keyspec;
    } else {
	keyfile = _rootpath;
	keyfile += "/";
	keyfile += keyspec;
    }
    
    
    if (caspec.find('/', 0) != string::npos) {
	cafile = caspec;
    } else {
	cafile = _rootpath;
	cafile += "/";
	cafile += caspec;
    }
#else
    keyfile = keyspec;
    cafile = caspec;
#endif

    // create the context
    _ctx.reset(SSL_CTX_new( SSLv23_method()));
    
    ERR_clear_error();
    if (!(SSL_CTX_load_verify_locations(_ctx.get(), cafile.c_str(),
					_rootpath.c_str()))) {
	log_error("Can't read CA list from \"%s\"!", cafile);
 	log_error("Error was: \"%s\"!", ERR_reason_error_string(ERR_get_error()));
	return false;
    } else {
	log_debug("Read CA list from \"%s\"", cafile);
    }
    
    // Load our keys and certificates
    ERR_clear_error();
    if ((ret = SSL_CTX_use_certificate_chain_file(_ctx.get(), keyfile.c_str())) != 1) {
	log_error("Can't read certificate file \"%s\"!", keyfile);
	return false;
    } else {
	log_debug("Read certificate file \"%s\".", keyfile);
    }

    // Set the password as a callback, otherwise we get prompted for it
    SSL_CTX_set_default_passwd_cb(_ctx.get(), password_cb);

    // Add the first private key in the keyfile to the context.
    ERR_clear_error();
    if((ret = SSL_CTX_use_PrivateKey_file(_ctx.get(), keyfile.c_str(),
					  SSL_FILETYPE_PEM)) != 1) {
	log_error("Can't read CERT file \"%s\"!", keyfile);
 	log_error("Error was: \"%s\"!", ERR_reason_error_string(ERR_get_error()));
	return false;
    } else {
	log_debug("Read key file \"%s\".", keyfile);
    }

     SSL_CTX_set_verify(_ctx.get(), SSL_VERIFY_PEER, verify_callback);

#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
    SSL_CTX_set_verify_depth(_ctx.get(), 4);
#endif

    return true;
}
示例#13
0
static
int tls_init_context(tls_t *tls, tls_issues_t const *ti)
{
  int verify;
  static int random_loaded;

  ONCE_INIT(tls_init_once);

  if (!random_loaded) {
    random_loaded = 1;

    if (ti->randFile &&
	!RAND_load_file(ti->randFile, 1024 * 1024)) {
      if (ti->configured > 1) {
	SU_DEBUG_3(("%s: cannot open randFile %s\n",
		   "tls_init_context", ti->randFile));
	tls_log_errors(3, "tls_init_context", 0);
      }
      /* errno = EIO; */
      /* return -1; */
    }
  }

#if HAVE_SIGPIPE
  /* Avoid possible SIGPIPE when sending close_notify */
  signal(SIGPIPE, SIG_IGN);
#endif

  if (tls->ctx == NULL)
    if (!(tls->ctx = SSL_CTX_new((SSL_METHOD*)SSLv23_method()))) {
      tls_log_errors(1, "SSL_CTX_new() failed", 0);
      errno = EIO;
      return -1;
    }
  if (!(ti->version & TPTLS_VERSION_SSLv2))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_SSLv2);
  if (!(ti->version & TPTLS_VERSION_SSLv3))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_SSLv3);
  if (!(ti->version & TPTLS_VERSION_TLSv1))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_TLSv1);
  if (!(ti->version & TPTLS_VERSION_TLSv1_1))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_TLSv1_1);
  if (!(ti->version & TPTLS_VERSION_TLSv1_2))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_TLSv1_2);
  SSL_CTX_sess_set_remove_cb(tls->ctx, NULL);
  SSL_CTX_set_timeout(tls->ctx, ti->timeout);

  /* Set callback if we have a passphrase */
  if (ti->passphrase != NULL) {
    SSL_CTX_set_default_passwd_cb(tls->ctx, passwd_cb);
    SSL_CTX_set_default_passwd_cb_userdata(tls->ctx, (void *)ti);
  }

  if (!SSL_CTX_use_certificate_file(tls->ctx,
				    ti->cert,
				    SSL_FILETYPE_PEM)) {
    if (ti->configured > 0) {
      SU_DEBUG_1(("%s: invalid local certificate: %s\n",
		 "tls_init_context", ti->cert));
      tls_log_errors(3, "tls_init_context", 0);
#if require_client_certificate
      errno = EIO;
      return -1;
#endif
    }
  }

  if (!SSL_CTX_use_PrivateKey_file(tls->ctx,
                                   ti->key,
                                   SSL_FILETYPE_PEM)) {
    if (ti->configured > 0) {
      SU_DEBUG_1(("%s: invalid private key: %s\n",
		 "tls_init_context", ti->key));
      tls_log_errors(3, "tls_init_context(key)", 0);
#if require_client_certificate
      errno = EIO;
      return -1;
#endif
    }
  }

  if (!SSL_CTX_check_private_key(tls->ctx)) {
    if (ti->configured > 0) {
      SU_DEBUG_1(("%s: private key does not match the certificate public key\n",
		  "tls_init_context"));
    }
#if require_client_certificate
    errno = EIO;
    return -1;
#endif
  }

  if (!SSL_CTX_load_verify_locations(tls->ctx,
                                     ti->CAfile,
                                     ti->CApath)) {
    SU_DEBUG_1(("%s: error loading CA list: %s\n",
		 "tls_init_context", ti->CAfile));
    if (ti->configured > 0)
      tls_log_errors(3, "tls_init_context(CA)", 0);
    errno = EIO;
    return -1;
  }

  /* corresponds to (enum tport_tls_verify_policy) */
  tls->verify_incoming = (ti->policy & 0x1) ? 1 : 0;
  tls->verify_outgoing = (ti->policy & 0x2) ? 1 : 0;
  tls->verify_subj_in  = (ti->policy & 0x4) ? tls->verify_incoming : 0;
  tls->verify_subj_out = (ti->policy & 0x8) ? tls->verify_outgoing : 0;
  tls->verify_date     = (ti->verify_date)  ? 1 : 0;

  if (tls->verify_incoming)
    verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
  else
    verify = SSL_VERIFY_NONE;

  SSL_CTX_set_verify_depth(tls->ctx, ti->verify_depth);
  SSL_CTX_set_verify(tls->ctx, verify, tls_verify_cb);

  if (tls_init_ecdh_curve(tls) == 0) {
    SU_DEBUG_3(("%s\n", "tls: initialized ECDH"));
  } else {
    SU_DEBUG_3(("%s\n", "tls: failed to initialize ECDH"));
  }

  if (!SSL_CTX_set_cipher_list(tls->ctx, ti->ciphers)) {
    SU_DEBUG_1(("%s: error setting cipher list\n", "tls_init_context"));
    tls_log_errors(3, "tls_init_context", 0);
    errno = EIO;
    return -1;
  }

  return 0;
}
示例#14
0
static int lua_co_tcp(lua_State *L)
{
    cosocket_t *c*k = (cosocket_t *) lua_newuserdata(L, sizeof(cosocket_t));

    if(!c*k) {
        lua_pushnil(L);
        lua_pushstring(L, "stack error!");
        return 2;
    }

    bzero(c*k, sizeof(cosocket_t));

    if(lua_isstring(L, 1) && lua_isstring(L, 2)) {
        if(c*k->ctx) {
            SSL_CTX_free(c*k->ctx);
        }

        c*k->ctx = SSL_CTX_new(SSLv23_client_method());

        if(c*k->ctx == NULL) {
            lua_pushnil(c*k->L);
            lua_pushstring(c*k->L, "SSL_CTX_new Error");
            return 2;
        }

        if(lua_isstring(L, 3)) {
            if(c*k->ssl_pw) {
                free(c*k->ssl_pw);
            }

            size_t len = 0;
            const char *p1 = lua_tolstring(L, 3, &len);
            c*k->ssl_pw = malloc(len + 1);

            if(c*k->ssl_pw) {
                memcpy(c*k->ssl_pw, p1, len);
                c*k->ssl_pw[len] = '\0';
                SSL_CTX_set_default_passwd_cb_userdata(c*k->ctx, (void *)c*k->ssl_pw);
                SSL_CTX_set_default_passwd_cb(c*k->ctx, ssl_password_cb);
            }

            int l = snprintf(temp_buf, 4096, "%s:%s:%s", lua_tostring(L, 1), lua_tostring(L, 2), p1);
            c*k->ssl_sign = fnv1a_32(temp_buf, l);

        } else {
            int l = snprintf(temp_buf, 4096, "%s:%s:", lua_tostring(L, 1), lua_tostring(L, 2));
            c*k->ssl_sign = fnv1a_32(temp_buf, l);
        }

        if(SSL_CTX_use_certificate_file(c*k->ctx, lua_tostring(L, 1), SSL_FILETYPE_PEM) != 1) {
            SSL_CTX_free(c*k->ctx);
            c*k->ctx = NULL;
            lua_pushnil(c*k->L);
            lua_pushstring(c*k->L, "SSL_CTX_use_certificate_file Error");
            return 2;
        }

        if(SSL_CTX_use_PrivateKey_file(c*k->ctx, lua_tostring(L, 2), SSL_FILETYPE_PEM) != 1) {
            SSL_CTX_free(c*k->ctx);
            c*k->ctx = NULL;
            lua_pushnil(c*k->L);
            lua_pushstring(c*k->L, "SSL_CTX_use_PrivateKey_file Error");
            return 2;
        }

        if(!SSL_CTX_check_private_key(c*k->ctx)) {
            SSL_CTX_free(c*k->ctx);
            c*k->ctx = NULL;
            lua_pushnil(c*k->L);
            lua_pushstring(c*k->L, "SSL_CTX_check_private_key Error");
            return 2;
        }

        c*k->use_ssl = 1;

    } else if(lua_isboolean(L, 1) && lua_toboolean(L, 1) == 1) {
        c*k->use_ssl = 1;

    } else {
        c*k->use_ssl = 0;
    }

    c*k->L = L;
    c*k->fd = -1;
    c*k->timeout = 30000;
    /*
    if(luaL_newmetatable(L, "cosocket")) {
        //luaL_checkstack(L, 1, "not enough stack to register connection MT");
        lua_pushvalue(L, lua_upvalueindex(1));
        setfuncs(L, M, 1);
        lua_pushvalue(L, -1);
        lua_setfield(L, -2, "__index");
    }*/
    luaL_getmetatable(L, "cosocket:tcp");
    lua_setmetatable(L, -2);

    return 1;
}
void context_init(void) { /* init SSL */
    int i;

#if SSLEAY_VERSION_NUMBER >= 0x00907000L
    /* Load all bundled ENGINEs into memory and make them visible */
    ENGINE_load_builtin_engines();
    /* Register all of them for every algorithm they collectively implement */
    ENGINE_register_all_complete();
#endif
    if(!init_prng())
        log(LOG_INFO, "PRNG seeded successfully");
    SSLeay_add_ssl_algorithms();
    SSL_load_error_strings();
    if(options.option.client) {
        ctx=SSL_CTX_new(SSLv3_client_method());
    } else { /* Server mode */
        ctx=SSL_CTX_new(SSLv23_server_method());
#ifndef NO_RSA
        SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
#endif /* NO_RSA */
        if(init_dh())
            log(LOG_WARNING, "Diffie-Hellman initialization failed");
    }
    if(options.ssl_options) {
        log(LOG_DEBUG, "Configuration SSL options: 0x%08lX",
            options.ssl_options);
        log(LOG_DEBUG, "SSL options set: 0x%08lX", 
            SSL_CTX_set_options(ctx, options.ssl_options));
    }
#if SSLEAY_VERSION_NUMBER >= 0x00906000L
    SSL_CTX_set_mode(ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif /* OpenSSL-0.9.6 */

    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
    SSL_CTX_set_timeout(ctx, options.session_timeout);
    if(options.option.cert) {
        if(!SSL_CTX_use_certificate_chain_file(ctx, options.cert)) {
            log(LOG_ERR, "Error reading certificate file: %s", options.cert);
            sslerror("SSL_CTX_use_certificate_chain_file");
            exit(1);
        }
        log(LOG_DEBUG, "Certificate: %s", options.cert);
        log(LOG_DEBUG, "Key file: %s", options.key);
#ifdef USE_WIN32
        SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
#endif
        for(i=0; i<3; i++) {
#ifdef NO_RSA
            if(SSL_CTX_use_PrivateKey_file(ctx, options.key,
                    SSL_FILETYPE_PEM))
#else /* NO_RSA */
            if(SSL_CTX_use_RSAPrivateKey_file(ctx, options.key,
                    SSL_FILETYPE_PEM))
#endif /* NO_RSA */
                break;
            if(i<2 && ERR_GET_REASON(ERR_peek_error())==EVP_R_BAD_DECRYPT) {
                sslerror_stack(); /* dump the error stack */
                log(LOG_ERR, "Wrong pass phrase: retrying");
                continue;
            }
#ifdef NO_RSA
            sslerror("SSL_CTX_use_PrivateKey_file");
#else /* NO_RSA */
            sslerror("SSL_CTX_use_RSAPrivateKey_file");
#endif /* NO_RSA */
            exit(1);
        }
        if(!SSL_CTX_check_private_key(ctx)) {
            sslerror("Private key does not match the certificate");
            exit(1);
        }
    }

    verify_init(); /* Initialize certificate verification */

    SSL_CTX_set_info_callback(ctx, info_callback);

    if(options.cipher_list) {
        if (!SSL_CTX_set_cipher_list(ctx, options.cipher_list)) {
            sslerror("SSL_CTX_set_cipher_list");
            exit(1);
        }
    }
}
void OpenSSLSession::Start()
{
	if(m_bStarted)
	{
		return;
	}

	SSL_load_error_strings();
	SSL_library_init();	
	ERR_load_BIO_strings();
	//OpenSSL_add_all_algorithms();

	//SSL protocol method
	const SSL_METHOD *meth = SSLv3_method();
	//Connection context using SSL protocol method
	m_ConnectionCtx = SSL_CTX_new(meth);
	if(!m_ConnectionCtx)
	{		
		ERR_print_errors_fp(stderr);
		return;
	}	

	if(SSL_CTX_set_cipher_list(m_ConnectionCtx, (char*)m_CipherList.c_str()) == 0)
	{
		ERR_print_errors_fp(stderr);
	}

	//Send SARA certificate to remote location
	if(m_bLocalVerification)
	{
		/* Load our keys and certificates*/
		//1. Load the certificates in to "m_ConnectionCtx"
		if (!SSL_CTX_use_certificate_file(m_ConnectionCtx, m_SARACertificate.c_str(), SSL_FILETYPE_PEM))
		{	
			ERR_print_errors_fp(stderr);
			return;
		}

		//2. Set the default password callback when loading/storing a PEM certificate with encryption
		SSL_CTX_set_default_passwd_cb(m_ConnectionCtx, GetPassword_CB);

		//3. Add the first private key found in file "m_SARACertificate" to "m_ConnectionCtx"
		if (!SSL_CTX_use_PrivateKey_file(m_ConnectionCtx, m_SARAPvtKeyFile.c_str(), SSL_FILETYPE_PEM))
		{			
			ERR_print_errors_fp(stderr);
			return;
		}

		//3_A. Check the private key is correct
		if(SSL_CTX_check_private_key(m_ConnectionCtx) == -1)
		{
			ERR_print_errors_fp(stderr);
			return;
		}
	}

	//Evaluation of remote certificate by SARA
	if(m_bRemoteVerification)
    {
		//4. Specify the location ("m_TrustedCACertificate") where CA certificates for verification purposes are located
		//   Used to authenticate the host to which we are connected. Loading all the CAs that we trust.
		if(!(SSL_CTX_load_verify_locations(m_ConnectionCtx, 0, m_TrustedCACertificate.c_str())))
		{			
			ERR_print_errors_fp(stderr);
			return;
		}

#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
		SSL_CTX_set_verify_depth(m_ConnectionCtx,1);
#else
		SSL_CTX_set_verify_depth(m_ConnectionCtx, m_iDepth);
#endif
		//5. Set verification for host.
		SSL_CTX_set_verify(m_ConnectionCtx, SSL_VERIFY_PEER, OpenSSLSession::SSL_VerifyCallback);
	}

	m_bStarted = true;
}
示例#17
0
static int
build_ssl_ctx(void)
{
	SSL_DATA *ssl;

	/* Library initialization */
	SSL_library_init();

	SSL_load_error_strings();
	bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

	if (!check_data->ssl)
		ssl = (SSL_DATA *) MALLOC(sizeof (ssl_data));
	else
		ssl = check_data->ssl;

	/* Initialize SSL context for SSL v2/3 */
	ssl->meth = (SSL_METHOD *) SSLv23_method();
	ssl->ctx = SSL_CTX_new(ssl->meth);

	/* return for autogen context */
	if (!check_data->ssl) {
		check_data->ssl = ssl;
		goto end;
	}

	/* Load our keys and certificates */
	if (check_data->ssl->keyfile)
		if (!
		    (SSL_CTX_use_certificate_chain_file
		     (ssl->ctx, check_data->ssl->keyfile))) {
			log_message(LOG_INFO,
			       "SSL error : Cant load certificate file...");
			return 0;
		}

	/* Handle password callback using userdata ssl */
	if (check_data->ssl->password) {
		SSL_CTX_set_default_passwd_cb_userdata(ssl->ctx,
						       check_data->ssl);
		SSL_CTX_set_default_passwd_cb(ssl->ctx, password_cb);
	}

	if (check_data->ssl->keyfile)
		if (!
		    (SSL_CTX_use_PrivateKey_file
		     (ssl->ctx, check_data->ssl->keyfile, SSL_FILETYPE_PEM))) {
			log_message(LOG_INFO, "SSL error : Cant load key file...");
			return 0;
		}

	/* Load the CAs we trust */
	if (check_data->ssl->cafile)
		if (!
		    (SSL_CTX_load_verify_locations
		     (ssl->ctx, check_data->ssl->cafile, 0))) {
			log_message(LOG_INFO, "SSL error : Cant load CA file...");
			return 0;
		}

      end:
#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
	SSL_CTX_set_verify_depth(ssl->ctx, 1);
#endif

	return 1;
}
示例#18
0
int
mowgli_vio_openssl_default_listen(mowgli_vio_t *vio, int backlog)
{
	return_val_if_fail(vio, -255);

	mowgli_ssl_connection_t *connection = vio->privdata;
	const SSL_METHOD *method;
	const int fd = mowgli_vio_getfd(vio);

	vio->error.op = MOWGLI_VIO_ERR_OP_LISTEN;

	switch (connection->settings.ssl_version)
	{
	case MOWGLI_VIO_SSLFLAGS_SSLV2:
		method = SSLv23_server_method();
		break;
	case MOWGLI_VIO_SSLFLAGS_SSLV3:
		method = SSLv3_server_method();
		break;
	case MOWGLI_VIO_SSLFLAGS_TLSV10:
	case MOWGLI_VIO_SSLFLAGS_TLSV11:
	case MOWGLI_VIO_SSLFLAGS_TLSV12:
		method = TLSv1_server_method();
		break;
	default:

		/* Compat method */
		method = SSLv23_server_method();
	}

	connection->ssl_context = SSL_CTX_new((SSL_METHOD *) method);

	if (connection->ssl_context == NULL)
		return mowgli_vio_err_sslerrcode(vio, ERR_get_error());

	connection->ssl_handle = SSL_new(connection->ssl_context);

	if (connection->ssl_handle == NULL)
		return mowgli_vio_err_sslerrcode(vio, ERR_get_error());

	SSL_set_accept_state(connection->ssl_handle);
	SSL_CTX_set_options(connection->ssl_context, SSL_OP_SINGLE_DH_USE);

	if (connection->settings.password_func)
	{
		SSL_CTX_set_default_passwd_cb(connection->ssl_context, connection->settings.password_func);
		SSL_CTX_set_default_passwd_cb_userdata(connection->ssl_context, vio->userdata);
	}

	if (SSL_CTX_use_certificate_file(connection->ssl_context, connection->settings.cert_path, SSL_FILETYPE_PEM) != 1)
		return mowgli_vio_err_sslerrcode(vio, ERR_get_error());

	if (SSL_CTX_use_PrivateKey_file(connection->ssl_context, connection->settings.privatekey_path, SSL_FILETYPE_PEM) != 1)
		return mowgli_vio_err_sslerrcode(vio, ERR_get_error());

	if (listen(fd, backlog) != 0)
		return mowgli_vio_err_errcode(vio, strerror, errno);

	if (!SSL_set_fd(connection->ssl_handle, fd))
		return mowgli_vio_err_sslerrcode(vio, ERR_get_error());

	mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISSERVER, true);
	vio->error.op = MOWGLI_VIO_ERR_OP_NONE;

	return 0;
}
示例#19
0
void echoclient_test(void* args)
{
    SOCKET_T sockfd = 0;

    FILE* fin   = stdin  ;
    FILE* fout = stdout;

    int inCreated  = 0;
    int outCreated = 0;

    char msg[1024];
    char reply[1024+1];

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    int doDTLS = 0;
    int doPSK = 0;
    int sendSz;
    int argc    = 0;
    char** argv = 0;
    word16 port = yasslPort;

    ((func_args*)args)->return_code = -1; /* error state */
    
#ifndef WOLFSSL_MDK_SHELL
    argc = ((func_args*)args)->argc;
    argv = ((func_args*)args)->argv;
#endif

    if (argc >= 2) {
        fin  = fopen(argv[1], "r"); 
        inCreated = 1;
    }
    if (argc >= 3) {
        fout = fopen(argv[2], "w");
        outCreated = 1;
    }

    if (!fin)  err_sys("can't open input file");
    if (!fout) err_sys("can't open output file");

#ifdef CYASSL_DTLS
    doDTLS  = 1;
#endif

#ifdef CYASSL_LEANPSK 
    doPSK = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    doPSK = 1;
#endif

#if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_SHELL)
    port = ((func_args*)args)->signal->port;
#endif

#if defined(CYASSL_DTLS)
    method  = DTLSv1_2_client_method();
#elif  !defined(NO_TLS)
    method = CyaSSLv23_client_method();
#elif defined(WOLFSSL_ALLOW_SSLV3)
    method = SSLv3_client_method();
#else
    #error "no valid client method type"
#endif
    ctx    = SSL_CTX_new(method);

#ifndef NO_FILESYSTEM
    #ifndef NO_RSA
    if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
        err_sys("can't load ca file, Please run from wolfSSL home dir");
    #endif
    #ifdef HAVE_ECC
        if (SSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
    #endif
#elif !defined(NO_CERTS)
    if (!doPSK)
        load_buffer(ctx, caCert, CYASSL_CA);
#endif

#if defined(CYASSL_SNIFFER)
    /* don't use EDH, can't sniff tmp keys */
    SSL_CTX_set_cipher_list(ctx, "AES256-SHA");
#endif
    if (doPSK) {
#ifndef NO_PSK
        const char *defaultCipherList;

        CyaSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
        #ifdef HAVE_NULL_CIPHER
            defaultCipherList = "PSK-NULL-SHA256";
        #elif defined(HAVE_AESGCM) && !defined(NO_DH)
            defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
        #else
            defaultCipherList = "PSK-AES128-CBC-SHA256";
        #endif
        if (CyaSSL_CTX_set_cipher_list(ctx,defaultCipherList) !=SSL_SUCCESS)
            err_sys("client can't set cipher list 2");
#endif
    }

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    #if defined(WOLFSSL_MDK_ARM)
    CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    #endif

    ssl = SSL_new(ctx);
    tcp_connect(&sockfd, yasslIP, port, doDTLS, ssl);
        
    SSL_set_fd(ssl, sockfd);
#if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER)
    /* let echoserver bind first, TODO: add Windows signal like pthreads does */
    Sleep(100);
#endif

    if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");

    while (fgets(msg, sizeof(msg), fin) != 0) {
     
        sendSz = (int)strlen(msg);

        if (SSL_write(ssl, msg, sendSz) != sendSz)
            err_sys("SSL_write failed");

        if (strncmp(msg, "quit", 4) == 0) {
            fputs("sending server shutdown command: quit!\n", fout);
            break;
        }

        if (strncmp(msg, "break", 5) == 0) {
            fputs("sending server session close: break!\n", fout);
            break;
        }

        #ifndef WOLFSSL_MDK_SHELL
        while (sendSz) {
            int got;
            if ( (got = SSL_read(ssl, reply, sizeof(reply)-1)) > 0) {
                reply[got] = 0;
                fputs(reply, fout);
                fflush(fout) ;
                sendSz -= got;
            }
            else
                break;
        }
        #else
        {
            int got;
            if ( (got = SSL_read(ssl, reply, sizeof(reply)-1)) > 0) {
                reply[got] = 0;
                fputs(reply, fout);
                fflush(fout) ;
                sendSz -= got;
            }
        }
        #endif
    }


#ifdef CYASSL_DTLS
    strncpy(msg, "break", 6);
    sendSz = (int)strlen(msg);
    /* try to tell server done */
    SSL_write(ssl, msg, sendSz);
#else
    SSL_shutdown(ssl);
#endif

    SSL_free(ssl);
    SSL_CTX_free(ctx);

    fflush(fout);
    if (inCreated)  fclose(fin);
    if (outCreated) fclose(fout);

    CloseSocket(sockfd);
    ((func_args*)args)->return_code = 0; 
}
示例#20
0
static int load_certificate(struct openconnect_info *vpninfo)
{
	if (!strncmp(vpninfo->sslkey, "pkcs11:", 7) ||
	    !strncmp(vpninfo->cert, "pkcs11:", 7)) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("This binary built without PKCS#11 support\n"));
		return -EINVAL;
	}

	vpn_progress(vpninfo, PRG_TRACE,
		     _("Using certificate file %s\n"), vpninfo->cert);

	if (strncmp(vpninfo->cert, "keystore:", 9) &&
	    (vpninfo->cert_type == CERT_TYPE_PKCS12 ||
	     vpninfo->cert_type == CERT_TYPE_UNKNOWN)) {
		FILE *f;
		PKCS12 *p12;

		f = fopen(vpninfo->cert, "r");
		if (!f) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to open certificate file %s: %s\n"),
				     vpninfo->cert, strerror(errno));
			return -ENOENT;
		}
		p12 = d2i_PKCS12_fp(f, NULL);
		fclose(f);
		if (p12)
			return load_pkcs12_certificate(vpninfo, p12);

		/* Not PKCS#12 */
		if (vpninfo->cert_type == CERT_TYPE_PKCS12) {
			vpn_progress(vpninfo, PRG_ERR, _("Read PKCS#12 failed\n"));
			openconnect_report_ssl_errors(vpninfo);
			return -EINVAL;
		}
		/* Clear error and fall through to see if it's a PEM file... */
		ERR_clear_error();
	}

	/* It's PEM or TPM now, and either way we need to load the plain cert: */
#ifdef ANDROID_KEYSTORE
	if (!strncmp(vpninfo->cert, "keystore:", 9)) {
		BIO *b = BIO_from_keystore(vpninfo, vpninfo->cert);
		if (!b)
			return -EINVAL;
		vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, pem_pw_cb, vpninfo);
		BIO_free(b);
		if (!vpninfo->cert_x509) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to load X509 certificate from keystore\n"));
			openconnect_report_ssl_errors(vpninfo);
			return -EINVAL;
		}
		if (!SSL_CTX_use_certificate(vpninfo->https_ctx, vpninfo->cert_x509)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to use X509 certificate from keystore\n"));
			openconnect_report_ssl_errors(vpninfo);
			X509_free(vpninfo->cert_x509);
			vpninfo->cert_x509 = NULL;
			return -EINVAL;
		}
	} else
#endif /* ANDROID_KEYSTORE */
	{
		if (!SSL_CTX_use_certificate_chain_file(vpninfo->https_ctx,
							vpninfo->cert)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Loading certificate failed\n"));
			openconnect_report_ssl_errors(vpninfo);
			return -EINVAL;
		}

		/* Ew, we can't get it back from the OpenSSL CTX in any sane fashion */
		reload_pem_cert(vpninfo);
	}

#ifdef ANDROID_KEYSTORE
	if (!strncmp(vpninfo->sslkey, "keystore:", 9)) {
		EVP_PKEY *key;
		BIO *b;

	again_android:
		b = BIO_from_keystore(vpninfo, vpninfo->sslkey);
		if (!b)
			return -EINVAL;
		key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, vpninfo);
		BIO_free(b);
		if (!key) {
			if (is_pem_password_error(vpninfo))
				goto again_android;
			return -EINVAL;
		}
		if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to use private key from keystore\n"));
			EVP_PKEY_free(key);
			X509_free(vpninfo->cert_x509);
			vpninfo->cert_x509 = NULL;
			return -EINVAL;
		}
		return 0;
	}
#endif /* ANDROID_KEYSTORE */

	if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
		FILE *f = fopen(vpninfo->sslkey, "r");
		char buf[256];

		if (!f) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to open private key file %s: %s\n"),
				     vpninfo->cert, strerror(errno));
			return -ENOENT;
		}

		buf[255] = 0;
		while (fgets(buf, 255, f)) {
			if (!strcmp(buf, "-----BEGIN TSS KEY BLOB-----\n")) {
				vpninfo->cert_type = CERT_TYPE_TPM;
				break;
			} else if (!strcmp(buf, "-----BEGIN RSA PRIVATE KEY-----\n") ||
				   !strcmp(buf, "-----BEGIN DSA PRIVATE KEY-----\n") ||
				   !strcmp(buf, "-----BEGIN ENCRYPTED PRIVATE KEY-----\n")) {
				vpninfo->cert_type = CERT_TYPE_PEM;
				break;
			}
		}
		fclose(f);
		if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to identify private key type in '%s'\n"),
				     vpninfo->sslkey);
			return -EINVAL;
		}
	}

	if (vpninfo->cert_type == CERT_TYPE_TPM)
		return load_tpm_certificate(vpninfo);

	/* Standard PEM certificate */
	SSL_CTX_set_default_passwd_cb(vpninfo->https_ctx, pem_pw_cb);
	SSL_CTX_set_default_passwd_cb_userdata(vpninfo->https_ctx, vpninfo);
 again:
	if (!SSL_CTX_use_RSAPrivateKey_file(vpninfo->https_ctx, vpninfo->sslkey,
					    SSL_FILETYPE_PEM)) {
		if (is_pem_password_error(vpninfo))
			goto again;
		return -EINVAL;
	}
	return 0;
}
示例#21
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = 0;
    SOCKET_T clientfd = 0;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    char   msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    idx;
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    word16 port = yasslPort;
    int    usePsk = 0;
    int    useAnon = 0;
    int    doDTLS = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    int    pkCallbacks  = 0;
    int    serverReadyFile = 0;
    char*  cipherList = NULL;
    const char* verifyCert = cliCert;
    const char* ourCert    = svrCert;
    const char* ourKey     = svrKey;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;
    (void)pkCallbacks;

#ifdef CYASSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    while ((ch = mygetopt(argc, argv, "?dbstnNufraPp:v:l:A:c:k:S:oO:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_CYASSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'r' :
                serverReadyFile = 1;
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS 
                pkCallbacks = 1;
            #endif
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker(); 
#endif

    switch (version) {
#ifndef NO_OLD_TLS
        case 0:
            method = SSLv3_server_method();
            break;

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif
                
#ifdef CYASSL_DTLS
        case -1:
            method = DTLSv1_server_method();
            break;

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!usePsk && !useAnon) {
        if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " CyaSSL home dir");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                               != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from CyaSSL home dir");
    }
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && !usePsk && !useAnon) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server private key file, check file and run "
                "from CyaSSL home dir");
    }
#endif

    if (usePsk) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
        SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
        if (cipherList == NULL) {
            const char *defaultCipherList;
            #ifdef HAVE_NULL_CIPHER
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

    if (useAnon) {
#ifdef HAVE_ANON
        CyaSSL_CTX_allow_anon_cipher(ctx);
        if (cipherList == NULL) {
            if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("server can't set cipher list 4");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0 && useAnon == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    }
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                           XSTRLEN(sniHostName)) != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL");

#ifdef HAVE_CRL
    CyaSSL_EnableCRL(ssl, 0);
    CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                     CYASSL_CRL_START_MON);
    CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
#ifdef HAVE_OCSP
    if (useOcsp) {
        if (ocspUrl != NULL) {
            CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
            CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
                                                    | CYASSL_OCSP_URL_OVERRIDE);
        }
        else
            CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
    }
#endif
#ifdef HAVE_PK_CALLBACKS
    if (pkCallbacks)
        SetupPkCallbacks(ctx, ssl);
#endif

    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS,
               serverReadyFile);
    if (!doDTLS) 
        CloseSocket(sockfd);

    SSL_set_fd(ssl, clientfd);
    if (usePsk == 0 || useAnon == 1 || cipherList != NULL) {
        #if !defined(NO_FILESYSTEM) && !defined(NO_DH)
            CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
        #elif !defined(NO_DH)
            SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
        #endif
    }

#ifndef CYASSL_CALLBACKS
    if (nonBlocking) {
        CyaSSL_set_using_nonblock(ssl, 1);
        tcp_set_nonblocking(&clientfd);
        NonBlockingSSL_Accept(ssl);
    } else if (SSL_accept(ssl) != SSL_SUCCESS) {
        int err = SSL_get_error(ssl, 0);
        char buffer[CYASSL_MAX_ERROR_SZ];
        printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
        err_sys("SSL_accept failed");
    }
#else
    NonBlockingSSL_Accept(ssl);
#endif
    showPeer(ssl);

    idx = SSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);

    }
    else if (idx < 0) {
        int readErr = SSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("SSL_read failed");
    }

    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
        err_sys("SSL_write failed");
        
    #if defined(CYASSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
        os_dly_wait(500) ;
    #elif defined (CYASSL_TIRTOS)
        Task_yield();
    #endif

    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = 0;


#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    ecc_fp_free();  /* free per thread cache */
#endif

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif

#ifdef CYASSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#ifndef CYASSL_TIRTOS
    return 0;
#endif
}
示例#22
0
void echoclient_test(void* args)
{
    SOCKET_T sockfd = 0;

    FILE* fin  = stdin;
    FILE* fout = stdout;

    int inCreated  = 0;
    int outCreated = 0;

    char msg[1024];
    char reply[1024];

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    int doDTLS = 0;
    int doLeanPSK = 0;
    int sendSz;
    int argc    = 0;
    char** argv = 0;

    ((func_args*)args)->return_code = -1; /* error state */
    argc = ((func_args*)args)->argc;
    argv = ((func_args*)args)->argv;

    if (argc >= 2) {
        fin  = fopen(argv[1], "r"); 
        inCreated = 1;
    }
    if (argc >= 3) {
        fout = fopen(argv[2], "w");
        outCreated = 1;
    }

    if (!fin)  err_sys("can't open input file");
    if (!fout) err_sys("can't open output file");

#ifdef CYASSL_DTLS
    doDTLS  = 1;
#endif

#ifdef CYASSL_LEANPSK 
    doLeanPSK = 1;
#endif

#if defined(CYASSL_DTLS)
    method  = DTLSv1_client_method();
#elif  !defined(NO_TLS)
    method = CyaSSLv23_client_method();
#else
    method = SSLv3_client_method();
#endif
    ctx    = SSL_CTX_new(method);

#ifndef NO_FILESYSTEM
    if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
        err_sys("can't load ca file, Please run from CyaSSL home dir");
    #ifdef HAVE_ECC
        if (SSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    #endif
#elif !defined(NO_CERTS)
    if (!doLeanPSK)
        load_buffer(ctx, caCert, CYASSL_CA);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    SSL_CTX_set_cipher_list(ctx, "AES256-SHA");
#endif
    if (doLeanPSK) {
#ifdef CYASSL_LEANPSK
        CyaSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
        SSL_CTX_set_cipher_list(ctx, "PSK-NULL-SHA");
#endif
    }

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
    ssl = SSL_new(ctx);

    if (doDTLS) {
        SOCKADDR_IN_T addr;
        build_addr(&addr, yasslIP, yasslPort);
        CyaSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
        tcp_socket(&sockfd, 1);
    }
    else {
        tcp_connect(&sockfd, yasslIP, yasslPort, 0);
    }

    SSL_set_fd(ssl, sockfd);
#if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER)
    /* let echoserver bind first, TODO: add Windows signal like pthreads does */
    Sleep(100);
#endif
    if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");

    while (fgets(msg, sizeof(msg), fin)) {

        sendSz = (int)strlen(msg);

        if (SSL_write(ssl, msg, sendSz) != sendSz)
            err_sys("SSL_write failed");

        if (strncmp(msg, "quit", 4) == 0) {
            fputs("sending server shutdown command: quit!\n", fout);
            break;
        }

        if (strncmp(msg, "break", 5) == 0) {
            fputs("sending server session close: break!\n", fout);
            break;
        }

        while (sendSz) {
            int got;
            if ( (got = SSL_read(ssl, reply, sizeof(reply))) > 0) {
                reply[got] = 0;
                fputs(reply, fout);
                sendSz -= got;
            }
            else
                break;
        }
    }

#ifdef CYASSL_DTLS
    strncpy(msg, "break", 6);
    sendSz = (int)strlen(msg);
    /* try to tell server done */
    SSL_write(ssl, msg, sendSz);
#else
    SSL_shutdown(ssl);
#endif

    SSL_free(ssl);
    SSL_CTX_free(ctx);

    fflush(fout);
    if (inCreated)  fclose(fin);
    if (outCreated) fclose(fout);

    CloseSocket(sockfd);
    ((func_args*)args)->return_code = 0; 
}
示例#23
0
/* Create a socket and connect it to 'ip' on port 'port'.
 * Returns -1 on failure (ip is NULL, socket creation/connection error)
 * Returns sock number on success.
 */
int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking)
{
	mosq_sock_t sock = INVALID_SOCKET;
	int rc;
#ifdef WITH_TLS
	int ret;
	BIO *bio;
#endif

	if(!mosq || !host || !port) return MOSQ_ERR_INVAL;

	rc = _mosquitto_try_connect(mosq, host, port, &sock, bind_address, blocking);
	if(rc > 0) return rc;

#ifdef WITH_TLS
	if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
		if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1.2")){
			mosq->ssl_ctx = SSL_CTX_new(TLSv1_2_client_method());
		}else if(!strcmp(mosq->tls_version, "tlsv1.1")){
			mosq->ssl_ctx = SSL_CTX_new(TLSv1_1_client_method());
		}else if(!strcmp(mosq->tls_version, "tlsv1")){
			mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
		}else{
			_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version);
			COMPAT_CLOSE(sock);
			return MOSQ_ERR_INVAL;
		}
#else
		if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1")){
			mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
		}else{
			_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version);
			COMPAT_CLOSE(sock);
			return MOSQ_ERR_INVAL;
		}
#endif
		if(!mosq->ssl_ctx){
			_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context.");
			COMPAT_CLOSE(sock);
			return MOSQ_ERR_TLS;
		}

#if OPENSSL_VERSION_NUMBER >= 0x10000000
		/* Disable compression */
		SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_COMPRESSION);
#endif
#ifdef SSL_MODE_RELEASE_BUFFERS
			/* Use even less memory per SSL connection. */
			SSL_CTX_set_mode(mosq->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
#endif

		if(mosq->tls_ciphers){
			ret = SSL_CTX_set_cipher_list(mosq->ssl_ctx, mosq->tls_ciphers);
			if(ret == 0){
				_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", mosq->tls_ciphers);
				COMPAT_CLOSE(sock);
				return MOSQ_ERR_TLS;
			}
		}
		if(mosq->tls_cafile || mosq->tls_capath){
			ret = SSL_CTX_load_verify_locations(mosq->ssl_ctx, mosq->tls_cafile, mosq->tls_capath);
			if(ret == 0){
#ifdef WITH_BROKER
				if(mosq->tls_cafile && mosq->tls_capath){
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\" and bridge_capath \"%s\".", mosq->tls_cafile, mosq->tls_capath);
				}else if(mosq->tls_cafile){
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile);
				}else{
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath);
				}
#else
				if(mosq->tls_cafile && mosq->tls_capath){
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\" and capath \"%s\".", mosq->tls_cafile, mosq->tls_capath);
				}else if(mosq->tls_cafile){
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile);
				}else{
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath);
				}
#endif
				COMPAT_CLOSE(sock);
				return MOSQ_ERR_TLS;
			}
			if(mosq->tls_cert_reqs == 0){
				SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_NONE, NULL);
			}else{
				SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_PEER, _mosquitto_server_certificate_verify);
			}

			if(mosq->tls_pw_callback){
				SSL_CTX_set_default_passwd_cb(mosq->ssl_ctx, mosq->tls_pw_callback);
				SSL_CTX_set_default_passwd_cb_userdata(mosq->ssl_ctx, mosq);
			}

			if(mosq->tls_certfile){
				ret = SSL_CTX_use_certificate_chain_file(mosq->ssl_ctx, mosq->tls_certfile);
				if(ret != 1){
#ifdef WITH_BROKER
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate, check bridge_certfile \"%s\".", mosq->tls_certfile);
#else
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile);
#endif
					COMPAT_CLOSE(sock);
					return MOSQ_ERR_TLS;
				}
			}
			if(mosq->tls_keyfile){
				ret = SSL_CTX_use_PrivateKey_file(mosq->ssl_ctx, mosq->tls_keyfile, SSL_FILETYPE_PEM);
				if(ret != 1){
#ifdef WITH_BROKER
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file, check bridge_keyfile \"%s\".", mosq->tls_keyfile);
#else
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile);
#endif
					COMPAT_CLOSE(sock);
					return MOSQ_ERR_TLS;
				}
				ret = SSL_CTX_check_private_key(mosq->ssl_ctx);
				if(ret != 1){
					_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent.");
					COMPAT_CLOSE(sock);
					return MOSQ_ERR_TLS;
				}
			}
#ifdef REAL_WITH_TLS_PSK
		}else if(mosq->tls_psk){
			SSL_CTX_set_psk_client_callback(mosq->ssl_ctx, psk_client_callback);
#endif
		}

		mosq->ssl = SSL_new(mosq->ssl_ctx);
		if(!mosq->ssl){
			COMPAT_CLOSE(sock);
			return MOSQ_ERR_TLS;
		}
		SSL_set_ex_data(mosq->ssl, tls_ex_index_mosq, mosq);
		bio = BIO_new_socket(sock, BIO_NOCLOSE);
		if(!bio){
			COMPAT_CLOSE(sock);
			return MOSQ_ERR_TLS;
		}
		SSL_set_bio(mosq->ssl, bio, bio);

		mosq->sock = sock;
		if(mosquitto__socket_connect_tls(mosq)){
			return MOSQ_ERR_TLS;
		}

	}
#endif

	mosq->sock = sock;

	return rc;
}
示例#24
0
static apr_status_t
init_ssl_context(serv_ctx_t *serv_ctx,
                 const char *keyfile,
                 const char **certfiles,
                 const char *client_cn)
{
    ssl_context_t *ssl_ctx = apr_pcalloc(serv_ctx->pool, sizeof(*ssl_ctx));
    serv_ctx->ssl_ctx = ssl_ctx;
    serv_ctx->client_cn = client_cn;
    serv_ctx->bio_read_status = APR_SUCCESS;

    /* Init OpenSSL globally */
    if (!init_done)
    {
        CRYPTO_malloc_init();
        ERR_load_crypto_strings();
        SSL_load_error_strings();
        SSL_library_init();
        OpenSSL_add_all_algorithms();
        init_done = 1;
    }

    /* Init this connection */
    if (!ssl_ctx->ctx) {
        X509_STORE *store;
        const char *certfile;
        int i;
        int rv;

        ssl_ctx->ctx = SSL_CTX_new(SSLv23_server_method());
        SSL_CTX_set_default_passwd_cb(ssl_ctx->ctx, pem_passwd_cb);
        rv = SSL_CTX_use_PrivateKey_file(ssl_ctx->ctx, keyfile,
                                         SSL_FILETYPE_PEM);
        if (rv != 1) {
            fprintf(stderr, "Cannot load private key from file '%s'\n", keyfile);
            exit(1);
        }

        /* Set server certificate, add ca certificates if provided. */
        certfile = certfiles[0];
        rv = SSL_CTX_use_certificate_file(ssl_ctx->ctx, certfile, SSL_FILETYPE_PEM);
        if (rv != 1) {
            fprintf(stderr, "Cannot load certficate from file '%s'\n", keyfile);
            exit(1);
        }

        i = 1;
        certfile = certfiles[i++];
        store = SSL_CTX_get_cert_store(ssl_ctx->ctx);

        while(certfile) {
            FILE *fp = fopen(certfile, "r");
            if (fp) {
                X509 *ssl_cert = PEM_read_X509(fp, NULL, NULL, NULL);
                fclose(fp);

                SSL_CTX_add_extra_chain_cert(ssl_ctx->ctx, ssl_cert);

                X509_STORE_add_cert(store, ssl_cert);
            }
            certfile = certfiles[i++];
        }

        /* This makes the server send a client certificate request during
           handshake. The client certificate is optional (most tests don't
           send one) by default, but mandatory if client_cn was specified. */
        SSL_CTX_set_verify(ssl_ctx->ctx, SSL_VERIFY_PEER,
                           validate_client_certificate);

        SSL_CTX_set_mode(ssl_ctx->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);

        ssl_ctx->bio = BIO_new(&bio_apr_socket_method);
        ssl_ctx->bio->ptr = serv_ctx;
        init_ssl(serv_ctx);
    }

    return APR_SUCCESS;
}
示例#25
0
/* If called without arguments, listen for connections.  Otherwise make a
 * connection to the specified first argument.
 */
int main(int argc, char *argv[]){
	get_args(argc, argv);
	
	//OpenSSL
	SSL_load_error_strings();
	ERR_load_BIO_strings();
	ERR_load_SSL_strings();
	SSL_library_init();
	OpenSSL_add_all_algorithms();
	/////////

	int port = DFL_PORT;
	if (prog_args.port != 0) {
		if ((port = atoi(prog_args.port)) <= 0) {
			fprintf(stderr, "%s: port must be positive integer\n",
			        prog_args.name);
			exit(1);
		}
	}

	/* Create and bind the socket.
	 */
	int s;
	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}

	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = INADDR_ANY;
	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("bind");
		exit(1);
	}
	
	//OpenSSL
	printf("Attempting to create SSL context... ");
	ctx = SSL_CTX_new(SSLv23_server_method());

	if(ctx == NULL)
	{
		printf("Failed. Aborting.\n");
		return 0;
	}

	printf("\nLoading certificates...\n");
	SSL_CTX_set_default_passwd_cb(ctx, callback);
	if(!SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
	{
		ERR_print_errors_fp(stdout);
		SSL_CTX_free(ctx);
		return 0;
	}
	if(!SSL_CTX_use_PrivateKey_file(ctx, PRI_KEY, SSL_FILETYPE_PEM))
	{
		ERR_print_errors_fp(stdout);
		SSL_CTX_free(ctx);
		return 0;
	}
	ssl = SSL_new(ctx);
	////////////

	do_recv(s);
	return 0;
}
示例#26
0
文件: tls_openssl.c 项目: AlD/bareos
/*
 * Create a new TLS_CONTEXT instance.
 *
 * Returns: Pointer to TLS_CONTEXT instance on success
 *          NULL on failure;
 */
TLS_CONTEXT *new_tls_context(const char *ca_certfile,
                             const char *ca_certdir,
                             const char *crlfile,
                             const char *certfile,
                             const char *keyfile,
                             CRYPTO_PEM_PASSWD_CB *pem_callback,
                             const void *pem_userdata,
                             const char *dhfile,
                             bool verify_peer)
{
   TLS_CONTEXT *ctx;
   BIO *bio;
   DH *dh;

   ctx = (TLS_CONTEXT *)malloc(sizeof(TLS_CONTEXT));

   /*
    * Allocate our OpenSSL TLSv1 Context
    */
   ctx->openssl = SSL_CTX_new(TLSv1_method());

   if (!ctx->openssl) {
      openssl_post_errors(M_FATAL, _("Error initializing SSL context"));
      goto err;
   }

   /*
    * Set up pem encryption callback
    */
   if (pem_callback) {
      ctx->pem_callback = pem_callback;
      ctx->pem_userdata = pem_userdata;
   } else {
      ctx->pem_callback = crypto_default_pem_callback;
      ctx->pem_userdata = NULL;
   }
   ctx->verify_peer = verify_peer;

   SSL_CTX_set_default_passwd_cb(ctx->openssl, tls_pem_callback_dispatch);
   SSL_CTX_set_default_passwd_cb_userdata(ctx->openssl, (void *) ctx);

   /*
    * Set certificate verification paths. This requires that at least one value be non-NULL
    */
   if (ca_certfile || ca_certdir) {
      if (!SSL_CTX_load_verify_locations(ctx->openssl, ca_certfile, ca_certdir)) {
         openssl_post_errors(M_FATAL, _("Error loading certificate verification stores"));
         goto err;
      }
   } else if (verify_peer) {
      /* At least one CA is required for peer verification */
      Jmsg0(NULL, M_ERROR, 0, _("Either a certificate file or a directory must be"
                         " specified as a verification store\n"));
      goto err;
   }

#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
   /*
    * Set certificate revocation list.
    */
   if (crlfile) {
      X509_STORE *store;
      X509_LOOKUP *lookup;

      store = SSL_CTX_get_cert_store(ctx->openssl);
      if (!store) {
         openssl_post_errors(M_FATAL, _("Error loading revocation list file"));
         goto err;
      }

      lookup = X509_STORE_add_lookup(store, X509_LOOKUP_crl_reloader());
      if (!lookup) {
         openssl_post_errors(M_FATAL, _("Error loading revocation list file"));
         goto err;
      }

      if (!load_new_crl_file(lookup, (char *)crlfile)) {
         openssl_post_errors(M_FATAL, _("Error loading revocation list file"));
         goto err;
      }

      X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
   }
#endif

   /*
    * Load our certificate file, if available. This file may also contain a
    * private key, though this usage is somewhat unusual.
    */
   if (certfile) {
      if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) {
         openssl_post_errors(M_FATAL, _("Error loading certificate file"));
         goto err;
      }
   }

   /*
    * Load our private key.
    */
   if (keyfile) {
      if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) {
         openssl_post_errors(M_FATAL, _("Error loading private key"));
         goto err;
      }
   }

   /*
    * Load Diffie-Hellman Parameters.
    */
   if (dhfile) {
      if (!(bio = BIO_new_file(dhfile, "r"))) {
         openssl_post_errors(M_FATAL, _("Unable to open DH parameters file"));
         goto err;
      }
      dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
      BIO_free(bio);
      if (!dh) {
         openssl_post_errors(M_FATAL, _("Unable to load DH parameters from specified file"));
         goto err;
      }
      if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) {
         openssl_post_errors(M_FATAL, _("Failed to set TLS Diffie-Hellman parameters"));
         DH_free(dh);
         goto err;
      }

      /*
       * Enable Single-Use DH for Ephemeral Keying
       */
      SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE);
   }

   if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) {
      Jmsg0(NULL, M_ERROR, 0,
             _("Error setting cipher list, no valid ciphers available\n"));
      goto err;
   }

   /*
    * Verify Peer Certificate
    */
   if (verify_peer) {
      /*
       * SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode
       */
      SSL_CTX_set_verify(ctx->openssl,
                         SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
                         openssl_verify_peer);
   } else {
      SSL_CTX_set_verify(ctx->openssl,
                         SSL_VERIFY_NONE,
                         NULL);
   }

   return ctx;

err:
   /*
    * Clean up after ourselves
    */
   if (ctx->openssl) {
      SSL_CTX_free(ctx->openssl);
   }
   free(ctx);
   return NULL;
}
示例#27
0
SSL *SSLSocket::createSSL(SSL_CTX *ctx) {
  ERR_clear_error();

  /* look at options in the stream and set appropriate verification flags */
  if (m_context[s_verify_peer].toBoolean()) {
    /* turn on verification callback */
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verifyCallback);

    /* CA stuff */
    String cafile = m_context[s_cafile].toString();
    String capath = m_context[s_capath].toString();

    if (!cafile.empty() || !capath.empty()) {
      if (!SSL_CTX_load_verify_locations(ctx, cafile.data(), capath.data())) {
        raise_warning("Unable to set verify locations `%s' `%s'",
                      cafile.data(), capath.data());
        return nullptr;
      }
    }

    int64_t depth = m_context[s_verify_depth].toInt64();
    if (depth) {
      SSL_CTX_set_verify_depth(ctx, depth);
    }
  } else {
    SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr);
  }

  /* callback for the passphrase (for localcert) */
  if (!m_context[s_passphrase].toString().empty()) {
    SSL_CTX_set_default_passwd_cb_userdata(ctx, this);
    SSL_CTX_set_default_passwd_cb(ctx, passwdCallback);
  }

  String cipherlist = m_context[s_ciphers].toString();
  if (cipherlist.empty()) {
    cipherlist = "DEFAULT";
  }
  SSL_CTX_set_cipher_list(ctx, cipherlist.data());

  String certfile = m_context[s_local_cert].toString();
  if (!certfile.empty()) {
    String resolved_path_buff = File::TranslatePath(certfile);
    if (!resolved_path_buff.empty()) {
      /* a certificate to use for authentication */
      if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff.data())
          != 1) {
        raise_warning("Unable to set local cert chain file `%s'; Check "
                      "that your cafile/capath settings include details of "
                      "your certificate and its issuer", certfile.data());
        return nullptr;
      }

      if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff.data(),
                                      SSL_FILETYPE_PEM) != 1) {
        raise_warning("Unable to set private key file `%s'",
                      resolved_path_buff.data());
        return nullptr;
      }

      SSL *tmpssl = SSL_new(ctx);
      X509 *cert = SSL_get_certificate(tmpssl);
      if (cert) {
        EVP_PKEY *key = X509_get_pubkey(cert);
        EVP_PKEY_copy_parameters(key, SSL_get_privatekey(tmpssl));
        EVP_PKEY_free(key);
      }
      SSL_free(tmpssl);

      if (!SSL_CTX_check_private_key(ctx)) {
        raise_warning("Private key does not match certificate!");
      }
    }
  }

  SSL *ssl = SSL_new(ctx);
  if (ssl) {
    SSL_set_ex_data(ssl, GetSSLExDataIndex(), this); /* map SSL => stream */
  }
  return ssl;
}
示例#28
0
/**
 * post processing of profile, e.g. init SSL
 *
 * @param ctx
 *
 * @return
 */
dpl_status_t
dpl_profile_post(dpl_ctx_t *ctx)
{
  int ret, ret2;

  //sanity checks
  if (NULL == ctx->host)
    {
      fprintf(stderr, "missing 'host' in profile\n");
      ret = DPL_FAILURE;
      goto end;
    }

  if (-1 == ctx->port)
    {
      if (0 == ctx->use_https)
        ctx->port = 80;
      else
        ctx->port = 443;
    }

  //ssl stuff
  if (1 == ctx->use_https)
    {
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
      const SSL_METHOD *method;
#else
      SSL_METHOD *method;
#endif

      if (NULL == ctx->ssl_cert_file ||
          NULL == ctx->ssl_key_file ||
          NULL == ctx->ssl_password)
        return DPL_EINVAL;

      ctx->ssl_bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
      if (NULL == ctx->ssl_bio_err)
        {
          ret = DPL_FAILURE;
          goto end;
        }

      method = SSLv23_method();
      ctx->ssl_ctx = SSL_CTX_new(method);

      if (!(SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, ctx->ssl_cert_file)))
        {
          BIO_printf(ctx->ssl_bio_err, "use_certificate_chain_file: ");
          ERR_print_errors(ctx->ssl_bio_err);
          BIO_printf(ctx->ssl_bio_err, "\n");
          ret = DPL_FAILURE;
          goto end;
        }

      SSL_CTX_set_default_passwd_cb(ctx->ssl_ctx, passwd_cb);
      SSL_CTX_set_default_passwd_cb_userdata(ctx->ssl_ctx, ctx);

      if (!(SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, ctx->ssl_key_file, SSL_FILETYPE_PEM)))
        {
          BIO_printf(ctx->ssl_bio_err, "use_private_key_file: ");
          ERR_print_errors(ctx->ssl_bio_err);
          BIO_printf(ctx->ssl_bio_err, "\n");
          ret = DPL_FAILURE;
          goto end;
        }

      if (NULL != ctx->ssl_ca_list)
        {
          if (!(SSL_CTX_load_verify_locations(ctx->ssl_ctx, ctx->ssl_ca_list, 0)))
            {
              BIO_printf(ctx->ssl_bio_err, "load_verify_location: ");
              ERR_print_errors(ctx->ssl_bio_err);
              BIO_printf(ctx->ssl_bio_err, "\n");
              ret = DPL_FAILURE;
              goto end;
            }
        }
    }

  //pricing
  if (NULL != ctx->pricing)
    {
      ret2 = dpl_pricing_load(ctx);
      if (DPL_SUCCESS != ret2)
        {
          ret = DPL_FAILURE;
          goto end;
        }
    }

  //encrypt
  OpenSSL_add_all_digests();
  OpenSSL_add_all_ciphers();

  //event log
  ret2 = dpl_open_event_log(ctx);
  if (DPL_SUCCESS != ret2)
    {
      ret = DPL_FAILURE;
      goto end;
    }

  //connection pool
  ret2 = dpl_conn_pool_init(ctx);
  if (DPL_SUCCESS != ret2)
    {
      ret = DPL_FAILURE;
      goto end;
    }

  ctx->cwds = dpl_dict_new(13);
  if (NULL == ctx->cwds)
    {
      ret = DPL_FAILURE;
      goto end;
    }

  ctx->cur_bucket = strdup("");
  if (NULL == ctx->cur_bucket)
    {
      ret = DPL_FAILURE;
      goto end;
    }

  ret = DPL_SUCCESS;

 end:

  return ret;
}
示例#29
0
static int ma_tls_set_certs(MYSQL *mysql)
{
  char *certfile= mysql->options.ssl_cert,
       *keyfile= mysql->options.ssl_key;
  
  /* add cipher */
  if ((mysql->options.ssl_cipher && 
        mysql->options.ssl_cipher[0] != 0) &&
      SSL_CTX_set_cipher_list(SSL_context, mysql->options.ssl_cipher) == 0)
    goto error;

  /* ca_file and ca_path */
  if (SSL_CTX_load_verify_locations(SSL_context, 
                                    mysql->options.ssl_ca,
                                    mysql->options.ssl_capath) == 0)
  {
    if (mysql->options.ssl_ca || mysql->options.ssl_capath)
      goto error;
    if (SSL_CTX_set_default_verify_paths(SSL_context) == 0)
      goto error;
  }

  if (keyfile && !certfile)
    certfile= keyfile;
  if (certfile && !keyfile)
    keyfile= certfile;

  /* set cert */
  if (certfile  && certfile[0] != 0)  
    if (SSL_CTX_use_certificate_file(SSL_context, certfile, SSL_FILETYPE_PEM) != 1)
      goto error; 

  /* If the private key file is encrypted, we need to register a callback function
   * for providing password. */
  if (OPT_HAS_EXT_VAL(mysql, tls_pw))
  {
    SSL_CTX_set_default_passwd_cb_userdata(SSL_context, (void *)mysql->options.extension->tls_pw);
    SSL_CTX_set_default_passwd_cb(SSL_context, ma_tls_get_password);
  }

  if (keyfile && keyfile[0])
  {
    if (SSL_CTX_use_PrivateKey_file(SSL_context, keyfile, SSL_FILETYPE_PEM) != 1)
    {
      unsigned long err= ERR_peek_error();
      if (!(ERR_GET_LIB(err) == ERR_LIB_X509 &&
	  ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE))
        goto error;
    }
  }
  if (OPT_HAS_EXT_VAL(mysql, tls_pw))
  {
    SSL_CTX_set_default_passwd_cb_userdata(SSL_context, NULL);
    SSL_CTX_set_default_passwd_cb(SSL_context, NULL);
  }
  /* verify key */
  if (certfile && !SSL_CTX_check_private_key(SSL_context))
    goto error;
  
  if (mysql->options.extension &&
      (mysql->options.extension->ssl_crl || mysql->options.extension->ssl_crlpath))
  {
    X509_STORE *certstore;

    if ((certstore= SSL_CTX_get_cert_store(SSL_context)))
    {
      if (X509_STORE_load_locations(certstore, mysql->options.extension->ssl_crl,
                                               mysql->options.extension->ssl_crlpath) == 0)
        goto error;

      X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
    }
  }
  return 0;

error:
  ma_tls_set_error(mysql);
  return 1;
}
示例#30
0
int main()
{
    SSL_library_init();
    SSL_load_error_strings();

    BIO * bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

    /* Set up a SIGPIPE handler */
    signal(SIGPIPE, SIG_IGN);

    /* Create our context*/
    SSL_CTX * ctx = SSL_CTX_new(SSLv23_method());

    /* Load our keys and certificates*/
    if(!(SSL_CTX_use_certificate_chain_file(ctx, "ftests/fixtures/rdpproxy-cert.pem")))
    {
        BIO_printf(bio_err, "Can't read certificate file\n");
        ERR_print_errors(bio_err);
        exit(0);
    }

    SSL_CTX_set_default_passwd_cb(ctx, password_cb0);
    SSL_CTX_set_default_passwd_cb_userdata(ctx, const_cast<char *>("inquisition"));
    if(!(SSL_CTX_use_PrivateKey_file(ctx, "ftests/fixtures/rdpproxy-key.pem", SSL_FILETYPE_PEM)))
    {
        BIO_printf(bio_err,"Can't read key file\n");
        ERR_print_errors(bio_err);
        exit(0);
    }

    DH *ret=nullptr;
    BIO *bio;

    if ((bio=BIO_new_file("ftests/fixtures/dh1024.pem","r")) == nullptr){
        BIO_printf(bio_err,"Couldn't open DH file\n");
        ERR_print_errors(bio_err);
        exit(0);
    }

    ret=PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
    BIO_free(bio);
    if(SSL_CTX_set_tmp_dh(ctx, ret)<0)
    {
        BIO_printf(bio_err,"Couldn't set DH parameters\n");
        ERR_print_errors(bio_err);
        exit(0);
    }


    union
    {
        struct sockaddr s;
        struct sockaddr_storage ss;
        struct sockaddr_in s4;
        struct sockaddr_in6 s6;
    } ucs;
    memset(&ucs, 0, sizeof(ucs));

    int val=1;

    int sock = socket(AF_INET, SOCK_STREAM,0);
    if(sock < 0) {
        fprintf(stderr, "Failed to make socket\n");
        exit(0);
    }

    memset(&ucs.s4, 0, sizeof(ucs));
    ucs.s4.sin_addr.s_addr = INADDR_ANY;
    ucs.s4.sin_family = AF_INET;
    ucs.s4.sin_port = htons(4433);
    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR, &val,sizeof(val));

    int bind_res = bind(sock,&ucs.s,  sizeof(ucs));
    if(bind_res < 0){
        fprintf(stderr, "Failed to bind\n");
        exit(0);
    }
    listen(sock,5);

    for (;;) {
        int s = accept(sock,nullptr,nullptr);
        if(s < 0){
            fprintf(stderr,"Problem accepting\n");
            break;
        }

        pid_t pid = fork();

        if(pid){
            close(s);
        }
        else {
            rdp_serve(ctx, s, bio_err);
            break;
        }
    }
    SSL_CTX_free(ctx);

    return 0;
}