nonce.h

00001 /*
00002  * $Id$
00003  *
00004  * Nonce related functions
00005  *
00006  * Copyright (C) 2001-2003 FhG Fokus
00007  *
00008  * This file is part of ser, a free SIP server.
00009  *
00010  * ser is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * For a license to use the ser software under conditions
00016  * other than those described here, or to purchase support for this
00017  * software, please contact iptel.org by e-mail at the following addresses:
00018  *    info@iptel.org
00019  *
00020  * ser is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  *
00025  * You should have received a copy of the GNU General Public License 
00026  * along with this program; if not, write to the Free Software 
00027  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028  */
00029 
00030 
00031 #ifndef NONCE_H
00032 #define NONCE_H
00033 
00034 #include "../../parser/msg_parser.h"
00035 #include "../../parser/digest/digest.h"
00036 #include "../../str.h"
00037 #include "../../basex.h"
00038 #include <time.h>
00039 
00040 
00041 /* auth_extra_checks flags */
00042 
00043 #define AUTH_CHECK_FULL_URI (1 << 0)
00044 #define AUTH_CHECK_CALLID   (1 << 1)
00045 #define AUTH_CHECK_FROMTAG  (1 << 2)
00046 #define AUTH_CHECK_SRC_IP   (1 << 3)
00047 /* nonce format:
00048  * base64(bin_nonce)
00049  * bin_nonce =  expire_timestamp(4) | since_timestamp(4) | \
00050  *   MD5(expire | since | secret1) (16)  \
00051  *   [|   MD5(info(auth_extra_checks) | secret2) (16) ]
00052  * if nonce-count or one-time nonces are enabled, the format changes to:
00053  *  bin_nonce = 
00054  * bin_nonce =  expire_timestamp(4) | since_timestamp(4) | 
00055  *  MD5(expire | since | nid | pf | secret1) [ | MD5... ] | nid(4) | pf(1) 
00056  * where pf is 1 byte, first 2 bits are flags, and the other 6 are 
00057  * the pool no:
00058  * bit7 : on => nid & pool are valid for nonce-count
00059  * bit6 : on => nid & pool are valid for one-time nonce
00060  */
00061 #if defined USE_NC || defined USE_OT_NONCE
00062 #define NF_VALID_NC_ID 128 
00063 #define NF_VALID_OT_ID  64 
00064 
00065 #define NF_POOL_NO_MASK  63
00066 #endif
00067 
00068 #if defined USE_NC || defined USE_OT_NONCE
00069 #define nonce_nid_extra_size (sizeof(unsigned int)+sizeof(unsigned char))
00070 
00071 #else /* USE_NC || USE_OT_NONCE*/
00072 
00073 #define nonce_nid_extra_size 0
00074 #endif /* USE_NC || USE_OT_NONCE */
00075 
00076 /* nonce structure, complete (maximum size) */
00077 struct bin_nonce_str{
00078         int expire;
00079         int since;
00080         char md5_1[16];
00081         char md5_2[16]; /* optional */
00082 #if defined USE_NC || defined USE_OT_NONCE
00083         unsigned int nid_i;
00084         unsigned char nid_pf; /* pool no & flags:
00085                                                           bits 7, 6 = flags, bits 5..0 pool no*/ 
00086 #endif /* USE_NC || USE_OT_NONCE */
00087 };
00088 
00089 /* nonce structure, small version  (no auth_extra_checks secondary md5) */
00090 struct bin_nonce_small_str{
00091         int expire;
00092         int since;
00093         char md5_1[16];
00094 #if defined USE_NC || defined USE_OT_NONCE
00095         unsigned int nid_i;
00096         unsigned char nid_pf; /* pool no & flags:
00097                                                           bits 7, 6 = flags, bits 5..0 pool no*/ 
00098 #endif /* USE_NC || USE_OT_NONCE */
00099 };
00100 
00101 /* nonce union */
00102 union bin_nonce{
00103         struct bin_nonce_str n;
00104         struct bin_nonce_small_str n_small;
00105         unsigned char raw[sizeof(struct bin_nonce_str)];
00106 };
00107 
00108 
00109 /* fill an union bin_nonce*, before computing the md5 */
00110 #define BIN_NONCE_PREPARE_COMMON(bn, expire_val, since_val) \
00111         do{\
00112                 (bn)->n.expire=htonl(expire_val); \
00113                 (bn)->n.since=htonl(since_val); \
00114         }while(0)
00115 
00116 #if defined USE_NC || defined USE_OT_NONCE
00117 #define BIN_NONCE_PREPARE(bn, expire_v, since_v, id_v, pf_v, cfg, msg)  \
00118         do{ \
00119                 BIN_NONCE_PREPARE_COMMON(bn, expire_v, since_v); \
00120                 if (cfg && msg){ \
00121                         (bn)->n.nid_i=htonl(id_v); \
00122                         (bn)->n.nid_pf=(pf_v); \
00123                 }else{ \
00124                         (bn)->n_small.nid_i=htonl(id_v); \
00125                         (bn)->n_small.nid_pf=(pf_v); \
00126                 } \
00127         }while(0)
00128 #else /* USE_NC || USE_OT_NONCE */
00129 #define BIN_NONCE_PREPARE(bn, expire, since, id, pf, cfg, msg)  \
00130         BIN_NONCE_PREPARE_COMMON(bn, expire, since)
00131 #endif /* USE_NC || USE_OT_NONCE */
00132 
00133 
00134 
00135 /* maximum nonce length in binary form (not converted to base64/hex):
00136  * expires_t | since_t | MD5(expires_t | since_t | s1) | \
00137  *   MD5(info(auth_extra_checks, s2))   => 4  + 4 + 16 + 16 = 40 bytes
00138  * or if nc_enabled:
00139  * expires_t | since_t | MD5...| MD5... | nonce_id | flag+pool_no(1 byte)
00140  * => 4 + 4 + 16 + 16 + 4 + 1 = 45 bytes
00141  * (sizeof(struct) cannot be used safely since structs can be padded
00142  *  by the compiler if not defined with special attrs)
00143  */
00144 #if defined USE_NC || defined USE_OT_NONCE
00145 #define MAX_BIN_NONCE_LEN (4 + 4 + 16 + 16 + 4 +1)
00146 #define MAX_NOCFG_BIN_NONCE_LEN (4 + 4 + 16 + 4 + 1)
00147 
00148 #define get_bin_nonce_len(cfg, nid_enabled) \
00149         ( ( (cfg)?MAX_BIN_NONCE_LEN:MAX_NOCFG_BIN_NONCE_LEN ) - \
00150                 (!(nid_enabled))*nonce_nid_extra_size )
00151 
00152 #else /* USE_NC || USE_OT_NONCE */
00153 #define MAX_BIN_NONCE_LEN (4 + 4 + 16 + 16)
00154 #define MAX_NOCFG_BIN_NONCE_LEN (4 + 4 + 16)
00155 
00156 #define get_bin_nonce_len(cfg, nid_enabled) \
00157                 ( (cfg)?MAX_BIN_NONCE_LEN:MAX_NOCFG_BIN_NONCE_LEN )
00158 
00159 #endif /* USE_NC || USE_OT_NONCE */
00160 
00161 /* minimum nonce length in binary form (not converted to base64/hex):
00162  * expires_t | since_t | MD5(expires_t | since_t | s1) => 4 + 4 + 16 = 24 
00163  * If nc_enabled the nonce will be bigger:
00164  * expires_t | since_t | MD5... | nonce_id | flag+pool_no(1 byte) 
00165  * => 4 + 4 + 16 + 4 + 1 = 29, but we always return the minimum */
00166 #define MIN_BIN_NONCE_LEN (4 + 4 + 16)
00167 
00168 
00169 /*
00170  * Maximum length of nonce string in bytes
00171  * nonce = expires_TIMESTAMP[4 chars] since_TIMESTAMP[4 chars] \
00172  * MD5SUM(expires_TIMESTAMP, since_TIMESTAMP, SECRET1)[16 chars] \
00173  * MD5SUM(info(auth_extra_checks), SECRET2)[16 chars] \
00174  * [nid [4 chars]  pflags[1 char]]
00175  */
00176 #define MAX_NONCE_LEN  base64_enc_len(MAX_BIN_NONCE_LEN)
00177 /*
00178  * Minimum length of the nonce string
00179  * nonce = expires_TIMESTAMP[4 chars] since_TIMESTAMP[4 chars] 
00180  * MD5SUM(expires_TIMESTAMP, since_TIMESTAMP, SECRET1)[16 chars]
00181  */
00182 #define MIN_NONCE_LEN base64_enc_len(MIN_BIN_NONCE_LEN)
00183 
00184 /*
00185  * length of nonces when no auth extra checks (cfg==0) are enabled
00186  */
00187 #define MAX_NOCFG_NONCE_LEN base64_enc_len(MAX_NOCFG_BIN_NONCE_LEN)
00188 
00189 
00190 /* Extra authentication checks for REGISTER messages */
00191 extern int auth_checks_reg;
00192 /* Extra authentication checks for out-of-dialog requests */
00193 extern int auth_checks_ood;
00194 /* Extra authentication checks for in-dialog requests */
00195 extern int auth_checks_ind;
00196 
00197 /* maximum time drift accepted for the nonce creation time
00198  * (e.g. nonce generated by another proxy in the same cluster with the
00199  * clock slightly in the future)
00200  */
00201 extern unsigned int  nonce_auth_max_drift;
00202 
00203 
00204 int get_auth_checks(struct sip_msg* msg);
00205 
00206 
00207 /*
00208  * get the configured nonce len
00209  */
00210 #define get_nonce_len(cfg, nid_enabled) \
00211                 base64_enc_len(get_bin_nonce_len(cfg, nid_enabled))
00212 
00213 
00214 /*
00215  * Calculate nonce value
00216  */
00217 int calc_nonce(char* nonce, int* nonce_len, int cfg, int since, int expires,
00218 #if defined USE_NC || defined USE_OT_NONCE
00219                                 unsigned int n_id, unsigned char pf,
00220 #endif /* USE_NC || USE_OT_NONCE */
00221                                 str* secret1, str* secret2, struct sip_msg* msg);
00222 
00223 
00224 /*
00225  * Check nonce value received from UA
00226  */
00227 int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
00228                                         struct sip_msg* msg);
00229 
00230 
00231 
00232 #endif /* NONCE_H */