Changeset 1488


Ignore:
Timestamp:
Oct 10, 2007 11:37:56 AM (12 years ago)
Author:
bennylp
Message:

Ticket #396: initial implementation of digest AKA (akav1-md5) authentication for IMS/3GPP

Location:
pjproject/trunk
Files:
15 added
19 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/build/Makefile

    r1349 r1488  
    2828export PJLIB_UTIL_SRCDIR = ../src/pjlib-util 
    2929export PJLIB_UTIL_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ 
    30                 crc32.o errno.o dns.o dns_dump.o getopt.o \ 
     30                base64.o crc32.o errno.o dns.o dns_dump.o getopt.o \ 
    3131                hmac_md5.o hmac_sha1.o md5.o resolver.o \ 
    3232                scanner.o sha1.o srv_resolver.o string.o stun_simple.o \ 
  • pjproject/trunk/pjlib-util/build/pjlib_util.dsp

    r1102 r1488  
    4141# PROP Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-release" 
    4242# PROP Target_Dir "" 
     43F90=df.exe 
    4344# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 
    4445# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c 
     
    6566# PROP Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-debug" 
    6667# PROP Target_Dir "" 
     68F90=df.exe 
    6769# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 
    6870# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c 
     
    8890# Begin Source File 
    8991 
     92SOURCE="..\src\pjlib-util\base64.c" 
     93# End Source File 
     94# Begin Source File 
     95 
    9096SOURCE="..\src\pjlib-util\crc32.c" 
    9197# End Source File 
     
    168174 
    169175# PROP Default_Filter "h;hpp;hxx;hm;inl" 
     176# Begin Source File 
     177 
     178SOURCE="..\include\pjlib-util\base64.h" 
     179# End Source File 
    170180# Begin Source File 
    171181 
  • pjproject/trunk/pjlib-util/src/pjlib-util-test/encryption.c

    r1266 r1488  
    466466 
    467467 
     468/* 
     469 * Base64 test vectors (RFC 4648) 
     470 */ 
     471static struct base64_test_vec 
     472{ 
     473    const char *base256; 
     474    const char *base64; 
     475} base64_test_vec[] =  
     476{ 
     477    { 
     478        "", 
     479        "" 
     480    }, 
     481    { 
     482        "f", 
     483        "Zg==" 
     484    }, 
     485    { 
     486        "fo", 
     487        "Zm8=" 
     488    }, 
     489    { 
     490        "foo", 
     491        "Zm9v" 
     492    }, 
     493    { 
     494        "foob", 
     495        "Zm9vYg==" 
     496    }, 
     497    { 
     498        "fooba", 
     499        "Zm9vYmE=", 
     500    }, 
     501    { 
     502        "foobar", 
     503        "Zm9vYmFy" 
     504    }, 
     505    { 
     506        "\x14\xfb\x9c\x03\xd9\x7e", 
     507        "FPucA9l+" 
     508    }, 
     509    { 
     510        "\x14\xfb\x9c\x03\xd9", 
     511        "FPucA9k=" 
     512    }, 
     513    { 
     514        "\x14\xfb\x9c\x03", 
     515        "FPucAw==" 
     516    } 
     517}; 
     518 
     519 
     520static int base64_test(void) 
     521{ 
     522    unsigned i; 
     523    char output[80]; 
     524    pj_status_t rc; 
     525 
     526    PJ_LOG(3, (THIS_FILE, "  base64 test..")); 
     527 
     528    for (i=0; i<PJ_ARRAY_SIZE(base64_test_vec); ++i) { 
     529        /* Encode test */ 
     530        pj_str_t input; 
     531        int out_len = sizeof(output); 
     532 
     533        rc = pj_base64_encode(base64_test_vec[i].base256,  
     534                              strlen(base64_test_vec[i].base256), 
     535                              output, &out_len); 
     536        if (rc != PJ_SUCCESS) 
     537            return -90; 
     538 
     539        if (out_len != strlen(base64_test_vec[i].base64)) 
     540            return -91; 
     541 
     542        output[out_len] = '\0'; 
     543        if (strcmp(output, base64_test_vec[i].base64) != 0) 
     544            return -92; 
     545 
     546        /* Decode test */ 
     547        out_len = sizeof(output); 
     548        input.ptr = base64_test_vec[i].base64; 
     549        input.slen = strlen(base64_test_vec[i].base64); 
     550        rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len); 
     551        if (rc != PJ_SUCCESS) 
     552            return -95; 
     553 
     554        if (out_len != strlen(base64_test_vec[i].base256)) 
     555            return -96; 
     556 
     557        output[out_len] = '\0'; 
     558 
     559        if (strcmp(output, base64_test_vec[i].base256) != 0) 
     560            return -97; 
     561    } 
     562 
     563    return 0; 
     564} 
     565 
     566 
    468567int encryption_test() 
    469568{ 
    470569    int rc; 
     570 
     571    rc = base64_test(); 
     572    if (rc != 0) 
     573        return rc; 
    471574 
    472575    rc = sha1_test1(); 
  • pjproject/trunk/pjproject-vs8.sln

    r1368 r1488  
    2929Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pjsua", "pjsip-apps\build\pjsua.vcproj", "{8310649E-A25E-4AF0-91E8-9E3CC659BB89}" 
    3030        ProjectSection(ProjectDependencies) = postProject 
     31                {2BB84911-C1B4-4747-B93D-36AA82CC5031} = {2BB84911-C1B4-4747-B93D-36AA82CC5031} 
     32                {4BF51C21-5A30-423B-82FE-1ED410E5769D} = {4BF51C21-5A30-423B-82FE-1ED410E5769D} 
    3133                {E53AA5FF-B737-40AA-BD13-387EFA99023D} = {E53AA5FF-B737-40AA-BD13-387EFA99023D} 
    3234                {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} = {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} 
     
    4244                {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} 
    4345                {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} 
    44                 {2BB84911-C1B4-4747-B93D-36AA82CC5031} = {2BB84911-C1B4-4747-B93D-36AA82CC5031} 
    4546        EndProjectSection 
    4647EndProject 
     
    4950Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_debug", "pjsip-apps\build\sample_debug.vcproj", "{A0F1AA62-0F6F-420D-B09A-AC04B6862821}" 
    5051        ProjectSection(ProjectDependencies) = postProject 
    51                 {2BB84911-C1B4-4747-B93D-36AA82CC5031} = {2BB84911-C1B4-4747-B93D-36AA82CC5031} 
    52                 {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} 
    5352                {E53AA5FF-B737-40AA-BD13-387EFA99023D} = {E53AA5FF-B737-40AA-BD13-387EFA99023D} 
    5453                {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} = {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} 
     
    6362                {6794B975-4E84-4F49-B2DC-C31F2224E03E} = {6794B975-4E84-4F49-B2DC-C31F2224E03E} 
    6463                {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} 
     64                {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} 
     65                {2BB84911-C1B4-4747-B93D-36AA82CC5031} = {2BB84911-C1B4-4747-B93D-36AA82CC5031} 
    6566        EndProjectSection 
    6667EndProject 
     
    102103EndProject 
    103104Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libresample_dll", "third_party\build\resample\libresample_dll.vcproj", "{C48EAAF5-F69E-410B-9CE4-23AB41B00E2A}" 
     105EndProject 
     106Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmilenage", "third_party\build\milenage\libmilenage.vcproj", "{4BF51C21-5A30-423B-82FE-1ED410E5769D}" 
    104107EndProject 
    105108Global 
     
    193196                {C48EAAF5-F69E-410B-9CE4-23AB41B00E2A}.Release|Win32.ActiveCfg = Release|Win32 
    194197                {C48EAAF5-F69E-410B-9CE4-23AB41B00E2A}.Release|Win32.Build.0 = Release|Win32 
     198                {4BF51C21-5A30-423B-82FE-1ED410E5769D}.Debug|Win32.ActiveCfg = Debug|Win32 
     199                {4BF51C21-5A30-423B-82FE-1ED410E5769D}.Debug|Win32.Build.0 = Debug|Win32 
     200                {4BF51C21-5A30-423B-82FE-1ED410E5769D}.Release|Win32.ActiveCfg = Release|Win32 
     201                {4BF51C21-5A30-423B-82FE-1ED410E5769D}.Release|Win32.Build.0 = Release|Win32 
    195202        EndGlobalSection 
    196203        GlobalSection(SolutionProperties) = preSolution 
  • pjproject/trunk/pjproject.dsw

    r1368 r1488  
    2828############################################################################### 
    2929 
     30Project: "libmilenage"=.\third_party\build\milenage\libmilenage.dsp - Package Owner=<4> 
     31 
     32Package=<5> 
     33{{{ 
     34}}} 
     35 
     36Package=<4> 
     37{{{ 
     38}}} 
     39 
     40############################################################################### 
     41 
    3042Project: "libportaudio"=.\THIRD_PARTY\BUILD\PORTAUDIO\libportaudio.dsp - Package Owner=<4> 
    3143 
     
    255267    Project_Dep_Name libresample 
    256268    End Project Dependency 
     269    Begin Project Dependency 
     270    Project_Dep_Name libmilenage 
     271    End Project Dependency 
    257272}}} 
    258273 
  • pjproject/trunk/pjsip-apps/build/wince-evc4/wince_demos.vcw

    r1478 r1488  
    2828############################################################################### 
    2929 
     30Project: "libmilenage"="..\..\..\third_party\build\milenage\libmilenage.vcp" - Package Owner=<4> 
     31 
     32Package=<5> 
     33{{{ 
     34}}} 
     35 
     36Package=<4> 
     37{{{ 
     38}}} 
     39 
     40############################################################################### 
     41 
    3042Project: "libportaudio"="..\..\..\THIRD_PARTY\BUILD\PORTAUDIO\libportaudio.vcp" - Package Owner=<4> 
    3143 
     
    243255    Project_Dep_Name libspeex 
    244256    End Project Dependency 
     257    Begin Project Dependency 
     258    Project_Dep_Name libmilenage 
     259    End Project Dependency 
    245260}}} 
    246261 
  • pjproject/trunk/pjsip/build/pjsip_core.dsp

    r1473 r1488  
    165165# Begin Source File 
    166166 
     167SOURCE=..\src\pjsip\sip_auth_aka.c 
     168# End Source File 
     169# Begin Source File 
     170 
    167171SOURCE=..\src\pjsip\sip_auth_client.c 
    168172# End Source File 
     
    309313# Begin Source File 
    310314 
     315SOURCE=..\include\pjsip\sip_auth_aka.h 
     316# End Source File 
     317# Begin Source File 
     318 
    311319SOURCE=..\include\pjsip\sip_auth_msg.h 
    312320# End Source File 
  • pjproject/trunk/pjsip/include/pjsip.h

    r974 r1488  
    4646/* Authentication. */ 
    4747#include <pjsip/sip_auth.h> 
     48#include <pjsip/sip_auth_aka.h> 
    4849 
    4950/* Transaction layer. */ 
  • pjproject/trunk/pjsip/include/pjsip/sip_auth.h

    r1407 r1488  
    4747 
    4848 
    49 /** Type of data in the credential information. */ 
     49/** Type of data in the credential information in #pjsip_cred_info. */ 
    5050typedef enum pjsip_cred_data_type 
    5151{ 
    52     PJSIP_CRED_DATA_PLAIN_PASSWD,   /**< Plain text password.   */ 
    53     PJSIP_CRED_DATA_DIGEST          /**< Hashed digest.         */ 
     52    PJSIP_CRED_DATA_PLAIN_PASSWD=0, /**< Plain text password.           */ 
     53    PJSIP_CRED_DATA_DIGEST      =1, /**< Hashed digest.                 */ 
     54 
     55    PJSIP_CRED_DATA_EXT_AKA     =16 /**< Extended AKA info is available */ 
     56 
    5457} pjsip_cred_data_type; 
    5558 
     
    6467 
    6568 
     69/** 
     70 * Type of callback function to create authentication response. 
     71 * Application can specify this callback in \a cb field of the credential info 
     72 * (#pjsip_cred_info) and specifying PJSIP_CRED_DATA_DIGEST_CALLBACK as  
     73 * \a data_type. When this function is called, most of the fields in the  
     74 * \a auth authentication response will have been filled by the framework.  
     75 * Application normally should just need to calculate the response digest  
     76 * of the authentication response. 
     77 * 
     78 * @param pool      Pool to allocate memory from if application needs to. 
     79 * @param chal      The authentication challenge sent by server in 401 
     80 *                  or 401 response, in either Proxy-Authenticate or 
     81 *                  WWW-Authenticate header. 
     82 * @param cred      The credential that has been selected by the framework 
     83 *                  to authenticate against the challenge. 
     84 * @param auth      The authentication response which application needs to 
     85 *                  calculate the response digest. 
     86 * 
     87 * @return          Application may return non-PJ_SUCCESS to abort the 
     88 *                  authentication process. When this happens, the  
     89 *                  framework will return failure to the original function 
     90 *                  that requested authentication. 
     91 */ 
     92typedef pj_status_t (*pjsip_cred_cb)(pj_pool_t *pool, 
     93                                     const pjsip_digest_challenge *chal, 
     94                                     const pjsip_cred_info *cred, 
     95                                     const pj_str_t *method, 
     96                                     pjsip_digest_credential *auth); 
     97 
     98 
    6699/**  
    67100 * This structure describes credential information.  
     
    70103 * 
    71104 * Note that since PJSIP 0.7.0.1, it is possible to make a credential that is 
    72  * valid for any realms, by setting the realm to star/asterisk character, 
     105 * valid for any realms, by setting the realm to star/wildcard character, 
    73106 * i.e. realm = pj_str("*");. 
    74107 */ 
     
    83116    pj_str_t    data;           /**< The data, which can be a plaintext  
    84117                                     password or a hashed digest.           */ 
     118 
     119    /** Extended data */ 
     120    union { 
     121        /** Digest AKA credential information. Note that when AKA credential 
     122         *  is being used, the \a data field of this #pjsip_cred_info is 
     123         *  not used, but it still must be initialized to an empty string. 
     124         */ 
     125        struct { 
     126            pj_str_t      k;    /**< Permanent key.                     */ 
     127            pj_str_t      op;   /**< Operator variant key.              */ 
     128            pj_str_t      amf;  /**< Authentication Management Field    */ 
     129            pjsip_cred_cb cb;   /**< Callback to create AKA digest.     */ 
     130        } aka; 
     131 
     132    } ext; 
    85133}; 
    86134 
     
    151199 
    152200/** 
     201 * Duplicate a credential info. 
     202 * 
     203 * @param pool      The memory pool. 
     204 * @param dst       Destination credential. 
     205 * @param src       Source credential. 
     206 */ 
     207PJ_DECL(void) pjsip_cred_info_dup(pj_pool_t *pool, 
     208                                  pjsip_cred_info *dst, 
     209                                  const pjsip_cred_info *src); 
     210 
     211/** 
    153212 * Type of function to lookup credential for the specified name. 
    154213 * 
     
    350409                                               pjsip_tx_data *tdata); 
    351410 
     411/** 
     412 * Helper function to create MD5 digest out of the specified  
     413 * parameters. 
     414 * 
     415 * @param result        String to store the response digest. This string 
     416 *                      must have been preallocated by caller with the  
     417 *                      buffer at least PJSIP_MD5STRLEN (32 bytes) in size. 
     418 * @param nonce         Optional nonce. 
     419 * @param nc            Nonce count. 
     420 * @param cnonce        Optional cnonce. 
     421 * @param qop           Optional qop. 
     422 * @param uri           URI. 
     423 * @param realm         Realm. 
     424 * @param cred_info     Credential info. 
     425 * @param method        SIP method. 
     426 */ 
     427PJ_DECL(void) pjsip_auth_create_digest(pj_str_t *result, 
     428                                       const pj_str_t *nonce, 
     429                                       const pj_str_t *nc, 
     430                                       const pj_str_t *cnonce, 
     431                                       const pj_str_t *qop, 
     432                                       const pj_str_t *uri, 
     433                                       const pj_str_t *realm, 
     434                                       const pjsip_cred_info *cred_info, 
     435                                       const pj_str_t *method); 
    352436 
    353437/** 
     
    355439 */ 
    356440 
    357 /* Internal function defined in sip_auth_client.c */ 
    358 void pjsip_auth_create_digest( pj_str_t *result, 
    359                                const pj_str_t *nonce, 
    360                                const pj_str_t *nc, 
    361                                const pj_str_t *cnonce, 
    362                                const pj_str_t *qop, 
    363                                const pj_str_t *uri, 
    364                                const pj_str_t *realm, 
    365                                const pjsip_cred_info *cred_info, 
    366                                const pj_str_t *method); 
    367  
    368441 
    369442 
  • pjproject/trunk/pjsip/include/pjsip/sip_errno.h

    r1417 r1488  
    382382 */ 
    383383#define PJSIP_EAUTHSTALECOUNT   (PJSIP_ERRNO_START_PJSIP + 111) /* 171111 */ 
     384/** 
     385 * @hideinitializer 
     386 * Invalid nonce value in the challenge. 
     387 */ 
     388#define PJSIP_EAUTHINNONCE      (PJSIP_ERRNO_START_PJSIP + 112) /* 171112 */ 
     389/** 
     390 * @hideinitializer 
     391 * Invalid AKA credential. 
     392 */ 
     393#define PJSIP_EAUTHINAKACRED    (PJSIP_ERRNO_START_PJSIP + 113) /* 171113 */ 
    384394 
    385395 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r1482 r1488  
    10301030 
    10311031 
    1032 /** 
    1033  * Duplicate credential. 
    1034  * 
    1035  * @param pool      The memory pool. 
    1036  * @param dst       Destination credential. 
    1037  * @param src       Source credential. 
    1038  * 
    1039  * \par Python: 
    1040  * Not applicable (for now). Probably we could just assign one credential 
    1041  * variable to another, but this has not been tested. 
    1042  */ 
    1043 PJ_DECL(void) pjsip_cred_dup( pj_pool_t *pool, 
    1044                               pjsip_cred_info *dst, 
    1045                               const pjsip_cred_info *src); 
     1032/* The implementation has been moved to sip_auth.h */ 
     1033#define pjsip_cred_dup  pjsip_cred_info_dup 
    10461034 
    10471035 
  • pjproject/trunk/pjsip/src/pjsip/sip_auth_client.c

    r1370 r1488  
    2020#include <pjsip/sip_auth.h> 
    2121#include <pjsip/sip_auth_parser.h>      /* just to get pjsip_DIGEST_STR */ 
     22#include <pjsip/sip_auth_aka.h> 
    2223#include <pjsip/sip_transport.h> 
    2324#include <pjsip/sip_endpoint.h> 
     
    4445#endif 
    4546 
     47#define PASSWD_MASK         0x000F 
     48#define EXT_MASK            0x00F0 
     49 
     50 
     51PJ_DEF(void) pjsip_cred_info_dup(pj_pool_t *pool, 
     52                                 pjsip_cred_info *dst, 
     53                                 const pjsip_cred_info *src) 
     54{ 
     55    pj_memcpy(dst, src, sizeof(pjsip_cred_info)); 
     56 
     57    pj_strdup_with_null(pool, &dst->realm, &src->realm); 
     58    pj_strdup_with_null(pool, &dst->scheme, &src->scheme); 
     59    pj_strdup_with_null(pool, &dst->username, &src->username); 
     60    pj_strdup_with_null(pool, &dst->data, &src->data); 
     61 
     62    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); 
     66    } 
     67} 
     68 
    4669 
    4770/* Transform digest to string. 
     
    6487 * digest ASCII in 'result'.  
    6588 */ 
    66 void pjsip_auth_create_digest( pj_str_t *result, 
    67                                const pj_str_t *nonce, 
    68                                const pj_str_t *nc, 
    69                                const pj_str_t *cnonce, 
    70                                const pj_str_t *qop, 
    71                                const pj_str_t *uri, 
    72                                const pj_str_t *realm, 
    73                                const pjsip_cred_info *cred_info, 
    74                                const pj_str_t *method) 
     89PJ_DEF(void) pjsip_auth_create_digest( pj_str_t *result, 
     90                                       const pj_str_t *nonce, 
     91                                       const pj_str_t *nc, 
     92                                       const pj_str_t *cnonce, 
     93                                       const pj_str_t *qop, 
     94                                       const pj_str_t *uri, 
     95                                       const pj_str_t *realm, 
     96                                       const pjsip_cred_info *cred_info, 
     97                                       const pj_str_t *method) 
    7598{ 
    7699    char ha1[PJSIP_MD5STRLEN]; 
     
    83106    AUTH_TRACE_((THIS_FILE, "Begin creating digest")); 
    84107 
    85     if (cred_info->data_type == PJSIP_CRED_DATA_PLAIN_PASSWD) { 
     108    if ((cred_info->data_type & PASSWD_MASK) == PJSIP_CRED_DATA_PLAIN_PASSWD) { 
    86109        /***  
    87110         *** ha1 = MD5(username ":" realm ":" password)  
     
    97120        digest2str(digest, ha1); 
    98121 
    99     } else if (cred_info->data_type == PJSIP_CRED_DATA_DIGEST) { 
     122    } else if ((cred_info->data_type & PASSWD_MASK) == PJSIP_CRED_DATA_DIGEST) { 
    100123        pj_assert(cred_info->data.slen == 32); 
    101124        pj_memcpy( ha1, cred_info->data.ptr, cred_info->data.slen ); 
     125    } else { 
     126        pj_assert(!"Invalid data_type"); 
    102127    } 
    103128 
     
    221246        /* Server doesn't require quality of protection. */ 
    222247 
    223         /* Convert digest to string and store in chal->response. */ 
    224         pjsip_auth_create_digest( &cred->response, &cred->nonce, NULL, NULL,  
    225                                   NULL, uri, &chal->realm, cred_info, method); 
     248        if ((cred_info->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) { 
     249            /* Call application callback to create the response digest */ 
     250            return (*cred_info->ext.aka.cb)(pool, chal, cred_info,  
     251                                            method, cred); 
     252        }  
     253        else { 
     254            /* Convert digest to string and store in chal->response. */ 
     255            pjsip_auth_create_digest( &cred->response, &cred->nonce, NULL,  
     256                                      NULL,  NULL, uri, &chal->realm,  
     257                                      cred_info, method); 
     258        } 
    226259 
    227260    } else if (has_auth_qop(pool, &chal->qop)) { 
     
    240273        } 
    241274 
    242         pjsip_auth_create_digest( &cred->response, &cred->nonce, &cred->nc,  
    243                                   cnonce, &pjsip_AUTH_STR, uri, &chal->realm,  
    244                                   cred_info, method ); 
     275        if ((cred_info->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) { 
     276            /* Call application callback to create the response digest */ 
     277            return (*cred_info->ext.aka.cb)(pool, chal, cred_info,  
     278                                            method, cred); 
     279        } 
     280        else { 
     281            pjsip_auth_create_digest( &cred->response, &cred->nonce,  
     282                                      &cred->nc, cnonce, &pjsip_AUTH_STR,  
     283                                      uri, &chal->realm, cred_info, method ); 
     284        } 
    245285 
    246286    } else { 
     
    425465        for (i=0; i<cred_cnt; ++i) { 
    426466            sess->cred_info[i].data_type = c[i].data_type; 
     467 
     468            /* When data_type is PJSIP_CRED_DATA_EXT_AKA,  
     469             * callback must be specified. 
     470             */ 
     471            if ((c[i].data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) { 
     472                /* Callback must be specified */ 
     473                PJ_ASSERT_RETURN(c[i].ext.aka.cb != NULL, PJ_EINVAL); 
     474 
     475                /* Verify K len */ 
     476                PJ_ASSERT_RETURN(c[i].ext.aka.k.slen == PJSIP_AKA_KLEN,  
     477                                 PJSIP_EAUTHINAKACRED); 
     478 
     479                /* Verify OP len */ 
     480                PJ_ASSERT_RETURN(c[i].ext.aka.op.slen == PJSIP_AKA_OPLEN,  
     481                                 PJSIP_EAUTHINAKACRED); 
     482 
     483                /* Verify AMF len */ 
     484                PJ_ASSERT_RETURN(c[i].ext.aka.amf.slen == PJSIP_AKA_AMFLEN, 
     485                                 PJSIP_EAUTHINAKACRED); 
     486 
     487                sess->cred_info[i].ext.aka.cb = c[i].ext.aka.cb; 
     488                pj_strdup(sess->pool, &sess->cred_info[i].ext.aka.k, 
     489                          &c[i].ext.aka.k); 
     490                pj_strdup(sess->pool, &sess->cred_info[i].ext.aka.op, 
     491                          &c[i].ext.aka.op); 
     492                pj_strdup(sess->pool, &sess->cred_info[i].ext.aka.amf, 
     493                          &c[i].ext.aka.amf); 
     494            } 
     495 
    427496            pj_strdup(sess->pool, &sess->cred_info[i].scheme, &c[i].scheme); 
    428497            pj_strdup(sess->pool, &sess->cred_info[i].realm, &c[i].realm); 
  • pjproject/trunk/pjsip/src/pjsip/sip_errno.c

    r1382 r1488  
    103103    PJ_BUILD_ERR( PJSIP_EAUTHINVALIDDIGEST,"Invalid authorization digest" ), 
    104104    PJ_BUILD_ERR( PJSIP_EAUTHSTALECOUNT,   "Maximum number of stale retries exceeded"), 
     105    PJ_BUILD_ERR( PJSIP_EAUTHINNONCE,      "Invalid nonce value in authentication challenge"), 
     106    PJ_BUILD_ERR( PJSIP_EAUTHINAKACRED,    "Invalid AKA credential"), 
    105107 
    106108    /* UA/dialog layer. */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c

    r1482 r1488  
    8080    cfg->max_calls = 4; 
    8181    cfg->thread_cnt = 1; 
    82 } 
    83  
    84 PJ_DEF(void) pjsip_cred_dup( pj_pool_t *pool, 
    85                              pjsip_cred_info *dst, 
    86                              const pjsip_cred_info *src) 
    87 { 
    88     pj_strdup_with_null(pool, &dst->realm, &src->realm); 
    89     pj_strdup_with_null(pool, &dst->scheme, &src->scheme); 
    90     pj_strdup_with_null(pool, &dst->username, &src->username); 
    91     pj_strdup_with_null(pool, &dst->data, &src->data); 
    9282} 
    9383 
  • pjproject/trunk/third_party/README.txt

    r1177 r1488  
    1616gsm:            gsm-1.0.12 
    1717ilbc:           from RFC 
    18 plc_steveu:     Steve Underwood's PLC 
    1918resample:       lib-resample, I think version 1.7 
  • pjproject/trunk/third_party/build/Makefile

    r1275 r1488  
    1 DIRS = resample 
     1DIRS = resample milenage 
    22 
    33include ../../build.mak 
  • pjproject/trunk/third_party/build/os-darwinos.mak

    r1202 r1488  
    1 DIRS = resample 
    21DIRS += gsm 
    32DIRS += ilbc 
  • pjproject/trunk/third_party/build/os-linux.mak

    r1202 r1488  
    1 DIRS = resample 
    21DIRS += gsm 
    32DIRS += ilbc 
  • pjproject/trunk/third_party/build/os-win32.mak

    r1202 r1488  
    1 DIRS = resample 
    21DIRS += gsm 
    32DIRS += ilbc 
Note: See TracChangeset for help on using the changeset viewer.