nonce.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /*
  2. * $Id$
  3. *
  4. * Nonce related functions
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of ser, a free SIP server.
  9. *
  10. * ser is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * For a license to use the ser software under conditions
  16. * other than those described here, or to purchase support for this
  17. * software, please contact iptel.org by e-mail at the following addresses:
  18. * [email protected]
  19. *
  20. * ser is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. /*
  30. * History:
  31. * --------
  32. * ...
  33. * 2007-10-19 auth extra checks: longer nonces that include selected message
  34. * parts to protect against various reply attacks without keeping
  35. * state (andrei)
  36. * 2008-07-01 switched to base64 for nonces; check staleness in check_nonce
  37. * (andrei)
  38. * 2008-07-04 nonce-count support (andrei)
  39. */
  40. #include <time.h>
  41. #include <string.h>
  42. #include <sys/types.h>
  43. #include <netinet/in.h>
  44. #include "../../compiler_opt.h"
  45. #include "../../md5.h"
  46. #include "../../dprint.h"
  47. #include "../../ut.h"
  48. #include "../../parser/msg_parser.h"
  49. #include "../../parser/parse_from.h"
  50. #include "../../ip_addr.h"
  51. #include "nonce.h"
  52. #include "../../globals.h"
  53. #include <assert.h>
  54. #ifdef USE_NC
  55. #include "nc.h"
  56. #endif
  57. #ifdef USE_OT_NONCE
  58. #include "ot_nonce.h"
  59. #endif
  60. int auth_checks_reg = 0;
  61. int auth_checks_ood = 0;
  62. int auth_checks_ind = 0;
  63. /* maximum time drift accepted for the nonce creation time
  64. * (e.g. nonce generated by another proxy in the same cluster with the
  65. * clock slightly in the future)
  66. */
  67. unsigned int nonce_auth_max_drift = 3; /* in s */
  68. /** Select extra check configuration based on request type.
  69. * This function determines which configuration variable for
  70. * extra authentication checks is to be used based on the
  71. * type of the request. It returns the value of auth_checks_reg
  72. * for REGISTER requests, the value auth_checks_ind for requests
  73. * that contain valid To tag and the value of auth_checks_ood
  74. * otherwise.
  75. */
  76. int get_auth_checks(struct sip_msg* msg)
  77. {
  78. str tag;
  79. if (msg == NULL) return 0;
  80. if (msg->REQ_METHOD == METHOD_REGISTER) {
  81. return auth_checks_reg;
  82. }
  83. if (!msg->to && parse_headers(msg, HDR_TO_F, 0) == -1) {
  84. DBG("auth: Error while parsing To header field\n");
  85. return auth_checks_ood;
  86. }
  87. if (msg->to) {
  88. tag = get_to(msg)->tag_value;
  89. if (tag.s && tag.len > 0) return auth_checks_ind;
  90. }
  91. return auth_checks_ood;
  92. }
  93. /* takes a pre-filled bin_nonce union (see BIN_NONCE_PREPARE), fills the
  94. * MD5s and returns the length of the binary nonce (cannot return error).
  95. * See calc_nonce below for more details.*/
  96. inline static int calc_bin_nonce_md5(union bin_nonce* b_nonce, int cfg,
  97. str* secret1, str* secret2,
  98. struct sip_msg* msg)
  99. {
  100. MD5_CTX ctx;
  101. str* s;
  102. int len;
  103. MD5Init(&ctx);
  104. U_MD5Update(&ctx, &b_nonce->raw[0], 4 + 4);
  105. if (cfg && msg){
  106. /* auth extra checks => 2 md5s */
  107. len = 4 + 4 + 16 + 16;
  108. #if defined USE_NC || defined USE_OT_NONCE
  109. if (b_nonce->n.nid_pf & (NF_VALID_NC_ID | NF_VALID_OT_ID)){
  110. /* if extra auth checks enabled, nid & pf are after the 2nd md5 */
  111. U_MD5Update(&ctx, (unsigned char*)&b_nonce->n.nid_i,
  112. nonce_nid_extra_size);
  113. len+=nonce_nid_extra_size;
  114. }
  115. #endif /* USE_NC || USE_OT_NONCE */
  116. MD5Update(&ctx, secret1->s, secret1->len);
  117. MD5Final(&b_nonce->n.md5_1[0], &ctx);
  118. /* second MD5(auth_extra_checks) */
  119. MD5Init(&ctx);
  120. if (cfg & AUTH_CHECK_FULL_URI) {
  121. s = GET_RURI(msg);
  122. MD5Update(&ctx, s->s, s->len);
  123. }
  124. if ((cfg & AUTH_CHECK_CALLID) &&
  125. !(parse_headers(msg, HDR_CALLID_F, 0) < 0 || msg->callid == 0)) {
  126. MD5Update(&ctx, msg->callid->body.s, msg->callid->body.len);
  127. }
  128. if ((cfg & AUTH_CHECK_FROMTAG) &&
  129. !(parse_from_header(msg) < 0 )) {
  130. MD5Update(&ctx, get_from(msg)->tag_value.s,
  131. get_from(msg)->tag_value.len);
  132. }
  133. if (cfg & AUTH_CHECK_SRC_IP) {
  134. U_MD5Update(&ctx, msg->rcv.src_ip.u.addr, msg->rcv.src_ip.len);
  135. }
  136. MD5Update(&ctx, secret2->s, secret2->len);
  137. MD5Final(&b_nonce->n.md5_2[0], &ctx);
  138. }else{
  139. /* no extra checks => only one md5 */
  140. len = 4 + 4 + 16;
  141. #if defined USE_NC || USE_OT_NONCE
  142. if (b_nonce->n_small.nid_pf & (NF_VALID_NC_ID | NF_VALID_OT_ID)){
  143. /* if extra auth checks are not enabled, nid & pf are after the
  144. * 1st md5 */
  145. U_MD5Update(&ctx, (unsigned char*)&b_nonce->n_small.nid_i,
  146. nonce_nid_extra_size);
  147. len+=nonce_nid_extra_size;
  148. }
  149. #endif /* USE_NC || USE_OT_NONCE*/
  150. MD5Update(&ctx, secret1->s, secret1->len);
  151. MD5Final(&b_nonce->n.md5_1[0], &ctx);
  152. }
  153. return len;
  154. }
  155. /** Calculates the nonce string for RFC2617 digest authentication.
  156. * This function creates the nonce string as it will be sent to the
  157. * user agent in digest challenge. The format of the nonce string
  158. * depends on the value of three module parameters, auth_checks_register,
  159. * auth_checks_no_dlg, and auth_checks_in_dlg. These module parameters
  160. * control the amount of information from the SIP requst that will be
  161. * stored in the nonce string for verification purposes.
  162. *
  163. * If all three parameters contain zero then the nonce string consists
  164. * of time in seconds since 1.1. 1970 and a secret phrase:
  165. * <expire_time> <valid_since> MD5(<expire_time>, <valid_since>, secret)
  166. * If any of the parameters is not zero (some optional checks are enabled
  167. * then the nonce string will also contain MD5 hash of selected parts
  168. * of the SIP request:
  169. * <expire_time> <valid_since> MD5(<expire_time>, <valid_since>, secret1) MD5(<extra_checks>, secret2)
  170. * @param nonce Pointer to a buffer of *nonce_len. It must have enough
  171. * space to hold the nonce. MAX_NONCE_LEN should be always
  172. * safe.
  173. * @param nonce_len A value/result parameter. Initially it contains the
  174. * nonce buffer length. If the length is too small, it
  175. * will be set to the needed length and the function will
  176. * return error immediately. After a succesfull call it will
  177. * contain the size of nonce written into the buffer,
  178. * without the terminating 0.
  179. * @param cfg This is the value of one of the tree module parameters that
  180. * control which optional checks are enabled/disabled and which
  181. * parts of the message will be included in the nonce string.
  182. * @param since Time when nonce was created, i.e. nonce is valid since <valid_since> up to <expires>
  183. * @param expires Time in seconds after which the nonce will be considered
  184. * stale.
  185. * @param n_id Nounce count and/or one-time nonce index value
  186. * (32 bit counter)
  187. * @param pf First 2 bits are flags, the rest is the index pool number
  188. * used if nonce counts or one-time nonces are enabled.
  189. * The possible flags values are: NF_VALID_NC_ID which means
  190. * the nonce-count support is enabled and NF_VALID_OT_ID
  191. * which means the one-time nonces support is enabled.
  192. * The pool number can be obtained by and-ing with
  193. * NF_POOL_NO_MASK
  194. * @param secret1 A secret used for the nonce expires integrity check:
  195. * MD5(<expire_time>, <valid_since>, secret1).
  196. * @param secret2 A secret used for integrity check of the message parts
  197. * selected by auth_extra_checks (if any):
  198. * MD5(<msg_parts(auth_extra_checks)>, secret2).
  199. * @param msg The message for which the nonce is computed. If
  200. * auth_extra_checks is set, the MD5 of some fields of the
  201. * message will be included in the generated nonce.
  202. * @return 0 on success and -1 on error
  203. */
  204. int calc_nonce(char* nonce, int *nonce_len, int cfg, int since, int expires,
  205. #if defined USE_NC || defined USE_OT_NONCE
  206. unsigned int n_id, unsigned char pf,
  207. #endif /* USE_NC || USE_OT_NONCE */
  208. str* secret1, str* secret2,
  209. struct sip_msg* msg)
  210. {
  211. union bin_nonce b_nonce;
  212. int len;
  213. if (unlikely(*nonce_len < MAX_NONCE_LEN)) {
  214. len=get_nonce_len(cfg, pf & NF_VALID_NC_ID);
  215. if (unlikely(*nonce_len<len)){
  216. *nonce_len=len;
  217. return -1;
  218. }
  219. }
  220. BIN_NONCE_PREPARE(&b_nonce, expires, since, n_id, pf, cfg, msg);
  221. len=calc_bin_nonce_md5(&b_nonce, cfg, secret1, secret2, msg);
  222. *nonce_len=base64_enc(&b_nonce.raw[0], len,
  223. (unsigned char*)nonce, *nonce_len);
  224. assert(*nonce_len>=0); /*FIXME*/
  225. return 0;
  226. }
  227. /** Returns the expire time of the nonce string.
  228. * This function returns the absolute expire time
  229. * extracted from the nonce string in the parameter.
  230. * @param bn is a valid pointer to a union bin_nonce (decoded nonce)
  231. * @return Absolute time when the nonce string expires.
  232. */
  233. #define get_bin_nonce_expire(bn) ((time_t)ntohl((bn)->n.expire))
  234. /** Returns the valid_since time of the nonce string.
  235. * This function returns the absolute time
  236. * extracted from the nonce string in the parameter.
  237. * @param bn is a valid pointer to a union bin_nonce (decoded nonce)
  238. * @return Absolute time when the nonce string was created.
  239. */
  240. #define get_bin_nonce_since(bn) ((time_t)ntohl((bn)->n.since))
  241. /** Checks if nonce is stale.
  242. * This function checks if a nonce given to it in the parameter is stale.
  243. * A nonce is stale if the expire time stored in the nonce is in the past.
  244. * @param b_nonce a pointer to a union bin_nonce to be checked.
  245. * @return 1 the nonce is stale, 0 the nonce is not stale.
  246. */
  247. #define is_bin_nonce_stale(b_nonce, t) (get_bin_nonce_expire(b_nonce) < (t))
  248. /** Utility to convert 8 hex digit string to int */
  249. static inline int l8hex2int(char* _s, unsigned int *_r)
  250. {
  251. unsigned int i, res = 0;
  252. for(i = 0; i < 8; i++) {
  253. res *= 16;
  254. if ((_s[i] >= '0') && (_s[i] <= '9')) {
  255. res += _s[i] - '0';
  256. } else if ((_s[i] >= 'a') && (_s[i] <= 'f')) {
  257. res += _s[i] - 'a' + 10;
  258. } else if ((_s[i] >= 'A') && (_s[i] <= 'F')) {
  259. res += _s[i] - 'A' + 10;
  260. } else return -1;
  261. }
  262. *_r = res;
  263. return 0;
  264. }
  265. /** Check whether the nonce returned by UA is valid.
  266. * This function checks whether the nonce string returned by UA
  267. * in digest response is valid. The function checks if the nonce
  268. * string hasn't expired, it verifies the secret stored in the nonce
  269. * string with the secret configured on the server. If any of the
  270. * optional extra integrity checks are enabled then it also verifies
  271. * whether the corresponding parts in the new SIP requests are same.
  272. * @param nonce A nonce string to be verified.
  273. * @param secret1 A secret used for the nonce expires integrity check:
  274. * MD5(<expire_time>,, secret1).
  275. * @param secret2 A secret used for integrity check of the message parts
  276. * selected by auth_extra_checks (if any):
  277. * MD5(<msg_parts(auth_extra_checks)>, secret2).
  278. * @param msg The message which contains the nonce being verified.
  279. * @return 0 - success (the nonce was not tampered with and if
  280. * auth_extra_checks are enabled - the selected message fields
  281. * have not changes from the time the nonce was generated)
  282. * -1 - invalid nonce
  283. * 1 - nonce length too small
  284. * 2 - no match
  285. * 3 - nonce expires ok, but the auth_extra checks failed
  286. * 4 - stale
  287. * 5 - invalid nc value (not an unsigned int)
  288. * 6 - nonce reused
  289. */
  290. int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
  291. struct sip_msg* msg)
  292. {
  293. str * nonce;
  294. int since, b_nonce2_len, b_nonce_len, cfg;
  295. union bin_nonce b_nonce;
  296. union bin_nonce b_nonce2;
  297. time_t t;
  298. #if defined USE_NC || defined USE_OT_NONCE
  299. unsigned int n_id;
  300. unsigned char pf;
  301. #endif /* USE_NC || USE_OT_NONCE */
  302. #ifdef USE_NC
  303. unsigned int nc;
  304. #endif
  305. cfg = get_auth_checks(msg);
  306. nonce=&auth->digest.nonce;
  307. if (unlikely(nonce->s == 0)) {
  308. return -1; /* Invalid nonce */
  309. }
  310. if (unlikely(nonce->len<MIN_NONCE_LEN)){
  311. return 1; /* length musth be >= then minimum length */
  312. }
  313. #if defined USE_NC || defined USE_OT_NONCE
  314. /* clear all possible nonce flags positions prior to decoding,
  315. * to make sure they can be used even if the nonce is shorter */
  316. b_nonce.n.nid_pf=0;
  317. b_nonce.n_small.nid_pf=0;
  318. #endif /* USE_NC || USE_OT_NONCE */
  319. /* decode nonce */
  320. b_nonce_len=base64_dec((unsigned char*)nonce->s, nonce->len,
  321. &b_nonce.raw[0], sizeof(b_nonce));
  322. if (unlikely(b_nonce_len < MIN_BIN_NONCE_LEN)){
  323. DBG("auth: check_nonce: base64_dec failed\n");
  324. return -1; /* error decoding the nonce (invalid nonce since we checked
  325. the len of the base64 enc. nonce above)*/
  326. }
  327. since = get_bin_nonce_since(&b_nonce);
  328. if (unlikely(since < up_since)) {
  329. /* if valid_since time is time pointing before ser was started
  330. * then we consider nonce as stalled.
  331. It may be the nonce generated by previous ser instance having
  332. different length (for example because of different auth.
  333. checks).. Therefore we force credentials to be rebuilt by UAC
  334. without prompting for password */
  335. return 4;
  336. }
  337. t=time(0);
  338. if (unlikely((since > t) && ((since-t) > nonce_auth_max_drift) )){
  339. /* the nonce comes from the future, either because of an external
  340. * time adjustment, or because it was generated by another host
  341. * which has the time slightly unsynchronized */
  342. return 4; /* consider it stale */
  343. }
  344. b_nonce2=b_nonce; /*pre-fill it with the values from the received nonce*/
  345. b_nonce2.n.expire=b_nonce.n.expire;
  346. b_nonce2.n.since=b_nonce.n.since;
  347. #if defined USE_NC || defined USE_OT_NONCE
  348. if (cfg){
  349. b_nonce2.n.nid_i=b_nonce.n.nid_i;
  350. b_nonce2.n.nid_pf=b_nonce.n.nid_pf;
  351. pf=b_nonce.n.nid_pf;
  352. n_id=ntohl(b_nonce.n.nid_i);
  353. }else{
  354. b_nonce2.n_small.nid_i=b_nonce.n_small.nid_i;
  355. b_nonce2.n_small.nid_pf=b_nonce.n_small.nid_pf;
  356. pf=b_nonce.n_small.nid_pf;
  357. n_id=ntohl(b_nonce.n_small.nid_i);
  358. }
  359. #ifdef UE_NC
  360. if (unlikely(nc_enabled && !(pf & NF_VALID_NC_ID)) )
  361. /* nounce count enabled, but nonce is not marked as nonce count ready
  362. * or is too short => either an old nonce (should
  363. * be caught by the ser start time check) or truncated nonce */
  364. return 4; /* return stale for now */
  365. }
  366. #endif /* USE_NC */
  367. #ifdef USE_OT_NONCE
  368. if (unlikely(otn_enabled && !(pf & NF_VALID_OT_ID))){
  369. /* same as above for one-time-nonce */
  370. return 4; /* return stale for now */
  371. }
  372. #endif /* USE_OT_NONCE */
  373. /* don't check if we got the expected length, if the length is smaller
  374. * then expected then the md5 check below will fail (since the nid
  375. * members of the bin_nonce struct will be 0); if the length is bigger
  376. * and it was not caught by the base64_dec above, and the md5 matches,
  377. * we ignore the extra stuff */
  378. #endif /* USE_NC || USE_OT_NONCE */
  379. b_nonce2_len=calc_bin_nonce_md5(&b_nonce2, cfg, secret1, secret2, msg);
  380. if (!memcmp(&b_nonce.n.md5_1[0], &b_nonce2.n.md5_1[0], 16)) {
  381. #ifdef USE_NC
  382. /* if nounce-count checks enabled & auth. headers has nc */
  383. if (nc_enabled && (pf & NF_VALID_NC_ID) && auth->digest.nc.s &&
  384. auth->digest.nc.len){
  385. if ((auth->digest.nc.len != 8) ||
  386. l8hex2int(auth->digest.nc.s, &nc) != 0) {
  387. ERR("check_nonce: bad nc value %.*s\n",
  388. auth->digest.nc.len, auth->digest.nc.s);
  389. return 5; /* invalid nc */
  390. }
  391. switch(nc_check_val(n_id, pf & NF_POOL_NO_MASK, nc)){
  392. case NC_OK:
  393. /* don't perform extra checks or one-time nonce checks
  394. * anymore, if we have nc */
  395. goto check_stale;
  396. case NC_ID_OVERFLOW: /* id too old => stale */
  397. case NC_TOO_BIG: /* nc overlfow => force re-auth => stale */
  398. case NC_REPLAY: /* nc seen before => re-auth => stale */
  399. case NC_INV_POOL: /* pool-no too big, maybe ser restart?*/
  400. return 4; /* stale */
  401. }
  402. }
  403. #endif /* USE_NC */
  404. #ifdef USE_OT_NONCE
  405. if (otn_enabled && (pf & NF_VALID_OT_ID)){
  406. switch(otn_check_id(n_id, pf & NF_POOL_NO_MASK)){
  407. case OTN_OK:
  408. /* continue in case auth extra checks are enabled */
  409. break;
  410. case OTN_ID_OVERFLOW:
  411. case OTN_INV_POOL:
  412. case OTN_REPLAY:
  413. return 6; /* reused */
  414. }
  415. }
  416. #endif
  417. if (cfg) {
  418. if (unlikely(b_nonce_len != b_nonce2_len))
  419. return 2; /* someone truncated our nonce? */
  420. if (memcmp(&b_nonce.n.md5_2[0], &b_nonce2.n.md5_2[0], 16))
  421. return 3; /* auth_extra_checks failed */
  422. }
  423. #ifdef USE_NC
  424. check_stale:
  425. #endif /* USE_NC */
  426. if (unlikely(is_bin_nonce_stale(&b_nonce, t)))
  427. return 4;
  428. return 0;
  429. }
  430. return 2;
  431. }