blob: 017a46237b8b2384071a20fec2097664c3d6f01c [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 Thompson2ce8f492013-09-17 18:01:25 -070065void
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080066KeyChain::sign(Data& data, const Name& certificateName)
Jeff Thompson2ce8f492013-09-17 18:01:25 -070067{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080068 identities().signByCertificate(data, certificateName);
Jeff Thompson29ce3102013-09-27 11:47:48 -070069}
70
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080071Signature
Jeff Thompsonc01e1782013-10-21 14:08:42 -070072KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
73{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080074 return identities().signByCertificate(buffer, bufferLength, certificateName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -070075}
76
Jeff Thompson29ce3102013-09-27 11:47:48 -070077void
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080078KeyChain::signByIdentity(Data& data, const Name& identityName)
Jeff Thompson29ce3102013-09-27 11:47:48 -070079{
80 Name signingCertificateName;
Jeff Thompson9296f0c2013-09-23 18:10:27 -070081
Jeff Thompson29ce3102013-09-27 11:47:48 -070082 if (identityName.getComponentCount() == 0) {
83 Name inferredIdentity = policyManager_->inferSigningIdentity(data.getName());
84 if (inferredIdentity.getComponentCount() == 0)
85 signingCertificateName = identityManager_->getDefaultCertificateName();
86 else
87 signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(inferredIdentity);
Jeff Thompson2ce8f492013-09-17 18:01:25 -070088 }
Jeff Thompson9296f0c2013-09-23 18:10:27 -070089 else
Jeff Thompson29ce3102013-09-27 11:47:48 -070090 signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
91
92 if (signingCertificateName.getComponentCount() == 0)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080093 throw Error("No qualified certificate name found!");
Jeff Thompson29ce3102013-09-27 11:47:48 -070094
95 if (!policyManager_->checkSigningPolicy(data.getName(), signingCertificateName))
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080096 throw Error("Signing Cert name does not comply with signing policy");
Jeff Thompson29ce3102013-09-27 11:47:48 -070097
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080098 identities().signByCertificate(data, signingCertificateName);
Jeff Thompson2ce8f492013-09-17 18:01:25 -070099}
100
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800101Signature
Jeff Thompsone9ffe792013-10-22 10:58:48 -0700102KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
103{
104 Name signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700105
Jeff Thompsone9ffe792013-10-22 10:58:48 -0700106 if (signingCertificateName.size() == 0)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800107 throw Error("No qualified certificate name found!");
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700108
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800109 return identities().signByCertificate(buffer, bufferLength, signingCertificateName);
Jeff Thompsone9ffe792013-10-22 10:58:48 -0700110}
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700111
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700112void
Jeff Thompson7c5d2312013-09-25 16:07:15 -0700113KeyChain::verifyData
Jeff Thompsonce115762013-12-18 14:59:56 -0800114 (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700115{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800116 if (policies().requireVerify(*data)) {
Jeff Thompsonce115762013-12-18 14:59:56 -0800117 ptr_lib::shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
Jeff Thompsonf309aa62013-10-31 17:03:54 -0700118 (data, stepCount, onVerified, onVerifyFailed);
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800119 if (nextStep)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800120 {
121 if (!face_)
122 throw Error("Face should be set prior to verifyData method to call");
123
124 face_->expressInterest
125 (*nextStep->interest_,
126 bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
127 bind(&KeyChain::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
128 }
Jeff Thompsonf309aa62013-10-31 17:03:54 -0700129 }
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800130 else if (policies().skipVerifyAndTrust(*data))
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700131 onVerified(data);
132 else
Jeff Thompson29ce3102013-09-27 11:47:48 -0700133 onVerifyFailed(data);
Jeff Thompson1e90d8c2013-08-12 16:09:25 -0700134}
135
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800136void
Jeff Thompsonce115762013-12-18 14:59:56 -0800137KeyChain::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 -0800138{
139 // Try to verify the certificate (data) according to the parameters in nextStep.
140 verifyData(data, nextStep->onVerified_, nextStep->onVerifyFailed_, nextStep->stepCount_);
141}
142
143void
144KeyChain::onCertificateInterestTimeout
Jeff Thompsonce115762013-12-18 14:59:56 -0800145 (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, const ptr_lib::shared_ptr<Data> &data,
146 ptr_lib::shared_ptr<ValidationRequest> nextStep)
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800147{
148 if (retry > 0)
149 // Issue the same expressInterest as in verifyData except decrement retry.
150 face_->expressInterest
151 (*interest,
152 bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
153 bind(&KeyChain::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, data, nextStep));
154 else
155 onVerifyFailed(data);
156}
157
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700158}