gsasl  2.2.1
digest.c
Go to the documentation of this file.
1 /* digest.c --- Generate a CRAM-MD5 hex encoded HMAC-MD5 response string.
2  * Copyright (C) 2002-2024 Simon Josefsson
3  *
4  * This file is part of GNU SASL Library.
5  *
6  * GNU SASL Library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * GNU SASL Library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with GNU SASL Library; if not, write to the Free
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include <config.h>
24 
25 #include <string.h>
26 
27 /* Get prototype. */
28 #include "digest.h"
29 
30 /* Get gc_hmac_md5. */
31 #include "gc.h"
32 
33 /*
34  * From draft-ietf-sasl-crammd5-02.txt:
35  *
36  * The latter is computed by applying the keyed MD5 algorithm from
37  * [KEYED-MD5] where the key is a shared secret and the digested
38  * text is the challenge (including angle-brackets). The client
39  * MUST NOT interpret or attempt to validate the contents of the
40  * challenge in any way.
41  *
42  * This shared secret is a string known only to the client and
43  * server. The "digest" parameter itself is a 16-octet value which
44  * is sent in hexadecimal format, using lower-case US-ASCII
45  * characters.
46  * ...
47  * digest = 32(DIGIT / %x61-66)
48  * ; A hexadecimal string using only lower-case
49  * ; letters
50  *
51  */
52 
53 #if CRAM_MD5_DIGEST_LEN != 2*GC_MD5_DIGEST_SIZE
54 # error MD5 length mismatch
55 #endif
56 
57 #define HEXCHAR(c) ((c & 0x0F) > 9 ? 'a' + (c & 0x0F) - 10 : '0' + (c & 0x0F))
58 
59 void
60 cram_md5_digest (const char *challenge,
61  size_t challengelen,
62  const char *secret,
63  size_t secretlen, char response[CRAM_MD5_DIGEST_LEN])
64 {
65  char hash[GC_MD5_DIGEST_SIZE];
66  size_t i;
67 
68  gc_hmac_md5 (secret, secretlen ? secretlen : strlen (secret),
69  challenge, challengelen ? challengelen : strlen (challenge),
70  hash);
71 
72  for (i = 0; i < GC_MD5_DIGEST_SIZE; i++)
73  {
74  *response++ = HEXCHAR (hash[i] >> 4);
75  *response++ = HEXCHAR (hash[i]);
76  }
77 }
#define HEXCHAR(c)
Definition: digest.c:57
void cram_md5_digest(const char *challenge, size_t challengelen, const char *secret, size_t secretlen, char response[CRAM_MD5_DIGEST_LEN])
Definition: digest.c:60
#define CRAM_MD5_DIGEST_LEN
Definition: digest.h:29