Opened 8 years ago

Last modified 8 years ago

#10828 new Bugs

Boost asio ssl: password callback not called if private key passed with context::use_private_key

Reported by: Paolo Brandoli <paolo.brandoli@…> Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.54.0 Severity: Problem
Keywords: ssl, openss. private key, callback, password Cc:

Description

I'm writing a test unit that uses the boost asio ssl.

I'm using Boost 1.54 on Ubuntu 14.04 64 bit.

I plan to make the test self-sufficient and not rely on files to specify the private key, so I want to hard encode the key and its password in the test itself (they are just test key and password).

The code is below. For now it does nothing but I'm just trying to make the password callback work when the private key is specified:


std::string password_callback(

std::size_t max_length, boost::asio::ssl::context::password_purpose purpose)

{

return "test";

}

TEST(StreamReader, sslStream) {

std::string certificate = "-----BEGIN CERTIFICATE-----\n\

MIIFJjCCAw4CCQDQjrFrRcdRkjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJT\n\ BLABLABLABLA";

std::string key = "-----BEGIN RSA PRIVATE KEY-----\n\

Proc-Type: 4,ENCRYPTED\n\ DEK-Info: DES-EDE3-CBC,06622C22CAB27AC2\n\ \n\ JMudxXy4ZxB733xh7QO4elsVCTzJZuWl9Go4ZMuWx0DZb2fYHqXynKZSf7UactSw\n\ vhKJnLPZaa5U+xOr9cdpSd3SwtQyNu6yaVQH3af2ILRwUsw9mQmI8yqIIF1Y6AgV\n\ BLABLABLABLA";

boost::asio::io_service io_service; boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12); ctx.set_password_callback(password_callback); ctx.use_certificate(boost::asio::const_buffer(certificate.c_str(), certificate.size()), boost::asio::ssl::context::pem); ctx.use_private_key(boost::asio::const_buffer(key.c_str(), key.size()), boost::asio::ssl::context::pem); ctx.set_verify_mode(boost::asio::ssl::verify_peer);

}


When use_private_key is executed then the password callback is not called and I have to enter the password manually in the console. If I replace use_private_key with use_private_key_file then the callback is called.

I would expect password_callback to be called also when use_private_key is used.

Checking the internals of use_private_key I find this: boost::system::error_code context::use_private_key(

const const_buffer& private_key, context::file_format format, boost::system::error_code& ec)

{

::ERR_clear_error();

bio_cleanup bio = { make_buffer_bio(private_key) }; if (bio.p) {

evp_pkey_cleanup evp_private_key = { 0 }; switch (format) { case context_base::asn1:

evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0); break;

case context_base::pem:

evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 0, 0); break;

default:

{

ec = boost::asio::error::invalid_argument; return ec;

}

}

if (evp_private_key.p) {

if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1) {

ec = boost::system::error_code(); return ec;

}

}

}

ec = boost::system::error_code(

static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category());

return ec;

}

PEM_read_bio_PrivateKey accepts a callback parameter or a passphrase, but they are left null.

Change History (1)

comment:1 by bugs@…, 8 years ago

As a point of interested, I've already tested that the intended behaviour is achieved when adding the callback like so:

      evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 0, 0);

to

      evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 
              handle_->default_passwd_callback,
              handle_->default_passwd_callback_userdata);
Note: See TracTickets for help on using tickets.