blob: ca6a819a0bfa87ba424a3636fd1d23e8bb26acf9 [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
Wentao Shangab9018d2012-12-18 11:35:45 -08009 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;
Wentao Shangab9018d2012-12-18 11:35:45 -080017
18 if (typeof _content == 'string') {
19 this.content = DataUtils.toNumbersFromString(_content);
20 } else {
21 this.content = _content;
22 }
23
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070024 this.signature = _signature;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070025
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070026
Jeff Thompson86aea882012-09-29 17:32:48 -070027 this.startSIG = null;
28 this.endSIG = null;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070029
Wentao Shangfddf90d2013-01-05 17:18:49 -080030 //this.startSignedInfo = null;
Jeff Thompson86aea882012-09-29 17:32:48 -070031 this.endContent = null;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070032
33 this.rawSignatureData = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070034};
35
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070036ContentObject.prototype.sign = function(){
Meki Cherkaoui8f173612012-06-06 01:05:40 -070037
Jeff Thompson86aea882012-09-29 17:32:48 -070038 var n1 = this.encodeObject(this.name);
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070039 var n2 = this.encodeObject(this.signedInfo);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070040 var n3 = this.encodeContent();
Jeff Thompson3d2393f2012-11-11 19:11:51 -080041 /*console.log('sign: ');
42 console.log(n1);
43 console.log(n2);
44 console.log(n3);*/
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070045
Jeff Thompson3d2393f2012-11-11 19:11:51 -080046 //var n = n1.concat(n2,n3);
47 var tempBuf = new ArrayBuffer(n1.length + n2.length + n3.length);
48 var n = new Uint8Array(tempBuf);
49 //console.log(n);
50 n.set(n1, 0);
51 //console.log(n);
52 n.set(n2, n1.length);
53 //console.log(n);
54 n.set(n3, n1.length + n2.length);
55 //console.log(n);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070056
Jeff Thompson3d2393f2012-11-11 19:11:51 -080057 if(LOG>4)console.log('Signature Data is (binary) '+n);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070058
Jeff Thompson3d2393f2012-11-11 19:11:51 -080059 if(LOG>4)console.log('Signature Data is (RawString)');
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070060
Jeff Thompson3d2393f2012-11-11 19:11:51 -080061 if(LOG>4)console.log( DataUtils.toString(n) );
Meki Cherkaoui8f173612012-06-06 01:05:40 -070062
Jeff Thompson3d2393f2012-11-11 19:11:51 -080063 //var sig = DataUtils.toString(n);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070064
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070065
66 var rsa = new RSAKey();
67
68 rsa.readPrivateKeyFromPEMString(globalKeyManager.privateKey);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070069
70 //var hSig = rsa.signString(sig, "sha256");
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070071
Meki Cherkaoui8f173612012-06-06 01:05:40 -070072 var hSig = rsa.signByteArrayWithSHA256(n);
73
74
Jeff Thompson3d2393f2012-11-11 19:11:51 -080075 if(LOG>4)console.log('SIGNATURE SAVED IS');
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070076
Jeff Thompson3d2393f2012-11-11 19:11:51 -080077 if(LOG>4)console.log(hSig);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070078
Jeff Thompson3d2393f2012-11-11 19:11:51 -080079 if(LOG>4)console.log( DataUtils.toNumbers(hSig.trim()));
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070080
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070081 this.signature.signature = DataUtils.toNumbers(hSig.trim());
Meki Cherkaoui8f173612012-06-06 01:05:40 -070082
83
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070084};
85
86ContentObject.prototype.encodeObject = function encodeObject(obj){
87 var enc = new BinaryXMLEncoder();
88
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070089 obj.to_ccnb(enc);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070090
91 var num = enc.getReducedOstream();
92
93 return num;
94
95
96};
97
98ContentObject.prototype.encodeContent = function encodeContent(obj){
99 var enc = new BinaryXMLEncoder();
100
Jeff Thompson86aea882012-09-29 17:32:48 -0700101 enc.writeElement(CCNProtocolDTags.Content, this.content);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700102
103 var num = enc.getReducedOstream();
104
105 return num;
106
107
108};
109
110ContentObject.prototype.saveRawData = function(bytes){
111
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800112 var sigBits = bytes.subarray(this.startSIG, this.endSIG);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700113
114 this.rawSignatureData = sigBits;
115};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700116
Jeff Thompson86aea882012-09-29 17:32:48 -0700117ContentObject.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700118
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700119 // TODO VALIDATE THAT ALL FIELDS EXCEPT SIGNATURE ARE PRESENT
120
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700121 decoder.readStartElement(this.getElementLabel());
122
Meki Cherkaoui8f173612012-06-06 01:05:40 -0700123
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700124 if( decoder.peekStartElement(CCNProtocolDTags.Signature) ){
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700125 this.signature = new Signature();
126 this.signature.from_ccnb(decoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700127 }
128
Jeff Thompson86aea882012-09-29 17:32:48 -0700129 //this.endSIG = decoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700130
Jeff Thompson86aea882012-09-29 17:32:48 -0700131 this.startSIG = decoder.offset;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700132
Jeff Thompsonf3bd3592012-09-29 23:25:30 -0700133 this.name = new Name();
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700134 this.name.from_ccnb(decoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700135
Jeff Thompson86aea882012-09-29 17:32:48 -0700136 //this.startSignedInfo = decoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700137
138
139 if( decoder.peekStartElement(CCNProtocolDTags.SignedInfo) ){
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700140 this.signedInfo = new SignedInfo();
141 this.signedInfo.from_ccnb(decoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700142 }
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700143
Jeff Thompsond4a1f862013-03-10 17:30:31 -0700144 this.content = decoder.readBinaryElement(CCNProtocolDTags.Content, null, true);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700145
Jeff Thompson86aea882012-09-29 17:32:48 -0700146 this.endSIG = decoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700147
148 decoder.readEndElement();
149
150 this.saveRawData(decoder.istream);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700151};
152
Jeff Thompson86aea882012-09-29 17:32:48 -0700153ContentObject.prototype.to_ccnb = function(/*XMLEncoder*/ encoder) {
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700154
Jeff Thompson86aea882012-09-29 17:32:48 -0700155 //TODO verify name, SignedInfo and Signature is present
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700156
157
158 encoder.writeStartElement(this.getElementLabel());
159
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700160
161
162
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700163 if(null!=this.signature) this.signature.to_ccnb(encoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700164
165
Jeff Thompson86aea882012-09-29 17:32:48 -0700166 this.startSIG = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700167
168
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700169 if(null!=this.name) this.name.to_ccnb(encoder);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700170
Jeff Thompson86aea882012-09-29 17:32:48 -0700171 //this.endSIG = encoder.offset;
172 //this.startSignedInfo = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700173
174
Jeff Thompsone85ff1d2012-09-29 21:21:57 -0700175 if(null!=this.signedInfo) this.signedInfo.to_ccnb(encoder);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700176
Jeff Thompson86aea882012-09-29 17:32:48 -0700177 encoder.writeElement(CCNProtocolDTags.Content, this.content);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700178
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700179
Jeff Thompson86aea882012-09-29 17:32:48 -0700180 this.endSIG = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700181
Jeff Thompson86aea882012-09-29 17:32:48 -0700182 //this.endContent = encoder.offset;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700183
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700184
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700185 encoder.writeEndElement();
186
187 this.saveRawData(encoder.ostream);
188
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700189};
190
191ContentObject.prototype.getElementLabel= function(){return CCNProtocolDTags.ContentObject;};
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700192
193/**
194 * Signature
195 */
196var Signature = function Signature(_witness,_signature,_digestAlgorithm) {
197
198 this.Witness = _witness;//byte [] _witness;
199 this.signature = _signature;//byte [] _signature;
200 this.digestAlgorithm = _digestAlgorithm//String _digestAlgorithm;
201};
202
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700203Signature.prototype.from_ccnb =function( decoder) {
204 decoder.readStartElement(this.getElementLabel());
205
Wentao Shang882e34e2013-01-05 02:49:51 -0800206 if(LOG>4)console.log('STARTED DECODING SIGNATURE');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700207
208 if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700209 if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
210 this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm);
211 }
212 if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800213 if(LOG>4)console.log('WITNESS FOUND');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700214 this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness);
215 }
216
217 //FORCE TO READ A SIGNATURE
218
Wentao Shang882e34e2013-01-05 02:49:51 -0800219 if(LOG>4)console.log('SIGNATURE FOUND');
220 this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700221
222 decoder.readEndElement();
223
224};
225
226
227Signature.prototype.to_ccnb= function( encoder){
228
229 if (!this.validate()) {
230 throw new Error("Cannot encode: field values missing.");
231 }
232
233 encoder.writeStartElement(this.getElementLabel());
234
235 if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
236 encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
237 }
238
239 if (null != this.Witness) {
240 // needs to handle null witness
241 encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
242 }
243
244 encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
245
246 encoder.writeEndElement();
247};
248
249Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
250
251
252Signature.prototype.validate = function() {
253 return null != this.signature;
254};
255
256
257/**
258 * SignedInfo
259 */
260var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
261var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
262var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
263
264var SignedInfo = function SignedInfo(_publisher,_timestamp,_type,_locator,_freshnessSeconds,_finalBlockID){
265
266 //TODO, Check types
267
268 this.publisher = _publisher; //publisherPublicKeyDigest
269 this.timestamp=_timestamp; // CCN Time
270 this.type=_type; // ContentType
271 this.locator =_locator;//KeyLocator
272 this.freshnessSeconds =_freshnessSeconds; // Integer
273 this.finalBlockID=_finalBlockID; //byte array
Wentao Shangab9018d2012-12-18 11:35:45 -0800274
275 // SWT: merge setFields() method into constructor
276 this.setFields();
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700277
278};
279
280SignedInfo.prototype.setFields = function(){
281 //BASE64 -> RAW STRING
282
283 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
284
285 var publicKeyHex = globalKeyManager.publicKey;
286
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800287 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
288 if(LOG>4)console.log(publicKeyHex);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700289
290 var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ;
291
292
293
294 //var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
295
296 //if(LOG>3)console.log('string Certificate is '+stringCertificate);
297
298 //HEX -> BYTE ARRAY
299 //var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
300
301 //if(LOG>3)console.log('publisher key is ');
302 //if(LOG>3)console.log(publisherkey);
303
304 var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
305
306 this.publisher = new PublisherPublicKeyDigest( DataUtils.toNumbers( publisherKeyDigest ) );
307
308 //this.publisher = new PublisherPublicKeyDigest(publisherkey);
309
310 var d = new Date();
311
312 var time = d.getTime();
313
314
315 this.timestamp = new CCNTime( time );
316
317 if(LOG>4)console.log('TIME msec is');
318
319 if(LOG>4)console.log(this.timestamp.msec);
320
321 //DATA
322 this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
323
324 //if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
325
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800326 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
327 if(LOG>4)console.log(publicKeyBytes);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700328
329 this.locator = new KeyLocator( publicKeyBytes ,KeyLocatorType.KEY );
330
331 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
332
333};
334
335SignedInfo.prototype.from_ccnb = function( decoder){
336
337 decoder.readStartElement( this.getElementLabel() );
338
339 if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800340 if(LOG>4)console.log('DECODING PUBLISHER KEY');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700341 this.publisher = new PublisherPublicKeyDigest();
342 this.publisher.from_ccnb(decoder);
343 }
344
345 if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800346 if(LOG>4)console.log('DECODING TIMESTAMP');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700347 this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700348 }
349
350 if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
Jeff Thompson48ff28a2013-02-18 22:53:29 -0800351 var binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte []
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700352
353
354 //TODO Implement type of Key Reading
355
356 if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
357
358 this.type = binType;
359
360
361 //TODO Implement type of Key Reading
362
363
364 if (null == this.type) {
365 throw new Error("Cannot parse signedInfo type: bytes.");
366 }
367
368 } else {
369 this.type = ContentType.DATA; // default
370 }
371
372 if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
373 this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
Wentao Shang882e34e2013-01-05 02:49:51 -0800374 if(LOG>4)console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700375 }
376
377 if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800378 if(LOG>4)console.log('DECODING FINAL BLOCKID');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700379 this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
380 }
381
382 if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800383 if(LOG>4)console.log('DECODING KEY LOCATOR');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700384 this.locator = new KeyLocator();
385 this.locator.from_ccnb(decoder);
386 }
387
388 decoder.readEndElement();
389};
390
391SignedInfo.prototype.to_ccnb = function( encoder) {
392 if (!this.validate()) {
393 throw new Error("Cannot encode : field values missing.");
394 }
395 encoder.writeStartElement(this.getElementLabel());
396
397 if (null!=this.publisher) {
398 if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
399
400 this.publisher.to_ccnb(encoder);
401 }
402
403 if (null!=this.timestamp) {
404 encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
405 }
406
407 if (null!=this.type && this.type !=0) {
408
409 encoder.writeElement(CCNProtocolDTags.type, this.type);
410 }
411
412 if (null!=this.freshnessSeconds) {
413 encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
414 }
415
416 if (null!=this.finalBlockID) {
417 encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
418 }
419
420 if (null!=this.locator) {
421 this.locator.to_ccnb(encoder);
422 }
423
424 encoder.writeEndElement();
425};
426
427SignedInfo.prototype.valueToType = function(){
428 //for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
429 //if (Arrays.equals(value, entry.getKey()))
430 //return entry.getValue();
431 //}
432 return null;
433
434};
435
436SignedInfo.prototype.getElementLabel = function() {
437 return CCNProtocolDTags.SignedInfo;
438};
439
440SignedInfo.prototype.validate = function() {
441 // We don't do partial matches any more, even though encoder/decoder
442 // is still pretty generous.
443 if (null ==this.publisher || null==this.timestamp ||null== this.locator)
444 return false;
445 return true;
446};