首页 > 解决方案 > wolfcryp RSA 解析密钥分段失败

问题描述

我正在尝试在 WolfCrypt 库的帮助下使用 RSA 公钥验证消息。使用 Openssl 完成的消息签名和验证通过以下命令成功。

openssl dgst -sha256 -sign private.pem -out Message.sign.rsa1024-sha-256 Message.txt 
openssl dgst -sha256 -verify public.der -signture Message.sign.rsa1024-sha-256 Message.txt 

现在,在尝试使用 WolfCrypt 库编写程序来验证消息时(程序不完整,我卡在解析公钥部分),程序在解析公钥本身时引发分段错误。但是,在尝试使用 GDB 调试程序时,执行的代码的 parse key 部分不会引发任何分段错误并进入下一步并正常退出。

为了避免段错误,我尝试使用 malloc,但仍然出现 alloc(): memory corruption 错误。

看起来问题出在 wc_RsaPublicKeyDecode 参数上。在 GDB 上,当步入这个函数时,参数看起来是空的。欢迎任何建议。

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

/* Import APIs for Signing and Verification */
#include "wolfssl/wolfcrypt/rsa.h"
#include "wolfssl/wolfcrypt/hash.h"
#include "wolfssl/wolfcrypt/signature.h"

/* Import WolfSSL Types */
#include "wolfssl/wolfcrypt/types.h"

typedef struct wrap_Key
{
    word32 _KeyIndex;
    RsaKey _RsaKey;
}Key_t;

typedef struct wrap_Signature
{
    /* Signature Algorithms */
    enum wc_SignatureType _TYPE;
    enum wc_HashType _DIGEST;

    /* Message & Signature */
    byte *_Message;
    word32 _MessageLength;
    byte *_Signature;
    word32 _SignatureLength;
    byte *_KeyBuffer;
    word32 _KeyBufferLength;

    /* RSA Key Structure */
    Key_t _PKCS;

}Signature_t;


static int wrap_ReadFileToBuffer( byte **BufferData, word32* BufferLength, byte* URI )
{
    int ret = EXIT_SUCCESS;

    FILE *file = NULL;

    file = fopen(URI, "r");

    if( NULL == file )
    {
    printf( "Error! Unable to stat file.\r\n" );
    return EXIT_FAILURE;
    }

    /* Get content length & Reset Cursor */
    fseek( file, 0, SEEK_END );
    *BufferLength = (word32) ftell(file);
    fseek( file, 0, SEEK_SET );

    /* Allocate Enough Buffer */
    *BufferData = (byte*)(malloc( *BufferLength ));
    if( NULL == *BufferData )
    {
    fclose(file);
    printf("Error! Memory Allocation Failed.\r\n");
    return EXIT_FAILURE;
    }

    /* Read File Content */
    if( ( ret = fread( *BufferData, 1, *BufferLength, file ) )
                != *BufferLength )
    {
    fclose(file);
    printf("Error! Unable to read file.\r\n");
    return EXIT_FAILURE;
    }

    fclose(file);

    return ret;
}

Signature_t *RSA1;

int main()
{
    int ret = EXIT_SUCCESS;

    RSA1 = malloc(sizeof(Signature_t));

    /* Define Signagure & Type */
    RSA1->_TYPE   = WC_SIGNATURE_TYPE_RSA;
    RSA1->_DIGEST = WC_HASH_TYPE_SHA256;

    /* Initialize Message & Signature  */
    RSA1->_Message   = NULL;
    RSA1->_Signature = NULL;

    /* Verify does the Hash given above is supproted? */
    if( wc_HashGetDigestSize( RSA1->_DIGEST ) <= 0 )
    {
        printf("Hash type %d not supported!\n", RSA1->_DIGEST);
        return EXIT_FAILURE;
    }

    if( wrap_ReadFileToBuffer( &(RSA1->_Message), 
                   &(RSA1->_MessageLength), "Message.txt" ) <= 0 )
    {
        printf("Error! Reading Message Failed.\r\n");
    return EXIT_FAILURE;
    }


    if( wrap_ReadFileToBuffer( &(RSA1->_Signature), 
                   &(RSA1->_SignatureLength),
                   "Message.sign.rsa1024-sha-256" ) <= 0 )
    {
        printf("Error! Reading Signature Failed.\r\n");
    return EXIT_FAILURE;
    }


    if( wrap_ReadFileToBuffer( &(RSA1->_KeyBuffer), &(RSA1->_KeyBufferLength),
                   "public.der" ) <= 0 )
    {
        printf("Error! Reading Key Failed.\r\n");
    return EXIT_FAILURE;
    }

    if( ( ret = wc_InitRsaKey( &(RSA1->_PKCS._RsaKey), NULL ) ) )
    {
        printf("Error! Initialize Key Failed: -%d.\r\n", -ret);
    return EXIT_FAILURE;
    }

    RSA1->_PKCS._KeyIndex = 0;

    if( ( ret = wc_RsaPublicKeyDecode( RSA1->_KeyBuffer, 
                       &RSA1->_PKCS._KeyIndex,
                           &RSA1->_PKCS._RsaKey,
                           RSA1->_KeyBufferLength ) ) )
    {
        printf("Error! Reading Key Failed: -%d.\r\n", -ret);
    return EXIT_FAILURE;
    }

    free(RSA1);

    printf("WolfCrypt - Sample program!\r\n");


    return ret;
}

在尝试使用 GDB 进行调试时,发现在wc_InitRsaKey函数之后,整个结构 *RSA1 正在获取 char 数组(此处为字节)缺少它的数据。

(gdb) p *RSA1
$43 = {_TYPE = WC_SIGNATURE_TYPE_RSA, _DIGEST = WC_HASH_TYPE_SHA256, 
  _Message = 0x5555557585d0 &quot;This is sample message to be signed!\n&quot;, _MessageLength = 37, 
  _Signature = 0x555555758600 &quot;$\372\324@\340M\353\&quot;\216\226\302V\372\265\210\242\377\362\343ɮ\032\021\206K\016/\f2\002\020!\274\234\024\212,\034\276\276,31\217\277\274sP\341c\024=u\236\233l\207\330\320&gt;Ė\300K\211]\325\322x\307_9\251\017#\021&apos;\225Oƞ\276\311\a\177\063`\016\271G8\r;\201\036,7x\246\251Wd\246j\273\272\220\304\354\244\305\370\027\321\312\017\250n\336&apos;\375v{\251\267\270\237M&quot;, _SignatureLength = 128, 
  _KeyBuffer = 0x555555758690 &quot;0\201\237\060\r\006\t*\206H\206\367\r\001\001\001\005&quot;, 
  _KeyBufferLength = 162, _PKCS = {_KeyIndex = 0, _RsaKey = {n = {used = 0, alloc = 0, 
        sign = 0, dp = 0x0}, e = {used = 0, alloc = 0, sign = 0, dp = 0x0}, d = {used = 0, 
        alloc = 0, sign = 0, dp = 0x0}, p = {used = 0, alloc = 0, sign = 0, dp = 0x0}, q = {
        used = 0, alloc = 0, sign = 0, dp = 0x0}, dP = {used = 0, alloc = 0, sign = 0, 
        dp = 0x0}, dQ = {used = 0, alloc = 0, sign = 0, dp = 0x0}, u = {used = 0, alloc = 0, 
        sign = 0, dp = 0x0}, heap = 0x0, data = 0x0, type = 0, state = 0, dataLen = 0, 
      dataIsAlloc = 0 &apos;\000&apos;}}}
(gdb) n
133     RSA1-&gt;_PKCS._KeyIndex = 0;
(gdb) p *RSA1
$44 = {_TYPE = WC_SIGNATURE_TYPE_RSA, _DIGEST = WC_HASH_TYPE_SHA256, 
  _Message = 0x5555557585d0 &quot;&quot;, _MessageLength = 37, _Signature = 0x555555758600 &quot;&quot;, 
  _SignatureLength = 128, _KeyBuffer = 0x555555758690 &quot;&quot;, _KeyBufferLength = 162, _PKCS = {
    _KeyIndex = 0, _RsaKey = {n = {used = 0, alloc = 0, sign = 0, dp = 0x0}, e = {used = 0, 
        alloc = 0, sign = 0, dp = 0x0}, d = {used = 0, alloc = 0, sign = 0, dp = 0x0}, p = {
        used = 0, alloc = 0, sign = 0, dp = 0x0}, q = {used = 0, alloc = 0, sign = 0, 
        dp = 0x0}, dP = {used = 0, alloc = 0, sign = 0, dp = 0x0}, dQ = {used = 0, alloc = 0, 
        sign = 0, dp = 0x0}, u = {used = 0, alloc = 0, sign = 0, dp = 0x0}, heap = 0x0, 
      data = 0x0, type = 0, state = 0, dataLen = 0, dataIsAlloc = 0 &apos;\000&apos;}}}

标签: cpointersstructsegmentation-fault

解决方案


@戈皮,

这种分段错误的最常见原因是应用程序和库的错误配置。首先要检查的是包含的标题。

/* Import APIs for Signing and Verification */
#include "wolfssl/wolfcrypt/rsa.h"
#include "wolfssl/wolfcrypt/hash.h"
#include "wolfssl/wolfcrypt/signature.h"

/* Import WolfSSL Types */
#include "wolfssl/wolfcrypt/types.h"

请注意,“wolfssl/options.h”或“wolfssl/wolfcrypt/settings.h”均未包含在内。如果您使用 ./configure && make 构建了 wolfSSL 库,请在所有其他 wolfSSL 标头之前包含“wolfssl/options.h”。如果您仅使用“wolfssl/wolfcrypt/settings.h”来控制构建并且未找到 options.h,那么至少在所有其他 wolfSSL 标头之前包含“wolfssl/wolfcrypt/settings.h”:

/* Import APIs for Signing and Verification */
#include <wolfssl/options.h> // If not found or not available then include <wolfssl/wolfcrypt/settings.h>
#include "wolfssl/wolfcrypt/rsa.h"
#include "wolfssl/wolfcrypt/hash.h"
#include "wolfssl/wolfcrypt/signature.h"

/* Import WolfSSL Types */
#include "wolfssl/wolfcrypt/types.h"

干杯,

ķ


推荐阅读