David Fletcher / Mbed 2 deprecated cc3100_Test_websock_Camera_CM4F

Dependencies:   mbed

Committer:
dflet
Date:
Wed Jun 24 09:54:16 2015 +0000
Revision:
0:50cedd586816
First commit work in progress

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dflet 0:50cedd586816 1 //*****************************************************************************
dflet 0:50cedd586816 2 // Copyright (C) 2014 Texas Instruments Incorporated
dflet 0:50cedd586816 3 //
dflet 0:50cedd586816 4 // All rights reserved. Property of Texas Instruments Incorporated.
dflet 0:50cedd586816 5 // Restricted rights to use, duplicate or disclose this code are
dflet 0:50cedd586816 6 // granted through contract.
dflet 0:50cedd586816 7 // The program may not be used without the written permission of
dflet 0:50cedd586816 8 // Texas Instruments Incorporated or against the terms and conditions
dflet 0:50cedd586816 9 // stipulated in the agreement under which this program has been supplied,
dflet 0:50cedd586816 10 // and under no circumstances can it be used with non-TI connectivity device.
dflet 0:50cedd586816 11 //
dflet 0:50cedd586816 12 //*****************************************************************************
dflet 0:50cedd586816 13
dflet 0:50cedd586816 14 #include "HttpAuth.h"
dflet 0:50cedd586816 15
dflet 0:50cedd586816 16 #ifdef HTTP_CORE_ENABLE_AUTH
dflet 0:50cedd586816 17
dflet 0:50cedd586816 18 #include <string.h>
dflet 0:50cedd586816 19 #include "HttpString.h"
dflet 0:50cedd586816 20 /**
dflet 0:50cedd586816 21 * @addtogroup HttpAuth
dflet 0:50cedd586816 22 * @{
dflet 0:50cedd586816 23 */
dflet 0:50cedd586816 24
dflet 0:50cedd586816 25 #define DIGEST_AUTHENTICATION_BUFFER_SIZE (32)
dflet 0:50cedd586816 26
dflet 0:50cedd586816 27 /**
dflet 0:50cedd586816 28 * This structure holds the HTTP digest-access authentication state
dflet 0:50cedd586816 29 */
dflet 0:50cedd586816 30 struct HttpAuthState
dflet 0:50cedd586816 31 {
dflet 0:50cedd586816 32 /// Last-generated nonce
dflet 0:50cedd586816 33 UINT8 nonce[DIGEST_AUTHENTICATION_BUFFER_SIZE];
dflet 0:50cedd586816 34 /// Last-generated opaque
dflet 0:50cedd586816 35 UINT8 opaque[DIGEST_AUTHENTICATION_BUFFER_SIZE];
dflet 0:50cedd586816 36 /// The hash of the username, realm, and password
dflet 0:50cedd586816 37 UINT8 ha1[DIGEST_AUTHENTICATION_BUFFER_SIZE];
dflet 0:50cedd586816 38 };
dflet 0:50cedd586816 39
dflet 0:50cedd586816 40
dflet 0:50cedd586816 41
dflet 0:50cedd586816 42 /// The global state for digest-access authentication
dflet 0:50cedd586816 43
dflet 0:50cedd586816 44 static struct HttpAuthState g_authState; // = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
dflet 0:50cedd586816 45 // {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
dflet 0:50cedd586816 46 // {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
dflet 0:50cedd586816 47
dflet 0:50cedd586816 48 ///
dflet 0:50cedd586816 49 MD5_CTX MD5state;
dflet 0:50cedd586816 50
dflet 0:50cedd586816 51 char HTTP_AUTH_REALM[] = "cc3200 web server";
dflet 0:50cedd586816 52
dflet 0:50cedd586816 53 /// Header strings to be used for response headers
dflet 0:50cedd586816 54 char HTTP_AUTHENTICATE_RESPONSE_REALM[] = "WWW-Authenticate: Digest realm=\"";
dflet 0:50cedd586816 55 char HTTP_AUTHENTICATE_RESPONSE_NONCE[] = "\",qop=\"auth\",nonce=\"";
dflet 0:50cedd586816 56 char HTTP_AUTHENTICATE_RESPONSE_OPAQUE[] = "\",opaque=\"";
dflet 0:50cedd586816 57 char HTTP_AUTHENTICATE_RESPONSE_EOH[] = "\"\r\n";
dflet 0:50cedd586816 58
dflet 0:50cedd586816 59 /// Authenticate header tokens
dflet 0:50cedd586816 60 char HTTP_AUTHENTICATE_REALM[] = "realm";
dflet 0:50cedd586816 61 char HTTP_AUTHENTICATE_QOP[] = "qop";
dflet 0:50cedd586816 62 char HTTP_AUTHENTICATE_AUTH[] = "auth";
dflet 0:50cedd586816 63 char HTTP_AUTHENTICATE_NONCE[] = "nonce";
dflet 0:50cedd586816 64 char HTTP_AUTHENTICATE_OPAQUE[] = "opaque";
dflet 0:50cedd586816 65 char HTTP_AUTHENTICATE_DIGEST[] = "digest";
dflet 0:50cedd586816 66 char HTTP_AUTHENTICATE_URI[] = "uri";
dflet 0:50cedd586816 67 char HTTP_AUTHENTICATE_NC[] = "nc=";
dflet 0:50cedd586816 68 char HTTP_AUTHENTICATE_CNONCE[] = "cnonce";
dflet 0:50cedd586816 69 char HTTP_AUTHENTICATE_RESPONSE[] = "response";
dflet 0:50cedd586816 70 char HTTP_AUTHENTICATE_USERNAME[] = "username";
dflet 0:50cedd586816 71 char HTTP_DELIMITER_QUOTE[] = "\"";
dflet 0:50cedd586816 72 char HTTP_DELIMITER_COMMA[] = ",";
dflet 0:50cedd586816 73
dflet 0:50cedd586816 74
dflet 0:50cedd586816 75 /// The length of the response authentication header
dflet 0:50cedd586816 76 /// The two 32 numbers represent nonce and opaque strings and the -5 is to compensate for the sizeof() calls
dflet 0:50cedd586816 77 UINT16 HTTP_AUTHENTICATE_RESPONSE_HEADER_LENGTH =
dflet 0:50cedd586816 78 sizeof(HTTP_AUTHENTICATE_RESPONSE_REALM) +
dflet 0:50cedd586816 79 sizeof(HTTP_AUTHENTICATE_RESPONSE_NONCE) +
dflet 0:50cedd586816 80 sizeof(HTTP_AUTHENTICATE_RESPONSE_OPAQUE) +
dflet 0:50cedd586816 81 sizeof(HTTP_AUTHENTICATE_RESPONSE_EOH) +
dflet 0:50cedd586816 82 sizeof(HTTP_AUTH_REALM) +
dflet 0:50cedd586816 83 DIGEST_AUTHENTICATION_BUFFER_SIZE + DIGEST_AUTHENTICATION_BUFFER_SIZE - 5;
dflet 0:50cedd586816 84
dflet 0:50cedd586816 85
dflet 0:50cedd586816 86 /**
dflet 0:50cedd586816 87 * Simple random generator
dflet 0:50cedd586816 88 * To improve randomness the initial seed has to be dynamic
dflet 0:50cedd586816 89 */
dflet 0:50cedd586816 90 static UINT32 GetRandomUint()
dflet 0:50cedd586816 91 {
dflet 0:50cedd586816 92 // set static seed
dflet 0:50cedd586816 93 static UINT32 m_z = 1234;
dflet 0:50cedd586816 94 static UINT32 m_w = 98877;
dflet 0:50cedd586816 95
dflet 0:50cedd586816 96 m_z = 36969 * (m_z & 65535) + (m_z >> 16);
dflet 0:50cedd586816 97 m_w = 18000 * (m_w & 65535) + (m_w >> 16);
dflet 0:50cedd586816 98 return (m_z << 16) + m_w;
dflet 0:50cedd586816 99 }
dflet 0:50cedd586816 100
dflet 0:50cedd586816 101 static void MD5_FinalToString(UINT8* str, MD5_CTX *md5stat)
dflet 0:50cedd586816 102 {
dflet 0:50cedd586816 103 UINT8 tmp[16];
dflet 0:50cedd586816 104 UINT8 i;
dflet 0:50cedd586816 105 struct HttpBlob location;
dflet 0:50cedd586816 106 location.uLength = 2;
dflet 0:50cedd586816 107 location.pData = str;
dflet 0:50cedd586816 108 MD5_Final(tmp, md5stat);
dflet 0:50cedd586816 109 for (i=0; i<16; i++, location.pData += 2)
dflet 0:50cedd586816 110 HttpString_htoa(tmp[i], &location, 1);
dflet 0:50cedd586816 111 }
dflet 0:50cedd586816 112
dflet 0:50cedd586816 113
dflet 0:50cedd586816 114 /**
dflet 0:50cedd586816 115 * This function will generate random 16 bytes to be used for Nonce and opaque strings
dflet 0:50cedd586816 116 */
dflet 0:50cedd586816 117 static void Generate32BytesRandomString(UINT8 *str)
dflet 0:50cedd586816 118 {
dflet 0:50cedd586816 119 struct HttpBlob str1;
dflet 0:50cedd586816 120 str1.uLength = 8;
dflet 0:50cedd586816 121 str1.pData = str;
dflet 0:50cedd586816 122 HttpString_htoa(GetRandomUint(), &str1, 1);
dflet 0:50cedd586816 123 str1.pData = str + 8;
dflet 0:50cedd586816 124 HttpString_htoa(GetRandomUint(), &str1, 1);
dflet 0:50cedd586816 125 str1.pData = str + 16;
dflet 0:50cedd586816 126 HttpString_htoa(GetRandomUint(), &str1, 1);
dflet 0:50cedd586816 127 str1.pData = str + 24;
dflet 0:50cedd586816 128 HttpString_htoa(GetRandomUint(), &str1, 1);
dflet 0:50cedd586816 129 }
dflet 0:50cedd586816 130
dflet 0:50cedd586816 131 void HttpAuth_Init(struct HttpBlob username, struct HttpBlob password)
dflet 0:50cedd586816 132 {
dflet 0:50cedd586816 133 MD5_Init(&MD5state);
dflet 0:50cedd586816 134 MD5_Update(&MD5state, username.pData, username.uLength);
dflet 0:50cedd586816 135 MD5_Update(&MD5state, ":", 1);
dflet 0:50cedd586816 136 MD5_Update(&MD5state, HTTP_AUTH_REALM, sizeof(HTTP_AUTH_REALM)-1);
dflet 0:50cedd586816 137 MD5_Update(&MD5state, ":", 1);
dflet 0:50cedd586816 138 MD5_Update(&MD5state, password.pData, password.uLength);
dflet 0:50cedd586816 139 MD5_FinalToString(g_authState.ha1, &MD5state);
dflet 0:50cedd586816 140 }
dflet 0:50cedd586816 141
dflet 0:50cedd586816 142 static void AddStringToBlob(struct HttpBlob * trgt, char *str, UINT16 length)
dflet 0:50cedd586816 143 {
dflet 0:50cedd586816 144 memcpy(trgt->pData + trgt->uLength, str, length);
dflet 0:50cedd586816 145 trgt->uLength += length;
dflet 0:50cedd586816 146 }
dflet 0:50cedd586816 147
dflet 0:50cedd586816 148 void HttpAuth_ResponseAuthenticate(struct HttpRequest* pRequest, struct HttpBlob* pWWWAuthenticate)
dflet 0:50cedd586816 149 {
dflet 0:50cedd586816 150 struct HttpBlob headerBlob;
dflet 0:50cedd586816 151
dflet 0:50cedd586816 152 if (pWWWAuthenticate->uLength < HTTP_AUTHENTICATE_RESPONSE_HEADER_LENGTH)
dflet 0:50cedd586816 153 {
dflet 0:50cedd586816 154 pWWWAuthenticate->uLength = 0;
dflet 0:50cedd586816 155 return;
dflet 0:50cedd586816 156 }
dflet 0:50cedd586816 157 // There is enough space to add the authenticate header
dflet 0:50cedd586816 158
dflet 0:50cedd586816 159 headerBlob.pData = pWWWAuthenticate->pData;
dflet 0:50cedd586816 160 headerBlob.uLength = 0;
dflet 0:50cedd586816 161
dflet 0:50cedd586816 162 // Generate new Nonce and opaque
dflet 0:50cedd586816 163 Generate32BytesRandomString(g_authState.nonce);
dflet 0:50cedd586816 164 Generate32BytesRandomString(g_authState.opaque);
dflet 0:50cedd586816 165
dflet 0:50cedd586816 166 // Build response header
dflet 0:50cedd586816 167 AddStringToBlob(&headerBlob, HTTP_AUTHENTICATE_RESPONSE_REALM, sizeof(HTTP_AUTHENTICATE_RESPONSE_REALM)-1);
dflet 0:50cedd586816 168 AddStringToBlob(&headerBlob, HTTP_AUTH_REALM, sizeof(HTTP_AUTH_REALM) -1);
dflet 0:50cedd586816 169 AddStringToBlob(&headerBlob, HTTP_AUTHENTICATE_RESPONSE_NONCE, sizeof(HTTP_AUTHENTICATE_RESPONSE_NONCE) -1);
dflet 0:50cedd586816 170 AddStringToBlob(&headerBlob, (char*)g_authState.nonce, sizeof(g_authState.nonce));
dflet 0:50cedd586816 171 AddStringToBlob(&headerBlob, HTTP_AUTHENTICATE_RESPONSE_OPAQUE, sizeof(HTTP_AUTHENTICATE_RESPONSE_OPAQUE) -1);
dflet 0:50cedd586816 172 AddStringToBlob(&headerBlob, (char*)g_authState.opaque, sizeof(g_authState.opaque));
dflet 0:50cedd586816 173 AddStringToBlob(&headerBlob, HTTP_AUTHENTICATE_RESPONSE_EOH, sizeof(HTTP_AUTHENTICATE_RESPONSE_EOH) - 1);
dflet 0:50cedd586816 174
dflet 0:50cedd586816 175 pWWWAuthenticate->uLength = headerBlob.uLength;
dflet 0:50cedd586816 176 }
dflet 0:50cedd586816 177
dflet 0:50cedd586816 178 /**
dflet 0:50cedd586816 179 * Find/verify name value pair in the input blob
dflet 0:50cedd586816 180 *
dflet 0:50cedd586816 181 * After return the location is stays in the same place since the order of the name value pairs in not constant
dflet 0:50cedd586816 182 * Returns: if header not found return 0
dflet 0:50cedd586816 183 * if value token is NULL - return pointer to start of value length of value till the \" delimiter
dflet 0:50cedd586816 184 * if value token is not NULL - return 1 if values match
dflet 0:50cedd586816 185 */
dflet 0:50cedd586816 186 static UINT16 HttpAuth_VerifyHeaderNameValue(struct HttpBlob *location, char* nameToken, UINT8 tokenlenLen, char *value, UINT8 valuelen, char** outValue)
dflet 0:50cedd586816 187 {
dflet 0:50cedd586816 188 UINT8 * found;
dflet 0:50cedd586816 189 struct HttpBlob originalLocation;
dflet 0:50cedd586816 190 originalLocation.uLength = location->uLength;
dflet 0:50cedd586816 191 originalLocation.pData = location->pData;
dflet 0:50cedd586816 192
dflet 0:50cedd586816 193 found = HttpString_nextToken(nameToken, tokenlenLen, *location);
dflet 0:50cedd586816 194
dflet 0:50cedd586816 195 // Missing header name
dflet 0:50cedd586816 196 if (found == 0)
dflet 0:50cedd586816 197 return 0;
dflet 0:50cedd586816 198 else
dflet 0:50cedd586816 199 {
dflet 0:50cedd586816 200 location->uLength = originalLocation.uLength - (UINT16)(found - originalLocation.pData) - (tokenlenLen + 2);
dflet 0:50cedd586816 201 location->pData = found + tokenlenLen + 2;
dflet 0:50cedd586816 202 // Return the value pointer and size
dflet 0:50cedd586816 203 if (value == NULL)
dflet 0:50cedd586816 204 {
dflet 0:50cedd586816 205 *outValue= (char*)location->pData;
dflet 0:50cedd586816 206 nameToken = (char *)location->pData;
dflet 0:50cedd586816 207 found = HttpString_nextToken(HTTP_DELIMITER_QUOTE, sizeof(HTTP_DELIMITER_QUOTE) - 1, *location);
dflet 0:50cedd586816 208 if (found==0)
dflet 0:50cedd586816 209 found = HttpString_nextToken(HTTP_DELIMITER_COMMA, sizeof(HTTP_DELIMITER_COMMA) - 1, *location);
dflet 0:50cedd586816 210
dflet 0:50cedd586816 211 // Restore current location
dflet 0:50cedd586816 212 location->uLength = originalLocation.uLength;
dflet 0:50cedd586816 213 location->pData = originalLocation.pData;
dflet 0:50cedd586816 214 return (UINT16)((char *)found - nameToken);
dflet 0:50cedd586816 215 }
dflet 0:50cedd586816 216
dflet 0:50cedd586816 217 found = HttpString_nextToken(value, valuelen, *location);
dflet 0:50cedd586816 218 // Value does not match - restore location
dflet 0:50cedd586816 219 if (found == 0)
dflet 0:50cedd586816 220 {
dflet 0:50cedd586816 221 location->uLength = originalLocation.uLength;
dflet 0:50cedd586816 222 location->pData = originalLocation.pData;
dflet 0:50cedd586816 223 return 0;
dflet 0:50cedd586816 224 }
dflet 0:50cedd586816 225
dflet 0:50cedd586816 226 // Restore location
dflet 0:50cedd586816 227 location->uLength = originalLocation.uLength;
dflet 0:50cedd586816 228 location->pData = originalLocation.pData;
dflet 0:50cedd586816 229 return 1;
dflet 0:50cedd586816 230 }
dflet 0:50cedd586816 231 }
dflet 0:50cedd586816 232
dflet 0:50cedd586816 233
dflet 0:50cedd586816 234 void HttpAuth_RequestAuthenticate(struct HttpRequest* pRequest, struct HttpBlob authorization)
dflet 0:50cedd586816 235 {
dflet 0:50cedd586816 236 UINT8 ha2[DIGEST_AUTHENTICATION_BUFFER_SIZE], correctResponse[DIGEST_AUTHENTICATION_BUFFER_SIZE];
dflet 0:50cedd586816 237 struct HttpBlob currentLocation, blob;
dflet 0:50cedd586816 238 // HA1 was not copmuted
dflet 0:50cedd586816 239 if ((UINT32)*g_authState.ha1 == 0)
dflet 0:50cedd586816 240 {
dflet 0:50cedd586816 241 return;
dflet 0:50cedd586816 242 }
dflet 0:50cedd586816 243
dflet 0:50cedd586816 244 // Parse the header - find relevant tokens and handle
dflet 0:50cedd586816 245 currentLocation.pData = authorization.pData;
dflet 0:50cedd586816 246 currentLocation.uLength = authorization.uLength;
dflet 0:50cedd586816 247
dflet 0:50cedd586816 248 // Verify the mandatory tokens, whose content we ignore are present
dflet 0:50cedd586816 249
dflet 0:50cedd586816 250 // verify we are in degest authentication method, any other is not supported
dflet 0:50cedd586816 251 if (HttpString_nextToken(HTTP_AUTHENTICATE_DIGEST, sizeof(HTTP_AUTHENTICATE_DIGEST)-1, currentLocation) == 0)
dflet 0:50cedd586816 252 return;
dflet 0:50cedd586816 253
dflet 0:50cedd586816 254 // verify username exists
dflet 0:50cedd586816 255 if (HttpString_nextToken(HTTP_AUTHENTICATE_USERNAME, sizeof(HTTP_AUTHENTICATE_USERNAME)-1, currentLocation) == 0)
dflet 0:50cedd586816 256 return;
dflet 0:50cedd586816 257
dflet 0:50cedd586816 258 // Verify realm
dflet 0:50cedd586816 259 if (HttpAuth_VerifyHeaderNameValue(&currentLocation, HTTP_AUTHENTICATE_REALM, sizeof(HTTP_AUTHENTICATE_REALM)-1, HTTP_AUTH_REALM, sizeof(HTTP_AUTH_REALM)-1, 0) != 1)
dflet 0:50cedd586816 260 return;
dflet 0:50cedd586816 261
dflet 0:50cedd586816 262 // Verify correct nonce
dflet 0:50cedd586816 263 if (HttpAuth_VerifyHeaderNameValue(&currentLocation, HTTP_AUTHENTICATE_NONCE, sizeof(HTTP_AUTHENTICATE_NONCE)-1, (char *)g_authState.nonce, DIGEST_AUTHENTICATION_BUFFER_SIZE, 0) != 1)
dflet 0:50cedd586816 264 return;
dflet 0:50cedd586816 265
dflet 0:50cedd586816 266 // Verify correct opaque
dflet 0:50cedd586816 267 if (HttpAuth_VerifyHeaderNameValue(&currentLocation, HTTP_AUTHENTICATE_OPAQUE, sizeof(HTTP_AUTHENTICATE_OPAQUE)-1, (char *)g_authState.opaque, DIGEST_AUTHENTICATION_BUFFER_SIZE, 0) != 1)
dflet 0:50cedd586816 268 return;
dflet 0:50cedd586816 269
dflet 0:50cedd586816 270 // Find neccessary tokents and compute HA2 if some tokens are not found - return
dflet 0:50cedd586816 271 blob.pData = NULL;
dflet 0:50cedd586816 272 blob.uLength = HttpAuth_VerifyHeaderNameValue(&currentLocation, HTTP_AUTHENTICATE_URI, sizeof(HTTP_AUTHENTICATE_URI)-1, 0, 0, (char**)&blob.pData);
dflet 0:50cedd586816 273 // Uri is missing
dflet 0:50cedd586816 274 if (blob.uLength == 0)
dflet 0:50cedd586816 275 return;
dflet 0:50cedd586816 276
dflet 0:50cedd586816 277 MD5_Init(&MD5state);
dflet 0:50cedd586816 278 if ((pRequest->uFlags & HTTP_REQUEST_FLAG_METHOD_POST) != 0)
dflet 0:50cedd586816 279 MD5_Update(&MD5state, "POST", 4);
dflet 0:50cedd586816 280 else
dflet 0:50cedd586816 281 MD5_Update(&MD5state, "GET", 3);
dflet 0:50cedd586816 282 MD5_Update(&MD5state, ":", 1);
dflet 0:50cedd586816 283 MD5_Update(&MD5state, blob.pData, blob.uLength);
dflet 0:50cedd586816 284 MD5_FinalToString(ha2, &MD5state);
dflet 0:50cedd586816 285
dflet 0:50cedd586816 286 // Find tokens to compute correct response
dflet 0:50cedd586816 287 blob.pData = HttpString_nextToken(HTTP_AUTHENTICATE_NC, sizeof(HTTP_AUTHENTICATE_NC)-1, currentLocation);
dflet 0:50cedd586816 288 // Ncount is missing
dflet 0:50cedd586816 289 if (blob.pData == 0)
dflet 0:50cedd586816 290 return;
dflet 0:50cedd586816 291 blob.pData += sizeof(HTTP_AUTHENTICATE_NC) - 1;
dflet 0:50cedd586816 292 blob.uLength = 8;
dflet 0:50cedd586816 293
dflet 0:50cedd586816 294 MD5_Init(&MD5state);
dflet 0:50cedd586816 295 MD5_Update(&MD5state, g_authState.ha1, DIGEST_AUTHENTICATION_BUFFER_SIZE);
dflet 0:50cedd586816 296 MD5_Update(&MD5state, ":", 1);
dflet 0:50cedd586816 297 MD5_Update(&MD5state, g_authState.nonce, DIGEST_AUTHENTICATION_BUFFER_SIZE);
dflet 0:50cedd586816 298 MD5_Update(&MD5state, ":", 1);
dflet 0:50cedd586816 299 MD5_Update(&MD5state, blob.pData, blob.uLength);
dflet 0:50cedd586816 300
dflet 0:50cedd586816 301 blob.pData = NULL;
dflet 0:50cedd586816 302 blob.uLength = HttpAuth_VerifyHeaderNameValue(&currentLocation, HTTP_AUTHENTICATE_CNONCE, sizeof(HTTP_AUTHENTICATE_CNONCE)-1, 0, 0, (char **)&blob.pData);
dflet 0:50cedd586816 303 // Cnonce is missing
dflet 0:50cedd586816 304 if (blob.uLength == 0)
dflet 0:50cedd586816 305 return;
dflet 0:50cedd586816 306 MD5_Update(&MD5state, ":", 1);
dflet 0:50cedd586816 307 MD5_Update(&MD5state, blob.pData, blob.uLength);
dflet 0:50cedd586816 308 MD5_Update(&MD5state, ":auth:", 6);
dflet 0:50cedd586816 309 MD5_Update(&MD5state, ha2, DIGEST_AUTHENTICATION_BUFFER_SIZE);
dflet 0:50cedd586816 310 MD5_FinalToString(correctResponse, &MD5state);
dflet 0:50cedd586816 311
dflet 0:50cedd586816 312 // Compare received response to the one computed locally - if equal then authorize
dflet 0:50cedd586816 313 blob.pData = NULL;
dflet 0:50cedd586816 314 blob.uLength = HttpAuth_VerifyHeaderNameValue(&currentLocation, HTTP_AUTHENTICATE_RESPONSE, sizeof(HTTP_AUTHENTICATE_RESPONSE)-1, 0, 0, (char **)&blob.pData);
dflet 0:50cedd586816 315 // Response is missing
dflet 0:50cedd586816 316 if (blob.uLength != DIGEST_AUTHENTICATION_BUFFER_SIZE)
dflet 0:50cedd586816 317 return;
dflet 0:50cedd586816 318
dflet 0:50cedd586816 319 currentLocation.pData = correctResponse;
dflet 0:50cedd586816 320 currentLocation.uLength = DIGEST_AUTHENTICATION_BUFFER_SIZE;
dflet 0:50cedd586816 321 // if the responses are equal
dflet 0:50cedd586816 322 if (HttpString_strcmp(blob, currentLocation) == 0)
dflet 0:50cedd586816 323 pRequest->uFlags |= HTTP_REQUEST_FLAG_AUTHENTICATED;
dflet 0:50cedd586816 324
dflet 0:50cedd586816 325 }
dflet 0:50cedd586816 326 #endif
dflet 0:50cedd586816 327
dflet 0:50cedd586816 328 /// @}
dflet 0:50cedd586816 329
dflet 0:50cedd586816 330