00001 #include <stdlib.h>
00002 #include "md5.h"
00003 #include "md5crypt.h"
00004
00005 #define Assert(Cond) if (!(Cond)) abort()
00006
00007 static const char Base64[] =
00008 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00009 static const char Pad64 = '=';
00010
00011
00012 int b64_ntop(u_char const *src,
00013 size_t srclength, char *target, size_t targsize)
00014 {
00015 size_t datalength = 0;
00016 u_char input[3];
00017 u_char output[4];
00018 size_t i;
00019
00020 while (2 < srclength) {
00021 input[0] = *src++;
00022 input[1] = *src++;
00023 input[2] = *src++;
00024 srclength -= 3;
00025
00026 output[0] = input[0] >> 2;
00027 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
00028 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
00029 output[3] = input[2] & 0x3f;
00030 Assert(output[0] < 64);
00031 Assert(output[1] < 64);
00032 Assert(output[2] < 64);
00033 Assert(output[3] < 64);
00034
00035 if (datalength + 4 > targsize)
00036 return (-1);
00037 target[datalength++] = Base64[output[0]];
00038 target[datalength++] = Base64[output[1]];
00039 target[datalength++] = Base64[output[2]];
00040 target[datalength++] = Base64[output[3]];
00041 }
00042
00043
00044 if (0 != srclength) {
00045
00046 input[0] = input[1] = input[2] = '\0';
00047 for (i = 0; i < srclength; i++)
00048 input[i] = *src++;
00049
00050 output[0] = input[0] >> 2;
00051 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
00052 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
00053 Assert(output[0] < 64);
00054 Assert(output[1] < 64);
00055 Assert(output[2] < 64);
00056
00057 if (datalength + 4 > targsize)
00058 return (-1);
00059 target[datalength++] = Base64[output[0]];
00060 target[datalength++] = Base64[output[1]];
00061 if (srclength == 1)
00062 target[datalength++] = Pad64;
00063 else
00064 target[datalength++] = Base64[output[2]];
00065 target[datalength++] = Pad64;
00066 }
00067 if (datalength >= targsize)
00068 return (-1);
00069 target[datalength] = '\0';
00070 return (datalength);
00071 }
00072
00073 char *md5crypt(const char *password)
00074 {
00075 MD5_CTX MD5context;
00076 unsigned char MD5digest[16];
00077 char base64digest[25];
00078
00079 MD5Init(&MD5context);
00080 MD5Update(&MD5context,
00081 (const unsigned char *) password, strlen(password));
00082 MD5Final(MD5digest, &MD5context);
00083 if (b64_ntop(MD5digest, sizeof(MD5digest),
00084 base64digest, sizeof(base64digest)) < 0) {
00085 return (NULL);
00086 }
00087 return (strdup(base64digest));
00088
00089 }