int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert) { RSA *rsa = NULL; RSA *pub_rsa; RSA_METHOD *rsa_meth; ASSERT (NULL != ctx); ASSERT (NULL != cert); /* allocate custom RSA method object */ ALLOC_OBJ_CLEAR (rsa_meth, RSA_METHOD); rsa_meth->name = "OpenVPN external private key RSA Method"; rsa_meth->rsa_pub_enc = rsa_pub_enc; rsa_meth->rsa_pub_dec = rsa_pub_dec; rsa_meth->rsa_priv_enc = rsa_priv_enc; rsa_meth->rsa_priv_dec = rsa_priv_dec; rsa_meth->init = NULL; rsa_meth->finish = rsa_finish; rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; rsa_meth->app_data = NULL; /* allocate RSA object */ rsa = RSA_new(); if (rsa == NULL) { SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); goto err; } /* get the public key */ ASSERT(cert->cert_info->key->pkey); /* NULL before SSL_CTX_use_certificate() is called */ pub_rsa = cert->cert_info->key->pkey->pkey.rsa; /* initialize RSA object */ rsa->n = BN_dup(pub_rsa->n); rsa->flags |= RSA_FLAG_EXT_PKEY; if (!RSA_set_method(rsa, rsa_meth)) goto err; /* bind our custom RSA object to ssl_ctx */ if (!SSL_CTX_use_RSAPrivateKey(ctx->ctx, rsa)) goto err; RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */ return 1; err: if (rsa) RSA_free(rsa); else { if (rsa_meth) free(rsa_meth); } msg (M_SSLERR, "Cannot enable SSL external private key capability"); return 0; }
void Context::usePrivateKey(const Poco::Crypto::RSAKey& key) { int errCode = SSL_CTX_use_RSAPrivateKey(_pSSLContext, key.impl()->getRSA()); if (errCode != 1) { std::string msg = Utility::getLastError(); throw SSLContextException("Cannot set private key for Context", msg); } }
int EdSSLContext::setSSLCertMem(void* crt, int crtlen, void* key, int keylen) { X509* xcert = d2i_X509(NULL, (const unsigned char**)&crt, crtlen); SSL_CTX_use_certificate(mCtx, xcert); RSA *pkey = d2i_RSAPrivateKey(NULL, (const unsigned char**)&key, keylen); SSL_CTX_use_RSAPrivateKey(mCtx, pkey); return 0; }
void SSLContext::usePrivateKey(const crypto::RSAKey& key) { int errCode = SSL_CTX_use_RSAPrivateKey(_sslContext, const_cast<RSA*>(&key)); if (errCode != 1) { std::string msg = getLastError(); throw std::runtime_error("SSL Error: Cannot set private key for Context: " + msg); } }
int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der, size_t der_len) { RSA *rsa = RSA_private_key_from_bytes(der, der_len); if (rsa == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); return 0; } int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); RSA_free(rsa); return ret; }
CSSLServerApplication::CSSLServerApplication() : CSSLApplication() { const SSL_METHOD* method; SSLMode = MODE_SSL_SERVER; NeedDataOp = OP_CLIENT_READ; // Create new context from method. method = SSLv23_server_method(); ctx = SSL_CTX_new(method); // These are for load certificate data from memory X509 *cert = NULL; RSA *rsa = NULL; BIO *cbio, *kbio; cbio = BIO_new_mem_buf((void*)cert_data, -1); cert = PEM_read_bio_X509(cbio, NULL, 0, NULL); ASSERT(cert != NULL); if (SSL_CTX_use_certificate(ctx, cert) <= 0) { ERR_print_errors_fp(stdout); exit(1); } kbio = BIO_new_mem_buf((void*)pkey_data, -1); rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL); ASSERT(rsa != NULL); if (SSL_CTX_use_RSAPrivateKey(ctx, rsa) <= 0) { ERR_print_errors_fp(stdout); exit(1); } // for read from file, use this // if (SSL_CTX_use_certificate_file(ctx, "Z:\\Develop\\opensslbin\\server.pem", SSL_FILETYPE_PEM) <= 0) // { // ERR_print_errors_fp(stdout); // exit(1); // } // if (SSL_CTX_use_PrivateKey_file(ctx, "Z:\\Develop\\opensslbin\\ca-nocap.key", SSL_FILETYPE_PEM) <= 0) // { // ERR_print_errors_fp(stdout); // exit(1); // } if (!SSL_CTX_check_private_key(ctx)) cerr << "Private key is invalid." << endl; else cout << "Private key is OK" << endl; return; }
wi_boolean_t wi_socket_tls_set_private_key(wi_socket_tls_t *tls, wi_rsa_t *rsa) { tls->private_key = false; if(SSL_CTX_use_RSAPrivateKey(tls->ssl_ctx, wi_rsa_rsa(rsa)) != 1) { wi_error_set_openssl_error(); return false; } tls->private_key = true; return true; }
int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) { int ret; RSA *rsa; if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) { SSLerrorx(ERR_R_ASN1_LIB); return (0); } ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); RSA_free(rsa); return (ret); }
int SSL_CTX_use_RSAPrivateKey_file (SSL_CTX * ctx, const char *file, int type) { int j, ret = 0; BIO *in; RSA *rsa = NULL; in = BIO_new (BIO_s_file_internal ()); if (in == NULL) { SSLerr (SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename (in, file) <= 0) { SSLerr (SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; rsa = d2i_RSAPrivateKey_bio (in, NULL); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; rsa = PEM_read_bio_RSAPrivateKey (in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata); } else { SSLerr (SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); goto end; } if (rsa == NULL) { SSLerr (SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); goto end; } ret = SSL_CTX_use_RSAPrivateKey (ctx, rsa); RSA_free (rsa); end: if (in != NULL) BIO_free (in); return (ret); }
int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) { int ret; const unsigned char *p; RSA *rsa; p=d; if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL) { SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1,ERR_R_ASN1_LIB); return(0); } ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa); RSA_free(rsa); return(ret); }
static void tls_load_from_memory(SSL_CTX* ctx, fs::Buffer cert_buffer, fs::Buffer key_buffer) { auto* cbio = BIO_new_mem_buf(cert_buffer.data(), cert_buffer.size()); auto* cert = PEM_read_bio_X509(cbio, NULL, 0, NULL); assert(cert != NULL); SSL_CTX_use_certificate(ctx, cert); BIO_free(cbio); auto* kbio = BIO_new_mem_buf(key_buffer.data(), key_buffer.size()); auto* key = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL); assert(key != NULL); SSL_CTX_use_RSAPrivateKey(ctx, key); BIO_free(kbio); }
void ThreadedSSLSocketInitiator::onInitialize(const SessionSettings &s) throw( RuntimeError) { if (m_sslInit) return; ssl_init(); std::string errStr; /* set up the application context */ if ((m_ctx = createSSLContext(false, m_settings, errStr)) == 0) { throw RuntimeError(errStr); } if (m_cert && m_key) { if (SSL_CTX_use_certificate(m_ctx, m_cert) < 1) { ssl_term(); throw RuntimeError("Failed to set certificate"); } if (SSL_CTX_use_RSAPrivateKey(m_ctx, m_key) <= 0) { ssl_term(); throw RuntimeError("Failed to set key"); } } else if (!loadSSLCert(m_ctx, false, m_settings, getLog(), ThreadedSSLSocketInitiator::passwordHandleCB, errStr)) { ssl_term(); throw RuntimeError(errStr); } int verifyLevel; if (!loadCAInfo(m_ctx, false, m_settings, getLog(), errStr, verifyLevel)) { ssl_term(); throw RuntimeError(errStr); } m_sslInit = true; }
int amqp_ssl_socket_set_key_buffer(amqp_socket_t *base, const char *cert, const void *key, size_t n) { int status = AMQP_STATUS_OK; BIO *buf = NULL; RSA *rsa = NULL; struct amqp_ssl_socket_t *self; if (base->klass != &amqp_ssl_socket_class) { amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); } if (n > INT_MAX) { return AMQP_STATUS_INVALID_PARAMETER; } self = (struct amqp_ssl_socket_t *)base; status = SSL_CTX_use_certificate_chain_file(self->ctx, cert); if (1 != status) { return AMQP_STATUS_SSL_ERROR; } buf = BIO_new_mem_buf((void *)key, (int)n); if (!buf) { goto error; } rsa = PEM_read_bio_RSAPrivateKey(buf, NULL, password_cb, NULL); if (!rsa) { goto error; } status = SSL_CTX_use_RSAPrivateKey(self->ctx, rsa); if (1 != status) { goto error; } exit: BIO_vfree(buf); RSA_free(rsa); return status; error: status = AMQP_STATUS_SSL_ERROR; goto exit; }
static int setKeyFile(SSL_CTX *ctx, cchar *keyFile) { RSA *key; BIO *bio; char *buf; int rc; assert(ctx); assert(keyFile); key = 0; bio = 0; buf = 0; rc = -1; if (ctx == NULL || keyFile == NULL) { ; } else if ((buf = mprReadPathContents(keyFile, NULL)) == 0) { mprLog("error openssl", 0, "Unable to read certificate %s", keyFile); } else if ((bio = BIO_new_mem_buf(buf, -1)) == 0) { mprLog("error openssl", 0, "Unable to allocate memory for key %s", keyFile); } else if ((key = PEM_read_bio_RSAPrivateKey(bio, NULL, 0, NULL)) == 0) { mprLog("error openssl", 0, "Unable to parse key %s", keyFile); } else if (SSL_CTX_use_RSAPrivateKey(ctx, key) != 1) { mprLog("error openssl", 0, "Unable to use key %s", keyFile); } else { rc = 0; } if (bio) { BIO_free(bio); } if (key) { RSA_free(key); } return rc; }
int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { int reason_code, ret = 0; BIO *in; RSA *rsa = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { reason_code = ERR_R_ASN1_LIB; rsa = d2i_RSAPrivateKey_bio(in, NULL); } else if (type == SSL_FILETYPE_PEM) { reason_code = ERR_R_PEM_LIB; rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata); } else { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); goto end; } if (rsa == NULL) { OPENSSL_PUT_ERROR(SSL, reason_code); goto end; } ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); RSA_free(rsa); end: BIO_free(in); return ret; }
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) { X509 *cert = NULL; BIO *bio = NULL; BIO *kbio = NULL; RSA *rsa = NULL; int ret; const char *mypem = /* www.cacert.org */ "-----BEGIN CERTIFICATE-----\n"\ "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\ "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\ "IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\ "Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\ "BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\ "MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\ "ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\ "CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\ "8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\ "zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\ "fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\ "w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\ "G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\ "epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\ "laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\ "QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\ "fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\ "YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\ "ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\ "gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\ "MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\ "IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\ "dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\ "czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\ "dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\ "aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\ "AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\ "b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\ "ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\ "nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\ "18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\ "gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\ "Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\ "sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\ "SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\ "CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\ "GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\ "zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\ "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\ "-----END CERTIFICATE-----\n"; /*replace the XXX with the actual RSA key*/ const char *mykey = "-----BEGIN RSA PRIVATE KEY-----\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ "-----END RSA PRIVATE KEY-----\n"; (void)curl; /* avoid warnings */ (void)parm; /* avoid warnings */ /* get a BIO */ bio = BIO_new_mem_buf((char *)mypem, -1); if(bio == NULL) { printf("BIO_new_mem_buf failed\n"); } /* use it to read the PEM formatted certificate from memory into an X509 * structure that SSL can use */ cert = PEM_read_bio_X509(bio, NULL, 0, NULL); if(cert == NULL) { printf("PEM_read_bio_X509 failed...\n"); } /*tell SSL to use the X509 certificate*/ ret = SSL_CTX_use_certificate((SSL_CTX*)sslctx, cert); if(ret != 1) { printf("Use certificate failed\n"); } /*create a bio for the RSA key*/ kbio = BIO_new_mem_buf((char *)mykey, -1); if(kbio == NULL) { printf("BIO_new_mem_buf failed\n"); } /*read the key bio into an RSA object*/ rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL); if(rsa == NULL) { printf("Failed to create key bio\n"); } /*tell SSL to use the RSA key from memory*/ ret = SSL_CTX_use_RSAPrivateKey((SSL_CTX*)sslctx, rsa); if(ret != 1) { printf("Use Key failed\n"); } /* free resources that have been allocated by openssl functions */ if(bio) BIO_free(bio); if(kbio) BIO_free(kbio); if(rsa) RSA_free(rsa); if(cert) X509_free(cert); /* all set to go */ return CURLE_OK; }
idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) { if (!connection || connection->ssl_data) return IDEVICE_E_INVALID_ARG; idevice_error_t ret = IDEVICE_E_SSL_ERROR; uint32_t return_me = 0; plist_t pair_record = NULL; userpref_read_pair_record(connection->udid, &pair_record); if (!pair_record) { debug_info("ERROR: Failed enabling SSL. Unable to read pair record for udid %s.", connection->udid); return ret; } #ifdef HAVE_OPENSSL key_data_t root_cert = { NULL, 0 }; key_data_t root_privkey = { NULL, 0 }; pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert); pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, &root_privkey); if (pair_record) plist_free(pair_record); /* Set up OpenSSL */ if (openssl_init_done == 0) { SSL_library_init(); openssl_init_done = 1; } BIO *ssl_bio = BIO_new(BIO_s_socket()); if (!ssl_bio) { debug_info("ERROR: Could not create SSL bio."); return ret; } BIO_set_fd(ssl_bio, (int)(long)connection->data, BIO_NOCLOSE); //SSL_CTX *ssl_ctx = SSL_CTX_new(SSLv3_method()); SSL_CTX *ssl_ctx = SSL_CTX_new(SSLv3_client_method()); if (ssl_ctx == NULL) { debug_info("ERROR: Could not create SSL context."); BIO_free(ssl_bio); return ret; } BIO* membp; X509* rootCert = NULL; membp = BIO_new_mem_buf(root_cert.data, root_cert.size); PEM_read_bio_X509(membp, &rootCert, NULL, NULL); BIO_free(membp); if (SSL_CTX_use_certificate(ssl_ctx, rootCert) != 1) { debug_info("WARNING: Could not load RootCertificate"); } X509_free(rootCert); free(root_cert.data); RSA* rootPrivKey = NULL; membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size); PEM_read_bio_RSAPrivateKey(membp, &rootPrivKey, NULL, NULL); BIO_free(membp); if (SSL_CTX_use_RSAPrivateKey(ssl_ctx, rootPrivKey) != 1) { debug_info("WARNING: Could not load RootPrivateKey"); } RSA_free(rootPrivKey); free(root_privkey.data); SSL *ssl = SSL_new(ssl_ctx); if (!ssl) { debug_info("ERROR: Could not create SSL object"); BIO_free(ssl_bio); SSL_CTX_free(ssl_ctx); return ret; } SSL_set_connect_state(ssl); SSL_set_verify(ssl, 0, ssl_verify_callback); SSL_set_bio(ssl, ssl_bio, ssl_bio); return_me = SSL_do_handshake(ssl); if (return_me != 1) { debug_info("ERROR in SSL_do_handshake: %s", ssl_error_to_string(SSL_get_error(ssl, return_me))); SSL_free(ssl); SSL_CTX_free(ssl_ctx); } else { ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); ssl_data_loc->session = ssl; ssl_data_loc->ctx = ssl_ctx; connection->ssl_data = ssl_data_loc; ret = IDEVICE_E_SUCCESS; debug_info("SSL mode enabled, cipher: %s", SSL_get_cipher(ssl)); } /* required for proper multi-thread clean up to prevent leaks */ #ifdef HAVE_ERR_REMOVE_THREAD_STATE ERR_remove_thread_state(NULL); #else ERR_remove_state(0); #endif #else ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); /* Set up GnuTLS... */ debug_info("enabling SSL mode"); errno = 0; gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); gnutls_certificate_client_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback); gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT); gnutls_priority_set_direct(ssl_data_loc->session, "NONE:+VERS-SSL3.0:+ANON-DH:+RSA:+AES-128-CBC:+AES-256-CBC:+SHA1:+MD5:+COMP-NULL", NULL); gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate); gnutls_session_set_ptr(ssl_data_loc->session, ssl_data_loc); gnutls_x509_crt_init(&ssl_data_loc->root_cert); gnutls_x509_crt_init(&ssl_data_loc->host_cert); gnutls_x509_privkey_init(&ssl_data_loc->root_privkey); gnutls_x509_privkey_init(&ssl_data_loc->host_privkey); pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, ssl_data_loc->root_cert); pair_record_import_crt_with_name(pair_record, USERPREF_HOST_CERTIFICATE_KEY, ssl_data_loc->host_cert); pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, ssl_data_loc->root_privkey); pair_record_import_key_with_name(pair_record, USERPREF_HOST_PRIVATE_KEY_KEY, ssl_data_loc->host_privkey); if (pair_record) plist_free(pair_record); debug_info("GnuTLS step 1..."); gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection); debug_info("GnuTLS step 2..."); gnutls_transport_set_push_function(ssl_data_loc->session, (gnutls_push_func) & internal_ssl_write); debug_info("GnuTLS step 3..."); gnutls_transport_set_pull_function(ssl_data_loc->session, (gnutls_pull_func) & internal_ssl_read); debug_info("GnuTLS step 4 -- now handshaking..."); if (errno) { debug_info("WARNING: errno says %s before handshake!", strerror(errno)); } return_me = gnutls_handshake(ssl_data_loc->session); debug_info("GnuTLS handshake done..."); if (return_me != GNUTLS_E_SUCCESS) { internal_ssl_cleanup(ssl_data_loc); free(ssl_data_loc); debug_info("GnuTLS reported something wrong."); gnutls_perror(return_me); debug_info("oh.. errno says %s", strerror(errno)); } else { connection->ssl_data = ssl_data_loc; ret = IDEVICE_E_SUCCESS; debug_info("SSL mode enabled"); } #endif return ret; }
ExternalPKIImpl(SSL_CTX* ssl_ctx, ::X509* cert, ExternalPKIBase* external_pki_arg) : external_pki(external_pki_arg), n_errors(0) { RSA *rsa = NULL; RSA_METHOD *rsa_meth = NULL; RSA *pub_rsa = NULL; const char *errtext = ""; /* allocate custom RSA method object */ rsa_meth = new RSA_METHOD; std::memset(rsa_meth, 0, sizeof(RSA_METHOD)); rsa_meth->name = "OpenSSLContext::ExternalPKIImpl private key RSA Method"; rsa_meth->rsa_pub_enc = rsa_pub_enc; rsa_meth->rsa_pub_dec = rsa_pub_dec; rsa_meth->rsa_priv_enc = rsa_priv_enc; rsa_meth->rsa_priv_dec = rsa_priv_dec; rsa_meth->init = NULL; rsa_meth->finish = rsa_finish; rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; rsa_meth->app_data = (char *)this; /* allocate RSA object */ rsa = RSA_new(); if (rsa == NULL) { SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); errtext = "RSA_new"; goto err; } /* get the public key */ if (cert->cert_info->key->pkey == NULL) /* NULL before SSL_CTX_use_certificate() is called */ { errtext = "pkey is NULL"; goto err; } pub_rsa = cert->cert_info->key->pkey->pkey.rsa; /* initialize RSA object */ rsa->n = BN_dup(pub_rsa->n); rsa->flags |= RSA_FLAG_EXT_PKEY; if (!RSA_set_method(rsa, rsa_meth)) { errtext = "RSA_set_method"; goto err; } /* bind our custom RSA object to ssl_ctx */ if (!SSL_CTX_use_RSAPrivateKey(ssl_ctx, rsa)) { errtext = "SSL_CTX_use_RSAPrivateKey"; goto err; } RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */ return; err: if (rsa) RSA_free(rsa); else { if (rsa_meth) free(rsa_meth); } OPENVPN_THROW(OpenSSLException, "OpenSSLContext::ExternalPKIImpl: " << errtext); }
/** * @warning Make sure you've called CryptoInitialize() first! */ bool TLSClientInitialize() { int ret; static bool is_initialised = false; if (is_initialised) { return true; } if (!TLSGenericInitialize()) { return false; } SSLCLIENTCONTEXT = SSL_CTX_new(SSLv23_client_method()); if (SSLCLIENTCONTEXT == NULL) { Log(LOG_LEVEL_ERR, "SSL_CTX_new: %s", ERR_reason_error_string(ERR_get_error())); goto err1; } TLSSetDefaultOptions(SSLCLIENTCONTEXT); if (PRIVKEY == NULL || PUBKEY == NULL) { Log(CryptoGetMissingKeyLogLevel(), "No public/private key pair is loaded, trying to reload"); LoadSecretKeys(); if (PRIVKEY == NULL || PUBKEY == NULL) { Log(CryptoGetMissingKeyLogLevel(), "No public/private key pair found"); goto err2; } } /* Create cert into memory and load it into SSL context. */ SSLCLIENTCERT = TLSGenerateCertFromPrivKey(PRIVKEY); if (SSLCLIENTCERT == NULL) { Log(LOG_LEVEL_ERR, "Failed to generate in-memory-certificate from private key"); goto err2; } SSL_CTX_use_certificate(SSLCLIENTCONTEXT, SSLCLIENTCERT); ret = SSL_CTX_use_RSAPrivateKey(SSLCLIENTCONTEXT, PRIVKEY); if (ret != 1) { Log(LOG_LEVEL_ERR, "Failed to use RSA private key: %s", ERR_reason_error_string(ERR_get_error())); goto err3; } /* Verify cert consistency. */ ret = SSL_CTX_check_private_key(SSLCLIENTCONTEXT); if (ret != 1) { Log(LOG_LEVEL_ERR, "Inconsistent key and TLS cert: %s", ERR_reason_error_string(ERR_get_error())); goto err3; } is_initialised = true; return true; err3: X509_free(SSLCLIENTCERT); SSLCLIENTCERT = NULL; err2: SSL_CTX_free(SSLCLIENTCONTEXT); SSLCLIENTCONTEXT = NULL; err1: return false; }
/** * @warning Make sure you've called CryptoInitialize() first! * * @TODO if this function is called a second time, it just returns true, and * does not do nothing more. What if the settings (e.g. tls_min_version) have * changed? This can happen when cf-serverd reloads policy. Fixing this goes * much deeper though, as it would require cf-serverd to call * GenericAgentDiscoverContext() when reloading policy. */ bool TLSClientInitialize(const char *tls_min_version, const char *ciphers) { int ret; static bool is_initialised = false; if (is_initialised) { return true; } if (PRIVKEY == NULL || PUBKEY == NULL) { /* VERBOSE in case it's a custom, local-only installation. */ Log(LOG_LEVEL_VERBOSE, "No public/private key pair is loaded," " please create one using cf-key"); return false; } if (!TLSGenericInitialize()) { return false; } SSLCLIENTCONTEXT = SSL_CTX_new(SSLv23_client_method()); if (SSLCLIENTCONTEXT == NULL) { Log(LOG_LEVEL_ERR, "SSL_CTX_new: %s", TLSErrorString(ERR_get_error())); goto err1; } TLSSetDefaultOptions(SSLCLIENTCONTEXT, tls_min_version); if (ciphers != NULL) { Log(LOG_LEVEL_VERBOSE, "Setting cipher list for outgoing TLS connections to: %s", ciphers); ret = SSL_CTX_set_cipher_list(SSLCLIENTCONTEXT, ciphers); if (ret != 1) { Log(LOG_LEVEL_ERR, "No valid ciphers in cipher list: %s", ciphers); goto err2; } } /* Create cert into memory and load it into SSL context. */ SSLCLIENTCERT = TLSGenerateCertFromPrivKey(PRIVKEY); if (SSLCLIENTCERT == NULL) { Log(LOG_LEVEL_ERR, "Failed to generate in-memory-certificate from private key"); goto err2; } SSL_CTX_use_certificate(SSLCLIENTCONTEXT, SSLCLIENTCERT); ret = SSL_CTX_use_RSAPrivateKey(SSLCLIENTCONTEXT, PRIVKEY); if (ret != 1) { Log(LOG_LEVEL_ERR, "Failed to use RSA private key: %s", TLSErrorString(ERR_get_error())); goto err3; } /* Verify cert consistency. */ ret = SSL_CTX_check_private_key(SSLCLIENTCONTEXT); if (ret != 1) { Log(LOG_LEVEL_ERR, "Inconsistent key and TLS cert: %s", TLSErrorString(ERR_get_error())); goto err3; } is_initialised = true; return true; err3: X509_free(SSLCLIENTCERT); SSLCLIENTCERT = NULL; err2: SSL_CTX_free(SSLCLIENTCONTEXT); SSLCLIENTCONTEXT = NULL; err1: return false; }
/** * @warning Make sure you've called CryptoInitialize() first! */ bool ServerTLSInitialize() { int ret; /* OpenSSL is needed for our new protocol over TLS. */ SSL_library_init(); SSL_load_error_strings(); assert(SSLSERVERCONTEXT == NULL); SSLSERVERCONTEXT = SSL_CTX_new(SSLv23_server_method()); if (SSLSERVERCONTEXT == NULL) { Log(LOG_LEVEL_ERR, "SSL_CTX_new: %s", ERR_reason_error_string(ERR_get_error())); goto err1; } /* Use only TLS v1 or later. TODO option for SSL_OP_NO_TLSv{1,1_1} */ SSL_CTX_set_options(SSLSERVERCONTEXT, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); /* * CFEngine is not a web server so we don't need many ciphers. We only * allow a safe but very common subset by default, extensible via * "allowciphers" in body server control. By default allow: * AES256-GCM-SHA384: most high-grade RSA-based cipher from TLSv1.2 * AES256-SHA: most backwards compatible but high-grade, from SSLv3 */ const char *cipher_list = SV.allowciphers; if (cipher_list == NULL) cipher_list ="AES256-GCM-SHA384:AES256-SHA"; ret = SSL_CTX_set_cipher_list(SSLSERVERCONTEXT, cipher_list); if (ret != 1) { Log(LOG_LEVEL_ERR, "No valid ciphers in cipher list: %s", cipher_list); } /* Never bother with retransmissions, SSL_write() should * always either write the whole amount or fail. */ SSL_CTX_set_mode(SSLSERVERCONTEXT, SSL_MODE_AUTO_RETRY); /* * Create cert into memory and load it into SSL context. */ if (PRIVKEY == NULL || PUBKEY == NULL) { Log(LOG_LEVEL_ERR, "No public/private key pair is loaded, create one with cf-key"); goto err2; } assert(SSLSERVERCERT == NULL); /* Generate self-signed cert valid from now to 50 years later. */ { X509 *x509 = X509_new(); X509_gmtime_adj(X509_get_notBefore(x509), 0); X509_time_adj(X509_get_notAfter(x509), 60*60*24*365*50, NULL); EVP_PKEY *pkey = EVP_PKEY_new(); EVP_PKEY_set1_RSA(pkey, PRIVKEY); X509_NAME *name = X509_get_subject_name(x509); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const char *) "", -1, -1, 0); X509_set_issuer_name(x509, name); X509_set_pubkey(x509, pkey); const EVP_MD *md = EVP_get_digestbyname("sha384"); if (md == NULL) { Log(LOG_LEVEL_ERR, "Uknown digest algorithm %s", "sha384"); return false; } ret = X509_sign(x509, pkey, md); EVP_PKEY_free(pkey); SSLSERVERCERT = x509; if (ret <= 0) { Log(LOG_LEVEL_ERR, "Couldn't sign the public key for the TLS handshake: %s", ERR_reason_error_string(ERR_get_error())); goto err3; } } SSL_CTX_use_certificate(SSLSERVERCONTEXT, SSLSERVERCERT); ret = SSL_CTX_use_RSAPrivateKey(SSLSERVERCONTEXT, PRIVKEY); if (ret != 1) { Log(LOG_LEVEL_ERR, "Failed to use RSA private key: %s", ERR_reason_error_string(ERR_get_error())); goto err3; } /* Verify cert consistency. */ ret = SSL_CTX_check_private_key(SSLSERVERCONTEXT); if (ret != 1) { Log(LOG_LEVEL_ERR, "Inconsistent key and TLS cert: %s", ERR_reason_error_string(ERR_get_error())); goto err3; } /* Set options to always request a certificate from the peer, either we * are client or server. */ SSL_CTX_set_verify(SSLSERVERCONTEXT, SSL_VERIFY_PEER, NULL); /* Always accept that certificate, we do proper checking after TLS * connection is established since OpenSSL can't pass a connection * specific pointer to the callback (so we would have to lock). */ SSL_CTX_set_cert_verify_callback(SSLSERVERCONTEXT, TLSVerifyCallback, NULL); return true; err3: X509_free(SSLSERVERCERT); SSLSERVERCERT = NULL; err2: SSL_CTX_free(SSLSERVERCONTEXT); SSLSERVERCONTEXT = NULL; err1: return false; }
void ssl_client_init() { /* * This is twisted. We can generate the required keys by calling RSA_generate_key, * however we cannot put the private part and the public part in the two containers. * For that we need to save each part to a file and then load each part from * the respective file. */ RSA *key = NULL; key = RSA_generate_key(1024, 17, NULL, NULL); if (!key) { correctly_initialized = false; return; } char name_template_private[] = "/tmp/tls_test/mnopqrXXXXXX"; char name_template_public[] = "/tmp/tls_test/stuvwxXXXXXX"; int private_key_file = 0; FILE *private_key_stream = NULL; int ret = 0; private_key_file = mkstemp(name_template_private); if (private_key_file < 0) { correctly_initialized = false; return; } private_key_stream = fdopen(private_key_file, "w+"); if (!private_key_stream) { correctly_initialized = false; return; } ret = PEM_write_RSAPrivateKey(private_key_stream, key, NULL, NULL, 0, 0, NULL); if (ret == 0) { correctly_initialized = false; return; } fseek(private_key_stream, 0L, SEEK_SET); PRIVKEY = PEM_read_RSAPrivateKey(private_key_stream, (RSA **)NULL, NULL, NULL); if (!PRIVKEY) { correctly_initialized = false; return; } fclose(private_key_stream); int public_key_file = 0; FILE *public_key_stream = NULL; public_key_file = mkstemp(name_template_public); if (public_key_file < 0) { correctly_initialized = false; return; } public_key_stream = fdopen(public_key_file, "w+"); if (!public_key_stream) { correctly_initialized = false; return; } ret = PEM_write_RSAPublicKey(public_key_stream, key); if (ret == 0) { correctly_initialized = false; return; } fseek(public_key_stream, 0L, SEEK_SET); PUBKEY = PEM_read_RSAPublicKey(public_key_stream, (RSA **)NULL, NULL, NULL); if (!PUBKEY) { correctly_initialized = false; return; } fclose(public_key_stream); RSA_free(key); SSLCLIENTCONTEXT = SSL_CTX_new(SSLv23_client_method()); if (SSLCLIENTCONTEXT == NULL) { Log(LOG_LEVEL_ERR, "SSL_CTX_new: %s", ERR_reason_error_string(ERR_get_error())); goto err1; } /* Use only TLS v1 or later. TODO option for SSL_OP_NO_TLSv{1,1_1} */ SSL_CTX_set_options(SSLCLIENTCONTEXT, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); /* Never bother with retransmissions, SSL_write() should * always either write the whole amount or fail. */ SSL_CTX_set_mode(SSLCLIENTCONTEXT, SSL_MODE_AUTO_RETRY); /* * Create cert into memory and load it into SSL context. */ if (PRIVKEY == NULL || PUBKEY == NULL) { correctly_initialized = false; return; } /* Generate self-signed cert valid from now to 50 years later. */ { X509 *x509 = X509_new(); X509_gmtime_adj(X509_get_notBefore(x509), 0); X509_time_adj(X509_get_notAfter(x509), 60*60*24*365*50, NULL); EVP_PKEY *pkey = EVP_PKEY_new(); EVP_PKEY_set1_RSA(pkey, PRIVKEY); X509_NAME *name = X509_get_subject_name(x509); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const char *) "", -1, -1, 0); X509_set_issuer_name(x509, name); X509_set_pubkey(x509, pkey); const EVP_MD *md = EVP_get_digestbyname("sha384"); if (md == NULL) { correctly_initialized = false; return; } ret = X509_sign(x509, pkey, md); EVP_PKEY_free(pkey); SSLCLIENTCERT = x509; if (ret <= 0) { Log(LOG_LEVEL_ERR, "Couldn't sign the public key for the TLS handshake: %s", ERR_reason_error_string(ERR_get_error())); goto err3; } } /* Log(LOG_LEVEL_ERR, "generate cert from priv key: %s", */ /* ERR_reason_error_string(ERR_get_error())); */ SSL_CTX_use_certificate(SSLCLIENTCONTEXT, SSLCLIENTCERT); ret = SSL_CTX_use_RSAPrivateKey(SSLCLIENTCONTEXT, PRIVKEY); if (ret != 1) { Log(LOG_LEVEL_ERR, "Failed to use RSA private key: %s", ERR_reason_error_string(ERR_get_error())); goto err3; } /* Verify cert consistency. */ ret = SSL_CTX_check_private_key(SSLCLIENTCONTEXT); if (ret != 1) { Log(LOG_LEVEL_ERR, "Inconsistent key and TLS cert: %s", ERR_reason_error_string(ERR_get_error())); goto err3; } /* Set options to always request a certificate from the peer, either we * are client or server. */ SSL_CTX_set_verify(SSLCLIENTCONTEXT, SSL_VERIFY_PEER, NULL); /* Always accept that certificate, we do proper checking after TLS * connection is established since OpenSSL can't pass a connection * specific pointer to the callback (so we would have to lock). */ SSL_CTX_set_cert_verify_callback(SSLCLIENTCONTEXT, TLSVerifyCallback, NULL); correctly_initialized = true; return; err3: X509_free(SSLCLIENTCERT); SSLCLIENTCERT = NULL; SSL_CTX_free(SSLCLIENTCONTEXT); SSLCLIENTCONTEXT = NULL; err1: correctly_initialized = false; return; }
/** * @warning Make sure you've called CryptoInitialize() first! */ bool ServerTLSInitialize() { int ret; if (!TLSGenericInitialize()) { return false; } assert(SSLSERVERCONTEXT == NULL); SSLSERVERCONTEXT = SSL_CTX_new(SSLv23_server_method()); if (SSLSERVERCONTEXT == NULL) { Log(LOG_LEVEL_ERR, "SSL_CTX_new: %s", TLSErrorString(ERR_get_error())); goto err1; } TLSSetDefaultOptions(SSLSERVERCONTEXT); /* * CFEngine is not a web server so we don't need many ciphers. We only * allow a safe but very common subset by default, extensible via * "allowciphers" in body server control. By default allow: * AES256-GCM-SHA384: most high-grade RSA-based cipher from TLSv1.2 * AES256-SHA: most backwards compatible but high-grade, from SSLv3 */ const char *cipher_list = SV.allowciphers; if (cipher_list == NULL) { cipher_list ="AES256-GCM-SHA384:AES256-SHA"; } ret = SSL_CTX_set_cipher_list(SSLSERVERCONTEXT, cipher_list); if (ret != 1) { Log(LOG_LEVEL_ERR, "No valid ciphers in cipher list: %s", cipher_list); } if (PRIVKEY == NULL || PUBKEY == NULL) { Log(LOG_LEVEL_ERR, "No public/private key pair is loaded, create one with cf-key"); goto err2; } assert(SSLSERVERCERT == NULL); /* Create cert into memory and load it into SSL context. */ SSLSERVERCERT = TLSGenerateCertFromPrivKey(PRIVKEY); if (SSLSERVERCERT == NULL) { Log(LOG_LEVEL_ERR, "Failed to generate in-memory certificate from private key"); goto err2; } SSL_CTX_use_certificate(SSLSERVERCONTEXT, SSLSERVERCERT); ret = SSL_CTX_use_RSAPrivateKey(SSLSERVERCONTEXT, PRIVKEY); if (ret != 1) { Log(LOG_LEVEL_ERR, "Failed to use RSA private key: %s", TLSErrorString(ERR_get_error())); goto err3; } /* Verify cert consistency. */ ret = SSL_CTX_check_private_key(SSLSERVERCONTEXT); if (ret != 1) { Log(LOG_LEVEL_ERR, "Inconsistent key and TLS cert: %s", TLSErrorString(ERR_get_error())); goto err3; } return true; err3: X509_free(SSLSERVERCERT); SSLSERVERCERT = NULL; err2: SSL_CTX_free(SSLSERVERCONTEXT); SSLSERVERCONTEXT = NULL; err1: return false; }
int SSL_CTX_use_pkcs11 ( IN OUT SSL_CTX * const ssl_ctx, IN const char * const pkcs11_slot_type, IN const char * const pkcs11_slot, IN const char * const pkcs11_id_type, IN const char * const pkcs11_id ) { X509 *x509 = NULL; RSA *rsa = NULL; pkcs11h_certificate_id_t certificate_id = NULL; pkcs11h_certificate_t certificate = NULL; pkcs11h_openssl_session_t openssl_session = NULL; CK_RV rv = CKR_OK; bool fOK = true; ASSERT (ssl_ctx!=NULL); ASSERT (pkcs11_slot_type!=NULL); ASSERT (pkcs11_slot!=NULL); ASSERT (pkcs11_id_type!=NULL); ASSERT (pkcs11_id!=NULL); dmsg ( D_PKCS11_DEBUG, "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_slot_type='%s', pkcs11_slot='%s', pkcs11_id_type='%s', pkcs11_id='%s'", (void *)ssl_ctx, pkcs11_slot_type, pkcs11_slot, pkcs11_id_type, pkcs11_id ); ASSERT (ssl_ctx!=NULL); ASSERT (pkcs11_slot_type!=NULL); ASSERT (pkcs11_slot!=NULL); ASSERT (pkcs11_id_type!=NULL); ASSERT (pkcs11_id!=NULL); if ( fOK && (rv = pkcs11h_locate_certificate ( pkcs11_slot_type, pkcs11_slot, pkcs11_id_type, pkcs11_id, &certificate_id )) != CKR_OK ) { fOK = false; msg (M_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv)); } if ( fOK && (rv = pkcs11h_certificate_create ( certificate_id, PKCS11H_PIN_CACHE_INFINITE, &certificate )) != CKR_OK ) { fOK = false; msg (M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv)); } if ( fOK && (openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL ) { fOK = false; msg (M_WARN, "PKCS#11: Cannot initialize openssl session"); } if (fOK) { /* * Will be released by openssl_session */ certificate = NULL; } if ( fOK && (rsa = pkcs11h_openssl_getRSA (openssl_session)) == NULL ) { fOK = false; msg (M_WARN, "PKCS#11: Unable get rsa object"); } if ( fOK && (x509 = pkcs11h_openssl_getX509 (openssl_session)) == NULL ) { fOK = false; msg (M_WARN, "PKCS#11: Unable get certificate object"); } if ( fOK && !SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa) ) { fOK = false; msg (M_WARN, "PKCS#11: Cannot set private key for openssl"); } if ( fOK && !SSL_CTX_use_certificate (ssl_ctx, x509) ) { fOK = false; msg (M_WARN, "PKCS#11: Cannot set certificate for openssl"); } /* * openssl objects have reference * count, so release them */ if (x509 != NULL) { X509_free (x509); x509 = NULL; } if (rsa != NULL) { RSA_free (rsa); rsa = NULL; } if (certificate != NULL) { pkcs11h_freeCertificate (certificate); certificate = NULL; } if (certificate_id != NULL) { pkcs11h_freeCertificateId (certificate_id); certificate_id = NULL; } if (openssl_session != NULL) { pkcs11h_openssl_freeSession (openssl_session); openssl_session = NULL; } dmsg ( D_PKCS11_DEBUG, "PKCS#11: SSL_CTX_use_pkcs11 - return fOK=%d, rv=%ld", fOK ? 1 : 0, rv ); return fOK ? 1 : 0; }
int pkcs11_init_tls_session(pkcs11h_certificate_t certificate, struct tls_root_ctx * const ssl_ctx) { int ret = 1; X509 *x509 = NULL; RSA *rsa = NULL; pkcs11h_openssl_session_t openssl_session = NULL; if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL) { msg (M_WARN, "PKCS#11: Cannot initialize openssl session"); goto cleanup; } /* * Will be released by openssl_session */ certificate = NULL; if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL) { msg (M_WARN, "PKCS#11: Unable get rsa object"); goto cleanup; } if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) { msg (M_WARN, "PKCS#11: Unable get certificate object"); goto cleanup; } if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx->ctx, rsa)) { msg (M_WARN, "PKCS#11: Cannot set private key for openssl"); goto cleanup; } if (!SSL_CTX_use_certificate (ssl_ctx->ctx, x509)) { msg (M_WARN, "PKCS#11: Cannot set certificate for openssl"); goto cleanup; } ret = 0; cleanup: /* * Certificate freeing is usually handled by openssl_session. * If something went wrong, creating the session we have to do it manually. */ if (certificate != NULL) { pkcs11h_certificate_freeCertificate (certificate); certificate = NULL; } /* * openssl objects have reference * count, so release them */ if (x509 != NULL) { X509_free (x509); x509 = NULL; } if (rsa != NULL) { RSA_free (rsa); rsa = NULL; } if (openssl_session != NULL) { pkcs11h_openssl_freeSession (openssl_session); openssl_session = NULL; } return ret; }
SSL* SDMMD_lockssl_handshake(SDMMD_lockdown_conn *lockdown_conn, CFTypeRef hostCert, CFTypeRef deviceCert, CFTypeRef hostPrivKey, uint32_t num) { SSL *ssl = NULL; SSL_CTX *sslCTX = NULL; sdmmd_return_t result = 0x0; BIO_METHOD *bioMethod = BIO_s_socket(); BIO *bioSocket = BIO_new(bioMethod); if (bioSocket) { BIO_set_fd(bioSocket, lockdown_conn->connection, 0); X509 *cert = SDMMD__decode_certificate(hostCert); if (cert == 0) { printf("_create_ssl_context: Could not certificate.\n"); } RSA *rsa = NULL; BIO *dataBIO = SDMMD__create_bio_from_data(hostPrivKey); if (dataBIO == 0) { printf("_create_ssl_context: Could not decode host private key.\n"); if (cert) { X509_free(cert); result = 0x0; } } else { PEM_read_bio_RSAPrivateKey(dataBIO, &rsa, 0x0, 0x0); BIO_free(dataBIO); if (rsa) { if (hostCert) { sslCTX = SSL_CTX_new(SSLv3_method()); if (sslCTX) { result = SSL_CTX_use_certificate(sslCTX, cert); if (result == 0) printf("_create_ssl_context: Could not set certificate.\n"); result = SSL_CTX_use_RSAPrivateKey(sslCTX, rsa); if (result == 0) printf("_create_ssl_context: Could not set private key.\n"); } else { printf("_create_ssl_context: Could not create SSLv3 context.\n"); } } RSA_free(rsa); if (cert) X509_free(cert); if (sslCTX) { ssl = SSL_new(sslCTX); if (ssl) { if (num) { SSL_set_connect_state(ssl); } else { SSL_set_accept_state(ssl); } SSL_set_verify(ssl, 0x3, SDMMD__ssl_verify_callback); SSL_set_verify_depth(ssl, 0x0); SSL_set_bio(ssl, bioSocket, bioSocket); SSL_set_ex_data(ssl, SDMMobileDevice->peer_certificate_data_index, (void*)deviceCert); result = SSL_do_handshake(ssl); if (result == 1) { SSL_CTX_free(sslCTX); } else { uint32_t err = SSL_get_error(ssl, result); if (err) { char *reason = SDMMD_ssl_strerror(ssl, err); printf("lockssl_handshake: SSL handshake fatal lower level error %d: %s.\n", err, reason); } else { char *reason = SDMMD_ssl_strerror(ssl, 0x0); printf("lockssl_handshake: SSL handshake controlled failure %d: %s.\n", err, reason); } SSL_free(ssl); } } else { printf("_create_ssl: Could not create SSL thing.\n"); } } } else { printf("_create_ssl_context: Could not decode private key.\n"); if (cert) { X509_free(cert); result = 0x0; } } } } else { printf("lockssl_handshake: Could not create SSL bio.\n"); } return ssl; }
static CURLcode ssl_ctx_callback(CURL *curl, void *ssl_ctx, void *userptr) { CURLcode result; if ( (curl == NULL) || (ssl_ctx == NULL) || (userptr == NULL) ) { LogError("unexpected parameter CURL *curl=%p, void *ssl_ctx=%p, void *userptr=%p", curl, ssl_ctx, userptr); result = CURLE_SSL_CERTPROBLEM; } else { HTTP_HANDLE_DATA *httpHandleData = (HTTP_HANDLE_DATA *)userptr; BIO *bio_certificate; bio_certificate = BIO_new_mem_buf(httpHandleData->x509certificate, -1); if (bio_certificate == NULL) { LogError("cannot create BIO *bio_certificate"); result = CURLE_OUT_OF_MEMORY; } else { X509 *cert = PEM_read_bio_X509(bio_certificate, NULL, 0, NULL); if (cert == NULL) { LogError("cannot create X509 *cert"); result = CURLE_SSL_CERTPROBLEM; } else { BIO *bio_privatekey; bio_privatekey = BIO_new_mem_buf(httpHandleData->x509privatekey, -1); if (bio_privatekey == NULL) { LogError("cannot create BIO *bio_privatekey;"); result = CURLE_OUT_OF_MEMORY; } else { RSA* privatekey = PEM_read_bio_RSAPrivateKey(bio_privatekey, NULL, 0, NULL); if (privatekey == NULL) { LogError("cannot create RSA* privatekey"); result = CURLE_SSL_CERTPROBLEM; /*there's no better code in CURL about not being able to load a private key*/ } else { if (SSL_CTX_use_certificate((SSL_CTX*)ssl_ctx, cert) != 1) { LogError("cannot SSL_CTX_use_certificate"); result = CURLE_SSL_CERTPROBLEM; /*there's no better code in CURL about not being able to SSL_CTX_use_certificate*/ } else { if (SSL_CTX_use_RSAPrivateKey(ssl_ctx, privatekey) != 1) { LogError("cannot SSL_CTX_use_RSAPrivateKey"); result = CURLE_SSL_CERTPROBLEM; /*there's no better code in CURL about not being able to put a private key in an SSL context*/ } else { result = CURLE_OK; } } RSA_free(privatekey); } BIO_free(bio_privatekey); } X509_free(cert); } BIO_free(bio_certificate); } } return result; }
int SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) { HCERTSTORE cs; X509 *cert = NULL; RSA *rsa = NULL, *pub_rsa; CAPI_DATA *cd = calloc(1, sizeof(*cd)); RSA_METHOD *my_rsa_method = calloc(1, sizeof(*my_rsa_method)); if (cd == NULL || my_rsa_method == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE); goto err; } /* search CURRENT_USER first, then LOCAL_MACHINE */ cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY"); if (cs == NULL) { CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE); goto err; } cd->cert_context = find_certificate_in_store(cert_prop, cs); CertCloseStore(cs, 0); if (!cd->cert_context) { cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY"); if (cs == NULL) { CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE); goto err; } cd->cert_context = find_certificate_in_store(cert_prop, cs); CertCloseStore(cs, 0); if (cd->cert_context == NULL) { CRYPTOAPIerr(CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE); goto err; } } /* cert_context->pbCertEncoded is the cert X509 DER encoded. */ cert = d2i_X509(NULL, (unsigned char **) &cd->cert_context->pbCertEncoded, cd->cert_context->cbCertEncoded); if (cert == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_ASN1_LIB); goto err; } /* set up stuff to use the private key */ #ifdef __MINGW32_VERSION /* MinGW w32api is incomplete when it comes to CryptoAPI, as per version 3.1 * anyway. This is a hack around that problem. */ if (crypt32dll == NULL) { crypt32dll = LoadLibrary("crypt32"); if (crypt32dll == NULL) { CRYPTOAPIerr(CRYPTOAPI_F_LOAD_LIBRARY); goto err; } } if (CryptAcquireCertificatePrivateKey == NULL) { CryptAcquireCertificatePrivateKey = GetProcAddress(crypt32dll, "CryptAcquireCertificatePrivateKey"); if (CryptAcquireCertificatePrivateKey == NULL) { CRYPTOAPIerr(CRYPTOAPI_F_GET_PROC_ADDRESS); goto err; } } #endif if (!CryptAcquireCertificatePrivateKey(cd->cert_context, CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &cd->crypt_prov, &cd->key_spec, &cd->free_crypt_prov)) { /* if we don't have a smart card reader here, and we try to access a * smart card certificate, we get: * "Error 1223: The operation was canceled by the user." */ CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY); goto err; } /* here we don't need to do CryptGetUserKey() or anything; all necessary key * info is in cd->cert_context, and then, in cd->crypt_prov. */ my_rsa_method->name = "Microsoft CryptoAPI RSA Method"; my_rsa_method->rsa_pub_enc = rsa_pub_enc; my_rsa_method->rsa_pub_dec = rsa_pub_dec; my_rsa_method->rsa_priv_enc = rsa_priv_enc; my_rsa_method->rsa_priv_dec = rsa_priv_dec; /* my_rsa_method->init = init; */ my_rsa_method->finish = finish; my_rsa_method->flags = RSA_METHOD_FLAG_NO_CHECK; my_rsa_method->app_data = (char *) cd; rsa = RSA_new(); if (rsa == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE); goto err; } /* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(), * so we do it here then... */ if (!SSL_CTX_use_certificate(ssl_ctx, cert)) goto err; /* the public key */ pub_rsa = cert->cert_info->key->pkey->pkey.rsa; /* SSL_CTX_use_certificate() increased the reference count in 'cert', so * we decrease it here with X509_free(), or it will never be cleaned up. */ X509_free(cert); cert = NULL; /* I'm not sure about what we have to fill in in the RSA, trying out stuff... */ /* rsa->n indicates the key size */ rsa->n = BN_dup(pub_rsa->n); rsa->flags |= RSA_FLAG_EXT_PKEY; if (!RSA_set_method(rsa, my_rsa_method)) goto err; if (!SSL_CTX_use_RSAPrivateKey(ssl_ctx, rsa)) goto err; /* SSL_CTX_use_RSAPrivateKey() increased the reference count in 'rsa', so * we decrease it here with RSA_free(), or it will never be cleaned up. */ RSA_free(rsa); return 1; err: if (cert) X509_free(cert); if (rsa) RSA_free(rsa); else { if (my_rsa_method) free(my_rsa_method); if (cd) { if (cd->free_crypt_prov && cd->crypt_prov) CryptReleaseContext(cd->crypt_prov, 0); if (cd->cert_context) CertFreeCertificateContext(cd->cert_context); free(cd); } } return 0; }