Implement trust anchor support with SecTrustCopyAnchorCertificates.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@21082 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2007-06-13 02:09:26 +00:00
parent 08ae4bf7bd
commit 7a61e0a75f

View File

@@ -254,6 +254,7 @@ set_private_key(hx509_context context,
*/ */
struct ks_keychain { struct ks_keychain {
int anchors;
SecKeychainRef keychain; SecKeychainRef keychain;
}; };
@@ -272,9 +273,9 @@ keychain_init(hx509_context context,
} }
if (residue) { if (residue) {
if (strcasecmp(residue, "system") == 0) if (strcasecmp(residue, "system-anchors") == 0)
residue = "/System/Library/Keychains/X509Anchors"; ctx->anchors = 1;
ret = SecKeychainOpen(residue, &ctx->keychain); ret = SecKeychainOpen(residue, &ctx->keychain);
if (ret != noErr) { if (ret != noErr) {
hx509_set_error_string(context, 0, ENOENT, hx509_set_error_string(context, 0, ENOENT,
@@ -307,6 +308,8 @@ keychain_free(hx509_certs certs, void *data)
*/ */
struct iter { struct iter {
hx509_certs certs;
void *cursor;
SecKeychainSearchRef searchRef; SecKeychainSearchRef searchRef;
}; };
@@ -316,7 +319,6 @@ keychain_iter_start(hx509_context context,
{ {
struct ks_keychain *ctx = data; struct ks_keychain *ctx = data;
struct iter *iter; struct iter *iter;
OSStatus ret;
iter = calloc(1, sizeof(*iter)); iter = calloc(1, sizeof(*iter));
if (iter == NULL) { if (iter == NULL) {
@@ -324,15 +326,72 @@ keychain_iter_start(hx509_context context,
return ENOMEM; return ENOMEM;
} }
ret = SecKeychainSearchCreateFromAttributes(ctx->keychain, if (ctx->anchors) {
kSecCertificateItemClass, CFArrayRef anchors;
NULL, int ret;
&iter->searchRef); int i;
if (ret) {
free(iter); ret = hx509_certs_init(context, "MEMORY:ks-file-create",
hx509_set_error_string(context, 0, ret, 0, NULL, &iter->certs);
"Failed to start search for attributes"); if (ret) {
return ENOMEM; free(iter);
return ret;
}
ret = SecTrustCopyAnchorCertificates(&anchors);
if (ret != 0) {
hx509_certs_free(&iter->certs);
free(iter);
hx509_set_error_string(context, 0, ENOMEM,
"Can't get trust anchors from Keychain");
return ENOMEM;
}
for (i = 0; i < CFArrayGetCount(anchors); i++) {
Certificate t;
hx509_cert cert;
SecCertificateRef cr =
(SecCertificateRef)CFArrayGetValueAtIndex(anchors, i);
CSSM_DATA cssm;
SecCertificateGetData(cr, &cssm);
ret = decode_Certificate(cssm.Data, cssm.Length, &t, NULL);
if (ret)
continue;
ret = hx509_cert_init(context, &t, &cert);
if (ret)
continue;
ret = hx509_certs_add(context, iter->certs, cert);
free_Certificate(&t);
hx509_cert_free(cert);
}
CFRelease(anchors);
}
if (iter->certs) {
int ret;
ret = hx509_certs_start_seq(context, iter->certs, &iter->cursor);
if (ret) {
hx509_certs_free(&iter->certs);
free(iter);
return ret;
}
} else {
OSStatus ret;
ret = SecKeychainSearchCreateFromAttributes(ctx->keychain,
kSecCertificateItemClass,
NULL,
&iter->searchRef);
if (ret) {
free(iter);
hx509_set_error_string(context, 0, ret,
"Failed to start search for attributes");
return ENOMEM;
}
} }
*cursor = iter; *cursor = iter;
@@ -359,6 +418,9 @@ keychain_iter(hx509_context context,
void *ptr = NULL; void *ptr = NULL;
size_t size; size_t size;
if (iter->certs)
return hx509_certs_next_cert(context, iter->certs, iter->cursor, cert);
*cert = NULL; *cert = NULL;
ret = SecKeychainSearchCopyNext(iter->searchRef, &itemRef); ret = SecKeychainSearchCopyNext(iter->searchRef, &itemRef);
@@ -449,7 +511,14 @@ keychain_iter_end(hx509_context context,
{ {
struct iter *iter = cursor; struct iter *iter = cursor;
CFRelease(iter->searchRef); if (iter->certs) {
int ret;
ret = hx509_certs_end_seq(context, iter->certs, iter->cursor);
hx509_certs_free(&iter->certs);
} else {
CFRelease(iter->searchRef);
}
memset(iter, 0, sizeof(*iter)); memset(iter, 0, sizeof(*iter));
free(iter); free(iter);
return 0; return 0;