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() 62 { 63 delete fPrivate; 64 } 65 66 67 int 68 BCertificate::Version() 69 { 70 return X509_get_version(fPrivate->fX509) + 1; 71 } 72 73 74 time_t 75 BCertificate::StartDate() 76 { 77 return parse_ASN1(X509_get_notBefore(fPrivate->fX509)); 78 } 79 80 81 time_t 82 BCertificate::ExpirationDate() 83 { 84 return parse_ASN1(X509_get_notAfter(fPrivate->fX509)); 85 } 86 87 88 bool 89 BCertificate::IsValidAuthority() 90 { 91 return X509_check_ca(fPrivate->fX509) > 0; 92 } 93 94 95 bool 96 BCertificate::IsSelfSigned() 97 { 98 return X509_check_issued(fPrivate->fX509, fPrivate->fX509) == X509_V_OK; 99 } 100 101 102 BString 103 BCertificate::Issuer() 104 { 105 X509_NAME* name = X509_get_issuer_name(fPrivate->fX509); 106 return decode_X509_NAME(name); 107 } 108 109 110 BString 111 BCertificate::Subject() 112 { 113 X509_NAME* name = X509_get_subject_name(fPrivate->fX509); 114 return decode_X509_NAME(name); 115 } 116 117 118 BString 119 BCertificate::SignatureAlgorithm() 120 { 121 int algorithmIdentifier = OBJ_obj2nid( 122 fPrivate->fX509->cert_info->key->algor->algorithm); 123 124 if (algorithmIdentifier == NID_undef) 125 return BString("undefined"); 126 127 const char* buffer = OBJ_nid2ln(algorithmIdentifier); 128 return BString(buffer); 129 } 130 131 132 BString 133 BCertificate::String() 134 { 135 BIO *buffer = BIO_new(BIO_s_mem()); 136 X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT); 137 138 char* pointer; 139 long length = BIO_get_mem_data(buffer, &pointer); 140 BString result(pointer, length); 141 142 BIO_free(buffer); 143 return result; 144 } 145 146 147 // #pragma mark - BCertificate::Private 148 149 150 BCertificate::Private::Private(X509* data) 151 : fX509(data) 152 { 153 } 154 155 156 #else 157 158 159 BCertificate::BCertificate(Private* data) 160 { 161 } 162 163 164 BCertificate::~BCertificate() 165 { 166 } 167 168 169 time_t 170 BCertificate::StartDate() 171 { 172 return B_NOT_SUPPORTED; 173 } 174 175 176 time_t 177 BCertificate::ExpirationDate() 178 { 179 return B_NOT_SUPPORTED; 180 } 181 182 183 bool 184 BCertificate::IsValidAuthority() 185 { 186 return false; 187 } 188 189 190 int 191 BCertificate::Version() 192 { 193 return B_NOT_SUPPORTED; 194 } 195 196 197 BString 198 BCertificate::Issuer() 199 { 200 return BString(); 201 } 202 203 204 BString 205 BCertificate::Subject() 206 { 207 return BString(); 208 } 209 210 211 BString 212 BCertificate::SignatureAlgorithm() 213 { 214 return BString(); 215 } 216 217 218 BString 219 BCertificate::String() 220 { 221 return BString(); 222 } 223 224 225 #endif 226