diff --git a/docs/curl.1 b/docs/curl.1
index 1aeeb46..c4cce98 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -390,6 +390,8 @@ NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
 loaded. If you want to use a file from the current directory, please precede
 it with "./" prefix, in order to avoid confusion with a nickname.
 
+(iOS and Mac OS X only) If curl is built against Secure Transport, then the certificate string must match the name of a certificate that's in the system or user keychain. The private key corresponding to the certificate, and certificate chain (if any),  must also be present in the keychain.
+
 If this option is used several times, the last one will be used.
 .IP "--engine <name>"
 Select the OpenSSL crypto engine to use for cipher
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 43d1502..f19882e 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -2222,6 +2222,8 @@ changed with \fICURLOPT_SSLCERTTYPE\fP.
 With NSS this can also be the nickname of the certificate you wish to
 authenticate with. If you want to use a file from the current directory, please
 precede it with "./" prefix, in order to avoid confusion with a nickname.
+
+(iOS and Mac OS X only) With Secure Transport, this string must match the name of a certificate that's in the system or user keychain. The private key corresponding to the certificate, and certificate chain (if any),  must also be present in the keychain.
 .IP CURLOPT_SSLCERTTYPE
 Pass a pointer to a zero terminated string as parameter. The string should be
 the format of your certificate. Supported formats are "PEM" and "DER".  (Added
@@ -2230,6 +2232,8 @@ in 7.9.3)
 Pass a pointer to a zero terminated string as parameter. The string should be
 the file name of your private key. The default format is "PEM" and can be
 changed with \fICURLOPT_SSLKEYTYPE\fP.
+
+(iOS and Mac OS X only) This option is ignored if curl was built against Secure Transport. Secure Transport expects the private key to be already present in the keychain containing the certificate.
 .IP CURLOPT_SSLKEYTYPE
 Pass a pointer to a zero terminated string as parameter. The string should be
 the format of your private key. Supported formats are "PEM", "DER" and "ENG".
diff --git a/lib/curl_darwinssl.c b/lib/curl_darwinssl.c
index 949a1b2..e24759f 100644
--- a/lib/curl_darwinssl.c
+++ b/lib/curl_darwinssl.c
@@ -691,6 +691,89 @@ CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
   return server_cert_summary;
 }
 
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+static OSStatus FindCertWithLabelOldSchool(char *label,
+                                           SecCertificateRef *outCert)
+{
+  OSStatus status = errSecItemNotFound;
+/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
+   deprecation warnings, so let's not compile this unless it's necessary: */
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
+  SecKeychainAttributeList attrList;
+  SecKeychainAttribute attr;
+  SecKeychainSearchRef searchRef = NULL;
+
+  /* Set up the attribute list: */
+  attrList.count = 1L;
+  attrList.attr = &attr;
+
+  /* Set up our lone search criterion: */
+  attr.tag = kSecLabelItemAttr;
+  attr.data = label;
+  attr.length = (UInt32)strlen(label);
+
+  /* Start searching: */
+  status = SecKeychainSearchCreateFromAttributes(NULL,
+                                                 kSecCertificateItemClass,
+                                                 &attrList,
+                                                 &searchRef);
+  if(status == noErr) {
+    status = SecKeychainSearchCopyNext(searchRef,
+                                       (SecKeychainItemRef *)outCert);
+  }
+
+  if(searchRef)
+    CFRelease(searchRef);
+#else
+#pragma unused(label, outCert)
+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7 */
+  return status;
+}
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
+
+static OSStatus FindCertWithLabel(char *label,
+                                  SecCertificateRef *outCert)
+{
+  OSStatus status = errSecItemNotFound;
+
+#if defined(__MAC_10_6) || defined(__IPHONE_2_0)
+  /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. If it
+     exists, let's use that to find the certificate. */
+  if(SecItemCopyMatching != NULL) {
+    CFTypeRef keys[3];
+    CFTypeRef values[3];
+    CFDictionaryRef queryDict;
+
+    /* Set up our search criteria and expected results: */
+    values[0] = kSecClassCertificate;
+    keys[0] = kSecClass;
+    values[1] = kCFBooleanTrue;
+    keys[1] = kSecReturnRef;
+    values[2] = CFStringCreateWithCString(NULL, label, kCFStringEncodingUTF8);
+    keys[2] = kSecAttrLabel;
+    queryDict = CFDictionaryCreate(NULL, (const void **)keys,
+                                  (const void **)values, 3L,
+                                  &kCFCopyStringDictionaryKeyCallBacks,
+                                  &kCFTypeDictionaryValueCallBacks);
+    CFRelease(values[2]);
+
+    /* Start searching: */
+    status = SecItemCopyMatching(queryDict, (CFTypeRef *)outCert);
+    CFRelease(queryDict);
+  }
+  else {
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+    /* On Leopard, fall back to SecKeychainSearch. */
+    status = FindCertWithLabelOldSchool(label, outCert);
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
+  }
+#elif (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+  /* For developers building on Leopard, we have no choice but to fall back. */
+  status = FindCertWithLabelOldSchool(label, outCert);
+#endif /* defined(__MAC_10_6) || defined(__IPHONE_2_0) */
+  return status;
+}
+
 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
                                         int sockindex)
 {
@@ -841,8 +924,65 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
   }
 #endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
 
-  /* No need to load certificates here. SecureTransport uses the Keychain
-   * (which is also part of the Security framework) to evaluate trust. */
+  if(data->set.str[STRING_KEY]) {
+    infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
+                "Transport. The private key must be in the Keychain.");
+  }
+
+  if(data->set.str[STRING_CERT]) {
+    SecCertificateRef cert = NULL;
+
+    /* User wants to authenticate with a client cert. Look for it: */
+    err = FindCertWithLabel(data->set.str[STRING_CERT], &cert);
+    if(err == noErr) {
+      SecIdentityRef cert_and_key;
+
+      /* Okay, we found the certificate, but do we have the private key? */
+      err = SecIdentityCreateWithCertificate(NULL, cert, &cert_and_key);
+      if(err == noErr) {
+        CFTypeRef certs_c[1];
+        CFArrayRef certs;
+        CFStringRef cert_summary = CopyCertSubject(cert);
+        char cert_summary_c[128];
+
+        if(cert_summary) {
+          memset(cert_summary_c, 0, 128);
+          if(CFStringGetCString(cert_summary,
+                                cert_summary_c,
+                                128,
+                                kCFStringEncodingUTF8)) {
+            infof(data, "Client certificate: %s\n", cert_summary_c);
+          }
+          CFRelease(cert_summary);
+        }
+
+        certs_c[0] = cert_and_key;
+        certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
+                              &kCFTypeArrayCallBacks);
+        err = SSLSetCertificate(connssl->ssl_ctx, certs);
+        if(certs)
+          CFRelease(certs);
+        CFRelease(cert_and_key);
+        if(err != noErr) {
+          failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
+          return CURLE_SSL_CERTPROBLEM;
+        }
+      }
+      else {
+        failf(data, "SSL: Can't find a private key in the Keychain that goes "
+              "with the certificate \"%s\".", data->set.str[STRING_CERT]);
+        return CURLE_SSL_CERTPROBLEM;
+      }
+
+      if(cert)
+        CFRelease(cert);
+    }
+    else {
+      failf(data, "SSL: Can't find the certificate \"%s\" in the Keychain.",
+            data->set.str[STRING_CERT]);
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
 
   /* SSL always tries to verify the peer, this only says whether it should
    * fail to connect if the verification fails, or if it should continue
@@ -1093,6 +1233,20 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
               "certificate format");
         return CURLE_SSL_CONNECT_ERROR;
 
+      /* These are all certificate problems with the client: */
+      case errSecAuthFailed:
+        failf(data, "SSL authentication failed");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLPeerHandshakeFail:
+        failf(data, "SSL peer handshake failed, the server most likely "
+              "requires a client certificate to connect");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLPeerUnknownCA:
+        failf(data, "SSL server rejected the client certificate due to "
+              "the certificate being signed by an unknown certificate "
+              "authority");
+        return CURLE_SSL_CONNECT_ERROR;
+
       /* This error is raised if the server's cert didn't match the server's
          host name: */
       case errSSLHostNameMismatch:

