Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Unified Diff: net/cert/x509_util_mac.cc

Issue 2746103003: Add X509CertificateBytes which uses CRYPTO_BUFFER instead of macOS-native certificate types. (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/cert/x509_util_mac.h ('k') | net/socket/ssl_client_socket_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/cert/x509_util_mac.cc
diff --git a/net/cert/x509_util_mac.cc b/net/cert/x509_util_mac.cc
index f2ce0f3b4b4f521255adf0944787ff6ff7559b0c..0e12a64702a787bb7e754066a3b6d5aaa168da0b 100644
--- a/net/cert/x509_util_mac.cc
+++ b/net/cert/x509_util_mac.cc
@@ -4,11 +4,14 @@
#include "net/cert/x509_util_mac.h"
+#include <CommonCrypto/CommonDigest.h>
+
#include "base/logging.h"
#include "base/mac/mac_util.h"
-#include "base/mac/scoped_cftyperef.h"
#include "base/strings/sys_string_conversions.h"
+#include "net/cert/x509_certificate.h"
#include "third_party/apple_apsl/cssmapplePriv.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
namespace net {
@@ -52,6 +55,161 @@ OSStatus CreatePolicy(const CSSM_OID* policy_oid,
} // namespace
+bool IsValidSecCertificate(SecCertificateRef cert_handle) {
+ const CSSM_X509_NAME* sanity_check = NULL;
+ OSStatus status = SecCertificateGetSubject(cert_handle, &sanity_check);
+ return status == noErr && sanity_check;
+}
+
+base::ScopedCFTypeRef<SecCertificateRef> CreateSecCertificateFromBytes(
+ const uint8_t* data,
+ size_t length) {
+ CSSM_DATA cert_data;
+ cert_data.Data = const_cast<uint8_t*>(data);
+ cert_data.Length = length;
+
+ base::ScopedCFTypeRef<SecCertificateRef> cert_handle;
+ OSStatus status = SecCertificateCreateFromData(&cert_data, CSSM_CERT_X_509v3,
+ CSSM_CERT_ENCODING_DER,
+ cert_handle.InitializeInto());
+ if (status != noErr)
+ return base::ScopedCFTypeRef<SecCertificateRef>();
+ if (!IsValidSecCertificate(cert_handle.get()))
+ return base::ScopedCFTypeRef<SecCertificateRef>();
+ return cert_handle;
+}
+
+base::ScopedCFTypeRef<SecCertificateRef>
+CreateSecCertificateFromX509Certificate(const X509Certificate* cert) {
+#if BUILDFLAG(USE_BYTE_CERTS)
+ return CreateSecCertificateFromBytes(
+ CRYPTO_BUFFER_data(cert->os_cert_handle()),
+ CRYPTO_BUFFER_len(cert->os_cert_handle()));
+#else
+ return base::ScopedCFTypeRef<SecCertificateRef>(
+ reinterpret_cast<SecCertificateRef>(
+ const_cast<void*>(CFRetain(cert->os_cert_handle()))));
+#endif
+}
+
+base::ScopedCFTypeRef<CFMutableArrayRef>
+CreateSecCertificateArrayForX509Certificate(X509Certificate* cert) {
+ base::ScopedCFTypeRef<CFMutableArrayRef> cert_list(
+ CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
+ if (!cert_list)
+ return base::ScopedCFTypeRef<CFMutableArrayRef>();
+#if BUILDFLAG(USE_BYTE_CERTS)
+ std::string bytes;
+ base::ScopedCFTypeRef<SecCertificateRef> sec_cert(
+ CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(cert->os_cert_handle()),
+ CRYPTO_BUFFER_len(cert->os_cert_handle())));
+ if (!sec_cert)
+ return base::ScopedCFTypeRef<CFMutableArrayRef>();
+ CFArrayAppendValue(cert_list, sec_cert);
+ for (X509Certificate::OSCertHandle intermediate :
+ cert->GetIntermediateCertificates()) {
+ base::ScopedCFTypeRef<SecCertificateRef> sec_cert(
+ CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(intermediate),
+ CRYPTO_BUFFER_len(intermediate)));
+ CFArrayAppendValue(cert_list, sec_cert);
+ }
+#else
+ X509Certificate::OSCertHandles intermediate_ca_certs =
+ cert->GetIntermediateCertificates();
+ CFArrayAppendValue(cert_list, cert->os_cert_handle());
+ for (size_t i = 0; i < intermediate_ca_certs.size(); ++i)
+ CFArrayAppendValue(cert_list, intermediate_ca_certs[i]);
+#endif
+ return cert_list;
+}
+
+scoped_refptr<X509Certificate> CreateX509CertificateFromSecCertificate(
+ SecCertificateRef sec_cert,
+ const std::vector<SecCertificateRef>& sec_chain) {
+#if BUILDFLAG(USE_BYTE_CERTS)
+ CSSM_DATA der_data;
+ if (!sec_cert || SecCertificateGetData(sec_cert, &der_data) != noErr)
+ return nullptr;
+ bssl::UniquePtr<CRYPTO_BUFFER> cert_handle(
+ X509Certificate::CreateOSCertHandleFromBytes(
+ reinterpret_cast<const char*>(der_data.Data), der_data.Length));
+ if (!cert_handle)
+ return nullptr;
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ X509Certificate::OSCertHandles intermediates_raw;
+ for (const SecCertificateRef& sec_intermediate : sec_chain) {
+ if (!sec_intermediate ||
+ SecCertificateGetData(sec_intermediate, &der_data) != noErr) {
+ return nullptr;
+ }
+ bssl::UniquePtr<CRYPTO_BUFFER> intermediate_cert_handle(
+ X509Certificate::CreateOSCertHandleFromBytes(
+ reinterpret_cast<const char*>(der_data.Data), der_data.Length));
+ if (!intermediate_cert_handle)
+ return nullptr;
+ intermediates_raw.push_back(intermediate_cert_handle.get());
+ intermediates.push_back(std::move(intermediate_cert_handle));
+ }
+ scoped_refptr<X509Certificate> result(
+ X509Certificate::CreateFromHandle(cert_handle.get(), intermediates_raw));
+ return result;
+#else
+ return X509Certificate::CreateFromHandle(sec_cert, sec_chain);
+#endif
+}
+
+bool IsSelfSigned(SecCertificateRef cert_handle) {
+ CSSMCachedCertificate cached_cert;
+ OSStatus status = cached_cert.Init(cert_handle);
+ if (status != noErr)
+ return false;
+
+ CSSMFieldValue subject;
+ status = cached_cert.GetField(&CSSMOID_X509V1SubjectNameStd, &subject);
+ if (status != CSSM_OK || !subject.field())
+ return false;
+
+ CSSMFieldValue issuer;
+ status = cached_cert.GetField(&CSSMOID_X509V1IssuerNameStd, &issuer);
+ if (status != CSSM_OK || !issuer.field())
+ return false;
+
+ if (subject.field()->Length != issuer.field()->Length ||
+ memcmp(subject.field()->Data, issuer.field()->Data,
+ issuer.field()->Length) != 0) {
+ return false;
+ }
+
+ CSSM_CL_HANDLE cl_handle = CSSM_INVALID_HANDLE;
+ status = SecCertificateGetCLHandle(cert_handle, &cl_handle);
+ if (status)
+ return false;
+ CSSM_DATA cert_data;
+ status = SecCertificateGetData(cert_handle, &cert_data);
+ if (status)
+ return false;
+
+ if (CSSM_CL_CertVerify(cl_handle, 0, &cert_data, &cert_data, NULL, 0))
+ return false;
+ return true;
+}
+
+SHA256HashValue CalculateFingerprint256(SecCertificateRef cert) {
+ SHA256HashValue sha256;
+ memset(sha256.data, 0, sizeof(sha256.data));
+
+ CSSM_DATA cert_data;
+ OSStatus status = SecCertificateGetData(cert, &cert_data);
+ if (status)
+ return sha256;
+
+ DCHECK(cert_data.Data);
+ DCHECK_NE(cert_data.Length, 0U);
+
+ CC_SHA256(cert_data.Data, cert_data.Length, sha256.data);
+
+ return sha256;
+}
OSStatus CreateSSLClientPolicy(SecPolicyRef* policy) {
*policy = SecPolicyCreateSSL(false /* server */, nullptr);
« no previous file with comments | « net/cert/x509_util_mac.h ('k') | net/socket/ssl_client_socket_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698