blob: e61013fe6f0a571dd1b24b1736d2ec7102ca41c1 [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
Alexander Afanasyev6be1a6a2014-01-06 00:08:14 -080013#include <ndn-cpp/security/identity/basic-identity-storage.hpp>
Alexander Afanasyevbd5ba402014-01-05 22:41:09 -080014
15
Jeff Thompson47c93cf2013-08-09 00:38:48 -070016using namespace std;
Jeff Thompson2381da82013-11-06 14:34:09 -080017using namespace ndn::func_lib;
Alexander Afanasyev6be1a6a2014-01-06 00:08:14 -080018#if NDN_CPP_HAVE_CXX11
Jeff Thompson09324ed2013-11-06 14:40:35 -080019// In the std library, the placeholders are in a different namespace than boost.
20using namespace ndn::func_lib::placeholders;
Jeff Thompson9bdeb6d2013-11-06 14:30:07 -080021#endif
Jeff Thompson47c93cf2013-08-09 00:38:48 -070022
23namespace ndn {
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080024
Alexander Afanasyevbd5ba402014-01-05 22:41:09 -080025const ptr_lib::shared_ptr<IdentityStorage> KeyChain::DefaultIdentityStorage = ptr_lib::shared_ptr<IdentityStorage>();
26const ptr_lib::shared_ptr<PrivateKeyStorage> KeyChain::DefaultPrivateKeyStorage = ptr_lib::shared_ptr<PrivateKeyStorage>();
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080027const ptr_lib::shared_ptr<PolicyManager> KeyChain::DefaultPolicyManager = ptr_lib::shared_ptr<PolicyManager>();
28const ptr_lib::shared_ptr<EncryptionManager> KeyChain::DefaultEncryptionManager = ptr_lib::shared_ptr<EncryptionManager>();
29
Alexander Afanasyevbd5ba402014-01-05 22:41:09 -080030KeyChain::KeyChain(const ptr_lib::shared_ptr<IdentityStorage> &publicInfoStorage /* = DefaultIdentityStorage */,
31 const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage /* = DefaultPrivateKeyStorage */,
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080032 const ptr_lib::shared_ptr<PolicyManager> &policyManager /* = DefaultPolicyManager */,
33 const ptr_lib::shared_ptr<EncryptionManager> &encryptionManager /* = DefaultEncryptionManager */)
Alexander Afanasyevbd5ba402014-01-05 22:41:09 -080034 : publicInfoStorage_(publicInfoStorage)
35 , privateKeyStorage_(privateKeyStorage)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080036 , policyManager_(policyManager)
37 , encryptionManager_(encryptionManager)
Alexander Afanasyev736708b2014-01-06 14:45:34 -080038 // , maxSteps_(100)
Alexander Afanasyevbd5ba402014-01-05 22:41:09 -080039{
40 if (publicInfoStorage_ == DefaultIdentityStorage)
41 {
42 publicInfoStorage_ = ptr_lib::make_shared<BasicIdentityStorage>();
43 }
44
45 if (privateKeyStorage_ == DefaultPrivateKeyStorage)
46 {
47#ifdef USE_OSX_PRIVATEKEY_STORAGE
48 privateStorage_ = ptr_lib::make_shared<OSXPrivatekeyStorage>();
49 // #else
50 // m_privateStorage = Ptr<SimpleKeyStore>::Create();
51#endif
52 }
53
54 identityManager_ = ptr_lib::make_shared<IdentityManager>(publicInfoStorage_, privateKeyStorage_);
55
56 if (policyManager_ == DefaultPolicyManager)
57 {
58 // #ifdef USE_SIMPLE_POLICY_MANAGER
59 // Ptr<SimplePolicyManager> policyManager = Ptr<SimplePolicyManager>(new SimplePolicyManager());
60 // Ptr<IdentityPolicyRule> rule1 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
61 // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
62 // ">", "\\1\\2", "\\1", true));
63 // Ptr<IdentityPolicyRule> rule2 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
64 // "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
65 // "==", "\\1", "\\1\\2", true));
66 // Ptr<IdentityPolicyRule> rule3 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^(<>*)$",
67 // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
68 // ">", "\\1", "\\1", true));
69 // policyManager->addVerificationPolicyRule(rule1);
70 // policyManager->addVerificationPolicyRule(rule2);
71 // policyManager->addVerificationPolicyRule(rule3);
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080072
Alexander Afanasyevbd5ba402014-01-05 22:41:09 -080073 // policyManager->addSigningPolicyRule(rule3);
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080074
Alexander Afanasyevbd5ba402014-01-05 22:41:09 -080075 // m_policyManager = policyManager;
76 //
77 // #else
78 // policyManager_ = new NoVerifyPolicyManager();
79 // #endif
80 }
81
82 if (encryptionManager_ == DefaultEncryptionManager)
83 {
84 }
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080085
86// #ifdef USE_BASIC_ENCRYPTION_MANAGER
87// encryptionManager_ = new BasicEncryptionManager(m_identityManager->getPrivateStorage(), "/tmp/encryption.db");
88// #endif
Jeff Thompson9296f0c2013-09-23 18:10:27 -070089}
90
Jeff Thompsonc01e1782013-10-21 14:08:42 -070091
Jeff Thompson29ce3102013-09-27 11:47:48 -070092void
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -080093KeyChain::signByIdentity(Data& data, const Name& identityName)
Jeff Thompson29ce3102013-09-27 11:47:48 -070094{
95 Name signingCertificateName;
Jeff Thompson9296f0c2013-09-23 18:10:27 -070096
Jeff Thompson29ce3102013-09-27 11:47:48 -070097 if (identityName.getComponentCount() == 0) {
98 Name inferredIdentity = policyManager_->inferSigningIdentity(data.getName());
99 if (inferredIdentity.getComponentCount() == 0)
100 signingCertificateName = identityManager_->getDefaultCertificateName();
101 else
102 signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(inferredIdentity);
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700103 }
Jeff Thompson9296f0c2013-09-23 18:10:27 -0700104 else
Jeff Thompson29ce3102013-09-27 11:47:48 -0700105 signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
106
107 if (signingCertificateName.getComponentCount() == 0)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800108 throw Error("No qualified certificate name found!");
Jeff Thompson29ce3102013-09-27 11:47:48 -0700109
110 if (!policyManager_->checkSigningPolicy(data.getName(), signingCertificateName))
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800111 throw Error("Signing Cert name does not comply with signing policy");
Jeff Thompson29ce3102013-09-27 11:47:48 -0700112
Alexander Afanasyeve64788e2014-01-05 22:38:21 -0800113 identities().signByCertificate(data, signingCertificateName);
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700114}
115
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800116Signature
Jeff Thompsone9ffe792013-10-22 10:58:48 -0700117KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
118{
119 Name signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700120
Jeff Thompsone9ffe792013-10-22 10:58:48 -0700121 if (signingCertificateName.size() == 0)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800122 throw Error("No qualified certificate name found!");
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700123
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800124 return identities().signByCertificate(buffer, bufferLength, signingCertificateName);
Jeff Thompsone9ffe792013-10-22 10:58:48 -0700125}
Jeff Thompsonc01e1782013-10-21 14:08:42 -0700126
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700127void
Jeff Thompson7c5d2312013-09-25 16:07:15 -0700128KeyChain::verifyData
Jeff Thompsonce115762013-12-18 14:59:56 -0800129 (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700130{
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800131 if (policies().requireVerify(*data)) {
Jeff Thompsonce115762013-12-18 14:59:56 -0800132 ptr_lib::shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
Jeff Thompsonf309aa62013-10-31 17:03:54 -0700133 (data, stepCount, onVerified, onVerifyFailed);
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800134 if (nextStep)
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800135 {
136 if (!face_)
137 throw Error("Face should be set prior to verifyData method to call");
138
139 face_->expressInterest
140 (*nextStep->interest_,
141 bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
142 bind(&KeyChain::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
143 }
Jeff Thompsonf309aa62013-10-31 17:03:54 -0700144 }
Alexander Afanasyevbf1a67a2014-01-05 23:36:13 -0800145 else if (policies().skipVerifyAndTrust(*data))
Jeff Thompson2ce8f492013-09-17 18:01:25 -0700146 onVerified(data);
147 else
Jeff Thompson29ce3102013-09-27 11:47:48 -0700148 onVerifyFailed(data);
Jeff Thompson1e90d8c2013-08-12 16:09:25 -0700149}
150
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800151void
Jeff Thompsonce115762013-12-18 14:59:56 -0800152KeyChain::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 -0800153{
154 // Try to verify the certificate (data) according to the parameters in nextStep.
155 verifyData(data, nextStep->onVerified_, nextStep->onVerifyFailed_, nextStep->stepCount_);
156}
157
158void
159KeyChain::onCertificateInterestTimeout
Jeff Thompsonce115762013-12-18 14:59:56 -0800160 (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, const ptr_lib::shared_ptr<Data> &data,
161 ptr_lib::shared_ptr<ValidationRequest> nextStep)
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800162{
163 if (retry > 0)
164 // Issue the same expressInterest as in verifyData except decrement retry.
165 face_->expressInterest
166 (*interest,
167 bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
168 bind(&KeyChain::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, data, nextStep));
169 else
170 onVerifyFailed(data);
171}
172
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700173}