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

📄 sec_de3s.cpp

📁 伯克利做的SFTP安全文件传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// sec_de3s.cpp// code for sec_de3s.h// copyright SafeTP Development Group, Inc., 2000  Terms of use are as specified in license.txt#include <stdio.h>          // printf#include <string.h>         // strlen#include "sec_de3s.h"       // this module#include "keyutils.h"       // LoadKey#include "globrand.h"       // getRandomBytes#include "exc.h"            // xsecurity#include "warn.h"           // warning#include "blokutil.h"       // Left, Right, ||, etc.#include "sdsa.h"           // DSA*#include "keydb.h"          // handleServerKey#include "sockutil.h"       // formatAddress// logging levels://   0  no logging//   1  diagDataBlock1: keys and challenges//   2  everything#ifndef PROTOCOL_LOGGING#  define PROTOCOL_LOGGING 0#endif#if PROTOCOL_LOGGING >= 1#  define diagDataBlock1(block, label) block.print(label)#else#  define diagDataBlock1(block, label)#endif#if PROTOCOL_LOGGING >= 2#  define diagnostic printf#  define diagDataBlock(block, label) diagDataBlock1(block, label)#  define diagDataBlock2(block) diagDataBlock1(block, #block)#else   static int dummyPrintf(char const *, ...) { return 0; }#  define diagnostic dummyPrintf#  define diagDataBlock(block, label)#  define diagDataBlock2(block)#endif// temp#if 0#  define tdiagnostic printf#  define tdiagDataBlock(block, label) block.print(label)#else#  define tdiagnostic dummyPrintf#  define tdiagDataBlock(block, label)#endifstatic void loadKey(char const *name, DataBlock &block, bool forceprotected=false){  string s(name);  if (!LoadKey(s, block, forceprotected)) {        xfailure(stringb("LoadKey for " << name << " failed"));  }}// ------------------ DE3S_Shared ---------------------------------DE3S_Shared::DE3S_Shared(bool ac)  : sha1HMacSigner(NULL),    sha1HMacVerifier(NULL),    amClient(ac){}DE3S_Shared::~DE3S_Shared(){  delete sha1HMacSigner;  delete sha1HMacVerifier;}// =================== DE3S_Control ==========================DE3S_Control::DE3S_Control(KeyEnvironment *env, IPAddress ma, IPAddress pa)  : DE3S_Shared(env != NULL /*amClient*/),    controlTripleDesEnc(NULL),    controlTripleDesDec(NULL),    myAddress(ma),    peerAddress(pa),    keyEnvironment(env){  if (amClient()) {    // load client keys    loadKey("ElGamal/public.key", clientElGamalPublicKey);    diagDataBlock1(clientElGamalPublicKey, "ElGamal public key");    loadKey("ElGamal/private.key", clientElGamalPrivateKey);    diagDataBlock1(clientElGamalPrivateKey, "ElGamal private key");  }  else {    // load server keys    loadKey("DSA/public.key", brandedServerDSAPublicKey, true);      // need to forceProtected, in case we're using KEYS_IN_REGISTRY    diagDataBlock1(brandedServerDSAPublicKey, "branded DSA public key");    loadKey("DSA/private.key", serverDSAPrivateKey, true);      // need to forceProtected, in case we're using KEYS_IN_REGISTRY    diagDataBlock1(serverDSAPrivateKey, "DSA private key");    // de-brand public key (also verifies the brand)    DSABrandedPublicKey branded(brandedServerDSAPublicKey);    branded.DSAPublicKey::encode(serverDSAPublicKey);    diagDataBlock1(serverDSAPublicKey, "DSA public key");  }  state = S_SERVER_PUBLIC_KEY;  sendSequenceNumber = INITIAL_SEQUENCE_NUMBER;  receiveSequenceNumber = INITIAL_SEQUENCE_NUMBER;}DE3S_Control::~DE3S_Control(){  delete controlTripleDesEnc;  delete controlTripleDesDec;}// ------------------- ADAT negotiation ----------------------// this returns true if the (client? "client" : "server")// is sending data in this statebool DE3S_Control::isSending(bool client) const{  if (client == true) {    // client    return state==S_CLIENT_PUBLIC_KEY ||           state==S_SERVER_CHALLENGE;  }  else {    // server    return state==S_SERVER_PUBLIC_KEY ||           state==S_MASTER_KEY;  }}bool DE3S_Control::hasOutgoingAdat() const{  return isSending(amClient());}STATICDEF DataBlock DE3S_Control::makeUpChallenge(){  return getRandomBytes(CHALLENGE_LENGTH);}// return a datablock containing a string, *without* the null terminatorstatic DataBlock tagBlock(char const *tag){  return DataBlock(tag, strlen(tag));}DataBlock DE3S_Control::make3DESKey(  char const *leftTag, char const *rightTag) const{  return    Sha1(masterKey || tagBlock(leftTag)) ||    Left(4, Sha1(masterKey || tagBlock(rightTag)));}DataBlock DE3S_Control::makeShaHMacKey(char const *tag) const{  return Sha1(masterKey || tagBlock(tag));}DataBlock DE3S_Control::make3DESIV(char const *tag) const{  return Left(8, Sha1(masterKey || tagBlock(tag)));}void DE3S_Control::makeExtraKeys(){  // compute new keys  clientControl3DesKey = make3DESKey("client 3des control left",                                     "client 3des control right");  serverControl3DesKey = make3DESKey("server 3des control left",                                     "server 3des control right");  clientControl3DesIV = make3DESIV("client control 3des iv");  serverControl3DesIV = make3DESIV("server control 3des iv");  clientData3DesKey = make3DESKey("client 3des data left",                                  "client 3des data right");  serverData3DesKey = make3DESKey("server 3des data left",                                  "server 3des data right");  clientSha1HMacKey = makeShaHMacKey("client shahmac");  serverSha1HMacKey = makeShaHMacKey("server shahmac");  // display them for diagnostic purposes  diagDataBlock1(clientControl3DesKey, "client control 3DES key");  diagDataBlock1(serverControl3DesKey, "server control 3DES key");  diagDataBlock1(clientData3DesKey, "client data 3DES key");  diagDataBlock1(serverData3DesKey, "server data 3DES key");  diagDataBlock1(clientSha1HMacKey, "client SHA1HMAC key");  diagDataBlock1(serverSha1HMacKey, "server SHA1HMAC key");  // make 3des objects  controlTripleDesEnc = new CBC3DESEncTrans(    amClient()? clientControl3DesKey : serverControl3DesKey,    amClient()? clientControl3DesIV  : serverControl3DesIV);  controlTripleDesDec = new CBC3DESDecTrans(    amClient()? serverControl3DesKey : clientControl3DesKey,    amClient()? serverControl3DesIV  : clientControl3DesIV);  // make sha1hmac objects  sha1HMacSigner = new SHA1HMAC(    amClient()? clientSha1HMacKey : serverSha1HMacKey);  sha1HMacVerifier = new SHA1HMAC(    amClient()? serverSha1HMacKey : clientSha1HMacKey);}void DE3S_Control::getNextOutgoingAdat(DataBlock &block){  if (amClient() == false) {     // server    if (state == S_SERVER_PUBLIC_KEY) {      block = brandedServerDSAPublicKey;    }    else {      xassert(state == S_MASTER_KEY);      // compute challenge      serverChallenge = makeUpChallenge();      diagDataBlock1(serverChallenge, "server challenge");      // compute master key      masterKey = getRandomBytes(MASTER_KEY_LENGTH);      diagDataBlock1(masterKey, "master key");      // compute final message      block = elGamalEncrypt(clientElGamalPublicKey, masterKey) ||              clientChallenge || serverChallenge;      appendIPAddress(block, myAddress);      dsaSign(serverDSAPrivateKey, block);      // compute the extra keys      makeExtraKeys();    }  }  else {     // client    if (state == S_CLIENT_PUBLIC_KEY) {      // compute challenge      clientChallenge = makeUpChallenge();      diagDataBlock1(clientChallenge, "client challenge");      // compute final message      block = clientElGamalPublicKey || clientChallenge;    }    else {      xassert(state == S_SERVER_CHALLENGE);      // compute the main keys      makeExtraKeys();      // compute block to send      block = serverChallenge;      controlTripleDesEnc->trans(block);    }  }  state = (State)(state + 1);}bool DE3S_Control::expectingIncomingAdat() const{  // I'm expecting data during precisely those states  // where the other guy is sending data  return isSending(!amClient());}void DE3S_Control::incomingAdat(DataBlock &block){  if (amClient() == false) {     // server    if (state == S_CLIENT_PUBLIC_KEY) {      // pull apart client challenge and client ElGamal public key      clientChallenge = removeBlock(block, CHALLENGE_LENGTH);      diagDataBlock1(clientChallenge, "client challenge");      clientElGamalPublicKey = block;      diagDataBlock1(clientElGamalPublicKey, "ElGamal public key");    }    else {      xassert(state == S_SERVER_CHALLENGE);      // un-3des      controlTripleDesDec->trans(block);      diagDataBlock1(block, "client's challenge response");      // compare to serverChallenge      if (block != serverChallenge) {        xsecurity("Client failed server's challenge.");      }      else {        diagnostic("client passed server's challenge\n");      }    }  }  else {     // client    if (state == S_SERVER_PUBLIC_KEY) {      // extract key      brandedServerDSAPublicKey = block;      diagDataBlock1(brandedServerDSAPublicKey, "branded DSA public key");      // de-brand key (and verify brand)      DSABrandedPublicKey branded(brandedServerDSAPublicKey);      branded.DSAPublicKey::encode(serverDSAPublicKey);      diagDataBlock1(serverDSAPublicKey, "DSA public key");      // consult public-key database      xassert(keyEnvironment != NULL);      handleServerKey(brandedServerDSAPublicKey,                      peerAddress /*host ip*/,                      *keyEnvironment);    }    else {      xassert(state == S_MASTER_KEY);      // check the DSA signature      dsaVerify(serverDSAPublicKey, block,                "Server's signature is invalid.");      // pull apart concatenated pieces      IPAddress serverIP = removeIPAddress(block);      if (serverIP != peerAddress) {        // have to make a policy decision; the called code can        // throw xsecurity if it doesn't want to allow it        keyEnvironment->policy.          serverIPMismatch(serverIP, peerAddress, serverDSAPublicKey);      }      serverChallenge = removeBlock(block, CHALLENGE_LENGTH);      diagDataBlock1(serverChallenge, "server challenge");      DataBlock clientChallengeTry = removeBlock(block, CHALLENGE_LENGTH);      diagDataBlock1(clientChallengeTry, "server's challenge response");      if (clientChallengeTry != clientChallenge) {        xsecurity("Server failed client's challenge.");      }      else {        diagnostic("server passed client's challenge\n");      }      // what remains is the encrypted master key      diagDataBlock1(block, "encrypted master key");      masterKey = elGamalDecrypt(clientElGamalPrivateKey, block);      diagDataBlock1(masterKey, "master key");    }  }  state = (State)(state + 1);}// ---------------- Steady-state encoding --------------------------void DE3S_Control::encode(DataBlock &data){  int srclen = data.getDataLen();  xassert(state == S_AUTHENTICATED);  tdiagDataBlock(data, "plaintext");  // append flag byte  appendNBO32(data, FLAG_CONTROL |                    (amClient()? FLAG_CLIENT : FLAG_SERVER));  tdiagDataBlock(data, "with flags");  // append sequence number  appendNBO32(data, sendSequenceNumber++);  tdiagDataBlock(data, "with seqnum");  // append SHA1HMac code  appendDigest(data, *sha1HMacSigner);  tdiagDataBlock(data, "with signature");  // triple-des the thing  controlTripleDesEnc->trans(data);  tdiagDataBlock(data, "ciphertext");  xassert(data.getDataLen() <= maximumEncodedSize(srclen));

⌨️ 快捷键说明

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