verification-helpers.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "verification-helpers.hpp"
23 
24 #include "data.hpp"
25 #include "interest.hpp"
27 #include "security/pib/key.hpp"
28 #include "security/pib/key.hpp"
29 #include "security/transform.hpp"
32 
33 namespace ndn {
34 namespace security {
35 
36 bool
37 verifySignature(const uint8_t* blob, size_t blobLen, const uint8_t* sig, size_t sigLen,
38  const v2::PublicKey& pKey)
39 {
40  bool result = false;
41  try {
42  using namespace transform;
43  bufferSource(blob, blobLen) >> verifierFilter(DigestAlgorithm::SHA256, pKey, sig, sigLen)
44  >> boolSink(result);
45  }
46  catch (const transform::Error&) {
47  return false;
48  }
49  return result;
50 }
51 
52 bool
53 verifySignature(const uint8_t* data, size_t dataLen, const uint8_t* sig, size_t sigLen,
54  const uint8_t* key, size_t keyLen)
55 {
56  v2::PublicKey pKey;
57  try {
58  pKey.loadPkcs8(key, keyLen);
59  }
60  catch (const transform::Error&) {
61  return false;
62  }
63 
64  return verifySignature(data, dataLen, sig, sigLen, pKey);
65 }
66 
67 static std::tuple<bool, const uint8_t*, size_t, const uint8_t*, size_t>
68 parse(const Data& data)
69 {
70  try {
71  return std::make_tuple(true,
72  data.wireEncode().value(),
73  data.wireEncode().value_size() - data.getSignature().getValue().size(),
74  data.getSignature().getValue().value(),
75  data.getSignature().getValue().value_size());
76  }
77  catch (const tlv::Error&) {
78  return std::make_tuple(false, nullptr, 0, nullptr, 0);
79  }
80 }
81 
82 static std::tuple<bool, const uint8_t*, size_t, const uint8_t*, size_t>
83 parse(const Interest& interest)
84 {
85  const Name& interestName = interest.getName();
86 
87  if (interestName.size() < signed_interest::MIN_SIZE)
88  return std::make_tuple(false, nullptr, 0, nullptr, 0);
89 
90  try {
91  const Block& nameBlock = interestName.wireEncode();
92 
93  return std::make_tuple(true,
94  nameBlock.value(), nameBlock.value_size() - interestName[signed_interest::POS_SIG_VALUE].size(),
95  interestName[signed_interest::POS_SIG_VALUE].blockFromValue().value(),
96  interestName[signed_interest::POS_SIG_VALUE].blockFromValue().value_size());
97  }
98  catch (const tlv::Error&) {
99  return std::make_tuple(false, nullptr, 0, nullptr, 0);
100  }
101 }
102 
103 static bool
104 verifySignature(const std::tuple<bool, const uint8_t*, size_t, const uint8_t*, size_t>& params,
105  const v2::PublicKey& pKey)
106 {
107  bool isParsable = false;
108  const uint8_t* buf = nullptr;
109  size_t bufLen = 0;
110  const uint8_t* sig = nullptr;
111  size_t sigLen = 0;
112 
113  std::tie(isParsable, buf, bufLen, sig, sigLen) = params;
114 
115  if (isParsable)
116  return verifySignature(buf, bufLen, sig, sigLen, pKey);
117  else
118  return false;
119 }
120 
121 static bool
122 verifySignature(const std::tuple<bool, const uint8_t*, size_t, const uint8_t*, size_t>& params,
123  const uint8_t* key, size_t keyLen)
124 {
125  bool isParsable = false;
126  const uint8_t* buf = nullptr;
127  size_t bufLen = 0;
128  const uint8_t* sig = nullptr;
129  size_t sigLen = 0;
130 
131  std::tie(isParsable, buf, bufLen, sig, sigLen) = params;
132 
133  if (isParsable)
134  return verifySignature(buf, bufLen, sig, sigLen, key, keyLen);
135  else
136  return false;
137 }
138 
139 bool
140 verifySignature(const Data& data, const v2::PublicKey& key)
141 {
142  return verifySignature(parse(data), key);
143 }
144 
145 bool
146 verifySignature(const Interest& interest, const v2::PublicKey& key)
147 {
148  return verifySignature(parse(interest), key);
149 }
150 
151 bool
152 verifySignature(const Data& data, const pib::Key& key)
153 {
154  return verifySignature(parse(data), key.getPublicKey().buf(), key.getPublicKey().size());
155 }
156 
157 bool
158 verifySignature(const Interest& interest, const pib::Key& key)
159 {
160  return verifySignature(parse(interest), key.getPublicKey().buf(), key.getPublicKey().size());
161 }
162 
163 bool
164 verifySignature(const Data& data, const uint8_t* key, size_t keyLen)
165 {
166  return verifySignature(parse(data), key, keyLen);
167 }
168 
169 bool
170 verifySignature(const Interest& interest, const uint8_t* key, size_t keyLen)
171 {
172  return verifySignature(parse(interest), key, keyLen);
173 }
174 
175 bool
176 verifySignature(const Data& data, const v2::Certificate& cert)
177 {
178  return verifySignature(parse(data), cert.getContent().value(), cert.getContent().value_size());
179 }
180 
181 bool
182 verifySignature(const Interest& interest, const v2::Certificate& cert)
183 {
184  return verifySignature(parse(interest), cert.getContent().value(), cert.getContent().value_size());
185 }
186 
188 
189 bool
190 verifyDigest(const uint8_t* blob, size_t blobLen, const uint8_t* digest, size_t digestLen,
191  DigestAlgorithm algorithm)
192 {
193  using namespace transform;
194 
195  OBufferStream os;
196  try {
197  bufferSource(blob, blobLen) >> digestFilter(algorithm) >> streamSink(os);
198  }
199  catch (const transform::Error&) {
200  return false;
201  }
202  ConstBufferPtr result = os.buf();
203 
204  if (result->size() != digestLen)
205  return false;
206 
207  // constant-time buffer comparison to mitigate timing attacks
208  return CRYPTO_memcmp(result->buf(), digest, digestLen) == 0;
209 }
210 
211 bool
212 verifyDigest(const Data& data, DigestAlgorithm algorithm)
213 {
214  bool isParsable = false;
215  const uint8_t* buf = nullptr;
216  size_t bufLen = 0;
217  const uint8_t* sig = nullptr;
218  size_t sigLen = 0;
219 
220  std::tie(isParsable, buf, bufLen, sig, sigLen) = parse(data);
221 
222  if (isParsable) {
223  return verifyDigest(buf, bufLen, sig, sigLen, algorithm);
224  }
225  else {
226  return false;
227  }
228 }
229 
230 bool
231 verifyDigest(const Interest& interest, DigestAlgorithm algorithm)
232 {
233  bool isParsable = false;
234  const uint8_t* buf = nullptr;
235  size_t bufLen = 0;
236  const uint8_t* sig = nullptr;
237  size_t sigLen = 0;
238 
239  std::tie(isParsable, buf, bufLen, sig, sigLen) = parse(interest);
240 
241  if (isParsable) {
242  return verifyDigest(buf, bufLen, sig, sigLen, algorithm);
243  }
244  else {
245  return false;
246  }
247 }
248 
249 } // namespace security
250 } // namespace ndn
const Name & getName() const
Definition: interest.hpp:226
Copyright (c) 2013-2016 Regents of the University of California.
Definition: common.hpp:74
The certificate following the certificate format naming convention.
const size_t MIN_SIZE
minimal number of components for Signed Interest
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:122
Class representing a wire element of NDN-TLV packet format.
Definition: block.hpp:43
represents an Interest packet
Definition: interest.hpp:42
const Block & getValue() const
Get SignatureValue in the wire format.
Definition: signature.hpp:105
size_t size() const
Definition: block.cpp:504
bool verifyDigest(const uint8_t *blob, size_t blobLen, const uint8_t *digest, size_t digestLen, DigestAlgorithm algorithm)
Verify blob against digest using algorithm.
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
Definition: data.cpp:52
uint8_t * buf()
Definition: buffer.hpp:87
A frontend handle of a key instance.
Definition: key.hpp:49
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:51
size_t size() const
Get the number of components.
Definition: name.hpp:400
unique_ptr< Transform > digestFilter(DigestAlgorithm algo)
Use the SHA256 hash of the public key as the key id.
Name abstraction to represent an absolute name.
Definition: name.hpp:46
Base class of transformation error.
unique_ptr< Transform > verifierFilter(DigestAlgorithm algo, const PublicKey &key, const uint8_t *sig, size_t sigLen)
size_t value_size() const
Definition: block.cpp:529
const ssize_t POS_SIG_VALUE
const Buffer & getPublicKey() const
Get public key bits.
Definition: key.cpp:56
const Signature & getSignature() const
Definition: data.hpp:348
bool verifySignature(const uint8_t *blob, size_t blobLen, const uint8_t *sig, size_t sigLen, const v2::PublicKey &pKey)
Verify blob using key against sig.
shared_ptr< Buffer > buf()
Flush written data to the stream and return shared pointer to the underlying buffer.
const Block & getContent() const
Get content Block.
Definition: data.cpp:230
static std::tuple< bool, const uint8_t *, size_t, const uint8_t *, size_t > parse(const Data &data)
const uint8_t * value() const
Definition: block.cpp:520
implements an output stream that constructs ndn::Buffer
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:33
represents a Data packet
Definition: data.hpp:37
unique_ptr< Sink > boolSink(bool &value)
Definition: bool-sink.cpp:51
represents an error in TLV encoding or decoding