您的位置:首页 > 其它

毕业设计之LDAP存储X509证书

2014-12-04 16:17 477 查看
http://blog.chinaunix.net/uid-20055870-id-1737019.html

LDAP存储证书

毕业程序需要在一个月内完成,而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<ldap.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;
 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(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;

}
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);
  /*

  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;

 
  cn_attribute.mod_op=LDAP_MOD_ADD;

  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;
  certNotBefore_attribute.mod_op=LDAP_MOD_ADD;

  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;

  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;

}
//保存证书

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");

  //(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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: