OPENSSL https 证书的使用Demo(证书加密码)

本文详细阐述了如何使用SSL进行TCP连接,并实现HTTPS请求的发送与接收过程,包括SSL上下文初始化、证书验证配置、SSL连接建立以及数据读写等关键步骤。

int httpsHandler(char *host, int port, char *requestpath, char *iso_buf, int len ,int method, int flag, char *certPath,char *mch_id )
{ 
    int fd;
    SSL *ssl;
    SSL_CTX *ctx;
    int nRet_Code, ret = 0;
    char buf[BUF_LEN];
    fd = create_tcpsocket(host, port, 60);

	const char *header2="User-Agent: Tuobao Http 1.1\r\nCache-Control: no-cache\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: */*\r\n";
	
	if(!method)
	{
		sprintf(buf, "GET https:\/\/%s%s%s HTTP/1.1\r\nHost:%s:%d\r\n\r\n",host,requestpath,iso_buf,host,port);
	}
    else
	{
		sprintf(buf, "POST https:\/\/%s%s HTTP/1.1\r\nHOST: %s:%d\r\n%sContent-Length: %d\r\n\r\n%s",host,requestpath,host,port, header2, len, iso_buf);
	}	

	printf("the request  data : [%s]\n",buf);
	if(fd == -1)
    {
        util_err_log( LERROR, "fail to create tcp socket.\n");
        return -1;
    }

    SSL_load_error_strings();
    SSL_library_init();
    ctx = SSL_CTX_new(SSLv23_client_method());
    if ( ctx == NULL )
    {
		util_err_log( LERROR, "init SSL CTX failed:%s\n", ERR_reason_error_string(ERR_get_error()));
		close(fd);
		return -1;
    }
	////////////////////////////////////
	if(flag)
    {
		// char tmpPath[260];
		// char tmpMch_id[20];
		// char tmpFile[25];
		
		// SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,NULL);
		// SSL_CTX_set_verify_depth(ctx, 10);
		// memset(tmpMch_id,0,sizeof(tmpMch_id));

		// strcpy(tmpMch_id,mch_id);
		// strcpy(tmpPath, certPath);
		// strcat(tmpPath, "cacert.pem");
		// printf("root ca path:%s\n", tmpPath);
		// SSL_CTX_load_verify_locations(ctx,tmpPath, NULL); 
		// SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(tmpPath));

		// strcpy(tmpPath, certPath);	
		// memset(tmpFile,0,sizeof(tmpFile));
		// sprintf(tmpFile, "%s.pem",tmpMch_id);
		// strcat(tmpPath, tmpFile);
		// printf("cert path:%s\n", tmpPath);
		
		// if(SSL_CTX_use_certificate_file(ctx, tmpPath, SSL_FILETYPE_PEM) <= 0)
		// 
			// printf("certificate file error!\n");
			// return -1;
		// }
		
		// memset(tmpFile,0,sizeof(tmpFile));
		// sprintf(tmpFile, "%s.pem",tmpMch_id);
		// strcpy(tmpPath, certPath);
		// strcat(tmpPath, tmpFile);
		
		// SSL_CTX_set_default_passwd_cb_userdata(ctx, "1900000109");
		// printf("private path:%s\n", tmpPath);
		// if(SSL_CTX_use_PrivateKey_file(ctx, tmpPath, SSL_FILETYPE_PEM) <= 0)
		// {
			// printf("private key file error!\n");
			// return -1;
		// }
		// if(!SSL_CTX_check_private_key(ctx))
		// {
			// printf("Check private key failed!\n");
			// return -1;
		// }	
		char tmpPath[260];
		SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb);
		SSL_CTX_set_verify_depth(ctx, 10);
		strcpy(tmpPath, certPath);
		strcat(tmpPath, "1900000109.pem");
		printf("root ca path:%s\n", tmpPath);
		SSL_CTX_load_verify_locations(ctx,tmpPath, NULL); 
		
		SSL_CTX_set_default_passwd_cb_userdata(ctx, "1900000109");
		 
		strcpy(tmpPath, certPath);
		strcat(tmpPath, "1900000109.pem");
		printf("cert path:%s\n", tmpPath);
		if(SSL_CTX_use_certificate_file(ctx, tmpPath, SSL_FILETYPE_PEM) <= 0)
		{
			printf("certificate file error!\n");
			return -1;
		}
		
		strcpy(tmpPath, certPath);
		strcat(tmpPath, "1900000109.pem");
		printf("cert path:%s\n", tmpPath);
		if(SSL_CTX_use_PrivateKey_file(ctx, tmpPath, SSL_FILETYPE_PEM) <= 0)
		{
			printf("private key file error!\n");
			return -1;
		}
		if(!SSL_CTX_check_private_key(ctx))
		{
			printf("Check private key failed!\n");
			return -1;
		}
	}
	
	/////////////////////////////////////////
    ssl = SSL_new(ctx);
    if ( ssl == NULL )
    {
		util_err_log( LERROR, "new SSL with created CTX failed:%s\n", ERR_reason_error_string(ERR_get_error()));
		close(fd);
		return -1;
    }
    nRet_Code = SSL_set_fd(ssl, fd);
    if ( nRet_Code == 0 )
    {
		util_err_log( LERROR, "add SSL to tcp socket failed:%s\n", ERR_reason_error_string(ERR_get_error()));
		close(fd);
		return -1;
    }
    /* PRNG */
    RAND_poll();
    while ( RAND_status() == 0 )
    {
        unsigned short rand_ret = rand() % 65536;
        RAND_seed(&rand_ret, sizeof(rand_ret));
    }
    /* SSL Connect */
    if( SSL_connect(ssl) != 1 )
    {
		util_err_log( LERROR, "SSL connection failed:%s\n", ERR_reason_error_string(ERR_get_error()));
		ret = -1;
		goto finish;
    }

    fflush(stdout);
	
	util_err_log( LERROR, "the ssl buf data for writing =[%s]",buf);
	printf("file,line>>>>>>>>>>>>>>>>\n");
    if(SSL_tcpWrite(fd, ssl, buf, strlen(buf), 600) != 0)
    {
        util_err_log( LERROR, "tcp write ssl socket failed.\n");
        ret = -1;
        goto finish;
    }
	util_err_log( LERROR, "the ssl buf data for writing =[%s]",buf);
	printf("fileline>>>>>>>>>>>>>>>>\n");
    memset(iso_buf, 0, 8192);

    if(SSL_tcpRead(fd, ssl, iso_buf, BUF_LEN-1, 600) < 0)
    {
        util_err_log( LERROR, "tcp read SSL socket failed.\n");
        ret = -1;
        goto finish;
    }
	printf("file>>>>>>>>>>>>>>>>\n");
	util_err_log( LERROR,"https returns response buffer:\n%s\n", iso_buf);
	
    /* close ssl tunnel.*/
finish:
	
    nRet_Code = SSL_shutdown(ssl); 	
    if( nRet_Code != 1 )
    {
		shutdown(fd,10);
        SSL_shutdown(ssl);	
    }
    /* close the plain socket handler.*/
    close(fd);
    /* clear ssl resource.*/
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    ERR_free_strings();
    return ret;
}

一、初始

   

SSL *ssl;
SSL_CTX *ctx;
SSL_load_error_strings();
SSL_library_init();
ctx = SSL_CTX_new(SSLv23_client_method());
if ( ctx == NULL )
{
<span style="white-space:pre">	</span>util_err_log( LERROR, "init SSL CTX failed:%s\n", ERR_reason_error_string(ERR_get_error()));
	close(fd);
	return -1;
}
</pre><p>二、</p><p></p><pre name="code" class="cpp">SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb);
<span style="white-space:pre">		</span>/*<span style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: 宋体;">缺省</span><span lang="EN-US" style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: Verdana;">mode</span><span style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: 宋体;">是</span><span lang="EN-US" style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: Verdana;">SSL_VERIFY_NONE,</span><span style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: 宋体;">如果想要验证对方的话</span><span lang="EN-US" style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: Verdana;">,</span><span style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: 宋体;">便要将此项变成</span><span lang="EN-US" style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: Verdana;">SSL_VERIFY_PEER.SSL/TLS</span><span style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: 宋体;">中缺省只验证</span><span lang="EN-US" style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: Verdana;">server,</span><span style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: 宋体;">如果没有设置</span><span lang="EN-US" style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: Verdana;"> SSL_VERIFY_PEER</span><span style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: 宋体;">的话</span><span lang="EN-US" style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: Verdana;">,</span><span style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: 宋体;">客户端连证书都不会发过来</span><span lang="EN-US" style="word-wrap: break-word; line-height: 26px; font-size: 10pt; font-family: Verdana;">.</span>*/
SSL_CTX_set_verify_depth(ctx, 10);<span style="color: rgb(102, 102, 102); font-family: 宋体, Arial; font-size: 16px; line-height: 26px;">  //设置最大的验证用户证书的上级数。</span><br style="word-wrap: break-word; color: rgb(102, 102, 102); font-family: 宋体, Arial; font-size: 16px; line-height: 26px;" />
三、

		SSL_CTX_load_verify_locations(ctx,"cacert.pem", NULL); //CA
		
		SSL_CTX_set_default_passwd_cb_userdata(ctx, "1900000109");//密码

		if(SSL_CTX_use_certificate_file(ctx, <span style="font-family: Arial, Helvetica, sans-serif;">"1900000109.pem"</span><span style="font-family: Arial, Helvetica, sans-serif;">, SSL_FILETYPE_PEM) <= 0)</span>
		{
			printf("certificate file error!\n");
			return -1;
		}
		
		if(SSL_CTX_use_PrivateKey_file(ctx, <span style="font-family: Arial, Helvetica, sans-serif;">"1900000109.pem"</span><span style="font-family: Arial, Helvetica, sans-serif;">, SSL_FILETYPE_PEM) <= 0)</span>
		{
			printf("private key file error!\n");
			return -1;
		}
		if(!SSL_CTX_check_private_key(ctx))
		{
			printf("Check private key failed!\n");
			return -1;
		}
//注意:二、三为证书通信才用
</pre><pre name="code" class="cpp">

此文主要特点是密码和SSL_VERIFY_NONE

以上参考:

http://blog.chinaunix.net/uid-14779297-id-1988328.html

http://blog.chinaunix.net/uid-12707183-id-2919172.html





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值