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 }