I am new to OpenSSL and is currently working on a C++ project that has a dependency on OpenSSL. Recently i started using a machine that had openSSL 3.0 installed but is unable to build the project because i get compiler errors like below ( please note that warnings are treated as error in the project)
error: 'MD5' is deprecated
if (!MD5((uint8_t*)key.data(), key.size(), hashOutput)) {
^
/usr/local/Cellar/openssl@3/3.0.0_1/include/openssl/md5.h:52:1: note: 'MD5' has been explicitly marked deprecated here
OSSL_DEPRECATEDIN_3_0 unsigned char *MD5(const unsigned char *d, size_t n,
^
/usr/local/Cellar/openssl@3/3.0.0_1/include/openssl/macros.h:182:49: note: expanded from macro 'OSSL_DEPRECATEDIN_3_0'
# define OSSL_DEPRECATEDIN_3_0 OSSL_DEPRECATED(3.0)
^
/usr/local/Cellar/openssl@3/3.0.0_1/include/openssl/macros.h:62:52: note: expanded from macro 'OSSL_DEPRECATED'
# define OSSL_DEPRECATED(since) __attribute__((deprecated))
^
1 error generated.
Doing some investigation i found that these API's were deprecated in OpenSSL 3.0.0 and now i have three options
Ignore the warnings. They are just warnings. The deprecated functions are still present and you may still use them. However be aware that they may be removed from a future version of OpenSSL.
Suppress the warnings. Refer to your compiler documentation on how to do this.
Remove your usage of the low level APIs. In this case you will need to rewrite your code to use the high level APIs instead.
I choose the third option but even after reading documentations related to OpenSSL, i am still not sure what is the EVP API equivalent of the MD5 method which got deprecated in OpenSSL 3.0.0. If you check the link https://www.openssl.org/docs/manmaster/man3/MD5.html it states that
All of the functions described on this page are deprecated. Applications should instead use EVP_DigestInit_ex(3), EVP_DigestUpdate(3) and EVP_DigestFinal_ex(3).
Would be great if someone can provide me some feedback/help or additional resources/links that might help me understand using the high Level OpenSSL API's in general so that i can make it work for my use case i.e MD5 encryption.
I must also mention that i downloaded OpenSSL repo from github and found that the implementation of md5 method is as below
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
{
MD5_CTX c;
static unsigned char m[MD5_DIGEST_LENGTH];
if (md == NULL)
md = m;
if (!MD5_Init(&c))
return NULL;
#ifndef CHARSET_EBCDIC
MD5_Update(&c, d, n);
#else
{
char temp[1024];
unsigned long chunk;
while (n > 0) {
chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
ebcdic2ascii(temp, d, chunk);
MD5_Update(&c, temp, chunk);
n -= chunk;
d += chunk;
}
}
#endif
MD5_Final(md, &c);
OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
return md;
}
I hope this example would help (I'm not checking for errors and exceptions in my example, so be aware of that):
Deprecated Implementation
#include <openssl/md5.h>
static void calculate_md5(unsigned char* buf, unsigned int buf_size)
{
unsigned char md5_digest[MD5_DIGEST_LENGTH];
MD5_CTX md5ctx;
MD5_Init(&md5ctx);
MD5_Update(&md5ctx, buf, buf_size);
MD5_Final(md5_digest, &md5ctx);
}
New Implementation:
#include <openssl/evp.h>
static void calculate_md5(unsigned char* buf, unsigned int buf_size)
{
EVP_MD_CTX *mdctx;
unsigned char *md5_digest;
unsigned int md5_digest_len = EVP_MD_size(EVP_md5());
// MD5_Init
mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
// MD5_Update
EVP_DigestUpdate(mdctx, buf, buf_size);
// MD5_Final
md5_digest = (unsigned char *)OPENSSL_malloc(md5_digest_len);
EVP_DigestFinal_ex(mdctx, md5_digest, &md5_digest_len);
EVP_MD_CTX_free(mdctx);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With