xref: /haiku/src/kits/network/libnetapi/Certificate.cpp (revision 97dfeb96704e5dbc5bec32ad7b21379d0125e031)
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_get_notBefore(fPrivate->fX509));
84 }
85 
86 
87 time_t
88 BCertificate::ExpirationDate() const
89 {
90 	return parse_ASN1(X509_get_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 = OBJ_obj2nid(
128 		fPrivate->fX509->cert_info->key->algor->algorithm);
129 
130 	if (algorithmIdentifier == NID_undef)
131 		return BString("undefined");
132 
133 	const char* buffer = OBJ_nid2ln(algorithmIdentifier);
134 	return BString(buffer);
135 }
136 
137 
138 BString
139 BCertificate::String() const
140 {
141 	BIO *buffer = BIO_new(BIO_s_mem());
142 	X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
143 
144 	char* pointer;
145 	long length = BIO_get_mem_data(buffer, &pointer);
146 	BString result(pointer, length);
147 
148 	BIO_free(buffer);
149 	return result;
150 }
151 
152 
153 bool
154 BCertificate::operator==(const BCertificate& other) const
155 {
156 	return X509_cmp(fPrivate->fX509, other.fPrivate->fX509) == 0;
157 }
158 
159 
160 // #pragma mark - BCertificate::Private
161 
162 
163 BCertificate::Private::Private(X509* data)
164 	: fX509(X509_dup(data))
165 {
166 }
167 
168 
169 BCertificate::Private::~Private()
170 {
171 	X509_free(fX509);
172 }
173 
174 
175 #else
176 
177 
178 BCertificate::BCertificate(const BCertificate& other)
179 {
180 }
181 
182 
183 BCertificate::BCertificate(Private* data)
184 {
185 }
186 
187 
188 BCertificate::~BCertificate()
189 {
190 }
191 
192 
193 time_t
194 BCertificate::StartDate() const
195 {
196 	return B_NOT_SUPPORTED;
197 }
198 
199 
200 time_t
201 BCertificate::ExpirationDate() const
202 {
203 	return B_NOT_SUPPORTED;
204 }
205 
206 
207 bool
208 BCertificate::IsValidAuthority() const
209 {
210 	return false;
211 }
212 
213 
214 int
215 BCertificate::Version() const
216 {
217 	return B_NOT_SUPPORTED;
218 }
219 
220 
221 BString
222 BCertificate::Issuer() const
223 {
224 	return BString();
225 }
226 
227 
228 BString
229 BCertificate::Subject() const
230 {
231 	return BString();
232 }
233 
234 
235 BString
236 BCertificate::SignatureAlgorithm() const
237 {
238 	return BString();
239 }
240 
241 
242 BString
243 BCertificate::String() const
244 {
245 	return BString();
246 }
247 
248 
249 bool
250 BCertificate::operator==(const BCertificate& other) const
251 {
252 	return false;
253 }
254 
255 #endif
256