Ignore:
Timestamp:
May 15, 2007 10:42:56 AM (17 years ago)
Author:
bennylp
Message:

Fixed several STUN bugs: USERNAME, REALM etc are not allowed in the response, retransmission timer calculation bug, etc.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/src/pjnath/stun_auth.c

    r1265 r1275  
    105105 
    106106 
    107 /* Verify credential */ 
    108 PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt, 
    109                                                unsigned pkt_len, 
    110                                                const pj_stun_msg *msg, 
    111                                                pj_stun_auth_cred *cred, 
    112                                                pj_pool_t *pool, 
    113                                                pj_stun_msg **p_response) 
     107/* Verify credential in the request */ 
     108PJ_DEF(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt, 
     109                                                 unsigned pkt_len, 
     110                                                 const pj_stun_msg *msg, 
     111                                                 pj_stun_auth_cred *cred, 
     112                                                 pj_pool_t *pool, 
     113                                                 pj_stun_msg **p_response) 
    114114{ 
    115115    pj_str_t realm, nonce, password; 
     
    122122    pj_hmac_sha1_context ctx; 
    123123    pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE]; 
    124     pj_uint8_t md5_digest[16]; 
    125124    pj_str_t key; 
    126125    pj_status_t status; 
     
    225224 
    226225        /* NONCE must be present. */ 
    227         if (anonce == NULL) { 
     226        if (anonce == NULL && nonce.slen) { 
    228227            if (p_response) { 
    229228                create_challenge(pool, msg, PJ_STUN_SC_MISSING_NONCE,  
     
    320319    } 
    321320 
    322     /* Determine which key to use */ 
    323     if (realm.slen) { 
    324         pj_stun_calc_md5_key(md5_digest, &realm, &auser->value, &password); 
    325         key.ptr = (char*)md5_digest; 
    326         key.slen = 16; 
    327     } else { 
    328         key = password; 
    329     } 
     321    /* Calculate key */ 
     322    pj_stun_create_key(pool, &key, &realm, &auser->value, &password); 
    330323 
    331324    /* Now calculate HMAC of the message, adding zero padding if necessary 
     
    334327    pj_hmac_sha1_init(&ctx, (pj_uint8_t*)key.ptr, key.slen); 
    335328    pj_hmac_sha1_update(&ctx, pkt, amsgi_pos); 
    336     if (amsgi_pos & 0x3F) { 
     329    if (amsgi_pos & 63) { 
    337330        pj_uint8_t zeroes[64]; 
    338331        pj_bzero(zeroes, sizeof(zeroes)); 
    339         pj_hmac_sha1_update(&ctx, zeroes, 64-(amsgi_pos & 0x3F)); 
     332        pj_hmac_sha1_update(&ctx, zeroes, 64-(amsgi_pos & 63)); 
    340333    } 
    341334    pj_hmac_sha1_final(&ctx, digest); 
     
    356349 
    357350 
     351/* Authenticate MESSAGE-INTEGRITY in the response */ 
     352PJ_DEF(pj_status_t) pj_stun_authenticate_response(const pj_uint8_t *pkt, 
     353                                                  unsigned pkt_len, 
     354                                                  const pj_stun_msg *msg, 
     355                                                  const pj_str_t *key) 
     356{ 
     357    const pj_stun_msgint_attr *amsgi; 
     358    unsigned amsgi_pos; 
     359    pj_hmac_sha1_context ctx; 
     360    pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE]; 
     361 
     362    PJ_ASSERT_RETURN(pkt && pkt_len && msg && key, PJ_EINVAL); 
     363 
     364    /* First check that MESSAGE-INTEGRITY is present */ 
     365    amsgi = (const pj_stun_msgint_attr*) 
     366            pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 0); 
     367    if (amsgi == NULL) { 
     368        return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_INTEGRITY_CHECK_FAILURE); 
     369    } 
     370 
     371 
     372    /* Check that message length is valid */ 
     373    if (msg->hdr.length < 24) { 
     374        return PJNATH_EINSTUNMSGLEN; 
     375    } 
     376 
     377    /* Get the position of MESSAGE-INTEGRITY in the packet */ 
     378    amsgi_pos = 20+msg->hdr.length-24; 
     379    if (GET_VAL16(pkt, amsgi_pos) == PJ_STUN_ATTR_MESSAGE_INTEGRITY) { 
     380        /* Found MESSAGE-INTEGRITY as the last attribute */ 
     381    } else { 
     382        amsgi_pos = 0; 
     383    } 
     384     
     385    if (amsgi_pos==0) { 
     386        /* Check that message length is valid */ 
     387        if (msg->hdr.length < 32) { 
     388            return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_INTEGRITY_CHECK_FAILURE); 
     389        } 
     390 
     391        amsgi_pos = 20+msg->hdr.length-8-24; 
     392        if (GET_VAL16(pkt, amsgi_pos) == PJ_STUN_ATTR_MESSAGE_INTEGRITY) { 
     393            /* Found MESSAGE-INTEGRITY before FINGERPRINT */ 
     394        } else { 
     395            amsgi_pos = 0; 
     396        } 
     397    } 
     398 
     399    if (amsgi_pos==0) { 
     400        return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_INTEGRITY_CHECK_FAILURE); 
     401    } 
     402 
     403    /* Now calculate HMAC of the message, adding zero padding if necessary 
     404     * to make the input 64 bytes aligned. 
     405     */ 
     406    pj_hmac_sha1_init(&ctx, (pj_uint8_t*)key->ptr, key->slen); 
     407    pj_hmac_sha1_update(&ctx, pkt, amsgi_pos); 
     408    if (amsgi_pos & 0x3F) { 
     409        pj_uint8_t zeroes[64]; 
     410        pj_bzero(zeroes, sizeof(zeroes)); 
     411        pj_hmac_sha1_update(&ctx, zeroes, 64-(amsgi_pos & 0x3F)); 
     412    } 
     413    pj_hmac_sha1_final(&ctx, digest); 
     414 
     415    /* Compare HMACs */ 
     416    if (pj_memcmp(amsgi->hmac, digest, 20)) { 
     417        /* HMAC value mismatch */ 
     418        return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_INTEGRITY_CHECK_FAILURE); 
     419    } 
     420 
     421    /* Everything looks okay! */ 
     422    return PJ_SUCCESS; 
     423} 
     424 
Note: See TracChangeset for help on using the changeset viewer.