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