#include "rsa-md4.h"
#include "arcfour-int.h"
-static void asctouni(unsigned char *unicode, unsigned char *ascii, size_t len)
+#if TARGET_OS_MAC
+#include <CoreFoundation/CFString.h>
+#endif
+
+static krb5_error_code
+utf8to16(unsigned char *utf16_buf, const char *utf8_str, size_t *len)
{
+ krb5_error_code err = 0;
+
+#if TARGET_OS_MAC
+ CFStringRef string = NULL;
+ CFIndex length = *len;
+
+ string = CFStringCreateWithCString (kCFAllocatorDefault,
+ utf8_str, kCFStringEncodingUTF8);
+ if (!string) { err = ENOMEM; }
+
+ if (!err) {
+ CFIndex copied = 0;
+ CFRange range = CFRangeMake (0, CFStringGetLength (string));
+
+ copied = CFStringGetBytes (string, range, kCFStringEncodingUTF16LE,
+ 0, false, utf16_buf, length, &length);
+ if (copied != range.length) { err = ENOMEM; }
+ }
+
+ if (!err) {
+ *len = length;
+ }
+
+ if (string) { CFRelease (string); }
+
+#else
+ /*
+ * This should be re-evaluated in the future, it makes the assumption that
+ * the user's password is in ascii, not utf-8. Use iconv?
+ */
size_t counter;
- for (counter=0;counter<len;counter++) {
- unicode[2*counter]=ascii[counter];
- unicode[2*counter + 1]=0x00;
+ for (counter=0;counter<*len;counter++) {
+ utf16_buf[2*counter]=utf8_str[counter];
+ utf16_buf[2*counter + 1]=0x00;
}
+#endif
+
+ return err;
}
krb5_error_code
const krb5_data *string, const krb5_data *salt,
const krb5_data *params, krb5_keyblock *key)
{
+ krb5_error_code err = 0;
size_t len,slen;
unsigned char *copystr;
krb5_MD4_CTX md4_context;
/* compute the space needed for the new string.
Since the password must be stored in unicode, we need to increase
that number by 2x.
-
- This should be re-evauated in the future, it makes the assumption that
- thes user's password is in ascii.
*/
slen = ((string->length)>128)?128:string->length;
len=(slen)*2;
return ENOMEM;
/* make the string. start by creating the unicode version of the password*/
- asctouni(copystr, (unsigned char *) string->data, slen);
+ err = utf8to16(copystr, string->data, &len);
+ if (err) goto cleanup;
/* the actual MD4 hash of the data */
krb5_MD4Init(&md4_context);
}
#endif /* 0 */
+cleanup:
/* Zero out the data behind us */
memset (copystr, 0, len);
memset(&md4_context, 0, sizeof(md4_context));
free(copystr);
- return 0;
+ return err;
}