{"id":105,"date":"2015-09-06T22:41:00","date_gmt":"2015-09-06T20:41:00","guid":{"rendered":"http:\/\/www.underealm.com\/tech\/?p=105"},"modified":"2015-09-06T22:41:00","modified_gmt":"2015-09-06T20:41:00","slug":"ssl-certificate-with-san","status":"publish","type":"post","link":"https:\/\/www.underealm.com\/tech\/2015\/09\/ssl-certificate-with-san\/","title":{"rendered":"Self-Signed Certificate with Subject Alternative Names (SAN) [AntiFUD]"},"content":{"rendered":"<p>Wrangling obscure OpenSSL functions to create and publish SSL certificates has always been kind of a mess. If you want(ed) to create a valid self-signed certificate for multi domains or, at least, <em>example.com<\/em> <strong>and<\/strong> <em>www.example.com<\/em>, you most likely were out of luck.<\/p>\n<p><a href=\"http:\/\/blog.endpoint.com\/2014\/10\/openssl-csr-with-alternative-names-one.html\" target=\"_blank\">There is<\/a> <a href=\"https:\/\/www.digicert.com\/subject-alternative-name-compatibility.htm\" target=\"_blank\">a lot of<\/a> <a href=\"https:\/\/rtcamp.com\/wordpress-nginx\/tutorials\/ssl\/multidomain-ssl-subject-alternative-names\/\" target=\"_blank\">wrong or partial<\/a> <a href=\"http:\/\/stackoverflow.com\/questions\/21488845\/how-can-i-generate-a-self-signed-certificate-with-subjectaltname-using-openssl\/21494483#21494483\" target=\"_blank\">documentation<\/a> <a href=\"https:\/\/www.prshanmu.com\/2009\/03\/generating-ssl-certificates-with-x509v3-extensions.html\" target=\"_blank\">on the subject<\/a>, but is\u2026 well\u2026 wrong and\/or incomplete. It is thus time for another episode of <strong>AntiFUD<\/strong>.<\/p>\n<h2>The problem<\/h2>\n<p>You have multiple paths of the same website to cover for, but a single <abbr title=\"Common Name\">CN<\/abbr>. If you use <em>example.com<\/em> then <em>www.example.com<\/em> will result in invalid SSL certificate, and vice versa. Suppose you have the following domain names:<\/p>\n<ul>\n<li>example.com<\/li>\n<li>www.example.com<\/li>\n<li>*.user.example.com<\/li>\n<\/ul>\n<p>In such a scenario there is no real victory no matter what you choose to use as a <abbr title=\"Common Name\">CN<\/abbr>: the most used wildcard <abbr title=\"Common Name\">CN<\/abbr>, <em>*.example.com<\/em>, is of no use either because it matches with <em>www.example.com<\/em> and <em>user.example.com<\/em>, but not with <em>username1.user.example.com<\/em>. The only way to address all these issues is to create and sign a <a href=\"https:\/\/en.wikipedia.org\/wiki\/X.509\">X.509 v3<\/a> SSL certificate, to allow <abbr title=\"Subject Alternative Names\">SAN<\/abbr>. The SAN extension has been introduce to resolve all of these problems, allowing the validity of multiple domains\/subdomains within the same certificate.<\/p>\n<h2>Creating the certificate<\/h2>\n<p>We have to start by creating an alternative configuration file to use with OpenSSL, and list the server names we need. As mentioned below we also have to enable the usage of v3 extensions.<\/p>\n<pre class=\"nums:false\" lang=\"cmd\"><code># mkdir certificates\r\n# cd certificates\r\n# cp \/etc\/ssl\/openssl.cnf .\/example-com.cnf<\/code><\/pre>\n<p>We can now edit the file and adjust as needed:<\/p>\n<pre class=\"nums:false toolbar:1\" lang=\"ini\" title=\"example-com.cnf\"><code>[ req ]\r\nx509_extensions = v3_ca\r\nreq_extensions = v3_req\r\n\r\n[ usr_cert ]\r\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment\r\n\r\n[ v3_req ]\r\nbasicConstraints = CA:FALSE\r\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment\r\nsubjectAltName=@alt_names\r\n\r\n[ v3_ca ]\r\nsubjectAltName=@alt_names\r\n\r\n[ alt_names ]\r\nDNS.1 = example.com\r\nDNS.2 = www.example.com\r\nDNS.3 = *.host.example.com<\/code><\/pre>\n<p>In the default file, parameters such as <strong>req_extensions<\/strong> and <strong>keyUsage<\/strong> are commented out, while <strong>subjectAltName<\/strong> is missing. We have to add it to v3_req and v3_ca, and create the respective section. It can be created anywhere in the file, but it is generally appended to the bottom. Since the CN is (or, at least, should be) ignored in the presence of SAN, we insert all the names in the <strong>alt_names<\/strong> field.<\/p>\n<p>With the configuration in place we can now create the certificate:<\/p>\n<pre class=\"nums:false\" lang=\"cmd\"><code># openssl genrsa -out example-com.key 4096\r\n# openssl req -new -config example-com.cnf -key example-com.key -out example-com.csr\r\n# openssl x509 -req -in example-com.csr -CA rootCA.pem -CAkey rootCA.key -CAserial rootCA.srl -out example-com.crt -days 365  -extfile example-com.cnf -extensions v3_ca<\/code><\/pre>\n<p>The deviation from the standard procedure is the addition of the v3 during the CA sign. We do this by using <strong>-extfile example-com.cnf<\/strong> to use the custom configurations, and specifying <strong>-extensions v3_ca<\/strong> to make sure SAN are passed through and saved in the signed certificate.<\/p>\n<p>To make sure it worked you can do the following:<\/p>\n<pre class=\"nums:false\" lang=\"cmd\"><code># openssl x509 -in example-com.crt -text -noout\r\n        [\u2026]\r\n        X509v3 extensions:\r\n            X509v3 Subject Alternative Name:\r\n                DNS:example.com, DNS:www.example.com, DNS:*.user.example.com\r\n            X509v3 Subject Key Identifier:\r\n                xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx\r\n            X509v3 Authority Key Identifier:\r\n                xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx\r\n\r\n            X509v3 Basic Constraints:\r\n                CA:TRUE\r\n        [\u2026]\r\n<\/code><\/pre>\n<p>The only thing left to do is to set up the certificates in the server, and everything will work as intended.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wrangling obscure OpenSSL functions to create and publish SSL certificates has always been kind of a mess. If you want(ed) to create a valid self-signed certificate for multi domains or, at least, example.com and www.example.com, you most likely were out of luck. There is a lot of wrong or partial documentation on the subject, but [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32],"tags":[33,38,36,37,39,35,34,40],"class_list":["post-105","post","type-post","status-publish","format-standard","hentry","category-antifud","tag-antifud-2","tag-ca","tag-certificate","tag-csr","tag-san","tag-self-signed","tag-ssl","tag-subject-additional-names"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.underealm.com\/tech\/wp-json\/wp\/v2\/posts\/105"}],"collection":[{"href":"https:\/\/www.underealm.com\/tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.underealm.com\/tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.underealm.com\/tech\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.underealm.com\/tech\/wp-json\/wp\/v2\/comments?post=105"}],"version-history":[{"count":0,"href":"https:\/\/www.underealm.com\/tech\/wp-json\/wp\/v2\/posts\/105\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.underealm.com\/tech\/wp-json\/wp\/v2\/media?parent=105"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.underealm.com\/tech\/wp-json\/wp\/v2\/categories?post=105"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.underealm.com\/tech\/wp-json\/wp\/v2\/tags?post=105"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}