void DummyClientFace::enableRegistrationReply() { onSendInterest.connect([this] (const Interest& interest) { static const Name localhostRegistration("/localhost/nfd/rib"); if (!localhostRegistration.isPrefixOf(interest.getName())) return; nfd::ControlParameters params(interest.getName().get(-5).blockFromValue()); params.setFaceId(1); params.setOrigin(0); if (interest.getName().get(3) == name::Component("register")) { params.setCost(0); } nfd::ControlResponse resp; resp.setCode(200); resp.setBody(params.wireEncode()); shared_ptr<Data> data = make_shared<Data>(interest.getName()); data->setContent(resp.wireEncode()); KeyChain keyChain; keyChain.sign(*data, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256)); this->getIoService().post([this, data] { this->receive(*data); }); }); }
BOOST_FIXTURE_TEST_CASE(Exemption, CommandInterestFixture) { KeyChain keyChain; Name identity("/TestCommandInterest/AnyKey"); Name certName; BOOST_REQUIRE_NO_THROW(certName = keyChain.createIdentity(identity)); CommandInterestGenerator generator; CommandInterestValidator validator; validator.addInterestBypassRule("^<TestCommandInterest><Exemption>"); //Test a legitimate command shared_ptr<Interest> commandInterest1 = make_shared<Interest>("/TestCommandInterest/Exemption/Command1"); generator.generateWithIdentity(*commandInterest1, identity); validator.validate(*commandInterest1, bind(&CommandInterestFixture::validated, this, _1), bind(&CommandInterestFixture::validationFailed, this, _1, _2)); BOOST_CHECK_EQUAL(m_validity, true); BOOST_CHECK_NO_THROW(keyChain.deleteIdentity(identity)); }
int ndnsec_unlock_tpm(int argc, char** argv) { #ifdef NDN_CXX_HAVE_GETPASS using namespace ndn; namespace po = boost::program_options; std::string keyName; po::options_description description("General Usage\n ndnsec unlock-tpm [-h] \nGeneral options"); description.add_options() ("help,h", "produce help message") ; po::variables_map vm; try { po::store(po::parse_command_line(argc, argv, description), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("help") != 0) { std::cerr << description << std::endl; return 0; } bool isUnlocked = false; KeyChain keyChain; char* password; password = getpass("Password to unlock the TPM: "); isUnlocked = keyChain.unlockTpm(password, strlen(password), true); memset(password, 0, strlen(password)); if (isUnlocked) { std::cerr << "OK: TPM is unlocked" << std::endl; return 0; } else { std::cerr << "ERROR: TPM is still locked" << std::endl; return 1; } #else std::cerr << "ERROR: Command not supported on this platform" << std::endl; return 1; #endif // NDN_CXX_HAVE_GETPASS }
BOOST_FIXTURE_TEST_CASE(ConstructorEmpty2Config, TestHomeAndPibFixture<PibPathEmptyFile>) { createClientConf({"tpm=tpm-file:%PATH%"}); BOOST_REQUIRE_NO_THROW(KeyChain()); KeyChain keyChain; BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-sqlite3:"); BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-file:" + m_pibDir); BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-file:" + m_pibDir); }
inline void CommandInterestGenerator::generate(Interest& interest, const Name& certificateName /*= Name()*/) { if (certificateName.empty()) m_keyChain.sign(interest); else m_keyChain.sign(interest, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_CERT, certificateName)); }
void CommandInterestGenerator::generate (Interest& interest, KeyChain& keyChain, const Name& certificateName, WireFormat& wireFormat) { MillisecondsSince1970 timestamp = ::round(ndn_getNowMilliseconds()); while (timestamp <= lastTimestamp_) timestamp += 1.0; // The timestamp is encoded as a TLV nonNegativeInteger. TlvEncoder encoder(8); encoder.writeNonNegativeInteger((uint64_t)timestamp); interest.getName().append(Blob(encoder.finish())); // The random value is a TLV nonNegativeInteger too, but we know it is 8 bytes, // so we don't need to call the nonNegativeInteger encoder. uint8_t randomBuffer[8]; ndn_Error error; if ((error = CryptoLite::generateRandomBytes(randomBuffer, sizeof(randomBuffer)))) throw runtime_error(ndn_getErrorString(error)); interest.getName().append(randomBuffer, sizeof(randomBuffer)); keyChain.sign(interest, certificateName, wireFormat); if (interest.getInterestLifetimeMilliseconds() < 0) // The caller has not set the interest lifetime, so set it here. interest.setInterestLifetimeMilliseconds(1000.0); // We successfully signed the interest, so update the timestamp. lastTimestamp_ = timestamp; }
int main(int argc, char** argv) { try { Name prefix("/nfd/edu/ucla/remap/test"); // Route to aleph.ndn.ucla.edu. Have to use the canonical name with // an IP address and port. string uri = "udp4://128.97.98.7:6363"; // The default Face connects to the local NFD. Face face; // Use the system default key chain and certificate name to sign commands. KeyChain keyChain; face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName()); // Create the /localhost/nfd/faces/query command interest, including the // FaceQueryFilter. Construct the FaceQueryFilter using the structure in // face-query-filter.pb.h which was produced by protoc. ndn_message::FaceQueryFilterMessage message; ndn_message::FaceQueryFilterMessage_FaceQueryFilter* filter = message.add_face_query_filter(); filter->set_uri(uri); Blob encodedFilter = ProtobufTlv::encode(message); Interest interest(Name("/localhost/nfd/faces/query")); interest.getName().append(encodedFilter); bool enabled = true; SegmentFetcher::fetch (face, interest, SegmentFetcher::DontVerifySegment, bind(&processFaceStatus, _1, prefix, uri, &face, &enabled), bind(&onError, _1, _2, &enabled)); // Loop calling processEvents until a callback sets enabled = false. while (enabled) { face.processEvents(); // We need to sleep for a few milliseconds so we don't use 100% of the CPU. usleep(10000); } } catch (std::exception& e) { cout << "exception: " << e.what() << endl; } return 0; }
int main(int argc, char** argv) { std::string logfile = createLogDir("./logs"); GLogger glog( argv[0], logfile.c_str() ); std::cout << "Log to path: " << logfile << std::endl; try { boost::asio::io_service ioService; ptr_lib::shared_ptr<ThreadsafeFace> face; face.reset(new ThreadsafeFace (ioService, "localhost")); // Use the system default key chain and certificate name to sign commands. KeyChain keyChain; face->setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName()); // Also use the default certificate name to sign data packets. Publisher publisher(ioService, face, keyChain, keyChain.getDefaultCertificateName()); if( !publisher.init() ) { cout << "Publisher init fail" << endl; return 0; } else { std::thread *captureThread = new std::thread(bind(&Publisher::start,&publisher)); captureThread->detach(); LOG(INFO) << "ioservice start" << endl; boost::asio::io_service::work work(ioService); ioService.run(); LOG(INFO) << "ioservice started" << endl; } } catch (std::exception& e) { cout << "exception: " << e.what() << endl; } return 0; }
void CommandInterestGenerator::generate (Interest& interest, KeyChain& keyChain, const Name& certificateName, WireFormat& wireFormat) { prepareCommandInterestName(interest, wireFormat); keyChain.sign(interest, certificateName, wireFormat); if (interest.getInterestLifetimeMilliseconds() < 0) // The caller has not set the interest lifetime, so set it here. interest.setInterestLifetimeMilliseconds(1000.0); }
TEST_F(TestInterestMethods, VerifyDigestSha256) { // Create a KeyChain but we don't need to add keys. ptr_lib::shared_ptr<MemoryIdentityStorage> identityStorage (new MemoryIdentityStorage()); KeyChain keyChain (ptr_lib::make_shared<IdentityManager> (identityStorage, ptr_lib::make_shared<MemoryPrivateKeyStorage>()), ptr_lib::make_shared<SelfVerifyPolicyManager>(identityStorage.get())); ptr_lib::shared_ptr<Interest> interest(new Interest(Name("/test/signed-interest"))); keyChain.signWithSha256(*interest); VerifyCounter counter; keyChain.verifyInterest (interest, bind(&VerifyCounter::onVerified, &counter, _1), // Cast to disambiguate from the deprecated OnVerifyInterestFailed. (const OnInterestValidationFailed)bind (&VerifyCounter::onInterestValidationFailed, &counter, _1, _2)); ASSERT_EQ(counter.onValidationFailedCallCount_, 0) << "Signature verification failed"; ASSERT_EQ(counter.onVerifiedCallCount_, 1) << "Verification callback was not used."; }
int main(int argc, char** argv) { try { Face face("localhost"); shared_ptr<MemoryIdentityStorage> identityStorage(new MemoryIdentityStorage()); shared_ptr<MemoryPrivateKeyStorage> privateKeyStorage(new MemoryPrivateKeyStorage()); KeyChain keyChain (make_shared<IdentityManager>(identityStorage, privateKeyStorage), make_shared<NoVerifyPolicyManager>()); keyChain.setFace(&face); // Initialize the storage. Name keyName("/testname/DSK-123"); Name certificateName = keyName.getSubName(0, keyName.size() - 1).append("KEY").append (keyName.get(keyName.size() - 1)).append("ID-CERT").append("0"); identityStorage->addKey(keyName, KEY_TYPE_RSA, Blob(DEFAULT_PUBLIC_KEY_DER, sizeof(DEFAULT_PUBLIC_KEY_DER))); privateKeyStorage->setKeyPairForKeyName (keyName, DEFAULT_PUBLIC_KEY_DER, sizeof(DEFAULT_PUBLIC_KEY_DER), DEFAULT_PRIVATE_KEY_DER, sizeof(DEFAULT_PRIVATE_KEY_DER)); Echo echo(keyChain, certificateName); Name prefix("/testecho"); cout << "Register prefix " << prefix.toUri() << endl; face.registerPrefix(prefix, ref(echo), ref(echo)); // The main event loop. // Wait forever to receive one interest for the prefix. while (echo.responseCount_ < 1) { face.processEvents(); // We need to sleep for a few milliseconds so we don't use 100% of the CPU. usleep(10000); } } catch (std::exception& e) { cout << "exception: " << e.what() << endl; } return 0; }
/** * Loop to decode a data packet nIterations times using C++. * @param nIterations The number of iterations. * @param useCrypto If true, verify the signature. If false, don't verify. * @param encoding The wire encoding to decode. * @return The number of seconds for all iterations. */ static double benchmarkDecodeDataSecondsCpp(int nIterations, bool useCrypto, const Blob& encoding) { // Initialize the KeyChain storage in case useCrypto is true. ptr_lib::shared_ptr<MemoryIdentityStorage> identityStorage(new MemoryIdentityStorage()); ptr_lib::shared_ptr<MemoryPrivateKeyStorage> privateKeyStorage(new MemoryPrivateKeyStorage()); KeyChain keyChain (ptr_lib::make_shared<IdentityManager>(identityStorage, privateKeyStorage), ptr_lib::make_shared<SelfVerifyPolicyManager>(identityStorage.get())); Name keyName("/testname/DSK-123"); identityStorage->addKey(keyName, KEY_TYPE_RSA, Blob(DEFAULT_RSA_PUBLIC_KEY_DER, sizeof(DEFAULT_RSA_PUBLIC_KEY_DER))); double start = getNowSeconds(); for (int i = 0; i < nIterations; ++i) { ptr_lib::shared_ptr<Data> data(new Data()); data->wireDecode(encoding); if (useCrypto) keyChain.verifyData(data, onVerified, onVerifyFailed); } double finish = getNowSeconds(); return finish - start; }
void onHelloInterest(const InterestFilter& filter, const Interest& interest){ // std::cout <<"Received hello interest\n"; std::cout << "\n\n\n----------this is test No. " <<++count << "------\n"<< std::endl; Name fileName(interest.getName()); int *content = new int[3]; content[0] = m_FileSize; content[1] = m_SegmentSize; content[2] = m_ContentSize; fileBuffer = new char[m_FileSize]; shared_ptr<Data> data = make_shared<Data>(); data->setName(fileName); data->setFreshnessPeriod(time::seconds(10)); data->setContent(reinterpret_cast<const uint8_t*>(content), 3 * sizeof(int)); m_keyChain.sign(*data); // m_keyChain.signWithSha256(*data); m_face.put(*data); }
BOOST_FIXTURE_TEST_CASE(ConstructorEmptyConfig, TestHomeAndPibFixture<PibPathSqlite3Empty>) { createClientConf({"pib=pib-sqlite3:%PATH%"}); #if defined(NDN_CXX_HAVE_OSX_SECURITY) std::string oldHOME; if (std::getenv("OLD_HOME")) oldHOME = std::getenv("OLD_HOME"); std::string HOME; if (std::getenv("HOME")) HOME = std::getenv("HOME"); if (!oldHOME.empty()) setenv("HOME", oldHOME.c_str(), true); else unsetenv("HOME"); #endif BOOST_REQUIRE_NO_THROW(KeyChain()); KeyChain keyChain; BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-sqlite3:" + m_pibDir); #if defined(NDN_CXX_HAVE_OSX_SECURITY) BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-osxkeychain:"); BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-osxkeychain:"); #else BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-file:"); BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-file:"); #endif #if defined(NDN_CXX_HAVE_OSX_SECURITY) if (!HOME.empty()) setenv("HOME", HOME.c_str(), true); else unsetenv("HOME"); #endif }
int ndnsec_delete(int argc, char** argv) { using namespace ndn; namespace po = boost::program_options; // bool deleteId = true; bool isDeleteKey = false; bool isDeleteCert = false; std::string name; po::options_description description("General Usage\n ndnsec delete [-h] [-k|c] name\nGeneral options"); description.add_options() ("help,h", "produce help message") ("delete-key,k", "(Optional) delete a key if specified.") ("delete-key2,K", "(Optional) delete a key if specified.") ("delete-cert,c", "(Optional) delete a certificate if specified.") ("delete-cert2,C", "(Optional) delete a certificate if specified.") ("name,n", po::value<std::string>(&name), "By default, it refers to an identity." "If -k is specified, it refers to a key." "If -c is specified, it refers to a certificate."); ; po::positional_options_description p; p.add("name", 1); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("help") != 0) { std::cerr << description << std::endl;; return 0; } if (vm.count("name") == 0) { std::cerr << "ERROR: name must be specified" << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("delete-cert") != 0 || vm.count("delete-cert2") != 0) { isDeleteCert = true; // deleteId = false; } else if (vm.count("delete-key") != 0 || vm.count("delete-key2") != 0) { isDeleteKey = true; // deleteId = false; } KeyChain keyChain; if (isDeleteCert) { keyChain.deleteCertificate(name); } else if (isDeleteKey) { keyChain.deleteKey(name); } else { keyChain.deleteIdentity(name); } return 0; }
int ndnsec_cert_gen(int argc, char** argv) { using boost::tokenizer; using boost::escaped_list_separator; using namespace ndn; using namespace ndn::time; namespace po = boost::program_options; std::string notBeforeStr; std::string notAfterStr; std::string subjectName; std::string requestFile("-"); std::string signId; std::string subjectInfo; std::string certPrefix; bool hasSignId = false; po::options_description description( "General Usage\n" " ndnsec cert-gen [-h] [-S date] [-E date] [-N subject-name] [-I subject-info] " "[-s sign-id] [-p cert-prefix] request\n" "General options"); description.add_options() ("help,h", "produce help message") ("not-before,S", po::value<std::string>(¬BeforeStr), "certificate starting date, YYYYMMDDhhmmss") ("not-after,E", po::value<std::string>(¬AfterStr), "certificate ending date, YYYYMMDDhhmmss") ("subject-name,N", po::value<std::string>(&subjectName), "subject name") ("subject-info,I", po::value<std::string>(&subjectInfo), "subject info, pairs of OID and string description: " "\"2.5.4.10 'University of California, Los Angeles'\"") ("sign-id,s", po::value<std::string>(&signId), "signing Identity, system default identity if not specified") ("cert-prefix,p", po::value<std::string>(&certPrefix), "cert prefix, which is the part of certificate name before " "KEY component") ("request,r", po::value<std::string>(&requestFile), "request file name, - for stdin") ; po::positional_options_description p; p.add("request", 1); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; return 1; } if (vm.count("help") != 0) { std::cerr << description << std::endl; return 0; } if (vm.count("sign-id") != 0) { hasSignId = true; } if (vm.count("subject-name") == 0) { std::cerr << "subject_name must be specified" << std::endl; return 1; } std::vector<CertificateSubjectDescription> subjectDescription; subjectDescription.push_back(CertificateSubjectDescription(oid::ATTRIBUTE_NAME, subjectName)); tokenizer<escaped_list_separator<char> > subjectInfoItems (subjectInfo, escaped_list_separator<char>("\\", " \t", "'\"")); tokenizer<escaped_list_separator<char> >::iterator it = subjectInfoItems.begin(); while (it != subjectInfoItems.end()) { std::string oid = *it; it++; if (it == subjectInfoItems.end()) { std::cerr << "ERROR: unmatched info for oid [" << oid << "]" << std::endl; return 1; } std::string value = *it; subjectDescription.push_back(CertificateSubjectDescription(OID(oid), value)); it++; } system_clock::TimePoint notBefore; system_clock::TimePoint notAfter; if (vm.count("not-before") == 0) { notBefore = system_clock::now(); } else { notBefore = fromIsoString(notBeforeStr.substr(0, 8) + "T" + notBeforeStr.substr(8, 6)); } if (vm.count("not-after") == 0) { notAfter = notBefore + days(365); } else { notAfter = fromIsoString(notAfterStr.substr(0, 8) + "T" + notAfterStr.substr(8, 6)); if (notAfter < notBefore) { std::cerr << "not-before is later than not-after" << std::endl; return 1; } } if (vm.count("request") == 0) { std::cerr << "request file must be specified" << std::endl; return 1; } shared_ptr<IdentityCertificate> selfSignedCertificate = getIdentityCertificate(requestFile); if (!static_cast<bool>(selfSignedCertificate)) { std::cerr << "ERROR: input error" << std::endl; return 1; } KeyChain keyChain; Name keyName = selfSignedCertificate->getPublicKeyName(); Name signIdName; Name prefix(certPrefix); if (!hasSignId) signIdName = keyChain.getDefaultIdentity(); else signIdName = Name(signId); shared_ptr<IdentityCertificate> certificate = keyChain.prepareUnsignedIdentityCertificate(keyName, selfSignedCertificate->getPublicKeyInfo(), signIdName, notBefore, notAfter, subjectDescription, prefix); if (!static_cast<bool>(certificate)) { std::cerr << "ERROR: key name is not formated correctly or does not match certificate name." << std::endl; return 1; } keyChain.createIdentity(signIdName); Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(signIdName); keyChain.sign(*certificate, signingCertificateName); Block wire = certificate->wireEncode(); try { using namespace CryptoPP; StringSource ss(wire.wire(), wire.size(), true, new Base64Encoder(new FileSink(std::cout), true, 64)); } catch (const CryptoPP::Exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; return 1; } return 0; }
int ndnsec_key_gen(int argc, char** argv) { using namespace ndn; namespace po = boost::program_options; std::string identityName; bool isDefault = true; char keyType = 'r'; std::string outputFilename; po::options_description description("General Usage\n" " ndnsec key-gen [-h] [-n] identity\n" "General options"); description.add_options() ("help,h", "produce help message") ("identity,i", po::value<std::string>(&identityName), "identity name, for example, /ndn/edu/ucla/alice") ("not_default,n", "optional, if not specified, the target identity will be set as " "the default identity of the system") ("dsk,d", "generate Data-Signing-Key (DSK) instead of the default Key-Signing-Key (KSK)") ("type,t", po::value<char>(&keyType)->default_value('r'), "optional, key type, r for RSA key (default), e for ECDSA key") // ("size,s", po::value<int>(&keySize)->default_value(2048), // "optional, key size, 2048 (default)") ; po::positional_options_description p; p.add("identity", 1); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("help") != 0) { std::cerr << description << std::endl; return 0; } if (vm.count("identity") == 0) { std::cerr << "identity must be specified" << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("not_default") != 0) isDefault = false; bool isKsk = (vm.count("dsk") == 0); KeyChain keyChain; Name keyName; try { switch (keyType) { case 'r': keyName = keyChain.generateRsaKeyPair(Name(identityName), isKsk, RsaKeyParams().getKeySize()); break; case 'e': keyName = keyChain.generateEcdsaKeyPair(Name(identityName), isKsk, EcdsaKeyParams().getKeySize()); break; default: std::cerr << "Unrecongized key type" << "\n"; std::cerr << description << std::endl; return 1; } if (0 == keyName.size()) { std::cerr << "Error: failed to generate key" << "\n"; return 1; } keyChain.setDefaultKeyNameForIdentity(keyName); shared_ptr<security::v1::IdentityCertificate> identityCert = keyChain.selfSign(keyName); if (isDefault) keyChain.setDefaultIdentity(Name(identityName)); io::save(*identityCert, std::cout); } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; } return 0; }
int ndnsec_get_default(int argc, char** argv) { using namespace ndn; namespace po = boost::program_options; bool isGetDefaultId = true; bool isGetDefaultKey = false; bool isGetDefaultCert = false; bool isQuiet = false; std::string identityString; std::string keyName; po::options_description description("General Usage\n ndnsec get-default [-h] [-k|c] [-i identity|-K key] [-q]\nGeneral options"); description.add_options() ("help,h", "produce help message") ("default_key,k", "get default key") ("default_cert,c", "get default certificate") ("identity,i", po::value<std::string>(&identityString), "target identity") ("key,K", po::value<std::string>(&keyName), "target key") ("quiet,q", "don't output trailing newline") ; po::variables_map vm; try { po::store(po::parse_command_line(argc, argv, description), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("help") != 0) { std::cerr << description << std::endl;; return 0; } if (vm.count("default_cert") != 0) { isGetDefaultCert = true; isGetDefaultId = false; } else if (vm.count("default_key") != 0) { isGetDefaultKey = true; isGetDefaultId = false; } if (vm.count("quiet") != 0) { isQuiet = true; } KeyChain keyChain; if (vm.count("key") != 0) { Name keyNdnName(keyName); if (isGetDefaultCert) { std::cout << keyChain.getDefaultCertificateNameForKey(keyNdnName); if (!isQuiet) std::cout << std::endl; return 0; } return 1; } else if (vm.count("identity") != 0) { Name identity(identityString); if (isGetDefaultKey) { std::cout << keyChain.getDefaultKeyNameForIdentity(identity); if (!isQuiet) std::cout << std::endl; return 0; } if (isGetDefaultCert) { std::cout << keyChain.getDefaultCertificateNameForIdentity(identity); if (!isQuiet) std::cout << std::endl; return 0; } return 1; } else { Name identity = keyChain.getDefaultIdentity(); if (isGetDefaultId) { std::cout << identity; if (!isQuiet) std::cout << std::endl; return 0; } if (isGetDefaultKey) { std::cout << keyChain.getDefaultKeyNameForIdentity(identity); if (!isQuiet) std::cout << std::endl; return 0; } if (isGetDefaultCert) { std::cout << keyChain.getDefaultCertificateNameForIdentity(identity); if (!isQuiet) std::cout << std::endl; return 0; } return 1; } }
int main(int argc, char** argv) { try { Interest interest; interest.wireDecode(TlvInterest, sizeof(TlvInterest)); cout << "Interest:" << endl; dumpInterest(interest); // Set the name again to clear the cached encoding so we encode again. interest.setName(interest.getName()); Blob encoding = interest.wireEncode(); cout << endl << "Re-encoded interest " << encoding.toHex() << endl; Interest reDecodedInterest; reDecodedInterest.wireDecode(encoding); cout << "Re-decoded Interest:" << endl; dumpInterest(reDecodedInterest); Interest freshInterest(Name("/ndn/abc")); freshInterest.setMinSuffixComponents(4) .setMaxSuffixComponents(6) .setInterestLifetimeMilliseconds(30000) .setChildSelector(1) .setMustBeFresh(true); freshInterest.getKeyLocator().setType(ndn_KeyLocatorType_KEY_LOCATOR_DIGEST); uint8_t digest[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; freshInterest.getKeyLocator().setKeyData(Blob(digest, sizeof(digest))); freshInterest.getExclude().appendComponent(Name("abc")[0]).appendAny(); ptr_lib::shared_ptr<MemoryIdentityStorage> identityStorage (new MemoryIdentityStorage()); ptr_lib::shared_ptr<MemoryPrivateKeyStorage> privateKeyStorage (new MemoryPrivateKeyStorage()); KeyChain keyChain (ptr_lib::make_shared<IdentityManager>(identityStorage, privateKeyStorage), ptr_lib::make_shared<SelfVerifyPolicyManager>(identityStorage.get())); // Initialize the storage. Name keyName("/testname/DSK-123"); Name certificateName = keyName.getSubName(0, keyName.size() - 1).append ("KEY").append(keyName[-1]).append("ID-CERT").append("0"); identityStorage->addKey (keyName, KEY_TYPE_RSA, Blob(DEFAULT_RSA_PUBLIC_KEY_DER, sizeof(DEFAULT_RSA_PUBLIC_KEY_DER))); privateKeyStorage->setKeyPairForKeyName (keyName, KEY_TYPE_RSA, DEFAULT_RSA_PUBLIC_KEY_DER, sizeof(DEFAULT_RSA_PUBLIC_KEY_DER), DEFAULT_RSA_PRIVATE_KEY_DER, sizeof(DEFAULT_RSA_PRIVATE_KEY_DER)); // Make a Face just so that we can sign the interest. Face face("localhost"); face.setCommandSigningInfo(keyChain, certificateName); face.makeCommandInterest(freshInterest); ptr_lib::shared_ptr<Interest> reDecodedFreshInterest(new Interest()); reDecodedFreshInterest->wireDecode(freshInterest.wireEncode()); cout << endl << "Re-decoded fresh Interest:" << endl; dumpInterest(*reDecodedFreshInterest); keyChain.verifyInterest (reDecodedFreshInterest, bind(&onVerified, "Freshly-signed Interest", _1), bind(&onVerifyFailed, "Freshly-signed Interest", _1)); } catch (std::exception& e) { cout << "exception: " << e.what() << endl; } return 0; }
BOOST_FIXTURE_TEST_CASE(CommandInterest, CommandInterestFixture) { KeyChain keyChain; Name identity("/TestCommandInterest/Validation"); identity.appendVersion(); Name certName; BOOST_REQUIRE_NO_THROW(certName = keyChain.createIdentity(identity)); CommandInterestGenerator generator; CommandInterestValidator validator; validator.addInterestRule("^<TestCommandInterest><Validation>", *keyChain.getCertificate(certName)); //Test a legitimate command shared_ptr<Interest> commandInterest1 = make_shared<Interest>("/TestCommandInterest/Validation/Command1"); generator.generateWithIdentity(*commandInterest1, identity); validator.validate(*commandInterest1, bind(&CommandInterestFixture::validated, this, _1), bind(&CommandInterestFixture::validationFailed, this, _1, _2)); BOOST_CHECK_EQUAL(m_validity, true); //Test an outdated command reset(); shared_ptr<Interest> commandInterest2 = make_shared<Interest>("/TestCommandInterest/Validation/Command2"); time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now()); timestamp -= time::seconds(5); Name commandName = commandInterest2->getName(); commandName .appendNumber(timestamp.count()) .appendNumber(random::generateWord64()); commandInterest2->setName(commandName); keyChain.signByIdentity(*commandInterest2, identity); validator.validate(*commandInterest2, bind(&CommandInterestFixture::validated, this, _1), bind(&CommandInterestFixture::validationFailed, this, _1, _2)); BOOST_CHECK_EQUAL(m_validity, false); //Test an unauthorized command Name identity2("/TestCommandInterest/Validation2"); Name certName2; BOOST_REQUIRE_NO_THROW(certName2 = keyChain.createIdentity(identity2)); shared_ptr<Interest> commandInterest3 = make_shared<Interest>("/TestCommandInterest/Validation/Command3"); generator.generateWithIdentity(*commandInterest3, identity2); validator.validate(*commandInterest3, bind(&CommandInterestFixture::validated, this, _1), bind(&CommandInterestFixture::validationFailed, this, _1, _2)); BOOST_CHECK_EQUAL(m_validity, false); //Test another unauthorized command shared_ptr<Interest> commandInterest4 = make_shared<Interest>("/TestCommandInterest/Validation2/Command"); generator.generateWithIdentity(*commandInterest4, identity); validator.validate(*commandInterest4, bind(&CommandInterestFixture::validated, this, _1), bind(&CommandInterestFixture::validationFailed, this, _1, _2)); BOOST_CHECK_EQUAL(m_validity, false); BOOST_CHECK_NO_THROW(keyChain.deleteIdentity(identity)); BOOST_CHECK_NO_THROW(keyChain.deleteIdentity(identity2)); }
int ndnsec_op_tool(int argc, char** argv) { using namespace ndn; namespace po = boost::program_options; std::string command; po::options_description description("General options"); description.add_options() ("help,h", "produce this help message") ("command", po::value<std::string>(&command), "command") ; po::positional_options_description p; p.add("command", 1); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; std::cerr << description << std::endl; return -1; } if (vm.count("help") != 0) { std::cerr << description << std::endl; return 0; } if (vm.count("command") == 0) { std::cerr << "command must be specified" << std::endl; std::cerr << description << std::endl; return 1; } if (command == "sign") // the content to be signed from stdin { KeyChain keyChain; Buffer dataToSign((istreambuf_iterator<char>(cin)), istreambuf_iterator<char>()); Block value = keyChain.sign(dataToSign.buf(), dataToSign.size(), security::SigningInfo(security::SigningInfo::SIGNER_TYPE_CERT, keyChain.getDefaultCertificateName())); if (value.value_size() == 0) { std::cerr << "Error signing with default key" << std::endl; return -1; } std::cout.write(reinterpret_cast<const char*>(value.wire()), value.size()); } return 0; }
int ndnsec_cert_dump(int argc, char** argv) { using namespace ndn; namespace po = boost::program_options; std::string name; bool isKeyName = false; bool isIdentityName = false; bool isCertName = true; // bool isFileName = false; bool isPretty = false; bool isStdOut = true; bool isRepoOut = false; std::string repoHost; std::string repoPort; // bool isDnsOut = false; po::options_description description("General Usage\n" " ndnsec cert-dump [-h] [-p] [-d] [-r [-H repo-host] " "[-P repo-port] ] [-i|k|f] name\n" "General options"); description.add_options() ("help,h", "produce help message") ("pretty,p", "display certificate in human readable format") ("identity,i", "treat the name parameter as identity name (e.g., /ndn/edu/ucla/alice") ("key,k", "treat the name parameter as key name " "(e.g., /ndn/edu/ucla/alice/ksk-123456789)") ("file,f", "treat the name parameter as file name with base64 encoded certificate, " "- for stdin") ("repo-output,r", "publish the certificate to the repo-ng") ("repo-host,H", po::value<std::string>(&repoHost)->default_value("localhost"), "the repo host if repo-output is specified") ("repo-port,P", po::value<std::string>(&repoPort)->default_value("7376"), "the repo port if repo-output is specified") // ("dns-output,d", "published the certificate to NDNS") ("name,n", po::value<std::string>(&name), "unless overridden with --identity or --key parameter, the certificate name, " "for example, /ndn/edu/ucla/KEY/cs/alice/ksk-1234567890" "/ID-CERT/%FD%FF%FF%FF%FF%FF%FF%FF") ; po::positional_options_description p; p.add("name", 1); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("help") != 0) { std::cerr << description << std::endl; return 0; } if (vm.count("name") == 0) { std::cerr << "identity_name must be specified" << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("key") != 0) { isCertName = false; isKeyName = true; } else if (vm.count("identity") != 0) { isCertName = false; isIdentityName = true; } else if (vm.count("file") != 0) { isCertName = false; // isFileName = true; } if (vm.count("pretty") != 0) isPretty = true; if (vm.count("repo-output") != 0) { isRepoOut = true; isStdOut = false; } else if (vm.count("dns-output") != 0) { // isDnsOut = true; isStdOut = false; std::cerr << "Error: DNS output is not supported yet!" << std::endl; return 1; } if (isPretty && !isStdOut) { std::cerr << "Error: pretty option can only be specified when other " << "output option is specified" << std::endl; return 1; } shared_ptr<IdentityCertificate> certificate; KeyChain keyChain; if (isIdentityName || isKeyName || isCertName) { if (isIdentityName) { Name certName = keyChain.getDefaultCertificateNameForIdentity(name); certificate = keyChain.getCertificate(certName); } else if (isKeyName) { Name certName = keyChain.getDefaultCertificateNameForKey(name); certificate = keyChain.getCertificate(certName); } else certificate = keyChain.getCertificate(name); if (!static_cast<bool>(certificate)) { std::cerr << "No certificate found!" << std::endl; return 1; } } else { certificate = getIdentityCertificate(name); if (!static_cast<bool>(certificate)) { std::cerr << "No certificate read!" << std::endl; return 1; } } if (isPretty) { std::cout << *certificate << std::endl; } else { if (isStdOut) { io::save(*certificate, std::cout); return 0; } if (isRepoOut) { using namespace boost::asio::ip; tcp::iostream request_stream; request_stream.expires_from_now(boost::posix_time::milliseconds(3000)); request_stream.connect(repoHost, repoPort); if (!request_stream) { std::cerr << "fail to open the stream!" << std::endl; return 1; } request_stream.write(reinterpret_cast<const char*>(certificate->wireEncode().wire()), certificate->wireEncode().size()); return 0; } } return 0; }
int ndnsec_sign_req(int argc, char** argv) { using namespace ndn; namespace po = boost::program_options; std::string name; bool isKeyName = false; po::options_description description("General Usage\n ndnsec sign-req [-h] [-k] name\nGeneral options"); description.add_options() ("help,h", "produce help message") ("key,k", "optional, if specified, name is keyName (e.g. /ndn/edu/ucla/alice/ksk-123456789), otherwise identity name") ("name,n", po::value<std::string>(&name), "name, for example, /ndn/edu/ucla/alice") ; po::positional_options_description p; p.add("name", 1); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("help") != 0) { std::cerr << description << std::endl; return 0; } if (vm.count("name") == 0) { std::cerr << "ERROR: name must be specified" << std::endl; std::cerr << description << std::endl; return 1; } if (vm.count("key") != 0) isKeyName = true; shared_ptr<IdentityCertificate> selfSignCert; KeyChain keyChain; if (isKeyName) selfSignCert = keyChain.selfSign(name); else { Name keyName = keyChain.getDefaultKeyNameForIdentity(name); selfSignCert = keyChain.selfSign(keyName); } if (static_cast<bool>(selfSignCert)) { io::save(*selfSignCert, std::cout); return 0; } else { std::cerr << "ERROR: Public key does not exist" << std::endl; return 1; } }
int ndnsec_cert_gen(int argc, char** argv) { using boost::tokenizer; using boost::escaped_list_separator; using namespace ndn; using namespace ndn::time; namespace po = boost::program_options; std::string notBeforeStr; std::string notAfterStr; std::string subjectName; std::string requestFile("-"); std::string signId; std::string subjectInfo; bool hasSignId = false; bool isNack = false; po::options_description description("General Usage\n ndnsec cert-gen [-h] [-S date] [-E date] [-N subject-name] [-I subject-info] [-s sign-id] request\nGeneral options"); description.add_options() ("help,h", "produce help message") ("not-before,S", po::value<std::string>(¬BeforeStr), "certificate starting date, YYYYMMDDhhmmss") ("not-after,E", po::value<std::string>(¬AfterStr), "certificate ending date, YYYYMMDDhhmmss") ("subject-name,N", po::value<std::string>(&subjectName), "subject name") ("subject-info,I", po::value<std::string>(&subjectInfo), "subject info, pairs of OID and string description: \"2.5.4.10 'University of California, Los Angeles'\"") ("nack", "Generate revocation certificate (NACK)") ("sign-id,s", po::value<std::string>(&signId), "signing Identity, system default identity if not specified") ("request,r", po::value<std::string>(&requestFile), "request file name, - for stdin") ; po::positional_options_description p; p.add("request", 1); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; return 1; } if (vm.count("help") != 0) { std::cerr << description << std::endl; return 0; } if (vm.count("sign-id") != 0) { hasSignId = true; } if (vm.count("nack") != 0) { isNack = true; } std::vector<CertificateSubjectDescription> otherSubDescrypt; tokenizer<escaped_list_separator<char> > subjectInfoItems (subjectInfo, escaped_list_separator<char> ("\\", " \t", "'\"")); tokenizer<escaped_list_separator<char> >::iterator it = subjectInfoItems.begin(); while (it != subjectInfoItems.end()) { std::string oid = *it; it++; if (it == subjectInfoItems.end()) { std::cerr << "ERROR: unmatched info for oid [" << oid << "]" << std::endl; return 1; } std::string value = *it; otherSubDescrypt.push_back(CertificateSubjectDescription(oid, value)); it++; } system_clock::TimePoint notBefore; system_clock::TimePoint notAfter; if (vm.count("not-before") == 0) { notBefore = system_clock::now(); } else { notBefore = fromIsoString(notBeforeStr.substr(0, 8) + "T" + notBeforeStr.substr(8, 6)); } if (vm.count("not-after") == 0) { notAfter = notBefore + days(365); } else { notAfter = fromIsoString(notAfterStr.substr(0, 8) + "T" + notAfterStr.substr(8, 6)); if (notAfter < notBefore) { std::cerr << "not-before is later than not-after" << std::endl; return 1; } } if (vm.count("request") == 0) { std::cerr << "request file must be specified" << std::endl; return 1; } shared_ptr<IdentityCertificate> selfSignedCertificate = getIdentityCertificate(requestFile); if (!static_cast<bool>(selfSignedCertificate)) { std::cerr << "ERROR: input error" << std::endl; return 1; } KeyChain keyChain; Name keyName = selfSignedCertificate->getPublicKeyName(); Name signIdName; Name certName; if (!hasSignId) signIdName = keyChain.getDefaultIdentity(); else signIdName = Name(signId); if (signIdName.isPrefixOf(keyName)) { // if signee's namespace is a sub-namespace of signer, for example, signer's namespace is // /ndn/test, signee's namespace is /ndn/test/alice, the generated certificate name is // /ndn/test/KEY/alice/ksk-1234/ID-CERT/%01%02 certName.append(signIdName) .append("KEY") .append(keyName.getSubName(signIdName.size())) .append("ID-CERT") .appendVersion(); } else { // if signee's namespace is not a sub-namespace of signer, for example, signer's namespace is // /ndn/test, signee's namespace is /ndn/ucla/bob, the generated certificate name is // /ndn/ucla/bob/KEY/ksk-1234/ID-CERT/%01%02 certName.append(keyName.getPrefix(-1)) .append("KEY") .append(keyName.get(-1)) .append("ID-CERT") .appendVersion(); } Block wire; if (!isNack) { if (vm.count("subject-name") == 0) { std::cerr << "subject_name must be specified" << std::endl; return 1; } CertificateSubjectDescription subDescryptName("2.5.4.41", subjectName); IdentityCertificate certificate; certificate.setName(certName); certificate.setNotBefore(notBefore); certificate.setNotAfter(notAfter); certificate.setPublicKeyInfo(selfSignedCertificate->getPublicKeyInfo()); certificate.addSubjectDescription(subDescryptName); for (size_t i = 0; i < otherSubDescrypt.size(); i++) certificate.addSubjectDescription(otherSubDescrypt[i]); certificate.encode(); keyChain.createIdentity(signIdName); Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(signIdName); keyChain.sign(certificate, signingCertificateName); wire = certificate.wireEncode(); } else { Data revocationCert; // revocationCert.setContent(void*, 0); // empty content revocationCert.setName(certName); keyChain.createIdentity(signIdName); Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(signIdName); keyChain.sign(revocationCert, signingCertificateName); wire = revocationCert.wireEncode(); } try { using namespace CryptoPP; StringSource ss(wire.wire(), wire.size(), true, new Base64Encoder(new FileSink(std::cout), true, 64)); } catch (const CryptoPP::Exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; return 1; } return 0; }
inline void CommandInterestGenerator::generateWithIdentity(Interest& interest, const Name& identity) { m_keyChain.sign(interest, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID, identity)); }
/** * Loop to encode a data packet nIterations times using C++. * @param nIterations The number of iterations. * @param useComplex If true, use a large name, large content and all fields. If false, use a small name, small content * and only required fields. * @param useCrypto If true, sign the data packet. If false, use a blank signature. * @param encoding Set this to the wire encoding. * @return The number of seconds for all iterations. */ static double benchmarkEncodeDataSecondsCpp(int nIterations, bool useComplex, bool useCrypto, Blob& encoding) { Name name; Blob content; if (useComplex) { // Use a large name and content. name = Name("/ndn/ucla.edu/apps/lwndn-test/numbers.txt/%FD%05%05%E8%0C%CE%1D/%00"); ostringstream contentStream; int count = 1; contentStream << (count++); while (contentStream.str().length() < 1115) contentStream << " " << (count++); content = Blob((uint8_t*)contentStream.str().c_str(), contentStream.str().length()); } else { // Use a small name and content. name = Name("/test"); content = Blob((uint8_t*)"abc", 3); } Blob finalBlockId((uint8_t*)"\x00", 1); // Initialize the KeyChain storage in case useCrypto is true. ptr_lib::shared_ptr<MemoryIdentityStorage> identityStorage(new MemoryIdentityStorage()); ptr_lib::shared_ptr<MemoryPrivateKeyStorage> privateKeyStorage(new MemoryPrivateKeyStorage()); KeyChain keyChain (ptr_lib::make_shared<IdentityManager>(identityStorage, privateKeyStorage), ptr_lib::make_shared<SelfVerifyPolicyManager>(identityStorage.get())); Name keyName("/testname/DSK-123"); Name certificateName = keyName.getSubName(0, keyName.size() - 1).append("KEY").append (keyName.get(keyName.size() - 1)).append("ID-CERT").append("0"); privateKeyStorage->setKeyPairForKeyName (keyName, KEY_TYPE_RSA, DEFAULT_RSA_PUBLIC_KEY_DER, sizeof(DEFAULT_RSA_PUBLIC_KEY_DER), DEFAULT_RSA_PRIVATE_KEY_DER, sizeof(DEFAULT_RSA_PRIVATE_KEY_DER)); uint8_t signatureBitsArray[256]; memset(signatureBitsArray, 0, sizeof(signatureBitsArray)); Blob signatureBits(signatureBitsArray, sizeof(signatureBitsArray)); double start = getNowSeconds(); for (int i = 0; i < nIterations; ++i) { Data data(name); data.setContent(content); if (useComplex) { data.getMetaInfo().setFreshnessPeriod(1000); data.getMetaInfo().setFinalBlockId(finalBlockId); } if (useCrypto) // This sets the signature fields. keyChain.sign(data, certificateName); else { // Imitate IdentityManager::signByCertificate to set up the signature fields, but don't sign. KeyLocator keyLocator; keyLocator.setType(ndn_KeyLocatorType_KEYNAME); keyLocator.setKeyName(certificateName); Sha256WithRsaSignature* sha256Signature = (Sha256WithRsaSignature*)data.getSignature(); sha256Signature->setKeyLocator(keyLocator); sha256Signature->setSignature(signatureBits); } encoding = data.wireEncode(); } double finish = getNowSeconds(); return finish - start; }
int ndnsec_delete(int argc, char** argv) { using namespace ndn; namespace po = boost::program_options; bool isDeleteKey = false; bool isDeleteCert = false; std::string name; po::options_description description("General Usage\n" "ndnsec delete [-h] [-k|c] name\n" "General options"); description.add_options() ("help,h", "produce help message") ("delete-key,k", "(Optional) delete a key if specified.") ("delete-key2,K", "(Optional) delete a key if specified.") ("delete-cert,c", "(Optional) delete a certificate if specified.") ("delete-cert2,C", "(Optional) delete a certificate if specified.") ("name,n", po::value<std::string>(&name), "By default, it refers to an identity." "If -k is specified, it refers to a key." "If -c is specified, it refers to a certificate."); ; po::positional_options_description p; p.add("name", 1); po::variables_map vm; try { po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "ERROR: " << e.what() << std::endl; std::cerr << description << std::endl; return 2; } if (vm.count("help") != 0) { std::cerr << description << std::endl;; return 0; } if (vm.count("name") == 0) { std::cerr << "ERROR: name must be specified" << std::endl; std::cerr << description << std::endl; return 2; } if (vm.count("delete-cert") != 0 || vm.count("delete-cert2") != 0) isDeleteCert = true; else if (vm.count("delete-key") != 0 || vm.count("delete-key2") != 0) isDeleteKey = true; KeyChain keyChain; try { if (isDeleteCert) { if (!keyChain.doesCertificateExist(name)) { std::cerr << "ERROR: Certificate does not exist: " << name << std::endl; return 1; } keyChain.deleteCertificate(name); std::cerr << "OK: Delete certificate: " << name << std::endl; } else if (isDeleteKey) { if (!keyChain.doesPublicKeyExist(name) && !keyChain.doesKeyExistInTpm(name, KEY_CLASS_PRIVATE)) { std::cerr << "ERROR: Key does not exist: " << name << std::endl; return 1; } keyChain.deleteKey(name); std::cerr << "OK: Delete key: " << name << std::endl; } else { if (!keyChain.doesIdentityExist(name)) { std::cerr << "ERROR: Identity does not exist: " << name << std::endl; return 1; } keyChain.deleteIdentity(name); std::cerr << "OK: Delete identity: " << name << std::endl; } } catch (const SecPublicInfo::Error& e) { std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl; return 2; } catch (const SecTpm::Error& e) { std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl; return 2; } catch (const KeyChain::Error& e) { std::cerr << "ERROR: " << e.what() << std::endl; return 2; } return 0; }