1 //
2 // X509Certificate.h
3 //
4 // Library: Crypto
5 // Package: Certificate
6 // Module: X509Certificate
7 //
8 // Definition of the X509Certificate class.
9 //
10 // Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
11 // and Contributors.
12 //
13 // SPDX-License-Identifier: BSL-1.0
14 //
15
16
17 #ifndef Crypto_X509Certificate_INCLUDED
18 #define Crypto_X509Certificate_INCLUDED
19
20
21 #include "Poco/Crypto/Crypto.h"
22 #include "Poco/Crypto/OpenSSLInitializer.h"
23 #include "Poco/DateTime.h"
24 #include "Poco/SharedPtr.h"
25 #include <vector>
26 #include <set>
27 #include <istream>
28 #include <openssl/ssl.h>
29
30
31 namespace Poco {
32 namespace Crypto {
33
34
35 class Crypto_API X509Certificate
36 /// This class represents a X509 Certificate.
37 {
38 public:
39 using List = std::vector<X509Certificate>;
40
41 enum NID
42 /// Name identifier for extracting information from
43 /// a certificate subject's or issuer's distinguished name.
44 {
45 NID_COMMON_NAME = 13,
46 NID_COUNTRY = 14,
47 NID_LOCALITY_NAME = 15,
48 NID_STATE_OR_PROVINCE = 16,
49 NID_ORGANIZATION_NAME = 17,
50 NID_ORGANIZATION_UNIT_NAME = 18,
51 NID_PKCS9_EMAIL_ADDRESS = 48,
52 NID_SERIAL_NUMBER = 105
53 };
54
55 explicit X509Certificate(std::istream& istr);
56 /// Creates the X509Certificate object by reading
57 /// a certificate in PEM format from a stream.
58
59 explicit X509Certificate(const std::string& path);
60 /// Creates the X509Certificate object by reading
61 /// a certificate in PEM format from a file.
62
63 explicit X509Certificate(X509* pCert);
64 /// Creates the X509Certificate from an existing
65 /// OpenSSL certificate. Ownership is taken of
66 /// the certificate.
67
68 X509Certificate(X509* pCert, bool shared);
69 /// Creates the X509Certificate from an existing
70 /// OpenSSL certificate. Ownership is taken of
71 /// the certificate. If shared is true, the
72 /// certificate's reference count is incremented.
73
74 X509Certificate(const X509Certificate& cert);
75 /// Creates the certificate by copying another one.
76
77 X509Certificate(X509Certificate&& cert) noexcept;
78 /// Creates the certificate by moving another one.
79
80 X509Certificate& operator = (const X509Certificate& cert);
81 /// Assigns a certificate.
82
83 X509Certificate& operator = (X509Certificate&& cert) noexcept;
84 /// Move assignment.
85
86 void swap(X509Certificate& cert);
87 /// Exchanges the certificate with another one.
88
89 ~X509Certificate();
90 /// Destroys the X509Certificate.
91
92 long version() const;
93 /// Returns the version of the certificate.
94
95 const std::string& serialNumber() const;
96 /// Returns the certificate serial number as a
97 /// string in decimal encoding.
98
99 const std::string& issuerName() const;
100 /// Returns the certificate issuer's distinguished name.
101
102 std::string issuerName(NID nid) const;
103 /// Extracts the information specified by the given
104 /// NID (name identifier) from the certificate issuer's
105 /// distinguished name.
106
107 const std::string& subjectName() const;
108 /// Returns the certificate subject's distinguished name.
109
110 std::string subjectName(NID nid) const;
111 /// Extracts the information specified by the given
112 /// NID (name identifier) from the certificate subject's
113 /// distinguished name.
114
115 std::string commonName() const;
116 /// Returns the common name stored in the certificate
117 /// subject's distinguished name.
118
119 void extractNames(std::string& commonName, std::set<std::string>& domainNames) const;
120 /// Extracts the common name and the alias domain names from the
121 /// certificate.
122
123 Poco::DateTime validFrom() const;
124 /// Returns the date and time the certificate is valid from.
125
126 Poco::DateTime expiresOn() const;
127 /// Returns the date and time the certificate expires.
128
129 void save(std::ostream& stream) const;
130 /// Writes the certificate to the given stream.
131 /// The certificate is written in PEM format.
132
133 void save(const std::string& path) const;
134 /// Writes the certificate to the file given by path.
135 /// The certificate is written in PEM format.
136
137 bool issuedBy(const X509Certificate& issuerCertificate) const;
138 /// Checks whether the certificate has been issued by
139 /// the issuer given by issuerCertificate. This can be
140 /// used to validate a certificate chain.
141 ///
142 /// Verifies if the certificate has been signed with the
143 /// issuer's private key, using the public key from the issuer
144 /// certificate.
145 ///
146 /// Returns true if verification against the issuer certificate
147 /// was successful, false otherwise.
148
149 bool equals(const X509Certificate& otherCertificate) const;
150 /// Checks whether the certificate is equal to
151 /// the other certificate, by comparing the hashes
152 /// of both certificates.
153 ///
154 /// Returns true if both certificates are identical,
155 /// otherwise false.
156
157 const X509* certificate() const;
158 /// Returns the underlying OpenSSL certificate.
159
160 X509* dup() const;
161 /// Duplicates and returns the underlying OpenSSL certificate. Note that
162 /// the caller assumes responsibility for the lifecycle of the created
163 /// certificate.
164
165 std::string signatureAlgorithm() const;
166 /// Returns the certificate signature algorithm long name.
167
168 void print(std::ostream& out) const;
169 /// Prints the certificate information to ostream.
170
171 static List readPEM(const std::string& pemFileName);
172 /// Reads and returns a list of certificates from
173 /// the specified PEM file.
174
175 static void writePEM(const std::string& pemFileName, const List& list);
176 /// Writes the list of certificates to the specified PEM file.
177
178 protected:
179 void load(std::istream& stream);
180 /// Loads the certificate from the given stream. The
181 /// certificate must be in PEM format.
182
183 void load(const std::string& path);
184 /// Loads the certificate from the given file. The
185 /// certificate must be in PEM format.
186
187 void init();
188 /// Extracts issuer and subject name from the certificate.
189
190 private:
191 enum
192 {
193 NAME_BUFFER_SIZE = 256
194 };
195
196 std::string _issuerName;
197 std::string _subjectName;
198 std::string _serialNumber;
199 X509* _pCert;
200 OpenSSLInitializer _openSSLInitializer;
201 };
202
203
204 //
205 // inlines
206 //
207
208
version()209 inline long X509Certificate::version() const
210 {
211 // This is defined by standards (X.509 et al) to be
212 // one less than the certificate version.
213 // So, eg. a version 3 certificate will return 2.
214 return X509_get_version(_pCert) + 1;
215 }
216
217
serialNumber()218 inline const std::string& X509Certificate::serialNumber() const
219 {
220 return _serialNumber;
221 }
222
223
issuerName()224 inline const std::string& X509Certificate::issuerName() const
225 {
226 return _issuerName;
227 }
228
229
subjectName()230 inline const std::string& X509Certificate::subjectName() const
231 {
232 return _subjectName;
233 }
234
235
certificate()236 inline const X509* X509Certificate::certificate() const
237 {
238 return _pCert;
239 }
240
241
dup()242 inline X509* X509Certificate::dup() const
243 {
244 return X509_dup(_pCert);
245 }
246
247
248 } } // namespace Poco::Crypto
249
250
251 #endif // Crypto_X509Certificate_INCLUDED
252