Project

General

Profile

« Previous | Next » 

Revision 83d2b83a

Added by Jim Pingle about 8 years ago

Allow a wider range of characters to be used in certificate fields, as laid out by RFC 4514. Fixes #7540

View differences:

src/etc/inc/certs.inc
995 995
	return "";
996 996
}
997 997

  
998
function cert_escape_x509_chars($str, $reverse = false) {
999
	/* Characters which need escaped when present in x.509 fields.
1000
	 * See https://www.ietf.org/rfc/rfc4514.txt
1001
	 *
1002
	 * The backslash (\) must be listed first in these arrays!
1003
	 */
1004
	$cert_directory_string_special_chars = array('\\', '"', '#', '+', ',', ';', '<', '=', '>');
1005
	$cert_directory_string_special_chars_esc = array('\\\\', '\"', '\#', '\+', '\,', '\;', '\<', '\=', '\>');
1006
	if ($reverse) {
1007
		return str_replace($cert_directory_string_special_chars_esc, $cert_directory_string_special_chars, $str);
1008
	} else {
1009
		/* First unescape and then escape again, to prevent possible double escaping. */
1010
		return str_replace($cert_directory_string_special_chars, $cert_directory_string_special_chars_esc, cert_escape_x509_chars($str, true));
1011
	}
1012
}
1013

  
998 1014
?>
src/usr/local/www/system_camanager.php
220 220
				if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST["dn_email"])) {
221 221
					array_push($input_errors, gettext("The field 'Distinguished name Email Address' contains invalid characters."));
222 222
				}
223
			} else if ($reqdfields[$i] == 'dn_commonname') {
224
				if (preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST["dn_commonname"])) {
225
					array_push($input_errors, gettext("The field 'Distinguished name Common Name' contains invalid characters."));
226
				}
227
			} else if (($reqdfields[$i] != "descr") && preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\.\"\']/", $_POST["$reqdfields[$i]"])) {
228
				array_push($input_errors, sprintf(gettext("The field '%s' contains invalid characters."), $reqdfieldsn[$i]));
229 223
			}
230 224
		}
231 225
		if (!in_array($_POST["keylen"], $ca_keylens)) {
......
266 260
			} else if ($pconfig['method'] == "internal") {
267 261
				$dn = array(
268 262
					'countryName' => $pconfig['dn_country'],
269
					'stateOrProvinceName' => $pconfig['dn_state'],
270
					'localityName' => $pconfig['dn_city'],
271
					'organizationName' => $pconfig['dn_organization'],
272
					'emailAddress' => $pconfig['dn_email'],
273
					'commonName' => $pconfig['dn_commonname']);
263
					'stateOrProvinceName' => cert_escape_x509_chars($pconfig['dn_state']),
264
					'localityName' => cert_escape_x509_chars($pconfig['dn_city']),
265
					'organizationName' => cert_escape_x509_chars($pconfig['dn_organization']),
266
					'emailAddress' => cert_escape_x509_chars($pconfig['dn_email']),
267
					'commonName' => cert_escape_x509_chars($pconfig['dn_commonname']));
274 268
				if (!empty($pconfig['dn_organizationalunit'])) {
275
					$dn['organizationalUnitName'] = $pconfig['dn_organizationalunit'];
269
					$dn['organizationalUnitName'] = cert_escape_x509_chars($pconfig['dn_organizationalunit']);
276 270
				}
277 271
				if (!ca_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['digest_alg'])) {
278 272
					$input_errors = array();
......
285 279
			} else if ($pconfig['method'] == "intermediate") {
286 280
				$dn = array(
287 281
					'countryName' => $pconfig['dn_country'],
288
					'stateOrProvinceName' => $pconfig['dn_state'],
289
					'localityName' => $pconfig['dn_city'],
290
					'organizationName' => $pconfig['dn_organization'],
291
					'emailAddress' => $pconfig['dn_email'],
292
					'commonName' => $pconfig['dn_commonname']);
282
					'stateOrProvinceName' => cert_escape_x509_chars($pconfig['dn_state']),
283
					'localityName' => cert_escape_x509_chars($pconfig['dn_city']),
284
					'organizationName' => cert_escape_x509_chars($pconfig['dn_organization']),
285
					'emailAddress' => cert_escape_x509_chars($pconfig['dn_email']),
286
					'commonName' => cert_escape_x509_chars($pconfig['dn_commonname']));
293 287
				if (!empty($pconfig['dn_organizationalunit'])) {
294
					$dn['organizationalUnitName'] = $pconfig['dn_organizationalunit'];
288
					$dn['organizationalUnitName'] = cert_escape_x509_chars($pconfig['dn_organizationalunit']);
295 289
				}
296 290
				if (!ca_inter_create($ca, $pconfig['keylen'], $pconfig['lifetime'], $dn, $pconfig['caref'], $pconfig['digest_alg'])) {
297 291
					$input_errors = array();
......
387 381
	} else {
388 382
		$issuer_name = gettext("external");
389 383
	}
390
	$subj = htmlspecialchars($subj);
384
	$subj = htmlspecialchars(cert_escape_x509_chars($subj, true));
391 385
	$issuer = htmlspecialchars($issuer);
392 386
	$certcount = 0;
393 387

  
src/usr/local/www/system_certmanager.php
351 351
					if (preg_match("/[\!\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST[$reqdfields[$i]])) {
352 352
						array_push($input_errors, gettext("The field 'Distinguished name Email Address' contains invalid characters."));
353 353
					}
354
				} else if (preg_match('/commonname/', $reqdfields[$i])) { /* dn_commonname or csr_dn_commonname */
355
					if (preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\"\']/", $_POST[$reqdfields[$i]])) {
356
						array_push($input_errors, gettext("The field 'Distinguished name Common Name' contains invalid characters."));
357
					}
358
				} else if (($reqdfields[$i] != "descr") && preg_match("/[\!\@\#\$\%\^\(\)\~\?\>\<\&\/\\\,\.\"\']/", $_POST[$reqdfields[$i]])) {
359
					array_push($input_errors, sprintf(gettext("The field '%s' contains invalid characters."), $reqdfieldsn[$i]));
360 354
				}
361 355
			}
362 356

  
......
443 437
				if ($pconfig['method'] == "internal") {
444 438
					$dn = array(
445 439
						'countryName' => $pconfig['dn_country'],
446
						'stateOrProvinceName' => $pconfig['dn_state'],
447
						'localityName' => $pconfig['dn_city'],
448
						'organizationName' => $pconfig['dn_organization'],
449
						'emailAddress' => $pconfig['dn_email'],
450
						'commonName' => $pconfig['dn_commonname']);
440
						'stateOrProvinceName' => cert_escape_x509_chars($pconfig['dn_state']),
441
						'localityName' => cert_escape_x509_chars($pconfig['dn_city']),
442
						'organizationName' => cert_escape_x509_chars($pconfig['dn_organization']),
443
						'emailAddress' => cert_escape_x509_chars($pconfig['dn_email']),
444
						'commonName' => cert_escape_x509_chars($pconfig['dn_commonname']));
451 445
					if (!empty($pconfig['dn_organizationalunit'])) {
452
						$dn['organizationalUnitName'] = $pconfig['dn_organizationalunit'];
446
						$dn['organizationalUnitName'] = cert_escape_x509_chars($pconfig['dn_organizationalunit']);
453 447
					}
454 448
					if (is_ipaddr($pconfig['dn_commonname'])) {
455 449
						$altnames_tmp = array("IP:{$pconfig['dn_commonname']}");
......
481 475
				if ($pconfig['method'] == "external") {
482 476
					$dn = array(
483 477
						'countryName' => $pconfig['csr_dn_country'],
484
						'stateOrProvinceName' => $pconfig['csr_dn_state'],
485
						'localityName' => $pconfig['csr_dn_city'],
486
						'organizationName' => $pconfig['csr_dn_organization'],
487
						'emailAddress' => $pconfig['csr_dn_email'],
488
						'commonName' => $pconfig['csr_dn_commonname']);
478
						'stateOrProvinceName' => cert_escape_x509_chars($pconfig['csr_dn_state']),
479
						'localityName' => cert_escape_x509_chars($pconfig['csr_dn_city']),
480
						'organizationName' => cert_escape_x509_chars($pconfig['csr_dn_organization']),
481
						'emailAddress' => cert_escape_x509_chars($pconfig['csr_dn_email']),
482
						'commonName' => cert_escape_x509_chars($pconfig['csr_dn_commonname']));
489 483
					if (!empty($pconfig['csr_dn_organizationalunit'])) {
490
						$dn['organizationalUnitName'] = $pconfig['csr_dn_organizationalunit'];
484
						$dn['organizationalUnitName'] = cert_escape_x509_chars($pconfig['csr_dn_organizationalunit']);
491 485
					}
492 486
					if (count($altnames)) {
493 487
						$altnames_tmp = "";
......
1119 1113
			$caname = '<i>'. gettext("external").'</i>';
1120 1114
		}
1121 1115

  
1122
		$subj = htmlspecialchars($subj);
1116
		$subj = htmlspecialchars(cert_escape_x509_chars($subj, true));
1123 1117
	} else {
1124 1118
		$subj = "";
1125 1119
		$issuer = "";
......
1130 1124
	}
1131 1125

  
1132 1126
	if ($cert['csr']) {
1133
		$subj = htmlspecialchars(csr_get_subject($cert['csr']));
1127
		$subj = htmlspecialchars(cert_escape_x509_chars(csr_get_subject($cert['csr']), true));
1134 1128
		$sans = cert_get_sans($cert['crt']);
1135 1129
		$caname = "<em>" . gettext("external - signature pending") . "</em>";
1136 1130
	}
......
1266 1260
				$subject = cert_get_subject_array($ca['crt']);
1267 1261
?>
1268 1262
				case "<?=$ca['refid'];?>":
1269
					$('#dn_country').val("<?=$subject[0]['v'];?>");
1270
					$('#dn_state').val("<?=$subject[1]['v'];?>");
1271
					$('#dn_city').val("<?=$subject[2]['v'];?>");
1272
					$('#dn_organization').val("<?=$subject[3]['v'];?>");
1273
					$('#dn_email').val("<?=$subject[4]['v'];?>");
1274
					$('#dn_organizationalunit').val("<?=$subject[6]['v'];?>");
1263
					$('#dn_country').val(<?=json_encode(cert_escape_x509_chars($subject[0]['v'], true));?>);
1264
					$('#dn_state').val(<?=json_encode(cert_escape_x509_chars($subject[1]['v'], true));?>);
1265
					$('#dn_city').val(<?=json_encode(cert_escape_x509_chars($subject[2]['v'], true));?>);
1266
					$('#dn_organization').val(<?=json_encode(cert_escape_x509_chars($subject[3]['v'], true));?>);
1267
					$('#dn_email').val(<?=json_encode(cert_escape_x509_chars($subject[4]['v'], true));?>);
1268
					$('#dn_organizationalunit').val(<?=json_encode(cert_escape_x509_chars($subject[6]['v'], true));?>);
1275 1269
					break;
1276 1270
<?php
1277 1271
			endforeach;

Also available in: Unified diff