Start implement signature verification
diff --git a/js/tools/build/ndn-js-uncomp.js b/js/tools/build/ndn-js-uncomp.js
index 73d3862..c287d2a 100644
--- a/js/tools/build/ndn-js-uncomp.js
+++ b/js/tools/build/ndn-js-uncomp.js
@@ -92,7 +92,6 @@
this.transport = getTransport();
this.getHostAndPort = (settings.getHostAndPort || this.transport.defaultGetHostAndPort);
this.host = (settings.host !== undefined ? settings.host : 'localhost');
- dump("this.host " + this.host + "\n");
this.port = (settings.port || 9696);
this.readyStatus = NDN.UNOPEN;
// Event handler
@@ -341,7 +340,22 @@
var entry = getEntryForRegisteredPrefix(nameStr);
if (entry != null) {
//console.log(entry);
- entry.closure.upcall(Closure.UPCALL_INTEREST, new UpcallInfo(ndn, interest, 0, null));
+ var info = new UpcallInfo(ndn, interest, 0, null);
+ var ret = entry.closure.upcall(Closure.UPCALL_INTEREST, info);
+ if (ret == Closure.RESULT_INTEREST_CONSUMED && info.contentObject != null) {
+ var coBinary = encodeToBinaryContentObject(info.contentObject);
+ // If we directly use coBinary.buffer to feed ws.send(), WebSocket
+ // will end up sending a packet with 10000 bytes of data. That
+ // is, WebSocket will flush the entire buffer in BinaryXMLEncoder
+ // regardless of the offset of the Uint8Array. So we have to
+ // create a new Uint8Array buffer with just the right size and
+ // copy the content from coBinary to the new buffer.
+ // ---Wentao
+ var bytearray = new Uint8Array(coBinary.length);
+ bytearray.set(coBinary);
+
+ self.ws.send(bytearray.buffer);
+ }
}
} else if (decoder.peekStartElement(CCNProtocolDTags.ContentObject)) { // Content packet
@@ -350,8 +364,39 @@
var co = new ContentObject();
co.from_ccnb(decoder);
if (LOG > 3) console.log(co);
- nameStr = co.name.getName();
- if (LOG > 3) console.log(nameStr);
+ var nameStr = co.name.getName();
+ console.log(nameStr);
+
+ // Key verification
+ if (co.signedInfo && co.signature) {
+ if (LOG > 3) console.log("Key verification...");
+ var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
+
+ var keylocator = co.signedInfo.locator;
+ if (keylocator.type == KeyLocatorType.KEYNAME) {
+ console.log("KeyLocator contains KEYNAME");
+ var keyname = keylocator.keyName.contentName.getName();
+ console.log(keyname);
+ } else if (keylocator.type == KeyLocatorType.KEY) {
+ console.log("Keylocator contains KEY");
+ var publickeyHex = DataUtils.toHex(co.signedInfo.locator.publicKey).toLowerCase();
+
+ var kp = publickeyHex.slice(56, 314);
+ var exp = publickeyHex.slice(318, 324);
+
+ var rsakey = new RSAKey();
+ rsakey.setPublic(kp, exp);
+ var result = rsakey.verifyByteArray(co.rawSignatureData, signature);
+ if (result)
+ console.log('SIGNATURE VALID');
+ else
+ console.log('SIGNATURE INVALID');
+ } else {
+ var cert = keylocator.certificate;
+ console.log("KeyLocator contains CERT");
+ console.log(cert);
+ }
+ }
if (self.ccndid == null && nameStr.match(NDN.ccndIdFetcher) != null) {
// We are in starting phase, record publisherPublicKeyDigest in self.ccndid
@@ -1015,26 +1060,37 @@
/*
* Find the last component in name that has a ContentDigest and return the digest value as Uint8Array,
- * or null if not found.
- * A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
+ * or null if not found. See Name.getComponentContentDigestValue.
*/
Name.prototype.getContentDigestValue = function() {
- var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length;
for (var i = this.components.length - 1; i >= 0; --i) {
- // Check for the correct length and equal ContentDigestPrefix and ContentDigestSuffix.
- if (this.components[i].length == digestComponentLength &&
- DataUtils.arraysEqual(this.components[i].subarray(0, Name.ContentDigestPrefix.length),
- Name.ContentDigestPrefix) &&
- DataUtils.arraysEqual(this.components[i].subarray
- (this.components[i].length - Name.ContentDigestSuffix.length, this.components[i].length),
- Name.ContentDigestSuffix))
- return this.components[i].subarray
- (Name.ContentDigestPrefix.length, Name.ContentDigestPrefix.length + 32);
+ var digestValue = Name.getComponentContentDigestValue(this.components[i]);
+ if (digestValue != null)
+ return digestValue;
}
return null;
}
+/*
+ * If component is a ContentDigest, return the digest value as a Uint8Array subarray (don't modify!).
+ * If not a ContentDigest, return null.
+ * A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
+ */
+Name.getComponentContentDigestValue = function(component) {
+ var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length;
+ // Check for the correct length and equal ContentDigestPrefix and ContentDigestSuffix.
+ if (component.length == digestComponentLength &&
+ DataUtils.arraysEqual(component.subarray(0, Name.ContentDigestPrefix.length),
+ Name.ContentDigestPrefix) &&
+ DataUtils.arraysEqual(component.subarray
+ (component.length - Name.ContentDigestSuffix.length, component.length),
+ Name.ContentDigestSuffix))
+ return component.subarray(Name.ContentDigestPrefix.length, Name.ContentDigestPrefix.length + 32);
+ else
+ return null;
+}
+
// Meta GUID "%C1.M.G%C1" + ContentDigest with a 32 byte BLOB.
Name.ContentDigestPrefix = new Uint8Array([0xc1, 0x2e, 0x4d, 0x2e, 0x47, 0xc1, 0x01, 0xaa, 0x02, 0x85]);
Name.ContentDigestSuffix = new Uint8Array([0x00]);
@@ -1080,7 +1136,7 @@
var ContentObject = function ContentObject(_name,_signedInfo,_content,_signature){
- if (typeof _name === 'string'){
+ if (typeof _name == 'string') {
this.name = new Name(_name);
}
else{
@@ -1088,7 +1144,13 @@
this.name = _name;
}
this.signedInfo = _signedInfo;
- this.content=_content;
+
+ if (typeof _content == 'string') {
+ this.content = DataUtils.toNumbersFromString(_content);
+ } else {
+ this.content = _content;
+ }
+
this.signature = _signature;
@@ -1344,6 +1406,9 @@
this.locator =_locator;//KeyLocator
this.freshnessSeconds =_freshnessSeconds; // Integer
this.finalBlockID=_finalBlockID; //byte array
+
+ // SWT: merge setFields() method into constructor
+ this.setFields();
};
@@ -1884,23 +1949,25 @@
* KeyLocator
*/
var KeyLocatorType = {
- NAME:1,
- KEY:2,
- CERTIFICATE:3
+ KEY:1,
+ CERTIFICATE:2,
+ KEYNAME:3
};
var KeyLocator = function KeyLocator(_input,_type){
- this.type=_type;
+ this.type = _type;
- if (_type==KeyLocatorType.NAME){
+ if (_type == KeyLocatorType.KEYNAME){
+ if (LOG>3) console.log('KeyLocator: SET KEYNAME');
this.keyName = _input;
}
- else if(_type==KeyLocatorType.KEY){
- if(LOG>4)console.log('SET KEY');
+ else if (_type == KeyLocatorType.KEY){
+ if (LOG>3) console.log('KeyLocator: SET KEY');
this.publicKey = _input;
}
- else if(_type==KeyLocatorType.CERTIFICATE){
+ else if (_type == KeyLocatorType.CERTIFICATE){
+ if (LOG>3) console.log('KeyLocator: SET CERTIFICATE');
this.certificate = _input;
}
@@ -1918,7 +1985,7 @@
//TODO FIX THIS, This should create a Key Object instead of keeping bytes
this.publicKey = encodedKey;//CryptoUtil.getPublicKey(encodedKey);
- this.type = 2;
+ this.type = KeyLocatorType.KEY;
if(LOG>4) console.log('PUBLIC KEY FOUND: '+ this.publicKey);
@@ -1946,7 +2013,7 @@
this.certificate = encodedCert;
- this.type = 3;
+ this.type = KeyLocatorType.CERTIFICATE;
if(LOG>4) console.log('CERTIFICATE FOUND: '+ this.certificate);
@@ -1957,9 +2024,8 @@
throw new Error("Cannot parse certificate! ");
}
} else {
- this.type = 1;
-
-
+ this.type = KeyLocatorType.KEYNAME;
+
this.keyName = new KeyName();
this.keyName.from_ccnb(decoder);
}
@@ -1991,7 +2057,7 @@
throw new Error("CertificateEncodingException attempting to write key locator: " + e);
}
- } else if (this.type == KeyLocatorType.NAME) {
+ } else if (this.type == KeyLocatorType.KEYNAME) {
this.keyName.to_ccnb(encoder);
}
@@ -4046,7 +4112,7 @@
/**
* Raw String to Uint8Array.
*/
-DataUtils.toNumbersFromString = function( str ){
+DataUtils.toNumbersFromString = function(str) {
var bytes = new Uint8Array(str.length);
for(var i=0;i<str.length;i++)
bytes[i] = str.charCodeAt(i);