aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorRenĂ© Meusel <[email protected]>2020-06-29 11:38:22 +0200
committerRenĂ© Meusel <[email protected]>2020-06-29 11:38:22 +0200
commitf0644ba3d891b0ba6be8109f83f8edcd0975c7e9 (patch)
treeb9c4d3068181fd192c78ce9e3b2943a7600c7fa5 /src/lib
parent15ac1adbfa84215601eb7d4158a12fe5aa1a231c (diff)
Refactor: move certificate parsing into helper function
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/x509/certstor_system_macos/certstor_macos.cpp108
1 files changed, 58 insertions, 50 deletions
diff --git a/src/lib/x509/certstor_system_macos/certstor_macos.cpp b/src/lib/x509/certstor_system_macos/certstor_macos.cpp
index adde24122..97938f352 100644
--- a/src/lib/x509/certstor_system_macos/certstor_macos.cpp
+++ b/src/lib/x509/certstor_system_macos/certstor_macos.cpp
@@ -209,7 +209,51 @@ std::shared_ptr<const X509_Certificate> readCertificate(SecCertificateRef cert)
return std::make_shared<Botan::X509_Certificate>(ds);
}
-}
+/**
+ * Reads all certificates from a given CFArrayRef into a result vector
+ */
+std::vector<std::shared_ptr<const X509_Certificate>> readAllCertificates(scoped_CFType<CFArrayRef> searchResult)
+ {
+ if(!searchResult)
+ {
+ return {}; // no certificates found
+ }
+
+ const auto count = CFArrayGetCount(searchResult.get());
+ BOTAN_ASSERT(count > 0, "certificate result list contains data");
+
+ std::vector<std::shared_ptr<const X509_Certificate>> output;
+ output.reserve(count);
+ for(unsigned int i = 0; i < count; ++i)
+ {
+ auto cfCert = to_SecCertificateRef(CFArrayGetValueAtIndex(searchResult.get(), i));
+ output.emplace_back(readCertificate(cfCert));
+ }
+
+ return output;
+ }
+
+/**
+ * Reads a single certificate from a given CFArrayRef into a result vector.
+ * Note that this simply takes the first certificate in the array if it contains
+ * more than one.
+ */
+std::shared_ptr<const X509_Certificate> readSingleCertificate(scoped_CFType<CFArrayRef> searchResult)
+ {
+ if(!searchResult)
+ {
+ return nullptr; // no certificate found
+ }
+
+ const auto count = CFArrayGetCount(searchResult.get());
+ BOTAN_ASSERT(count > 0, "certificate result list contains an object");
+
+ // `count` might be greater than 1, but we'll just select the first match
+ auto cfCert = to_SecCertificateRef(CFArrayGetValueAtIndex(searchResult.get(), 0));
+ return readCertificate(cfCert);
+ }
+
+} // namespace
/**
* Internal class implementation (i.e. Pimpl) to keep the required platform-
@@ -339,28 +383,20 @@ Certificate_Store_MacOS::Certificate_Store_MacOS() :
std::vector<X509_DN> Certificate_Store_MacOS::all_subjects() const
{
- scoped_CFType<CFArrayRef> result(m_impl->search());
-
- if(!result)
- {
- return {}; // not a single certificate found in the keychain
- }
-
- const auto count = CFArrayGetCount(result.get());
- BOTAN_ASSERT(count > 0, "subject result list contains data");
+ // Note: This fetches and parses all certificates in the trust store.
+ // Apple's API provides SecCertificateCopyNormalizedSubjectSequence
+ // which facilitates reading the certificate DN without parsing the
+ // entire certificate via Botan::X509_Certificate. However, this
+ // function applies the same DN "normalization" as stated above.
+ const auto certificates = readAllCertificates(m_impl->search());
std::vector<X509_DN> output;
- output.reserve(count);
- for(unsigned int i = 0; i < count; ++i)
+ std::transform(certificates.cbegin(), certificates.cend(),
+ std::back_inserter(output),
+ [](const std::shared_ptr<const X509_Certificate> cert)
{
- // Note: Apple's API provides SecCertificateCopyNormalizedSubjectSequence
- // which would have saved us from reading a Botan::X509_Certificate,
- // however, this function applies the same DN "normalization" as
- // stated above.
- auto cfCert = to_SecCertificateRef(CFArrayGetValueAtIndex(result.get(), i));
- auto cert = readCertificate(cfCert);
- output.emplace_back(cert->subject_dn());
- }
+ return cert->subject_dn();
+ });
return output;
}
@@ -403,25 +439,7 @@ std::vector<std::shared_ptr<const X509_Certificate>> Certificate_Store_MacOS::fi
query_params.push_back({kSecAttrSubjectKeyID, keyid_cfdata.get()});
}
- scoped_CFType<CFArrayRef> result(m_impl->search(std::move(query_params)));
-
- if(!result)
- {
- return {}; // no certificates found
- }
-
- const auto count = CFArrayGetCount(result.get());
- BOTAN_ASSERT(count > 0, "certificate result list contains data");
-
- std::vector<std::shared_ptr<const X509_Certificate>> output;
- output.reserve(count);
- for(unsigned int i = 0; i < count; ++i)
- {
- auto cfCert = to_SecCertificateRef(CFArrayGetValueAtIndex(result.get(), i));
- output.emplace_back(readCertificate(cfCert));
- }
-
- return output;
+ return readAllCertificates(m_impl->search(std::move(query_params)));
}
std::shared_ptr<const X509_Certificate>
@@ -440,17 +458,7 @@ Certificate_Store_MacOS::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& ke
{kSecAttrPublicKeyHash, key_hash_cfdata.get()},
}));
- if(!result)
- {
- return nullptr; // no certificate found
- }
-
- const auto count = CFArrayGetCount(result.get());
- BOTAN_ASSERT(count > 0, "certificate result list contains an object");
-
- // `count` might be greater than 1, but we'll just select the first match
- auto cfCert = to_SecCertificateRef(CFArrayGetValueAtIndex(result.get(), 0));
- return readCertificate(cfCert);
+ return readSingleCertificate(std::move(result));
}
std::shared_ptr<const X509_Certificate>