diff options
Diffstat (limited to 'camel/camel-sasl-digest-md5.c')
-rw-r--r-- | camel/camel-sasl-digest-md5.c | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/camel/camel-sasl-digest-md5.c b/camel/camel-sasl-digest-md5.c index 0b1a7f4432..c4b2953c5a 100644 --- a/camel/camel-sasl-digest-md5.c +++ b/camel/camel-sasl-digest-md5.c @@ -528,16 +528,6 @@ digest_hex (guchar *digest, guchar hex[33]) sprintf (p, "%.2x", *s); } -static void -digest_kd (const char *k, const char *s, guchar digest[16]) -{ - char *str; - - str = g_strdup_printf ("%s:%s", k, s); - md5_get_digest (str, strlen (str), digest); - g_free (str); -} - static char * digest_uri_to_string (struct _DigestURI *uri) { @@ -551,57 +541,71 @@ static void compute_response (struct _DigestResponse *resp, const char *passwd, gboolean client, guchar out[33]) { guchar hex_a1[33], hex_a2[33]; - GByteArray *buffer; guchar digest[16]; + MD5Context ctx; char *buf; /* compute A1 */ - buf = g_strdup_printf ("%s:%s:%s", resp->username, resp->realm, passwd); - md5_get_digest (buf, strlen (buf), digest); - g_free (buf); - if (resp->authzid) - buf = g_strdup_printf (":%s:%s:%s", resp->nonce, resp->cnonce, resp->authzid); - else - buf = g_strdup_printf (":%s:%s", resp->nonce, resp->cnonce); - buffer = g_byte_array_new (); - g_byte_array_append (buffer, digest, 16); - g_byte_array_append (buffer, buf, strlen (buf)); - g_free (buf); + md5_init (&ctx); + md5_update (&ctx, resp->username, strlen (resp->username)); + md5_update (&ctx, ":", 1); + md5_update (&ctx, resp->realm, strlen (resp->realm)); + md5_update (&ctx, ":", 1); + md5_update (&ctx, passwd, strlen (passwd)); + md5_final (&ctx, digest); + + md5_init (&ctx); + md5_update (&ctx, digest, 16); + md5_update (&ctx, ":", 1); + md5_update (&ctx, resp->nonce, strlen (resp->nonce)); + md5_update (&ctx, ":", 1); + md5_update (&ctx, resp->cnonce, strlen (resp->cnonce)); + if (resp->authzid) { + md5_update (&ctx, ":", 1); + md5_update (&ctx, resp->authzid, strlen (resp->authzid)); + } - /* now hash and hex A1 */ - md5_get_digest (buffer->data, buffer->len, digest); - g_byte_array_free (buffer, TRUE); + /* hexify A1 */ + md5_final (&ctx, digest); digest_hex (digest, hex_a1); /* compute A2 */ - buffer = g_byte_array_new (); + md5_init (&ctx); if (client) { - g_byte_array_append (buffer, "AUTHENTICATE:", strlen ("AUTHENTICATE:")); - buf = digest_uri_to_string (resp->uri); - g_byte_array_append (buffer, buf, strlen (buf)); - g_free (buf); + /* we are calculating the client response */ + md5_update (&ctx, "AUTHENTICATE:", strlen ("AUTHENTICATE:")); } else { /* we are calculating the server rspauth */ - g_byte_array_append (buffer, ":", 1); - buf = digest_uri_to_string (resp->uri); - g_byte_array_append (buffer, buf, strlen (buf)); - g_free (buf); + md5_update (&ctx, ":", 1); } + buf = digest_uri_to_string (resp->uri); + md5_update (&ctx, buf, strlen (buf)); + g_free (buf); + if (resp->qop == QOP_AUTH_INT || resp->qop == QOP_AUTH_CONF) - g_byte_array_append (buffer, ":00000000000000000000000000000000", - strlen (":00000000000000000000000000000000")); - /* now hash and hex A2 */ - md5_get_digest (buffer->data, buffer->len, digest); - g_byte_array_free (buffer, TRUE); + md5_update (&ctx, ":00000000000000000000000000000000", 33); + + /* now hexify A2 */ + md5_final (&ctx, digest); digest_hex (digest, hex_a2); /* compute KD */ - buf = g_strdup_printf ("%s:%s:%s:%s:%s", resp->nonce, resp->nc, resp->cnonce, - qop_to_string (resp->qop), hex_a2); - digest_kd (hex_a1, buf, digest); + md5_init (&ctx); + md5_update (&ctx, hex_a1, 32); + md5_update (&ctx, ":", 1); + md5_update (&ctx, resp->nonce, strlen (resp->nonce)); + md5_update (&ctx, ":", 1); + md5_update (&ctx, resp->nc, 8); + md5_update (&ctx, ":", 1); + md5_update (&ctx, resp->cnonce, strlen (resp->cnonce)); + md5_update (&ctx, ":", 1); + md5_update (&ctx, qop_to_string (resp->qop), strlen (qop_to_string (resp->qop))); + md5_update (&ctx, ":", 1); + md5_update (&ctx, hex_a2, 32); + md5_final (&ctx, digest); + digest_hex (digest, out); - g_free (buf); } static struct _DigestResponse * @@ -615,7 +619,7 @@ generate_response (struct _DigestChallenge *challenge, struct hostent *host, resp = g_new0 (struct _DigestResponse, 1); resp->username = g_strdup (user); /* FIXME: we should use the preferred realm */ - if (challenge->realms) + if (challenge->realms && challenge->realms->len > 0) resp->realm = g_strdup (challenge->realms->pdata[0]); else resp->realm = g_strdup (""); |