char * _mongoc_secure_transport_extract_subject (const char *filename, const char *passphrase) { bool success; char *retval = NULL; CFArrayRef items = NULL; SecExternalItemType type = kSecItemTypeCertificate; success = _mongoc_secure_transport_import_pem (filename, passphrase, &items, &type); if (!success) { return NULL; } if (type == kSecItemTypeAggregate) { for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) { CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i)); if (item_id == SecCertificateGetTypeID()) { retval = _mongoc_secure_transport_RFC2253_from_cert ((SecCertificateRef)CFArrayGetValueAtIndex (items, i)); break; } } } else if (type == kSecItemTypeCertificate) { retval = _mongoc_secure_transport_RFC2253_from_cert ((SecCertificateRef)items); } if (items) { CFRelease (items); } return retval; }
bool mongoc_secure_transport_setup_ca ( mongoc_stream_tls_secure_transport_t *secure_transport, mongoc_ssl_opt_t *opt) { if (opt->ca_file) { CFArrayRef items; SecExternalItemType type = kSecItemTypeCertificate; bool success = _mongoc_secure_transport_import_pem ( opt->ca_file, NULL, &items, &type); if (!success) { MONGOC_ERROR ("Can't find certificate in \"%s\"", opt->ca_file); return false; } if (type == kSecItemTypeAggregate) { CFMutableArrayRef anchors = CFArrayCreateMutable ( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) { CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i)); if (item_id == SecCertificateGetTypeID ()) { CFArrayAppendValue (anchors, CFArrayGetValueAtIndex (items, i)); } } secure_transport->anchors = anchors; CFRelease (items); } else if (type == kSecItemTypeCertificate) { secure_transport->anchors = items; } else { CFRelease (items); } /* This should be SSLSetCertificateAuthorities But the /TLS/ tests fail * when it is */ success = !SSLSetTrustedRoots ( secure_transport->ssl_ctx_ref, secure_transport->anchors, true); TRACE ("Setting certificate authority %s (%s)", success ? "succeeded" : "failed", opt->ca_file); return true; } TRACE ("%s", "No CA provided, using defaults"); return false; }
bool mongoc_secure_transport_setup_certificate (mongoc_stream_tls_secure_transport_t *secure_transport, mongoc_ssl_opt_t *opt) { bool success; CFArrayRef items; SecIdentityRef id; SecKeyRef key = NULL; SecCertificateRef cert = NULL; SecExternalItemType type = kSecItemTypeCertificate; if (!opt->pem_file) { MONGOC_INFO ("No private key provided, the server won't be able to verify us"); return false; } success = _mongoc_secure_transport_import_pem (opt->pem_file, opt->pem_pwd, &items, &type); if (!success) { MONGOC_ERROR ("Can't find certificate in: '%s'", opt->pem_file); return false; } if (type != kSecItemTypeAggregate) { MONGOC_ERROR ("Cannot work with keys of type \"%d\". Please file a JIRA", type); CFRelease (items); return false; } for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) { CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i)); if (item_id == SecCertificateGetTypeID()) { cert = (SecCertificateRef) CFArrayGetValueAtIndex (items, i); } else if (item_id == SecKeyGetTypeID()) { key = (SecKeyRef) CFArrayGetValueAtIndex (items, i); } } if (!cert || !key) { MONGOC_ERROR ("Couldn't find valid private key"); CFRelease (items); return false; } id = SecIdentityCreate (kCFAllocatorDefault, cert, key); secure_transport->my_cert = CFArrayCreateMutableCopy(kCFAllocatorDefault, (CFIndex)2, items); CFArraySetValueAtIndex(secure_transport->my_cert, 0, id); CFArraySetValueAtIndex(secure_transport->my_cert, 1, cert); /* * Secure Transport assumes the following: * * The certificate references remain valid for the lifetime of the session. * * The identity specified in certRefs[0] is capable of signing. */ success = !SSLSetCertificate (secure_transport->ssl_ctx_ref, secure_transport->my_cert); MONGOC_DEBUG("Setting client certificate %s", success ? "succeeded" : "failed"); CFRelease (items); return true; }