⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sec_de3s.cpp

📁 伯克利做的SFTP安全文件传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}int DE3S_Control::maximumEncodedSize(int decodedLen) const{  int len = decodedLen;  //tdiagnostic("%d: len = %d\n", __LINE__, len);  len += 8;                      // flag, sequence #  //tdiagnostic("%d: len = %d\n", __LINE__, len);  len += sha1HMacSigner->DigestSize();  //tdiagnostic("%d: len = %d\n", __LINE__, len);  len = controlTripleDesEnc->maxOutputSize(len);  //tdiagnostic("%d: len = %d\n", __LINE__, len);  return len;}void DE3S_Control::decode(DataBlock &data){  int srclen = data.getDataLen();  xassert(state == S_AUTHENTICATED);  tdiagDataBlock(data, "ciphertext");  // triple-des decode  controlTripleDesDec->trans(data);  tdiagDataBlock(data, "un-3des'd");  // check SHA1HMac code  checkDigest(data, *sha1HMacVerifier,              "SHA1HMac does not match.");  tdiagDataBlock(data, "removed sig");  // check sequence number  checkNBO32(data, receiveSequenceNumber++,             "Sequence number does not match.");  tdiagDataBlock(data, "removed seqnum");  // check flags  checkNBO32(data, FLAG_CONTROL |                   (amClient()? FLAG_SERVER : FLAG_CLIENT),             "Flags word does not match.");  tdiagDataBlock(data, "plaintext");  xassert(data.getDataLen() <= maximumDecodedSize(srclen));}int DE3S_Control::maximumDecodedSize(int encodedLen) const{  int len = encodedLen;  //tdiagnostic("%d: len = %d\n", __LINE__, len);  len = controlTripleDesDec->maxOutputSize(len);  //tdiagnostic("%d: len = %d\n", __LINE__, len);  len -= sha1HMacVerifier->DigestSize();  //tdiagnostic("%d: len = %d\n", __LINE__, len);  len -= 8;     // flags, sequence #  //tdiagnostic("%d: len = %d\n", __LINE__, len);  return len;}// ---------------------- DES3_Data -------------------------DE3S_Data::DE3S_Data(DE3S_Shared &sh)  : shared(sh),    dataTripleDesEnc(NULL),    dataTripleDesDec(NULL),    sequenceNumber(INITIAL_SEQUENCE_NUMBER),    fileNumber(INITIAL_FILE_NUMBER),    fileDSL(DSL_NONE)      // to detect failure to call newFile{}DE3S_Data::~DE3S_Data(){  deleteCryptoObjs();}void DE3S_Data::deleteCryptoObjs(){  delete dataTripleDesEnc;  dataTripleDesEnc = NULL;  delete dataTripleDesDec;  dataTripleDesDec = NULL;}void DE3S_Data::buildCryptoObjs(){  // construct the initialization vector:  // 64-bit big-endian representation of file #  DataBlock IV;  appendNBO32(IV, 0);           // high 32 bits are 0  appendNBO32(IV, fileNumber);  // low 32 bits are file #  // Some rationale on initialization vectors:  The basic idea is that we  // only need, for each encrypted message (with a particular key), to use  // a *different* IV.  We don't need secret IVs, nor random IVs.  The reason  // secrecy is not necessary is, because of the construction, all IVs after  // the first are transmitted in the clear anyway, as the ciphertext blocks  // themselves.  The reason randomness isn't necessary is because we XOR the  // IV with the first plaintext block, and *then* encrypt-- the encryption  // effectively jumbles things up.  Even the first IV, which is 0, isn't a  // problem because it will still be unique.  //  // Most of this reasoning is based on Schneier, pp. 193-194.  // The CRC Handbook of Cryptography seems to confirm this.  // Note that using the file # as the initialization vector means if the  // client and server get out of sync, decryption becomes impossible and  // the HMAC will not match.  // construct crypto objects  dataTripleDesEnc = new CBC3DESEncTrans(    shared.amClient? shared.clientData3DesKey :                     shared.serverData3DesKey,    IV);  dataTripleDesDec = new CBC3DESDecTrans(    shared.amClient? shared.serverData3DesKey :                     shared.clientData3DesKey,    IV);}// I'm letting part of the object's initialization take place after// the ctor because it's convenient to construct it early, but the// data we need (the 3des keys) isn't available thenvoid DE3S_Data::ensureCryptoObjs() const{  // verify they're either both null, or both non-null  xassert((dataTripleDesEnc == NULL) ==          (dataTripleDesDec == NULL));  // build them if necessary  if (dataTripleDesEnc == NULL) {    // this call is a violation of this fn being 'const'; however,    // since 'ensureCryptoObjs' is called before any use of them,    // the state change that occurs here is not visible from the    // outside    const_cast<DE3S_Data*>(this)->      buildCryptoObjs();  }}void DE3S_Data::encode(DataBlock &data){  if (fileDSL == DSL_NONE) {    xfailure("you have to call newFile before encode");  }  ensureCryptoObjs();  int srclen = data.getDataLen();  tdiagDataBlock(data, "plaintext");  // flags  appendNBO32(data, FLAG_DATA |                    (shared.amClient? FLAG_CLIENT : FLAG_SERVER));  tdiagDataBlock(data, "with flags block");  // sequencing  appendNBO32(data, fileNumber);  appendNBO32(data, sequenceNumber++);  tdiagDataBlock(data, "with sequencing info");  // attach the message authentication code  appendDigest(data, *shared.sha1HMacSigner);  tdiagDataBlock(data, "signed");  if (fileDSL == DSL_PRIVATE) {    // encrypt it    dataTripleDesEnc->trans(data);    tdiagDataBlock(data, "cihpertext");  }  xassert(data.getDataLen() <= maximumEncodedSize(srclen, fileDSL));}int DE3S_Data::maximumEncodedSize(int decodedSize,                                  DataSecurityLevel level) const{  ensureCryptoObjs();  int len = decodedSize;  len += 12;                  // flags, sequencing  len += shared.sha1HMacSigner->DigestSize();  if (level == DSL_PRIVATE) {    len = dataTripleDesEnc->maxOutputSize(len);  }  return len;}int DE3S_Data::maximumEncodedSize(int decodedSize) const{  // largest encoding is with privacy on  return maximumEncodedSize(decodedSize, DSL_PRIVATE);}void DE3S_Data::decode(DataBlock &data){  if (fileDSL == DSL_NONE) {    xfailure("you have to call newFile before decode");  }  ensureCryptoObjs();  int srclen = data.getDataLen();  tdiagDataBlock(data, "ciphertext");  if (fileDSL == DSL_PRIVATE) {    // decrypt    dataTripleDesDec->trans(data);    tdiagDataBlock(data, "decrypted");  }  // verify message authentication code  checkDigest(data, *shared.sha1HMacVerifier,              "SHA1HMac does not match.");  tdiagDataBlock(data, "removed sig");  // check sequence number  checkNBO32(data, sequenceNumber++,             "Sequence number does not match.");  tdiagDataBlock(data, "removed seqnum");  // check file #  checkNBO32(data, fileNumber,             "File number does not match.");  tdiagDataBlock(data, "removed file #");  // check flags  checkNBO32(data, FLAG_DATA |                   (shared.amClient? FLAG_SERVER : FLAG_CLIENT),             "Flags word does not match.");  tdiagDataBlock(data, "removed flags");  if (!( data.getDataLen() <= maximumDecodedSize(srclen, fileDSL) )) {    breaker();  }  xassert(data.getDataLen() <= maximumDecodedSize(srclen, fileDSL));}int DE3S_Data::maximumDecodedSize(int encodedSize,                                  DataSecurityLevel level) const{  ensureCryptoObjs();  int len = encodedSize;  if (level == DSL_PRIVATE) {    len = dataTripleDesDec->maxOutputSize(len);  }  len -= shared.sha1HMacVerifier->DigestSize();  len -= 12;     // flags, sequencing  return len;}int DE3S_Data::maximumDecodedSize(int encodedSize) const{  // max decoded happens when the data was *not* encrypted  return maximumDecodedSize(encodedSize, DSL_INTEGRITY);}DataSecurityLevel DE3S_Data::getSupportedProtLevels() const{          // this object does *not* support cleartext -- that is handled  // by having the data simply never pass through the DE3S_Data  // object  return (DataSecurityLevel)(DSL_INTEGRITY | DSL_PRIVATE);    // I continue to be annoyed by the erratic treatment enums gets  // w/respect to bitwise or..}// called between data channel filesvoid DE3S_Data::newFile(DataSecurityLevel level){  // check that level is among named levels  DataSecurity::newFile(level);  sequenceNumber = INITIAL_SEQUENCE_NUMBER;  fileNumber++;  fileDSL = level;  // this will force them to be created anew  deleteCryptoObjs();}char DE3S_Data::getCodeForLevel(DataSecurityLevel level) const{  switch (level) {    case DSL_INTEGRITY:  return 'T';    case DSL_PRIVATE:    return 'P';    default:      xfailure("invalid security level");      return '!';        // silence warning  }}DataSecurityLevel DE3S_Data::getLevelForCode(char code) const{  // Note: I am assuming the argument to PROT case-sensitive  // see which level it is  switch (code) {    case 'S':    // 2228: "safe"    case 'E':    // 2228: "confidential"    case 'P':    // 2228: "private" (integrity + confidentiality)      // unfortunately, my original implementation mapped S, E, and P      // all to P, effectively.  so, rather than change the meaning of      // existing letters, we continue to support the original meaning..      return DSL_PRIVATE;    case 'T':    // means (roughly) what 2228 means by "safe"      // ..and instead *extend*, by using what was before an illegal code      return DSL_INTEGRITY;    default:      // unknown code      return DSL_NONE;  }}// ---------------- DE3S_Provider -------------------------DE3S_Provider::DE3S_Provider(KeyEnvironment *env, IPAddress myAddr,                             IPAddress peerAddr){  // I was forced to make these objects separate from the  // provider by one of two things:  //   1. g++ sucks  //   2. I forgot to recompile after a certain change  // since I already know that (1) is true I'm not going to  // waste time finding out if it was responsible for this  // particular issue  _control = new DE3S_Control(env, myAddr, peerAddr);  _data = new DE3S_Data(*_control);}DE3S_Provider::~DE3S_Provider(){  delete _control;  delete _data;}// -------------- test code -----------------// at this point, this just tests CBC3DES{Enc,Dec}Trans and SHA1HMAC// (provider.cc gives everything a good workout)#ifdef TEST_SEC_DE3S#include "test.h"      // USUAL_MAINvoid entry(){  bool ok = true;  DataBlock key("abcdefghijklmnopqrstuvwx", 24),            IV("12345678", 8);  CBC3DESEncTrans enc(key, IV);  CBC3DESDecTrans dec(key, IV);  TransPair desPair(enc, dec);  ok &= desPair.test(100 /*iters*/);  // the following lines don't compile, I don't  // care why  #if 0  SHA1HMAC sign(key);  SHA1HMAC verify(key);  TransPair hmacPair(sign, verify);  ok &= hmacPair.test(100 /*iters*/);  #endif // 0  PVAL(ok);}USUAL_MAIN#endif // TEST_SEC_DE3S

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -