Как функции OpenSSL работают с памятью?

На официальном wiki openssl есть пример функции создания цифровой подписи (Calculating HMAC).

  1. При первом вызове функции выделяется память, но не освобождается (снимок 3).
  2. При повторном вызове функции память уже не выделяется (снимок 4).

введите сюда описание изображения

Функция подписи из примера:

int hmac_it(const unsigned char* msg, size_t mlen, unsigned char** val, size_t* vlen, EVP_PKEY* pkey)
{
    /* Returned to caller */
    int result = 0;
    EVP_MD_CTX* ctx = NULL;
    size_t req = 0;
    int rc;

    if (!msg || !mlen || !val || !pkey)
        return 0;

    *val = NULL;
    *vlen = 0;

    ctx = EVP_MD_CTX_new();
    if (ctx == NULL) {
        printf("EVP_MD_CTX_create failed, error 0x%lx\n", ERR_get_error());
        goto err;
    }

    rc = EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, pkey);
    if (rc != 1) {
        printf("EVP_DigestSignInit failed, error 0x%lx\n", ERR_get_error());
        goto err;
    }

    rc = EVP_DigestSignUpdate(ctx, msg, mlen);
    if (rc != 1) {
        printf("EVP_DigestSignUpdate failed, error 0x%lx\n", ERR_get_error());
        goto err;
    }

    rc = EVP_DigestSignFinal(ctx, NULL, &req);
    if (rc != 1) {
        printf("EVP_DigestSignFinal failed (1), error 0x%lx\n", ERR_get_error());
        goto err;
    }

    //*val = OPENSSL_malloc(req);
    *val = (unsigned char*)OPENSSL_malloc(req);
    if (*val == NULL) {
        printf("OPENSSL_malloc failed, error 0x%lx\n", ERR_get_error());
        goto err;
    }

    *vlen = req;
    rc = EVP_DigestSignFinal(ctx, *val, vlen);
    if (rc != 1) {
        printf("EVP_DigestSignFinal failed (3), return code %d, error 0x%lx\n", rc, ERR_get_error());
        goto err;
    }

    result = 1;


err:
    EVP_MD_CTX_free(ctx);
    if (!result) {
        OPENSSL_free(*val);
        *val = NULL;
    }
    return result;
}

Вызов функции 2 раза подряд:

EVP_PKEY* pKey = nullptr;
...
// Создаем pKey
...
unsigned char* signData = nullptr;
size_t signedDataLen = 0;

std::string msg1 = "message 1";
std::string msg2 = "message 2";

// СНИМОК 2 (Состояние до первого вызова функции)
// Первый вызов    
hmac_it((const unsigned char*)msg1.data(), msg1.length(), &signData, &signedDataLen, pKey);

OPENSSL_free(signData);

// СНИМОК 3
// Второй вызов
hmac_it((const unsigned char*)msg2.data(), msg2.length(), &signData, &signedDataLen, pKey);

OPENSSL_free(signData);

// СНИМОК 4 (Состояние после второго вызова функции)

Почему между 3им и 2ым снимками память выделяется, а между 3им и 4ым нет. Я же вызываю одну и ту же функцию?


Ответы (0 шт):