Advertisement
Guest User

fish.cpp for ZNC 1.4

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