发布时间:2010-4-5 11:57
分类名称:OpenSSL
另外,有很多函数是由宏定义通过控制函数BIO_ctrl实现,比如BIO_set_nbio、BIO_get_fd和BIO_eof等等。
编程示例
1) mem bio
#include <stdio.h>
#include <openssl/bio.h>
int main()
{
BIO *b=NULL;
int len=0;
char *out=NULL;
b=BIO_new(BIO_s_mem());
len=BIO_write(b,"openssl",4);
len=BIO_printf(b,"%s","zcp");
len=BIO_ctrl_pending(b);
out=(char *)OPENSSL_malloc(len);
len=BIO_read(b,out,len);
OPENSSL_free(out);
BIO_free(b);
return 0;
}
说明:
b=BIO_new(BIO_s_mem());生成一个mem类型的BIO。
len=BIO_write(b,"openssl",7);将字符串"openssl"写入bio。
len=BIO_printf(b,"bio test",8);将字符串"bio test"写入bio。
len=BIO_ctrl_pending(b);得到缓冲区中待读取大小。
len=BIO_read(b,out,50);将bio中的内容写入out缓冲区。
2)file bio
#include <stdio.h>
#include <openssl/bio.h>
int main()
{
BIO *b=NULL;
int len=0,outlen=0;
char *out=NULL;
b=BIO_new_file("bf.txt","w");
len=BIO_write(b,"openssl",4);
len=BIO_printf(b,"%s","zcp");
BIO_free(b);
b=BIO_new_file("bf.txt","r");
len=BIO_pending(b);
len=50;
out=(char *)OPENSSL_malloc(len);
len=1;
while(len>0)
{
len=BIO_read(b,out+outlen,1);
outlen+=len;
}
BIO_free(b);
free(out);
return 0;
}
3)socket bio
服务端:
#include <stdio.h>
#include <openssl/bio.h>
#include <string.h>
int main()
{
BIO *b=NULL,*c=NULL;
int sock,ret,len;
char *addr=NULL;
char out[80];
sock=BIO_get_accept_socket("2323",0);
b=BIO_new_socket(sock, BIO_NOCLOSE);
ret=BIO_accept(sock,&addr);
BIO_set_fd(b,ret,BIO_NOCLOSE);
while(1)
{
memset(out,0,80);
len=BIO_read(b,out,80);
break;
printf("%s",out);
}
BIO_free(b);
return 0;
}
客户端telnet此端口成功后,输入字符,服务端会显示出来(linux下需要输入回车)。
客户端:
#include <openssl/bio.h>
int main()
{
BIO *cbio, *out;
int len;
char tmpbuf[1024];
cbio = BIO_new_connect("localhost:http");
out = BIO_new_fp(stdout, BIO_NOCLOSE);
<= 0)
{
fprintf(stderr, "Error connecting to server\n");
}
BIO_puts(cbio, "GET / HTTP/1.0\n\n");
for(;;)
{
len = BIO_read(cbio, tmpbuf, 1024);
break;
BIO_write(out, tmpbuf, len);
}
BIO_free(cbio);
BIO_free(out);
return 0;
}
说明:本示例用来获取本机的web服务信息。
cbio = BIO_new_connect("localhost:http");用来生成建立连接到本地web服务的BIO。
out = BIO_new_fp(stdout, BIO_NOCLOSE);生成一个输出到屏幕的BIO。
BIO_puts(cbio, "GET / HTTP/1.0\n\n");通过BIO发送数据。
len = BIO_read(cbio, tmpbuf, 1024);将web服务响应的数据写入缓存,此函数循环调用
直到无数据。
BIO_write(out, tmpbuf, len);通过BIO打印收到的数据。
4) md BIO
#include <openssl/bio.h>
#include <openssl/evp.h>
int main()
{
BIO *bmd=NULL,*b=NULL;
const EVP_MD *md=EVP_md5();
int len;
char tmp[1024];
bmd=BIO_new(BIO_f_md());
BIO_set_md(bmd,md);
b= BIO_new(BIO_s_null());
b=BIO_push(bmd,b);
len=BIO_write(b,"openssl",7);
len=BIO_gets(b,tmp,1024);
BIO_free(b);
return 0;
}
说明:本示例用md BIO对字符串"opessl"进行md5摘要。
bmd=BIO_new(BIO_f_md());生成一个md BIO。
BIO_set_md(bmd,md);设置md BIO 为md5 BIO。
b= BIO_new(BIO_s_null());生成一个null BIO。
b=BIO_push(bmd,b);构造BIO 链,md5 BIO在顶部。
len=BIO_write(b,"openssl",7);将字符串送入BIO做摘要。
len=BIO_gets(b,tmp,1024);将摘要结果写入tmp缓冲区。
5)cipher BIO
#include <string.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
int main()
{
/* 加密 */
BIO *bc=NULL,*b=NULL;
const EVP_CIPHER *c=EVP_des_ecb();
int len,i;
char tmp[1024];
unsigned char key[8],iv[8];
for(i=0;i<8;i++)
{
memset(&key[i],i+1,1);
memset(&iv[i],i+1,1);
}
bc=BIO_new(BIO_f_cipher());
BIO_set_cipher(bc,c,key,iv,1);
b= BIO_new(BIO_s_null());
b=BIO_push(bc,b);
len=BIO_write(b,"openssl",7);
len=BIO_read(b,tmp,1024);
BIO_free(b);
/* 解密 */
BIO *bdec=NULL,*bd=NULL;
const EVP_CIPHER *cd=EVP_des_ecb();
bdec=BIO_new(BIO_f_cipher());
BIO_set_cipher(bdec,cd,key,iv,0);
bd= BIO_new(BIO_s_null());
bd=BIO_push(bdec,bd);
len=BIO_write(bdec,tmp,len);
len=BIO_read(bdec,tmp,1024);
BIO_free(bdec);
return 0;
}
说明:本示例采用cipher BIO对字符串"openssl"进行加密和解密,本示例编译需要用c++编译器;
关键说明:
BIO_set_cipher(bc,c,key,iv,1);设置加密BI。
BIO_set_cipher(bdec,cd,key,iv,0);设置解密BIO。
其中key为对称密钥,iv为初始化向量。
加/解密结果通过BIO_read获取。
6) ssl BIO
#include <openssl/bio.h>
#include <openssl/ssl.h>
int main()
{
BIO *sbio, *out;
int len;
char tmpbuf[1024];
SSL_CTX *ctx;
SSL *ssl;
SSLeay_add_ssl_algorithms();
OpenSSL_add_all_algorithms();
ctx = SSL_CTX_new(SSLv3_client_method());
sbio = BIO_new_ssl_connect(ctx);
BIO_get_ssl(sbio, &ssl);
{
fprintf(stderr, "Can not locate SSL pointer\n");
return 0;
}
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
BIO_set_conn_hostname(sbio, "mybank.icbc.com.cn:https");
out = BIO_new_fp(stdout, BIO_NOCLOSE);
BIO_printf(out,”链接中….\n”);
<= 0)
{
fprintf(stderr, "Error connecting to server\n");
return 0;
}
<= 0)
{
fprintf(stderr, "Error establishing SSL connection\n");
return 0;
}
BIO_puts(sbio, "GET / HTTP/1.0\n\n");
for(;;)
{
len = BIO_read(sbio, tmpbuf, 1024);
break;
BIO_write(out, tmpbuf, len);
}
BIO_free_all(sbio);
BIO_free(out);
return 0;
}
本函数用ssl bio来链接mybank.icbc.com.cn的https服务,并请求首页文件。其中SSLeay_add_ssl_algorithms和OpenSSL_add_all_algorithms函数必不可少,否则不能找到ssl加密套件并且不能找到各种算法。
7) 其他示例
#include <openssl/bio.h>
#include <openssl/asn1.h>
int main()
{
int ret,len,indent;
BIO *bp;
char *pp,buf[5000];
FILE *fp;
bp=BIO_new(BIO_s_file());
BIO_set_fp(bp,stdout,BIO_NOCLOSE);
fp=fopen("der.cer","rb");
len=fread(buf,1,5000,fp);
fclose(fp);
pp=buf;
indent=5;
ret=BIO_dump_indent(bp,pp,len,indent);
BIO_free(bp);
return 0;
}