TLSv1.2及Https协议示例

编译

SSL/TLS client server examples using openssl

## Build
$ mkdir build
$ cd build
$ cmake ..
$ make
$ cp -rf ../certs ./

测试运行

### Server side
$ ./server
Certificate Verify Success
Client Hello World
```


### Client Side
$ ./client
Socket successfully created..
connected to the server..
Certificate Verify Success
SSL server send Client Hello World Appended by SSL serve
```

证书

示例代码

//ssl_client_libssl.c
#define SSL_CLIENT_RSA_CERT	"./certs/client.crt"
#define SSL_CLIENT_RSA_KEY	"./certs/client.key"
#define SSL_CLIENT_RSA_CA_CERT	"./certs/ca.crt"
#define SSL_SERVER_ADDR		"/tmp/ssl_server"
#define OFF	0
#define ON	1
#define USE_AF_UNIX 0
#define MAX 80
#define IP  "127.0.0.1"
#define PORT 10001
#define SA struct sockaddr

int main(void)
{
	int verify_peer = ON;
	SSL_METHOD *client_meth;
	SSL_CTX *ssl_client_ctx;
	int clientsocketfd;
	int handshakestatus;
	SSL *clientssl;
	char buffer[1024] = "Client Hello World";
	int ret;

	SSL_library_init();
	SSL_load_error_strings();
	client_meth = TLSv1_2_client_method();
	ssl_client_ctx = SSL_CTX_new(client_meth);

	if(!ssl_client_ctx)
	{
		ERR_print_errors_fp(stderr);
		return -1;
	}
	printf("[c]SSL init successfully\n");

	if(verify_peer)
	{
		if(SSL_CTX_use_certificate_file(ssl_client_ctx, SSL_CLIENT_RSA_CERT, SSL_FILETYPE_PEM) <= 0)
		{
			ERR_print_errors_fp(stderr);
			return -1;
		}


		if(SSL_CTX_use_PrivateKey_file(ssl_client_ctx, SSL_CLIENT_RSA_KEY, SSL_FILETYPE_PEM) <= 0)
		{
			ERR_print_errors_fp(stderr);
			return -1;
		}

		if(SSL_CTX_check_private_key(ssl_client_ctx) != 1)
		{
			printf("[c]Private and certificate is not matching\n");
			return -1;
		}
		printf("[c]Private and certificate successfully\n");
	}

	//See function man pages for instructions on generating CERT files
	if(!SSL_CTX_load_verify_locations(ssl_client_ctx, SSL_CLIENT_RSA_CA_CERT, NULL))
	{
		ERR_print_errors_fp(stderr);
		return -1;
	}

	SSL_CTX_set_verify(ssl_client_ctx, SSL_VERIFY_PEER, NULL);
	SSL_CTX_set_verify_depth(ssl_client_ctx, 4);

	#if USE_AF_UNIX
		struct sockaddr_un serveraddr;
		if((clientsocketfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
		{
			printf("[c]Error on socket creation\n");
			return -1;
		}
		memset(&serveraddr, 0, sizeof(struct sockaddr_un));
		serveraddr.sun_family = AF_UNIX;
		serveraddr.sun_path[0] = 0;
		strncpy(&(serveraddr.sun_path[1]), SSL_SERVER_ADDR, strlen(SSL_SERVER_ADDR) + 1);
		connect(clientsocketfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr_un));
	#else
		struct sockaddr_in serveraddr;
		// socket create and varification
		clientsocketfd = socket(AF_INET, SOCK_STREAM, 0);
		if (clientsocketfd == -1) {
			printf("[c]socket creation failed...\n");
			exit(0);
		}
		else
			printf("[c]Socket successfully created OK..\n");
		bzero(&serveraddr, sizeof(serveraddr));

		// assign IP, PORT
		serveraddr.sin_family = AF_INET;
		serveraddr.sin_addr.s_addr = inet_addr(IP);
		serveraddr.sin_port = htons(PORT);

		// connect the client socket to server socket
		if (connect(clientsocketfd, (SA*)&serveraddr, sizeof(serveraddr)) != 0) {
			printf("[c]connection with the server failed...\n");
			exit(0);
		}
		else
			printf("[c]connected to the server OK..\n");
	#endif


	clientssl = SSL_new(ssl_client_ctx);
	if(!clientssl)
	{
		printf("[c]Error SSL_new\n");
		return -1;
	}
	SSL_set_fd(clientssl, clientsocketfd);
	printf("[c]clientssl=%d,clientsocketfd=%d\n",clientssl,clientsocketfd);

	if((ret = SSL_connect(clientssl)) != 1)
	{
		printf("[c]SSL_connect,Handshake Error %d\n", SSL_get_error(clientssl, ret));
		return -1;
	}
    printf("[c]Handshake OK..\n"); 
  
	X509 *ssl_client_cert = NULL;

	ssl_client_cert = SSL_get_peer_certificate(clientssl);

	if(ssl_client_cert)
	{
		long verifyresult;

		verifyresult = SSL_get_verify_result(clientssl);
		if(verifyresult == X509_V_OK)
			printf("[c]Certificate Verify Success\n");
		else
			printf("[c]Certificate Verify Failed\n");
		X509_free(ssl_client_cert);
	}
	else
		printf("[c]There is no client certificate\n");

	SSL_write(clientssl, buffer, strlen(buffer));
	printf("[c]SSL client send: %s\n", buffer);
	memset(buffer, 0, sizeof(buffer));
	SSL_read(clientssl, buffer, sizeof(buffer));
	printf("[c]SSL client recv: %s\n", buffer);
	SSL_shutdown(clientssl);
	close(clientsocketfd);
	SSL_free(clientssl);
	SSL_CTX_free(ssl_client_ctx);
	return 0;
}
//ssl_server_libssl.c

int main(void)
{
	int verify_peer = ON;
	const SSL_METHOD *server_meth;
	SSL_CTX *ssl_server_ctx;
	int serversocketfd;
	int clientsocketfd;
	int handshakestatus;

	SSL_library_init();
	SSL_load_error_strings();
	server_meth = TLSv1_2_server_method();
	ssl_server_ctx = SSL_CTX_new(server_meth);

	if(!ssl_server_ctx)
	{
		ERR_print_errors_fp(stderr);
		return -1;
	}
	printf("[s]SSL init successfully\n");

	if(SSL_CTX_use_certificate_file(ssl_server_ctx, SSL_SERVER_RSA_CERT, SSL_FILETYPE_PEM) <= 0)
	{
		ERR_print_errors_fp(stderr);
		return -1;
	}


	if(SSL_CTX_use_PrivateKey_file(ssl_server_ctx, SSL_SERVER_RSA_KEY, SSL_FILETYPE_PEM) <= 0)
	{
		ERR_print_errors_fp(stderr);
		return -1;
	}

	if(SSL_CTX_check_private_key(ssl_server_ctx) != 1)
	{
		printf("[s]Private and certificate is not matching\n");
		return -1;
	}
	printf("[s]Private and certificate successfully\n");

	if(verify_peer)
	{
		//See function man pages for instructions on generating CERT files
		if(!SSL_CTX_load_verify_locations(ssl_server_ctx, SSL_SERVER_RSA_CA_CERT, NULL))
		{
			ERR_print_errors_fp(stderr);
			return -1;
		}
		SSL_CTX_set_verify(ssl_server_ctx, SSL_VERIFY_PEER, NULL);
		SSL_CTX_set_verify_depth(ssl_server_ctx, 1);
	}

	#if USE_AF_UNIX
		struct sockaddr_un serveraddr;

		if((serversocketfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
		{
			printf("[s]Error on socket creation\n");
			return -1;
		}
		memset(&serveraddr, 0, sizeof(struct sockaddr_un));
		serveraddr.sun_family = AF_UNIX;
		serveraddr.sun_path[0] = 0;
		strncpy(&(serveraddr.sun_path[1]), SSL_SERVER_ADDR, strlen(SSL_SERVER_ADDR) + 1);
		if(bind(serversocketfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr_un)))
		{
			printf("[s]server bind error\n");
			return -1;
		}
	#else
		struct sockaddr_in serveraddr;

		if((serversocketfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		{
			printf("[s]Error on socket creation\n");
			return -1;
		}

		memset(&serveraddr, 0, sizeof(struct sockaddr_in));

		// assign IP, PORT
    	    serveraddr.sin_family = AF_INET;
    	    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    	    serveraddr.sin_port = htons(PORT);

		if ((bind(serversocketfd, (SA*)&serveraddr, sizeof(serveraddr))) != 0)
		{
			printf("[s]server bind error\n");
			return -1;
		}
		printf("[s]server bind OK\n");
	#endif


	if(listen(serversocketfd, SOMAXCONN))
	{
		printf("[s]Error on listen\n");
		return -1;
	}
	printf("[s]server listen OK\n");

	while(1)
	{
		SSL *serverssl;
		char buffer[1024] = {0};
		int bytesread = 0;
		int addedstrlen;
		int ret;

		clientsocketfd = accept(serversocketfd, NULL, 0);
		serverssl = SSL_new(ssl_server_ctx);
		if(!serverssl)
		{
			printf("[s]Error SSL_new\n");
			return -1;
		}
		SSL_set_fd(serverssl, clientsocketfd);
		printf("[s]serverssl=%d,clientsocketfd=%d\n",serverssl,clientsocketfd);

		if((ret = SSL_accept(serverssl))!= 1)
		{
			printf("[s]SSL_accept,Handshake Error %d\n", SSL_get_error(serverssl, ret));
			return -1;
		}
		printf("[s]Handshake OK..\n"); 

		if(verify_peer)
		{
			X509 *ssl_client_cert = NULL;

			ssl_client_cert = SSL_get_peer_certificate(serverssl);

			if(ssl_client_cert)
			{
				long verifyresult;

				verifyresult = SSL_get_verify_result(serverssl);
				if(verifyresult == X509_V_OK)
					printf("[s]Certificate Verify Success\n");
				else
					printf("[s]Certificate Verify Failed\n");
				X509_free(ssl_client_cert);
			}
			else
				printf("[s]There is no client certificate\n");
		}
		bytesread = SSL_read(serverssl, buffer, sizeof(buffer));
		addedstrlen = strlen("Appended by SSL server");
		printf("[s]SSL server recv:%s\n", buffer);
		strncpy(&buffer[bytesread], " Appended by SSL server", addedstrlen);
		SSL_write(serverssl, buffer, bytesread + addedstrlen);
		printf("[s]SSL server send:%s\n", buffer);
		SSL_shutdown(serverssl);
		close(clientsocketfd);
		clientsocketfd = -1;
		SSL_free(serverssl);
		serverssl = NULL;
	}
	close(serversocketfd);
	SSL_CTX_free(ssl_server_ctx);
	return 0;
}
原创文章 96 获赞 48 访问量 6万+

猜你喜欢

转载自blog.csdn.net/wteruiycbqqvwt/article/details/101286689
今日推荐