33

When I try to use Curl on windows, to retrieve an https url, I get the dreaded "connection error (60)."

enter image description here

The exact error message is:

curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html

How to resolve this?

4
  • SU doesn't like the word "problem" in the title because it's not descriptive. If you can't figure out a way to re-phrase your title without the word "problem," you're not trying hard enough. :)
    – Garrett
    Commented Jun 28, 2012 at 21:49
  • 1
    it's an exact quote of the message I'm asking about. I don't want to try to remove that word, it's an important one, for search indexing.
    – Cheeso
    Commented Jun 28, 2012 at 22:56
  • 1
    @Cheeso: Post contents get indexed as well, someone searching for your question would see it in the description under the title. Commented Sep 22, 2012 at 13:47
  • Please visit this link for windows users. This might be helpful. Link Commented Jun 5, 2021 at 12:41

3 Answers 3

39

I don't know why but I did not find this information all in one place.

  1. Download the SSL-aware version of Curl, or build the SSL-aware version yourself.

  2. From http://curl.haxx.se/docs/caextract.html , Download the cacert.pem file.

  3. Place the curl.exe and the .pem file in the same directory.

  4. Rename the cacert.pem file to curl-ca-bundle.crt

  5. Re-run curl.exe !


EDIT:

There are other ways to solve the problem. this particular way relies on a cacert produced by the maker of Curl. That may not be what you want, and in particular, it may not work for cases where you have a less-than-well-known certifying authority (such as an authority known only to your corporation) for the certificate used by the SSL site. In that case, you will want to generate your own curl-ca-bundle.crt file. You can use certreq.exe and openssl.exe to export such a cert from the IE/Windows store, and then convert-to-pem-format, respectively.

7
  • 1
    Thank you!!! I tried to cURL an HTTPS recently and had a heck of a time trying to figure out how to get it to work. Like you, I too had to check a variety of sources for information, but unfortunately, I did not find the part about having to download the cert file from the cURL site (I saw plenty of stuff about downloading the cert from the target site, but not this).
    – Synetech
    Commented Jun 28, 2012 at 21:07
  • Glad it helped.
    – Cheeso
    Commented Jun 28, 2012 at 21:18
  • What is the point of renaming it to curl-ca-bundle.crt? Is it windows specific?
    – nawfal
    Commented Nov 9, 2015 at 11:58
  • Thanks! I was using curl marked WinSSL on Windows 7. According to the documentation link, versions so-marked should just work using the system's certificates. However, I was getting the error until I followed your solution.
    – George
    Commented Apr 22, 2018 at 2:00
  • However, if the end user does not have admin righrts, they will not be able to put the new certificate on folders that belong to the system. Alternatively, the user can use the environment variable set CURL_CA_BUNDLE=<path to crt>. Make shure the format of the file is proper. This method will work even if you have multiple curl installations, e.g. git, vagrant...
    – Aaron C
    Commented May 2, 2018 at 18:56
8

I have created a PowerShell script that is capable of writing the ca-cert.crt file based on the CA certificates that are installed in your Windows certification store (CurrentUser or LocalMachine). Run the script like this:

CreateCaCert.ps1 -StoreLocation CurrentUser | Out-File -Encoding utf8 curl-ca-cert.crt

This will create the curl-ca-cert.crt file that should be stored in the same directory as curl.exe and you should be able to validate the same sites as you can in your Windows applications (note that this file can also be consumed by git).

The "official" script can be found on GitHub, but the initial version is listed here for reference:

[CmdletBinding()]
Param(
    [ValidateSet(
        [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser,
        [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)]
    [string]
    $StoreLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser
)

$maxLineLength = 77

# Open the store
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store ([System.Security.Cryptography.X509Certificates.StoreName]::Root, $StoreLocation)
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly);

# Write header
Write-Output "# Root certificates ($StoreLocation) generated at $(Get-Date)"

# Write all certificates
Foreach ($certificate in $store.Certificates)
{
    # Start with an empty line
    Write-Output ""

    # Convert the certificate to a BASE64 encoded string
    $certString = [Convert]::ToBase64String($certificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Cert));

    # Write the actual certificate
    Write-Output "# Friendly name: $($certificate.FriendlyName)"
    Write-Output "# Issuer:        $($certificate.Issuer)"
    Write-Output "# Expiration:    $($certificate.GetExpirationDateString())"
    Write-Output "# Serial:        $($certificate.SerialNumber)"
    Write-Output "# Thumbprint:    $($certificate.Thumbprint)"
    Write-Output "-----BEGIN CERTIFICATE-----"
    For ($i = 0; $i -lt $certString.Length; $i += $maxLineLength)
    {
        Write-Output $certString.Substring($i, [Math]::Min($maxLineLength, $certString.Length - $i))
    }
    Write-Output "-----END CERTIFICATE-----"
}
1
  • Thank you, very helpful. One side note: PowerShell won't allow ps1 commands in the current directory without specifying a path. So you need to start it as ".\CreateCaCert.ps1..." Commented Mar 15, 2022 at 22:12
2

Actually we had the same problem with Typheous/Ruby. The Solution was downloading the cacert.pem and save it to C:\Windows\System32 (or whereever your Windows is). After that we set a global environment variable like discribed here where the "Variable Name" must be CURL_CA_BUNDLE and the "Variable Value" the path to the file %SystemRoot%\System32\cacert.pem.

When starting a new CMD Session you can now just use Typheous/Libcurl thing to authenticate SSL Connections. I've successfully tried this with Windows 8.1.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .