rfc2617.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* The source in this file is derived from the reference implementation
10  * in RFC 2617.
11  * RFC 2617 is Copyright (C) The Internet Society (1999). All Rights Reserved.
12  *
13  * The Squid copyright and licence statement covers all changes made to the
14  * reference implementation.
15  *
16  * Key changes were: alteration to a plain C layout.
17  * Create CvtBin function
18  * Allow CalcHA1 to make use of precaculated username:password:realm hash's
19  * to prevent squid knowing the users password (idea suggested in RFC 2617).
20  */
21 
22 #include "squid.h"
23 #include <string.h>
24 #include "md5.h"
25 #include "rfc2617.h"
26 
27 void
28 CvtHex(const HASH Bin, HASHHEX Hex)
29 {
30  unsigned short i;
31  unsigned char j;
32 
33  for (i = 0; i < HASHLEN; i++) {
34  j = (Bin[i] >> 4) & 0xf;
35  if (j <= 9)
36  Hex[i * 2] = (j + '0');
37  else
38  Hex[i * 2] = (j + 'a' - 10);
39  j = Bin[i] & 0xf;
40  if (j <= 9)
41  Hex[i * 2 + 1] = (j + '0');
42  else
43  Hex[i * 2 + 1] = (j + 'a' - 10);
44  }
45  Hex[HASHHEXLEN] = '\0';
46 }
47 
48 void
49 CvtBin(const HASHHEX Hex, HASH Bin)
50 {
51  unsigned short i;
52  unsigned char j;
53 
54  for (i = 0; i < HASHHEXLEN; i++) {
55  unsigned char n;
56  j = Hex[i];
57  if (('0' <= j) && (j <= '9'))
58  n = j - '0';
59  else if (('a' <= j) && (j <= 'f'))
60  n = j - 'a' + 10;
61  else if (('A' <= j) && (j <= 'F'))
62  n = j - 'A' + 10;
63  else
64  continue;
65  if (i % 2 == 0)
66  Bin[i / 2] = n << 4;
67  else
68  Bin[i / 2] |= n;
69  }
70 
71 #if HASHHEXLEN != (2*HASHLEN)
72  /*
73  Why? :: right here i == 32
74  which means the first step of the for loop makes i==16
75  and cannot be < HASHLEN (which is also 16)
76 
77  But only guaranteed if HASHHEXLEN == 2*HASHLEN
78  This will ensure correct 0-ing of bins no matter what.
79  */
80  for (i = i / 2; i < HASHLEN; i++) {
81  Bin[i] = '\0';
82  }
83 #endif
84 }
85 
86 /* calculate H(A1) as per spec */
87 void
89  const char *pszAlg,
90  const char *pszUserName,
91  const char *pszRealm,
92  const char *pszPassword,
93  const char *pszNonce,
94  const char *pszCNonce,
95  HASH HA1,
96  HASHHEX SessionKey
97 )
98 {
99  SquidMD5_CTX Md5Ctx;
100 
101  if (pszUserName) {
102  SquidMD5Init(&Md5Ctx);
103  SquidMD5Update(&Md5Ctx, pszUserName, strlen(pszUserName));
104  SquidMD5Update(&Md5Ctx, ":", 1);
105  SquidMD5Update(&Md5Ctx, pszRealm, strlen(pszRealm));
106  SquidMD5Update(&Md5Ctx, ":", 1);
107  SquidMD5Update(&Md5Ctx, pszPassword, strlen(pszPassword));
108  SquidMD5Final((unsigned char *) HA1, &Md5Ctx);
109  }
110  if (strcasecmp(pszAlg, "md5-sess") == 0) {
111  HASHHEX HA1Hex;
112  CvtHex(HA1, HA1Hex); /* RFC2617 errata */
113  SquidMD5Init(&Md5Ctx);
114  SquidMD5Update(&Md5Ctx, HA1Hex, HASHHEXLEN);
115  SquidMD5Update(&Md5Ctx, ":", 1);
116  SquidMD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
117  SquidMD5Update(&Md5Ctx, ":", 1);
118  SquidMD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
119  SquidMD5Final((unsigned char *) HA1, &Md5Ctx);
120  }
121  CvtHex(HA1, SessionKey);
122 }
123 
124 /* calculate request-digest/response-digest as per HTTP Digest spec */
125 void
127  const HASHHEX HA1, /* H(A1) */
128  const char *pszNonce, /* nonce from server */
129  const char *pszNonceCount, /* 8 hex digits */
130  const char *pszCNonce, /* client nonce */
131  const char *pszQop, /* qop-value: "", "auth", "auth-int" */
132  const char *pszMethod, /* method from the request */
133  const char *pszDigestUri, /* requested URL */
134  const HASHHEX HEntity, /* H(entity body) if qop="auth-int" */
135  HASHHEX Response /* request-digest or response-digest */
136 )
137 {
138  SquidMD5_CTX Md5Ctx;
139  HASH HA2;
140  HASH RespHash;
141  HASHHEX HA2Hex;
142 
143  /* calculate H(A2)
144  */
145  SquidMD5Init(&Md5Ctx);
146  SquidMD5Update(&Md5Ctx, pszMethod, strlen(pszMethod));
147  SquidMD5Update(&Md5Ctx, ":", 1);
148  SquidMD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri));
149  if (pszQop && strcasecmp(pszQop, "auth-int") == 0) {
150  SquidMD5Update(&Md5Ctx, ":", 1);
151  SquidMD5Update(&Md5Ctx, HEntity, HASHHEXLEN);
152  }
153  SquidMD5Final((unsigned char *) HA2, &Md5Ctx);
154  CvtHex(HA2, HA2Hex);
155 
156  /* calculate response
157  */
158  SquidMD5Init(&Md5Ctx);
159  SquidMD5Update(&Md5Ctx, HA1, HASHHEXLEN);
160  SquidMD5Update(&Md5Ctx, ":", 1);
161  SquidMD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
162  SquidMD5Update(&Md5Ctx, ":", 1);
163  if (pszQop) {
164  SquidMD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount));
165  SquidMD5Update(&Md5Ctx, ":", 1);
166  SquidMD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
167  SquidMD5Update(&Md5Ctx, ":", 1);
168  SquidMD5Update(&Md5Ctx, pszQop, strlen(pszQop));
169  SquidMD5Update(&Md5Ctx, ":", 1);
170  }
171  SquidMD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN);
172  SquidMD5Final((unsigned char *) RespHash, &Md5Ctx);
173  CvtHex(RespHash, Response);
174 }
175 
SQUIDCEXTERN void SquidMD5Init(struct SquidMD5Context *context)
Definition: md5.c:73
#define HASHLEN
Definition: rfc2617.h:30
void DigestCalcResponse(const HASHHEX HA1, const char *pszNonce, const char *pszNonceCount, const char *pszCNonce, const char *pszQop, const char *pszMethod, const char *pszDigestUri, const HASHHEX HEntity, HASHHEX Response)
Definition: rfc2617.c:126
SQUIDCEXTERN void SquidMD5Final(uint8_t digest[16], struct SquidMD5Context *context)
void CvtBin(const HASHHEX Hex, HASH Bin)
Definition: rfc2617.c:49
void CvtHex(const HASH Bin, HASHHEX Hex)
Definition: rfc2617.c:28
#define HASHHEXLEN
Definition: rfc2617.h:32
char HASHHEX[HASHHEXLEN+1]
Definition: rfc2617.h:33
void DigestCalcHA1(const char *pszAlg, const char *pszUserName, const char *pszRealm, const char *pszPassword, const char *pszNonce, const char *pszCNonce, HASH HA1, HASHHEX SessionKey)
Definition: rfc2617.c:88
SQUIDCEXTERN void SquidMD5Update(struct SquidMD5Context *context, const void *buf, unsigned len)
Definition: md5.c:89
char HASH[HASHLEN]
Definition: rfc2617.h:31

 

Introduction

Documentation

Support

Miscellaneous