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