<?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>Forem: Ian Spence</title>
    <description>The latest articles on Forem by Ian Spence (@ecnepsnai).</description>
    <link>https://forem.com/ecnepsnai</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%2F2772%2Faed73efe-4ced-4c55-b46a-ad5cc86375b5.png</url>
      <title>Forem: Ian Spence</title>
      <link>https://forem.com/ecnepsnai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ecnepsnai"/>
    <language>en</language>
    <item>
      <title>Securing Your GitHub Account</title>
      <dc:creator>Ian Spence</dc:creator>
      <pubDate>Wed, 11 Mar 2020 18:38:51 +0000</pubDate>
      <link>https://forem.com/ecnepsnai/securing-your-github-account-boo</link>
      <guid>https://forem.com/ecnepsnai/securing-your-github-account-boo</guid>
      <description>&lt;p&gt;Let's talk about some of the simple &amp;amp; practical steps you can take to improve your GitHub account security.&lt;/p&gt;

&lt;p&gt;There's plenty of good reasons why you should try to keep any online account safe, but I feel that GitHub deserves special attention among developers. With automation through CI and CD taking center stage, it's not only important to you but also anybody who might rely on your code to ensure your GitHub account is secure.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Basics
&lt;/h1&gt;

&lt;p&gt;Let's start with the basics, things that don't just apply to GitHub but to nearly any online service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passwords
&lt;/h2&gt;

&lt;p&gt;Let's face it, passwords freaking suck. We all know we're supposed to make them hard to guess and not to reuse them, but who has time to remember each and every password? Nobody, that's who.&lt;/p&gt;

&lt;p&gt;But what if there was a solution where you could have unique passwords for each of your accounts, not have to remember them all, and have strong passwords that are difficult for both humans and computers alike to guess?&lt;/p&gt;

&lt;p&gt;The solution is a Password Manager. A password manager is a bit of an abstract term that describes a way to record passwords for your accounts in a secure location. These managers can range from web-based services that tie in to your browser, or something as simple as a physical book you write in.&lt;/p&gt;

&lt;p&gt;There are advantages and disadvantages to all of these options, but by properly using a manager you're protecting yourself from many common attack scenarios, the most common being password reuse.&lt;/p&gt;

&lt;p&gt;If you're looking for a web-based solution, check out 1Password or LastPass. If you want something in-between consider KeepassX. If you want to kick it old school with a book, most office supply stores sell password books - but a good old fashioned phone book will work just as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two-Factor Authentication
&lt;/h2&gt;

&lt;p&gt;Two-Factor authentication, sometimes called "Two-Step" or "Multi-Factor" (MFA), is a security measure provided by some websites to enhance your accounts security.&lt;/p&gt;

&lt;p&gt;To understand why Two-Factor authentication works, you first need to understand what a "Factor" is.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication Factors
&lt;/h3&gt;

&lt;p&gt;There are three common authentication factors: "What you know", "What you are", and "What you have".&lt;/p&gt;

&lt;p&gt;Passwords and passphrases are things you know. Fingerprints and facial recognition are things your are. Lastly, your cell phone or a physical key are things you have.&lt;/p&gt;

&lt;p&gt;One of the many problems with passwords is that while you may know them, other people can know them as well. To a website, it's very difficult to be sure who's who. With two-factor authentication, a website will require that you provide two forms of authentication. Most commonly this is your password, plus a one-time password generated by an app on your phone.&lt;/p&gt;

&lt;p&gt;In the event somebody happens to have your password, with two-factor authentication they would also require your cell phone to get in to your account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enable Two-Factor Authentication
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click on your Avatar in the top right and select "Settings"&lt;/li&gt;
&lt;li&gt;Click on "Security" on the left hand side&lt;/li&gt;
&lt;li&gt;Click on "Enable" under "Two-factor Authentication"&lt;/li&gt;
&lt;li&gt;Click on "Set up using an app" &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwfvy5xmo6n4opnd2s5jh.PNG" alt="Screenshot showing the setup page for configuring two factor authentication on github"&gt;
&lt;/li&gt;
&lt;li&gt;Save the recovery codes (Protip: If you're using a password manager, record the codes in the notes section for the websites entry)&lt;/li&gt;
&lt;li&gt;Scan the QR code using authenticator app of your choosing&lt;/li&gt;
&lt;li&gt;Enter the one-time password from your phone to finish setting up two-factor authentication&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Connected Apps
&lt;/h2&gt;

&lt;p&gt;Like many online services, GitHub uses a technology known as OAuth to allow applications to interact with your GitHub account without requiring your username and password.&lt;/p&gt;

&lt;p&gt;It's very important that you periodically review the applications you've authorized to use your GitHub account and remove any you no longer use.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on your Avatar in the top right and select "Settings"&lt;/li&gt;
&lt;li&gt;Click on "Applications" on the left hand side&lt;/li&gt;
&lt;li&gt;Click on the "Authorized OAuth Apps" tab&lt;/li&gt;
&lt;li&gt;To revoke an app, tap on the "..." for the app and select "Revoke" &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frvepsqquou6btbs6e8j2.PNG" alt="Screenshot showing a list of authorized apps"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Active Sessions
&lt;/h2&gt;

&lt;p&gt;GitHub lets you view active login sessions, and approximately where that computer or device is. It's always a good idea to periodically take a look at the list and ensure that only the devices you intend to use GitHub with are listed. If you see any login sessions from weird devices, or from the wrong country, it could be an indicator that your account is compromised.&lt;/p&gt;

&lt;p&gt;To see your active sessions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on your Avatar in the top right and select "Settings"&lt;/li&gt;
&lt;li&gt;Click on "Security" on the left hand side&lt;/li&gt;
&lt;li&gt;Scroll to the bottom of the page&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Take the following example, where my current session is in Canada but a recent login occurred in Romania.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcm6klaak592htueb13ef.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcm6klaak592htueb13ef.PNG" alt="Screenshot showing a three sessions with two in vancouver and one in romania"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you see something out of the ordinary here, change your password immediately.&lt;/p&gt;

&lt;h1&gt;
  
  
  GitHub as a Git Remote
&lt;/h1&gt;

&lt;p&gt;Now that we've covered the basics, let's dive into the real reason why I'm writing this guide: GitHub is, obviously, a Git service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid using SSH
&lt;/h2&gt;

&lt;p&gt;GitHub, like nearly all Git services, lets you connect to it either one of two ways: using SSH or HTTPS.&lt;/p&gt;

&lt;p&gt;From a cryptographic perspective, both of these provide strong encryption and protection against tampering, but there's a huge benefit to using HTTPS that SSH lacks: Public Key Infrastructure, or PKI. &lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Primer: How PKI works for HTTPS
&lt;/h3&gt;

&lt;p&gt;When you connected to dev.to to read this article your browser performed a TLS Handshake and trust verification with the web server hosting this site. Part of this process is the web server presenting its certificate to your browser. Your browser then looked at the parents of the servers certificate. If the browser trusts the root (or top-level) of the certificate chain, it can mathematically prove that the certificate was issued from a trusted authority, and after performing some additional tests, confirm that the web server is who they say they are.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fro6yi9rhg3m8jtugqvvg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fro6yi9rhg3m8jtugqvvg.png" alt="diagram of how PKI works"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why SSH is the wrong choice for Git
&lt;/h3&gt;

&lt;p&gt;SSH lacks nearly all of this, especially all of those additional checks that are done.&lt;/p&gt;

&lt;p&gt;When you connect to a host using SSH your computer only has the servers public key to go on to determine trust. If you've never connected to server before, it will prompt you if you want to trust their public key. The next time, if the public key matches it will connect without asking you, but if the public key changes it will show this scary warning at you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3fp4f1b5129u7niec3va.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3fp4f1b5129u7niec3va.png" alt="screenshot of SSH host key verification error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fatal flaw with SSH's trust mechanism is placing ultimate and permanent trust in the hosts key. Once you've trusted a key, that key can never change without causing errors as seen above. In GitHub's case changing their key would cause huge confusion among its users.&lt;/p&gt;

&lt;p&gt;Whereas with HTTPS, GitHub's certificates are &lt;a href="https://crt.sh/?q=*.github.com" rel="noopener noreferrer"&gt;rotated regularly without you even realizing it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;SSH also lacks a large amount of other security enhancements that HTTPS has, such as: certificate lifespans, revocation and automatic status checks, transparency, and key usage restrictions.&lt;/p&gt;

&lt;p&gt;Now that I've lectured you enough on why SSH is not the right choice, let's look at how we can go about using HTTPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Access Tokens
&lt;/h2&gt;

&lt;p&gt;Git over HTTPS works just like Git over SSH, you just have to sign in to GitHub with your username and password instead of adding your SSH key to your account.&lt;/p&gt;

&lt;p&gt;However, if you're using Two-Factor authentication (You are, right? See the section above). You won't be able to use Git over HTTPS since there's no way to prompt for your one-time password.&lt;/p&gt;

&lt;p&gt;Not to worry though, GitHub has you covered with so-called "Access Tokens". These are sometimes called "Application Passwords" on other services and let you sign in on applications that don't support multi-factor authentication. The idea is that you sign in and generate these passwords but only use them for a specific application.&lt;/p&gt;

&lt;p&gt;Here's how you generate an access token:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on your Avatar in the top right and select "Settings"&lt;/li&gt;
&lt;li&gt;Click on "Developer Settings" on the left hand side&lt;/li&gt;
&lt;li&gt;Click on "Personal Access Tokens" on the left hand side&lt;/li&gt;
&lt;li&gt;Click on "Generate New Token"&lt;/li&gt;
&lt;li&gt;Give the token a name and select only the required permissions for the token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsfpz5hb9xzxtszi8ug2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsfpz5hb9xzxtszi8ug2c.png" alt="screenshot showing the setup page for a github access token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, when you configure your git remote to use HTTPS you'll be asked to provide your username and password. Use the access token as your password and you've authenticated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git fetch
Username for 'https://github.com': ecnepsnai
Password for 'https://ecnepsnai@github.com': &amp;lt;my access token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Storing Access Tokens
&lt;/h2&gt;

&lt;p&gt;There are 4 options to store your credentials if you don't want to type your access token every time (Who would?)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Don't store them&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Didn't I just ask who wants to type their access token out each time? With this, git doesn't remember your credentials. Each time you access the remote, you have to type in your credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Cache them for a limited time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This method is marginally better than option 1. Git will remember your username and access token for a limited period of time before requiring you to enter them again. This is similar to how &lt;code&gt;sudo&lt;/code&gt; works if you've used that before.&lt;/p&gt;

&lt;p&gt;You can enable this method using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git config --global credential.helper 'cache --timeout=3600'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;3600&lt;/code&gt; is the number of seconds to cache the credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 3: Store them in a plain-text file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This method is the easiest to set up, but not the most secure. With this, git will store your username and access token in a plain-text file in your home directory. It won't prompt you for your username or access token once saved.&lt;/p&gt;

&lt;p&gt;You can enable this method using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git config --global credential.helper store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option 4: Store them using a credential helper&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This method can be tricky to set up but provides the best balance of convenience and security. A credential helper is an application that stores keys in a secure location that git can use.&lt;/p&gt;

&lt;p&gt;On macOS you can use the systems Keychain, which is encrypted with your users password. See &lt;a href="https://help.github.com/en/github/using-git/caching-your-github-password-in-git" rel="noopener noreferrer"&gt;GitHub's documentation&lt;/a&gt; on how to setup and configure the credential helper.&lt;/p&gt;

&lt;p&gt;On Linux you can use the &lt;code&gt;gnome-keyring&lt;/code&gt; package, which is very similar to the Keychain from macOS. Setup varies depending on your distribution and isn't covered in this document.&lt;/p&gt;

&lt;h1&gt;
  
  
  Anything Else?
&lt;/h1&gt;

&lt;p&gt;That's all for the tips I have in this guide. Do you have any other ideas on ways to protect your account? Let me know in the comments!&lt;/p&gt;

</description>
      <category>github</category>
      <category>security</category>
    </item>
    <item>
      <title>All About Apache Cassandra: Snapshots</title>
      <dc:creator>Ian Spence</dc:creator>
      <pubDate>Sat, 27 Jul 2019 22:15:23 +0000</pubDate>
      <link>https://forem.com/ecnepsnai/all-about-apache-cassandra-snapshots-3oo2</link>
      <guid>https://forem.com/ecnepsnai/all-about-apache-cassandra-snapshots-3oo2</guid>
      <description>&lt;p&gt;Welcome to the inaugural post of "All About Apache Cassandra", a new series of posts I'll be writing about Apache Cassandra exclusively on dev.to!&lt;/p&gt;




&lt;h1&gt;
  
  
  The concept of a "Snapshot"
&lt;/h1&gt;

&lt;p&gt;In computing, a snapshot is a point-in-time copy of data or state of a machine.&lt;/p&gt;

&lt;p&gt;You ever end up doing something like this?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsw980mwi707amruv5l6g.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsw980mwi707amruv5l6g.PNG" alt="Screenshot of the windows file explorer showing multiple word documents each being a draft of the same essay"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each one of these files is a snapshot, as it's a copy of your essay at the point-in-time when you saved it.&lt;/p&gt;

&lt;p&gt;Snapshots provide us with an easy way to undo changes and backup systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Cassandra Stores Data
&lt;/h2&gt;

&lt;p&gt;Cassandra breaks its data down by &lt;em&gt;Keyspace&lt;/em&gt; (which is like a Database in MySQL or Schema in PostgreSQL), and &lt;em&gt;Column Family&lt;/em&gt; (a table). Data for the column families is stores on &lt;em&gt;SSTables&lt;/em&gt; (Sorted String Tables).&lt;/p&gt;

&lt;p&gt;When Cassandra writes to disk it does so by writing a new SSTable. Every SSTable is immutable, so it will always make a new SSTable each time it flushes. A process known as &lt;em&gt;Compaction&lt;/em&gt; will automatically merge the tables into a single new table.&lt;/p&gt;

&lt;p&gt;For example, if we have a column family named &lt;code&gt;Users&lt;/code&gt; in the keyspace &lt;code&gt;App&lt;/code&gt;, the data for that table would look like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;Cassandra Data&amp;gt;/App/Users/
1-big-Data.db
2-big-Data.db
3-big-Data.db
4-big-Data.db


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Each &lt;code&gt;big-Data&lt;/code&gt; file is a SSTable. Compaction would take all of these tables and merge them into a single, new file &lt;code&gt;5-big-Data.db&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Cassandra Takes Snapshots
&lt;/h1&gt;

&lt;p&gt;When you take a snapshot with Apache Cassandra, it creates a &lt;em&gt;Hard Link&lt;/em&gt; of all live SSTables. Easy, right? Well it's a little more complex than you might think&lt;/p&gt;

&lt;h2&gt;
  
  
  What's a hard link?
&lt;/h2&gt;

&lt;p&gt;A hard link is a file that points to the same data as another file.&lt;/p&gt;

&lt;p&gt;In UNIX-like systems (Linux, macOS, BSD), the system uses &lt;em&gt;INodes&lt;/em&gt; to reference the data on disk, and files on your computer reference INodes. A hard link is a file that shares the same INode as another file.&lt;/p&gt;

&lt;p&gt;Hard links are different than &lt;em&gt;Soft Links&lt;/em&gt;, which tell the application reading that file where the actual file path is.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Catch
&lt;/h1&gt;

&lt;p&gt;There's a &lt;strong&gt;very important catch&lt;/strong&gt; with hard links: The data on disk will only be deleted when all references to it are removed.&lt;/p&gt;

&lt;p&gt;For example: Inode 1001 references 500MB of data on the disk and we have two files that point to Inode 1001. If we deleted the first link, the 500MB data will still be on disk because of the second link. We won't free up that 500MB from disk until &lt;strong&gt;all links have been deleted&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Where Cassandra Stores Snapshots
&lt;/h1&gt;

&lt;p&gt;Since snapshots are hard links of existing files, these files must be on the same filesystem as your data. Therefor, snapshots are stored in the &lt;code&gt;snapshots&lt;/code&gt; directory within your Column Family. If we took a snapshot named &lt;code&gt;snapshot1&lt;/code&gt; on our existing Users table, it would result in:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;Cassandra Data&amp;gt;/App/Users/
1-big-Data.db
2-big-Data.db
3-big-Data.db
4-big-Data.db
&amp;lt;Cassandra Data&amp;gt;/App/Users/snapshots/snapshot1
1-big-Data.db (Hard link)
2-big-Data.db (Hard link)
3-big-Data.db (Hard link)
4-big-Data.db (Hard link)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When compaction occurs and the SSTables are merged, our snapshot is unaffected:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;Cassandra Data&amp;gt;/App/Users/
5-big-Data.db
&amp;lt;Cassandra Data&amp;gt;/App/Users/snapshots/snapshot1
1-big-Data.db
2-big-Data.db
3-big-Data.db
4-big-Data.db


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Because there is still at least one reference to the data of SSTables 1-4, the system will not delete that data from disk.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Snapshots Affect Capacity
&lt;/h1&gt;

&lt;p&gt;As with any distributed storage system, calculating your capacity is not as simple as just looking at how much free disk space you have.&lt;/p&gt;

&lt;p&gt;Snapshots can have a very large impact on your clusters capacity, and great care is needed if you're considering taking snapshots on a schedule.&lt;/p&gt;

&lt;p&gt;Because of that &lt;em&gt;one important catch&lt;/em&gt; with hard links (see above), compaction jobs can dramatically increase the amount of data used by snapshots.&lt;/p&gt;

&lt;p&gt;When you take a snapshot on a server with no activity whatsoever, that snapshot will not consume any (meaningful) amount of data on disk. But as soon as a new SSTable is written or compaction occurs, that snapshot will begin to take up space, potentially doubling the amount of data on your disk.&lt;/p&gt;

&lt;p&gt;Let me try and break it down:&lt;/p&gt;

&lt;p&gt;Let's assume you have a 100GB disk, and Cassandra is using 50GB of that for its data.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You take a new snapshot. This isn't going to use that much disk space. Still 50% full.&lt;/li&gt;
&lt;li&gt;A major compaction occurs, something like a cleanup or a scrub, which re-writes all tables on disk.&lt;/li&gt;
&lt;li&gt;That snapshot now references versions of SSTables that have been rewritten entirely, and is essentially duplicated data. &lt;strong&gt;Now 100% full.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Of course, this is a slightly exaggerated example, but the reality is that snapshots and compaction can wreck your disk capacity and ruin your day.&lt;/p&gt;

&lt;h1&gt;
  
  
  Restoring From a Snapshot
&lt;/h1&gt;

&lt;p&gt;Restoring from a snapshot is a destructive action that will result in the loss of any new data created after the snapshot was taken. You should only restore from a snapshot when you have no other option. There is no automated way to restore Cassandra to a snapshot, it is a manual process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;While the cluster is running:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Truncate the table you need to restore&lt;/li&gt;
&lt;li&gt;Stop the Cassandra service&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Why truncate?&lt;/em&gt; If there are any tombstones remaining, they will be deleted after you restore. Truncating removes any tombstones from that table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On all nodes in the cluster:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the directory for the snapshot you wish to restore from&lt;/li&gt;
&lt;li&gt;Copy over all SSTables in that directory into the data directory for the table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Finally:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start up the service&lt;/li&gt;
&lt;li&gt;Run a &lt;code&gt;nodetool refresh&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Command Line Reference
&lt;/h1&gt;

&lt;p&gt;As with most operational tasks, you'll be using the &lt;code&gt;nodetool&lt;/code&gt; application to manage snapshots on a server. These are some of the commands you might use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take a snapshots
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

nodetool snapshot [options] [keyspace]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Reference: &lt;a href="https://cassandra.apache.org/doc/latest/tools/nodetool/snapshot.html" rel="noopener noreferrer"&gt;https://cassandra.apache.org/doc/latest/tools/nodetool/snapshot.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Take a snapshot with a specific name&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;nodetool snapshot -t &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Take a snapshot on all tables in a specific keyspace&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;nodetool snapshot &amp;lt;keyspace&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Take a snapshot on two specific tables&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;nodetool snapshot -kt &amp;lt;comma separated list of keyspace.tableName&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  List all snapshots
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

nodetool listsnapshots


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Reference: &lt;a href="https://cassandra.apache.org/doc/latest/tools/nodetool/listsnapshots.html" rel="noopener noreferrer"&gt;https://cassandra.apache.org/doc/latest/tools/nodetool/listsnapshots.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Remove one or more snapshots
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

nodetool clearsnapshot [options] [keyspaces]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Reference: &lt;a href="https://cassandra.apache.org/doc/latest/tools/nodetool/clearsnapshot.html" rel="noopener noreferrer"&gt;https://cassandra.apache.org/doc/latest/tools/nodetool/clearsnapshot.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove all snapshots&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;nodetool clearsnapshot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove a snapshot named:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;nodetool clearsnapshot -t &amp;lt;snapshot name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove snapshots from a specific keyspace:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;nodetool clearsnapshot &amp;lt;keyspace&amp;gt;&lt;/code&gt;&lt;/p&gt;

</description>
      <category>cassandra</category>
      <category>database</category>
      <category>nosql</category>
      <category>devops</category>
    </item>
    <item>
      <title>What the heck is OCSP?</title>
      <dc:creator>Ian Spence</dc:creator>
      <pubDate>Fri, 10 May 2019 01:18:22 +0000</pubDate>
      <link>https://forem.com/ecnepsnai/what-the-heck-is-ocsp-3li6</link>
      <guid>https://forem.com/ecnepsnai/what-the-heck-is-ocsp-3li6</guid>
      <description>&lt;p&gt;The online certificate status protocol, or OCSP for short, is a way for TLS clients (like your web browser) to check if a certificate has been revoked or not.&lt;/p&gt;

&lt;h1&gt;
  
  
  Certificate Revocation?
&lt;/h1&gt;

&lt;p&gt;With asymmetrical encryption, your encryption is only as good as long as your private key remains private. &lt;a href="https://github.com/search?l=Text&amp;amp;o=desc&amp;amp;q=-----BEGIN+RSA+PRIVATE+KEY-----&amp;amp;s=indexed&amp;amp;type=Code"&gt;This is often not the case&lt;/a&gt; and private keys end up exposed.&lt;/p&gt;

&lt;p&gt;This is just one of the many possible reasons why a certificate may be revoked. And a certificate authority, or a certificate holder may revoke their certificate to mark it as untrusted. Since there's no way to change a certificate once its been created, status checks are used to see if its been revoked. This is where OCSP comes into play.&lt;/p&gt;

&lt;h1&gt;
  
  
  A basic example
&lt;/h1&gt;

&lt;p&gt;Let's take a look at the certificate for dev.to, in it we'll see the URL for the OCSP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X509v3 extensions:
    Authority Information Access:
        CA Issuers - URI:http://secure.globalsign.com/cacert/cloudsslsha2g3.crt
        OCSP - URI:http://ocsp2.globalsign.com/cloudsslsha2g3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If OCSP is enabled in your web browser (which it probably isn't, we'll get to that later), when you browsed to dev.to your browser made a quick HTTP request to ocsp2.globalsign.com/cloudsslsha2g3 with the SHA1 fingerprint of the certificate. Globalsign, the CA for dev.to's certificate, will check its database for that certificate and if its been revoked or not, and respond back with a signed response.&lt;/p&gt;

&lt;p&gt;Depending on the response from the OCSP server, the browser may either continue on to the site or consider the certificate revoked and untrustworthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP? SHA-1? What year is this?
&lt;/h2&gt;

&lt;p&gt;Yup, you read that right. OCSP requests are all in good-old insecure HTTP, and most clients use typically end up using SHA-1 fingerprints.&lt;/p&gt;

&lt;p&gt;The reason OCSP operates over HTTP is because if it operated over HTTPS, then we'd have to check the status of the certificate used for the OCSP server, then that server, and the next one, and so on and so on. We'd end up in a forever loop of checking certificates. OCSP responses are signed to prevent tampering.&lt;/p&gt;

&lt;p&gt;The OCSP specification mandates that SHA-1 must be the minimum required hashing algorithm for servers and clients, giving room for more secure hashing algorithms to be used. However, since status checks are meant to be fast, TLS Clients often don't want to get stuck in a retry loop trying to negotiate a algorithm with the server. Therefor, most clients use the default of SHA-1 and just live with it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Are there privacy concerns?
&lt;/h1&gt;

&lt;p&gt;You bet! With OCSP, an extra third-party is made aware of you browsing to a website that typically wouldn't know otherwise.&lt;/p&gt;

&lt;p&gt;With our above example, GlobalSign knows that you visited dev.to from a specific IP, with a specific browser, at a specific time. All because of OCSP.&lt;/p&gt;

&lt;p&gt;Thankfully, there is a commonly implemented and accepted solution: OCSP Stapling.&lt;/p&gt;

&lt;p&gt;With OCSP stapling, the web server itself makes an OCSP request on your behalf and includes it with the connection information. This means that the third-party does not know who connected to that site at that time, only that &lt;em&gt;somebody&lt;/em&gt; did.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting the OCSP URL from a X.509 Certificate
&lt;/h1&gt;

&lt;p&gt;The OCSP URL for a certificate in within the “Certificate Authority Information Access” extension. To get the URL of the responder, get the information access extension, then iterate through each possible item for that extension and locate the OCSP object. It’s a IA4 ASN1 string value, so you’ll need to decode it to use it as a regular string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;X509&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ocspURL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;AUTHORITY_INFO_ACCESS&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X509_get_ext_d2i&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NID_info_access&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sk_ACCESS_DESCRIPTION_num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Look for the OCSP entry&lt;/span&gt;
    &lt;span class="n"&gt;ACCESS_DESCRIPTION&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sk_ACCESS_DESCRIPTION_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OBJ_obj2nid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;NID_ad_OCSP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;GEN_URI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Hold on to this URL for later use&lt;/span&gt;
            &lt;span class="n"&gt;ocspURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i2s_ASN1_IA5STRING&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ia5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Generating a OCSP request
&lt;/h1&gt;

&lt;p&gt;An OCSP request is one or more "Key IDs", which is a fingerprint of the certificate. Most clients typically only include one certificate per request, and there are no restrictions on servers refusing to respond to requests with multiple certificates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;X509&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;X509&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Passing NULL as the first parameter will use SHA-1&lt;/span&gt;
&lt;span class="n"&gt;OCSP_CERTID&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;certID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OCSP_cert_to_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;OCSP_REQUEST&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OCSP_REQUEST_new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;OCSP_request_add0_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;certid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Hold on to request_data and len for later use.&lt;/span&gt;
&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;request_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i2d_OCSP_REQUEST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;request_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Making the OCSP Request
&lt;/h1&gt;

&lt;p&gt;The actual request is just a simple HTTP POST to the responder URL, with the body being a ASN-encoded OCSP request.&lt;/p&gt;

&lt;p&gt;Like with all HTTP POST requests, you'll need to provide the &lt;code&gt;Content-Type&lt;/code&gt; and &lt;code&gt;Accept&lt;/code&gt; headers. Most OCSP servers will refuse to respond without the correct header values, so make sure you don't forget these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content-Type: application/ocsp-request
Accept: application/ocsp-response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: This post does not cover actually making a HTTP POST request. libCURL works well for this.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An OCSP response contains an outer response object, and at least one inner certificate result. (One result per certificate requested).&lt;/p&gt;

&lt;p&gt;Once you've gotten a response back from the OCSP responder, decode the response body as a &lt;code&gt;OCSP_RESPONSE&lt;/code&gt; object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Assuming this is the bytes of the HTTP response body&lt;/span&gt;
&lt;span class="n"&gt;OCSP_RESPONSE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d2i_OCSP_RESPONSE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check to see if the OCSP request itself was successful. This does &lt;em&gt;not&lt;/em&gt; indicate that the certificate is revoked or not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;requestResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OCSP_response_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ocspResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestResponse&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;OCSP_RESPONSE_STATUS_SUCCESSFUL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Uh oh!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you're sure that the OCSP request was successful, get the basic response object, which contains all of the certificate status results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;OCSP_BASICRESP&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;basicResp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OCSP_response_get1_basic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ocspResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basicResp&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Something bad happened!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Least but not last, get the result of your certificate!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// If the certificate is revoked or not&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// A CRL reason (if revoked)&lt;/span&gt;
&lt;span class="n"&gt;ASN1_GENERALIZEDTIME&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;revocationTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// When the certificate was revoked (if revoked)&lt;/span&gt;
&lt;span class="n"&gt;ASN1_GENERALIZEDTIME&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;thisUP&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// The last time this certificate was updated&lt;/span&gt;
&lt;span class="n"&gt;ASN1_GENERALIZEDTIME&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;nextUP&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// The time of the next update (how long you can cache until&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;OCSP_resp_find_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;certID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;revocationTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;thisUP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;nextUP&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// There was a problem getting the status - probably the certificate wasnt found&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome, now we finally have the result of our certificate!&lt;/p&gt;

&lt;h1&gt;
  
  
  Verifying Certificate Status
&lt;/h1&gt;

&lt;p&gt;Now that we have the status of our certificate, we need to see if our certificate is revoked or not.&lt;/p&gt;

&lt;p&gt;With OCSP there are three possible status' for a certificate: &lt;code&gt;GOOD&lt;/code&gt;, &lt;code&gt;REVOKED&lt;/code&gt;, or &lt;code&gt;UNKNOWN&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GOOD means that the certificate is not revoked according to this OCSP responder. It does &lt;strong&gt;not&lt;/strong&gt; mean the certificate is valid otherwise (I.E. could still be expired).&lt;/li&gt;
&lt;li&gt;REVOKED means that the certificate is revoked.&lt;/li&gt;
&lt;li&gt;UNKNOWN means that the OCSP responder does not know about this certificate. You must be careful with unknown responses, as many applications consider UNKNOWN responses to be the same as GOOD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the certificate has a &lt;code&gt;REVOKED&lt;/code&gt; status, then you'll want to check the reason why it's revoked. OCSP uses the reason codes defined in the certificate revocation list (CRL) specification. The reasons are:&lt;/p&gt;

&lt;p&gt;– unspecified: can be used to revoke certificates for reasons other than the specific codes.&lt;br&gt;
– keyCompromise: is used in revoking an end-entity certificate; it indicates that it is known or suspected that the subject's private key, or other aspects of the subject validated in the certificate, have been compromised.&lt;br&gt;
– cACompromise: is used in revoking a CA-certificate; it indicates that it is known or suspected that the subject's private key, or other aspects of the subject validated in the certificate, have been compromised.&lt;br&gt;
– affiliationChanged: indicates that the subject's name or other information in the certificate has been modified but there is no cause to suspect that the private key has been compromised.&lt;br&gt;
– superseded: indicates that the certificate has been superseded but there is no cause to suspect that the private key has been compromised.&lt;br&gt;
– cessationOfOperation: indicates that the certificate is no longer needed for the purpose for which it was issued but there is no cause to suspect that the private key has been compromised.&lt;br&gt;
– privilegeWithdrawn: indicates that a certificate (public-key or attribute certificate) was revoked because a privilege contained within that certificate has been withdrawn.&lt;br&gt;
– aACompromise: indicates that it is known or suspected that aspects of the AA validated in the attribute certificate have been compromised.&lt;/p&gt;

&lt;p&gt;^&lt;a href="https://security.stackexchange.com/a/174331"&gt;source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All these reasons are well and good, and there's likely nothing your application has to do for any of them, but then there's two edge cases that really complicate matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;certificateHold: indicates that a certificate authority no longer vouches for this certificate, but that may change at a later date.&lt;/li&gt;
&lt;li&gt;removeFromCrl: indicates that a certificate was previously on hold, but is no longer on hold and considered not revoked.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So it's always important to check the reason, because even if the status is REVOKED, if the reason is &lt;code&gt;removeFromCrl&lt;/code&gt;, then it's not actually revoked.&lt;/p&gt;

&lt;p&gt;If you're looking for easily verify your certificates on-the-go using your iOS mobile device, check out one of my projects: &lt;a href="https://tlsinspector.com"&gt;TLS Inspector&lt;/a&gt;. The worlds first Free &amp;amp; Libre X509 Certificate Inspector on iOS (&lt;a href="https://github.com/certificate-helper/tls-inspector"&gt;GitHub&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>ocsp</category>
      <category>tls</category>
      <category>security</category>
    </item>
    <item>
      <title>Pragmatically Generating a Self-Signed Certificate and Private Key using OpenSSL</title>
      <dc:creator>Ian Spence</dc:creator>
      <pubDate>Wed, 22 Feb 2017 19:27:07 +0000</pubDate>
      <link>https://forem.com/ecnepsnai/pragmatically-generating-a-self-signed-certificate-and-private-key-usingopenssl</link>
      <guid>https://forem.com/ecnepsnai/pragmatically-generating-a-self-signed-certificate-and-private-key-usingopenssl</guid>
      <description>&lt;p&gt;Recently I found myself needing to generate a HTTPS Server Certificate and Private Key for an iOS app using OpenSSL, what surprised me was the total lack of documentation for OpenSSL.&lt;/p&gt;

&lt;p&gt;While there is plenty of function documentation, what OpenSSL really lacks is examples of how it all fits together. It's like having all of the pieces of a puzzle, but no picture of that the finished product will look like. Many online examples are insecure or make use of deprecated functions, a serious concern considering the consequences.&lt;/p&gt;

&lt;p&gt;This tutorial will cover the basics for how to generate a RSA or ECDSA Private Key and a X509 Server Certificate for your application in C. For this tutorial, we will be using OpenSSL 1.1.0f.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important note:&lt;/strong&gt; This tutorial is written for the modern version of OpenSSL, 1.1.x, and is not backwards compatible with OpenSSL 1.0.x. If you are still on the 1.0.x train, it's &lt;strong&gt;highly&lt;/strong&gt; recommended that you upgrade your application.&lt;/p&gt;

&lt;h1&gt;
  
  
  Generating the Private Key
&lt;/h1&gt;

&lt;p&gt;A private key is required for any PKI encryption setup, and you generally have two choices for algorithms: RSA and ECDSA.&lt;/p&gt;

&lt;h2&gt;
  
  
  ECDSA V.S. RSA
&lt;/h2&gt;

&lt;p&gt;RSA has been the defacto standard for private keys for quite a long time, and if used correctly is still secure. The security of an RSA key relies on how large the “big number is when the key is created. The recommended size of this number keeps going up and up as we're getting better and better at breaking smaller numbers.&lt;br&gt;
ECDSA keys, however, are created differently than RSA keys, and are much harder to break. In fact, no tangible progress has been made on solving the problem that ECDSA keys use The Elliptic Curve Discrete Logarithm Problem (ECDLP) since 1985. Because of this, ECDSA keys provide much greater security without the need for larger numbers. For example: a 256-bit ECDSA key is equivalent to a 3,248-bit RSA key.&lt;br&gt;
Not only are ECDSA keys more secure than most RSA keys, they're also much less CPU intensive. CloudFlare dissected the performance of the two in their &lt;a href="https://blog.cloudflare.com/ecdsa-the-digital-signature-algorithm-of-a-better-internet/"&gt;write up on the algorithm&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                            sign/s
256 bit ecdsa (nistp256)    9516.8
rsa 2048 bits               1001.8

(openssl 1.0.2 beta on x86_64 with enable-ec_nistp_64_gcc_128)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To put it simply: ECDSA keys are 9x less CPU intensive while providing greater security than RSA keys.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating an RSA Private Key
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include &amp;lt;openssl/x509v3.h&amp;gt;
#include &amp;lt;openssl/rsa.h&amp;gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="n"&gt;OPENSSL_init_ssl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;OPENSSL_init_crypto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;EVP_PKEY&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pkey&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EVP_PKEY_new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;BIGNUM&lt;/span&gt;   &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;bigNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BN_new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;        &lt;span class="n"&gt;exponent&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RSA_F4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;RSA&lt;/span&gt;      &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RSA_new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BN_set_word&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bigNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RSA_generate_key_ex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;bigNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;EVP_PKEY_set1_RSA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;cleanup&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;RSA_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;BN_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bigNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generating a ECDSA Private Key
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include &amp;lt;openssl/x509v3.h&amp;gt;
#include &amp;lt;openssl/ecdsa.h&amp;gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="n"&gt;OPENSSL_init_ssl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;OPENSSL_init_crypto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;EVP_PKEY&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pkey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EVP_PKEY_new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;EC_KEY&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ecc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EC_KEY_new_by_curve_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NID_X9_62_prime256v1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ecc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;EC_KEY_set_asn1_flag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ecc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OPENSSL_EC_NAMED_CURVE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EC_KEY_generate_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ecc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EVP_PKEY_assign_EC_KEY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ecc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Generating the Server Certificate
&lt;/h1&gt;

&lt;p&gt;The server certificate is the client-facing piece of information that details the connection to the server. It tells the client what type of cipher to use, and validates the identity of the server. We're generating a self-signed certificate in this case, so your computer won't trust the certificate until you install it locally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include &amp;lt;openssl/x509v3.h&amp;gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="n"&gt;OPENSSL_init_ssl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;OPENSSL_init_crypto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;X509&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;x509&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X509_new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// 2 means Version 3.&lt;/span&gt;
&lt;span class="n"&gt;X509_set_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2L&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Generate your private key using one of the above methods&lt;/span&gt;
&lt;span class="n"&gt;EVP_PKEY&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;X509_set_pubkey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;EVP_PKEY_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Generate a random serial number for this certificate.&lt;/span&gt;
&lt;span class="c1"&gt;// There are various ways to do this, depending on the platform.&lt;/span&gt;
&lt;span class="c1"&gt;// I'll leave this up to you.&lt;/span&gt;
&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;random_serial_number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Set Serial Number&lt;/span&gt;
&lt;span class="n"&gt;ASN1_INTEGER_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X509_get_serialNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;random_serial_number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Set Validity Date Range&lt;/span&gt;
&lt;span class="c1"&gt;// These value is appended to the systems current time stamp meaning that 0 = now.&lt;/span&gt;
&lt;span class="n"&gt;X509_gmtime_adj&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;ASN1_TIME&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;X509_get0_notBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 60 * 60 * 24 * NUMBER_OF_DAYS_TO_BE_VALID&lt;/span&gt;
&lt;span class="n"&gt;X509_gmtime_adj&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;ASN1_TIME&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;X509_get0_notAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;7776000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;X509_NAME&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X509_get_subject_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Now to add the subject name fields to the certificate&lt;/span&gt;
&lt;span class="c1"&gt;// I use a macro here to make it cleaner.&lt;/span&gt;
&lt;span class="cp"&gt;#define addName(field, value) X509_NAME_add_entry_by_txt(name, field,  MBSTRING_ASC, (unsigned char *)value, -1, -1, 0)
&lt;/span&gt;
&lt;span class="c1"&gt;// The domain name or IP address that the certificate is issued for.&lt;/span&gt;
&lt;span class="n"&gt;addName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ecn.io"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// The organizational unit for the cert. Usually this is a department.&lt;/span&gt;
&lt;span class="n"&gt;addName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OU"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Certificate Authority"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// The organization of the cert.&lt;/span&gt;
&lt;span class="n"&gt;addName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"O"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s"&gt;"ecn.io Blog"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// The city of the organization.&lt;/span&gt;
&lt;span class="n"&gt;addName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"L"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s"&gt;"Vancouver"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// The state/province of the organization.&lt;/span&gt;
&lt;span class="n"&gt;addName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"S"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s"&gt;"British Columbia"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// The country (ISO 3166) of the organization&lt;/span&gt;
&lt;span class="n"&gt;addName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s"&gt;"CA"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;X509_set_issuer_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Modern browsers ignore the CN subject field and refer only to the Subject&lt;/span&gt;
&lt;span class="c1"&gt;// Alternative Name extension, which allows you to specify&lt;/span&gt;
&lt;span class="c1"&gt;// multiple domain names, IP addresses, and more for a single certificate.&lt;/span&gt;
&lt;span class="c1"&gt;// The SAN value is in the following format:&lt;/span&gt;
&lt;span class="c1"&gt;// &amp;lt;TYPE&amp;gt;.&amp;lt;INDEX&amp;gt;:&amp;lt;VALUE&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// Common types are:&lt;/span&gt;
&lt;span class="c1"&gt;// - DNS&lt;/span&gt;
&lt;span class="c1"&gt;// - IP&lt;/span&gt;
&lt;span class="c1"&gt;// - email&lt;/span&gt;
&lt;span class="c1"&gt;// - URI&lt;/span&gt;
&lt;span class="c1"&gt;// Join multiple SAN entries using a comma.&lt;/span&gt;
&lt;span class="c1"&gt;// In this example, this certificate is for both the `ecn.io` and `*.ecn.io`&lt;/span&gt;
&lt;span class="c1"&gt;// domains. Which means it'll cover all single level subdomains for ecn.io&lt;/span&gt;
&lt;span class="c1"&gt;// (E.G. blog.ecn.io but not awesome.blog.ecn.io)&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;san_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"DNS.1:ecn.io,DNS.2:*.ecn.io"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;X509_EXTENSION&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X509V3_EXT_conf_nid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NID_subject_alt_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;san_value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X509_add_ext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="n"&gt;X509_EXTENSION_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;X509_EXTENSION_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Specify the encryption algorithm of the signature.&lt;/span&gt;
&lt;span class="c1"&gt;// SHA256 should suit your needs.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X509_sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EVP_sha256&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Saving your private key and certificate
&lt;/h1&gt;

&lt;p&gt;OpenSSL provides you with the mechanisms to save your private key and certificate to disk, in various formats. There are many ways to encode certificate and keys, I'm going to show you how to use the most common two, PKCS12 (P12), and PEM.&lt;/p&gt;

&lt;p&gt;The security of the private key is the most critical component of PKI, and all of your work can easily be wasted if you don't take good care to ensure your private key is safe. There are many things you can do to keep your private key safe, but at a minimum you should be changing the file permissions to not be world-readable. Jeff Atwood has a good write-up on &lt;a href="https://blog.codinghorror.com/keeping-private-keys-private/"&gt;Keeping Private Keys Private&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  PKCS12 V.S. PEM
&lt;/h2&gt;

&lt;p&gt;As mentioned above, theres many ways to encode keys, but the two that I'll go over are PKCS12 and PEM. PKCS12 (also known as P12) is the successor to Microsoft's PFX format, which was criticized for being overly complex and difficult to use, and while P12 is still quite complex thankfully OpenSSL does nearly all of the heavy lifting for you, leaving you to only implement a handful of commands.&lt;/p&gt;

&lt;p&gt;The largest advantage to using P12 is that they are always encrypted using a pass phrase, and can contain multiple certificates and keys, in so called "buckets", within a single file.&lt;/p&gt;

&lt;p&gt;The common alternative to P12 is Privacy Enhanced Mail (PEM). PEM is a very simple standard for encoding certificates and keys using base64, which can be easily moved around as ASCII text, as opposed to binary data like with DER and P12.&lt;/p&gt;

&lt;p&gt;As PEM is strictly just an encoding, it does not require encrypting any data, and therefor is commonly used on Web Servers so no hard-coded passwords need to be added to configuration files. As well, unlike P12, PEM encoding is 1 object per file, meaning 1 certificate file and 1 key file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Save using PKCS12
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include &amp;lt;openssl/x509v3.h&amp;gt;
#include &amp;lt;openssl/pkcs12.h&amp;gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="n"&gt;OPENSSL_init_ssl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;OPENSSL_init_crypto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Prompt the user for the password to encrypt the P12 file using&lt;/span&gt;
&lt;span class="c1"&gt;// DON'T USE A HARD-CODED PASSWORD OR I WILL PERSONALLY COME OVER&lt;/span&gt;
&lt;span class="c1"&gt;// THERE AND SCREAM AT YOU&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;export_password&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;PKCS12&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p12&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PKCS12_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;export_password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PKCS12_DEFAULT_ITER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NID_key_usage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// The full path of the P12 file that you'll create&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;save_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"./server.p12"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;save_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"wb"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i2d_PKCS12_fp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;finished&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Save using PEM
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include &amp;lt;openssl/x509v3.h&amp;gt;
#include &amp;lt;openssl/pem.h&amp;gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="c1"&gt;// The full path of the key and crt file that you'll create&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;key_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"./server.key"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;crt_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"./server.crt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"wb"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Prompt the user for the password to encrypt the key file using&lt;/span&gt;
&lt;span class="c1"&gt;// DON'T USE A HARD-CODED PASSWORD OR I WILL PERSONALLY COME OVER&lt;/span&gt;
&lt;span class="c1"&gt;// THERE AND SCREAM AT YOU&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;export_password&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Here you write the private key (pkey) to disk. OpenSSL will encrypt the&lt;/span&gt;
&lt;span class="c1"&gt;// file using the password and cipher you provide.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PEM_write_PrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="n"&gt;EVP_des_ede3_cbc&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;export_password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;export_password&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                         &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;crt_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"wb"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Here you write the certificate to the disk. No encryption is needed here&lt;/span&gt;
&lt;span class="c1"&gt;// since this is public facing information&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PEM_write_X509&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OpenSSL Error. Use `ERR_peek_last_error_line` to find out more.&lt;/span&gt;
    &lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Verifying our Server Certificate
&lt;/h1&gt;

&lt;p&gt;OpenSSL has a nifty little function that lets you quickly print out the summary of a X509 certificate to a file (or stdout):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X509 * cert = ...
X509_print_fp(stdout, cert);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspecting the certificate created with a RSA private key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1365365151 (0x5161d19f)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=ecn.io, OU=Certificate Authority, O=ecn.io, L=Vancouver, C=CA
        Validity
            Not Before: Oct 30 20:33:01 2017 GMT
            Not After : Oct 31 02:33:00 2018 GMT
        Subject: CN=ecn.io, OU=Certificate Authority, O=ecn.io, L=Vancouver, C=CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...omitted...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:ecn.io, DNS:*.ecn.io
    Signature Algorithm: sha256WithRSAEncryption
         ...omitted...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with the ECDSA key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1365365151 (0x5161d19f)
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN=ecn.io, OU=Certificate Authority, O=ecn.io, L=Vancouver, C=CA
        Validity
            Not Before: Oct 30 20:33:01 2017 GMT
            Not After : Oct 31 02:33:00 2018 GMT
        Subject: CN=ecn.io, OU=Certificate Authority, O=ecn.io, L=Vancouver, C=CA
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    ...omitted...
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:ecn.io, DNS:*.ecn.io
    Signature Algorithm: ecdsa-with-SHA256
         ...omitted...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're looking for easily verify your new X509 certificate on-the-go using your iOS mobile device, check out one of my projects: &lt;a href="https://tlsinspector.com"&gt;TLS Inspector&lt;/a&gt;. The worlds first Free &amp;amp; Libre X509 Certificate Inspector on iOS (&lt;a href="https://github.com/certificate-helper/tls-inspector"&gt;GitHub&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>openssl</category>
      <category>c</category>
      <category>cryptography</category>
      <category>tls</category>
    </item>
    <item>
      <title>Hi, I'm Ian Spence</title>
      <dc:creator>Ian Spence</dc:creator>
      <pubDate>Sat, 04 Feb 2017 18:46:26 +0000</pubDate>
      <link>https://forem.com/ecnepsnai/hi-im-ian-spence</link>
      <guid>https://forem.com/ecnepsnai/hi-im-ian-spence</guid>
      <description>&lt;p&gt;I have been coding for 7 years.&lt;/p&gt;

&lt;p&gt;You can find me on GitHub as &lt;a href="https://github.com/ecnepsnai" rel="noopener noreferrer"&gt;ecnepsnai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in Vancouver, BC.&lt;/p&gt;

&lt;p&gt;I mostly program in these languages: Objective-C, C, Golang, Javascript&lt;/p&gt;

&lt;p&gt;I am currently learning more about TLS, OpenSSL/LibreSSL.&lt;/p&gt;

&lt;p&gt;Nice to meet you.&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
