source: rtems/c/src/libnetworking/rtems_webserver/websda.c @ 2e7f00fc

4.104.114.84.95
Last change on this file since 2e7f00fc was 2e7f00fc, checked in by Joel Sherrill <joel.sherrill@…>, on 04/11/03 at 16:34:49

2003-04-11 Joel Sherrill <joel@…>

  • rtems_webserver/cgi.c, rtems_webserver/sockGen.c, rtems_webserver/umui.c, rtems_webserver/websSSL.c, rtems_webserver/websSSL.h, rtems_webserver/websda.c, rtems_webserver/websda.h: New files. Not included in previous commit.
  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * websda.c -- Digest Access Authentication routines
3 *
4 * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
5 *
6 * See the file "license.txt" for usage and redistribution license requirements
7 *
8 * $Id$
9 */
10
11/******************************** Description *********************************/
12
13/*
14 *      Routines for generating DAA data.       The module uses the
15 *      "RSA Data Security, Inc. MD5 Message-Digest Algorithm" found in md5c.c
16 */
17
18/********************************* Includes ***********************************/
19
20#ifndef CE
21#include        <time.h>
22#endif
23#include        "websda.h"
24#include        "md5.h"
25
26/******************************** Local Data **********************************/
27
28#define RANDOMKEY       T("onceuponatimeinparadise")
29#define NONCE_SIZE      34
30#define HASH_SIZE   16
31
32/*********************************** Code *************************************/
33/*
34 *      websMD5binary returns the MD5 hash
35 */
36
37char *websMD5binary(unsigned char *buf, int length)
38{
39    const char          *hex = "0123456789abcdef";
40    MD5_CONTEXT         md5ctx;
41    unsigned char       hash[HASH_SIZE];
42    char                        *r, *strReturn;
43        char                    result[(HASH_SIZE * 2) + 1];
44    int                         i;
45
46/*
47 *      Take the MD5 hash of the string argument.
48 */
49    MD5Init(&md5ctx);
50    MD5Update(&md5ctx, buf, (unsigned int)length);
51    MD5Final(hash, &md5ctx);
52
53/*
54 *      Prepare the resulting hash string
55 */
56    for (i = 0, r = result; i < 16; i++) {
57                *r++ = hex[hash[i] >> 4];
58                *r++ = hex[hash[i] & 0xF];
59    }
60
61/*
62 *      Zero terminate the hash string
63 */
64    *r = '\0';
65
66/*
67 *      Allocate a new copy of the hash string
68 */
69        strReturn = balloc(B_L, sizeof(result));
70        strcpy(strReturn, result);
71
72    return strReturn;
73}
74
75/*****************************************************************************/
76/*
77 *      Convenience call to websMD5binary
78 *      (Performs char_t to char conversion and back)
79 */
80
81char_t *websMD5(char_t *string)
82{
83        char_t  *strReturn;
84
85        a_assert(string && *string);
86
87        if (string && *string) {
88                char    *strTemp, *strHash;
89                int             nLen;
90/*
91 *              Convert input char_t string to char string
92 */
93                nLen = gstrlen(string);
94                strTemp = ballocUniToAsc(string, nLen + 1);
95/*
96 *              Execute the digest calculation
97 */
98                strHash = websMD5binary((unsigned char *)strTemp, nLen);
99/*
100 *              Convert the returned char string digest to a char_t string
101 */
102                nLen = strlen(strHash);
103                strReturn = ballocAscToUni(strHash, nLen);
104/*
105 *              Free up the temporary allocated resources
106 */
107                bfree(B_L, strTemp);
108                bfree(B_L, strHash);
109        } else {
110                strReturn = NULL;
111        }
112
113        return strReturn;
114}
115
116/******************************************************************************/
117/*
118 *      Get a Nonce value for passing along to the client.  This function
119 *      composes the string "RANDOMKEY:timestamp:myrealm" and
120 *      calculates the MD5 digest placing it in output.
121 */
122
123char_t *websCalcNonce(webs_t wp)
124{
125        char_t          *nonce, *prenonce;
126        struct tm       *newtime;
127        time_t          longTime;
128
129        a_assert(wp);
130/*
131 *      Get time as long integer.
132 */
133        time(&longTime);
134/*
135 *      Convert to local time.
136 */
137        newtime = localtime(&longTime);
138/*
139 *      Create prenonce string.
140 */
141        prenonce = NULL;
142#ifdef DIGEST_ACCESS_SUPPORT
143        fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
144                wp->realm);
145#else
146        fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime),
147                RANDOMKEY);
148#endif
149        a_assert(prenonce);
150/*
151 *      Create the nonce
152 */
153    nonce = websMD5(prenonce);
154/*
155 *      Cleanup
156 */
157        bfreeSafe(B_L, prenonce);
158
159        return nonce;
160}
161
162/******************************************************************************/
163/*
164 *      Get an Opaque value for passing along to the client
165 */
166
167char_t *websCalcOpaque(webs_t wp)
168{
169        char_t *opaque;
170        a_assert(wp);
171/*
172 *      Temporary stub!
173 */
174    opaque = bstrdup(B_L, T("5ccc069c403ebaf9f0171e9517f40e41"));
175
176        return opaque;
177}
178
179/******************************************************************************/
180/*
181 *      Get a Digest value using the MD5 algorithm
182 */
183
184char_t *websCalcDigest(webs_t wp)
185{
186#ifdef DIGEST_ACCESS_SUPPORT
187        char_t  *digest, *a1, *a1prime, *a2, *a2prime, *preDigest, *method;
188
189        a_assert(wp);
190        digest = NULL;
191
192/*
193 *      Calculate first portion of digest H(A1)
194 */
195        a1 = NULL;
196        fmtAlloc(&a1, 255, T("%s:%s:%s"), wp->userName, wp->realm, wp->password);
197        a_assert(a1);
198        a1prime = websMD5(a1);
199        bfreeSafe(B_L, a1);
200/*
201 *      Calculate second portion of digest H(A2)
202 */
203        method = websGetVar(wp, T("REQUEST_METHOD"), NULL);
204        a_assert(method);
205        a2 = NULL;
206        fmtAlloc(&a2, 255, T("%s:%s"), method, wp->uri);
207        a_assert(a2);
208        a2prime = websMD5(a2);
209        bfreeSafe(B_L, a2);
210/*
211 *      Construct final digest KD(H(A1):nonce:H(A2))
212 */
213        a_assert(a1prime);
214        a_assert(a2prime);
215        a_assert(wp->nonce);
216
217        preDigest = NULL;
218        if (!wp->qop) {
219                fmtAlloc(&preDigest, 255, T("%s:%s:%s"), a1prime, wp->nonce, a2prime);
220        } else {
221                fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"),
222                        a1prime,
223                        wp->nonce,
224                        wp->nc,
225                        wp->cnonce,
226                        wp->qop,
227                        a2prime);
228        }
229
230        a_assert(preDigest);
231        digest = websMD5(preDigest);
232/*
233 *      Now clean up
234 */
235        bfreeSafe(B_L, a1prime);
236        bfreeSafe(B_L, a2prime);
237        bfreeSafe(B_L, preDigest);
238        return digest;
239#else
240        return NULL;
241#endif /* DIGEST_ACCESS_SUPPORT */
242}
243
244/******************************************************************************/
Note: See TracBrowser for help on using the repository browser.