| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/cert/x509_certificate.h" | |
| 6 | |
| 7 #include <openssl/asn1.h> | |
| 8 #include <openssl/bytestring.h> | |
| 9 #include <openssl/crypto.h> | |
| 10 #include <openssl/obj_mac.h> | |
| 11 #include <openssl/pem.h> | |
| 12 #include <openssl/sha.h> | |
| 13 #include <openssl/ssl.h> | |
| 14 #include <openssl/x509v3.h> | |
| 15 | |
| 16 #include "base/memory/singleton.h" | |
| 17 #include "base/pickle.h" | |
| 18 #include "base/sha1.h" | |
| 19 #include "base/strings/string_number_conversions.h" | |
| 20 #include "base/strings/string_piece.h" | |
| 21 #include "base/strings/string_util.h" | |
| 22 #include "crypto/openssl_util.h" | |
| 23 #include "crypto/scoped_openssl_types.h" | |
| 24 #include "net/base/net_errors.h" | |
| 25 #include "net/base/net_util.h" | |
| 26 #include "net/cert/x509_util_openssl.h" | |
| 27 | |
| 28 #if defined(OS_ANDROID) | |
| 29 #include "base/logging.h" | |
| 30 #include "net/android/network_library.h" | |
| 31 #endif | |
| 32 | |
| 33 namespace net { | |
| 34 | |
| 35 namespace { | |
| 36 | |
| 37 typedef crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>::Type | |
| 38 ScopedGENERAL_NAMES; | |
| 39 | |
| 40 void CreateOSCertHandlesFromPKCS7Bytes( | |
| 41 const char* data, int length, | |
| 42 X509Certificate::OSCertHandles* handles) { | |
| 43 crypto::EnsureOpenSSLInit(); | |
| 44 crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE); | |
| 45 | |
| 46 CBS der_data; | |
| 47 CBS_init(&der_data, reinterpret_cast<const uint8_t*>(data), length); | |
| 48 STACK_OF(X509)* certs = sk_X509_new_null(); | |
| 49 | |
| 50 if (PKCS7_get_certificates(certs, &der_data)) { | |
| 51 for (size_t i = 0; i < sk_X509_num(certs); ++i) { | |
| 52 X509* x509_cert = | |
| 53 X509Certificate::DupOSCertHandle(sk_X509_value(certs, i)); | |
| 54 handles->push_back(x509_cert); | |
| 55 } | |
| 56 } | |
| 57 sk_X509_pop_free(certs, X509_free); | |
| 58 } | |
| 59 | |
| 60 void ParsePrincipalValues(X509_NAME* name, | |
| 61 int nid, | |
| 62 std::vector<std::string>* fields) { | |
| 63 for (int index = -1; | |
| 64 (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) { | |
| 65 std::string field; | |
| 66 if (!x509_util::ParsePrincipalValueByIndex(name, index, &field)) | |
| 67 break; | |
| 68 fields->push_back(field); | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 void ParsePrincipal(X509Certificate::OSCertHandle cert, | |
| 73 X509_NAME* x509_name, | |
| 74 CertPrincipal* principal) { | |
| 75 if (!x509_name) | |
| 76 return; | |
| 77 | |
| 78 ParsePrincipalValues(x509_name, NID_streetAddress, | |
| 79 &principal->street_addresses); | |
| 80 ParsePrincipalValues(x509_name, NID_organizationName, | |
| 81 &principal->organization_names); | |
| 82 ParsePrincipalValues(x509_name, NID_organizationalUnitName, | |
| 83 &principal->organization_unit_names); | |
| 84 ParsePrincipalValues(x509_name, NID_domainComponent, | |
| 85 &principal->domain_components); | |
| 86 | |
| 87 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, | |
| 88 &principal->common_name); | |
| 89 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, | |
| 90 &principal->locality_name); | |
| 91 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, | |
| 92 &principal->state_or_province_name); | |
| 93 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, | |
| 94 &principal->country_name); | |
| 95 } | |
| 96 | |
| 97 void ParseSubjectAltName(X509Certificate::OSCertHandle cert, | |
| 98 std::vector<std::string>* dns_names, | |
| 99 std::vector<std::string>* ip_addresses) { | |
| 100 DCHECK(dns_names || ip_addresses); | |
| 101 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); | |
| 102 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); | |
| 103 if (!alt_name_ext) | |
| 104 return; | |
| 105 | |
| 106 ScopedGENERAL_NAMES alt_names( | |
| 107 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); | |
| 108 if (!alt_names.get()) | |
| 109 return; | |
| 110 | |
| 111 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { | |
| 112 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); | |
| 113 if (name->type == GEN_DNS && dns_names) { | |
| 114 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); | |
| 115 if (!dns_name) | |
| 116 continue; | |
| 117 int dns_name_len = ASN1_STRING_length(name->d.dNSName); | |
| 118 dns_names->push_back( | |
| 119 std::string(reinterpret_cast<const char*>(dns_name), dns_name_len)); | |
| 120 } else if (name->type == GEN_IPADD && ip_addresses) { | |
| 121 const unsigned char* ip_addr = name->d.iPAddress->data; | |
| 122 if (!ip_addr) | |
| 123 continue; | |
| 124 int ip_addr_len = name->d.iPAddress->length; | |
| 125 if (ip_addr_len != static_cast<int>(kIPv4AddressSize) && | |
| 126 ip_addr_len != static_cast<int>(kIPv6AddressSize)) { | |
| 127 // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName iPAddress | |
| 128 // to have 4 or 16 bytes, whereas in a name constraint it includes a | |
| 129 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup. | |
| 130 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len; | |
| 131 continue; | |
| 132 } | |
| 133 ip_addresses->push_back( | |
| 134 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len)); | |
| 135 } | |
| 136 } | |
| 137 } | |
| 138 | |
| 139 class X509InitSingleton { | |
| 140 public: | |
| 141 static X509InitSingleton* GetInstance() { | |
| 142 // We allow the X509 store to leak, because it is used from a non-joinable | |
| 143 // worker that is not stopped on shutdown, hence may still be using | |
| 144 // OpenSSL library after the AtExit runner has completed. | |
| 145 return Singleton<X509InitSingleton, | |
| 146 LeakySingletonTraits<X509InitSingleton> >::get(); | |
| 147 } | |
| 148 X509_STORE* store() const { return store_.get(); } | |
| 149 | |
| 150 void ResetCertStore() { | |
| 151 store_.reset(X509_STORE_new()); | |
| 152 DCHECK(store_.get()); | |
| 153 X509_STORE_set_default_paths(store_.get()); | |
| 154 // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)). | |
| 155 } | |
| 156 | |
| 157 private: | |
| 158 friend struct DefaultSingletonTraits<X509InitSingleton>; | |
| 159 X509InitSingleton() { | |
| 160 crypto::EnsureOpenSSLInit(); | |
| 161 ResetCertStore(); | |
| 162 } | |
| 163 | |
| 164 crypto::ScopedOpenSSL<X509_STORE, X509_STORE_free>::Type store_; | |
| 165 | |
| 166 DISALLOW_COPY_AND_ASSIGN(X509InitSingleton); | |
| 167 }; | |
| 168 | |
| 169 // Used to free a list of X509_NAMEs and the objects it points to. | |
| 170 void sk_X509_NAME_free_all(STACK_OF(X509_NAME)* sk) { | |
| 171 sk_X509_NAME_pop_free(sk, X509_NAME_free); | |
| 172 } | |
| 173 | |
| 174 } // namespace | |
| 175 | |
| 176 // static | |
| 177 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( | |
| 178 OSCertHandle cert_handle) { | |
| 179 DCHECK(cert_handle); | |
| 180 return X509_up_ref(cert_handle); | |
| 181 } | |
| 182 | |
| 183 // static | |
| 184 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { | |
| 185 // Decrement the ref-count for the cert and, if all references are gone, | |
| 186 // free the memory and any application-specific data associated with the | |
| 187 // certificate. | |
| 188 X509_free(cert_handle); | |
| 189 } | |
| 190 | |
| 191 void X509Certificate::Initialize() { | |
| 192 crypto::EnsureOpenSSLInit(); | |
| 193 fingerprint_ = CalculateFingerprint(cert_handle_); | |
| 194 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); | |
| 195 | |
| 196 ASN1_INTEGER* serial_num = X509_get_serialNumber(cert_handle_); | |
| 197 if (serial_num) { | |
| 198 // ASN1_INTEGERS represent the decoded number, in a format internal to | |
| 199 // OpenSSL. Most notably, this may have leading zeroes stripped off for | |
| 200 // numbers whose first byte is >= 0x80. Thus, it is necessary to | |
| 201 // re-encoded the integer back into DER, which is what the interface | |
| 202 // of X509Certificate exposes, to ensure callers get the proper (DER) | |
| 203 // value. | |
| 204 int bytes_required = i2c_ASN1_INTEGER(serial_num, NULL); | |
| 205 unsigned char* buffer = reinterpret_cast<unsigned char*>( | |
| 206 WriteInto(&serial_number_, bytes_required + 1)); | |
| 207 int bytes_written = i2c_ASN1_INTEGER(serial_num, &buffer); | |
| 208 DCHECK_EQ(static_cast<size_t>(bytes_written), serial_number_.size()); | |
| 209 } | |
| 210 | |
| 211 ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_); | |
| 212 ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_); | |
| 213 x509_util::ParseDate(X509_get_notBefore(cert_handle_), &valid_start_); | |
| 214 x509_util::ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_); | |
| 215 } | |
| 216 | |
| 217 // static | |
| 218 void X509Certificate::ResetCertStore() { | |
| 219 X509InitSingleton::GetInstance()->ResetCertStore(); | |
| 220 } | |
| 221 | |
| 222 // static | |
| 223 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) { | |
| 224 SHA1HashValue sha1; | |
| 225 unsigned int sha1_size = static_cast<unsigned int>(sizeof(sha1.data)); | |
| 226 int ret = X509_digest(cert, EVP_sha1(), sha1.data, &sha1_size); | |
| 227 CHECK(ret); | |
| 228 CHECK_EQ(sha1_size, sizeof(sha1.data)); | |
| 229 return sha1; | |
| 230 } | |
| 231 | |
| 232 // static | |
| 233 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) { | |
| 234 SHA256HashValue sha256; | |
| 235 unsigned int sha256_size = static_cast<unsigned int>(sizeof(sha256.data)); | |
| 236 int ret = X509_digest(cert, EVP_sha256(), sha256.data, &sha256_size); | |
| 237 CHECK(ret); | |
| 238 CHECK_EQ(sha256_size, sizeof(sha256.data)); | |
| 239 return sha256; | |
| 240 } | |
| 241 | |
| 242 // static | |
| 243 SHA1HashValue X509Certificate::CalculateCAFingerprint( | |
| 244 const OSCertHandles& intermediates) { | |
| 245 SHA1HashValue sha1; | |
| 246 memset(sha1.data, 0, sizeof(sha1.data)); | |
| 247 | |
| 248 SHA_CTX sha1_ctx; | |
| 249 SHA1_Init(&sha1_ctx); | |
| 250 base::StringPiece der; | |
| 251 for (size_t i = 0; i < intermediates.size(); ++i) { | |
| 252 if (!x509_util::GetDER(intermediates[i], &der)) | |
| 253 return sha1; | |
| 254 SHA1_Update(&sha1_ctx, der.data(), der.length()); | |
| 255 } | |
| 256 SHA1_Final(sha1.data, &sha1_ctx); | |
| 257 | |
| 258 return sha1; | |
| 259 } | |
| 260 | |
| 261 // static | |
| 262 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( | |
| 263 const char* data, int length) { | |
| 264 if (length < 0) | |
| 265 return NULL; | |
| 266 crypto::EnsureOpenSSLInit(); | |
| 267 const unsigned char* d2i_data = | |
| 268 reinterpret_cast<const unsigned char*>(data); | |
| 269 // Don't cache this data for x509_util::GetDER as this wire format | |
| 270 // may be not be identical from the i2d_X509 roundtrip. | |
| 271 X509* cert = d2i_X509(NULL, &d2i_data, length); | |
| 272 return cert; | |
| 273 } | |
| 274 | |
| 275 // static | |
| 276 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( | |
| 277 const char* data, int length, Format format) { | |
| 278 OSCertHandles results; | |
| 279 if (length < 0) | |
| 280 return results; | |
| 281 | |
| 282 switch (format) { | |
| 283 case FORMAT_SINGLE_CERTIFICATE: { | |
| 284 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); | |
| 285 if (handle) | |
| 286 results.push_back(handle); | |
| 287 break; | |
| 288 } | |
| 289 case FORMAT_PKCS7: { | |
| 290 CreateOSCertHandlesFromPKCS7Bytes(data, length, &results); | |
| 291 break; | |
| 292 } | |
| 293 default: { | |
| 294 NOTREACHED() << "Certificate format " << format << " unimplemented"; | |
| 295 break; | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 return results; | |
| 300 } | |
| 301 | |
| 302 void X509Certificate::GetSubjectAltName( | |
| 303 std::vector<std::string>* dns_names, | |
| 304 std::vector<std::string>* ip_addrs) const { | |
| 305 if (dns_names) | |
| 306 dns_names->clear(); | |
| 307 if (ip_addrs) | |
| 308 ip_addrs->clear(); | |
| 309 | |
| 310 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); | |
| 311 } | |
| 312 | |
| 313 // static | |
| 314 X509_STORE* X509Certificate::cert_store() { | |
| 315 return X509InitSingleton::GetInstance()->store(); | |
| 316 } | |
| 317 | |
| 318 // static | |
| 319 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, | |
| 320 std::string* encoded) { | |
| 321 base::StringPiece der; | |
| 322 if (!cert_handle || !x509_util::GetDER(cert_handle, &der)) | |
| 323 return false; | |
| 324 encoded->assign(der.data(), der.length()); | |
| 325 return true; | |
| 326 } | |
| 327 | |
| 328 // static | |
| 329 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, | |
| 330 X509Certificate::OSCertHandle b) { | |
| 331 DCHECK(a && b); | |
| 332 if (a == b) | |
| 333 return true; | |
| 334 | |
| 335 // X509_cmp only checks the fingerprint, but we want to compare the whole | |
| 336 // DER data. Encoding it from OSCertHandle is an expensive operation, so we | |
| 337 // cache the DER (if not already cached via X509_set_ex_data). | |
| 338 base::StringPiece der_a, der_b; | |
| 339 | |
| 340 return x509_util::GetDER(a, &der_a) && | |
| 341 x509_util::GetDER(b, &der_b) && | |
| 342 der_a == der_b; | |
| 343 } | |
| 344 | |
| 345 // static | |
| 346 X509Certificate::OSCertHandle | |
| 347 X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { | |
| 348 const char* data; | |
| 349 int length; | |
| 350 if (!pickle_iter->ReadData(&data, &length)) | |
| 351 return NULL; | |
| 352 | |
| 353 return CreateOSCertHandleFromBytes(data, length); | |
| 354 } | |
| 355 | |
| 356 // static | |
| 357 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, | |
| 358 Pickle* pickle) { | |
| 359 base::StringPiece der; | |
| 360 if (!x509_util::GetDER(cert_handle, &der)) | |
| 361 return false; | |
| 362 | |
| 363 return pickle->WriteData(der.data(), der.length()); | |
| 364 } | |
| 365 | |
| 366 // static | |
| 367 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, | |
| 368 size_t* size_bits, | |
| 369 PublicKeyType* type) { | |
| 370 *type = kPublicKeyTypeUnknown; | |
| 371 *size_bits = 0; | |
| 372 | |
| 373 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle)); | |
| 374 if (!scoped_key.get()) | |
| 375 return; | |
| 376 | |
| 377 CHECK(scoped_key.get()); | |
| 378 EVP_PKEY* key = scoped_key.get(); | |
| 379 | |
| 380 switch (key->type) { | |
| 381 case EVP_PKEY_RSA: | |
| 382 *type = kPublicKeyTypeRSA; | |
| 383 *size_bits = EVP_PKEY_size(key) * 8; | |
| 384 break; | |
| 385 case EVP_PKEY_DSA: | |
| 386 *type = kPublicKeyTypeDSA; | |
| 387 *size_bits = EVP_PKEY_size(key) * 8; | |
| 388 break; | |
| 389 case EVP_PKEY_EC: | |
| 390 *type = kPublicKeyTypeECDSA; | |
| 391 *size_bits = EVP_PKEY_bits(key); | |
| 392 break; | |
| 393 case EVP_PKEY_DH: | |
| 394 *type = kPublicKeyTypeDH; | |
| 395 *size_bits = EVP_PKEY_size(key) * 8; | |
| 396 break; | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 bool X509Certificate::IsIssuedByEncoded( | |
| 401 const std::vector<std::string>& valid_issuers) { | |
| 402 if (valid_issuers.empty()) | |
| 403 return false; | |
| 404 | |
| 405 // Convert to a temporary list of X509_NAME objects. | |
| 406 // It will own the objects it points to. | |
| 407 crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all>::Type | |
| 408 issuer_names(sk_X509_NAME_new_null()); | |
| 409 if (!issuer_names.get()) | |
| 410 return false; | |
| 411 | |
| 412 for (std::vector<std::string>::const_iterator it = valid_issuers.begin(); | |
| 413 it != valid_issuers.end(); ++it) { | |
| 414 const unsigned char* p = | |
| 415 reinterpret_cast<const unsigned char*>(it->data()); | |
| 416 long len = static_cast<long>(it->length()); | |
| 417 X509_NAME* ca_name = d2i_X509_NAME(NULL, &p, len); | |
| 418 if (ca_name == NULL) | |
| 419 return false; | |
| 420 sk_X509_NAME_push(issuer_names.get(), ca_name); | |
| 421 } | |
| 422 | |
| 423 // Create a temporary list of X509_NAME objects corresponding | |
| 424 // to the certificate chain. It doesn't own the object it points to. | |
| 425 std::vector<X509_NAME*> cert_names; | |
| 426 X509_NAME* issuer = X509_get_issuer_name(cert_handle_); | |
| 427 if (issuer == NULL) | |
| 428 return false; | |
| 429 | |
| 430 cert_names.push_back(issuer); | |
| 431 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); | |
| 432 it != intermediate_ca_certs_.end(); ++it) { | |
| 433 issuer = X509_get_issuer_name(*it); | |
| 434 if (issuer == NULL) | |
| 435 return false; | |
| 436 cert_names.push_back(issuer); | |
| 437 } | |
| 438 | |
| 439 // and 'cert_names'. | |
| 440 for (size_t n = 0; n < cert_names.size(); ++n) { | |
| 441 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) { | |
| 442 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m); | |
| 443 if (X509_NAME_cmp(issuer, cert_names[n]) == 0) { | |
| 444 return true; | |
| 445 } | |
| 446 } | |
| 447 } | |
| 448 | |
| 449 return false; | |
| 450 } | |
| 451 | |
| 452 // static | |
| 453 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) { | |
| 454 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle)); | |
| 455 if (!scoped_key) | |
| 456 return false; | |
| 457 | |
| 458 // NOTE: X509_verify() returns 1 in case of success, 0 or -1 on error. | |
| 459 return X509_verify(cert_handle, scoped_key.get()) == 1; | |
| 460 } | |
| 461 | |
| 462 } // namespace net | |
| OLD | NEW |