bool KviMircryptionEngine::doEncryptCBC(KviCString & plain, KviCString & encoded) { // make sure it is a multiple of 8 bytes (eventually pad with zeroes) if(plain.len() % 8) { int oldL = plain.len(); plain.setLen(plain.len() + (8 - (plain.len() % 8))); char * padB = plain.ptr() + oldL; char * padE = plain.ptr() + plain.len(); while(padB < padE) *padB++ = 0; } int ll = plain.len() + 8; unsigned char * in = (unsigned char *)KviMemory::allocate(ll); InitVectorEngine::fillRandomIV(in, 8); KviMemory::copy(in + 8, plain.ptr(), plain.len()); // encrypt unsigned char * out = (unsigned char *)KviMemory::allocate(ll); BlowFish bf((unsigned char *)m_szEncryptKey.ptr(), m_szEncryptKey.len()); bf.ResetChain(); bf.Encrypt(in, out, ll, BlowFish::CBC); KviMemory::free(in); encoded.bufferToBase64((const char *)out, ll); KviMemory::free(out); encoded.prepend('*'); // prepend the signature return true; }
KviCryptEngine::EncryptResult KviMircryptionEngine::encrypt(const char * plainText, KviCString & outBuffer) { KviCString szPlain = plainText; outBuffer = ""; if(m_bEncryptCBC) { if(!doEncryptCBC(szPlain, outBuffer)) return KviCryptEngine::EncryptError; } else { if(!doEncryptECB(szPlain, outBuffer)) return KviCryptEngine::EncryptError; } outBuffer.prepend("+OK "); if(outBuffer.len() > maxEncryptLen()) { if(maxEncryptLen() > 0) { setLastError(__tr2qs("Data buffer too long")); return KviCryptEngine::EncryptError; } } //outBuffer = MCPS2_STARTTAG; //outBuffer += MCPS2_ENDTAG; return KviCryptEngine::Encrypted; }
void blockFromBuffer(KviCString & szBuffer) { indent(szBuffer); szBuffer.prepend("{\n"); szBuffer.stripRightWhiteSpace(); szBuffer.ensureLastCharIs('\n'); szBuffer.append("}\n"); }
KviCryptEngine::EncryptResult KviRijndaelEngine::encrypt(const char * plainText, KviCString & outBuffer) { if(!m_pEncryptCipher) { setLastError(__tr2qs("Oops! Encryption cipher not initialized")); return KviCryptEngine::EncryptError; } int len = (int)kvi_strLen(plainText); char * buf = (char *)KviMemory::allocate(len + 16); // needed for the eventual padding unsigned char * iv = nullptr; if(m_bEncryptMode == CBC) { iv = (unsigned char *)KviMemory::allocate(MAX_IV_SIZE); InitVectorEngine::fillRandomIV(iv, MAX_IV_SIZE); } int retVal = m_pEncryptCipher->padEncrypt((const unsigned char *)plainText, len, (unsigned char *)buf, iv); if(retVal < 0) { KviMemory::free(buf); setLastErrorFromRijndaelErrorCode(retVal); return KviCryptEngine::EncryptError; } if(m_bEncryptMode == CBC) { // prepend the iv to the cyphered text buf = (char *)KviMemory::reallocate(buf, retVal + MAX_IV_SIZE); KviMemory::move(buf + MAX_IV_SIZE, buf, retVal); KviMemory::move(buf, iv, MAX_IV_SIZE); KviMemory::free(iv); retVal += MAX_IV_SIZE; } if(!binaryToAscii(buf, retVal, outBuffer)) { KviMemory::free(buf); return KviCryptEngine::EncryptError; } KviMemory::free(buf); if(outBuffer.len() > maxEncryptLen()) { if(maxEncryptLen() > 0) { setLastError(__tr2qs("Data buffer too long")); return KviCryptEngine::EncryptError; } } outBuffer.prepend(KviControlCodes::CryptEscape); return KviCryptEngine::Encrypted; }
bool KviCryptController::initializeEngine(KviCryptEngine * pEngine) { KviCString szEncryptKey; KviCString szDecryptKey; KviCString szEncKey = ""; KviCString szDecKey = ""; if(m_pEnableEncrypt->isChecked()) { bool bEcb=false, bOld=false; szEncryptKey = m_pEncryptKeyEdit->text(); if(kvi_strEqualCIN("ecb:",szEncryptKey.ptr(),4) && (szEncryptKey.len() > 4)) { szEncryptKey.cutLeft(4); bEcb=true; } else if(kvi_strEqualCIN("old:",szEncryptKey.ptr(),4) && (szEncryptKey.len() > 4)) { szEncryptKey.cutLeft(4); bOld=true; } else if(kvi_strEqualCIN("cbc:",szEncryptKey.ptr(),4)) { szEncryptKey.cutLeft(4); } if(m_pEncryptHexKeyCheck->isChecked()) { char * pcTmpKey; if(szEncryptKey.hexToBuffer(&pcTmpKey,false)) { szEncKey = pcTmpKey; KviCString::freeBuffer(pcTmpKey); } } else { szEncKey = szEncryptKey; } if(bEcb) szEncKey.prepend("ecb:"); else if(bOld) szEncKey.prepend("old:"); } if(m_pEnableDecrypt->isChecked()) { bool bEcb=false, bOld=false; szDecryptKey = m_pDecryptKeyEdit->text(); if(kvi_strEqualCIN("ecb:",szDecryptKey.ptr(),4) && (szDecryptKey.len() > 4)) { szDecryptKey.cutLeft(4); bEcb=true; } else if(kvi_strEqualCIN("old:",szDecryptKey.ptr(),4) && (szDecryptKey.len() > 4)) { szDecryptKey.cutLeft(4); bOld=true; } else if(kvi_strEqualCIN("cbc:",szDecryptKey.ptr(),4)) { szDecryptKey.cutLeft(4); } if(m_pDecryptHexKeyCheck->isChecked()) { char * pcTmpKey; if(szDecryptKey.hexToBuffer(&pcTmpKey,false)) { szDecKey = pcTmpKey; KviCString::freeBuffer(pcTmpKey); } } else { szDecKey = szDecryptKey; } if(bEcb) szDecKey.prepend("ecb:"); else if(bOld) szDecKey.prepend("old:"); } bool bRet = pEngine->init(szEncKey.ptr(),szEncKey.len(),szDecKey.ptr(),szDecKey.len()); return bRet; }
static void dccModuleParseDccRecv(KviDccRequest * dcc) { // DCC [TS]RECV <filename> <ipaddr> <port> <resume-filesize> if(!dcc_module_check_limits(dcc)) return; if(!dcc_module_check_concurrent_transfers_limit(dcc)) return; if(!dcc_module_normalize_target_data(dcc, dcc->szParam2, dcc->szParam3)) return; if(!(dcc->szParam4.isUnsignedNum())) { if(!dcc->ctcpMsg->msg->haltOutput()) { dcc->ctcpMsg->msg->console()->outputNoFmt(KVI_OUT_DCCMSG, __tr2qs_ctx("The above request has resume file size missing, assuming a resume file size of 0", "dcc")); } dcc->szParam4 = "0"; } if(dcc->szParam1.contains('/')) { if(!dcc->ctcpMsg->msg->haltOutput()) { dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG, __tr2qs_ctx("The above request is broken: the filename contains path components, stripping the leading path and trying to continue", "dcc"), dcc->szParam1.ptr()); } dcc->szParam1.cutToLast('/'); } KviCString szExtensions = dcc->szType; szExtensions.cutRight(4); // cut off RECV bool bTurboExtension = szExtensions.contains('T', false); #ifdef COMPILE_SSL_SUPPORT bool bSSLExtension = szExtensions.contains('S', false); #else //!COMPILE_SSL_SUPPORT if(szExtensions.contains('S', false)) { dcc_module_request_error(dcc, __tr2qs_ctx("This executable has been compiled without SSL support, the SSL extension to DCC RECV is not available", "dcc")); return; } #endif //!COMPILE_SSL_SUPPORT // If we have a file offer for this...do it automatically KviSharedFile * o = g_pSharedFilesManager->lookupSharedFile(dcc->szParam1.ptr(), dcc->ctcpMsg->pSource, 0); if(o) { unsigned int uResumeSize = dcc->szParam4.toUInt(); // this will NEVER fail if(uResumeSize >= o->fileSize()) { // senseless request QString szError = QString(__tr2qs_ctx("Invalid RECV request: position %1 is larger than file size", "dcc")).arg(uResumeSize); dcc_module_request_error(dcc, szError); return; } // ok...we have requested this send // #warning "Maybe remove this file offer now ?" DccDescriptor * d = new DccDescriptor(dcc->pConsole); d->szNick = dcc->ctcpMsg->pSource->nick(); d->szUser = dcc->ctcpMsg->pSource->user(); d->szHost = dcc->ctcpMsg->pSource->host(); d->szFileName = dcc->szParam1.ptr(); d->szFileSize = dcc->szParam4.ptr(); //d->bResume = false; // This is actually useless d->szLocalFileName = o->absFilePath(); d->szLocalFileSize.setNum(o->fileSize()); // Should we look it up again ? d->bRecvFile = false; d->bNoAcks = bTurboExtension; d->bAutoAccept = true; d->bIsIncomingAvatar = false; d->bIsTdcc = bTurboExtension; #ifdef COMPILE_SSL_SUPPORT d->bIsSSL = bSSLExtension; #endif d->bOverrideMinimize = false; // We know everything dcc_fill_local_nick_user_host(d, dcc); d->bDoTimeout = true; d->szIp = dcc->szParam2.ptr(); d->szPort = dcc->szParam3.ptr(); d->bActive = true; dcc_module_set_dcc_type(d, "SEND"); d->triggerCreationEvent(); g_pDccBroker->sendFileExecute(nullptr, d); return; } else { dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG, __tr2qs_ctx("%Q [%Q@%Q] is ready to receive the file \"%s\"", "dcc"), &(dcc->ctcpMsg->pSource->nick()), &(dcc->ctcpMsg->pSource->user()), &(dcc->ctcpMsg->pSource->host()), dcc->szParam1.ptr()); dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG, __tr2qs_ctx("The remote client is listening on interface %s and port %s", "dcc"), dcc->szParam2.ptr(), dcc->szParam3.ptr()); KviCString szSwitches = "-c"; if(bTurboExtension) szSwitches.prepend("-t "); #ifdef COMPILE_SSL_SUPPORT if(bSSLExtension) szSwitches.prepend("-s "); #endif dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG, __tr2qs_ctx("Use %c\r![!dbl]dcc.send %s -i=%s -p=%s %Q\r/dcc.send %s -i=%s -p=%s %Q\r%c to send the file (or double-click on the socket)", "dcc"), KviControlCodes::Bold, szSwitches.ptr(), dcc->szParam2.ptr(), dcc->szParam3.ptr(), &(dcc->ctcpMsg->pSource->nick()), szSwitches.ptr(), dcc->szParam2.ptr(), dcc->szParam3.ptr(), &(dcc->ctcpMsg->pSource->nick()), KviControlCodes::Bold); } }