00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <libzrtpcpp/crypto/ZrtpDH.h>
00023 #include <libzrtpcpp/crypto/hmac256.h>
00024 #include <libzrtpcpp/crypto/sha256.h>
00025 #include <libzrtpcpp/crypto/aesCFB.h>
00026
00027 #include <libzrtpcpp/ZRtp.h>
00028 #include <libzrtpcpp/ZrtpStateClass.h>
00029 #include <libzrtpcpp/ZIDFile.h>
00030 #include <libzrtpcpp/ZIDRecord.h>
00031 #include <libzrtpcpp/Base32.h>
00032
00033 static void hexdump(const char* title, const unsigned char *s, int l) {
00034 int n=0;
00035
00036 if (s == NULL) return;
00037
00038 fprintf(stderr, "%s",title);
00039 for( ; n < l ; ++n)
00040 {
00041 if((n%16) == 0)
00042 fprintf(stderr, "\n%04x",n);
00043 fprintf(stderr, " %02x",s[n]);
00044 }
00045 fprintf(stderr, "\n");
00046 }
00047
00048
00049
00050
00051
00052 #ifdef __cplusplus
00053 extern "C" {
00054 #endif
00055 int ZrtpAvailable()
00056 {
00057 return 1;
00058 }
00059 #ifdef __cplusplus
00060 }
00061 #endif
00062
00063 ZRtp::ZRtp(uint8_t *myZid, ZrtpCallback *cb):
00064 callback(cb), dhContext(NULL) {
00065
00066 DHss = NULL;
00067 zpDH2 = NULL;
00068
00069 memcpy(zid, myZid, 12);
00070 zrtpHello.setZid(zid);
00071
00072 msgShaContext = createSha256Context();
00073
00074 stateEngine = new ZrtpStateClass(this);
00075 }
00076
00077 ZRtp::~ZRtp() {
00078 stopZrtp();
00079
00080 if (DHss != NULL) {
00081 free(DHss);
00082 DHss = NULL;
00083 }
00084 if (zpDH2 != NULL) {
00085 delete zpDH2;
00086 zpDH2 = NULL;
00087 }
00088 if (stateEngine != NULL) {
00089 delete stateEngine;
00090 stateEngine = NULL;
00091 }
00092 if (dhContext != NULL) {
00093 delete dhContext;
00094 dhContext = NULL;
00095 }
00096 if (msgShaContext != NULL) {
00097 closeSha256Context(msgShaContext, NULL);
00098 msgShaContext = NULL;
00099 }
00100 memset(hmacKeyI, 0, SHA256_DIGEST_LENGTH);
00101 memset(hmacKeyR, 0, SHA256_DIGEST_LENGTH);
00102
00103 memset(zrtpKeyI, 0, SHA256_DIGEST_LENGTH);
00104 memset(zrtpKeyR, 0, SHA256_DIGEST_LENGTH);
00105
00106
00107
00108 memset(srtpKeyI, 0, SHA256_DIGEST_LENGTH);
00109 memset(srtpSaltI, 0, SHA256_DIGEST_LENGTH);
00110
00111
00112
00113 memset(srtpKeyR, 0, SHA256_DIGEST_LENGTH);
00114 memset(srtpSaltR, 0, SHA256_DIGEST_LENGTH);
00115
00116 memset(s0, 0, SHA256_DIGEST_LENGTH);
00117 }
00118
00119 int32_t ZRtp::processZrtpMessage(uint8_t *message) {
00120 Event_t ev;
00121
00122 ev.type = ZrtpPacket;
00123 ev.data.packet = message;
00124
00125 int32_t ret;
00126 if (stateEngine != NULL) {
00127 ret = stateEngine->processEvent(&ev);
00128 }
00129 return ret;
00130 }
00131
00132 int32_t ZRtp::processTimeout() {
00133 Event_t ev;
00134
00135 ev.type = Timer;
00136 ev.data.packet = NULL;
00137 int32_t ret;
00138 if (stateEngine != NULL) {
00139 ret = stateEngine->processEvent(&ev);
00140 }
00141 return ret;
00142
00143 }
00144
00145 #ifdef oldgoclear
00146 bool ZRtp::handleGoClear(uint8_t *message)
00147 {
00148 char *msg, first, last;
00149
00150 msg = (char *)message + 4;
00151 first = tolower(*msg);
00152 last = tolower(*(msg+6));
00153
00154 if (first == 'g' && last == 'r') {
00155 Event_t ev;
00156
00157 ev.type = ZrtpGoClear;
00158 ev.data.packet = message;
00159 if (stateEngine != NULL) {
00160 stateEngine->processEvent(&ev);
00161 }
00162 return true;
00163 }
00164 else {
00165 return false;
00166 }
00167 }
00168 #endif
00169
00170 void ZRtp::startZrtpEngine() {
00171 Event_t ev;
00172
00173 ev.type = ZrtpInitial;
00174 stateEngine->processEvent(&ev);
00175 }
00176
00177 void ZRtp::stopZrtp() {
00178 Event_t ev;
00179
00180
00181
00182
00183
00184
00185 if (stateEngine != NULL) {
00186 if (!stateEngine->inState(SecureState)) {
00187 stateEngine->nextState(Initial);
00188 return;
00189 }
00190 ev.type = ZrtpClose;
00191 stateEngine->processEvent(&ev);
00192 }
00193 }
00194
00195 int32_t ZRtp::checkState(int32_t state)
00196 {
00197 if (stateEngine != NULL) {
00198 return stateEngine->inState(state);
00199 }
00200 else {
00201 return -1;
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210 ZrtpPacketCommit* ZRtp::prepareCommit(ZrtpPacketHello *hello, uint32_t* errMsg) {
00211
00212 sendInfo(Info, "Hello received, preparing a Commit");
00213
00214 if (memcmp(hello->getVersion(), zrtpVersion, 4) != 0) {
00215 *errMsg = UnsuppZRTPVersion;
00216 sendInfo(Error, "Received Hello packet with unsupported version number.");
00217 return NULL;
00218 }
00219
00220 uint8_t* cid = hello->getClientId();
00221 memcpy(peerZid, hello->getZid(), 12);
00222 if (memcmp(peerZid, zid, 12) == 0) {
00223 *errMsg = EqualZIDHello;
00224 sendInfo(Error, "Received Hello packet with same ZID.");
00225 return NULL;
00226 }
00227
00228
00229
00230
00231
00232
00233 cipher = findBestCipher(hello);
00234 if (cipher >= NumSupportedSymCiphers) {
00235 *errMsg = UnsuppCiphertype;
00236 sendInfo(Error, "Hello message does not contain a supported Cipher");
00237 return NULL;
00238 }
00239 hash = findBestHash(hello);
00240 if (hash >= NumSupportedHashes) {
00241 *errMsg = UnsuppHashType;
00242 sendInfo(Error, "Hello message does not contain a supported Hash");
00243 return NULL;
00244 }
00245 pubKey = findBestPubkey(hello);
00246 if (pubKey >= NumSupportedPubKeys) {
00247 *errMsg = UnsuppPKExchange;
00248 sendInfo(Error, "Hello message does not contain a supported public key algorithm");
00249 return NULL;
00250 }
00251 sasType = findBestSASType(hello);
00252 if (sasType >= NumSupportedSASTypes) {
00253 *errMsg = UnsuppSASScheme;
00254 sendInfo(Error, "Hello message does not contain a supported SAS algorithm");
00255 return NULL;
00256 }
00257 authLength = findBestAuthLen(hello);
00258 if (authLength >= NumSupportedAuthLenghts) {
00259 *errMsg = UnsuppSRTPAuthTag;
00260 sendInfo(Error, "Hello message does not contain a supported authentication length");
00261 return NULL;
00262 }
00263
00264 if (cipher == Aes256 && pubKey != Dh4096) {
00265 sendInfo(Warning, "Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096");
00266 }
00267
00268
00269 int32_t maxPubKeySize;
00270 if (pubKey == Dh3072) {
00271 dhContext = new ZrtpDH(3072);
00272 maxPubKeySize = 384;
00273
00274 }
00275 else if (pubKey == Dh4096) {
00276 dhContext = new ZrtpDH(4096);
00277 maxPubKeySize = 512;
00278 }
00279 else {
00280 *errMsg = CriticalSWError;
00281 return NULL;
00282
00283 }
00284 dhContext->generateKey();
00285 pubKeyLen = dhContext->getPubKeySize();
00286 dhContext->getPubKeyBytes(pubKeyBytes);
00287
00288 char buffer[128];
00289 snprintf((char *)buffer, 128, "Commit: Generated a public DH key of size: %d", dhContext->getPubKeySize());
00290 sendInfo(Info, buffer);
00291
00292
00293
00294
00295 dhContext->random(randomIV, sizeof(randomIV));
00296
00297
00298
00299
00300
00301
00302
00303 ZIDRecord zidRec(peerZid);
00304 ZIDFile *zidFile = ZIDFile::getInstance();
00305 zidFile->getRecord(&zidRec);
00306
00307
00308 computeSharedSecretSet(zidRec);
00309
00310
00311
00312 zpDH2 = new ZrtpPacketDHPart(pubKey);
00313
00314
00315 zpDH2->setMessageType((uint8_t*)DHPart2Msg);
00316 zpDH2->setRs1Id(rs1IDi);
00317 zpDH2->setRs2Id(rs2IDi);
00318 zpDH2->setSigsId(sigsIDi);
00319 zpDH2->setSrtpsId(srtpsIDi);
00320 zpDH2->setOtherSecretId(otherSecretIDi);
00321 zpDH2->setPv(pubKeyBytes);
00322
00323
00324 computeHvi(zpDH2, hello);
00325
00326 ZrtpPacketCommit *commit = new ZrtpPacketCommit();
00327 commit->setZid(zid);
00328 commit->setHashType((uint8_t*)supportedHashes[hash]);
00329 commit->setCipherType((uint8_t*)supportedCipher[cipher]);
00330 commit->setAuthLen((uint8_t*)supportedAuthLen[authLength]);
00331 commit->setPubKeyType((uint8_t*)supportedPubKey[pubKey]);
00332 commit->setSasType((uint8_t*)supportedSASType[sasType]);
00333 commit->setHvi(hvi);
00334
00335
00336
00337
00338 sha256Ctx(msgShaContext, (unsigned char*)hello->getHeaderBase(), hello->getLength() * ZRTP_WORD_SIZE);
00339 sha256Ctx(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
00340 return commit;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 ZrtpPacketDHPart* ZRtp::prepareDHPart1(ZrtpPacketCommit *commit, uint32_t* errMsg) {
00353
00354 int i;
00355
00356 sendInfo(Info, "Responder: Commit received, preparing DHPart1");
00357
00358
00359 uint8_t *cp = commit->getCipherType();
00360 for (i = 0; i < NumSupportedSymCiphers; i++) {
00361 if (!memcmp(cp, supportedCipher[i], ZRTP_WORD_SIZE)) {
00362 break;
00363 }
00364 }
00365 if (i >= NumSupportedSymCiphers) {
00366 *errMsg = UnsuppCiphertype;
00367 sendInfo(Alert, "Cannot find a supported Cipher in Commit message");
00368 return NULL;
00369 }
00370 cipher = (SupportedSymCiphers)i;
00371
00372
00373 cp = commit->getAuthLen();
00374 for (i = 0; i < NumSupportedAuthLenghts; i++) {
00375 if (!memcmp(cp, supportedAuthLen[i], ZRTP_WORD_SIZE)) {
00376 break;
00377 }
00378 }
00379 if (i >= NumSupportedAuthLenghts) {
00380 *errMsg = UnsuppSRTPAuthTag;
00381 sendInfo(Alert, "Cannot find a supported authentication length in Commit message");
00382 return NULL;
00383 }
00384 authLength = (SupportedAuthLengths)i;
00385
00386
00387 cp = commit->getHashType();
00388 for (i = 0; i < NumSupportedHashes; i++) {
00389 if (!memcmp(cp, supportedHashes[i], ZRTP_WORD_SIZE)) {
00390 break;
00391 }
00392 }
00393 if (i >= NumSupportedHashes) {
00394 *errMsg = UnsuppHashType;
00395 sendInfo(Alert, "Cannot find a supported Hash in Commit message");
00396 return NULL;
00397 }
00398 hash = (SupportedHashes)i;
00399
00400
00401 cp = commit->getPubKeysType();
00402 for (i = 0; i < NumSupportedPubKeys; i++) {
00403 if (!memcmp(cp, supportedPubKey[i], ZRTP_WORD_SIZE)) {
00404 break;
00405 }
00406 }
00407 if (i >= NumSupportedPubKeys) {
00408 *errMsg = UnsuppPKExchange;
00409 sendInfo(Alert, "Cannot find a supported public key algorithm in Commit message");
00410 return NULL;
00411 }
00412 pubKey = (SupportedPubKeys)i;
00413
00414
00415 cp = commit->getSasType();
00416 for (i = 0; i < NumSupportedSASTypes; i++) {
00417 if (!memcmp(cp, supportedSASType[i], ZRTP_WORD_SIZE)) {
00418 break;
00419 }
00420 }
00421 if (i >= NumSupportedSASTypes) {
00422 *errMsg = UnsuppSASScheme;
00423 sendInfo(Alert, "Cannot find a supported SAS algorithm in Commit message");
00424 return NULL;
00425 }
00426 sasType = (SupportedSASTypes)i;
00427
00428 int32_t maxPubKeySize;
00429
00430 if (cipher == Aes256 && pubKey != Dh4096) {
00431 sendInfo(Warning, "Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096");
00432
00433 }
00434
00435
00436 if (dhContext != NULL) {
00437 delete dhContext;
00438 dhContext = NULL;
00439 }
00440
00441 if (pubKey == Dh3072) {
00442 dhContext = new ZrtpDH(3072);
00443 maxPubKeySize = 384;
00444
00445 }
00446 else if (pubKey == Dh4096) {
00447 dhContext = new ZrtpDH(4096);
00448 maxPubKeySize = 512;
00449 }
00450 else {
00451 *errMsg = CriticalSWError;
00452 return NULL;
00453
00454 }
00455 dhContext->generateKey();
00456 pubKeyLen = dhContext->getPubKeySize();
00457
00458 char buffer[128];
00459 snprintf(buffer, 128, "DH1Part: Generated a public DH key of size: %d", pubKeyLen);
00460 sendInfo(Info, buffer);
00461
00462 if (pubKeyLen > maxPubKeySize) {
00463 *errMsg = CriticalSWError;
00464 snprintf(buffer, 128, "Generated DH public key too big: %d, max: %d", pubKeyLen, maxPubKeySize);
00465 sendInfo(Error, buffer);
00466 return NULL;
00467 }
00468 dhContext->getPubKeyBytes(pubKeyBytes);
00469
00470
00471
00472
00473
00474
00475
00476 if (zpDH2 != NULL) {
00477 delete zpDH2;
00478 zpDH2 = NULL;
00479 }
00480 else {
00481
00482
00483 memcpy(peerZid, commit->getZid(), 12);
00484
00485
00486
00487
00488 dhContext->random(randomIV, sizeof(randomIV));
00489
00490
00491 ZIDRecord zidRec(peerZid);
00492 ZIDFile *zid = ZIDFile::getInstance();
00493 zid->getRecord(&zidRec);
00494
00495
00496
00497
00498
00499 computeSharedSecretSet(zidRec);
00500 }
00501
00502
00503 ZrtpPacketDHPart *zpDH = new ZrtpPacketDHPart(pubKey);
00504 zpDH->setMessageType((uint8_t*)DHPart1Msg);
00505 zpDH->setRs1Id(rs1IDr);
00506 zpDH->setRs2Id(rs2IDr);
00507 zpDH->setSigsId(sigsIDr);
00508 zpDH->setSrtpsId(srtpsIDr);
00509 zpDH->setOtherSecretId(otherSecretIDr);
00510 zpDH->setPv(pubKeyBytes);
00511
00512
00513 myRole = Responder;
00514 memcpy(peerHvi, commit->getHvi(), SHA256_DIGEST_LENGTH);
00515
00516
00517
00518 if (msgShaContext != NULL) {
00519 closeSha256Context(msgShaContext, NULL);
00520 }
00521 msgShaContext = createSha256Context();
00522
00523
00524
00525
00526
00527 sha256Ctx(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(),
00528 zrtpHello.getLength() * ZRTP_WORD_SIZE);
00529 sha256Ctx(msgShaContext, (unsigned char*)commit->getHeaderBase(),
00530 commit->getLength() * ZRTP_WORD_SIZE);
00531 sha256Ctx(msgShaContext, (unsigned char*)zpDH->getHeaderBase(),
00532 zpDH->getLength() * ZRTP_WORD_SIZE);
00533
00534 return zpDH;
00535 }
00536
00537
00538
00539
00540 ZrtpPacketDHPart* ZRtp::prepareDHPart2(ZrtpPacketDHPart *dhPart1, uint32_t* errMsg) {
00541
00542 uint8_t* pvr;
00543 uint8_t sas[SHA256_DIGEST_LENGTH+1];
00544
00545 sendInfo(Info, "Initiator: DHPart1 received, preparing DHPart2");
00546
00547
00548 DHss = (uint8_t*)malloc(dhContext->getSecretSize());
00549 if (DHss == NULL) {
00550 sendInfo(Error, "Out of memory");
00551 return NULL;
00552 }
00553
00554
00555 pvr = dhPart1->getPv();
00556 if (pubKey == Dh3072) {
00557 if (!dhContext->checkPubKey(pvr, 384)) {
00558 *errMsg = DHErrorWrongPV;
00559 sendInfo(Alert, "Wrong/weak public key value (pvr) received from other party");
00560 return NULL;
00561 }
00562 dhContext->computeKey(pvr, 384, DHss);
00563 }
00564 else {
00565 if (!dhContext->checkPubKey(pvr, 512)) {
00566 *errMsg = DHErrorWrongPV;
00567 sendInfo(Alert, "Wrong/weak public key value (pvr) received from other party");
00568 return NULL;
00569 }
00570 dhContext->computeKey(pvr, 512, DHss);
00571 }
00572
00573
00574
00575
00576 ZrtpPacketDHPart *zpDH = zpDH2;
00577 zpDH2 = NULL;
00578
00579 myRole = Initiator;
00580
00581
00582
00583
00584 sha256Ctx(msgShaContext, (unsigned char*)dhPart1->getHeaderBase(), dhPart1->getLength() * ZRTP_WORD_SIZE);
00585 sha256Ctx(msgShaContext, (unsigned char*)zpDH->getHeaderBase(), zpDH->getLength() * ZRTP_WORD_SIZE);
00586
00587
00588 closeSha256Context(msgShaContext, messageHash);
00589 msgShaContext = NULL;
00590
00591
00592
00593 ZIDRecord zidRec(peerZid);
00594 ZIDFile *zid = ZIDFile::getInstance();
00595 zid->getRecord(&zidRec);
00596
00597
00598 generateS0Initiator(dhPart1, zidRec);
00599 delete dhContext;
00600 dhContext = NULL;
00601
00602 return zpDH;
00603 }
00604
00605
00606
00607
00608 ZrtpPacketConfirm* ZRtp::prepareConfirm1(ZrtpPacketDHPart* dhPart2, uint32_t* errMsg) {
00609
00610 uint8_t* pvi;
00611 uint8_t sas[SHA256_DIGEST_LENGTH+1];
00612
00613 sendInfo(Info, "Responder: DHPart2 received, preparing Confirm1");
00614
00615
00616 DHss = (uint8_t*)malloc(dhContext->getSecretSize());
00617 if (DHss == NULL) {
00618
00619 return NULL;
00620 }
00621
00622
00623 pvi = dhPart2->getPv();
00624 if (pubKey == Dh3072) {
00625 if (!dhContext->checkPubKey(pvi, 384)) {
00626 *errMsg = DHErrorWrongPV;
00627 sendInfo(Alert, "Wrong/weak public key value (pvi) received from other party");
00628 return NULL;
00629 }
00630 dhContext->computeKey(pvi, 384, DHss);
00631 }
00632 else {
00633 if (!dhContext->checkPubKey(pvi, 512)) {
00634 *errMsg = DHErrorWrongPV;
00635 sendInfo(Alert, "Wrong/weak public key value (pvi) received from other party");
00636 return NULL;
00637 }
00638 dhContext->computeKey(pvi, 512, DHss);
00639 }
00640
00641
00642
00643
00644
00645 computeHvi(dhPart2, &zrtpHello);
00646 if (memcmp(hvi, peerHvi, SHA256_DIGEST_LENGTH) != 0) {
00647 *errMsg = DHErrorWrongHVI;
00648 sendInfo(Alert, "Mismatch of HVI values. Possible MitM problem?");
00649 return NULL;
00650 }
00651
00652
00653 sha256Ctx(msgShaContext, (unsigned char*)dhPart2->getHeaderBase(),
00654 dhPart2->getLength() * ZRTP_WORD_SIZE);
00655
00656 closeSha256Context(msgShaContext, messageHash);
00657 msgShaContext = NULL;
00658
00659
00660
00661 ZIDRecord zidRec(peerZid);
00662 ZIDFile *zid = ZIDFile::getInstance();
00663 zid->getRecord(&zidRec);
00664
00665
00666
00667
00668
00669
00670 generateS0Responder(dhPart2, zidRec);
00671
00672 delete dhContext;
00673 dhContext = NULL;
00674
00675
00676 ZrtpPacketConfirm* zpConf = new ZrtpPacketConfirm(static_cast<uint8_t>(0));
00677 zpConf->setMessageType((uint8_t*)Confirm1Msg);
00678
00679
00680
00681 if (zidRec.isSasVerified()) {
00682 zpConf->setSASFlag();
00683 }
00684 zpConf->setExpTime(0xFFFFFFFF);
00685 zpConf->setIv(randomIV);
00686
00687 uint8_t confMac[SHA256_DIGEST_LENGTH];
00688 uint32_t macLen;
00689
00690
00691 int16_t hmlen = (zpConf->getLength() - 9) * ZRTP_WORD_SIZE;
00692 aesCfbEncrypt(zrtpKeyR, (cipher == Aes128) ? 16 : 32, randomIV,
00693 (unsigned char*)zpConf->getFiller(), hmlen);
00694 hmac_sha256(hmacKeyR, SHA256_DIGEST_LENGTH, (unsigned char*)zpConf->getFiller(),
00695 hmlen, confMac, &macLen);
00696
00697 zpConf->setHmac(confMac);
00698 return zpConf;
00699 }
00700
00701 ZrtpPacketConfirm* ZRtp::prepareConfirm2(ZrtpPacketConfirm *confirm1, uint32_t* errMsg) {
00702
00703 sendInfo(Info, "Initiator: Confirm1 received, preparing Confirm2");
00704
00705 uint8_t confMac[SHA256_DIGEST_LENGTH];
00706 uint32_t macLen;
00707
00708
00709
00710 int16_t hmlen = (confirm1->getLength() - 9) * ZRTP_WORD_SIZE;
00711 hmac_sha256(hmacKeyR, SHA256_DIGEST_LENGTH, (unsigned char*)confirm1->getFiller(),
00712 hmlen, confMac, &macLen);
00713
00714 if (memcmp(confMac, confirm1->getHmac(), 2*ZRTP_WORD_SIZE) != 0) {
00715 *errMsg = ConfirmHMACWrong;
00716 sendInfo(Error, "HMAC verification of Confirm1 message failed");
00717 return NULL;
00718 }
00719 aesCfbDecrypt(zrtpKeyR, (cipher == Aes128) ? 16 : 32,
00720 (unsigned char*)confirm1->getIv(),
00721 (unsigned char*)confirm1->getFiller(), hmlen);
00722
00723
00724
00725
00726 bool sasFlag = confirm1->isSASFlag();
00727
00728
00729 ZIDRecord zidRec(peerZid);
00730
00731 ZIDFile *zid = ZIDFile::getInstance();
00732 zid->getRecord(&zidRec);
00733
00734
00735
00736 if (!sasFlag) {
00737 zidRec.resetSasVerified();
00738 }
00739
00740
00741
00742 sasFlag = zidRec.isSasVerified() ? true : false;
00743
00744
00745 const char* c = (cipher == Aes128) ? "AES-CM-128" : "AES-CM-256";
00746 const char* s = (zidRec.isSasVerified()) ? NULL : SAS.c_str();
00747 callback->srtpSecretsOn(c, s);
00748
00749
00750
00751 zidRec.setNewRs1((const uint8_t*)newRs1);
00752 zid->saveRecord(&zidRec);
00753
00754
00755 ZrtpPacketConfirm* zpConf = new ZrtpPacketConfirm(static_cast<uint8_t>(0));
00756 zpConf->setMessageType((uint8_t*)Confirm2Msg);
00757 if (sasFlag) {
00758 zpConf->setSASFlag();
00759 }
00760 zpConf->setExpTime(0xFFFFFFFF);
00761 zpConf->setIv(randomIV);
00762
00763
00764 hmlen = (zpConf->getLength() - 9) * ZRTP_WORD_SIZE;
00765 aesCfbEncrypt(zrtpKeyI, (cipher == Aes128) ? 16 : 32, randomIV,
00766 (unsigned char*)zpConf->getFiller(), hmlen);
00767 hmac_sha256(hmacKeyI, SHA256_DIGEST_LENGTH, (unsigned char*)zpConf->getFiller(),
00768 hmlen, confMac, &macLen);
00769
00770 zpConf->setHmac(confMac);
00771 return zpConf;
00772 }
00773
00774 ZrtpPacketConf2Ack* ZRtp::prepareConf2Ack(ZrtpPacketConfirm *confirm2, uint32_t* errMsg) {
00775
00776 sendInfo(Info, "Responder: Confirm2 received, preparing Conf2Ack");
00777
00778 uint8_t confMac[SHA256_DIGEST_LENGTH];
00779 uint32_t macLen;
00780
00781
00782
00783 int16_t hmlen = (confirm2->getLength() - 9) * ZRTP_WORD_SIZE;
00784 hmac_sha256(hmacKeyI, SHA256_DIGEST_LENGTH, (unsigned char*)confirm2->getFiller(),
00785 hmlen, confMac, &macLen);
00786
00787 if (memcmp(confMac, confirm2->getHmac(), 2*ZRTP_WORD_SIZE) != 0) {
00788 *errMsg = ConfirmHMACWrong;
00789 sendInfo(Error, "HMAC verification of Confirm2 message failed");
00790 return NULL;
00791 }
00792 aesCfbDecrypt(zrtpKeyI, (cipher == Aes128) ? 16 : 32,
00793 (unsigned char*)confirm2->getIv(),
00794 (unsigned char*)confirm2->getFiller(), hmlen);
00795
00796
00797
00798
00799
00800 bool sasFlag = confirm2->isSASFlag();
00801
00802
00803 ZIDRecord zidRec(peerZid);
00804
00805 ZIDFile *zid = ZIDFile::getInstance();
00806 zid->getRecord(&zidRec);
00807
00808
00809
00810 if (!sasFlag) {
00811 zidRec.resetSasVerified();
00812 }
00813
00814
00815 const char* c = (cipher == Aes128) ? "AES-CM-128" : "AES-CM-256";
00816 const char* s = (zidRec.isSasVerified()) ? NULL : SAS.c_str();
00817 callback->srtpSecretsOn(c, s);
00818
00819
00820 zidRec.setNewRs1((const uint8_t*)newRs1);
00821 zid->saveRecord(&zidRec);
00822
00823 return &zrtpConf2Ack;
00824 }
00825
00826 ZrtpPacketErrorAck* ZRtp::prepareErrorAck(ZrtpPacketError* epkt)
00827 {
00828 char buffer[128];
00829 snprintf((char *)buffer, 128, "Error: Received an Error message, code: %x", epkt->getErrorCode());
00830
00831 sendInfo(Error, buffer);
00832 return &zrtpErrorAck;
00833 }
00834
00835 ZrtpPacketError* ZRtp::prepareError(uint32_t errMsg)
00836 {
00837 ZrtpPacketError* err = &zrtpError;
00838 err->setErrorCode(errMsg);
00839 return err;
00840 }
00841
00842
00843 ZrtpPacketClearAck* ZRtp::prepareClearAck(ZrtpPacketGoClear* gpkt)
00844 {
00845 sendInfo(Warning, "Received a GoClear message");
00846 return &zrtpClearAck;
00847 }
00848
00849 ZrtpPacketGoClear* ZRtp::prepareGoClear(uint32_t errMsg)
00850 {
00851 uint8_t msg[16];
00852 ZrtpPacketGoClear* gclr = &zrtpGoClear;
00853 gclr->clrClearHmac();
00854 return gclr;
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 SupportedHashes ZRtp::findBestHash(ZrtpPacketHello *hello) {
00876
00877 int i;
00878 int ii;
00879 int num = hello->getNumHashes();
00880
00881 if (num == 0) {
00882 return Sha256;
00883 }
00884 for (i = 0; i < NumSupportedHashes; i++) {
00885 for (ii = 0; ii < num; ii++) {
00886 if (*(uint32_t*)hello->getHashType(ii) == *(uint32_t*)supportedHashes[i]) {
00887 return (SupportedHashes)i;
00888 }
00889 }
00890 }
00891 return Sha256;
00892 }
00893
00894 SupportedSymCiphers ZRtp::findBestCipher(ZrtpPacketHello *hello) {
00895
00896 int i;
00897 int ii;
00898 int num = hello->getNumCiphers();
00899
00900 if (num == 0) {
00901 return Aes128;
00902 }
00903 for (i = 0; i < NumSupportedSymCiphers; i++) {
00904 for (ii = 0; ii < num; ii++) {
00905 if (*(uint32_t*)hello->getCipherType(ii) == *(uint32_t*)supportedCipher[i]) {
00906 return (SupportedSymCiphers)i;
00907 }
00908 }
00909 }
00910 return Aes128;
00911 }
00912
00913 SupportedPubKeys ZRtp::findBestPubkey(ZrtpPacketHello *hello) {
00914
00915 int i;
00916 int ii;
00917 int num = hello->getNumPubKeys();
00918
00919 if (num == 0) {
00920 return Dh3072;
00921 }
00922 for (i = 0; i < NumSupportedPubKeys; i++) {
00923 for (ii = 0; ii < num; ii++) {
00924 if (*(uint32_t*)hello->getPubKeyType(ii) == *(uint32_t*)supportedPubKey[i]) {
00925 return (SupportedPubKeys)i;
00926 }
00927 }
00928 }
00929 return Dh3072;
00930 }
00931
00932 SupportedSASTypes ZRtp::findBestSASType(ZrtpPacketHello *hello) {
00933
00934 int i;
00935 int ii;
00936 int num = hello->getNumSas();
00937
00938 if (num == 0) {
00939 return Libase32;
00940 }
00941 for (i = 0; i < NumSupportedSASTypes ; i++) {
00942 for (ii = 0; ii < num; ii++) {
00943 if (*(uint32_t*)hello->getSasType(ii) == *(uint32_t*)supportedSASType[i]) {
00944 return (SupportedSASTypes)i;
00945 }
00946 }
00947 }
00948 return Libase32;
00949 }
00950
00951 SupportedAuthLengths ZRtp::findBestAuthLen(ZrtpPacketHello *hello) {
00952
00953 int i;
00954 int ii;
00955 int num = hello->getNumAuth();
00956
00957 if (num == 0) {
00958 return AuthLen32;
00959 }
00960 for (i = 0; i < NumSupportedAuthLenghts ; i++) {
00961 for (ii = 0; ii < num; ii++) {
00962 if (*(uint32_t*)hello->getAuthLen(ii) == *(uint32_t*)supportedAuthLen[i]) {
00963 return (SupportedAuthLengths)i;
00964 }
00965 }
00966 }
00967 return AuthLen32;
00968 }
00969
00970 void ZRtp::computeHvi(ZrtpPacketDHPart* dh, ZrtpPacketHello *hello) {
00971
00972 unsigned char* data[3];
00973 unsigned int length[3];
00974
00975
00976
00977
00978 data[0] = (uint8_t*)dh->getHeaderBase();;
00979 length[0] = dh->getLength() * ZRTP_WORD_SIZE;
00980
00981 data[1] = (uint8_t*)hello->getHeaderBase();
00982 length[1] = hello->getLength() * ZRTP_WORD_SIZE;
00983
00984 data[2] = NULL;
00985 sha256(data, length, hvi);
00986 return;
00987 }
00988
00989 void ZRtp:: computeSharedSecretSet(ZIDRecord &zidRec) {
00990
00991
00992
00993
00994 uint8_t randBuf[RS_LENGTH];
00995 uint32_t macLen;
00996
00997 if (!zidRec.isRs1Valid()) {
00998 dhContext->random(randBuf, RS_LENGTH);
00999 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator,
01000 strlen(initiator), rs1IDi, &macLen);
01001 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder,
01002 strlen(responder), rs1IDr, &macLen);
01003 }
01004 else {
01005 hmac_sha256((unsigned char*)zidRec.getRs1(), RS_LENGTH,
01006 (unsigned char*)initiator, strlen(initiator),
01007 rs1IDi, &macLen);
01008 hmac_sha256((unsigned char*)zidRec.getRs1(), RS_LENGTH,
01009 (unsigned char*)responder, strlen(responder),
01010 rs1IDr, &macLen);
01011 }
01012
01013 if (!zidRec.isRs2Valid()) {
01014 dhContext->random(randBuf, RS_LENGTH);
01015 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator,
01016 strlen(initiator), rs2IDi, &macLen);
01017 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder,
01018 strlen(responder), rs2IDr, &macLen);
01019 }
01020 else {
01021 hmac_sha256((unsigned char*)zidRec.getRs2(), RS_LENGTH,
01022 (unsigned char*)initiator, strlen(initiator),
01023 rs2IDi, &macLen);
01024 hmac_sha256((unsigned char*)zidRec.getRs2(), RS_LENGTH,
01025 (unsigned char*)responder, strlen(responder),
01026 rs2IDr, &macLen);
01027 }
01028
01029
01030
01031
01032
01033
01034 dhContext->random(randBuf, RS_LENGTH);
01035 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator,
01036 strlen(initiator), sigsIDi, &macLen);
01037 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder,
01038 strlen(responder), sigsIDr, &macLen);
01039
01040 dhContext->random(randBuf, RS_LENGTH);
01041 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator,
01042 strlen(initiator), srtpsIDi, &macLen);
01043 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder,
01044 strlen(responder), srtpsIDr, &macLen);
01045
01046 dhContext->random(randBuf, RS_LENGTH);
01047 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator,
01048 strlen(initiator), otherSecretIDi, &macLen);
01049 hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder,
01050 strlen(responder), otherSecretIDr, &macLen);
01051 }
01052
01053
01054
01055
01056
01057
01058 void ZRtp::generateS0Initiator(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec) {
01059 const uint8_t* setD[5];
01060 int32_t rsFound = 0;
01061
01062 setD[0] = setD[1] = setD[2] = setD[3] = setD[4] = NULL;
01063
01064
01065
01066
01067 int matchingSecrets = 0;
01068 if (memcmp(rs1IDr, dhPart->getRs1Id(), 8) == 0) {
01069 DEBUGOUT((fprintf(stdout, "%c: Match for Rs1 found\n", zid[0])));
01070 setD[matchingSecrets++] = zidRec.getRs1();
01071 rsFound = 0x1;
01072 }
01073 if (memcmp(rs2IDr, dhPart->getRs2Id(), 8) == 0) {
01074 DEBUGOUT((fprintf(stdout, "%c: Match for Rs2 found\n", zid[0])));
01075 setD[matchingSecrets++] = zidRec.getRs2();
01076 rsFound |= 0x2;
01077 }
01078 if (memcmp(sigsIDr, dhPart->getSigsId(), 8) == 0) {
01079 DEBUGOUT((fprintf(stdout, "%c: Match for SigS found\n", zid[0])));
01080 setD[matchingSecrets++] = zidRec.getRs2();
01081 }
01082 if (memcmp(srtpsIDr, dhPart->getSrtpsId(), 8) == 0) {
01083 DEBUGOUT((fprintf(stdout, "%c: Match for Srtps found\n", zid[0])));
01084 setD[matchingSecrets++] = zidRec.getRs2();
01085 }
01086 if (memcmp(otherSecretIDr, dhPart->getOtherSecretId(), 8) == 0) {
01087 DEBUGOUT((fprintf(stdout, "%c: Match for Other_secret found\n", zid[0])));
01088 setD[matchingSecrets++] = zidRec.getRs2();
01089 }
01090
01091
01092 if (rsFound == 0) {
01093 sendInfo(Warning, "No retained secret matches - verify SAS");
01094 }
01095 if ((rsFound & 0x1) && (rsFound & 0x2)) {
01096 sendInfo(Info, "Both retained secrets match - security OK");
01097 }
01098