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