You are sending a pointer to a pointer to the function pjsip_auth_create_aka_response() when the argument should be a pointer. Try changing the line: pjsip_auth_create_aka_response(&pool,&chal,&cred,&method,&auth); to: pjsip_auth_create_aka_response(pool,&chal,&cred,&method,&auth); Regards, Dan Sanjay Nayak wrote: > Hi All > > I have written a code as follows for generation of response for Algorithm > AKAv1-MD5. But i am getting access violation error : 0xC0000005 in the > section /* Decode nonce */ of the following code > at the line > nonce_bin.ptr = pj_pool_alloc(pool, nonce_bin.slen + 1); during run time. > > Plz suggest what is the problem in the following code? > > The code is as follows: > > > #include <string.h> > #define PJ_WIN32 1; > #include <pjlib.h> > #include <pjlib-util.h> > #include <pjnath.h> > #include <pjsip.h> > #include <pjsip_ua.h> > #include <pjsip_simple.h> > #include <pjsua-lib/pjsua.h> > #include <pjmedia.h> > #include <pjmedia-codec.h> > #include <pjsua-lib/pjsua.h> > #include <pj/string.h> > #include <pj/types.h> > #include <pj/config_site.h > > > #include <pjsip/sip_auth.h> > #include <pjsip/sip_auth_parser.h> /* just to get pjsip_DIGEST_STR */ > #include <pjsip/sip_auth_aka.h> > #include <pjsip/sip_transport.h> > #include <pjsip/sip_endpoint.h> > #include <pjsip/sip_errno.h> > #include <pjsip/sip_util.h> > #include <pjlib-util/md5.h> > #include <pj/log.h> > #include <pj/string.h> > #include <pj/pool.h> > #include <pj/guid.h> > #include <pj/assert.h> > #include <pj/ctype.h> > #include<E:/pjproject-1.0.1/pjsip/src/pjsip/sip_auth_client.c> > #include <pjlib.h> > > > #define PJSIP_HAS_DIGEST_AKA_AUTH 1 > > > #define PJSIP_AKA_AKLEN 6 > #define PJSIP_AKA_AMFLEN 2 > #define PJSIP_AKA_AUTNLEN 16 > #define PJSIP_AKA_CKLEN 16 > #define PJSIP_AKA_IKLEN 16 > #define PJSIP_AKA_KLEN 16 > #define PJSIP_AKA_MACLEN 8 > #define PJSIP_AKA_OPLEN 16 > #define PJSIP_AKA_RANDLEN 16 > #define PJSIP_AKA_RESLEN 8 > #define PJSIP_AKA_SQNLEN 6 > > typedef int pj_status_t; > > > > > > > #include "E:/pjproject-1.0.1/third_party/milenage/milenage.h" > > > pj_status_t pjsip_auth_create_aka_response(pj_pool_t * pool, > const pjsip_digest_challenge * chal, > const pjsip_cred_info * cred, > const pj_str_t * method, > pjsip_digest_credential * auth); > > > pj_status_t pjsip_auth_create_aka_response( > pj_pool_t *pool, > const pjsip_digest_challenge*chal, > const pjsip_cred_info *cred, > const pj_str_t *method, > pjsip_digest_credential *auth) > { > > pj_str_t nonce_bin; > > int aka_version; > const pj_str_t pjsip_AKAv1_MD5 = { "AKAv1-MD5", 9 }; > const pj_str_t pjsip_AKAv2_MD5 = { "AKAv2-MD5", 9 }; > pj_uint8_t *chal_rand, *chal_sqnxoraka, *chal_mac; > pj_uint8_t k[PJSIP_AKA_KLEN]; > pj_uint8_t op[PJSIP_AKA_OPLEN]; > pj_uint8_t amf[PJSIP_AKA_AMFLEN]; > pj_uint8_t res[PJSIP_AKA_RESLEN]; > pj_uint8_t ck[PJSIP_AKA_CKLEN]; > pj_uint8_t ik[PJSIP_AKA_IKLEN]; > pj_uint8_t ak[PJSIP_AKA_AKLEN]; > pj_uint8_t sqn[PJSIP_AKA_SQNLEN]; > pj_uint8_t xmac[PJSIP_AKA_MACLEN]; > pjsip_cred_info aka_cred; > int i, len; > pj_status_t status; > > /* Check the algorithm is supported. */ > if (chal->algorithm.slen==0 || pj_stricmp2(&chal->algorithm, "md5") == > 0) { > /* > * A normal MD5 authentication is requested. Fallbackt to the usual > * MD5 digest creation. > */ > pjsip_auth_create_digest(&auth->response, &auth->nonce, &auth->nc, > &auth->cnonce, &auth->qop, &auth->uri, > &auth->realm, cred, method); > return PJ_SUCCESS; > > } else if (pj_stricmp(&chal->algorithm, &pjsip_AKAv1_MD5) == 0) { > /* > * AKA version 1 is requested. > */ > aka_version = 1; > > } else if (pj_stricmp(&chal->algorithm, &pjsip_AKAv2_MD5) == 0) { > /* > * AKA version 2 is requested. > */ > aka_version = 2; > > } else { > /* Unsupported algorithm */ > return PJSIP_EINVALIDALGORITHM; > } > > /* Decode nonce */ > nonce_bin.slen = len = PJ_BASE64_TO_BASE256_LEN(chal->nonce.slen); > nonce_bin.ptr = pj_pool_alloc(pool, nonce_bin.slen + 1); > status = pj_base64_decode(&chal->nonce, (pj_uint8_t*)nonce_bin.ptr, > &len); > nonce_bin.slen = len; > if (status != PJ_SUCCESS) > return PJSIP_EAUTHINNONCE; > > if (nonce_bin.slen < PJSIP_AKA_RANDLEN + PJSIP_AKA_AUTNLEN) > return PJSIP_EAUTHINNONCE; > > /* Get RAND, AUTN, and MAC */ > chal_rand = (pj_uint8_t*)(nonce_bin.ptr + 0); > chal_sqnxoraka = (pj_uint8_t*) (nonce_bin.ptr + PJSIP_AKA_RANDLEN); > chal_mac = (pj_uint8_t*) (nonce_bin.ptr + PJSIP_AKA_RANDLEN + > PJSIP_AKA_SQNLEN + PJSIP_AKA_AMFLEN); > > /* Copy k. op, and amf */ > pj_bzero(k, sizeof(k)); > pj_bzero(op, sizeof(op)); > pj_bzero(amf, sizeof(amf)); > > if (cred->ext.aka.k.slen) > pj_memcpy(k, cred->ext.aka.k.ptr, cred->ext.aka.k.slen); > if (cred->ext.aka.op.slen) > pj_memcpy(op, cred->ext.aka.op.ptr, cred->ext.aka.op.slen); > if (cred->ext.aka.amf.slen) > pj_memcpy(amf, cred->ext.aka.amf.ptr, cred->ext.aka.amf.slen); > > /* Given key K and random challenge RAND, compute response RES, > * confidentiality key CK, integrity key IK and anonymity key AK. > */ > f2345(k, chal_rand, res, ck, ik, ak, op); > > /* Compute sequence number SQN */ > for (i=0; i<PJSIP_AKA_SQNLEN; ++i) > sqn[i] = (pj_uint8_t) (chal_sqnxoraka[i] ^ ak[i]); > > /* Verify MAC in the challenge */ > /* Compute XMAC */ > f1(k, chal_rand, sqn, amf, xmac, op); > > if (pj_memcmp(chal_mac, xmac, PJSIP_AKA_MACLEN) != 0) { > return PJSIP_EAUTHINNONCE; > } > > /* Build a temporary credential info to create MD5 digest, using > * "res" as the password. > */ > pj_memcpy(&aka_cred, cred, sizeof(aka_cred)); > aka_cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; > > /* Create a response */ > if (aka_version == 1) { > /* > * For AKAv1, the password is RES > */ > aka_cred.data.ptr = (char*)res; > aka_cred.data.slen = PJSIP_AKA_RESLEN; > > pjsip_auth_create_digest(&auth->response, &chal->nonce, > &auth->nc, &auth->cnonce, &auth->qop, > &auth->uri, &chal->realm, &aka_cred, method); > > } else if (aka_version == 2) { > /* > * For AKAv2, password is base64 encoded [1] parameters: > * PRF(RES||IK||CK,"http-digest-akav2-password") > * > * The pseudo-random function (PRF) is HMAC-MD5 in this case. > * > * Hmmm.. but those above doesn't seem to work, and this below does! > */ > aka_cred.data.slen = PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN + > PJSIP_AKA_CKLEN; > aka_cred.data.ptr = pj_pool_alloc(pool, aka_cred.data.slen); > > pj_memcpy(aka_cred.data.ptr + 0, res, PJSIP_AKA_RESLEN); > pj_memcpy(aka_cred.data.ptr + PJSIP_AKA_RESLEN, ik, PJSIP_AKA_IKLEN); > pj_memcpy(aka_cred.data.ptr + PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN, > ck, PJSIP_AKA_CKLEN); > > pjsip_auth_create_digest(&auth->response, &chal->nonce, > &auth->nc, &auth->cnonce, &auth->qop, > &auth->uri, &chal->realm, &aka_cred, method); > > } else { > pj_assert(!"Bug!"); > return PJ_EBUG; > } > > /* Done */ > > return PJ_SUCCESS; > } > > static void my_perror(const char *title, pj_status_t status) > { > char errmsg[PJ_ERR_MSG_SIZE]; > > pj_strerror(status, errmsg, sizeof(errmsg)); > //PJ_LOG(1,(THIS_FILE, "%s: %s [status=%d]", title, errmsg, > status)); > printf(status); > } > > > int main() > { > > pj_str_t method; > pjsip_cred_info cred; > pjsip_digest_challenge chal; > pjsip_digest_credential auth; > pj_pool_t *pool; > > pj_caching_pool cp; > pj_status_t status; > > status = pj_init(); > > if (status != PJ_SUCCESS) > > { > my_perror("Error initializing PJLIB", status); > return 1; > } > // Create the pool factory, in this case, a caching pool, > // using default pool policy. > pj_caching_pool_init(&cp, NULL, 1024*1024 ); > > pool = pj_pool_create(&cp.factory, // the factory > "pool11", // pool's name > 40000, // initial size > 40000, // increment size > NULL); // use default callback. > > if (pool == NULL) > { > my_perror("Error creating pool", PJ_ENOMEM); > return; > } > > //mentioning method name > method = pj_str("REGISTER"); > > //Authentication challange Parameters > > pj_bzero(&chal, sizeof(chal)); > > pj_bzero(&chal, sizeof(chal)); > > chal.realm = pj_str("ptinovacao.pt"); > chal.domain = pj_str("ptinovacao.pt"); > chal.nonce = pj_str("AABHegAACUAAAEsHAAAMzULdXEXBS7m5ew/MiBUkHdR="); > chal.opaque = pj_str(""); > chal.algorithm = pj_str("AKAv1-MD5"); > chal.qop = pj_str (""); > > > //authorization parameters > pj_bzero(&auth, sizeof(auth)); > > auth.realm = pj_str("ptinovacao.pt"); > auth.username = pj_str("bob at ptinovacao.pt"); > auth.nonce = pj_str("AABHegAACUAAAEsHAAAMzULdXEXBS7m5ew/MiBUkHdR="); > auth.algorithm = pj_str ("AKAv1-MD5"); > > // Credential parameters > > pj_bzero(&cred, sizeof(cred)); > > cred.scheme = pj_str("Digest"); > cred.realm = pj_str("ptinovacao.pt"); > cred.username = pj_str("bob at ptinovacao.pt"); > cred.data_type = PJSIP_CRED_DATA_EXT_AKA; > cred.data = pj_str(""); > > // AKA extended info > > cred.ext.aka.k = pj_str(""); > cred.ext.aka.op = pj_str("00000000000000000000000000000000"); > cred.ext.aka.amf = pj_str("0000"); > cred.ext.aka.cb = &pjsip_auth_create_aka_response; > > > pjsip_auth_create_aka_response(&pool,&chal,&cred,&method,&auth); > > > // Done with demos, destroy caching pool before exiting app. > > pj_caching_pool_destroy(&cp); > > > return 0; > > } > > Regd's > Sanjay > > > > ------------------------------------------------------------------------ > > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip at lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org