⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tls_openssl.c

📁 hostapd无线AP工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * WPA Supplicant / SSL/TLS interface functions for openssl * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include <stdlib.h>#include <stdio.h>#include <string.h>#ifndef CONFIG_SMARTCARD#ifndef OPENSSL_NO_ENGINE#define OPENSSL_NO_ENGINE#endif#endif#include <openssl/ssl.h>#include <openssl/err.h>#include <openssl/pkcs12.h>#include <openssl/x509v3.h>#ifndef OPENSSL_NO_ENGINE#include <openssl/engine.h>#endif /* OPENSSL_NO_ENGINE */#include "common.h"#include "tls.h"struct tls_connection {	SSL *ssl;	BIO *ssl_in, *ssl_out;#ifndef OPENSSL_NO_ENGINE	ENGINE *engine;        /* functional reference to the engine */	EVP_PKEY *private_key; /* the private key if using engine */#endif /* OPENSSL_NO_ENGINE */	char *subject_match, *altsubject_match;	int read_alerts, write_alerts, failed;};static void ssl_info_cb(const SSL *ssl, int where, int ret){	const char *str;	int w;	wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret);	w = where & ~SSL_ST_MASK;	if (w & SSL_ST_CONNECT)		str = "SSL_connect";	else if (w & SSL_ST_ACCEPT)		str = "SSL_accept";	else		str = "undefined";	if (where & SSL_CB_LOOP) {		wpa_printf(MSG_DEBUG, "SSL: %s:%s",			   str, SSL_state_string_long(ssl));	} else if (where & SSL_CB_ALERT) {		wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s",			   where & SSL_CB_READ ?			   "read (remote end reported an error)" :			   "write (local SSL3 detected an error)",			   SSL_alert_type_string_long(ret),			   SSL_alert_desc_string_long(ret));		if ((ret >> 8) == SSL3_AL_FATAL) {			struct tls_connection *conn =				SSL_get_app_data((SSL *) ssl);			if (where & SSL_CB_READ)				conn->read_alerts++;			else				conn->write_alerts++;		}	} else if (where & SSL_CB_EXIT && ret <= 0) {		wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",			   str, ret == 0 ? "failed" : "error",			   SSL_state_string_long(ssl));	}}#ifndef OPENSSL_NO_ENGINE/** * tls_engine_load_dynamic_generic - load any openssl engine * @pre: an array of commands and values that load an engine initialized *       in the engine specific function * @post: an array of commands and values that initialize an already loaded *        engine (or %NULL if not required) * @id: the engine id of the engine to load (only required if post is not %NULL * * This function is a generic function that loads any openssl engine. * * Returns: 0 on success, -1 on failure */static int tls_engine_load_dynamic_generic(const char *pre[],					   const char *post[], const char *id){	ENGINE *engine;	const char *dynamic_id = "dynamic";	engine = ENGINE_by_id(id);	if (engine) {		ENGINE_free(engine);		wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already "			   "available", id);		return 0;	}	ERR_clear_error();	engine = ENGINE_by_id(dynamic_id);	if (engine == NULL) {		wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",			   dynamic_id,			   ERR_error_string(ERR_get_error(), NULL));		return -1;	}	/* Perform the pre commands. This will load the engine. */	while (pre && pre[0]) {		wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]);		if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) {			wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: "				   "%s %s [%s]", pre[0], pre[1],				   ERR_error_string(ERR_get_error(), NULL));			ENGINE_free(engine);			return -1;		}		pre += 2;	}	/*	 * Free the reference to the "dynamic" engine. The loaded engine can	 * now be looked up using ENGINE_by_id().	 */	ENGINE_free(engine);	engine = ENGINE_by_id(id);	if (engine == NULL) {		wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",			   id, ERR_error_string(ERR_get_error(), NULL));		return -1;	}	while (post && post[0]) {		wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]);		if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) {			wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:"				" %s %s [%s]", post[0], post[1],				   ERR_error_string(ERR_get_error(), NULL));			ENGINE_remove(engine);			ENGINE_free(engine);			return -1;		}		post += 2;	}	ENGINE_free(engine);	return 0;}/** * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc * @pkcs11_so_path: pksc11_so_path from the configuration * @pcks11_module_path: pkcs11_module_path from the configuration */static int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path,					  const char *pkcs11_module_path){	char *engine_id = "pkcs11";	const char *pre_cmd[] = {		"SO_PATH", pkcs11_so_path,		"ID", engine_id,		"LIST_ADD", "1",		/* "NO_VCHECK", "1", */		"LOAD", NULL,		NULL, NULL	};	const char *post_cmd[] = {		"MODULE_PATH", pkcs11_module_path,		NULL, NULL	};	if (!pkcs11_so_path || !pkcs11_module_path)		return 0;	wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s",		   pkcs11_so_path);	return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id);}/** * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc * @opensc_so_path: opensc_so_path from the configuration */static int tls_engine_load_dynamic_opensc(const char *opensc_so_path){	char *engine_id = "opensc";	const char *pre_cmd[] = {		"SO_PATH", opensc_so_path,		"ID", engine_id,		"LIST_ADD", "1",		"LOAD", NULL,		NULL, NULL	};	if (!opensc_so_path)		return 0;	wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s",		   opensc_so_path);	return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id);}#endif /* OPENSSL_NO_ENGINE */void * tls_init(const struct tls_config *conf){	SSL_CTX *ssl;	SSL_load_error_strings();	SSL_library_init();	/* TODO: if /dev/urandom is available, PRNG is seeded automatically.	 * If this is not the case, random data should be added here. */#ifdef PKCS12_FUNCS	PKCS12_PBE_add();#endif  /* PKCS12_FUNCS */	ssl = SSL_CTX_new(TLSv1_method());	if (ssl == NULL)		return NULL;	SSL_CTX_set_info_callback(ssl, ssl_info_cb);#ifndef OPENSSL_NO_ENGINE	if (conf &&	    (conf->opensc_engine_path || conf->pkcs11_engine_path ||	     conf->pkcs11_module_path)) {		wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine");		ERR_load_ENGINE_strings();		ENGINE_load_dynamic();		if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) ||		    tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path,						   conf->pkcs11_module_path)) {			tls_deinit(ssl);			return NULL;		}	}#endif /* OPENSSL_NO_ENGINE */	return ssl;}void tls_deinit(void *ssl_ctx){	SSL_CTX *ssl = ssl_ctx;	SSL_CTX_free(ssl);#ifndef OPENSSL_NO_ENGINE	ENGINE_cleanup();#endif /* OPENSSL_NO_ENGINE */	ERR_free_strings();	EVP_cleanup();}int tls_engine_init(struct tls_connection *conn, const char *engine_id,		    char **ppin, const char *key_id){#ifndef OPENSSL_NO_ENGINE	if (ppin == NULL) {		wpa_printf(MSG_DEBUG, "ENGINE: %s - ppin is NULL", __func__);		return -1;	}	if (engine_id == NULL) {		wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set");		return -1;	}	if (*ppin == NULL) {		wpa_printf(MSG_ERROR, "ENGINE: Smartcard PIN not set");		return -1;	}	if (key_id == NULL) {		wpa_printf(MSG_ERROR, "ENGINE: Key Id not set");		return -1;	}	ERR_clear_error();	conn->engine = ENGINE_by_id(engine_id);	if (!conn->engine) {		char *error = ERR_error_string(ERR_get_error(), NULL);		wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]",			   engine_id, error);		goto err;	}	if (ENGINE_init(conn->engine) != 1) {		char *error = ERR_error_string(ERR_get_error(), NULL);		wpa_printf(MSG_ERROR, "ENGINE: engine init failed "			   "(engine: %s) [%s]", engine_id, error);		goto err;	}	wpa_printf(MSG_DEBUG, "ENGINE: engine initialized");	if (ENGINE_ctrl_cmd_string(conn->engine, "PIN", *ppin, 0) == 0) {		char *error = ERR_error_string(ERR_get_error(), NULL);		wpa_printf(MSG_ERROR, "ENGINE: can't set pin [%s]", error);		goto err;	}	conn->private_key = ENGINE_load_private_key(conn->engine,						    key_id, NULL, NULL);	if (!conn->private_key) {		char *error = ERR_error_string(ERR_get_error(), NULL);		wpa_printf(MSG_ERROR, "ENGINE: can't load private key with id"				" '%s' [%s]", key_id, error);		/* At this point with the pkcs11 engine the PIN might be wrong.		 * We reset the PIN in the configuration to be sure to not use		 * it again and the calling function must request a new one */		free(*ppin);		*ppin = NULL;		goto err;	}	return 0;err:	if (conn->engine) {		ENGINE_free(conn->engine);		conn->engine = NULL;	}	if (conn->private_key) {		EVP_PKEY_free(conn->private_key);		conn->private_key = NULL;	}	return -1;#else /* OPENSSL_NO_ENGINE */	return 0;#endif /* OPENSSL_NO_ENGINE */}static void tls_engine_deinit(struct tls_connection *conn){#ifndef OPENSSL_NO_ENGINE	wpa_printf(MSG_DEBUG, "ENGINE: engine deinit");	if (conn->private_key) {		EVP_PKEY_free(conn->private_key);		conn->private_key = NULL;	}	if (conn->engine) {		ENGINE_finish(conn->engine);		conn->engine = NULL;	}#endif /* OPENSSL_NO_ENGINE */}int tls_get_errors(void *ssl_ctx){	int count = 0;	unsigned long err;	while ((err = ERR_get_error())) {		wpa_printf(MSG_INFO, "TLS - SSL error: %s",			   ERR_error_string(err, NULL));		count++;	}	return count;}struct tls_connection * tls_connection_init(void *ssl_ctx){	SSL_CTX *ssl = ssl_ctx;	struct tls_connection *conn;	conn = malloc(sizeof(*conn));	if (conn == NULL)		return NULL;	memset(conn, 0, sizeof(*conn));	conn->ssl = SSL_new(ssl);	if (conn->ssl == NULL) {		wpa_printf(MSG_INFO, "TLS: Failed to initialize new SSL "			   "connection: %s",			   ERR_error_string(ERR_get_error(), NULL));		free(conn);		return NULL;	}	SSL_set_app_data(conn->ssl, conn);	SSL_set_options(conn->ssl,			SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |			SSL_OP_SINGLE_DH_USE);	conn->ssl_in = BIO_new(BIO_s_mem());	if (!conn->ssl_in) {		wpa_printf(MSG_INFO, "SSL: Failed to create a new BIO for "			   "ssl_in: %s",			   ERR_error_string(ERR_get_error(), NULL));		SSL_free(conn->ssl);		free(conn);		return NULL;	}	conn->ssl_out = BIO_new(BIO_s_mem());	if (!conn->ssl_out) {		wpa_printf(MSG_INFO, "SSL: Failed to create a new BIO for "			   "ssl_out: %s",			   ERR_error_string(ERR_get_error(), NULL));		SSL_free(conn->ssl);		BIO_free(conn->ssl_in);		free(conn);		return NULL;	}	SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out);	return conn;}void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn){	if (conn == NULL)		return;	SSL_free(conn->ssl);	tls_engine_deinit(conn);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -