1 /* 2 * Copyright 2014 Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <Certificate.h> 8 9 #include <String.h> 10 11 #include "CertificatePrivate.h" 12 13 14 #ifdef OPENSSL_ENABLED 15 16 17 #include <openssl/x509v3.h> 18 19 20 static time_t 21 parse_ASN1(ASN1_GENERALIZEDTIME *asn1) 22 { 23 // Get the raw string data out of the ASN1 container. It looks like this: 24 // "YYMMDDHHMMSSZ" 25 struct tm time; 26 27 if (sscanf((char*)asn1->data, "%2d%2d%2d%2d%2d%2d", &time.tm_year, 28 &time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min, 29 &time.tm_sec) == 6) { 30 31 // Month is 0 based, and year is 1900-based for mktime. 32 time.tm_year += 100; 33 time.tm_mon -= 1; 34 35 return mktime(&time); 36 } 37 return B_BAD_DATA; 38 } 39 40 41 static BString 42 decode_X509_NAME(X509_NAME* name) 43 { 44 char* buffer = X509_NAME_oneline(name, NULL, 0); 45 46 BString result(buffer); 47 OPENSSL_free(buffer); 48 return result; 49 } 50 51 52 // #pragma mark - BCertificate 53 54 55 BCertificate::BCertificate(Private* data) 56 { 57 fPrivate = data; 58 } 59 60 61 BCertificate::BCertificate(const BCertificate& other) 62 { 63 fPrivate = new(std::nothrow) BCertificate::Private(other.fPrivate->fX509); 64 } 65 66 67 BCertificate::~BCertificate() 68 { 69 delete fPrivate; 70 } 71 72 73 int 74 BCertificate::Version() const 75 { 76 return X509_get_version(fPrivate->fX509) + 1; 77 } 78 79 80 time_t 81 BCertificate::StartDate() const 82 { 83 return parse_ASN1(X509_get_notBefore(fPrivate->fX509)); 84 } 85 86 87 time_t 88 BCertificate::ExpirationDate() const 89 { 90 return parse_ASN1(X509_get_notAfter(fPrivate->fX509)); 91 } 92 93 94 bool 95 BCertificate::IsValidAuthority() const 96 { 97 return X509_check_ca(fPrivate->fX509) > 0; 98 } 99 100 101 bool 102 BCertificate::IsSelfSigned() const 103 { 104 return X509_check_issued(fPrivate->fX509, fPrivate->fX509) == X509_V_OK; 105 } 106 107 108 BString 109 BCertificate::Issuer() const 110 { 111 X509_NAME* name = X509_get_issuer_name(fPrivate->fX509); 112 return decode_X509_NAME(name); 113 } 114 115 116 BString 117 BCertificate::Subject() const 118 { 119 X509_NAME* name = X509_get_subject_name(fPrivate->fX509); 120 return decode_X509_NAME(name); 121 } 122 123 124 BString 125 BCertificate::SignatureAlgorithm() const 126 { 127 int algorithmIdentifier = OBJ_obj2nid( 128 fPrivate->fX509->cert_info->key->algor->algorithm); 129 130 if (algorithmIdentifier == NID_undef) 131 return BString("undefined"); 132 133 const char* buffer = OBJ_nid2ln(algorithmIdentifier); 134 return BString(buffer); 135 } 136 137 138 BString 139 BCertificate::String() const 140 { 141 BIO *buffer = BIO_new(BIO_s_mem()); 142 X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT); 143 144 char* pointer; 145 long length = BIO_get_mem_data(buffer, &pointer); 146 BString result(pointer, length); 147 148 BIO_free(buffer); 149 return result; 150 } 151 152 153 bool 154 BCertificate::operator==(const BCertificate& other) const 155 { 156 return X509_cmp(fPrivate->fX509, other.fPrivate->fX509) == 0; 157 } 158 159 160 // #pragma mark - BCertificate::Private 161 162 163 BCertificate::Private::Private(X509* data) 164 : fX509(X509_dup(data)) 165 { 166 } 167 168 169 BCertificate::Private::~Private() 170 { 171 X509_free(fX509); 172 } 173 174 175 #else 176 177 178 BCertificate::BCertificate(const BCertificate& other) 179 { 180 } 181 182 183 BCertificate::BCertificate(Private* data) 184 { 185 } 186 187 188 BCertificate::~BCertificate() 189 { 190 } 191 192 193 time_t 194 BCertificate::StartDate() const 195 { 196 return B_NOT_SUPPORTED; 197 } 198 199 200 time_t 201 BCertificate::ExpirationDate() const 202 { 203 return B_NOT_SUPPORTED; 204 } 205 206 207 bool 208 BCertificate::IsValidAuthority() const 209 { 210 return false; 211 } 212 213 214 int 215 BCertificate::Version() const 216 { 217 return B_NOT_SUPPORTED; 218 } 219 220 221 BString 222 BCertificate::Issuer() const 223 { 224 return BString(); 225 } 226 227 228 BString 229 BCertificate::Subject() const 230 { 231 return BString(); 232 } 233 234 235 BString 236 BCertificate::SignatureAlgorithm() const 237 { 238 return BString(); 239 } 240 241 242 BString 243 BCertificate::String() const 244 { 245 return BString(); 246 } 247 248 249 bool 250 BCertificate::operator==(const BCertificate& other) const 251 { 252 return false; 253 } 254 255 #endif 256