xref: /haiku/src/kits/network/libnetapi/Certificate.cpp (revision 0ea56347bdcee47b7db0f5d927fc2fe182d6bd00)
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 
17c86ad7f9SAdrien Destugues #include <openssl/x509v3.h>
18c86ad7f9SAdrien Destugues 
19c86ad7f9SAdrien Destugues 
20385a7d89SAdrien Destugues static time_t
parse_ASN1(ASN1_GENERALIZEDTIME * asn1)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
decode_X509_NAME(X509_NAME * name)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 
BCertificate(Private * data)555ebdc799SAdrien Destugues BCertificate::BCertificate(Private* data)
565ebdc799SAdrien Destugues {
575ebdc799SAdrien Destugues 	fPrivate = data;
585ebdc799SAdrien Destugues }
595ebdc799SAdrien Destugues 
605ebdc799SAdrien Destugues 
BCertificate(const BCertificate & other)616c32f50aSAdrien Destugues BCertificate::BCertificate(const BCertificate& other)
626c32f50aSAdrien Destugues {
634849ab6cSAdrien Destugues 	fPrivate = new(std::nothrow) BCertificate::Private(other.fPrivate->fX509);
646c32f50aSAdrien Destugues }
656c32f50aSAdrien Destugues 
666c32f50aSAdrien Destugues 
~BCertificate()675ebdc799SAdrien Destugues BCertificate::~BCertificate()
685ebdc799SAdrien Destugues {
695ebdc799SAdrien Destugues 	delete fPrivate;
705ebdc799SAdrien Destugues }
715ebdc799SAdrien Destugues 
725ebdc799SAdrien Destugues 
73c86ad7f9SAdrien Destugues int
Version() const746c32f50aSAdrien Destugues BCertificate::Version() const
755ebdc799SAdrien Destugues {
76c86ad7f9SAdrien Destugues 	return X509_get_version(fPrivate->fX509) + 1;
775ebdc799SAdrien Destugues }
785ebdc799SAdrien Destugues 
795ebdc799SAdrien Destugues 
8067af469eSAdrien Destugues time_t
StartDate() const816c32f50aSAdrien Destugues BCertificate::StartDate() const
825ebdc799SAdrien Destugues {
83*0ea56347SPulkoMandy 	return parse_ASN1(X509_getm_notBefore(fPrivate->fX509));
845ebdc799SAdrien Destugues }
855ebdc799SAdrien Destugues 
865ebdc799SAdrien Destugues 
8767af469eSAdrien Destugues time_t
ExpirationDate() const886c32f50aSAdrien Destugues BCertificate::ExpirationDate() const
895ebdc799SAdrien Destugues {
90*0ea56347SPulkoMandy 	return parse_ASN1(X509_getm_notAfter(fPrivate->fX509));
915ebdc799SAdrien Destugues }
925ebdc799SAdrien Destugues 
935ebdc799SAdrien Destugues 
94c86ad7f9SAdrien Destugues bool
IsValidAuthority() const956c32f50aSAdrien Destugues BCertificate::IsValidAuthority() const
96c86ad7f9SAdrien Destugues {
97c86ad7f9SAdrien Destugues 	return X509_check_ca(fPrivate->fX509) > 0;
98c86ad7f9SAdrien Destugues }
99c86ad7f9SAdrien Destugues 
100c86ad7f9SAdrien Destugues 
101c86ad7f9SAdrien Destugues bool
IsSelfSigned() const1026c32f50aSAdrien Destugues BCertificate::IsSelfSigned() const
103c86ad7f9SAdrien Destugues {
104c86ad7f9SAdrien Destugues 	return X509_check_issued(fPrivate->fX509, fPrivate->fX509) == X509_V_OK;
105c86ad7f9SAdrien Destugues }
106c86ad7f9SAdrien Destugues 
107c86ad7f9SAdrien Destugues 
1085ebdc799SAdrien Destugues BString
Issuer() const1096c32f50aSAdrien 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
Subject() const1176c32f50aSAdrien 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 
124c86ad7f9SAdrien Destugues BString
SignatureAlgorithm() const1256c32f50aSAdrien Destugues BCertificate::SignatureAlgorithm() const
126c86ad7f9SAdrien Destugues {
127b8aadcd2SAugustin Cavalier 	int algorithmIdentifier;
128b8aadcd2SAugustin Cavalier 	if (!X509_get_signature_info(fPrivate->fX509, NULL, &algorithmIdentifier,
129b8aadcd2SAugustin Cavalier 			NULL, NULL)) {
130b8aadcd2SAugustin Cavalier 		return BString("invalid");
131b8aadcd2SAugustin Cavalier 	}
132c86ad7f9SAdrien Destugues 
133c86ad7f9SAdrien Destugues 	if (algorithmIdentifier == NID_undef)
134c86ad7f9SAdrien Destugues 		return BString("undefined");
135c86ad7f9SAdrien Destugues 
136c86ad7f9SAdrien Destugues 	const char* buffer = OBJ_nid2ln(algorithmIdentifier);
137c86ad7f9SAdrien Destugues 	return BString(buffer);
138c86ad7f9SAdrien Destugues }
139c86ad7f9SAdrien Destugues 
140c86ad7f9SAdrien Destugues 
141c86ad7f9SAdrien Destugues BString
String() const1426c32f50aSAdrien Destugues BCertificate::String() const
143c86ad7f9SAdrien Destugues {
144c86ad7f9SAdrien Destugues 	BIO *buffer = BIO_new(BIO_s_mem());
145c86ad7f9SAdrien Destugues 	X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
146c86ad7f9SAdrien Destugues 
147c86ad7f9SAdrien Destugues 	char* pointer;
148c86ad7f9SAdrien Destugues 	long length = BIO_get_mem_data(buffer, &pointer);
149c86ad7f9SAdrien Destugues 	BString result(pointer, length);
150c86ad7f9SAdrien Destugues 
151c86ad7f9SAdrien Destugues 	BIO_free(buffer);
152c86ad7f9SAdrien Destugues 	return result;
153c86ad7f9SAdrien Destugues }
154c86ad7f9SAdrien Destugues 
155c86ad7f9SAdrien Destugues 
1566c32f50aSAdrien Destugues bool
operator ==(const BCertificate & other) const1574849ab6cSAdrien Destugues BCertificate::operator==(const BCertificate& other) const
1586c32f50aSAdrien Destugues {
159f26dbfe7SAdrien Destugues 	return X509_cmp(fPrivate->fX509, other.fPrivate->fX509) == 0;
1606c32f50aSAdrien Destugues }
1616c32f50aSAdrien Destugues 
1626c32f50aSAdrien Destugues 
1635ebdc799SAdrien Destugues // #pragma mark - BCertificate::Private
1645ebdc799SAdrien Destugues 
1655ebdc799SAdrien Destugues 
Private(X509 * data)1665ebdc799SAdrien Destugues BCertificate::Private::Private(X509* data)
1676c32f50aSAdrien Destugues 	: fX509(X509_dup(data))
1685ebdc799SAdrien Destugues {
1695ebdc799SAdrien Destugues }
170159d1fb6SAdrien Destugues 
1713b657701SAdrien Destugues 
~Private()1726c32f50aSAdrien Destugues BCertificate::Private::~Private()
1736c32f50aSAdrien Destugues {
1744849ab6cSAdrien Destugues 	X509_free(fX509);
1756c32f50aSAdrien Destugues }
1766c32f50aSAdrien Destugues 
1776c32f50aSAdrien Destugues 
178159d1fb6SAdrien Destugues #else
179159d1fb6SAdrien Destugues 
180159d1fb6SAdrien Destugues 
BCertificate(const BCertificate & other)1816c32f50aSAdrien Destugues BCertificate::BCertificate(const BCertificate& other)
1826c32f50aSAdrien Destugues {
1836c32f50aSAdrien Destugues }
1846c32f50aSAdrien Destugues 
1856c32f50aSAdrien Destugues 
BCertificate(Private * data)186159d1fb6SAdrien Destugues BCertificate::BCertificate(Private* data)
187159d1fb6SAdrien Destugues {
188159d1fb6SAdrien Destugues }
189159d1fb6SAdrien Destugues 
190159d1fb6SAdrien Destugues 
~BCertificate()191159d1fb6SAdrien Destugues BCertificate::~BCertificate()
192159d1fb6SAdrien Destugues {
193159d1fb6SAdrien Destugues }
194159d1fb6SAdrien Destugues 
195159d1fb6SAdrien Destugues 
19667af469eSAdrien Destugues time_t
StartDate() const1976c32f50aSAdrien Destugues BCertificate::StartDate() const
198159d1fb6SAdrien Destugues {
199159d1fb6SAdrien Destugues 	return B_NOT_SUPPORTED;
200159d1fb6SAdrien Destugues }
201159d1fb6SAdrien Destugues 
202159d1fb6SAdrien Destugues 
20367af469eSAdrien Destugues time_t
ExpirationDate() const2046c32f50aSAdrien Destugues BCertificate::ExpirationDate() const
205159d1fb6SAdrien Destugues {
206159d1fb6SAdrien Destugues 	return B_NOT_SUPPORTED;
207159d1fb6SAdrien Destugues }
208159d1fb6SAdrien Destugues 
209159d1fb6SAdrien Destugues 
210c86ad7f9SAdrien Destugues bool
IsValidAuthority() const2116c32f50aSAdrien Destugues BCertificate::IsValidAuthority() const
212c86ad7f9SAdrien Destugues {
213c86ad7f9SAdrien Destugues 	return false;
214c86ad7f9SAdrien Destugues }
215c86ad7f9SAdrien Destugues 
216c86ad7f9SAdrien Destugues 
217c86ad7f9SAdrien Destugues int
Version() const2186c32f50aSAdrien Destugues BCertificate::Version() const
219c86ad7f9SAdrien Destugues {
220c86ad7f9SAdrien Destugues 	return B_NOT_SUPPORTED;
221c86ad7f9SAdrien Destugues }
222c86ad7f9SAdrien Destugues 
223c86ad7f9SAdrien Destugues 
224159d1fb6SAdrien Destugues BString
Issuer() const2256c32f50aSAdrien Destugues BCertificate::Issuer() const
226159d1fb6SAdrien Destugues {
227159d1fb6SAdrien Destugues 	return BString();
228159d1fb6SAdrien Destugues }
229159d1fb6SAdrien Destugues 
230159d1fb6SAdrien Destugues 
231159d1fb6SAdrien Destugues BString
Subject() const2326c32f50aSAdrien Destugues BCertificate::Subject() const
233159d1fb6SAdrien Destugues {
23476b3c7f4SAdrien Destugues 	return BString();
235159d1fb6SAdrien Destugues }
236159d1fb6SAdrien Destugues 
237159d1fb6SAdrien Destugues 
238c86ad7f9SAdrien Destugues BString
SignatureAlgorithm() const2396c32f50aSAdrien Destugues BCertificate::SignatureAlgorithm() const
240c86ad7f9SAdrien Destugues {
241c86ad7f9SAdrien Destugues 	return BString();
242c86ad7f9SAdrien Destugues }
243c86ad7f9SAdrien Destugues 
244c86ad7f9SAdrien Destugues 
245c86ad7f9SAdrien Destugues BString
String() const2466c32f50aSAdrien Destugues BCertificate::String() const
247c86ad7f9SAdrien Destugues {
248c86ad7f9SAdrien Destugues 	return BString();
249c86ad7f9SAdrien Destugues }
250c86ad7f9SAdrien Destugues 
251c86ad7f9SAdrien Destugues 
2526c32f50aSAdrien Destugues bool
operator ==(const BCertificate & other) const2534849ab6cSAdrien Destugues BCertificate::operator==(const BCertificate& other) const
2546c32f50aSAdrien Destugues {
2556c32f50aSAdrien Destugues 	return false;
2566c32f50aSAdrien Destugues }
2576c32f50aSAdrien Destugues 
258159d1fb6SAdrien Destugues #endif
259