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 Destuguesstatic time_t
21385a7d89SAdrien Destuguesparse_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) {
303b657701SAdrien 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;
345ebdc799SAdrien Destugues
353b657701SAdrien Destugues		return mktime(&time);
363b657701SAdrien Destugues	}
375ebdc799SAdrien Destugues	return B_BAD_DATA;
385ebdc799SAdrien Destugues}
395ebdc799SAdrien Destugues
405ebdc799SAdrien Destugues
41385a7d89SAdrien Destuguesstatic BString
42385a7d89SAdrien Destuguesdecode_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 DestuguesBCertificate::BCertificate(Private* data)
565ebdc799SAdrien Destugues{
575ebdc799SAdrien Destugues	fPrivate = data;
585ebdc799SAdrien Destugues}
595ebdc799SAdrien Destugues
605ebdc799SAdrien Destugues
616c32f50aSAdrien DestuguesBCertificate::BCertificate(const BCertificate& other)
626c32f50aSAdrien Destugues{
634849ab6cSAdrien Destugues	fPrivate = new(std::nothrow) BCertificate::Private(other.fPrivate->fX509);
646c32f50aSAdrien Destugues}
656c32f50aSAdrien Destugues
666c32f50aSAdrien Destugues
675ebdc799SAdrien DestuguesBCertificate::~BCertificate()
685ebdc799SAdrien Destugues{
695ebdc799SAdrien Destugues	delete fPrivate;
705ebdc799SAdrien Destugues}
715ebdc799SAdrien Destugues
725ebdc799SAdrien Destugues
73c86ad7f9SAdrien Destuguesint
746c32f50aSAdrien DestuguesBCertificate::Version() const
755ebdc799SAdrien Destugues{
76c86ad7f9SAdrien Destugues	return X509_get_version(fPrivate->fX509) + 1;
775ebdc799SAdrien Destugues}
785ebdc799SAdrien Destugues
795ebdc799SAdrien Destugues
8067af469eSAdrien Destuguestime_t
816c32f50aSAdrien DestuguesBCertificate::StartDate() const
825ebdc799SAdrien Destugues{
835ebdc799SAdrien Destugues	return parse_ASN1(X509_get_notBefore(fPrivate->fX509));
845ebdc799SAdrien Destugues}
855ebdc799SAdrien Destugues
865ebdc799SAdrien Destugues
8767af469eSAdrien Destuguestime_t
886c32f50aSAdrien DestuguesBCertificate::ExpirationDate() const
895ebdc799SAdrien Destugues{
905ebdc799SAdrien Destugues	return parse_ASN1(X509_get_notAfter(fPrivate->fX509));
915ebdc799SAdrien Destugues}
925ebdc799SAdrien Destugues
935ebdc799SAdrien Destugues
94c86ad7f9SAdrien Destuguesbool
956c32f50aSAdrien DestuguesBCertificate::IsValidAuthority() const
96c86ad7f9SAdrien Destugues{
97c86ad7f9SAdrien Destugues	return X509_check_ca(fPrivate->fX509) > 0;
98c86ad7f9SAdrien Destugues}
99c86ad7f9SAdrien Destugues
100c86ad7f9SAdrien Destugues
101c86ad7f9SAdrien Destuguesbool
1026c32f50aSAdrien DestuguesBCertificate::IsSelfSigned() const
103c86ad7f9SAdrien Destugues{
104c86ad7f9SAdrien Destugues	return X509_check_issued(fPrivate->fX509, fPrivate->fX509) == X509_V_OK;
105c86ad7f9SAdrien Destugues}
106c86ad7f9SAdrien Destugues
107c86ad7f9SAdrien Destugues
1085ebdc799SAdrien DestuguesBString
1096c32f50aSAdrien DestuguesBCertificate::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 DestuguesBString
1176c32f50aSAdrien DestuguesBCertificate::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 DestuguesBString
1256c32f50aSAdrien DestuguesBCertificate::SignatureAlgorithm() const
126c86ad7f9SAdrien Destugues{
127c86ad7f9SAdrien Destugues	int algorithmIdentifier = OBJ_obj2nid(
128c86ad7f9SAdrien Destugues		fPrivate->fX509->cert_info->key->algor->algorithm);
129c86ad7f9SAdrien Destugues
130c86ad7f9SAdrien Destugues	if (algorithmIdentifier == NID_undef)
131c86ad7f9SAdrien Destugues		return BString("undefined");
132c86ad7f9SAdrien Destugues
133c86ad7f9SAdrien Destugues	const char* buffer = OBJ_nid2ln(algorithmIdentifier);
134c86ad7f9SAdrien Destugues	return BString(buffer);
135c86ad7f9SAdrien Destugues}
136c86ad7f9SAdrien Destugues
137c86ad7f9SAdrien Destugues
138c86ad7f9SAdrien DestuguesBString
1396c32f50aSAdrien DestuguesBCertificate::String() const
140c86ad7f9SAdrien Destugues{
141c86ad7f9SAdrien Destugues	BIO *buffer = BIO_new(BIO_s_mem());
142c86ad7f9SAdrien Destugues	X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
143c86ad7f9SAdrien Destugues
144c86ad7f9SAdrien Destugues	char* pointer;
145c86ad7f9SAdrien Destugues	long length = BIO_get_mem_data(buffer, &pointer);
146c86ad7f9SAdrien Destugues	BString result(pointer, length);
147c86ad7f9SAdrien Destugues
148c86ad7f9SAdrien Destugues	BIO_free(buffer);
149c86ad7f9SAdrien Destugues	return result;
150c86ad7f9SAdrien Destugues}
151c86ad7f9SAdrien Destugues
152c86ad7f9SAdrien Destugues
1536c32f50aSAdrien Destuguesbool
1544849ab6cSAdrien DestuguesBCertificate::operator==(const BCertificate& other) const
1556c32f50aSAdrien Destugues{
156f26dbfe7SAdrien 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 DestuguesBCertificate::Private::Private(X509* data)
1646c32f50aSAdrien Destugues	: fX509(X509_dup(data))
1656c32f50aSAdrien Destugues{
1666c32f50aSAdrien Destugues}
1676c32f50aSAdrien Destugues
1686c32f50aSAdrien Destugues
1696c32f50aSAdrien DestuguesBCertificate::Private::~Private()
1705ebdc799SAdrien Destugues{
1714849ab6cSAdrien Destugues	X509_free(fX509);
1725ebdc799SAdrien Destugues}
173159d1fb6SAdrien Destugues
1743b657701SAdrien Destugues
175159d1fb6SAdrien Destugues#else
176159d1fb6SAdrien Destugues
177159d1fb6SAdrien Destugues
1786c32f50aSAdrien DestuguesBCertificate::BCertificate(const BCertificate& other)
1796c32f50aSAdrien Destugues{
1806c32f50aSAdrien Destugues}
1816c32f50aSAdrien Destugues
1826c32f50aSAdrien Destugues
183159d1fb6SAdrien DestuguesBCertificate::BCertificate(Private* data)
184159d1fb6SAdrien Destugues{
185159d1fb6SAdrien Destugues}
186159d1fb6SAdrien Destugues
187159d1fb6SAdrien Destugues
188159d1fb6SAdrien DestuguesBCertificate::~BCertificate()
189159d1fb6SAdrien Destugues{
190159d1fb6SAdrien Destugues}
191159d1fb6SAdrien Destugues
192159d1fb6SAdrien Destugues
193c86ad7f9SAdrien Destuguestime_t
1946c32f50aSAdrien DestuguesBCertificate::StartDate() const
195159d1fb6SAdrien Destugues{
196c86ad7f9SAdrien Destugues	return B_NOT_SUPPORTED;
197159d1fb6SAdrien Destugues}
198159d1fb6SAdrien Destugues
199159d1fb6SAdrien Destugues
20067af469eSAdrien Destuguestime_t
2016c32f50aSAdrien DestuguesBCertificate::ExpirationDate() const
202159d1fb6SAdrien Destugues{
203159d1fb6SAdrien Destugues	return B_NOT_SUPPORTED;
204159d1fb6SAdrien Destugues}
205159d1fb6SAdrien Destugues
206159d1fb6SAdrien Destugues
207c86ad7f9SAdrien Destuguesbool
2086c32f50aSAdrien DestuguesBCertificate::IsValidAuthority() const
209c86ad7f9SAdrien Destugues{
210c86ad7f9SAdrien Destugues	return false;
211c86ad7f9SAdrien Destugues}
212c86ad7f9SAdrien Destugues
213c86ad7f9SAdrien Destugues
214c86ad7f9SAdrien Destuguesint
2156c32f50aSAdrien DestuguesBCertificate::Version() const
216159d1fb6SAdrien Destugues{
217159d1fb6SAdrien Destugues	return B_NOT_SUPPORTED;
218159d1fb6SAdrien Destugues}
219159d1fb6SAdrien Destugues
220159d1fb6SAdrien Destugues
221159d1fb6SAdrien DestuguesBString
2226c32f50aSAdrien DestuguesBCertificate::Issuer() const
223159d1fb6SAdrien Destugues{
224159d1fb6SAdrien Destugues	return BString();
225159d1fb6SAdrien Destugues}
226159d1fb6SAdrien Destugues
227159d1fb6SAdrien Destugues
228159d1fb6SAdrien DestuguesBString
2296c32f50aSAdrien DestuguesBCertificate::Subject() const
230159d1fb6SAdrien Destugues{
23176b3c7f4SAdrien Destugues	return BString();
232159d1fb6SAdrien Destugues}
233159d1fb6SAdrien Destugues
234159d1fb6SAdrien Destugues
235c86ad7f9SAdrien DestuguesBString
2366c32f50aSAdrien DestuguesBCertificate::SignatureAlgorithm() const
237c86ad7f9SAdrien Destugues{
238c86ad7f9SAdrien Destugues	return BString();
239c86ad7f9SAdrien Destugues}
240c86ad7f9SAdrien Destugues
241c86ad7f9SAdrien Destugues
242c86ad7f9SAdrien DestuguesBString
2436c32f50aSAdrien DestuguesBCertificate::String() const
244c86ad7f9SAdrien Destugues{
245c86ad7f9SAdrien Destugues	return BString();
246c86ad7f9SAdrien Destugues}
247c86ad7f9SAdrien Destugues
248c86ad7f9SAdrien Destugues
2496c32f50aSAdrien Destuguesbool
2504849ab6cSAdrien DestuguesBCertificate::operator==(const BCertificate& other) const
2516c32f50aSAdrien Destugues{
2526c32f50aSAdrien Destugues	return false;
2536c32f50aSAdrien Destugues}
2546c32f50aSAdrien Destugues
255159d1fb6SAdrien Destugues#endif
256