113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci/* <DESC> 2513498266Sopenharmony_ci * Use an in-memory user certificate and RSA key and retrieve an https page. 2613498266Sopenharmony_ci * </DESC> 2713498266Sopenharmony_ci */ 2813498266Sopenharmony_ci/* Written by Ishan SinghLevett, based on Theo Borm's cacertinmem.c. 2913498266Sopenharmony_ci * Note that to maintain simplicity this example does not use a CA certificate 3013498266Sopenharmony_ci * for peer verification. However, some form of peer verification 3113498266Sopenharmony_ci * must be used in real circumstances when a secure connection is required. 3213498266Sopenharmony_ci */ 3313498266Sopenharmony_ci 3413498266Sopenharmony_ci#include <openssl/ssl.h> 3513498266Sopenharmony_ci#include <openssl/x509.h> 3613498266Sopenharmony_ci#include <openssl/pem.h> 3713498266Sopenharmony_ci#include <curl/curl.h> 3813498266Sopenharmony_ci#include <stdio.h> 3913498266Sopenharmony_ci 4013498266Sopenharmony_cistatic size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream) 4113498266Sopenharmony_ci{ 4213498266Sopenharmony_ci fwrite(ptr, size, nmemb, stream); 4313498266Sopenharmony_ci return (nmemb*size); 4413498266Sopenharmony_ci} 4513498266Sopenharmony_ci 4613498266Sopenharmony_cistatic CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) 4713498266Sopenharmony_ci{ 4813498266Sopenharmony_ci X509 *cert = NULL; 4913498266Sopenharmony_ci BIO *bio = NULL; 5013498266Sopenharmony_ci BIO *kbio = NULL; 5113498266Sopenharmony_ci RSA *rsa = NULL; 5213498266Sopenharmony_ci int ret; 5313498266Sopenharmony_ci 5413498266Sopenharmony_ci const char *mypem = /* www.cacert.org */ 5513498266Sopenharmony_ci "-----BEGIN CERTIFICATE-----\n"\ 5613498266Sopenharmony_ci "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\ 5713498266Sopenharmony_ci "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\ 5813498266Sopenharmony_ci "IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\ 5913498266Sopenharmony_ci "Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\ 6013498266Sopenharmony_ci "BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\ 6113498266Sopenharmony_ci "MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\ 6213498266Sopenharmony_ci "ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\ 6313498266Sopenharmony_ci "CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\ 6413498266Sopenharmony_ci "8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\ 6513498266Sopenharmony_ci "zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\ 6613498266Sopenharmony_ci "fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\ 6713498266Sopenharmony_ci "w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\ 6813498266Sopenharmony_ci "G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\ 6913498266Sopenharmony_ci "epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\ 7013498266Sopenharmony_ci "laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\ 7113498266Sopenharmony_ci "QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\ 7213498266Sopenharmony_ci "fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\ 7313498266Sopenharmony_ci "YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\ 7413498266Sopenharmony_ci "ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\ 7513498266Sopenharmony_ci "gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\ 7613498266Sopenharmony_ci "MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\ 7713498266Sopenharmony_ci "IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\ 7813498266Sopenharmony_ci "dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\ 7913498266Sopenharmony_ci "czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\ 8013498266Sopenharmony_ci "dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\ 8113498266Sopenharmony_ci "aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\ 8213498266Sopenharmony_ci "AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\ 8313498266Sopenharmony_ci "b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\ 8413498266Sopenharmony_ci "ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\ 8513498266Sopenharmony_ci "nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\ 8613498266Sopenharmony_ci "18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\ 8713498266Sopenharmony_ci "gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\ 8813498266Sopenharmony_ci "Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\ 8913498266Sopenharmony_ci "sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\ 9013498266Sopenharmony_ci "SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\ 9113498266Sopenharmony_ci "CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\ 9213498266Sopenharmony_ci "GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\ 9313498266Sopenharmony_ci "zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\ 9413498266Sopenharmony_ci "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\ 9513498266Sopenharmony_ci "-----END CERTIFICATE-----\n"; 9613498266Sopenharmony_ci 9713498266Sopenharmony_ci/* replace the XXX with the actual RSA key */ 9813498266Sopenharmony_ci const char *mykey = 9913498266Sopenharmony_ci "-----BEGIN RSA PRIVATE KEY-----\n"\ 10013498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 10113498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 10213498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 10313498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 10413498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 10513498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 10613498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 10713498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 10813498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 10913498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 11013498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 11113498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 11213498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 11313498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 11413498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 11513498266Sopenharmony_ci "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ 11613498266Sopenharmony_ci "-----END RSA PRIVATE KEY-----\n"; 11713498266Sopenharmony_ci 11813498266Sopenharmony_ci (void)curl; /* avoid warnings */ 11913498266Sopenharmony_ci (void)parm; /* avoid warnings */ 12013498266Sopenharmony_ci 12113498266Sopenharmony_ci /* get a BIO */ 12213498266Sopenharmony_ci bio = BIO_new_mem_buf((char *)mypem, -1); 12313498266Sopenharmony_ci 12413498266Sopenharmony_ci if(!bio) { 12513498266Sopenharmony_ci printf("BIO_new_mem_buf failed\n"); 12613498266Sopenharmony_ci } 12713498266Sopenharmony_ci 12813498266Sopenharmony_ci /* use it to read the PEM formatted certificate from memory into an X509 12913498266Sopenharmony_ci * structure that SSL can use 13013498266Sopenharmony_ci */ 13113498266Sopenharmony_ci cert = PEM_read_bio_X509(bio, NULL, 0, NULL); 13213498266Sopenharmony_ci if(!cert) { 13313498266Sopenharmony_ci printf("PEM_read_bio_X509 failed...\n"); 13413498266Sopenharmony_ci } 13513498266Sopenharmony_ci 13613498266Sopenharmony_ci /* tell SSL to use the X509 certificate */ 13713498266Sopenharmony_ci ret = SSL_CTX_use_certificate((SSL_CTX*)sslctx, cert); 13813498266Sopenharmony_ci if(ret != 1) { 13913498266Sopenharmony_ci printf("Use certificate failed\n"); 14013498266Sopenharmony_ci } 14113498266Sopenharmony_ci 14213498266Sopenharmony_ci /* create a bio for the RSA key */ 14313498266Sopenharmony_ci kbio = BIO_new_mem_buf((char *)mykey, -1); 14413498266Sopenharmony_ci if(!kbio) { 14513498266Sopenharmony_ci printf("BIO_new_mem_buf failed\n"); 14613498266Sopenharmony_ci } 14713498266Sopenharmony_ci 14813498266Sopenharmony_ci /* read the key bio into an RSA object */ 14913498266Sopenharmony_ci rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL); 15013498266Sopenharmony_ci if(!rsa) { 15113498266Sopenharmony_ci printf("Failed to create key bio\n"); 15213498266Sopenharmony_ci } 15313498266Sopenharmony_ci 15413498266Sopenharmony_ci /* tell SSL to use the RSA key from memory */ 15513498266Sopenharmony_ci ret = SSL_CTX_use_RSAPrivateKey((SSL_CTX*)sslctx, rsa); 15613498266Sopenharmony_ci if(ret != 1) { 15713498266Sopenharmony_ci printf("Use Key failed\n"); 15813498266Sopenharmony_ci } 15913498266Sopenharmony_ci 16013498266Sopenharmony_ci /* free resources that have been allocated by openssl functions */ 16113498266Sopenharmony_ci if(bio) 16213498266Sopenharmony_ci BIO_free(bio); 16313498266Sopenharmony_ci 16413498266Sopenharmony_ci if(kbio) 16513498266Sopenharmony_ci BIO_free(kbio); 16613498266Sopenharmony_ci 16713498266Sopenharmony_ci if(rsa) 16813498266Sopenharmony_ci RSA_free(rsa); 16913498266Sopenharmony_ci 17013498266Sopenharmony_ci if(cert) 17113498266Sopenharmony_ci X509_free(cert); 17213498266Sopenharmony_ci 17313498266Sopenharmony_ci /* all set to go */ 17413498266Sopenharmony_ci return CURLE_OK; 17513498266Sopenharmony_ci} 17613498266Sopenharmony_ci 17713498266Sopenharmony_ciint main(void) 17813498266Sopenharmony_ci{ 17913498266Sopenharmony_ci CURL *ch; 18013498266Sopenharmony_ci CURLcode rv; 18113498266Sopenharmony_ci 18213498266Sopenharmony_ci curl_global_init(CURL_GLOBAL_ALL); 18313498266Sopenharmony_ci ch = curl_easy_init(); 18413498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_VERBOSE, 0L); 18513498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_HEADER, 0L); 18613498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_NOPROGRESS, 1L); 18713498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L); 18813498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, writefunction); 18913498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_WRITEDATA, stdout); 19013498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_HEADERFUNCTION, writefunction); 19113498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_HEADERDATA, stderr); 19213498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, "PEM"); 19313498266Sopenharmony_ci 19413498266Sopenharmony_ci /* both VERIFYPEER and VERIFYHOST are set to 0 in this case because there is 19513498266Sopenharmony_ci no CA certificate */ 19613498266Sopenharmony_ci 19713498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 0L); 19813498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, 0L); 19913498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/"); 20013498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_SSLKEYTYPE, "PEM"); 20113498266Sopenharmony_ci 20213498266Sopenharmony_ci /* first try: retrieve page without user certificate and key -> will fail 20313498266Sopenharmony_ci */ 20413498266Sopenharmony_ci rv = curl_easy_perform(ch); 20513498266Sopenharmony_ci if(rv == CURLE_OK) { 20613498266Sopenharmony_ci printf("*** transfer succeeded ***\n"); 20713498266Sopenharmony_ci } 20813498266Sopenharmony_ci else { 20913498266Sopenharmony_ci printf("*** transfer failed ***\n"); 21013498266Sopenharmony_ci } 21113498266Sopenharmony_ci 21213498266Sopenharmony_ci /* second try: retrieve page using user certificate and key -> will succeed 21313498266Sopenharmony_ci * load the certificate and key by installing a function doing the necessary 21413498266Sopenharmony_ci * "modifications" to the SSL CONTEXT just before link init 21513498266Sopenharmony_ci */ 21613498266Sopenharmony_ci curl_easy_setopt(ch, CURLOPT_SSL_CTX_FUNCTION, sslctx_function); 21713498266Sopenharmony_ci rv = curl_easy_perform(ch); 21813498266Sopenharmony_ci if(rv == CURLE_OK) { 21913498266Sopenharmony_ci printf("*** transfer succeeded ***\n"); 22013498266Sopenharmony_ci } 22113498266Sopenharmony_ci else { 22213498266Sopenharmony_ci printf("*** transfer failed ***\n"); 22313498266Sopenharmony_ci } 22413498266Sopenharmony_ci 22513498266Sopenharmony_ci curl_easy_cleanup(ch); 22613498266Sopenharmony_ci curl_global_cleanup(); 22713498266Sopenharmony_ci return rv; 22813498266Sopenharmony_ci} 229