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-2024 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 2.4.0
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  osStrcpy(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  osStrcpy(authParams->nonce, "");
77  osStrcpy(authParams->cnonce, "");
78  osStrcpy(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 = osStrlen(authParams->username) + osStrlen(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 = osSprintf(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 = osSprintf(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  osSprintf(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 = osStrchr(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 = osStrchr(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((uint8_t *) authParams->cnonce,
196  //Any error to report?
197  if(error)
198  return error;
199 
200  //Convert the byte array to hex string
201  httpEncodeHexString((const uint8_t *) authParams->cnonce,
202  HTTP_CLIENT_CNONCE_SIZE, authParams->cnonce);
203 
204  //Count of the number of requests (including the current request)
205  //that the client has sent with the nonce value in this request
206  authParams->nc++;
207  }
208 
209  //Perform digest operation
210  error = httpClientComputeDigest(authParams, context->method,
211  osStrlen(context->method), uri, uriLen, response);
212  //Any error to report?
213  if(error)
214  return error;
215 
216  //Determine the length of the header field
217  n = osStrlen(authParams->username) + osStrlen(authParams->realm) +
218  uriLen + osStrlen(authParams->nonce) + osStrlen(authParams->cnonce) +
219  osStrlen(response) + osStrlen(authParams->opaque);
220 
221  //Make sure the buffer is large enough
222  if((context->bufferLen + n + 121) > HTTP_CLIENT_BUFFER_SIZE)
223  return ERROR_BUFFER_OVERFLOW;
224 
225  //Point to the buffer where to format the Authorization header field
226  p = context->buffer + context->bufferLen - 2;
227 
228  //Format Authorization header field
229  n = osSprintf(p, "Authorization: Digest ");
230 
231  //Format username and realm parameter
232  n += osSprintf(p + n, "username=\"%s\", ", authParams->username);
233  n += osSprintf(p + n, "realm=\"%s\", ", authParams->realm);
234 
235  //Format uri parameter
236  n += osSprintf(p + n, "uri=\"");
237  osStrncpy(p + n, uri, uriLen);
238  n += uriLen;
239  n += osSprintf(p + n, "\", ");
240 
241  //Format nonce parameter
242  n += osSprintf(p + n, "nonce=\"%s\", ", authParams->nonce);
243 
244  //Check quality of protection
245  if(authParams->qop == HTTP_AUTH_QOP_AUTH)
246  {
247  //Format qop, nc, cnonce parameters
248  n += osSprintf(p + n, "qop=auth, ");
249  n += osSprintf(p + n, "nc=%08x, ", authParams->nc);
250  n += osSprintf(p + n, "cnonce=\"%s\", ", authParams->cnonce);
251  }
252 
253  //Format response parameter
254  n += osSprintf(p + n, "response=\"%s\"", response);
255 
256  //The opaque parameter should be returned by the client unchanged in
257  //the Authorization header field of subsequent requests
258  if(authParams->opaque[0] != '\0')
259  {
260  //Format opaque parameter
261  n += osSprintf(p + n, ", opaque=\"%s\"", authParams->opaque);
262  }
263 
264  //Terminate the header field with a CRLF sequence
265  osSprintf(p + n, "\r\n\r\n");
266 
267  //Adjust the length of the request header
268  context->bufferLen = context->bufferLen + n + 2;
269  }
270  else
271 #endif
272  //Unknown authentication scheme?
273  {
274  //Just for sanity
275  }
276 
277  //Successful processing
278  return NO_ERROR;
279 }
280 
281 
282 /**
283  * @brief Parse WWW-Authenticate header field
284  * @param[in] context Pointer to the HTTP client context
285  * @param[in] value NULL-terminated string that contains the value of header field
286  * @return Error code
287  **/
288 
290  const char_t *value)
291 {
292  error_t error;
293  const char_t *p;
294  HttpParam param;
295  HttpWwwAuthenticateHeader authHeader;
296 
297  //Point to the first character of the string
298  p = value;
299 
300  //Get the first token
301  error = httpParseParam(&p, &param);
302 
303  //The WWW-Authenticate header field indicates the authentication scheme(s)
304  //and parameters applicable to the target resource
305  while(!error)
306  {
307  //The authentication scheme must be a valid token followed by a
308  //BWS character
309  if(param.value == NULL && (*p == ' ' || *p == '\t'))
310  {
311  //Clear authentication parameters
312  osMemset(&authHeader, 0, sizeof(HttpWwwAuthenticateHeader));
313 
314 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED && HTTP_CLIENT_MD5_SUPPORT == ENABLED)
315  //If the algorithm parameter is not present, it is assumed to be
316  //MD5 (refer to RFC 7616, section 3.3)
317  authHeader.algorithm = MD5_HASH_ALGO;
318 #endif
319  //A case-insensitive token is used to identify the authentication
320  //scheme
321  if(httpCompareParamName(&param, "Basic"))
322  {
323  //Basic access authentication
324  authHeader.mode = HTTP_AUTH_MODE_BASIC;
325  }
326  else if(httpCompareParamName(&param, "Digest"))
327  {
328  //Digest access authentication
329  authHeader.mode = HTTP_AUTH_MODE_DIGEST;
330  }
331  else
332  {
333  //Unknown authentication scheme
334  authHeader.mode = HTTP_AUTH_MODE_NONE;
335  }
336 
337  //The authentication scheme is followed by a comma-separated list
338  //of attribute-value pairs which carry the parameters necessary for
339  //achieving authentication via that scheme
340  while(!error)
341  {
342  //Parse authentication parameter
343  error = httpParseParam(&p, &param);
344 
345  //Check status code
346  if(!error)
347  {
348  //Valid attribute-value pair?
349  if(param.value != NULL)
350  {
351  //Realm parameter?
352  if(httpCompareParamName(&param, "realm"))
353  {
354  //The realm is a string to be displayed to users so they
355  //know which username and password to use
356  authHeader.realm = param.value;
357  authHeader.realmLen = param.valueLen;
358  }
359 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
360  //Quality of protection parameter?
361  else if(httpCompareParamName(&param, "qop"))
362  {
363  //The qop parameter is a quoted string of one or more
364  //tokens indicating the "quality of protection" values
365  //supported by the server
366  httpClientParseQopParam(&param, &authHeader);
367  }
368  //Algorithm parameter?
369  else if(httpCompareParamName(&param, "algorithm"))
370  {
371  //This parameter indicates the algorithm used to produce
372  //the digest
373  httpClientParseAlgorithmParam(&param, &authHeader);
374  }
375  //Nonce parameter?
376  else if(httpCompareParamName(&param, "nonce"))
377  {
378  //The nonce is a server-specified string which should be
379  //uniquely generated each time a 401 response is made
380  authHeader.nonce = param.value;
381  authHeader.nonceLen = param.valueLen;
382  }
383  //Opaque parameter?
384  else if(httpCompareParamName(&param, "opaque"))
385  {
386  //The opaque parameter is a string of data, specified by the
387  //server, that should be returned by the client unchanged in
388  //the Authorization header field of subsequent requests
389  authHeader.opaque = param.value;
390  authHeader.opaqueLen = param.valueLen;
391  }
392  //Stale parameter?
393  else if(httpCompareParamName(&param, "stale"))
394  {
395  //The stale flag is a case-insensitive flag indicating that
396  //the previous request from the client was rejected because
397  //the nonce value was stale
398  if(httpCompareParamValue(&param, "true"))
399  {
400  authHeader.stale = TRUE;
401  }
402  else
403  {
404  authHeader.stale = FALSE;
405  }
406  }
407 #endif
408  //Unknown parameter?
409  else
410  {
411  //Discard unknown attributes
412  }
413  }
414  else
415  {
416  //Parse next authentication scheme
417  break;
418  }
419  }
420  }
421 
422 #if (HTTP_CLIENT_BASIC_AUTH_SUPPORT == ENABLED)
423  //Valid basic authentication parameters?
424  if(authHeader.mode == HTTP_AUTH_MODE_BASIC &&
425  authHeader.realmLen > 0 &&
426  authHeader.realmLen <= HTTP_CLIENT_MAX_REALM_LEN)
427  {
428  //Save authentication mode
429  context->authParams.mode = authHeader.mode;
430 
431  //Save realm
432  osStrncpy(context->authParams.realm, authHeader.realm, authHeader.realmLen);
433  context->authParams.realm[authHeader.realmLen] = '\0';
434  }
435  else
436 #endif
437 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
438  //Valid digest authentication parameters?
439  if(authHeader.mode == HTTP_AUTH_MODE_DIGEST &&
440  authHeader.algorithm != NULL &&
441  authHeader.realmLen > 0 &&
442  authHeader.realmLen <= HTTP_CLIENT_MAX_REALM_LEN &&
443  authHeader.nonceLen > 0 &&
444  authHeader.nonceLen <= HTTP_CLIENT_MAX_NONCE_LEN &&
446  {
447  //Save authentication mode
448  context->authParams.mode = authHeader.mode;
449  //Save qop parameter
450  context->authParams.qop = authHeader.qop;
451  //Save digest algorithm
452  context->authParams.algorithm = authHeader.algorithm;
453 
454  //Save realm
455  osStrncpy(context->authParams.realm, authHeader.realm, authHeader.realmLen);
456  context->authParams.realm[authHeader.realmLen] = '\0';
457 
458  //Save nonce value
459  osStrncpy(context->authParams.nonce, authHeader.nonce, authHeader.nonceLen);
460  context->authParams.nonce[authHeader.nonceLen] = '\0';
461 
462  //Save opaque parameter
463  osStrncpy(context->authParams.opaque, authHeader.opaque, authHeader.opaqueLen);
464  context->authParams.opaque[authHeader.opaqueLen] = '\0';
465 
466  //Save stale flag
467  context->authParams.stale = authHeader.stale;
468  }
469  else
470 #endif
471  //Invalid parameters
472  {
473  //Ignore the challenge
474  }
475  }
476  else
477  {
478  //Get next token
479  error = httpParseParam(&p, &param);
480  }
481  }
482 
483  //Successful processing
484  return NO_ERROR;
485 }
486 
487 
488 /**
489  * @brief Parse qop parameter
490  * @param[in] param Pointer to the algorithm parameter
491  * @param[in,out] authHeader Pointer to the WWW-Authenticate header field
492  **/
493 
495  HttpWwwAuthenticateHeader *authHeader)
496 {
497 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
498  size_t i;
499  size_t n;
500 
501  //This parameter is a quoted string of one or more tokens indicating
502  //the "quality of protection" values supported by the server
503  authHeader->qop = HTTP_AUTH_QOP_NONE;
504 
505  //Parse the comma-separated list
506  for(i = 0; i < param->valueLen; i += (n + 1))
507  {
508  //Calculate the length of the current token
509  for(n = 0; (i + n) < param->valueLen; n++)
510  {
511  //Separator character found?
512  if(osStrchr(", \t", param->value[i + n]) != NULL)
513  {
514  break;
515  }
516  }
517 
518  //Check current token
519  if(n == 4 && !osStrncasecmp(param->value + i, "auth", 4))
520  {
521  //The value "auth" indicates authentication
522  authHeader->qop = HTTP_AUTH_QOP_AUTH;
523  }
524  }
525 
526  //Quality of protection not supported?
527  if(authHeader->qop == HTTP_AUTH_QOP_NONE)
528  {
529  //The challenge should be ignored
530  authHeader->mode = HTTP_AUTH_MODE_NONE;
531  }
532 #endif
533 }
534 
535 
536 /**
537  * @brief Parse algorithm parameter
538  * @param[in] param Pointer to the algorithm parameter
539  * @param[in,out] authHeader Pointer to the WWW-Authenticate header field
540  **/
541 
543  HttpWwwAuthenticateHeader *authHeader)
544 {
545 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
546 #if (HTTP_CLIENT_MD5_SUPPORT == ENABLED)
547  //MD5 digest algorithm?
548  if(httpCompareParamValue(param, "MD5"))
549  {
550  //Select MD5 digest algorithm
551  authHeader->algorithm = MD5_HASH_ALGO;
552  }
553  else
554 #endif
555 #if (HTTP_CLIENT_SHA256_SUPPORT == ENABLED)
556  //SHA-256 digest algorithm?
557  if(httpCompareParamValue(param, "SHA-256"))
558  {
559  //Select SHA-256 digest algorithm
560  authHeader->algorithm = SHA256_HASH_ALGO;
561  }
562  else
563 #endif
564 #if (HTTP_CLIENT_SHA512_256_SUPPORT == ENABLED)
565  //SHA-512/256 digest algorithm?
566  if(httpCompareParamValue(param, "SHA-512-256"))
567  {
568  //Select SHA-512/256 digest algorithm
569  authHeader->algorithm = SHA512_256_HASH_ALGO;
570  }
571  else
572 #endif
573  //Unknown digest algorithm?
574  {
575  //If the algorithm is not understood, the challenge should be
576  //ignored (refer to RFC 7616, section 3.3)
577  authHeader->mode = HTTP_AUTH_MODE_NONE;
578  }
579 #endif
580 }
581 
582 
583 /**
584  * @brief Digest operation
585  * @param[in] authParams HTTP authentication parameters
586  * @param[in] method Pointer to the HTTP method
587  * @param[in] methodLen Length of the HTTP method
588  * @param[in] uri Pointer to the URI
589  * @param[in] uriLen Length of the URI
590  * @param[out] response Pointer to the resulting digest
591  * @return Error code
592  **/
593 
595  const char_t *method, size_t methodLen, const char_t *uri,
596  size_t uriLen, char_t *response)
597 {
598 #if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
599  size_t i;
600  char_t buffer[9];
603  HashContext hashContext;
604  const HashAlgo *hash;
605 
606  //Point to the hash algorithm to be used
607  hash = authParams->algorithm;
608  //Make sure the hash algorithm is valid
609  if(hash == NULL)
610  return ERROR_FAILURE;
611 
612  //Compute H(A1) = H(username : realm : password)
613  hash->init(&hashContext);
614  hash->update(&hashContext, authParams->username, osStrlen(authParams->username));
615  hash->update(&hashContext, ":", 1);
616  hash->update(&hashContext, authParams->realm, osStrlen(authParams->realm));
617  hash->update(&hashContext, ":", 1);
618  hash->update(&hashContext, authParams->password, osStrlen(authParams->password));
619  hash->final(&hashContext, ha1);
620 
621  //Compute H(A2) = H(method : uri)
622  hash->init(&hashContext);
623  hash->update(&hashContext, method, methodLen);
624  hash->update(&hashContext, ":", 1);
625  hash->update(&hashContext, uri, uriLen);
626  hash->final(&hashContext, ha2);
627 
628  //Compute H(H(A1) : nonce : nc : cnonce : qop : H(A2))
629  hash->init(&hashContext);
630 
631  //Digest H(A1) as an hex string
632  for(i = 0; i < hash->digestSize; i++)
633  {
634  //Convert the current byte to hex representation
635  osSprintf(buffer, "%02" PRIx8, ha1[i]);
636  //Digest the resulting value
637  hash->update(&hashContext, buffer, 2);
638  }
639 
640  //Digest nonce parameter
641  hash->update(&hashContext, ":", 1);
642  hash->update(&hashContext, authParams->nonce, osStrlen(authParams->nonce));
643  hash->update(&hashContext, ":", 1);
644 
645  //Convert the nonce count to hex string
646  osSprintf(buffer, "%08x", authParams->nc);
647 
648  //Check quality of protection
649  if(authParams->qop == HTTP_AUTH_QOP_AUTH ||
650  authParams->qop == HTTP_AUTH_QOP_AUTH_INT)
651  {
652  //Digest nc, cnonce and qop parameters
653  hash->update(&hashContext, buffer, 8);
654  hash->update(&hashContext, ":", 1);
655  hash->update(&hashContext, authParams->cnonce, osStrlen(authParams->cnonce));
656  hash->update(&hashContext, ":", 1);
657  hash->update(&hashContext, "auth", 4);
658  hash->update(&hashContext, ":", 1);
659  }
660 
661  //Digest H(A2) as an hex string
662  for(i = 0; i < hash->digestSize; i++)
663  {
664  //Convert the current byte to hex representation
665  osSprintf(buffer, "%02" PRIx8, ha2[i]);
666  //Digest the resulting value
667  hash->update(&hashContext, buffer, 2);
668  }
669 
670  //Finalize hash computation
671  hash->final(&hashContext, (uint8_t *) response);
672 
673  //Convert the resulting digest to hex string
674  httpEncodeHexString((const uint8_t *) response, hash->digestSize, response);
675 
676  //Successful processing
677  return NO_ERROR;
678 #else
679  //Digest authentication is not implemented
680  return ERROR_NOT_IMPLEMENTED;
681 #endif
682 }
683 
684 #endif
void base64Encode(const void *input, size_t inputLen, char_t *output, size_t *outputLen)
Base64 encoding algorithm.
Definition: base64.c:142
char char_t
Definition: compiler_port.h:48
Debugging facilities.
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_PRNG_NOT_READY
Definition: error.h:250
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:142
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
HTTP client (HyperText Transfer Protocol)
#define HttpClientContext
Definition: http_client.h:198
#define HTTP_CLIENT_MAX_OPAQUE_LEN
Definition: http_client.h:159
#define HTTP_CLIENT_CNONCE_SIZE
Definition: http_client.h:152
#define HTTP_CLIENT_MAX_NONCE_LEN
Definition: http_client.h:145
#define HTTP_CLIENT_BUFFER_SIZE
Definition: http_client.h:96
#define HTTP_CLIENT_MAX_REALM_LEN
Definition: http_client.h:138
void httpClientParseQopParam(const HttpParam *param, HttpWwwAuthenticateHeader *authHeader)
Parse qop parameter.
void httpClientInitAuthParams(HttpClientAuthParams *authParams)
Initialize HTTP authentication parameters.
error_t httpClientParseWwwAuthenticateField(HttpClientContext *context, const char_t *value)
Parse WWW-Authenticate header field.
error_t httpClientFormatAuthorizationField(HttpClientContext *context)
Format Authorization header field.
error_t httpClientComputeDigest(HttpClientAuthParams *authParams, const char_t *method, size_t methodLen, const char_t *uri, size_t uriLen, char_t *response)
Digest operation.
void httpClientParseAlgorithmParam(const HttpParam *param, HttpWwwAuthenticateHeader *authHeader)
Parse algorithm parameter.
HTTP authentication.
#define HTTP_CLIENT_MAX_RESPONSE_LEN
#define HTTP_CLIENT_MAX_HASH_DIGEST_SIZE
error_t httpParseParam(const char_t **pos, HttpParam *param)
Parse a list of parameters.
Definition: http_common.c:117
void httpEncodeHexString(const uint8_t *input, size_t inputLen, char_t *output)
Convert byte array to hex string.
Definition: http_common.c:475
bool_t httpCompareParamValue(const HttpParam *param, const char_t *value)
Compare parameter name with the supplied string.
Definition: http_common.c:401
bool_t httpCompareParamName(const HttpParam *param, const char_t *name)
Compare parameter name with the supplied string.
Definition: http_common.c:368
@ HTTP_AUTH_MODE_DIGEST
Definition: http_common.h:75
@ HTTP_AUTH_MODE_NONE
Definition: http_common.h:73
@ HTTP_AUTH_MODE_BASIC
Definition: http_common.h:74
@ HTTP_AUTH_QOP_NONE
Definition: http_common.h:85
@ HTTP_AUTH_QOP_AUTH_INT
Definition: http_common.h:87
@ HTTP_AUTH_QOP_AUTH
Definition: http_common.h:86
#define MD5_HASH_ALGO
Definition: md5.h:49
uint8_t p
Definition: ndp.h:300
uint8_t m
Definition: ndp.h:304
TCP/IP stack core.
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osStrchr(s, c)
Definition: os_port.h:195
#define osStrlen(s)
Definition: os_port.h:165
#define osSprintf(dest,...)
Definition: os_port.h:231
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define osStrcpy(s1, s2)
Definition: os_port.h:207
#define osStrncasecmp(s1, s2, length)
Definition: os_port.h:189
#define osStrncpy(s1, s2, length)
Definition: os_port.h:213
#define SHA256_HASH_ALGO
Definition: sha256.h:49
#define SHA512_256_HASH_ALGO
Definition: sha512_256.h:45
Common interface for hash algorithms.
Definition: crypto.h:1014
HashAlgoFinal final
Definition: crypto.h:1026
HashAlgoUpdate update
Definition: crypto.h:1025
size_t digestSize
Definition: crypto.h:1020
HashAlgoInit init
Definition: crypto.h:1024
HTTP authentication parameters.
Definition: http_client.h:244
HttpAuthMode mode
HTTP authentication mode.
Definition: http_client.h:245
char_t cnonce[HTTP_CLIENT_CNONCE_SIZE *2+1]
Cnonce value.
Definition: http_client.h:254
char_t nonce[HTTP_CLIENT_MAX_NONCE_LEN+1]
Nonce value.
Definition: http_client.h:253
char_t password[HTTP_CLIENT_MAX_PASSWORD_LEN+1]
Password.
Definition: http_client.h:247
char_t username[HTTP_CLIENT_MAX_USERNAME_LEN+1]
User name.
Definition: http_client.h:246
char_t opaque[HTTP_CLIENT_MAX_OPAQUE_LEN+1]
Opaque parameter.
Definition: http_client.h:255
uint32_t nc
Nonce count.
Definition: http_client.h:252
bool_t stale
Stale flag.
Definition: http_client.h:256
HttpAuthQop qop
Quality of protection.
Definition: http_client.h:250
const HashAlgo * algorithm
Digest algorithm.
Definition: http_client.h:251
char_t realm[HTTP_CLIENT_MAX_REALM_LEN+1]
Realm.
Definition: http_client.h:248
Attribute-value pair.
Definition: http_common.h:157
const char_t * value
Definition: http_common.h:160
size_t valueLen
Definition: http_common.h:161
WWW-Authenticate header field.
HttpAuthMode mode
Authentication scheme.
size_t realmLen
Length of the realm.
const char_t * nonce
Nonce value.
const char_t * opaque
Opaque parameter.
size_t opaqueLen
Length of the opaque parameter.
size_t nonceLen
Length of the nonce value.
HttpAuthQop qop
Quality of protection.
const HashAlgo * algorithm
Digest algorithm.
const char_t * realm
Realm.
uint8_t value[]
Definition: tcp.h:369
Generic hash algorithm context.