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); key = g_malloc0 (digest_len + 1);
if (!crypto_md5_hash (salt, crypto_md5_hash (salt,
salt_len, salt_len,
password, password,
strlen (password), strlen (password),
key, key,
digest_len, digest_len);
error))
goto error;
*out_len = digest_len; *out_len = digest_len;
return key; return key;
error:
if (key) {
/* Don't leak stale key material */
memset (key, 0, digest_len);
g_free (key);
}
return NULL;
} }
static GByteArray * static GByteArray *
@ -746,3 +736,51 @@ crypto_verify_private_key (const char *filename,
} }
return format; 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 */ /* Internal utils API bits for crypto providers */
gboolean crypto_md5_hash (const char *salt, void crypto_md5_hash (const char *salt,
const gsize salt_len, const gsize salt_len,
const char *password, const char *password,
gsize password_len, gsize password_len,
char *buffer, char *buffer,
gsize buflen, gsize buflen);
GError **error);
char * crypto_decrypt (const char *cipher, char * crypto_decrypt (const char *cipher,
int key_type, int key_type,

View file

@ -56,63 +56,6 @@ crypto_init (GError **error)
return TRUE; 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 * char *
crypto_decrypt (const char *cipher, crypto_decrypt (const char *cipher,
int key_type, int key_type,

View file

@ -72,61 +72,6 @@ crypto_init (GError **error)
return TRUE; 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 * char *
crypto_decrypt (const char *cipher, crypto_decrypt (const char *cipher,
int key_type, int key_type,

View file

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

View file

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