http_client_auth.c
Go to the documentation of this file.
1 /**
2  * @file http_client_auth.c
3  * @brief HTTP authentication
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @section Description
28  *
29  * The HTTP authentication framework consists of Basic and Digest access
30  * authentication schemes. Basic access authentication scheme is not considered
31  * to be a secure method of user authentication (unless used in conjunction with
32  * some external secure system such as SSL), as the user name and password are
33  * passed over the network as cleartext. Digest access authentication verifies
34  * that both parties know a shared secret; unlike Basic, this verification can
35  * be done without sending the password in the clear. Refer to the following
36  * RFCs for complete details:
37  * - RFC 2617: HTTP Authentication: Basic and Digest Access Authentication
38  * - RFC 7235: Hypertext Transfer Protocol (HTTP/1.1): Authentication
39  * - RFC 7616: HTTP Digest Access Authentication
40  * - RFC 7617: The Basic HTTP Authentication Scheme
41  *
42  * @author Oryx Embedded SARL (www.oryx-embedded.com)
43  * @version 1.9.4
44  **/
45 
46 //Switch to the appropriate trace level
47 #define TRACE_LEVEL HTTP_TRACE_LEVEL
48 
49 //Dependencies
50 #include "core/net.h"
51 #include "http/http_client.h"
52 #include "http/http_client_auth.h"
53 #include "debug.h"
54 
55 //Check TCP/IP stack configuration
56 #if (HTTP_CLIENT_SUPPORT == ENABLED && HTTP_CLIENT_AUTH_SUPPORT == ENABLED)
57 
58 
59 /**
60  * @brief Initialize HTTP authentication parameters
61  * @param[in] authParams HTTP authentication parameters
62  **/
63 
65 {
66  //Reset authentication scheme to its default value
67  authParams->mode = HTTP_AUTH_MODE_NONE;
68 
69  //Clear realm
70  strcpy(authParams->realm, "");
71 
72 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
73  //Reset authentication parameters
74  authParams->qop = HTTP_AUTH_QOP_NONE;
75  authParams->algorithm = NULL;
76  strcpy(authParams->nonce, "");
77  strcpy(authParams->cnonce, "");
78  strcpy(authParams->opaque, "");
79 
80  //Reset stale flag
81  authParams->stale = FALSE;
82 #endif
83 }
84 
85 
86 /**
87  * @brief Format Authorization header field
88  * @param[in] context Pointer to the HTTP client context
89  * @return Error code
90  **/
91 
93 {
94  size_t n;
95  char_t *p;
96  HttpClientAuthParams *authParams;
97 
98  //Make sure the buffer contains a valid HTTP request
99  if(context->bufferLen < 2 || context->bufferLen > HTTP_CLIENT_BUFFER_SIZE)
100  return ERROR_INVALID_SYNTAX;
101 
102  //Point to the HTTP authentication parameters
103  authParams = &context->authParams;
104 
105 #if (HTTP_CLIENT_BASIC_AUTH_SUPPORT == ENABLED)
106  //Basic authentication scheme?
107  if(authParams->mode == HTTP_AUTH_MODE_BASIC)
108  {
109  size_t k;
110  size_t m;
111 
112  //Calculate the length of the username and password
113  n = strlen(authParams->username) + strlen(authParams->password);
114 
115  //Make sure the buffer is large enough
116  if((context->bufferLen + n + 22) > HTTP_CLIENT_BUFFER_SIZE)
117  return ERROR_BUFFER_OVERFLOW;
118 
119  //Point to the buffer where to format the Authorization header field
120  p = context->buffer + context->bufferLen - 2;
121 
122  //Format Authorization header field
123  n = sprintf(p, "Authorization: Basic ");
124 
125  //The client sends the username and password, separated by a single
126  //colon character, within a Base64-encoded string in the credentials
127  m = sprintf(p + n, "%s:%s", authParams->username, authParams->password);
128 
129  //The first pass calculates the length of the Base64-encoded string
130  base64Encode(p + n, m, NULL, &k);
131 
132  //Make sure the buffer is large enough
133  if((context->bufferLen + n + k) > HTTP_CLIENT_BUFFER_SIZE)
134  return ERROR_BUFFER_OVERFLOW;
135 
136  //The second pass encodes the string using Base64
137  base64Encode(p + n, m, p + n, &k);
138  //Update the total length of the header field
139  n += k;
140 
141  //Make sure the buffer is large enough
142  if((context->bufferLen + n + 2) > HTTP_CLIENT_BUFFER_SIZE)
143  return ERROR_BUFFER_OVERFLOW;
144 
145  //Terminate the header field with a CRLF sequence
146  sprintf(p + n, "\r\n\r\n");
147 
148  //Adjust the length of the request header
149  context->bufferLen = context->bufferLen + n + 2;
150  }
151  else
152 #endif
153 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
154  //Digest authentication scheme?
155  if(authParams->mode == HTTP_AUTH_MODE_DIGEST)
156  {
157  error_t error;
158  const char_t *q;
159  const char_t *uri;
160  size_t uriLen;
161  char_t response[HTTP_CLIENT_MAX_RESPONSE_LEN + 1];
162 
163  //Properly terminate the string with a NULL character
164  context->buffer[context->bufferLen] = '\0';
165 
166  //The Request-Line begins with a method token
167  q = strchr(context->buffer, ' ');
168  //Any parsing error?
169  if(q == NULL)
170  return ERROR_INVALID_SYNTAX;
171 
172  //The method token is followed by the Request-URI
173  uri = q + 1;
174 
175  //Point to the end of the Request-URI
176  q = strchr(uri, ' ');
177  //Any parsing error?
178  if(q == NULL)
179  return ERROR_INVALID_SYNTAX;
180 
181  //Compute the length of the current URI
182  uriLen = q - uri;
183 
184  //Check quality of protection
185  if(authParams->qop == HTTP_AUTH_QOP_AUTH ||
186  authParams->qop == HTTP_AUTH_QOP_AUTH_INT)
187  {
188  //Make sure that a valid callback function has been registered
189  if(context->randCallback == NULL)
190  return ERROR_PRNG_NOT_READY;
191 
192  //A cryptographically strong random number generator must be used to
193  //generate the cnonce
194  error = context->randCallback(authParams->cnonce, HTTP_CLIENT_CNONCE_SIZE);
195  //Any error to report?
196  if(error)
197  return error;
198 
199  //Convert the byte array to hex string
201  authParams->cnonce);
202 
203  //Count of the number of requests (including the current request)
204  //that the client has sent with the nonce value in this request
205  authParams->nc++;
206  }
207 
208  //Perform digest operation
209  error = httpClientComputeDigest(authParams, context->method,
210  strlen(context->method), uri, uriLen, response);
211  //Any error to report?
212  if(error)
213  return error;
214 
215  //Determine the length of the header field
216  n = strlen(authParams->username) + strlen(authParams->realm) +
217  uriLen + strlen(authParams->nonce) + strlen(authParams->cnonce) +
218  strlen(response) + strlen(authParams->opaque);
219 
220  //Make sure the buffer is large enough
221  if((context->bufferLen + n + 121) > HTTP_CLIENT_BUFFER_SIZE)
222  return ERROR_BUFFER_OVERFLOW;
223 
224  //Point to the buffer where to format the Authorization header field
225  p = context->buffer + context->bufferLen - 2;
226 
227  //Format Authorization header field
228  n = sprintf(p, "Authorization: Digest ");
229 
230  //Format username and realm parameter
231  n += sprintf(p + n, "username=\"%s\", ", authParams->username);
232  n += sprintf(p + n, "realm=\"%s\", ", authParams->realm);
233 
234  //Format uri parameter
235  n += sprintf(p + n, "uri=\"");
236  strncpy(p + n, uri, uriLen);
237  n += uriLen;
238  n += sprintf(p + n, "\", ");
239 
240  //Format nonce parameter
241  n += sprintf(p + n, "nonce=\"%s\", ", authParams->nonce);
242 
243  //Check quality of protection
244  if(authParams->qop == HTTP_AUTH_QOP_AUTH)
245  {
246  //Format qop, nc, cnonce parameters
247  n += sprintf(p + n, "qop=auth, ");
248  n += sprintf(p + n, "nc=%08x, ", authParams->nc);
249  n += sprintf(p + n, "cnonce=\"%s\", ", authParams->cnonce);
250  }
251 
252  //Format response parameter
253  n += sprintf(p + n, "response=\"%s\"", response);
254 
255  //The opaque parameter should be returned by the client unchanged in
256  //the Authorization header field of subsequent requests
257  if(authParams->opaque[0] != '\0')
258  {
259  //Format opaque parameter
260  n += sprintf(p + n, ", opaque=\"%s\"", authParams->opaque);
261  }
262 
263  //Terminate the header field with a CRLF sequence
264  sprintf(p + n, "\r\n\r\n");
265 
266  //Adjust the length of the request header
267  context->bufferLen = context->bufferLen + n + 2;
268  }
269  else
270 #endif
271  //Unknown authentication scheme?
272  {
273  //Just for sanity
274  }
275 
276  //Successful processing
277  return NO_ERROR;
278 }
279 
280 
281 /**
282  * @brief Parse WWW-Authenticate header field
283  * @param[in] context Pointer to the HTTP client context
284  * @param[in] value NULL-terminated string that contains the value of header field
285  * @return Error code
286  **/
287 
289  const char_t *value)
290 {
291  error_t error;
292  const char_t *p;
293  HttpParam param;
294  HttpWwwAuthenticateHeader authHeader;
295 
296  //Point to the first character of the string
297  p = value;
298 
299  //Get the first token
300  error = httpParseParam(&p, &param);
301 
302  //The WWW-Authenticate header field indicates the authentication scheme(s)
303  //and parameters applicable to the target resource
304  while(!error)
305  {
306  //The authentication scheme must be a valid token followed by a
307  //BWS character
308  if(param.value == NULL && (*p == ' ' || *p == '\t'))
309  {
310  //Clear authentication parameters
311  memset(&authHeader, 0, sizeof(HttpWwwAuthenticateHeader));
312 
313 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED && HTTP_CLIENT_MD5_SUPPORT == ENABLED)
314  //If the algorithm parameter is not present, it is assumed to be
315  //MD5 (refer to RFC 7616, section 3.3)
316  authHeader.algorithm = MD5_HASH_ALGO;
317 #endif
318  //A case-insensitive token is used to identify the authentication
319  //scheme
320  if(httpCompareParamName(&param, "Basic"))
321  {
322  //Basic access authentication
323  authHeader.mode = HTTP_AUTH_MODE_BASIC;
324  }
325  else if(httpCompareParamName(&param, "Digest"))
326  {
327  //Digest access authentication
328  authHeader.mode = HTTP_AUTH_MODE_DIGEST;
329  }
330  else
331  {
332  //Unknown authentication scheme
333  authHeader.mode = HTTP_AUTH_MODE_NONE;
334  }
335 
336  //The authentication scheme is followed by a comma-separated list
337  //of attribute-value pairs which carry the parameters necessary for
338  //achieving authentication via that scheme
339  while(!error)
340  {
341  //Parse authentication parameter
342  error = httpParseParam(&p, &param);
343 
344  //Check status code
345  if(!error)
346  {
347  //Valid attribute-value pair?
348  if(param.value != NULL)
349  {
350  //Realm parameter?
351  if(httpCompareParamName(&param, "realm"))
352  {
353  //The realm is a string to be displayed to users so they
354  //know which username and password to use
355  authHeader.realm = param.value;
356  authHeader.realmLen = param.valueLen;
357  }
358 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
359  //Quality of protection parameter?
360  else if(httpCompareParamName(&param, "qop"))
361  {
362  //The qop parameter is a quoted string of one or more
363  //tokens indicating the "quality of protection" values
364  //supported by the server
365  httpClientParseQopParam(&param, &authHeader);
366  }
367  //Algorithm parameter?
368  else if(httpCompareParamName(&param, "algorithm"))
369  {
370  //This parameter indicates the algorithm used to produce
371  //the digest
372  httpClientParseAlgorithmParam(&param, &authHeader);
373  }
374  //Nonce parameter?
375  else if(httpCompareParamName(&param, "nonce"))
376  {
377  //The nonce is a server-specified string which should be
378  //uniquely generated each time a 401 response is made
379  authHeader.nonce = param.value;
380  authHeader.nonceLen = param.valueLen;
381  }
382  //Opaque parameter?
383  else if(httpCompareParamName(&param, "opaque"))
384  {
385  //The opaque parameter is a string of data, specified by the
386  //server, that should be returned by the client unchanged in
387  //the Authorization header field of subsequent requests
388  authHeader.opaque = param.value;
389  authHeader.opaqueLen = param.valueLen;
390  }
391  //Stale parameter?
392  else if(httpCompareParamName(&param, "stale"))
393  {
394  //The stale flag is a case-insensitive flag indicating that
395  //the previous request from the client was rejected because
396  //the nonce value was stale
397  if(httpCompareParamValue(&param, "true"))
398  authHeader.stale = TRUE;
399  else
400  authHeader.stale = FALSE;
401  }
402 #endif
403  //Unknown parameter?
404  else
405  {
406  //Discard unknown attributes
407  }
408  }
409  else
410  {
411  //Parse next authentication scheme
412  break;
413  }
414  }
415  }
416 
417 #if (HTTP_CLIENT_BASIC_AUTH_SUPPORT == ENABLED)
418  //Valid basic authentication parameters?
419  if(authHeader.mode == HTTP_AUTH_MODE_BASIC &&
420  authHeader.realmLen > 0 &&
421  authHeader.realmLen <= HTTP_CLIENT_MAX_REALM_LEN)
422  {
423  //Save authentication mode
424  context->authParams.mode = authHeader.mode;
425 
426  //Save realm
427  strncpy(context->authParams.realm, authHeader.realm, authHeader.realmLen);
428  context->authParams.realm[authHeader.realmLen] = '\0';
429  }
430  else
431 #endif
432 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
433  //Valid digest authentication parameters?
434  if(authHeader.mode == HTTP_AUTH_MODE_DIGEST &&
435  authHeader.algorithm != NULL &&
436  authHeader.realmLen > 0 &&
437  authHeader.realmLen <= HTTP_CLIENT_MAX_REALM_LEN &&
438  authHeader.nonceLen > 0 &&
439  authHeader.nonceLen <= HTTP_CLIENT_MAX_NONCE_LEN &&
441  {
442  //Save authentication mode
443  context->authParams.mode = authHeader.mode;
444  //Save qop parameter
445  context->authParams.qop = authHeader.qop;
446  //Save digest algorithm
447  context->authParams.algorithm = authHeader.algorithm;
448 
449  //Save realm
450  strncpy(context->authParams.realm, authHeader.realm, authHeader.realmLen);
451  context->authParams.realm[authHeader.realmLen] = '\0';
452 
453  //Save nonce value
454  strncpy(context->authParams.nonce, authHeader.nonce, authHeader.nonceLen);
455  context->authParams.nonce[authHeader.nonceLen] = '\0';
456 
457  //Save opaque parameter
458  strncpy(context->authParams.opaque, authHeader.opaque, authHeader.opaqueLen);
459  context->authParams.opaque[authHeader.opaqueLen] = '\0';
460 
461  //Save stale flag
462  context->authParams.stale = authHeader.stale;
463  }
464  else
465 #endif
466  //Invalid parameters
467  {
468  //Ignore the challenge
469  }
470  }
471  else
472  {
473  //Get next token
474  error = httpParseParam(&p, &param);
475  }
476  }
477 
478  //Successful processing
479  return NO_ERROR;
480 }
481 
482 
483 /**
484  * @brief Parse qop parameter
485  * @param[in] param Pointer to the algorithm parameter
486  * @param[in,out] authHeader Pointer to the WWW-Authenticate header field
487  **/
488 
490  HttpWwwAuthenticateHeader *authHeader)
491 {
492 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
493  size_t i;
494  size_t n;
495 
496  //This parameter is a quoted string of one or more tokens indicating
497  //the "quality of protection" values supported by the server
498  authHeader->qop = HTTP_AUTH_QOP_NONE;
499 
500  //Parse the comma-separated list
501  for(i = 0; i < param->valueLen; i += (n + 1))
502  {
503  //Calculate the length of the current token
504  for(n = 0; (i + n) < param->valueLen; n++)
505  {
506  //Separator character found?
507  if(strchr(", \t", param->value[i + n]))
508  break;
509  }
510 
511  //Check current token
512  if(n == 4 && !strncasecmp(param->value + i, "auth", 4))
513  {
514  //The value "auth" indicates authentication
515  authHeader->qop = HTTP_AUTH_QOP_AUTH;
516  }
517  }
518 
519  //Quality of protection not supported?
520  if(authHeader->qop == HTTP_AUTH_QOP_NONE)
521  {
522  //The challenge should be ignored
523  authHeader->mode = HTTP_AUTH_MODE_NONE;
524  }
525 #endif
526 }
527 
528 
529 /**
530  * @brief Parse algorithm parameter
531  * @param[in] param Pointer to the algorithm parameter
532  * @param[in,out] authHeader Pointer to the WWW-Authenticate header field
533  **/
534 
536  HttpWwwAuthenticateHeader *authHeader)
537 {
538 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
539 #if (HTTP_CLIENT_MD5_SUPPORT == ENABLED)
540  //MD5 digest algorithm?
541  if(httpCompareParamValue(param, "MD5"))
542  {
543  //Select MD5 digest algorithm
544  authHeader->algorithm = MD5_HASH_ALGO;
545  }
546  else
547 #endif
548 #if (HTTP_CLIENT_SHA256_SUPPORT == ENABLED)
549  //SHA-256 digest algorithm?
550  if(httpCompareParamValue(param, "SHA-256"))
551  {
552  //Select SHA-256 digest algorithm
553  authHeader->algorithm = SHA256_HASH_ALGO;
554  }
555  else
556 #endif
557 #if (HTTP_CLIENT_SHA512_256_SUPPORT == ENABLED)
558  //SHA-512/256 digest algorithm?
559  if(httpCompareParamValue(param, "SHA-512-256"))
560  {
561  //Select SHA-512/256 digest algorithm
562  authHeader->algorithm = SHA512_256_HASH_ALGO;
563  }
564  else
565 #endif
566  //Unknown digest algorithm?
567  {
568  //If the algorithm is not understood, the challenge should be
569  //ignored (refer to RFC 7616, section 3.3)
570  authHeader->mode = HTTP_AUTH_MODE_NONE;
571  }
572 #endif
573 }
574 
575 
576 /**
577  * @brief Digest operation
578  * @param[in] authParams HTTP authentication parameters
579  * @param[in] method Pointer to the HTTP method
580  * @param[in] methodLen Length of the HTTP method
581  * @param[in] uri Pointer to the URI
582  * @param[in] uriLen Length of the URI
583  * @param[out] response Pointer to the resulting digest
584  * @return Error code
585  **/
586 
588  const char_t *method, size_t methodLen, const char_t *uri,
589  size_t uriLen, char_t *response)
590 {
591 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
592  size_t i;
593  char_t buffer[9];
596  uint8_t hashContext[HTTP_CLIENT_MAX_HASH_CONTEXT_SIZE];
597  const HashAlgo *hash;
598 
599  //Point to the hash algorithm to be used
600  hash = authParams->algorithm;
601  //Make sure the hash algorithm is valid
602  if(hash == NULL)
603  return ERROR_FAILURE;
604 
605  //Compute H(A1) = H(username : realm : password)
606  hash->init(hashContext);
607  hash->update(hashContext, authParams->username, strlen(authParams->username));
608  hash->update(hashContext, ":", 1);
609  hash->update(hashContext, authParams->realm, strlen(authParams->realm));
610  hash->update(hashContext, ":", 1);
611  hash->update(hashContext, authParams->password, strlen(authParams->password));
612  hash->final(hashContext, ha1);
613 
614  //Compute H(A2) = H(method : uri)
615  hash->init(hashContext);
616  hash->update(hashContext, method, methodLen);
617  hash->update(hashContext, ":", 1);
618  hash->update(hashContext, uri, uriLen);
619  hash->final(hashContext, ha2);
620 
621  //Compute H(H(A1) : nonce : nc : cnonce : qop : H(A2))
622  hash->init(hashContext);
623 
624  //Digest H(A1) as an hex string
625  for(i = 0; i < hash->digestSize; i++)
626  {
627  //Convert the current byte to hex representation
628  sprintf(buffer, "%02" PRIx8, ha1[i]);
629  //Digest the resulting value
630  hash->update(hashContext, buffer, 2);
631  }
632 
633  //Digest nonce parameter
634  hash->update(hashContext, ":", 1);
635  hash->update(hashContext, authParams->nonce, strlen(authParams->nonce));
636  hash->update(hashContext, ":", 1);
637 
638  //Convert the nonce count to hex string
639  sprintf(buffer, "%08x", authParams->nc);
640 
641  //Check quality of protection
642  if(authParams->qop == HTTP_AUTH_QOP_AUTH ||
643  authParams->qop == HTTP_AUTH_QOP_AUTH_INT)
644  {
645  //Digest nc, cnonce and qop parameters
646  hash->update(hashContext, buffer, 8);
647  hash->update(hashContext, ":", 1);
648  hash->update(hashContext, authParams->cnonce, strlen(authParams->cnonce));
649  hash->update(hashContext, ":", 1);
650  hash->update(hashContext, "auth", 4);
651  hash->update(hashContext, ":", 1);
652  }
653 
654  //Digest H(A2) as an hex string
655  for(i = 0; i < hash->digestSize; i++)
656  {
657  //Convert the current byte to hex representation
658  sprintf(buffer, "%02" PRIx8, ha2[i]);
659  //Digest the resulting value
660  hash->update(hashContext, buffer, 2);
661  }
662 
663  //Finalize hash computation
664  hash->final(hashContext, response);
665 
666  //Convert the resulting digest to hex string
667  httpEncodeHexString(response, hash->digestSize, response);
668 
669  //Successful processing
670  return NO_ERROR;
671 #else
672  //Digest authentication is not implemented
673  return ERROR_NOT_IMPLEMENTED;
674 #endif
675 }
676 
677 #endif
HttpAuthMode mode
HTTP authentication mode.
Definition: http_client.h:252
char_t password[HTTP_CLIENT_MAX_PASSWORD_LEN+1]
Password.
Definition: http_client.h:254
const char_t * value
Definition: http_common.h:158
char_t nonce[HTTP_CLIENT_MAX_NONCE_LEN+1]
Nonce value.
Definition: http_client.h:260
char char_t
Definition: compiler_port.h:43
#define HTTP_CLIENT_BUFFER_SIZE
Definition: http_client.h:96
const HashAlgo * algorithm
Digest algorithm.
HTTP authentication parameters.
Definition: http_client.h:250
char_t realm[HTTP_CLIENT_MAX_REALM_LEN+1]
Realm.
Definition: http_client.h:255
TCP/IP stack core.
#define HttpClientContext
Definition: http_client.h:205
#define HTTP_CLIENT_CNONCE_SIZE
Definition: http_client.h:152
bool_t stale
Stale flag.
#define HTTP_CLIENT_MAX_RESPONSE_LEN
#define HTTP_CLIENT_MAX_OPAQUE_LEN
Definition: http_client.h:159
Debugging facilities.
uint8_t hash
Definition: tls.h:1365
HttpAuthQop qop
Quality of protection.
uint8_t p
Definition: ndp.h:298
Generic error code.
Definition: error.h:45
#define SHA512_256_HASH_ALGO
Definition: sha512_256.h:47
error_t httpClientParseWwwAuthenticateField(HttpClientContext *context, const char_t *value)
Parse WWW-Authenticate header field.
void httpClientParseQopParam(const HttpParam *param, HttpWwwAuthenticateHeader *authHeader)
Parse qop parameter.
error_t httpParseParam(const char_t **pos, HttpParam *param)
Parse a list of parameters.
Definition: http_common.c:117
#define HTTP_CLIENT_MAX_HASH_DIGEST_SIZE
const char_t * nonce
Nonce value.
#define HTTP_CLIENT_MAX_NONCE_LEN
Definition: http_client.h:145
HttpAuthQop qop
Quality of protection.
Definition: http_client.h:257
void base64Encode(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
Base64 encoding algorithm.
Definition: base64.c:78
uint8_t m
Definition: ndp.h:302
size_t valueLen
Definition: http_common.h:159
size_t nonceLen
Length of the nonce value.
#define TRUE
Definition: os_port.h:50
#define HTTP_CLIENT_MAX_HASH_CONTEXT_SIZE
error_t httpClientComputeDigest(HttpClientAuthParams *authParams, const char_t *method, size_t methodLen, const char_t *uri, size_t uriLen, char_t *response)
Digest operation.
#define SHA256_HASH_ALGO
Definition: sha256.h:46
bool_t stale
Stale flag.
Definition: http_client.h:263
Attribute-value pair.
Definition: http_common.h:154
uint32_t nc
Nonce count.
Definition: http_client.h:259
char_t username[HTTP_CLIENT_MAX_USERNAME_LEN+1]
User name.
Definition: http_client.h:253
char_t opaque[HTTP_CLIENT_MAX_OPAQUE_LEN+1]
Opaque parameter.
Definition: http_client.h:262
void httpEncodeHexString(const uint8_t *input, size_t inputLen, char_t *output)
Convert byte array to hex string.
Definition: http_common.c:476
const char_t * opaque
Opaque parameter.
void httpClientInitAuthParams(HttpClientAuthParams *authParams)
Initialize HTTP authentication parameters.
Success.
Definition: error.h:44
error_t
Error codes.
Definition: error.h:42
void httpClientParseAlgorithmParam(const HttpParam *param, HttpWwwAuthenticateHeader *authHeader)
Parse algorithm parameter.
error_t httpClientFormatAuthorizationField(HttpClientContext *context)
Format Authorization header field.
HttpAuthMode mode
Authentication scheme.
#define strncasecmp
char_t cnonce[HTTP_CLIENT_CNONCE_SIZE *2+1]
Cnonce value.
Definition: http_client.h:261
uint8_t value[]
Definition: dtls_misc.h:143
#define HTTP_CLIENT_MAX_REALM_LEN
Definition: http_client.h:138
WWW-Authenticate header field.
const HashAlgo * algorithm
Digest algorithm.
Definition: http_client.h:258
size_t opaqueLen
Length of the opaque parameter.
Common interface for hash algorithms.
Definition: crypto.h:1070
uint8_t n
const char_t * realm
Realm.
HTTP client (HyperText Transfer Protocol)
size_t realmLen
Length of the realm.
HTTP authentication.
#define FALSE
Definition: os_port.h:46
bool_t httpCompareParamName(const HttpParam *param, const char_t *name)
Compare parameter name with the supplied string.
Definition: http_common.c:368
bool_t httpCompareParamValue(const HttpParam *param, const char_t *value)
Compare parameter name with the supplied string.
Definition: http_common.c:401
#define MD5_HASH_ALGO
Definition: md5.h:46