OpenSSL证书操作

                             OpenSSL证书操作

1.目的

    (1) 掌握OpenSSL X509证书验证和获取证书信息的原理以及常用的API;

    (2) 基于OpenSSL库开发X509证书验证和证书信息查看程序。

2.步骤

  (1) 在函数tX509_Verify() 中,完成对证书的验证。

  (2) 在函数tGetX509Info() 中,获取证书的信息,包括证书版本号、证书序列号、证书颁发者信息、证书使用者信息、证书有效期和证书公钥。

  (3) 程序输出参考下图:

  OpenSSL证书操作_第1张图片

 3.结果

   (1) 对证书“guojing.cer”和“huangfeihong.cer”进行了验证,包括证书有效期、证书颁发者签名、证书链和CRL验证;对证书进行解析,显示了证书的版本、序列号、颁发者、使用者、公钥、有效期等信息。

   (2) 实验代码:

#include
#include
#include
#include
#include
void tX509_Verify()
{
    unsigned char usrCertificate1[4096];
	   unsigned long usrCertificate1Len;
    unsigned char usrCertificate2[4096];
    unsigned long usrCertificate2Len;
    unsigned char derCrl[4096];
unsigned long derCrlLen;
    unsigned char derRootCert[4096];
	   unsigned long derRootCertLen;
int rv;

	X509_STORE_CTX *ctx=NULL;
	X509 *usrCert1=NULL;
	X509 *usrCert2=NULL;
	X509 *caCert=NULL;
 X509 *rootCert=NULL;
	X509_CRL *Crl=NULL;
	STACK_OF(X509)*caCertStack=NULL;
	X509_STORE *rootCertStore =NULL;
	int j=0;
 const unsigned char *pTmp=NULL;
	FILE *fp;

	fp=fopen("root.cer","rb");
	if(fp==NULL)
	{
		printf("open file\"root.cer\"err.\n");
		return;
	}
	derRootCertLen=fread(derRootCert,1,4096,fp);
	fclose(fp);

    fp=fopen("crl.crl","rb");
	if(fp==NULL)
	{
		printf("open file\"crl.crl\"err.\n");
		return;
	}
	derCrlLen=fread(derCrl,1,4096,fp);
	fclose(fp);

	fp=fopen("guojing.cer","rb");
	if(fp==NULL)
	{
		printf("open file\"guojing.cer\"err.\n");
		return;
	}
	usrCertificate1Len=fread(usrCertificate1,1,4096,fp);
	fclose(fp);

	fp=fopen("huangfeihong.cer","rb");
	if(fp==NULL)
	{
		printf("open file\"huangfeihong.cer\"err.\n");
		return;
	}
	usrCertificate2Len=fread(usrCertificate2,1,4096,fp);
	fclose(fp);

	pTmp=derRootCert;
	rootCert=d2i_X509(NULL,&pTmp,derRootCertLen);
	if(rootCert==NULL)
	{
		printf("d2i_X509 err.\n");
		return;
	}

	pTmp=usrCertificate1;
	usrCert1=d2i_X509(NULL,&pTmp,usrCertificate1Len);
	if(usrCert1==NULL)
	{
		printf("d2i_X509 err.\n");
		return;
	}

    pTmp=usrCertificate2;
	usrCert2=d2i_X509(NULL,&pTmp,usrCertificate2Len);
	if(usrCert2==NULL)
	{
		printf("d2i_X509 err.\n");
		return;
	}
    
    pTmp=derCrl;
	Crl=d2i_X509_CRL(NULL,&pTmp,derCrlLen);
	if(usrCert2==NULL)
	{
		printf("d2i_X509_CRL err.\n");
		return;
	}

	printf("---------------Certificate Verify ---------------\n");
	rootCertStore=X509_STORE_new();
	X509_STORE_add_cert(rootCertStore,rootCert);
	X509_STORE_set_flags(rootCertStore,X509_V_FLAG_CRL_CHECK);
	X509_STORE_add_crl(rootCertStore,Crl);

	ctx=X509_STORE_CTX_new();
	rv=X509_STORE_CTX_init(ctx,rootCertStore,usrCert1,caCertStack);
	if(rv!=1)
	{
		printf("X509_STORE_CTX_init err.\n");
		X509_free(usrCert1);
		X509_free(usrCert2);
		X509_free(rootCert);
        X509_STORE_CTX_cleanup(ctx);
		X509_STORE_CTX_free(ctx);
		X509_STORE_free(rootCertStore);
		return;
	}

    rv=X509_verify_cert(ctx);
	if(rv!=1)
	{
		printf("verify guojing.cer err. error=%d,info:%s.\n",ctx->error,X509_verify_cert_error_string(ctx->error));
	}
	else
	{
		printf("verify guojing.cer OK.\n");
	}
    
	rv=X509_STORE_CTX_init(ctx,rootCertStore,usrCert2,caCertStack);
	if(rv!=1)
	{
		printf("X509_STORE_CTX_init err.\n");
		X509_free(usrCert1);
		X509_free(usrCert2);
		X509_free(rootCert);
        X509_STORE_CTX_cleanup(ctx);
		X509_STORE_CTX_free(ctx);
		X509_STORE_free(rootCertStore);
		return;
	}

    rv=X509_verify_cert(ctx);
	if(rv!=1)
	{
		printf("verify huangfeihong.cer err. error=%d,info:%s.\n",ctx->error,X509_verify_cert_error_string(ctx->error));
	}
	else
	{
		printf("verify huangfeihong.cer OK.\n");
	}
    
	X509_free(usrCert1);
	X509_free(usrCert2);
	X509_free(rootCert);
	X509_STORE_CTX_cleanup(ctx);
	X509_STORE_CTX_free(ctx);
	X509_STORE_free(rootCertStore);
	return;
}


void tGetX509Info()
{
	unsigned char usrCertificate[4096];
	unsigned long usrCertificateLen;
	X509 *x509Cert=NULL;
    const unsigned char *pTmp=NULL;
	X509_NAME *issuer=NULL;
	X509_NAME *subject=NULL;
	int i;
	int entriesNum;
	X509_NAME_ENTRY *name_entry;
	ASN1_INTEGER *Serial=NULL;
	long Nid;
	ASN1_TIME *time;
	EVP_PKEY *pubKey;
	long Version;
	FILE *fp;
	unsigned char derpubkey[1024];
	int derpubkeyLen;
	unsigned char msginfo[1024];
	int msginfoLen;
	unsigned short *pUtf8=NULL;
	int nUtf8;
	int rv;

	fp=fopen("huangfeihong.cer","rb");
	if(fp==NULL)
	{
		printf("open file err.\n");
		return;
	}
	usrCertificateLen=fread(usrCertificate,1,4096,fp);
	fclose(fp);
	pTmp=usrCertificate;
	x509Cert=d2i_X509(NULL,&pTmp,usrCertificateLen);
	if(x509Cert==NULL)
	{
		printf("d2i_X509 err.\n");
		return;
	}

	printf("---------------Certificate Info --------------\n");
	Version=X509_get_version(x509Cert);
    printf("X509 Version:%d\n",Version);
	Serial =X509_get_serialNumber(x509Cert);
	printf("serialNumber:");
	for(i=0;ilength;i++)
	{
		printf("%02x",Serial->data[i]);
	}
	printf("\n--------------------------------------------\n");
	issuer=X509_get_issuer_name(x509Cert);
	entriesNum=sk_X509_NAME_ENTRY_num(issuer->entries);
	for(i=0;ientries,i);
		Nid=OBJ_obj2nid(name_entry->object);
		if(name_entry->value->type==V_ASN1_UTF8STRING)
		{
			nUtf8=2*name_entry->value->length;
//			pUtf8=malloc(nUtf8);
			memset(pUtf8,0,nUtf8);
			rv=MultiByteToWideChar(
                            CP_UTF8,
                            0,
                            (char*)name_entry->value->data,
                            name_entry->value->length,
                            pUtf8,
                            nUtf8);
                        rv=WideCharToMultiByte(
                           CP_ACP,
                           0,
                           pUtf8,
                           rv,
                           (char*)msginfo,
                           nUtf8,
                           NULL,
                           NULL);
                        free(pUtf8);
                        pUtf8=NULL;
                        msginfoLen=rv;
                        msginfo[msginfoLen]='\0';
                   }
                  else
                  {
                     msginfoLen=name_entry->value->length;
                     memcpy(msginfo,name_entry->value->data,msginfoLen);
                     msginfo[msginfoLen]='\0';
                   }
                 switch(Nid)
                 {
                    case NID_countryName:
                         printf("Issuer's countryName:%s\n",msginfo);
                         break;
                    case NID_stateOrProvinceName:
                         printf("Issuer's ProvinceName:%s\n",msginfo);
                         break;
                    case NID_localityName:
                         printf("Issuer's localityName:%s\n",msginfo);
                         break;
                    case NID_organizationName:
                         printf("Issuer's organizationName:%s\n",msginfo);
                         break;
                    case NID_organizationalUnitName:
                         printf("Issuer's organizationalUnitName:%s\n",msginfo);
                         break;
                    case NID_commonName:
                         printf("Issuer's commonName:%s\n",msginfo);
                         break;
                    case NID_pkcs9_emailAddress:
                         printf("Issuer's emailAddress:%s\n",msginfo);
                         break;
                  }
             }
             printf("-----------------\n");
             subject=X509_get_subject_name(x509Cert);
             entriesNum=sk_X509_NAME_ENTRY_num(subject->entries);
             for(i=0;ientries,i);
               Nid=OBJ_obj2nid(name_entry->object);
               if(name_entry->value->type==V_ASN1_UTF8STRING)
               {
                  nUtf8=2*name_entry->value->length;
                  //pUtf8=malloc(nUtf8);
                  memset(pUtf8,0,nUtf8);
                  rv=MultiByteToWideChar(
                     CP_UTF8,
                     0,
                     (char*)name_entry->value->data,
                     name_entry->value->length,
                     pUtf8,
                     nUtf8);
                  rv=WideCharToMultiByte(
                     CP_ACP,
                     0,
                     pUtf8,
                     rv,
                     (char*)msginfo,
                     nUtf8,
                     NULL,
                     NULL);
                  free(pUtf8);
                  pUtf8=NULL;
                  msginfoLen=rv;
                  msginfo[msginfoLen]='\0';
                }
                else
                {
                   msginfoLen=name_entry->value->length;
                   memcpy(msginfo,name_entry->value->data,msginfoLen);
                   msginfo[msginfoLen]='\0';
                 }
                switch(Nid)
                {
                    case NID_countryName:
                         printf("Subject's countryName:%s\n",msginfo);
                         break;
                    case NID_stateOrProvinceName:
                         printf("Subject's ProvinceName:%s\n",msginfo);
                         break;
                    case NID_localityName:
                         printf("Subject's localityName:%s\n",msginfo);
                         break;
                    case NID_organizationName:
                         printf("Subject's organizationName:%s\n",msginfo);
                         break;
                    case NID_organizationalUnitName:
                         printf("Subject's organizationalUnitName:%s\n",msginfo);
                         break;
                    case NID_commonName:
                         printf("Subject's commonName:%s\n",msginfo);
                         break;
                    case NID_pkcs9_emailAddress:
                         printf("Subject's emailAddress:%s\n",msginfo);
                         break;
                 }
             }
       printf("-----------------\n");
       time=X509_get_notBefore(x509Cert);
       printf("Cert notBefore:%s\n",time->data);
       time=X509_get_notAfter(x509Cert);
       printf("Cert notAfter:%s\n",time->data);
       printf("---------------------------\n");
       pubKey=X509_get_pubkey(x509Cert);
 /*    pTmp=derpubkey;
       derpubkeyLen=i2d_PublicKey(pubKey,&pTmp);
       printf("PublicKey is:\n");
       for(i=0;i
OpenSSL证书操作_第2张图片

 4.问题及解决方法

   (1) 传参问题:

  unsigned char *pTmp=NULL;
  rootCert=d2i_X509(NULL, &pTmp ,derRootCertLen);
  usrCert1=d2i_X509(NULL,&pTmp,usrCertificate1Len);
  usrCert2=d2i_X509(NULL,&pTmp,usrCertificate2Len);

   解决方法为将unsigned char *pTmp=NULL;改为const unsigned char *pTmp=NULL;

  (2) 证书验证存在问题:证书与实验所要用的证书有所不同。

  (3) 未打印出公钥public key:

   

你可能感兴趣的:(PKI原理与技术,证书操作,openssl)