blob: 9299d847e7b95f4a1a1c5041c7226cd4aa2fa62b [file] [log] [blame]
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07001/*
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 */
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();
Jeff Thompson3d2393f2012-11-11 19:11:51 -080035 /*console.log('sign: ');
36 console.log(n1);
37 console.log(n2);
38 console.log(n3);*/
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070039
Jeff Thompson3d2393f2012-11-11 19:11:51 -080040 //var n = n1.concat(n2,n3);
41 var tempBuf = new ArrayBuffer(n1.length + n2.length + n3.length);
42 var n = new Uint8Array(tempBuf);
43 //console.log(n);
44 n.set(n1, 0);
45 //console.log(n);
46 n.set(n2, n1.length);
47 //console.log(n);
48 n.set(n3, n1.length + n2.length);
49 //console.log(n);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070050
Jeff Thompson3d2393f2012-11-11 19:11:51 -080051 if(LOG>4)console.log('Signature Data is (binary) '+n);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070052
Jeff Thompson3d2393f2012-11-11 19:11:51 -080053 if(LOG>4)console.log('Signature Data is (RawString)');
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070054
Jeff Thompson3d2393f2012-11-11 19:11:51 -080055 if(LOG>4)console.log( DataUtils.toString(n) );
Meki Cherkaoui8f173612012-06-06 01:05:40 -070056
Jeff Thompson3d2393f2012-11-11 19:11:51 -080057 //var sig = DataUtils.toString(n);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070058
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070059
60 var rsa = new RSAKey();
61
62 rsa.readPrivateKeyFromPEMString(globalKeyManager.privateKey);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070063
64 //var hSig = rsa.signString(sig, "sha256");
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070065
Meki Cherkaoui8f173612012-06-06 01:05:40 -070066 var hSig = rsa.signByteArrayWithSHA256(n);
67
68
Jeff Thompson3d2393f2012-11-11 19:11:51 -080069 if(LOG>4)console.log('SIGNATURE SAVED IS');
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070070
Jeff Thompson3d2393f2012-11-11 19:11:51 -080071 if(LOG>4)console.log(hSig);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070072
Jeff Thompson3d2393f2012-11-11 19:11:51 -080073 if(LOG>4)console.log( DataUtils.toNumbers(hSig.trim()));
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070074
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070075 this.signature.signature = DataUtils.toNumbers(hSig.trim());
Meki Cherkaoui8f173612012-06-06 01:05:40 -070076
77
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070078};
79
80ContentObject.prototype.encodeObject = function encodeObject(obj){
81 var enc = new BinaryXMLEncoder();
82
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070083 obj.to_ccnb(enc);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070084
85 var num = enc.getReducedOstream();
86
87 return num;
88
89
90};
91
92ContentObject.prototype.encodeContent = function encodeContent(obj){
93 var enc = new BinaryXMLEncoder();
94
Jeff Thompson86aea882012-09-29 17:32:48 -070095 enc.writeElement(CCNProtocolDTags.Content, this.content);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070096
97 var num = enc.getReducedOstream();
98
99 return num;
100
101
102};
103
104ContentObject.prototype.saveRawData = function(bytes){
105
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800106 var sigBits = bytes.subarray(this.startSIG, this.endSIG);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700107
108 this.rawSignatureData = sigBits;
109};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700110
Jeff Thompson86aea882012-09-29 17:32:48 -0700111ContentObject.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700112
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700113 // TODO VALIDATE THAT ALL FIELDS EXCEPT SIGNATURE ARE PRESENT
114
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700115 decoder.readStartElement(this.getElementLabel());
116
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700117
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700118 if( decoder.peekStartElement(CCNProtocolDTags.Signature) ){
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700119 this.signature = new Signature();
120 this.signature.from_ccnb(decoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700121 }
122
Jeff Thompson86aea882012-09-29 17:32:48 -0700123 //this.endSIG = decoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700124
Jeff Thompson86aea882012-09-29 17:32:48 -0700125 this.startSIG = decoder.offset;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700126
Jeff Thompsonf3bd3592012-09-29 23:25:30 -0700127 this.name = new Name();
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700128 this.name.from_ccnb(decoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700129
Jeff Thompson86aea882012-09-29 17:32:48 -0700130 //this.startSignedInfo = decoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700131
132
133 if( decoder.peekStartElement(CCNProtocolDTags.SignedInfo) ){
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700134 this.signedInfo = new SignedInfo();
135 this.signedInfo.from_ccnb(decoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700136 }
137
Jeff Thompson86aea882012-09-29 17:32:48 -0700138 this.content = decoder.readBinaryElement(CCNProtocolDTags.Content);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700139
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700140
Jeff Thompson86aea882012-09-29 17:32:48 -0700141 //this.endContent = decoder.offset;
142 this.endSIG = decoder.offset;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700143
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700144
145 decoder.readEndElement();
146
147 this.saveRawData(decoder.istream);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700148};
149
Jeff Thompson86aea882012-09-29 17:32:48 -0700150ContentObject.prototype.to_ccnb = function(/*XMLEncoder*/ encoder) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700151
Jeff Thompson86aea882012-09-29 17:32:48 -0700152 //TODO verify name, SignedInfo and Signature is present
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700153
154
155 encoder.writeStartElement(this.getElementLabel());
156
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700157
158
159
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700160 if(null!=this.signature) this.signature.to_ccnb(encoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700161
162
Jeff Thompson86aea882012-09-29 17:32:48 -0700163 this.startSIG = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700164
165
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700166 if(null!=this.name) this.name.to_ccnb(encoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700167
Jeff Thompson86aea882012-09-29 17:32:48 -0700168 //this.endSIG = encoder.offset;
169 //this.startSignedInfo = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700170
171
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700172 if(null!=this.signedInfo) this.signedInfo.to_ccnb(encoder);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700173
Jeff Thompson86aea882012-09-29 17:32:48 -0700174 encoder.writeElement(CCNProtocolDTags.Content, this.content);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700175
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700176
Jeff Thompson86aea882012-09-29 17:32:48 -0700177 this.endSIG = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700178
Jeff Thompson86aea882012-09-29 17:32:48 -0700179 //this.endContent = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700180
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700181
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700182 encoder.writeEndElement();
183
184 this.saveRawData(encoder.ostream);
185
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700186};
187
188ContentObject.prototype.getElementLabel= function(){return CCNProtocolDTags.ContentObject;};
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700189
190/**
191 * Signature
192 */
193var Signature = function Signature(_witness,_signature,_digestAlgorithm) {
194
195 this.Witness = _witness;//byte [] _witness;
196 this.signature = _signature;//byte [] _signature;
197 this.digestAlgorithm = _digestAlgorithm//String _digestAlgorithm;
198};
199
200var generateSignature = function(contentName,content,signedinfo){
201
202 var enc = new BinaryXMLEncoder();
203 contentName.to_ccnb(enc);
204 var hex1 = toHex(enc.getReducedOstream());
205
206 var enc = new BinaryXMLEncoder();
207 content.to_ccnb(enc);
208 var hex2 = toHex(enc.getReducedOstream());
209
210 var enc = new BinaryXMLEncoder();
211 signedinfo.to_ccnb(enc);
212 var hex3 = toHex(enc.getReducedOstream());
213
214 var hex = hex1+hex2+hex3;
215
216 //globalKeyManager.sig
217
218};
219
220Signature.prototype.from_ccnb =function( decoder) {
221 decoder.readStartElement(this.getElementLabel());
222
223 if(LOG>4)console.log('STARTED DECODING SIGNATURE ');
224
225 if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
226
227 if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
228 this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm);
229 }
230 if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
231 if(LOG>4)console.log('WITNESS FOUND FOUND');
232 this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness);
233 }
234
235 //FORCE TO READ A SIGNATURE
236
237 //if(LOG>4)console.log('SIGNATURE FOUND ');
238 this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);
239 if(LOG>4)console.log('READ SIGNATURE ');
240
241 decoder.readEndElement();
242
243};
244
245
246Signature.prototype.to_ccnb= function( encoder){
247
248 if (!this.validate()) {
249 throw new Error("Cannot encode: field values missing.");
250 }
251
252 encoder.writeStartElement(this.getElementLabel());
253
254 if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
255 encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
256 }
257
258 if (null != this.Witness) {
259 // needs to handle null witness
260 encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
261 }
262
263 encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
264
265 encoder.writeEndElement();
266};
267
268Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
269
270
271Signature.prototype.validate = function() {
272 return null != this.signature;
273};
274
275
276/**
277 * SignedInfo
278 */
279var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
280var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
281var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
282
283var SignedInfo = function SignedInfo(_publisher,_timestamp,_type,_locator,_freshnessSeconds,_finalBlockID){
284
285 //TODO, Check types
286
287 this.publisher = _publisher; //publisherPublicKeyDigest
288 this.timestamp=_timestamp; // CCN Time
289 this.type=_type; // ContentType
290 this.locator =_locator;//KeyLocator
291 this.freshnessSeconds =_freshnessSeconds; // Integer
292 this.finalBlockID=_finalBlockID; //byte array
293
294};
295
296SignedInfo.prototype.setFields = function(){
297 //BASE64 -> RAW STRING
298
299 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
300
301 var publicKeyHex = globalKeyManager.publicKey;
302
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800303 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
304 if(LOG>4)console.log(publicKeyHex);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700305
306 var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ;
307
308
309
310 //var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
311
312 //if(LOG>3)console.log('string Certificate is '+stringCertificate);
313
314 //HEX -> BYTE ARRAY
315 //var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
316
317 //if(LOG>3)console.log('publisher key is ');
318 //if(LOG>3)console.log(publisherkey);
319
320 var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
321
322 this.publisher = new PublisherPublicKeyDigest( DataUtils.toNumbers( publisherKeyDigest ) );
323
324 //this.publisher = new PublisherPublicKeyDigest(publisherkey);
325
326 var d = new Date();
327
328 var time = d.getTime();
329
330
331 this.timestamp = new CCNTime( time );
332
333 if(LOG>4)console.log('TIME msec is');
334
335 if(LOG>4)console.log(this.timestamp.msec);
336
337 //DATA
338 this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
339
340 //if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
341
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800342 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
343 if(LOG>4)console.log(publicKeyBytes);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700344
345 this.locator = new KeyLocator( publicKeyBytes ,KeyLocatorType.KEY );
346
347 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
348
349};
350
351SignedInfo.prototype.from_ccnb = function( decoder){
352
353 decoder.readStartElement( this.getElementLabel() );
354
355 if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
356 if(LOG>3) console.log('DECODING PUBLISHER KEY');
357 this.publisher = new PublisherPublicKeyDigest();
358 this.publisher.from_ccnb(decoder);
359 }
360
361 if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
362 this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
363 if(LOG>4)console.log('TIMESTAMP FOUND IS '+this.timestamp);
364
365 }
366
367 if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
368 binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte []
369
370
371 //TODO Implement type of Key Reading
372
373 if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
374
375 this.type = binType;
376
377
378 //TODO Implement type of Key Reading
379
380
381 if (null == this.type) {
382 throw new Error("Cannot parse signedInfo type: bytes.");
383 }
384
385 } else {
386 this.type = ContentType.DATA; // default
387 }
388
389 if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
390 this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
391 if(LOG>4) console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
392 }
393
394 if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
395 this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
396 }
397
398 if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
399 this.locator = new KeyLocator();
400 this.locator.from_ccnb(decoder);
401 }
402
403 decoder.readEndElement();
404};
405
406SignedInfo.prototype.to_ccnb = function( encoder) {
407 if (!this.validate()) {
408 throw new Error("Cannot encode : field values missing.");
409 }
410 encoder.writeStartElement(this.getElementLabel());
411
412 if (null!=this.publisher) {
413 if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
414
415 this.publisher.to_ccnb(encoder);
416 }
417
418 if (null!=this.timestamp) {
419 encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
420 }
421
422 if (null!=this.type && this.type !=0) {
423
424 encoder.writeElement(CCNProtocolDTags.type, this.type);
425 }
426
427 if (null!=this.freshnessSeconds) {
428 encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
429 }
430
431 if (null!=this.finalBlockID) {
432 encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
433 }
434
435 if (null!=this.locator) {
436 this.locator.to_ccnb(encoder);
437 }
438
439 encoder.writeEndElement();
440};
441
442SignedInfo.prototype.valueToType = function(){
443 //for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
444 //if (Arrays.equals(value, entry.getKey()))
445 //return entry.getValue();
446 //}
447 return null;
448
449};
450
451SignedInfo.prototype.getElementLabel = function() {
452 return CCNProtocolDTags.SignedInfo;
453};
454
455SignedInfo.prototype.validate = function() {
456 // We don't do partial matches any more, even though encoder/decoder
457 // is still pretty generous.
458 if (null ==this.publisher || null==this.timestamp ||null== this.locator)
459 return false;
460 return true;
461};