diff --git a/src/security/v1/certificate.cpp b/src/security/v1/certificate.cpp
new file mode 100644
index 0000000..823c994
--- /dev/null
+++ b/src/security/v1/certificate.cpp
@@ -0,0 +1,359 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ * @author Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ */
+
+#include "certificate.hpp"
+#include "../../util/time.hpp"
+#include "cryptopp.hpp"
+#include "../../encoding/cryptopp/asn_ext.hpp"
+#include "../../encoding/buffer-stream.hpp"
+#include "../../util/concepts.hpp"
+#include "../../util/indented-stream.hpp"
+
+#include <boost/algorithm/string/split.hpp>
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+BOOST_CONCEPT_ASSERT((WireEncodable<Certificate>));
+BOOST_CONCEPT_ASSERT((WireDecodable<Certificate>));
+static_assert(std::is_base_of<tlv::Error, Certificate::Error>::value,
+              "Certificate::Error must inherit from tlv::Error");
+
+Certificate::Certificate()
+  : m_notBefore(time::system_clock::TimePoint::max())
+  , m_notAfter(time::system_clock::TimePoint::min())
+{
+}
+
+Certificate::Certificate(const Data& data)
+  // Use the copy constructor.  It clones the signature object.
+  : Data(data)
+{
+  decode();
+}
+
+Certificate::Certificate(const Block& block)
+  : Data(block)
+{
+  decode();
+}
+
+Certificate::~Certificate()
+{
+}
+
+void
+Certificate::wireDecode(const Block& wire)
+{
+  Data::wireDecode(wire);
+  decode();
+}
+
+bool
+Certificate::isTooEarly()
+{
+  if (time::system_clock::now() < m_notBefore)
+    return true;
+  else
+    return false;
+}
+
+bool
+Certificate::isTooLate()
+{
+  if (time::system_clock::now() > m_notAfter)
+    return true;
+  else
+    return false;
+}
+
+void
+Certificate::encode()
+{
+  // Name
+  //    <key_name>/ID-CERT/<id#>
+  // Content
+  // DER encoded idCert:
+  //
+  //    idCert ::= SEQUENCE {
+  //        validity            Validity,
+  //        subject             Name,
+  //        subjectPubKeyInfo   SubjectPublicKeyInfo,
+  //        extension           Extensions OPTIONAL   }
+  //
+  //    Validity ::= SEQUENCE {
+  //        notBefore           Time,
+  //        notAfter            Time   }
+  //
+  //    Name ::= CHOICE {
+  //        RDNSequence   }
+  //
+  //    RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+  //
+  //    RelativeDistinguishedName ::=
+  //        SET OF AttributeTypeAndValue
+  //
+  //    SubjectPublicKeyInfo ::= SEQUENCE {
+  //        algorithm           AlgorithmIdentifier
+  //        keybits             BIT STRING   }
+  //
+  //    Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+  //
+  // (see http://www.ietf.org/rfc/rfc3280.txt for more detail)
+  //
+  // KeyLocator
+  //    issuer’s certificate name
+  // Signature
+
+  using namespace CryptoPP;
+
+  OBufferStream os;
+  CryptoPP::FileSink sink(os);
+
+  // idCert ::= SEQUENCE {
+  //     validity            Validity,
+  //     subject             Name,
+  //     subjectPubKeyInfo   SubjectPublicKeyInfo,
+  //     extension           Extensions OPTIONAL   }
+  DERSequenceEncoder idCert(sink);
+  {
+    // Validity ::= SEQUENCE {
+    //       notBefore           Time,
+    //       notAfter            Time   }
+    DERSequenceEncoder validity(idCert);
+    {
+      DEREncodeGeneralTime(validity, m_notBefore);
+      DEREncodeGeneralTime(validity, m_notAfter);
+    }
+    validity.MessageEnd();
+
+    // Name ::= CHOICE {
+    //     RDNSequence   }
+    //
+    // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+    DERSequenceEncoder name(idCert);
+    {
+      for (SubjectDescriptionList::iterator it = m_subjectDescriptionList.begin();
+           it != m_subjectDescriptionList.end(); ++it)
+        {
+          it->encode(name);
+        }
+    }
+    name.MessageEnd();
+
+    // SubjectPublicKeyInfo
+    m_key.encode(idCert);
+
+    // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+    //
+    // Extension ::= SEQUENCE {
+    //        extnID      OBJECT IDENTIFIER,
+    //        critical    BOOLEAN DEFAULT FALSE,
+    //        extnValue   OCTET STRING  }
+    if (!m_extensionList.empty())
+      {
+        DERSequenceEncoder extensions(idCert);
+        {
+          for (ExtensionList::iterator it = m_extensionList.begin();
+               it != m_extensionList.end(); ++it)
+            {
+              it->encode(extensions);
+            }
+        }
+        extensions.MessageEnd();
+      }
+  }
+
+  idCert.MessageEnd();
+
+  setContent(os.buf());
+  setContentType(tlv::ContentType_Key);
+}
+
+void
+Certificate::decode()
+{
+  using namespace CryptoPP;
+
+  try {
+    OBufferStream os;
+    StringSource source(getContent().value(), getContent().value_size(), true);
+
+    // idCert ::= SEQUENCE {
+    //     validity            Validity,
+    //     subject             Name,
+    //     subjectPubKeyInfo   SubjectPublicKeyInfo,
+    //     extension           Extensions OPTIONAL   }
+    BERSequenceDecoder idCert(source);
+    {
+      // Validity ::= SEQUENCE {
+      //       notBefore           Time,
+      //       notAfter            Time   }
+      BERSequenceDecoder validity(idCert);
+      {
+        BERDecodeTime(validity, m_notBefore);
+        BERDecodeTime(validity, m_notAfter);
+      }
+      validity.MessageEnd();
+
+      // Name ::= CHOICE {
+      //     RDNSequence   }
+      //
+      // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+      m_subjectDescriptionList.clear();
+      BERSequenceDecoder name(idCert);
+      {
+        while (!name.EndReached())
+          {
+            m_subjectDescriptionList.push_back(CertificateSubjectDescription(name));
+          }
+      }
+      name.MessageEnd();
+
+      // SubjectPublicKeyInfo ::= SEQUENCE {
+      //     algorithm           AlgorithmIdentifier
+      //     keybits             BIT STRING   }
+      m_key.decode(idCert);
+
+      // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+      //
+      // Extension ::= SEQUENCE {
+      //        extnID      OBJECT IDENTIFIER,
+      //        critical    BOOLEAN DEFAULT FALSE,
+      //        extnValue   OCTET STRING  }
+      m_extensionList.clear();
+      if (!idCert.EndReached())
+        {
+          BERSequenceDecoder extensions(idCert);
+          {
+            while (!extensions.EndReached())
+              {
+                m_extensionList.push_back(CertificateExtension(extensions));
+              }
+          }
+          extensions.MessageEnd();
+        }
+    }
+
+    idCert.MessageEnd();
+  }
+  catch (CryptoPP::BERDecodeErr&) {
+    BOOST_THROW_EXCEPTION(Error("Certificate Decoding Error"));
+  }
+}
+
+void
+Certificate::printCertificate(std::ostream& oss, const std::string& indent) const
+{
+  util::IndentedStream os(oss, indent);
+
+  os << "Certificate name:\n";
+  os << "  " << getName() << "\n";
+  os << "Validity:\n";
+  {
+    os << "  NotBefore: " << time::toIsoString(m_notBefore) << "\n";
+    os << "  NotAfter: "  << time::toIsoString(m_notAfter)  << "\n";
+  }
+
+  os << "Subject Description:\n";
+  for (const auto& description : m_subjectDescriptionList)
+    os << "  " << description.getOidString() << ": " << description.getValue() << "\n";
+
+  os << "Public key bits: ";
+  switch (m_key.getKeyType()) {
+  case KeyType::RSA:
+    os << "(RSA)";
+    break;
+  case KeyType::EC:
+    os << "(ECDSA)";
+    break;
+  default:
+    os << "(Unknown key type)";
+    break;
+  }
+  os << "\n";
+
+  {
+    util::IndentedStream os2(os, "  ");
+    CryptoPP::Base64Encoder encoder(new CryptoPP::FileSink(os2), true, 64);
+    m_key.encode(encoder);
+  }
+
+  os << "Signature Information:\n";
+  {
+    os << "  Signature Type: ";
+    switch (getSignature().getType()) {
+    case tlv::SignatureTypeValue::DigestSha256:
+      os << "DigestSha256";
+      break;
+    case tlv::SignatureTypeValue::SignatureSha256WithRsa:
+      os << "SignatureSha256WithRsa";
+      break;
+    case tlv::SignatureTypeValue::SignatureSha256WithEcdsa:
+      os << "SignatureSha256WithEcdsa";
+      break;
+    default:
+      os << "Unknown Signature Type";
+    }
+    os << "\n";
+
+    if (getSignature().hasKeyLocator()) {
+      const KeyLocator& keyLocator = getSignature().getKeyLocator();
+      os << "  Key Locator: ";
+      switch (keyLocator.getType()) {
+      case KeyLocator::KeyLocator_Name:
+        {
+          const Name& signerName = keyLocator.getName();
+          if (signerName.isPrefixOf(getName()))
+            os << "(Self-Signed) " << keyLocator.getName();
+          else
+            os << "(Name) " << keyLocator.getName();
+          break;
+        }
+      case KeyLocator::KeyLocator_KeyDigest:
+        os << "(KeyDigest)";
+        break;
+      case KeyLocator::KeyLocator_None:
+        os << "None";
+        break;
+      default:
+        os << "Unknown";
+      }
+      os << "\n";
+    }
+  }
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Certificate& cert)
+{
+  cert.printCertificate(os);
+  return os;
+}
+
+} // namespace v1
+} // namespace security
+} // namespace ndn
