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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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); 
Note: See TracChangeset for help on using the changeset viewer.