<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohamed Barakat</title>
    <description>The latest articles on DEV Community by Mohamed Barakat (@mobarakat).</description>
    <link>https://dev.to/mobarakat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F139118%2Fd96accee-65e9-43d2-8a3f-ac00e303b657.jpeg</url>
      <title>DEV Community: Mohamed Barakat</title>
      <link>https://dev.to/mobarakat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mobarakat"/>
    <language>en</language>
    <item>
      <title>Working with self-signed Certificates</title>
      <dc:creator>Mohamed Barakat</dc:creator>
      <pubDate>Fri, 24 May 2019 11:42:11 +0000</pubDate>
      <link>https://dev.to/mobarakat/working-with-self-signed-certificates-4ga</link>
      <guid>https://dev.to/mobarakat/working-with-self-signed-certificates-4ga</guid>
      <description>&lt;p&gt;I was working on building software to communicate with external device. The connection should be secured. Here comes to use ssl certificates. &lt;/p&gt;

&lt;p&gt;To do so, I needed to 3 things:&lt;/p&gt;

&lt;p&gt;1) Create all needed certificates for Certificate Authority(CA), server and client to simulate the connection.&lt;/p&gt;

&lt;p&gt;2) Create server and client using &lt;a href="https://nodejs.org"&gt;Nodejs&lt;/a&gt; to test the certificate.&lt;/p&gt;

&lt;p&gt;3) In my c++ project, I was using &lt;a href="https://github.com/microsoft/cpprestsdk"&gt;CPP Rest API&lt;/a&gt;. I wanted it to embedded my client certificate in the connection to the server to authorize the connection and manage to communicate to the server successfully. &lt;/p&gt;

&lt;p&gt;I will go through each step:&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Certificates
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1) Download and install Openssl
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;For more detailed information, please check &lt;a href="https://github.com/openssl/openssl"&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2) Create certificate authority[CA] configuration file
&lt;/h4&gt;

&lt;p&gt;It is optional step but it is easy to pass the information to openssl using a file rather than inserting that each time.&lt;/p&gt;

&lt;p&gt;I tried to create a simple example &lt;a href="https://github.com/mobarakat/mb-create-selfsignedcertificate/blob/master/cert-authority.cnf"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;You can check the file format &lt;a href="https://pages.github.com/"&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3) Create CA certifcate and key
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl req -new -x509 -config cert-authority.cnf -keyout cert-authority-key.pem -out cert-authority-crt.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; &lt;code&gt;cert-authority-key.pem, cert-authority-crt.pem&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Server
&lt;/h1&gt;

&lt;h4&gt;
  
  
  1) Create server private key
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl genrsa -out server-key.pem 4096
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; &lt;code&gt;server-key.pem&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2) Create server configuration file
&lt;/h4&gt;

&lt;p&gt;I tried to create a simple example &lt;a href="https://github.com/mobarakat/mb-create-selfsignedcertificate/blob/master/server.cnf"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3) Create server certifacate signing request
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl req -new -config server.cnf -key server-key.pem -out server-csr.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; &lt;code&gt;server-csr.pem&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4) Sign server certificate
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl x509 -req -extfile server.cnf -passin "pass:12345" -in server-csr.pem -CA cert-authority-crt.pem -CAkey cert-authority-key.pem -CAcreateserial -out server-crt.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Client
&lt;/h1&gt;

&lt;h4&gt;
  
  
  1) Create client private key
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl genrsa -out client-key.pem 4096
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; &lt;code&gt;client-key.pem&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2) Create client configuration file
&lt;/h4&gt;

&lt;p&gt;I tried to create a simple example &lt;a href="https://github.com/mobarakat/mb-create-selfsignedcertificate/blob/master/client.cnf"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3) Create client certifacate signing request
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl req -new -config client.cnf -key client-key.pem -out client-csr.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; &lt;code&gt;client-csr.pem&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4) Sign client certificate
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl x509 -req -extfile client.cnf -passin "pass:12345" -in client-csr.pem -CA cert-authority-crt.pem -CAkey cert-authority-key.pem -CAcreateserial -out client-crt.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  5) Verify client certificate
&lt;/h4&gt;

&lt;p&gt;you can verify client certificate using CA or server certificates as following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl verify -CAfile cert-authority-crt.pem client-crt.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Use Nodejs to create server and client
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Server
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var fs = require('fs'); 
var https = require('https'); 

var options = { 
    key: fs.readFileSync('server-key.pem'), 
    cert: fs.readFileSync('server-crt.pem'), 
    ca: fs.readFileSync('cert-authority-crt.pem'), 
    strictSSL: true,
    requestCert: true, 
    rejectUnauthorized: true
}; 
var srv = https.createServer(options, function (req, res) { 
    console.log('Recieve an request from authorized client!'); 
    res.writeHead(200); 
    res.end("Hello secured world!"); 
}).listen(3000, function() {
     console.log('Hello! I am at https://localhost:'+ srv.address().port);
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Client
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var fs = require('fs'); 
var https = require('https'); 
var options = { 
    hostname: 'localhost', 
    port: 3000, 
    path: '/', 
    method: 'GET', 
    key: fs.readFileSync(__dirname +'/client-key.pem'), 
    cert: fs.readFileSync(__dirname +'/client-crt.pem'), 
    ca: fs.readFileSync(__dirname +'/cert-authority-crt.pem') }; 
var req = https.request(options, function(res) { 
    res.on('data', function(data) { 
        process.stdout.write(data); 
    }); 
}); 
req.end(); 
req.on('error', function(e) { 
    console.error(e); 
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  C++ Code
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1) Notes before going into the code
&lt;/h4&gt;

&lt;p&gt;After you create your certificates we need to install your certificate authority into your machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl pkcs12 -export -out cert-authority.p12 -inkey cert-authority-key.pem -in cert-authority-cert.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Double-click on cert-authority.p12 and install the authourity under "Trusted Root Certification Authorities"&lt;/p&gt;

&lt;p&gt;Now convert your client certificate using the same way to loaded later in c++:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl pkcs12 -export -out client.p12 -inkey client-key.pem -in client-cert.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally do not include the following library in you linker&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Crypt32.lib
winhttp.lib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  2) Load certificate Function
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void loadOrFindCertificate() {
  if (_pCertContext) return;

  HANDLE _certFileHandle = NULL;

  /*Open File*/
  _certFileHandle = CreateFile(L"client.p12", GENERIC_READ, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

  if (INVALID_HANDLE_VALUE == _certFileHandle)
    return;

  DWORD certEncodedSize = GetFileSize(_certFileHandle, NULL);

  /*Check if file size */
  if (!certEncodedSize) {
    CloseHandle(_certFileHandle);
    return;
  }

  BYTE* certEncoded = new BYTE[(int)certEncodedSize];

  /*Read File */
  auto result = ReadFile(_certFileHandle, certEncoded, certEncodedSize, &amp;amp;certEncodedSize, 0);

  if (!result) {
    CloseHandle(_certFileHandle);
    return;
  }

  CRYPT_DATA_BLOB data;
  data.cbData = certEncodedSize;
  data.pbData = certEncoded;

  // Convert key-pair data to the in-memory certificate store
  WCHAR pszPassword[] = L"12345";
  HCERTSTORE hCertStore = PFXImportCertStore(&amp;amp;data, pszPassword, 0);
  SecureZeroMemory(pszPassword, sizeof(pszPassword));

  if (!hCertStore) {
    CloseHandle(_certFileHandle);
    return;
  }

  //get handle of loaded certificate
  _pCertContext = CertFindCertificateInStore
  (hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);

  CloseHandle(_certFileHandle);

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  3) Test with sending request to server
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Create http_client configuration.
  web::http::client::http_client_config config;
  config.set_timeout(std::chrono::seconds(2));

  config.set_validate_certificates(true);

  auto func = [&amp;amp;](web::http::client::native_handle handle) {

    loadOrFindCertificate();

    //Attach certificate with request
    if (_pCertContext)
      WinHttpSetOption(handle, WINHTTP_OPTION_CLIENT_CERT_CONTEXT,
      (LPVOID)_pCertContext, sizeof(CERT_CONTEXT));
  };

  config.set_nativehandle_options(func);



  // Create http_client to send the request.
  web::http::client::http_client client(U("https://localhost:4150"), config);

  // Build request URI and start the request.
  auto requestTask = client.request(web::http::methods::GET)
    // Handle response headers arriving.
  .then([=](web::http::http_response response)
  {
    auto status(response.status_code());
    printf("Received response status code:%u\n", status);

    /* Extract plain text only if status code signals success */
    if (status &amp;gt;= 200 &amp;amp;&amp;amp; status &amp;lt; 300)
      return response.extract_string(true);
    else
      return Concurrency::task&amp;lt;utility::string_t&amp;gt;([=] { return utility::string_t(); });

  }).then([=](utility::string_t val) {
    printf("Received response message:%s\n", utility::conversions::to_utf8string(val).c_str());
  });

  // Wait for all the outstanding I/O to complete and handle any exceptions
  try
  {
    requestTask.wait();
  }
  catch (const std::exception &amp;amp;e)
  {
    printf("Error exception:%s\n", e.what());
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/mobarakat/mb-create-selfsignedcertificate"&gt;Create server/client Certificates using openssl&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mobarakat/mb-nodjs-client_server-selfsignedcertificate"&gt;Create server and client using NodeJS&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mobarakat/mb-cpp-client-selfsignedcertificate"&gt;Load certificate with CPP REST API&lt;/a&gt;&lt;/p&gt;

</description>
      <category>https</category>
      <category>node</category>
      <category>cpp</category>
      <category>openssl</category>
    </item>
  </channel>
</rss>
