1/* validate.c --- Validate consistency of SCRAM tokens.
2 * Copyright (C) 2009-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
33bool
34scram_valid_client_first (struct scram_client_first *cf)
35{
36 /* Check that cbflag is one of permitted values. */
37 switch (cf->cbflag)
38 {
39 case 'p':
40 case 'n':
41 case 'y':
42 break;
43
44 default:
45 return false;
46 }
47
48 /* Check that cbname is only set when cbflag is p. */
49 if (cf->cbflag == 'p' && cf->cbname == NULL)
50 return false;
51 else if (cf->cbflag != 'p' && cf->cbname != NULL)
52 return false;
53
54 if (cf->cbname)
55 {
56 const char *p = cf->cbname;
57
58 while (*p && strchr ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
59 "abcdefghijklmnopqrstuvwxyz" "0123456789.-", *p))
60 p++;
61 if (*p)
62 return false;
63 }
64
65 /* We require a non-zero username string. */
66 if (cf->username == NULL || *cf->username == '\0')
67 return false;
68
69 /* We require a non-zero client nonce. */
70 if (cf->client_nonce == NULL || *cf->client_nonce == '\0')
71 return false;
72
73 /* Nonce cannot contain ','. */
74 if (strchr (cf->client_nonce, ','))
75 return false;
76
77 return true;
78}
79
80bool
81scram_valid_server_first (struct scram_server_first * sf)
82{
83 /* We require a non-zero nonce. */
84 if (sf->nonce == NULL || *sf->nonce == '\0')
85 return false;
86
87 /* Nonce cannot contain ','. */
88 if (strchr (sf->nonce, ','))
89 return false;
90
91 /* We require a non-zero salt. */
92 if (sf->salt == NULL || *sf->salt == '\0')
93 return false;
94
95 /* FIXME check that salt is valid base64. */
96 if (strchr (sf->salt, ','))
97 return false;
98
99 if (sf->iter == 0)
100 return false;
101
102 return true;
103}
104
105bool
106scram_valid_client_final (struct scram_client_final * cl)
107{
108 /* We require a non-zero cbind. */
109 if (cl->cbind == NULL || *cl->cbind == '\0')
110 return false;
111
112 /* FIXME check that cbind is valid base64. */
113 if (strchr (cl->cbind, ','))
114 return false;
115
116 /* We require a non-zero nonce. */
117 if (cl->nonce == NULL || *cl->nonce == '\0')
118 return false;
119
120 /* Nonce cannot contain ','. */
121 if (strchr (cl->nonce, ','))
122 return false;
123
124 /* We require a non-zero proof. */
125 if (cl->proof == NULL || *cl->proof == '\0')
126 return false;
127
128 /* FIXME check that proof is valid base64. */
129 if (strchr (cl->proof, ','))
130 return false;
131
132 return true;
133}
134
135bool
136scram_valid_server_final (struct scram_server_final * sl)
137{
138 /* We require a non-zero verifier. */
139 if (sl->verifier == NULL || *sl->verifier == '\0')
140 return false;
141
142 /* FIXME check that verifier is valid base64. */
143 if (strchr (sl->verifier, ','))
144 return false;
145
146 return true;
147}
148