blob: eb45d6f75eb2dfb6f6270c2688ce73d0572826b7 [file] [log] [blame]
Jeff Thompsona5dc3512013-10-17 10:26:19 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
6 * See COPYING for copyright and distribution information.
7 */
8
Alexander Afanasyev09c613f2014-01-29 00:23:58 -08009#include "common.hpp"
Alexander Afanasyev8e96e582013-11-19 12:07:04 -080010
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080011#include "certificate.hpp"
Alexander Afanasyev8e96e582013-11-19 12:07:04 -080012
Yingdi Yu4f324632014-01-15 18:10:03 -080013#include "../util/logging.hpp"
14#include "../util/time.hpp"
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080015
Junxiao Shi482ccc52014-03-31 13:05:24 -070016#include "cryptopp.hpp"
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080017
Yingdi Yu4f324632014-01-15 18:10:03 -080018#include "../encoding/cryptopp/asn_ext.hpp"
Jeff Thompsona5dc3512013-10-17 10:26:19 -070019
Yingdi Yu21157162014-02-28 13:02:34 -080020INIT_LOGGER("ndn.Certificate");
Jeff Thompsona5dc3512013-10-17 10:26:19 -070021
22using namespace std;
Jeff Thompsona5dc3512013-10-17 10:26:19 -070023
24namespace ndn {
25
26Certificate::Certificate()
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070027 : notBefore_(time::system_clock::TimePoint::max())
28 , notAfter_(time::system_clock::TimePoint::min())
Jeff Thompsona5dc3512013-10-17 10:26:19 -070029{}
30
31Certificate::Certificate(const Data& data)
32// Use the copy constructor. It clones the signature object.
33: Data(data)
34{
35 // _LOG_DEBUG("Finish local copy: " << getContent().getContent().size());
36
37 decode();
38}
39
40Certificate::~Certificate()
41{
42 //TODO:
43}
44
45bool
46Certificate::isTooEarly()
47{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070048 if(time::system_clock::now() < notBefore_)
Jeff Thompsona5dc3512013-10-17 10:26:19 -070049 return true;
50 else
51 return false;
52}
53
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070054bool
Jeff Thompsona5dc3512013-10-17 10:26:19 -070055Certificate::isTooLate()
56{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070057 if(time::system_clock::now() > notAfter_)
Jeff Thompsona5dc3512013-10-17 10:26:19 -070058 return true;
59 else
60 return false;
61}
62
Jeff Thompsona5dc3512013-10-17 10:26:19 -070063void
64Certificate::encode()
65{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080066 // Name
67 // <key_name>/ID-CERT/<id#>
68 // Content
69 // DER encoded idCert:
70 //
71 // idCert ::= SEQUENCE {
72 // validity Validity,
73 // subject Name,
74 // subjectPubKeyInfo SubjectPublicKeyInfo,
75 // extension Extensions OPTIONAL }
76 //
77 // Validity ::= SEQUENCE {
78 // notBefore Time,
79 // notAfter Time }
80 //
81 // Name ::= CHOICE {
82 // RDNSequence }
83 //
84 // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
85 //
86 // RelativeDistinguishedName ::=
87 // SET OF AttributeTypeAndValue
88 //
89 // SubjectPublicKeyInfo ::= SEQUENCE {
90 // algorithm AlgorithmIdentifier
91 // keybits BIT STRING }
92 //
93 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
94 //
95 // (see http://www.ietf.org/rfc/rfc3280.txt for more detail)
96 //
97 // KeyLocator
98 // issuer’s certificate name
99 // Signature
100
101 using namespace CryptoPP;
102
103 OBufferStream os;
104 CryptoPP::FileSink sink(os);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700105
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800106 // idCert ::= SEQUENCE {
107 // validity Validity,
108 // subject Name,
109 // subjectPubKeyInfo SubjectPublicKeyInfo,
110 // extension Extensions OPTIONAL }
111 DERSequenceEncoder idCert(sink);
112 {
113 // Validity ::= SEQUENCE {
114 // notBefore Time,
115 // notAfter Time }
116 DERSequenceEncoder validity(idCert);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700117 {
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800118 DEREncodeGeneralTime(validity, notBefore_);
119 DEREncodeGeneralTime(validity, notAfter_);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700120 }
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800121 validity.MessageEnd();
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700122
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800123 // Name ::= CHOICE {
124 // RDNSequence }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700125 //
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800126 // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
127 DERSequenceEncoder name(idCert);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700128 {
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800129 for(SubjectDescriptionList::iterator it = subjectDescriptionList_.begin();
130 it != subjectDescriptionList_.end(); ++it)
131 {
132 it->encode(name);
133 }
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700134 }
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800135 name.MessageEnd();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700136
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800137 // SubjectPublicKeyInfo
138 key_.encode(idCert);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700139
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800140 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
141 //
142 // Extension ::= SEQUENCE {
143 // extnID OBJECT IDENTIFIER,
144 // critical BOOLEAN DEFAULT FALSE,
145 // extnValue OCTET STRING }
146 if(!extensionList_.empty())
147 {
148 DERSequenceEncoder extensions(idCert);
149 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700150
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800151 for(ExtensionList::iterator it = extensionList_.begin();
152 it != extensionList_.end(); ++it)
153 {
154 it->encode(extensions);
155 }
156 }
157 extensions.MessageEnd();
158 }
159 }
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700160
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800161 idCert.MessageEnd();
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700162
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800163 setContent(os.buf());
164 setContentType(MetaInfo::TYPE_KEY);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700165}
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700166
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700167void
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700168Certificate::decode()
169{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800170 using namespace CryptoPP;
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700171
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800172 OBufferStream os;
173 CryptoPP::StringSource source(getContent().value(), getContent().value_size(), true);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700174
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800175 // idCert ::= SEQUENCE {
176 // validity Validity,
177 // subject Name,
178 // subjectPubKeyInfo SubjectPublicKeyInfo,
179 // extension Extensions OPTIONAL }
180 BERSequenceDecoder idCert(source);
181 {
182 // Validity ::= SEQUENCE {
183 // notBefore Time,
184 // notAfter Time }
185 BERSequenceDecoder validity(idCert);
186 {
187 BERDecodeTime(validity, notBefore_);
188 BERDecodeTime(validity, notAfter_);
189 }
190 validity.MessageEnd();
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700191
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800192 // Name ::= CHOICE {
193 // RDNSequence }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700194 //
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800195 // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
196 subjectDescriptionList_.clear();
197 BERSequenceDecoder name(idCert);
198 {
199 while(!name.EndReached())
200 {
201 subjectDescriptionList_.push_back(CertificateSubjectDescription(name));
202 }
203 }
204 name.MessageEnd();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700205
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800206 // SubjectPublicKeyInfo ::= SEQUENCE {
207 // algorithm AlgorithmIdentifier
208 // keybits BIT STRING }
209 key_.decode(idCert);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700210
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800211 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
212 //
213 // Extension ::= SEQUENCE {
214 // extnID OBJECT IDENTIFIER,
215 // critical BOOLEAN DEFAULT FALSE,
216 // extnValue OCTET STRING }
217 extensionList_.clear();
218 if(!idCert.EndReached())
219 {
220 BERSequenceDecoder extensions(idCert);
221 {
222 while(!extensions.EndReached())
223 {
224 extensionList_.push_back(CertificateExtension(extensions));
225 }
226 }
227 extensions.MessageEnd();
228 }
229 }
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700230
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800231 idCert.MessageEnd();
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700232}
233
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700234void
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800235Certificate::printCertificate(std::ostream &os) const
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700236{
Alexander Afanasyev049f8f72013-12-26 19:07:15 -0800237 os << "Certificate name:" << endl;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800238 os << " " << getName() << endl;
239 os << "Validity:" << endl;
240 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700241 os << " NotBefore: " << time::toIsoString(notBefore_) << endl;
242 os << " NotAfter: " << time::toIsoString(notAfter_) << endl;
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700243 }
244
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700245 os << "Subject Description:" << endl;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800246 for(SubjectDescriptionList::const_iterator it = subjectDescriptionList_.begin();
247 it != subjectDescriptionList_.end(); ++it)
248 {
249 os << " " << it->getOidString() << ": " << it->getValue() << endl;
250 }
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700251
Alexander Afanasyev049f8f72013-12-26 19:07:15 -0800252 os << "Public key bits:" << endl;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800253 CryptoPP::Base64Encoder encoder(new CryptoPP::FileSink(os), true, 64);
254 key_.encode(encoder);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700255
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800256 // ndnboost::iostreams::stream<ndnboost::iostreams::array_source> is((const char*)key_.getKeyDer().buf(), key_.getKeyDer().size());
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700257
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800258 // ptr_lib::shared_ptr<der::DerNode> keyRoot = der::DerNode::parse(reinterpret_cast<der::InputIterator&> (is));
259
260 // der::PrintVisitor printVisitor;
261 // keyRoot->accept(printVisitor, string(""));
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700262}
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700263
Yingdi Yufc40d872014-02-18 12:56:04 -0800264} // namespace ndn