Boost C++ Libraries: Ticket #10828: Boost asio ssl: password callback not called if private key passed with context::use_private_key https://svn.boost.org/trac10/ticket/10828 <p> I'm writing a test unit that uses the boost asio ssl. </p> <p> I'm using Boost 1.54 on Ubuntu 14.04 64 bit. </p> <p> 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). </p> <p> 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: </p> <hr /> <p> std::string password_callback( </p> <blockquote> <p> std::size_t max_length, boost::asio::ssl::context::password_purpose purpose) </p> </blockquote> <p> { </p> <blockquote> <p> return "test"; </p> </blockquote> <p> } </p> <p> TEST(<a class="missing wiki">StreamReader</a>, sslStream) { </p> <blockquote> <p> std::string certificate = "-----BEGIN CERTIFICATE-----\n\ </p> </blockquote> <p> MIIFJjCCAw4CCQDQjrFrRcdRkjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJT\n\ BLABLABLABLA"; </p> <blockquote> <p> std::string key = "-----BEGIN RSA PRIVATE KEY-----\n\ </p> </blockquote> <p> Proc-Type: 4,ENCRYPTED\n\ DEK-Info: DES-EDE3-CBC,06622C22CAB27AC2\n\ \n\ JMudxXy4ZxB733xh7QO4elsVCTzJZuWl9Go4ZMuWx0DZb2fYHqXynKZSf7UactSw\n\ vhKJnLPZaa5U+xOr9cdpSd3SwtQyNu6yaVQH3af2ILRwUsw9mQmI8yqIIF1Y6AgV\n\ BLABLABLABLA"; </p> <blockquote> <p> 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); </p> </blockquote> <p> } </p> <hr /> <p> 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. </p> <p> I would expect password_callback to be called also when use_private_key is used. </p> <p> Checking the internals of use_private_key I find this: boost::system::error_code context::use_private_key( </p> <blockquote> <p> const const_buffer&amp; private_key, context::file_format format, boost::system::error_code&amp; ec) </p> </blockquote> <p> { </p> <blockquote> <p> ::ERR_clear_error(); </p> </blockquote> <blockquote> <p> bio_cleanup bio = { make_buffer_bio(private_key) }; if (bio.p) { </p> <blockquote> <p> evp_pkey_cleanup evp_private_key = { 0 }; switch (format) { case context_base::asn1: </p> <blockquote> <p> evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0); break; </p> </blockquote> <p> case context_base::pem: </p> <blockquote> <p> evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 0, 0); break; </p> </blockquote> <p> default: </p> <blockquote> <p> { </p> <blockquote> <p> ec = boost::asio::error::invalid_argument; return ec; </p> </blockquote> <p> } </p> </blockquote> <p> } </p> </blockquote> </blockquote> <blockquote> <blockquote> <p> if (evp_private_key.p) { </p> <blockquote> <p> if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1) { </p> <blockquote> <p> ec = boost::system::error_code(); return ec; </p> </blockquote> <p> } </p> </blockquote> <p> } </p> </blockquote> <p> } </p> </blockquote> <blockquote> <p> ec = boost::system::error_code( </p> <blockquote> <p> static_cast&lt;int&gt;(::ERR_get_error()), boost::asio::error::get_ssl_category()); </p> </blockquote> <p> return ec; </p> </blockquote> <p> } </p> <p> PEM_read_bio_PrivateKey accepts a callback parameter or a passphrase, but they are left null. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/10828 Trac 1.4.3 bugs@… Sun, 30 Nov 2014 22:38:53 GMT <link>https://svn.boost.org/trac10/ticket/10828#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10828#comment:1</guid> <description> <p> As a point of interested, I've already tested that the intended behaviour is achieved when adding the callback like so: </p> <pre class="wiki"> evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 0, 0); </pre><p> to </p> <pre class="wiki"> evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, handle_-&gt;default_passwd_callback, handle_-&gt;default_passwd_callback_userdata); </pre> </description> <category>Ticket</category> </item> </channel> </rss>