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