In KeyLocator, added support for KeyName.
diff --git a/ndn-cpp/c/data.h b/ndn-cpp/c/data.h
index c8d97fc..98a1d76 100644
--- a/ndn-cpp/c/data.h
+++ b/ndn-cpp/c/data.h
@@ -54,15 +54,18 @@
 
 /**
  * Initialize the ndn_SignedInfo struct with values for none and the type to the default ndn_ContentType_DATA.
- * @param self pointer to the ndn_SignedInfo struct.
+ * @param self A pointer to the ndn_SignedInfo struct.
+ * @param keyNameComponents The pre-allocated array of ndn_NameComponent for the keyLocator.
+ * @param maxKeyNameComponents The number of elements in the allocated keyNameComponents array.
  */
-static inline void ndn_SignedInfo_init(struct ndn_SignedInfo *self) {
+static inline void ndn_SignedInfo_init
+  (struct ndn_SignedInfo *self, struct ndn_NameComponent *keyNameComponents, unsigned int maxKeyNameComponents) {
   ndn_PublisherPublicKeyDigest_init(&self->publisherPublicKeyDigest);
   self->type = ndn_ContentType_DATA;
   self->freshnessSeconds = -1;
   self->finalBlockID = 0;
   self->finalBlockIDLength = 0;
-  ndn_KeyLocator_init(&self->keyLocator);
+  ndn_KeyLocator_init(&self->keyLocator, keyNameComponents, maxKeyNameComponents);
 }
 
 struct ndn_Data {
@@ -74,17 +77,21 @@
 };
 
 /**
- * Initialize an ndn_Data struct with the pre-allocated nameComponents,
+ * Initialize an ndn_Data struct with the pre-allocated nameComponents and keyNameComponents,
  * and defaults for all the values.
- * @param self pointer to the ndn_Data struct
- * @param nameComponents the pre-allocated array of ndn_NameComponent
- * @param maxNameComponents the number of elements in the allocated nameComponents array
+ * @param self A pointer to the ndn_Data struct.
+ * @param nameComponents The pre-allocated array of ndn_NameComponent.
+ * @param maxNameComponents The number of elements in the allocated nameComponents array.
+ * @param keyNameComponents The pre-allocated array of ndn_NameComponent for the signedInfo.keyLocator.
+ * @param maxKeyNameComponents The number of elements in the allocated keyNameComponents array.
  */
-static inline void ndn_Data_init(struct ndn_Data *self, struct ndn_NameComponent *nameComponents, unsigned int maxNameComponents) 
+static inline void ndn_Data_init
+  (struct ndn_Data *self, struct ndn_NameComponent *nameComponents, unsigned int maxNameComponents, 
+   struct ndn_NameComponent *keyNameComponents, unsigned int maxKeyNameComponents) 
 {
   ndn_Signature_init(&self->signature);
   ndn_Name_init(&self->name, nameComponents, maxNameComponents);
-  ndn_SignedInfo_init(&self->signedInfo);
+  ndn_SignedInfo_init(&self->signedInfo, keyNameComponents, maxKeyNameComponents);
   self->content = 0;
   self->contentLength = 0;
 }
diff --git a/ndn-cpp/c/encoding/binary-xml-data.c b/ndn-cpp/c/encoding/binary-xml-data.c
index 564e6f4..37513f9 100644
--- a/ndn-cpp/c/encoding/binary-xml-data.c
+++ b/ndn-cpp/c/encoding/binary-xml-data.c
@@ -188,7 +188,7 @@
       return error;
   }
   else
-    ndn_SignedInfo_init(&data->signedInfo);
+    ndn_SignedInfo_init(&data->signedInfo, data->signedInfo.keyLocator.keyName.components, data->signedInfo.keyLocator.keyName.maxComponents);
 
   // Require a Content element, but set allowNull to allow a missing BLOB.
   if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
diff --git a/ndn-cpp/c/encoding/binary-xml-key.c b/ndn-cpp/c/encoding/binary-xml-key.c
index c1df758..42e4463 100644
--- a/ndn-cpp/c/encoding/binary-xml-key.c
+++ b/ndn-cpp/c/encoding/binary-xml-key.c
@@ -8,6 +8,54 @@
 #include "binary-xml-structure-decoder.h"
 #include "binary-xml-key.h"
 
+static ndn_Error decodeKeyNameData(struct ndn_KeyLocator *keyLocator, struct ndn_BinaryXmlDecoder *decoder)
+{
+  int gotExpectedTag;
+  ndn_Error error; 
+  if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, &gotExpectedTag)))
+    return error;
+  if (gotExpectedTag) {
+    keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST;
+    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
+        (decoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+      return error;
+  }
+  else {
+    if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, &gotExpectedTag)))
+      return error;
+    if (gotExpectedTag) {
+      keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST;
+      if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
+          (decoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+        return error;
+    }
+    else {
+      if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, &gotExpectedTag)))
+        return error;
+      if (gotExpectedTag) {
+        keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST;
+        if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
+            (decoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+          return error;
+      }
+      else {
+        if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, &gotExpectedTag)))
+          return error;
+        if (gotExpectedTag) {
+          keyLocator->keyNameType = ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST;
+          if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement
+              (decoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, 0, &keyLocator->keyData, &keyLocator->keyDataLength)))
+            return error;
+        }
+        else
+          return NDN_ERROR_decodeBinaryXmlKeyLocator_unrecognized_key_name_type;
+      }
+    }
+  }
+  
+  return NDN_ERROR_success;
+}
+
 ndn_Error ndn_encodeBinaryXmlKeyLocator(struct ndn_KeyLocator *keyLocator, struct ndn_BinaryXmlEncoder *encoder)
 {
   if (keyLocator->type < 0)
@@ -28,7 +76,36 @@
       return error;    
   }
   else if (keyLocator->type == ndn_KeyLocatorType_KEYNAME) {
-    // TODO: Implement keyName
+    if ((error = ndn_BinaryXmlEncoder_writeElementStartDTag(encoder, ndn_BinaryXml_DTag_KeyName)))
+      return error;
+    if ((error = ndn_encodeBinaryXmlName(&keyLocator->keyName, encoder)))
+      return error;
+    
+    if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST) {
+      if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
+          (encoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, keyLocator->keyData, keyLocator->keyDataLength)))
+        return error;    
+    }
+    else if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST) {
+      if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
+          (encoder, ndn_BinaryXml_DTag_PublisherCertificateDigest, keyLocator->keyData, keyLocator->keyDataLength)))
+        return error;    
+    }
+    else if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST) {
+      if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
+          (encoder, ndn_BinaryXml_DTag_PublisherIssuerKeyDigest, keyLocator->keyData, keyLocator->keyDataLength)))
+        return error;    
+    }
+    else if (keyLocator->keyNameType == ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST) {
+      if ((error = ndn_BinaryXmlEncoder_writeBlobDTagElement
+          (encoder, ndn_BinaryXml_DTag_PublisherIssuerCertificateDigest, keyLocator->keyData, keyLocator->keyDataLength)))
+        return error;    
+    }
+    else
+      return NDN_ERROR_unrecognized_ndn_KeyNameType;
+
+    if ((error = ndn_BinaryXmlEncoder_writeElementClose(encoder)))
+      return error;
   }
   else
     return NDN_ERROR_unrecognized_ndn_KeyLocatorType;
@@ -69,16 +146,16 @@
       if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_KeyName, &gotExpectedTag)))
         return error;
       if (gotExpectedTag) {
-        // TODO: Implement keyName. For now, just use a structure decoder to skip it.
-        struct ndn_BinaryXmlStructureDecoder structureDecoder;
-        ndn_BinaryXmlStructureDecoder_init(&structureDecoder);
+        keyLocator->type = ndn_KeyLocatorType_KEYNAME;
         
-        ndn_BinaryXmlStructureDecoder_seek(&structureDecoder, decoder->offset);
-        if ((error = ndn_BinaryXmlStructureDecoder_findElementEnd(&structureDecoder, decoder->input, decoder->inputLength)))
+        if ((error = ndn_BinaryXmlDecoder_readElementStartDTag(decoder, ndn_BinaryXml_DTag_KeyName)))
           return error;
-        if (!structureDecoder.gotElementEnd)
-          return NDN_ERROR_read_past_the_end_of_the_input;
-        ndn_BinaryXmlDecoder_seek(decoder, structureDecoder.offset);        
+        if ((error = ndn_decodeBinaryXmlName(&keyLocator->keyName, decoder)))
+          return error;
+        if ((error = decodeKeyNameData(keyLocator, decoder)))
+          return error;        
+        if ((error = ndn_BinaryXmlDecoder_readElementClose(decoder)))
+          return error;
       }
       else
         return NDN_ERROR_decodeBinaryXmlKeyLocator_unrecognized_key_locator_type;
@@ -102,7 +179,7 @@
       return error;
   }
   else
-    ndn_KeyLocator_init(keyLocator);
+    ndn_KeyLocator_init(keyLocator, keyLocator->keyName.components, keyLocator->keyName.maxComponents);
   
   return NDN_ERROR_success;
 }
diff --git a/ndn-cpp/c/errors.c b/ndn-cpp/c/errors.c
index 8c87d77..6811b6a 100644
--- a/ndn-cpp/c/errors.c
+++ b/ndn-cpp/c/errors.c
@@ -50,8 +50,12 @@
     return      "unrecognized ndn_ExcludeType";
   case NDN_ERROR_unrecognized_ndn_KeyLocatorType:
     return      "unrecognized ndn_KeyLocatorType";
+  case NDN_ERROR_unrecognized_ndn_KeyNameType:
+    return      "unrecognized ndn_KeyNameType";
   case NDN_ERROR_decodeBinaryXmlKeyLocator_unrecognized_key_locator_type:
     return      "decodeBinaryXmlKeyLocator unrecognized key locator type";
+  case NDN_ERROR_decodeBinaryXmlKeyLocator_unrecognized_key_name_type:
+    return      "decodeBinaryXmlKeyLocator unrecognized key name type";
   case NDN_ERROR_unrecognized_ndn_SocketTransport:
     return      "unrecognized ndn_SocketTransport";
   case NDN_ERROR_SocketTransport_error_in_getaddrinfo:
diff --git a/ndn-cpp/c/errors.h b/ndn-cpp/c/errors.h
index f6adb08..2e64492 100644
--- a/ndn-cpp/c/errors.h
+++ b/ndn-cpp/c/errors.h
@@ -33,7 +33,9 @@
   NDN_ERROR_DynamicUCharArray_realloc_failed,
   NDN_ERROR_unrecognized_ndn_ExcludeType,
   NDN_ERROR_unrecognized_ndn_KeyLocatorType,
+  NDN_ERROR_unrecognized_ndn_KeyNameType,
   NDN_ERROR_decodeBinaryXmlKeyLocator_unrecognized_key_locator_type,
+  NDN_ERROR_decodeBinaryXmlKeyLocator_unrecognized_key_name_type,
   NDN_ERROR_unrecognized_ndn_SocketTransport,
   NDN_ERROR_SocketTransport_error_in_getaddrinfo,
   NDN_ERROR_SocketTransport_cannot_connect_to_socket,
diff --git a/ndn-cpp/c/key.h b/ndn-cpp/c/key.h
index bb0aee6..5bfe05e 100644
--- a/ndn-cpp/c/key.h
+++ b/ndn-cpp/c/key.h
@@ -6,6 +6,8 @@
 #ifndef NDN_KEY_H
 #define NDN_KEY_H
 
+#include "name.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -15,20 +17,45 @@
   ndn_KeyLocatorType_CERTIFICATE = 2,
   ndn_KeyLocatorType_KEYNAME = 3
 } ndn_KeyLocatorType;
-  
+
+typedef enum {
+  ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST = 1,
+  ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST = 2,
+  ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST = 3,
+  ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST = 4
+} ndn_KeyNameType;
+
+/**
+ * An ndn_KeyLocator holds the type of key locator and related data.
+ */
 struct ndn_KeyLocator {
-  ndn_KeyLocatorType type;         /**< -1 for none */
-  unsigned char *keyData; /**< if type is ndn_KeyLocatorType_KEY, pointer to the pre-allocated buffer for the key value.
-                               if type is ndn_KeyLocatorType_CERTIFICATE, pointer to the pre-allocated buffer for the cetrificate value. */
-  unsigned int keyDataLength;
-  // TODO: Implement keyName.
+  ndn_KeyLocatorType type;     /**< -1 for none */
+  unsigned char *keyData;      /**< A pointer to a pre-allocated buffer for the key data as follows:
+    *   If type is ndn_KeyLocatorType_KEY, the key data.
+    *   If type is ndn_KeyLocatorType_CERTIFICATE, the certificate data. 
+    *   If type is ndn_KeyLocatorType_KEYNAME and keyNameType is ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST, the publisher public key digest. 
+    *   If type is ndn_KeyLocatorType_KEYNAME and keyNameType is ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST, the publisher certificate digest. 
+    *   If type is ndn_KeyLocatorType_KEYNAME and keyNameType is ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST, the publisher issuer key digest. 
+    *   If type is ndn_KeyLocatorType_KEYNAME and keyNameType is ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST, the publisher issuer certificate digest. 
+    */
+  unsigned int keyDataLength;  /**< The length of keyData. */
+  struct ndn_Name keyName;     /**< The key name (only used if type is ndn_KeyLocatorType_KEYNAME.) */
+  ndn_KeyNameType keyNameType; /**< The type of data for keyName (only used if type is ndn_KeyLocatorType_KEYNAME.) */
 };
 
-static inline void ndn_KeyLocator_init(struct ndn_KeyLocator *self) {
+/**
+ * Initialize an ndn_KeyLocator struct with the pre-allocated nameComponents, and defaults for all the values.
+ * @param self A pointer to the ndn_KeyLocator struct.
+ * @param keyNameComponents The pre-allocated array of ndn_NameComponent.
+ * @param maxKeyNameComponents The number of elements in the allocated keyNameComponents array.
+ */
+static inline void ndn_KeyLocator_init
+  (struct ndn_KeyLocator *self, struct ndn_NameComponent *keyNameComponents, unsigned int maxKeyNameComponents) {
   self->type = (ndn_KeyLocatorType)-1;
   self->keyData = 0;
   self->keyDataLength = 0;
-  // TODO: Implement keyName.
+  ndn_Name_init(&self->keyName, keyNameComponents, maxKeyNameComponents);
+  self->keyNameType = (ndn_KeyNameType)-1;
 }
 
 #ifdef __cplusplus