blob: 931a40e8440a738688acd38aeb951813fde83a35 [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
16#include <cryptopp/asn.h>
17#include <cryptopp/base64.h>
18#include <cryptopp/files.h>
19
Yingdi Yu4f324632014-01-15 18:10:03 -080020#include "../encoding/cryptopp/asn_ext.hpp"
Jeff Thompsona5dc3512013-10-17 10:26:19 -070021
Yingdi Yu21157162014-02-28 13:02:34 -080022INIT_LOGGER("ndn.Certificate");
Jeff Thompsona5dc3512013-10-17 10:26:19 -070023
24using namespace std;
Jeff Thompsona5dc3512013-10-17 10:26:19 -070025
26namespace ndn {
27
28Certificate::Certificate()
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070029 : notBefore_(time::system_clock::TimePoint::max())
30 , notAfter_(time::system_clock::TimePoint::min())
Jeff Thompsona5dc3512013-10-17 10:26:19 -070031{}
32
33Certificate::Certificate(const Data& data)
34// Use the copy constructor. It clones the signature object.
35: Data(data)
36{
37 // _LOG_DEBUG("Finish local copy: " << getContent().getContent().size());
38
39 decode();
40}
41
42Certificate::~Certificate()
43{
44 //TODO:
45}
46
47bool
48Certificate::isTooEarly()
49{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070050 if(time::system_clock::now() < notBefore_)
Jeff Thompsona5dc3512013-10-17 10:26:19 -070051 return true;
52 else
53 return false;
54}
55
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070056bool
Jeff Thompsona5dc3512013-10-17 10:26:19 -070057Certificate::isTooLate()
58{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070059 if(time::system_clock::now() > notAfter_)
Jeff Thompsona5dc3512013-10-17 10:26:19 -070060 return true;
61 else
62 return false;
63}
64
Jeff Thompsona5dc3512013-10-17 10:26:19 -070065void
66Certificate::encode()
67{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080068 // Name
69 // <key_name>/ID-CERT/<id#>
70 // Content
71 // DER encoded idCert:
72 //
73 // idCert ::= SEQUENCE {
74 // validity Validity,
75 // subject Name,
76 // subjectPubKeyInfo SubjectPublicKeyInfo,
77 // extension Extensions OPTIONAL }
78 //
79 // Validity ::= SEQUENCE {
80 // notBefore Time,
81 // notAfter Time }
82 //
83 // Name ::= CHOICE {
84 // RDNSequence }
85 //
86 // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
87 //
88 // RelativeDistinguishedName ::=
89 // SET OF AttributeTypeAndValue
90 //
91 // SubjectPublicKeyInfo ::= SEQUENCE {
92 // algorithm AlgorithmIdentifier
93 // keybits BIT STRING }
94 //
95 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
96 //
97 // (see http://www.ietf.org/rfc/rfc3280.txt for more detail)
98 //
99 // KeyLocator
100 // issuer’s certificate name
101 // Signature
102
103 using namespace CryptoPP;
104
105 OBufferStream os;
106 CryptoPP::FileSink sink(os);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700107
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800108 // idCert ::= SEQUENCE {
109 // validity Validity,
110 // subject Name,
111 // subjectPubKeyInfo SubjectPublicKeyInfo,
112 // extension Extensions OPTIONAL }
113 DERSequenceEncoder idCert(sink);
114 {
115 // Validity ::= SEQUENCE {
116 // notBefore Time,
117 // notAfter Time }
118 DERSequenceEncoder validity(idCert);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700119 {
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800120 DEREncodeGeneralTime(validity, notBefore_);
121 DEREncodeGeneralTime(validity, notAfter_);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700122 }
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800123 validity.MessageEnd();
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700124
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800125 // Name ::= CHOICE {
126 // RDNSequence }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700127 //
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800128 // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
129 DERSequenceEncoder name(idCert);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700130 {
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800131 for(SubjectDescriptionList::iterator it = subjectDescriptionList_.begin();
132 it != subjectDescriptionList_.end(); ++it)
133 {
134 it->encode(name);
135 }
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700136 }
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800137 name.MessageEnd();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700138
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800139 // SubjectPublicKeyInfo
140 key_.encode(idCert);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700141
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800142 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
143 //
144 // Extension ::= SEQUENCE {
145 // extnID OBJECT IDENTIFIER,
146 // critical BOOLEAN DEFAULT FALSE,
147 // extnValue OCTET STRING }
148 if(!extensionList_.empty())
149 {
150 DERSequenceEncoder extensions(idCert);
151 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700152
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800153 for(ExtensionList::iterator it = extensionList_.begin();
154 it != extensionList_.end(); ++it)
155 {
156 it->encode(extensions);
157 }
158 }
159 extensions.MessageEnd();
160 }
161 }
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700162
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800163 idCert.MessageEnd();
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700164
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800165 setContent(os.buf());
166 setContentType(MetaInfo::TYPE_KEY);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700167}
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700168
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700169void
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700170Certificate::decode()
171{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800172 using namespace CryptoPP;
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700173
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800174 OBufferStream os;
175 CryptoPP::StringSource source(getContent().value(), getContent().value_size(), true);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700176
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800177 // idCert ::= SEQUENCE {
178 // validity Validity,
179 // subject Name,
180 // subjectPubKeyInfo SubjectPublicKeyInfo,
181 // extension Extensions OPTIONAL }
182 BERSequenceDecoder idCert(source);
183 {
184 // Validity ::= SEQUENCE {
185 // notBefore Time,
186 // notAfter Time }
187 BERSequenceDecoder validity(idCert);
188 {
189 BERDecodeTime(validity, notBefore_);
190 BERDecodeTime(validity, notAfter_);
191 }
192 validity.MessageEnd();
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700193
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800194 // Name ::= CHOICE {
195 // RDNSequence }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700196 //
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800197 // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
198 subjectDescriptionList_.clear();
199 BERSequenceDecoder name(idCert);
200 {
201 while(!name.EndReached())
202 {
203 subjectDescriptionList_.push_back(CertificateSubjectDescription(name));
204 }
205 }
206 name.MessageEnd();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700207
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800208 // SubjectPublicKeyInfo ::= SEQUENCE {
209 // algorithm AlgorithmIdentifier
210 // keybits BIT STRING }
211 key_.decode(idCert);
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700212
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800213 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
214 //
215 // Extension ::= SEQUENCE {
216 // extnID OBJECT IDENTIFIER,
217 // critical BOOLEAN DEFAULT FALSE,
218 // extnValue OCTET STRING }
219 extensionList_.clear();
220 if(!idCert.EndReached())
221 {
222 BERSequenceDecoder extensions(idCert);
223 {
224 while(!extensions.EndReached())
225 {
226 extensionList_.push_back(CertificateExtension(extensions));
227 }
228 }
229 extensions.MessageEnd();
230 }
231 }
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700232
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800233 idCert.MessageEnd();
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700234}
235
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700236void
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800237Certificate::printCertificate(std::ostream &os) const
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700238{
Alexander Afanasyev049f8f72013-12-26 19:07:15 -0800239 os << "Certificate name:" << endl;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800240 os << " " << getName() << endl;
241 os << "Validity:" << endl;
242 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700243 os << " NotBefore: " << time::toIsoString(notBefore_) << endl;
244 os << " NotAfter: " << time::toIsoString(notAfter_) << endl;
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700245 }
246
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700247 os << "Subject Description:" << endl;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800248 for(SubjectDescriptionList::const_iterator it = subjectDescriptionList_.begin();
249 it != subjectDescriptionList_.end(); ++it)
250 {
251 os << " " << it->getOidString() << ": " << it->getValue() << endl;
252 }
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700253
Alexander Afanasyev049f8f72013-12-26 19:07:15 -0800254 os << "Public key bits:" << endl;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800255 CryptoPP::Base64Encoder encoder(new CryptoPP::FileSink(os), true, 64);
256 key_.encode(encoder);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700257
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800258 // ndnboost::iostreams::stream<ndnboost::iostreams::array_source> is((const char*)key_.getKeyDer().buf(), key_.getKeyDer().size());
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700259
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800260 // ptr_lib::shared_ptr<der::DerNode> keyRoot = der::DerNode::parse(reinterpret_cast<der::InputIterator&> (is));
261
262 // der::PrintVisitor printVisitor;
263 // keyRoot->accept(printVisitor, string(""));
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700264}
Jeff Thompsona5dc3512013-10-17 10:26:19 -0700265
Yingdi Yufc40d872014-02-18 12:56:04 -0800266} // namespace ndn