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

📄 sdsa.cpp

📁 伯克利做的SFTP安全文件传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  if (!ok) {    // used to say: "Invalid DSA signature" (I keep this for grepping value)    xsecurity("The DSA signature does not match");  }}void DSAVerifier::trans(DataBlock &data){  verify(data, data);}// ---------------- DSABrandedPublicKey --------------------DSABrandedPublicKey::DSABrandedPublicKey(DSABrandedPublicKey const &obj)  : DSAPublicKey(obj),    name(obj.name),    brandedKey(obj.brandedKey){}    DSABrandedPublicKey::~DSABrandedPublicKey(){}DSABrandedPublicKey::DSABrandedPublicKey(  DSASigner &signer, char const *aName, int aVersion)  : DSAPublicKey(signer),    name(aName),    brandedKey(),     // start empty    version(aVersion){  validateVersion();  // construct a branded key in the 'brandedKey' block  if (version == 1) {    // format:    //   [ encoded public key ][ encoded name ][ signature ]    signer.DSAPublicKey::encode(brandedKey);    appendString(brandedKey, name);    signer.trans(brandedKey);  }  else {    xfailure("unknown DSA key version number");  }  // append the version number (note that the signature does  // *not* include the version number-- this could turn into  // a security hole if we are careless with how versions are  // defined)  appendByte(brandedKey, (byte)version);}// since this is used above, where the version is// supplied by an argument, it's slightly nonideal// to throw xFormat always, but whatevervoid DSABrandedPublicKey::validateVersion(){  checkFormat(1 <= version &&                   version <= MAX_POSSIBLE_VERSION,              "DSA public key version is outside legal range.");  if (version > CURRENT_KEY_VERSION) {    xformat("DSA public key version is unknown");  }}DSABrandedPublicKey::DSABrandedPublicKey(DataBlock const &bkey)  : DSAPublicKey(DSAParameters(DSA_512bit_parameters), 1 /*y*/),      // dummy public key, at first    brandedKey(bkey),    version(0){  // we want to map any invalid formatting to an xSecurity since  // it is a reasonable conclusion that bad formatting is a  // consequence of tampering  try {    // get version    DataBlock stream(bkey);    version = removeByte(stream);    validateVersion();    if (version == 1) {      // extract name and public key      checkFormat(stream.getDataLen() >= DSA_SIGNATURE_LENGTH,                  "Key is too small to contain a DSA signature.");      stream.growDataLen(-DSA_SIGNATURE_LENGTH);      name = removeString(stream);      DSAPublicKey pubKey(stream);      // verify signature      stream = bkey;      stream.growDataLen(-1);     // since the version byte is not DSA-signed      DSAVerifier ver(pubKey);      ver.trans(stream);          // this throws an exception when the signature is invalid      // since signature matches, assign pubKey's members      // to this object's public-key values      p = pubKey.getP();      q = pubKey.getQ();      g = pubKey.getG();      y = pubKey.getY();    }    else {      // this would be a bug; validateVersion should have caught it before here      xfailure("validateVersion failed to detect an unknown version");    }  }  catch (xFormat &x) {    xsecurity(stringb("Corrupt branded DSA key: " << x.cond()));  }}string DSABrandedPublicKey::getShaString() const{  // compute sha of key  DataBlock sha = Sha1(brandedKey);  // render it as a hex string  int datalen = sha.getDataLen();  string ret(datalen * 3 + 1);  for (int i=0; i<datalen; i++) {    sprintf(ret.pchar() + i*3, "%02X ", sha.getDataC()[i]);  }  // trim final space  ret[datalen*3] = 0;  return ret;}// -------------------- test code -------------------------------#ifdef TEST_SDSA#include "rng.h"        // LC_RNG//#include "nbtheory.h"   // IsPrime#include "test.h"       // USUAL_MAINinline bool IsPrime(Integer const &v)  { return probablyPrime(v); }// simple random number generatorLC_RNG rng(1);bool testWithParameters(char const * const params[3]){  bool pass = true;  Integer const p(params[0], 10);  Integer const q(params[1], 10);  Integer const g(params[2], 10);  // make up a new private key  Integer x, y;  {    TimedSection ts("keygen");    DSA_keygen(      x, y,         // new key pair      p, q, g,      // parameters      rng);         // randomness  }      // print what we got  //PVAL(p);  //PVAL(q);  //PVAL(g);  PVAL(x);  PVAL(y);      // verify properties  {    TimedSection ts("parameter verification");    PVAL(IsPrime(p));    PVAL( ((p-1)/q)*q == p-1 );    PVAL(IsPrime(q));    PVAL(g > 1);    PVAL( a_exp_b_mod_c(g, x, p) == y );  }      {    TimedSection ts("find h");    int h;    enum { MAX_H = 6 };    for (h=2; h<=MAX_H; h++) {      if (a_exp_b_mod_c(h, (p-1)/q, p) == g) {        cout << h << "^((p-1)/q) mod p = g   (h = "             << h << ")\n";        break;      }    }    if (h > MAX_H) {      cout << "couldn't find h (tried 2 through " << (int)MAX_H << ")\n";    }  }  // sign something (use a value that will be treated as a digest,  // rather than going through the hassle of using SHA here)  byte const message[] = "abcdefghijklmnopqrst";    // 160 bits  Integer const digest(dataBlock2Integer(DataBlock(message, 20)));  //Integer const digest(message, 20);    // this ctor just uses the raw bits  Integer r, s;  {    TimedSection ts("sign");    DSA_sign(r, s,       // signature output             p, q, g,    // parameters             x,          // private key             digest,     // message to sign             rng);       // for computing k  }      PVAL(r);  PVAL(s);      // verify the signature  bool ok;  {    TimedSection ts("verify");    ok =      DSA_verify(p, q, g,     // parameters                 y,           // public key                 r, s,        // signature                 digest);     // message digest    pass &= ok;  }  cout << "verification: " << ok << endl;      // try to verify a false signature  {    TimedSection ts("false verify");    ok =      DSA_verify(p, q, g,                 y,                 r, s+1 /*wrong*/,                 digest);    pass &= !ok;  }  cout << "false verification: " << ok << endl;      return pass;}        // print a diagnostic saying what we are doing and what the key size isvoid sayWhatDoing(char const *funcname, char const * const *params_array){  int bits = 0;  if (params_array == DSA_512bit_parameters) {    bits = 512;  }  else if (params_array == DSA_1024bit_parameters) {    bits = 1024;  }  else {    xfailure("unknown params array");  }      printf("%s: %d bits\n", funcname, bits);}        bool testSignerAndVerifier(DSASigner &signer, DSAVerifier &verifier);    bool objectTest(char const * const *params_array){  bool ok = true;      sayWhatDoing("object test", params_array);  // decode array  DSAParameters params(params_array);  // generate a new private key, and encode the  // keys as a pair of DataBlocks  DataBlock pubKeyBlock, privKeyBlock;  {    DSAPrivateKey keys(params, rng);    keys.DSAPublicKey::encode(pubKeyBlock);    keys.encode(privKeyBlock);  }  // create encryption objects from DataBlocks  DSASigner signer(privKeyBlock, rng);  DSAVerifier verifier(pubKeyBlock);  return ok & testSignerAndVerifier(signer, verifier);}        bool testSignerAndVerifier(DSASigner &signer, DSAVerifier &verifier){  bool ok = true;  // some sample messages to sign  DataBlock const arr[] = {    DataBlock("abcdefghijkl"),    DataBlock("a\0b\0c\0d\0", 8),    DataBlock("this is a message to sign")  };  loopi(TABLESIZE(arr)) {    // sign the block    DataBlock block(arr[i]);    signer.trans(block);    // verify the block    try {      verifier.trans(block);      xassert(block == arr[i]);    }    catch (xSecurity &x) {      cout << x << ":" << endl;      arr[i].print("failing block");      ok = false;    }    // sign it again    signer.trans(block);    // modify the signature by flipping a bit    block.getData()[ block.getDataLen() - 1 ] ^= 0x40;    // observe failure to verify    try {      cout << "Expecting an exception: ";      verifier.trans(block);      cout << "failed to detect false signature:" << endl;      arr[i].print("failing block");      ok = false;    }    catch (xSecurity &)    {}  }  // test as a general trans/inverse pair  TransPair pair(signer, verifier);  ok &= pair.test(5 /*iters*/, false /*echo*/);  return ok;}bool brandingTest(char const * const *params_array){  bool ok = true;  sayWhatDoing("branding test", params_array);  // decode array  DSAParameters params(params_array);  // generate a new private key, and encode the  // keys as a pair of DataBlocks  DataBlock brandedPubKeyBlock, privKeyBlock;  {    // make private key    DSAPrivateKey keys(params, rng);    keys.encode(privKeyBlock);        // make branded public key    DSASigner signer(keys, rng);    DSABrandedPublicKey bkey(signer, "ftp.yadda-smacker.com");    brandedPubKeyBlock = bkey.encode();  }  // verify that we can read + verify the branded key  DSABrandedPublicKey pubKey(brandedPubKeyBlock);  cout << "branded name: " << pubKey.getName() << endl;  // make a signer and verifier  DSASigner signer(privKeyBlock, rng);  DSAVerifier verifier(pubKey);  // test them together  ok &= testSignerAndVerifier(signer, verifier);  // confirm that a modified branded key won't verify  brandedPubKeyBlock.getData()[5] ^= 0x40;  // flip 1 bit  cout << "expecting exception: ";  try {    DSABrandedPublicKey pubKey(brandedPubKeyBlock);    cout << "FAILED to detect modified branded key!\n";    ok = false;  }  catch (...)  {}  return ok;}// helper for robustnessTestclass RobustTestTrans : public Trans {public:  virtual void trans(DataBlock &data);  void testblock(DataBlock &data);};void RobustTestTrans::trans(DataBlock &data){  // try block as-is (almost always fails version check)  testblock(data);  // append a 1, so it will pass version test, then  // try it  DataBlock temp(data);  appendByte(temp, CURRENT_KEY_VERSION);  testblock(data);}void RobustTestTrans::testblock(DataBlock &data){  try {    DSABrandedPublicKey pubkey(data);    xfailure("random data passed test ?!?!");  }  catch (xSecurity &x) {    // this is what we want, always  }  // otherwise, the exception escapes}// test DSABrandedPublicKey's ability to not throw anything// except xSecurity when presented with any argumentbool robustnessTest(){  cout << "DSA branding robustness test\n";  // since we're going to be throwing exceptions all  // over the place, turn off logging  bool prev = xBase::logExceptions;  xBase::logExceptions = false;  // this sequence is just a convenient way of  // presenting RobustTestTrans::trans with lost  // of random buffers  Trans identity;  RobustTestTrans testPubkey;  TransPair pair(testPubkey, identity);  bool ret = pair.test(100 /*iters*/);  // turn exception logging back on (I know, an  // exception thrown from here defeats this.. it  // doesn't really matter, since we'd just print  // it and exit anyway)  xBase::logExceptions = prev;  return ret;}void entry(){  bool ok = true;  ok &= objectTest(DSA_512bit_parameters);  //ok &= objectTest(DSA_1024bit_parameters);  //ok &= testWithParameters(DSA_512bit_parameters);  //ok &= testWithParameters(DSA_1024bit_parameters);  //ok &= brandingTest(DSA_512bit_parameters);  //ok &= brandingTest(DSA_1024bit_parameters);  //ok &= robustnessTest();  if (ok) {    cout << "all tests PASSED\n";  }  else {    cout << "at least one test FAILED\n";  }}    USUAL_MAIN#endif // TEST_SDSA

⌨️ 快捷键说明

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