blob: cf7bfdb0d434a9507e1414799aa70b58df73e500 [file] [log] [blame]
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07001/*
2 * @author: ucla-cs
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 */
Jeff Thompson86aea882012-09-29 17:32:48 -07006var ContentObject = function ContentObject(_name,_signedInfo,_content,_signature){
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07007
8
Jeff Thompson86aea882012-09-29 17:32:48 -07009 if (typeof _name === 'string'){
Jeff Thompsonf3bd3592012-09-29 23:25:30 -070010 this.name = new Name(_name);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070011 }
12 else{
Jeff Thompson86aea882012-09-29 17:32:48 -070013 //TODO Check the class of _name
14 this.name = _name;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070015 }
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070016 this.signedInfo = _signedInfo;
Jeff Thompson86aea882012-09-29 17:32:48 -070017 this.content=_content;
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070018 this.signature = _signature;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070019
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070020
Jeff Thompson86aea882012-09-29 17:32:48 -070021 this.startSIG = null;
22 this.endSIG = null;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070023
Jeff Thompson86aea882012-09-29 17:32:48 -070024 this.startSignedInfo = null;
25 this.endContent = null;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070026
27 this.rawSignatureData = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070028};
29
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070030ContentObject.prototype.sign = function(){
Meki Cherkaoui8f173612012-06-06 01:05:40 -070031
Jeff Thompson86aea882012-09-29 17:32:48 -070032 var n1 = this.encodeObject(this.name);
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070033 var n2 = this.encodeObject(this.signedInfo);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070034 var n3 = this.encodeContent();
35
36 var n = n1.concat(n2,n3);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070037
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070038 if(LOG>2)console.log('Signature Data is (binary) '+n);
39
Meki Cherkaoui8f173612012-06-06 01:05:40 -070040 if(LOG>2)console.log('Signature Data is (RawString)');
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070041
Meki Cherkaoui8f173612012-06-06 01:05:40 -070042 if(LOG>2)console.log( DataUtils.toString(n) );
43
44 var sig = DataUtils.toString(n);
45
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070046
47 var rsa = new RSAKey();
48
49 rsa.readPrivateKeyFromPEMString(globalKeyManager.privateKey);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070050
51 //var hSig = rsa.signString(sig, "sha256");
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070052
Meki Cherkaoui8f173612012-06-06 01:05:40 -070053 var hSig = rsa.signByteArrayWithSHA256(n);
54
55
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070056 if(LOG>2)console.log('SIGNATURE SAVED IS');
57
58 if(LOG>2)console.log(hSig);
59
Meki Cherkaoui8f173612012-06-06 01:05:40 -070060 if(LOG>2)console.log( DataUtils.toNumbers(hSig.trim()));
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070061
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070062 this.signature.signature = DataUtils.toNumbers(hSig.trim());
Meki Cherkaoui8f173612012-06-06 01:05:40 -070063
64
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070065};
66
67ContentObject.prototype.encodeObject = function encodeObject(obj){
68 var enc = new BinaryXMLEncoder();
69
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070070 obj.to_ccnb(enc);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070071
72 var num = enc.getReducedOstream();
73
74 return num;
75
76
77};
78
79ContentObject.prototype.encodeContent = function encodeContent(obj){
80 var enc = new BinaryXMLEncoder();
81
Jeff Thompson86aea882012-09-29 17:32:48 -070082 enc.writeElement(CCNProtocolDTags.Content, this.content);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070083
84 var num = enc.getReducedOstream();
85
86 return num;
87
88
89};
90
91ContentObject.prototype.saveRawData = function(bytes){
92
Jeff Thompson86aea882012-09-29 17:32:48 -070093 var sigBits = bytes.slice(this.startSIG, this.endSIG );
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070094
95 this.rawSignatureData = sigBits;
96};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070097
Jeff Thompson86aea882012-09-29 17:32:48 -070098ContentObject.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070099
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700100 // TODO VALIDATE THAT ALL FIELDS EXCEPT SIGNATURE ARE PRESENT
101
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700102 decoder.readStartElement(this.getElementLabel());
103
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700104
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700105 if( decoder.peekStartElement(CCNProtocolDTags.Signature) ){
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700106 this.signature = new Signature();
107 this.signature.from_ccnb(decoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700108 }
109
Jeff Thompson86aea882012-09-29 17:32:48 -0700110 //this.endSIG = decoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700111
Jeff Thompson86aea882012-09-29 17:32:48 -0700112 this.startSIG = decoder.offset;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700113
Jeff Thompsonf3bd3592012-09-29 23:25:30 -0700114 this.name = new Name();
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700115 this.name.from_ccnb(decoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700116
Jeff Thompson86aea882012-09-29 17:32:48 -0700117 //this.startSignedInfo = decoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700118
119
120 if( decoder.peekStartElement(CCNProtocolDTags.SignedInfo) ){
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700121 this.signedInfo = new SignedInfo();
122 this.signedInfo.from_ccnb(decoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700123 }
124
Jeff Thompson86aea882012-09-29 17:32:48 -0700125 this.content = decoder.readBinaryElement(CCNProtocolDTags.Content);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700126
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700127
Jeff Thompson86aea882012-09-29 17:32:48 -0700128 //this.endContent = decoder.offset;
129 this.endSIG = decoder.offset;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700130
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700131
132 decoder.readEndElement();
133
134 this.saveRawData(decoder.istream);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700135};
136
Jeff Thompson86aea882012-09-29 17:32:48 -0700137ContentObject.prototype.to_ccnb = function(/*XMLEncoder*/ encoder) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700138
Jeff Thompson86aea882012-09-29 17:32:48 -0700139 //TODO verify name, SignedInfo and Signature is present
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700140
141
142 encoder.writeStartElement(this.getElementLabel());
143
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700144
145
146
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700147 if(null!=this.signature) this.signature.to_ccnb(encoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700148
149
Jeff Thompson86aea882012-09-29 17:32:48 -0700150 this.startSIG = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700151
152
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700153 if(null!=this.name) this.name.to_ccnb(encoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700154
Jeff Thompson86aea882012-09-29 17:32:48 -0700155 //this.endSIG = encoder.offset;
156 //this.startSignedInfo = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700157
158
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700159 if(null!=this.signedInfo) this.signedInfo.to_ccnb(encoder);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700160
Jeff Thompson86aea882012-09-29 17:32:48 -0700161 encoder.writeElement(CCNProtocolDTags.Content, this.content);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700162
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700163
Jeff Thompson86aea882012-09-29 17:32:48 -0700164 this.endSIG = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700165
Jeff Thompson86aea882012-09-29 17:32:48 -0700166 //this.endContent = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700167
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700168
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700169 encoder.writeEndElement();
170
171 this.saveRawData(encoder.ostream);
172
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700173};
174
175ContentObject.prototype.getElementLabel= function(){return CCNProtocolDTags.ContentObject;};
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700176
177/**
178 * Signature
179 */
180var Signature = function Signature(_witness,_signature,_digestAlgorithm) {
181
182 this.Witness = _witness;//byte [] _witness;
183 this.signature = _signature;//byte [] _signature;
184 this.digestAlgorithm = _digestAlgorithm//String _digestAlgorithm;
185};
186
187var generateSignature = function(contentName,content,signedinfo){
188
189 var enc = new BinaryXMLEncoder();
190 contentName.to_ccnb(enc);
191 var hex1 = toHex(enc.getReducedOstream());
192
193 var enc = new BinaryXMLEncoder();
194 content.to_ccnb(enc);
195 var hex2 = toHex(enc.getReducedOstream());
196
197 var enc = new BinaryXMLEncoder();
198 signedinfo.to_ccnb(enc);
199 var hex3 = toHex(enc.getReducedOstream());
200
201 var hex = hex1+hex2+hex3;
202
203 //globalKeyManager.sig
204
205};
206
207Signature.prototype.from_ccnb =function( decoder) {
208 decoder.readStartElement(this.getElementLabel());
209
210 if(LOG>4)console.log('STARTED DECODING SIGNATURE ');
211
212 if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
213
214 if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
215 this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm);
216 }
217 if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
218 if(LOG>4)console.log('WITNESS FOUND FOUND');
219 this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness);
220 }
221
222 //FORCE TO READ A SIGNATURE
223
224 //if(LOG>4)console.log('SIGNATURE FOUND ');
225 this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);
226 if(LOG>4)console.log('READ SIGNATURE ');
227
228 decoder.readEndElement();
229
230};
231
232
233Signature.prototype.to_ccnb= function( encoder){
234
235 if (!this.validate()) {
236 throw new Error("Cannot encode: field values missing.");
237 }
238
239 encoder.writeStartElement(this.getElementLabel());
240
241 if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
242 encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
243 }
244
245 if (null != this.Witness) {
246 // needs to handle null witness
247 encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
248 }
249
250 encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
251
252 encoder.writeEndElement();
253};
254
255Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
256
257
258Signature.prototype.validate = function() {
259 return null != this.signature;
260};
261
262
263/**
264 * SignedInfo
265 */
266var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
267var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
268var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
269
270var SignedInfo = function SignedInfo(_publisher,_timestamp,_type,_locator,_freshnessSeconds,_finalBlockID){
271
272 //TODO, Check types
273
274 this.publisher = _publisher; //publisherPublicKeyDigest
275 this.timestamp=_timestamp; // CCN Time
276 this.type=_type; // ContentType
277 this.locator =_locator;//KeyLocator
278 this.freshnessSeconds =_freshnessSeconds; // Integer
279 this.finalBlockID=_finalBlockID; //byte array
280
281};
282
283SignedInfo.prototype.setFields = function(){
284 //BASE64 -> RAW STRING
285
286 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
287
288 var publicKeyHex = globalKeyManager.publicKey;
289
290 console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
291 console.log(publicKeyHex);
292
293 var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ;
294
295
296
297 //var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
298
299 //if(LOG>3)console.log('string Certificate is '+stringCertificate);
300
301 //HEX -> BYTE ARRAY
302 //var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
303
304 //if(LOG>3)console.log('publisher key is ');
305 //if(LOG>3)console.log(publisherkey);
306
307 var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
308
309 this.publisher = new PublisherPublicKeyDigest( DataUtils.toNumbers( publisherKeyDigest ) );
310
311 //this.publisher = new PublisherPublicKeyDigest(publisherkey);
312
313 var d = new Date();
314
315 var time = d.getTime();
316
317
318 this.timestamp = new CCNTime( time );
319
320 if(LOG>4)console.log('TIME msec is');
321
322 if(LOG>4)console.log(this.timestamp.msec);
323
324 //DATA
325 this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
326
327 //if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
328
329 console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
330 console.log(publicKeyBytes);
331
332 this.locator = new KeyLocator( publicKeyBytes ,KeyLocatorType.KEY );
333
334 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
335
336};
337
338SignedInfo.prototype.from_ccnb = function( decoder){
339
340 decoder.readStartElement( this.getElementLabel() );
341
342 if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
343 if(LOG>3) console.log('DECODING PUBLISHER KEY');
344 this.publisher = new PublisherPublicKeyDigest();
345 this.publisher.from_ccnb(decoder);
346 }
347
348 if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
349 this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
350 if(LOG>4)console.log('TIMESTAMP FOUND IS '+this.timestamp);
351
352 }
353
354 if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
355 binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte []
356
357
358 //TODO Implement type of Key Reading
359
360 if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
361
362 this.type = binType;
363
364
365 //TODO Implement type of Key Reading
366
367
368 if (null == this.type) {
369 throw new Error("Cannot parse signedInfo type: bytes.");
370 }
371
372 } else {
373 this.type = ContentType.DATA; // default
374 }
375
376 if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
377 this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
378 if(LOG>4) console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
379 }
380
381 if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
382 this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
383 }
384
385 if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
386 this.locator = new KeyLocator();
387 this.locator.from_ccnb(decoder);
388 }
389
390 decoder.readEndElement();
391};
392
393SignedInfo.prototype.to_ccnb = function( encoder) {
394 if (!this.validate()) {
395 throw new Error("Cannot encode : field values missing.");
396 }
397 encoder.writeStartElement(this.getElementLabel());
398
399 if (null!=this.publisher) {
400 if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
401
402 this.publisher.to_ccnb(encoder);
403 }
404
405 if (null!=this.timestamp) {
406 encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
407 }
408
409 if (null!=this.type && this.type !=0) {
410
411 encoder.writeElement(CCNProtocolDTags.type, this.type);
412 }
413
414 if (null!=this.freshnessSeconds) {
415 encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
416 }
417
418 if (null!=this.finalBlockID) {
419 encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
420 }
421
422 if (null!=this.locator) {
423 this.locator.to_ccnb(encoder);
424 }
425
426 encoder.writeEndElement();
427};
428
429SignedInfo.prototype.valueToType = function(){
430 //for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
431 //if (Arrays.equals(value, entry.getKey()))
432 //return entry.getValue();
433 //}
434 return null;
435
436};
437
438SignedInfo.prototype.getElementLabel = function() {
439 return CCNProtocolDTags.SignedInfo;
440};
441
442SignedInfo.prototype.validate = function() {
443 // We don't do partial matches any more, even though encoder/decoder
444 // is still pretty generous.
445 if (null ==this.publisher || null==this.timestamp ||null== this.locator)
446 return false;
447 return true;
448};