blob: ec2efde55611fd7c1da4e4845fbc9512a56501e6 [file] [log] [blame]
Wentao Shangbd63e462012-12-03 16:19:33 -08001/**
Jeff Thompson146d7de2012-11-17 16:15:28 -08002 * @author: Meki Cheraoui
Jeff Thompson745026e2012-10-13 12:49:20 -07003 * See COPYING for copyright and distribution information.
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07004 * This class represents ContentObject Objects
5 */
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07006
Jeff Thompson2b14c7e2013-07-29 15:09:56 -07007/**
8 * Create a new ContentObject with the optional values.
9 *
10 * @constructor
11 * @param {Name} name
12 * @param {SignedInfo} signedInfo
13 * @param {Uint8Array} content
Jeff Thompson2b14c7e2013-07-29 15:09:56 -070014 */
Jeff Thompson2c580442013-07-31 11:51:18 -070015var ContentObject = function ContentObject(name, signedInfo, content) {
Jeff Thompson2b14c7e2013-07-29 15:09:56 -070016 if (typeof name == 'string')
17 this.name = new Name(name);
18 else
19 //TODO Check the class of name
20 this.name = name;
21
22 this.signedInfo = signedInfo;
23
24 if (typeof content == 'string')
25 this.content = DataUtils.toNumbersFromString(content);
26 else
27 this.content = content;
28
Jeff Thompson2c580442013-07-31 11:51:18 -070029 this.signature = new Signature();
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070030
Jeff Thompson86aea882012-09-29 17:32:48 -070031 this.startSIG = null;
32 this.endSIG = null;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070033
Jeff Thompson86aea882012-09-29 17:32:48 -070034 this.endContent = null;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070035
36 this.rawSignatureData = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070037};
38
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070039ContentObject.prototype.sign = function(){
Meki Cherkaoui8f173612012-06-06 01:05:40 -070040
Jeff Thompson86aea882012-09-29 17:32:48 -070041 var n1 = this.encodeObject(this.name);
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070042 var n2 = this.encodeObject(this.signedInfo);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070043 var n3 = this.encodeContent();
Jeff Thompson3d2393f2012-11-11 19:11:51 -080044 /*console.log('sign: ');
45 console.log(n1);
46 console.log(n2);
47 console.log(n3);*/
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070048
Jeff Thompson3d2393f2012-11-11 19:11:51 -080049 //var n = n1.concat(n2,n3);
50 var tempBuf = new ArrayBuffer(n1.length + n2.length + n3.length);
51 var n = new Uint8Array(tempBuf);
52 //console.log(n);
53 n.set(n1, 0);
54 //console.log(n);
55 n.set(n2, n1.length);
56 //console.log(n);
57 n.set(n3, n1.length + n2.length);
58 //console.log(n);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070059
Jeff Thompson3d2393f2012-11-11 19:11:51 -080060 if(LOG>4)console.log('Signature Data is (binary) '+n);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070061
Jeff Thompson3d2393f2012-11-11 19:11:51 -080062 if(LOG>4)console.log('Signature Data is (RawString)');
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070063
Jeff Thompson3d2393f2012-11-11 19:11:51 -080064 if(LOG>4)console.log( DataUtils.toString(n) );
Meki Cherkaoui8f173612012-06-06 01:05:40 -070065
Jeff Thompson3d2393f2012-11-11 19:11:51 -080066 //var sig = DataUtils.toString(n);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070067
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070068
69 var rsa = new RSAKey();
70
71 rsa.readPrivateKeyFromPEMString(globalKeyManager.privateKey);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070072
73 //var hSig = rsa.signString(sig, "sha256");
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070074
Meki Cherkaoui8f173612012-06-06 01:05:40 -070075 var hSig = rsa.signByteArrayWithSHA256(n);
76
77
Jeff Thompson3d2393f2012-11-11 19:11:51 -080078 if(LOG>4)console.log('SIGNATURE SAVED IS');
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070079
Jeff Thompson3d2393f2012-11-11 19:11:51 -080080 if(LOG>4)console.log(hSig);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070081
Jeff Thompson3d2393f2012-11-11 19:11:51 -080082 if(LOG>4)console.log( DataUtils.toNumbers(hSig.trim()));
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070083
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070084 this.signature.signature = DataUtils.toNumbers(hSig.trim());
Meki Cherkaoui8f173612012-06-06 01:05:40 -070085
86
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070087};
88
89ContentObject.prototype.encodeObject = function encodeObject(obj){
90 var enc = new BinaryXMLEncoder();
91
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070092 obj.to_ccnb(enc);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070093
94 var num = enc.getReducedOstream();
95
96 return num;
97
98
99};
100
101ContentObject.prototype.encodeContent = function encodeContent(obj){
102 var enc = new BinaryXMLEncoder();
103
Jeff Thompson86aea882012-09-29 17:32:48 -0700104 enc.writeElement(CCNProtocolDTags.Content, this.content);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700105
106 var num = enc.getReducedOstream();
107
108 return num;
109
110
111};
112
113ContentObject.prototype.saveRawData = function(bytes){
114
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800115 var sigBits = bytes.subarray(this.startSIG, this.endSIG);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700116
117 this.rawSignatureData = sigBits;
118};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700119
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700120/**
121 * @deprecated Use BinaryXMLWireFormat.decodeContentObject.
122 */
Jeff Thompson86aea882012-09-29 17:32:48 -0700123ContentObject.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
Jeff Thompson86bcd022013-07-26 17:55:03 -0700124 BinaryXMLWireFormat.decodeContentObject(this, decoder);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700125};
126
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700127/**
128 * @deprecated Use BinaryXMLWireFormat.encodeContentObject.
129 */
Jeff Thompson86aea882012-09-29 17:32:48 -0700130ContentObject.prototype.to_ccnb = function(/*XMLEncoder*/ encoder) {
Jeff Thompson86bcd022013-07-26 17:55:03 -0700131 BinaryXMLWireFormat.encodeContentObject(this, encoder);
132};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700133
Jeff Thompson86bcd022013-07-26 17:55:03 -0700134/**
135 * Encode this ContentObject for a particular wire format.
136 * @param {WireFormat} wireFormat if null, use BinaryXMLWireFormat.
137 * @returns {Uint8Array}
138 */
139ContentObject.prototype.encode = function(wireFormat) {
140 wireFormat = (wireFormat || BinaryXMLWireFormat.instance);
141 return wireFormat.encodeContentObject(this);
142};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700143
Jeff Thompson86bcd022013-07-26 17:55:03 -0700144/**
145 * Decode the input using a particular wire format and update this ContentObject.
146 * @param {Uint8Array} input
147 * @param {WireFormat} wireFormat if null, use BinaryXMLWireFormat.
148 */
149ContentObject.prototype.decode = function(input, wireFormat) {
150 wireFormat = (wireFormat || BinaryXMLWireFormat.instance);
151 wireFormat.decodeContentObject(this, input);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700152};
153
154ContentObject.prototype.getElementLabel= function(){return CCNProtocolDTags.ContentObject;};
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700155
156/**
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700157 * Create a new Signature with the optional values.
158 * @constructor
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700159 */
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700160var Signature = function Signature(witness, signature, digestAlgorithm) {
161 this.Witness = witness;
162 this.signature = signature;
163 this.digestAlgorithm = digestAlgorithm
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700164};
165
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700166Signature.prototype.from_ccnb =function( decoder) {
167 decoder.readStartElement(this.getElementLabel());
168
Wentao Shang882e34e2013-01-05 02:49:51 -0800169 if(LOG>4)console.log('STARTED DECODING SIGNATURE');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700170
171 if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700172 if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
173 this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm);
174 }
175 if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800176 if(LOG>4)console.log('WITNESS FOUND');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700177 this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness);
178 }
179
180 //FORCE TO READ A SIGNATURE
181
Wentao Shang882e34e2013-01-05 02:49:51 -0800182 if(LOG>4)console.log('SIGNATURE FOUND');
183 this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700184
185 decoder.readEndElement();
186
187};
188
189
190Signature.prototype.to_ccnb= function( encoder){
191
192 if (!this.validate()) {
193 throw new Error("Cannot encode: field values missing.");
194 }
195
196 encoder.writeStartElement(this.getElementLabel());
197
198 if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
199 encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
200 }
201
202 if (null != this.Witness) {
203 // needs to handle null witness
204 encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
205 }
206
207 encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
208
209 encoder.writeEndElement();
210};
211
212Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
213
214
215Signature.prototype.validate = function() {
216 return null != this.signature;
217};
218
219
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700220var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
221var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
222var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
223
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700224/**
225 * Create a new SignedInfo with the optional values.
226 * @constructor
227 */
228var SignedInfo = function SignedInfo(publisher, timestamp, type, locator, freshnessSeconds, finalBlockID) {
229 this.publisher = publisher; //publisherPublicKeyDigest
230 this.timestamp=timestamp; // CCN Time
231 this.type=type; // ContentType
232 this.locator =locator;//KeyLocator
233 this.freshnessSeconds =freshnessSeconds; // Integer
234 this.finalBlockID=finalBlockID; //byte array
Wentao Shangab9018d2012-12-18 11:35:45 -0800235
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700236 this.setFields();
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700237};
238
239SignedInfo.prototype.setFields = function(){
240 //BASE64 -> RAW STRING
241
242 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
243
244 var publicKeyHex = globalKeyManager.publicKey;
245
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800246 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
247 if(LOG>4)console.log(publicKeyHex);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700248
249 var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ;
250
251
252
253 //var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
254
255 //if(LOG>3)console.log('string Certificate is '+stringCertificate);
256
257 //HEX -> BYTE ARRAY
258 //var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
259
260 //if(LOG>3)console.log('publisher key is ');
261 //if(LOG>3)console.log(publisherkey);
262
263 var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
264
265 this.publisher = new PublisherPublicKeyDigest( DataUtils.toNumbers( publisherKeyDigest ) );
266
267 //this.publisher = new PublisherPublicKeyDigest(publisherkey);
268
269 var d = new Date();
270
271 var time = d.getTime();
272
273
274 this.timestamp = new CCNTime( time );
275
276 if(LOG>4)console.log('TIME msec is');
277
278 if(LOG>4)console.log(this.timestamp.msec);
279
280 //DATA
281 this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
282
283 //if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
284
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800285 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
286 if(LOG>4)console.log(publicKeyBytes);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700287
288 this.locator = new KeyLocator( publicKeyBytes ,KeyLocatorType.KEY );
289
290 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
291
292};
293
294SignedInfo.prototype.from_ccnb = function( decoder){
295
296 decoder.readStartElement( this.getElementLabel() );
297
298 if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800299 if(LOG>4)console.log('DECODING PUBLISHER KEY');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700300 this.publisher = new PublisherPublicKeyDigest();
301 this.publisher.from_ccnb(decoder);
302 }
303
304 if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800305 if(LOG>4)console.log('DECODING TIMESTAMP');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700306 this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700307 }
308
309 if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
Jeff Thompson48ff28a2013-02-18 22:53:29 -0800310 var binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte []
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700311
312
313 //TODO Implement type of Key Reading
314
315 if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
316
317 this.type = binType;
318
319
320 //TODO Implement type of Key Reading
321
322
323 if (null == this.type) {
324 throw new Error("Cannot parse signedInfo type: bytes.");
325 }
326
327 } else {
328 this.type = ContentType.DATA; // default
329 }
330
331 if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
332 this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
Wentao Shang882e34e2013-01-05 02:49:51 -0800333 if(LOG>4)console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700334 }
335
336 if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800337 if(LOG>4)console.log('DECODING FINAL BLOCKID');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700338 this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
339 }
340
341 if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800342 if(LOG>4)console.log('DECODING KEY LOCATOR');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700343 this.locator = new KeyLocator();
344 this.locator.from_ccnb(decoder);
345 }
346
347 decoder.readEndElement();
348};
349
350SignedInfo.prototype.to_ccnb = function( encoder) {
351 if (!this.validate()) {
352 throw new Error("Cannot encode : field values missing.");
353 }
354 encoder.writeStartElement(this.getElementLabel());
355
356 if (null!=this.publisher) {
357 if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
358
359 this.publisher.to_ccnb(encoder);
360 }
361
362 if (null!=this.timestamp) {
363 encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
364 }
365
366 if (null!=this.type && this.type !=0) {
367
368 encoder.writeElement(CCNProtocolDTags.type, this.type);
369 }
370
371 if (null!=this.freshnessSeconds) {
372 encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
373 }
374
375 if (null!=this.finalBlockID) {
376 encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
377 }
378
379 if (null!=this.locator) {
380 this.locator.to_ccnb(encoder);
381 }
382
383 encoder.writeEndElement();
384};
385
386SignedInfo.prototype.valueToType = function(){
387 //for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
388 //if (Arrays.equals(value, entry.getKey()))
389 //return entry.getValue();
390 //}
391 return null;
392
393};
394
395SignedInfo.prototype.getElementLabel = function() {
396 return CCNProtocolDTags.SignedInfo;
397};
398
399SignedInfo.prototype.validate = function() {
400 // We don't do partial matches any more, even though encoder/decoder
401 // is still pretty generous.
402 if (null ==this.publisher || null==this.timestamp ||null== this.locator)
403 return false;
404 return true;
405};