fix and chore: pinned maennchen/zipstream-php version to work with arm7 and updated...
[openemr.git] / library / create_ssl_certificate.php
blob093eda4183291e708e407fa13869401657ab4ed5
1 <?php
3 /**
4 * library/create_ssl_certificate.php
6 * @package OpenEMR
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 */
20 /**
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.
31 function create_csr(
32 $commonName,
33 $emailAddress,
34 $countryName,
35 $stateOrProvinceName,
36 $localityName,
37 $organizationName,
38 $organizationalUnitName
39 ) {
41 if ($commonName == "") {
42 return false;
45 /* Build the Distinguished Name (DN) for the certificate */
46 $dn = array("commonName" => $commonName);
48 if ($emailAddress) {
49 $dn = array_merge($dn, array("emailAddress" => $emailAddress));
52 if ($countryName) {
53 $dn = array_merge($dn, array("countryName" => $countryName));
56 if ($stateOrProvinceName) {
57 $dn = array_merge($dn, array("stateOrProvinceName" => $stateOrProvinceName));
60 if ($localityName) {
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) {
75 return false;
78 $csr = openssl_csr_new($dn, $privkey);
79 if ($csr === false) {
80 return false;
83 return array($csr, $privkey);
87 /**
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));
97 return $cert;
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) {
116 return false;
119 $csr = $arr[0];
120 $privkey = $arr[1];
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(
130 $csr,
131 file_get_contents($cacert),
132 file_get_contents($cakey),
133 $valid_days,
134 ['digest_alg' => 'sha256'],
135 $serial
138 if ($cert === false) {
139 return 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) {
147 return false;
150 return $p12Out;