Revision 7e83055a
Added by Jim Pingle over 5 years ago
src/usr/local/www/system_camanager.php | ||
---|---|---|
63 | 63 |
$act = $_REQUEST['act']; |
64 | 64 |
} |
65 | 65 |
|
66 |
if ($_POST['act'] == "del") { |
|
67 |
|
|
68 |
if (!isset($a_ca[$id])) { |
|
69 |
pfSenseHeader("system_camanager.php"); |
|
70 |
exit; |
|
71 |
} |
|
72 |
|
|
73 |
/* Only remove CA reference when deleting. It can be reconnected if a new matching CA is imported */ |
|
74 |
$index = count($a_cert) - 1; |
|
75 |
for (;$index >= 0; $index--) { |
|
76 |
if ($a_cert[$index]['caref'] == $a_ca[$id]['refid']) { |
|
77 |
unset($a_cert[$index]['caref']); |
|
78 |
} |
|
79 |
} |
|
80 |
|
|
81 |
/* Remove any CRLs for this CA, there is no way to recover the connection once the CA has been removed. */ |
|
82 |
$index = count($a_crl) - 1; |
|
83 |
for (;$index >= 0; $index--) { |
|
84 |
if ($a_crl[$index]['caref'] == $a_ca[$id]['refid']) { |
|
85 |
unset($a_crl[$index]); |
|
86 |
} |
|
87 |
} |
|
88 |
|
|
89 |
$name = $a_ca[$id]['descr']; |
|
90 |
unset($a_ca[$id]); |
|
91 |
write_config(); |
|
92 |
ca_setup_trust_store(); |
|
93 |
$savemsg = sprintf(gettext("Certificate Authority %s and its CRLs (if any) successfully deleted."), htmlspecialchars($name)); |
|
66 |
/* Actions other than 'new' require an ID. |
|
67 |
* 'del' action must be submitted via POST. */ |
|
68 |
if ((!empty($act) && |
|
69 |
($act != 'new') && |
|
70 |
!$a_ca[$id]) || |
|
71 |
(($act == 'del') && empty($_POST))) { |
|
94 | 72 |
pfSenseHeader("system_camanager.php"); |
95 | 73 |
exit; |
96 | 74 |
} |
97 | 75 |
|
98 |
if ($act == "edit") { |
|
99 |
if (!$a_ca[$id]) { |
|
100 |
pfSenseHeader("system_camanager.php"); |
|
101 |
exit; |
|
102 |
} |
|
103 |
$pconfig['method'] = 'existing'; |
|
104 |
$pconfig['descr'] = $a_ca[$id]['descr']; |
|
105 |
$pconfig['refid'] = $a_ca[$id]['refid']; |
|
106 |
$pconfig['cert'] = base64_decode($a_ca[$id]['crt']); |
|
107 |
$pconfig['serial'] = $a_ca[$id]['serial']; |
|
108 |
$pconfig['trust'] = ($a_ca[$id]['trust'] == 'enabled'); |
|
109 |
$pconfig['randomserial'] = ($a_ca[$id]['randomserial'] == 'enabled'); |
|
110 |
if (!empty($a_ca[$id]['prv'])) { |
|
111 |
$pconfig['key'] = base64_decode($a_ca[$id]['prv']); |
|
112 |
} |
|
113 |
} |
|
114 |
|
|
115 |
if ($act == "new") { |
|
116 |
$pconfig['method'] = $_POST['method']; |
|
117 |
$pconfig['keytype'] = "RSA"; |
|
118 |
$pconfig['keylen'] = "2048"; |
|
119 |
$pconfig['ecname'] = "brainpoolP256r1"; |
|
120 |
$pconfig['digest_alg'] = "sha256"; |
|
121 |
$pconfig['lifetime'] = $default_lifetime; |
|
122 |
$pconfig['dn_commonname'] = "internal-ca"; |
|
123 |
} |
|
124 |
|
|
125 |
if ($act == "exp") { |
|
126 |
|
|
127 |
if (!$a_ca[$id]) { |
|
128 |
pfSenseHeader("system_camanager.php"); |
|
129 |
exit; |
|
130 |
} |
|
131 |
|
|
132 |
$exp_name = urlencode("{$a_ca[$id]['descr']}.crt"); |
|
133 |
$exp_data = base64_decode($a_ca[$id]['crt']); |
|
134 |
$exp_size = strlen($exp_data); |
|
135 |
|
|
136 |
header("Content-Type: application/octet-stream"); |
|
137 |
header("Content-Disposition: attachment; filename={$exp_name}"); |
|
138 |
header("Content-Length: $exp_size"); |
|
139 |
echo $exp_data; |
|
140 |
exit; |
|
141 |
} |
|
142 |
|
|
143 |
if ($act == "expkey") { |
|
144 |
|
|
145 |
if (!$a_ca[$id]) { |
|
76 |
switch ($act) { |
|
77 |
case 'del': |
|
78 |
/* Only remove CA reference when deleting. It can be reconnected if a new matching CA is imported */ |
|
79 |
$index = count($a_cert) - 1; |
|
80 |
for (;$index >= 0; $index--) { |
|
81 |
if ($a_cert[$index]['caref'] == $a_ca[$id]['refid']) { |
|
82 |
unset($a_cert[$index]['caref']); |
|
83 |
} |
|
84 |
} |
|
85 |
/* Remove any CRLs for this CA, there is no way to recover the connection once the CA has been removed. */ |
|
86 |
$index = count($a_crl) - 1; |
|
87 |
for (;$index >= 0; $index--) { |
|
88 |
if ($a_crl[$index]['caref'] == $a_ca[$id]['refid']) { |
|
89 |
unset($a_crl[$index]); |
|
90 |
} |
|
91 |
} |
|
92 |
$name = $a_ca[$id]['descr']; |
|
93 |
unset($a_ca[$id]); |
|
94 |
write_config(); |
|
95 |
ca_setup_trust_store(); |
|
96 |
$savemsg = sprintf(gettext("Certificate Authority %s and its CRLs (if any) successfully deleted."), htmlspecialchars($name)); |
|
146 | 97 |
pfSenseHeader("system_camanager.php"); |
147 | 98 |
exit; |
148 |
} |
|
149 |
|
|
150 |
$exp_name = urlencode("{$a_ca[$id]['descr']}.key"); |
|
151 |
$exp_data = base64_decode($a_ca[$id]['prv']); |
|
152 |
$exp_size = strlen($exp_data); |
|
153 |
|
|
154 |
header("Content-Type: application/octet-stream"); |
|
155 |
header("Content-Disposition: attachment; filename={$exp_name}"); |
|
156 |
header("Content-Length: $exp_size"); |
|
157 |
echo $exp_data; |
|
158 |
exit; |
|
99 |
break; |
|
100 |
case 'edit': |
|
101 |
/* Editing an existing CA, so populate values. */ |
|
102 |
$pconfig['method'] = 'existing'; |
|
103 |
$pconfig['descr'] = $a_ca[$id]['descr']; |
|
104 |
$pconfig['refid'] = $a_ca[$id]['refid']; |
|
105 |
$pconfig['cert'] = base64_decode($a_ca[$id]['crt']); |
|
106 |
$pconfig['serial'] = $a_ca[$id]['serial']; |
|
107 |
$pconfig['trust'] = ($a_ca[$id]['trust'] == 'enabled'); |
|
108 |
$pconfig['randomserial'] = ($a_ca[$id]['randomserial'] == 'enabled'); |
|
109 |
if (!empty($a_ca[$id]['prv'])) { |
|
110 |
$pconfig['key'] = base64_decode($a_ca[$id]['prv']); |
|
111 |
} |
|
112 |
break; |
|
113 |
case 'new': |
|
114 |
/* New CA, so set default values */ |
|
115 |
$pconfig['method'] = $_POST['method']; |
|
116 |
$pconfig['keytype'] = "RSA"; |
|
117 |
$pconfig['keylen'] = "2048"; |
|
118 |
$pconfig['ecname'] = "brainpoolP256r1"; |
|
119 |
$pconfig['digest_alg'] = "sha256"; |
|
120 |
$pconfig['lifetime'] = $default_lifetime; |
|
121 |
$pconfig['dn_commonname'] = "internal-ca"; |
|
122 |
break; |
|
123 |
case 'exp': |
|
124 |
/* Exporting a ca */ |
|
125 |
send_user_download('data', base64_decode($a_ca[$id]['crt']), "{$a_ca[$id]['descr']}.crt"); |
|
126 |
break; |
|
127 |
case 'expkey': |
|
128 |
/* Exporting a private key */ |
|
129 |
send_user_download('data', base64_decode($a_ca[$id]['prv']), "{$a_ca[$id]['descr']}.key"); |
|
130 |
break; |
|
131 |
default: |
|
132 |
break; |
|
159 | 133 |
} |
160 | 134 |
|
161 | 135 |
if ($_POST['save']) { |
162 |
|
|
163 | 136 |
unset($input_errors); |
164 | 137 |
$input_errors = array(); |
165 | 138 |
$pconfig = $_POST; |
166 | 139 |
|
167 | 140 |
/* input validation */ |
168 |
if ($pconfig['method'] == "existing") { |
|
169 |
$reqdfields = explode(" ", "descr cert"); |
|
170 |
$reqdfieldsn = array( |
|
171 |
gettext("Descriptive name"), |
|
172 |
gettext("Certificate data")); |
|
173 |
if ($_POST['cert'] && (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE"))) { |
|
174 |
$input_errors[] = gettext("This certificate does not appear to be valid."); |
|
175 |
} |
|
176 |
if ($_POST['key'] && strstr($_POST['key'], "ENCRYPTED")) { |
|
177 |
$input_errors[] = gettext("Encrypted private keys are not yet supported."); |
|
178 |
} |
|
179 |
if (!$input_errors && !empty($_POST['key']) && cert_get_publickey($_POST['cert'], false) != cert_get_publickey($_POST['key'], false, 'prv')) { |
|
180 |
$input_errors[] = gettext("The submitted private key does not match the submitted certificate data."); |
|
181 |
} |
|
182 |
/* we must ensure the certificate is capable of acting as a CA |
|
183 |
* https://redmine.pfsense.org/issues/7885 |
|
184 |
*/ |
|
185 |
if (!$input_errors) { |
|
186 |
$purpose = cert_get_purpose($_POST['cert'], false); |
|
187 |
if ($purpose['ca'] != 'Yes') { |
|
188 |
$input_errors[] = gettext("The submitted certificate does not appear to be a Certificate Authority, import it on the Certificates tab instead."); |
|
141 |
switch ($pconfig['method']) { |
|
142 |
case 'existing': |
|
143 |
$reqdfields = explode(" ", "descr cert"); |
|
144 |
$reqdfieldsn = array( |
|
145 |
gettext("Descriptive name"), |
|
146 |
gettext("Certificate data")); |
|
147 |
if ($_POST['cert'] && (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE"))) { |
|
148 |
$input_errors[] = gettext("This certificate does not appear to be valid."); |
|
189 | 149 |
} |
190 |
} |
|
191 |
} |
|
192 |
if ($pconfig['method'] == "internal") { |
|
193 |
$reqdfields = explode(" ", |
|
194 |
"descr keylen ecname keytype lifetime dn_commonname"); |
|
195 |
$reqdfieldsn = array( |
|
196 |
gettext("Descriptive name"), |
|
197 |
gettext("Key length"), |
|
198 |
gettext("Elliptic Curve Name"), |
|
199 |
gettext("Key type"), |
|
200 |
gettext("Lifetime"), |
|
201 |
gettext("Common Name")); |
|
202 |
} |
|
203 |
if ($pconfig['method'] == "intermediate") { |
|
204 |
$reqdfields = explode(" ", |
|
205 |
"descr caref keylen ecname keytype lifetime dn_commonname"); |
|
206 |
$reqdfieldsn = array( |
|
207 |
gettext("Descriptive name"), |
|
208 |
gettext("Signing Certificate Authority"), |
|
209 |
gettext("Key length"), |
|
210 |
gettext("Elliptic Curve Name"), |
|
211 |
gettext("Key type"), |
|
212 |
gettext("Lifetime"), |
|
213 |
gettext("Common Name")); |
|
150 |
if ($_POST['key'] && strstr($_POST['key'], "ENCRYPTED")) { |
|
151 |
$input_errors[] = gettext("Encrypted private keys are not yet supported."); |
|
152 |
} |
|
153 |
if (!$input_errors && !empty($_POST['key']) && cert_get_publickey($_POST['cert'], false) != cert_get_publickey($_POST['key'], false, 'prv')) { |
|
154 |
$input_errors[] = gettext("The submitted private key does not match the submitted certificate data."); |
|
155 |
} |
|
156 |
/* we must ensure the certificate is capable of acting as a CA |
|
157 |
* https://redmine.pfsense.org/issues/7885 |
|
158 |
*/ |
|
159 |
if (!$input_errors) { |
|
160 |
$purpose = cert_get_purpose($_POST['cert'], false); |
|
161 |
if ($purpose['ca'] != 'Yes') { |
|
162 |
$input_errors[] = gettext("The submitted certificate does not appear to be a Certificate Authority, import it on the Certificates tab instead."); |
|
163 |
} |
|
164 |
} |
|
165 |
break; |
|
166 |
case 'internal': |
|
167 |
$reqdfields = explode(" ", |
|
168 |
"descr keylen ecname keytype lifetime dn_commonname"); |
|
169 |
$reqdfieldsn = array( |
|
170 |
gettext("Descriptive name"), |
|
171 |
gettext("Key length"), |
|
172 |
gettext("Elliptic Curve Name"), |
|
173 |
gettext("Key type"), |
|
174 |
gettext("Lifetime"), |
|
175 |
gettext("Common Name")); |
|
176 |
break; |
|
177 |
case 'intermediate': |
|
178 |
$reqdfields = explode(" ", |
|
179 |
"descr caref keylen ecname keytype lifetime dn_commonname"); |
|
180 |
$reqdfieldsn = array( |
|
181 |
gettext("Descriptive name"), |
|
182 |
gettext("Signing Certificate Authority"), |
|
183 |
gettext("Key length"), |
|
184 |
gettext("Elliptic Curve Name"), |
|
185 |
gettext("Key type"), |
|
186 |
gettext("Lifetime"), |
|
187 |
gettext("Common Name")); |
|
188 |
break; |
|
189 |
default: |
|
190 |
break; |
|
214 | 191 |
} |
215 | 192 |
|
216 | 193 |
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors); |
Also available in: Unified diff
CA/Cert/CRL code optimizations
While here, use the new download function when exporting items