|
Mixe for Privacy and Anonymity in the Internet
|
00001 /* 00002 Copyright (c) 2000, The JAP-Team 00003 All rights reserved. 00004 Redistribution and use in source and binary forms, with or without modification, 00005 are permitted provided that the following conditions are met: 00006 00007 - Redistributions of source code must retain the above copyright notice, 00008 this list of conditions and the following disclaimer. 00009 00010 - Redistributions in binary form must reproduce the above copyright notice, 00011 this list of conditions and the following disclaimer in the documentation and/or 00012 other materials provided with the distribution. 00013 00014 - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 00015 may be used to endorse or promote products derived from this software without specific 00016 prior written permission. 00017 00018 00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00027 */ 00028 #include "StdAfx.h" 00029 #include "CALocalProxy.hpp" 00030 #include "CASocketList.hpp" 00031 #include "CASocketGroup.hpp" 00032 #include "CAMsg.hpp" 00033 #include "CACmdLnOptions.hpp" 00034 #include "CAUtil.hpp" 00035 #include "CASocketAddrINet.hpp" 00036 #include "CABase64.hpp" 00037 #include "CALibProxytest.hpp" 00038 #include "xml/DOM_Output.hpp" 00039 #ifndef NEW_MIX_TYPE 00040 00041 // signals the main loop whether to capture or replay packets 00042 bool CALocalProxy::bCapturePackets; 00043 bool CALocalProxy::bReplayPackets; 00044 int CALocalProxy::iCapturedPackets; 00045 00046 // Signal handler for SIGUSR1. 00047 // This starts the capture with the next channel-open message. 00048 void SIGUSR1_handler(int signum) 00049 { 00050 CAMsg::printMsg(LOG_DEBUG,"Starting to capture packets for replay attack.\n"); 00051 CALocalProxy::bCapturePackets = true; 00052 CALocalProxy::iCapturedPackets = 0; 00053 } 00054 00055 // Signal handler for SIGUSR2. 00056 // This replays the currently captured packets. 00057 void SIGUSR2_handler(int signum) 00058 { 00059 CAMsg::printMsg(LOG_DEBUG,"Starting replay of packets.\n"); 00060 CALocalProxy::bReplayPackets = true; 00061 } 00062 00063 00064 SINT32 CALocalProxy::start() 00065 { 00066 if(initOnce()!=E_SUCCESS) 00067 return E_UNKNOWN; 00068 for(;;) 00069 { 00070 CAMsg::printMsg(LOG_DEBUG, "CALocalProxy main: before init()\n"); 00071 if(init() == E_SUCCESS) 00072 { 00073 CAMsg::printMsg(LOG_DEBUG, "CALocalProxy main: init() returned success\n"); 00074 CAMsg::printMsg(LOG_INFO, "The local proxy is now on-line.\n"); 00075 loop(); 00076 CAMsg::printMsg(LOG_DEBUG, "CAMix local proxy: loop() returned, maybe connection lost.\n"); 00077 } 00078 else 00079 { 00080 CAMsg::printMsg(LOG_DEBUG, "init() failed, maybe no connection.\n"); 00081 } 00082 00083 CAMsg::printMsg(LOG_DEBUG, "CALocalProxy main: before clean()\n"); 00084 clean(); 00085 CAMsg::printMsg(LOG_DEBUG, "CAMix LocalProxy: after clean()\n"); 00086 sSleep(20); 00087 } 00088 } 00089 00090 00091 SINT32 CALocalProxy::initOnce() 00092 { 00093 if(CALibProxytest::getOptions()->getListenerInterfaceCount()<1) 00094 { 00095 CAMsg::printMsg(LOG_CRIT,"No Listener Interface spezified!\n"); 00096 return E_UNKNOWN; 00097 } 00098 00099 bCapturePackets = bReplayPackets = false; 00100 #if defined(REPLAY_DETECTION)&&!defined(_WIN32) 00101 // Set up signal handling for the replay attack. 00102 signal(SIGUSR1, SIGUSR1_handler); 00103 signal(SIGUSR2, SIGUSR2_handler); 00104 #endif 00105 00106 UINT8 strTarget[255]; 00107 if(CALibProxytest::getOptions()->getMixHost(strTarget,255)!=E_SUCCESS) 00108 { 00109 CAMsg::printMsg(LOG_CRIT,"No AnonServer specified!\n"); 00110 return E_UNKNOWN; 00111 } 00112 return E_SUCCESS; 00113 } 00114 00115 SINT32 CALocalProxy::init() 00116 { 00117 CAListenerInterface* pListener; 00118 m_nFlowControlDownstreamSendMe=FLOW_CONTROL_SENDME_SOFT_LIMIT; 00119 m_bWithNewFlowControl=false; 00120 m_bWithEnhancedChannelEncryption=false; 00121 m_bWithFirstMixSymmetric=false; 00122 m_socketIn.create(); 00123 m_socketIn.setReuseAddr(true); 00124 pListener=CALibProxytest::getOptions()->getListenerInterface(1); 00125 if(pListener==NULL) 00126 { 00127 CAMsg::printMsg(LOG_CRIT,"No listener specified\n"); 00128 return E_UNKNOWN; 00129 } 00130 CASocketAddrINet* pSocketAddrIn=(CASocketAddrINet*)pListener->getAddr(); 00131 delete pListener; 00132 pListener = NULL; 00133 if(pSocketAddrIn->isAnyIP()) 00134 pSocketAddrIn->setAddr((UINT8*)"127.0.0.1",pSocketAddrIn->getPort()); 00135 if(m_socketIn.listen(*pSocketAddrIn)!=E_SUCCESS) 00136 { 00137 CAMsg::printMsg(LOG_CRIT,"Cannot listen (1)\n"); 00138 delete pSocketAddrIn; 00139 pSocketAddrIn = NULL; 00140 return E_UNKNOWN; 00141 } 00142 delete pSocketAddrIn; 00143 pSocketAddrIn = NULL; 00144 /* if(CALibProxytest::getOptions()->getSOCKSServerPort()!=(UINT16)-1) 00145 { 00146 socketAddrIn.setAddr((UINT8*)"127.0.0.1",CALibProxytest::getOptions()->getSOCKSServerPort()); 00147 m_socketSOCKSIn.create(); 00148 m_socketSOCKSIn.setReuseAddr(true); 00149 if(m_socketSOCKSIn.listen(socketAddrIn)!=E_SUCCESS) 00150 { 00151 CAMsg::printMsg(LOG_CRIT,"Cannot listen (2)\n"); 00152 return E_UNKNOWN; 00153 } 00154 }*/ 00155 CASocketAddrINet addrNext; 00156 UINT8 strTarget[255]; 00157 CALibProxytest::getOptions()->getMixHost(strTarget,255); 00158 addrNext.setAddr(strTarget,CALibProxytest::getOptions()->getMixPort()); 00159 CAMsg::printMsg(LOG_INFO,"Try connecting to next Mix...\n"); 00160 00161 m_muxOut.getCASocket()->create(); 00162 m_muxOut.getCASocket()->setSendBuff(MIXPACKET_SIZE*50); 00163 m_muxOut.getCASocket()->setRecvBuff(MIXPACKET_SIZE*50); 00164 if(m_muxOut.connect(addrNext)==E_SUCCESS) 00165 { 00166 CAMsg::printMsg(LOG_INFO," connected!\n"); 00167 UINT16 size; 00168 UINT8 byte; 00169 m_muxOut.getCASocket()->receiveFully((UINT8*)&size,2); 00170 m_muxOut.getCASocket()->receiveFully((UINT8*)&byte,1); 00171 CAMsg::printMsg(LOG_INFO,"Received Key Info!\n"); 00172 size=ntohs(size); 00173 #ifdef _DEBUG 00174 CAMsg::printMsg(LOG_INFO,"Key Info size is:%u\n",size); 00175 #endif 00176 if(byte=='<')//assuming XML 00177 { 00178 #ifdef _DEBUG 00179 CAMsg::printMsg(LOG_INFO,"Key Info is XML!\n"); 00180 #endif 00181 UINT8* buff=new UINT8[size+1]; 00182 buff[0]=byte; 00183 m_muxOut.getCASocket()->receiveFully(buff+1,size-1); 00184 buff[size]=0; 00185 #ifdef _DEBUG 00186 CAMsg::printMsg(LOG_INFO,"Key Info is:\n"); 00187 CAMsg::printMsg(LOG_INFO,"%s\n",buff); 00188 #endif 00189 SINT32 ret=processKeyExchange(buff,size); 00190 delete[] buff; 00191 buff = NULL; 00192 if(ret!=E_SUCCESS) 00193 return E_UNKNOWN; 00194 } 00195 else 00196 { 00197 return E_UNKNOWN; 00198 } 00199 return E_SUCCESS; 00200 } 00201 else 00202 { 00203 CAMsg::printMsg(LOG_CRIT,"Cannot connect to next Mix!\n"); 00204 return E_UNKNOWN; 00205 } 00206 } 00207 00208 SINT32 CALocalProxy::loop() 00209 { 00210 CASocketList oSocketList; 00211 CASocketGroup oSocketGroup(false); 00212 oSocketGroup.add(m_socketIn); 00213 UINT16 socksPort=CALibProxytest::getOptions()->getSOCKSServerPort(); 00214 bool bHaveSocks=(socksPort!=0xFFFF); 00215 if(bHaveSocks) 00216 oSocketGroup.add(m_socketSOCKSIn); 00217 oSocketGroup.add(m_muxOut); 00218 MIXPACKET* pMixPacket=new MIXPACKET; 00219 00220 memset(pMixPacket,0,MIXPACKET_SIZE); 00221 SINT32 len,ret; 00222 CASocket* newSocket;//,*tmpSocket; 00223 CASymCipher* newCipher; 00224 int countRead; 00225 CONNECTION oConnection; 00226 00227 // Temporary storage for packets that could be replayed. 00228 MIXPACKET* pReplayMixPackets=new MIXPACKET[REPLAY_COUNT]; 00229 memset(pReplayMixPackets,0,MIXPACKET_SIZE*REPLAY_COUNT); 00230 // channel ID from which packets are captured 00231 unsigned uCapturedChannel = 0; 00232 00233 00234 for(;;) 00235 { 00236 // Add timeout to select to allow for a replay attack to take place. 00237 if((countRead=oSocketGroup.select(100))==SOCKET_ERROR) 00238 { 00239 sSleep(1); 00240 continue; 00241 } 00242 00243 // Start a replay attack, if a packet is present 00244 if(bReplayPackets) 00245 { 00246 if(iCapturedPackets > 0) 00247 { 00248 for(int i = 0; i < iCapturedPackets; i++) 00249 { 00250 memcpy(pMixPacket,&pReplayMixPackets[i],MIXPACKET_SIZE); 00251 CAMsg::printMsg(LOG_DEBUG,"Replaying packet #%d: %X %X %X %X\n", (i+1), *pMixPacket->data, *(pMixPacket->data+1), *(pMixPacket->data+2), *(pMixPacket->data+3)); 00252 if(m_muxOut.send(pMixPacket)==SOCKET_ERROR) 00253 { 00254 CAMsg::printMsg(LOG_CRIT,"Mux-Channel Sending Data Error - Exiting!\n"); 00255 ret=E_UNKNOWN; 00256 goto MIX_CONNECTION_ERROR; 00257 } 00258 } 00259 memset(pMixPacket,0,MIXPACKET_SIZE); 00260 } 00261 else 00262 { 00263 CAMsg::printMsg(LOG_DEBUG,"No captured packets found.\n"); 00264 } 00265 CAMsg::printMsg(LOG_DEBUG,"Replay finished.\n"); 00266 bReplayPackets = false; 00267 } 00268 00269 if(oSocketGroup.isSignaled(m_socketIn)) 00270 { 00271 countRead--; 00272 #ifdef _DEBUG 00273 CAMsg::printMsg(LOG_DEBUG,"New Connection from Browser!\n"); 00274 #endif 00275 newSocket=new CASocket; 00276 if(m_socketIn.accept(*newSocket)!=E_SUCCESS) 00277 { 00278 #ifdef _DEBUG 00279 CAMsg::printMsg(LOG_DEBUG,"Accept Error - Connection from Browser!\n"); 00280 #endif 00281 delete newSocket; 00282 newSocket = NULL; 00283 } 00284 else 00285 { 00286 newCipher=new CASymCipher[m_chainlen]; 00287 oSocketList.add(newSocket,newCipher); 00288 oSocketGroup.add(*newSocket); 00289 } 00290 } 00291 if(bHaveSocks&&oSocketGroup.isSignaled(m_socketSOCKSIn)) 00292 { 00293 countRead--; 00294 #ifdef _DEBUG 00295 CAMsg::printMsg(LOG_DEBUG,"New Connection from SOCKS!\n"); 00296 #endif 00297 newSocket=new CASocket; 00298 if(m_socketSOCKSIn.accept(*newSocket)!=E_SUCCESS) 00299 { 00300 #ifdef _DEBUG 00301 CAMsg::printMsg(LOG_DEBUG,"Accept Error - Connection from SOCKS!\n"); 00302 #endif 00303 delete newSocket; 00304 newSocket = NULL; 00305 } 00306 else 00307 { 00308 newCipher=new CASymCipher[m_chainlen]; 00309 oSocketList.add(newSocket,newCipher); 00310 oSocketGroup.add(*newSocket); 00311 } 00312 } 00313 //Recevie from next Mix 00314 if(oSocketGroup.isSignaled(m_muxOut)) 00315 { 00316 countRead--; 00317 ret=m_muxOut.receive(pMixPacket); 00318 if(ret==SOCKET_ERROR) 00319 { 00320 CAMsg::printMsg(LOG_CRIT,"Mux-Channel Receiving Data Error - Exiting!\n"); 00321 ret=E_UNKNOWN; 00322 goto MIX_CONNECTION_ERROR; 00323 } 00324 00325 if(oSocketList.get(pMixPacket->channel,&oConnection)==E_SUCCESS) 00326 { 00327 if(pMixPacket->flags==CHANNEL_CLOSE) 00328 { 00329 #ifdef _DEBUG 00330 CAMsg::printMsg(LOG_DEBUG,"Closing Channel: %u ... ",pMixPacket->channel); 00331 #endif 00332 /*tmpSocket=*/oSocketList.remove(pMixPacket->channel); 00333 if(oConnection.pSocket!=NULL) 00334 { 00335 oSocketGroup.remove(*oConnection.pSocket); 00336 oConnection.pSocket->close(); 00337 #ifdef _DEBUG 00338 CAMsg::printMsg(LOG_DEBUG,"closed!\n"); 00339 #endif 00340 delete oConnection.pSocket; 00341 oConnection.pSocket = NULL; 00342 delete [] oConnection.pCiphers; 00343 oConnection.pCiphers = NULL; 00344 00345 // stop capturing packets when the channel is closed 00346 if(pMixPacket->channel == uCapturedChannel) 00347 { 00348 CAMsg::printMsg(LOG_DEBUG,"Stopping to capture packets.\n"); 00349 bCapturePackets = false; 00350 } 00351 } 00352 } 00353 else 00354 { 00355 for(UINT32 c=0;c<m_chainlen;c++) 00356 oConnection.pCiphers[c].crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE); 00357 UINT32 truelen=ntohs(pMixPacket->payload.len); 00358 truelen=truelen&PAYLOAD_LEN_MASK; 00359 oConnection.pSocket->send(pMixPacket->payload.data,truelen); 00360 #ifdef _DEBUG 00361 CAMsg::printMsg(LOG_DEBUG,"Sending Data to Browser (%u bytes)!\n",truelen); 00362 #endif 00363 if(m_bWithNewFlowControl) 00364 { 00365 if(oConnection.currentSendMeCounter+1>=m_nFlowControlDownstreamSendMe) 00366 { 00367 //send a SEND_ME MixPacket 00368 pMixPacket->flags=CHANNEL_DATA; 00369 pMixPacket->channel=oConnection.outChannel; 00370 getRandom(pMixPacket->data,DATA_SIZE); 00371 pMixPacket->payload.len=htons(NEW_FLOW_CONTROL_FLAG); 00372 pMixPacket->payload.type=MIX_PAYLOAD_HTTP; 00373 for(UINT32 c=0;c<m_chainlen;c++) 00374 oConnection.pCiphers[c].crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE); 00375 m_muxOut.send(pMixPacket); 00376 #ifdef _DEBUG 00377 CAMsg::printMsg(LOG_DEBUG,"sent sendme!\n"); 00378 #endif 00379 oSocketList.addSendMeCounter(oConnection.outChannel,-(m_nFlowControlDownstreamSendMe-1)); 00380 } 00381 else 00382 { 00383 oSocketList.addSendMeCounter(oConnection.outChannel,1); 00384 } 00385 } 00386 } 00387 } 00388 } 00389 if(countRead>0) 00390 { 00391 CONNECTION* tmpCon; 00392 tmpCon=oSocketList.getFirst(); 00393 while(tmpCon!=NULL&&countRead>0) 00394 { 00395 if(oSocketGroup.isSignaled(*tmpCon->pSocket)) 00396 { 00397 countRead--; 00398 getRandom(pMixPacket->payload.data,PAYLOAD_SIZE); 00399 if(!tmpCon->pCiphers[0].isKeyValid()) 00400 len=tmpCon->pSocket->receive(pMixPacket->payload.data,PAYLOAD_SIZE-m_chainlen*m_SymChannelEncryptedKeySize); 00401 else 00402 len=tmpCon->pSocket->receive(pMixPacket->payload.data,PAYLOAD_SIZE); 00403 if(len==SOCKET_ERROR||len==0) 00404 { 00405 CAMsg::printMsg(LOG_DEBUG,"client side close channel - upstream sent: %u\n",tmpCon->upstreamBytes); 00406 CASocket* tmpSocket=oSocketList.remove(tmpCon->outChannel); 00407 if(tmpSocket!=NULL) 00408 { 00409 oSocketGroup.remove(*tmpSocket); 00410 pMixPacket->flags=CHANNEL_CLOSE; 00411 pMixPacket->channel=tmpCon->outChannel; 00412 getRandom(pMixPacket->data,DATA_SIZE); 00413 m_muxOut.send(pMixPacket); 00414 tmpSocket->close(); 00415 delete tmpSocket; 00416 tmpSocket = NULL; 00417 delete [] tmpCon->pCiphers; 00418 tmpCon->pCiphers = NULL; 00419 } 00420 } 00421 else 00422 { 00423 pMixPacket->channel=tmpCon->outChannel; 00424 tmpCon->upstreamBytes+=len; 00425 pMixPacket->payload.len=htons((UINT16)len); 00426 if(bHaveSocks&&tmpCon->pSocket->getLocalPort()==socksPort) 00427 { 00428 pMixPacket->payload.type=MIX_PAYLOAD_SOCKS; 00429 } 00430 else 00431 { 00432 pMixPacket->payload.type=MIX_PAYLOAD_HTTP; 00433 } 00434 if(!tmpCon->pCiphers[0].isKeyValid()) //First time --> rsa key 00435 { 00436 //Has to bee optimized!!!! 00437 UINT8 buff[DATA_SIZE]; 00438 //UINT32 size=DATA_SIZE-KEY_SIZE; 00439 //tmpCon->pCipher->generateEncryptionKey(); //generate Key 00440 for(UINT32 c=0;c<m_chainlen;c++) 00441 { 00442 getRandom(buff,m_SymChannelKeySize); 00443 buff[0]&=0x7F; // Hack for RSA to ensure m < n !!!!! 00444 tmpCon->pCiphers[c].setKeys(buff,m_SymChannelKeySize); 00445 /* 00446 PROTOCOL CHANGE: 00447 This is a change in the protocol between JAP and the mixes: 00448 In the RSA encrypted part of the channel-open packet apart 00449 from the symmetric key for each mix, we now include a 00450 TIMESTAMP_SIZE bytes wide timestamp. This reduces the storage 00451 space for symmetrical keys in the RSA_SIZE wide part of the 00452 packet (from 8 to 7). 00453 */ 00454 #ifdef WITH_TIMESTAMP 00455 //TODO insert timesampt 00456 //currentTimestamp(buff+KEY_SIZE,true); 00457 #endif 00458 if(m_bWithFirstMixSymmetric&&c==m_chainlen-1) 00459 { 00460 memcpy(buff+m_SymChannelKeySize,pMixPacket->data,DATA_SIZE-m_SymChannelKeySize); 00461 m_pSymCipher->crypt1(buff,buff,m_SymChannelKeySize); 00462 UINT8 iv[16]; 00463 memset(iv,0xFF,16); 00464 tmpCon->pCiphers[c].setIV2(iv); 00465 tmpCon->pCiphers[c].crypt1(buff+m_SymChannelKeySize,buff+m_SymChannelKeySize,DATA_SIZE-m_SymChannelKeySize); 00466 } 00467 else 00468 { 00469 memcpy(buff+m_SymChannelKeySize,pMixPacket->data,DATA_SIZE-m_SymChannelEncryptedKeySize); 00470 if(m_bWithEnhancedChannelEncryption) 00471 { 00472 UINT8 tmpBuff[1000]; 00473 UINT32 lk=1000; 00474 m_arRSA[c].encryptOAEP(buff,128-42,tmpBuff,&lk); 00475 tmpCon->pCiphers[c].crypt1(buff+RSA_SIZE-42,tmpBuff+RSA_SIZE,DATA_SIZE-RSA_SIZE); 00476 memcpy(buff,tmpBuff,DATA_SIZE); 00477 } 00478 else 00479 { 00480 m_arRSA[c].encrypt(buff,buff); 00481 tmpCon->pCiphers[c].crypt1(buff+RSA_SIZE,buff+RSA_SIZE,DATA_SIZE-RSA_SIZE); 00482 } 00483 // Does RSA_SIZE need to be increased by RSA_SIZE/KEY_SIZE*TIMESTAMP_SIZE? 00484 } 00485 memcpy(pMixPacket->data,buff,DATA_SIZE); 00486 //size-=KEY_SIZE; 00487 //len+=KEY_SIZE; 00488 } 00489 pMixPacket->flags=CHANNEL_OPEN; 00490 } 00491 else //sonst 00492 { 00493 for(UINT32 c=0;c<m_chainlen;c++) 00494 tmpCon->pCiphers[c].crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE); 00495 pMixPacket->flags=CHANNEL_DATA; 00496 } 00497 00498 // Capture the this packet for future replay 00499 if(bCapturePackets) 00500 { 00501 if(!iCapturedPackets && (pMixPacket->flags == CHANNEL_OPEN)) 00502 { 00503 CAMsg::printMsg(LOG_DEBUG,"Captured channel-open packet: %X %X %X %X\n", *pMixPacket->data, *(pMixPacket->data+1), *(pMixPacket->data+2), *(pMixPacket->data+3)); 00504 memcpy(&pReplayMixPackets[iCapturedPackets++],pMixPacket,MIXPACKET_SIZE); 00505 uCapturedChannel = pMixPacket->channel; 00506 } 00507 else if(iCapturedPackets && (uCapturedChannel == pMixPacket->channel)) 00508 { 00509 CAMsg::printMsg(LOG_DEBUG,"Captured data packet: %X %X %X %X\n", *pMixPacket->data, *(pMixPacket->data+1), *(pMixPacket->data+2), *(pMixPacket->data+3)); 00510 memcpy(&pReplayMixPackets[iCapturedPackets++],pMixPacket,MIXPACKET_SIZE); 00511 } 00512 } 00513 if(iCapturedPackets >= REPLAY_COUNT) 00514 { 00515 CAMsg::printMsg(LOG_DEBUG,"Storage full, stopping to capture packets.\n"); 00516 bCapturePackets = false; 00517 } 00518 00519 if(m_muxOut.send(pMixPacket)==SOCKET_ERROR) 00520 { 00521 CAMsg::printMsg(LOG_CRIT,"Mux-Channel Sending Data Error - Exiting!\n"); 00522 ret=E_UNKNOWN; 00523 goto MIX_CONNECTION_ERROR; 00524 } 00525 } 00526 break; 00527 } 00528 tmpCon=oSocketList.getNext(); 00529 } 00530 } 00531 } 00532 MIX_CONNECTION_ERROR: 00533 CONNECTION* tmpCon=oSocketList.getFirst(); 00534 while(tmpCon!=NULL) 00535 { 00536 delete [] tmpCon->pCiphers; 00537 tmpCon->pCiphers = NULL; 00538 delete tmpCon->pSocket; 00539 tmpCon->pSocket = NULL; 00540 tmpCon=tmpCon->next; 00541 } 00542 delete pMixPacket; 00543 pMixPacket = NULL; 00544 if(ret==E_SUCCESS) 00545 return E_SUCCESS; 00546 if(CALibProxytest::getOptions()->getAutoReconnect()) 00547 return E_UNKNOWN; 00548 else 00549 exit(-1); 00550 } 00551 00552 SINT32 CALocalProxy::clean() 00553 { 00554 m_socketIn.close(); 00555 m_socketSOCKSIn.close(); 00556 m_muxOut.close(); 00557 00558 delete[] m_arRSA; 00559 m_arRSA=NULL; 00560 00561 delete m_pSymCipher; 00562 m_pSymCipher=NULL; 00563 00564 return E_SUCCESS; 00565 } 00566 00567 SINT32 CALocalProxy::processKeyExchange(UINT8* buff,UINT32 len) 00568 { 00569 m_SymChannelEncryptedKeySize=16; 00570 m_SymChannelKeySize=16; 00571 CAMsg::printMsg(LOG_INFO,"Login process and key exchange started...\n"); 00572 //Parsing KeyInfo received from Mix n+1 00573 XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(buff,len); 00574 if(doc==NULL) 00575 { 00576 CAMsg::printMsg(LOG_INFO,"Error parsing Key Info from Mix!\n"); 00577 return E_UNKNOWN; 00578 } 00579 00580 00581 DOMElement* root=doc->getDocumentElement(); 00582 DOMElement* elemVersion=NULL; 00583 getDOMChildByName(root,"MixProtocolVersion",elemVersion,false); 00584 UINT8 strVersion[255]; 00585 UINT32 tmpLen=255; 00586 if(getDOMElementValue(elemVersion,strVersion,&tmpLen)==E_SUCCESS) 00587 { 00588 #ifdef _DEBUG 00589 CAMsg::printMsg(LOG_INFO,"XML MixProtocolVersion value:%s\n",strVersion); 00590 #endif 00591 if(tmpLen==3&&memcmp(strVersion,"0.4",3)==0) 00592 { 00593 CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.4\n"); 00594 m_MixCascadeProtocolVersion=MIX_CASCADE_PROTOCOL_VERSION_0_4; 00595 m_bWithFirstMixSymmetric=true; 00596 } 00597 else if(tmpLen==3&&memcmp(strVersion,"0.3",3)==0) 00598 { 00599 CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.3\n"); 00600 m_MixCascadeProtocolVersion=MIX_CASCADE_PROTOCOL_VERSION_0_3; 00601 } 00602 else if(tmpLen==3&&memcmp(strVersion,"0.2",3)==0) 00603 { 00604 CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.2\n"); 00605 m_MixCascadeProtocolVersion=MIX_CASCADE_PROTOCOL_VERSION_0_2; 00606 } 00607 else if(tmpLen==4&&memcmp(strVersion,"0.10",4)==0) 00608 { 00609 CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.10\n"); 00610 m_MixCascadeProtocolVersion=MIX_CASCADE_PROTOCOL_VERSION_0_1_0; 00611 m_bWithEnhancedChannelEncryption=true; 00612 m_SymChannelKeySize=32; 00613 m_SymChannelEncryptedKeySize=m_SymChannelKeySize+42; 00614 m_bWithFirstMixSymmetric=true; 00615 } 00616 else 00617 { 00618 CAMsg::printMsg(LOG_ERR,"Unsupported MixProtocolVersion!\n"); 00619 return E_UNKNOWN; 00620 } 00621 } 00622 else 00623 { 00624 #ifdef _DEBUG 00625 CAMsg::printMsg(LOG_ERR,"No MixProtocolVersion given!\n"); 00626 return E_UNKNOWN; 00627 #endif 00628 } 00629 DOMElement* elemMixes=NULL; 00630 getDOMChildByName(root,"Mixes",elemMixes,false); 00631 SINT32 chainlen=-1; 00632 if(elemMixes==NULL||getDOMElementAttribute(elemMixes,"count",&chainlen)!=E_SUCCESS) 00633 { 00634 #ifdef _DEBUG 00635 CAMsg::printMsg(LOG_ERR,"No count of Mixes given!\n"); 00636 return E_UNKNOWN; 00637 #endif 00638 } 00639 m_chainlen=(UINT32)chainlen; 00640 #ifdef _DEBUG 00641 CAMsg::printMsg(LOG_INFO,"Number of Mixes is: %u\n",m_chainlen); 00642 #endif 00643 if(m_chainlen==0) 00644 { 00645 #ifdef _DEBUG 00646 CAMsg::printMsg(LOG_ERR,"Number of Mixes is 0!\n"); 00647 return E_UNKNOWN; 00648 #endif 00649 } 00650 UINT32 i=0; 00651 m_arRSA=new CAASymCipher[m_chainlen]; 00652 DOMNode* child=elemMixes->getLastChild(); 00653 bool bIsLast=true; 00654 while(child!= NULL&&chainlen>0) 00655 { 00656 if(equals(child->getNodeName(),"Mix")) 00657 { 00658 DOMNode* nodeKey=child->getFirstChild(); 00659 if(m_arRSA[i++].setPublicKeyAsDOMNode(nodeKey)!=E_SUCCESS) 00660 { 00661 #ifdef _DEBUG 00662 CAMsg::printMsg(LOG_ERR,"Error in parsing the public key of a Mix\n"); 00663 return E_UNKNOWN; 00664 #endif 00665 } 00666 if(bIsLast) 00667 { 00668 DOMNode* tmpNode=NULL; 00669 getDOMChildByName(child,"MixProtocolVersion",tmpNode); 00670 UINT8 tmpBuff[255]; 00671 UINT32 tmpBuffLen=255; 00672 if(getDOMElementValue(tmpNode,tmpBuff,&tmpBuffLen)==E_SUCCESS) 00673 { 00674 CAMsg::printMsg(LOG_DEBUG,"Last Mix Protcol Version %s\n",tmpBuff); 00675 if(strcmp("0.6",(char*)tmpBuff)==0) 00676 { 00677 m_bWithNewFlowControl=true; 00678 CAMsg::printMsg(LOG_DEBUG,"Last Mix uses new flow control\n"); 00679 } 00680 } 00681 if(m_bWithNewFlowControl) 00682 { 00683 getDOMChildByName(child,"FlowControl",tmpNode); 00684 DOMElement* nodeDownstreamSendMe=NULL; 00685 getDOMChildByName(tmpNode,"DownstreamSendMe",nodeDownstreamSendMe); 00686 getDOMElementValue(nodeDownstreamSendMe,m_nFlowControlDownstreamSendMe,m_nFlowControlDownstreamSendMe); 00687 CAMsg::printMsg(LOG_DEBUG,"Last Mix new flow control downstream sewnd me: %u\n",m_nFlowControlDownstreamSendMe); 00688 } 00689 bIsLast=false; 00690 } 00691 chainlen--; 00692 } 00693 child=child->getPreviousSibling(); 00694 } 00695 if(chainlen!=0) 00696 { 00697 #ifdef _DEBUG 00698 CAMsg::printMsg(LOG_ERR,"Expected information for %u Mixes but found only %u!\n",m_chainlen,m_chainlen-chainlen); 00699 return E_UNKNOWN; 00700 #endif 00701 } 00702 //Now sending SymKeys.... 00703 if(m_MixCascadeProtocolVersion==MIX_CASCADE_PROTOCOL_VERSION_0_2) 00704 { 00705 MIXPACKET oPacket; 00706 getRandom((UINT8*)&oPacket,MIXPACKET_SIZE); 00707 oPacket.flags=0; 00708 oPacket.channel=0; 00709 UINT8 keys[32]; 00710 getRandom(keys,32); 00711 m_muxOut.setReceiveKey(keys,16); 00712 m_muxOut.setSendKey(keys+16,16); 00713 memcpy(oPacket.data,"KEYPACKET",9); 00714 memcpy(oPacket.data+9,keys,32); 00715 m_arRSA[m_chainlen-1].encrypt(oPacket.data,oPacket.data); 00716 m_muxOut.send(&oPacket); 00717 m_muxOut.setCrypt(true); 00718 } 00719 else 00720 { 00721 const char* XML_HEADER="<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 00722 const UINT32 XML_HEADER_SIZE=strlen(XML_HEADER); 00723 const char* XML_JAP_KEY_TEMPLATE="<JAPKeyExchange version=\"0.1\"><LinkEncryption>%s</LinkEncryption><MixEncryption>%s</MixEncryption></JAPKeyExchange>"; 00724 //DOM_Document doc=DOM_Document::createDocument(); 00725 //DOM_Element e = doc.createElement("JAPKeyExchange"); 00726 //doc.appendChild(e); 00727 //e.setAttribute("version", "0.1"); 00728 //DOM_Element elemLinkEnc = doc.createElement("LinkEncryption"); 00729 UINT8* buff=new UINT8[9000]; 00730 UINT8 linkKeys[64]; 00731 getRandom(linkKeys,64); 00732 UINT8 outBuffLinkKey[512]; 00733 UINT32 outlenLinkKey=512; 00734 CABase64::encode(linkKeys,64,outBuffLinkKey,&outlenLinkKey); 00735 outBuffLinkKey[outlenLinkKey]=0; 00736 //setDOMElementValue(elemLinkEnc,outBuff); 00737 //e.appendChild(elemLinkEnc); 00738 //DOM_Element elemMixEnc = doc.createElement("MixEncryption"); 00739 UINT8 mixKeys[32]; 00740 getRandom(mixKeys,32); 00741 m_pSymCipher=new CASymCipher(); 00742 m_pSymCipher->setKey(mixKeys); 00743 m_pSymCipher->setIVs(mixKeys+16); 00744 UINT8 outBuffMixKey[512]; 00745 UINT32 outlenMixKey=512; 00746 CABase64::encode(mixKeys,32,outBuffMixKey,&outlenMixKey); 00747 outBuffMixKey[outlenMixKey]=0; 00748 //setDOMElementValue(elemMixEnc,outBuff); 00749 //e.appendChild(elemMixEnc); 00750 sprintf((char*)buff,XML_JAP_KEY_TEMPLATE,outBuffLinkKey,outBuffMixKey); 00751 UINT32 encbufflen; 00752 UINT8* encbuff=encryptXMLElement(buff,strlen((char*)buff),encbufflen,&m_arRSA[m_chainlen-1]); 00753 UINT16 size2=htons((UINT16)(encbufflen+XML_HEADER_SIZE)); 00754 SINT32 ret=m_muxOut.getCASocket()->send((UINT8*)&size2,2); 00755 ret=m_muxOut.getCASocket()->send((UINT8*)XML_HEADER,XML_HEADER_SIZE); 00756 ret=m_muxOut.getCASocket()->send(encbuff,encbufflen); 00757 delete[] encbuff; 00758 encbuff = NULL; 00759 delete[] buff; 00760 buff = NULL; 00761 // Checking Signature send from Mix 00762 ret=m_muxOut.getCASocket()->receiveFully((UINT8*)&size2,2); 00763 size2=ntohs(size2); 00764 UINT8* xmlbuff=new UINT8[size2]; 00765 ret=m_muxOut.getCASocket()->receiveFully(xmlbuff,size2); 00766 delete[] xmlbuff; 00767 xmlbuff = NULL; 00768 m_muxOut.setSendKey(linkKeys,32); 00769 m_muxOut.setReceiveKey(linkKeys+32,32); 00770 m_muxOut.setCrypt(true); 00771 } 00772 if (doc != NULL) 00773 { 00774 doc->release(); 00775 doc = NULL; 00776 } 00777 CAMsg::printMsg(LOG_INFO,"Login process and key exchange finished!\n"); 00778 return E_SUCCESS; 00779 } 00780 #endif //!NEW_MIX_TYPE
1.7.6.1