Advertisement
knarzling

fish.cpp znc-git-recent

Jun 7th, 2012
1,252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.62 KB | None | 0 0
  1. #include "znc/main.h"
  2. #include "znc/User.h"
  3. #include "znc/Nick.h"
  4. #include "znc/Modules.h"
  5. #include "znc/Chan.h"
  6. #include "znc/IRCNetwork.h"
  7.  
  8. #include <string.h>
  9. using std::pair;
  10. using std::map;
  11.  
  12. #include <netinet/in.h>
  13.  
  14. #include <openssl/opensslv.h>
  15. #include <openssl/blowfish.h>
  16.  
  17. #define REQUIRESSL  1
  18.  
  19. #if (OPENSSL_VERSION_NUMBER < 0x0090800f)
  20. #error "We require openssl >= 0.9.8"
  21. #endif
  22.  
  23. /*
  24.     Public Base64 conversion tables
  25. */
  26. unsigned char B64ABC[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  27. unsigned char b64buf[256];
  28.  
  29.  
  30. /*
  31.     void initb64();
  32.     Initializes the base64->base16 conversion tab.
  33.     Call this function once when your program starts.
  34.     and always after your B64 table has been changed.
  35. */
  36. void initb64(){
  37.     unsigned int i;
  38.     for (i=0; i<256; i++) b64buf[i]=0x00;
  39.     for (i=0; i<64; i++) b64buf[(B64ABC[i])]=i;
  40. }
  41.  
  42. /*
  43.    int b64toh(lpBase64String, lpDestinationBuffer);
  44.    Converts base64 string b to hexnumber d.
  45.    Returns size of hexnumber in bytes.
  46. */
  47. int b64toh(char *b, char *d){
  48.     int i,k,l;
  49.  
  50.     l=strlen(b);
  51.     if (l<2) return 0;
  52.     for (i=l-1;i>-1;i--){
  53.         if (b64buf[(unsigned char)(b[i])]==0) l--;
  54.         else break;
  55.     }
  56.  
  57.     if (l<2) return 0;
  58.     i=0, k=0;
  59.     while (1) {
  60.         i++;
  61.         if (k+1<l) d[i-1]=((b64buf[(unsigned char)(b[k])])<<2);
  62.         else break;
  63.         k++;
  64.         if (k<l) d[i-1]|=((b64buf[(unsigned char)(b[k])])>>4);
  65.         else break;
  66.         i++;
  67.         if (k+1<l) d[i-1]=((b64buf[(unsigned char)(b[k])])<<4);
  68.         else break;
  69.         k++;
  70.         if (k<l) d[i-1]|=((b64buf[(unsigned char)(b[k])])>>2);
  71.         else break;
  72.         i++;
  73.         if (k+1<l) d[i-1]=((b64buf[(unsigned char)(b[k])])<<6);
  74.         else break;
  75.         k++;
  76.         if (k<l) d[i-1]|=(b64buf[(unsigned char)(b[k])]);
  77.         else break;
  78.         k++;
  79.     }
  80.     return i-1;
  81. }
  82.  
  83. /*
  84.    int htob64(lpHexNumber, lpDestinationBuffer);
  85.    Converts hexnumber h (with length l bytes) to base64 string d.
  86.    Returns length of base64 string.
  87. */
  88. int htob64(char *h, char *d, unsigned int l){
  89.     unsigned int i,j,k;
  90.     unsigned char m,t;
  91.  
  92.     if (!l) return 0;
  93.     l<<=3;                              // no. bits
  94.     m=0x80;
  95.     for (i=0,j=0,k=0,t=0; i<l; i++){
  96.         if (h[(i>>3)]&m) t|=1;
  97.         j++;
  98.         if (!(m>>=1)) m=0x80;
  99.         if (!(j%6)) {
  100.             d[k]=B64ABC[t];
  101.             t&=0;
  102.             k++;
  103.         }
  104.         t<<=1;
  105.     }
  106.     m=5-(j%6);
  107.     t<<=m;
  108.     if (m) {
  109.         d[k]=B64ABC[t];
  110.         k++;
  111.     }
  112.     d[k]&=0;
  113.     return strlen(d);
  114. }
  115.  
  116. unsigned char B64[]="./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  117.  
  118. const char *prime1080="FBE1022E23D213E8ACFA9AE8B9DFADA3EA6B7AC7A7B7E95AB5EB2DF858921FEADE95E6AC7BE7DE6ADBAB8A783E7AF7A7FA6A2B7BEB1E72EAE2B72F9FA2BFB2A2EFBEFAC868BADB3E828FA8BADFADA3E4CC1BE7E8AFE85E9698A783EB68FA07A77AB6AD7BEB618ACF9CA2897EB28A6189EFA07AB99A8A7FA9AE299EFA7BA66DEAFEFBEFBF0B7D8B";
  119.  
  120. int base64dec(char c)
  121. {
  122.     int i;
  123.  
  124.     for (i = 0; i < 64; i++)
  125.         if (B64[i] == c) return i;
  126.  
  127.     return 0;
  128. }
  129.  
  130. char *encrypts(char *key,char *str) {
  131.   char *result;
  132.   unsigned int length;
  133.   unsigned int left,right;
  134.   char *s,*d;
  135.   unsigned char *p;
  136.   BF_KEY bfkey;
  137.   int i;
  138.  
  139.   if(key==NULL||str==NULL) return NULL;
  140.  
  141.   length=strlen(str);
  142.   BF_set_key(&bfkey, strlen(key), (const unsigned char *)key);
  143.  
  144.   s=(char *)malloc(length+9);
  145.  
  146.   strncpy(s,str,length);
  147.   memset(s+length,0,9);
  148.  
  149.   result=(char *)malloc(((length%8==0) ? length/8*12 : 12+length/8*12)+1);
  150.  
  151.   p=(unsigned char *)s;
  152.   d=result;
  153.  
  154.   while(*p) {
  155.     BF_ecb_encrypt((const unsigned char *)p, (unsigned char *)p, &bfkey, BF_ENCRYPT);
  156.     left = ((*p++) << 24);
  157.     left += ((*p++) << 16);
  158.     left += ((*p++) << 8);
  159.     left += (*p++);
  160.     right = ((*p++) << 24);
  161.     right += ((*p++) << 16);
  162.     right += ((*p++) << 8);
  163.     right += (*p++);
  164.     for (i = 0; i < 6; i++) {
  165.         *d++=B64[right & 0x3f];
  166.         right = (right >> 6);
  167.     }
  168.  
  169.     for (i = 0; i < 6; i++) {
  170.         *d++=B64[left & 0x3f];
  171.         left = (left >> 6);
  172.     }
  173.   }
  174.   *d = '\0';
  175.  
  176.   memset(s,0,length+9);
  177.   free(s);
  178.   return result;
  179. }
  180.  
  181. char *decrypts(char *key, char *str) {
  182.   char *result;
  183.   unsigned int length;
  184.   unsigned int left,right;
  185.   int i;
  186.   char *d;
  187.   unsigned char *c;
  188.   BF_KEY bfkey;
  189.  
  190.   if(key==NULL||str==NULL) return NULL;
  191.  
  192.   length=strlen(str);
  193.   BF_set_key(&bfkey,strlen(key),(const unsigned char *)key);
  194.  
  195.   result=(char *)malloc((length/12*8)+1);
  196.   c=(unsigned char *)result;
  197.   d=str;
  198.   while(*d) {
  199.     right=0;
  200.     left=0;
  201.     for (i = 0; i < 6; i++) right |= (base64dec(*d++)) << (i * 6);
  202.     for (i = 0; i < 6; i++) left |= (base64dec(*d++)) << (i * 6);
  203.     right=htonl(right);
  204.     left=htonl(left);
  205.     memcpy(c,&left,4);
  206.     memcpy(c+4,&right,4);
  207.     BF_ecb_encrypt(c,c,&bfkey,BF_DECRYPT);
  208.     c+=8;
  209.   }
  210.   *c='\0';
  211.   return result;
  212. }
  213.  
  214. class CKeyExchangeTimer : public CTimer {
  215. public:
  216.     CKeyExchangeTimer(CModule* pModule)
  217.             : CTimer(pModule, 5, 0, "KeyExchangeTimer", "Key exchange timer removes stale exchanges") {}
  218.  
  219. protected:
  220.     virtual void RunJob();
  221. };
  222.  
  223. class CFishMod : public CModule {
  224. public:
  225.     MODCONSTRUCTOR(CFishMod) {}
  226.     virtual ~CFishMod() {
  227.     }
  228.  
  229.         virtual EModRet OnPrivNotice(CNick& Nick, CString& sMessage) {
  230.         CString command = sMessage.Token(0);
  231.         CString sOtherPub_Key = sMessage.Token(1);
  232.  
  233.         if (command.CaseCmp("DH1080_INIT") == 0 && !sOtherPub_Key.empty()) {
  234.             CString sPriv_Key;
  235.             CString sPub_Key;
  236.             CString sSecretKey;
  237.  
  238.             DH1080_gen(sPriv_Key, sPub_Key);
  239.             if (!DH1080_comp(sPriv_Key, sOtherPub_Key, sSecretKey)) {
  240.             PutModule("Error in DH1080 with " + Nick.GetNick() + ": " + sSecretKey);
  241.             return CONTINUE;
  242.             }
  243.             PutModule("Received DH1080 public key from " + Nick.GetNick() + ", sending mine...");
  244.             PutIRC("NOTICE " + Nick.GetNick() + " :DH1080_FINISH " + sPub_Key);
  245.             SetNV(Nick.GetNick().AsLower(), sSecretKey);
  246.             PutModule("Key for " + Nick.GetNick() + " successfully set.");
  247.             return HALT;
  248.         } else if (command.CaseCmp("DH1080_FINISH") == 0 && !sOtherPub_Key.empty()) {
  249.             CString sPriv_Key;
  250.             CString sSecretKey;
  251.  
  252.             map<CString, pair<time_t, CString> >::iterator it = m_msKeyExchange.find(Nick.GetNick().AsLower());
  253.             if (it == m_msKeyExchange.end()) {
  254.             PutModule("Received unexpected DH1080_FINISH from " + Nick.GetNick() + ".");
  255.             } else {
  256.             sPriv_Key = it->second.second;
  257.             if (DH1080_comp(sPriv_Key, sOtherPub_Key, sSecretKey)) {
  258.                 SetNV(Nick.GetNick().AsLower(), sSecretKey);
  259.                 PutModule("Key for " + Nick.GetNick() + " successfully set.");
  260.                 m_msKeyExchange.erase(Nick.GetNick().AsLower());
  261.             }
  262.             }
  263.             return HALT;
  264.         } else {
  265.             FilterIncoming(Nick.GetNick(), Nick, sMessage);
  266.         }
  267.  
  268.                 return CONTINUE;
  269.         }
  270.  
  271.     virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage) {
  272.         MCString::iterator it = FindNV(sTarget.AsLower());
  273.  
  274.         if (it != EndNV()) {
  275.             CChan* pChan = m_pNetwork->FindChan(sTarget);
  276.             if ((pChan) && (pChan->AutoClearChanBuffer())) {
  277.                 pChan->AddBuffer(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :" + sMessage);
  278.             }
  279.             char * cMsg = encrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
  280.  
  281.             CString sMsg = "+OK " + CString(cMsg);
  282.             PutIRC("PRIVMSG " + sTarget + " :" + sMsg);
  283.             m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :" + sMessage, NULL, m_pClient);
  284.  
  285.             free(cMsg);
  286.             return HALTCORE;
  287.         }
  288.  
  289.         return CONTINUE;
  290.     }
  291.  
  292.     virtual EModRet OnUserAction(CString& sTarget, CString& sMessage) {
  293.         MCString::iterator it = FindNV(sTarget.AsLower());
  294.  
  295.         if (it != EndNV()) {
  296.             CChan* pChan = m_pNetwork->FindChan(sTarget);
  297.             if ((pChan) && (pChan->AutoClearChanBuffer())) {
  298.                 pChan->AddBuffer(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :\001ACTION " + sMessage + "\001");
  299.             }
  300.             char * cMsg = encrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
  301.  
  302.             CString sMsg = "+OK " + CString(cMsg);
  303.             PutIRC("PRIVMSG " + sTarget + " :\001ACTION " + sMsg + "\001");
  304.             m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :\001ACTION " + sMessage + "\001", NULL, m_pClient);
  305.  
  306.             free(cMsg);
  307.             return HALTCORE;
  308.         }
  309.  
  310.         return CONTINUE;
  311.     }
  312.  
  313.     virtual EModRet OnUserNotice(CString& sTarget, CString& sMessage) {
  314.         MCString::iterator it = FindNV(sTarget.AsLower());
  315.  
  316.         if (it != EndNV()) {
  317.             CChan* pChan = m_pNetwork->FindChan(sTarget);
  318.             if ((pChan) && (pChan->AutoClearChanBuffer())) {
  319.                 pChan->AddBuffer(":" + m_pNetwork->GetIRCNick().GetNickMask() + " NOTICE " + sTarget + " :" + sMessage);
  320.             }
  321.             char * cMsg = encrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
  322.  
  323.             CString sMsg = "+OK " + CString(cMsg);
  324.             PutIRC("NOTICE " + sTarget + " :" + sMsg);
  325.             m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " NOTICE " + sTarget + " :" + sMessage, NULL, m_pClient);
  326.  
  327.             free(cMsg);
  328.             return HALTCORE;
  329.         }
  330.  
  331.         return CONTINUE;
  332.  
  333.     }
  334.  
  335.     virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic) {
  336.         if (!sTopic.empty()) {
  337.             MCString::iterator it = FindNV(sChannel.AsLower());
  338.             if (it != EndNV()) {
  339.                 char * cTopic = encrypts((char *)it->second.c_str(), (char *)sTopic.c_str());
  340.                 sTopic = "+OK " + CString(cTopic);
  341.                 free(cTopic);
  342.             }
  343.         }
  344.  
  345.         return CONTINUE;
  346.     }
  347.  
  348.     virtual EModRet OnPrivMsg(CNick& Nick, CString& sMessage) {
  349.         FilterIncoming(Nick.GetNick(), Nick, sMessage);
  350.         return CONTINUE;
  351.     }
  352.  
  353.     virtual EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) {
  354.         FilterIncoming(Channel.GetName(), Nick, sMessage);
  355.         return CONTINUE;
  356.     }
  357.  
  358.     virtual EModRet OnPrivAction(CNick& Nick, CString& sMessage) {
  359.         FilterIncoming(Nick.GetNick(), Nick, sMessage);
  360.         return CONTINUE;
  361.     }
  362.  
  363.     virtual EModRet OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage) {
  364.         FilterIncoming(Channel.GetName(), Nick, sMessage);
  365.         return CONTINUE;
  366.     }
  367.    
  368.     virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) {
  369.         FilterIncoming(Channel.GetName(), Nick, sTopic);
  370.         return CONTINUE;
  371.     }
  372.  
  373.     virtual EModRet OnRaw(CString& sLine) {
  374.         if (sLine.WildCmp(":* 332 *") && sLine.Token(1) == "332") {
  375.             CChan* pChan = m_pNetwork->FindChan(sLine.Token(3));
  376.             if (pChan) {
  377.                 CNick Nick(sLine.Token(2));
  378.                 CString sTopic = sLine.Token(4, true);
  379.                 sTopic.LeftChomp();
  380.                 FilterIncoming(pChan->GetName(), Nick, sTopic);
  381.                 sLine = sLine.Token(0) + " " + sLine.Token(1) + " " + sLine.Token(2) + " " + pChan->GetName() + " :" + sTopic;
  382.             }
  383.         }
  384.         return CONTINUE;
  385.     }
  386.  
  387.     void FilterIncoming(const CString& sTarget, CNick& Nick, CString& sMessage) {
  388.         if (sMessage.Left(4) == "+OK " || sMessage.Left(5) == "mcps ") {
  389.             MCString::iterator it = FindNV(sTarget.AsLower());
  390.  
  391.             if (it != EndNV()) {
  392.                 if (sMessage.Left(4) == "+OK ") {
  393.                     sMessage.LeftChomp(4);
  394.                 } else if (sMessage.Left(5) == "mcps ") {
  395.                     sMessage.LeftChomp(5);
  396.                 }
  397.  
  398.                 unsigned int msg_len = strlen(sMessage.c_str());
  399.  
  400.                 if ((strspn(sMessage.c_str(), (char *)B64) != msg_len) || msg_len < 12) {
  401.                     return;
  402.                 }
  403.  
  404.                 unsigned int mark_broken_block = 0;
  405.  
  406.                 if (msg_len != (msg_len/12)*12) {
  407.                     msg_len = msg_len - (msg_len/12)*12;
  408.                     sMessage.RightChomp(msg_len);
  409.                     mark_broken_block = 1;
  410.                 }
  411.  
  412.                 char *cMsg = decrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
  413.                 sMessage = CString(cMsg);
  414.  
  415.                 if (mark_broken_block) {
  416.                     sMessage += "  \002&\002";
  417.                 }
  418.  
  419.                 free(cMsg);
  420.             }
  421.         }
  422.     }
  423.  
  424.     virtual void OnModCommand(const CString& sCommand) {
  425.         CString sCmd = sCommand.Token(0);
  426.  
  427.         if (sCmd.CaseCmp("DELKEY") == 0) {
  428.             CString sTarget = sCommand.Token(1);
  429.  
  430.             if (!sTarget.empty()) {
  431.                 if (DelNV(sTarget.AsLower())) {
  432.                     PutModule("Target [" + sTarget + "] deleted");
  433.                 } else {
  434.                     PutModule("Target [" + sTarget + "] not found");
  435.                 }
  436.             } else {
  437.                 PutModule("Usage DelKey <#chan|Nick>");
  438.             }
  439.         } else if (sCmd.CaseCmp("SETKEY") == 0) {
  440.             CString sTarget = sCommand.Token(1);
  441.             CString sKey = sCommand.Token(2, true);
  442.  
  443.             if (!sKey.empty()) {
  444.                 SetNV(sTarget.AsLower(), sKey);
  445.                 PutModule("Set encryption key for [" + sTarget + "] to [" + sKey + "]");
  446.             } else {
  447.                 PutModule("Usage: SetKey <#chan|Nick> <Key>");
  448.             }
  449.         } else if (sCmd.CaseCmp("SHOWKEY") == 0) {
  450.             CString sTarget = sCommand.Token(1);
  451.  
  452.             if (!sTarget.empty()) {
  453.                 MCString::iterator it = FindNV(sTarget.AsLower());
  454.  
  455.                 if (it != EndNV()) {
  456.                     PutModule("Target key is " + it->second);
  457.                 } else {
  458.                     PutModule("Target not found.");
  459.                 }
  460.             } else {
  461.                 PutModule("Usage ShowKey <#chan|Nick>");
  462.             }
  463.         } else if (sCmd.CaseCmp("LISTKEYS") == 0) {
  464.             if (BeginNV() == EndNV()) {
  465.                 PutModule("You have no encryption keys set.");
  466.             } else {
  467.                 CTable Table;
  468.                 Table.AddColumn("Target");
  469.                 Table.AddColumn("Key");
  470.  
  471.                 for (MCString::iterator it = BeginNV(); it != EndNV(); it++) {
  472.                     Table.AddRow();
  473.                     Table.SetCell("Target", it->first);
  474.                     Table.SetCell("Key", it->second);
  475.                 }
  476.  
  477.                 if (Table.size()) {
  478.                     unsigned int uTableIdx = 0;
  479.                     CString sLine;
  480.  
  481.                     while (Table.GetLine(uTableIdx++, sLine)) {
  482.                         PutModule(sLine);
  483.                     }
  484.                 }
  485.             }
  486.         } else if (sCmd.CaseCmp("KEYX") == 0) {
  487.             CString sTarget = sCommand.Token(1);
  488.  
  489.             if (sTarget.empty()) {
  490.                 PutModule("You did not specify a target for the key exchange.");
  491.             } else {
  492.                 map<CString, pair<time_t, CString> >::iterator it = m_msKeyExchange.find(sTarget.AsLower());
  493.                 if (it != m_msKeyExchange.end()) {
  494.                 PutModule("Keyexchange with " + sTarget + " already in progress.");
  495.                 } else {
  496.                 CString sPriv_Key;
  497.                 CString sPub_Key;
  498.  
  499.                 DH1080_gen(sPriv_Key, sPub_Key);
  500.                 m_msKeyExchange.insert(make_pair(sTarget.AsLower(), make_pair(time(NULL), sPriv_Key)));
  501.                 PutIRC("NOTICE " + sTarget + " :DH1080_INIT " + sPub_Key);
  502.                 PutModule("Sent my DH1080 public key to " + sTarget + ", waiting for reply ...");
  503.                 if (FindTimer("KeyExchangeTimer") == NULL) {
  504.                     AddTimer(new CKeyExchangeTimer(this));
  505.                 }
  506.                 }
  507.             }
  508.         } else if (sCmd.CaseCmp("HELP") == 0) {
  509.             PutModule("Try: SetKey <target> <key>, DelKey <target>, ShowKey <target>, ListKeys, KeyX <target>");
  510.         } else {
  511.             PutModule("Unknown command, try 'Help'");
  512.         }
  513.     }
  514.  
  515.     void DelStaleKeyExchanges(time_t iTime) {
  516.         for (map<CString, pair<time_t, CString> >::const_iterator it = m_msKeyExchange.begin(); it != m_msKeyExchange.end(); it++) {
  517.             if (iTime - 5 >= it->second.first) {
  518.             PutModule("Keyexchange with " + it->first + " did expire before completition.");
  519.                 m_msKeyExchange.erase(it->first);
  520.             }
  521.         }
  522.         if (m_msKeyExchange.size() <= 0) {
  523.             RemTimer("KeyExchangeTimer");
  524.         }
  525.     }
  526.  
  527. private:
  528.  
  529.     void DH1080_gen(CString& sPriv_Key, CString& sPub_Key) {
  530.         sPriv_Key = "";
  531.         sPub_Key = "";
  532.  
  533.         unsigned char raw_buf[200];
  534.         unsigned long len;
  535.         unsigned char *a, *b;
  536.  
  537.         DH *dh;
  538.         BIGNUM *b_prime=NULL;
  539.         BIGNUM *b_generator=NULL;
  540.  
  541.         initb64();
  542.  
  543.         dh=DH_new();
  544.  
  545.         if (!BN_hex2bn(&b_prime, prime1080)) {
  546.             return;
  547.         }
  548.  
  549.         if (!BN_dec2bn(&b_generator, "2")) {
  550.             return;
  551.         }
  552.  
  553.         dh->p=b_prime;
  554.         dh->g=b_generator;
  555.  
  556.         if (!DH_generate_key(dh)) {
  557.             return;
  558.         }
  559.  
  560.         len = BN_num_bytes(dh->priv_key);
  561.         a = (unsigned char *)malloc(len);
  562.         BN_bn2bin(dh->priv_key,a);
  563.  
  564.         memset(raw_buf, 0, 200);
  565.         htob64((char *)a, (char *)raw_buf, len);
  566.         sPriv_Key = CString((char *)raw_buf);
  567.         len=BN_num_bytes(dh->pub_key);
  568.         b = (unsigned char *)malloc(len);
  569.         BN_bn2bin(dh->pub_key,b);
  570.         memset(raw_buf, 0, 200);
  571.         htob64((char *)b, (char *)raw_buf, len);
  572.         sPub_Key = CString((char *)raw_buf);
  573.         DH_free(dh);
  574.         free(a);
  575.         free(b);
  576.     }
  577.  
  578.  
  579.     bool DH1080_comp(CString& sPriv_Key, CString& sOtherPub_Key, CString& sSecret_Key) {
  580.         int len;
  581.         unsigned char SHA256digest[32];
  582.         char *key;
  583.         BIGNUM *b_prime=NULL;
  584.         BIGNUM *b_myPrivkey=NULL;
  585.         BIGNUM *b_HisPubkey=NULL;
  586.         BIGNUM *b_generator=NULL;
  587.         DH *dh;
  588.         CString sSHA256digest;
  589.         unsigned char raw_buf[200];
  590.  
  591.         if (!BN_hex2bn(&b_prime, prime1080)) {
  592.             return false;
  593.         }
  594.  
  595.         if (!BN_dec2bn(&b_generator, "2")) {
  596.             return false;
  597.         }
  598.  
  599.         dh=DH_new();
  600.         dh->p=b_prime;
  601.         dh->g=b_generator;
  602.  
  603.         memset(raw_buf, 0, 200);
  604.         len = b64toh((char *)sPriv_Key.c_str(), (char *)raw_buf);
  605.         b_myPrivkey=BN_bin2bn(raw_buf, len, NULL);
  606.         dh->priv_key=b_myPrivkey;
  607.  
  608.         memset(raw_buf, 0, 200);
  609.         len = b64toh((char *)sOtherPub_Key.c_str(), (char *)raw_buf);
  610.  
  611.         b_HisPubkey=BN_bin2bn(raw_buf, len, NULL);
  612.  
  613.         key=(char *)malloc(DH_size(dh));
  614.         memset(key, 0, DH_size(dh));
  615.         len=DH_compute_key((unsigned char *)key, b_HisPubkey, dh);
  616.         if (len == -1) {
  617.             // Bad pub key
  618.             unsigned long err = ERR_get_error();
  619.             DEBUG("** DH Error:" << ERR_error_string(err,NULL));
  620.             DH_free(dh);
  621.             BN_clear_free(b_HisPubkey);
  622.             free(key);
  623.  
  624.             sSecret_Key = CString(ERR_error_string(err,NULL)).Token(4,true,":");
  625.             return false;
  626.         }
  627.  
  628.         SHA256_CTX c;
  629.         SHA256_Init(&c);
  630.         memset(SHA256digest, 0, 32);
  631.         SHA256_Update(&c, key, len);
  632.         SHA256_Final(SHA256digest, &c);
  633.         memset(raw_buf, 0, 200);
  634.         len = htob64((char *)SHA256digest, (char *)raw_buf, 32);
  635.         sSecret_Key = "";
  636.         sSecret_Key.append((char *)raw_buf, len);
  637.  
  638.         DH_free(dh);
  639.         BN_clear_free(b_HisPubkey);
  640.         free(key);
  641.         return true;
  642.     }
  643.  
  644.     map<CString, pair<time_t, CString> >    m_msKeyExchange;
  645.  
  646. };
  647.  
  648. void CKeyExchangeTimer::RunJob() {
  649.         CFishMod *p = (CFishMod *)m_pModule;
  650.         p->DelStaleKeyExchanges(time(NULL));
  651. }
  652.  
  653. MODULEDEFS(CFishMod, "FiSH encryption for channel/private messages")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement