1
2 #define HTTP_MAX_BINARY_MD5 16
3 #define HTTP_MAX_ASCII_MD5 32
4 #define HTTP_SERVER_NONCE_SIZE 32
5 #define HTTP_MAX_RESOURCE 64
6
http_hex_ascii_convert(CHAR * source,UINT source_length,CHAR * destination)7 VOID http_hex_ascii_convert(CHAR *source, UINT source_length, CHAR *destination)
8 {
9
10 UINT i,j;
11 CHAR digit;
12
13
14 /* Setup destination index. */
15 j = 0;
16
17 /* Loop to process the entire source string. */
18 for (i = 0; i < source_length; i++)
19 {
20
21 /* Pickup the first nibble. */
22 digit = (source[i] >> 4) & 0xF;
23
24 /* Convert to ASCII and store. */
25 if (digit <= 9)
26 destination[j++] = (CHAR)(digit + '0');
27 else
28 destination[j++] = (CHAR)(digit + 'a' - 10);
29
30 /* Pickup the second nibble. */
31 digit = source[i] & 0xF;
32
33 /* Convert to ASCII and store. */
34 if (digit <= 9)
35 destination[j++] = (CHAR)(digit + '0');
36 else
37 destination[j++] = (CHAR)(digit + 'a' - 10);
38 }
39
40 /* Finally, place a NULL in the destination string. */
41 destination[j] = (CHAR) NX_NULL;
42 }
43
http_nonce_retrieve(NX_PACKET * packet_ptr,CHAR * nonce)44 UINT http_nonce_retrieve(NX_PACKET *packet_ptr, CHAR *nonce)
45 {
46 UINT length;
47 UINT found;
48 CHAR *buffer_ptr;
49
50 found = NX_FALSE;
51 length = 0;
52 nonce[0] = NX_NULL;
53
54 buffer_ptr = (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
55
56 while (((buffer_ptr + 6) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
57 {
58
59 /* Check for the uri token. */
60 if (((*(buffer_ptr) == 'n') || (*(buffer_ptr) == 'N')) &&
61 ((*(buffer_ptr+1) == 'o') || (*(buffer_ptr+1) == 'O')) &&
62 ((*(buffer_ptr+2) == 'n') || (*(buffer_ptr+2) == 'N')) &&
63 ((*(buffer_ptr+3) == 'c') || (*(buffer_ptr+3) == 'C')) &&
64 ((*(buffer_ptr+4) == 'e') || (*(buffer_ptr+4) == 'E')) &&
65 (*(buffer_ptr+5) == '='))
66 {
67
68 /* Move the pointer up to the actual authorization string. */
69 buffer_ptr = buffer_ptr + 6;
70 found = NX_TRUE;
71
72 break;
73 }
74
75 /* Move the pointer up to the next character. */
76 buffer_ptr++;
77 }
78
79 if (found == NX_FALSE)
80 {
81 return(NX_NOT_FOUND);
82 }
83
84 /* Now remove any extra blanks and quotes. */
85 while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
86 {
87
88 /* Move the pointer up one character. */
89 buffer_ptr++;
90 }
91
92 /* Now pickup the nonce string. */
93 length = 0;
94 while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (length < HTTP_SERVER_NONCE_SIZE))
95 {
96
97 /* Determine if the ending quote is present. */
98 if (*buffer_ptr == (CHAR) 0x22)
99 {
100
101 break;
102 }
103
104 /* Copy a character of the authorization string into the destination. */
105 nonce[length++] = *buffer_ptr++;
106 }
107
108 nonce[length] = NX_NULL;
109 return(NX_SUCCESS);
110 }
111
http_digest_response_calculate(NX_MD5 * md5data,CHAR * username,CHAR * realm,CHAR * password,CHAR * nonce,CHAR * method,CHAR * uri,CHAR * nc,CHAR * cnonce,CHAR * result)112 VOID http_digest_response_calculate(NX_MD5 *md5data, CHAR *username, CHAR *realm, CHAR *password, CHAR *nonce, CHAR *method, CHAR *uri, CHAR *nc, CHAR *cnonce, CHAR *result)
113 {
114
115 CHAR md5_binary[HTTP_MAX_BINARY_MD5];
116 CHAR ha1_string[HTTP_MAX_ASCII_MD5 + 1];
117 CHAR ha2_string[HTTP_MAX_ASCII_MD5 + 1];
118 UINT username_length;
119 UINT password_length;
120 UINT realm_length;
121 UINT method_length;
122 UINT uri_length;
123 UINT nc_length;
124 UINT cnonce_length;
125
126 /* Get string length. */
127 username_length = strlen(username);
128 password_length = strlen(password);
129 realm_length = strlen(realm);
130 method_length = strlen(method);
131 uri_length = strlen(uri);
132 nc_length = strlen(nc);
133 cnonce_length = strlen(cnonce);
134
135
136 /* Calculate the H(A1) portion of the digest. */
137 _nx_md5_initialize(md5data);
138 _nx_md5_update(md5data, (unsigned char *) username, username_length);
139 _nx_md5_update(md5data, (unsigned char *) ":", 1);
140 _nx_md5_update(md5data, (unsigned char *) realm, realm_length);
141 _nx_md5_update(md5data, (unsigned char *) ":", 1);
142 _nx_md5_update(md5data, (unsigned char *) password, password_length);
143 _nx_md5_digest_calculate(md5data, (unsigned char *) md5_binary);
144
145 /* Convert this H(A1) portion to ASCII Hex representation. */
146 http_hex_ascii_convert(md5_binary, HTTP_MAX_BINARY_MD5, ha1_string);
147
148 /* Make the H(A2) portion of the digest. */
149 _nx_md5_initialize(md5data);
150 _nx_md5_update(md5data, (unsigned char *) method, method_length);
151 _nx_md5_update(md5data, (unsigned char *) ":", 1);
152 _nx_md5_update(md5data, (unsigned char *) uri, uri_length);
153 _nx_md5_digest_calculate(md5data, (unsigned char *) md5_binary);
154
155 /* Convert this H(A2) portion to ASCII Hex representation. */
156 http_hex_ascii_convert(md5_binary, HTTP_MAX_BINARY_MD5, ha2_string);
157
158 /* Now make the final MD5 digest. */
159 _nx_md5_initialize(md5data);
160 _nx_md5_update(md5data, (unsigned char *) ha1_string, sizeof(ha1_string) - 1);
161 _nx_md5_update(md5data, (unsigned char *) ":", 1);
162 _nx_md5_update(md5data, (unsigned char *) nonce, HTTP_SERVER_NONCE_SIZE);
163
164 /* Start of Internet Explorer bug work-around. */
165 _nx_md5_update(md5data, (unsigned char *) ":", 1);
166 _nx_md5_update(md5data, (unsigned char *) nc, nc_length);
167 _nx_md5_update(md5data, (unsigned char *) ":", 1);
168 _nx_md5_update(md5data, (unsigned char *) cnonce, cnonce_length);
169 _nx_md5_update(md5data, (unsigned char *) ":auth", 5);
170 /* End of Internet Explorer bug work-around. */
171
172 _nx_md5_update(md5data, (unsigned char *) ":", 1);
173 _nx_md5_update(md5data, (unsigned char *) ha2_string, sizeof(ha2_string) - 1);
174 _nx_md5_digest_calculate(md5data, (unsigned char *) md5_binary);
175
176 /* Finally, convert the response back to an ASCII string and place in
177 the destination. */
178 http_hex_ascii_convert(md5_binary, HTTP_MAX_BINARY_MD5, result);
179 }