无法使用 WolfSSL 解析 PKCS7 证书,但可以通过 OpenSSL 解析

Could not parse PKCS7 certificate using WolfSSL but same could be parsed by OpenSSL

我正在尝试使用 WolfSSL 解析 PKCS7 证书,但它返回 ERROR_CODE:-140 (ASN_PARSE_E) 但是我能够使用 OpenSSL 解析相同的证书。

我有 Base64 编码的 PKCS7 文件,正在解码以接收 DER 格式的 PKCS7 证书。这种 DER 格式 PKCS7 是我试图使用 wolfssl 解析的格式,但是代码 returns -140 (ASN_PARSE_E).

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/pkcs7.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/coding.h>


#define PKCS7CERT                                                       \
"MIICcAYJKoZIhvcNAQcCoIICYTCCAl0CAQExADALBgkqhkiG9w0BBwGgggJFMIIC\r\n"  \
"QTCCAeegAwIBAgICLBMwCgYIKoZIzj0EAwIwFzEVMBMGA1UEAxMMZXN0RXhhbXBs\r\n"  \
"ZUNBMB4XDTIwMTEzMDAzMTQwMVoXDTIxMTEzMDAzMTQwMVowFTETMBEGA1UEAxMK\r\n"  \
"ZXN0RXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKn474FX\r\n"  \
"/P+KUY0W0d7C4IFbFDKp1RBUJ8h9DsvfpcRx7chaxAGlVC/3F0iB0OpNPYA057FU\r\n"  \
"QqMfsDVU0/SeQ+sSBzRVJptHdBYdCvfCZqW87MmL7D7j218/pafVmozkzINkKHmB\r\n"  \
"EAHUx4Wtjh5O5R8ttQlBIedDwd4nIswtHUhqMFGg82SWtw+BThBXvzLpNa7Imb29\r\n"  \
"lANriivGc/lbY2kzvNuCoGboW0eGu+TYWaNHfX7gnOwHJ/b30/hscEA3gtPxQksy\r\n"  \
"4etQhBz635yeu9b0cMtR5puOoh0se9vuyj/XkqxJrQ+9oqdVTendY5d7djQZcR1a\r\n"  \
"Z1iummM0LtZK59UCAwEAAaNaMFgwCQYDVR0TBAIwADALBgNVHQ8EBAMCB4AwHQYD\r\n"  \
"VR0OBBYEFHri7Gfy4mq5x2bJ/vBFbJCTB29/MB8GA1UdIwQYMBaAFNn/DnEhuCfA\r\n"  \
"dyz1NtN3MlBdg0AhMAoGCCqGSM49BAMCA0gAMEUCIBS+wxEQu5dM55D8txtgZ9uC\r\n"  \
"w9WCdU+UDBTWER116+8IAiEAhmZ51Ak8mZk7bAMx/EmeqvTjCU/8hdzSUWWyP/mO\r\n"  \
"nrIxAA==\r\n" 



int main()
{   
    int ret = 0;
    PKCS7 pkcs7;
    printf("Conversion of PKCS7 to X.509\r\n");
    char cert [] = PKCS7CERT;
    int certs_len = sizeof(cert);
    char out[certs_len];
    int outLen = sizeof(out) ;
    
   ret = Base64_Decode(cert, certs_len, out, &outLen);
   if (ret != 0)
   {
        printf("Failed! Base64_Decode_ret : %d",ret);
        return ret;
   }
    
   ret = wc_PKCS7_Init(&pkcs7, NULL, INVALID_DEVID);
   if (ret != 0)
    {
        printf(" error wc_PKCS7_Init : ret_code : %d",ret);
        return ret;
    } 
    
   ret = wc_PKCS7_InitWithCert(&pkcs7, out, (word32)(outLen));  
   if (ret != 0)
    {
        printf(" error wc_PKCS7_InitWithCert : ret_code : %d",ret);
        return ret;
    }
   
    wc_PKCS7_Free(&pkcs7);
    return ret;
 }

相同的 PKCS7CERT 已使用 openssl(命令行和通过程序)成功解析。 下面我提到的是OpenSSL代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/pem.h>    

#define PKCS7CERT                                                       \
"MIICcAYJKoZIhvcNAQcCoIICYTCCAl0CAQExADALBgkqhkiG9w0BBwGgggJFMIIC\r\n"  \
"QTCCAeegAwIBAgICLBMwCgYIKoZIzj0EAwIwFzEVMBMGA1UEAxMMZXN0RXhhbXBs\r\n"  \
"ZUNBMB4XDTIwMTEzMDAzMTQwMVoXDTIxMTEzMDAzMTQwMVowFTETMBEGA1UEAxMK\r\n"  \
"ZXN0RXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKn474FX\r\n"  \
"/P+KUY0W0d7C4IFbFDKp1RBUJ8h9DsvfpcRx7chaxAGlVC/3F0iB0OpNPYA057FU\r\n"  \
"QqMfsDVU0/SeQ+sSBzRVJptHdBYdCvfCZqW87MmL7D7j218/pafVmozkzINkKHmB\r\n"  \
"EAHUx4Wtjh5O5R8ttQlBIedDwd4nIswtHUhqMFGg82SWtw+BThBXvzLpNa7Imb29\r\n"  \
"lANriivGc/lbY2kzvNuCoGboW0eGu+TYWaNHfX7gnOwHJ/b30/hscEA3gtPxQksy\r\n"  \
"4etQhBz635yeu9b0cMtR5puOoh0se9vuyj/XkqxJrQ+9oqdVTendY5d7djQZcR1a\r\n"  \
"Z1iummM0LtZK59UCAwEAAaNaMFgwCQYDVR0TBAIwADALBgNVHQ8EBAMCB4AwHQYD\r\n"  \
"VR0OBBYEFHri7Gfy4mq5x2bJ/vBFbJCTB29/MB8GA1UdIwQYMBaAFNn/DnEhuCfA\r\n"  \
"dyz1NtN3MlBdg0AhMAoGCCqGSM49BAMCA0gAMEUCIBS+wxEQu5dM55D8txtgZ9uC\r\n"  \
"w9WCdU+UDBTWER116+8IAiEAhmZ51Ak8mZk7bAMx/EmeqvTjCU/8hdzSUWWyP/mO\r\n"  \
"nrIxAA==\r\n"                                                          

int main()
{   
     int i ;
    char cert [] = PKCS7CERT;
    int certs_len = strlen(cert);
    BIO *buff = NULL;
    BIO *b64 = NULL;
    BIO *out =NULL;
    PKCS7 *p7 = NULL;
    STACK_OF(X509) *certs = NULL;

     printf("Conversion of PKCS7 to X.509\r\n");
    //printf("\r\n BASE64 decode start : \r\n");
    
    b64 = BIO_new(BIO_f_base64());
    buff = BIO_new_mem_buf(cert, certs_len);
    buff = BIO_push(b64, buff);
    out =  BIO_new(BIO_s_mem());
         
    p7 = d2i_PKCS7_bio(buff, NULL);
    if (p7 == NULL)
    {
        printf("Error loading PKCS7 file \n");
    }
    
    i = OBJ_obj2nid(p7->type);
    
    if(i == NID_pkcs7_signed)
    {
        certs = p7->d.sign->cert;
    } 
    
    else if(i == NID_pkcs7_signedAndEnveloped) 
    {
        certs = p7->d.signed_and_enveloped->cert;
    }

    for (i = 0; certs && i < sk_X509_num(certs); i++) 
    {
        X509 *x = sk_X509_value(certs,i);
      PEM_write_bio_X509(out,x);
    }
    
    BUF_MEM *bptr;
    BIO_get_mem_ptr(out, &bptr); 
    char *buffer = (char *)malloc(bptr->length);
    memcpy(buffer, bptr->data, bptr->length-1);
    int buf_len = bptr->length-1;
    buffer[bptr->length-1] = 0;
    printf("X509_CERT After Conversion :\r\n %s\r\n",buffer);
    BIO_free_all(buff);
    BIO_free_all(out);
    free(buffer);
    PKCS7_free(p7);     
}

我哪里可能出错了?

如果替换 PKCS7 证书将正确加载:

    wc_PKCS7_Init(&pkcs7, NULL, INVALID_DEVID);
    wc_PKCS7_InitWithCert(&pkcs7, out, (word32)(outLen));

与:

    wc_PKCS7_Init(&pkcs7, NULL, INVALID_DEVID);
    wc_PKCS7_InitWithCert(&pkcs7, NULL, 0); //? maybe redundant
    wc_PKCS7_VerifySignedData(&pkcs7, out, (word32)outLen);

wc_PKCS7_InitWithCert call doesn't seem to be necessary when there is no recipient certificate, but it's still present in WolfSSL's own pkcs7-verify.c 示例。