xref: /haiku/src/kits/network/libnetapi/Certificate.cpp (revision ca8ed5ea660fb6275799a3b7f138b201c41a667b)
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()
62 {
63 	delete fPrivate;
64 }
65 
66 
67 int
68 BCertificate::Version()
69 {
70 	return X509_get_version(fPrivate->fX509) + 1;
71 }
72 
73 
74 time_t
75 BCertificate::StartDate()
76 {
77 	return parse_ASN1(X509_get_notBefore(fPrivate->fX509));
78 }
79 
80 
81 time_t
82 BCertificate::ExpirationDate()
83 {
84 	return parse_ASN1(X509_get_notAfter(fPrivate->fX509));
85 }
86 
87 
88 bool
89 BCertificate::IsValidAuthority()
90 {
91 	return X509_check_ca(fPrivate->fX509) > 0;
92 }
93 
94 
95 bool
96 BCertificate::IsSelfSigned()
97 {
98 	return X509_check_issued(fPrivate->fX509, fPrivate->fX509) == X509_V_OK;
99 }
100 
101 
102 BString
103 BCertificate::Issuer()
104 {
105 	X509_NAME* name = X509_get_issuer_name(fPrivate->fX509);
106 	return decode_X509_NAME(name);
107 }
108 
109 
110 BString
111 BCertificate::Subject()
112 {
113 	X509_NAME* name = X509_get_subject_name(fPrivate->fX509);
114 	return decode_X509_NAME(name);
115 }
116 
117 
118 BString
119 BCertificate::SignatureAlgorithm()
120 {
121 	int algorithmIdentifier = OBJ_obj2nid(
122 		fPrivate->fX509->cert_info->key->algor->algorithm);
123 
124 	if (algorithmIdentifier == NID_undef)
125 		return BString("undefined");
126 
127 	const char* buffer = OBJ_nid2ln(algorithmIdentifier);
128 	return BString(buffer);
129 }
130 
131 
132 BString
133 BCertificate::String()
134 {
135 	BIO *buffer = BIO_new(BIO_s_mem());
136 	X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
137 
138 	char* pointer;
139 	long length = BIO_get_mem_data(buffer, &pointer);
140 	BString result(pointer, length);
141 
142 	BIO_free(buffer);
143 	return result;
144 }
145 
146 
147 // #pragma mark - BCertificate::Private
148 
149 
150 BCertificate::Private::Private(X509* data)
151 	: fX509(data)
152 {
153 }
154 
155 
156 #else
157 
158 
159 BCertificate::BCertificate(Private* data)
160 {
161 }
162 
163 
164 BCertificate::~BCertificate()
165 {
166 }
167 
168 
169 time_t
170 BCertificate::StartDate()
171 {
172 	return B_NOT_SUPPORTED;
173 }
174 
175 
176 time_t
177 BCertificate::ExpirationDate()
178 {
179 	return B_NOT_SUPPORTED;
180 }
181 
182 
183 bool
184 BCertificate::IsValidAuthority()
185 {
186 	return false;
187 }
188 
189 
190 int
191 BCertificate::Version()
192 {
193 	return B_NOT_SUPPORTED;
194 }
195 
196 
197 BString
198 BCertificate::Issuer()
199 {
200 	return BString();
201 }
202 
203 
204 BString
205 BCertificate::Subject()
206 {
207 	return BString();
208 }
209 
210 
211 BString
212 BCertificate::SignatureAlgorithm()
213 {
214 	return BString();
215 }
216 
217 
218 BString
219 BCertificate::String()
220 {
221 	return BString();
222 }
223 
224 
225 #endif
226