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