blob: c9662205bf08e247520b1a973c373ed05ae6fa94 [file] [log] [blame]
/**
* @author: Meki Cheraoui
* See COPYING for copyright and distribution information.
* This class represents ContentObject Objects
*/
var ContentObject = function ContentObject(_name,_signedInfo,_content,_signature){
if (typeof _name == 'string') {
this.name = new Name(_name);
}
else{
//TODO Check the class of _name
this.name = _name;
}
this.signedInfo = _signedInfo;
if (typeof _content == 'string') {
this.content = DataUtils.toNumbersFromString(_content);
} else {
this.content = _content;
}
this.signature = _signature;
this.startSIG = null;
this.endSIG = null;
this.startSignedInfo = null;
this.endContent = null;
this.rawSignatureData = null;
};
ContentObject.prototype.sign = function(){
var n1 = this.encodeObject(this.name);
var n2 = this.encodeObject(this.signedInfo);
var n3 = this.encodeContent();
/*console.log('sign: ');
console.log(n1);
console.log(n2);
console.log(n3);*/
//var n = n1.concat(n2,n3);
var tempBuf = new ArrayBuffer(n1.length + n2.length + n3.length);
var n = new Uint8Array(tempBuf);
//console.log(n);
n.set(n1, 0);
//console.log(n);
n.set(n2, n1.length);
//console.log(n);
n.set(n3, n1.length + n2.length);
//console.log(n);
if(LOG>4)console.log('Signature Data is (binary) '+n);
if(LOG>4)console.log('Signature Data is (RawString)');
if(LOG>4)console.log( DataUtils.toString(n) );
//var sig = DataUtils.toString(n);
var rsa = new RSAKey();
rsa.readPrivateKeyFromPEMString(globalKeyManager.privateKey);
//var hSig = rsa.signString(sig, "sha256");
var hSig = rsa.signByteArrayWithSHA256(n);
if(LOG>4)console.log('SIGNATURE SAVED IS');
if(LOG>4)console.log(hSig);
if(LOG>4)console.log( DataUtils.toNumbers(hSig.trim()));
this.signature.signature = DataUtils.toNumbers(hSig.trim());
};
ContentObject.prototype.encodeObject = function encodeObject(obj){
var enc = new BinaryXMLEncoder();
obj.to_ccnb(enc);
var num = enc.getReducedOstream();
return num;
};
ContentObject.prototype.encodeContent = function encodeContent(obj){
var enc = new BinaryXMLEncoder();
enc.writeElement(CCNProtocolDTags.Content, this.content);
var num = enc.getReducedOstream();
return num;
};
ContentObject.prototype.saveRawData = function(bytes){
var sigBits = bytes.subarray(this.startSIG, this.endSIG);
this.rawSignatureData = sigBits;
};
ContentObject.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
// TODO VALIDATE THAT ALL FIELDS EXCEPT SIGNATURE ARE PRESENT
decoder.readStartElement(this.getElementLabel());
if( decoder.peekStartElement(CCNProtocolDTags.Signature) ){
this.signature = new Signature();
this.signature.from_ccnb(decoder);
}
//this.endSIG = decoder.offset;
this.startSIG = decoder.offset;
this.name = new Name();
this.name.from_ccnb(decoder);
//this.startSignedInfo = decoder.offset;
if( decoder.peekStartElement(CCNProtocolDTags.SignedInfo) ){
this.signedInfo = new SignedInfo();
this.signedInfo.from_ccnb(decoder);
}
this.content = decoder.readBinaryElement(CCNProtocolDTags.Content);
//this.endContent = decoder.offset;
this.endSIG = decoder.offset;
decoder.readEndElement();
this.saveRawData(decoder.istream);
};
ContentObject.prototype.to_ccnb = function(/*XMLEncoder*/ encoder) {
//TODO verify name, SignedInfo and Signature is present
encoder.writeStartElement(this.getElementLabel());
if(null!=this.signature) this.signature.to_ccnb(encoder);
this.startSIG = encoder.offset;
if(null!=this.name) this.name.to_ccnb(encoder);
//this.endSIG = encoder.offset;
//this.startSignedInfo = encoder.offset;
if(null!=this.signedInfo) this.signedInfo.to_ccnb(encoder);
encoder.writeElement(CCNProtocolDTags.Content, this.content);
this.endSIG = encoder.offset;
//this.endContent = encoder.offset;
encoder.writeEndElement();
this.saveRawData(encoder.ostream);
};
ContentObject.prototype.getElementLabel= function(){return CCNProtocolDTags.ContentObject;};
/**
* Signature
*/
var Signature = function Signature(_witness,_signature,_digestAlgorithm) {
this.Witness = _witness;//byte [] _witness;
this.signature = _signature;//byte [] _signature;
this.digestAlgorithm = _digestAlgorithm//String _digestAlgorithm;
};
Signature.prototype.from_ccnb =function( decoder) {
decoder.readStartElement(this.getElementLabel());
if(LOG>4)console.log('STARTED DECODING SIGNATURE');
if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm);
}
if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
if(LOG>4)console.log('WITNESS FOUND');
this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness);
}
//FORCE TO READ A SIGNATURE
if(LOG>4)console.log('SIGNATURE FOUND');
this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);
decoder.readEndElement();
};
Signature.prototype.to_ccnb= function( encoder){
if (!this.validate()) {
throw new Error("Cannot encode: field values missing.");
}
encoder.writeStartElement(this.getElementLabel());
if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
}
if (null != this.Witness) {
// needs to handle null witness
encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
}
encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
encoder.writeEndElement();
};
Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
Signature.prototype.validate = function() {
return null != this.signature;
};
/**
* SignedInfo
*/
var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
var SignedInfo = function SignedInfo(_publisher,_timestamp,_type,_locator,_freshnessSeconds,_finalBlockID){
//TODO, Check types
this.publisher = _publisher; //publisherPublicKeyDigest
this.timestamp=_timestamp; // CCN Time
this.type=_type; // ContentType
this.locator =_locator;//KeyLocator
this.freshnessSeconds =_freshnessSeconds; // Integer
this.finalBlockID=_finalBlockID; //byte array
// SWT: merge setFields() method into constructor
this.setFields();
};
SignedInfo.prototype.setFields = function(){
//BASE64 -> RAW STRING
//this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
var publicKeyHex = globalKeyManager.publicKey;
if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
if(LOG>4)console.log(publicKeyHex);
var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ;
//var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
//if(LOG>3)console.log('string Certificate is '+stringCertificate);
//HEX -> BYTE ARRAY
//var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
//if(LOG>3)console.log('publisher key is ');
//if(LOG>3)console.log(publisherkey);
var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
this.publisher = new PublisherPublicKeyDigest( DataUtils.toNumbers( publisherKeyDigest ) );
//this.publisher = new PublisherPublicKeyDigest(publisherkey);
var d = new Date();
var time = d.getTime();
this.timestamp = new CCNTime( time );
if(LOG>4)console.log('TIME msec is');
if(LOG>4)console.log(this.timestamp.msec);
//DATA
this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
//if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
if(LOG>4)console.log(publicKeyBytes);
this.locator = new KeyLocator( publicKeyBytes ,KeyLocatorType.KEY );
//this.locator = new KeyLocator( DataUtils.toNumbersFromString(stringCertificate) ,KeyLocatorType.CERTIFICATE );
};
SignedInfo.prototype.from_ccnb = function( decoder){
decoder.readStartElement( this.getElementLabel() );
if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
if(LOG>4)console.log('DECODING PUBLISHER KEY');
this.publisher = new PublisherPublicKeyDigest();
this.publisher.from_ccnb(decoder);
}
if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
if(LOG>4)console.log('DECODING TIMESTAMP');
this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
}
if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte []
//TODO Implement type of Key Reading
if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
this.type = binType;
//TODO Implement type of Key Reading
if (null == this.type) {
throw new Error("Cannot parse signedInfo type: bytes.");
}
} else {
this.type = ContentType.DATA; // default
}
if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
if(LOG>4)console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
}
if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
if(LOG>4)console.log('DECODING FINAL BLOCKID');
this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
}
if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
if(LOG>4)console.log('DECODING KEY LOCATOR');
this.locator = new KeyLocator();
this.locator.from_ccnb(decoder);
}
decoder.readEndElement();
};
SignedInfo.prototype.to_ccnb = function( encoder) {
if (!this.validate()) {
throw new Error("Cannot encode : field values missing.");
}
encoder.writeStartElement(this.getElementLabel());
if (null!=this.publisher) {
if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
this.publisher.to_ccnb(encoder);
}
if (null!=this.timestamp) {
encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
}
if (null!=this.type && this.type !=0) {
encoder.writeElement(CCNProtocolDTags.type, this.type);
}
if (null!=this.freshnessSeconds) {
encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
}
if (null!=this.finalBlockID) {
encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
}
if (null!=this.locator) {
this.locator.to_ccnb(encoder);
}
encoder.writeEndElement();
};
SignedInfo.prototype.valueToType = function(){
//for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
//if (Arrays.equals(value, entry.getKey()))
//return entry.getValue();
//}
return null;
};
SignedInfo.prototype.getElementLabel = function() {
return CCNProtocolDTags.SignedInfo;
};
SignedInfo.prototype.validate = function() {
// We don't do partial matches any more, even though encoder/decoder
// is still pretty generous.
if (null ==this.publisher || null==this.timestamp ||null== this.locator)
return false;
return true;
};