2016-09-22 78 views
2

我生成的自簽名證書(與我自己的CA),現在我試圖有一個提升ASIO客戶端驗證服務器的身份。我使用openssl驗證了這些,驗證似乎可行。無法驗證我的自簽名證書與提升

服務器和客戶端代碼分別爲herehere

我只修改了以下幾個部分:

class server 
{ 
public: 
    server(boost::asio::io_service& io_service, unsigned short port) 
    : io_service_(io_service), 
     acceptor_(io_service, 
      boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)), 
     context_(boost::asio::ssl::context::tlsv12_server) 
    { 
    context_.set_options(
     boost::asio::ssl::context::default_workarounds 
     | boost::asio::ssl::context::no_sslv2 
     | boost::asio::ssl::context::single_dh_use); 
    context_.set_password_callback(boost::bind(&server::get_password, this)); 

    // Use the certificate for my website that I had generated  context_.use_certificate_file("/home/paul/ca/intermediate/certs/mywebsite.net.cert.pem", boost::asio::ssl::context::pem); 

    // Not sure if I need this, probably not. I do have an intermediate CA though   
    //context_.use_certificate_chain_file("/home/paul/ca/intermediate/certs/ca-chain.cert.pem"); 

    // Use website private key  context_.use_private_key_file("/home/paul/ca/intermediate/private/mywebsite.net.key.pem", boost::asio::ssl::context::pem); 
    context_.use_tmp_dh_file("/home/paul/SSLTest/dh512.pem"); 

    start_accept(); 
    } 

,並在客戶端:

bool verify_certificate(bool preverified, 
     boost::asio::ssl::verify_context& ctx) 
    { 
    // The verify callback can be used to check whether the certificate that is 
    // being presented is valid for the peer. For example, RFC 2818 describes 
    // the steps involved in doing this for HTTPS. Consult the OpenSSL 
    // documentation for more details. Note that the callback is called once 
    // for each certificate in the certificate chain, starting from the root 
    // certificate authority. 

    // In this example we will simply print the certificate's subject name. 
    char subject_name[256]; 
    X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle()); 
    X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256); 
    std::cout << "Verifying " << subject_name << "\n"; 
    std::cout << "preverified: " << std::boolalpha << preverified << "\n"; 

    return preverified; 
    } 

... 

int main(int argc, char* argv[]) 
{ 
    try 
    { 
    boost::asio::io_service io_service; 

    boost::asio::ip::tcp::resolver resolver(io_service); 
    boost::asio::ip::tcp::resolver::query query("localhost", "3232"); 
    boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query); 

    boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12_client); 


    std::ifstream ca_file("/home/paul/ca/certs/ca.cert.pem", std::ios::binary | std::ios::ate); 
    std::vector<char> data; 
    auto size = ca_file.tellg(); 
    data.resize(size); 
    ca_file.seekg(0, std::ios::beg); 
    ca_file.read(data.data(), size); 
    ca_file.close(); 

    // Have my own CA added to the list of known CAs 
    ctx.add_certificate_authority(boost::asio::buffer(data, data.size())); 

    // Not sure if I need something here, the CA should be enough to 
    // validate the server's certificate prompted (even if signed by the 
    // intermediate CA) 
    //ctx.load_verify_file("/home/paul/ca/private/ca.key.pem"); 

    //ctx.load_verify_file("/home/paul/ca/intermediate/private/intermediate.key.pem"); 

    client c(io_service, ctx, iterator); 

但是這是行不通的,並且客戶端返回

Verifying /C=IT/ST=Italy/L=Milan/O=MyCompanyLtd/OU=MyCompanyLtd Auth/CN=mywebsite.net/[email protected] 
preverified: false 
Handshake failed: certificate verify failed 

我意識到在回調中沒有執行驗證,但我認爲在中設置了回調預先驗證後會調用(因此參數爲preverified)。

我在哪裏出錯?

+2

通過「自我分配」,你是指[自簽名](https://en.wikipedia.org/wiki/Self-signed_certificate)證書嗎? –

+0

@DanMašek確實如此。抱歉。 – Dean

+2

@Dean 19小時太短而無法修復標題? – sehe

回答

0

它不會只處理您提供的數據。沒有足夠的信息來驗證證書。你通常應該稱這兩個。

ctx.use_certificate_chain_file("path"); 
ctx.use_private_key_file("path", boost::asio::ssl::context::pem);