Menu
blog.headdesk.me
blog.headdesk.me

Create CSR with SANs on php

Posted on 2017/04/112017/04/15

Ever tried generating CSR with SANs? It is tedious work. It involves populating an openssl config file with the additional domain names. Put it on a webapp, it does not eliminate the work, but only require minimal coding once.

SANs certificate is an extension to X.509, which allows additional domain names to be added to a certificate. As people starts to put more and more domains in a certificate, the work to generate a CSR becomes cumbersome. Maybe the future version of openssl will simplify the process. Until then, the domain names need to be put in a config file for openssl to read.

Building a webapp, or more like a couple of php pages make life easier. First, check that the openssl extension is enabled on php. Then here comes the php code.

Generate a RSA key, export the private key to a string variable

$keypair = openssl_pkey_new(array('private_key_bits' => 2048));
openssl_pkey_export($keypair, $privKey);

Create a form, get the usual inputs

$dn = array(
    "countryName" => $_POST["country"],
    "stateOrProvinceName" => $_POST["state"],
    "localityName" => $_POST["city"],
    "organizationName" => $_POST["orgname"],
    "commonName" => $_POST["cn"],
    "emailAddress" => $_POST["email"]
);

Use a textarea to gather the SANs, then put it in an array

	$sansRaw = $_POST["sans"];
	$sansArr = explode("\n", $sansRaw);
	$sansArr = array_filter($sansArr, 'trim');

Write that to a temp openssl config file

$sslConfig = file_get_contents("/data/sites/x/csr/ssl-template.cnf");
	$counter = 1;

	foreach ($sansArr as $line) {
		$fqdn = tidyFqdn($line);
		$sslConfig = $sslConfig . "\nDNS." . $counter . "=" . $fqdn;
		$counter++;
	}

	$sslConfigFile = "/data/sites/x/csr/tmp/ssl.cnf-" . rand();

	file_put_contents($sslConfigFile, $sslConfig);

The template config looks like this

[ req ]
distinguished_name    = req_distinguished_name

[ req_distinguished_name ]
countryName            = Country Name (2 letter code)
stateOrProvinceName        = State or Province Name (full name)
stateOrProvinceName_default    = Some-State
localityName            = Locality Name (eg, city)
0.organizationName        = Organization Name (eg, company)
organizationalUnitName        = Organizational Unit Name (eg, section)
commonName            = Common Name (e.g. server FQDN or YOUR name)
emailAddress            = Email Address

[ v3_req ]
subjectAltName = @req_sans

[ req_sans ]

Create a config array and generate the CSR

	$csrConfig = array(
	    "digest_alg" => "sha256",
	    "req_extensions" => "v3_req",
   	    "config" => $sslConfigFile
	);

	$csrRes = openssl_csr_new($dn, $privKey, $csrConfig);
        openssl_csr_export($csrRes, $csr);

The CSR is now in the $csr variable. The private key that goes with it is in $privKey.

Loading

facebookShare on Facebook
TwitterTweet

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Full text search

Recent Posts

  • Upgrade RockyLinux 8 to 9
  • Terraform and segregated permissions
  • LVM Compression and Deduplication
  • Edit gpg encrypted file with vim
  • Lelit Elizabeth PL92T Pressure Tuning
  • aws (8)
  • coffee (1)
  • headfi (1)
  • linux (6)
  • others (59)
  • security (2)
  • tech (36)
  • wordpress (2)

Loading

apache apigateway aws awscli azure backup cloud coffee docker ec2 EL8 ElasticBeanstalk enpass espresso featured kernel lelit linux lvm meltdown MFA nat gateway nginx php proliant python rdp Redhat RHEL rpm Ryzen s2s scp serverless site-to-site smartarray snapshot spectre tech terraform transit gateway ubuntu ubuntu upgrade vpn wordpress

©2023 blog.headdesk.me | Powered by SuperbThemes & WordPress