Mixe for Privacy and Anonymity in the Internet
CAMiddleMix.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2000, The JAP-Team
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without modification,
5 are permitted provided that the following conditions are met:
6 
7  - Redistributions of source code must retain the above copyright notice,
8  this list of conditions and the following disclaimer.
9 
10  - Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation and/or
12  other materials provided with the distribution.
13 
14  - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
15  may be used to endorse or promote products derived from this software without specific
16  prior written permission.
17 
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
20 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
27 */
28 
29 #include "StdAfx.h"
30 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
31 #include "CAMiddleMix.hpp"
32 #include "CASingleSocketGroup.hpp"
33 #include "CAMsg.hpp"
34 #include "CACmdLnOptions.hpp"
35 #include "CASocketAddrINet.hpp"
36 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
37  #include "CASocketAddrUnix.hpp"
38 #endif
39 #include "CAThread.hpp"
40 #include "CAInfoService.hpp"
41 #include "CAUtil.hpp"
42 #include "CABase64.hpp"
43 #include "CAPool.hpp"
44 #include "xml/DOM_Output.hpp"
45 #include "CAStatusManager.hpp"
46 #include "CALibProxytest.hpp"
48 #include "CASymChannelCipher.hpp"
50 
52  {
53  CAMsg::printMsg(LOG_DEBUG,"Starting MiddleMix InitOnce\n");
54  //m_pSignature=CALibProxytest::getOptions()->getSignKey();
56  if(m_pMultiSignature==NULL)
57  {
58  return E_UNKNOWN;
59  }
60  if(CALibProxytest::getOptions()->getListenerInterfaceCount()<1)
61  {
62  CAMsg::printMsg(LOG_CRIT,"No ListenerInterfaces specified!\n");
63  return E_UNKNOWN;
64  }
65  return E_SUCCESS;
66  }
67 
85  {
86  UINT8* recvBuff=NULL;
87  UINT32 len;
88  SINT32 ret;
89 
91  {
92  if (ret != E_UNKNOWN)
93  {
94  CAMsg::printMsg(LOG_INFO,"Error receiving Key Info length from next Mix. Reason: '%s' (%i)\n",
96  }
97  else
98  {
99  CAMsg::printMsg(LOG_INFO,"Error receiving Key Info length from next Mix.");
100  }
102  return E_UNKNOWN;
103  }
104  len=ntohl(len);
105  CAMsg::printMsg(LOG_INFO,"Received Key Info length %u\n",len);
106 
107  if (len > 100000)
108  {
109  CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
110  }
111 
112  recvBuff=new UINT8[len+1]; //for the \0 at the end
113  if(recvBuff==NULL)
114  return E_UNKNOWN;
116  {
117  if (ret != E_UNKNOWN)
118  {
119  CAMsg::printMsg(LOG_INFO,"Error receiving Key Info from next Mix. Reason: '%s' (%i)\n",
121  }
122  else
123  {
124  CAMsg::printMsg(LOG_INFO,"Error receiving Key Info from next Mix.");
125  }
127  delete []recvBuff;
128  recvBuff = NULL;
129  return E_UNKNOWN;
130  }
131  recvBuff[len]=0; //make a string
132  CAMsg::printMsg(LOG_INFO,"Received Key Info...\n");
133  CAMsg::printMsg(LOG_INFO,"%s\n",recvBuff);
134 
135  //Parsing KeyInfo received from Mix n+1
136  XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(recvBuff,len);
137  delete []recvBuff;
138  recvBuff = NULL;
139  if(doc==NULL)
140  {
141  CAMsg::printMsg(LOG_INFO,"Error parsing Key Info from next Mix!\n");
143  return E_UNKNOWN;
144  }
145 
146  DOMElement* root=doc->getDocumentElement();
147 
148  //Finding first <Mix> entry and sending symetric key...
149  bool bFoundNextMix=false;
150  DOMNode* child=root->getFirstChild();
151  SINT32 result;
152  SINT32 resultCompatibility = E_SUCCESS;
153  while(child!=NULL)
154  {
155  if(equals(child->getNodeName(),"Mix"))
156  {
157  //verify certificate from next mix if enabled
158  if(CALibProxytest::getOptions()->verifyMixCertificates())
159  {
161  if(nextMixCert != NULL)
162  {
163  CAMsg::printMsg(LOG_DEBUG, "Next mix certificate was verified by a trusted root CA.\n");
165  }
166  else
167  {
168  CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from next mix!\n");
169  return E_UNKNOWN;
170  }
171  }
172  //check Signature....
173  //CASignature oSig;
175  //oSig.setVerifyKey(nextCert);
176  ret = CAMultiSignature::verifyXML(child, nextCert);
177  //ret=oSig.verifyXML(child,NULL);
178  delete nextCert;
179  nextCert = NULL;
180  if(ret!=E_SUCCESS)
181  {
183  //CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from next mix! The operator of the next mix has to send you his current mix certificate, and you will have to import it in your configuration. Alternatively, you might import the proper root certification authority for verifying the certificate.\n");
184  CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from next mix! The operator of the next mix has to send you his current mix certificate, and you will have to import it in your configuration.\n");
185  return E_UNKNOWN;
186  }
187 
188  if (resultCompatibility == E_SUCCESS)
189  {
190  resultCompatibility = checkCompatibility(child, "next");
191  }
192 
193  //extracting Nonce and computing Hash of them
194  DOMElement* elemNonce;
195  getDOMChildByName(child,"Nonce",elemNonce,false);
196  UINT32 lenNonce=1024;
197  UINT8 arNonce[1024];
198  UINT32 tmpLen=1024;
199  if(elemNonce==NULL)
200  {
202  CAMsg::printMsg(LOG_INFO,"No nonce found in Key Info from next Mix!\n");
203  if (doc != NULL)
204  {
205  doc->release();
206  doc = NULL;
207  }
208  return E_UNKNOWN;
209  }
210  getDOMElementValue(elemNonce,arNonce,&lenNonce);
211  CABase64::decode(arNonce,lenNonce,arNonce,&tmpLen);
212  lenNonce=tmpLen;
213  tmpLen=1024;
214  CABase64::encode(SHA1(arNonce,lenNonce,NULL),SHA_DIGEST_LENGTH,
215  arNonce,&tmpLen);
216  arNonce[tmpLen]=0;
217 
218  //Extracting PubKey of Mix n+1, generating SymKey for link encryption
219  //with Mix n+1, encrypt and send them
220  DOMNode* rsaKey=child->getFirstChild();
221  CAASymCipher oRSA;
222  oRSA.setPublicKeyAsDOMNode(rsaKey);
223  UINT8 key[64];
224 #ifdef SET_STATIC_MUX_SOCKET_KEY
225  CAMsg::printMsg(LOG_CRIT, "Warning! Will use an all zero MuxSocket key - do not use this Mix in a productive environment -- only for testing!\n");
226  memset(key, 0, 64);
227 #else
228  getRandom(key, 64);
229 #endif
230  XERCES_CPP_NAMESPACE::DOMDocument *docSymKey = ::createDOMDocument();
231  DOMElement* elemRoot=NULL;
232  ::encodeXMLEncryptedKey(key,64,elemRoot,docSymKey,&oRSA);
233  docSymKey->appendChild(elemRoot);
234 
235  appendCompatibilityInfo(elemRoot);
236 
237  DOMElement* elemNonceHash=createDOMElement(docSymKey,"Nonce");
238  ::setDOMElementValue(elemNonceHash,arNonce);
239  elemRoot->appendChild(elemNonceHash);
240 
242  DOMElement *elemKeepAlive;
243  DOMElement *elemKeepAliveSendInterval;
244  DOMElement *elemKeepAliveRecvInterval;
245  getDOMChildByName(child,"KeepAlive",elemKeepAlive,false);
246  getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval,false);
247  getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval,false);
248  UINT32 tmpSendInterval,tmpRecvInterval;
249  getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if now send interval was given set it to "infinite"
250  getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite"
251  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- ReceiveInterval %u\n",tmpSendInterval,tmpRecvInterval);
252  // Add Info about KeepAlive traffic
253  UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval();
254  UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval();
255  elemKeepAlive=createDOMElement(docSymKey,"KeepAlive");
256  elemKeepAliveSendInterval=createDOMElement(docSymKey,"SendInterval");
257  elemKeepAliveRecvInterval=createDOMElement(docSymKey,"ReceiveInterval");
258  elemKeepAlive->appendChild(elemKeepAliveSendInterval);
259  elemKeepAlive->appendChild(elemKeepAliveRecvInterval);
260  setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval);
261  setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval);
262  elemRoot->appendChild(elemKeepAlive);
263  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval);
264  m_u32KeepAliveSendInterval2=max(u32KeepAliveSendInterval,tmpRecvInterval);
266  m_u32KeepAliveSendInterval2-=10000; //make the send interval a little bit smaller than the related receive intervall
267  m_u32KeepAliveRecvInterval2=max(u32KeepAliveRecvInterval,tmpSendInterval);
268 
269  m_u32KeepAliveSendInterval2 = u32KeepAliveSendInterval;
270  if (m_u32KeepAliveSendInterval2 > tmpRecvInterval - 10000)
271  m_u32KeepAliveSendInterval2-=10000; //make the send interval a little bit smaller than the related receive interval
272  m_u32KeepAliveRecvInterval2=max(u32KeepAliveRecvInterval,tmpSendInterval);
273  if (m_u32KeepAliveRecvInterval2 - 10000 < tmpSendInterval)
274  {
276  }
277 
278  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval2,m_u32KeepAliveRecvInterval2);
279 
280  //m_pSignature->signXML(elemRoot);
281  m_pMultiSignature->signXML(elemRoot, true);
282  m_pMuxOut->setSendKey(key,32);
283  m_pMuxOut->setReceiveKey(key+32,32);
284  UINT32 outlen=0;
285  UINT8* out=DOM_Output::dumpToMem(docSymKey,&outlen);
286  CAMsg::printMsg(LOG_DEBUG,"send length %u\n", outlen);
287  UINT32 size=htonl(outlen);
288  m_pMuxOut->getCASocket()->send((UINT8*)&size, sizeof(size));
289  m_pMuxOut->getCASocket()->send(out, outlen);
290  if (docSymKey != NULL)
291  {
292  docSymKey->release();
293  docSymKey = NULL;
294  }
295  delete[] out;
296  out = NULL;
297  bFoundNextMix=true;
298  break;
299  }
300  child=child->getNextSibling();
301  }
302 
303 
304  if(!bFoundNextMix)
305  {
306  CAMsg::printMsg(LOG_INFO,"Error -- no Key Info found for next Mix!\n");
308  if (doc != NULL)
309  {
310  doc->release();
311  doc = NULL;
312  }
313  return E_UNKNOWN;
314  }
315  // -----------------------------------------
316  // ---- Start exchange with Mix n-1 --------
317  // -----------------------------------------
318  //Inserting own (key) info
319  UINT32 count=0;
320  if(getDOMElementAttribute(root,"count",count)!=E_SUCCESS)
321  {
323  if (doc != NULL)
324  {
325  doc->release();
326  doc = NULL;
327  }
328  return E_UNKNOWN;
329  }
330  count++;
331  ::setDOMElementAttribute(root,"count",count);
332 
333  addMixInfo(root, true);
334  DOMElement* mixNode=NULL;
335  ::getDOMChildByName(root, "Mix", mixNode, false);
336 
337 
338  UINT8 tmpBuff[50];
339  CALibProxytest::getOptions()->getMixId(tmpBuff,50); //the mix id...
340  ::setDOMElementAttribute(mixNode,"id",tmpBuff);
341  //Supported Mix Protocol -->currently "0.3"
342  DOMElement* elemMixProtocolVersion=createDOMElement(doc,"MixProtocolVersion");
343  mixNode->appendChild(elemMixProtocolVersion);
344  ::setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.3");
345 
346  DOMElement* elemKey=NULL;
347  m_pRSA->getPublicKeyAsDOMElement(elemKey,doc); //the key
348  mixNode->appendChild(elemKey);
349 
350  appendCompatibilityInfo(mixNode);
351 
352  //inserting Nonce
353  DOMElement* elemNonce=createDOMElement(doc,"Nonce");
354  UINT8 arNonce[16];
355  getRandom(arNonce,16);
356  UINT32 tmpLen=50;
357  CABase64::encode(arNonce,16,tmpBuff,&tmpLen);
358  tmpBuff[tmpLen]=0;
359  setDOMElementValue(elemNonce,tmpBuff);
360  mixNode->appendChild(elemNonce);
361 
362 // Add Info about KeepAlive traffic
363  DOMElement* elemKeepAlive;
364  UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval();
365  UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval();
366  elemKeepAlive=createDOMElement(doc,"KeepAlive");
367  DOMElement* elemKeepAliveSendInterval;
368  DOMElement* elemKeepAliveRecvInterval;
369  elemKeepAliveSendInterval=createDOMElement(doc,"SendInterval");
370  elemKeepAliveRecvInterval=createDOMElement(doc,"ReceiveInterval");
371  elemKeepAlive->appendChild(elemKeepAliveSendInterval);
372  elemKeepAlive->appendChild(elemKeepAliveRecvInterval);
373  setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval);
374  setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval);
375  mixNode->appendChild(elemKeepAlive);
376  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval);
377 
378  /* append the terms and conditions, if there are any, to the KeyInfo
379  * Extensions, (nodes that can be removed from the KeyInfo without
380  * destroying the signature of the "Mix"-node).
381  */
382 #ifdef PAYMENT
383  if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
384  {
385  appendTermsAndConditionsExtension(doc, root);
386  mixNode->appendChild(termsAndConditionsInfoNode(doc));
387  }
388 #endif
389  // create signature
390  if(signXML(mixNode)!=E_SUCCESS)
391  {
392  CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo send to users...\n");
393  }
394 
395 
396 
397  //UINT8* out=new UINT8[0xFFFF];
398  //memset(out, 0, (sizeof(UINT8)*0xFFFF));
399  UINT32 outlen = 0;
400  UINT8* out = DOM_Output::dumpToMem(doc, &outlen);
401 #ifdef _DEBUG
402  CAMsg::printMsg(LOG_DEBUG,"New Key Info size: %u\n", outlen);
403 #endif
404  len = htonl(outlen);
405  //memcpy(out,&len, sizeof(len));
406 
407  m_pMuxIn->getCASocket()->send((UINT8*) &len, sizeof(len));
408 
409  ret=m_pMuxIn->getCASocket()->send(out, outlen);
410  delete[] out;
411  out = NULL;
412  if( (ret < 0) || (ret != (SINT32)outlen) )
413  {
414  CAMsg::printMsg(LOG_DEBUG,"Error sending new New Key Info\n");
416  if (doc != NULL)
417  {
418  doc->release();
419  doc = NULL;
420  }
421  return E_UNKNOWN;
422  }
424  CAMsg::printMsg(LOG_DEBUG,"Sending new key info succeeded\n");
425 
426  CAMsg::printMsg(LOG_INFO,"Waiting for length of symmetric key from previous Mix...\n");
427  //Now receiving the symmetric key form Mix n-1
429  {
430  if (ret != E_UNKNOWN)
431  {
432  CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length from the previous mix! Reason: '%s' (%i)\n",
434  }
435  else
436  {
437  CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length from the previous mix!");
438  }
439  return E_UNKNOWN;
440  }
441 
442  len = ntohl(len);
443 
444  if (len > 100000)
445  {
446  CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
447  }
448 
449 
450  recvBuff = new UINT8[len+1]; //for \0 at the end
451 
453  //if((recLen = m_pMuxIn->getCASocket()->receive(recvBuff, len)) != len)
454  {
456  if (ret != E_UNKNOWN)
457  {
458  CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! Reason: '%s' (%i) The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n",
460  }
461  else
462  {
463  CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n");
464  }
465  delete []recvBuff;
466  recvBuff = NULL;
467  if (doc != NULL)
468  {
469  doc->release();
470  doc = NULL;
471  }
472  return E_UNKNOWN;
473  }
474  recvBuff[len]=0;
475  CAMsg::printMsg(LOG_INFO,"Symmetric Key Info received is:\n");
476  CAMsg::printMsg(LOG_INFO,"%s\n",(char*)recvBuff);
477  //Parsing doc received
478  doc=parseDOMDocument(recvBuff, len);
479  delete[] recvBuff;
480  recvBuff = NULL;
481  if(doc==NULL)
482  {
484  CAMsg::printMsg(LOG_INFO,"Error parsing Key Info from previous Mix!\n");
485  return E_UNKNOWN;
486  }
487  DOMElement* elemRoot=doc->getDocumentElement();
488  //verify certificate from previous mix if enabled
489  if(CALibProxytest::getOptions()->verifyMixCertificates())
490  {
492  if(prevMixCert != NULL)
493  {
494  CAMsg::printMsg(LOG_DEBUG, "Previous mix certificate was verified by a trusted root CA.\n");
496  }
497  else
498  {
499  CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from previous mix!\n");
500  return E_UNKNOWN;
501  }
502  }
503  //verify signature
504  //CASignature oSig;
506  //oSig.setVerifyKey(pCert);
507  result = CAMultiSignature::verifyXML(elemRoot, pCert);
508  delete pCert;
509  pCert = NULL;
510  //if(oSig.verifyXML(elemRoot)!=E_SUCCESS)
511  if(result != E_SUCCESS)
512  {
514  //CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from previous mix! The operator of the previous mix has to send you his current mix certificate, and you will have to import it in your configuration. Alternatively, you might import the proper root certification authority for verifying the certificate.\n");
515  CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from previous mix! The operator of the previous mix has to send you his current mix certificate, and you will have to import it in your configuration.\n");
516  if (doc != NULL)
517  {
518  doc->release();
519  doc = NULL;
520  }
521  return E_UNKNOWN;
522  }
523 
524 
525 
526  if (resultCompatibility != E_SUCCESS ||
527  (resultCompatibility = checkCompatibility(elemRoot, "previous")) != E_SUCCESS)
528  {
529  if (doc != NULL)
530  {
531  doc->release();
532  doc = NULL;
533  }
534  return resultCompatibility;
535  }
536 
537  //Verifying nonce
538  elemNonce=NULL;
539  getDOMChildByName(elemRoot,"Nonce",elemNonce,false);
540  tmpLen=50;
541  memset(tmpBuff,0,tmpLen);
542  if(elemNonce==NULL||getDOMElementValue(elemNonce,tmpBuff,&tmpLen)!=E_SUCCESS||
543  CABase64::decode(tmpBuff,tmpLen,tmpBuff,&tmpLen)!=E_SUCCESS||
544  tmpLen!=SHA_DIGEST_LENGTH ||
545  memcmp(SHA1(arNonce,16,NULL),tmpBuff,SHA_DIGEST_LENGTH)!=0
546  )
547  {
549  CAMsg::printMsg(LOG_CRIT,"Could not verify the Nonce from previous mix!\n");
550  if (doc != NULL)
551  {
552  doc->release();
553  doc = NULL;
554  }
555  return E_UNKNOWN;
556  }
557  CAMsg::printMsg(LOG_INFO,"Verified the symmetric key of the previous mix!\n");
558 
559  UINT8 key[150];
560  UINT32 keySize=150;
561 
562  ret=::decodeXMLEncryptedKey(key,&keySize,elemRoot,m_pRSA);
563 /*
564 SGX Mix
565  ret=E_SUCCESS;
566  DOMNode* elemCipherValue=NULL;
567  if(getDOMChildByName(elemRoot,"CipherValue",elemCipherValue,true)!=E_SUCCESS)
568  ret=E_UNKNOWN;
569  UINT8 buff[2048];
570  UINT32 bufflen=2048;
571  if(getDOMElementValue(elemCipherValue,buff,&bufflen)!=E_SUCCESS)
572  ret = E_UNKNOWN;
573  //send cipher value
574  locksem(upstreamSemPostId, SN_EMPTY);
575  memcpy(upstreamPostBuffer, &buff, 2048);
576  unlocksem(upstreamSemPostId, SN_FULL);
577  //send new bufflen
578  locksem(downstreamSemPostId,SN_EMPTY);
579  memcpy(downstreamPostBuffer, &bufflen, sizeof(UINT32));
580  unlocksem(downstreamSemPostId,SN_FULL);
581 
582  CABase64::decode(buff,bufflen,buff,&bufflen);
583 
584  UINT8 buff2[bufflen];
585  //get keys
586  locksem(upstreamSemPostId, SN_FULL);
587  memcpy(&buff2,upstreamPostBuffer,bufflen);
588  unlocksem(upstreamSemPostId,SN_EMPTY);
589  for(SINT32 i=127;i>=0;i--)
590  {
591  if(buff2[i]!=0)
592  {
593  if(i>32)
594  keySize=64;
595  else if(i>16)
596  keySize=32;
597  else
598  keySize=16;
599  }
600  }
601  memcpy(key,buff2+128-(keySize),(keySize));
602 */
603 
604  if(ret!=E_SUCCESS||keySize!=64)
605  {
607  CAMsg::printMsg(LOG_CRIT,"Could not set the symmetric key from previous mix to be used by the MuxSocket!\n");
608  if (doc != NULL)
609  {
610  doc->release();
611  doc = NULL;
612  }
613  return E_UNKNOWN;
614  }
616  m_pMuxIn->setReceiveKey(key,32);
617  m_pMuxIn->setSendKey(key+32,32);
618 
620  elemKeepAlive=NULL;
621  elemKeepAliveSendInterval=NULL;
622  elemKeepAliveRecvInterval=NULL;
623  getDOMChildByName(elemRoot,"KeepAlive",elemKeepAlive);
624  getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval);
625  getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval);
626  UINT32 tmpSendInterval,tmpRecvInterval;
627  getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if no send interval was given set it to "infinite"
628  getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite"
629  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- Receive Interval %u\n",tmpSendInterval,tmpRecvInterval);
630  m_u32KeepAliveSendInterval = u32KeepAliveSendInterval;
631  if (m_u32KeepAliveSendInterval > tmpRecvInterval - 10000)
632  m_u32KeepAliveSendInterval-=10000; //make the send interval a little bit smaller than the related receive interval
633  m_u32KeepAliveRecvInterval=max(u32KeepAliveRecvInterval,tmpSendInterval);
634  if (m_u32KeepAliveRecvInterval - 10000 < tmpSendInterval)
635  {
637  }
638  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval,m_u32KeepAliveRecvInterval);
639 
640  if (doc != NULL)
641  {
642  doc->release();
643  doc = NULL;
644  }
645 
646  return E_SUCCESS;
647  }
648 
650  {
651 #ifdef DYNAMIC_MIX
652  m_bBreakNeeded = m_bReconfigured;
653 #endif
654 #ifdef WITH_SGX_IGNORED
655  if(m_bShMemConfigured==false){
656 
657  CAMsg::printMsg(LOG_INFO,"start sh mem conf");
658  int upstreamShMemPre_fd,upstreamShMemPost_fd;
659  int downstreamShMemPre_fd,downstreamShMemPost_fd;
660  void *upstreamShMemPreData, *upstreamShMemPostData;
661  void *downstreamShMemPreData, *downstreamShMemPostData;
662 
663  upstreamShMemPre_fd = shm_open(upstreamMemoryPreName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH);
664  upstreamShMemPost_fd = shm_open(upstreamMemoryPostName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH);
665  downstreamShMemPre_fd = shm_open(downstreamMemoryPreName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH);
666  downstreamShMemPost_fd = shm_open(downstreamMemoryPostName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH);
667 
668  ftruncate(upstreamShMemPre_fd,SIZE);
669  ftruncate(upstreamShMemPost_fd, SIZE);
670  ftruncate(downstreamShMemPre_fd,SIZE);
671  ftruncate(downstreamShMemPost_fd, SIZE);
672 
673  upstreamShMemPreData = mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, upstreamShMemPre_fd, 0);
674  if (upstreamShMemPreData == MAP_FAILED) {
675  printf("Map failed\n");
676  return -1;
677  }
678  upstreamShMemPostData = mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, upstreamShMemPost_fd, 0);
679  if (upstreamShMemPostData == MAP_FAILED) {
680  printf("Map failed\n");
681  return -1;
682  }
683  downstreamShMemPreData = mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, downstreamShMemPre_fd, 0);
684  if (downstreamShMemPreData == MAP_FAILED) {
685  printf("Map failed\n");
686  return -1;
687  }
688  downstreamShMemPostData = mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, downstreamShMemPost_fd, 0);
689  if (downstreamShMemPostData == MAP_FAILED) {
690  printf("Map failed\n");
691  return -1;
692  }
693 
694  /*Semaphoren*/
695  union semun sunionUpstreamPre;
696  union semun sunionUpstreamPost;
697  union semun sunionDownstreamPre;
698  union semun sunionDownstreamPost;
699 
700  /* Ein Semaphor erstellen */
701  upstreamSemPreId = safesemget (IPC_PRIVATE, 2, SHM_R | SHM_W);
702  upstreamSemPostId = safesemget(IPC_PRIVATE, 2, SHM_R | SHM_W);
703  downstreamSemPreId = safesemget (IPC_PRIVATE, 2, SHM_R | SHM_W);
704  downstreamSemPostId = safesemget(IPC_PRIVATE, 2, SHM_R | SHM_W);
705 
706 
707  /* Semaphor initialisieren */
708  sunionUpstreamPre.val = 1;
709  safesemctl (upstreamSemPreId, SN_EMPTY, SETVAL, sunionUpstreamPre);
710  sunionUpstreamPre.val = 0;
711  safesemctl (upstreamSemPreId, SN_FULL, SETVAL, sunionUpstreamPre);
712  sunionUpstreamPost.val = 1;
713  safesemctl (upstreamSemPostId, SN_EMPTY, SETVAL, sunionUpstreamPost);
714  sunionUpstreamPost.val = 0;
715  safesemctl (upstreamSemPostId, SN_FULL, SETVAL, sunionUpstreamPost);
716 
717  sunionDownstreamPre.val = 1;
718  safesemctl (downstreamSemPreId, SN_EMPTY, SETVAL, sunionDownstreamPre);
719  sunionDownstreamPre.val = 0;
720  safesemctl (downstreamSemPreId, SN_FULL, SETVAL, sunionDownstreamPre);
721  sunionDownstreamPost.val = 1;
722  safesemctl (downstreamSemPostId, SN_EMPTY, SETVAL, sunionDownstreamPost);
723  sunionDownstreamPost.val = 0;
724  safesemctl (downstreamSemPostId, SN_FULL, SETVAL, sunionDownstreamPost);
725 
726  *(int *) upstreamShMemPreData = upstreamSemPreId;
727  *(int *) upstreamShMemPostData = upstreamSemPostId;
728  *(int *) downstreamShMemPreData = downstreamSemPreId;
729  *(int *) downstreamShMemPostData = downstreamSemPostId;
730 
731  upstreamPreBuffer=upstreamShMemPreData + sizeof(int);
732  upstreamPostBuffer=upstreamShMemPostData + sizeof(int);
733  downstreamPreBuffer=downstreamShMemPreData + sizeof(int);
734  downstreamPostBuffer=downstreamShMemPostData + sizeof(int);
735  //shared memory + semaphoren ende
736 
737  //get RSA from inner mix
738  m_pRSA= new CAASymCipher();
739  UINT32 keyFileBuffLen=8096;
740 
741  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
742 
743  UINT8* keyBuff=new UINT8[keyFileBuffLen];
744  locksem(upstreamSemPostId,SN_FULL);
745  memcpy(keyBuff,upstreamPostBuffer,keyFileBuffLen);
746  unlocksem(upstreamSemPostId,SN_EMPTY);
747  m_pRSA->setPublicKeyAsXML(keyBuff,keyFileBuffLen);
748  delete[] keyBuff;
749  m_bShMemConfigured=true;
750 
751  }
752 
753 #endif
754 
755 
756  CAMsg::printMsg(LOG_INFO,"Creating Key...\n");
757  m_pRSA=new CAASymCipher();
758 #ifdef EXPORT_ASYM_PRIVATE_KEY
759  if(CALibProxytest::getOptions()->isImportKey())
760  {
761  UINT32 keyFileBuffLen=8096;
762  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
763  CALibProxytest::getOptions()->getEncryptionKeyImportFile(keyFileBuff,keyFileBuffLen);
764  UINT8* keyBuff=readFile(keyFileBuff,&keyFileBuffLen);
765  m_pRSA->setPrivateKeyAsXML(keyBuff,keyFileBuffLen);
766  delete[] keyFileBuff;
767  delete[] keyBuff;
768  }
769  else
770 #endif
771  {
772  if(m_pRSA->generateKeyPair(1024)!=E_SUCCESS)
773  {
774  CAMsg::printMsg(LOG_CRIT,"Could not generate a valid key pair\n");
775  return E_UNKNOWN;
776  }
777  }
778 #ifdef EXPORT_ASYM_PRIVATE_KEY
779  if(CALibProxytest::getOptions()->isExportKey())
780  {
781  UINT32 keyFileBuffLen=8096;
782  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
783  UINT8* keyBuff=new UINT8[keyFileBuffLen];
784  CALibProxytest::getOptions()->getEncryptionKeyExportFile(keyFileBuff,keyFileBuffLen);
785  m_pRSA->getPrivateKeyAsXML(keyBuff,&keyFileBuffLen);
786  saveFile(keyFileBuff,keyBuff,keyFileBuffLen);
787  delete[] keyFileBuff;
788  delete[] keyBuff;
789  }
790 #endif
791 
792  // connect to next mix
793  CASocketAddr* pAddrNext=NULL;
795  {
796  CATargetInterface oNextMix;
798  if(oNextMix.getTargetType()==TARGET_MIX)
799  {
800  pAddrNext=oNextMix.getAddr();
801  break;
802  }
803  oNextMix.cleanAddr();
804  }
805  if(pAddrNext==NULL)
806  {
807  CAMsg::printMsg(LOG_CRIT,"No next Mix specified!\n");
808  return E_UNKNOWN;
809  }
810 
812 
813  if(m_pMuxOut->getCASocket()->create(pAddrNext->getType())!=E_SUCCESS)
814  {
815  CAMsg::printMsg(LOG_CRIT,"Init: Cannot create SOCKET for outgoing connection...\n");
816  return E_UNKNOWN;
817  }
820 
821 
822  CAListenerInterface* pListener=NULL;
824  for(UINT32 i=1;i<=interfaces;i++)
825  {
827  if(!pListener->isVirtual())
828  break;
829  delete pListener;
830  pListener=NULL;
831  }
832  if(pListener==NULL)
833  {
834  CAMsg::printMsg(LOG_CRIT,"Failed to initialize socket for previous mix! Reason: no usable (non virtual) listener interface found!\n");
835  return E_UNKNOWN;
836  }
837  const CASocketAddr* pAddr=NULL;
838  pAddr=pListener->getAddr();
839  delete pListener;
840  pListener = NULL;
841 
842  UINT8 buff[255];
843  pAddr->toString(buff,255);
844  CAMsg::printMsg(LOG_INFO,"Waiting for connection from previous Mix on %s...\n", buff);
845 
846  m_pMuxIn=new CAMuxSocket(OFB);
847 #ifdef DYNAMIC_MIX
848  // LERNGRUPPE Do not block if we are currently reconfiguring
849  if(m_bBreakNeeded != m_bReconfigured)
850  {
851  return E_UNKNOWN;
852  }
853 #endif
854  SINT32 ret=m_pMuxIn->accept(*pAddr);
855  delete pAddr;
856  pAddr = NULL;
857  if(ret!=E_SUCCESS)
858  {
859  CAMsg::printMsg(LOG_CRIT,"Error waiting for previous Mix... -- restart!\n");
860  return E_UNKNOWN;
861  }
862  CAMsg::printMsg(LOG_INFO," connected!\n");
864 
868 
869 
870  //pAddrNext->toString(buff,255);
871  //CAMsg::printMsg(LOG_INFO,"Connecting to next Mix on %s...\n", buff);
872 
874  if(connectToNextMix(pAddrNext) != E_SUCCESS)
875  {
876  delete pAddrNext;
877  pAddrNext = NULL;
879  CAMsg::printMsg(LOG_DEBUG, "CAMiddleMix::init - Unable to connect to next mix\n");
880  return E_UNKNOWN;
881  }
882  delete pAddrNext;
883  pAddrNext = NULL;
884 
885 // mSocketGroup.add(muxOut);
887  CAMsg::printMsg(LOG_INFO," connected!\n");
888 
890 
891 
892  if((ret = processKeyExchange())!=E_SUCCESS)
893  {
894  CAMsg::printMsg(LOG_CRIT,"Error in proccessKeyExchange()!\n");
895  return ret;
896  }
897 
900 
902 
903 #ifdef REPLAY_DETECTION
904  m_pReplayDB=new CADatabase();
905  m_pReplayDB->start();
908  m_u64ReferenceTime=time(NULL);
909 #endif
911 #ifdef LOG_PACKET_TIMES
912  m_pLogPacketStats = new CALogPacketStats();
913  m_pLogPacketStats->setLogIntervallInMinutes(FM_PACKET_STATS_LOG_INTERVALL);
914  m_pLogPacketStats->start();
915 #endif
916  return E_SUCCESS;
917  }
918 
921  {
922  INIT_STACK;
923  BEGIN_STACK("CAFirstMix::fm_loopSendToMixAfter");
924 
925  CAMiddleMix* pMiddleMix = static_cast<CAMiddleMix*>(param);
926  CAQueue* pQueue = pMiddleMix->m_pQueueSendToMixAfter;
927  CAMuxSocket* pMuxSocket=pMiddleMix->m_pMuxOut;
928 
929  UINT32 len;
930  SINT32 ret;
931  tPoolEntry* pPoolEntry=new tPoolEntry;
932  MIXPACKET* pMixPacket=&pPoolEntry->packet;
933  UINT32 u32KeepAliveSendInterval=pMiddleMix->m_u32KeepAliveSendInterval2;
934  while(pMiddleMix->m_bRun)
935  {
936  len=sizeof(tPoolEntry);
937  ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,u32KeepAliveSendInterval);
938  if(!(pMiddleMix->m_bRun))
939  {
940  CAMsg::printMsg(LOG_INFO,"SendToMixAfter thread: was interrupted.\n");
942  break;
943  }
944  if(ret==E_TIMEDOUT)
945  {//send a dummy as keep-alive-traffic
946  pMixPacket->flags=CHANNEL_DUMMY;
947  pMixPacket->channel=DUMMY_CHANNEL;
948  getRandom(pMixPacket->data,DATA_SIZE);
949  }
950  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
951  {
953  CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixAfter - Error in dequeueing MixPaket\n");
954  CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
955  break;
956  }
957  if((pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE))
958  {
960  CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixAfter - Error in sending MixPaket\n");
961  break;
962  }
963 #ifdef LOG_PACKET_TIMES
964  if(!isZero64(pPoolEntry->timestamp_proccessing_start))
965  {
966  getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
967  pMiddleMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry, pMixPacket->flags, true);
968  }
969 #endif
970  }
971  pMiddleMix->m_bRun = false;
972  delete pPoolEntry;
973  pPoolEntry = NULL;
974  FINISH_STACK("CAFirstMix::fm_loopSendToMixAfter");
975 
976  CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMixAfter\n");
978  }
979 
982  {
983  INIT_STACK;
984  BEGIN_STACK("CAFirstMix::fm_loopSendToMixBefore");
985 
986  CAMiddleMix* pMiddleMix = static_cast<CAMiddleMix*>(param);
987  CAQueue* pQueue=pMiddleMix->m_pQueueSendToMixBefore;
988  CAMuxSocket* pMuxSocket=pMiddleMix->m_pMuxIn;
989 
990  UINT32 len;
991  SINT32 ret;
992  tPoolEntry* pPoolEntry=new tPoolEntry;
993  MIXPACKET* pMixPacket=&pPoolEntry->packet;
994  UINT32 u32KeepAliveSendInterval=pMiddleMix->m_u32KeepAliveSendInterval;
995  while(pMiddleMix->m_bRun)
996  {
997  len=sizeof(tPoolEntry);
998  ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,u32KeepAliveSendInterval);
999  if(!(pMiddleMix->m_bRun))
1000  {
1001  CAMsg::printMsg(LOG_INFO,"SendToMixBefore thread: was interrupted.\n");
1002  break;
1003  }
1004  if(ret==E_TIMEDOUT)
1005  {//send a dummy as keep-alive-traffic
1006  pMixPacket->flags=CHANNEL_DUMMY;
1007  pMixPacket->channel=DUMMY_CHANNEL;
1008  getRandom(pMixPacket->data,DATA_SIZE);
1009  }
1010  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
1011  {
1013  CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixBefore - Error in dequeueing MixPaket\n");
1014  CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
1015  break;
1016  }
1017  if((pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE))
1018  {
1020  CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixBefore - Error in sending MixPaket\n");
1021  break;
1022  }
1023 #ifdef LOG_PACKET_TIMES
1024  if(!isZero64(pPoolEntry->timestamp_proccessing_start))
1025  {
1026  getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
1027  pMiddleMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,pMixPacket->flags,true);
1028  }
1029 #endif
1030  }
1031  pMiddleMix->m_bRun = false;
1032  delete pPoolEntry;
1033  pPoolEntry = NULL;
1034  FINISH_STACK("CAFirstMix::fm_loopSendToMixBefore");
1035 
1036  CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMixBefore\n");
1038  }
1039 
1040 #define MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS 2*KEY_SIZE
1041 #define MIDDLE_MIX_ASYM_PADDING_SIZE 42
1042 
1043 /*** Read and process Mix packets from previous mix/
1044 */
1046  {
1047  CAMiddleMix* pMix=(CAMiddleMix*)param;
1048  HCHANNEL channelOut = 0;
1049 #ifdef LOG_CRIME
1050  HCHANNEL channelIn = 0;
1051 #endif
1052  tPoolEntry* pPoolEntry=new tPoolEntry;
1053  MIXPACKET* pMixPacket=&pPoolEntry->packet;
1054 
1055  CAQueue* pQueue=pMix->m_pQueueSendToMixAfter;
1056 
1057  CASymChannelCipher* pCipher;
1058  SINT32 ret;
1059  UINT8* tmpRSABuff=new UINT8[RSA_SIZE];
1060  UINT32 rsaOutLen=RSA_SIZE;
1061  CASingleSocketGroup oSocketGroup(false);
1062  oSocketGroup.add(*(pMix->m_pMuxIn));
1063 
1064  #ifdef USE_POOL
1065  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
1066  #endif
1067 
1068  while(pMix->m_bRun)
1069  {
1071  {
1072 #ifdef DEBUG
1073  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::Queue prev is full!\n");
1074 #endif
1075  msSleep(200);
1076  continue;
1077  }
1078  #ifndef USE_POOL
1079  ret=oSocketGroup.select(1000);
1080  #else
1081  ret=oSocketGroup.select(MIX_POOL_TIMEOUT);
1082  #endif
1083  if(ret!=1)
1084  {
1085  if(ret==E_TIMEDOUT)
1086  {
1087  #ifndef USE_POOL
1088  continue;
1089  #else
1090  pMixPacket->channel=DUMMY_CHANNEL;
1091  pMixPacket->flags=CHANNEL_DUMMY;
1092  getRandom(pMixPacket->data,DATA_SIZE);
1093  pPool->pool(pPoolEntry);
1094 /*
1095  locksem(upstreamSemPreId, SN_EMPTY);
1096  memcpy(upstreamPreBuffer,pPoolEntry, sizeof(tPoolEntry));
1097  unlocksem(upstreamSemPreId, SN_FULL);
1098 
1099  locksem(upstreamSemPostId, SN_FULL);
1100  memcpy(pPoolEntry,upstreamPostBuffer, sizeof(tPoolEntry));
1101  unlocksem(upstreamSemPostId, SN_EMPTY);
1102 */
1103  if(m_pMuxOut->send(pMixPacket)==SOCKET_ERROR)
1104  pMix->m_bRun=false;
1105  #endif
1106  }
1107  else
1108  {
1109  CAMsg::printMsg(LOG_CRIT,"loopUpStream -- Fehler bei select() -- goto ERR!\n");
1110  pMix->m_bRun=false;
1112  }
1113  }
1114  else
1115  {
1116  ret=pMix->m_pMuxIn->receive(pMixPacket);
1117 
1118  if ((ret!=SOCKET_ERROR)&&(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS))
1119  {
1120  CAMsg::printMsg(LOG_INFO,"loopUpStream received a packet with invalid flags: %0X . Removing them.\n",(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS));
1121  pMixPacket->flags&=CHANNEL_ALLOWED_FLAGS;
1122  }
1123 
1124  if(ret==SOCKET_ERROR)
1125  {
1126 
1127  CAMsg::printMsg(LOG_CRIT,"Fehler beim Empfangen -- Exiting!\n");
1128  pMix->m_bRun=false;
1130  }
1131  #ifdef USE_POOL
1132  else if(pMixPacket->channel==DUMMY_CHANNEL)
1133  {
1134  pMixPacket->flags=CHANNEL_DUMMY;
1135  getRandom(pMixPacket->data,DATA_SIZE);
1136  pPool->pool(pPoolEntry);
1137 /* SGX MIX locksem(upstreamSemPreId, SN_EMPTY);
1138  memcpy(upstreamPreBuffer,pPoolEntry, sizeof(tPoolEntry));
1139  unlocksem(upstreamSemPreId, SN_FULL);
1140  locksem(upstreamSemPostId, SN_FULL);
1141  memcpy(pPoolEntry,upstreamPostBuffer, sizeof(tPoolEntry));
1142  unlocksem(upstreamSemPostId, SN_EMPTY);
1143 */
1144  if(pMix->m_pMuxOut->send(pMixPacket)==SOCKET_ERROR)
1145  pMix->m_bRun=false;
1146  }
1147  #endif
1148 
1149  else //receive successful
1150  {
1151 
1152 /* locksem(pMix->upstreamSemPreId, SN_EMPTY);
1153  memcpy(pMix->upstreamPreBuffer,pPoolEntry, sizeof(tPoolEntry));
1154 SGX MIX unlocksem(pMix->upstreamSemPreId, SN_FULL);
1155  locksem(pMix->upstreamSemPostId, SN_FULL);
1156  memcpy(pPoolEntry,pMix->upstreamPostBuffer, sizeof(tPoolEntry));
1157  unlocksem(pMix->upstreamSemPostId, SN_EMPTY);
1158  if(pMixPacket->channel==0) continue;
1159  #ifdef LOG_CRIME
1160  crimeSurveillanceUpstream(pMixPacket, channelIn);
1161  #endif
1162  pQueue->add(pPoolEntry,sizeof(tPoolEntry));
1163 */
1164 #ifdef LOG_CRIME
1165  channelIn = pMixPacket->channel;
1166 #endif
1167  if(pMix->m_pMiddleMixChannelList->getInToOut(pMixPacket->channel,&channelOut,&pCipher)!=E_SUCCESS)
1168  {//new connection ?
1169  if(pMixPacket->flags & CHANNEL_OPEN) //if not channel-open flag set -->drop this packet
1170  {
1171  #ifdef _DEBUG
1172  CAMsg::printMsg(LOG_DEBUG,"New Connection from previous Mix!\n");
1173  #endif
1174  if (pMix->m_pRSA->decryptOAEP(pMixPacket->data, tmpRSABuff, &rsaOutLen) != E_SUCCESS)
1175  {
1176  CAMsg::printMsg(LOG_ERR, "Received wrongly decrypted Channel Open Packet!\n");
1177  continue;
1178  }
1179  #ifdef REPLAY_DETECTION
1180  // replace time(NULL) with the real timestamp ()
1181  // packet-timestamp + m_u64ReferenceTime
1182  UINT32 stamp=((UINT32)(tmpRSABuff[13]<<16)+(UINT32)(tmpRSABuff[14]<<8)+(UINT32)(tmpRSABuff[15]))*REPLAY_BASE;
1183  if(pMix->m_pReplayDB->insert(tmpRSABuff,stamp+pMix->m_u64ReferenceTime)!=E_SUCCESS)
1184 // if(pMix->m_pReplayDB->insert(tmpRSABuff,time(NULL))!=E_SUCCESS)
1185  {
1186  CAMsg::printMsg(LOG_INFO,"Replay: Duplicate packet ignored.\n");
1187  continue;
1188  }
1189  #endif
1190 
1191  pCipher=CASymChannelCipherFactory::createCipher(CALibProxytest::getOptions()->getSymChannelCipherAlgorithm());
1192  pCipher->setKeys(tmpRSABuff,MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS);
1193  pCipher->crypt1(pMixPacket->data+RSA_SIZE,
1194  pMixPacket->data+rsaOutLen-MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS,
1196  memcpy(pMixPacket->data,tmpRSABuff+MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS,rsaOutLen-MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS);
1198  pMix->m_pMiddleMixChannelList->add(pMixPacket->channel,pCipher,&channelOut);
1199  pMixPacket->channel=channelOut;
1200  #ifdef USE_POOL
1201  pPool->pool(pPoolEntry);
1202  #endif
1203  #ifdef LOG_CRIME
1204  crimeSurveillanceUpstream(pMixPacket, channelIn);
1205  #endif
1206  pQueue->add(pPoolEntry,sizeof(tPoolEntry));
1207  }
1208  }
1209  else
1210  {//established connection
1211  pCipher->crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE);
1212  pCipher->unlock();
1213  #ifdef USE_POOL
1214  pPool->pool(pPoolEntry);
1215  #endif
1216  if((pMixPacket->flags&CHANNEL_CLOSE)!=0)
1217  {//Channel close received -->remove channel form channellist
1218  pMix->m_pMiddleMixChannelList->remove(pMixPacket->channel);
1219  }
1220  pMixPacket->channel=channelOut;
1221  #ifdef LOG_CRIME
1222  crimeSurveillanceUpstream(pMixPacket, channelIn);
1223  #endif
1224  pQueue->add(pPoolEntry,sizeof(tPoolEntry));
1225  }
1226  }
1227  }
1228  }
1229 
1230  CAMsg::printMsg(LOG_CRIT,"loopReadFromMixBefore -- Exiting clean ups...\n");
1231  pMix->m_bRun=false;
1232  UINT8 b[sizeof(tQueueEntry)+1];
1233  /* write bytes to the send queues to accelerate loop()-joins for the send threads*/
1234  if(pMix->m_pQueueSendToMixBefore!=NULL)
1235  {
1236  pMix->m_pQueueSendToMixBefore->add(b,sizeof(tQueueEntry)+1);
1237  }
1238  if(pMix->m_pQueueSendToMixAfter!=NULL)
1239  {
1240  pMix->m_pQueueSendToMixAfter->add(b,sizeof(tQueueEntry)+1);
1241  }
1242  delete[] tmpRSABuff;
1243  tmpRSABuff = NULL;
1244  delete pPoolEntry;
1245  pPoolEntry = NULL;
1246  #ifdef USE_POOL
1247  delete pPool;
1248  pPool = NULL;
1249  #endif
1250  CAMsg::printMsg(LOG_CRIT,"loopReadFromMixBefore -- Now Exiting!\n");
1252  }
1253 
1255  {
1256  CAMiddleMix* pMix = static_cast<CAMiddleMix*>(param);
1257  HCHANNEL channelIn;
1258  CASymChannelCipher* pCipher=NULL;
1259 
1260  tPoolEntry* pPoolEntry=new tPoolEntry;
1261  MIXPACKET* pMixPacket=&pPoolEntry->packet;
1262 
1263  SINT32 ret;
1264  CASingleSocketGroup oSocketGroup(false);
1265  oSocketGroup.add(*(pMix->m_pMuxOut));
1266 
1267  CAQueue* pQueueSendtoMix=pMix->m_pQueueSendToMixBefore;
1268 
1269 #ifdef USE_POOL
1270  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
1271 #endif
1272  while(pMix->m_bRun)
1273  {
1274  if(pQueueSendtoMix->getSize()>MAX_READ_FROM_NEXT_MIX_QUEUE_SIZE)
1275  {
1276 #ifdef DEBUG
1277  CAMsg::printMsg(LOG_DEBUG,"CAMiddleMix::Queue next is full!\n");
1278 #endif
1279  msSleep(200);
1280  continue;
1281  }
1282  #ifndef USE_POOL
1283  ret=oSocketGroup.select(1000);
1284  #else
1285  ret=oSocketGroup.select(MIX_POOL_TIMEOUT);
1286  #endif
1287  if(ret!=1)
1288  {
1289  if(ret==E_TIMEDOUT)
1290  {
1291  #ifndef USE_POOL
1292  continue;
1293  #else
1294  pMixPacket->channel=DUMMY_CHANNEL;
1295  pMixPacket->flags=CHANNEL_DUMMY;
1296  getRandom(pMixPacket->data,DATA_SIZE);
1297  pPool->pool(pPoolEntry);
1298 /* SGX MIX
1299  locksem(downstreamSemPreId, SN_EMPTY);
1300  memcpy(downstreamPreBuffer,pPoolEntry, sizeof(tPoolEntry));
1301  unlocksem(downstreamSemPreId, SN_FULL);
1302 
1303  locksem(downstreamSemPostId, SN_FULL);
1304  memcpy(pPoolEntry,downstreamPostBuffer, sizeof(tPoolEntry));
1305  unlocksem(downstreamSemPostId, SN_EMPTY);
1306 */
1307  if(pMix->m_pMuxIn->send(pMixPacket)==SOCKET_ERROR)
1308  pMix->m_bRun=false;
1309  #endif
1310  }
1311  else
1312  {
1313  CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Error on select() while waiting for data from next mix -- goto ERR!\n");
1314  pMix->m_bRun=false;
1316  }
1317  }
1318  else
1319  {
1320  ret=pMix->m_pMuxOut->receive(pMixPacket);
1321  if ((ret!=SOCKET_ERROR)&&(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS))
1322  {
1323  CAMsg::printMsg(LOG_INFO,"loopReadFromMixAfter -- received a packet with invalid flags: %0X . Removing them.\n",(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS));
1324  pMixPacket->flags&=CHANNEL_ALLOWED_FLAGS;
1325  }
1326  if(ret==SOCKET_ERROR)
1327  {
1328  CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Error while receiving data from next mix. Reason: %s (%i)\n",
1330  pMix->m_bRun=false;
1332  }
1333  #ifdef USE_POOL
1334  else if(pMixPacket->channel==DUMMY_CHANNEL)
1335  {
1336  pMixPacket->flags=CHANNEL_DUMMY;
1337  getRandom(pMixPacket->data,DATA_SIZE);
1338  pPool->pool(pPoolEntry);
1348  if(pMix->m_pMuxIn->send(pMixPacket)==SOCKET_ERROR)
1349  pMix->m_bRun=false;
1350  }
1351  #endif
1352  #ifdef REPLAY_DETECTION
1353  else if(pMixPacket->channel==REPLAY_CONTROL_CHANNEL_ID)
1354  {
1355  pQueue->add(pPoolEntry,sizeof(tPoolEntry));
1356  }
1357  #endif
1358  else if(pMix->m_pMiddleMixChannelList->getOutToIn(&channelIn,pMixPacket->channel,&pCipher)==E_SUCCESS)
1359  {//connection found
1360 
1371 #ifdef LOG_CRIME
1372  HCHANNEL channelOut = pMixPacket->channel;
1373 #endif
1374  pMixPacket->channel=channelIn;
1375 #ifdef LOG_CRIME
1376  if((pMixPacket->flags&CHANNEL_SIG_CRIME)==CHANNEL_SIG_CRIME)
1377  {
1378  getRandom(pMixPacket->data,DATA_SIZE);
1379  //Log in and out channel number, to allow
1380  CAMsg::printMsg(LOG_CRIT,"Detecting crime activity - previous mix channel: %u, "
1381  "next mix channel: %u\n", channelIn, channelOut);
1382  }
1383  else
1384 #endif
1385  pCipher->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE);
1386  pCipher->unlock();
1387  #ifdef USE_POOL
1388  pPool->pool(pPoolEntry);
1389  #endif
1390  if((pMixPacket->flags&CHANNEL_CLOSE)!=0)
1391  {//Channel close received -->remove channel form channellist
1392  pMix->m_pMiddleMixChannelList->remove(channelIn);
1393  }
1394  pMix->putMixPacketIntoQueueSendToMixBefore(pPoolEntry);
1395  }
1396  }
1397  }
1398 
1399  CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Exiting clean ups...\n");
1400  pMix->m_bRun=false;
1401  UINT8 b[sizeof(tQueueEntry)+1];
1402  /* write bytes to the send queues to accelerate loop()-joins for the send threads*/
1403  if(pMix->m_pQueueSendToMixBefore!=NULL)
1404  {
1405  pMix->m_pQueueSendToMixBefore->add(b,sizeof(tQueueEntry)+1);
1406  }
1407  if(pMix->m_pQueueSendToMixAfter!=NULL)
1408  {
1409  pMix->m_pQueueSendToMixAfter->add(b,sizeof(tQueueEntry)+1);
1410  }
1411  delete pPoolEntry;
1412  pPoolEntry = NULL;
1413  #ifdef USE_POOL
1414  delete pPool;
1415  pPool = NULL;
1416  #endif
1417  CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Now Exiting!\n");
1419  }
1420 
1422  {
1423  m_pQueueSendToMixBefore->add(pPoolEntry, sizeof(tPoolEntry));
1424  return E_SUCCESS;
1425  }
1426 
1427 
1429 {
1430 #define RETRIES 100
1431 #define RETRYTIME 10
1432  UINT8 buff[255];
1433  a_pAddrNext->toString(buff,255);
1434  CAMsg::printMsg(LOG_INFO,"Try to connect to next Mix on %s ...\n",buff);
1435  UINT32 i = 0;
1436  SINT32 err = E_UNKNOWN;
1437  SINT32 errLast = E_SUCCESS;
1438  for(i=0; i < RETRIES; i++)
1439  {
1440 #ifdef DYNAMIC_MIX
1442  if(m_bBreakNeeded != m_bReconfigured)
1443  {
1444  CAMsg::printMsg(LOG_DEBUG, "CAMiddleMix::connectToNextMix - Broken the connect loop!\n");
1445  break;
1446  }
1447 #endif
1448  err = m_pMuxOut->connect(*a_pAddrNext);
1449  if(err != E_SUCCESS)
1450  {
1451  err=GET_NET_ERROR;
1452 #ifdef _DEBUG
1453  CAMsg::printMsg(LOG_DEBUG,"Con-Error: %i\n",err);
1454 #endif
1456  {
1457  CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i)\n",
1458  buff, GET_NET_ERROR_STR(err), err);
1459  break;
1460  }
1461 
1462  if (errLast != err || i % 10 == 0)
1463  {
1464  CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i). Retrying...\n",
1465  buff, GET_NET_ERROR_STR(err), err);
1466  errLast = err;
1467  }
1468  else
1469  {
1470  #ifdef _DEBUG
1471  CAMsg::printMsg(LOG_DEBUG,"Cannot connect... retrying\n");
1472  #endif
1473  }
1474  sSleep(RETRYTIME);
1475  }
1476  else
1477  {
1478  break;
1479  }
1480  }
1481  return err;
1482 }
1483 
1486  {
1487 
1488 // CASingleSocketGroup oSocketGroup(false);
1489 // oSocketGroup.add(*m_pMuxIn);
1490  m_pMuxIn->setCrypt(true);
1491  m_pMuxOut->setCrypt(true);
1492 
1493  m_bRun=true;
1494 
1495  CAThread oThread;
1497  oThread.start(this);
1498 
1499  CAThread bThread;
1501  bThread.start(this);
1502 
1503  CAThread cThread;
1505  cThread.start(this);
1506 
1507  CAThread dThread;
1509  dThread.start(this);
1510 
1511  cThread.join();
1512 
1513  CAMsg::printMsg(LOG_CRIT,"loop(): Preparing for restart...\n");
1514  m_bRun=false;
1515 
1516  oThread.join();
1517  bThread.join();
1518  dThread.join();
1519 
1520  m_pMuxIn->close();
1521  m_pMuxOut->close();
1522 
1523  CAMsg::printMsg(LOG_CRIT,"loop(): Seems that we are restarting now!!\n");
1524  return E_UNKNOWN;
1525  }
1527 {
1528  delete m_pQueueSendToMixBefore;
1530 
1531  delete m_pQueueSendToMixAfter;
1533 
1534 #ifdef REPLAY_DETECTION
1535  delete m_pReplayMsgProc;
1536  m_pReplayMsgProc=NULL;
1537 #endif
1538  if(m_pMuxIn!=NULL)
1539  {
1540  m_pMuxIn->close();
1541  delete m_pMuxIn;
1542  m_pMuxIn=NULL;
1543  }
1544 
1545  if(m_pMuxOut!=NULL)
1546  {
1547  m_pMuxOut->close();
1548  delete m_pMuxOut;
1549  m_pMuxOut=NULL;
1550  }
1551 
1552  delete m_pRSA;
1553  m_pRSA=NULL;
1554 
1556 #ifdef WITH_SGX_IGNORED
1557  if(m_bShutDown){
1558 
1559  delete m_pRSA;
1560  m_pRSA=NULL;
1561 
1562 
1563  //delete semaphors
1564  if (semctl (upstreamSemPreId, 0, IPC_RMID, 0) == -1) {
1565  printf ("Fehler beim Löschen des Semaphors pre.\n");
1566  }
1567  if (semctl (upstreamSemPostId, 0, IPC_RMID, 0) == -1) {
1568  printf ("Fehler beim Löschen des Semaphors post.\n");
1569  }
1570  if (semctl (downstreamSemPreId, 0, IPC_RMID, 0) == -1) {
1571  printf ("Fehler beim Löschen des Semaphors pre.\n");
1572  }
1573  if (semctl (downstreamSemPostId, 0, IPC_RMID, 0) == -1) {
1574  printf ("Fehler beim Löschen des Semaphors post.\n");
1575  }
1576 
1577  //remove shared memory segments
1578 
1579  if (shm_unlink(upstreamMemoryPreName) == -1) {
1580  printf("Error removing %s\n",upstreamMemoryPreName);
1581  exit(-1);
1582  }
1583  if (shm_unlink(upstreamMemoryPostName) == -1) {
1584  printf("Error removing %s\n",upstreamMemoryPostName);
1585  exit(-1);
1586  }
1587  if (shm_unlink(downstreamMemoryPreName) == -1) {
1588  printf("Error removing %s\n",downstreamMemoryPreName);
1589  exit(-1);
1590  }
1591  if (shm_unlink(downstreamMemoryPostName) == -1) {
1592  printf("Error removing %s\n",downstreamMemoryPostName);
1593  exit(-1);
1594  }
1595  }
1596 #endif //WITH_SGX
1597 #ifdef LOG_PACKET_TIMES
1598  if (m_pLogPacketStats != NULL)
1599  {
1600  CAMsg::printMsg(LOG_CRIT, "Wait for LoopLogPacketStats to terminate!\n");
1601  m_pLogPacketStats->stop();
1602  delete m_pLogPacketStats;
1603  }
1604  m_pLogPacketStats = NULL;
1605 #endif
1606  delete m_pMiddleMixChannelList;
1608  return E_SUCCESS;
1609  }
1610 #endif //ONLY_LOCAL_PROXY
1611 
1612 #ifdef LOG_CRIME
1613  static void crimeSurveillanceUpstream(MIXPACKET *pMixPacket, HCHANNEL prevMixChannel)
1614  {
1615  if(pMixPacket->flags & CHANNEL_SIG_CRIME)
1616  {
1617  CAMsg::printMsg(LOG_CRIT,"Crime detection: User surveillance, previous mix channel: %u, "
1618  "next mix channel %u\n", prevMixChannel, pMixPacket->channel);
1619  }
1620  }
1621 #endif
#define RSA_SIZE
#define RETRYTIME
THREAD_RETURN mm_loopSendToMixBefore(void *param)
DOWNSTREAM (to Client) Take the packets from the Queue and write them to the Socket.
#define MIDDLE_MIX_ASYM_PADDING_SIZE
THREAD_RETURN mm_loopSendToMixAfter(void *param)
UPSTREAM (to WEB) Take the packets from the Queue and write them to the Socket.
#define MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS
THREAD_RETURN mm_loopReadFromMixAfter(void *param)
#define RETRIES
THREAD_RETURN mm_loopReadFromMixBefore(void *param)
#define REPLAY_BASE
#define MONITORING_FIRE_NET_EVENT(e_type)
#define INIT_STACK
Definition: CAThread.hpp:48
#define BEGIN_STACK(methodName)
Definition: CAThread.hpp:49
#define FINISH_STACK(methodName)
Definition: CAThread.hpp:50
SINT32 setDOMElementAttribute(DOMNode *pElem, const char *attrName, const char *value)
Definition: CAUtil.cpp:831
SINT32 getDOMElementValue(const DOMNode *const pElem, UINT8 *value, UINT32 *valuelen)
Returns the content of the text node(s) under elem as null-terminated C String.
Definition: CAUtil.cpp:746
UINT8 * readFile(const UINT8 *const name, UINT32 *size)
ONLY_LOCAL_PROXY or first.
Definition: CAUtil.cpp:1330
SINT32 setDOMElementValue(DOMElement *pElem, SINT32 value)
Definition: CAUtil.cpp:939
SINT32 getcurrentTimeMicros(UINT64 &u64Time)
Gets the current Systemtime in micros seconds.
Definition: CAUtil.cpp:280
bool equals(const XMLCh *const e1, const char *const e2)
Definition: CAUtil.cpp:645
SINT32 sSleep(UINT32 sec)
Sleeps sec Seconds.
Definition: CAUtil.cpp:425
XERCES_CPP_NAMESPACE::DOMDocument * parseDOMDocument(const UINT8 *const buff, UINT32 len)
Parses a buffer containing an XML document and returns this document.
Definition: CAUtil.cpp:663
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
XERCES_CPP_NAMESPACE::DOMDocument * createDOMDocument()
Parses a timestamp in JDBC timestamp escape format (as it comes from the BI) and outputs the value in...
Definition: CAUtil.cpp:1568
DOMElement * createDOMElement(XERCES_CPP_NAMESPACE::DOMDocument *pOwnerDoc, const char *const name)
Creates a new DOMElement with the given name which belongs to the DOMDocument owernDoc.
Definition: CAUtil.cpp:814
SINT32 getDOMChildByName(const DOMNode *pNode, const char *const name, DOMElement *&child, bool deep)
Definition: CAUtil.cpp:458
SINT32 getDOMElementAttribute(const DOMNode *const elem, const char *attrName, UINT8 *value, UINT32 *len)
Definition: CAUtil.cpp:780
SINT32 saveFile(const UINT8 *const name, const UINT8 *const buff, UINT32 buffSize)
Definition: CAUtil.cpp:1352
SINT32 encodeXMLEncryptedKey(UINT8 *key, UINT32 keylen, UINT8 *xml, UINT32 *xmllen, CAASymCipher *pRSA)
Definition: CAUtil.cpp:1683
SINT32 decodeXMLEncryptedKey(UINT8 *key, UINT32 *keylen, const UINT8 *const xml, UINT32 xmllen, CAASymCipher *pRSA)
Definition: CAUtil.cpp:1625
SINT32 msSleep(UINT32 ms)
Sleeps ms milliseconds.
Definition: CAUtil.cpp:406
bool isZero64(UINT64 &op1)
Definition: CAUtil.hpp:464
#define GET_NET_ERROR
Definition: StdAfx.h:469
#define MAX_READ_FROM_PREV_MIX_QUEUE_SIZE
Definition: StdAfx.h:226
#define GET_NET_ERROR_STR(x)
Definition: StdAfx.h:471
#define MIX_POOL_TIMEOUT
Definition: StdAfx.h:245
#define REPLAY_TIMESTAMP_PROPAGATION_INTERVALL
Definition: StdAfx.h:176
#define THREAD_RETURN
Definition: StdAfx.h:540
#define ERR_INTERN_CONNREFUSED
Definition: StdAfx.h:475
#define SOCKET_ERROR
Definition: StdAfx.h:464
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542
#define MAX_READ_FROM_NEXT_MIX_QUEUE_SIZE
Definition: StdAfx.h:227
#define ERR_INTERN_TIMEDOUT
Definition: StdAfx.h:474
#define DUMMY_CHANNEL
Definition: StdAfx.h:246
#define FM_PACKET_STATS_LOG_INTERVALL
Definition: StdAfx.h:248
#define MIX_POOL_SIZE
Definition: StdAfx.h:243
#define max(a, b)
Definition: StdAfx.h:654
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
SINT32 getPublicKeyAsDOMElement(DOMElement *&elemRoot, XERCES_CPP_NAMESPACE::DOMDocument *docOwner)
SINT32 setPublicKeyAsDOMNode(DOMNode *node)
SINT32 setPublicKeyAsXML(const UINT8 *buff, UINT32 len)
Sets the public key to the values stored in key.
SINT32 generateKeyPair(UINT32 size)
Generates a new random key-pair of size bits.
static SINT32 encode(const UINT8 *in, UINT32 len, UINT8 *out, UINT32 *outlen)
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff...
Definition: CABase64.cpp:102
static SINT32 decode(const UINT8 *in, UINT32 len, UINT8 *out, UINT32 *outlen)
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff...
Definition: CABase64.cpp:41
CACertificate * verifyMixCert(DOMNode *mixNode)
This function parses the certificates from a <Mix>-node and tries to build a certPath to the trusted ...
UINT32 getListenerInterfaceCount()
SINT32 getMixId(UINT8 *id, UINT32 len)
SINT32 setPrevMixTestCertificate(CACertificate *cert)
UINT32 getKeepAliveRecvInterval()
CAMultiSignature * getMultiSigner()
CAListenerInterface * getListenerInterface(UINT32 nr)
CACertificate * getNextMixTestCertificate()
SINT32 setNextMixTestCertificate(CACertificate *cert)
UINT32 getKeepAliveSendInterval()
CACertStore * getTrustedCertificateStore()
UINT32 getTargetInterfaceCount()
CACertificate * getPrevMixTestCertificate()
SINT32 getTargetInterface(CATargetInterface &oTargetInterface, UINT32 nr)
Fills a TargetInterface struct with the values which belongs to the target interface nr.
This class "dispatches" messages which it receives via proccessMixPacket() to the associated control ...
SINT32 start()
Definition: CADatabase.cpp:220
static CACmdLnOptions * getOptions()
CASocketAddr * getAddr() const
SINT32 unlock()
Unlocks the lockable object by threadsafe decrementing a reference counter.
Definition: CALockAble.hpp:67
Data structure that stores all information about the currently open Mix channels.
UINT32 m_u32KeepAliveSendInterval2
CAQueue * m_pQueueSendToMixAfter
void * upstreamPreBuffer
friend THREAD_RETURN mm_loopReadFromMixAfter(void *)
friend THREAD_RETURN mm_loopSendToMixAfter(void *)
UPSTREAM (to WEB) Take the packets from the Queue and write them to the Socket.
SINT32 init()
int upstreamSemPreId
UINT32 m_u32KeepAliveRecvInterval2
const char * downstreamMemoryPreName
CAASymCipher * m_pRSA
int upstreamSemPostId
virtual SINT32 processKeyExchange()
Processes key exchange with Mix n+1 and Mix n-1.
Definition: CAMiddleMix.cpp:84
SINT32 loop()
Processes Upstream-MixPackets.
const char * downstreamMemoryPostName
void * downstreamPreBuffer
SINT32 connectToNextMix(CASocketAddr *a_pAddrNext)
SINT32 clean()
const char * upstreamMemoryPreName
int downstreamSemPostId
CAQueue * m_pQueueSendToMixBefore
volatile bool m_bRun
bool m_bShMemConfigured
friend THREAD_RETURN mm_loopReadFromMixBefore(void *)
friend THREAD_RETURN mm_loopSendToMixBefore(void *)
DOWNSTREAM (to Client) Take the packets from the Queue and write them to the Socket.
const char * upstreamMemoryPostName
int downstreamSemPreId
void * downstreamPostBuffer
CAMuxSocket * m_pMuxOut
CAMiddleMixChannelList * m_pMiddleMixChannelList
SINT32 initOnce()
Definition: CAMiddleMix.cpp:51
SINT32 putMixPacketIntoQueueSendToMixBefore(tPoolEntry *pPoolEntry)
void * upstreamPostBuffer
CAMuxSocket * m_pMuxIn
SINT32 appendCompatibilityInfo(DOMNode *a_parent)
Definition: CAMix.cpp:634
SINT32 checkCompatibility(DOMNode *a_parent, const char *a_mixPosition)
Definition: CAMix.cpp:670
SINT32 signXML(DOMNode *a_element)
Definition: CAMix.cpp:806
static const UINT32 TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT
Definition: CAMix.hpp:59
SINT32 addMixInfo(DOMNode *a_element, bool a_bForceFirstNode)
Definition: CAMix.cpp:437
CAControlChannelDispatcher * m_pMuxInControlChannelDispatcher
Definition: CAMix.hpp:196
UINT32 m_u32KeepAliveRecvInterval
Definition: CAMix.hpp:186
CAMultiSignature * m_pMultiSignature
Definition: CAMix.hpp:183
volatile bool m_bShutDown
Definition: CAMix.hpp:144
UINT32 m_u32KeepAliveSendInterval
Definition: CAMix.hpp:187
CADatabase * m_pReplayDB
CAReplayCtrlChannelMsgProc * m_pReplayMsgProc
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
static SINT32 verifyXML(const UINT8 *const in, UINT32 inlen, CACertificate *a_cert)
SINT32 signXML(DOMNode *a_node, bool appendCerts)
SINT32 close()
Closes the underlying socket.
SINT32 accept(UINT16 port)
SINT32 connect(CASocketAddr &psa)
SINT32 setSendKey(UINT8 *key, UINT32 keyLen)
SINT32 setReceiveKey(UINT8 *key, UINT32 keyLen)
SINT32 setCrypt(bool b)
SINT32 send(MIXPACKET *pPacket)
Sends a MixPacket over the Network.
SINT32 receiveFully(UINT8 *buff, UINT32 len)
Receives some "plain" bytes from the underlying socket - just a convenient function....
Definition: CAMuxSocket.hpp:69
CASocket * getCASocket()
Definition: CAMuxSocket.hpp:84
This class implements the pool strategie of a Mix.
Definition: CAPool.hpp:43
SINT32 pool(tPoolEntry *pPoolEntry)
Definition: CAPool.cpp:83
This is a simple FIFO-Queue.
Definition: CAQueue.hpp:50
SINT32 add(const void *buff, UINT32 size)
Adds data to the Queue.
Definition: CAQueue.cpp:76
SINT32 getOrWait(UINT8 *pbuff, UINT32 *psize)
Gets data from the Queue or waits until some data is available, if the Queue is empty.
Definition: CAQueue.cpp:209
UINT32 getSize()
Returns the size of stored data in byte.
Definition: CAQueue.hpp:101
SINT32 startTimeStampPorpagation(UINT32 minutesPropagationIntervall)
Sends the current replay timestamp periodically on the downstream replay control channel.
This is an abstract class for representing a socket address used in CASocket, CADatagramSocket and CA...
virtual SINT32 getType() const =0
The type (family) of socket for which this address is useful.
virtual SINT32 toString(UINT8 *buff, UINT32 bufflen) const =0
Returns a string which describes this address in a human readable form.
SINT32 add(SOCKET &s)
virtual SINT32 send(const UINT8 *buff, UINT32 len)
Sends some data over the network.
Definition: CASocket.cpp:400
virtual SINT32 setKeepAlive(bool b)
Enables/disables the socket keep-alive option.
Definition: CASocket.cpp:906
virtual SINT32 setRecvBuff(UINT32 r)
Definition: CASocket.cpp:846
virtual SINT32 setSendBuff(SINT32 r)
Returns < 0 on error, otherwise the new sendbuffersize (which may be less than r)
Definition: CASocket.cpp:862
virtual SINT32 create()
Definition: CASocket.cpp:73
static CASymChannelCipher * createCipher(SYMCHANNELCIPHER_ALGORITHM alg)
virtual SINT32 setKeys(const UINT8 *key, UINT32 keysize)=0
Sets the keys for crypt1() and crypt2() either to the same key (if keysize==KEY_SIZE) or to different...
virtual SINT32 crypt2(const UINT8 *in, UINT8 *out, UINT32 len)=0
virtual SINT32 crypt1(const UINT8 *in, UINT8 *out, UINT32 len)=0
TargetType getTargetType() const
CASocketAddr * getAddr() const
SINT32 start(void *param, bool bDaemon=false, bool bSilent=false)
Starts the execution of the main function of this thread.
Definition: CAThread.cpp:115
SINT32 setMainLoop(THREAD_MAIN_TYP fnc)
Sets the main function which will be executed within this thread.
Definition: CAThread.hpp:148
SINT32 join()
Waits for the main function to finish execution.
Definition: CAThread.cpp:187
static SINT32 dumpToMem(const DOMNode *node, UINT8 *buff, UINT32 *size)
Dumps the node and all childs into buff.
Definition: DOM_Output.hpp:161
#define REPLAY_CONTROL_CHANNEL_ID
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_UNKNOWN
Definition: errorcodes.hpp:3
#define E_TIMEDOUT
Definition: errorcodes.hpp:10
@ ev_net_nextConnectionClosed
@ ev_net_keyExchangePrevSuccessful
@ ev_net_prevConnectionClosed
@ ev_net_keyExchangeNextSuccessful
@ ev_net_keyExchangePrevFailed
@ ev_net_keyExchangeNextFailed
@ ev_net_nextConnected
@ ev_net_prevConnected
CAMix * pMix
Definition: proxytest.cpp:75
HCHANNEL channel
Definition: typedefs.hpp:117
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
Definition: typedefs.hpp:169
MIXPACKET packet
Definition: typedefs.hpp:170
@ TARGET_MIX
Definition: typedefs.hpp:32
#define MIXPACKET_SIZE
Definition: typedefs.hpp:40
#define CHANNEL_ALLOWED_FLAGS
Definition: typedefs.hpp:60
#define CHANNEL_DUMMY
Definition: typedefs.hpp:50
UINT32 HCHANNEL
Definition: typedefs.hpp:34
#define CHANNEL_CLOSE
Definition: typedefs.hpp:47
struct t_queue_entry tQueueEntry
Definition: typedefs.hpp:188
UINT16 len
Definition: typedefs.hpp:0
tQueueEntry tPoolEntry
Definition: typedefs.hpp:192
#define CHANNEL_SIG_CRIME
Definition: typedefs.hpp:58
#define CHANNEL_OPEN
Definition: typedefs.hpp:43
#define DATA_SIZE
Definition: typedefs.hpp:69