inline size_t calculateSkip(const Name& name, const Name& hint, const Name& zone) { size_t skip = 0; if (!hint.empty()) { // These are only asserts. The caller should supply the right parameters skip = hint.size() + 1 + zone.size(); BOOST_ASSERT(name.size() > skip); BOOST_ASSERT(name.getPrefix(hint.size()) == hint); BOOST_ASSERT(name.get(hint.size()) == FORWARDING_HINT_LABEL); BOOST_ASSERT(name.getSubName(hint.size() + 1, zone.size()) == zone); } else { skip = zone.size(); BOOST_ASSERT(name.size() > skip); BOOST_ASSERT(name.getPrefix(zone.size()) == zone); } BOOST_ASSERT(name.get(skip) == NDNS_ITERATIVE_QUERY || name.get(skip) == NDNS_CERT_QUERY); ++skip; return skip; }
void ValidatorInvitation::internalCheck(const uint8_t* buf, size_t size, const Signature& signature, const Name& keyLocatorName, const Data& innerData, const OnValidated& onValidated, const OnValidationFailed& onValidationFailed) { Name signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName); TrustAnchors::const_iterator keyIt = m_trustAnchors.find(signingKeyName); if (keyIt == m_trustAnchors.end()) return onValidationFailed("Cannot reach any trust anchor"); if (!Validator::verifySignature(buf, size, signature, keyIt->second)) return onValidationFailed("Cannot verify outer signature"); // Temporarily disabled, we should get it back when we create a specific key for the chatroom. // if(!Validator::verifySignature(innerData, m_trustAnchors[signingKeyName])) // return onValidationFailed("Cannot verify inner signature"); if (!m_innerKeyRegex.match(innerData.getName()) || m_innerKeyRegex.expand() != signingKeyName.getPrefix(-1)) return onValidationFailed("Inner certificate does not comply with the rule"); return onValidated(); }
inline void CertificateCacheTtl::remove(const Name& certificateName) { Name name = certificateName.getPrefix(-1); Cache::iterator it = m_cache.find(name); if (it != m_cache.end()) m_cache.erase(it); }
void setNameComponent(Name& name, ssize_t index, const A& ...a) { Name name2 = name.getPrefix(index); name2.append(name::Component(a...)); name2.append(name.getSubName(name2.size())); name = name2; }
shared_ptr<ndn::Data> NdnDataManager::operator[]( shared_ptr<const ndn::Interest> interest ) { Name subname = interest->getName(); auto it = subname.end()-1; while( ( it->isVersion() || it->isSegment() || it->isSegmentOffset() || it->isTimestamp() || it->isSequenceNumber() ) && ( it-- ) != subname.begin() ); subname = subname.getPrefix( it - subname.begin() + 1 ); if( m_producers.find( subname ) != m_producers.end() ) { // find data producer auto producer = m_producers[subname]; // if access level is 0, no access needs to be provided if( interest->getAuthTag().getAccessLevel() == 0 ) { Coordinator:: producerSatisfiedRequest( interest->getName().getPrefix( 2 ), interest->getName() ); return producer->makeData( interest ); } // generate data packet shared_ptr<Data> data = producer->makeData( interest ); // check that the interest's access rights // satisfy the data's requirements if( m_auth_manager->getTagAccess( interest->getAuthTag() ) < data->getAccessLevel() ) { Coordinator:: producerDeniedRequest( interest->getName().getPrefix( 2 ), interest->getName(), "Insufficient Auth" ); return makeNack( *data ); } // check that the data satisfies interest if( interest->matchesData( *data ) ) { Coordinator:: producerSatisfiedRequest( interest->getName().getPrefix(2), interest->getName() ); return data; } } Coordinator::producerOther( interest->getName().getPrefix( 2 ), "No data matching " + interest->getName().toUri() ); return NULL; };
shared_ptr<IdentityCertificate> Pib::prepareCertificate(const Name& keyName, const KeyParams& keyParams, const time::system_clock::TimePoint& notBefore, const time::system_clock::TimePoint& notAfter, const Name& signerName) { // Generate mgmt key m_tpm->generateKeyPairInTpm(keyName, keyParams); shared_ptr<PublicKey> publicKey = m_tpm->getPublicKeyFromTpm(keyName); // Set mgmt cert auto certificate = make_shared<IdentityCertificate>(); Name certName = keyName.getPrefix(-1); certName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion(); certificate->setName(certName); certificate->setNotBefore(notBefore); certificate->setNotAfter(notAfter); certificate->setPublicKeyInfo(*publicKey); CertificateSubjectDescription subjectName(oid::ATTRIBUTE_NAME, keyName.getPrefix(-1).toUri()); certificate->addSubjectDescription(subjectName); certificate->encode(); Name signingKeyName; KeyLocator keyLocator; if (signerName == EMPTY_SIGNER_NAME) { // Self-sign mgmt cert keyLocator = KeyLocator(certificate->getName().getPrefix(-1)); signingKeyName = keyName; } else { keyLocator = KeyLocator(signerName.getPrefix(-1)); signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(signerName); } SignatureSha256WithRsa signature(keyLocator); certificate->setSignature(signature); EncodingBuffer encoder; certificate->wireEncode(encoder, true); Block signatureValue = m_tpm->signInTpm(encoder.buf(), encoder.size(), signingKeyName, DIGEST_ALGORITHM_SHA256); certificate->wireEncode(encoder, signatureValue); return certificate; }
void SecPublicInfoMemory::addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKey) { Name identityName = keyName.getPrefix(-1); addIdentity(identityName); m_keyStore[keyName.toUri()] = make_shared<KeyRecord>(keyType, publicKey); }
Strategy::ParsedInstanceName Strategy::parseInstanceName(const Name& input) { for (ssize_t i = input.size() - 1; i > 0; --i) { if (input[i].isVersion()) { return {input.getPrefix(i + 1), input[i].toVersion(), input.getSubName(i + 1)}; } } return {input, nullopt, PartialName()}; }
inline void SecPublicInfo::addCertificateAsSystemDefault(const IdentityCertificate& certificate) { addCertificate(certificate); Name certName = certificate.getName(); Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certName); setDefaultIdentityInternal(keyName.getPrefix(-1)); setDefaultKeyNameForIdentityInternal(keyName); setDefaultCertificateNameForKeyInternal(certName); refreshDefaultCertificate(); }
shared_ptr<RibEntry> Rib::findParent(const Name& prefix) const { for (int i = prefix.size() - 1; i >= 0; i--) { RibTable::const_iterator it = m_rib.find(prefix.getPrefix(i)); if (it != m_rib.end()) { return (it->second); } } return shared_ptr<RibEntry>(); }
ptr_lib::shared_ptr<Signature> IdentityManager::makeSignatureByCertificate (const Name& certificateName, DigestAlgorithm& digestAlgorithm) { Name keyName = IdentityCertificate::certificateNameToPublicKeyName (certificateName); ptr_lib::shared_ptr<PublicKey> publicKey = privateKeyStorage_->getPublicKey (keyName); KeyType keyType = publicKey->getKeyType(); if (keyType == KEY_TYPE_RSA) { ptr_lib::shared_ptr<Sha256WithRsaSignature> signature (new Sha256WithRsaSignature()); digestAlgorithm = DIGEST_ALGORITHM_SHA256; signature->getKeyLocator().setType(ndn_KeyLocatorType_KEYNAME); signature->getKeyLocator().setKeyName(certificateName.getPrefix(-1)); // Ignore witness and leave the digestAlgorithm as the default. signature->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest (publicKey->getDigest()); return signature; } else if (keyType == KEY_TYPE_ECDSA) { ptr_lib::shared_ptr<Sha256WithEcdsaSignature> signature (new Sha256WithEcdsaSignature()); digestAlgorithm = DIGEST_ALGORITHM_SHA256; signature->getKeyLocator().setType(ndn_KeyLocatorType_KEYNAME); signature->getKeyLocator().setKeyName(certificateName.getPrefix(-1)); return signature; } else throw SecurityException("Key type is not recognized"); }
shared_ptr<const Data> ResponseCache::find(const Name& dataName, bool hasVersion) const { if (!hasVersion) { Storage::const_iterator it = m_storage.find(dataName); if (it != m_storage.end()) return it->second; else return shared_ptr<const Data>(); } else { Storage::const_iterator it = m_storage.find(dataName.getPrefix(-1)); if (it != m_storage.end() && it->second->getName() == dataName) return it->second; else return shared_ptr<const Data>(); } }
uint64_t RepoEnumerator::enumerate(bool showImplicitDigest) { sqlite3_stmt* m_stmt = 0; int rc = SQLITE_DONE; string sql = string("SELECT id, name, keylocatorHash FROM NDN_REPO;"); rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &m_stmt, 0); if (rc != SQLITE_OK) throw Error("Initiation Read Entries from Database Prepare error"); uint64_t entryNumber = 0; while (true) { rc = sqlite3_step(m_stmt); if (rc == SQLITE_ROW) { Name name; name.wireDecode(Block(sqlite3_column_blob(m_stmt, 1), sqlite3_column_bytes(m_stmt, 1))); try { if (showImplicitDigest) { std::cout << name << std::endl; } else { std::cout << name.getPrefix(-1) << std::endl; } } catch (...){ sqlite3_finalize(m_stmt); throw; } entryNumber++; } else if (rc == SQLITE_DONE) { sqlite3_finalize(m_stmt); break; } else { sqlite3_finalize(m_stmt); throw Error("Initiation Read Entries error"); } } return entryNumber; }
void PipelineInterests::runWithExcludedSegment(const Data& data, DataCallback onData, FailureCallback onFailure) { BOOST_ASSERT(onData != nullptr); // record the start time of running pipeline m_startTime = time::steady_clock::now(); m_onData = std::move(onData); m_onFailure = std::move(onFailure); m_numOfSegmentReceived++; // count the excluded segment Name dataName = data.getName(); m_prefix = dataName.getPrefix(-1); m_excludeSegmentNo = dataName[-1].toSegment(); if (!data.getFinalBlockId().empty()) { m_hasFinalBlockId = true; m_lastSegmentNo = data.getFinalBlockId().toSegment(); } else { // Name must contain a final block ID so that consumer knows when download finishes fail("Name of Data packet: " + data.getName().toUri() + " must a final block ID!"); } // schedule the event to check retransmission timer. m_eventCheckRto = m_scheduler.scheduleEvent(time::milliseconds(m_options.rtoCheckInterval), bind(&PipelineInterests::checkRto, this)); if (m_options.keepStats) { // schedule the event to keep track the history of cwnd size m_eventRecordCwnd = m_scheduler.scheduleEvent(time::milliseconds(m_options.cwndRecordInterval), bind(&PipelineInterests::recordCwnd, this)); } sendFirstInterest(); }
ptr_lib::shared_ptr<IdentityCertificate> IdentityManager::selfSign(const Name& keyName) { ptr_lib::shared_ptr<IdentityCertificate> certificate(new IdentityCertificate()); Blob keyBlob = identityStorage_->getKey(keyName); ptr_lib::shared_ptr<PublicKey> publicKey(new PublicKey(keyBlob)); #if NDN_CPP_HAVE_GMTIME_SUPPORT time_t nowSeconds = time(NULL); struct tm current = *gmtime(&nowSeconds); current.tm_hour = 0; current.tm_min = 0; current.tm_sec = 0; MillisecondsSince1970 notBefore = timegm(¤t) * 1000.0; current.tm_year = current.tm_year + 2; MillisecondsSince1970 notAfter = timegm(¤t) * 1000.0; certificate->setNotBefore(notBefore); certificate->setNotAfter(notAfter); #else // Don't really expect this to happen. throw SecurityException("selfSign: Can't set certificate validity because time functions are not supported by the standard library."); #endif Name certificateName = keyName.getPrefix(-1).append("KEY").append (keyName.get(-1)).append("ID-CERT").append (Name::Component::fromNumber((uint64_t)ndn_getNowMilliseconds())); certificate->setName(certificateName); certificate->setPublicKeyInfo(*publicKey); certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri())); certificate->encode(); signByCertificate(*certificate, certificate->getName()); return certificate; }
Producer::Producer(const Name& prefix, Face& face, KeyChain& keyChain, const security::SigningInfo& signingInfo, time::milliseconds freshnessPeriod, size_t maxSegmentSize, bool isVerbose, bool needToPrintVersion, std::istream& is) : m_face(face) , m_keyChain(keyChain) , m_signingInfo(signingInfo) , m_freshnessPeriod(freshnessPeriod) , m_maxSegmentSize(maxSegmentSize) , m_isVerbose(isVerbose) { if (prefix.size() > 0 && prefix[-1].isVersion()) { m_prefix = prefix.getPrefix(-1); m_versionedPrefix = prefix; } else { m_prefix = prefix; m_versionedPrefix = Name(m_prefix).appendVersion(); } populateStore(is); if (needToPrintVersion) std::cout << m_versionedPrefix[-1] << std::endl; m_face.setInterestFilter(m_prefix, bind(&Producer::onInterest, this, _2), RegisterPrefixSuccessCallback(), bind(&Producer::onRegisterFailed, this, _1, _2)); if (m_isVerbose) std::cerr << "Data published with name: " << m_versionedPrefix << std::endl; }
void KeyChain::sign (Interest& interest, const Name& certificateName, WireFormat& wireFormat) { // TODO: Handle signature algorithms other than Sha256WithRsa. Sha256WithRsaSignature signature; signature.getKeyLocator().setType(ndn_KeyLocatorType_KEYNAME); signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1)); // Append the encoded SignatureInfo. interest.getName().append(wireFormat.encodeSignatureInfo(signature)); // Append an empty signature so that the "signedPortion" is correct. interest.getName().append(Name::Component()); // Encode once to get the signed portion, and sign. SignedBlob encoding = interest.wireEncode(wireFormat); ptr_lib::shared_ptr<Signature> signedSignature = sign (encoding.signedBuf(), encoding.signedSize(), certificateName); // Remove the empty signature and append the real one. interest.setName(interest.getName().getPrefix(-1).append (wireFormat.encodeSignatureValue(*signedSignature))); }
// Name Prefix Lookup. Create Name Tree Entry if not found shared_ptr<name_tree::Entry> NameTree::lookup(const Name& prefix) { NFD_LOG_TRACE("lookup " << prefix); shared_ptr<name_tree::Entry> entry; shared_ptr<name_tree::Entry> parent; for (size_t i = 0; i <= prefix.size(); i++) { Name temp = prefix.getPrefix(i); // insert() will create the entry if it does not exist. std::pair<shared_ptr<name_tree::Entry>, bool> ret = insert(temp); entry = ret.first; if (ret.second == true) { m_nItems++; // Increase the counter entry->m_parent = parent; if (static_cast<bool>(parent)) { parent->m_children.push_back(entry); } } if (m_nItems > m_enlargeThreshold) { resize(m_enlargeFactor * m_nBuckets); } parent = entry; } return entry; }
void StrategyChoice::erase(const Name& prefix) { BOOST_ASSERT(prefix.size() > 0); shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.findExactMatch(prefix); if (!static_cast<bool>(nameTreeEntry)) { return; } shared_ptr<Entry> entry = nameTreeEntry->getStrategyChoiceEntry(); if (!static_cast<bool>(entry)) { return; } Strategy& oldStrategy = entry->getStrategy(); Strategy& parentStrategy = this->findEffectiveStrategy(prefix.getPrefix(-1)); this->changeStrategy(entry, oldStrategy.shared_from_this(), parentStrategy.shared_from_this()); nameTreeEntry->setStrategyChoiceEntry(shared_ptr<Entry>()); m_nameTree.eraseEntryIfEmpty(nameTreeEntry); --m_nItems; }
void StrategyChoice::erase(const Name& prefix) { BOOST_ASSERT(prefix.size() > 0); shared_ptr<name_tree::Entry> nte = m_nameTree.findExactMatch(prefix); if (nte == nullptr) { return; } shared_ptr<Entry> entry = nte->getStrategyChoiceEntry(); if (entry == nullptr) { return; } Strategy& oldStrategy = entry->getStrategy(); Strategy& parentStrategy = this->findEffectiveStrategy(prefix.getPrefix(-1)); this->changeStrategy(*entry, oldStrategy, parentStrategy); nte->setStrategyChoiceEntry(shared_ptr<Entry>()); m_nameTree.eraseEntryIfEmpty(nte); --m_nItems; }
int64_t PibDb::addKey(const Name& keyName, const PublicKey& key) { if (keyName.empty()) return 0; Name&& identity = keyName.getPrefix(-1); if (!hasIdentity(identity)) addIdentity(identity); sqlite3_stmt* statement; sqlite3_prepare_v2(m_database, "INSERT INTO keys (identity_id, key_name, key_type, key_bits) \ values ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)", -1, &statement, nullptr); sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT); sqlite3_bind_block(statement, 2, keyName.wireEncode(), SQLITE_TRANSIENT); sqlite3_bind_int(statement, 3, key.getKeyType()); sqlite3_bind_blob(statement, 4, key.get().buf(), key.get().size(), SQLITE_STATIC); sqlite3_step(statement); sqlite3_finalize(statement); return sqlite3_last_insert_rowid(m_database); }
shared_ptr<ndn::Data> makeData( shared_ptr<const ndn::Interest> interest ) override { auto data = make_shared<Data>(interest->getName()); streamoff offset = 0; streamoff segment = 0; Name name = interest->getName(); // find segment and offset auto it = name.end() - 1; if( it->isSegmentOffset() ) { offset = it->toSegmentOffset(); name = name.getPrefix( name.size() - 1 ); } it = name.end() - 1; if( it->isSegment() ) { segment = it->toSegment(); name = name.getPrefix( name.size() - 1 ); } // open file ifstream file( m_filename ); if( !file.is_open() ) BOOST_THROW_EXCEPTION(runtime_error ("Unable to open file") ); // figure out filesize file.seekg( 0, ios_base::end ); streamoff end = file.tellg(); // check that segment is available if( streamoff(segment*FILE_SEGMENT_SIZE + offset) < end ) { // make segment file.seekg( segment*FILE_SEGMENT_SIZE + offset, ios_base::beg ); int64_t segsize = min( streamoff(end - segment * FILE_SEGMENT_SIZE + offset ), streamoff(FILE_SEGMENT_SIZE) ); auto buffer = make_shared<Buffer>( segsize ); file.readsome( (char*) buffer->buf(), segsize ); data->setContentType( tlv::ContentType_Blob ); data->setContent( buffer ); data->setAccessLevel( m_access_level ); data->setFreshnessPeriod( time::days( 1 ) ); } else { data->setContentType( tlv::ContentType_Nack ); data->setFreshnessPeriod( time::milliseconds( 0 ) ); data->setAccessLevel( 0 ); } // close file file.close(); m_signer.sign( *data ); return data; }
BOOST_FIXTURE_TEST_CASE(GeneralSigningInterface, IdentityManagementFixture) { Name id("/id"); Name certName = m_keyChain.createIdentity(id); shared_ptr<v1::IdentityCertificate> idCert = m_keyChain.getCertificate(certName); Name keyName = idCert->getPublicKeyName(); m_keyChain.setDefaultIdentity(id); Name id2("/id2"); Name cert2Name = m_keyChain.createIdentity(id2); shared_ptr<v1::IdentityCertificate> id2Cert = m_keyChain.getCertificate(cert2Name); // SigningInfo is set to default Data data1("/data1"); m_keyChain.sign(data1); BOOST_CHECK(Validator::verifySignature(data1, idCert->getPublicKeyInfo())); BOOST_CHECK_EQUAL(data1.getSignature().getKeyLocator().getName(), certName.getPrefix(-1)); Interest interest1("/interest1"); m_keyChain.sign(interest1); BOOST_CHECK(Validator::verifySignature(interest1, idCert->getPublicKeyInfo())); SignatureInfo sigInfo1(interest1.getName()[-2].blockFromValue()); BOOST_CHECK_EQUAL(sigInfo1.getKeyLocator().getName(), certName.getPrefix(-1)); // SigningInfo is set to Identity Data data2("/data2"); m_keyChain.sign(data2, SigningInfo(SigningInfo::SIGNER_TYPE_ID, id2)); BOOST_CHECK(Validator::verifySignature(data2, id2Cert->getPublicKeyInfo())); BOOST_CHECK_EQUAL(data2.getSignature().getKeyLocator().getName(), cert2Name.getPrefix(-1)); Interest interest2("/interest2"); m_keyChain.sign(interest2, SigningInfo(SigningInfo::SIGNER_TYPE_ID, id2)); BOOST_CHECK(Validator::verifySignature(interest2, id2Cert->getPublicKeyInfo())); SignatureInfo sigInfo2(interest2.getName()[-2].blockFromValue()); BOOST_CHECK_EQUAL(sigInfo2.getKeyLocator().getName(), cert2Name.getPrefix(-1)); // SigningInfo is set to Key Data data3("/data3"); m_keyChain.sign(data3, SigningInfo(SigningInfo::SIGNER_TYPE_KEY, keyName)); BOOST_CHECK(Validator::verifySignature(data3, idCert->getPublicKeyInfo())); BOOST_CHECK_EQUAL(data3.getSignature().getKeyLocator().getName(), certName.getPrefix(-1)); Interest interest3("/interest3"); m_keyChain.sign(interest3); BOOST_CHECK(Validator::verifySignature(interest3, idCert->getPublicKeyInfo())); SignatureInfo sigInfo3(interest1.getName()[-2].blockFromValue()); BOOST_CHECK_EQUAL(sigInfo3.getKeyLocator().getName(), certName.getPrefix(-1)); // SigningInfo is set to Cert Data data4("/data4"); m_keyChain.sign(data4, SigningInfo(SigningInfo::SIGNER_TYPE_CERT, certName)); BOOST_CHECK(Validator::verifySignature(data4, idCert->getPublicKeyInfo())); BOOST_CHECK_EQUAL(data4.getSignature().getKeyLocator().getName(), certName.getPrefix(-1)); Interest interest4("/interest4"); m_keyChain.sign(interest4, SigningInfo(SigningInfo::SIGNER_TYPE_CERT, certName)); BOOST_CHECK(Validator::verifySignature(interest4, idCert->getPublicKeyInfo())); SignatureInfo sigInfo4(interest4.getName()[-2].blockFromValue()); BOOST_CHECK_EQUAL(sigInfo4.getKeyLocator().getName(), certName.getPrefix(-1)); // SigningInfo is set to DigestSha256 Data data5("/data5"); m_keyChain.sign(data5, SigningInfo(SigningInfo::SIGNER_TYPE_SHA256)); BOOST_CHECK(Validator::verifySignature(data5, DigestSha256(data5.getSignature()))); Interest interest5("/interest4"); m_keyChain.sign(interest5, SigningInfo(SigningInfo::SIGNER_TYPE_SHA256)); BOOST_CHECK(Validator::verifySignature(interest5, DigestSha256(Signature(interest5.getName()[-2].blockFromValue(), interest5.getName()[-1].blockFromValue())))); }
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; }