Search code examples
libcurlsslv3

libcurl with client ssl certificate returns 403 but curl works fine


I'm trying to use Azure Service Management REST API on Ubuntu with culr and curl works fine:

curl --libcurl mylibcurl.c -v -H "Content-Type: application/xml" -H "x-ms-version: 2012-08-01" -E /home/azure/tmp/cert.pem: https://management.core.windows.net/your_subscription_id/services/hostedservices/your_service/deployments/your_vm

* Hostname was NOT found in DNS cache
*   Trying 157.55.195.251...
* Connected to management.core.windows.net (157.55.195.251) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using AES128-SHA256
* Server certificate:
*        subject: C=US; ST=WA; L=Redmond; O=Microsoft; OU=OrganizationName; CN=ussouth2.management.core.windows.net
*        start date: 2013-06-07 19:45:29 GMT
*        expire date: 2015-06-07 19:45:29 GMT
*        subjectAltName: management.core.windows.net matched
*        issuer: DC=com; DC=microsoft; DC=corp; DC=redmond; CN=MSIT Machine Auth CA 2
*        SSL certificate verify ok.
> GET /your_subscription_id/services/hostedservices/shchVmFromCUrl/deployments/shchVmFromCUrl HTTP/1.1
> User-Agent: curl/7.35.0
> Host: management.core.windows.net
> Accept: */*
> Content-Type: application/xml
> x-ms-version: 2012-08-01
>
* SSLv3, TLS handshake, Hello request (0):
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Request CERT (13):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS handshake, CERT verify (15):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
< HTTP/1.1 200 OK
< Cache-Control: no-cache
< Content-Length: 2865
< Content-Type: application/xml; charset=utf-8
* Server 1.0.6198.110 (rd_rdfe_stable.140729-1337) Microsoft-HTTPAPI/2.0 is not blacklisted
< Server: 1.0.6198.110 (rd_rdfe_stable.140729-1337) Microsoft-HTTPAPI/2.0
< x-ms-servedbyregion: ussouth2
< x-ms-request-id: 0d64fdafdce8c30c8ef517d1a97635af
< Date: Thu, 07 Aug 2014 20:57:13 GMT
<
<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Name>
... 
</Deployment>

But the same request with libcurl returns 403 Forbidden.

az you can see I used --libcurl mylibcurl.c flag in curl to make it create a c file to use it with libculr

this is how this file looks like:

/********* Sample code generated by the curl command line tool **********
 * All curl_easy_setopt() options are documented at:
 * http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
 ************************************************************************/
#include <curl/curl.h>

int main(int argc, char *argv[])
{
  CURLcode ret;
  CURL *hnd;
  struct curl_slist *slist1;

  slist1 = NULL;
  slist1 = curl_slist_append(slist1, "Content-Type: application/xml");
  slist1 = curl_slist_append(slist1, "x-ms-version: 2012-08-01");

  hnd = curl_easy_init();
  curl_easy_setopt(hnd, CURLOPT_URL, "https://management.core.windows.net/your_subscription_id/services/hostedservices/your_service/deployments/your_vm")
  curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
  curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.35.0");
  curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1);
  curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
  curl_easy_setopt(hnd, CURLOPT_SSLCERT, "/home/azure/tmp/cert.pem");
  curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
  curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);

  /* Here is a list of options the curl code used that cannot get generated
     as source easily. You may select to either not use them or implement
     them yourself.

  CURLOPT_WRITEDATA set to a objectpointer
  CURLOPT_WRITEFUNCTION set to a functionpointer
  CURLOPT_READDATA set to a objectpointer
  CURLOPT_READFUNCTION set to a functionpointer
  CURLOPT_SEEKDATA set to a objectpointer
  CURLOPT_SEEKFUNCTION set to a functionpointer
  CURLOPT_ERRORBUFFER set to a objectpointer
  CURLOPT_STDERR set to a objectpointer
  CURLOPT_DEBUGFUNCTION set to a functionpointer
  CURLOPT_DEBUGDATA set to a objectpointer
  CURLOPT_HEADERFUNCTION set to a functionpointer
  CURLOPT_HEADERDATA set to a objectpointer

  */

  ret = curl_easy_perform(hnd);

  curl_easy_cleanup(hnd);
  hnd = NULL;
  curl_slist_free_all(slist1);
  slist1 = NULL;

  return (int)ret;
}
/**** End of sample code ****/

I built it

gcc mylibcurl.c -o mylibcurl -lcurl

and start it

mylibcurl

* Hostname was NOT found in DNS cache
*   Trying 157.55.195.251...
* Connected to management.core.windows.net (157.55.195.251) port 443 (#0)
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
*        server certificate verification OK
*        common name: ussouth2.management.core.windows.net (matched)
*        server certificate expiration date OK
*        server certificate activation date OK
*        certificate public key: RSA
*        certificate version: #3
*        subject: C=US,ST=WA,L=Redmond,O=Microsoft,OU=OrganizationName,CN=ussouth2.management.core.windows.net
*        start date: Fri, 07 Jun 2013 19:45:29 GMT

*        expire date: Sun, 07 Jun 2015 19:45:29 GMT

*        issuer: DC=com,DC=microsoft,DC=corp,DC=redmond,CN=MSIT Machine Auth CA 2
*        compression: NULL
*        cipher: AES-128-CBC
*        MAC: SHA256
> GET /your_subscription_id/services/hostedservices/shchVmFromCUrl/deployments/shchVmFromCUrl HTTP/1.1
User-Agent: curl/7.35.0
Host: management.core.windows.net
Accept: */*
Content-Type: application/xml
x-ms-version: 2012-08-01

< HTTP/1.1 403 Forbidden
< Content-Length: 288
< Content-Type: application/xml; charset=utf-8
* Server Microsoft-HTTPAPI/2.0 is not blacklisted
< Server: Microsoft-HTTPAPI/2.0
< Date: Thu, 07 Aug 2014 23:57:17 GMT
<
* Connection #0 to host management.core.windows.net left intact
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Code>Forb
ddenError</Code><Message>The server failed to authenticate the request. Verify that the certificate is valid and is ass
ciated with this subscription.</Message></Error>

What did I miss?


Solution

  • Add this. Probably your local ssl cert isn't verifying:

    curl_easy_setopt(hnd,  CURLOPT_SSL_VERIFYPEER, 0);
    

    It tells it to ignore checking if the cert is valid. There is a more secure and complicated way of doing this but this will at least pinpoint the error and make it run.