http://blog.chinaunix.net/uid-20055870-id-1737019.html
LDAP存储证书
毕业程序需要在一个月内完成,而openssl编程资料奇缺,时间仓促,完成过程中肯定存在很多问题,没有对程序进行优化,所以这里我们主要说明程序的实现过程。欢迎大家批评指正。
该文件主要完成把x509证书存储到LDAP库中。
1、由openssl生成相应的证书
2、使用openssl库函数读取证书
3、根据证书的类型,使用LDAP API保存证书到不同的目录中。
毕业程序需要在一个月内完成,而openssl编程资料奇缺,时间仓促,完成过程中肯定存在很多问题,没有对程序进行优化,所以这里我们主要说明程序的实现过程。欢迎大家批评指正。
该文件主要完成把x509证书存储到LDAP库中。
1、由openssl生成相应的证书
2、使用openssl库函数读取证书
3、根据证书的类型,使用LDAP API保存证书到不同的目录中。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include<ldap.h>
#include<lber.h>
#include<unistd.h>
#include <sys/stat.h>
#include<lber.h>
#include<unistd.h>
#include <sys/stat.h>
BIO *bio_err=NULL;
BIO *STDout=NULL;
void print_name(BIO *out, char *title, X509_NAME *nm, unsigned long lflags)
{
char *buf;
char mline = 0;
int indent = 0;
BIO *STDout=NULL;
void print_name(BIO *out, char *title, X509_NAME *nm, unsigned long lflags)
{
char *buf;
char mline = 0;
int indent = 0;
if(title) BIO_puts(out, title);
if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
mline = 1;
indent = 4;
}
if(lflags == XN_FLAG_COMPAT) {
buf = X509_NAME_oneline(nm, 0, 0);
BIO_puts(out, buf);
BIO_puts(out, "\n");
OPENSSL_free(buf);
} else {
if(mline) BIO_puts(out, "\n");
X509_NAME_print_ex(out, nm, indent, lflags);
BIO_puts(out, "\n");
}
}
int myX509V3_extensions_print(BIO *bp, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned index, unsigned long flag, int indent)
{
int i, j;
if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
mline = 1;
indent = 4;
}
if(lflags == XN_FLAG_COMPAT) {
buf = X509_NAME_oneline(nm, 0, 0);
BIO_puts(out, buf);
BIO_puts(out, "\n");
OPENSSL_free(buf);
} else {
if(mline) BIO_puts(out, "\n");
X509_NAME_print_ex(out, nm, indent, lflags);
BIO_puts(out, "\n");
}
}
int myX509V3_extensions_print(BIO *bp, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned index, unsigned long flag, int indent)
{
int i, j;
if(sk_X509_EXTENSION_num(exts) <= 0) return 1;
if(title)
{
BIO_printf(bp,"%*s%s:",indent, "", title);
indent += 4;
}
if(sk_X509_EXTENSION_num(exts)<=index||index<=0)
{
for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
{
ASN1_OBJECT *obj;
X509_EXTENSION *ex;
ex=sk_X509_EXTENSION_value(exts, i);
if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0;
obj=X509_EXTENSION_get_object(ex);
i2a_ASN1_OBJECT(bp,obj);
j=X509_EXTENSION_get_critical(ex);
if (BIO_printf(bp,": %s\n",j?"critical":"","") <= 0)
return 0;
if(!X509V3_EXT_print(bp, ex, flag, indent + 4))
{
BIO_printf(bp, "%*s", indent + 4, "");
M_ASN1_OCTET_STRING_print(bp,ex->value);
}
if (BIO_write(bp,"\n",1) <= 0) return 0;
}
}
else
{
indent=0;
ASN1_OBJECT *obj;
X509_EXTENSION *ex;
ex=sk_X509_EXTENSION_value(exts, index);
if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0;
obj=X509_EXTENSION_get_object(ex);
i2a_ASN1_OBJECT(bp,obj);
j=X509_EXTENSION_get_critical(ex);
if (BIO_printf(bp,": %s",j?"critical":"","") <= 0)
return 0;
if(!X509V3_EXT_print(bp, ex, flag, indent))
{
//BIO_printf(bp, "%*s", indent + 4, "");
M_ASN1_OCTET_STRING_print(bp,ex->value);
}
if (BIO_write(bp,"",1) <= 0) return 0;
}
return 1;
}
{
BIO_printf(bp,"%*s%s:",indent, "", title);
indent += 4;
}
if(sk_X509_EXTENSION_num(exts)<=index||index<=0)
{
for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
{
ASN1_OBJECT *obj;
X509_EXTENSION *ex;
ex=sk_X509_EXTENSION_value(exts, i);
if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0;
obj=X509_EXTENSION_get_object(ex);
i2a_ASN1_OBJECT(bp,obj);
j=X509_EXTENSION_get_critical(ex);
if (BIO_printf(bp,": %s\n",j?"critical":"","") <= 0)
return 0;
if(!X509V3_EXT_print(bp, ex, flag, indent + 4))
{
BIO_printf(bp, "%*s", indent + 4, "");
M_ASN1_OCTET_STRING_print(bp,ex->value);
}
if (BIO_write(bp,"\n",1) <= 0) return 0;
}
}
else
{
indent=0;
ASN1_OBJECT *obj;
X509_EXTENSION *ex;
ex=sk_X509_EXTENSION_value(exts, index);
if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0;
obj=X509_EXTENSION_get_object(ex);
i2a_ASN1_OBJECT(bp,obj);
j=X509_EXTENSION_get_critical(ex);
if (BIO_printf(bp,": %s",j?"critical":"","") <= 0)
return 0;
if(!X509V3_EXT_print(bp, ex, flag, indent))
{
//BIO_printf(bp, "%*s", indent + 4, "");
M_ASN1_OCTET_STRING_print(bp,ex->value);
}
if (BIO_write(bp,"",1) <= 0) return 0;
}
return 1;
}
int main(int argc, char **argv)
{
STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
unsigned long nmflag = 0;
char *infile=argv[1];
printf("sore cert name is %s\n",infile);
BIO *in;
in=BIO_new(BIO_s_file());
if (in == NULL)
{
BIO_printf(bio_err,"create in file error!\n");
goto end;
}
if (BIO_read_filename(in,infile) <= 0)
{
BIO_printf(bio_err,"File:%s is reading error!\n",infile);
BIO_free(in);
goto end;
}
X509 *x = NULL;
if (!PEM_read_bio_X509(in, &x, 0, NULL))
{
BIO_printf(bio_err,"PEM loading to X509 error!\n");
BIO_free(in);
goto end;
}
//打印需要保存的证书的内容
BIO *mem = BIO_new(BIO_s_mem());
char *ptr=NULL;
int length=0;
//print_name(mem, NULL,X509_get_issuer_name(x), nmflag);
char cn_buf[256]={'\0'};
char sn_buf[256]={'\0'};
char sern_buf[256]={'\0'};
char nb_buf[256]={'\0'};
char na_buf[256]={'\0'};
char ext_buf[512]={'\0'};
char certType[32]={'\0'};
print_name(mem, NULL, X509_get_subject_name(x), nmflag);
length = BIO_get_mem_data(mem, &ptr);
memcpy(sn_buf,ptr,length-1);/*去掉一个换行符*/
printf("length=%d,subject=%s\n",length,sn_buf);
BIO_free(mem);
getValueFromStr1(sn_buf, "CN", cn_buf);
mem = BIO_new(BIO_s_mem());
i2a_ASN1_INTEGER(mem,x->cert_info->serialNumber);
length = BIO_get_mem_data(mem, &ptr);
memcpy(sern_buf,ptr,length);
printf("length=%d,serialNumber=%s\n",length,sern_buf);
BIO_free(mem);
mem = BIO_new(BIO_s_mem());
ASN1_TIME_print(mem,X509_get_notBefore(x));
length = BIO_get_mem_data(mem, &ptr);
memcpy(nb_buf,ptr,length);
printf("length=%d,notBefore=%s\n",length,nb_buf);
BIO_free(mem);
mem = BIO_new(BIO_s_mem());
ASN1_TIME_print(mem,X509_get_notAfter(x));
length = BIO_get_mem_data(mem, &ptr);
memcpy(na_buf,ptr,length);
printf("length=%d,notAfter=%s\n",length,na_buf);
BIO_free(mem);
mem = BIO_new(BIO_s_mem());
X509V3_CTX ctx2;
STACK_OF(X509_EXTENSION) *extensions=x->cert_info->extensions;
myX509V3_extensions_print(mem, NULL, extensions, 1, 0, 0);
length = BIO_get_mem_data(mem, &ptr);
memcpy(ext_buf,ptr,length);
printf("length=%d,extension=%s\n",length,ext_buf);
getValueFromStr(ext_buf,"CertType",certType);
printf("CertType=%s\n",certType);
{
STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
unsigned long nmflag = 0;
char *infile=argv[1];
printf("sore cert name is %s\n",infile);
BIO *in;
in=BIO_new(BIO_s_file());
if (in == NULL)
{
BIO_printf(bio_err,"create in file error!\n");
goto end;
}
if (BIO_read_filename(in,infile) <= 0)
{
BIO_printf(bio_err,"File:%s is reading error!\n",infile);
BIO_free(in);
goto end;
}
X509 *x = NULL;
if (!PEM_read_bio_X509(in, &x, 0, NULL))
{
BIO_printf(bio_err,"PEM loading to X509 error!\n");
BIO_free(in);
goto end;
}
//打印需要保存的证书的内容
BIO *mem = BIO_new(BIO_s_mem());
char *ptr=NULL;
int length=0;
//print_name(mem, NULL,X509_get_issuer_name(x), nmflag);
char cn_buf[256]={'\0'};
char sn_buf[256]={'\0'};
char sern_buf[256]={'\0'};
char nb_buf[256]={'\0'};
char na_buf[256]={'\0'};
char ext_buf[512]={'\0'};
char certType[32]={'\0'};
print_name(mem, NULL, X509_get_subject_name(x), nmflag);
length = BIO_get_mem_data(mem, &ptr);
memcpy(sn_buf,ptr,length-1);/*去掉一个换行符*/
printf("length=%d,subject=%s\n",length,sn_buf);
BIO_free(mem);
getValueFromStr1(sn_buf, "CN", cn_buf);
mem = BIO_new(BIO_s_mem());
i2a_ASN1_INTEGER(mem,x->cert_info->serialNumber);
length = BIO_get_mem_data(mem, &ptr);
memcpy(sern_buf,ptr,length);
printf("length=%d,serialNumber=%s\n",length,sern_buf);
BIO_free(mem);
mem = BIO_new(BIO_s_mem());
ASN1_TIME_print(mem,X509_get_notBefore(x));
length = BIO_get_mem_data(mem, &ptr);
memcpy(nb_buf,ptr,length);
printf("length=%d,notBefore=%s\n",length,nb_buf);
BIO_free(mem);
mem = BIO_new(BIO_s_mem());
ASN1_TIME_print(mem,X509_get_notAfter(x));
length = BIO_get_mem_data(mem, &ptr);
memcpy(na_buf,ptr,length);
printf("length=%d,notAfter=%s\n",length,na_buf);
BIO_free(mem);
mem = BIO_new(BIO_s_mem());
X509V3_CTX ctx2;
STACK_OF(X509_EXTENSION) *extensions=x->cert_info->extensions;
myX509V3_extensions_print(mem, NULL, extensions, 1, 0, 0);
length = BIO_get_mem_data(mem, &ptr);
memcpy(ext_buf,ptr,length);
printf("length=%d,extension=%s\n",length,ext_buf);
getValueFromStr(ext_buf,"CertType",certType);
printf("CertType=%s\n",certType);
/*
print_name(STDout, "issuer= ",X509_get_issuer_name(x), nmflag);
print_name(STDout, "subject= ",X509_get_subject_name(x), nmflag);
BIO_puts(STDout,"serialNumber=");
i2a_ASN1_INTEGER(STDout,x->cert_info->serialNumber);
BIO_printf(STDout,"\n");
BIO_puts(STDout,"notBefore=");
ASN1_TIME_print(STDout,X509_get_notBefore(x));
BIO_puts(STDout,"\n");
BIO_puts(STDout,"notAfter=");
ASN1_TIME_print(STDout,X509_get_notAfter(x));
BIO_puts(STDout,"\n");
X509V3_CTX ctx2;
STACK_OF(X509_EXTENSION) *extensions=x->cert_info->extensions;
//X509V3_extensions_print(STDout, "X509v3 extensions", extensions, 0, 0);
myX509V3_extensions_print(STDout, NULL, extensions, 1, 0, 0);
*/
//开始保存证书
LDAPMod cert_attribute,cn_attribute,sn_attribute,serialNumber_attribute,certType_attribute,certNotBefore_attribute,certNotAfter_attribute,userCertificate_attribute,objectClass_attribute;
printf("cn=%s\n",cn_buf);
printf("sn=%s\n",sn_buf);
printf("sern=%s\n",sern_buf);
printf("nb=%s\n",nb_buf);
printf("na=%s\n",na_buf);
char *cn_vals[]={cn_buf,NULL};
char *sn_vals[]={sn_buf,NULL};
char *serialNumber_vals[]={sern_buf,NULL};
char *certNotBefore_vals[]={nb_buf,NULL};
char *certNotAfter_vals[]={na_buf,NULL};
char *objectClass_vals[]={certType,NULL};
//pem转换成der格式保存
int len;
char *Cert_buf,*byte;
print_name(STDout, "issuer= ",X509_get_issuer_name(x), nmflag);
print_name(STDout, "subject= ",X509_get_subject_name(x), nmflag);
BIO_puts(STDout,"serialNumber=");
i2a_ASN1_INTEGER(STDout,x->cert_info->serialNumber);
BIO_printf(STDout,"\n");
BIO_puts(STDout,"notBefore=");
ASN1_TIME_print(STDout,X509_get_notBefore(x));
BIO_puts(STDout,"\n");
BIO_puts(STDout,"notAfter=");
ASN1_TIME_print(STDout,X509_get_notAfter(x));
BIO_puts(STDout,"\n");
X509V3_CTX ctx2;
STACK_OF(X509_EXTENSION) *extensions=x->cert_info->extensions;
//X509V3_extensions_print(STDout, "X509v3 extensions", extensions, 0, 0);
myX509V3_extensions_print(STDout, NULL, extensions, 1, 0, 0);
*/
//开始保存证书
LDAPMod cert_attribute,cn_attribute,sn_attribute,serialNumber_attribute,certType_attribute,certNotBefore_attribute,certNotAfter_attribute,userCertificate_attribute,objectClass_attribute;
printf("cn=%s\n",cn_buf);
printf("sn=%s\n",sn_buf);
printf("sern=%s\n",sern_buf);
printf("nb=%s\n",nb_buf);
printf("na=%s\n",na_buf);
char *cn_vals[]={cn_buf,NULL};
char *sn_vals[]={sn_buf,NULL};
char *serialNumber_vals[]={sern_buf,NULL};
char *certNotBefore_vals[]={nb_buf,NULL};
char *certNotAfter_vals[]={na_buf,NULL};
char *objectClass_vals[]={certType,NULL};
//pem转换成der格式保存
int len;
char *Cert_buf,*byte;
len = i2d_X509(x, NULL);
byte = (char*)malloc(len);
if (byte == NULL)
{
BIO_printf(bio_err,"malloc error!\n");
BIO_free(in);
goto end;
}
Cert_buf = byte;
//printf("len=%d",len);
//printf("cert_buff=%s",Cert_buf);
i2d_X509(x, &byte);//证书的DER编码二进制格式保存在buf中
struct berval cert_berval;
struct berval *cert_values[2];
cert_attribute.mod_op=LDAP_MOD_ADD | LDAP_MOD_BVALUES;
cert_attribute.mod_type="userCertificate;binary";
cert_berval.bv_len = len;
cert_berval.bv_val = Cert_buf;
cert_values[0] = &cert_berval;
cert_values[1] = NULL;
cert_attribute.mod_values =cert_values;
byte = (char*)malloc(len);
if (byte == NULL)
{
BIO_printf(bio_err,"malloc error!\n");
BIO_free(in);
goto end;
}
Cert_buf = byte;
//printf("len=%d",len);
//printf("cert_buff=%s",Cert_buf);
i2d_X509(x, &byte);//证书的DER编码二进制格式保存在buf中
struct berval cert_berval;
struct berval *cert_values[2];
cert_attribute.mod_op=LDAP_MOD_ADD | LDAP_MOD_BVALUES;
cert_attribute.mod_type="userCertificate;binary";
cert_berval.bv_len = len;
cert_berval.bv_val = Cert_buf;
cert_values[0] = &cert_berval;
cert_values[1] = NULL;
cert_attribute.mod_values =cert_values;
cn_attribute.mod_op=LDAP_MOD_ADD;
cn_attribute.mod_type="cn";
cn_attribute.mod_values=cn_vals;
cn_attribute.mod_type="cn";
cn_attribute.mod_values=cn_vals;
sn_attribute.mod_op=LDAP_MOD_ADD;
sn_attribute.mod_type="sn";
sn_attribute.mod_values=sn_vals;
serialNumber_attribute.mod_op=LDAP_MOD_ADD;
serialNumber_attribute.mod_type="serialNumber";
serialNumber_attribute.mod_values=serialNumber_vals;
sn_attribute.mod_type="sn";
sn_attribute.mod_values=sn_vals;
serialNumber_attribute.mod_op=LDAP_MOD_ADD;
serialNumber_attribute.mod_type="serialNumber";
serialNumber_attribute.mod_values=serialNumber_vals;
certNotBefore_attribute.mod_op=LDAP_MOD_ADD;
certNotBefore_attribute.mod_type="certNotBefore";
certNotBefore_attribute.mod_values=certNotBefore_vals;
certNotBefore_attribute.mod_type="certNotBefore";
certNotBefore_attribute.mod_values=certNotBefore_vals;
certNotAfter_attribute.mod_op=LDAP_MOD_ADD;
certNotAfter_attribute.mod_type="certNotAfter";
certNotAfter_attribute.mod_values=certNotAfter_vals;
objectClass_attribute.mod_op=LDAP_MOD_ADD;
objectClass_attribute.mod_type="objectClass";
objectClass_attribute.mod_values=objectClass_vals;
objectClass_attribute.mod_type="objectClass";
objectClass_attribute.mod_values=objectClass_vals;
LDAPMod *mods[8];
mods[0]=&cn_attribute;
mods[1]=&sn_attribute;
mods[2]=&serialNumber_attribute;
mods[3]=&certNotBefore_attribute;
mods[4]=&certNotAfter_attribute;
mods[5]=&cert_attribute;
mods[6]=&objectClass_attribute;
mods[7]=NULL;
char new_dn[100]={'\0'};
strcpy(new_dn,"cn=");
strcpy(&new_dn[3],cn_buf);
strcpy((new_dn+strlen(cn_buf)+3),",ou=");
strcpy((new_dn+strlen(new_dn)),certType);
strcpy((new_dn+strlen(new_dn)),",dc=Jlu,dc=Grid");
printf("dn=%s\n",new_dn);
storecert(mods,new_dn);
end:
//BIO_printf(bio_err,"program is exiting!\n");
return 0;
}
//BIO_printf(bio_err,"program is exiting!\n");
return 0;
}
//保存证书
int storecert(LDAPMod *mods,char *new_dn)
{
//服务器配置
LDAP *ld;
int res;
int authmod=LDAP_AUTH_SIMPLE;
char *ldap_host="localhost";
char *user_dn="cn=root,dc=Jlu,dc=Grid";
char *user_pw="lgl135";
printf("starting store cert!\n");
//初始化ldap
if ((ld=ldap_init(ldap_host,LDAP_PORT))==NULL)
{
perror("Failure of ldap_init");
exit(EXIT_FAILURE);
}
printf("initing done!\n");
//绑定ldap
if(ldap_bind_s(ld,user_dn,user_pw,authmod)!=LDAP_SUCCESS)
{
ldap_perror(ld,"Failure of ldap_bind");
exit(EXIT_FAILURE);
}
int storecert(LDAPMod *mods,char *new_dn)
{
//服务器配置
LDAP *ld;
int res;
int authmod=LDAP_AUTH_SIMPLE;
char *ldap_host="localhost";
char *user_dn="cn=root,dc=Jlu,dc=Grid";
char *user_pw="lgl135";
printf("starting store cert!\n");
//初始化ldap
if ((ld=ldap_init(ldap_host,LDAP_PORT))==NULL)
{
perror("Failure of ldap_init");
exit(EXIT_FAILURE);
}
printf("initing done!\n");
//绑定ldap
if(ldap_bind_s(ld,user_dn,user_pw,authmod)!=LDAP_SUCCESS)
{
ldap_perror(ld,"Failure of ldap_bind");
exit(EXIT_FAILURE);
}
printf("ldap_bind_s done!\n");
//添加记录
if(ldap_add_s(ld,new_dn,mods)!=LDAP_SUCCESS)
{
ldap_perror(ld,"Failure of ldap_add_s");
exit(EXIT_FAILURE);
}
printf("cert has been saved in LDAP server.\n");
//添加记录
if(ldap_add_s(ld,new_dn,mods)!=LDAP_SUCCESS)
{
ldap_perror(ld,"Failure of ldap_add_s");
exit(EXIT_FAILURE);
}
printf("cert has been saved in LDAP server.\n");
//(void)ldap_msgfree(ldap_message_set);
//关闭绑定
res=ldap_unbind_s(ld);
if(res!=0){
fprintf(stderr,"ldap_unbind_s failed:%s\n",ldap_err2string(res));
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
int getValueFromStr(char *src, char *title, char *rt)
{
int slen=strlen(src);
int tlen=strlen(title),start=0,end = 0;
int length =0;
int i=0;
if(strcmp(title,"CertType")==0)
{
for(i=0;i<(slen);i++)
{
if(src[i]=='[')
{
end=i;
break;
}
}
if(end)
length = end;
else
length = (i);
strncpy(rt,src+strlen("Netscape Comment: "),length-strlen("Netscape Comment: "));
return length;
}
else if(strcmp(title,"CertValue")==0)
{
for(i=0;i<(slen);i++)
{
if(src[i]=='[')
{
start=i+1;
break;
}
}
for(i=start;i<slen;i++)
{
if(*(src+i)==']')
{
end=i;
break;
}
}
if(start == 0 ||end ==0)
{
printf("The value no right!\n");
return 0;
}
else{
length =(end-start);
strncpy(rt,&src[start],(length));
rt[length]='\0';
return length;
}
}
else
{
return -1;
}
}
int getValueFromStr1(char *src, char *title, char *rt)
{
int slen=strlen(src);
int tlen=strlen(title),start,end;
int i=0;
for(i=0;i<(slen-tlen);i++)
{
if(strncmp((src+i),title,tlen) == 0)
{
if(src[i+tlen]=='=')
{
start=i+tlen+1;
break;
}
}
}
if(start == 0) return 0;
for(i=start;i<slen;i++)
{
if(*(src+i)=='\/')
{
end=i;
break;
}
}
end=i;
int realLength=0;
if(end == slen)
realLength=(end-start)-1;
else
realLength=(end-start);
memcpy(rt,&src[start],realLength);
rt[realLength]='\0';
return (end-start+1);
}
编译生成可执行文件
gcc -I /usr/local/ssl/include -I/u01/apps/ladp2.3/include -L/usr/local/ssl/lib/
-L/u01/apps/ladp2.3/lib -lldap -llber -o storecert storecert.c
gcc -I /usr/local/ssl/include -I/u01/apps/ladp2.3/include -L/usr/local/ssl/lib/
-L/u01/apps/ladp2.3/lib -lldap -llber -o storecert storecert.c