blob: 9567e44c4de417248214f54ec50ba72021fade8e [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 */
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
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700200Signature.prototype.from_ccnb =function( decoder) {
201 decoder.readStartElement(this.getElementLabel());
202
203 if(LOG>4)console.log('STARTED DECODING SIGNATURE ');
204
205 if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
206
207 if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
208 this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm);
209 }
210 if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
211 if(LOG>4)console.log('WITNESS FOUND FOUND');
212 this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness);
213 }
214
215 //FORCE TO READ A SIGNATURE
216
217 //if(LOG>4)console.log('SIGNATURE FOUND ');
218 this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);
219 if(LOG>4)console.log('READ SIGNATURE ');
220
221 decoder.readEndElement();
222
223};
224
225
226Signature.prototype.to_ccnb= function( encoder){
227
228 if (!this.validate()) {
229 throw new Error("Cannot encode: field values missing.");
230 }
231
232 encoder.writeStartElement(this.getElementLabel());
233
234 if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
235 encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
236 }
237
238 if (null != this.Witness) {
239 // needs to handle null witness
240 encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
241 }
242
243 encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
244
245 encoder.writeEndElement();
246};
247
248Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
249
250
251Signature.prototype.validate = function() {
252 return null != this.signature;
253};
254
255
256/**
257 * SignedInfo
258 */
259var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
260var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
261var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
262
263var SignedInfo = function SignedInfo(_publisher,_timestamp,_type,_locator,_freshnessSeconds,_finalBlockID){
264
265 //TODO, Check types
266
267 this.publisher = _publisher; //publisherPublicKeyDigest
268 this.timestamp=_timestamp; // CCN Time
269 this.type=_type; // ContentType
270 this.locator =_locator;//KeyLocator
271 this.freshnessSeconds =_freshnessSeconds; // Integer
272 this.finalBlockID=_finalBlockID; //byte array
273
274};
275
276SignedInfo.prototype.setFields = function(){
277 //BASE64 -> RAW STRING
278
279 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
280
281 var publicKeyHex = globalKeyManager.publicKey;
282
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800283 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
284 if(LOG>4)console.log(publicKeyHex);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700285
286 var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ;
287
288
289
290 //var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
291
292 //if(LOG>3)console.log('string Certificate is '+stringCertificate);
293
294 //HEX -> BYTE ARRAY
295 //var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
296
297 //if(LOG>3)console.log('publisher key is ');
298 //if(LOG>3)console.log(publisherkey);
299
300 var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
301
302 this.publisher = new PublisherPublicKeyDigest( DataUtils.toNumbers( publisherKeyDigest ) );
303
304 //this.publisher = new PublisherPublicKeyDigest(publisherkey);
305
306 var d = new Date();
307
308 var time = d.getTime();
309
310
311 this.timestamp = new CCNTime( time );
312
313 if(LOG>4)console.log('TIME msec is');
314
315 if(LOG>4)console.log(this.timestamp.msec);
316
317 //DATA
318 this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
319
320 //if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
321
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800322 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
323 if(LOG>4)console.log(publicKeyBytes);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700324
325 this.locator = new KeyLocator( publicKeyBytes ,KeyLocatorType.KEY );
326
327 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
328
329};
330
331SignedInfo.prototype.from_ccnb = function( decoder){
332
333 decoder.readStartElement( this.getElementLabel() );
334
335 if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
336 if(LOG>3) console.log('DECODING PUBLISHER KEY');
337 this.publisher = new PublisherPublicKeyDigest();
338 this.publisher.from_ccnb(decoder);
339 }
340
341 if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
342 this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
343 if(LOG>4)console.log('TIMESTAMP FOUND IS '+this.timestamp);
344
345 }
346
347 if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
348 binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte []
349
350
351 //TODO Implement type of Key Reading
352
353 if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
354
355 this.type = binType;
356
357
358 //TODO Implement type of Key Reading
359
360
361 if (null == this.type) {
362 throw new Error("Cannot parse signedInfo type: bytes.");
363 }
364
365 } else {
366 this.type = ContentType.DATA; // default
367 }
368
369 if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
370 this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
371 if(LOG>4) console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
372 }
373
374 if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
375 this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
376 }
377
378 if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
379 this.locator = new KeyLocator();
380 this.locator.from_ccnb(decoder);
381 }
382
383 decoder.readEndElement();
384};
385
386SignedInfo.prototype.to_ccnb = function( encoder) {
387 if (!this.validate()) {
388 throw new Error("Cannot encode : field values missing.");
389 }
390 encoder.writeStartElement(this.getElementLabel());
391
392 if (null!=this.publisher) {
393 if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
394
395 this.publisher.to_ccnb(encoder);
396 }
397
398 if (null!=this.timestamp) {
399 encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
400 }
401
402 if (null!=this.type && this.type !=0) {
403
404 encoder.writeElement(CCNProtocolDTags.type, this.type);
405 }
406
407 if (null!=this.freshnessSeconds) {
408 encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
409 }
410
411 if (null!=this.finalBlockID) {
412 encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
413 }
414
415 if (null!=this.locator) {
416 this.locator.to_ccnb(encoder);
417 }
418
419 encoder.writeEndElement();
420};
421
422SignedInfo.prototype.valueToType = function(){
423 //for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
424 //if (Arrays.equals(value, entry.getKey()))
425 //return entry.getValue();
426 //}
427 return null;
428
429};
430
431SignedInfo.prototype.getElementLabel = function() {
432 return CCNProtocolDTags.SignedInfo;
433};
434
435SignedInfo.prototype.validate = function() {
436 // We don't do partial matches any more, even though encoder/decoder
437 // is still pretty generous.
438 if (null ==this.publisher || null==this.timestamp ||null== this.locator)
439 return false;
440 return true;
441};