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