blob: ec54a3832c6d04e734b7acd754f22eee9c1b6874 [file] [log] [blame]
Yingdi Yufa4ce792014-02-06 18:09:22 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Yingdi Yu
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
9 */
10
11#include "validator-invitation.h"
Yingdi Yu348f5ea2014-03-01 14:47:25 -080012#include "invitation.h"
Yingdi Yufa4ce792014-02-06 18:09:22 -080013
14#include "logging.h"
15
16using namespace std;
17using namespace ndn;
18
19INIT_LOGGER("ValidatorInvitation");
20
21namespace chronos{
22
23const shared_ptr<CertificateCache> ValidatorInvitation::DefaultCertificateCache = shared_ptr<CertificateCache>();
24
Yingdi Yu348f5ea2014-03-01 14:47:25 -080025ValidatorInvitation::ValidatorInvitation()
26 : Validator()
27 , m_invitationReplyRule("^([^<CHRONOCHAT-INVITATION>]*)<CHRONOCHAT-INVITATION>",
28 "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
29 "==", "\\1", "\\1\\2", true)
30 , m_invitationInterestRule("^[^<CHRONOCHAT-INVITATION>]*<CHRONOCHAT-INVITATION><>{6}$")
31 , m_innerKeyRegex("^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT><>$", "\\1\\2")
Yingdi Yufa4ce792014-02-06 18:09:22 -080032{
Yingdi Yu348f5ea2014-03-01 14:47:25 -080033}
Yingdi Yufa4ce792014-02-06 18:09:22 -080034
35void
Yingdi Yu348f5ea2014-03-01 14:47:25 -080036ValidatorInvitation::checkPolicy (const Data& data,
Yingdi Yufa4ce792014-02-06 18:09:22 -080037 int stepCount,
38 const OnDataValidated& onValidated,
39 const OnDataValidationFailed& onValidationFailed,
40 vector<shared_ptr<ValidationRequest> >& nextSteps)
41{
Yingdi Yu348f5ea2014-03-01 14:47:25 -080042 try
Yingdi Yufa4ce792014-02-06 18:09:22 -080043 {
Yingdi Yu348f5ea2014-03-01 14:47:25 -080044 SignatureSha256WithRsa sig(data.getSignature());
45 const Name & keyLocatorName = sig.getKeyLocator().getName();
46
47 if(!m_invitationReplyRule.satisfy(data.getName(), keyLocatorName))
48 return onValidationFailed(data.shared_from_this(),
49 "Does not comply with the invitation rule: "
50 + data.getName().toUri() + " signed by: "
51 + keyLocatorName.toUri());
52
53 Data innerData;
54 innerData.wireDecode(data.getContent().blockFromValue());
55
56 return internalCheck(data.wireEncode().wire(),
57 data.wireEncode().size(),
58 sig,
59 innerData,
60 bind(onValidated, data.shared_from_this()),
61 bind(onValidationFailed, data.shared_from_this(), _1));
Yingdi Yufa4ce792014-02-06 18:09:22 -080062 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -080063 catch(SignatureSha256WithRsa::Error &e)
64 {
65 return onValidationFailed(data.shared_from_this(),
66 "Not SignatureSha256WithRsa signature: " + data.getName().toUri());
67 }
Yingdi Yufa4ce792014-02-06 18:09:22 -080068}
69
70void
Yingdi Yu348f5ea2014-03-01 14:47:25 -080071ValidatorInvitation::checkPolicy (const Interest& interest,
Yingdi Yufa4ce792014-02-06 18:09:22 -080072 int stepCount,
73 const OnInterestValidated& onValidated,
74 const OnInterestValidationFailed& onValidationFailed,
75 vector<shared_ptr<ValidationRequest> >& nextSteps)
76{
Yingdi Yu348f5ea2014-03-01 14:47:25 -080077 try
Yingdi Yufa4ce792014-02-06 18:09:22 -080078 {
Yingdi Yu348f5ea2014-03-01 14:47:25 -080079 Name interestName = interest.getName();
80
81 if(!m_invitationInterestRule.match(interestName))
82 return onValidationFailed(interest.shared_from_this(),
83 "Invalid interest name: " + interest.getName().toUri());
Yingdi Yufa4ce792014-02-06 18:09:22 -080084
Yingdi Yu348f5ea2014-03-01 14:47:25 -080085 Name signedName = interestName.getPrefix(-1);
86 Buffer signedBlob = Buffer(signedName.wireEncode().value(), signedName.wireEncode().value_size());
87
88 Block signatureBlock = interestName.get(Invitation::SIGNATURE).blockFromValue();
89 Block signatureInfo = interestName.get(Invitation::KEY_LOCATOR).blockFromValue();
90 Signature signature(signatureInfo, signatureBlock);
91 SignatureSha256WithRsa sig(signature);
92
93 Data innerData;
94 innerData.wireDecode(interestName.get(Invitation::INVITER_CERT).blockFromValue());
95
96 return internalCheck(signedBlob.buf(),
97 signedBlob.size(),
98 sig,
99 innerData,
100 bind(onValidated, interest.shared_from_this()),
101 bind(onValidationFailed, interest.shared_from_this(), _1));
Yingdi Yufa4ce792014-02-06 18:09:22 -0800102 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800103 catch(SignatureSha256WithRsa::Error& e)
104 {
105 return onValidationFailed(interest.shared_from_this(),
106 "Not SignatureSha256WithRsa signature: " + interest.getName().toUri());
107 }
Yingdi Yufa4ce792014-02-06 18:09:22 -0800108}
109
110void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800111ValidatorInvitation::internalCheck(const uint8_t* buf, size_t size,
112 const SignatureSha256WithRsa& sig,
113 const Data& innerData,
114 const OnValidated& onValidated,
115 const OnValidationFailed& onValidationFailed)
116{
117 try
118 {
119 const Name & keyLocatorName = sig.getKeyLocator().getName();
120 Name signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
121
122 if(m_trustAnchors.find(signingKeyName) == m_trustAnchors.end())
123 return onValidationFailed("Cannot reach any trust anchor");
124
125 if(!Validator::verifySignature(buf, size, sig, m_trustAnchors[signingKeyName]))
126 return onValidationFailed("Cannot verify interest signature");
127
128 if(!Validator::verifySignature(innerData, m_trustAnchors[signingKeyName]))
129 return onValidationFailed("Cannot verify interest signature");
130
131 if(!m_innerKeyRegex.match(innerData.getName())
132 || m_innerKeyRegex.expand() != signingKeyName.getPrefix(-1))
133 return onValidationFailed("Inner certificate does not comply with the rule");
134
135 return onValidated();
136 }
137 catch(KeyLocator::Error& e)
138 {
139 return onValidationFailed("Key Locator is not a name");
140 }
141}
142
Yingdi Yufa4ce792014-02-06 18:09:22 -0800143
144}//chronos