<commit_before>/*
    This file is part of libcapwap.

    libcapwap is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    libcapwap is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.

*/
#include <errno.h>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>


#include "dtls_openssl.h"

#include "cw_log.h"
#include "conn.h"


int pem_passwd_cb(char *buf, int size, int rwflag, void *password)
{
         strncpy(buf, (char *)(password), size);
         buf[size - 1] = '\0';
         return(strlen(buf));
}








int dtls_openssl_init()
{
	cw_log_debug0("Init ssl library");
	SSL_load_error_strings();
	return SSL_library_init();
}


int dtls_openssl_log_error_queue(const char *txt)
{
	int e = ERR_get_error();
	if (e==0)
		return 0;

	char errstr[256];
	while (e!=0){
		ERR_error_string(e,errstr);
		cw_log(LOG_ERR,"%s - %s",txt,errstr);
		e = ERR_get_error();
	}
	return 1;
}

int dtls_openssl_log_error(SSL * ssl, int rc, const char *txt)
{
	int en = errno; /* save errno */

	if (!ssl){
		return dtls_openssl_log_error_queue(txt);
	}

	int e;
	e = SSL_get_error(ssl,rc);

	char errstr[256];
	ERR_error_string(e,errstr);
	cw_log(LOG_ERR,"%s - %s","SSSSS",errstr);

	switch (e){
		case SSL_ERROR_ZERO_RETURN:
			break;
		case SSL_ERROR_SYSCALL:
			if (!dtls_openssl_log_error_queue(txt)){
				/* error queu was empty */
				if (rc<0){
					cw_log(LOG_ERR,"%s - %s",txt,strerror(en));
					return 1;
				}
				
				cw_log(LOG_ERR,"%s - EOF observed",txt);
				return 1;
			}
			

	}	
	return 0;
}


void dtls_openssl_data_destroy(struct dtls_openssl_data * d){
	if (!d)
		return;

	if (d->ssl)
		SSL_free(d->ssl);

	if (d->ctx)
		SSL_CTX_free(d->ctx);


	free(d);
}






struct dtls_openssl_data * dtls_openssl_data_create(struct conn * conn, const SSL_METHOD * method, BIO_METHOD * bio)
{
	struct dtls_openssl_data * d = malloc(sizeof(struct dtls_openssl_data));
	if (!d)
		return 0;
	memset(d,0,sizeof(struct dtls_openssl_data));

	d->ctx = SSL_CTX_new(method);
	if (!d->ctx){
		dtls_openssl_data_destroy(d);	
		return 0;
	}

	SSL_CTX_set_read_ahead(d->ctx, 1);
//	int rc = SSL_CTX_set_cipher_list(d->ctx, "PSK-AES128-CBC-SHA");
	
	//int rc = SSL_CTX_set_cipher_list(d->ctx, "PSiaK-AXES128-C5BC-SaHA");
	int rc = SSL_CTX_set_cipher_list(d->ctx, conn->dtls_cipher);
	if (!rc){
		dtls_openssl_log_error(0,rc,"DTLS:");
		dtls_openssl_data_destroy(d);	
		return 0;
	}


	if (conn->dtls_key_file && conn->dtls_cert_file){
		SSL_CTX_set_default_passwd_cb_userdata(d->ctx, conn->dtls_key_pass);
		SSL_CTX_set_default_passwd_cb(d->ctx, pem_passwd_cb);


		cw_log_debug1("DTLS - Setting key file %s",conn->dtls_key_file);
		rc = SSL_CTX_use_PrivateKey_file(d->ctx,conn->dtls_key_file,SSL_FILETYPE_PEM);
		if (!rc){

			dtls_openssl_log_error(0,rc,"DTLS:");
			dtls_openssl_data_destroy(d);	
			return 0;
		}

		cw_log_debug1("DTLS - Setting cert file %s",conn->dtls_cert_file);
		rc = SSL_CTX_use_certificate_file(d->ctx,conn->dtls_cert_file,SSL_FILETYPE_PEM);
		if (!rc){

			dtls_openssl_log_error(0,rc,"DTLS:");
			dtls_openssl_data_destroy(d);	
			return 0;
		}



	}




	d->ssl = SSL_new(d->ctx);
	if (!d->ssl){
		dtls_openssl_data_destroy(d);
		return 0;
	}


/*
printf("Checccccccccccccccccccccccccccccc Allllllllllllllllllllllllllllllllllllll is ok!\n");

printf("Allllllllllllllllllllllllllllllllllllll is ok!\n");
*/
	
	d->bio = BIO_new(bio);
	d->bio->ptr = conn;
	SSL_set_bio(d->ssl, d->bio, d->bio);

	return d;
}


/* 
 * Convert the PSK key (psk_key) in ascii to binary (psk).
 */
int dtls_openssl_psk_key2bn(const char *psk_key, unsigned char *psk, unsigned int max_psk_len) {

	unsigned int psk_len = 0;
	int ret;
	BIGNUM *bn = NULL;<commit_msg>Created function to set certificates.<commit_after>/*
    This file is part of libcapwap.

    libcapwap is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    libcapwap is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.

*/
#include <errno.h>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>


#include "dtls_openssl.h"

#include "cw_log.h"
#include "conn.h"


int pem_passwd_cb(char *buf, int size, int rwflag, void *password)
{
         strncpy(buf, (char *)(password), size);
         buf[size - 1] = '\0';
         return(strlen(buf));
}








int dtls_openssl_init()
{
	cw_log_debug0("Init ssl library");
	SSL_load_error_strings();
	return SSL_library_init();
}


int dtls_openssl_log_error_queue(const char *txt)
{
	int e = ERR_get_error();
	if (e==0)
		return 0;

	char errstr[256];
	while (e!=0){
		ERR_error_string(e,errstr);
		cw_log(LOG_ERR,"%s - %s",txt,errstr);
		e = ERR_get_error();
	}
	return 1;
}

int dtls_openssl_log_error(SSL * ssl, int rc, const char *txt)
{
	int en = errno; /* save errno */

	if (!ssl){
		return dtls_openssl_log_error_queue(txt);
	}

	int e;
	e = SSL_get_error(ssl,rc);

	char errstr[256];
	ERR_error_string(e,errstr);
	cw_log(LOG_ERR,"%s - %s","SSSSS",errstr);

	switch (e){
		case SSL_ERROR_ZERO_RETURN:
			break;
		case SSL_ERROR_SYSCALL:
			if (!dtls_openssl_log_error_queue(txt)){
				/* error queu was empty */
				if (rc<0){
					cw_log(LOG_ERR,"%s - %s",txt,strerror(en));
					return 1;
				}
				
				cw_log(LOG_ERR,"%s - EOF observed",txt);
				return 1;
			}
			

	}	
	return 0;
}


void dtls_openssl_data_destroy(struct dtls_openssl_data * d){
	if (!d)
		return;

	if (d->ssl)
		SSL_free(d->ssl);

	if (d->ctx)
		SSL_CTX_free(d->ctx);


	free(d);
}

int dtls_openssl_set_certs(struct conn * conn, struct dtls_openssl_data *d)
{
	int rc;
	if (conn->dtls_key_file && conn->dtls_cert_file){
		SSL_CTX_set_default_passwd_cb_userdata(d->ctx, conn->dtls_key_pass);
		SSL_CTX_set_default_passwd_cb(d->ctx, pem_passwd_cb);


		cw_log_debug1("DTLS - Setting key file %s",conn->dtls_key_file);
		rc = SSL_CTX_use_PrivateKey_file(d->ctx,conn->dtls_key_file,SSL_FILETYPE_PEM);
		if (!rc){

			dtls_openssl_log_error(0,rc,"DTLS:");
			dtls_openssl_data_destroy(d);	
			return 0;
		}

		cw_log_debug1("DTLS - Setting cert file %s",conn->dtls_cert_file);
		rc = SSL_CTX_use_certificate_file(d->ctx,conn->dtls_cert_file,SSL_FILETYPE_PEM);
		if (!rc){

			dtls_openssl_log_error(0,rc,"DTLS:");
			dtls_openssl_data_destroy(d);	
			return 0;
		}

	}

	return 1;
}




struct dtls_openssl_data * dtls_openssl_data_create(struct conn * conn, const SSL_METHOD * method, BIO_METHOD * bio)
{
	struct dtls_openssl_data * d = malloc(sizeof(struct dtls_openssl_data));
	if (!d)
		return 0;
	memset(d,0,sizeof(struct dtls_openssl_data));

	d->ctx = SSL_CTX_new(method);
	if (!d->ctx){
		dtls_openssl_data_destroy(d);	
		return 0;
	}

	SSL_CTX_set_read_ahead(d->ctx, 1);
//	int rc = SSL_CTX_set_cipher_list(d->ctx, "PSK-AES128-CBC-SHA");
	
	//int rc = SSL_CTX_set_cipher_list(d->ctx, "PSiaK-AXES128-C5BC-SaHA");
	int rc = SSL_CTX_set_cipher_list(d->ctx, conn->dtls_cipher);
	if (!rc){
		dtls_openssl_log_error(0,rc,"DTLS:");
		dtls_openssl_data_destroy(d);	
		return 0;
	}


/*
	if (conn->dtls_key_file && conn->dtls_cert_file){
		SSL_CTX_set_default_passwd_cb_userdata(d->ctx, conn->dtls_key_pass);
		SSL_CTX_set_default_passwd_cb(d->ctx, pem_passwd_cb);


		cw_log_debug1("DTLS - Setting key file %s",conn->dtls_key_file);
		rc = SSL_CTX_use_PrivateKey_file(d->ctx,conn->dtls_key_file,SSL_FILETYPE_PEM);
		if (!rc){

			dtls_openssl_log_error(0,rc,"DTLS:");
			dtls_openssl_data_destroy(d);	
			return 0;
		}

		cw_log_debug1("DTLS - Setting cert file %s",conn->dtls_cert_file);
		rc = SSL_CTX_use_certificate_file(d->ctx,conn->dtls_cert_file,SSL_FILETYPE_PEM);
		if (!rc){

			dtls_openssl_log_error(0,rc,"DTLS:");
			dtls_openssl_data_destroy(d);	
			return 0;
		}



	}

*/
	rc = dtls_openssl_set_certs(conn,d);
	if (!rc)
		return 0;



	d->ssl = SSL_new(d->ctx);
	if (!d->ssl){
		dtls_openssl_data_destroy(d);
		return 0;
	}

	
	d->bio = BIO_new(bio);
	d->bio->ptr = conn;
	SSL_set_bio(d->ssl, d->bio, d->bio);

	return d;
}


/* 
 * Convert the PSK key (psk_key) in ascii to binary (psk).
 */
int dtls_openssl_psk_key2bn(const char *psk_key, unsigned char *psk, unsigned int max_psk_len) {

	unsigned int psk_len = 0;
	int ret;
	BIGNUM *bn = NULL;
{'fraction_non_alphanumeric': 0.1352121943195526, 'fraction_numerical': 0.009650180940892641, 'mean_word_length': 4.117845117845118, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 86, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 3, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '484925', 'n_tokens_mistral': 4082, 'n_tokens_neox': 3655, 'n_words': 772}