Major update: Refactor to rename ContentName to Name.  Delete KeyName.js.  For the moment, the KeyName class is now in KeyLocator.js.
This is done according to the API notes:
http://sea.remap.ucla.edu:8080/attachments/download/23/lwndn_api-notes_21020830.txt
diff --git a/js/KeyLocator.js b/js/KeyLocator.js
index 14f283c..0a73cb5 100644
--- a/js/KeyLocator.js
+++ b/js/KeyLocator.js
@@ -126,4 +126,54 @@
 KeyLocator.prototype.validate = function() {
 	return (  (null != this.keyName) || (null != this.publicKey) || (null != this.certificate)   );
 };
-	
\ No newline at end of file
+
+/**
+ * KeyName is only used by KeyLocator.
+ */
+var KeyName = function KeyName() {
+	
+
+	this.contentName = this.contentName;//contentName
+	this.publisherID =this.publisherID;//publisherID
+
+};
+
+KeyName.prototype.from_ccnb=function( decoder){
+	
+
+	decoder.readStartElement(this.getElementLabel());
+
+	this.contentName = new Name();
+	this.contentName.from_ccnb(decoder);
+	
+	if(LOG>4) console.log('KEY NAME FOUND: ');
+	
+	if ( PublisherID.peek(decoder) ) {
+		this.publisherID = new PublisherID();
+		this.publisherID.from_ccnb(decoder);
+	}
+	
+	decoder.readEndElement();
+};
+
+KeyName.prototype.to_ccnb = function( encoder) {
+	if (!this.validate()) {
+		throw new Error("Cannot encode : field values missing.");
+	}
+	
+	encoder.writeStartElement(this.getElementLabel());
+	
+	this.contentName.to_ccnb(encoder);
+	if (null != this.publisherID)
+		this.publisherID.to_ccnb(encoder);
+
+	encoder.writeEndElement();   		
+};
+	
+KeyName.prototype.getElementLabel = function() { return CCNProtocolDTags.KeyName; };
+
+KeyName.prototype.validate = function() {
+		// DKS -- do we do recursive validation?
+		// null signedInfo ok
+		return (null != this.contentName);
+};