
使用相同的ca生成两个证书,一个是server.cer,一个是client.cer,注意生成server.cer的时候必须指明证书可以用于服务端的。
服务器代码:
1.#include "openssl/bio.h"
2.#include "openssl/ssl.h"
3.#include "openssl/err.h"
4.
5.#include 6. 7.#define EXIT_IF_TRUE(x) if (x) \\ 8. do { \\ 9. fprintf(stderr, "Check '%s' is true\\n", #x); \\ 10. ERR_print_errors_fp(stderr); \\ 11. exit(2); \\ 12. }while(0) 13. 14.int main(int argc, char **argv) 15.{ 16. SSL_CTX *ctx; 17. SSL *ssl; 18. X509 *client_cert; 19. 20. char szBuffer[1024]; 21. int nLen; 22. 23. struct sockaddr_in addr; 24. int len; 25. int nListenFd, nAcceptFd; 26. 27. // 初始化 28. cutil_init(); 29. cutil_log_set_level(LOG_ALL); 30. cutil_log_set_stderr(1); 31. SSLeay_add_ssl_algorithms(); 32. OpenSSL_add_all_algorithms(); 33. SSL_load_error_strings(); 34. ERR_load_BIO_strings(); 35. 36. // 我们使用SSL V3,V2 37. EXIT_IF_TRUE((ctx = SSL_CTX_new (SSLv23_method())) == NULL); 38. 39. // 要求校验对方证书 40. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 41. 42. // 加载CA的证书 43. EXIT_IF_TRUE (!SSL_CTX_load_verify_locations(ctx, "cacert.cer", NULL)); 44. 45. // 加载自己的证书 46. EXIT_IF_TRUE (SSL_CTX_use_certificate_file(ctx, "server.cer", SSL_FILETYPE_PEM) <= 0) ; 47. 48. // 加载自己的私钥 49. EXIT_IF_TRUE (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) <= 0) ; 50. 51. // 判定私钥是否正确 52. EXIT_IF_TRUE (!SSL_CTX_check_private_key(ctx)); 53. 54. // 创建并等待连接 55. nListenFd = cutil_socket_new(SOCK_STREAM); 56. cutil_socket_bind(nListenFd, NULL, 8812, 1); 57. 58. memset(&addr, 0, sizeof(addr)); 59. len = sizeof(addr); 60. nAcceptFd = accept(nListenFd, (struct sockaddr *)&addr, (size_t *)&len); 61. cutil_log_debug("Accept a connect from [%s:%d]\\n", 62. inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); 63. . // 将连接付给SSL 65. EXIT_IF_TRUE( (ssl = SSL_new (ctx)) == NULL); 66. SSL_set_fd (ssl, nAcceptFd); 67. EXIT_IF_TRUE( SSL_accept (ssl) != 1); 68. 69. // 进行操作 70. memset(szBuffer, 0, sizeof(szBuffer)); 71. nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer)); 72. fprintf(stderr, "Get Len %d %s ok\\n", nLen, szBuffer); 73. strcat(szBuffer, " this is from server"); 74. SSL_write(ssl, szBuffer, strlen(szBuffer)); 75. 76. // 释放资源 77. SSL_free (ssl); 78. SSL_CTX_free (ctx); 79. close(nAcceptFd); 80.} 客户端代码 1.#include "openssl/bio.h" 2.#include "openssl/ssl.h" 3.#include "openssl/err.h" 4. 5.#include 6. 7.#define EXIT_IF_TRUE(x) if (x) \\ 8. do { \\ 9. fprintf(stderr, "Check '%s' is true\\n", #x); \\ 10. ERR_print_errors_fp(stderr); \\ 11. exit(2); \\ 12. }while(0) 13. 14.int main(int argc, char **argv) 15.{ 16. SSL_METHOD *meth; 17. SSL_CTX *ctx; 18. SSL *ssl; 19. 20. int nFd; 21. int nLen; 22. char szBuffer[1024]; 23. 24. // 初始化 25. cutil_init(); 26. cutil_log_set_level(LOG_ALL); 27. cutil_log_set_stderr(1); 28. SSLeay_add_ssl_algorithms(); 29. OpenSSL_add_all_algorithms(); 30. SSL_load_error_strings(); 31. ERR_load_BIO_strings(); 32. 33. // 我们使用SSL V3,V2 34. EXIT_IF_TRUE((ctx = SSL_CTX_new (SSLv23_method())) == NULL); 35. 36. // 要求校验对方证书 37. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 38. 39. // 加载CA的证书 40. EXIT_IF_TRUE (!SSL_CTX_load_verify_locations(ctx, "cacert.cer", NULL)); 41. 42. // 加载自己的证书 43. EXIT_IF_TRUE (SSL_CTX_use_certificate_file(ctx, "client.cer", SSL_FILETYPE_PEM) <= 0) ; 44. 45. // 加载自己的私钥 46. EXIT_IF_TRUE (SSL_CTX_use_PrivateKey_file(ctx, "client.key", SSL_FILETYPE_PEM) <= 0) ; 47. 48. // 判定私钥是否正确 49. EXIT_IF_TRUE (!SSL_CTX_check_private_key(ctx)); 50. 51. // 创建连接 52. nFd = cutil_socket_new(SOCK_STREAM); 53. if(cutil_socket_connect(nFd, "127.0.0.1", 8812, 30) < 0) 54. { 55. cutil_log_error("连接服务器失败\\n"); 56. return -1; 57. } 58. 59. // 将连接付给SSL 60. EXIT_IF_TRUE( (ssl = SSL_new (ctx)) == NULL); 61. SSL_set_fd (ssl, nFd); 62. EXIT_IF_TRUE( SSL_connect (ssl) != 1); 63. . // 进行操作 65. sprintf(szBuffer, "this is from client %d", getpid()); 66. SSL_write(ssl, szBuffer, strlen(szBuffer)); 67. 68. // 释放资源 69. memset(szBuffer, 0, sizeof(szBuffer)); 70. nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer)); 71. fprintf(stderr, "Get Len %d %s ok\\n", nLen, szBuffer); 72. 73. SSL_free (ssl); 74. SSL_CTX_free (ctx); 75. close(nFd); 76.}
