gsasl  2.2.1
digest-md5/validate.c
Go to the documentation of this file.
1 /* validate.c --- Validate consistency of DIGEST-MD5 tokens.
2  * Copyright (C) 2004-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 /* Get prototypes. */
26 #include "validate.h"
27 
28 /* Get strcmp, strlen. */
29 #include <string.h>
30 
31 int
33 {
34  /* This directive is required and MUST appear exactly once; if
35  not present, or if multiple instances are present, the
36  client should abort the authentication exchange. */
37  if (!c->nonce)
38  return -1;
39 
40  /* This directive must be present exactly once if "auth-conf" is
41  offered in the "qop-options" directive */
42  if (c->ciphers && !(c->qops & DIGEST_MD5_QOP_AUTH_CONF))
43  return -1;
44  if (!c->ciphers && (c->qops & DIGEST_MD5_QOP_AUTH_CONF))
45  return -1;
46 
47  return 0;
48 }
49 
50 int
52 {
53  /* This directive is required and MUST be present exactly
54  once; otherwise, authentication fails. */
55  if (!r->username)
56  return -1;
57 
58  /* This directive is required and MUST be present exactly
59  once; otherwise, authentication fails. */
60  if (!r->nonce)
61  return -1;
62 
63  /* This directive is required and MUST be present exactly once;
64  otherwise, authentication fails. */
65  if (!r->cnonce)
66  return -1;
67 
68  /* This directive is required and MUST be present exactly once;
69  otherwise, or if the value is 0, authentication fails. */
70  if (!r->nc)
71  return -1;
72 
73  /* This directive is required and MUST be present exactly
74  once; if multiple instances are present, the client MUST
75  abort the authentication exchange. */
76  if (!r->digesturi)
77  return -1;
78 
79  /* This directive is required and MUST be present exactly
80  once; otherwise, authentication fails. */
81  if (!*r->response)
82  return -1;
83 
84  if (strlen (r->response) != DIGEST_MD5_RESPONSE_LENGTH)
85  return -1;
86 
87  /* This directive MUST appear exactly once if "auth-conf" is
88  negotiated; if required and not present, authentication fails.
89  If the client recognizes no cipher and the server only advertised
90  "auth-conf" in the qop option, the client MUST abort the
91  authentication exchange. */
92  if (r->qop == DIGEST_MD5_QOP_AUTH_CONF && !r->cipher)
93  return -1;
94  if (r->qop != DIGEST_MD5_QOP_AUTH_CONF && r->cipher)
95  return -1;
96 
97  return 0;
98 }
99 
100 int
102 {
103  if (!*f->rspauth)
104  return -1;
105 
106  /* A string of 32 hex digits */
107  if (strlen (f->rspauth) != DIGEST_MD5_RESPONSE_LENGTH)
108  return -1;
109 
110  return 0;
111 }
112 
113 int
115 {
116  if (!c->nonce || !r->nonce)
117  return -1;
118 
119  if (strcmp (c->nonce, r->nonce) != 0)
120  return -1;
121 
122  if (r->nc != 1)
123  return -1;
124 
125  if (!c->utf8 && r->utf8)
126  return -1;
127 
128  if (!((c->qops ? c->qops : DIGEST_MD5_QOP_AUTH) &
129  (r->qop ? r->qop : DIGEST_MD5_QOP_AUTH)))
130  return -1;
131 
132  if ((r->qop & DIGEST_MD5_QOP_AUTH_CONF) && !(c->ciphers & r->cipher))
133  return -1;
134 
135  /* FIXME: Check more? */
136 
137  return 0;
138 }
@ DIGEST_MD5_QOP_AUTH_CONF
@ DIGEST_MD5_QOP_AUTH
#define DIGEST_MD5_RESPONSE_LENGTH
int digest_md5_validate(digest_md5_challenge *c, digest_md5_response *r)
int digest_md5_validate_challenge(digest_md5_challenge *c)
int digest_md5_validate_response(digest_md5_response *r)
int digest_md5_validate_finish(digest_md5_finish *f)
char rspauth[DIGEST_MD5_RESPONSE_LENGTH+1]
digest_md5_cipher cipher
char response[DIGEST_MD5_RESPONSE_LENGTH+1]