File: nonce.h

package info (click to toggle)
kamailio 4.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 56,100 kB
  • sloc: ansic: 552,832; xml: 166,484; sh: 8,659; makefile: 7,676; sql: 6,235; perl: 3,487; yacc: 3,428; python: 1,457; cpp: 1,219; php: 1,047; java: 449; pascal: 194; cs: 40; awk: 27
file content (232 lines) | stat: -rw-r--r-- 7,177 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
 * $Id$
 *
 * Nonce related functions
 *
 * Copyright (C) 2001-2003 FhG Fokus
 *
 * This file is part of ser, a free SIP server.
 *
 * ser is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version
 *
 * For a license to use the ser software under conditions
 * other than those described here, or to purchase support for this
 * software, please contact iptel.org by e-mail at the following addresses:
 *    info@iptel.org
 *
 * ser is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */


#ifndef NONCE_H
#define NONCE_H

#include "../../parser/msg_parser.h"
#include "../../parser/digest/digest.h"
#include "../../str.h"
#include "../../basex.h"
#include <time.h>


/* auth_extra_checks flags */

#define AUTH_CHECK_FULL_URI (1 << 0)
#define AUTH_CHECK_CALLID   (1 << 1)
#define AUTH_CHECK_FROMTAG  (1 << 2)
#define AUTH_CHECK_SRC_IP   (1 << 3)
/* nonce format:
 * base64(bin_nonce)
 * bin_nonce =  expire_timestamp(4) | since_timestamp(4) | \
 *   MD5(expire | since | secret1) (16)  \
 *   [|   MD5(info(auth_extra_checks) | secret2) (16) ]
 * if nonce-count or one-time nonces are enabled, the format changes to:
 *  bin_nonce = 
 * bin_nonce =  expire_timestamp(4) | since_timestamp(4) | 
 *  MD5(expire | since | nid | pf | secret1) [ | MD5... ] | nid(4) | pf(1) 
 * where pf is 1 byte, first 2 bits are flags, and the other 6 are 
 * the pool no:
 * bit7 : on => nid & pool are valid for nonce-count
 * bit6 : on => nid & pool are valid for one-time nonce
 */
#if defined USE_NC || defined USE_OT_NONCE
#define NF_VALID_NC_ID 128 
#define NF_VALID_OT_ID  64 

#define NF_POOL_NO_MASK  63
#endif

#if defined USE_NC || defined USE_OT_NONCE
#define nonce_nid_extra_size (sizeof(unsigned int)+sizeof(unsigned char))

#else /* USE_NC || USE_OT_NONCE*/

#define nonce_nid_extra_size 0
#endif /* USE_NC || USE_OT_NONCE */

/* nonce structure, complete (maximum size) */
struct bin_nonce_str{
	int expire;
	int since;
	char md5_1[16];
	char md5_2[16]; /* optional */
#if defined USE_NC || defined USE_OT_NONCE
	unsigned int nid_i;
	unsigned char nid_pf; /* pool no & flags:
						 	  bits 7, 6 = flags, bits 5..0 pool no*/ 
#endif /* USE_NC || USE_OT_NONCE */
};

/* nonce structure, small version  (no auth_extra_checks secondary md5) */
struct bin_nonce_small_str{
	int expire;
	int since;
	char md5_1[16];
#if defined USE_NC || defined USE_OT_NONCE
	unsigned int nid_i;
	unsigned char nid_pf; /* pool no & flags:
							  bits 7, 6 = flags, bits 5..0 pool no*/ 
#endif /* USE_NC || USE_OT_NONCE */
};

/* nonce union */
union bin_nonce{
	struct bin_nonce_str n;
	struct bin_nonce_small_str n_small;
	unsigned char raw[sizeof(struct bin_nonce_str)];
};


/* fill an union bin_nonce*, before computing the md5 */
#define BIN_NONCE_PREPARE_COMMON(bn, expire_val, since_val) \
	do{\
		(bn)->n.expire=htonl(expire_val); \
		(bn)->n.since=htonl(since_val); \
	}while(0)

#if defined USE_NC || defined USE_OT_NONCE
#define BIN_NONCE_PREPARE(bn, expire_v, since_v, id_v, pf_v, cfg, msg)  \
	do{ \
		BIN_NONCE_PREPARE_COMMON(bn, expire_v, since_v); \
		if (cfg && msg){ \
			(bn)->n.nid_i=htonl(id_v); \
			(bn)->n.nid_pf=(pf_v); \
		}else{ \
			(bn)->n_small.nid_i=htonl(id_v); \
			(bn)->n_small.nid_pf=(pf_v); \
		} \
	}while(0)
#else /* USE_NC || USE_OT_NONCE */
#define BIN_NONCE_PREPARE(bn, expire, since, id, pf, cfg, msg)  \
	BIN_NONCE_PREPARE_COMMON(bn, expire, since)
#endif /* USE_NC || USE_OT_NONCE */



/* maximum nonce length in binary form (not converted to base64/hex):
 * expires_t | since_t | MD5(expires_t | since_t | s1) | \
 *   MD5(info(auth_extra_checks, s2))   => 4  + 4 + 16 + 16 = 40 bytes
 * or if nc_enabled:
 * expires_t | since_t | MD5...| MD5... | nonce_id | flag+pool_no(1 byte)
 * => 4 + 4 + 16 + 16 + 4 + 1 = 45 bytes
 * (sizeof(struct) cannot be used safely since structs can be padded
 *  by the compiler if not defined with special attrs)
 */
#if defined USE_NC || defined USE_OT_NONCE
#define MAX_BIN_NONCE_LEN (4 + 4 + 16 + 16 + 4 +1)
#define MAX_NOCFG_BIN_NONCE_LEN (4 + 4 + 16 + 4 + 1)

#define get_bin_nonce_len(cfg, nid_enabled) \
	( ( (cfg)?MAX_BIN_NONCE_LEN:MAX_NOCFG_BIN_NONCE_LEN ) - \
		(!(nid_enabled))*nonce_nid_extra_size )

#else /* USE_NC || USE_OT_NONCE */
#define MAX_BIN_NONCE_LEN (4 + 4 + 16 + 16)
#define MAX_NOCFG_BIN_NONCE_LEN (4 + 4 + 16)

#define get_bin_nonce_len(cfg, nid_enabled) \
		( (cfg)?MAX_BIN_NONCE_LEN:MAX_NOCFG_BIN_NONCE_LEN )

#endif /* USE_NC || USE_OT_NONCE */

/* minimum nonce length in binary form (not converted to base64/hex):
 * expires_t | since_t | MD5(expires_t | since_t | s1) => 4 + 4 + 16 = 24 
 * If nc_enabled the nonce will be bigger:
 * expires_t | since_t | MD5... | nonce_id | flag+pool_no(1 byte) 
 * => 4 + 4 + 16 + 4 + 1 = 29, but we always return the minimum */
#define MIN_BIN_NONCE_LEN (4 + 4 + 16)


/*
 * Maximum length of nonce string in bytes
 * nonce = expires_TIMESTAMP[4 chars] since_TIMESTAMP[4 chars] \
 * MD5SUM(expires_TIMESTAMP, since_TIMESTAMP, SECRET1)[16 chars] \
 * MD5SUM(info(auth_extra_checks), SECRET2)[16 chars] \
 * [nid [4 chars]  pflags[1 char]]
 */
#define MAX_NONCE_LEN  base64_enc_len(MAX_BIN_NONCE_LEN)
/*
 * Minimum length of the nonce string
 * nonce = expires_TIMESTAMP[4 chars] since_TIMESTAMP[4 chars] 
 * MD5SUM(expires_TIMESTAMP, since_TIMESTAMP, SECRET1)[16 chars]
 */
#define MIN_NONCE_LEN base64_enc_len(MIN_BIN_NONCE_LEN)

/*
 * length of nonces when no auth extra checks (cfg==0) are enabled
 */
#define MAX_NOCFG_NONCE_LEN base64_enc_len(MAX_NOCFG_BIN_NONCE_LEN)


/* Extra authentication checks for REGISTER messages */
extern int auth_checks_reg;
/* Extra authentication checks for out-of-dialog requests */
extern int auth_checks_ood;
/* Extra authentication checks for in-dialog requests */
extern int auth_checks_ind;

/* maximum time drift accepted for the nonce creation time
 * (e.g. nonce generated by another proxy in the same cluster with the
 * clock slightly in the future)
 */
extern unsigned int  nonce_auth_max_drift;


int get_auth_checks(struct sip_msg* msg);


/*
 * get the configured nonce len
 */
#define get_nonce_len(cfg, nid_enabled) \
		base64_enc_len(get_bin_nonce_len(cfg, nid_enabled))


/*
 * Calculate nonce value
 */
int calc_nonce(char* nonce, int* nonce_len, int cfg, int since, int expires,
#if defined USE_NC || defined USE_OT_NONCE
				unsigned int n_id, unsigned char pf,
#endif /* USE_NC || USE_OT_NONCE */
				str* secret1, str* secret2, struct sip_msg* msg);


/*
 * Check nonce value received from UA
 */
int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
					struct sip_msg* msg);



#endif /* NONCE_H */