zoukankan      html  css  js  c++  java
  • openssl 生成CSR

    openssl 生成CSR

     分类:
     

    将openssl如何生成CSR写了一上DEMO,支持扩展属性,同时增加了通过DN字符串转X509_NAME的方法。

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #include <string.h>  
    2. #include <openssl/x509.h>  
    3. #include <openssl/rsa.h>  
    4. #pragma comment(lib, "libeay32.lib")  
    5.   
    6. /* 
    7. * subject is expected to be in the format /type0=value0/type1=value1/type2=... 
    8. * where characters may be escaped by  
    9. */  
    10. X509_NAME *parse_name(char *subject, long chtype, int multirdn)  
    11. {  
    12.     size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */  
    13.     char *buf = OPENSSL_malloc(buflen);  
    14.     size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */  
    15.     char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));  
    16.     char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));  
    17.     int *mval = OPENSSL_malloc (max_ne * sizeof (int));  
    18.       
    19.     char *sp = subject, *bp = buf;  
    20.     int i, ne_num = 0;  
    21.       
    22.     X509_NAME *n = NULL;  
    23.     int nid;  
    24.       
    25.     if (!buf || !ne_types || !ne_values || !mval)  
    26.     {  
    27.         //BIO_printf(bio_err, "malloc error ");  
    28.         goto error;  
    29.     }     
    30.       
    31.     if (*subject != '/')  
    32.     {  
    33.         //BIO_printf(bio_err, "Subject does not start with '/'. ");  
    34.         goto error;  
    35.     }  
    36.     sp++; /* skip leading / */  
    37.       
    38.     /* no multivalued RDN by default */  
    39.     mval[ne_num] = 0;  
    40.       
    41.     while (*sp)  
    42.     {  
    43.         /* collect type */  
    44.         ne_types[ne_num] = bp;  
    45.         while (*sp)  
    46.         {  
    47.             if (*sp == '\') /* is there anything to escape in the type...? */  
    48.             {  
    49.                 if (*++sp)  
    50.                     *bp++ = *sp++;  
    51.                 else      
    52.                 {  
    53.                     //BIO_printf(bio_err, "escape character at end of string ");  
    54.                     goto error;  
    55.                 }  
    56.             }     
    57.             else if (*sp == '=')  
    58.             {  
    59.                 sp++;  
    60.                 *bp++ = '';  
    61.                 break;  
    62.             }  
    63.             else  
    64.                 *bp++ = *sp++;  
    65.         }  
    66.         if (!*sp)  
    67.         {  
    68.             //BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d ", ne_num);  
    69.             goto error;  
    70.         }  
    71.         ne_values[ne_num] = bp;  
    72.         while (*sp)  
    73.         {  
    74.             if (*sp == '\')  
    75.             {  
    76.                 if (*++sp)  
    77.                     *bp++ = *sp++;  
    78.                 else  
    79.                 {  
    80.                     //BIO_printf(bio_err, "escape character at end of string ");  
    81.                     goto error;  
    82.                 }  
    83.             }  
    84.             else if (*sp == '/')  
    85.             {  
    86.                 sp++;  
    87.                 /* no multivalued RDN by default */  
    88.                 mval[ne_num+1] = 0;  
    89.                 break;  
    90.             }  
    91.             else if (*sp == '+' && multirdn)  
    92.             {  
    93.                 /* a not escaped + signals a mutlivalued RDN */  
    94.                 sp++;  
    95.                 mval[ne_num+1] = -1;  
    96.                 break;  
    97.             }  
    98.             else  
    99.                 *bp++ = *sp++;  
    100.         }  
    101.         *bp++ = '';  
    102.         ne_num++;  
    103.     }     
    104.       
    105.     if (!(n = X509_NAME_new()))  
    106.         goto error;  
    107.       
    108.     for (i = 0; i < ne_num; i++)  
    109.     {  
    110.         if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)  
    111.         {  
    112.             //BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped ", ne_types[i]);  
    113.             continue;  
    114.         }  
    115.           
    116.         if (!*ne_values[i])  
    117.         {  
    118.             //BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped ", ne_types[i]);  
    119.             continue;  
    120.         }  
    121.           
    122.         if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i]))  
    123.             goto error;  
    124.     }  
    125.       
    126.     OPENSSL_free(ne_values);  
    127.     OPENSSL_free(ne_types);  
    128.     OPENSSL_free(buf);  
    129.     OPENSSL_free(mval);  
    130.     return n;  
    131.       
    132. error:  
    133.     X509_NAME_free(n);  
    134.     if (ne_values)  
    135.         OPENSSL_free(ne_values);  
    136.     if (ne_types)  
    137.         OPENSSL_free(ne_types);  
    138.     if (mval)  
    139.         OPENSSL_free(mval);  
    140.     if (buf)  
    141.         OPENSSL_free(buf);  
    142.     return NULL;  
    143. }  
    144.   
    145. X509_NAME *CreateDN(char *pbEmail, char *pbCN, char *pbOU, char *pbO, char *pbL, char *pbST, char *pbC)  
    146. {  
    147.     X509_NAME *pX509Name = NULL;  
    148.     if(pbCN == NULL)  
    149.     {  
    150.         return NULL;  
    151.     }  
    152.       
    153.     if (!(pX509Name = X509_NAME_new()))  
    154.     {  
    155.         return NULL;  
    156.     }  
    157.     X509_NAME_add_entry_by_txt(pX509Name, "emailAddress", V_ASN1_UTF8STRING, pbEmail, -1, -1, 0);  
    158.     X509_NAME_add_entry_by_txt(pX509Name, "CN", V_ASN1_UTF8STRING, pbCN, -1, -1, 0);  
    159.     X509_NAME_add_entry_by_txt(pX509Name, "OU", V_ASN1_UTF8STRING, pbOU, -1, -1, 0);  
    160.     X509_NAME_add_entry_by_txt(pX509Name, "O", V_ASN1_UTF8STRING, pbO, -1, -1, 0);  
    161.     X509_NAME_add_entry_by_txt(pX509Name, "L", V_ASN1_UTF8STRING, pbL, -1, -1, 0);  
    162.     X509_NAME_add_entry_by_txt(pX509Name, "ST", V_ASN1_UTF8STRING, pbST, -1, -1, 0);  
    163.     X509_NAME_add_entry_by_txt(pX509Name, "C", V_ASN1_UTF8STRING, pbC, -1, -1, 0);  
    164.     return pX509Name;  
    165. }  
    166.   
    167. int GenCSR(char *pbDN, int nDNLen, char *pCSR, size_t nCSRSize)  
    168. {  
    169.     char szAltName[] = "DNS:www.jinhill.com";  
    170.     char szComment[] = "Create by Jinhill";  
    171.     char szKeyUsage[] = "digitalSignature, nonRepudiation";  
    172.     char szExKeyUsage[] = "serverAuth, clientAuth";  
    173.       
    174.     X509_REQ        *pX509Req = NULL;  
    175.     int             iRV = 0;  
    176.     long            lVer = 3;  
    177.     X509_NAME       *pX509DN = NULL;  
    178.     EVP_PKEY        *pEVPKey = NULL;  
    179.     RSA             *pRSA = NULL;  
    180.     X509_NAME_ENTRY *pX509Entry = NULL;  
    181.     char            szBuf[255] = {0};  
    182.     char            mdout[20];  
    183.     int             nLen, nModLen;  
    184.     int             bits = 2048;  
    185.     unsigned long   E = RSA_3;  
    186.     unsigned char   *pDer = NULL;  
    187.     unsigned char   *p = NULL;  
    188.     FILE            *fp = NULL;  
    189.     const EVP_MD    *md = NULL;  
    190.     X509            *pX509 = NULL;  
    191.     BIO             *pBIO = NULL;  
    192.     BIO             *pPemBIO = NULL;  
    193.     BUF_MEM         *pBMem = NULL;  
    194.       
    195.     //STACK_OF(X509_EXTENSION) *pX509Ext;  
    196.       
    197.     if(pbDN == NULL)  
    198.     {  
    199.         return -1;  
    200.     }  
    201.     pX509DN = parse_name(pbDN, V_ASN1_UTF8STRING, 0);  
    202.       
    203.     pX509Req = X509_REQ_new();  
    204.       
    205.     iRV = X509_REQ_set_version(pX509Req, lVer);  
    206.       
    207.     // subject pX509Name   
    208.     iRV = X509_REQ_set_subject_name(pX509Req, pX509DN);  
    209.       
    210.     /* pub key */  
    211.     pEVPKey = EVP_PKEY_new();  
    212.     pRSA = RSA_generate_key(bits, E, NULL, NULL);  
    213.     EVP_PKEY_assign_RSA(pEVPKey, pRSA);  
    214.     iRV = X509_REQ_set_pubkey(pX509Req, pEVPKey);  
    215.       
    216.     /* attribute */  
    217.     strcpy(szBuf, szAltName);  
    218.     nLen = strlen(szBuf);  
    219.     iRV = X509_REQ_add1_attr_by_txt(pX509Req, "subjectAltName", V_ASN1_UTF8STRING, szBuf, nLen);  
    220.       
    221.     strcpy(szBuf, szKeyUsage);  
    222.     nLen = strlen(szBuf);  
    223.     iRV = X509_REQ_add1_attr_by_txt(pX509Req, "keyUsage", V_ASN1_UTF8STRING, szBuf, nLen);  
    224.       
    225.       
    226.     strcpy(szBuf, szExKeyUsage);  
    227.     nLen = strlen(szBuf);  
    228.     iRV = X509_REQ_add1_attr_by_txt(pX509Req, "extendedKeyUsage", V_ASN1_UTF8STRING, szBuf, nLen);  
    229.       
    230.       
    231.     strcpy(szBuf, szComment);  
    232.     nLen = strlen(szBuf);  
    233.     iRV = X509_REQ_add1_attr_by_txt(pX509Req, "nsComment", V_ASN1_UTF8STRING, szBuf, nLen);  
    234.       
    235.       
    236.     md = EVP_sha1();  
    237.     iRV = X509_REQ_digest(pX509Req, md, mdout, &nModLen);  
    238.     iRV = X509_REQ_sign(pX509Req, pEVPKey, md);  
    239.     if(!iRV)  
    240.     {  
    241.         printf("sign err! ");  
    242.         X509_REQ_free(pX509Req);  
    243.         return -1;  
    244.     }  
    245.       
    246.     // 写入文件PEM格式   
    247.     //  pBIO = BIO_new_file("certreq.txt", "w");  
    248.     //  PEM_write_bio_X509_REQ(pBIO, pX509Req, NULL, NULL);  
    249.     //  BIO_free(pBIO);  
    250.       
    251.     //返回PEM字符  
    252.     pPemBIO = BIO_new(BIO_s_mem());  
    253.     PEM_write_bio_X509_REQ(pPemBIO, pX509Req, NULL, NULL);  
    254.     BIO_get_mem_ptr(pPemBIO,&pBMem);  
    255.     if(pBMem->length <= nCSRSize)  
    256.     {  
    257.         memcpy(pCSR, pBMem->data, pBMem->length);  
    258.     }  
    259.     BIO_free(pPemBIO);  
    260.       
    261.     /* DER编码 */  
    262.     //nLen = i2d_X509_REQ(pX509Req, NULL);  
    263.     //pDer = (unsigned char *)malloc(nLen);  
    264.     //p = pDer;  
    265.     //nLen = i2d_X509_REQ(pX509Req, &p);  
    266.     //free(pDer);  
    267.       
    268.     //  验证CSR  
    269.     OpenSSL_add_all_algorithms();  
    270.     iRV = X509_REQ_verify(pX509Req, pEVPKey);  
    271.     if(iRV<0)  
    272.     {  
    273.         printf("verify err. ");  
    274.     }  
    275.       
    276.     X509_REQ_free(pX509Req);  
    277.     return nCSRSize;  
    278. }  
    279.   
    280.   
    281. int main()  
    282. {  
    283.     char chDN[255] = "/CN=www.jinhill.com/O=Beijing Jinhill Inc./C=CN";  
    284.     char chCSR[2048] = {0};  
    285.     int rv = GenCSR(chDN, strlen(chDN), chCSR, sizeof(chCSR));  
    286.     printf("CSR: %s", chCSR);  
    287. }  
  • 相关阅读:
    Understanding String Table Size in HotSpot
    Java性能优化之JVM GC(垃圾回收机制)
    为什么新生代内存需要有两个Survivor区
    jmap命令详解
    JVM GC 机制与性能优化
    JVM1.6 GC详解
    jstat命令详解
    锁的性能相关
    JAVA AQS源码分析
    kafka的安装 (单机)
  • 原文地址:https://www.cnblogs.com/developer-ios/p/6268216.html
Copyright © 2011-2022 走看看