客户端程序代码:
-
- #include <winsock2.h>
- #include <conio.h>
- #include <stdio.h>
- #include "openssl/x509.h"
- #include "openssl/ssl.h"
- #include "openssl/err.h"
- #include "openssl/rand.h"
-
- #define PORT 1111
- #define SERVER "127.0.0.1"
- #define CACERT "ca.crt"
- #define MYCERTF "yuliding.crt"
- #define MYKEYF "yuliding.key"
- #define MSGLENGTH 1024
-
- int main()
- {
- WSADATA wsadata;
- WSAStartup(MAKEWORD(2,2), &wsadata);
- sockaddr_in sin;
- int seed_int[100];
-
- SSL*ssl;
- SSL_METHOD *meth;
- SSL_CTX *ctx;
-
-
- OpenSSL_add_ssl_algorithms();
-
- SSL_load_error_strings();
-
-
- meth = TLSv1_client_method();
-
- ctx = SSL_CTX_new(meth);
- if (NULL == ctx)
- exit(1);
-
-
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
- SSL_CTX_load_verify_locations(ctx, CACERT, NULL);
-
- if (0 >= SSL_CTX_use_certificate_file(ctx, MYCERTF, SSL_FILETYPE_PEM)) {
- ERR_print_errors_fp(stderr);
- exit(1);
- }
-
- if (0 >= SSL_CTX_use_PrivateKey_file(ctx, MYKEYF, SSL_FILETYPE_PEM)) {
- ERR_print_errors_fp(stderr);
- exit(1);
- }
-
- if (!SSL_CTX_check_private_key(ctx)) {
- printf("Private key does not match the certificate public key\n");
- exit(1);
- }
-
- srand((unsigned)time(NULL));
- for (int i = 0; i < 100; i++)
- seed_int[i] = rand();
- RAND_seed(seed_int, sizeof(seed_int));
-
-
- SSL_CTX_set_cipher_list(ctx, "RC4-MD5");
-
- SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
-
-
- SOCKET sock;
- printf("Begin tcp socket...\n");
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock == INVALID_SOCKET) {
- printf("SOCKET有问题. \n");
- }
-
- memset(&sin, '\0', sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = inet_addr(SERVER);
- sin.sin_port = htons(PORT);
-
- int icnn = connect(sock, (sockaddr *)&sin, sizeof(sin));
- if (icnn == SOCKET_ERROR) {
- printf("连不上服务器\n", GetLastError());
- exit(1);
- }
-
-
-
- ssl = SSL_new(ctx);
- if (NULL == ssl)
- exit(1);
- if (0 >= SSL_set_fd(ssl, sock)) {
- printf("Attach to Line fail!\n");
- exit(1);
- }
-
-
- int k = SSL_connect(ssl);
- if (0 >= k) {
- printf("%d\n", k);
- printf("SSL connect fail!\n");
- exit(1);
- }
- printf("连接服务器成功\n");
-
- char sendmsg[MSGLENGTH] = "\0";
- char revmsg[MSGLENGTH] = "\0";
-
- int err = SSL_read(ssl, revmsg, sizeof(revmsg));
- revmsg[err] = '\0';
- printf("%s\n", revmsg);
-
- while (1) {
- printf("请输入所要发送的数据:\n");
- scanf("%s", sendmsg);
- SSL_write(ssl, sendmsg, strlen(sendmsg));
- printf("发送消息“ %s ”成功!\n", sendmsg);
- }
-
-
- SSL_shutdown(ssl);
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- closesocket(sock);
- WSACleanup();
- getch();
- return 0;
- }
服务端程序代码:
-
- #include <winsock2.h>
- #include <conio.h>
- #include <stdio.h>
- #include <winsock.h>
- #include "openssl/x509.h"
- #include "openssl/ssl.h"
- #include "openssl/err.h"
-
- #define MSGLENGTH 1024
- #define PORT 1111
- #define CACERT "ca.crt"
- #define SVRCERTF "server.crt"
- #define SVRKEYF "server.key"
-
- int main()
- {
- WSADATA wsaData;
- WSAStartup(MAKEWORD(2,2), &wsaData);
- SOCKET sock;
- SSL_METHOD *meth;
- SSL_CTX* ctx;
- SSL* ssl;
-
- OpenSSL_add_ssl_algorithms();
-
- SSL_load_error_strings();
-
-
- meth = TLSv1_server_method();
-
- ctx = SSL_CTX_new(meth);
- if (NULL == ctx)
- exit(1);
-
-
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
- SSL_CTX_load_verify_locations(ctx, CACERT, NULL);
-
- if (0 >= SSL_CTX_use_certificate_file(ctx, SVRCERTF, SSL_FILETYPE_PEM)) {
- ERR_print_errors_fp(stderr);
- exit(1);
- }
-
- if (0 >= SSL_CTX_use_PrivateKey_file(ctx, SVRKEYF, SSL_FILETYPE_PEM)) {
- ERR_print_errors_fp(stderr);
- exit(1);
- }
-
- if (!SSL_CTX_check_private_key(ctx)) {
- printf("Private key does not match the certificate public key\n");
- exit(1);
- }
-
-
- SSL_CTX_set_cipher_list(ctx, "RC4-MD5");
-
- SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
-
-
- printf("Begin tcp socket...\n");
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock == INVALID_SOCKET) {
- printf("SOCKET有问题. \n");
- return 0;
- }
-
- sockaddr_in addr;
- memset(&addr, '\0', sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(PORT);
- addr.sin_addr.s_addr = INADDR_ANY;
-
-
- int nResult = bind(sock, (sockaddr *)&addr, sizeof(addr));
- if (nResult == SOCKET_ERROR) {
- printf("绑定SOCKET有问题. \n");
- return 0;
- }
- printf("服务器启动成功,端口:%d\n正在等待连接\n", PORT);
-
-
- sockaddr_in sa_cli;
- int err = listen(sock, 5);
- if (-1 == err)
- exit(1);
- int client_len = sizeof(sa_cli);
- int ss = accept(sock, (struct sockaddr *) &sa_cli, &client_len);
- if (ss == -1) {
- exit(1);
- }
- closesocket(sock);
- printf("Connection from %d, port %d\n", sa_cli.sin_addr.s_addr, sa_cli.sin_port);
-
-
-
- ssl = SSL_new(ctx);
- if (NULL == ssl)
- exit(1);
- if (0 >= SSL_set_fd(ssl, ss)) {
- printf("Attach to Line fail!\n");
- exit(1);
- }
-
-
- int k = SSL_accept(ssl);
- if (0 >= k) {
- printf("%d\n", k);
- printf("SSL connect fail!\n");
- exit(1);
- }
-
- X509 *client_cert;
- client_cert = SSL_get_peer_certificate(ssl);
-
- printf("发现客户端尝试连接\n");
- if (client_cert != NULL) {
- printf ("Client certificate:\n");
-
-
- char *str = X509_NAME_oneline(X509_get_subject_name(client_cert), 0, 0);
- if (NULL == str) {
- printf("认证出错!\n");
- exit(1);
- }
- printf("subject: %s\n", str);
-
- str = X509_NAME_oneline(X509_get_issuer_name(client_cert), 0, 0);
- if (NULL == str) {
- printf("证书名为空\n");
- exit(1);
- }
- printf("issuer: %s\n", str);
- printf("连接成功\n");
-
- X509_free (client_cert);
- OPENSSL_free(str);
- }
- else {
- printf("找不到客户端的认证证书\n");
- exit(1);
- }
-
- char buf[MSGLENGTH];
- SSL_write(ssl, "Server is connect to you!\n", strlen("Server is connect to you!\n"));
- printf("Listen to the client: \n");
- while (1) {
- err = SSL_read(ssl, buf, sizeof(buf));
- buf[err] = '\0';
- printf("%s\n", buf);
- }
-
-
- SSL_shutdown(ssl);
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- WSACleanup();
- getch();
- return 0;
- }