blob: 38c80661e985c232a5a92094bb2f5f06708278a3 [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 */
Meki Cherkaouif441d3a2012-04-22 15:17:52 -07006
Jeff Thompson2b14c7e2013-07-29 15:09:56 -07007/**
8 * Create a new ContentObject with the optional values.
9 *
10 * @constructor
11 * @param {Name} name
12 * @param {SignedInfo} signedInfo
13 * @param {Uint8Array} content
14 * @param {Signature} signature
15 */
16var ContentObject = function ContentObject(name, signedInfo, content, signature) {
17 if (typeof name == 'string')
18 this.name = new Name(name);
19 else
20 //TODO Check the class of name
21 this.name = name;
22
23 this.signedInfo = signedInfo;
24
25 if (typeof content == 'string')
26 this.content = DataUtils.toNumbersFromString(content);
27 else
28 this.content = content;
29
30 this.signature = signature;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070031
Jeff Thompson86aea882012-09-29 17:32:48 -070032 this.startSIG = null;
33 this.endSIG = null;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070034
Jeff Thompson86aea882012-09-29 17:32:48 -070035 this.endContent = null;
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070036
37 this.rawSignatureData = null;
Meki Cherkaouif441d3a2012-04-22 15:17:52 -070038};
39
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070040ContentObject.prototype.sign = function(){
Meki Cherkaoui8f173612012-06-06 01:05:40 -070041
Jeff Thompson86aea882012-09-29 17:32:48 -070042 var n1 = this.encodeObject(this.name);
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070043 var n2 = this.encodeObject(this.signedInfo);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070044 var n3 = this.encodeContent();
Jeff Thompson3d2393f2012-11-11 19:11:51 -080045 /*console.log('sign: ');
46 console.log(n1);
47 console.log(n2);
48 console.log(n3);*/
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070049
Jeff Thompson3d2393f2012-11-11 19:11:51 -080050 //var n = n1.concat(n2,n3);
51 var tempBuf = new ArrayBuffer(n1.length + n2.length + n3.length);
52 var n = new Uint8Array(tempBuf);
53 //console.log(n);
54 n.set(n1, 0);
55 //console.log(n);
56 n.set(n2, n1.length);
57 //console.log(n);
58 n.set(n3, n1.length + n2.length);
59 //console.log(n);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070060
Jeff Thompson3d2393f2012-11-11 19:11:51 -080061 if(LOG>4)console.log('Signature Data is (binary) '+n);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070062
Jeff Thompson3d2393f2012-11-11 19:11:51 -080063 if(LOG>4)console.log('Signature Data is (RawString)');
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070064
Jeff Thompson3d2393f2012-11-11 19:11:51 -080065 if(LOG>4)console.log( DataUtils.toString(n) );
Meki Cherkaoui8f173612012-06-06 01:05:40 -070066
Jeff Thompson3d2393f2012-11-11 19:11:51 -080067 //var sig = DataUtils.toString(n);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070068
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070069
70 var rsa = new RSAKey();
71
72 rsa.readPrivateKeyFromPEMString(globalKeyManager.privateKey);
Meki Cherkaoui8f173612012-06-06 01:05:40 -070073
74 //var hSig = rsa.signString(sig, "sha256");
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070075
Meki Cherkaoui8f173612012-06-06 01:05:40 -070076 var hSig = rsa.signByteArrayWithSHA256(n);
77
78
Jeff Thompson3d2393f2012-11-11 19:11:51 -080079 if(LOG>4)console.log('SIGNATURE SAVED IS');
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070080
Jeff Thompson3d2393f2012-11-11 19:11:51 -080081 if(LOG>4)console.log(hSig);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070082
Jeff Thompson3d2393f2012-11-11 19:11:51 -080083 if(LOG>4)console.log( DataUtils.toNumbers(hSig.trim()));
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070084
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070085 this.signature.signature = DataUtils.toNumbers(hSig.trim());
Meki Cherkaoui8f173612012-06-06 01:05:40 -070086
87
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070088};
89
90ContentObject.prototype.encodeObject = function encodeObject(obj){
91 var enc = new BinaryXMLEncoder();
92
Jeff Thompsone85ff1d2012-09-29 21:21:57 -070093 obj.to_ccnb(enc);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -070094
95 var num = enc.getReducedOstream();
96
97 return num;
98
99
100};
101
102ContentObject.prototype.encodeContent = function encodeContent(obj){
103 var enc = new BinaryXMLEncoder();
104
Jeff Thompson86aea882012-09-29 17:32:48 -0700105 enc.writeElement(CCNProtocolDTags.Content, this.content);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700106
107 var num = enc.getReducedOstream();
108
109 return num;
110
111
112};
113
114ContentObject.prototype.saveRawData = function(bytes){
115
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800116 var sigBits = bytes.subarray(this.startSIG, this.endSIG);
Meki Cherkaouif3d8f692012-05-18 15:44:28 -0700117
118 this.rawSignatureData = sigBits;
119};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700120
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700121/**
122 * @deprecated Use BinaryXMLWireFormat.decodeContentObject.
123 */
Jeff Thompson86aea882012-09-29 17:32:48 -0700124ContentObject.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
Jeff Thompson86bcd022013-07-26 17:55:03 -0700125 BinaryXMLWireFormat.decodeContentObject(this, decoder);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700126};
127
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700128/**
129 * @deprecated Use BinaryXMLWireFormat.encodeContentObject.
130 */
Jeff Thompson86aea882012-09-29 17:32:48 -0700131ContentObject.prototype.to_ccnb = function(/*XMLEncoder*/ encoder) {
Jeff Thompson86bcd022013-07-26 17:55:03 -0700132 BinaryXMLWireFormat.encodeContentObject(this, encoder);
133};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700134
Jeff Thompson86bcd022013-07-26 17:55:03 -0700135/**
136 * Encode this ContentObject for a particular wire format.
137 * @param {WireFormat} wireFormat if null, use BinaryXMLWireFormat.
138 * @returns {Uint8Array}
139 */
140ContentObject.prototype.encode = function(wireFormat) {
141 wireFormat = (wireFormat || BinaryXMLWireFormat.instance);
142 return wireFormat.encodeContentObject(this);
143};
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700144
Jeff Thompson86bcd022013-07-26 17:55:03 -0700145/**
146 * Decode the input using a particular wire format and update this ContentObject.
147 * @param {Uint8Array} input
148 * @param {WireFormat} wireFormat if null, use BinaryXMLWireFormat.
149 */
150ContentObject.prototype.decode = function(input, wireFormat) {
151 wireFormat = (wireFormat || BinaryXMLWireFormat.instance);
152 wireFormat.decodeContentObject(this, input);
Meki Cherkaouif441d3a2012-04-22 15:17:52 -0700153};
154
155ContentObject.prototype.getElementLabel= function(){return CCNProtocolDTags.ContentObject;};
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700156
157/**
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700158 * Create a new Signature with the optional values.
159 * @constructor
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700160 */
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700161var Signature = function Signature(witness, signature, digestAlgorithm) {
162 this.Witness = witness;
163 this.signature = signature;
164 this.digestAlgorithm = digestAlgorithm
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700165};
166
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700167Signature.prototype.from_ccnb =function( decoder) {
168 decoder.readStartElement(this.getElementLabel());
169
Wentao Shang882e34e2013-01-05 02:49:51 -0800170 if(LOG>4)console.log('STARTED DECODING SIGNATURE');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700171
172 if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700173 if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
174 this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm);
175 }
176 if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800177 if(LOG>4)console.log('WITNESS FOUND');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700178 this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness);
179 }
180
181 //FORCE TO READ A SIGNATURE
182
Wentao Shang882e34e2013-01-05 02:49:51 -0800183 if(LOG>4)console.log('SIGNATURE FOUND');
184 this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700185
186 decoder.readEndElement();
187
188};
189
190
191Signature.prototype.to_ccnb= function( encoder){
192
193 if (!this.validate()) {
194 throw new Error("Cannot encode: field values missing.");
195 }
196
197 encoder.writeStartElement(this.getElementLabel());
198
199 if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
200 encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
201 }
202
203 if (null != this.Witness) {
204 // needs to handle null witness
205 encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
206 }
207
208 encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
209
210 encoder.writeEndElement();
211};
212
213Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
214
215
216Signature.prototype.validate = function() {
217 return null != this.signature;
218};
219
220
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700221var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
222var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
223var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
224
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700225/**
226 * Create a new SignedInfo with the optional values.
227 * @constructor
228 */
229var SignedInfo = function SignedInfo(publisher, timestamp, type, locator, freshnessSeconds, finalBlockID) {
230 this.publisher = publisher; //publisherPublicKeyDigest
231 this.timestamp=timestamp; // CCN Time
232 this.type=type; // ContentType
233 this.locator =locator;//KeyLocator
234 this.freshnessSeconds =freshnessSeconds; // Integer
235 this.finalBlockID=finalBlockID; //byte array
Wentao Shangab9018d2012-12-18 11:35:45 -0800236
Jeff Thompson2b14c7e2013-07-29 15:09:56 -0700237 this.setFields();
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700238};
239
240SignedInfo.prototype.setFields = function(){
241 //BASE64 -> RAW STRING
242
243 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
244
245 var publicKeyHex = globalKeyManager.publicKey;
246
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800247 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
248 if(LOG>4)console.log(publicKeyHex);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700249
250 var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ;
251
252
253
254 //var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
255
256 //if(LOG>3)console.log('string Certificate is '+stringCertificate);
257
258 //HEX -> BYTE ARRAY
259 //var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
260
261 //if(LOG>3)console.log('publisher key is ');
262 //if(LOG>3)console.log(publisherkey);
263
264 var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
265
266 this.publisher = new PublisherPublicKeyDigest( DataUtils.toNumbers( publisherKeyDigest ) );
267
268 //this.publisher = new PublisherPublicKeyDigest(publisherkey);
269
270 var d = new Date();
271
272 var time = d.getTime();
273
274
275 this.timestamp = new CCNTime( time );
276
277 if(LOG>4)console.log('TIME msec is');
278
279 if(LOG>4)console.log(this.timestamp.msec);
280
281 //DATA
282 this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
283
284 //if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
285
Jeff Thompson3d2393f2012-11-11 19:11:51 -0800286 if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
287 if(LOG>4)console.log(publicKeyBytes);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700288
289 this.locator = new KeyLocator( publicKeyBytes ,KeyLocatorType.KEY );
290
291 //this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
292
293};
294
295SignedInfo.prototype.from_ccnb = function( decoder){
296
297 decoder.readStartElement( this.getElementLabel() );
298
299 if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800300 if(LOG>4)console.log('DECODING PUBLISHER KEY');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700301 this.publisher = new PublisherPublicKeyDigest();
302 this.publisher.from_ccnb(decoder);
303 }
304
305 if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800306 if(LOG>4)console.log('DECODING TIMESTAMP');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700307 this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700308 }
309
310 if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
Jeff Thompson48ff28a2013-02-18 22:53:29 -0800311 var binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte []
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700312
313
314 //TODO Implement type of Key Reading
315
316 if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
317
318 this.type = binType;
319
320
321 //TODO Implement type of Key Reading
322
323
324 if (null == this.type) {
325 throw new Error("Cannot parse signedInfo type: bytes.");
326 }
327
328 } else {
329 this.type = ContentType.DATA; // default
330 }
331
332 if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
333 this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
Wentao Shang882e34e2013-01-05 02:49:51 -0800334 if(LOG>4)console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700335 }
336
337 if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800338 if(LOG>4)console.log('DECODING FINAL BLOCKID');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700339 this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
340 }
341
342 if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
Wentao Shang882e34e2013-01-05 02:49:51 -0800343 if(LOG>4)console.log('DECODING KEY LOCATOR');
Jeff Thompsonb9ce4582012-09-30 17:52:51 -0700344 this.locator = new KeyLocator();
345 this.locator.from_ccnb(decoder);
346 }
347
348 decoder.readEndElement();
349};
350
351SignedInfo.prototype.to_ccnb = function( encoder) {
352 if (!this.validate()) {
353 throw new Error("Cannot encode : field values missing.");
354 }
355 encoder.writeStartElement(this.getElementLabel());
356
357 if (null!=this.publisher) {
358 if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
359
360 this.publisher.to_ccnb(encoder);
361 }
362
363 if (null!=this.timestamp) {
364 encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
365 }
366
367 if (null!=this.type && this.type !=0) {
368
369 encoder.writeElement(CCNProtocolDTags.type, this.type);
370 }
371
372 if (null!=this.freshnessSeconds) {
373 encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
374 }
375
376 if (null!=this.finalBlockID) {
377 encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
378 }
379
380 if (null!=this.locator) {
381 this.locator.to_ccnb(encoder);
382 }
383
384 encoder.writeEndElement();
385};
386
387SignedInfo.prototype.valueToType = function(){
388 //for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
389 //if (Arrays.equals(value, entry.getKey()))
390 //return entry.getValue();
391 //}
392 return null;
393
394};
395
396SignedInfo.prototype.getElementLabel = function() {
397 return CCNProtocolDTags.SignedInfo;
398};
399
400SignedInfo.prototype.validate = function() {
401 // We don't do partial matches any more, even though encoder/decoder
402 // is still pretty generous.
403 if (null ==this.publisher || null==this.timestamp ||null== this.locator)
404 return false;
405 return true;
406};