國密SKF設備接口-SM2證書請求生成

前言:

    由於國密標準規定,設備的SM2私鑰文件外部無法訪問,導致研發人員無法使用【密鑰文件.pem】生成【證書請求文件.csr】

花費了半天時間寫了基於SKF標準的生成【證書請求文件.csr】API接口,現在給大家進行參考,減少時間浪費。

準備工具:

    LInux上安裝最新的openssl工具箱,用於驗證證書請求文件格式準確。

 源碼:

#define SIGN_SEQUENCE      (0x30)
#define SIGN_OBJECT        (0x06)
#define SIGN_SET           (0x31)
#define SIGN_UTF8STRING    (0x0c)
#define SIGN_BIT_STRING    (0x03)
#define SIGN_ATTRIBUTES    (0xa0)
#define SIGN_VERSION       (0x02)
#define SIGN_ONEBIT        (0x81)
#define SIGN_TWOBIT        (0x82)
#define SIGN_PRIVATE       (0x02)
#define SIGN_SIGNATURE     (0x03)

typedef struct{
	char CommonName[64];           /* 通用名稱CN */
	char OrganizationUnit[64];     /* 組織單位OU */
	char OrganizationName[64];     /* 組織部門O */
	char LocalityName[64];         /* 本地名稱L */
	char StateOrProvince[64];      /* 州/省 TH*/
	char Country[64];              /* 國家 C*/
}QCard_DN;

void QCard_SetASN1Data(unsigned char sign, unsigned char *in, unsigned long inLen,
                       unsigned char **out, unsigned long *outLen)
{
    int i = 0, iNum = 0;
    unsigned char *data = 0;
    int u8len = sizeof(unsigned long);
    
    iNum = (inLen % 0xff) ? inLen /0xff + 1 : inLen /0xff ;
    *outLen = iNum ? 1 + iNum + inLen : 1 + 1 + inLen;
    data = (unsigned char *)QCARD_MALLOC(*outLen);
    data[0] = sign;

    switch(iNum)
    {
    case 1:
        data[1] = ((u8*)(&inLen))[0];
        break;
    case 2:
        data[1] = ((u8*)(&inLen))[1];
        data[2] = ((u8*)(&inLen))[0];
        break;
    }

    memcpy( data + 1 + iNum, in, inLen);
    //LOG_DATA(data, *outLen);
    *out = data;
}

void QCard_AddASN1Data(unsigned char *d1, unsigned long d1Len,
                       unsigned char *d2, unsigned long d2Len,
                       unsigned char **d3, unsigned long *d3Len)
{
    *d3Len = d1Len + d2Len;
    *d3 = (unsigned char *)QCARD_MALLOC(*d3Len);
    memcpy(*d3, d1, d1Len);
    memcpy((*d3)+d1Len, d2, d2Len);
    return;
}

void QCard_AddASN1Data2(unsigned char **d1, unsigned long *d1Len,
                       unsigned char *d2, unsigned long d2Len)

{
    unsigned char *d3 =0;
    unsigned long d3Len = 0;
    QCard_AddASN1Data(*d1, *d1Len, d2, d2Len, &d3, &d3Len);
    QCARD_FREE(*d1);
    *d1 = d3;
    *d1Len = d3Len;
}



void QCard_GetANS1DnData(char *data, unsigned char *type, unsigned long typeLen, QCARD_ANS1DATA **out)
{
    unsigned char *d1 = 0, *d2 = 0, *d3 = 0, *d4 =0, *d5 = 0;
    unsigned long d1Len = 0, d2Len = 0, d3Len = 0, d4Len = 0, d5Len = 0;
    QCARD_ANS1DATA *ans1 = 0;
    
    QCard_SetASN1Data(SIGN_UTF8STRING, (unsigned char *)data, strlen(data), &d1, &d1Len);
    QCard_SetASN1Data(SIGN_OBJECT, type, typeLen, &d2, &d2Len);
    QCard_AddASN1Data(d2, d2Len, d1, d1Len, &d3, &d3Len);
    QCard_SetASN1Data(SIGN_SEQUENCE, d3, d3Len, &d4, &d4Len);
    QCard_SetASN1Data(SIGN_SET, d4, d4Len, &d5, &d5Len);

    ans1 = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));
    ans1->data = d5;
    ans1->len = d5Len;
    *out = ans1;
    QCARD_FREE(d1);
    QCARD_FREE(d2);
    QCARD_FREE(d3);
    QCARD_FREE(d4);
    return;
}

void QCard_SetANS1Dn(QCARD_ANS1DATA *SEQUENCE_C, QCARD_ANS1DATA *SEQUENCE_ST, QCARD_ANS1DATA *SEQUENCE_L,
                     QCARD_ANS1DATA *SEQUENCE_O, QCARD_ANS1DATA *SEQUENCE_OU ,QCARD_ANS1DATA *SEQUENCE_CN,
                     QCARD_ANS1DATA **SEQUENCE_DN)
{
    unsigned char *data = 0;
    unsigned long dataLen = 0;

    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_C->data, SEQUENCE_C->len);
    //LOG_DATA(data, dataLen);
    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_ST->data, SEQUENCE_ST->len);
   // LOG_DATA(data, dataLen);
    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_L->data, SEQUENCE_L->len);
   // LOG_DATA(data, dataLen);
    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_O->data, SEQUENCE_O->len);
   // LOG_DATA(data, dataLen);
    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_OU->data, SEQUENCE_OU->len);
   // LOG_DATA(data, dataLen);
    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_CN->data, SEQUENCE_CN->len);
   // LOG_DATA(data, dataLen);

    *SEQUENCE_DN = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));
    QCard_SetASN1Data(SIGN_SEQUENCE, data, dataLen, &((*SEQUENCE_DN)->data), &((*SEQUENCE_DN)->len));
    QCARD_FREE(data);
}

void QCard_SetANS1Id(unsigned char *id_OID, unsigned long id_OIDLen, 
                     unsigned char *id_CURVE, unsigned long id_CURVELen,
                     QCARD_ANS1DATA **out)
{
    unsigned char *d1 = 0, *d2 = 0, *d3 = 0, *d4 =0;
    unsigned long d1Len = 0, d2Len = 0, d3Len = 0, d4Len = 0;
    QCARD_ANS1DATA *ans1 = 0;

    QCard_SetASN1Data(SIGN_OBJECT, id_OID, id_OIDLen, &d1, &d1Len);
    QCard_SetASN1Data(SIGN_OBJECT, id_CURVE, id_CURVELen, &d2, &d2Len);
    QCard_AddASN1Data(d1, d1Len, d2, d2Len, &d3, &d3Len);
    QCard_SetASN1Data(SIGN_SEQUENCE, d3, d3Len, &d4, &d4Len);

    ans1 = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));
    ans1->data = d4;
    ans1->len = d4Len;
    *out = ans1;
    QCARD_FREE(d1);
    QCARD_FREE(d2);
    QCARD_FREE(d3);
    return;

}

void QCard_SetANS1PublicKey(unsigned char *pucPublicKey, unsigned long ululPublicKeyLen,
                         QCARD_ANS1DATA **out)
{
    unsigned char *d1 = 0;
    unsigned long d1Len = 0;
    QCARD_ANS1DATA *ans1 = 0;

    QCard_SetASN1Data(SIGN_BIT_STRING, pucPublicKey, ululPublicKeyLen, &d1, &d1Len);

    ans1 = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));
    ans1->data = d1;
    ans1->len = d1Len;
    *out = ans1;
    return;

}

void QCard_SetANS1Simpleness(unsigned char type, unsigned char *in, unsigned long inLen,
                             QCARD_ANS1DATA **out)
{
    unsigned char *d1 = 0;
    unsigned long d1Len = 0;
    QCARD_ANS1DATA *ans1 = 0;

    QCard_SetASN1Data(type, in, inLen, &d1, &d1Len);

    ans1 = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));
    ans1->data = d1;
    ans1->len = d1Len;
    *out = ans1;
    return;
}

void QCard_SetANS1ALG(unsigned char *in, unsigned long inLen,
                             QCARD_ANS1DATA **out)
{
    unsigned char *d1 = 0, *d2 = 0;
    unsigned long d1Len = 0, d2Len = 0;
    QCARD_ANS1DATA *ans1 = 0;

    QCard_SetASN1Data(SIGN_OBJECT, in, inLen, &d1, &d1Len);
    QCard_SetASN1Data(SIGN_SEQUENCE, d1, d1Len, &d2, &d2Len);

    ans1 = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));
    ans1->data = d2;
    ans1->len = d2Len;
    *out = ans1;
    QCARD_FREE(d1);
    return;
}


void QCard_SetANS1Pub(QCARD_ANS1DATA *SEQUENCE_PUBLICKEY, QCARD_ANS1DATA *SEQUENCE_ID,
                      QCARD_ANS1DATA **out)
{
    unsigned char *d1 = 0, *d2 = 0;
    unsigned long d1Len = 0, d2Len = 0;
    QCARD_ANS1DATA *ans1 = 0;

    QCard_AddASN1Data(SEQUENCE_ID->data, SEQUENCE_ID->len, 
        SEQUENCE_PUBLICKEY->data, SEQUENCE_PUBLICKEY->len, &d1, &d1Len);
   
    QCard_SetASN1Data(SIGN_SEQUENCE, d1, d1Len, &d2, &d2Len);

    ans1 = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));

    ans1->data = d2;
    ans1->len = d2Len;
    *out = ans1;
    QCARD_FREE(d1);
    return;
}

void QCard_SetANS1CSR(QCARD_ANS1DATA *SEQUENCE_CSRDATA, QCARD_ANS1DATA *SEQUENCE_ALG, QCARD_ANS1DATA *SEQUENCE_SIGN,
                      QCARD_ANS1DATA **out)
{
    unsigned char *d1 = 0, *d2 = 0, *d3 = 0;
    unsigned long d1Len = 0, d2Len = 0, d3Len = 0;
    QCARD_ANS1DATA *ans1 = 0;
    unsigned char bit[] = {SIGN_SEQUENCE};

    QCard_AddASN1Data2(&d1, &d1Len, SEQUENCE_CSRDATA->data, SEQUENCE_CSRDATA->len);
    QCard_AddASN1Data2(&d1, &d1Len, SEQUENCE_ALG->data, SEQUENCE_ALG->len);
    QCard_AddASN1Data2(&d1, &d1Len, SEQUENCE_SIGN->data, SEQUENCE_SIGN->len);

   
    QCard_SetASN1Data(SIGN_TWOBIT, d1, d1Len, &d2, &d2Len);
    QCard_AddASN1Data2(&d3, &d3Len, bit, sizeof(bit));
    QCard_AddASN1Data2(&d3, &d3Len, d2, d2Len);

    ans1 = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));

    ans1->data = d3;
    ans1->len = d3Len;
    *out = ans1;
    QCARD_FREE(d1);
    QCARD_FREE(d2);
    return;
}



void QCard_SetANS1CsrData(QCARD_ANS1DATA *SEQUENCE_VERSION, QCARD_ANS1DATA *SEQUENCE_DN,
                          QCARD_ANS1DATA *SEQUENCE_PUBLIC, QCARD_ANS1DATA *SEQUENCE_ATTRIBUTES,
                          QCARD_ANS1DATA **SEQUENCE_CSRDATA)
{
    unsigned char *data = 0, *d2 = 0;
    unsigned long dataLen = 0, d2Len = 0;
    unsigned char sign[] = {SIGN_SEQUENCE};

    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_VERSION->data, SEQUENCE_VERSION->len);
    //LOG_DATA(data, dataLen);
    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_DN->data, SEQUENCE_DN->len);
   // LOG_DATA(data, dataLen);
    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_PUBLIC->data, SEQUENCE_PUBLIC->len);
   // LOG_DATA(data, dataLen);
    QCard_AddASN1Data2(&data, &dataLen, SEQUENCE_ATTRIBUTES->data, SEQUENCE_ATTRIBUTES->len);

    *SEQUENCE_CSRDATA = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));
    QCard_SetASN1Data(SIGN_ONEBIT, data, dataLen, &d2, &d2Len);
    QCard_AddASN1Data(sign, sizeof(sign), d2, d2Len,  &((*SEQUENCE_CSRDATA)->data), &((*SEQUENCE_CSRDATA)->len));
    QCARD_FREE(data);
    QCARD_FREE(d2);
}

void QCard_FreeQCARD_ANS1DATA(QCARD_ANS1DATA **in)
{
    if(*in)
    {
        QCARD_FREE((*in)->data);
        QCARD_FREE(*in);
    }
}

int QCard_Sm2SignWithSm3(HCONTAINER hContainer, unsigned char *data, unsigned long dataLen, 
                         QCARD_ANS1DATA **out)
{
    u32 ret = 0;
    unsigned char *d1 = 0 , *d2 = 0, *d3 = 0, *d4 = 0, *d5 = 0, *d6 = 0;
    unsigned long d1Len = 0, d2Len = 0, d3Len = 0, d4Len = 0, d5Len = 0, d6Len = 0;
    unsigned char digest[SM3_DIGEST_LENGTH] = {0};
    unsigned char bit[] = {0x00};
    ECCSIGNATUREBLOB Signature;
    QCARD_ANS1DATA *ans1 = 0;


    memset(&Signature, 0, sizeof(ECCSIGNATUREBLOB));

    sm3(data, dataLen, digest);
    //LOG_DATA(digest, SM3_DIGEST_LENGTH);
    ret = SKF_ECCSignData (hContainer, digest, SM3_DIGEST_LENGTH, &Signature);
    if(ret)
    {
        return ret;
    }

    //LOG_DATA(Signature.r, ECC_MAX_XCOORDINATE_BITS_LEN/8);
    //LOG_DATA(Signature.s, ECC_MAX_XCOORDINATE_BITS_LEN/8);

    QCard_SetASN1Data(SIGN_PRIVATE, &(Signature.r[31]), 33, &d1, &d1Len);
   // LOG_DATA(d1, d1Len);
    QCard_SetASN1Data(SIGN_PRIVATE, &(Signature.s[31]), 33, &d2, &d2Len);
   // LOG_DATA(d2, d2Len);
    QCard_AddASN1Data(d1, d1Len, d2, d2Len, &d3, &d3Len);
    QCard_SetASN1Data(SIGN_SEQUENCE, d3, d3Len, &d4, &d4Len);
    QCard_AddASN1Data(bit, sizeof(bit), d4, d4Len, &d5, &d5Len);
    QCard_SetASN1Data(SIGN_SIGNATURE, d5, d5Len, &d6, &d6Len);
  //  LOG_DATA(d6, d6Len);

    ans1 = (QCARD_ANS1DATA *)QCARD_MALLOC(sizeof(QCARD_ANS1DATA));
    ans1->data = d6;
    ans1->len = d6Len;
    *out = ans1;
    QCARD_FREE(d1);
    QCARD_FREE(d2);
    QCARD_FREE(d3);
    QCARD_FREE(d4);
    QCARD_FREE(d5);

    return 0;
}

int QCard_GenECCReq(HCONTAINER hContainer, QCard_DN DN, unsigned char *pucPublicKey, unsigned long ululPublicKeyLen,
                     unsigned char **pucReq, unsigned long *pulReqLen)
{
    QCARD_ANS1DATA *SEQUENCE_VERSION= 0;
    QCARD_ANS1DATA *SEQUENCE_C = 0, *SEQUENCE_ST = 0, *SEQUENCE_L = 0, *SEQUENCE_O = 0, *SEQUENCE_OU = 0, *SEQUENCE_CN = 0;
    QCARD_ANS1DATA *SEQUENCE_DN= 0;
    QCARD_ANS1DATA *SEQUENCE_ID = 0;
    QCARD_ANS1DATA *SEQUENCE_PUBLICKEY = 0;
    QCARD_ANS1DATA *SEQUENCE_PUBLIC = 0;
    QCARD_ANS1DATA *SEQUENCE_ATTRIBUTES= 0;
    QCARD_ANS1DATA *SEQUENCE_CSRDATA= 0;
    QCARD_ANS1DATA *SEQUENCE_ALG= 0;
    QCARD_ANS1DATA *SEQUENCE_SIGN= 0;
    QCARD_ANS1DATA *SEQUENCE_CSR= 0;
    unsigned char type_C[] = {0x55, 0x04, 0x06};
    unsigned char type_ST[] = {0x55, 0x04, 0x08};
    unsigned char type_L[] = {0x55, 0x04, 0x07};
    unsigned char type_O[] = {0x55, 0x04, 0x0a};
    unsigned char type_OU[] = {0x55, 0x04, 0x0b};
    unsigned char type_CN[] = {0x55, 0x04, 0x03};
    unsigned char id_OID[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01};
    unsigned char id_CURVE[] = {0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D};
    unsigned char id_ALG[] = {0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x75};
    unsigned char version[] = {0x00};
    int ret = 0;

    QCard_SetANS1Simpleness(SIGN_VERSION, version, sizeof(version), &SEQUENCE_VERSION);
    //LOG_DATA(SEQUENCE_VERSION->data, SEQUENCE_VERSION->len);

    QCard_GetANS1DnData(DN.Country, type_C, sizeof(type_C), &SEQUENCE_C);
    QCard_GetANS1DnData(DN.StateOrProvince, type_ST, sizeof(type_ST), &SEQUENCE_ST);
    QCard_GetANS1DnData(DN.LocalityName, type_L, sizeof(type_L), &SEQUENCE_L);
    QCard_GetANS1DnData(DN.OrganizationName, type_O, sizeof(type_O), &SEQUENCE_O);
    QCard_GetANS1DnData(DN.OrganizationUnit, type_OU, sizeof(type_OU), &SEQUENCE_OU);
    QCard_GetANS1DnData(DN.CommonName, type_CN, sizeof(type_CN), &SEQUENCE_CN);
    QCard_SetANS1Dn(SEQUENCE_C, SEQUENCE_ST, SEQUENCE_L, SEQUENCE_O, SEQUENCE_OU, SEQUENCE_CN, &SEQUENCE_DN );
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_C);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_ST);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_L);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_O);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_OU);
    //LOG_DATA(SEQUENCE_DN->data, SEQUENCE_DN->len);

    QCard_SetANS1Id(id_OID, sizeof(id_OID), id_CURVE, sizeof(id_CURVE), &SEQUENCE_ID);
    QCard_SetANS1PublicKey(pucPublicKey, ululPublicKeyLen, &SEQUENCE_PUBLICKEY);
    QCard_SetANS1Pub(SEQUENCE_PUBLICKEY, SEQUENCE_ID, &SEQUENCE_PUBLIC);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_PUBLICKEY);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_ID);
    //LOG_DATA(SEQUENCE_PUBLIC->data, SEQUENCE_PUBLIC->len);

    QCard_SetANS1Simpleness(SIGN_ATTRIBUTES, 0, 0, &SEQUENCE_ATTRIBUTES);
    //LOG_DATA(SEQUENCE_ATTRIBUTES->data, SEQUENCE_ATTRIBUTES->len);

    QCard_SetANS1CsrData(SEQUENCE_VERSION, SEQUENCE_DN, SEQUENCE_PUBLIC,SEQUENCE_ATTRIBUTES,
                          &SEQUENCE_CSRDATA);
    
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_VERSION);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_DN);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_PUBLIC);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_ATTRIBUTES);
   // LOG_DATA(SEQUENCE_CSRDATA->data, SEQUENCE_CSRDATA->len);

    QCard_SetANS1ALG(id_ALG, sizeof(id_ALG), &SEQUENCE_ALG);
    //LOG_DATA(SEQUENCE_ALG->data, SEQUENCE_ALG->len);
    //QCard_SetANS1Simpleness(SIGN_ATTRIBUTES, 0, 0, &SEQUENCE_ATTRIBUTES);

    ret = QCard_Sm2SignWithSm3(hContainer, SEQUENCE_CSRDATA->data, SEQUENCE_CSRDATA->len,
        &SEQUENCE_SIGN);
    if(ret)
    {
        QCard_FreeQCARD_ANS1DATA(&SEQUENCE_CSRDATA);
        return ret;
    }
    //LOG_DATA(SEQUENCE_SIGN->data, SEQUENCE_SIGN->len);

    QCard_SetANS1CSR(SEQUENCE_CSRDATA, SEQUENCE_ALG, SEQUENCE_SIGN,&SEQUENCE_CSR);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_CSRDATA);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_SIGN);
    QCard_FreeQCARD_ANS1DATA(&SEQUENCE_ALG);
    //LOG_DATA(SEQUENCE_CSR->data, SEQUENCE_CSR->len);

    *pucReq = SEQUENCE_CSR->data;
    *pulReqLen = SEQUENCE_CSR->len;
    QCARD_FREE(SEQUENCE_CSR);

    return 0;
}




校驗結果:

命令【openssl req -in dev.csr -noout -text】


Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = 00, ST = Some-State, L = 11, O = 22, OU = 33, CN = 44
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:b4:a1:13:44:b7:4a:8e:7e:40:26:4f:39:14:c4:
                    62:72:37:8d:78:ca:ba:9c:6f:e3:52:33:88:b3:c6:
                    0f:cf:79:6f:e3:83:bd:8d:6f:c1:9b:dd:f5:03:36:
                    0b:e3:4d:ce:de:fc:22:66:86:bd:75:58:9f:bd:b5:
                    af:e1:fc:31:f7
                ASN1 OID: sm2p256v1
                NIST CURVE: SM2
        Attributes:
            a0:00
    Signature Algorithm: sm2sign-with-sm3
         30:46:02:21:00:90:d3:b3:92:fe:56:59:30:e2:e1:fc:d6:9d:
         17:f3:82:43:49:ca:1e:51:a0:f4:8f:6e:bc:ee:b5:3f:e3:b8:
         81:02:21:00:91:88:8c:80:81:11:03:a8:cb:58:9f:e5:14:4e:
         b8:aa:59:b1:1f:ed:d6:d4:07:90:86:37:e5:96:2d:cc:35:09
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章