You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/modules/auth/nonce.h

233 lines
7.0 KiB

/*
* $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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */