blob: a95f89897cc52ae5930f1327391dca7f2e1e9c50 [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
Yingdi Yufa4ce792014-02-06 18:09:22 -080016using namespace ndn;
17
18INIT_LOGGER("ValidatorInvitation");
19
20namespace chronos{
21
Yingdi Yu17032f82014-03-25 15:48:23 -070022using ndn::shared_ptr;
23
Yingdi Yufa4ce792014-02-06 18:09:22 -080024const shared_ptr<CertificateCache> ValidatorInvitation::DefaultCertificateCache = shared_ptr<CertificateCache>();
25
Yingdi Yu348f5ea2014-03-01 14:47:25 -080026ValidatorInvitation::ValidatorInvitation()
27 : Validator()
28 , m_invitationReplyRule("^([^<CHRONOCHAT-INVITATION>]*)<CHRONOCHAT-INVITATION>",
29 "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
30 "==", "\\1", "\\1\\2", true)
31 , m_invitationInterestRule("^[^<CHRONOCHAT-INVITATION>]*<CHRONOCHAT-INVITATION><>{6}$")
32 , m_innerKeyRegex("^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT><>$", "\\1\\2")
Yingdi Yufa4ce792014-02-06 18:09:22 -080033{
Yingdi Yu348f5ea2014-03-01 14:47:25 -080034}
Yingdi Yufa4ce792014-02-06 18:09:22 -080035
36void
Yingdi Yu348f5ea2014-03-01 14:47:25 -080037ValidatorInvitation::checkPolicy (const Data& data,
Yingdi Yufa4ce792014-02-06 18:09:22 -080038 int stepCount,
39 const OnDataValidated& onValidated,
40 const OnDataValidationFailed& onValidationFailed,
Yingdi Yu17032f82014-03-25 15:48:23 -070041 std::vector<shared_ptr<ValidationRequest> >& nextSteps)
Yingdi Yufa4ce792014-02-06 18:09:22 -080042{
Yingdi Yu348f5ea2014-03-01 14:47:25 -080043 try
Yingdi Yufa4ce792014-02-06 18:09:22 -080044 {
Yingdi Yu348f5ea2014-03-01 14:47:25 -080045 SignatureSha256WithRsa sig(data.getSignature());
46 const Name & keyLocatorName = sig.getKeyLocator().getName();
47
48 if(!m_invitationReplyRule.satisfy(data.getName(), keyLocatorName))
49 return onValidationFailed(data.shared_from_this(),
50 "Does not comply with the invitation rule: "
51 + data.getName().toUri() + " signed by: "
52 + keyLocatorName.toUri());
53
54 Data innerData;
55 innerData.wireDecode(data.getContent().blockFromValue());
56
Yingdi Yu233a9722014-03-07 15:47:09 -080057 return internalCheck(data.wireEncode().value(),
58 data.wireEncode().value_size() - data.getSignature().getValue().size(),
Yingdi Yu348f5ea2014-03-01 14:47:25 -080059 sig,
60 innerData,
61 bind(onValidated, data.shared_from_this()),
62 bind(onValidationFailed, data.shared_from_this(), _1));
Yingdi Yufa4ce792014-02-06 18:09:22 -080063 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -080064 catch(SignatureSha256WithRsa::Error &e)
65 {
66 return onValidationFailed(data.shared_from_this(),
67 "Not SignatureSha256WithRsa signature: " + data.getName().toUri());
68 }
Yingdi Yufa4ce792014-02-06 18:09:22 -080069}
70
71void
Yingdi Yu348f5ea2014-03-01 14:47:25 -080072ValidatorInvitation::checkPolicy (const Interest& interest,
Yingdi Yufa4ce792014-02-06 18:09:22 -080073 int stepCount,
74 const OnInterestValidated& onValidated,
75 const OnInterestValidationFailed& onValidationFailed,
Yingdi Yu17032f82014-03-25 15:48:23 -070076 std::vector<shared_ptr<ValidationRequest> >& nextSteps)
Yingdi Yufa4ce792014-02-06 18:09:22 -080077{
Yingdi Yu348f5ea2014-03-01 14:47:25 -080078 try
Yingdi Yufa4ce792014-02-06 18:09:22 -080079 {
Yingdi Yu348f5ea2014-03-01 14:47:25 -080080 Name interestName = interest.getName();
81
82 if(!m_invitationInterestRule.match(interestName))
83 return onValidationFailed(interest.shared_from_this(),
84 "Invalid interest name: " + interest.getName().toUri());
Yingdi Yufa4ce792014-02-06 18:09:22 -080085
Yingdi Yu348f5ea2014-03-01 14:47:25 -080086 Name signedName = interestName.getPrefix(-1);
87 Buffer signedBlob = Buffer(signedName.wireEncode().value(), signedName.wireEncode().value_size());
88
89 Block signatureBlock = interestName.get(Invitation::SIGNATURE).blockFromValue();
90 Block signatureInfo = interestName.get(Invitation::KEY_LOCATOR).blockFromValue();
91 Signature signature(signatureInfo, signatureBlock);
92 SignatureSha256WithRsa sig(signature);
93
94 Data innerData;
95 innerData.wireDecode(interestName.get(Invitation::INVITER_CERT).blockFromValue());
96
97 return internalCheck(signedBlob.buf(),
98 signedBlob.size(),
99 sig,
100 innerData,
101 bind(onValidated, interest.shared_from_this()),
102 bind(onValidationFailed, interest.shared_from_this(), _1));
Yingdi Yufa4ce792014-02-06 18:09:22 -0800103 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800104 catch(SignatureSha256WithRsa::Error& e)
105 {
106 return onValidationFailed(interest.shared_from_this(),
107 "Not SignatureSha256WithRsa signature: " + interest.getName().toUri());
108 }
Yingdi Yufa4ce792014-02-06 18:09:22 -0800109}
110
111void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800112ValidatorInvitation::internalCheck(const uint8_t* buf, size_t size,
113 const SignatureSha256WithRsa& sig,
114 const Data& innerData,
115 const OnValidated& onValidated,
116 const OnValidationFailed& onValidationFailed)
117{
118 try
119 {
120 const Name & keyLocatorName = sig.getKeyLocator().getName();
121 Name signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
122
123 if(m_trustAnchors.find(signingKeyName) == m_trustAnchors.end())
124 return onValidationFailed("Cannot reach any trust anchor");
125
126 if(!Validator::verifySignature(buf, size, sig, m_trustAnchors[signingKeyName]))
Yingdi Yu233a9722014-03-07 15:47:09 -0800127 return onValidationFailed("Cannot verify outer signature");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800128
Yingdi Yu233a9722014-03-07 15:47:09 -0800129 // Temporarily disabled, we should get it back when we create a specific key for the chatroom.
130 // if(!Validator::verifySignature(innerData, m_trustAnchors[signingKeyName]))
131 // return onValidationFailed("Cannot verify inner signature");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800132
133 if(!m_innerKeyRegex.match(innerData.getName())
134 || m_innerKeyRegex.expand() != signingKeyName.getPrefix(-1))
135 return onValidationFailed("Inner certificate does not comply with the rule");
136
137 return onValidated();
138 }
139 catch(KeyLocator::Error& e)
140 {
141 return onValidationFailed("Key Locator is not a name");
142 }
143}
144
Yingdi Yufa4ce792014-02-06 18:09:22 -0800145
146}//chronos