コード例 #1
0
ファイル: back-end-mem.cpp プロジェクト: cawka/ndn-cxx
ConstBufferPtr
BackEndMem::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
{
  OBufferStream os;
  m_impl->keys[keyName]->savePkcs8(os, pw, pwLen);
  return os.buf();
}
コード例 #2
0
ConstBufferPtr
SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
{
  OBufferStream privateKeyOs;
  CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
                       new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));

  return privateKeyOs.buf();
}
コード例 #3
0
ファイル: block.cpp プロジェクト: PatrickGuo/ndn-cxx-master
void
Block::encode()
{
  if (hasWire())
    return;

  OBufferStream os;
  Tlv::writeVarNumber(os, type());

  if (hasValue())
    {
      Tlv::writeVarNumber(os, value_size());
      os.write(reinterpret_cast<const char*>(value()), value_size());
    }
  else if (m_subBlocks.size() == 0)
    {
      Tlv::writeVarNumber(os, 0);
    }
  else
    {
      size_t valueSize = 0;
      for (element_const_iterator i = m_subBlocks.begin(); i != m_subBlocks.end(); ++i) {
        valueSize += i->size();
      }

      Tlv::writeVarNumber(os, valueSize);

      for (element_const_iterator i = m_subBlocks.begin(); i != m_subBlocks.end(); ++i) {
        if (i->hasWire())
          os.write(reinterpret_cast<const char*>(i->wire()), i->size());
        else if (i->hasValue()) {
          Tlv::writeVarNumber(os, i->type());
          Tlv::writeVarNumber(os, i->value_size());
          os.write(reinterpret_cast<const char*>(i->value()), i->value_size());
        }
        else
          throw Error("Underlying value buffer is empty");
      }
    }

  // now assign correct block

  m_buffer = os.buf();
  m_begin = m_buffer->begin();
  m_end   = m_buffer->end();
  m_size  = m_end - m_begin;

  m_value_begin = m_buffer->begin();
  m_value_end   = m_buffer->end();

  Tlv::readType(m_value_begin, m_value_end);
  Tlv::readVarNumber(m_value_begin, m_value_end);
}
コード例 #4
0
ConstBufferPtr
BackEndFile::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
{
  shared_ptr<PrivateKey> key;
  try {
    key = loadKey(keyName);
  }
  catch (const PrivateKey::Error&) {
    BOOST_THROW_EXCEPTION(Error("Cannot export private key"));
  }
  OBufferStream os;
  key->savePkcs8(os, pw, pwLen);
  return os.buf();
}
コード例 #5
0
ファイル: io.hpp プロジェクト: PatrickGuo/ndn-cxx-master
shared_ptr<T>
load(std::istream& is, IoEncoding encoding = BASE_64)
{
  typedef typename T::Error TypeError;
  try
    {
      using namespace CryptoPP;

      shared_ptr<T> object = make_shared<T>();

      OBufferStream os;

      switch (encoding)
        {
        case NO_ENCODING:
          {
            FileSource ss(is, true, new FileSink(os));
            break;
          }
        case BASE_64:
          {
            FileSource ss(is, true, new Base64Decoder(new FileSink(os)));
            break;
          }
        case HEX:
          {
            FileSource ss(is, true, new HexDecoder(new FileSink(os)));
            break;
          }
        default:
          return shared_ptr<T>();
        }

      object->wireDecode(Block(os.buf()));
      return object;
    }
  catch (CryptoPP::Exception& e)
    {
      return shared_ptr<T>();
    }
  catch (Tlv::Error& e)
    {
      return shared_ptr<T>();
    }
  catch (TypeError& e)
    {
      return shared_ptr<T>();
    }
}
コード例 #6
0
void
SegmentFetcher::finalizeFetch()
{
  // Combine segments into final buffer
  OBufferStream buf;
  // We may have received more segments than exist in the object.
  BOOST_ASSERT(m_receivedSegments.size() >= static_cast<uint64_t>(m_nSegments));

  for (int64_t i = 0; i < m_nSegments; i++) {
    buf.write(m_receivedSegments[i].get<const char>(), m_receivedSegments[i].size());
  }

  onComplete(buf.buf());
  stop();
}
コード例 #7
0
shared_ptr<const Buffer>
fromHex(const std::string& hexString)
{
  if (hexString.size() % 2 != 0) {
    BOOST_THROW_EXCEPTION(StringHelperError("Invalid number of characters in the supplied hex "
                                            "string"));
  }

  using namespace CryptoPP;

  OBufferStream os;
  StringSource(hexString, true, new HexDecoder(new FileSink(os)));
  shared_ptr<const Buffer> buffer = os.buf();

  if (buffer->size() * 2 != hexString.size()) {
    BOOST_THROW_EXCEPTION(StringHelperError("The supplied hex string contains non-hex characters"));
  }

  return buffer;
}
コード例 #8
0
ファイル: sec-tpm.cpp プロジェクト: named-data-ndnSIM/ndn-cxx
ConstBufferPtr
SecTpm::exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& passwordStr)
{
  using namespace CryptoPP;

  uint8_t salt[8] = {0};
  uint8_t iv[8] = {0};

  // derive key
  if (!generateRandomBlock(salt, 8) || !generateRandomBlock(iv, 8))
    BOOST_THROW_EXCEPTION(Error("Cannot generate salt or iv"));

  uint32_t iterationCount = 2048;

  PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
  size_t derivedLen = 24; // For DES-EDE3-CBC-PAD
  byte derived[24] = {0};
  byte purpose = 0;

  try {
    keyGenerator.DeriveKey(derived, derivedLen, purpose,
                           reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
                           salt, 8, iterationCount);
  }
  catch (const CryptoPP::Exception& e) {
    BOOST_THROW_EXCEPTION(Error("Cannot derived the encryption key"));
  }

  // encrypt
  CBC_Mode< DES_EDE3 >::Encryption e;
  e.SetKeyWithIV(derived, derivedLen, iv);

  ConstBufferPtr pkcs8PrivateKey = exportPrivateKeyPkcs8FromTpm(keyName);

  if (pkcs8PrivateKey == nullptr)
    BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #1"));

  OBufferStream encryptedOs;
  try {
    StringSource stringSource(pkcs8PrivateKey->buf(), pkcs8PrivateKey->size(), true,
                              new StreamTransformationFilter(e, new FileSink(encryptedOs)));
  }
  catch (const CryptoPP::Exception& e) {
    BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #2"));
  }

  // encode
  Oid pbes2Id("1.2.840.113549.1.5.13");
  Oid pbkdf2Id("1.2.840.113549.1.5.12");
  Oid pbes2encsId("1.2.840.113549.3.7");

  OBufferStream pkcs8Os;
  try {
    FileSink sink(pkcs8Os);

    // EncryptedPrivateKeyInfo ::= SEQUENCE {
    //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
    //   encryptedData        OCTET STRING }
    DERSequenceEncoder encryptedPrivateKeyInfo(sink);
    {
      // EncryptionAlgorithmIdentifier ::= SEQUENCE {
      //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
      //   parameters     SEQUENCE {{PBES2-params}} }
      DERSequenceEncoder encryptionAlgorithm(encryptedPrivateKeyInfo);
      {
        pbes2Id.encode(encryptionAlgorithm);
        // PBES2-params ::= SEQUENCE {
        //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
        //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
        DERSequenceEncoder pbes2Params(encryptionAlgorithm);
        {
          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
          //   parameters     SEQUENCE {{PBKDF2-params}} }
          DERSequenceEncoder pbes2KDFs(pbes2Params);
          {
            pbkdf2Id.encode(pbes2KDFs);
            // AlgorithmIdentifier ::= SEQUENCE {
            //   salt           OCTET STRING,
            //   iterationCount INTEGER (1..MAX),
            //   keyLength      INTEGER (1..MAX) OPTIONAL,
            //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
            DERSequenceEncoder pbkdf2Params(pbes2KDFs);
            {
              DEREncodeOctetString(pbkdf2Params, salt, 8);
              DEREncodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
            }
            pbkdf2Params.MessageEnd();
          }
          pbes2KDFs.MessageEnd();

          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
          //   parameters  OCTET STRING} {{iv}} }
          DERSequenceEncoder pbes2Encs(pbes2Params);
          {
            pbes2encsId.encode(pbes2Encs);
            DEREncodeOctetString(pbes2Encs, iv, 8);
          }
          pbes2Encs.MessageEnd();
        }
        pbes2Params.MessageEnd();
      }
      encryptionAlgorithm.MessageEnd();

      DEREncodeOctetString(encryptedPrivateKeyInfo,
                           encryptedOs.buf()->buf(), encryptedOs.buf()->size());
    }
    encryptedPrivateKeyInfo.MessageEnd();

    return pkcs8Os.buf();
  }
  catch (const CryptoPP::Exception& e) {
    BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #3"));
  }
}
コード例 #9
0
ファイル: sec-tpm.cpp プロジェクト: named-data-ndnSIM/ndn-cxx
bool
SecTpm::importPrivateKeyPkcs5IntoTpm(const Name& keyName,
                                     const uint8_t* buf, size_t size,
                                     const std::string& passwordStr)
{
  using namespace CryptoPP;

  Oid pbes2Id;
  Oid pbkdf2Id;
  SecByteBlock saltBlock;
  uint32_t iterationCount;
  Oid pbes2encsId;
  SecByteBlock ivBlock;
  SecByteBlock encryptedDataBlock;

  try {
    // decode some decoding processes are not necessary for now,
    // because we assume only one encryption scheme.
    StringSource source(buf, size, true);

    // EncryptedPrivateKeyInfo ::= SEQUENCE {
    //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
    //   encryptedData        OCTET STRING }
    BERSequenceDecoder encryptedPrivateKeyInfo(source);
    {
      // EncryptionAlgorithmIdentifier ::= SEQUENCE {
      //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
      //   parameters     SEQUENCE {{PBES2-params}} }
      BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
      {
        pbes2Id.decode(encryptionAlgorithm);
        // PBES2-params ::= SEQUENCE {
        //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
        //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
        BERSequenceDecoder pbes2Params(encryptionAlgorithm);
        {
          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
          //   parameters     SEQUENCE {{PBKDF2-params}} }
          BERSequenceDecoder pbes2KDFs(pbes2Params);
          {
            pbkdf2Id.decode(pbes2KDFs);
            // AlgorithmIdentifier ::= SEQUENCE {
            //   salt           OCTET STRING,
            //   iterationCount INTEGER (1..MAX),
            //   keyLength      INTEGER (1..MAX) OPTIONAL,
            //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
            BERSequenceDecoder pbkdf2Params(pbes2KDFs);
            {
              BERDecodeOctetString(pbkdf2Params, saltBlock);
              BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
            }
            pbkdf2Params.MessageEnd();
          }
          pbes2KDFs.MessageEnd();

          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
          //   parameters  OCTET STRING} {{iv}} }
          BERSequenceDecoder pbes2Encs(pbes2Params);
          {
            pbes2encsId.decode(pbes2Encs);
            BERDecodeOctetString(pbes2Encs, ivBlock);
          }
          pbes2Encs.MessageEnd();
        }
        pbes2Params.MessageEnd();
      }
      encryptionAlgorithm.MessageEnd();

      BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
    }
    encryptedPrivateKeyInfo.MessageEnd();
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
  size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
  byte derived[24] = {0};
  byte purpose = 0;

  try {
    keyGenerator.DeriveKey(derived, derivedLen,
                           purpose,
                           reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
                           saltBlock.BytePtr(), saltBlock.size(),
                           iterationCount);
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  //decrypt
  CBC_Mode< DES_EDE3 >::Decryption d;
  d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());

  OBufferStream privateKeyOs;
  try {
    StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true,
                                 new StreamTransformationFilter(d,  new FileSink(privateKeyOs)));
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  if (!importPrivateKeyPkcs8IntoTpm(keyName,
                                    privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
    return false;

  // determine key type
  StringSource privateKeySource(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size(), true);

  KeyType publicKeyType = KeyType::NONE;
  SecByteBlock rawKeyBits;
  // PrivateKeyInfo ::= SEQUENCE {
  //   INTEGER,
  //   SEQUENCE,
  //   OCTECT STRING}
  BERSequenceDecoder privateKeyInfo(privateKeySource);
  {
    uint32_t versionNum;
    BERDecodeUnsigned<uint32_t>(privateKeyInfo, versionNum, INTEGER);
    BERSequenceDecoder sequenceDecoder(privateKeyInfo);
    {
      Oid keyTypeOid;
      keyTypeOid.decode(sequenceDecoder);
      if (keyTypeOid == oid::RSA)
        publicKeyType = KeyType::RSA;
      else if (keyTypeOid == oid::ECDSA)
        publicKeyType = KeyType::EC;
      else
        return false; // Unsupported key type;
    }
  }


  // derive public key
  OBufferStream publicKeyOs;

  try {
    switch (publicKeyType) {
      case KeyType::RSA: {
        RSA::PrivateKey privateKey;
        privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
        RSAFunction publicKey(privateKey);

        FileSink publicKeySink(publicKeyOs);
        publicKey.DEREncode(publicKeySink);
        publicKeySink.MessageEnd();
        break;
      }

      case KeyType::EC: {
        ECDSA<ECP, SHA256>::PrivateKey privateKey;
        privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());

        ECDSA<ECP, SHA256>::PublicKey publicKey;
        privateKey.MakePublicKey(publicKey);
        publicKey.AccessGroupParameters().SetEncodeAsOID(true);

        FileSink publicKeySink(publicKeyOs);
        publicKey.DEREncode(publicKeySink);
        publicKeySink.MessageEnd();
        break;
      }

      default:
        return false;
    }
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  if (!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
    return false;

  return true;
}
コード例 #10
0
ファイル: certificate.cpp プロジェクト: AaronTien/ndn-cxx
void
Certificate::encode()
{
  // Name
  //    <key_name>/ID-CERT/<id#>
  // Content
  // DER encoded idCert:
  //
  //    idCert ::= SEQUENCE {
  //        validity            Validity,
  //        subject             Name,
  //        subjectPubKeyInfo   SubjectPublicKeyInfo,
  //        extension           Extensions OPTIONAL   }
  //
  //    Validity ::= SEQUENCE {
  //        notBefore           Time,
  //        notAfter            Time   }
  //
  //    Name ::= CHOICE {
  //        RDNSequence   }
  //
  //    RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
  //
  //    RelativeDistinguishedName ::=
  //        SET OF AttributeTypeAndValue
  //
  //    SubjectPublicKeyInfo ::= SEQUENCE {
  //        algorithm           AlgorithmIdentifier
  //        keybits             BIT STRING   }
  //
  //    Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
  //
  // (see http://www.ietf.org/rfc/rfc3280.txt for more detail)
  //
  // KeyLocator
  //    issuer’s certificate name
  // Signature

  using namespace CryptoPP;

  OBufferStream os;
  CryptoPP::FileSink sink(os);

  // idCert ::= SEQUENCE {
  //     validity            Validity,
  //     subject             Name,
  //     subjectPubKeyInfo   SubjectPublicKeyInfo,
  //     extension           Extensions OPTIONAL   }
  DERSequenceEncoder idCert(sink);
  {
    // Validity ::= SEQUENCE {
    //       notBefore           Time,
    //       notAfter            Time   }
    DERSequenceEncoder validity(idCert);
    {
      DEREncodeGeneralTime(validity, m_notBefore);
      DEREncodeGeneralTime(validity, m_notAfter);
    }
    validity.MessageEnd();

    // Name ::= CHOICE {
    //     RDNSequence   }
    //
    // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
    DERSequenceEncoder name(idCert);
    {
      for (SubjectDescriptionList::iterator it = m_subjectDescriptionList.begin();
           it != m_subjectDescriptionList.end(); ++it)
        {
          it->encode(name);
        }
    }
    name.MessageEnd();

    // SubjectPublicKeyInfo
    m_key.encode(idCert);

    // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
    //
    // Extension ::= SEQUENCE {
    //        extnID      OBJECT IDENTIFIER,
    //        critical    BOOLEAN DEFAULT FALSE,
    //        extnValue   OCTET STRING  }
    if (!m_extensionList.empty())
      {
        DERSequenceEncoder extensions(idCert);
        {
          for (ExtensionList::iterator it = m_extensionList.begin();
               it != m_extensionList.end(); ++it)
            {
              it->encode(extensions);
            }
        }
        extensions.MessageEnd();
      }
  }

  idCert.MessageEnd();

  setContent(os.buf());
  setContentType(tlv::ContentType_Key);
}
コード例 #11
0
Block
SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
                      const Name& keyName, DigestAlgorithm digestAlgorithm)
{
  string keyURI = keyName.toUri();

  if (!doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
    BOOST_THROW_EXCEPTION(Error("private key doesn't exist"));

  try {
    using namespace CryptoPP;
    AutoSeededRandomPool rng;

    // Read public key
    shared_ptr<v1::PublicKey> pubkeyPtr;
    pubkeyPtr = getPublicKeyFromTpm(keyName);

    switch (pubkeyPtr->getKeyType()) {
      case KeyType::RSA: {
        // Read private key
        ByteQueue bytes;
        FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
                        true, new Base64Decoder);
        file.TransferTo(bytes);
        bytes.MessageEnd();
        RSA::PrivateKey privateKey;
        privateKey.Load(bytes);

        // Sign message
        switch (digestAlgorithm) {
          case DigestAlgorithm::SHA256: {
            RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);

            OBufferStream os;
            StringSource(data, dataLength,
                         true,
                         new SignerFilter(rng, signer, new FileSink(os)));

            return Block(tlv::SignatureValue, os.buf());
          }

          default:
            BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
        }
      }

      case KeyType::EC: {
        // Read private key
        ByteQueue bytes;
        FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
                        true, new Base64Decoder);
        file.TransferTo(bytes);
        bytes.MessageEnd();

        // Sign message
        switch (digestAlgorithm) {
          case DigestAlgorithm::SHA256: {
            ECDSA<ECP, SHA256>::PrivateKey privateKey;
            privateKey.Load(bytes);
            ECDSA<ECP, SHA256>::Signer signer(privateKey);

            OBufferStream os;
            StringSource(data, dataLength,
                         true,
                         new SignerFilter(rng, signer, new FileSink(os)));

            uint8_t buf[200];
            size_t bufSize = DSAConvertSignatureFormat(buf, sizeof(buf), DSA_DER,
                                                       os.buf()->buf(), os.buf()->size(),
                                                       DSA_P1363);

            shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);

            return Block(tlv::SignatureValue, sigBuffer);
          }

          default:
            BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
        }
      }

      default:
        BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
    }
  }
  catch (const CryptoPP::Exception& e) {
    BOOST_THROW_EXCEPTION(Error(e.what()));
  }
}