blob: d3e7a6aacba782275d9b02e2f25049b50643b258 [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.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson47c93cf2013-08-09 00:38:48 -07005 * See COPYING for copyright and distribution information.
6 */
7
Jeff Thompson7a67cb62013-08-26 11:43:18 -07008#include "../c/util/crypto.h"
9#include "../c/encoding/binary-xml-data.h"
10#include "../encoding/binary-xml-encoder.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070011#include <ndn-cpp/sha256-with-rsa-signature.hpp>
Jeff Thompson9296f0c2013-09-23 18:10:27 -070012#include "../util/logging.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070013#include <ndn-cpp/security/security-exception.hpp>
14#include <ndn-cpp/security/policy/policy-manager.hpp>
Jeff Thompsonf309aa62013-10-31 17:03:54 -070015#include "policy/validation-request.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070016#include <ndn-cpp/security/key-chain.hpp>
Jeff Thompson47c93cf2013-08-09 00:38:48 -070017
18using namespace std;
Jeff Thompsond4144fe2013-09-18 15:59:57 -070019using namespace ndn::ptr_lib;
Jeff Thompson9bdeb6d2013-11-06 14:30:07 -080020#if NDN_CPP_HAVE_STD_FUNCTION
21// In the std library, the placeholders are in a different namespace than boost.
22using namespace func_lib::placeholders;
23#endif
Jeff Thompson47c93cf2013-08-09 00:38:48 -070024
25namespace ndn {
26
Jeff Thompson29ce3102013-09-27 11:47:48 -070027KeyChain::KeyChain(const shared_ptr<IdentityManager>& identityManager, const shared_ptr<PolicyManager>& policyManager)
28: identityManager_(identityManager), policyManager_(policyManager), face_(0), maxSteps_(100)
Jeff Thompson9296f0c2013-09-23 18:10:27 -070029{
30}
31
Jeff Thompson2ce8f492013-09-17 18:01:25 -070032void
Jeff Thompson29ce3102013-09-27 11:47:48 -070033KeyChain::sign(Data& data, const Name& certificateName, WireFormat& wireFormat)
Jeff Thompson2ce8f492013-09-17 18:01:25 -070034{
Jeff Thompson29ce3102013-09-27 11:47:48 -070035 identityManager_->signByCertificate(data, certificateName, wireFormat);
36}
37
Jeff Thompsonc01e1782013-10-21 14:08:42 -070038shared_ptr<Signature>
39KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
40{
41 return identityManager_->signByCertificate(buffer, bufferLength, certificateName);
42}
43
Jeff Thompson29ce3102013-09-27 11:47:48 -070044void
45KeyChain::signByIdentity(Data& data, const Name& identityName, WireFormat& wireFormat)
46{
47 Name signingCertificateName;
Jeff Thompson9296f0c2013-09-23 18:10:27 -070048
Jeff Thompson29ce3102013-09-27 11:47:48 -070049 if (identityName.getComponentCount() == 0) {
50 Name inferredIdentity = policyManager_->inferSigningIdentity(data.getName());
51 if (inferredIdentity.getComponentCount() == 0)
52 signingCertificateName = identityManager_->getDefaultCertificateName();
53 else
54 signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(inferredIdentity);
Jeff Thompson2ce8f492013-09-17 18:01:25 -070055 }
Jeff Thompson9296f0c2013-09-23 18:10:27 -070056 else
Jeff Thompson29ce3102013-09-27 11:47:48 -070057 signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
58
59 if (signingCertificateName.getComponentCount() == 0)
60 throw SecurityException("No qualified certificate name found!");
61
62 if (!policyManager_->checkSigningPolicy(data.getName(), signingCertificateName))
Jeff Thompson9296f0c2013-09-23 18:10:27 -070063 throw SecurityException("Signing Cert name does not comply with signing policy");
Jeff Thompson29ce3102013-09-27 11:47:48 -070064
Jeff Thompson56e62652013-10-31 16:13:25 -070065 identityManager_->signByCertificate(data, signingCertificateName, wireFormat);
Jeff Thompson2ce8f492013-09-17 18:01:25 -070066}
67
Jeff Thompsone9ffe792013-10-22 10:58:48 -070068shared_ptr<Signature>
69KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
70{
71 Name signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
Jeff Thompsonc01e1782013-10-21 14:08:42 -070072
Jeff Thompsone9ffe792013-10-22 10:58:48 -070073 if (signingCertificateName.size() == 0)
74 throw SecurityException("No qualified certificate name found!");
Jeff Thompsonc01e1782013-10-21 14:08:42 -070075
Jeff Thompsone9ffe792013-10-22 10:58:48 -070076 return identityManager_->signByCertificate(buffer, bufferLength, signingCertificateName);
77}
Jeff Thompsonc01e1782013-10-21 14:08:42 -070078
Jeff Thompson2ce8f492013-09-17 18:01:25 -070079void
Jeff Thompson7c5d2312013-09-25 16:07:15 -070080KeyChain::verifyData
81 (const shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
Jeff Thompson2ce8f492013-09-17 18:01:25 -070082{
Jeff Thompson2ce8f492013-09-17 18:01:25 -070083 _LOG_TRACE("Enter Verify");
Jeff Thompson2ce8f492013-09-17 18:01:25 -070084
Jeff Thompsonf309aa62013-10-31 17:03:54 -070085 if (policyManager_->requireVerify(*data)) {
86 shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
87 (data, stepCount, onVerified, onVerifyFailed);
Jeff Thompsoncda349e2013-11-05 17:37:39 -080088 if (nextStep)
89 face_->expressInterest
90 (*nextStep->interest_,
91 bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
92 bind(&KeyChain::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
Jeff Thompsonf309aa62013-10-31 17:03:54 -070093 }
94 else if (policyManager_->skipVerifyAndTrust(*data))
Jeff Thompson2ce8f492013-09-17 18:01:25 -070095 onVerified(data);
96 else
Jeff Thompson29ce3102013-09-27 11:47:48 -070097 onVerifyFailed(data);
Jeff Thompson1e90d8c2013-08-12 16:09:25 -070098}
99
Jeff Thompsoncda349e2013-11-05 17:37:39 -0800100void
101KeyChain::onCertificateData(const shared_ptr<const Interest> &interest, const shared_ptr<Data> &data, shared_ptr<ValidationRequest> nextStep)
102{
103 // Try to verify the certificate (data) according to the parameters in nextStep.
104 verifyData(data, nextStep->onVerified_, nextStep->onVerifyFailed_, nextStep->stepCount_);
105}
106
107void
108KeyChain::onCertificateInterestTimeout
109 (const shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, const shared_ptr<Data> &data,
110 shared_ptr<ValidationRequest> nextStep)
111{
112 if (retry > 0)
113 // Issue the same expressInterest as in verifyData except decrement retry.
114 face_->expressInterest
115 (*interest,
116 bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
117 bind(&KeyChain::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, data, nextStep));
118 else
119 onVerifyFailed(data);
120}
121
Jeff Thompson47c93cf2013-08-09 00:38:48 -0700122}