Loading docs/curl.1 +6 −4 Original line number Diff line number Diff line Loading @@ -394,7 +394,8 @@ If this option is used several times, the last one will be used. .IP "-E, --cert <certificate[:password]>" (SSL) Tells curl to use the specified client certificate file when getting a file with HTTPS, FTPS or another SSL-based protocol. The certificate must be in PEM format. If the optional password isn't specified, it will be queried in PKCS#12 format if using Secure Transport, or PEM format if using any other engine. If the optional password isn't specified, it will be queried for on the terminal. Note that this option assumes a \&"certificate" file that is the private key and the private certificate concatenated! See \fI--cert\fP and \fI--key\fP to specify them independently. Loading @@ -410,9 +411,10 @@ recognized as password delimiter. If the nickname contains "\\", it needs to be escaped as "\\\\" so that it is not recognized as an escape character. (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. certificate string can either be the name of a certificate/private key in the system or user keychain, or the path to a PKCS#12-encoded certificate and private key. If you want to use a file from the current directory, please precede it with "./" prefix, in order to avoid confusion with a nickname. If this option is used several times, the last one will be used. .IP "--engine <name>" Loading docs/libcurl/curl_easy_setopt.3 +13 −15 Original line number Diff line number Diff line Loading @@ -2305,22 +2305,20 @@ timeout is set, the internal default of 60000 will be used. (Added in 7.24.0) .SH SSL and SECURITY OPTIONS .IP CURLOPT_SSLCERT Pass a pointer to a zero terminated string as parameter. The string should be the file name of your certificate. The default format is "PEM" and can be 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. You should encode this string in UTF-8 format in case it contains non-ASCII characters. The private key corresponding to the certificate, and certificate chain (if any), must also be present in the keychain. (Added in 7.31.0) the file name of your certificate. The default format is "P12" on Secure Transport and "PEM" on other engines, and can be changed with \fICURLOPT_SSLCERTTYPE\fP. With NSS or Secure Transport, this can also be the nickname of the certificate you wish to authenticate with as it is named in the security database. If you want to use a file from the current directory, please precede it with "./" prefix, in order to avoid confusion with a nickname. .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 in 7.9.3) the format of your certificate. Supported formats are "PEM" and "DER", except with Secure Transport. OpenSSL (versions 0.9.3 and later) and Secure Transport (on iOS 5 or later, or OS X 10.6 or later) also support "P12" for PKCS#12-encoded files. (Added in 7.9.3) .IP CURLOPT_SSLKEY 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 Loading @@ -2328,7 +2326,7 @@ 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. the keychain or PKCS#12 file 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". Loading lib/curl_darwinssl.c +105 −4 Original line number Diff line number Diff line Loading @@ -819,6 +819,68 @@ static OSStatus CopyIdentityWithLabel(char *label, return status; } static OSStatus CopyIdentityFromPKCS12File(const char *cPath, const char *cPassword, SecIdentityRef *out_cert_and_key) { OSStatus status = errSecItemNotFound; CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8 *)cPath, strlen(cPath), false); CFStringRef password = cPassword ? CFStringCreateWithCString(NULL, cPassword, kCFStringEncodingUTF8) : NULL; CFDataRef pkcs_data = NULL; /* We can import P12 files on iOS or OS X 10.6 or later: */ #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data, NULL, NULL, &status)) { const void *cKeys[] = {kSecImportExportPassphrase}; const void *cValues[] = {password}; CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues, password ? 1L : 0L, NULL, NULL); CFArrayRef items = NULL; /* Here we go: */ status = SecPKCS12Import(pkcs_data, options, &items); if(status == noErr) { CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L); const void *temp_identity = CFDictionaryGetValue(identity_and_trust, kSecImportItemIdentity); /* Retain the identity; we don't care about any other data... */ CFRetain(temp_identity); *out_cert_and_key = (SecIdentityRef)temp_identity; CFRelease(items); } CFRelease(options); CFRelease(pkcs_data); } #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ if(password) CFRelease(password); CFRelease(pkcs_url); return status; } /* This code was borrowed from nss.c, with some modifications: * Determine whether the nickname passed in is a filename that needs to * be loaded as a PEM or a regular NSS nickname. * * returns 1 for a file * returns 0 for not a file */ CF_INLINE bool is_file(const char *filename) { struct_stat st; if(filename == NULL) return false; if(stat(filename, &st) == 0) return S_ISREG(st.st_mode); return false; } static CURLcode darwinssl_connect_step1(struct connectdata *conn, int sockindex) { Loading Loading @@ -988,9 +1050,27 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, if(data->set.str[STRING_CERT]) { SecIdentityRef cert_and_key = NULL; /* User wants to authenticate with a client cert. Look for it: */ bool is_cert_file = is_file(data->set.str[STRING_CERT]); /* User wants to authenticate with a client cert. Look for it: If we detect that this is a file on disk, then let's load it. Otherwise, assume that the user wants to use an identity loaded from the Keychain. */ if(is_cert_file) { if(!data->set.str[STRING_CERT_TYPE]) infof(data, "WARNING: SSL: Certificate type not set, assuming " "PKCS#12 format.\n"); else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12", strlen(data->set.str[STRING_CERT_TYPE])) != 0) infof(data, "WARNING: SSL: The Security framework only supports " "loading identities that are in PKCS#12 format.\n"); err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT], data->set.str[STRING_KEY_PASSWD], &cert_and_key); } else err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key); if(err == noErr) { SecCertificateRef cert = NULL; CFTypeRef certs_c[1]; Loading Loading @@ -1027,8 +1107,29 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, CFRelease(cert_and_key); } else { failf(data, "SSL: Can't find the certificate \"%s\" and its private key " "in the Keychain.", data->set.str[STRING_CERT]); switch(err) { case errSecPkcs12VerifyFailure: case errSecAuthFailed: failf(data, "SSL: Incorrect password for the certificate \"%s\" " "and its private key.", data->set.str[STRING_CERT]); break; case errSecDecode: case errSecUnknownFormat: failf(data, "SSL: Couldn't make sense of the data in the " "certificate \"%s\" and its private key.", data->set.str[STRING_CERT]); break; case errSecPassphraseRequired: failf(data, "SSL The certificate \"%s\" requires a password.", data->set.str[STRING_CERT]); break; case errSecItemNotFound: failf(data, "SSL: Can't find the certificate \"%s\" and its private " "key in the Keychain.", data->set.str[STRING_CERT]); break; default: failf(data, "SSL: Can't load the certificate \"%s\" and its private " "key: OSStatus %d", data->set.str[STRING_CERT], err); break; } return CURLE_SSL_CERTPROBLEM; } } Loading Loading
docs/curl.1 +6 −4 Original line number Diff line number Diff line Loading @@ -394,7 +394,8 @@ If this option is used several times, the last one will be used. .IP "-E, --cert <certificate[:password]>" (SSL) Tells curl to use the specified client certificate file when getting a file with HTTPS, FTPS or another SSL-based protocol. The certificate must be in PEM format. If the optional password isn't specified, it will be queried in PKCS#12 format if using Secure Transport, or PEM format if using any other engine. If the optional password isn't specified, it will be queried for on the terminal. Note that this option assumes a \&"certificate" file that is the private key and the private certificate concatenated! See \fI--cert\fP and \fI--key\fP to specify them independently. Loading @@ -410,9 +411,10 @@ recognized as password delimiter. If the nickname contains "\\", it needs to be escaped as "\\\\" so that it is not recognized as an escape character. (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. certificate string can either be the name of a certificate/private key in the system or user keychain, or the path to a PKCS#12-encoded certificate and private key. If you want to use a file from the current directory, please precede it with "./" prefix, in order to avoid confusion with a nickname. If this option is used several times, the last one will be used. .IP "--engine <name>" Loading
docs/libcurl/curl_easy_setopt.3 +13 −15 Original line number Diff line number Diff line Loading @@ -2305,22 +2305,20 @@ timeout is set, the internal default of 60000 will be used. (Added in 7.24.0) .SH SSL and SECURITY OPTIONS .IP CURLOPT_SSLCERT Pass a pointer to a zero terminated string as parameter. The string should be the file name of your certificate. The default format is "PEM" and can be 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. You should encode this string in UTF-8 format in case it contains non-ASCII characters. The private key corresponding to the certificate, and certificate chain (if any), must also be present in the keychain. (Added in 7.31.0) the file name of your certificate. The default format is "P12" on Secure Transport and "PEM" on other engines, and can be changed with \fICURLOPT_SSLCERTTYPE\fP. With NSS or Secure Transport, this can also be the nickname of the certificate you wish to authenticate with as it is named in the security database. If you want to use a file from the current directory, please precede it with "./" prefix, in order to avoid confusion with a nickname. .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 in 7.9.3) the format of your certificate. Supported formats are "PEM" and "DER", except with Secure Transport. OpenSSL (versions 0.9.3 and later) and Secure Transport (on iOS 5 or later, or OS X 10.6 or later) also support "P12" for PKCS#12-encoded files. (Added in 7.9.3) .IP CURLOPT_SSLKEY 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 Loading @@ -2328,7 +2326,7 @@ 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. the keychain or PKCS#12 file 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". Loading
lib/curl_darwinssl.c +105 −4 Original line number Diff line number Diff line Loading @@ -819,6 +819,68 @@ static OSStatus CopyIdentityWithLabel(char *label, return status; } static OSStatus CopyIdentityFromPKCS12File(const char *cPath, const char *cPassword, SecIdentityRef *out_cert_and_key) { OSStatus status = errSecItemNotFound; CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8 *)cPath, strlen(cPath), false); CFStringRef password = cPassword ? CFStringCreateWithCString(NULL, cPassword, kCFStringEncodingUTF8) : NULL; CFDataRef pkcs_data = NULL; /* We can import P12 files on iOS or OS X 10.6 or later: */ #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data, NULL, NULL, &status)) { const void *cKeys[] = {kSecImportExportPassphrase}; const void *cValues[] = {password}; CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues, password ? 1L : 0L, NULL, NULL); CFArrayRef items = NULL; /* Here we go: */ status = SecPKCS12Import(pkcs_data, options, &items); if(status == noErr) { CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L); const void *temp_identity = CFDictionaryGetValue(identity_and_trust, kSecImportItemIdentity); /* Retain the identity; we don't care about any other data... */ CFRetain(temp_identity); *out_cert_and_key = (SecIdentityRef)temp_identity; CFRelease(items); } CFRelease(options); CFRelease(pkcs_data); } #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ if(password) CFRelease(password); CFRelease(pkcs_url); return status; } /* This code was borrowed from nss.c, with some modifications: * Determine whether the nickname passed in is a filename that needs to * be loaded as a PEM or a regular NSS nickname. * * returns 1 for a file * returns 0 for not a file */ CF_INLINE bool is_file(const char *filename) { struct_stat st; if(filename == NULL) return false; if(stat(filename, &st) == 0) return S_ISREG(st.st_mode); return false; } static CURLcode darwinssl_connect_step1(struct connectdata *conn, int sockindex) { Loading Loading @@ -988,9 +1050,27 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, if(data->set.str[STRING_CERT]) { SecIdentityRef cert_and_key = NULL; /* User wants to authenticate with a client cert. Look for it: */ bool is_cert_file = is_file(data->set.str[STRING_CERT]); /* User wants to authenticate with a client cert. Look for it: If we detect that this is a file on disk, then let's load it. Otherwise, assume that the user wants to use an identity loaded from the Keychain. */ if(is_cert_file) { if(!data->set.str[STRING_CERT_TYPE]) infof(data, "WARNING: SSL: Certificate type not set, assuming " "PKCS#12 format.\n"); else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12", strlen(data->set.str[STRING_CERT_TYPE])) != 0) infof(data, "WARNING: SSL: The Security framework only supports " "loading identities that are in PKCS#12 format.\n"); err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT], data->set.str[STRING_KEY_PASSWD], &cert_and_key); } else err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key); if(err == noErr) { SecCertificateRef cert = NULL; CFTypeRef certs_c[1]; Loading Loading @@ -1027,8 +1107,29 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, CFRelease(cert_and_key); } else { failf(data, "SSL: Can't find the certificate \"%s\" and its private key " "in the Keychain.", data->set.str[STRING_CERT]); switch(err) { case errSecPkcs12VerifyFailure: case errSecAuthFailed: failf(data, "SSL: Incorrect password for the certificate \"%s\" " "and its private key.", data->set.str[STRING_CERT]); break; case errSecDecode: case errSecUnknownFormat: failf(data, "SSL: Couldn't make sense of the data in the " "certificate \"%s\" and its private key.", data->set.str[STRING_CERT]); break; case errSecPassphraseRequired: failf(data, "SSL The certificate \"%s\" requires a password.", data->set.str[STRING_CERT]); break; case errSecItemNotFound: failf(data, "SSL: Can't find the certificate \"%s\" and its private " "key in the Keychain.", data->set.str[STRING_CERT]); break; default: failf(data, "SSL: Can't load the certificate \"%s\" and its private " "key: OSStatus %d", data->set.str[STRING_CERT], err); break; } return CURLE_SSL_CERTPROBLEM; } } Loading