blob: 9d2db414e1ef7010718323c8fa422e67917ee539 [file] [log] [blame]
Jeff Thompson5cae5e52013-07-10 19:41:20 -07001/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07002 * Copyright (C) 2013 Regents of the University of California.
3 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson5cae5e52013-07-10 19:41:20 -07004 * See COPYING for copyright and distribution information.
5 */
6
7#include <cstdlib>
8#include <sstream>
9#include <iostream>
Jeff Thompsonade5b1e2013-08-09 12:16:45 -070010#include <time.h>
Jeff Thompson17882b42013-08-23 16:23:22 -070011#include "../ndn-cpp/data.hpp"
Jeff Thompson7a67cb62013-08-26 11:43:18 -070012#include "../ndn-cpp/security/key-chain.hpp"
Jeff Thompson20af0732013-09-12 17:01:45 -070013#include "../ndn-cpp/sha256-with-rsa-signature.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070014
15using namespace std;
16using namespace ndn;
Jeff Thompsondb008cc2013-09-17 16:35:07 -070017using namespace func_lib;
18#if HAVE_STD_FUNCTION
19// In the std library, the placeholders are in a different namespace than boost.
20using namespace func_lib::placeholders;
21#endif
Jeff Thompson5cae5e52013-07-10 19:41:20 -070022
Jeff Thompson56ec9e22013-08-02 11:34:07 -070023unsigned char Data1[] = {
240x04, 0x82, // NDN Data
Jeff Thompson5cae5e52013-07-10 19:41:20 -070025 0x02, 0xaa, // Signature
26 0x03, 0xb2, // SignatureBits
27 0x08, 0x85, 0x20, 0xea, 0xb5, 0xb0, 0x63, 0xda, 0x94, 0xe9, 0x68, 0x7a,
28 0x8e, 0x65, 0x60, 0xe0, 0xc6, 0x43, 0x96, 0xd9, 0x69, 0xb4, 0x40, 0x72, 0x52, 0x00, 0x2c, 0x8e, 0x2a, 0xf5,
29 0x47, 0x12, 0x59, 0x93, 0xda, 0xed, 0x82, 0xd0, 0xf8, 0xe6, 0x65, 0x09, 0x87, 0x84, 0x54, 0xc7, 0xce, 0x9a,
30 0x93, 0x0d, 0x47, 0xf1, 0xf9, 0x3b, 0x98, 0x78, 0x2c, 0x22, 0x21, 0xd9, 0x2b, 0xda, 0x03, 0x30, 0x84, 0xf3,
31 0xc5, 0x52, 0x64, 0x2b, 0x1d, 0xde, 0x50, 0xe0, 0xee, 0xca, 0xa2, 0x73, 0x7a, 0x93, 0x30, 0xa8, 0x47, 0x7f,
32 0x6f, 0x41, 0xb0, 0xc8, 0x6e, 0x89, 0x1c, 0xcc, 0xf9, 0x01, 0x44, 0xc3, 0x08, 0xcf, 0x77, 0x47, 0xfc, 0xed,
33 0x48, 0xf0, 0x4c, 0xe9, 0xc2, 0x3b, 0x7d, 0xef, 0x6e, 0xa4, 0x80, 0x40, 0x9e, 0x43, 0xb6, 0x77, 0x7a, 0x1d,
34 0x51, 0xed, 0x98, 0x33, 0x93, 0xdd, 0x88, 0x01, 0x0e, 0xd3,
35 0x00,
36 0x00,
37 0xf2, 0xfa, 0x9d, 0x6e, 0x64, 0x6e, 0x00, 0xfa, 0x9d, 0x61, 0x62, 0x63, 0x00, 0x00, // Name
38 0x01, 0xa2, // SignedInfo
39 0x03, 0xe2, // PublisherPublicKeyDigest
40 0x02, 0x85, 0xb5, 0x50, 0x6b, 0x1a,
41 0xba, 0x3d, 0xa7, 0x76, 0x1b, 0x0f, 0x8d, 0x61, 0xa4, 0xaa, 0x7e, 0x3b, 0x6d, 0x15, 0xb4, 0x26, 0xfe, 0xb5,
42 0xbd, 0xa8, 0x23, 0x89, 0xac, 0xa7, 0x65, 0xa3, 0xb8, 0x1c,
43 0x00,
Jeff Thompson5cae5e52013-07-10 19:41:20 -070044 0x02, 0xba, // Timestamp
45 0xb5, 0x05, 0x1d, 0xde, 0xe9, 0x5b, 0xdb,
46 0x00,
Jeff Thompson5cae5e52013-07-10 19:41:20 -070047 0x01, 0xe2, // KeyLocator
48 0x01, 0xda, // Key
49 0x0a, 0x95, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
50 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81,
51 0x81, 0x00, 0xe1, 0x7d, 0x30, 0xa7, 0xd8, 0x28, 0xab, 0x1b, 0x84, 0x0b, 0x17, 0x54, 0x2d, 0xca, 0xf6, 0x20,
52 0x7a, 0xfd, 0x22, 0x1e, 0x08, 0x6b, 0x2a, 0x60, 0xd1, 0x6c, 0xb7, 0xf5, 0x44, 0x48, 0xba, 0x9f, 0x3f, 0x08,
53 0xbc, 0xd0, 0x99, 0xdb, 0x21, 0xdd, 0x16, 0x2a, 0x77, 0x9e, 0x61, 0xaa, 0x89, 0xee, 0xe5, 0x54, 0xd3, 0xa4,
54 0x7d, 0xe2, 0x30, 0xbc, 0x7a, 0xc5, 0x90, 0xd5, 0x24, 0x06, 0x7c, 0x38, 0x98, 0xbb, 0xa6, 0xf5, 0xdc, 0x43,
55 0x60, 0xb8, 0x45, 0xed, 0xa4, 0x8c, 0xbd, 0x9c, 0xf1, 0x26, 0xa7, 0x23, 0x44, 0x5f, 0x0e, 0x19, 0x52, 0xd7,
56 0x32, 0x5a, 0x75, 0xfa, 0xf5, 0x56, 0x14, 0x4f, 0x9a, 0x98, 0xaf, 0x71, 0x86, 0xb0, 0x27, 0x86, 0x85, 0xb8,
57 0xe2, 0xc0, 0x8b, 0xea, 0x87, 0x17, 0x1b, 0x4d, 0xee, 0x58, 0x5c, 0x18, 0x28, 0x29, 0x5b, 0x53, 0x95, 0xeb,
58 0x4a, 0x17, 0x77, 0x9f, 0x02, 0x03, 0x01, 0x00, 0x01,
59 0x00,
60 0x00,
61 0x00,
62 0x01, 0x9a, // Content
63 0xc5, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x21,
64 0x00,
650x00,
661
67};
68
Jeff Thompson1656e6a2013-08-29 18:01:48 -070069static void dumpData(const Data& data)
Jeff Thompson61c4ecf2013-08-08 15:56:46 -070070{
71 cout << "name: " << data.getName().to_uri() << endl;
72 if (data.getContent().size() > 0) {
73 cout << "content (raw): ";
74 for (unsigned int i = 0; i < data.getContent().size(); ++i)
Jeff Thompson18db5a52013-09-12 13:24:43 -070075 cout << (*data.getContent())[i];
Jeff Thompson61c4ecf2013-08-08 15:56:46 -070076 cout<< endl;
Jeff Thompson18db5a52013-09-12 13:24:43 -070077 cout << "content (hex): " << toHex(*data.getContent()) << endl;
Jeff Thompson61c4ecf2013-08-08 15:56:46 -070078 }
79 else
80 cout << "content: <empty>" << endl;
Jeff Thompsonfec716d2013-09-11 13:54:36 -070081
Jeff Thompsonfec716d2013-09-11 13:54:36 -070082 cout << "metaInfo.timestamp: ";
83 if (data.getMetaInfo().getTimestampMilliseconds() >= 0) {
84 time_t seconds = data.getMetaInfo().getTimestampMilliseconds() / 1000.0;
85 cout << data.getMetaInfo().getTimestampMilliseconds() << " milliseconds, UTC time: " << asctime(gmtime(&seconds));
86 }
87 else
88 cout << "<none>" << endl;
89 if (!(data.getMetaInfo().getType() < 0 || data.getMetaInfo().getType() == ndn_ContentType_DATA)) {
90 cout << "metaInfo.type: ";
91 if (data.getMetaInfo().getType() == ndn_ContentType_ENCR)
92 cout << "ENCR" << endl;
93 else if (data.getMetaInfo().getType() == ndn_ContentType_GONE)
94 cout << "GONE" << endl;
95 else if (data.getMetaInfo().getType() == ndn_ContentType_KEY)
96 cout << "KEY" << endl;
97 else if (data.getMetaInfo().getType() == ndn_ContentType_LINK)
98 cout << "LINK" << endl;
99 else if (data.getMetaInfo().getType() == ndn_ContentType_NACK)
100 cout << "NACK" << endl;
101 }
102 cout << "metaInfo.freshnessSeconds: ";
103 if (data.getMetaInfo().getFreshnessSeconds() >= 0)
104 cout << data.getMetaInfo().getFreshnessSeconds() << endl;
105 else
106 cout << "<none>" << endl;
107 cout << "metaInfo.finalBlockID: "
Jeff Thompson85db6d72013-09-12 12:41:18 -0700108 << (data.getMetaInfo().getFinalBlockID().getValue().size() > 0 ?
109 toHex(*data.getMetaInfo().getFinalBlockID().getValue()).c_str() : "<none>") << endl;
Jeff Thompson61c4ecf2013-08-08 15:56:46 -0700110
Jeff Thompson20af0732013-09-12 17:01:45 -0700111 const Sha256WithRsaSignature *signature = dynamic_cast<const Sha256WithRsaSignature*>(data.getSignature());
112 if (signature) {
113 cout << "signature.digestAlgorithm: "
114 << (signature->getDigestAlgorithm().size() > 0 ? toHex(*signature->getDigestAlgorithm()).c_str() : "default (sha-256)") << endl;
115 cout << "signature.witness: "
116 << (signature->getWitness().size() > 0 ? toHex(*signature->getWitness()).c_str() : "<none>") << endl;
117 cout << "signature.signature: "
118 << (signature->getSignature().size() > 0 ? toHex(*signature->getSignature()).c_str() : "<none>") << endl;
119 cout << "signature.publisherPublicKeyDigest: "
120 << (signature->getPublisherPublicKeyDigest().getPublisherPublicKeyDigest().size() > 0 ?
121 toHex(*signature->getPublisherPublicKeyDigest().getPublisherPublicKeyDigest()).c_str() : "<none>") << endl;
122 cout << "signature.keyLocator: ";
123 if ((int)signature->getKeyLocator().getType() >= 0) {
124 if (signature->getKeyLocator().getType() == ndn_KeyLocatorType_KEY)
125 cout << "Key: " << toHex(*signature->getKeyLocator().getKeyData()) << endl;
126 else if (signature->getKeyLocator().getType() == ndn_KeyLocatorType_CERTIFICATE)
127 cout << "Certificate: " << toHex(*signature->getKeyLocator().getKeyData()) << endl;
128 else if (signature->getKeyLocator().getType() == ndn_KeyLocatorType_KEYNAME) {
129 cout << "KeyName: " << signature->getKeyLocator().getKeyName().to_uri() << endl;
Jeff Thompsondb008cc2013-09-17 16:35:07 -0700130 cout << "signature.keyLocator: ";
Jeff Thompson20af0732013-09-12 17:01:45 -0700131 if ((int)signature->getKeyLocator().getKeyNameType() >= 0) {
132 bool showKeyNameData = true;
133 if (signature->getKeyLocator().getKeyNameType() == ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST)
134 cout << "PublisherPublicKeyDigest: ";
135 else if (signature->getKeyLocator().getKeyNameType() == ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST)
136 cout << "PublisherCertificateDigest: ";
137 else if (signature->getKeyLocator().getKeyNameType() == ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST)
138 cout << "PublisherIssuerKeyDigest: ";
139 else if (signature->getKeyLocator().getKeyNameType() == ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST)
140 cout << "PublisherIssuerCertificateDigest: ";
141 else {
142 cout << "<unrecognized ndn_KeyNameType " << signature->getKeyLocator().getKeyNameType() << ">" << endl;
143 showKeyNameData = false;
144 }
145 if (showKeyNameData)
Jeff Thompsondb008cc2013-09-17 16:35:07 -0700146 cout << (signature->getKeyLocator().getKeyData().size() > 0 ?
147 toHex(*signature->getKeyLocator().getKeyData()).c_str() : "<none>") << endl;
Jeff Thompsonf4585af2013-09-11 14:56:59 -0700148 }
Jeff Thompson20af0732013-09-12 17:01:45 -0700149 else
150 cout << "<no key digest>" << endl;
Jeff Thompsonf4585af2013-09-11 14:56:59 -0700151 }
152 else
Jeff Thompson20af0732013-09-12 17:01:45 -0700153 cout << "<unrecognized ndn_KeyLocatorType " << signature->getKeyLocator().getType() << ">" << endl;
Jeff Thompsonf4585af2013-09-11 14:56:59 -0700154 }
155 else
Jeff Thompson20af0732013-09-12 17:01:45 -0700156 cout << "<none>" << endl;
Jeff Thompsonf4585af2013-09-11 14:56:59 -0700157 }
Jeff Thompson61c4ecf2013-08-08 15:56:46 -0700158}
159
Jeff Thompsondb008cc2013-09-17 16:35:07 -0700160static void onVerified(const char *prefix, const Data &data)
161{
162 cout << prefix << " signature verification: VERIFIED" << endl;
163}
164
165static void onVerifyFailed(const char *prefix)
166{
167 cout << prefix << " signature verification: FAILED" << endl;
168}
169
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700170int main(int argc, char** argv)
171{
172 try {
Jeff Thompson56ec9e22013-08-02 11:34:07 -0700173 Data data;
Jeff Thompson67e9e0a2013-08-02 19:16:19 -0700174 data.wireDecode(Data1, sizeof(Data1));
Jeff Thompson61c4ecf2013-08-08 15:56:46 -0700175 cout << "Decoded Data:" << endl;
176 dumpData(data);
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700177
Jeff Thompsonc2b7b142013-09-12 15:29:04 -0700178 Blob encoding = data.wireEncode();
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700179
Jeff Thompson56ec9e22013-08-02 11:34:07 -0700180 Data reDecodedData;
Jeff Thompson67e9e0a2013-08-02 19:16:19 -0700181 reDecodedData.wireDecode(*encoding);
Jeff Thompson61c4ecf2013-08-08 15:56:46 -0700182 cout << endl << "Re-decoded Data:" << endl;
183 dumpData(reDecodedData);
Jeff Thompsonb81192e2013-08-09 09:34:51 -0700184
185 Data freshData(Name("/ndn/abc"));
Jeff Thompsonecc1a822013-08-09 10:53:48 -0700186 const unsigned char freshContent[] = "SUCCESS!";
187 freshData.setContent(freshContent, sizeof(freshContent) - 1);
Jeff Thompsonfec716d2013-09-11 13:54:36 -0700188 freshData.getMetaInfo().setTimestampMilliseconds(time(NULL) * 1000.0);
Jeff Thompsonb81192e2013-08-09 09:34:51 -0700189
Jeff Thompsondb008cc2013-09-17 16:35:07 -0700190 ptr_lib::shared_ptr<PrivateKeyStorage> privateKeyStorage(new PrivateKeyStorage());
191 ptr_lib::shared_ptr<IdentityManager> identityManager(new IdentityManager(privateKeyStorage));
192 KeyChain keyChain(identityManager);
193
194 keyChain.sign(freshData);
Jeff Thompson1e90d8c2013-08-12 16:09:25 -0700195 cout << endl << "Freshly-signed Data:" << endl;
Jeff Thompsonb81192e2013-08-09 09:34:51 -0700196 dumpData(freshData);
Jeff Thompsonc2b7b142013-09-12 15:29:04 -0700197 Blob freshEncoding = freshData.wireEncode();
Jeff Thompsondb008cc2013-09-17 16:35:07 -0700198
199 // Do verification at the end because it uses callbacks.
200 cout << endl;
201 keyChain.verifyData(data, bind(&onVerified, "Decoded Data", _1), bind(&onVerifyFailed, "Decoded Data"));
202 keyChain.verifyData(reDecodedData, bind(&onVerified, "Re-decoded Data", _1), bind(&onVerifyFailed, "Re-decoded Data"));
203 keyChain.verifyData(freshData, bind(&onVerified, "Freshly-signed Data", _1), bind(&onVerifyFailed, "Freshly-signed Data"));
204 } catch (std::exception& e) {
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700205 cout << "exception: " << e.what() << endl;
206 }
207 return 0;
208}