Hi All I have written a code as follows for creating response for algorithm AKAv1-MD5. But i am getting access violation error in the section /* Given key K and random challenge RAND, compute response RES at the line f2345(k, chal_rand, res, ck, ik, ak, op); if i wrote cred.ext.aka.k = pj_str("626f6200000000000000000000000000"); in the main function. But if i kept it as cred.ext.aka.k = pj_str(" "); in the main function. Then i am getting error 171112 (Invalid credentials) at the line if (pj_memcmp(chal_mac, xmac, PJSIP_AKA_MACLEN) != 0) { return PJSIP_EAUTHINNONCE; } in the section /* Given key K and random challenge RAND, compute response RES. Plz suggest what is the problem in my 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(errmsg); } int main() { char *output; pj_status_t status; pj_str_t method; pjsip_cred_info cred; pjsip_digest_challenge chal; pjsip_digest_credential auth; pj_pool_t *pool; pj_caching_pool cp; 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 4000, // initial size 4000, // 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("cdc202d5123e20f62b6d676ac72cb318"); cred.ext.aka.amf = pj_str("0000"); cred.ext.aka.cb = &pjsip_auth_create_aka_response; status = pjsip_auth_create_aka_response(pool,&chal,&cred,&method,&auth); if (status != PJ_SUCCESS) { my_perror("Error initializing PJLIB", status); return 1; } // Done with demos, destroy caching pool before exiting app. pj_caching_pool_destroy(&cp); return 0; } Regd's Sanjay -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20090217/dab548ae/attachment-0001.html>