mirror of https://github.com/aria2/aria2
AppleTLS: Properly support Snow Leopard (10.6)
Tested on 10.6.8 + XCode 4.2 (llvm-gcc-4.2, clang)pull/89/head
parent
0adc4b795e
commit
51ddcaf5b1
|
@ -48,12 +48,15 @@ namespace {
|
||||||
using namespace aria2;
|
using namespace aria2;
|
||||||
|
|
||||||
#if defined(__MAC_10_6)
|
#if defined(__MAC_10_6)
|
||||||
|
|
||||||
|
#if defined(__MAC_10_7)
|
||||||
static const void *query_keys[] = {
|
static const void *query_keys[] = {
|
||||||
kSecClass,
|
kSecClass,
|
||||||
kSecReturnRef,
|
kSecReturnRef,
|
||||||
kSecMatchPolicy,
|
kSecMatchPolicy,
|
||||||
kSecMatchLimit
|
kSecMatchLimit
|
||||||
};
|
};
|
||||||
|
#endif // defined(__MAC_10_7)
|
||||||
|
|
||||||
class cfrelease {
|
class cfrelease {
|
||||||
const void *ptr_;
|
const void *ptr_;
|
||||||
|
@ -112,6 +115,31 @@ namespace {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool checkIdentity(const SecIdentityRef id, const std::string& fingerPrint,
|
||||||
|
const std::vector<std::string> supported)
|
||||||
|
{
|
||||||
|
SecCertificateRef ref = 0;
|
||||||
|
if (SecIdentityCopyCertificate(id, &ref) != errSecSuccess) {
|
||||||
|
A2_LOG_ERROR("Failed to get a certref!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cfrelease del_ref(ref);
|
||||||
|
CFDataRef data = SecCertificateCopyData(ref);
|
||||||
|
if (!data) {
|
||||||
|
A2_LOG_ERROR("Failed to get a data!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cfrelease del_data(data);
|
||||||
|
|
||||||
|
// Do try all supported hash algorithms.
|
||||||
|
// Usually the fingerprint would be sha1 or md5, however this is more
|
||||||
|
// future-proof. Also "usually" doesn't cut it; there is already software
|
||||||
|
// using SHA-2 class algos, and SHA-3 is standardized and potential users
|
||||||
|
// cannot be far.
|
||||||
|
return std::find_if(supported.begin(), supported.end(),
|
||||||
|
hash_finder(data, fingerPrint)) != supported.end();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // defined(__MAC_10_6)
|
#endif // defined(__MAC_10_6)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -166,7 +194,7 @@ bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__MAC_10_6)
|
#if defined(__MAC_10_7)
|
||||||
A2_LOG_DEBUG(fmt("Looking for cert with fingerprint %s", fp.c_str()));
|
A2_LOG_DEBUG(fmt("Looking for cert with fingerprint %s", fp.c_str()));
|
||||||
|
|
||||||
// Build and run the KeyChain the query.
|
// Build and run the KeyChain the query.
|
||||||
|
@ -204,25 +232,7 @@ bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
|
||||||
A2_LOG_ERROR("Failed to get a value!");
|
A2_LOG_ERROR("Failed to get a value!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SecCertificateRef ref = 0;
|
if (!checkIdentity(id, fp, ht)) {
|
||||||
if (SecIdentityCopyCertificate(id, &ref) != errSecSuccess) {
|
|
||||||
A2_LOG_ERROR("Failed to get a certref!");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cfrelease del_ref(ref);
|
|
||||||
CFDataRef data = SecCertificateCopyData(ref);
|
|
||||||
if (!data) {
|
|
||||||
A2_LOG_ERROR("Failed to get a data!");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cfrelease del_data(data);
|
|
||||||
|
|
||||||
// Do try all supported hash algorithms.
|
|
||||||
// Usually the fingerprint would be sha1 or md5, however this is more
|
|
||||||
// future-proof. Also "usually" doesn't cut it; there is already software
|
|
||||||
// using SHA-2 class algos, and SHA-3 is standardized and potential users
|
|
||||||
// cannot be far.
|
|
||||||
if (std::find_if(ht.begin(), ht.end(), hash_finder(data, fp)) == ht.end()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
A2_LOG_INFO("Found cert with matching fingerprint");
|
A2_LOG_INFO("Found cert with matching fingerprint");
|
||||||
|
@ -234,12 +244,38 @@ bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
|
||||||
A2_LOG_ERROR(fmt("Failed to lookup %s in your KeyChain", fingerprint.c_str()));
|
A2_LOG_ERROR(fmt("Failed to lookup %s in your KeyChain", fingerprint.c_str()));
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
#else // defined(__MAC_10_7)
|
||||||
|
#if defined(__MAC_10_6)
|
||||||
|
|
||||||
|
SecIdentitySearchRef search;
|
||||||
|
|
||||||
|
// Deprecated as of 10.7
|
||||||
|
OSStatus err = SecIdentitySearchCreate(0, CSSM_KEYUSE_SIGN, &search);
|
||||||
|
if (err != errSecSuccess) {
|
||||||
|
A2_LOG_ERROR("Certificate search failed: " + errToString(err));
|
||||||
|
}
|
||||||
|
cfrelease del_search(search);
|
||||||
|
|
||||||
|
SecIdentityRef id;
|
||||||
|
while (SecIdentitySearchCopyNext(search, &id) == errSecSuccess) {
|
||||||
|
if (!checkIdentity(id, fp, ht)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
A2_LOG_INFO("Found cert with matching fingerprint");
|
||||||
|
credentials_ = id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
A2_LOG_ERROR(fmt("Failed to lookup %s in your KeyChain", fingerprint.c_str()));
|
||||||
|
return false;
|
||||||
|
|
||||||
#else // defined(__MAC_10_6)
|
#else // defined(__MAC_10_6)
|
||||||
|
|
||||||
A2_LOG_ERROR("Your system does not support creditials via fingerprints; Upgrade to OSX 10.6 or later");
|
A2_LOG_ERROR("Your system does not support creditials via fingerprints; Upgrade to OSX 10.6 or later");
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#endif // defined(__MAC_10_6)
|
#endif // defined(__MAC_10_6)
|
||||||
|
#endif // defined(__MAC_10_7)
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
Loading…
Reference in New Issue