近來研究如何使用openssl進行編程,下面是一些概要。
1.使用相同的ca生成兩個證書,一個是server.cer,一個是client.cer,注意生成server.cer的時候必須指明證書可以用於服務端的。
服務器代碼:
客戶端代碼
- #include "openssl/bio.h"
- #include "openssl/ssl.h"
- #include "openssl/err.h"
- #include <cutil.h>
- #define EXIT_IF_TRUE(x) if (x) \
- do { \
- fprintf(stderr, "Check '%s' is true\n", #x); \
- ERR_print_errors_fp(stderr); \
- exit(2); \
- }while(0)
- int main(int argc, char **argv)
- {
- SSL_CTX *ctx;
- SSL *ssl;
- X509 *client_cert;
- char szBuffer[1024];
- int nLen;
- struct sockaddr_in addr;
- int len;
- int nListenFd, nAcceptFd;
- // 初始化
- cutil_init();
- cutil_log_set_level(LOG_ALL);
- cutil_log_set_stderr(1);
- SSLeay_add_ssl_algorithms();
- OpenSSL_add_all_algorithms();
- SSL_load_error_strings();
- ERR_load_BIO_strings();
- // 我們使用SSL V3,V2
- EXIT_IF_TRUE((ctx = SSL_CTX_new (SSLv23_method())) == NULL);
- // 要求校驗對方證書
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
- // 加載CA的證書
- EXIT_IF_TRUE (!SSL_CTX_load_verify_locations(ctx, "cacert.cer", NULL));
- // 加載自己的證書
- EXIT_IF_TRUE (SSL_CTX_use_certificate_file(ctx, "server.cer", SSL_FILETYPE_PEM) <= 0) ;
- // 加載自己的私鑰
- EXIT_IF_TRUE (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) <= 0) ;
- // 判定私鑰是否正確
- EXIT_IF_TRUE (!SSL_CTX_check_private_key(ctx));
- // 創建並等待連接
- nListenFd = cutil_socket_new(SOCK_STREAM);
- cutil_socket_bind(nListenFd, NULL, 8812, 1);
- memset(&addr, 0, sizeof(addr));
- len = sizeof(addr);
- nAcceptFd = accept(nListenFd, (struct sockaddr *)&addr, (size_t *)&len);
- cutil_log_debug("Accept a connect from [%s:%d]\n",
- inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
- // 將連接付給SSL
- EXIT_IF_TRUE( (ssl = SSL_new (ctx)) == NULL);
- SSL_set_fd (ssl, nAcceptFd);
- EXIT_IF_TRUE( SSL_accept (ssl) != 1);
- // 進行操作
- memset(szBuffer, 0, sizeof(szBuffer));
- nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));
- fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);
- strcat(szBuffer, " this is from server");
- SSL_write(ssl, szBuffer, strlen(szBuffer));
- // 釋放資源
- SSL_free (ssl);
- SSL_CTX_free (ctx);
- close(nAcceptFd);
- }
- #include "openssl/bio.h"
- #include "openssl/ssl.h"
- #include "openssl/err.h"
- #include <cutil.h>
- #define EXIT_IF_TRUE(x) if (x) \
- do { \
- fprintf(stderr, "Check '%s' is true\n", #x); \
- ERR_print_errors_fp(stderr); \
- exit(2); \
- }while(0)
- int main(int argc, char **argv)
- {
- SSL_METHOD *meth;
- SSL_CTX *ctx;
- SSL *ssl;
- int nFd;
- int nLen;
- char szBuffer[1024];
- // 初始化
- cutil_init();
- cutil_log_set_level(LOG_ALL);
- cutil_log_set_stderr(1);
- SSLeay_add_ssl_algorithms();
- OpenSSL_add_all_algorithms();
- SSL_load_error_strings();
- ERR_load_BIO_strings();
- // 我們使用SSL V3,V2
- EXIT_IF_TRUE((ctx = SSL_CTX_new (SSLv23_method())) == NULL);
- // 要求校驗對方證書
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
- // 加載CA的證書
- EXIT_IF_TRUE (!SSL_CTX_load_verify_locations(ctx, "cacert.cer", NULL));
- // 加載自己的證書
- EXIT_IF_TRUE (SSL_CTX_use_certificate_file(ctx, "client.cer", SSL_FILETYPE_PEM) <= 0) ;
- // 加載自己的私鑰
- EXIT_IF_TRUE (SSL_CTX_use_PrivateKey_file(ctx, "client.key", SSL_FILETYPE_PEM) <= 0) ;
- // 判定私鑰是否正確
- EXIT_IF_TRUE (!SSL_CTX_check_private_key(ctx));
- // 創建連接
- nFd = cutil_socket_new(SOCK_STREAM);
- if(cutil_socket_connect(nFd, "127.0.0.1", 8812, 30) < 0)
- {
- cutil_log_error("連接服務器失敗\n");
- return -1;
- }
- // 將連接付給SSL
- EXIT_IF_TRUE( (ssl = SSL_new (ctx)) == NULL);
- SSL_set_fd (ssl, nFd);
- EXIT_IF_TRUE( SSL_connect (ssl) != 1);
- // 進行操作
- sprintf(szBuffer, "this is from client %d", getpid());
- SSL_write(ssl, szBuffer, strlen(szBuffer));
- // 釋放資源
- memset(szBuffer, 0, sizeof(szBuffer));
- nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));
- fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);
- SSL_free (ssl);
- SSL_CTX_free (ctx);
- close(nFd);
- }