// Test vectors from RFC 6070. (See file header, above.) bool PBKDF2_TEST() { MemBuf mDig(100); MemBuf mOut(100); CvtHex( "0c60c80f961f0e71f3a9b524af6012062fe037a6", mDig ); if (0 != memcmp( mDig, PBKDF2("password", "salt", 1, 20, mOut), 20 )) { return false; } CvtHex( "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", mDig ); if (0 != memcmp( mDig, PBKDF2("password", "salt", 2, 20, mOut), 20 )) { return false; } CvtHex( "4b007901b765489abead49d926f721d065a429c1", mDig ); if (0 != memcmp( mDig, PBKDF2("password", "salt", 4096, 20, mOut), 20)) { return false; } // This one is rather time consuming. //CvtHex( "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", mDig ); //if (0 != memcmp( mDig, PBKDF2("password", "salt", 16777216, 20, mOut), 20)) { return false; } CvtHex( "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", mDig ); if (0 != memcmp( mDig, PBKDF2("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25, mOut), 25)) { return false; } CvtHex( "56fa6aa75548099dcc37d7f03425e0c3", mDig ); BYTE text[] = { 'p', 'a', 's', 's', 0, 'w', 'o', 'r', 'd' } ; BYTE salt[] = { 's', 'a', 0, 'l', 't' } ; if (0 != memcmp( mDig, PBKDF2( MemBuf(text,NELEM(text)), MemBuf(salt,NELEM(salt)), 4096, 16, mOut), 16)) { return false; } return true; }
bool WPAPSK_TEST() { MemBuf mDig(32); MemBuf mOut(32); CvtHex( "f42c6fc52df0ebef9ebb4b90b38a5f902e83fe1b135a70e23aed762e9710a12e", mDig ); if (0 != memcmp( mDig, WPAPSK("password", "IEEE", mOut), 32 )) { return false; } CvtHex( "0dc0d6eb90555ed6419756b9a15ec3e3209b63df707dd508d14581f8982721af", mDig ); if (0 != memcmp( mDig, WPAPSK("ThisIsAPassword", "ThisIsASSID", mOut), 32 )) { return false; } CvtHex( "becb93866bb8c3832cb777c2f559807c8c59afcb6eae734885001300a981cc62", mDig ); if (0 != memcmp( mDig, WPAPSK("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", mOut), 32 )) { return false; } return true; }
int eXosip_reg_init (eXosip_reg_t ** jr, const char *from, const char *proxy, const char *contact) { static int r_id; *jr = (eXosip_reg_t *) osip_malloc (sizeof (eXosip_reg_t)); if (*jr == NULL) return -1; if (r_id > 1000000) /* keep it non-negative */ r_id = 0; memset (*jr, '\0', sizeof (eXosip_reg_t)); (*jr)->r_id = ++r_id; (*jr)->r_reg_period = 3600; /* delay between registration */ (*jr)->r_aor = osip_strdup (from); /* sip identity */ (*jr)->r_contact = osip_strdup (contact); /* sip identity */ (*jr)->r_registrar = osip_strdup (proxy); /* registrar */ { MD5_CTX Md5Ctx; HASH hval; HASHHEX key_line; MD5Init (&Md5Ctx); MD5Update (&Md5Ctx, (unsigned char *) from, strlen (from)); MD5Update (&Md5Ctx, (unsigned char *) ":", 1); MD5Update (&Md5Ctx, (unsigned char *) proxy, strlen (proxy)); MD5Final ((unsigned char *) hval, &Md5Ctx); CvtHex (hval, key_line); osip_strncpy((*jr)->r_line, key_line, sizeof((*jr)->r_line)); } return 0; }
int eXosip_reg_init(eXosip_reg_t ** jr, const char *from, const char *proxy, const char *contact) { static int r_id = 0; *jr = (eXosip_reg_t *) osip_malloc(sizeof(eXosip_reg_t)); if (*jr == NULL) return OSIP_NOMEM; if (r_id == 32767) /* keep it non-negative */ r_id = 0; memset(*jr, '\0', sizeof(eXosip_reg_t)); (*jr)->r_id = ++r_id; (*jr)->r_reg_period = 3600; /* delay between registration */ (*jr)->r_aor = osip_strdup(from); /* sip identity */ if ((*jr)->r_aor == NULL) { osip_free(*jr); *jr = NULL; return OSIP_NOMEM; } (*jr)->r_contact = osip_strdup(contact); /* sip identity */ (*jr)->r_registrar = osip_strdup(proxy); /* registrar */ if ((*jr)->r_registrar == NULL) { osip_free((*jr)->r_contact); osip_free((*jr)->r_aor); osip_free(*jr); *jr = NULL; return OSIP_NOMEM; } { osip_MD5_CTX Md5Ctx; HASH hval; HASHHEX key_line; char localip[128]; char firewall_ip[65]; char firewall_port[10]; memset(localip, '\0', sizeof(localip)); memset(firewall_ip, '\0', sizeof(firewall_ip)); memset(firewall_port, '\0', sizeof(firewall_port)); eXosip_guess_localip(AF_INET, localip, 128); if (eXosip.eXtl != NULL && eXosip.eXtl->tl_get_masquerade_contact != NULL) { eXosip.eXtl->tl_get_masquerade_contact(firewall_ip, sizeof(firewall_ip), firewall_port, sizeof(firewall_port)); } osip_MD5Init(&Md5Ctx); osip_MD5Update(&Md5Ctx, (unsigned char *) from, strlen(from)); osip_MD5Update(&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update(&Md5Ctx, (unsigned char *) proxy, strlen(proxy)); osip_MD5Update(&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update(&Md5Ctx, (unsigned char *) localip, strlen(localip)); osip_MD5Update(&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update(&Md5Ctx, (unsigned char *) firewall_ip, strlen(firewall_ip)); osip_MD5Update(&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update(&Md5Ctx, (unsigned char *) firewall_port, strlen(firewall_port)); osip_MD5Final((unsigned char *) hval, &Md5Ctx); CvtHex(hval, key_line); osip_strncpy((*jr)->r_line, key_line, sizeof((*jr)->r_line) - 1); } return OSIP_SUCCESS; }
int _eXosip_reg_init (struct eXosip_t *excontext, eXosip_reg_t ** jr, const char *from, const char *proxy, const char *contact) { static int r_id = 0; *jr = (eXosip_reg_t *) osip_malloc (sizeof (eXosip_reg_t)); if (*jr == NULL) return OSIP_NOMEM; if (r_id == INT_MAX) /* keep it non-negative */ r_id = 0; memset (*jr, '\0', sizeof (eXosip_reg_t)); (*jr)->r_id = ++r_id; (*jr)->r_reg_period = 3600; /* delay between registration */ (*jr)->r_aor = osip_strdup (from); /* sip identity */ if ((*jr)->r_aor == NULL) { osip_free (*jr); *jr = NULL; return OSIP_NOMEM; } (*jr)->r_contact = osip_strdup (contact); /* sip identity */ (*jr)->r_registrar = osip_strdup (proxy); /* registrar */ if ((*jr)->r_registrar == NULL) { osip_free ((*jr)->r_contact); osip_free ((*jr)->r_aor); osip_free (*jr); *jr = NULL; return OSIP_NOMEM; } { osip_MD5_CTX Md5Ctx; HASH hval; HASHHEX key_line; char localip[128]; char firewall_ip[65]; char firewall_port[10]; char somerandom[31]; memset (somerandom, 0, sizeof (somerandom)); eXosip_generate_random (somerandom, 16); memset (localip, '\0', sizeof (localip)); memset (firewall_ip, '\0', sizeof (firewall_ip)); memset (firewall_port, '\0', sizeof (firewall_port)); eXosip_guess_localip (excontext, AF_INET, localip, 128); if (excontext->eXtl_transport.tl_get_masquerade_contact != NULL) { excontext->eXtl_transport.tl_get_masquerade_contact (excontext, firewall_ip, sizeof (firewall_ip), firewall_port, sizeof (firewall_port)); } osip_MD5Init (&Md5Ctx); osip_MD5Update (&Md5Ctx, (unsigned char *) from, (unsigned int) strlen (from)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) proxy, (unsigned int) strlen (proxy)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) localip, (unsigned int) strlen (localip)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) firewall_ip, (unsigned int) strlen (firewall_ip)); osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) firewall_port, (unsigned int) strlen (firewall_port)); /* previously, "line" was common accross several identical restart. */ /* including random will help to read a correct "expires" parameter */ /* from 2xx REGISTER answers */ osip_MD5Update (&Md5Ctx, (unsigned char *) ":", 1); osip_MD5Update (&Md5Ctx, (unsigned char *) somerandom, (unsigned int) strlen (somerandom)); osip_MD5Final ((unsigned char *) hval, &Md5Ctx); CvtHex (hval, key_line); osip_strncpy ((*jr)->r_line, key_line, sizeof ((*jr)->r_line) - 1); } return OSIP_SUCCESS; }
/* * SIP_CALCULATE_BRANCH * * Calculates a branch parameter according to RFC3261 section 16.11 * * The returned 'id' will be HASHHEXLEN + strlen(magic_cookie) * characters (32 + 7) long. The caller must supply at least this * amount of space in 'id'. * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int sip_calculate_branch_id (sip_ticket_t *ticket, char *id) { /* RFC3261 section 16.11 recommends the following procedure: * The stateless proxy MAY use any technique it likes to guarantee * uniqueness of its branch IDs across transactions. However, the * following procedure is RECOMMENDED. The proxy examines the * branch ID in the topmost Via header field of the received * request. If it begins with the magic cookie, the first * component of the branch ID of the outgoing request is computed * as a hash of the received branch ID. Otherwise, the first * component of the branch ID is computed as a hash of the topmost * Via, the tag in the To header field, the tag in the From header * field, the Call-ID header field, the CSeq number (but not * method), and the Request-URI from the received request. One of * these fields will always vary across two different * transactions. * * The branch value will consist of: * - magic cookie "z9hG4bK" * - 1st part (unique calculated ID * - 2nd part (value for loop detection) <<- not yet used by siproxd */ osip_message_t *sip_msg=ticket->sipmsg; static char *magic_cookie="z9hG4bK"; osip_via_t *via; osip_uri_param_t *param=NULL; osip_call_id_t *call_id=NULL; HASHHEX hashstring; hashstring[0]='\0'; /* * Examine topmost via and look for a magic cookie. * If it is there, I use THIS branch parameter as input for * our hash calculation */ via = osip_list_get (sip_msg->vias, 0); if (via == NULL) { ERROR("have a SIP message without any via header"); return STS_FAILURE; } param=NULL; osip_via_param_get_byname(via, "branch", ¶m); if (param && param->gvalue) { DEBUGC(DBCLASS_BABBLE, "looking for magic cookie [%s]",param->gvalue); if (strncmp(param->gvalue, magic_cookie, strlen(magic_cookie))==0) { /* calculate MD5 hash */ MD5_CTX Md5Ctx; HASH HA1; MD5Init(&Md5Ctx); MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue)); MD5Final(HA1, &Md5Ctx); CvtHex(HA1, hashstring); DEBUGC(DBCLASS_BABBLE, "existing branch -> branch hash [%s]", hashstring); } } /* * If I don't have a branch parameter in the existing topmost via, * then I need: * - the topmost via * - the tag in the To header field * - the tag in the From header field * - the Call-ID header field * - the CSeq number (but not method) * - the Request-URI from the received request */ if (hashstring[0] == '\0') { /* calculate MD5 hash */ MD5_CTX Md5Ctx; HASH HA1; char *tmp; MD5Init(&Md5Ctx); /* topmost via */ osip_via_to_str(via, &tmp); if (tmp) { MD5Update(&Md5Ctx, tmp, strlen(tmp)); osip_free(tmp); } /* Tag in To header */ osip_to_get_tag(sip_msg->to, ¶m); if (param && param->gvalue) { MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue)); } /* Tag in From header */ osip_from_get_tag(sip_msg->from, ¶m); if (param && param->gvalue) { MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue)); } /* Call-ID */ call_id = osip_message_get_call_id(sip_msg); osip_call_id_to_str(call_id, &tmp); if (tmp) { MD5Update(&Md5Ctx, tmp, strlen(tmp)); osip_free(tmp); } /* CSeq number (but not method) */ tmp = osip_cseq_get_number(sip_msg->cseq); if (tmp) { MD5Update(&Md5Ctx, tmp, strlen(tmp)); } /* Request URI */ osip_uri_to_str(sip_msg->req_uri, &tmp); if (tmp) { MD5Update(&Md5Ctx, tmp, strlen(tmp)); osip_free(tmp); } MD5Final(HA1, &Md5Ctx); CvtHex(HA1, hashstring); DEBUGC(DBCLASS_BABBLE, "non-existing branch -> branch hash [%s]", hashstring); } /* include the magic cookie */ sprintf(id, "%s%s", magic_cookie, hashstring); return STS_SUCCESS; }