forked from openemr/openemr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
create_ssl_certificate.php
151 lines (126 loc) · 4.56 KB
/
create_ssl_certificate.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<?php
/**
* library/create_ssl_certificate.php
*
* @package OpenEMR
* @link https://www.open-emr.org
* @author visolve <[email protected]>
* @author Brady Miller <[email protected]>
* @author Jerry Padgett <[email protected]>
* @copyright Copyright (c) visolve <[email protected]>
* @copyright Copyright (c) 2020 Brady Miller <[email protected]>
* @copyright Copyright (c) 2020 Jerry Padgett <[email protected]>
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*/
/* This file contains routines for creating SSL certificates */
/**
* Create a Certificate Signing Request (CSR) with the given values
* @param $commonName - The username/hostname
* @param $emailAddress - The email of the username
* @param $countryName - Two letter country code, like "US"
* @param $stateOrProvinceName - State name
* @param $localityName - City name
* @param $organizationName - Organization Name
* @param $organizationalUnitName - Organization Unit Name
* @return array [ CSR data, privatekey ], or 'false' on error.
*/
function create_csr(
$commonName,
$emailAddress,
$countryName,
$stateOrProvinceName,
$localityName,
$organizationName,
$organizationalUnitName
) {
if ($commonName == "") {
return false;
}
/* Build the Distinguished Name (DN) for the certificate */
$dn = array("commonName" => $commonName);
if ($emailAddress) {
$dn = array_merge($dn, array("emailAddress" => $emailAddress));
}
if ($countryName) {
$dn = array_merge($dn, array("countryName" => $countryName));
}
if ($stateOrProvinceName) {
$dn = array_merge($dn, array("stateOrProvinceName" => $stateOrProvinceName));
}
if ($localityName) {
$dn = array_merge($dn, array("localityName" => $localityName));
}
if ($organizationName) {
$dn = array_merge($dn, array("organizationName" => $organizationName));
}
if ($organizationalUnitName) {
$dn = array_merge($dn, array("organizationalUnitName" => $organizationalUnitName));
}
/* Create the public/private key pair */
$privkey = openssl_pkey_new();
if ($privkey === false) {
return false;
}
$csr = openssl_csr_new($dn, $privkey);
if ($csr === false) {
return false;
}
return array($csr, $privkey);
}
/**
* Create a certificate, signed by the given Certificate Authority.
* @param $csr - The certificate signing request
* @param $cacert - The Certificate Authority to sign with, or NULL if not used.
* @param $cakey - The Certificate Authority private key data to sign with.
* @return data - A signed certificate, or false on error.
*/
function create_crt($csr, $cacert, $cakey)
{
$cert = openssl_csr_sign($csr, $cacert, $cakey, 3650, ['digest_alg' => 'sha256'], rand(1000, 9999));
return $cert;
}
/**
* Create a new client certificate for a username or client hostname.
* @param $commonName - The username or hostname
* @param $emailAddress - The user's email address
* @param $serial - The serial number
* @param $cacert - Path to Certificate Authority cert file.
* @param $cakey - Path to Certificate Authority key file.
* @param $valid_days - validity in number of days for the user certificate
* @return string - The client certificate signed by the Certificate Authority, or false on error.
*/
function create_user_certificate($commonName, $emailAddress, $serial, $cacert, $cakey, $valid_days)
{
/* Generate a certificate signing request */
$arr = create_csr($commonName, $emailAddress, "", "", "", "", "");
if ($arr === false) {
return false;
}
$csr = $arr[0];
$privkey = $arr[1];
/* user id is used as serial number to sign a certificate */
$serial = (is_int($serial)) ? $serial : 0;
$res = sqlStatement("SELECT id FROM users WHERE username = ?", array($commonName));
if ($row = sqlFetchArray($res)) {
$serial = $row['id'];
}
$cert = openssl_csr_sign(
$csr,
file_get_contents($cacert),
file_get_contents($cakey),
$valid_days,
['digest_alg' => 'sha256'],
$serial
);
if ($cert === false) {
return false;
}
/* Convert the user certificate to .p12 (PKCS 12) format, which is the
* standard format used by browsers.
*/
$clientPassPhrase = trim($_POST['clientPassPhrase']);
if (openssl_pkcs12_export($cert, $p12Out, $privkey, $clientPassPhrase) === false) {
return false;
}
return $p12Out;
}