blob: ba9060d55bf58f022cbbb680cbc841b854cdc9c3 [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson47c93cf2013-08-09 00:38:48 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
Jeff Thompsonba16b8f2013-12-16 13:11:47 -08004 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
Jeff Thompson7687dc02013-09-13 11:54:07 -07005 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson47c93cf2013-08-09 00:38:48 -07006 * See COPYING for copyright and distribution information.
7 */
8
Jeff Thompson25b4e612013-10-10 16:03:24 -07009#include <ndn-cpp/security/key-chain.hpp>
Jeff Thompson47c93cf2013-08-09 00:38:48 -070010
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080011#include <ndn-cpp/security/policy/policy-manager.hpp>
12
Jeff Thompson47c93cf2013-08-09 00:38:48 -070013using namespace std;
Jeff Thompson2381da82013-11-06 14:34:09 -080014using namespace ndn::func_lib;
Jeff Thompson9bdeb6d2013-11-06 14:30:07 -080015#if NDN_CPP_HAVE_STD_FUNCTION
Jeff Thompson09324ed2013-11-06 14:40:35 -080016// In the std library, the placeholders are in a different namespace than boost.
17using namespace ndn::func_lib::placeholders;
Jeff Thompson9bdeb6d2013-11-06 14:30:07 -080018#endif
Jeff Thompson47c93cf2013-08-09 00:38:48 -070019
20namespace ndn {
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080021
22const ptr_lib::shared_ptr<IdentityManager> KeyChain::DefaultIdentityManager = ptr_lib::shared_ptr<IdentityManager>();
23const ptr_lib::shared_ptr<PolicyManager> KeyChain::DefaultPolicyManager = ptr_lib::shared_ptr<PolicyManager>();
24const ptr_lib::shared_ptr<EncryptionManager> KeyChain::DefaultEncryptionManager = ptr_lib::shared_ptr<EncryptionManager>();
25
26
27KeyChain::KeyChain(const ptr_lib::shared_ptr<IdentityManager> &identityManager /* = DefaultIdentityManager */,
28 const ptr_lib::shared_ptr<PolicyManager> &policyManager /* = DefaultPolicyManager */,
29 const ptr_lib::shared_ptr<EncryptionManager> &encryptionManager /* = DefaultEncryptionManager */)
30 : identityManager_(identityManager)
31 , policyManager_(policyManager)
32 , encryptionManager_(encryptionManager)
33 , maxSteps_(100)
Jeff Thompson9296f0c2013-09-23 18:10:27 -070034{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080035// #ifdef USE_SIMPLE_POLICY_MANAGER
36// Ptr<SimplePolicyManager> policyManager = Ptr<SimplePolicyManager>(new SimplePolicyManager());
37// Ptr<IdentityPolicyRule> rule1 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
38// "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
39// ">", "\\1\\2", "\\1", true));
40// Ptr<IdentityPolicyRule> rule2 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
41// "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
42// "==", "\\1", "\\1\\2", true));
43// Ptr<IdentityPolicyRule> rule3 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^(<>*)$",
44// "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
45// ">", "\\1", "\\1", true));
46// policyManager->addVerificationPolicyRule(rule1);
47// policyManager->addVerificationPolicyRule(rule2);
48// policyManager->addVerificationPolicyRule(rule3);
49
50// policyManager->addSigningPolicyRule(rule3);
51
52// m_policyManager = policyManager;
53// #endif
54
55// if (!policyManager_)
56// {
57// policyManager_ = new NoVerifyPolicyManager();
58// }
59
60// #ifdef USE_BASIC_ENCRYPTION_MANAGER
61// encryptionManager_ = new BasicEncryptionManager(m_identityManager->getPrivateStorage(), "/tmp/encryption.db");
62// #endif
Jeff Thompson9296f0c2013-09-23 18:10:27 -070063}
64
Jeff Thompsonc01e1782013-10-21 14:08:42 -070065
Jeff Thompson29ce3102013-09-27 11:47:48 -070066void
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080067KeyChain::signByIdentity(Data& data, const Name& identityName)
Jeff Thompson29ce3102013-09-27 11:47:48 -070068{
69 Name signingCertificateName;
Jeff Thompson9296f0c2013-09-23 18:10:27 -070070
Jeff Thompson29ce3102013-09-27 11:47:48 -070071 if (identityName.getComponentCount() == 0) {
72 Name inferredIdentity = policyManager_->inferSigningIdentity(data.getName());
73 if (inferredIdentity.getComponentCount() == 0)
74 signingCertificateName = identityManager_->getDefaultCertificateName();
75 else
76 signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(inferredIdentity);
Jeff Thompson2ce8f492013-09-17 18:01:25 -070077 }
Jeff Thompson9296f0c2013-09-23 18:10:27 -070078 else
Jeff Thompson29ce3102013-09-27 11:47:48 -070079 signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
80
81 if (signingCertificateName.getComponentCount() == 0)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080082 throw Error("No qualified certificate name found!");
Jeff Thompson29ce3102013-09-27 11:47:48 -070083
84 if (!policyManager_->checkSigningPolicy(data.getName(), signingCertificateName))
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080085 throw Error("Signing Cert name does not comply with signing policy");
Jeff Thompson29ce3102013-09-27 11:47:48 -070086
Alexander Afanasyeve64788e2014-01-05 22:38:21 -080087 identities().signByCertificate(data, signingCertificateName);
Jeff Thompson2ce8f492013-09-17 18:01:25 -070088}
89
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080090Signature
Jeff Thompsone9ffe792013-10-22 10:58:48 -070091KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
92{
93 Name signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -070094
Jeff Thompsone9ffe792013-10-22 10:58:48 -070095 if (signingCertificateName.size() == 0)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080096 throw Error("No qualified certificate name found!");
Jeff Thompsonc01e1782013-10-21 14:08:42 -070097
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080098 return identities().signByCertificate(buffer, bufferLength, signingCertificateName);
Jeff Thompsone9ffe792013-10-22 10:58:48 -070099}
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700100
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700101void
Jeff Thompson7c5d2312013-09-25 16:07:15 -0700102KeyChain::verifyData
Jeff Thompsonce115762013-12-18 14:59:56 -0800103 (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700104{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800105 if (policies().requireVerify(*data)) {
Jeff Thompsonce115762013-12-18 14:59:56 -0800106 ptr_lib::shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
Jeff Thompsonf309aa62013-10-31 17:03:54 -0700107 (data, stepCount, onVerified, onVerifyFailed);
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800108 if (nextStep)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800109 {
110 if (!face_)
111 throw Error("Face should be set prior to verifyData method to call");
112
113 face_->expressInterest
114 (*nextStep->interest_,
115 bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
116 bind(&KeyChain::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
117 }
Jeff Thompsonf309aa62013-10-31 17:03:54 -0700118 }
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800119 else if (policies().skipVerifyAndTrust(*data))
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700120 onVerified(data);
121 else
Jeff Thompson29ce3102013-09-27 11:47:48 -0700122 onVerifyFailed(data);
Jeff Thompson1e90d8c2013-08-12 16:09:25 -0700123}
124
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800125void
Jeff Thompsonce115762013-12-18 14:59:56 -0800126KeyChain::onCertificateData(const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep)
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800127{
128 // Try to verify the certificate (data) according to the parameters in nextStep.
129 verifyData(data, nextStep->onVerified_, nextStep->onVerifyFailed_, nextStep->stepCount_);
130}
131
132void
133KeyChain::onCertificateInterestTimeout
Jeff Thompsonce115762013-12-18 14:59:56 -0800134 (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, const ptr_lib::shared_ptr<Data> &data,
135 ptr_lib::shared_ptr<ValidationRequest> nextStep)
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800136{
137 if (retry > 0)
138 // Issue the same expressInterest as in verifyData except decrement retry.
139 face_->expressInterest
140 (*interest,
141 bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
142 bind(&KeyChain::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, data, nextStep));
143 else
144 onVerifyFailed(data);
145}
146
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700147}