libnm-core: reimplement crypto_md5_hash() using GChecksum

Reimplement crypto_md5_hash() using GChecksum. Remove the gboolean
return value and GError argument, since it cannot fail now.
This commit is contained in:
Dan Winship 2014-12-01 13:46:14 -05:00
parent 34519eee13
commit 48ff21b5bc
6 changed files with 66 additions and 171 deletions

View file

@ -404,25 +404,15 @@ make_des_aes_key (const char *cipher,
key = g_malloc0 (digest_len + 1);
if (!crypto_md5_hash (salt,
salt_len,
password,
strlen (password),
key,
digest_len,
error))
goto error;
crypto_md5_hash (salt,
salt_len,
password,
strlen (password),
key,
digest_len);
*out_len = digest_len;
return key;
error:
if (key) {
/* Don't leak stale key material */
memset (key, 0, digest_len);
g_free (key);
}
return NULL;
}
static GByteArray *
@ -746,3 +736,51 @@ crypto_verify_private_key (const char *filename,
}
return format;
}
void
crypto_md5_hash (const char *salt,
const gsize salt_len,
const char *password,
gsize password_len,
char *buffer,
gsize buflen)
{
GChecksum *ctx;
int nkey = buflen;
gsize digest_len;
int count = 0;
char digest[16];
char *p = buffer;
g_assert_cmpint (g_checksum_type_get_length (G_CHECKSUM_MD5), ==, sizeof (digest));
if (salt)
g_return_if_fail (salt_len >= 8);
g_return_if_fail (password != NULL);
g_return_if_fail (password_len > 0);
g_return_if_fail (buffer != NULL);
g_return_if_fail (buflen > 0);
ctx = g_checksum_new (G_CHECKSUM_MD5);
while (nkey > 0) {
int i = 0;
g_checksum_reset (ctx);
if (count++)
g_checksum_update (ctx, (const guchar *) digest, digest_len);
g_checksum_update (ctx, (const guchar *) password, password_len);
if (salt)
g_checksum_update (ctx, (const guchar *) salt, 8); /* Only use 8 bytes of salt */
g_checksum_get_digest (ctx, (guchar *) digest, &digest_len);
while (nkey && (i < digest_len)) {
*(p++) = digest[i++];
nkey--;
}
}
memset (digest, 0, sizeof (digest));
g_checksum_free (ctx);
}

View file

@ -78,13 +78,12 @@ NMCryptoFileFormat crypto_verify_private_key (const char *file,
/* Internal utils API bits for crypto providers */
gboolean crypto_md5_hash (const char *salt,
const gsize salt_len,
const char *password,
gsize password_len,
char *buffer,
gsize buflen,
GError **error);
void crypto_md5_hash (const char *salt,
const gsize salt_len,
const char *password,
gsize password_len,
char *buffer,
gsize buflen);
char * crypto_decrypt (const char *cipher,
int key_type,

View file

@ -56,63 +56,6 @@ crypto_init (GError **error)
return TRUE;
}
gboolean
crypto_md5_hash (const char *salt,
const gsize salt_len,
const char *password,
gsize password_len,
char *buffer,
gsize buflen,
GError **error)
{
gcry_md_hd_t ctx;
gcry_error_t err;
int nkey = buflen;
const gsize digest_len = 16;
int count = 0;
char digest[MD5_HASH_LEN];
char *p = buffer;
if (salt)
g_return_val_if_fail (salt_len >= SALT_LEN, FALSE);
g_return_val_if_fail (password != NULL, FALSE);
g_return_val_if_fail (password_len > 0, FALSE);
g_return_val_if_fail (buffer != NULL, FALSE);
g_return_val_if_fail (buflen > 0, FALSE);
err = gcry_md_open (&ctx, GCRY_MD_MD5, 0);
if (err) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_FAILED,
_("Failed to initialize the MD5 engine: %s / %s."),
gcry_strsource (err), gcry_strerror (err));
return FALSE;
}
while (nkey > 0) {
int i = 0;
if (count++)
gcry_md_write (ctx, digest, digest_len);
gcry_md_write (ctx, password, password_len);
if (salt)
gcry_md_write (ctx, salt, SALT_LEN); /* Only use 8 bytes of salt */
gcry_md_final (ctx);
memcpy (digest, gcry_md_read (ctx, 0), digest_len);
gcry_md_reset (ctx);
while (nkey && (i < digest_len)) {
*(p++) = digest[i++];
nkey--;
}
}
memset (digest, 0, sizeof (digest));
gcry_md_close (ctx);
return TRUE;
}
char *
crypto_decrypt (const char *cipher,
int key_type,

View file

@ -72,61 +72,6 @@ crypto_init (GError **error)
return TRUE;
}
gboolean
crypto_md5_hash (const char *salt,
const gsize salt_len,
const char *password,
gsize password_len,
char *buffer,
gsize buflen,
GError **error)
{
PK11Context *ctx;
int nkey = buflen;
unsigned int digest_len;
int count = 0;
char digest[MD5_HASH_LEN];
char *p = buffer;
if (salt)
g_return_val_if_fail (salt_len >= 8, FALSE);
g_return_val_if_fail (password != NULL, FALSE);
g_return_val_if_fail (password_len > 0, FALSE);
g_return_val_if_fail (buffer != NULL, FALSE);
g_return_val_if_fail (buflen > 0, FALSE);
ctx = PK11_CreateDigestContext (SEC_OID_MD5);
if (!ctx) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERROR_FAILED,
_("Failed to initialize the MD5 context: %d."),
PORT_GetError ());
return FALSE;
}
while (nkey > 0) {
int i = 0;
PK11_DigestBegin (ctx);
if (count++)
PK11_DigestOp (ctx, (const unsigned char *) digest, digest_len);
PK11_DigestOp (ctx, (const unsigned char *) password, password_len);
if (salt)
PK11_DigestOp (ctx, (const unsigned char *) salt, 8); /* Only use 8 bytes of salt */
PK11_DigestFinal (ctx, (unsigned char *) digest, &digest_len, sizeof (digest));
while (nkey && (i < digest_len)) {
*(p++) = digest[i++];
nkey--;
}
}
memset (digest, 0, sizeof (digest));
PK11_DestroyContext (ctx, PR_TRUE);
return TRUE;
}
char *
crypto_decrypt (const char *cipher,
int key_type,

View file

@ -1976,33 +1976,15 @@ nm_utils_uuid_generate (void)
char *
nm_utils_uuid_generate_from_string (const char *s)
{
GError *error = NULL;
uuid_t *uuid;
char *buf = NULL;
if (!nm_utils_init (&error)) {
g_warning ("error initializing crypto: (%d) %s",
error ? error->code : 0,
error ? error->message : "unknown");
if (error)
g_error_free (error);
return NULL;
}
uuid = g_malloc0 (sizeof (*uuid));
if (!crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (*uuid), &error)) {
g_warning ("error generating UUID: (%d) %s",
error ? error->code : 0,
error ? error->message : "unknown");
if (error)
g_error_free (error);
goto out;
}
crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (*uuid));
buf = g_malloc0 (37);
uuid_unparse_lower (*uuid, &buf[0]);
out:
g_free (uuid);
return buf;
}
@ -2012,8 +1994,7 @@ make_key (const char *cipher,
const char *salt,
const gsize salt_len,
const char *password,
gsize *out_len,
GError **error)
gsize *out_len)
{
char *key;
guint32 digest_len = 24; /* DES-EDE3-CBC */
@ -2030,13 +2011,8 @@ make_key (const char *cipher,
key = g_malloc0 (digest_len + 1);
if (!crypto_md5_hash (salt, salt_len, password, strlen (password), key, digest_len, error)) {
*out_len = 0;
memset (key, 0, digest_len);
g_free (key);
key = NULL;
} else
*out_len = digest_len;
crypto_md5_hash (salt, salt_len, password, strlen (password), key, digest_len);
*out_len = digest_len;
return key;
}
@ -2097,10 +2073,7 @@ nm_utils_rsa_key_encrypt_helper (const char *cipher,
if (!crypto_randomize (salt, salt_len, error))
goto out;
key = make_key (cipher, &salt[0], salt_len, in_password, &key_len, error);
if (!key)
goto out;
key = make_key (cipher, &salt[0], salt_len, in_password, &key_len);
enc = crypto_encrypt (cipher, data, len, salt, salt_len, key, key_len, &enc_len, error);
if (!enc)
goto out;

View file

@ -435,7 +435,6 @@ test_md5 (void)
{
char digest[LONG_DIGEST], *hex;
int i;
GError *error = NULL;
for (i = 0; i < G_N_ELEMENTS (md5_tests); i++) {
memset (digest, 0, sizeof (digest));
@ -443,9 +442,7 @@ test_md5 (void)
md5_tests[i].salt ? strlen (md5_tests[i].salt) : 0,
md5_tests[i].password,
strlen (md5_tests[i].password),
digest, md5_tests[i].digest_size,
&error);
g_assert_no_error (error);
digest, md5_tests[i].digest_size);
hex = nm_utils_bin2hexstr (digest, md5_tests[i].digest_size, -1);
g_assert_cmpstr (hex, ==, md5_tests[i].result);