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.