xref: /haiku/src/kits/network/libnetapi/Certificate.cpp (revision eea5774f46bba925156498abf9cb1a1165647bf7)
1 /*
2  * Copyright 2014 Haiku, Inc.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <Certificate.h>
8 
9 #include <String.h>
10 
11 #include "CertificatePrivate.h"
12 
13 
14 #ifdef OPENSSL_ENABLED
15 
16 
17 #include <openssl/x509v3.h>
18 
19 
20 static time_t
21 parse_ASN1(ASN1_GENERALIZEDTIME *asn1)
22 {
23 	// Get the raw string data out of the ASN1 container. It looks like this:
24 	// "YYMMDDHHMMSSZ"
25 	struct tm time;
26 
27 	if (sscanf((char*)asn1->data, "%2d%2d%2d%2d%2d%2d", &time.tm_year,
28 			&time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min,
29 			&time.tm_sec) == 6) {
30 
31 		// Month is 0 based, and year is 1900-based for mktime.
32 		time.tm_year += 100;
33 		time.tm_mon -= 1;
34 
35 		return mktime(&time);
36 	}
37 	return B_BAD_DATA;
38 }
39 
40 
41 static BString
42 decode_X509_NAME(X509_NAME* name)
43 {
44 	char* buffer = X509_NAME_oneline(name, NULL, 0);
45 
46 	BString result(buffer);
47 	OPENSSL_free(buffer);
48 	return result;
49 }
50 
51 
52 // #pragma mark - BCertificate
53 
54 
55 BCertificate::BCertificate(Private* data)
56 {
57 	fPrivate = data;
58 }
59 
60 
61 BCertificate::BCertificate(const BCertificate& other)
62 {
63 	fPrivate = new(std::nothrow) BCertificate::Private(other.fPrivate->fX509);
64 }
65 
66 
67 BCertificate::~BCertificate()
68 {
69 	delete fPrivate;
70 }
71 
72 
73 int
74 BCertificate::Version() const
75 {
76 	return X509_get_version(fPrivate->fX509) + 1;
77 }
78 
79 
80 time_t
81 BCertificate::StartDate() const
82 {
83 	return parse_ASN1(X509_getm_notBefore(fPrivate->fX509));
84 }
85 
86 
87 time_t
88 BCertificate::ExpirationDate() const
89 {
90 	return parse_ASN1(X509_getm_notAfter(fPrivate->fX509));
91 }
92 
93 
94 bool
95 BCertificate::IsValidAuthority() const
96 {
97 	return X509_check_ca(fPrivate->fX509) > 0;
98 }
99 
100 
101 bool
102 BCertificate::IsSelfSigned() const
103 {
104 	return X509_check_issued(fPrivate->fX509, fPrivate->fX509) == X509_V_OK;
105 }
106 
107 
108 BString
109 BCertificate::Issuer() const
110 {
111 	X509_NAME* name = X509_get_issuer_name(fPrivate->fX509);
112 	return decode_X509_NAME(name);
113 }
114 
115 
116 BString
117 BCertificate::Subject() const
118 {
119 	X509_NAME* name = X509_get_subject_name(fPrivate->fX509);
120 	return decode_X509_NAME(name);
121 }
122 
123 
124 BString
125 BCertificate::SignatureAlgorithm() const
126 {
127 	int algorithmIdentifier;
128 	if (!X509_get_signature_info(fPrivate->fX509, NULL, &algorithmIdentifier,
129 			NULL, NULL)) {
130 		return BString("invalid");
131 	}
132 
133 	if (algorithmIdentifier == NID_undef)
134 		return BString("undefined");
135 
136 	const char* buffer = OBJ_nid2ln(algorithmIdentifier);
137 	return BString(buffer);
138 }
139 
140 
141 BString
142 BCertificate::String() const
143 {
144 	BIO *buffer = BIO_new(BIO_s_mem());
145 	X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
146 
147 	char* pointer;
148 	long length = BIO_get_mem_data(buffer, &pointer);
149 	BString result(pointer, length);
150 
151 	BIO_free(buffer);
152 	return result;
153 }
154 
155 
156 bool
157 BCertificate::operator==(const BCertificate& other) const
158 {
159 	return X509_cmp(fPrivate->fX509, other.fPrivate->fX509) == 0;
160 }
161 
162 
163 // #pragma mark - BCertificate::Private
164 
165 
166 BCertificate::Private::Private(X509* data)
167 	: fX509(X509_dup(data))
168 {
169 }
170 
171 
172 BCertificate::Private::~Private()
173 {
174 	X509_free(fX509);
175 }
176 
177 
178 #else
179 
180 
181 BCertificate::BCertificate(const BCertificate& other)
182 {
183 }
184 
185 
186 BCertificate::BCertificate(Private* data)
187 {
188 }
189 
190 
191 BCertificate::~BCertificate()
192 {
193 }
194 
195 
196 time_t
197 BCertificate::StartDate() const
198 {
199 	return B_NOT_SUPPORTED;
200 }
201 
202 
203 time_t
204 BCertificate::ExpirationDate() const
205 {
206 	return B_NOT_SUPPORTED;
207 }
208 
209 
210 bool
211 BCertificate::IsValidAuthority() const
212 {
213 	return false;
214 }
215 
216 
217 int
218 BCertificate::Version() const
219 {
220 	return B_NOT_SUPPORTED;
221 }
222 
223 
224 BString
225 BCertificate::Issuer() const
226 {
227 	return BString();
228 }
229 
230 
231 BString
232 BCertificate::Subject() const
233 {
234 	return BString();
235 }
236 
237 
238 BString
239 BCertificate::SignatureAlgorithm() const
240 {
241 	return BString();
242 }
243 
244 
245 BString
246 BCertificate::String() const
247 {
248 	return BString();
249 }
250 
251 
252 bool
253 BCertificate::operator==(const BCertificate& other) const
254 {
255 	return false;
256 }
257 
258 #endif
259