simplessl.c (4900B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 /* <DESC> 25 * Shows HTTPS usage with client certs and optional ssl engine use. 26 * </DESC> 27 */ 28 #include <stdio.h> 29 30 #include <curl/curl.h> 31 32 /* some requirements for this to work: 33 1. set pCertFile to the file with the client certificate 34 2. if the key is passphrase protected, set pPassphrase to the 35 passphrase you use 36 3. if you are using a crypto engine: 37 3.1. set a #define USE_ENGINE 38 3.2. set pEngine to the name of the crypto engine you use 39 3.3. set pKeyName to the key identifier you want to use 40 4. if you do not use a crypto engine: 41 4.1. set pKeyName to the filename of your client key 42 4.2. if the format of the key file is DER, set pKeyType to "DER" 43 44 !! verify of the server certificate is not implemented here !! 45 46 **** This example only works with libcurl 7.9.3 and later! **** 47 48 */ 49 50 int main(void) 51 { 52 CURL *curl; 53 CURLcode res; 54 FILE *headerfile; 55 const char *pPassphrase = NULL; 56 57 static const char *pCertFile = "testcert.pem"; 58 static const char *pCACertFile = "cacert.pem"; 59 static const char *pHeaderFile = "dumpit"; 60 61 const char *pKeyName; 62 const char *pKeyType; 63 64 const char *pEngine; 65 66 #ifdef USE_ENGINE 67 pKeyName = "rsa_test"; 68 pKeyType = "ENG"; 69 pEngine = "chil"; /* for nChiper HSM... */ 70 #else 71 pKeyName = "testkey.pem"; 72 pKeyType = "PEM"; 73 pEngine = NULL; 74 #endif 75 76 headerfile = fopen(pHeaderFile, "wb"); 77 if(!headerfile) 78 return 1; 79 80 curl_global_init(CURL_GLOBAL_DEFAULT); 81 82 curl = curl_easy_init(); 83 if(curl) { 84 /* what call to write: */ 85 curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://secure.site.example"); 86 curl_easy_setopt(curl, CURLOPT_HEADERDATA, headerfile); 87 88 #ifdef _MSC_VER 89 #pragma warning(push) 90 #pragma warning(disable:4127) /* conditional expression is constant */ 91 #endif 92 do { /* dummy loop, just to break out from */ 93 if(pEngine) { 94 /* use crypto engine */ 95 if(curl_easy_setopt(curl, CURLOPT_SSLENGINE, pEngine) != CURLE_OK) { 96 /* load the crypto engine */ 97 fprintf(stderr, "cannot set crypto engine\n"); 98 break; 99 } 100 if(curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L) != CURLE_OK) { 101 /* set the crypto engine as default */ 102 /* only needed for the first time you load 103 an engine in a curl object... */ 104 fprintf(stderr, "cannot set crypto engine as default\n"); 105 break; 106 } 107 } 108 /* cert is stored PEM coded in file... */ 109 /* since PEM is default, we needn't set it for PEM */ 110 curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); 111 112 /* set the cert for client authentication */ 113 curl_easy_setopt(curl, CURLOPT_SSLCERT, pCertFile); 114 115 /* sorry, for engine we must set the passphrase 116 (if the key has one...) */ 117 if(pPassphrase) 118 curl_easy_setopt(curl, CURLOPT_KEYPASSWD, pPassphrase); 119 120 /* if we use a key stored in a crypto engine, 121 we must set the key type to "ENG" */ 122 curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, pKeyType); 123 124 /* set the private key (file or ID in engine) */ 125 curl_easy_setopt(curl, CURLOPT_SSLKEY, pKeyName); 126 127 /* set the file with the certs validating the server */ 128 curl_easy_setopt(curl, CURLOPT_CAINFO, pCACertFile); 129 130 /* disconnect if we cannot validate server's cert */ 131 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); 132 133 /* Perform the request, res gets the return code */ 134 res = curl_easy_perform(curl); 135 /* Check for errors */ 136 if(res != CURLE_OK) 137 fprintf(stderr, "curl_easy_perform() failed: %s\n", 138 curl_easy_strerror(res)); 139 140 /* we are done... */ 141 } while(0); 142 #ifdef _MSC_VER 143 #pragma warning(pop) 144 #endif 145 /* always cleanup */ 146 curl_easy_cleanup(curl); 147 } 148 149 curl_global_cleanup(); 150 151 fclose(headerfile); 152 153 return 0; 154 }