4 * library/create_ssl_certificate.php
7 * @link https://www.open-emr.org
8 * @author visolve <vicareplus_engg@visolve.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @author Jerry Padgett <sjpadgett@gmail.com>
11 * @copyright Copyright (c) visolve <vicareplus_engg@visolve.com>
12 * @copyright Copyright (c) 2020 Brady Miller <brady.g.miller@gmail.com>
13 * @copyright Copyright (c) 2020 Jerry Padgett <sjpadgett@gmail.com>
14 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
17 /* This file contains routines for creating SSL certificates */
21 * Create a Certificate Signing Request (CSR) with the given values
22 * @param $commonName - The username/hostname
23 * @param $emailAddress - The email of the username
24 * @param $countryName - Two letter country code, like "US"
25 * @param $stateOrProvinceName - State name
26 * @param $localityName - City name
27 * @param $organizationName - Organization Name
28 * @param $organizationalUnitName - Organization Unit Name
29 * @return array [ CSR data, privatekey ], or 'false' on error.
38 $organizationalUnitName
41 if ($commonName == "") {
45 /* Build the Distinguished Name (DN) for the certificate */
46 $dn = array("commonName" => $commonName);
49 $dn = array_merge($dn, array("emailAddress" => $emailAddress));
53 $dn = array_merge($dn, array("countryName" => $countryName));
56 if ($stateOrProvinceName) {
57 $dn = array_merge($dn, array("stateOrProvinceName" => $stateOrProvinceName));
61 $dn = array_merge($dn, array("localityName" => $localityName));
64 if ($organizationName) {
65 $dn = array_merge($dn, array("organizationName" => $organizationName));
68 if ($organizationalUnitName) {
69 $dn = array_merge($dn, array("organizationalUnitName" => $organizationalUnitName));
72 /* Create the public/private key pair */
73 $privkey = openssl_pkey_new();
74 if ($privkey === false) {
78 $csr = openssl_csr_new($dn, $privkey);
83 return array($csr, $privkey);
88 * Create a certificate, signed by the given Certificate Authority.
89 * @param $csr - The certificate signing request
90 * @param $cacert - The Certificate Authority to sign with, or NULL if not used.
91 * @param $cakey - The Certificate Authority private key data to sign with.
92 * @return data - A signed certificate, or false on error.
94 function create_crt($csr, $cacert, $cakey)
96 $cert = openssl_csr_sign($csr, $cacert, $cakey, 3650, ['digest_alg' => 'sha256'], rand(1000, 9999));
102 * Create a new client certificate for a username or client hostname.
103 * @param $commonName - The username or hostname
104 * @param $emailAddress - The user's email address
105 * @param $serial - The serial number
106 * @param $cacert - Path to Certificate Authority cert file.
107 * @param $cakey - Path to Certificate Authority key file.
108 * @param $valid_days - validity in number of days for the user certificate
109 * @return string - The client certificate signed by the Certificate Authority, or false on error.
111 function create_user_certificate($commonName, $emailAddress, $serial, $cacert, $cakey, $valid_days)
113 /* Generate a certificate signing request */
114 $arr = create_csr($commonName, $emailAddress, "", "", "", "", "");
115 if ($arr === false) {
122 /* user id is used as serial number to sign a certificate */
123 $serial = (is_int($serial)) ?
$serial : 0;
124 $res = sqlStatement("SELECT id FROM users WHERE username = ?", array($commonName));
125 if ($row = sqlFetchArray($res)) {
126 $serial = $row['id'];
129 $cert = openssl_csr_sign(
131 file_get_contents($cacert),
132 file_get_contents($cakey),
134 ['digest_alg' => 'sha256'],
138 if ($cert === false) {
142 /* Convert the user certificate to .p12 (PKCS 12) format, which is the
143 * standard format used by browsers.
145 $clientPassPhrase = trim($_POST['clientPassPhrase']);
146 if (openssl_pkcs12_export($cert, $p12Out, $privkey, $clientPassPhrase) === false) {