Changeset 1500


Ignore:
Timestamp:
Oct 15, 2007 7:04:59 AM (11 years ago)
Author:
bennylp
Message:

Continuing ticket #396: tested digest AKAv1, implemented AKAv2, and some works in the authentication framework to support it

Location:
pjproject/trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/build.symbian/pjsip.mmp

    r1417 r1500  
    3333// PJSIP-CORE files 
    3434 
     35//SOURCE        sip_auth_aka.c 
    3536SOURCE  sip_auth_client.c 
    3637SOURCE  sip_auth_msg.c 
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c

    r1495 r1500  
    672672            cur_acc->cred_info[cur_acc->cred_count].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; 
    673673            cur_acc->cred_info[cur_acc->cred_count].data = pj_str(pj_optarg); 
     674#if PJSIP_HAS_DIGEST_AKA_AUTH 
     675            cur_acc->cred_info[cur_acc->cred_count].data_type |= PJSIP_CRED_DATA_EXT_AKA; 
     676            cur_acc->cred_info[cur_acc->cred_count].ext.aka.k = pj_str(pj_optarg); 
     677            cur_acc->cred_info[cur_acc->cred_count].ext.aka.cb = &pjsip_auth_create_aka_response; 
     678#endif 
    674679            break; 
    675680 
  • pjproject/trunk/pjsip/include/pjsip/print_util.h

    r1389 r1500  
    5151        } while (0) 
    5252 
     53#define copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend) \ 
     54        do { \ 
     55                printed = len1+str2.slen+2; \ 
     56                if (printed >= (endbuf-buf)) return -1; \ 
     57                pj_memcpy(buf,str1,len1); \ 
     58                *(buf+len1)=quotebegin; \ 
     59                pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \ 
     60                *(buf+printed-1) = quoteend; \ 
     61                buf += printed; \ 
     62        } while (0) 
     63 
    5364#define copy_advance_pair_escape(buf,str1,len1,str2,unres)      \ 
    5465        do { \ 
     
    8697#define copy_advance            copy_advance_check 
    8798#define copy_advance_pair       copy_advance_pair_check 
    88 #define copy_advance_pair_quote copy_advance_pair_quote_check 
    8999 
    90100#define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \ 
  • pjproject/trunk/pjsip/include/pjsip/sip_auth.h

    r1488 r1500  
    122122         *  is being used, the \a data field of this #pjsip_cred_info is 
    123123         *  not used, but it still must be initialized to an empty string. 
     124         * Please see \ref PJSIP_AUTH_AKA_API for more information. 
    124125         */ 
    125126        struct { 
    126             pj_str_t      k;    /**< Permanent key.                     */ 
     127            pj_str_t      k;    /**< Permanent subscriber key.          */ 
    127128            pj_str_t      op;   /**< Operator variant key.              */ 
    128129            pj_str_t      amf;  /**< Authentication Management Field    */ 
  • pjproject/trunk/pjsip/include/pjsip/sip_auth_aka.h

    r1488 r1500  
    3030 
    3131/** 
    32  * @defgroup PJSIP_AUTH_AKA_API Digest AKA Authentication API's 
     32 * @defgroup PJSIP_AUTH_AKA_API Digest AKAv1 and AKAv2 Authentication API 
    3333 * @ingroup PJSIP_AUTH_API 
    34  * @brief Digest AKA helper API. 
     34 * @brief Digest AKAv1 and AKAv2 Authentication API 
    3535 * @{ 
    3636 * 
    37  * This module currently exports one function, #pjsip_auth_create_akav1_response(), 
    38  * which can be registered as the callback function in \a ext.aka.cb field 
    39  * of #pjsip_cred_info structure, to calculate the MD5-AKAv1 digest 
    40  * response. 
    41  */ 
    42  
    43  
     37 * This module implements HTTP digest authentication using Authentication 
     38 * and Key Agreement (AKA) version 1 and version 2 (AKAv1-MD5 and AKAv2-MD5), 
     39 * as specified in RFC 3310 and RFC 4169. SIP AKA authentication is used 
     40 * by 3GPP and IMS systems. 
     41 * 
     42 * @section pjsip_aka_using Using Digest AKA Authentication 
     43 * 
     44 * Support for digest AKA authentication is currently made optional, so 
     45 * application needs to declare \a PJSIP_HAS_DIGEST_AKA_AUTH to non-zero 
     46 * in <tt>config_site.h</tt> to enable AKA support: 
     47 * 
     48 @code 
     49   #define PJSIP_HAS_DIGEST_AKA_AUTH   1 
     50 @endcode 
     51 
     52 * 
     53 * In addition, application would need to link with <b>libmilenage</b> 
     54 * library from \a third_party directory. 
     55 * 
     56 * Application then specifies digest AKA credential by initializing the  
     57 * authentication credential as follows: 
     58 * 
     59 @code 
     60 
     61    pjsip_cred_info cred; 
     62 
     63    pj_bzero(&cred, sizeof(cred)); 
     64 
     65    cred.scheme = pj_str("Digest"); 
     66    cred.realm = pj_str("ims-domain.test"); 
     67    cred.username = pj_str("user@ims-domain.test"); 
     68    cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD | PJSIP_CRED_DATA_EXT_AKA; 
     69    cred.data = pj_str("password"); 
     70 
     71    // AKA extended info 
     72    cred.ext.aka.k = pj_str("password"); 
     73    cred.ext.aka.cb = &pjsip_auth_create_aka_response 
     74 
     75 @endcode 
     76 * 
     77 * Description: 
     78 * - To support AKA, application adds \a PJSIP_CRED_DATA_EXT_AKA flag in the 
     79 * \a data_type field. This indicates that extended information specific to 
     80 * AKA authentication is available in the credential, and that response  
     81 * digest computation will use the callback function instead of the usual MD5 
     82 * digest computation. 
     83 * 
     84 * - The \a scheme for the credential is "Digest".  
     85 * 
     86 * - The \a realm is the expected realm in the challenge. Application may  
     87 * also specify wildcard realm ("*") if it wishes to respond to any realms  
     88 * in the challenge. 
     89 * 
     90 * - The \a data field is optional. Application may fill this with the password 
     91 * if it wants to support both MD5 and AKA MD5 in a single credential. The 
     92 * pjsip_auth_create_aka_response() function will use this field if the 
     93 * challenge indicates "MD5" as the algorithm instead of "AKAv1-MD5" or 
     94 * "AKAv2-MD5". 
     95 * 
     96 * - The \a ext.aka.k field specifies the permanent subscriber key to be used 
     97 * for AKA authentication. Application may specify binary password containing 
     98 * NULL character in this key, since the length of the key is indicated in 
     99 * the \a slen field of the string. 
     100 * 
     101 * - The \a ext.aka.cb field specifies the callback function to calculate the 
     102 * response digest. Application can specify pjsip_auth_create_aka_response() 
     103 * in this field to use PJSIP's implementation, but it's free to provide 
     104 * it's own function. 
     105 * 
     106 * - Optionally application may set \a ext.aka.op and \a ext.aka.amf in the 
     107 * credential to specify AKA Operator variant key and AKA Authentication  
     108 * Management Field information. 
     109 */ 
     110 
     111/** 
     112 * Length of Authentication Key (AK) in bytes. 
     113 */ 
    44114#define PJSIP_AKA_AKLEN         6 
     115 
     116/** 
     117 * Length of Authentication Management Field (AMF) in bytes. 
     118 */ 
    45119#define PJSIP_AKA_AMFLEN        2 
     120 
     121/** 
     122 * Length of AUTN in bytes. 
     123 */ 
    46124#define PJSIP_AKA_AUTNLEN       16 
     125 
     126/** 
     127 * Length of Confidentiality Key (CK) in bytes. 
     128 */ 
    47129#define PJSIP_AKA_CKLEN         16 
     130 
     131/** 
     132 * Length of Integrity Key (AK) in bytes. 
     133 */ 
    48134#define PJSIP_AKA_IKLEN         16 
     135 
     136/** 
     137 * Length of permanent/subscriber Key (K) in bytes. 
     138 */ 
    49139#define PJSIP_AKA_KLEN          16 
     140 
     141/** 
     142 * Length of AKA authentication code in bytes. 
     143 */ 
     144#define PJSIP_AKA_MACLEN        8 
     145 
     146/** 
     147 * Length of operator key in bytes. 
     148 */ 
    50149#define PJSIP_AKA_OPLEN         16 
     150 
     151/** 
     152 * Length of random challenge (RAND) in bytes. 
     153 */ 
    51154#define PJSIP_AKA_RANDLEN       16 
     155 
     156/** 
     157 * Length of response digest in bytes. 
     158 */ 
    52159#define PJSIP_AKA_RESLEN        8 
    53 #define PJSIP_AKA_MACLEN        8 
    54  
    55 /** 
    56  * This function creates MD5 AKAv1 response for the specified challenge 
    57  * in \a chal, based on the information in the credential \a cred. 
     160 
     161/** 
     162 * Length of sequence number (SQN) in bytes. 
     163 */ 
     164#define PJSIP_AKA_SQNLEN        6 
     165 
     166/** 
     167 * This function creates MD5, AKAv1-MD5, or AKAv2-MD5 response for 
     168 * the specified challenge in \a chal, according to the algorithm  
     169 * specified in the challenge, and based on the information in the  
     170 * credential \a cred. 
     171 * 
    58172 * Application may register this function as \a ext.aka.cb field of 
    59173 * #pjsip_cred_info structure to make PJSIP automatically call this 
    60  * function to calculate the response digest. 
     174 * function to calculate the response digest. To do so, it needs to 
     175 * add \a PJSIP_CRED_DATA_EXT_AKA flag in the \a data_type field of 
     176 * the credential, and fills up other AKA specific information in 
     177 * the credential. 
    61178 * 
    62179 * @param pool      Pool to allocate memory. 
    63180 * @param chal      The authentication challenge sent by server in 401 
    64  *                  or 401 response, in either Proxy-Authenticate or 
     181 *                  or 401 response, as either Proxy-Authenticate or 
    65182 *                  WWW-Authenticate header. 
    66  * @param cred      The credential that has been selected by the framework 
    67  *                  to authenticate against the challenge. 
     183 * @param cred      The credential to be used. 
    68184 * @param method    The request method. 
    69  * @param auth      The authentication credential where the digest response 
    70  *                  will be placed to. 
     185 * @param auth      The digest credential where the digest response 
     186 *                  will be placed to. Upon calling this function, the 
     187 *                  nonce, nc, cnonce, qop, uri, and realm fields of 
     188 *                  this structure must have been set by caller. Upon 
     189 *                  return, the \a response field will be initialized 
     190 *                  by this function. 
    71191 * 
    72192 * @return          PJ_SUCCESS if response has been created successfully. 
    73193 */ 
    74 PJ_DECL(pj_status_t) pjsip_auth_create_akav1(pj_pool_t *pool, 
     194PJ_DECL(pj_status_t) pjsip_auth_create_aka_response( 
     195                                             pj_pool_t *pool, 
    75196                                             const pjsip_digest_challenge*chal, 
    76197                                             const pjsip_cred_info *cred, 
  • pjproject/trunk/pjsip/include/pjsip/sip_config.h

    r1489 r1500  
    617617 
    618618/** 
    619  * Specify support for IMS/3GPP digest AKA authentication. 
    620  * 
    621  * Default: 0 (disabled for now) 
    622  */ 
    623 #ifndef PJSIP_HAS_DIGEST_AKAV1_AUTH 
    624 #   define PJSIP_HAS_DIGEST_AKAV1_AUTH      0 
     619 * Specify support for IMS/3GPP digest AKA authentication version 1 and 2 
     620 * (AKAv1-MD5 and AKAv2-MD5 respectively). 
     621 * 
     622 * Default: 0 (disabled, for now) 
     623 */ 
     624#ifndef PJSIP_HAS_DIGEST_AKA_AUTH 
     625#   define PJSIP_HAS_DIGEST_AKA_AUTH        0 
    625626#endif 
    626627 
  • pjproject/trunk/pjsip/src/pjsip/sip_auth_aka.c

    r1492 r1500  
    2121#include <pjlib-util/base64.h> 
    2222#include <pjlib-util/md5.h> 
     23#include <pjlib-util/hmac_md5.h> 
    2324#include <pj/assert.h> 
    2425#include <pj/log.h> 
     
    2627#include <pj/string.h> 
    2728 
    28 #if PJSIP_HAS_DIGEST_AKAV1_AUTH 
     29#if PJSIP_HAS_DIGEST_AKA_AUTH 
    2930 
    3031#include "../../third_party/milenage/milenage.h" 
     
    3334 * Create MD5-AKA1 digest response. 
    3435 */ 
    35 PJ_DEF(pj_status_t) pjsip_auth_create_akav1( pj_pool_t *pool, 
     36PJ_DEF(pj_status_t) pjsip_auth_create_aka_response(  
     37                                             pj_pool_t *pool, 
    3638                                             const pjsip_digest_challenge*chal, 
    3739                                             const pjsip_cred_info *cred, 
     
    4042{ 
    4143    pj_str_t nonce_bin; 
    42     pj_uint8_t *chal_rand, *chal_autn, *chal_mac; 
     44    int aka_version; 
     45    const pj_str_t pjsip_AKAv1_MD5 = { "AKAv1-MD5", 9 }; 
     46    const pj_str_t pjsip_AKAv2_MD5 = { "AKAv2-MD5", 9 }; 
     47    pj_uint8_t *chal_rand, *chal_sqnxoraka, *chal_mac; 
     48    pj_uint8_t k[PJSIP_AKA_KLEN]; 
     49    pj_uint8_t op[PJSIP_AKA_OPLEN]; 
     50    pj_uint8_t amf[PJSIP_AKA_AMFLEN]; 
    4351    pj_uint8_t res[PJSIP_AKA_RESLEN]; 
    4452    pj_uint8_t ck[PJSIP_AKA_CKLEN]; 
    4553    pj_uint8_t ik[PJSIP_AKA_IKLEN]; 
    4654    pj_uint8_t ak[PJSIP_AKA_AKLEN]; 
    47     pj_uint8_t sqn[PJSIP_AKA_AUTNLEN]; 
     55    pj_uint8_t sqn[PJSIP_AKA_SQNLEN]; 
    4856    pj_uint8_t xmac[PJSIP_AKA_MACLEN]; 
    4957    pjsip_cred_info aka_cred; 
     
    5260 
    5361    /* Check the algorithm is supported. */ 
    54     if (pj_stricmp2(&chal->algorithm, "md5") == 0) { 
     62    if (chal->algorithm.slen==0 || pj_stricmp2(&chal->algorithm, "md5") == 0) { 
     63        /* 
     64         * A normal MD5 authentication is requested. Fallbackt to the usual 
     65         * MD5 digest creation. 
     66         */ 
    5567        pjsip_auth_create_digest(&auth->response, &auth->nonce, &auth->nc, 
    5668                                 &auth->cnonce, &auth->qop, &auth->uri, 
     
    5870        return PJ_SUCCESS; 
    5971 
    60     } else if (pj_stricmp2(&chal->algorithm, "AKAv1-MD5") != 0) { 
     72    } else if (pj_stricmp(&chal->algorithm, &pjsip_AKAv1_MD5) == 0) { 
     73        /* 
     74         * AKA version 1 is requested. 
     75         */ 
     76        aka_version = 1; 
     77 
     78    } else if (pj_stricmp(&chal->algorithm, &pjsip_AKAv2_MD5) == 0) { 
     79        /* 
     80         * AKA version 2 is requested. 
     81         */ 
     82        aka_version = 2; 
     83 
     84    } else { 
    6185        /* Unsupported algorithm */ 
    6286        return PJSIP_EINVALIDALGORITHM; 
     
    7195        return PJSIP_EAUTHINNONCE; 
    7296 
    73     if (nonce_bin.slen < PJSIP_AKA_RANDLEN + PJSIP_AKA_AUTNLEN + PJSIP_AKA_MACLEN) 
     97    if (nonce_bin.slen < PJSIP_AKA_RANDLEN + PJSIP_AKA_AUTNLEN) 
    7498        return PJSIP_EAUTHINNONCE; 
    7599 
    76100    /* Get RAND, AUTN, and MAC */ 
    77     chal_rand = (pj_uint8_t*) (nonce_bin.ptr + 0); 
    78     chal_autn = (pj_uint8_t*) (nonce_bin.ptr + PJSIP_AKA_RANDLEN); 
    79     chal_mac =  (pj_uint8_t*) (nonce_bin.ptr + PJSIP_AKA_RANDLEN + PJSIP_AKA_AUTNLEN); 
     101    chal_rand = (pj_uint8_t*)(nonce_bin.ptr + 0); 
     102    chal_sqnxoraka = (pj_uint8_t*) (nonce_bin.ptr + PJSIP_AKA_RANDLEN); 
     103    chal_mac = (pj_uint8_t*) (nonce_bin.ptr + PJSIP_AKA_RANDLEN +  
     104                              PJSIP_AKA_SQNLEN + PJSIP_AKA_AMFLEN); 
    80105 
    81     /* Verify credential */ 
    82     PJ_ASSERT_RETURN(cred->ext.aka.k.slen == PJSIP_AKA_KLEN, PJSIP_EAUTHINAKACRED); 
    83     PJ_ASSERT_RETURN(cred->ext.aka.op.slen == PJSIP_AKA_OPLEN, PJSIP_EAUTHINAKACRED); 
     106    /* Copy k. op, and amf */ 
     107    pj_bzero(k, sizeof(k)); 
     108    pj_bzero(op, sizeof(op)); 
     109    pj_bzero(amf, sizeof(amf)); 
     110 
     111    if (cred->ext.aka.k.slen) 
     112        pj_memcpy(k, cred->ext.aka.k.ptr, cred->ext.aka.k.slen); 
     113    if (cred->ext.aka.op.slen) 
     114        pj_memcpy(op, cred->ext.aka.op.ptr, cred->ext.aka.op.slen); 
     115    if (cred->ext.aka.amf.slen) 
     116        pj_memcpy(amf, cred->ext.aka.amf.ptr, cred->ext.aka.amf.slen); 
    84117 
    85118    /* Given key K and random challenge RAND, compute response RES, 
    86119     * confidentiality key CK, integrity key IK and anonymity key AK. 
    87120     */ 
    88     f2345((pj_uint8_t*)cred->ext.aka.k.ptr,  
    89           chal_rand,  
    90           res, ck, ik, ak,  
    91           (pj_uint8_t*)cred->ext.aka.op.ptr); 
     121    f2345(k, chal_rand, res, ck, ik, ak, op); 
    92122 
    93123    /* Compute sequence number SQN */ 
    94     for (i=0; i<PJSIP_AKA_AUTNLEN; ++i) 
    95         sqn[i] = (pj_uint8_t) (chal_autn[i] ^ ak[i]); 
    96  
    97     /* Compute XMAC */ 
    98     f1((pj_uint8_t*)cred->ext.aka.k.ptr, chal_rand, sqn, 
    99        (pj_uint8_t*)cred->ext.aka.amf.ptr, xmac,  
    100        (pj_uint8_t*)cred->ext.aka.op.ptr); 
     124    for (i=0; i<PJSIP_AKA_SQNLEN; ++i) 
     125        sqn[i] = (pj_uint8_t) (chal_sqnxoraka[i] ^ ak[i]); 
    101126 
    102127    /* Verify MAC in the challenge */ 
     128    /* Compute XMAC */ 
     129    f1(k, chal_rand, sqn, amf, xmac, op); 
     130 
    103131    if (pj_memcmp(chal_mac, xmac, PJSIP_AKA_MACLEN) != 0) { 
    104132        return PJSIP_EAUTHINNONCE; 
     
    110138    pj_memcpy(&aka_cred, cred, sizeof(aka_cred)); 
    111139    aka_cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; 
    112     aka_cred.data.ptr = (char*)res; 
    113     aka_cred.data.slen = PJSIP_AKA_RESLEN; 
    114140 
    115141    /* Create a response */ 
    116     pjsip_auth_create_digest(&auth->response, &chal->nonce,  
    117                              &auth->nc, &auth->cnonce, &auth->qop, &auth->uri, 
    118                              &chal->realm, &aka_cred, method); 
     142    if (aka_version == 1) { 
     143        /* 
     144         * For AKAv1, the password is RES 
     145         */ 
     146        aka_cred.data.ptr = (char*)res; 
     147        aka_cred.data.slen = PJSIP_AKA_RESLEN; 
     148 
     149        pjsip_auth_create_digest(&auth->response, &chal->nonce,  
     150                                 &auth->nc, &auth->cnonce, &auth->qop,  
     151                                 &auth->uri, &chal->realm, &aka_cred, method); 
     152 
     153    } else if (aka_version == 2) { 
     154        /* 
     155         * For AKAv2, password is base64 encoded [1] parameters: 
     156         *    PRF(RES||IK||CK,"http-digest-akav2-password") 
     157         * 
     158         * The pseudo-random function (PRF) is HMAC-MD5 in this case. 
     159         */ 
     160        pj_hmac_md5_context ctx; 
     161        pj_uint8_t hmac_digest[16]; 
     162        char hmac_digest64[24]; 
     163        int out_len; 
     164 
     165        pj_hmac_md5_init(&ctx, (pj_uint8_t*)"http-digest-akav2-password", 26); 
     166        pj_hmac_md5_update(&ctx, res, PJSIP_AKA_RESLEN); 
     167        pj_hmac_md5_update(&ctx, ik, PJSIP_AKA_IKLEN); 
     168        pj_hmac_md5_update(&ctx, ck, PJSIP_AKA_CKLEN); 
     169        pj_hmac_md5_final(&ctx, hmac_digest); 
     170 
     171        out_len = sizeof(hmac_digest64); 
     172        status = pj_base64_encode(hmac_digest, 16, hmac_digest64, &out_len); 
     173        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
     174 
     175        aka_cred.data.ptr = hmac_digest64; 
     176        aka_cred.data.slen = out_len; 
     177 
     178        pjsip_auth_create_digest(&auth->response, &chal->nonce,  
     179                                 &auth->nc, &auth->cnonce, &auth->qop,  
     180                                 &auth->uri, &chal->realm, &aka_cred, method); 
     181 
     182    } else { 
     183        pj_assert(!"Bug!"); 
     184        return PJ_EBUG; 
     185    } 
    119186 
    120187    /* Done */ 
     
    123190 
    124191 
    125 #endif  /* PJSIP_HAS_DIGEST_AKAV1_AUTH */ 
     192#endif  /* PJSIP_HAS_DIGEST_AKA_AUTH */ 
    126193 
  • pjproject/trunk/pjsip/src/pjsip/sip_auth_client.c

    r1489 r1500  
    4949 
    5050 
     51static void dup_bin(pj_pool_t *pool, pj_str_t *dst, const pj_str_t *src) 
     52{ 
     53    dst->slen = src->slen; 
     54 
     55    if (dst->slen) { 
     56        dst->ptr = (char*) pj_pool_alloc(pool, src->slen); 
     57        pj_memcpy(dst->ptr, src->ptr, src->slen); 
     58    } else { 
     59        dst->ptr = NULL; 
     60    } 
     61} 
     62 
    5163PJ_DEF(void) pjsip_cred_info_dup(pj_pool_t *pool, 
    5264                                 pjsip_cred_info *dst, 
     
    6173 
    6274    if ((dst->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) { 
    63         pj_strdup(pool, &dst->ext.aka.k, &src->ext.aka.k); 
    64         pj_strdup(pool, &dst->ext.aka.op, &src->ext.aka.op); 
    65         pj_strdup(pool, &dst->ext.aka.amf, &src->ext.aka.amf); 
     75        dup_bin(pool, &dst->ext.aka.k, &src->ext.aka.k); 
     76        dup_bin(pool, &dst->ext.aka.op, &src->ext.aka.op); 
     77        dup_bin(pool, &dst->ext.aka.amf, &src->ext.aka.amf); 
    6678    } 
    6779} 
     
    223235                                   const pj_str_t *method) 
    224236{ 
    225     /* Check algorithm is supported. We only support MD5. */ 
    226     if (chal->algorithm.slen && pj_stricmp(&chal->algorithm, &pjsip_MD5_STR)) 
     237    const pj_str_t pjsip_AKAv1_MD5_STR = { "AKAv1-MD5", 9 }; 
     238 
     239    /* Check algorithm is supported. We support MD5 and AKAv1-MD5. */ 
     240    if (chal->algorithm.slen==0 || 
     241        (pj_stricmp(&chal->algorithm, &pjsip_MD5_STR) || 
     242         pj_stricmp(&chal->algorithm, &pjsip_AKAv1_MD5_STR))) 
    227243    { 
     244        ; 
     245    } 
     246    else { 
    228247        PJ_LOG(4,(THIS_FILE, "Unsupported digest algorithm \"%.*s\"", 
    229248                  chal->algorithm.slen, chal->algorithm.ptr)); 
     
    236255    pj_strdup(pool, &cred->nonce, &chal->nonce); 
    237256    pj_strdup(pool, &cred->uri, uri); 
    238     cred->algorithm = pjsip_MD5_STR; 
     257    pj_strdup(pool, &cred->algorithm, &chal->algorithm); 
    239258    pj_strdup(pool, &cred->opaque, &chal->opaque); 
    240      
     259 
    241260    /* Allocate memory. */ 
    242261    cred->response.ptr = (char*) pj_pool_alloc(pool, PJSIP_MD5STRLEN); 
     
    471490            if ((c[i].data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) { 
    472491 
    473 #if !PJSIP_HAS_DIGEST_AKAV1_AUTH 
    474                 pj_assert(!"PJSIP_HAS_DIGEST_AKAV1_AUTH is not enabled"); 
     492#if !PJSIP_HAS_DIGEST_AKA_AUTH 
     493                pj_assert(!"PJSIP_HAS_DIGEST_AKA_AUTH is not enabled"); 
    475494                return PJSIP_EAUTHINAKACRED; 
    476495#endif 
     
    480499 
    481500                /* Verify K len */ 
    482                 PJ_ASSERT_RETURN(c[i].ext.aka.k.slen == PJSIP_AKA_KLEN,  
     501                PJ_ASSERT_RETURN(c[i].ext.aka.k.slen <= PJSIP_AKA_KLEN,  
    483502                                 PJSIP_EAUTHINAKACRED); 
    484503 
    485504                /* Verify OP len */ 
    486                 PJ_ASSERT_RETURN(c[i].ext.aka.op.slen == PJSIP_AKA_OPLEN,  
     505                PJ_ASSERT_RETURN(c[i].ext.aka.op.slen <= PJSIP_AKA_OPLEN,  
    487506                                 PJSIP_EAUTHINAKACRED); 
    488507 
    489508                /* Verify AMF len */ 
    490                 PJ_ASSERT_RETURN(c[i].ext.aka.amf.slen == PJSIP_AKA_AMFLEN, 
     509                PJ_ASSERT_RETURN(c[i].ext.aka.amf.slen <= PJSIP_AKA_AMFLEN, 
    491510                                 PJSIP_EAUTHINAKACRED); 
    492511 
     
    793812                           &sent_auth->credential.common.realm )==0) 
    794813            { 
    795                 break; 
     814                /* If this authorization has empty response, remove it. */ 
     815                if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 && 
     816                    sent_auth->credential.digest.response.slen == 0) 
     817                { 
     818                    /* This is empty authorization, remove it. */ 
     819                    hdr = hdr->next; 
     820                    pj_list_erase(sent_auth); 
     821                    continue; 
     822                } else { 
     823                    /* Found previous authorization attempt */ 
     824                    break; 
     825                } 
    796826            } 
    797827        } 
  • pjproject/trunk/pjsip/src/pjsip/sip_auth_msg.c

    r1417 r1500  
    7272    copy_advance_pair_quote_cond(buf, "username=", 9, cred->username, '"', '"'); 
    7373    copy_advance_pair_quote_cond(buf, ", realm=", 8, cred->realm, '"', '"'); 
    74     copy_advance_pair_quote_cond(buf, ", nonce=", 8, cred->nonce, '"', '"'); 
     74    copy_advance_pair_quote(buf, ", nonce=", 8, cred->nonce, '"', '"'); 
    7575    copy_advance_pair_quote_cond(buf, ", uri=", 6, cred->uri, '"', '"'); 
    76     copy_advance_pair_quote_cond(buf, ", response=", 11, cred->response, '"', '"'); 
     76    copy_advance_pair_quote(buf, ", response=", 11, cred->response, '"', '"'); 
    7777    copy_advance_pair(buf, ", algorithm=", 12, cred->algorithm); 
    7878    copy_advance_pair_quote_cond(buf, ", cnonce=", 9, cred->cnonce, '"', '"'); 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c

    r1454 r1500  
    737737        status = pjsip_regc_register(pjsua_var.acc[acc_id].regc, 1,  
    738738                                     &tdata); 
     739 
     740        if (0 && status == PJ_SUCCESS && pjsua_var.acc[acc_id].cred_cnt) { 
     741            pjsua_acc *acc = &pjsua_var.acc[acc_id]; 
     742            pjsip_authorization_hdr *h; 
     743            char *uri; 
     744            int d; 
     745 
     746            uri = (char*) pj_pool_alloc(tdata->pool, acc->cfg.reg_uri.slen+10); 
     747            d = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, tdata->msg->line.req.uri, 
     748                                uri, acc->cfg.reg_uri.slen+10); 
     749            pj_assert(d > 0); 
     750 
     751            h = pjsip_authorization_hdr_create(tdata->pool); 
     752            h->scheme = pj_str("Digest"); 
     753            h->credential.digest.username = acc->cred[0].username; 
     754            h->credential.digest.realm = acc->srv_domain; 
     755            h->credential.digest.uri = pj_str(uri); 
     756            h->credential.digest.algorithm = pj_str("md5"); 
     757 
     758            pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)h); 
     759        } 
    739760 
    740761    } else { 
  • pjproject/trunk/third_party/build/milenage

    • Property svn:ignore
      •  

        old new  
        33*.vco 
        44*.depend 
         5*.plg 
Note: See TracChangeset for help on using the changeset viewer.