Added KeyChain::selfVerifyData.
diff --git a/ndn-cpp/key-chain.cpp b/ndn-cpp/key-chain.cpp
index 1da6f9d..fc656c0 100644
--- a/ndn-cpp/key-chain.cpp
+++ b/ndn-cpp/key-chain.cpp
@@ -126,8 +126,7 @@
   // TODO: use RSA_size to get the proper size of the signature buffer.
   unsigned char signature[1000];
   unsigned int signatureLength;
-  const unsigned char *keyPointer = privateKeyDer;
-  RSA *privateKey = d2i_RSAPrivateKey(NULL, &keyPointer, privateKeyDerLength);
+  RSA *privateKey = d2i_RSAPrivateKey(NULL, &privateKeyDer, privateKeyDerLength);
   if (!privateKey)
     throw std::runtime_error("Error decoding private key in d2i_RSAPrivateKey");
   int success = RSA_sign(NID_sha256, dataFieldsDigest, sizeof(dataFieldsDigest), signature, &signatureLength, privateKey);
@@ -144,4 +143,40 @@
   sign(data, DEFAULT_PUBLIC_KEY_DER, sizeof(DEFAULT_PUBLIC_KEY_DER), DEFAULT_PRIVATE_KEY_DER, sizeof(DEFAULT_PRIVATE_KEY_DER));
 }
 
+bool KeyChain::selfVerifyData(const unsigned char *input, unsigned int inputLength, WireFormat &wireFormat)
+{
+  // Decode the data packet and digest the data fields.
+  Data data;
+  unsigned int signedFieldsBeginOffset, signedFieldsEndOffset;
+  wireFormat.decodeData(data, input, inputLength, &signedFieldsBeginOffset, &signedFieldsEndOffset);
+  if (data.getSignature().getDigestAlgorithm().size() != 0)
+    // TODO: Allow a non-default digest algorithm.
+    throw std::runtime_error("Cannot verify a data packet with a non-default digest algorithm");
+  unsigned char dataFieldsDigest[SHA256_DIGEST_LENGTH];
+  digestSha256(input + signedFieldsBeginOffset, signedFieldsEndOffset - signedFieldsBeginOffset, dataFieldsDigest);
+  
+  // Find the public key.
+  const unsigned char *publicKeyDer;
+  unsigned int publicKeyDerLength;
+  if (data.getSignedInfo().getKeyLocator().getType() == ndn_KeyLocatorType_KEY) {
+    publicKeyDer = &data.getSignedInfo().getKeyLocator().getKeyOrCertificate().front();
+    publicKeyDerLength = data.getSignedInfo().getKeyLocator().getKeyOrCertificate().size();
+  }
+  else
+    // Can't find a public key.
+    return false;
+
+  // Verify the dataFieldsDigest.
+  RSA *publicKey = d2i_RSA_PUBKEY(NULL, &publicKeyDer, publicKeyDerLength);
+  if (!publicKey)
+    throw std::runtime_error("Error decoding public key in d2i_RSAPublicKey");
+  int success = RSA_verify
+    (NID_sha256, dataFieldsDigest, sizeof(dataFieldsDigest), &data.getSignature().getSignature().front(), 
+     data.getSignature().getSignature().size(), publicKey);
+  // Free the public key before checking for success.
+  RSA_free(publicKey);
+  
+  return (success == 1);
+}
+
 }
diff --git a/ndn-cpp/key-chain.hpp b/ndn-cpp/key-chain.hpp
index 8de7a62..6fa9c0a 100644
--- a/ndn-cpp/key-chain.hpp
+++ b/ndn-cpp/key-chain.hpp
@@ -32,6 +32,23 @@
    * @param data
    */
   static void defaultSign(Data &data);
+  
+  /**
+   * Use the WireFormat to decode the input as a Data packet and use the public key in the key locator to 
+   * verify the signature.
+   * This does just uses the public key without checking whether it is certified.
+   * @param input A pointer to the input buffer to decode.
+   * @param inputLength The number of bytes in input.
+   * @param wireFormat The WireFormat for calling decodeData.
+   * @return true if the public key in the Data object verifies the object, false if not or if the Data object
+   * doesn't have a public key.
+   */
+  static bool selfVerifyData(const unsigned char *input, unsigned int inputLength, WireFormat &wireFormat);
+  
+  static bool selfVerifyData(const unsigned char *input, unsigned int inputLength)
+  {
+    return selfVerifyData(input, inputLength, *WireFormat::getDefaultWireFormat());
+  }
 };
 
 }
diff --git a/tests/test-encode-decode-data.cpp b/tests/test-encode-decode-data.cpp
index 0c0de84..176353c 100644
--- a/tests/test-encode-decode-data.cpp
+++ b/tests/test-encode-decode-data.cpp
@@ -138,6 +138,7 @@
     data.wireDecode(Data1, sizeof(Data1));
     cout << "Decoded Data:" << endl;
     dumpData(data);
+    cout << "Decoded Data signature verification: " << (KeyChain::selfVerifyData(Data1, sizeof(Data1)) ? "VERIFIED" : "FAILED") << endl;
     
     ptr_lib::shared_ptr<vector<unsigned char> > encoding = data.wireEncode();
     
@@ -145,6 +146,7 @@
     reDecodedData.wireDecode(*encoding);
     cout << endl << "Re-decoded Data:" << endl;
     dumpData(reDecodedData);
+    cout << "Re-decoded Data signature verification: " << (KeyChain::selfVerifyData(&encoding->front(), encoding->size()) ? "VERIFIED" : "FAILED") << endl;
   
     Data freshData(Name("/ndn/abc"));
     const unsigned char freshContent[] = "SUCCESS!";
@@ -152,8 +154,10 @@
     freshData.getSignedInfo().setTimestampMilliseconds(time(NULL) * 1000.0);
     
     KeyChain::defaultSign(freshData);
-    cout << endl << "Freshly signed data:" << endl;
+    cout << endl << "Freshly-signed Data:" << endl;
     dumpData(freshData);
+    ptr_lib::shared_ptr<vector<unsigned char> > freshEncoding = freshData.wireEncode();
+    cout << "Freshly-signed Data signature verification: " << (KeyChain::selfVerifyData(&freshEncoding->front(), freshEncoding->size()) ? "VERIFIED" : "FAILED") << endl;
   } catch (exception &e) {
     cout << "exception: " << e.what() << endl;
   }