1/*
2 * MD5 password support for CUPS.
3 *
4 * Copyright 2007-2010 by Apple Inc.
5 * Copyright 1997-2005 by Easy Software Products.
6 *
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file.  If this file is
11 * missing or damaged, see the license at "http://www.cups.org/".
12 *
13 * This file is subject to the Apple OS-Developed Software exception.
14 */
15
16/*
17 * Include necessary headers...
18 */
19
20#include "http-private.h"
21#include "string-private.h"
22
23
24/*
25 * 'httpMD5()' - Compute the MD5 sum of the username:group:password.
26 */
27
28char *					/* O - MD5 sum */
29httpMD5(const char *username,		/* I - User name */
30        const char *realm,		/* I - Realm name */
31        const char *passwd,		/* I - Password string */
32	char       md5[33])		/* O - MD5 string */
33{
34  _cups_md5_state_t	state;		/* MD5 state info */
35  unsigned char		sum[16];	/* Sum data */
36  char			line[256];	/* Line to sum */
37
38
39 /*
40  * Compute the MD5 sum of the user name, group name, and password.
41  */
42
43  snprintf(line, sizeof(line), "%s:%s:%s", username, realm, passwd);
44  _cupsMD5Init(&state);
45  _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
46  _cupsMD5Finish(&state, sum);
47
48 /*
49  * Return the sum...
50  */
51
52  return (httpMD5String(sum, md5));
53}
54
55
56/*
57 * 'httpMD5Final()' - Combine the MD5 sum of the username, group, and password
58 *                    with the server-supplied nonce value, method, and
59 *                    request-uri.
60 */
61
62char *					/* O - New sum */
63httpMD5Final(const char *nonce,		/* I - Server nonce value */
64             const char *method,	/* I - METHOD (GET, POST, etc.) */
65	     const char *resource,	/* I - Resource path */
66             char       md5[33])	/* IO - MD5 sum */
67{
68  _cups_md5_state_t	state;		/* MD5 state info */
69  unsigned char		sum[16];	/* Sum data */
70  char			line[1024];	/* Line of data */
71  char			a2[33];		/* Hash of method and resource */
72
73
74 /*
75  * First compute the MD5 sum of the method and resource...
76  */
77
78  snprintf(line, sizeof(line), "%s:%s", method, resource);
79  _cupsMD5Init(&state);
80  _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
81  _cupsMD5Finish(&state, sum);
82  httpMD5String(sum, a2);
83
84 /*
85  * Then combine A1 (MD5 of username, realm, and password) with the nonce
86  * and A2 (method + resource) values to get the final MD5 sum for the
87  * request...
88  */
89
90  snprintf(line, sizeof(line), "%s:%s:%s", md5, nonce, a2);
91
92  _cupsMD5Init(&state);
93  _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
94  _cupsMD5Finish(&state, sum);
95
96  return (httpMD5String(sum, md5));
97}
98
99
100/*
101 * 'httpMD5String()' - Convert an MD5 sum to a character string.
102 */
103
104char *					/* O - MD5 sum in hex */
105httpMD5String(const unsigned char *sum,	/* I - MD5 sum data */
106              char                md5[33])
107					/* O - MD5 sum in hex */
108{
109  int		i;			/* Looping var */
110  char		*md5ptr;		/* Pointer into MD5 string */
111  static const char hex[] = "0123456789abcdef";
112					/* Hex digits */
113
114
115 /*
116  * Convert the MD5 sum to hexadecimal...
117  */
118
119  for (i = 16, md5ptr = md5; i > 0; i --, sum ++)
120  {
121    *md5ptr++ = hex[*sum >> 4];
122    *md5ptr++ = hex[*sum & 15];
123  }
124
125  *md5ptr = '\0';
126
127  return (md5);
128}
129