xref: /haiku/src/kits/network/libnetapi/Certificate.cpp (revision 6c32f50a645c8bbb774ae2cd4f38779dd91c1d2e)
15ebdc799SAdrien Destugues /*
25ebdc799SAdrien Destugues  * Copyright 2014 Haiku, Inc.
35ebdc799SAdrien Destugues  * Distributed under the terms of the MIT License.
45ebdc799SAdrien Destugues  */
55ebdc799SAdrien Destugues 
65ebdc799SAdrien Destugues 
75ebdc799SAdrien Destugues #include <Certificate.h>
85ebdc799SAdrien Destugues 
95ebdc799SAdrien Destugues #include <String.h>
105ebdc799SAdrien Destugues 
115ebdc799SAdrien Destugues #include "CertificatePrivate.h"
125ebdc799SAdrien Destugues 
135ebdc799SAdrien Destugues 
14159d1fb6SAdrien Destugues #ifdef OPENSSL_ENABLED
15159d1fb6SAdrien Destugues 
16159d1fb6SAdrien Destugues 
17*c86ad7f9SAdrien Destugues #include <openssl/x509v3.h>
18*c86ad7f9SAdrien Destugues 
19*c86ad7f9SAdrien Destugues 
20385a7d89SAdrien Destugues static time_t
21385a7d89SAdrien Destugues parse_ASN1(ASN1_GENERALIZEDTIME *asn1)
225ebdc799SAdrien Destugues {
235ebdc799SAdrien Destugues 	// Get the raw string data out of the ASN1 container. It looks like this:
245ebdc799SAdrien Destugues 	// "YYMMDDHHMMSSZ"
255ebdc799SAdrien Destugues 	struct tm time;
265ebdc799SAdrien Destugues 
275ebdc799SAdrien Destugues 	if (sscanf((char*)asn1->data, "%2d%2d%2d%2d%2d%2d", &time.tm_year,
285ebdc799SAdrien Destugues 			&time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min,
293b657701SAdrien Destugues 			&time.tm_sec) == 6) {
305ebdc799SAdrien Destugues 
313b657701SAdrien Destugues 		// Month is 0 based, and year is 1900-based for mktime.
323b657701SAdrien Destugues 		time.tm_year += 100;
333b657701SAdrien Destugues 		time.tm_mon -= 1;
343b657701SAdrien Destugues 
353b657701SAdrien Destugues 		return mktime(&time);
363b657701SAdrien Destugues 	}
375ebdc799SAdrien Destugues 	return B_BAD_DATA;
385ebdc799SAdrien Destugues }
395ebdc799SAdrien Destugues 
405ebdc799SAdrien Destugues 
41385a7d89SAdrien Destugues static BString
42385a7d89SAdrien Destugues decode_X509_NAME(X509_NAME* name)
435ebdc799SAdrien Destugues {
443b657701SAdrien Destugues 	char* buffer = X509_NAME_oneline(name, NULL, 0);
455ebdc799SAdrien Destugues 
463b657701SAdrien Destugues 	BString result(buffer);
473b657701SAdrien Destugues 	OPENSSL_free(buffer);
483b657701SAdrien Destugues 	return result;
495ebdc799SAdrien Destugues }
505ebdc799SAdrien Destugues 
515ebdc799SAdrien Destugues 
525ebdc799SAdrien Destugues // #pragma mark - BCertificate
535ebdc799SAdrien Destugues 
545ebdc799SAdrien Destugues 
555ebdc799SAdrien Destugues BCertificate::BCertificate(Private* data)
565ebdc799SAdrien Destugues {
575ebdc799SAdrien Destugues 	fPrivate = data;
585ebdc799SAdrien Destugues }
595ebdc799SAdrien Destugues 
605ebdc799SAdrien Destugues 
616c32f50aSAdrien Destugues BCertificate::BCertificate(const BCertificate& other)
626c32f50aSAdrien Destugues {
636c32f50aSAdrien Destugues 	fPrivate = new<std::nothrow>BCertificate::Private(other.fPrivate);
646c32f50aSAdrien Destugues }
656c32f50aSAdrien Destugues 
666c32f50aSAdrien Destugues 
675ebdc799SAdrien Destugues BCertificate::~BCertificate()
685ebdc799SAdrien Destugues {
695ebdc799SAdrien Destugues 	delete fPrivate;
705ebdc799SAdrien Destugues }
715ebdc799SAdrien Destugues 
725ebdc799SAdrien Destugues 
73*c86ad7f9SAdrien Destugues int
746c32f50aSAdrien Destugues BCertificate::Version() const
755ebdc799SAdrien Destugues {
76*c86ad7f9SAdrien Destugues 	return X509_get_version(fPrivate->fX509) + 1;
775ebdc799SAdrien Destugues }
785ebdc799SAdrien Destugues 
795ebdc799SAdrien Destugues 
8067af469eSAdrien Destugues time_t
816c32f50aSAdrien Destugues BCertificate::StartDate() const
825ebdc799SAdrien Destugues {
835ebdc799SAdrien Destugues 	return parse_ASN1(X509_get_notBefore(fPrivate->fX509));
845ebdc799SAdrien Destugues }
855ebdc799SAdrien Destugues 
865ebdc799SAdrien Destugues 
8767af469eSAdrien Destugues time_t
886c32f50aSAdrien Destugues BCertificate::ExpirationDate() const
895ebdc799SAdrien Destugues {
905ebdc799SAdrien Destugues 	return parse_ASN1(X509_get_notAfter(fPrivate->fX509));
915ebdc799SAdrien Destugues }
925ebdc799SAdrien Destugues 
935ebdc799SAdrien Destugues 
94*c86ad7f9SAdrien Destugues bool
956c32f50aSAdrien Destugues BCertificate::IsValidAuthority() const
96*c86ad7f9SAdrien Destugues {
97*c86ad7f9SAdrien Destugues 	return X509_check_ca(fPrivate->fX509) > 0;
98*c86ad7f9SAdrien Destugues }
99*c86ad7f9SAdrien Destugues 
100*c86ad7f9SAdrien Destugues 
101*c86ad7f9SAdrien Destugues bool
1026c32f50aSAdrien Destugues BCertificate::IsSelfSigned() const
103*c86ad7f9SAdrien Destugues {
104*c86ad7f9SAdrien Destugues 	return X509_check_issued(fPrivate->fX509, fPrivate->fX509) == X509_V_OK;
105*c86ad7f9SAdrien Destugues }
106*c86ad7f9SAdrien Destugues 
107*c86ad7f9SAdrien Destugues 
1085ebdc799SAdrien Destugues BString
1096c32f50aSAdrien Destugues BCertificate::Issuer() const
1105ebdc799SAdrien Destugues {
1115ebdc799SAdrien Destugues 	X509_NAME* name = X509_get_issuer_name(fPrivate->fX509);
1125ebdc799SAdrien Destugues 	return decode_X509_NAME(name);
1135ebdc799SAdrien Destugues }
1145ebdc799SAdrien Destugues 
1155ebdc799SAdrien Destugues 
1165ebdc799SAdrien Destugues BString
1176c32f50aSAdrien Destugues BCertificate::Subject() const
1185ebdc799SAdrien Destugues {
1195ebdc799SAdrien Destugues 	X509_NAME* name = X509_get_subject_name(fPrivate->fX509);
1205ebdc799SAdrien Destugues 	return decode_X509_NAME(name);
1215ebdc799SAdrien Destugues }
1225ebdc799SAdrien Destugues 
1235ebdc799SAdrien Destugues 
124*c86ad7f9SAdrien Destugues BString
1256c32f50aSAdrien Destugues BCertificate::SignatureAlgorithm() const
126*c86ad7f9SAdrien Destugues {
127*c86ad7f9SAdrien Destugues 	int algorithmIdentifier = OBJ_obj2nid(
128*c86ad7f9SAdrien Destugues 		fPrivate->fX509->cert_info->key->algor->algorithm);
129*c86ad7f9SAdrien Destugues 
130*c86ad7f9SAdrien Destugues 	if (algorithmIdentifier == NID_undef)
131*c86ad7f9SAdrien Destugues 		return BString("undefined");
132*c86ad7f9SAdrien Destugues 
133*c86ad7f9SAdrien Destugues 	const char* buffer = OBJ_nid2ln(algorithmIdentifier);
134*c86ad7f9SAdrien Destugues 	return BString(buffer);
135*c86ad7f9SAdrien Destugues }
136*c86ad7f9SAdrien Destugues 
137*c86ad7f9SAdrien Destugues 
138*c86ad7f9SAdrien Destugues BString
1396c32f50aSAdrien Destugues BCertificate::String() const
140*c86ad7f9SAdrien Destugues {
141*c86ad7f9SAdrien Destugues 	BIO *buffer = BIO_new(BIO_s_mem());
142*c86ad7f9SAdrien Destugues 	X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
143*c86ad7f9SAdrien Destugues 
144*c86ad7f9SAdrien Destugues 	char* pointer;
145*c86ad7f9SAdrien Destugues 	long length = BIO_get_mem_data(buffer, &pointer);
146*c86ad7f9SAdrien Destugues 	BString result(pointer, length);
147*c86ad7f9SAdrien Destugues 
148*c86ad7f9SAdrien Destugues 	BIO_free(buffer);
149*c86ad7f9SAdrien Destugues 	return result;
150*c86ad7f9SAdrien Destugues }
151*c86ad7f9SAdrien Destugues 
152*c86ad7f9SAdrien Destugues 
1536c32f50aSAdrien Destugues bool
1546c32f50aSAdrien Destugues BCertificate::operator==(const BCertificate& other)
1556c32f50aSAdrien Destugues {
1566c32f50aSAdrien Destugues 	return X509_cmp(fPrivate.fX509, other.fPrivate.fX509) == 0;
1576c32f50aSAdrien Destugues }
1586c32f50aSAdrien Destugues 
1596c32f50aSAdrien Destugues 
1605ebdc799SAdrien Destugues // #pragma mark - BCertificate::Private
1615ebdc799SAdrien Destugues 
1625ebdc799SAdrien Destugues 
1635ebdc799SAdrien Destugues BCertificate::Private::Private(X509* data)
1646c32f50aSAdrien Destugues 	: fX509(X509_dup(data))
1655ebdc799SAdrien Destugues {
1665ebdc799SAdrien Destugues }
167159d1fb6SAdrien Destugues 
1683b657701SAdrien Destugues 
1696c32f50aSAdrien Destugues BCertificate::Private::~Private()
1706c32f50aSAdrien Destugues {
1716c32f50aSAdrien Destugues 	sk_X509_pop_free(chain, X509_free)
1726c32f50aSAdrien Destugues }
1736c32f50aSAdrien Destugues 
1746c32f50aSAdrien Destugues 
175159d1fb6SAdrien Destugues #else
176159d1fb6SAdrien Destugues 
177159d1fb6SAdrien Destugues 
1786c32f50aSAdrien Destugues BCertificate::BCertificate(const BCertificate& other)
1796c32f50aSAdrien Destugues {
1806c32f50aSAdrien Destugues }
1816c32f50aSAdrien Destugues 
1826c32f50aSAdrien Destugues 
183159d1fb6SAdrien Destugues BCertificate::BCertificate(Private* data)
184159d1fb6SAdrien Destugues {
185159d1fb6SAdrien Destugues }
186159d1fb6SAdrien Destugues 
187159d1fb6SAdrien Destugues 
188159d1fb6SAdrien Destugues BCertificate::~BCertificate()
189159d1fb6SAdrien Destugues {
190159d1fb6SAdrien Destugues }
191159d1fb6SAdrien Destugues 
192159d1fb6SAdrien Destugues 
19367af469eSAdrien Destugues time_t
1946c32f50aSAdrien Destugues BCertificate::StartDate() const
195159d1fb6SAdrien Destugues {
196159d1fb6SAdrien Destugues 	return B_NOT_SUPPORTED;
197159d1fb6SAdrien Destugues }
198159d1fb6SAdrien Destugues 
199159d1fb6SAdrien Destugues 
20067af469eSAdrien Destugues time_t
2016c32f50aSAdrien Destugues BCertificate::ExpirationDate() const
202159d1fb6SAdrien Destugues {
203159d1fb6SAdrien Destugues 	return B_NOT_SUPPORTED;
204159d1fb6SAdrien Destugues }
205159d1fb6SAdrien Destugues 
206159d1fb6SAdrien Destugues 
207*c86ad7f9SAdrien Destugues bool
2086c32f50aSAdrien Destugues BCertificate::IsValidAuthority() const
209*c86ad7f9SAdrien Destugues {
210*c86ad7f9SAdrien Destugues 	return false;
211*c86ad7f9SAdrien Destugues }
212*c86ad7f9SAdrien Destugues 
213*c86ad7f9SAdrien Destugues 
214*c86ad7f9SAdrien Destugues int
2156c32f50aSAdrien Destugues BCertificate::Version() const
216*c86ad7f9SAdrien Destugues {
217*c86ad7f9SAdrien Destugues 	return B_NOT_SUPPORTED;
218*c86ad7f9SAdrien Destugues }
219*c86ad7f9SAdrien Destugues 
220*c86ad7f9SAdrien Destugues 
221159d1fb6SAdrien Destugues BString
2226c32f50aSAdrien Destugues BCertificate::Issuer() const
223159d1fb6SAdrien Destugues {
224159d1fb6SAdrien Destugues 	return BString();
225159d1fb6SAdrien Destugues }
226159d1fb6SAdrien Destugues 
227159d1fb6SAdrien Destugues 
228159d1fb6SAdrien Destugues BString
2296c32f50aSAdrien Destugues BCertificate::Subject() const
230159d1fb6SAdrien Destugues {
23176b3c7f4SAdrien Destugues 	return BString();
232159d1fb6SAdrien Destugues }
233159d1fb6SAdrien Destugues 
234159d1fb6SAdrien Destugues 
235*c86ad7f9SAdrien Destugues BString
2366c32f50aSAdrien Destugues BCertificate::SignatureAlgorithm() const
237*c86ad7f9SAdrien Destugues {
238*c86ad7f9SAdrien Destugues 	return BString();
239*c86ad7f9SAdrien Destugues }
240*c86ad7f9SAdrien Destugues 
241*c86ad7f9SAdrien Destugues 
242*c86ad7f9SAdrien Destugues BString
2436c32f50aSAdrien Destugues BCertificate::String() const
244*c86ad7f9SAdrien Destugues {
245*c86ad7f9SAdrien Destugues 	return BString();
246*c86ad7f9SAdrien Destugues }
247*c86ad7f9SAdrien Destugues 
248*c86ad7f9SAdrien Destugues 
2496c32f50aSAdrien Destugues bool
2506c32f50aSAdrien Destugues BCertificate::operator==(const BCertificate& other)
2516c32f50aSAdrien Destugues {
2526c32f50aSAdrien Destugues 	return false;
2536c32f50aSAdrien Destugues }
2546c32f50aSAdrien Destugues 
255159d1fb6SAdrien Destugues #endif
256