Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

ZRtp.cxx

Go to the documentation of this file.
00001 /*
00002   Copyright (C) 2006-2007 Werner Dittmann
00003 
00004   This program is free software: you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation, either version 3 of the License, or
00007   (at your option) any later version.
00008 
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details.
00013 
00014   You should have received a copy of the GNU General Public License
00015   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 */
00017 
00018 /*
00019  * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
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  * This method simplifies detection of libzrtpcpp inside Automake, configure
00050  * and friends
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(); // prepare for Initiator case
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      * Clear the Initiator's srtp key and salt
00107      */
00108     memset(srtpKeyI, 0, SHA256_DIGEST_LENGTH);
00109     memset(srtpSaltI, 0,  SHA256_DIGEST_LENGTH);
00110     /*
00111      * Clear he Responder's srtp key and salt
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      * If we need to stop the state engine before we reached SecureState
00182      * reset to initial state only. This state ignores any event except
00183      * ZrtpInitial and effectively stops the engine.
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  * At this point we will assume the role of Initiator. This role may change
00207  * in case we have a commit-clash. Refer to chapter 5.2 in the spec how
00208  * to break this tie.
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     // Save our peer's (presumably the Responder) ZRTP id
00220     uint8_t* cid = hello->getClientId();
00221     memcpy(peerZid, hello->getZid(), 12);
00222     if (memcmp(peerZid, zid, 12) == 0) {       // peers have same ZID????
00223         *errMsg = EqualZIDHello;
00224         sendInfo(Error, "Received Hello packet with same ZID.");
00225         return NULL;
00226     }
00227 
00228     /*
00229      * The Following section extracts the algorithm from the Hello
00230      * packet. Always the best possible (offered) algorithms are
00231      * used.
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     // Generate the DH data and keys regarding the selected DH algorithm
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         // Error - shouldn't happen
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     // Prepare IV data that we will use during confirm packet encryption. 
00293     // This is done in advance to that we can destroy the DH data at the 
00294     // earliest posible time.
00295     dhContext->random(randomIV, sizeof(randomIV));
00296 
00297     /*
00298      * Prepare our DHPart2 packet here. Required to compute HVI. If we stay
00299      * in Initiator role then we reuse this packet later in prepareDHPart2().
00300      * To create this DH packet we have to compute the retained secret ids
00301      * first. Thus get our peer's retained secret data first.
00302      */
00303     ZIDRecord zidRec(peerZid);
00304     ZIDFile *zidFile = ZIDFile::getInstance();
00305     zidFile->getRecord(&zidRec);
00306 
00307     //Compute the Initator's and Responder's retained secret ids.
00308     computeSharedSecretSet(zidRec);
00309 
00310     // Construct a DHPart2 message (Initiator's DH message). This packet
00311     // is required to compute the HVI (Hash Value Initiator).
00312     zpDH2 = new ZrtpPacketDHPart(pubKey);
00313 
00314     // Fill the values in the DHPart2 packet
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     // Compute the HVI, refer to chapter 5.4.1 of the specification
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     // hash first messages to produce overall message hash
00336     // First the Responder's Hello message, second the Commit 
00337     // (always Initator's)
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  * At this point we will take the role of the Responder. We may have been in 
00345  * the role of the Initiator before and already sent a commit packet that
00346  * clashed with a commit packet from our peer. If our HVI was lower than out
00347  * peer's HVI the we switched to Responder and handle our peer's commit packet
00348  * here. This method takes care to delete and refresh data left over from a
00349  * possible Initiator preparation. This belongs to a prepared DHPart2 packet,
00350  * DH data, message hash SHA context
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     // check if we support the commited Cipher type
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) { // no match - something went wrong
00366         *errMsg = UnsuppCiphertype;
00367         sendInfo(Alert, "Cannot find a supported Cipher in Commit message");
00368         return NULL;
00369     }
00370     cipher = (SupportedSymCiphers)i;
00371 
00372     // check if we support the commited Authentication length
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) { // no match - something went wrong
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     // check if we support the commited hash type
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) { // no match - something went wrong
00394         *errMsg = UnsuppHashType;
00395         sendInfo(Alert, "Cannot find a supported Hash in Commit message");
00396         return NULL;
00397     }
00398     hash = (SupportedHashes)i;
00399 
00400     // check if we support the commited pub key type
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) { // no match - something went wrong
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     // check if we support the commited SAS type
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) { // no match - something went wrong
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         // generate a warning
00433     }
00434 
00435     // check if a cleanup is required 
00436     if (dhContext != NULL) {
00437         delete dhContext;
00438         dhContext = NULL;
00439     }
00440     // setup the DH context and generate a fresh DH key pair
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         // Error - shouldn't happen
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      * If a DH2 packet was computed then also the retained secret ids were
00472      * computed. This maybe a leftover acting as Initiator. Delete the DH2
00473      * packet only and keep the computed retained secretd ids. 
00474      * If no DH2 packet exists just compute the reteined secrets.
00475      */
00476     if (zpDH2 != NULL) {        // DH2 and retained secrets already computed but
00477         delete zpDH2;           // we are responder, DH2 packet not needed anymore
00478         zpDH2 = NULL;
00479     }
00480     else {                      // need to compute retained secrets
00481         // We may have not received a Hello at all at this point .
00482         // Set our peer's ZID
00483         memcpy(peerZid, commit->getZid(), 12);
00484 
00485         // prepare IV data that we will use during confirm packet handling.
00486         // if a DH2 packet was created then we switched roles and an IV was
00487         // already generated (see prepareCommit() )
00488         dhContext->random(randomIV, sizeof(randomIV));
00489 
00490         // Initialize a ZID record to get retained secrets for this peer
00491         ZIDRecord zidRec(peerZid);      
00492         ZIDFile *zid = ZIDFile::getInstance();
00493         zid->getRecord(&zidRec);
00494 
00495         /*
00496          * Compute the shared Secret Ids. Because here we are responder the real
00497          * keys, salt, and HAMACS are computed after we got the DHPart2.
00498          */
00499         computeSharedSecretSet(zidRec);
00500     }
00501 
00502     // Construct and setup a DHPart1 packet.
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     // We are definitly responder. Save the peer's hvi for later compare.
00513     myRole = Responder;
00514     memcpy(peerHvi, commit->getHvi(), SHA256_DIGEST_LENGTH);
00515 
00516     // Because we are responder close a possibly pre-computed SHA256 context
00517     // because this was prepared for Initiator. Then create a new one.
00518     if (msgShaContext != NULL) {
00519         closeSha256Context(msgShaContext, NULL);
00520     }
00521     msgShaContext = createSha256Context();
00522 
00523     // Hash messages to produce overall message hash:
00524     // First the Responder's (my) Hello message, second the Commit 
00525     // (always Initator's), then the DH1 message (which is always a 
00526     // Responder's message)
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  * At this point we will take the role of the Initiator.
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     // get memory to store DH result TODO: make it fixed memory
00548     DHss = (uint8_t*)malloc(dhContext->getSecretSize());
00549     if (DHss == NULL) {
00550         sendInfo(Error, "Out of memory");       // serious error
00551         return NULL;
00552     }
00553 
00554     // get and check Responder's public value, see chap. 5.4.3 in the spec
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     // Get precomputed DHPart2 packet and set internal pointer to NULL. The
00574     // DHPart2 packet is handed over to ZrtpStateClass. The method 
00575     // evWaitConfirm1() deletes this packet after it was sent to our peer.
00576     ZrtpPacketDHPart *zpDH = zpDH2;
00577     zpDH2 = NULL;
00578 
00579     myRole = Initiator;
00580 
00581     // We are Inititaor: the Responder's Hello and the Initiator's (our) Commit
00582     // are already hashed in the context. Now hash the Responder's DH1 and then
00583     // the Initiator's (our) DH2 in that order.
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     // Compute the message Hash
00588     closeSha256Context(msgShaContext, messageHash);
00589     msgShaContext = NULL;
00590 
00591     // To compute the S0 for the Initiator we need the retained secrets of our
00592     // peer. Get them from the storage.
00593     ZIDRecord zidRec(peerZid);
00594     ZIDFile *zid = ZIDFile::getInstance();
00595     zid->getRecord(&zidRec);
00596 
00597     // Now compute the S0, all dependend keys and the new RS1
00598     generateS0Initiator(dhPart1, zidRec);
00599     delete dhContext;
00600     dhContext = NULL;
00601 
00602     return zpDH;
00603 }
00604 
00605 /*
00606  * At this point we are Responder.
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     // TODO: fixed memory
00616     DHss = (uint8_t*)malloc(dhContext->getSecretSize());
00617     if (DHss == NULL) {
00618         // serious error
00619         return NULL;
00620     }
00621 
00622     // Get and check the Initiator's public value, see chap. 5.4.2 of the spec
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     // Now we have the peer's pvi. Because we are responder re-compute my hvi
00642     // using my Hello packet and the Initiator's DHPart2 and compare with
00643     // hvi sent in commit packet. If it doesn't macht then a MitM attack
00644     // may have occured.
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     // Hash the Initiator's DH2 into the message Hash (other messages already
00652     // prepared, see method prepareDHPart1().
00653     sha256Ctx(msgShaContext, (unsigned char*)dhPart2->getHeaderBase(),
00654               dhPart2->getLength() * ZRTP_WORD_SIZE);
00655 
00656     closeSha256Context(msgShaContext, messageHash);
00657     msgShaContext = NULL;
00658 
00659     // To compute the S0 for the Initiator we need the retained secrets of our
00660     // peer. Get them from the storage.
00661     ZIDRecord zidRec(peerZid);
00662     ZIDFile *zid = ZIDFile::getInstance();
00663     zid->getRecord(&zidRec);
00664 
00665     /*
00666      * The expected shared secret Ids were already computed when we built the
00667      * DHPart1 packet. Generate s0, all depended keys, and the new RS1 value
00668      * for the ZID record.
00669      */
00670     generateS0Responder(dhPart2, zidRec);
00671 
00672     delete dhContext;
00673     dhContext = NULL;
00674 
00675     // Create a Confirm1 packet and fill it.
00676     ZrtpPacketConfirm* zpConf = new ZrtpPacketConfirm(static_cast<uint8_t>(0));
00677     zpConf->setMessageType((uint8_t*)Confirm1Msg);
00678 
00679     // Check if user verfied the SAS in a previous call and thus verfied
00680     // the retained secret.
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     // Encrypt and HMAC with Responder's key - we are Respondere here
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     // Use the Responder's keys here because we are Initiator here and
00709     // receive packets from Responder
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      * The Confirm1 is ok, handle the Retained secret stuff and inform
00724      * GUI about state.
00725      */
00726     bool sasFlag = confirm1->isSASFlag();
00727 
00728     // Initialize a ZID record to get peer's retained secrets
00729     ZIDRecord zidRec(peerZid);
00730 
00731     ZIDFile *zid = ZIDFile::getInstance();
00732     zid->getRecord(&zidRec);
00733 
00734     // Our peer did not confirm the SAS in last session, thus reset
00735     // our SAS flag too.
00736     if (!sasFlag) {
00737       zidRec.resetSasVerified();
00738     }
00739 
00740     // get verified flag from current RS1 before set a new RS1. This
00741     // may not be set even if peer's flag is set in confirm1 message.
00742     sasFlag = zidRec.isSasVerified() ? true : false;
00743 
00744     // Inform GUI about security state and SAS state
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     // now we are ready to save the new RS1 which inherits the verified
00750     // flag from old RS1
00751     zidRec.setNewRs1((const uint8_t*)newRs1);
00752     zid->saveRecord(&zidRec);
00753 
00754     // now generate my Confirm2 message
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     // Encrypt and HMAC with Initiator's key - we are Initiator here
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     // Use the Initiator's keys here because we are Responder here and
00782     // reveice packets from Initiator
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      * The Confirm2 is ok, handle the Retained secret stuff and inform
00798      * GUI about state.
00799      */
00800     bool sasFlag = confirm2->isSASFlag();
00801 
00802     // Initialize a ZID record to get peer's retained secrets
00803     ZIDRecord zidRec(peerZid);
00804 
00805     ZIDFile *zid = ZIDFile::getInstance();
00806     zid->getRecord(&zidRec);
00807 
00808     // Our peer did not confirm the SAS in last session, thus reset
00809     // our SAS flag too.
00810     if (!sasFlag) {
00811       zidRec.resetSasVerified();
00812     }
00813 
00814     // Inform GUI about security state and SAS state
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     // save new RS1, this inherits the verified flag from old RS1
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 // TODO Implement GoClear handling
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  * The next functions look up and return a prefered algorithm. These
00859  * functions work as follows:
00860  * - If the Hello packet does not contain an algorithm (number of algorithms is
00861  *   zero) then return our prefered algorithm. This prefered algorithm must be
00862  *   one of the mandatory algorithms specified in chapter 6.1.x.
00863  * - If the functions find a match return the found algorithm.
00864  * - If the functions do not find a match return a prefered, mandatory
00865  *   algorithm.
00866  * This guarantees that we always return a supported alogrithm.
00867  *
00868  * The mandatory algorithms are: (internal enums are our prefered algoritms)
00869  * Hash:                S256 (SHA 256)             (internal enum Sha256)
00870  * Symmetric Cipher:    AES1 (AES 128)             (internal enum Aes128)
00871  * SRTP Authentication: HS32 and HS80 (32/80 bits) (internal enum AuthLen32)
00872  * Key Agreement:       DH3k (3072 Diffie-Helman)  (internal enum Dh3072)
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      * populate the vector to compute the HVI hash according to the
00976      * ZRTP specification.
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;            // terminate data chunks
00985     sha256(data, length, hvi);
00986     return;
00987 }
00988 
00989 void ZRtp:: computeSharedSecretSet(ZIDRecord &zidRec) {
00990 
00991    /*
00992     * Compute the Initiator's and Reponder's retained shared secret Ids.
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     * For the time being we don't support these types of shared secrect. Could be
01031     * easily done: somebody sets some data into our ZRtp object, check it here
01032     * and use it. Otherwise use the random data.
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  * The DH packet for this function is DHPart1 and contains the Responder's
01055  * retained secret ids. Compare them with the expected secret ids (refer
01056  * to chapter 5.3.2 in the specification).
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      * Select the real secrets into setD
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     // Check if some retained secrets found
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