ccnx: Rename Key to Cert; fix bug with the usage of Hash

Change-Id: Ic7656e6d8d46729d663ccfa5412e78443aff76bc
diff --git a/ccnx/ccnx-key.cc b/ccnx/ccnx-cert.cpp
similarity index 89%
rename from ccnx/ccnx-key.cc
rename to ccnx/ccnx-cert.cpp
index c3fdf10..e202c65 100644
--- a/ccnx/ccnx-key.cc
+++ b/ccnx/ccnx-cert.cpp
@@ -18,33 +18,33 @@
  * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
  *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
-#include "ccnx-key.h"
+#include "ccnx-cert.h"
 #include <tinyxml.h>
 #include <boost/lexical_cast.hpp>
 #include "logging.h"
 
-INIT_LOGGER ("Ccnx.Key");
+INIT_LOGGER ("Ccnx.Cert");
 
 using namespace std;
 
 namespace Ccnx {
 
-Key::Key()
+Cert::Cert()
     : m_meta("", "",  0, 0)
 {
 }
 
-Key::Key(const PcoPtr &keyObject, const PcoPtr &metaObject = PcoPtr())
+Cert::Cert(const PcoPtr &keyObject, const PcoPtr &metaObject = PcoPtr())
     : m_meta("", "", 0, 0)
 {
   m_name = keyObject->name();
   m_raw = keyObject->content();
-  m_hash = *(Hash::FromString(string((const char *)head(m_raw), m_raw.size())));
+  m_hash = *(Hash::FromBytes(m_raw));
   updateMeta(metaObject);
 }
 
 void
-Key::updateMeta(const PcoPtr &metaObject)
+Cert::updateMeta(const PcoPtr &metaObject)
 {
   if (metaObject)
   {
@@ -90,8 +90,8 @@
   }
 }
 
-Key::VALIDITY
-Key::validity()
+Cert::VALIDITY
+Cert::validity()
 {
   if (m_meta.validFrom == 0 && m_meta.validTo == 0)
   {
diff --git a/ccnx/ccnx-key.h b/ccnx/ccnx-cert.h
similarity index 84%
rename from ccnx/ccnx-key.h
rename to ccnx/ccnx-cert.h
index 3d14afc..c0e2b74 100644
--- a/ccnx/ccnx-key.h
+++ b/ccnx/ccnx-cert.h
@@ -19,8 +19,8 @@
  *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
 
-#ifndef CCNX_KEY_H
-#define CCNX_KEY_H
+#ifndef CCNX_CERT_H
+#define CCNX_CERT_H
 
 #include "ccnx-common.h"
 #include "ccnx-name.h"
@@ -30,7 +30,7 @@
 
 namespace Ccnx {
 
-class Key
+class Cert
 {
 public:
   enum VALIDITY
@@ -41,8 +41,8 @@
     OTHER
   };
 
-  Key();
-  Key(const PcoPtr &keyObject, const PcoPtr &metaObject);
+  Cert();
+  Cert(const PcoPtr &keyObject, const PcoPtr &metaObject);
 
   void
   updateMeta(const PcoPtr &metaObject);
@@ -54,7 +54,7 @@
   raw() { return m_raw; }
 
   Hash
-  hash() { return m_hash; }
+  keyDigest() { return m_hash; }
 
   std::string
   realworldID() { return m_meta.realworldID; }
@@ -66,9 +66,9 @@
   validity();
 
 private:
-  struct KeyMeta
+  struct Meta
   {
-    KeyMeta(std::string id, std::string affi, time_t from, time_t to)
+    Meta(std::string id, std::string affi, time_t from, time_t to)
       : realworldID(id)
       , affiliation(affi)
       , validFrom(from)
@@ -84,11 +84,11 @@
   Name m_name;
   Hash m_hash; // publisherPublicKeyHash
   Bytes m_raw;
-  KeyMeta m_meta;
+  Meta m_meta;
 };
 
-typedef boost::shared_ptr<Key> KeyPtr;
+typedef boost::shared_ptr<Cert> CertPtr;
 
 }
 
-#endif // CCNX_KEY_H
+#endif // CCNX_CERT_H
diff --git a/ccnx/ccnx-pco.cpp b/ccnx/ccnx-pco.cpp
index 4ca46c7..700e1e5 100644
--- a/ccnx/ccnx-pco.cpp
+++ b/ccnx/ccnx-pco.cpp
@@ -106,11 +106,17 @@
 Name
 ParsedContentObject::keyName() const
 {
-  CcnxCharbufPtr ptr = boost::make_shared<CcnxCharbuf>();
-  ccn_charbuf_append(ptr->getBuf(), head(m_bytes) + m_pco.offset[CCN_PCO_B_KeyName_Name], m_pco.offset[CCN_PCO_E_KeyName_Name] - m_pco.offset[CCN_PCO_B_KeyName_Name]);
+  if (m_pco.offset[CCN_PCO_E_KeyName_Name] > m_pco.offset[CCN_PCO_B_KeyName_Name])
+  {
+    CcnxCharbufPtr ptr = boost::make_shared<CcnxCharbuf>();
+    ccn_charbuf_append(ptr->getBuf(), head(m_bytes) + m_pco.offset[CCN_PCO_B_KeyName_Name], m_pco.offset[CCN_PCO_E_KeyName_Name] - m_pco.offset[CCN_PCO_B_KeyName_Name]);
 
-  return Name(*ptr);
-
+    return Name(*ptr);
+  }
+  else
+  {
+    return Name();
+  }
 }
 
 HashPtr
diff --git a/ccnx/ccnx-verifier.cpp b/ccnx/ccnx-verifier.cpp
index e2832ac..cee45a9 100644
--- a/ccnx/ccnx-verifier.cpp
+++ b/ccnx/ccnx-verifier.cpp
@@ -47,11 +47,11 @@
   }
 
   HashPtr publisherPublicKeyDigest = pco->publisherPublicKeyDigest();
-  KeyCache::iterator it = m_keyCache.find(*publisherPublicKeyDigest);
-  if (it != m_keyCache.end())
+  CertCache::iterator it = m_certCache.find(*publisherPublicKeyDigest);
+  if (it != m_certCache.end())
   {
-    KeyPtr key = it->second;
-    if (key->validity() == Key::WITHIN_VALID_TIME_SPAN)
+    CertPtr cert = it->second;
+    if (cert->validity() == Cert::WITHIN_VALID_TIME_SPAN)
     {
       // integrity checked, and the key is trustworthy
       pco->setVerified(true);
@@ -59,8 +59,8 @@
     }
     else
     {
-      // delete the invalid key cache
-      m_keyCache.erase(it);
+      // delete the invalid cert cache
+      m_certCache.erase(it);
     }
   }
 
@@ -68,6 +68,11 @@
   Name keyName = pco->keyName();
   int keyNameSize = keyName.size();
 
+  if (keyNameSize == 0)
+  {
+    return false;
+  }
+
   // for keys, we have to make sure key name is strictly prefix of the content name
   if (pco->type() == ParsedContentObject::KEY)
   {
@@ -105,20 +110,20 @@
     return false;
   }
 
-  KeyPtr key = boost::make_shared<Key>(keyObject, metaObject);
-  if (key->validity() != Key::WITHIN_VALID_TIME_SPAN)
+  CertPtr cert = boost::make_shared<Cert>(keyObject, metaObject);
+  if (cert->validity() != Cert::WITHIN_VALID_TIME_SPAN)
   {
     return false;
   }
 
   // check pco is actually signed by this key (maybe redundant)
-  if (! (*pco->publisherPublicKeyDigest() == key->hash()))
+  if (! (*pco->publisherPublicKeyDigest() == cert->keyDigest()))
   {
     return false;
   }
 
-  // now we only need to make sure the keyObject is trustworthy
-  if (key->hash() == m_rootKeyDigest)
+  // now we only need to make sure the key is trustworthy
+  if (cert->keyDigest() == m_rootKeyDigest)
   {
     // the key is the root key
     // do nothing now
@@ -134,7 +139,7 @@
 
   // ok, keyObject verified, because metaObject is signed by the same parent key and integrity checked
   // so metaObject is also verified
-  m_keyCache.insert(std::make_pair(key->hash(), key));
+  m_certCache.insert(std::make_pair(cert->keyDigest(), cert));
 
   pco->setVerified(true);
   return true;
diff --git a/ccnx/ccnx-verifier.h b/ccnx/ccnx-verifier.h
index 2ee6def..0b1fd84 100644
--- a/ccnx/ccnx-verifier.h
+++ b/ccnx/ccnx-verifier.h
@@ -25,7 +25,7 @@
 #include "ccnx-common.h"
 #include "ccnx-wrapper.h"
 #include "ccnx-name.h"
-#include "ccnx-key.h"
+#include "ccnx-cert.h"
 #include "ccnx-pco.h"
 #include <map>
 
@@ -33,7 +33,7 @@
 
 class CcnxWrapper;
 
-// not thread-safe, don't want to add a mutex for KeyCache
+// not thread-safe, don't want to add a mutex for CertCache
 // which increases the possibility of dead-locking
 // ccnx-wrapper would take care of thread-safety issue
 class Verifier
@@ -49,8 +49,8 @@
 private:
   CcnxWrapper *m_ccnx;
   Hash m_rootKeyDigest;
-  typedef std::map<Hash, KeyPtr> KeyCache;
-  KeyCache m_keyCache;
+  typedef std::map<Hash, CertPtr> CertCache;
+  CertCache m_certCache;
 };
 
 } // Ccnx
diff --git a/src/hash-helper.cc b/src/hash-helper.cc
index 6fe0ca9..11b29e2 100644
--- a/src/hash-helper.cc
+++ b/src/hash-helper.cc
@@ -167,3 +167,25 @@
 
   return retval;
 }
+
+HashPtr
+Hash::FromBytes (const Ccnx::Bytes &bytes)
+{
+  HashPtr retval = make_shared<Hash> (reinterpret_cast<void*> (0), 0);
+  retval->m_buf = new unsigned char [EVP_MAX_MD_SIZE];
+
+  EVP_MD_CTX *hash_context = EVP_MD_CTX_create ();
+  EVP_DigestInit_ex (hash_context, HASH_FUNCTION (), 0);
+
+  // not sure whether it's bad to do so if bytes.size is huge
+  EVP_DigestUpdate(hash_context, Ccnx::head(bytes), bytes.size());
+
+  retval->m_buf = new unsigned char [EVP_MAX_MD_SIZE];
+
+  EVP_DigestFinal_ex (hash_context,
+                      retval->m_buf, &retval->m_length);
+
+  EVP_MD_CTX_destroy (hash_context);
+
+  return retval;
+}
diff --git a/src/hash-helper.h b/src/hash-helper.h
index 64a625e..9050573 100644
--- a/src/hash-helper.h
+++ b/src/hash-helper.h
@@ -27,6 +27,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/exception/all.hpp>
 #include <boost/filesystem.hpp>
+#include "ccnx-common.h"
 
 // Other options: VP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_sha256, EVP_dss, EVP_dss1, EVP_mdc2, EVP_ripemd160
 #define HASH_FUNCTION EVP_sha256
@@ -72,6 +73,9 @@
   static HashPtr
   FromFileContent (const boost::filesystem::path &fileName);
 
+  static HashPtr
+  FromBytes (const Ccnx::Bytes &bytes);
+
   ~Hash ()
   {
     if (m_length != 0)
diff --git a/wscript b/wscript
index 76afad9..0021e41 100644
--- a/wscript
+++ b/wscript
@@ -192,7 +192,7 @@
         defines = "WAF",
         source = bld.path.ant_glob(['fs-watcher/*.cc']),
         use = "SQLITE3 LOG4CXX scheduler executor QTCORE",
-        includes = "fs-watcher scheduler executor src",
+        includes = "fs-watcher scheduler executor src ccnx",
         )
 
     # Unit tests