LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2143|回复: 0

如何使用openssl写https服务

[复制链接]
发表于 2008-3-10 17:33:59 | 显示全部楼层 |阅读模式
首先,创建私钥
openssl genrsa -out privkey.pem 2048
通过私钥创建证书(自签名,有效期一年)
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 365
也可以创建成向某个CA提交的证书注册申请,但因为一般CA价格昂贵,所以这里不推荐
最后编程实践,以下是个例子
  1. #include <openssl/ssl.h>
  2. #include <stdio.h>
  3. #include <sys/socket.h>
  4. #include <arpa/inet.h>
  5. #include <errno.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <fcntl.h>
  9. #define CHECKRESULT( fun, ret)\
  10.         if( (ret)<0) {fprintf(stderr, "line %d function "#fun" failed: %s\n",__LINE__,strerror(errno));}
  11. typedef struct _ssl_server
  12. {
  13.         SSL_CTX*        ctx;
  14.         char*                cafile;
  15.         char*                keyfile;
  16.         int                        sock;//监听用的socket,默认绑定在443端口       
  17. } SSLServer;
  18. int
  19. sock_select( int sock, int seconds, int useconds)
  20. {
  21.         int ret;
  22.         struct timeval tv;
  23.         fd_set rfds;
  24.         FD_ZERO(&rfds);
  25.         FD_SET((unsigned)sock,&rfds);
  26.         tv.tv_usec=useconds;
  27.         tv.tv_sec=seconds;
  28.         ret = select(sock+1,&rfds,NULL,NULL,&tv);
  29.         FD_CLR((unsigned)sock,&rfds);
  30.         return ret;
  31. }
  32. int main( int argc, char* argv[])
  33. {
  34.         if( argc < 3) {
  35.                 puts("Wrong usage");
  36.                 printf("%s $(Cert File) $(Key file)\n", argv[0]);
  37.                 return -1;
  38.         }
  39.         //创建SSL上下文       
  40.         SSLServer server;
  41.         server.cafile = argv[1];
  42.         server.keyfile = argv[2];
  43.         SSL_load_error_strings( );
  44.         SSLeay_add_ssl_algorithms( );        
  45.         server.ctx = SSL_CTX_new( SSLv23_server_method());
  46.         if (SSL_CTX_use_certificate_file( server.ctx, server.cafile, SSL_FILETYPE_PEM) <= 0) {
  47.                 ERR_print_errors_fp(stderr);
  48.                 exit(3);
  49.         }
  50.         if (SSL_CTX_use_PrivateKey_file( server.ctx, server.keyfile, SSL_FILETYPE_PEM) <= 0) {
  51.                 ERR_print_errors_fp(stderr);
  52.                 exit(4);
  53.         }                     
  54.         if (SSL_CTX_check_private_key( server.ctx)<= 0){
  55.                 ERR_print_errors_fp(stderr);
  56.                 exit(4);
  57.         }
  58.        
  59.         //创建监听socket
  60.         int rc;
  61.         server.sock = socket( PF_INET, SOCK_STREAM, 0);
  62.         CHECKRESULT( socket, server.sock);
  63.         struct sockaddr_in addr;
  64.         addr.sin_addr.s_addr = 0;
  65.         addr.sin_family = AF_INET;
  66.         addr.sin_port = htons( 4443);
  67.         rc = bind( server.sock, (struct sockaddr*)&addr, sizeof(addr));
  68.         CHECKRESULT( bind, rc);
  69.         //rc = fcntl( server.sock, F_SETFL, O_NONBLOCK);
  70.         //CHECKRESULT( fcntl, rc);
  71.         rc = listen( server.sock, SOMAXCONN);
  72.         CHECKRESULT( listen, rc);
  73.        
  74.         //主循环       
  75.         while( 1) {
  76.                 char buf[4096] = {0};
  77.                 int         newsock = -1;
  78.                 struct sockaddr from;
  79.                 long sz;
  80.                 size_t fromlen = sizeof(from);
  81.                 newsock = accept( server.sock, &from, &fromlen);
  82.                 if( newsock < 0 && EINTR == errno)
  83.                         continue;
  84.                 SSL* ssl = SSL_new( server.ctx);
  85.                 SSL_set_fd( ssl, newsock);
  86.                 SSL_accept( ssl);               
  87.                
  88.                 while( sock_select( newsock, 1, 0) > 0) {
  89.                         sz = SSL_read( ssl, buf, sizeof(buf));
  90.                         if( sz == -1) break;
  91.                         puts( buf);
  92.                 }
  93.                 strcpy(buf, "HTTP/1.1 200 OK\r\n"
  94.                         "Server:TESTSSL\r\n"
  95.                         "Content-Type:text/plain\r\n"
  96.                         "Connection:close\r\n"
  97.                         "Accept-Ranges: bytes\r\n"
  98.                         "Content-Length:14\r\n\r\n"                       
  99.                         "Hello OPENSSL!");
  100.                 SSL_write( ssl, buf, strlen(buf));                                                     
  101.                 SSL_free( ssl);
  102.         }
  103.         return 0;
  104.        
  105. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表