Как функции OpenSSL работают с памятью?
На официальном wiki openssl есть пример функции создания цифровой подписи (Calculating HMAC).
- При первом вызове функции выделяется память, но не освобождается (снимок 3).
- При повторном вызове функции память уже не выделяется (снимок 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ым нет. Я же вызываю одну и ту же функцию?
