/* * Compute MD5( "<user>:<realm>:<pass>" ) * if use8859_1 is non-zero, then user/realm is 8859-1 charset * if supplied lengths are 0, strlen() is used * places result in hash_pass (of size DIGEST_SIZE) and returns it. */ static unsigned char * digest_hash_pass(const char *user, int ulen, const char *realm, int rlen, const char *pass, int passlen, int use8859_1, unsigned char *hash_pass) { MD5_CTX ctx; MD5Init(&ctx); if (ulen == 0) ulen = strlen(user); if (use8859_1) { MD5Update(&ctx, (CONST_UCHAR *) user, ulen); } else { MD5_UTF8_8859_1(&ctx, (CONST_UCHAR *) user, ulen); } MD5Update(&ctx, colon, 1); if (rlen == 0) rlen = strlen(realm); if (use8859_1) { MD5Update(&ctx, (CONST_UCHAR *) realm, rlen); } else { MD5_UTF8_8859_1(&ctx, (CONST_UCHAR *) realm, rlen); } MD5Update(&ctx, colon, 1); if (passlen == 0) passlen = strlen(pass); MD5Update(&ctx, (CONST_UCHAR *) pass, passlen); MD5Final(hash_pass, &ctx); return (hash_pass); }
void DigestCalcSecret( unsigned char *pszUserName, unsigned char *pszRealm, unsigned char *Password, size_t PasswordLen, HASH HA1) { bool In_8859_1; MD5_CTX Md5Ctx; /* Chris Newman clarified that the following text in DIGEST-MD5 spec is bogus: "if name and password are both in ISO 8859-1 charset" We shoud use code example instead */ MD5_Init(&Md5Ctx); /* We have to convert UTF-8 to ISO-8859-1 if possible */ In_8859_1 = UTF8_In_8859_1(pszUserName, (int)strlen((char *) pszUserName)); MD5_UTF8_8859_1(&Md5Ctx, In_8859_1, pszUserName, (int)strlen((char *) pszUserName)); MD5_Update(&Md5Ctx, COLON, 1); if (pszRealm != NULL && pszRealm[0] != '\0') { /* a NULL realm is equivalent to the empty string */ MD5_Update(&Md5Ctx, pszRealm, strlen((char *) pszRealm)); } MD5_Update(&Md5Ctx, COLON, 1); /* We have to convert UTF-8 to ISO-8859-1 if possible */ In_8859_1 = UTF8_In_8859_1(Password, PasswordLen); MD5_UTF8_8859_1(&Md5Ctx, In_8859_1, Password, PasswordLen); MD5_Final(HA1, &Md5Ctx); }