security: Implement most of Certificate.cpp
diff --git a/Makefile.am b/Makefile.am
index e781f48..eced317 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -95,7 +95,8 @@
   ndn-cpp/c/util/crypto.c ndn-cpp/c/util/crypto.h \
   ndn-cpp/c/util/dynamic-uint8-array.c ndn-cpp/c/util/dynamic-uint8-array.h \
   ndn-cpp/c/util/ndn_memory.c ndn-cpp/c/util/ndn_memory.h \
-  ndn-cpp/c/util/ndn_realloc.c ndn-cpp/c/util/ndn_realloc.h
+  ndn-cpp/c/util/ndn_realloc.c ndn-cpp/c/util/ndn_realloc.h \
+  ndn-cpp/c/util/time.c ndn-cpp/c/util/time.h
 
 # C++ code and also the C code.
 libndn_cpp_la_SOURCES = $(libndn_c_la_SOURCES) $(ndn_cpp_cpp_headers) \
@@ -127,6 +128,7 @@
   ndn-cpp/security/security-exception.cpp \
   ndn-cpp/security/certificate/certificate-extension.cpp \
   ndn-cpp/security/certificate/certificate-subject-description.cpp \
+  ndn-cpp/security/certificate/certificate.cpp \
   ndn-cpp/security/certificate/identity-certificate.cpp \
   ndn-cpp/security/certificate/public-key.cpp \
   ndn-cpp/security/identity/basic-identity-storage.cpp \
diff --git a/Makefile.in b/Makefile.in
index eca3905..0958a1a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -151,7 +151,8 @@
 	ndn-cpp/c/encoding/binary-xml-structure-decoder.lo \
 	ndn-cpp/c/transport/socket-transport.lo \
 	ndn-cpp/c/util/crypto.lo ndn-cpp/c/util/dynamic-uint8-array.lo \
-	ndn-cpp/c/util/ndn_memory.lo ndn-cpp/c/util/ndn_realloc.lo
+	ndn-cpp/c/util/ndn_memory.lo ndn-cpp/c/util/ndn_realloc.lo \
+	ndn-cpp/c/util/time.lo
 libndn_c_la_OBJECTS = $(am_libndn_c_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -172,7 +173,8 @@
 	ndn-cpp/c/encoding/binary-xml-structure-decoder.lo \
 	ndn-cpp/c/transport/socket-transport.lo \
 	ndn-cpp/c/util/crypto.lo ndn-cpp/c/util/dynamic-uint8-array.lo \
-	ndn-cpp/c/util/ndn_memory.lo ndn-cpp/c/util/ndn_realloc.lo
+	ndn-cpp/c/util/ndn_memory.lo ndn-cpp/c/util/ndn_realloc.lo \
+	ndn-cpp/c/util/time.lo
 am_libndn_cpp_la_OBJECTS = $(am__objects_2) $(am__objects_1) \
 	ndn-cpp/common.lo ndn-cpp/data.lo ndn-cpp/face.lo \
 	ndn-cpp/forwarding-entry.lo ndn-cpp/interest.lo ndn-cpp/key.lo \
@@ -191,6 +193,7 @@
 	ndn-cpp/security/security-exception.lo \
 	ndn-cpp/security/certificate/certificate-extension.lo \
 	ndn-cpp/security/certificate/certificate-subject-description.lo \
+	ndn-cpp/security/certificate/certificate.lo \
 	ndn-cpp/security/certificate/identity-certificate.lo \
 	ndn-cpp/security/certificate/public-key.lo \
 	ndn-cpp/security/identity/basic-identity-storage.lo \
@@ -640,7 +643,8 @@
   ndn-cpp/c/util/crypto.c ndn-cpp/c/util/crypto.h \
   ndn-cpp/c/util/dynamic-uint8-array.c ndn-cpp/c/util/dynamic-uint8-array.h \
   ndn-cpp/c/util/ndn_memory.c ndn-cpp/c/util/ndn_memory.h \
-  ndn-cpp/c/util/ndn_realloc.c ndn-cpp/c/util/ndn_realloc.h
+  ndn-cpp/c/util/ndn_realloc.c ndn-cpp/c/util/ndn_realloc.h \
+  ndn-cpp/c/util/time.c ndn-cpp/c/util/time.h
 
 
 # C++ code and also the C code.
@@ -673,6 +677,7 @@
   ndn-cpp/security/security-exception.cpp \
   ndn-cpp/security/certificate/certificate-extension.cpp \
   ndn-cpp/security/certificate/certificate-subject-description.cpp \
+  ndn-cpp/security/certificate/certificate.cpp \
   ndn-cpp/security/certificate/identity-certificate.cpp \
   ndn-cpp/security/certificate/public-key.cpp \
   ndn-cpp/security/identity/basic-identity-storage.cpp \
@@ -847,6 +852,8 @@
 	ndn-cpp/c/util/$(DEPDIR)/$(am__dirstamp)
 ndn-cpp/c/util/ndn_realloc.lo: ndn-cpp/c/util/$(am__dirstamp) \
 	ndn-cpp/c/util/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/c/util/time.lo: ndn-cpp/c/util/$(am__dirstamp) \
+	ndn-cpp/c/util/$(DEPDIR)/$(am__dirstamp)
 
 libndn-c.la: $(libndn_c_la_OBJECTS) $(libndn_c_la_DEPENDENCIES) $(EXTRA_libndn_c_la_DEPENDENCIES) 
 	$(AM_V_CCLD)$(LINK) -rpath $(libdir) $(libndn_c_la_OBJECTS) $(libndn_c_la_LIBADD) $(LIBS)
@@ -941,6 +948,9 @@
 ndn-cpp/security/certificate/certificate-subject-description.lo:  \
 	ndn-cpp/security/certificate/$(am__dirstamp) \
 	ndn-cpp/security/certificate/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/security/certificate/certificate.lo:  \
+	ndn-cpp/security/certificate/$(am__dirstamp) \
+	ndn-cpp/security/certificate/$(DEPDIR)/$(am__dirstamp)
 ndn-cpp/security/certificate/identity-certificate.lo:  \
 	ndn-cpp/security/certificate/$(am__dirstamp) \
 	ndn-cpp/security/certificate/$(DEPDIR)/$(am__dirstamp)
@@ -1119,6 +1129,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/util/$(DEPDIR)/dynamic-uint8-array.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/util/$(DEPDIR)/ndn_memory.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/util/$(DEPDIR)/ndn_realloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/util/$(DEPDIR)/time.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/$(DEPDIR)/binary-xml-wire-format.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/$(DEPDIR)/element-listener.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/$(DEPDIR)/oid.Plo@am__quote@
@@ -1132,6 +1143,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/security/$(DEPDIR)/security-exception.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/security/certificate/$(DEPDIR)/certificate-extension.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/security/certificate/$(DEPDIR)/certificate-subject-description.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/security/certificate/$(DEPDIR)/certificate.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/security/certificate/$(DEPDIR)/identity-certificate.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/security/certificate/$(DEPDIR)/public-key.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/security/identity/$(DEPDIR)/basic-identity-storage.Plo@am__quote@
diff --git a/include/ndn-cpp/security/certificate/certificate.hpp b/include/ndn-cpp/security/certificate/certificate.hpp
index 270bfb0..21745e2 100644
--- a/include/ndn-cpp/security/certificate/certificate.hpp
+++ b/include/ndn-cpp/security/certificate/certificate.hpp
@@ -32,17 +32,13 @@
    * Create a Certificate from the content in the data packet.
    * @param data The data packet with the content to decode.
    */
-#if 0 // TODO: Define in certificate.cpp
   Certificate(const Data& data);
-#else
-  Certificate(const Data& data) {}
-#endif
  
   /**
    * The virtual destructor.
    */
   virtual 
-  ~Certificate() {}
+  ~Certificate();
 
   /**
    * encode certificate info into content
diff --git a/ndn-cpp/security/certificate/certificate.cpp b/ndn-cpp/security/certificate/certificate.cpp
new file mode 100644
index 0000000..9a01424
--- /dev/null
+++ b/ndn-cpp/security/certificate/certificate.cpp
@@ -0,0 +1,152 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include <float.h>
+#include <ndn-cpp/sha256-with-rsa-signature.hpp>
+#if 0
+#include "../../encoding/der/visitor/certificate-data-visitor.hpp"
+#include "../../encoding/der/visitor/print-visitor.hpp"
+#endif
+#include "../../util/logging.hpp"
+#include "../../c/util/time.h"
+#include <ndn-cpp/security/certificate/certificate.hpp>
+
+INIT_LOGGER("ndn.security.Certificate");
+
+using namespace std;
+using namespace ndn::ptr_lib;
+
+namespace ndn {
+
+Certificate::Certificate()
+  : notBefore_(DBL_MAX)
+  , notAfter_(-DBL_MAX)
+{}
+
+Certificate::Certificate(const Data& data)
+// Use the copy constructor.  It clones the signature object.
+: Data(data)
+{
+  // _LOG_DEBUG("Finish local copy: " << getContent().getContent().size());
+
+  decode();
+}
+
+Certificate::~Certificate()
+{
+  //TODO:
+}
+
+bool
+Certificate::isTooEarly()
+{
+  Time now = ndn_getNowMilliseconds();
+  if(now < notBefore_)
+    return true;
+  else
+    return false;
+}
+
+bool 
+Certificate::isTooLate()
+{
+  Time now = ndn_getNowMilliseconds();
+  if(now > notAfter_)
+    return true;
+  else
+    return false;
+}
+
+#if 0
+void
+Certificate::encode()
+{
+  Ptr<der::DerSequence> root = Ptr<der::DerSequence>::Create();
+  
+  Ptr<der::DerSequence> validity = Ptr<der::DerSequence>::Create();
+  Ptr<der::DerGtime> notBefore = Ptr<der::DerGtime>(new der::DerGtime(notBefore_));
+  Ptr<der::DerGtime> notAfter = Ptr<der::DerGtime>(new der::DerGtime(notAfter_));
+  validity->addChild(notBefore);
+  validity->addChild(notAfter);
+  root->addChild(validity);
+
+  Ptr<der::DerSequence> subjectList = Ptr<der::DerSequence>::Create();
+  SubDescryptList::iterator it = m_subjectList.begin();
+  for(; it != m_subjectList.end(); it++)
+    {
+      Ptr<der::DerNode> child = it->toDER();
+      subjectList->addChild(child);
+    }
+  root->addChild(subjectList);
+
+  root->addChild(key_.toDER());
+
+  if(!m_extnList.empty())
+    {
+      Ptr<der::DerSequence> extnList = Ptr<der::DerSequence>::Create();
+      ExtensionList::iterator it = m_extnList.begin();
+      for(; it != m_extnList.end(); it++)
+        extnList->addChild(it->toDER());
+      root->addChild(extnList);
+    }
+
+  blob_stream blobStream;
+  OutputIterator& start = reinterpret_cast<OutputIterator&>(blobStream);
+
+  root->encode(start);
+
+  Ptr<Blob> blob = blobStream.buf();
+  Content content(blob->buf(), blob->size());
+  setContent(content);
+}
+#endif
+
+void 
+Certificate::decode()
+{
+#if 0
+  Blob blob = getContent();
+
+  boost::iostreams::stream
+    <boost::iostreams::array_source> is(blob.buf(), blob.size());
+
+  shared_ptr<der::DerNode> node = der::DerNode::parse(reinterpret_cast<InputIterator&>(is));
+
+  // der::PrintVisitor printVisitor;
+  // node->accept(printVisitor, string(""));
+
+  der::CertificateDataVisitor certDataVisitor;
+  node->accept(certDataVisitor, this);
+#endif
+}
+
+#if 0
+void 
+Certificate::printCertificate()
+{
+  cout << "Validity:" << endl;
+  cout << notBefore_ << endl;
+  cout << notAfter_ << endl;
+
+  cout << "Subject Info:" << endl;  
+  vector<CertificateSubDescrypt>::iterator it = m_subjectList.begin();
+  for(; it < m_subjectList.end(); it++){
+    cout << it->getOidStr() << "\t" << it->getValue() << endl;
+  }
+
+  boost::iostreams::stream
+    <boost::iostreams::array_source> is(key_.getKeyBlob().buf (), m_key.getKeyBlob().size ());
+
+  Ptr<der::DerNode> keyRoot = der::DerNode::parse(reinterpret_cast<InputIterator&> (is));
+
+  der::PrintVisitor printVisitor;
+  keyRoot->accept(printVisitor, string(""));
+}
+#endif
+
+}