<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
		<meta name="description" content="Online x509 Certificate Generator. Create self-signed certificates, certificate signing requests (CSR), or a root certificate authority. Featuring support for multiple subject alternative names, multiple common names, x509 v3 extensions, RSA and elliptic curve cryptography. OpenSSL commands are shown so they can be run securely offline.">
		<meta name="keywords" content="openssl command,certificate request,online certificate request generator,certificate request creator, openssl, csr, multiple subject alternative name, multiple common name, SAN, CN, existing certificate, template, multiple domains, private key, elliptic curve cryptography, generate self-signed certificate, self-signed certificate, certificate authority, create, generate, online, tool">
		<meta name="author" content="Lyas Spiehler">
		<META NAME="ROBOTS" CONTENT="INDEX, FOLLOW">
                <link rel="apple-touch-icon" sizes="57x57" href="/images/apple-icon-57x57.png">
                <link rel="apple-touch-icon" sizes="60x60" href="/images/apple-icon-60x60.png">
                <link rel="apple-touch-icon" sizes="72x72" href="/images/apple-icon-72x72.png">
                <link rel="apple-touch-icon" sizes="76x76" href="/images/apple-icon-76x76.png">
                <link rel="apple-touch-icon" sizes="114x114" href="/images/apple-icon-114x114.png">
                <link rel="apple-touch-icon" sizes="120x120" href="/images/apple-icon-120x120.png">
                <link rel="apple-touch-icon" sizes="144x144" href="/images/apple-icon-144x144.png">
                <link rel="apple-touch-icon" sizes="152x152" href="/images/apple-icon-152x152.png">
                <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-icon-180x180.png">
                <link rel="icon" type="image/png" sizes="192x192"  href="/images/android-icon-192x192.png">
                <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png">
                <link rel="icon" type="image/png" sizes="96x96" href="/images/favicon-96x96.png">
                <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png">
		<meta property="og:title" content="CertificateTools.com">
		<meta property="og:description" content="Online x509 Certificate Generator. CertificateTools.com offers the quickest and easiest way to create self-signed certificates, certificate signing requests (CSR), or create a root certificate authority and use it to sign other x509 certificates. We support multiple subject alternative names, multiple common names, all x509 v3 extensions, RSA and elliptic curve cryptography private keys. All OpenSSL commands are shown so they can be run securely offline.">
		<meta property="og:image" content="https://certificatetools.com/images/og_certificatetools.png">
		<meta property="og:url" content="https://certificatetools.com">
		<meta property="og:site_name" content="CertificateTools.com">
		<meta property="og:locale" content="en_US">
		<meta property="og:type" content="website">
		<!--<link rel="manifest" href="/manifest.json">-->
                <meta name="msapplication-TileColor" content="#ffffff">
                <meta name="msapplication-TileImage" content="/images/ms-icon-144x144.png">
                <meta name="theme-color" content="#ffffff">
		<title>CertificateTools.com - Online X509 Certificate Generator</title>
		<script type="text/javascript" src="bower_components/jquery/dist/jquery.min.js"></script>
		<link rel="stylesheet" href="bower_components/jquery-ui/themes/base/jquery-ui.min.css">
		<script type="text/javascript" src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
		<script src="bower_components/jquery-ui/jquery-ui.min.js"></script>
		<script type="text/javascript" src="bower_components/moment/min/moment.min.js"></script>
		<script type="text/javascript" src="bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js"></script>
		<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css" />
		<link rel="stylesheet" href="bower_components/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css" />
		<style>
			body {
				padding-top: 70px;
			}
			.list-group-item {
				padding: 3px 10px;
			}
			.rightbtn {
				text-align: right;
			}
			.list-group {
				margin-bottom: 5px;
			}
			.content pre {
				white-space: -moz-pre-wrap;
				white-space: -pre-wrap;
				white-space: -o-pre-wrap;
				white-space: pre-wrap; 
				word-wrap: break-word; /* Internet Explorer 5.5+ */  
			}
		</style>
		<script>
			var hosted = {{hosted}};
		</script>
		<!-- Global site tag (gtag.js) - Google Analytics -->
		<script async src="https://www.googletagmanager.com/gtag/js?id=UA-75343349-1"></script>
		<script>
			if(hosted) {
				window.dataLayer = window.dataLayer || [];
				function gtag(){dataLayer.push(arguments);}
				gtag('js', new Date());

				gtag('config', 'UA-75343349-1');
			}
		</script>	
		<script>
			var certtemplates = {{{javascripttemplates}}}
			var downloadedcerts = {
				lastparams: '',
				certs: []
			}
			var generated = [];
			var x509obj = function() {
				this.key = {};
				this.csr = {};
				this.cert = {}
			}
			var index = {
				commonName: {
					title: 'Common Names',
					section: 'cnsection',
					list: 'commonnames',
					input: 'cninput',
					note: 'Add a common name',
					name: 'common name',
					maxlength: 64,
					defaultvalue: false,
					placeholder: 'certificatetools.com',
					multivalue: true,
					enabled: true
				},
				countryName: {
					title: 'Country',
					section: 'csection',
					list: 'country',
					input: 'cinput',
					note: 'Add a country',
					name: 'country',
					maxlength: 2,
					defaultvalue: 'US',
					placeholder: 'US',
					multivalue: false,
					enabled: true
				},
				stateOrProvinceName: {
					title: 'State',
					section: 'statesection',
					list: 'state',
					input: 'stateinput',
					note: 'Add a state',
					name: 'state',
					maxlength: 128,
					defaultvalue: false,
					placeholder: 'Louisiana',
					multivalue: false,
					enabled: true
				},
				localityName: {
					title: 'Locality',
					section: 'lsection',
					list: 'locality',
					input: 'linput',
					note: 'Add a locality',
					name: 'locality',
					maxlength: 128,
					defaultvalue: false,
					placeholder: 'Slidell',
					multivalue: false,
					enabled: true
				},
				streetAddress: {
					title: 'Street Address',
					section: 'streetsection',
					list: 'street',
					input: 'streetinput',
					note: 'Add a street address',
					name: 'street',
					maxlength: 128,
					defaultvalue: false,
					placeholder: '555 Bird Ln.',
					multivalue: false,
					enabled: false
				},
				organizationName: {
					title: 'Organization',
					section: 'orgsection',
					list: 'organization',
					input: 'orginput',
					note: 'Add an organization',
					name: 'organization',
					maxlength: 64,
					defaultvalue: false,
					placeholder: 'Acme Inc.',
					multivalue: false,
					enabled: true
				},
				organizationalUnitName: {
					title: 'Organizational Unit',
					section: 'ousection',
					list: 'ou',
					input: 'ouinput',
					note: 'Add an organizational unit',
					name: 'organizational unit',
					maxlength: 64,
					defaultvalue: false,
					placeholder: 'Information Technology',
					multivalue: false,
					enabled: false
				},
				postalCode:  {
					title: 'Postal Code',
					section: 'zipsection',
					list: 'zipcode',
					input: 'zipinput',
					note: 'Add an postal code',
					name: 'zipcode',
					maxlength: 64,
					defaultvalue: false,
					placeholder: '70458',
					multivalue: false,
					enabled: false
				},
				emailAddress: {
					title: 'Email Address',
					section: 'emailsection',
					list: 'email',
					input: 'emailinput',
					note: 'Add an email address',
					name: 'email',
					maxlength: 128,
					defaultvalue: false,
					placeholder: 'email@gmail.com',
					multivalue: false,
					enabled: false
				}
			}
			
			function delItem(type, item) {
				item.parentNode.parentNode.removeChild(item.parentNode);
				var list = document.getElementById(index[type]['list']);
				var items = list.getElementsByTagName('li');
				if(items.length == 0) {
					var li = document.createElement('li');
					var span = document.createElement('span');
					li.className = 'list-group-item';
					li.style.border = 'none';
					span.innerText = index[type]['note'];
					span.className = 'none';
					li.appendChild(span);
					list.appendChild(li);
				}
				var input = document.getElementById(index[type]['input']);
				input.value = item.parentNode.childNodes[1].innerText;
				input.select();
			}
			function selectDefaultCurve() {
				selcurve = document.getElementById('selcurve');
				for(var i = 0; i <= selcurve.options.length - 1; i++) {
					if(selcurve.options[i].value=='prime256v1') {
						selcurve.options[i].selected = true;
					}
				}
			}
			function delSAN(item) {
				item.parentNode.parentNode.removeChild(item.parentNode);
				var list = document.getElementById('sanlist');
				var items = list.getElementsByTagName('li');
				//console.log(items.length);
				if(items.length == 0) {
					var li = document.createElement('li');
					var span = document.createElement('span');
					li.className = 'list-group-item';
					li.style.border = 'none';
					span.innerText = 'Add a subject alternative name';
					span.className = 'none';
					li.appendChild(span);
					list.appendChild(li);
				}
				var typeinput = document.getElementById('typeinput');
				for(var i = 0; i <= typeinput.options.length - 1; i++) {
					if(typeinput.options[i].value==item.parentNode.childNodes[1].innerText) {
						typeinput.selectedIndex = i;
					}
				}
				var saninput = document.getElementById('saninput');
				saninput.value = item.parentNode.childNodes[3].innerText;
				saninput.select();
			}
			function processSANInput() {
				var list = document.getElementById('sanlist');
				var items = list.getElementsByTagName('li');
				var saninput = document.getElementById('saninput');
				var typeinput = document.getElementById('typeinput');
				if(saninput.value=='') {
					alert('Cannot add a blank subject alternative name.');
					saninput.select();
					return;
				}
				//console.log(items[0].childNodes);
				if(items.length == 1 && items[0].childNodes.length == 1) {
					list.removeChild(items[0]);
				} else {
					for(var i = 0; i <= items.length - 1; i++) {
						//console.log(items[i].childNodes[1].innerText);
						var current = typeinput.value + saninput.value;
						var exist = items[i].childNodes[1].innerText + items[i].childNodes[3].innerText;
						if(current==exist) {
							alert('The "' + typeinput.value + '" subject alternative name "' + saninput.value + '" has already been added');
							return;
						}
					}
				}
				addSAN(typeinput.value, saninput.value);
				saninput.select();
			}
			function addSAN(type, value) {
				var list = document.getElementById('sanlist');
				var li = document.createElement('li');
				li.className = 'list-group-item';
				li.style.border = 'none';
				var spandel = document.createElement('span');
				var spantype = document.createElement('span');
				var spandelim = document.createElement('span');
				var spanval = document.createElement('span');
				spandel.style.color = '#a31d00';
				spandel.style.fontFamily = 'Verdana';
				spandel.style.fontWeight = 'bolder';
				spandel.style.fontSize = '17px';
				//spandel.fontWeight = 'bold';
				spandel.innerText = 'X ';
				spandel.style.cursor = 'pointer';
				spandel.onclick = function(e) {
					delSAN(e.target);
				}
				spandel.addEventListener('touchstart', function(e) {
					// If there's exactly one finger inside this element
					e.preventDefault();
					delSAN(e.target);
				}, false);
				spantype.innerText = type;
				spandelim.innerText = ' : ';
				spanval.innerText = value;
				li.appendChild(spandel);
				li.appendChild(spantype);
				li.appendChild(spandelim);
				li.appendChild(spanval);
				list.appendChild(li);
			}
			
			function processItem(type) {
				var list = document.getElementById(index[type]['list']);
				var items = list.getElementsByTagName('li');
				var input = document.getElementById(index[type]['input']);
				if(input.value=='') {
					alert('Cannot add a blank ' + index[type]['name'] + '.');
					input.select();
					return;
				}
				if(items.length == 1 && items[0].childNodes.length == 1) {
					list.removeChild(items[0]);
				} else {
					for(var i = 0; i <= items.length - 1; i++) {
						//console.log(items[i].childNodes[1].innerText);
						if(input.value==items[i].childNodes[1].innerText) {
							alert('The ' + index[type]['name'] + ' "' + input.value + '" has already been added');
							return;
						}
					}
				}
				addItem(type, input.value)
				input.select();
			}
			
			function addItem(type, value) {
				var list = document.getElementById(index[type]['list']);
				var li = document.createElement('li');
				li.className = 'list-group-item';
				li.style.border = 'none';
				var spandel = document.createElement('span');
				var spancn = document.createElement('span');
				spandel.style.color = '#a31d00';
				spandel.style.fontFamily = 'Verdana';
				spandel.style.fontWeight = 'bolder';
				spandel.style.fontSize = '17px';
				spandel.innerText = 'X ';
				spandel.style.cursor = 'pointer';
				spandel.onclick = function(e) {
					delItem(type, e.target);
				}
				spandel.addEventListener('touchstart', function(e) {
					// If there's exactly one finger inside this element
					e.preventDefault();
					delItem(type, e.target);
				}, false);
				spancn.innerText = value;
				li.appendChild(spandel);
				li.appendChild(spancn);
				list.appendChild(li);
			}
			
			function addEvent(elem, param) {
				elem.addEventListener("click", function() {
					//alert(param);
					processItem(param);
				});
			}
			
			function addRemoveSubjectAttrs() {
				var addremove = document.getElementById('addremove');
				var table = document.createElement('table');
				for(var key in index) {
					var row = table.insertRow();
					var col = row.insertCell(0);
					var col2 = row.insertCell(1);
					
					var mainspanmv = document.createElement('span');
					mainspanmv.style.display = 'block';
					var titlespanmv = document.createElement('span');
					titlespanmv.innerText = ' Multi-value';
					var labelmv = document.createElement('label');
					labelmv.className = 'checkbox-inline';
					var inputmv = document.createElement('input');
					if(index[key]['multivalue']) {
						//addSubjectAttr(key, true);
						inputmv.checked = true;
					} else {
						//addSubjectAttr(key, false);
						inputmv.checked = false;
					}
					if(index[key]['enabled']) {
						inputmv.disabled = false;
					} else {
						inputmv.disabled = true;
					}
					inputmv.value = key;
					inputmv.id = key + 'mvcheck';
					inputmv.type = 'checkbox';
					inputmv.addEventListener('change', function(e) {
						if(e.target.checked) {
							//console.log('add');
							enableMultiValue(e.target.value)
						} else {
							//console.log('remove');
							disableMultiValue(e.target.value)
						}
					});
					
					labelmv.appendChild(inputmv);
					labelmv.appendChild(titlespanmv);
					mainspanmv.appendChild(labelmv);
					//mainspan.appendChild(titlespan);
					col2.appendChild(mainspanmv);
					
					var mainspan = document.createElement('span');
					mainspan.style.display = 'block';
					var titlespan = document.createElement('span');
					titlespan.innerText = ' ' + index[key]['title'];
					var label = document.createElement('label');
					label.className = 'checkbox-inline';
					var input = document.createElement('input');
					if(index[key]['enabled']) {
						addSubjectAttr(key, true);
						input.checked = true;
					} else {
						addSubjectAttr(key, false);
						input.checked = false;
					}
					input.value = key;
					input.id = key + 'check';
					input.type = 'checkbox';
					input.addEventListener('change', function(e) {
						if(e.target.checked) {
							//console.log('add');
							showSubjectAttr(e.target.value)
						} else {
							//console.log('remove');
							hideSubjectAttr(e.target.value)
						}
					});
					label.appendChild(input);
					label.appendChild(titlespan);
					mainspan.appendChild(label);
					//mainspan.appendChild(titlespan);
					col.appendChild(mainspan);
					//addremove.appendChild();
				}
				addremove.appendChild(table);
			}
			
			function enableMultiValue(key) {
				var row = document.getElementById(index[key]['name'] + 'multivaluerow');
				var button = document.getElementById(index[key]['name'] + 'multivaluebutton');
				var list = document.getElementById(index[key]['list']);
				
				row.style.display = 'block';
				button.style.display = 'block';
				list.style.display = 'block';
			}
			
			function disableMultiValue(key) {
				var row = document.getElementById(index[key]['name'] + 'multivaluerow');
				var button = document.getElementById(index[key]['name'] + 'multivaluebutton');
				var list = document.getElementById(index[key]['list']);
				
				row.style.display = 'none';
				button.style.display = 'none';
				list.style.display = 'none';
			}
			
			function hideSubjectAttr(key) {
				//var subject = document.getElementById('subject');
				var attr = document.getElementById(index[key]['section']);
				attr.style.display = 'none';
				var multicheck = document.getElementById(key + 'mvcheck');
				multicheck.disabled = true;
			}
			
			function showSubjectAttr(key) {
				//var subject = document.getElementById('subject');
				var attr = document.getElementById(index[key]['section']);
				attr.style.display = 'block';
				var multicheck = document.getElementById(key + 'mvcheck');
				multicheck.disabled = false;
			}
			
			function addSubjectAttr(key, enabled) {
				var conrow = document.createElement('div');
				conrow.id = index[key]['section']
				conrow.className = 'row';
				
				if(enabled) {
					conrow.style.display = 'block';
				} else {
					conrow.style.display = 'none';
				}
				
				var concol = document.createElement('div');
				concol.className = 'col';
				
				var row1 = document.createElement('div');
				row1.className = 'row';
				var row1col1 = document.createElement('div');
				row1col1.innerText = index[key]['title'];
				row1.appendChild(row1col1);
				
				var row2 = document.createElement('div');
				row2.className = 'row';
				
				var row2input = document.createElement('input');
				row2input.type = 'text';
				row2input.placeholder = index[key]['placeholder'];
				if(index[key]['defaultvalue']) {
					row2input.value = index[key]['defaultvalue'];
				}
				row2input.maxLength = index[key]['maxlength'];
				row2input.className = 'form-control';
				row2input.id = index[key]['input'];
				var row2col1 = document.createElement('div');
				row2col1.className = 'col-lg-10 col-lg-10 col-sm-9 col-xs-9';
				row2col1.appendChild(row2input);
				row2.appendChild(row2col1);
				
				concol.appendChild(row1);
				concol.appendChild(row2);
				
				var row3 = document.createElement('div');
				row3.id = index[key]['name'] + 'multivaluerow';
				
				var list = document.createElement('ul');
				
				var row2col2 = document.createElement('div');
				row2col2.className = 'col-lg-2 col-lg-2 col-sm-3 col-xs-3 rightbtn';
				row2col2.id = index[key]['name'] + 'multivaluebutton';
				var row2btn = document.createElement('button');
				row2btn.className = 'btn btn-primary';
				row2btn.type = 'button';
				row2btn.innerText = 'Add';
				/*row2btn.addEventListener("click", () => {
					alert(id);
					addItem(id);
				});*/
				addEvent(row2btn, key);
				
				if(index[key]['multivalue']) {
					
				} else {
					row2col2.style.display = 'none';
					row3.style.display = 'none';
					list.style.display = 'none';
				}
				
				row2col2.appendChild(row2btn);
				
//					row2.appendChild(row2col1);
				row2.appendChild(row2col2);
					
				row3.className = 'row';
				
				var row3col1 = document.createElement('div');
				row3col1.className = 'col-lg-1 col-lg-1 col-sm-1 col-xs-0';
				
				var row3col2 = document.createElement('div');
				row3col2.className = 'col-lg-11 col-lg-11 col-sm-11 col-xs-12';
				list.className = 'list-group';
				list.id = index[key]['list'];
				var item = document.createElement('li');
				item.className = 'list-group-item';
				item.style.border = 'none';
				var placeholder = document.createElement('span');
				placeholder.className = 'none';
				placeholder.innerText = index[key]['note'];
				
				item.appendChild(placeholder);
				list.appendChild(item);
				row3col2.appendChild(list);
				
				row3.appendChild(row3col2);
				concol.appendChild(row3);
				
				var subject = document.getElementById('subject');
				
				conrow.appendChild(concol);
				subject.appendChild(conrow);
			}
			function enableGenerate(enable) {
				var keysizecol = document.getElementById("keysizecol");
				if(enable) {
					keysizecol.style.display = 'block';
				} else {
					keysizecol.style.display = 'none';
				}
				keyEncrypt();
			}
			function keyEncrypt() {
				var method = document.getElementById('keymethod');
				var encryptcol = document.getElementById("encryptcol");
				if(method.value=='PKCS1' || method.value=='PKCS8' || method.value=='PKCS1ECC' || method.value=='PKCS8ECC') {
					var encryption = document.getElementById("encryption");
					encryptcol.style.display = 'block';
					toggleEncryption(encryption);
				} else {
					passwordcol.style.display = 'none';
					ciphercol.style.display = 'none';
					encryptcol.style.display = 'none';
				}
			}
			function enableGenerateECC(enable) {
				var curvescol = document.getElementById("curvescol");
				if(enable) {
					curvescol.style.display = 'block';
				} else {
					curvescol.style.display = 'none';
				}
				keyEncrypt();
			}
			function enablePaste(enable) {
				var pastedkeycol = document.getElementById("pastedkeycol");
				if(enable) {
					pastedkeycol.style.display = 'block';
				} else {
					pastedkeycol.style.display = 'none';
				}
			}
			function enableUpload(enable) {
				var uploadcol = document.getElementById("uploadcol");
				if(enable) {
					uploadcol.style.display = 'block';
				} else {
					uploadcol.style.display = 'none';
				}
			}
			function toggleEncryption(encryption) {
				var passwordcol = document.getElementById("passwordcol");
				var ciphercol = document.getElementById("ciphercol");
				if(encryption.checked) {
					passwordcol.style.display = 'block';
					ciphercol.style.display = 'block';
				} else {
					passwordcol.style.display = 'none';
					ciphercol.style.display = 'none';
				}
			}
			function togglePathLen(initial) {
				var isca = document.getElementById("isca");
				var pathlen1 = document.getElementById("pathlen1");
				var pathlen2 = document.getElementById("pathlen2");
				if(isca.options[isca.selectedIndex].value=="TRUE") {
					pathlen1.style.display = 'block';
					pathlen2.style.display = 'block';
				} else {
					pathlen1.style.display = 'none';
					pathlen2.style.display = 'none';
				}
				if(!initial) {
					$( "#basicconstraintssection" ).accordion("refresh");
				}
			}
			function changePrivateKeyMethod(method) {
				if(method.value=='PKCS1' || method.value=='PKCS8') {
					enableUpload(false);
					enablePaste(false);
					enableGenerate(true);
					enableGenerateECC(false);
				} else if(method.value=='PKCS1ECC' || method.value=='PKCS8ECC') {
					enableUpload(false);
					enablePaste(false);
					enableGenerateECC(true);
					enableGenerate(false);
				} else if(method.value=='paste') {
					enableGenerate(false);
					enableGenerateECC(false);
					enableUpload(false);
					enablePaste(true);
				} else if(method.value=='pasteecc') {
					enableGenerateECC(false);
					enableGenerate(false);
					enableUpload(false);
					enablePaste(true);
				} else if(method.value=='upload') {
					enableGenerate(false);
					enableGenerateECC(false);
					enablePaste(false);
					enableUpload(true);
				} else if(method.value=='uploadecc') {
					enableGenerateECC(false);
					enableGenerate(false);
					enablePaste(false);
					enableUpload(true);
				} else {
					alert('Unrecognized option');
				}
			}
			function getCSRParams() {
				var csr = {}
				var subject = {}
				
				//add hash algorithm
				
				var hashalg = document.getElementById('hashalg');
				csr['hash'] = hashalg.options[hashalg.selectedIndex].value;
				
				//add subject attributes
				var addsubj = false;
				for(var key in index) {
					//index[key]['list']
					//index[key]['input']
					var list = document.getElementById(index[key]['list']);
					var attr = [];
					if(list.style.display != 'none') {
						for(var i = 0; i <= list.childNodes.length - 1; i++) {
							if(list.childNodes[i].childNodes.length > 1) {
								attr.push(list.childNodes[i].childNodes[1].innerText);
								//console.log(list.childNodes[i].childNodes[1].innerText);
							}
						}
					} else {
						var input = document.getElementById(index[key]['input']);
						let enabled = document.getElementById(key + 'check');
						if(input.value != '') {
							if(enabled.checked) {
								attr.push(input.value);
							}
						}
					}
					if(attr.length > 1) {
						addsubj = true;
						subject[key] = [];
						for(var i = 0; i <= attr.length - 1; i++) {
							subject[key].push(attr[i]);
						}
					} else if(attr.length==1) {
						addsubj = true;
						subject[key] = attr[0];
					} else {
						//attr not used
					}
				}
				if(addsubj) {
					csr['subject'] = subject
				}
				if(!csr.subject.commonName) {
					var proceed = confirm('You have not added any common names. Click OK to proceed anyway or cancel to go back and add a common name.');
					if(!proceed) {
						return false;
					}
				}
				//add SANS
				var list = document.getElementById('sanlist');
				var sans = {};
				var addsan = false;
				for(var i = 0; i <= list.childNodes.length - 1; i++) {
					if(list.childNodes[i].childNodes.length > 1) {
						addsan = true;
						if(sans[list.childNodes[i].childNodes[1].innerText]) {
							sans[list.childNodes[i].childNodes[1].innerText].push(list.childNodes[i].childNodes[3].innerText);
						} else {
							sans[list.childNodes[i].childNodes[1].innerText] = [list.childNodes[i].childNodes[3].innerText];
						}
					}
				}
				if(addsan) {
					if(!csr['extensions']) {
						csr['extensions'] = {}
					}
					csr['extensions']['SANs'] = sans
				}
				if(!csr.extensions) {
					var proceed = confirm('You have not added any subject alternative names. Click OK to proceed anyway or cancel to go back and add a subject alternative name.');
					if(!proceed) {
						return false;
					}
				}
				//add key usage
				var keyusage = document.getElementsByName('keyusagevals');
				var ku = []
				for(var i = 0; i <= keyusage.length - 1; i++) {
					if(keyusage[i].checked) {
						ku.push(keyusage[i].value);
						//console.log(keyusage[i].value);
					}
				}
				if(ku.length > 0) {
					if(!csr['extensions']) {
						csr['extensions'] = {}
					}
					csr['extensions']['keyUsage'] = {
						usages: ku
					};
					var keyusagecritical = document.getElementById('keyusagecritical');
					if(keyusagecritical.checked) {
						csr['extensions']['keyUsage']['critical'] = true
					} else {
						csr['extensions']['keyUsage']['critical'] = false;
					}
				}
				
				//add extended key usage
				var extendedkeyusage = document.getElementsByName('extendedkeyusagevals');
				var ku = []
				for(var i = 0; i <= extendedkeyusage.length - 1; i++) {
					if(extendedkeyusage[i].checked) {
						ku.push(extendedkeyusage[i].value);
						//console.log(extendedkeyusage[i].value);
					}
				}
				if(ku.length > 0) {
					if(!csr['extensions']) {
						csr['extensions'] = {}
					}
					csr['extensions']['extendedKeyUsage'] = {
						usages: ku
					};
					var extendedkeyusagecritical = document.getElementById('extendedkeyusagecritical');
					if(extendedkeyusagecritical.checked) {
						csr['extensions']['extendedKeyUsage']['critical'] = true
					} else {
						csr['extensions']['extendedKeyUsage']['critical'] = false;
					}
				}
				
				//add basic constraints
				var iscainput = document.getElementById('isca');
				var isca = iscainput.options[iscainput.selectedIndex].value;
				if(isca == 'undefined') {
					// do nothing
				} else {
					if(!csr['extensions']) {
						csr['extensions'] = {}
					}
					var cavalue;
					if(isca == 'TRUE') {
						cavalue = true;
					} else {
						cavalue = false;
					}
					csr['extensions']['basicConstraints'] = {};
					csr['extensions']['basicConstraints']['CA'] = cavalue;
					var pathleninput = document.getElementById('pathlen');
					var pathlen = pathleninput.options[pathleninput.selectedIndex].value;
					if(pathlen != 'None') {
						csr['extensions']['basicConstraints']['pathlen'] = parseInt(pathlen);
					}
					var bccritical = document.getElementById('bccritical');
					if(bccritical.checked) {
						csr['extensions']['basicConstraints']['critical'] = true
					} else {
						csr['extensions']['basicConstraints']['critical'] = false;
					}
				}
				
				return csr;
			}
			
			function getKeyParams() {
				var rsakeyoptions = {};
			
				var keymethod = document.getElementById('keymethod');
				var method = keymethod.options[keymethod.selectedIndex].value
				if(method=="PKCS1" || method=="PKCS8") {
					var keysizeinput = document.getElementById('keysize');
					rsakeyoptions.rsa_keygen_bits = keysizeinput.options[keysizeinput.selectedIndex].value
				} else {
					var curve = document.getElementById('selcurve');
					rsakeyoptions.curve = curve.options[curve.selectedIndex].value
				}
				
				var encryptioninput = document.getElementById('encryption');
				if(encryption.checked) {
					rsakeyoptions.encryption = {};
					var password = document.getElementById('password').value;
					if(password == '') {
						alert('Encrypted private key password cannot be blank!');
						return false;
					}
					rsakeyoptions.encryption.password = document.getElementById('password').value;
					var cipherinput = document.getElementById('cipher');
					rsakeyoptions.encryption.cipher = cipherinput.options[cipherinput.selectedIndex].value
				}
				
				return rsakeyoptions;
			}
			
			function toggleSelfSign(elem) {
				var signcert = elem.options[elem.options.selectedIndex];
				var timetype = document.getElementById('timetypecol');
				var timelength = document.getElementById('timelengthcol');
				//var manageca = document.getElementById('managecacol');
				//var date1 = document.getElementById('date1');
				//var date2 = document.getElementById('date2');
				if(signcert.value!='nosign') {
					if(signcert.innerText[0] == '*') {
						timetype.style.display = 'none';
						timelength.style.display = 'none';
						//manageca.style.display = 'block';
						//date1.style.display = 'block';
						//date2.style.display = 'block';
						$('#datetimepicker1').datetimepicker().show();
						$('#datetimepicker1').data("DateTimePicker").date(new Date());
						$('#datetimepicker2').datetimepicker().show();
						$('#datetimepicker2').data("DateTimePicker").date(moment(new Date()).add(1, 'years'));
						//console.log($('#datetimepicker2').data("DateTimePicker").date().toDate());
					} else {
						timetype.style.display = 'block';
						timelength.style.display = 'block';
						//manageca.style.display = 'none';
						//date1.style.display = 'none';
						//date2.style.display = 'none';
						$('#datetimepicker1').datetimepicker().hide();
						$('#datetimepicker2').datetimepicker().hide();
					}
				} else {
					timetype.style.display = 'none';
					timelength.style.display = 'none';
					//manageca.style.display = 'none';
					//date1.style.display = 'none';
					//date2.style.display = 'none';
					$('#datetimepicker1').datetimepicker().hide();
					$('#datetimepicker2').datetimepicker().hide();
				}
			}
			
			function appendCAToSignList(index) {
				var signcert = document.getElementById('signcert');
				var option = document.createElement('option');
				option.innerText = 'Sign with Certificate Authority ' + index;
				option.value = index;
				signcert.add(option);
			}
			
			function checkCAAttributes(x509) {
				var isca = document.getElementById('isca');
				var iscavalue = isca.options[isca.options.selectedIndex].value
				if(iscavalue=="TRUE") {
					//appendCAToSignList(x509);
					return true;
				} else {
					return false;
				}
			}
			
			function getdays() {
				var timetypeinput = document.getElementById('timetype');
				var timetype = timetypeinput.options[timetypeinput.selectedIndex].value;
				var timelength = document.getElementById('timelength');
				var days = 365;
				if(timetype == 'day') {
					days = timelength.value;
				} else if(timetype == 'week') {
					days = timelength.value * 7;
				} else if(timetype == 'month') {
					days = timelength.value * 30;
				} else if(timetype == 'year') {
					days = timelength.value * 365;
				} else {
					//invalid time
				}
				return days;
			}
			
			function processCSR(keyresponse, x509, callback) {
				//console.log(generated);
				//var keyinput = document.getElementById('key');
				//keyinput.innerText = keyresponse.command + '\r\n\r\n' + keyresponse.key;
				var signvalue = signcert.options[signcert.options.selectedIndex].value;
				googleAnalyticsEvent('Interaction', 'Generate', 'x509', signvalue)
				var csroptions = getCSRParams();
				if(!csroptions) {
					return false;
				}
				var data = {
					options: csroptions,
					key: keyresponse.key,
					keypass: getKeyPassword(),
					sign: signvalue
				}
				openSSLRESTAPI('generateCSR', data, function(error, response) {
					if(error) {
						//console.log(error);
						alert('OpenSSL Error:\r\n\r\n' + error);
						callback(error);
						return;
					} else {
						//let index = generated.length - 1;
						//var x509 = generated[index];
						x509.csr.config = response.command.files.config;
						x509.csr.json = data;
						x509.csr.command = response.command.command;
						x509.csr.data = response.csr;
						//var csr = document.getElementById('csr');
						//csr.innerText = response.command.files.config + '\r\n\r\n' + response.command.command[0] + '\r\n\r\n' + response.csr;
						var signcert = document.getElementById('signcert');
						if(signvalue=="selfsign") {
							data.csr = response.csr;
							data.options.days = getdays();
							openSSLRESTAPI('selfSignCSR', data, function(error, response) {
								x509.cert.signingca = -1;
								x509.cert.config = response.command.files.config;
								x509.cert.json = data;
								x509.cert.command = response.command.command;
								x509.cert.data = response.crt;
								//var cer = document.getElementById('cer');
								//cer.innerText = response.command.files.config + '\r\n\r\n' + response.command.command[0] + '\r\n\r\n' + response.crt;
								x509.cert.isca = checkCAAttributes(x509);
								generated.push(x509);
								var certindex = generated.length - 1;
								if(x509.cert.isca) {
									appendCAToSignList(certindex);
								}
								callback(false, x509, certindex);
							});
						} else if(signvalue=='nosign') {
							x509.cert = false;
							generated.push(x509);
							callback(false, x509, generated.length - 1);
						} else {
							//data.csr = response.csr;
							data.csr = response.csr;
							if($('#datetimepicker1').data("DateTimePicker").date()) {
								data.options.startdate = $('#datetimepicker1').data("DateTimePicker").date().toDate();
								data.options.enddate = $('#datetimepicker2').data("DateTimePicker").date().toDate();
							} else {
								data.options.days = getdays();
							}
							data.options.days = getdays();
							//console.log(parseInt(signvalue));
							if(x509.ca) {
								data.ca = {}
								data.ca.path = x509.ca.path;
								data.ca.keypass = x509.ca.keypass;
								x509.cert.signingca = -1;
							} else {
								var certindex = parseInt(signvalue);
								x509.cert.signingca = certindex;
								var capassword = false;
								if(generated[certindex].key.generated) {
									if(generated[certindex].key.encryption) {
										capassword = generated[certindex].key.encryption.password;
									}
								} else {
									if(generated[certindex].key.password) {
										capassword = generated[certindex].key.password;
									}
								}
								data.ca = {}
								data.ca.key = generated[certindex].key.data;
								data.ca.keypass = capassword;
								data.ca.cert = generated[certindex].cert.data
							}
							openSSLRESTAPI('CASignCSR', data, function(err, response) {
								if(err) {
									console.log(response);
								} else {
									x509.cert.config = response.command.files.config;
									x509.cert.json = data;
									x509.cert.command = response.command.command;
									x509.cert.data = response.crt;
									if(response.cacrt) {
										x509.ca.data = response.cacrt;
										x509.ca.keypass = null;
									}
									//var cer = document.getElementById('cer');
									//cer.innerText = response.command.files.config + '\r\n\r\n' + response.command.command[0] + '\r\n\r\n' + response.crt;
									x509.cert.isca = checkCAAttributes(x509);
									generated.push(x509);
									var certindex = generated.length - 1;
									if(x509.cert.isca) {
										appendCAToSignList(certindex);
									}
									callback(false, x509, certindex);
									}
							});
						}
					}
				});
			}
			
			function checkCAPassword(data, callback) {
				var request = new XMLHttpRequest();
				request.open('POST', 'api/openssl/checkCAKey', true);
				request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
				
				request.onload = function() {
					if (request.status >= 200 && request.status < 400) {
						// Success!
						var resp = JSON.parse(request.responseText);
						callback(resp);
						return;
						//var key = document.getElementById('key');
						//key.innerText = resp.command + '\r\n\r\n' + resp.key;
						//var csroptions = getCSRParams();
						//generateCSR(resp.key, csroptions);
					} else {
						// We reached our target server, but it returned an error
						callback(false);
						return;
					}
				};

				request.onerror = function() {
					callback(false);
					return;
					// There was a connection error of some sort
				};

				request.send(JSON.stringify(data));
			}
			
			function processForm() {
				$( "#capassword" ).dialog("close");
				var signcert = document.getElementById('signcert');
				//console.log(signcert.options[signcert.selectedIndex].value[0]);
				if(signcert.options[signcert.selectedIndex].innerText[0] == '*') {
					if(!$('#datetimepicker1').data("DateTimePicker").date() || !$('#datetimepicker2').data("DateTimePicker").date()) {
						alert("You must specify a valid start and end date for the certificate.");
						return false;
					}
					var data = {
						ca: signcert.options[signcert.selectedIndex].value.replace('* '),
						password: document.getElementById('capasswordinput').value
					}
					checkCAPassword(data, function(result) {
						if(result) {
							$( "#capassword" ).dialog("close");
							var x509 = new x509obj();
							x509.ca = {};
							x509.ca.keypass = document.getElementById('capasswordinput').value;
							x509.ca.path = result.path;
							document.getElementById('capasswordinput').value = '';
							processFormNext(x509);
						} else {
							$( "#capassword" ).dialog("open");
						}
					});
					return false;
				} else {
					var x509 = new x509obj();
					processFormNext(x509);
				}
			}
			
			function processFormNext(x509) {
				$( "#dialog" ).dialog("close");
				var keymethodinput = document.getElementById('keymethod');
				var keymethod = keymethodinput.options[keymethodinput.selectedIndex].value
				//var x509 = new x509obj();
				//x509.key.generated = false;
				if(keymethod=='PKCS1' || keymethod=='PKCS8') {
					var keyoptions = getKeyParams();
					if(!keyoptions) {
						return false;
					}
					x509.key = keyoptions;
					x509.key.format = keymethod;
					keyoptions.format = keymethod;
					openSSLRESTAPI('generateRSAPrivateKey', keyoptions, function(err, response) {
						if(err) {
							console.log(response);
						} else {
							x509.key.generated = true;
							x509.key.command = response.command;
							x509.key.data = response.key;
							//generated.push(x509);
							processCSR(response, x509, function(err, x509, index) {
								processCompleted(err, x509, index);
							});
						}
					});
				} else if(keymethod=='PKCS1ECC' || keymethod=='PKCS8ECC') {
					var keyoptions = getKeyParams();
					if(!keyoptions) {
						return false;
					}
					x509.key = keyoptions;
					x509.key.format = keymethod.replace('ECC','');
					keyoptions.format = keymethod.replace('ECC','');
					openSSLRESTAPI('generateECCPrivateKey', keyoptions, function(err, response) {
						if(err) {
							console.log(response);
						} else {
							console.log(response);
							x509.key.generated = true;
							x509.key.command = response.command;
							x509.key.data = response.key;
							//generated.push(x509);
							processCSR(response, x509, function(err, x509, index) {
								processCompleted(err, x509, index);
							});
						}
					});
				} else if(keymethod=='paste' || keymethod=='pasteecc') {
					x509.key.generated = false;
					var pastedkey = document.getElementById('pastedkey');
					var passwordprompt = document.getElementById('passwordprompt');
					var password = false;
					if(passwordprompt.value=='') {
						if(pastedkey.value.indexOf('ENCRYPTED') >= 0) {
							$( "#dialog" ).dialog("open");
							return;
						}
					} else {
						password = passwordprompt.value;
					}
					var data = {
						key: pastedkey.value,
						password: password
					}
					pasteKey(keymethod, data, function(err, response) {
						if(err) {
							console.log(err);
							$( "#dialog" ).dialog("open");
						} else {
							//x509.key.data = response.key;
							x509.key.data = pastedkey.value;
							x509.key.password = password;
							//generated.push(x509);
							var keydata = {
								command: false,
								key: pastedkey.value
							}
							processCSR(keydata, x509, function(err, x509, index) {
								processCompleted(err, x509, index);
							});
						}
					});
				} else if(keymethod=='upload' || keymethod=='uploadecc') {
					x509.key.generated = false;
					var passwordprompt = document.getElementById('passwordprompt');
					var password = false;
					if(passwordprompt.value!='') {
						password = passwordprompt.value;
					}
					uploadKey(keymethod, password, function(err, response) {
						if(err) {
							$( "#dialog" ).dialog("open");
						} else {
							x509.key.data = response.key;
							x509.key.password = password;
							//generated.push(x509);
							var keydata = {
								command: false,
								key: response.key
							}
							processCSR(keydata, x509, function(err, x509, index) {
								processCompleted(err, x509, index);
							});
						}
					});
				} else {
					alert('Unrecognized private key method');
				}
			}
			function downloadText(text, filename, type) {
				//alert(text);
				googleAnalyticsEvent('Interaction', 'Download', type, '')
				var form = document.getElementById('downloadtext');
				form.action = 'api/openssl/returnDownload';
				form.method = 'POST';
				var datainput = document.createElement('textarea');
				datainput.name = "data"
				datainput.innerHTML = text;
				datainput.style.display = "none";
				var filenameinput = document.createElement('input');
				filenameinput.name = "filename"
				filenameinput.value = filename;
				filenameinput.type = "hidden";
				form.appendChild(datainput);
				form.appendChild(filenameinput);
				form.submit();
				
				form.removeChild(datainput);
				form.removeChild(filenameinput);
			}
			
			function nameCA(index) {
				var caindex = document.getElementById('caindex');
				caindex.value = index;
				var caname = document.getElementById('caname');
				if(generated[index].csr.json.options.subject.commonName) {
					if(typeof(generated[index].csr.json.options.subject.commonName)=='string') {
						caname.value = generated[index].csr.json.options.subject.commonName;
					} else {
						caname.value = generated[index].csr.json.options.subject.commonName[0];
					}
				}
				$( "#saveca" ).dialog( "open" );
			}
			
			function saveCA() {
				var caindex = document.getElementById('caindex');
				
				var chain = true;
				var certindex = caindex.value;
				var loop = 0;
				var cert;
				var cachain = [];
				while(chain) {
					//var cert = document.createElement('textarea');
					//cert.name = "data" + certindex
					//cert.innerHTML = generated[certindex].cert.data;
					//cert.style.display = "none";
					//remove.push(cert);
					//form.appendChild(cert);
					if(generated[certindex].cert.signingca < 0) {
						chain = false;
					} else {
						certindex = generated[certindex].cert.signingca;
					}
					if(loop==0) {
						cert = generated[certindex].cert.data;
					} else {
						cachain.push(generated[certindex].cert.data);
					}
					loop++;
				}
				
				if(generated[caindex.value].ca) {
					/*var cert = document.createElement('textarea');
					cert.name = "dataca"
					cert.innerHTML = generated[index].ca.data;
					cert.style.display = "none";
					remove.push(cert);
					form.appendChild(cert);*/
					cachain.push(generated[certindex].ca.data);
				}
				//console.log(generated[certindex].key.data);
				//console.log(cert);
				let rootchain;
				if(cachain.length > 0) {
					rootchain = cachain.join('');
				} else {
					rootchain = false;
				}
				var caname = document.getElementById('caname');
				fileName = caname.value.replace(/[^A-Za-z0-9\- ]/g, "");
				let keypass = false;
				if(generated[certindex].key.encryption) {
					keypass = generated[certindex].key.encryption.password;
				}
				var data = {
					name: fileName,
					key: generated[certindex].key.data,
					keypass: keypass,
					cert: cert,
					chain: rootchain
				}
				openSSLRESTAPI('saveCA', data, function(error, response) {
					if(error) {
						alert('This name already exists on the server.');
					} else {
						$( "#saveca" ).dialog( "close" );
						updateCAName(caindex.value, data);
					}
				});
			}
			
			function updateCAName(index, data) {
				var signcert = document.getElementById('signcert');
				console.log(signcert.options);
				for(var i = 0; i <= signcert.options.length - 1; i++) {
					console.log(index);
					if(signcert.options[i].value==index) {
						//console.log('match');
						signcert.options[i].value = data.name;
						signcert.options[i].innerText = '* ' + data.name;
					}
				}
			}
			
			function downloadPKCS7(index) {
				//alert(text);
				googleAnalyticsEvent('Interaction', 'Download', 'PKCS7', '')
				var form = document.getElementById('downloadtext');
				form.action = 'api/openssl/downloadPKCS7';
				form.method = 'POST';
				//var x5090 = generated[index].cert.data;
				//var cert0 = document.createElement('textarea');
				//cert0.name = "data0"
				//cert0.innerHTML = x5090;
				//cert0.style.display = "none";
				var chain = true;
				var certindex = index;
				var remove = [];
				while(chain) {
					var cert = document.createElement('textarea');
					cert.name = "data" + certindex
					cert.innerHTML = generated[certindex].cert.data;
					cert.style.display = "none";
					remove.push(cert);
					form.appendChild(cert);
					if(generated[certindex].cert.signingca < 0) {
						chain = false;
					} else {
						certindex = generated[certindex].cert.signingca;
					}
				}
				
				if(generated[index].ca) {
					var cert = document.createElement('textarea');
					cert.name = "dataca"
					cert.innerHTML = generated[index].ca.data;
					cert.style.display = "none";
					remove.push(cert);
					form.appendChild(cert);
				}
				
				form.submit();
				
				for(var i = 0; i <= remove.length - 1; i++) {
					form.removeChild(remove[i]);
				}
			}
			
			function downloadPFX(index, password) {
				//alert(text);
				googleAnalyticsEvent('Interaction', 'Download', 'PKCS12', '')
				$( "#pkcs12dialog" ).dialog( "close" );
				var form = document.getElementById('downloadtext');
				form.action = 'api/openssl/downloadPFX';
				form.method = 'POST';
				var certinput = document.createElement('textarea');
				certinput.name = "crt"
				certinput.innerHTML = generated[index].cert.data;
				certinput.style.display = "none";
				var keyinput = document.createElement('textarea');
				keyinput.name = "key"
				keyinput.innerHTML = generated[index].key.data;
				keyinput.style.display = "none";
				var passin = document.createElement('input');
				passin.name = "passin"
				if(generated[index].key.generated) {
					if(generated[index].key.encryption) {
						passin.value = generated[index].key.encryption.password;
					} else {
						passin.value = '';
					}
				} else {
					if(generated[index].key.password) {
						passin.value = generated[index].key.password;
					} else {
						passin.value = '';
					}
				}
				var passout = document.createElement('input');
				passout.name = "passout"
				passout.type = "hidden";
				if(password) {
					var password = document.getElementById('pkcs12password');
					passout.value = password.value;
					password.value = '';
				} else {
					passout.value = '';
				}
				passin.type = "hidden";
				form.appendChild(certinput);
				form.appendChild(keyinput);
				form.appendChild(passin);
				form.appendChild(passout);
				form.submit();
				
				form.removeChild(certinput);
				form.removeChild(keyinput);
				form.removeChild(passin);
				form.removeChild(passout);
			}
			
			function getCommands(x509, index) {
				var commandoutput = [];
				if(x509.key.command) {
					commandoutput.push('#generate the RSA private key');
					commandoutput.push(x509.key.command[0]);
					if(x509.key.command.length > 1) {
						commandoutput.push('');
						commandoutput.push('#Convert the private key to PKCS#1');
						commandoutput.push(x509.key.command[1]);
					}
					commandoutput.push('');
				}
				commandoutput.push('#Create the CSR (Click csrconfig.txt in the command below to download config)');
				commandoutput.push(x509.csr.command[0].replace('csrconfig.txt', '<a href="javascript: downloadText(generated[' + index + '].csr.config, \'csrconfig.txt\', \'csrconfig\');">csrconfig.txt</a>'));
				if(x509.cert) {
					commandoutput.push('');
					if(x509.cert.signingca >= 0) {
						commandoutput.push('#Sign your CSR with a root CA cert. You will need to download the CA certs your previously generated. (Click certconfig.txt in the command below to download config)');
					} else {
						commandoutput.push('#Self-sign your CSR (Click certconfig.txt in the command below to download config)');
					}
					commandoutput.push(x509.cert.command[0].replace('certconfig.txt', '<a href="javascript: downloadText(generated[' + index + '].cert.config, \'certconfig.txt\', \'certconfig\');">certconfig.txt</a>'));
				}
				//console.log(commandoutput)
				return commandoutput.join('\r\n')
			}
			function returnDownloadLinks(x509, index) {
				var div = document.createElement('div');
				var keydownload = document.createElement('a');
				keydownload.href = 'javascript: downloadText(generated[' + index + '].key.data, \'cert.key\', \'key\');';
				keydownload.innerText = 'Private Key';
				
				var csrdownload = document.createElement('a');
				csrdownload.href = 'javascript: downloadText(generated[' + index + '].csr.data, \'cert.csr\', \'csr\');';
				csrdownload.innerText = 'Certificate Signing Request';
				
				div.appendChild(keydownload);
				div.appendChild(document.createElement('br'));
				div.appendChild(csrdownload);
				
				if(x509.cert) {
					var certdownload = document.createElement('a');
					certdownload.href = 'javascript: downloadText(generated[' + index + '].cert.data, \'cert.crt\', \'cert\');';
					certdownload.innerText = 'PEM Certificate';
					div.appendChild(document.createElement('br'));
					div.appendChild(certdownload);
					
					var pfxdownload = document.createElement('a');
					pfxdownload.href = 'javascript: pfxPasswordPrompt(' + index + ');';
					pfxdownload.innerText = 'PKCS#12 Certificate and Key';
					div.appendChild(document.createElement('br'));
					div.appendChild(pfxdownload);
					
					var pkcs7download = document.createElement('a');
					pkcs7download.href = 'javascript: downloadPKCS7(' + index + ');';
					pkcs7download.innerText = 'PKCS#7 Certificate(s)';
					div.appendChild(document.createElement('br'));
					div.appendChild(pkcs7download);
					
					if(x509.cert.isca) {
						var saveca = document.createElement('a');
						saveca.href = 'javascript: nameCA(' + index + ');';
						saveca.innerText = 'Make this CA Persistent';
						saveca.title = 'This will save a copy of the CA on the server so you can sign more certificates with it later.';
						div.appendChild(document.createElement('br'));
						div.appendChild(document.createElement('br'));
						div.appendChild(saveca);
					}
				}
				
				return div;
			}
			
			function pfxPasswordPrompt(index) {
				var submit = document.getElementById('pkcs12submit');
				var cancel = document.getElementById('pkcs12cancel');
				submit.onclick = function() {
					downloadPFX(index, true);
				}
				cancel.onclick = function() {
					downloadPFX(index, false);
				}
				$( "#pkcs12dialog" ).dialog( "open" );
			}
			
			function x509Accordion(x509, index, active) {
				var x509body = document.createElement('div');
				x509body.className = 'accordion';
				//var keydiv = document.createElement('div');
				let downloadtitle = document.createElement('h3');
				downloadtitle.innerText = 'Download';
				let downloadbody = document.createElement('div');
				downloadbody.appendChild(returnDownloadLinks(x509, index));
				let keytitle = document.createElement('h3');
				keytitle.innerText = 'Private Key';
				let keybody = document.createElement('div');
				keybody.appendChild(x509Text(x509.key.data));
				let csrtitle = document.createElement('h3');
				csrtitle.innerText = 'Certificate Signing Request';
				let csrbody = document.createElement('div');
				csrbody.appendChild(x509Text(x509.csr.data));
				let csrconfigtitle = document.createElement('h3');
				csrconfigtitle.innerText = 'OpenSSL CSR Config';
				let csrconfigbody = document.createElement('div');
				csrconfigbody.appendChild(x509Text(x509.csr.config));
				let opensslcommandtitle = document.createElement('h3');
				opensslcommandtitle.innerText = 'OpenSSL Commands';
				let opensslcommandbody = document.createElement('div');
				opensslcommandbody.appendChild(x509Text(getCommands(x509, index)));
				//keydiv.appendChild(keytitle);
				//keydiv.appendChild(keybody);
				x509body.appendChild(downloadtitle);
				x509body.appendChild(downloadbody);
				x509body.appendChild(keytitle);
				x509body.appendChild(keybody);
				x509body.appendChild(opensslcommandtitle);
				x509body.appendChild(opensslcommandbody);
				x509body.appendChild(csrtitle);
				x509body.appendChild(csrbody);
				x509body.appendChild(csrconfigtitle);
				x509body.appendChild(csrconfigbody);
				if(x509.cert) {
					let certtitle = document.createElement('h3');
					certtitle.innerText = 'Certificate';
					let certbody = document.createElement('div');
					certbody.appendChild(x509Text(x509.cert.data));
					let certconfigtitle = document.createElement('h3');
					certconfigtitle.innerText = 'OpenSSL Certificate Config';
					let certconfigbody = document.createElement('div');
					certconfigbody.appendChild(x509Text(x509.cert.config));
					x509body.appendChild(certtitle);
					x509body.appendChild(certbody);
					x509body.appendChild(certconfigtitle);
					x509body.appendChild(certconfigbody);
				}
				//getCommands(x509, index);
				
				$( x509body ).accordion({
					collapsible: true,
					active: active,
					heightStyle: 'content'
				});
				
				return x509body;
			}
			function x509Text(text) {
				var xtext = document.createElement('pre');
				xtext.innerHTML = text;
				return xtext;
			}
			function processCompleted(err, x509, index) {
				if(err) {
					
				} else {
					var output = document.getElementById('output');
					let active = 0;
					if(output.childNodes.length <= 0) {
						var accordiondiv = document.createElement('div');
						accordiondiv.id = 'accordionoutput';
						let title = document.createElement('h3');
						if(x509.cert) {
							if(x509.cert.isca) {
								title.innerText = 'Certificate Authority ' + index;
							} else {
								title.innerText = 'Certificate ' + index;
							}
						} else {
							active = 3;
							title.innerText = 'Certificate Signing Request ' + index;
						}
						let body = document.createElement('div');
						let csr = x509Accordion(x509, index, active);
						body.appendChild(csr);
						accordiondiv.appendChild(title);
						accordiondiv.appendChild(body);
						output.appendChild(accordiondiv);
						/*$( csr ).accordion({
							collapsible: true,
							active: 0,
							heightStyle: 'content'
						});*/
						/*$( '.accordion' ).accordion({
							collapsible: true,
							active: false,
							//autoHeight:false
						});*/
						$( accordiondiv ).accordion({
							collapsible: true,
							active: 0,
							heightStyle: 'content'
							//autoHeight:false
						});
					} else {
						$( '#accordionoutput' ).accordion();
						if(x509.cert) {
							if(x509.cert.isca) {
								$( "<h3>Certificate Authority " + index + "</h3>" ).appendTo( "#accordionoutput" );
							} else {
								$( "<h3>Certificate " + index + "</h3>" ).appendTo( "#accordionoutput" );
							}
						} else {
							$( "<h3>Certificate Signing Request " + index + "</h3>" ).appendTo( "#accordionoutput" );
							active = 3;
						}
						$( x509Accordion(x509, index, active) ).appendTo( "#accordionoutput" );
						//$( "<div>" + x509.key.data + "</div>" ).appendTo( "#accordionoutput" );
						$( "#accordionoutput" ).accordion( "refresh" );
						$( "#accordionoutput" ).accordion( "option", "active", -1 );
					}
					//console.log(x509);
					//alert('submission complete');
				}
			}
			function uploadKey(type, pass, callback) {
				var formData = new FormData(),
					file = document.getElementById('uploadedkey').files[0],
					password = pass,
					request = new XMLHttpRequest();
				
				formData.append('file', file);
				formData.append('password', password);
				if(type=="uploadecc") {
					request.open('POST', 'api/openssl/uploadECCPrivateKey', true);
				} else {
					request.open('POST', 'api/openssl/uploadPrivateKey', true);
				}
				//request.setRequestHeader('Content-Disposition', 'attachment; filename="' + file + '"');
				//request.setRequestHeader('Content-Type', file.type);
				//request.setRequestHeader('Content-Type', 'multipart/form-data; charset=UTF-8');
				
				request.onload = function() {
					if (request.status >= 200 && request.status < 400) {
						// Success!
						var resp = JSON.parse(request.responseText);
						//console.log();
						if(resp.error) {
							callback(resp.error, resp);
						} else {
							callback(false, resp);
						}
					} else {
						callback(request.responseText, false);
						//console.log("Error " + request.status + " occurred uploading your file.", request);
						return;
					}
				};

				request.onerror = function() {
					//console.log("Error " + request.status + " occurred uploading your file.", request);
					callback(true, false);
					return;
				};
				
				request.send(formData);
			}
			
			function getKeyPassword() {
				var keymethodinput = document.getElementById('keymethod');
				var keymethod = keymethodinput.options[keymethodinput.selectedIndex].value
				var password;
				if(keymethod=='PKCS1' || keymethod=='PKCS8' || keymethod=='PKCS1ECC' || keymethod=='PKCS8ECC') {
					password = document.getElementById('password').value;
				} else {
					password = document.getElementById('passwordprompt').value;
				}
				if(password == '') {
					return false;
				} else {
					return password;
				}
			}
			
			function pasteKey(type, data, callback) {
				//console.log(data);
				var request = new XMLHttpRequest();
				if(type=="pasteecc") {
					request.open('POST', 'api/openssl/pasteECCKey', true);
				} else {
					request.open('POST', 'api/openssl/pasteKey', true);
				}
				request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
				
				request.onload = function() {
					if (request.status >= 200 && request.status < 400) {
						// Success!
						var resp = JSON.parse(request.responseText);
						if(resp.error) {
							callback(resp.error, resp);
						} else {
							callback(false, resp);
						}
					} else {
						callback(request.responseText, false);
						return;
					}
				};

				request.onerror = function() {
					callback(true, false);
					return;
				};

				request.send(JSON.stringify(data));
			}
			
			function populateSubject() {
				ipAPI(function(err, data) {
					if(err) {
						console.log(err);
					} else {
						console.log(data);
						var country = document.getElementById('cinput');
						var state = document.getElementById('stateinput');
						var city = document.getElementById('linput');
						var zipcode = document.getElementById('zipinput');
						country.value = data.country;
						state.value = data.region;
						city.value = data.city;
						zipcode.value = data.postal;
					}
				});
			}
			
			function ipAPI(callback) {
				var request = new XMLHttpRequest();
				request.open('GET', 'https://ipapi.co//json/', true);
				request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
				
				request.onload = function() {
					if (request.status >= 200 && request.status < 400) {
						// Success!
						var resp = JSON.parse(request.responseText);
						if(resp.reserved) {
							callback(resp, resp);
						} else {
							callback(false, resp);
						}
						return;
						//var key = document.getElementById('key');
						//key.innerText = resp.command + '\r\n\r\n' + resp.key;
						//var csroptions = getCSRParams();
						//generateCSR(resp.key, csroptions);
					} else {
						// We reached our target server, but it returned an error
						callback(resp, false);
						return;
					}
				};

				request.onerror = function() {
					callback(true, false);
					return;
					// There was a connection error of some sort
				};

				request.send();
			}
			
			function listCAs() {
				getCAs(function(err, resp) {
					if(err) {
						console.log(err);
					} else {
						let cas = document.getElementById('signcert');
						for(var i = 0; i <= resp.length - 1; i++) {
							let option = document.createElement('option');
							option.value = resp[i];
							option.innerText = '* ' + resp[i];
							cas.add(option);
						}
						//console.log(resp);
					}
				});
			}
			
			function getCAs(callback) {
				var request = new XMLHttpRequest();
				request.open('GET', 'api/openssl/getCAs', true);
				request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
				
				request.onload = function() {
					if (request.status >= 200 && request.status < 400) {
						// Success!
						var resp = JSON.parse(request.responseText);
						if(resp.reserved) {
							callback(resp, resp);
						} else {
							callback(false, resp);
						}
						return;
						//var key = document.getElementById('key');
						//key.innerText = resp.command + '\r\n\r\n' + resp.key;
						//var csroptions = getCSRParams();
						//generateCSR(resp.key, csroptions);
					} else {
						// We reached our target server, but it returned an error
						callback(resp, false);
						return;
					}
				};

				request.onerror = function() {
					callback(true, false);
					return;
					// There was a connection error of some sort
				};

				request.send();
			}
			
			function openSSLRESTAPI(api, data, callback) {
				var request = new XMLHttpRequest();
				request.open('POST', 'api/openssl/' + api, true);
				request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
				
				request.onload = function() {
					if (request.status >= 200 && request.status < 400) {
						// Success!
						var resp = JSON.parse(request.responseText);
						if(resp.error) {
							callback(resp.error, resp);
						} else {
							callback(false, resp);
						}
						return;
						//var key = document.getElementById('key');
						//key.innerText = resp.command + '\r\n\r\n' + resp.key;
						//var csroptions = getCSRParams();
						//generateCSR(resp.key, csroptions);
					} else {
						// We reached our target server, but it returned an error
						callback(resp, false);
						return;
					}
				};

				request.onerror = function() {
					callback(true, false);
					return;
					// There was a connection error of some sort
				};

				request.send(JSON.stringify(data));
			}
			function templateMethod(elem) {
				var method = elem.options[elem.selectedIndex].value;
				var ssltlsinput = document.getElementById('ssltls');
				var starttlsinput = document.getElementById('starttls');
				var protocolcontain = document.getElementById('protocolcontain');
				var hostcontain = document.getElementById('hostcontain');
				var portcontain = document.getElementById('portcontain');
				var delimcontain = document.getElementById('delimcontain');
				var pastecontain = document.getElementById('pastecontain');
				if(method=='ssltls') {
					pastecontain.style.display = 'none';
					delimcontain.style.display = 'block';
					protocolcontain.style.display = 'block';
					hostcontain.style.display = 'block';
					portcontain.style.display = 'block';
					ssltlsinput.style.display = 'inline';
					starttlsinput.style.display = 'none';
					changeProtocol(ssltlsinput);
				} else if(method=='starttls') {
					pastecontain.style.display = 'none';
					delimcontain.style.display = 'block';
					protocolcontain.style.display = 'block';
					hostcontain.style.display = 'block';
					portcontain.style.display = 'block';
					ssltlsinput.style.display = 'none';
					starttlsinput.style.display = 'inline';
					changeProtocol(starttlsinput);
				} else {
					delimcontain.style.display = 'none';
					pastecontain.style.display = 'block';
					protocolcontain.style.display = 'none';
					hostcontain.style.display = 'none';
					portcontain.style.display = 'none';
				}
			}
			function changeProtocol(elem) {
				var protocol = elem.options[elem.selectedIndex].value;
				var port = document.getElementById('port');
				if(protocol=='https') {
					port.value = '443';
					port.readOnly = true;
				} else if(protocol=='smtps') {
					port.value = '465';
					port.readOnly = true;
				} else if(protocol=='pop3s') {
					port.value = '995';
					port.readOnly = true;
				} else if(protocol=='imaps') {
					port.value = '993';
					port.readOnly = true;
				} else if(protocol=='ftps') {
					port.value = '990';
					port.readOnly = true;
				} else if(protocol=='ldaps') {
					port.value = '636';
					port.readOnly = true;
				} else if(protocol=='smtp') {
					port.readOnly = false;
					port.focus();
					port.value = '25';
				} else {
					port.readOnly = false;
					port.value = '';
					port.focus();
				}
			}
			
			function showDownloadedCerts(certs) {
				if(certs) {
					var downloadedcerts = document.getElementById('downloadedcerts');
					for(var i = downloadedcerts.options.length - 1; i >= 0; i--) {
						downloadedcerts.remove(i);
					}
					for(var i = 0; i <= certs.length - 1; i++) {
						var option = document.createElement('option');
						option.value = i;
						if(certs[i].options.subject.commonName) {
							if(typeof(certs[i].options.subject.commonName)=='object') {
								option.innerText = certs[i].options.subject.commonName[0];
							} else {
								option.innerText = certs[i].options.subject.commonName
							}
						} else {
							option.innerText = 'Certificate' + i;
						}
						downloadedcerts.add(option);
					}
				}
				$( "#choosecert" ).dialog("open");
			}
			
			function getSelectedCert() {
				var downloadedcert = document.getElementById('downloadedcerts');
				var cert = downloadedcert.options[downloadedcert.selectedIndex].value;
				processImportedCert(downloadedcerts.certs[cert].options);
			}
			
			function importCert() {
				var netcertoptions = {};
				googleAnalyticsEvent('Interaction', 'Import', 'x509')
				var methodinput = document.getElementById('templatemethod');
				var method = methodinput.options[methodinput.selectedIndex].value;
				if(method != 'paste') {
					var protocolinput = document.getElementById(method);
					var protocol = protocolinput.options[protocolinput.selectedIndex].value;
					var hostname = document.getElementById('hostname');
					var port = document.getElementById('port');
					netcertoptions.hostname = hostname.value;
					netcertoptions.port = parseInt(port.value);
					if(method=='starttls') {
						netcertoptions.starttls = true;
					} else {
						netcertoptions.starttls = false;
					}
					netcertoptions.protocol = protocol;
					if(downloadedcerts.lastparams == JSON.stringify(netcertoptions)) {
						$( "#template" ).dialog("close");
						if(downloadedcerts.certs.length == 1 ) {
							processImportedCert(downloadedcerts.certs[0].options);
						} else {
							showDownloadedCerts(false);
						}
					} else {
						openSSLRESTAPI('getCertFromNetwork', netcertoptions, function(error, response) {
							if(error) {
								alert(error);
							} else {
								$( "#template" ).dialog("close");
								//console.log(response);
								downloadedcerts.certs.length = 0;
								downloadedcerts.lastparams = JSON.stringify(netcertoptions);
								downloadedcerts.certs = response.csroptions;
								if(response.csroptions.length == 1 ) {
									processImportedCert(response.csroptions[0].options);
								} else {
									showDownloadedCerts(response.csroptions);
								}
							}
						});
					}
				} else {
					var pastedcert = document.getElementById('pastedcert');
					var data = {
						cert: pastedcert.value
					}
					openSSLRESTAPI('getCSRFromCert', data, function(error, response) {
						if(error) {
						
						} else {
							$( "#template" ).dialog("close");
							//console.log(response);
							processImportedCert(response.csroptions);
						}
					});
				}
			}
			function openTemplateDialogue() {
				$( "#template" ).dialog("open");
			}
			
			function clearKeyUsage() {
				var keyusagecritical = document.getElementById('keyusagecritical');
				keyusagecritical.checked = false;
				var keyusage = document.getElementsByName('keyusagevals');
				for(var i = 0; i <= keyusage.length - 1; i++) {
					keyusage[i].checked = false;
				}
			}
			
			function clearExtendedKeyUsage() {
				var extendedkeyusagecritical = document.getElementById('extendedkeyusagecritical');
				extendedkeyusagecritical.checked = false;
				var extendedkeyusage = document.getElementsByName('extendedkeyusagevals');
				for(var i = 0; i <= extendedkeyusage.length - 1; i++) {
					extendedkeyusage[i].checked = false;
				}
			}
			
			function selectKeyUsage(usages) {
				var keyusage = document.getElementsByName('keyusagevals');
				//console.log(keyusage);
				for(var i = 0; i <= keyusage.length - 1; i++) {
					for(var j = 0; j <= usages.length - 1; j++) {
						if(usages[j]==keyusage[i].value) {
							keyusage[i].checked = true;
						}
					}
				}
			}
			
			function selectExtendedKeyUsage(usages) {
				var extendedkeyusage = document.getElementsByName('extendedkeyusagevals');
				for(var i = 0; i <= extendedkeyusage.length - 1; i++) {
					for(var j = 0; j <= usages.length - 1; j++) {
						//console.log(usages[j]);
						//console.log(extendedkeyusage[i].value);
						if(usages[j]==extendedkeyusage[i].value) {
							extendedkeyusage[i].checked = true;
						}
					}
				}
			}
			
			function processX509ExtensionTemplate(element) {
				var template = element.options[element.selectedIndex].value
				for(var i = 0; i <= certtemplates.length - 1; i++) {
					if(certtemplates[i].name==template) {
						var options = {
							extensions: certtemplates[i].extensions
						}
						processImportedCert(options);
						return;
					}
				}
			}
			
			function processImportedCert(csroptions) {
				$( "#choosecert" ).dialog("close");
				console.log(csroptions);
				clearKeyUsage();
				clearExtendedKeyUsage();
				if(csroptions.extensions) {
					//if sans exist, add them
					if(csroptions.extensions.SANs) {
						//return;
						var list = document.getElementById('sanlist');
						deleteAllAttr(list);
						for(key in csroptions.extensions.SANs) {
							for(var i = 0; i <= csroptions.extensions.SANs[key].length - 1; i++) {
								addSAN(key, csroptions.extensions.SANs[key][i]);
								//console.log(csroptions.extensions.SANs[key][i]);
							}
						}
					}
					if(csroptions.extensions.keyUsage) {
						selectKeyUsage(csroptions.extensions.keyUsage.usages);
						if(csroptions.extensions.keyUsage.critical) {
							var keyusagecritical = document.getElementById('keyusagecritical');
							keyusagecritical.checked = true;
						}
					}
					if(csroptions.extensions.extendedKeyUsage) {
						selectExtendedKeyUsage(csroptions.extensions.extendedKeyUsage.usages);
						if(csroptions.extensions.extendedKeyUsage.critical) {
							var extendedkeyusagecritical = document.getElementById('extendedkeyusagecritical');
							extendedkeyusagecritical.checked = true;
						}
					}
					var bccritical = document.getElementById('bccritical');
					var isca = document.getElementById('isca');
					var pathlen = document.getElementById('pathlen');
					if(csroptions.extensions.basicConstraints) {
						if(csroptions.extensions.basicConstraints.critical) {
							bccritical.checked = true;
						} else {
							bccritical.checked = false;
						}
						if(csroptions.extensions.basicConstraints.CA) {
							isca.selectedIndex = 2;
						} else {
							isca.selectedIndex = 1;
						}
						if(csroptions.extensions.basicConstraints.pathlen !== undefined) {
							selectOption(csroptions.extensions.basicConstraints.pathlen, pathlen);
						} else {
							pathlen.selectedIndex = 0;
						}
					} else {
						bccritical.checked = false;
						isca.selectedIndex = 0;
						pathlen.selectedIndex = 0;
					}
					togglePathLen(false);
				}
				//add all subject attributes
				for(key in index) {
					for(attr in csroptions.subject) {
						if(key==attr) {
							var enabled = document.getElementById(key + 'check');
							var multivalue = document.getElementById(key + 'mvcheck');
							if(!enabled.checked) {
								enabled.checked = true;
								showSubjectAttr(key);
							}
							
							//if multivalued, make sure multivalue is enabled
							if(typeof(csroptions.subject[attr]) != 'string') {
								multivalue.checked = true;
								enableMultiValue(key);
							}
							
							if(!multivalue.checked) {
								var input = document.getElementById(index[key]['input']);
								input.value = csroptions.subject[attr]
							} else {
								var list = document.getElementById(index[key]['list']);
								deleteAllAttr(list);
								if(typeof(csroptions.subject[attr]) != 'string') {
									for(var i = 0; i <= csroptions.subject[attr].length - 1; i++) {
										addItem(key, csroptions.subject[attr][i]);
									}
								} else {
									addItem(key, csroptions.subject[attr]);
								}
							}
						}
					}
				}
			}
			
			function selectOption(value, selelem) {
				console.log(value);
				for(var i = 0; i <= selelem.options.length - 1; i++) {
					if(selelem.options[i].value==value) {
						selelem.selectedIndex = i;
					}
				}
			}
			
			function deleteAllAttr(list) {
				var items = list.getElementsByTagName('li');
				//alert(items.length);
				for(var i = items.length - 1; i >= 0; i--) {
					//console.log(items[i]);
					list.removeChild(items[i]);
				}
			}
			
			function googleAnalyticsEvent(category, action, label, value) {
				if(hosted) {
					gtag('event', action, {
						'event_category': category,
						'event_label': label,
						'value': value
					});
				}
			}
		</script>
	</head>
	<body>
		<!--<nav class="navbar navbar-default navbar-fixed-top">
			<div class="container-fluid">
				<a class="navbar-brand" href="https://certificatetools.com">CertificateTools.com</a>
			</div>
		</nav>-->
		{{{header}}}
		<div style="text-align: center;">
			<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
                                                <!-- CertificateTools.com Left -->
                                                <ins class="adsbygoogle"
                                                     style="display:block"
                                                     data-ad-client="ca-pub-4797561390067055"
                                                     data-ad-slot="8688054055"
                                                     data-ad-format="auto"
                                                     data-full-width-responsive="true"></ins>
                                                <script>
                                                (adsbygoogle = window.adsbygoogle || []).push({});
                                        </script>
		</div>
		<div class="container-fluid">
			<div class="row">
				<div class="col-lg-3 col-md-3 col-sm-2 col-xs-1">
					
				</div>
				<div class="col-lg-6 col-md-6 col-sm-8 col-xs-10">
					<div class="row">
						<div class="col">
							<div class="row">
								<div class="col">
									<div class="row">
										<div class="col text-center">
											<h1 class="text-center">{{title}}</h1>
										</div>
									</div>
									<div class="row">
										<div class="col-lg-1 col-md-0 col-sm-0 col-xs-0"></div>
										<div class="text-center col-lg-5 col-md-6 col-sm-6 col-xs-12">
											<button onclick="openTemplateDialogue();" class="btn btn-primary" type="button">Use Existing Certificate as a Template</button>
										</div>
										<div class="col-lg-5 col-md-6 col-sm-6 col-xs-12">
											<select onchange="processX509ExtensionTemplate(this)" class="form-control">
												<option selected="selected">X509v3 Extension Templates</option>
												{{#certtemplates}}
													<option value="{{name}}">{{name}}</option>
												{{/certtemplates}}
											</select>
										</div>
										<div class="col-lg-1 col-md-0 col-sm-0 col-xs-0"></div>
									</div>	
									<div class="row">
										<div class="col">
											<h4>Private Key</h4>
										</div>
									</div>
									<div class="row">
										<div class="col-lg-3 col-md-4 col-sm-8 col-xs-8">
											<select id="keymethod" onchange="changePrivateKeyMethod(this);" class="form-control">
												<option value="PKCS8">Generate PKCS#8 RSA Private Key</option>
												<option value="PKCS1">Generate PKCS#1 RSA Private Key</option>
												<option value="PKCS8ECC">Generate PKCS#8 ECC Private Key</option>
												<option value="PKCS1ECC">Generate PKCS#1 ECC Private Key</option>
												<option value="paste">Paste Existing PEM RSA Private Key</option>
												<option value="pasteecc">Paste Existing PEM ECC Private Key</option>
												<option value="upload">Upload Existing RSA Private Key</option>
												<option value="uploadecc">Upload Existing ECC Private Key</option>
											</select>
										</div>
										<div id="keysizecol" class="col-lg-2 col-md-3 col-sm-4 col-xs-4">
											<select id="keysize" class="form-control">
												<option value="512">512 Bit</option>
												<option value="1024">1024 Bit</option>
												<option selected value="2048">2048 Bit</option>
												<option value="4096">4096 Bit</option>
											</select>
										</div>
										<div style="display: none;" id="curvescol" class="col-lg-2 col-md-3 col-sm-4 col-xs-4">
											<select id="selcurve" class="form-control">
												<!--<option value="secp256k1">secp256k1</option>
												<option value="secp384r1">secp384r1</option>
												<option value="secp521r1">secp521r1</option>
												<option selected value="prime256v1">prime256v1</option>-->
												{{#capabilities.curves}}
													<option value="{{curve}}">{{curve}}</option>
												{{/capabilities.curves}}
											</select>
										</div>
										<div id="encryptcol" class="col-lg-1 col-md-2 col-sm-2 col-xs-3">
											<label class="checkbox-inline"><input type="checkbox" id="encryption" onclick="toggleEncryption(this);" value="">Encrypt</label>
										</div>
										<div id="passwordcol" style="display: none;" class="col-lg-3 col-md-3 col-sm-5 col-xs-5">
											<input id="password" class="form-control" type="password" placeholder="Password"/>
										</div>
										<div id="ciphercol" style="display: none;" class="col-lg-2 col-md-3 col-sm-5 col-xs-4">
											<select id="cipher" class="form-control">
												<option value="des3">Cipher...</option>
												<option value="des3">DES3</option>
												<option value="aes128">AES128</option>
												<option value="aes192">AES192</option>
												<option value="aes256">AES256</option>
											</select>
										</div>
										<div id="uploadcol" style="display: none;" class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
											<input id="uploadedkey" type="file" />
										</div>
										<div id="pastedkeycol" style="display: none;" class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
											<textarea rows="5" class="form-control" style="white-space: pre; word-wrap: normal; overflow-wrap: normal; overflow-x: auto; font-family: Courier, monospace;" id="pastedkey" placeholder="-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDAv/hueVhGvyaz
ogC55oZC38uTcbfsoPVFmSeY/prj8JyJWZkpF1VH86tDJ818Ud4hxDWmFdSKAhTA
D8NXkjnrKZEh7zP6x6KTQCK/57xoUTYYpvRnFacwwmqpbxVLFgdFwp1YdM3ktsoN
rFFS92WYBLt6MXe/87gmcvXp+yA7tJ5dCapurMEs1RXGf0IE0zPGqHb46jbqMrwG
Pt8ZxbBRUzUjzvkAwbayuArBJt57weVDIn1D4bc/cwNzY3NpelJBwgWtsXgUA3CH
T4qDYHRvNolbQHXVgRfe92ljIgnpcIu5f0E0PqSamB7aT8GO2OYsfZITPFzOUaOJ
jE9J418tAgMBAAECggEAB2ucicw8HMUhHUtAUefRBWQON0fqd76ekqZZwucSWXIa
5KLBZbaTPujfj/9JRt7z+ULPeexfOUzpNZelwopLloUMJE1MJ/xlgtu2OsMWGsH9
nidXQ1yvCg6CArHXFQPtFb9vRUeB4aszziDzJImHrLmJ6iNbY9VjIn/MfcyAKiwx
pg04MtkAAXnY/qqhwicCtmCRSLmmFHk3K5OpKMo1RdEZJqKPgeI66iawvBsR++bA
r5j0HzW513vIfpVUMUA/ykhsTWzwbNcAr9IRx/zV+NHfI513V4a4pdg6CdX+qpRG
w9wCpii9kMuTNo2l8IjDqG8I+yhenZpR4/FHUIl7oQKBgQD+Q3kD4RQcSyDUM1Z8
g87XXdbBK6IY5yyw1dk1LPwxpH7ITjgDCEWVbrivpHkyG49oxkwzx5UZqXCNbt9g
+Ll48Pdrtj3rIlw+giQr6Co9wqNsuOgViGt9BmEFrcxfYk2y69Cd2/qZWpKLFiVw
SdHc5uYz9MJxpGx46pIFANzoGQKBgQDCEPQp8gcn7ZcwX/ThBfYrXJ1jR6g5zR1q
yqSzhL8jjkAvk1yAbWajtn3lbnruVPYN2ob3/ck2EaJF4qTeVExCe3y3nDVd4sur
flhcEFfNlvpor0WB/R9T9wpGrrxmlqqS+w98qznS4b7As/HaISNtZjF0BCksnMMG
EQJHqnQiNQKBgAx7IWiYVtVgtrbT4k3wZmnZ+F25F5bjWiVACg57K9IAAh0xAbzc
XhYMvlIY374e7jY1ba4pAN+mmpjGtX5cFzahlXObGYT+RcrntoDVP6WSdVUz6miM
LsKPWpndwyd3etrqim4FS1LVyFW9e478gKm4R9qLDDRp3s08rnhCZ5WZAoGANaB1
uDmXXKM9CjMZ+iypj+Xx4ANnK0HRBTemN61RHEQs3Hi+MQcKO+cr9wCGm+GCdOWU
MmdA+N36l5E/uehVgnGZTyutW5pWabdqN1aUzM0RuWflrzwBMjSr9EhI65hq3l7e
MrcmLW4QRjPzezF5FrwMomCb+CYBhmWg2ajympkCgYEAt5ljkEpWX1fTU1R8NHRM
kEoFeiBVjPc5PhXfp+EeSGx2xuT5k8ey0Rkozefkm3JbjVQz0E00Nn5BS4vQS35Z
NcLWDb/NXY/hj1qMAvou5kYgw+inQ/r4FxHxlZoyB5yS9cNSZPp7Kg5NlRPRMs74
dyzGibcJ0i4KVZzXKLIZ0Qw=
-----END PRIVATE KEY-----"></textarea>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="row">
						<div class="col">
							<div class="row">
								<div class="col">
									<div class="row">
										<div class="col">
											<h4>Subject Attributes</h4>
										</div>
									</div>
									<div class="row">
										<div class="col">
											<div id="accordion">
												<h3>Add / Remove Attributes</h3>
												<div>
													<div>
														<p>Add and remove subject attributes:</p>
													</div>
													<div id="addremove">
													
													</div>
												</div>
											</div>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="row">
						<div id="subject" class="col">
						</div>
					</div>
					<div class="row">
						<div class="col">	
							<div class="row">
								<div class="col">
									<div class="row">
										<div class="col">
											<h4>Subject Alternative Names</h4>
										</div>
									</div>
									<div class="row">
										<div class="col-lg-2 col-md-3 col-sm-4 col-xs-4">
											<select id="typeinput" class="form-control">
												<option value="DNS">DNS</option>
												<option value="IP">IP</option>
												<option value="URI">URI</option>
												<option value="email">email</option>
												<option value="otherName">otherName</option>
											</select>
										</div>
										<div class="col-lg-8 col-md-7 col-sm-5 col-xs-5">
											<input placeholder="certificatetools.com" type="text" maxlength="128" class="form-control" id="saninput" />
										</div>
										<div class="col-lg-2 col-md-2 col-sm-3 col-xs-3 rightbtn">
											<button class="btn btn-primary" onclick="processSANInput();" type="button">Add</button>
										</div>
									</div>
									<div class="row">
										<div class="col-lg-11 col-lg-11 col-sm-11 col-xs-12">
											<ul id="sanlist" class="list-group">
												<li class="list-group-item" style="border: medium none;"><span class="none">Add a subject alternative name</span></li>
											</ul>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="row">
						<div class="col">
							<div class="row">
								<div class="col">
									<div class="row">
										<div class="col">
											<h4>x509v3 Extensions</h4>
										</div>
									</div>
									<div class="row">
										<div class="col">
											<div id="keyusagesection">
												<h3>Key Usage</h3>
												<div>
													<div>
														<p>Modify key usage:</p>
													</div>
													<div>
														<label class="checkbox-inline"><input checked id="keyusagecritical" type="checkbox" value="critical" />Critical</label><br /><br />
														<label class="checkbox-inline"><input checked name="keyusagevals" type="checkbox" value="digitalSignature" />Digital Signature</label><br />
														<label class="checkbox-inline"><input checked name="keyusagevals" type="checkbox" value="keyEncipherment" />Key Encipherment</label><br />
														<label class="checkbox-inline"><input name="keyusagevals" type="checkbox" value="nonRepudiation" />Non Repudiation</label><br />
														<label class="checkbox-inline"><input name="keyusagevals" type="checkbox" value="dataEncipherment" />Data Encipherment</label><br />
														<label class="checkbox-inline"><input name="keyusagevals" type="checkbox" value="keyAgreement" />Key Agreement</label><br />
														<label class="checkbox-inline"><input name="keyusagevals" type="checkbox" value="keyCertSign" />Certificate Sign</label><br />
														<label class="checkbox-inline"><input name="keyusagevals" type="checkbox" value="cRLSign" />CRL Sign</label><br />
														<label class="checkbox-inline"><input name="keyusagevals" type="checkbox" value="encipherOnly" />Encipher Only</label><br />
														<label class="checkbox-inline"><input name="keyusagevals" type="checkbox" value="decipherOnly" />Decipher Only</label>
													</div>
												</div>
											</div>
										</div>
									</div>
									<div class="row">
										<div class="col">
											<div id="extendedkeyusagesection">
												<h3>Extended Key Usage</h3>
												<div>
													<div>
														<p>Modify extended key usage:</p>
													</div>
													<div>
														<label class="checkbox-inline"><input checked id="extendedkeyusagecritical" type="checkbox" value="critical" />Critical</label><br /><br />
														<label class="checkbox-inline"><input checked name="extendedkeyusagevals" type="checkbox" value="serverAuth" />TLS Web Server Authentication</label><br />
														<label class="checkbox-inline"><input checked name="extendedkeyusagevals" type="checkbox" value="clientAuth" />TLS Web Client Authentication</label><br />
														<label class="checkbox-inline"><input name="extendedkeyusagevals" type="checkbox" value="codeSigning" />Code Signing</label><br />
														<label class="checkbox-inline"><input name="extendedkeyusagevals" type="checkbox" value="emailProtection" />E-mail Protection</label><br />
														<label class="checkbox-inline"><input name="extendedkeyusagevals" type="checkbox" value="timeStamping" />Time Stamping</label><br />
														<label class="checkbox-inline"><input name="extendedkeyusagevals" type="checkbox" value="OCSPSigning" />OCSP Signing</label><br />
														<label class="checkbox-inline"><input name="extendedkeyusagevals" type="checkbox" value="msCodeInd" />Microsoft Individual Code Signing</label><br />
														<label class="checkbox-inline"><input name="extendedkeyusagevals" type="checkbox" value="msCodeCom" />Microsoft Commercial Code Signing</label><br />
														<label class="checkbox-inline"><input name="extendedkeyusagevals" type="checkbox" value="msCTLSign" />Microsoft Trust List Signing</label><br />
														<label class="checkbox-inline"><input name="extendedkeyusagevals" type="checkbox" value="msEFS" />Microsoft Encrypted File System</label>
													</div>
												</div>
											</div>
										</div>
									</div>
									<div class="row">
										<div class="col">
											<div id="basicconstraintssection">
												<h3>Basic Constraints (CA)</h3>
												<div>
													<div>
														<p>Modify basic constraints:</p>
													</div>
													<div>
														<label class="checkbox-inline"><input checked id="bccritical" type="checkbox" value="critical" />Critical</label><br /><br />
														<div class="container-fluid">
															<div class="row">
																<div class="col">
																	Will this CSR be used as a certificate authority to sign other certificates? (CA)
																</div>
															</div>
															<div class="row">
																<div class="col-lg-6 col-lg-6 col-sm-8 col-xs-12">
																	<select id="isca" onchange="togglePathLen(false);" class="form-control">
																		<option value="undefined">Undefined</option>
																		<option value="FALSE">No</option>
																		<option value="TRUE">Yes</option>
																	</select>
																</div>
															</div>
															<div id="pathlen1" class="row">
																<div class="col">
																	How long do you want to limit the certificate chain leading to this CA? (Path Length)
																</div>
															</div>
															<div id="pathlen2" class="row">
																<div class="col-lg-6 col-lg-6 col-sm-8 col-xs-12">
																	<select id="pathlen" class="form-control">
																		<option value="None">No Limit</option>
																		<option value="0">0</option>
																		<option value="1">1</option>
																		<option value="2">2</option>
																		<option value="3">3</option>
																		<option value="4">4</option>
																		<option value="5">5</option>
																		<option value="6">6</option>
																		<option value="7">7</option>
																		<option value="8">8</option>
																		<option value="9">9</option>
																		<option value="10">10</option>
																	</select>
																</div>
															</div>
														</div>
													</div>
												</div>
											</div>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="row">
						<div class="col">	
							<div class="row">
								<div class="col">
									<div class="row">
										<div class="col">
											<h4>CSR Options</h4>
										</div>
									</div>
									<div class="row">
										<div class="col-lg-2 col-md-2 col-sm-8 col-xs-8">
											<select id="hashalg" class="form-control">
												<option value="sha256">Hash Algorithm...</option>
												<option value="sha">SHA</option>
												<option value="md5">MD5</option>
												<option value="sha1">SHA1</option>
												<option value="sha224">SHA224</option>
												<option selected value="sha256">SHA256</option>
												<option value="sha384">SHA384</option>
												<option value="sha512">SHA512</option>
											</select>
										</div>
										<div class="col-lg-2 col-md-2 col-sm-4 col-xs-4">
											<!--<label class="checkbox-inline"><input id="selfsign" type="checkbox" onchange="toggleSelfSign(this);" value=""/>Self-Sign Certificate</label>-->
											<select id="signcert" class="form-control" onchange="toggleSelfSign(this);">
												<option value="nosign">CSR Only</option>
												<option value="selfsign">Self-Sign</option>
											</select>
										</div>
										<!--<div id="managecacol" class="col-lg-2 col-md-2 col-sm-3 col-xs-3">
											<button class="btn btn-primary" onclick="manageCA();" type="button">Manage</button>
										</div>-->
										<div id="timelengthcol" class="col-lg-2 col-md-2 col-sm-4 col-xs-4">
											<input value="1" id="timelength" type="text" class="form-control"  />
										</div>
										<div id="timetypecol" class="col-lg-3 col-md-3 col-sm-4 col-xs-4">
											<select id="timetype" class="form-control">
												<option value="year">Year(s)</option>
												<option value="month">Month(s)</option>
												<option value="week">Week(s)</option>
												<option value="day">Day(s)</option>
											</select>
										</div>
										<div id="date1" class='col-lg-3 col-md-3 col-sm-6 col-xs-6'>
											<div class="form-group">
												<div class='input-group date' id='datetimepicker1'>
													<input placeholder="Start Date" type='text' class="form-control" />
													<span class="input-group-addon">
														<span class="glyphicon glyphicon-calendar"></span>
													</span>
												</div>
											</div>
										</div>
										<script type="text/javascript">
											$(function () {
												$('#datetimepicker1').datetimepicker({
													defaultDate: new Date()
												});
											});
										</script>
										<div id="date2" class='col-lg-3 col-md-3 col-sm-6 col-xs-6'>
											<div class="form-group">
												<div class='input-group date' id='datetimepicker2'>
													<input placeholder="End Date" type='text' class="form-control" />
													<span class="input-group-addon">
														<span class="glyphicon glyphicon-calendar"></span>
													</span>
												</div>
											</div>
										</div>
										<script type="text/javascript">
											$(function () {
												$('#datetimepicker2').datetimepicker();
											});
										</script>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="row">
						<div class="col">	
							<div class="row">
								<div class="col">
									<div class="row">
										<div class="col text-center">
											<button class="btn btn-primary" style="margin-top: 10px; margin-bottom: 10px;" onclick="processForm();" type="button">Submit</button>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="row">
						<div class="col">	
							<div class="row">
								<div class="col">
									<div class="row">
										<div id="output" class="col"></div>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="row">
						<div class="col">	
							<div class="row">
								<div class="col">
									<div class="row">
										<div style="margin-top: 10px; margin-bottom: 20px;" id="developedby" class="col text-center">
											Developed by Lyas Spiehler<br />
											<!-- Go to www.addthis.com/dashboard to customize your tools --> <div class="addthis_sharing_toolbox"></div><br />
											<a href="https://www.youtube.com/watch?v=O9-Ld_ceL0E">Checkout CertificateTools.com on YouTube</a>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="row">
						<div class="col">	
							<div class="row">
								<div class="col">
									<div class="row">
										<div id="chat" style="margin-top: 20px;" class="col">
											<div id="disqus_thread"></div>
											<script>
												//if domain is certificatetools.com, show chat
												if(hosted) {
													/**
													*  RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS.
													*  LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables*/
													
													var disqus_config = function () {
													this.page.url = 'https://certificatetools.com';  // Replace PAGE_URL with your page's canonical URL variable
													this.page.identifier = 'csrgenerator'; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
													};
													
													(function() { // DON'T EDIT BELOW THIS LINE
														var d = document, s = d.createElement('script');
														s.src = 'https://certificatetools.disqus.com/embed.js';
														s.setAttribute('data-timestamp', +new Date());
														(d.head || d.body).appendChild(s);
													})();
												}
											</script>
											<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
				<div class="col-lg-3 col-md-3 col-sm-2 col-xs-1">
					
				</div>
			</div>
			<!--<div class="row">
				<div id="key" style="font-family: Courier, monospace;" class="col">
				
				</div>
				<div id="csr" style="font-family: Courier, monospace;" class="col">
				
				</div>
				<div id="cer" style="font-family: Courier, monospace;" class="col">
				
				</div>
			</div>-->
		</div>
		<div id="dialog" title="Encrypted Private Key">
			<p>The private key is encrypted and requires a password</p>
			<table>
				<tr>
					<td>Password:</td>
					<td>&nbsp;</td>
					<td>
						<input id="passwordprompt" type="password" class="form-control" />
					</td>
				</tr>
				<tr>
					<td>&nbsp;</td>
				</tr>
				<tr>
					<td align="center" colspan="3">
						<button class="btn btn-primary" onclick="processForm();" type="button">Submit</button>
					</td>
				</tr>
			</table>
		</div>
		<div id="saveca" title="Save Certificate Authority">
			<p>Enter a name for this certificate authority</p>
			<table>
				<tr>
					<td>Name:</td>
					<td>&nbsp;</td>
					<td>
						<input id="caname" type="text" class="form-control" /><input type="hidden" id="caindex" />
					</td>
				</tr>
				<tr>
					<td>&nbsp;</td>
				</tr>
				<tr>
					<td align="center" colspan="3">
						<button class="btn btn-primary" onclick="saveCA();" type="button">Submit</button>
					</td>
				</tr>
			</table>
		</div>
		<div id="capassword" title="CA Password">
			<p>Enter the password for the selected certificate authority</p>
			<table>
				<tr>
					<td>Password:</td>
					<td>&nbsp;</td>
					<td>
						<input id="capasswordinput" type="password" class="form-control" />
					</td>
				</tr>
				<tr>
					<td>&nbsp;</td>
				</tr>
				<tr>
					<td align="center" colspan="3">
						<button class="btn btn-primary" onclick="processForm();" type="button">Submit</button>
					</td>
				</tr>
			</table>
		</div>
		<div id="pkcs12dialog" title="Encrypt PKCS#12 Certificate">
			<p>The private key is included in the PKCS#12 format certificate. Enter a password if you'd like to encrypt it, or click cancel to proceed without a password.</p>
			<table>
				<tr>
					<td>Password:</td>
					<td>&nbsp;</td>
					<td>
						<input id="pkcs12password" type="password" class="form-control" />
					</td>
				</tr>
				<tr>
					<td>&nbsp;</td>
				</tr>
				<tr>
					<td align="center" colspan="3">
						<button id="pkcs12submit" class="btn btn-primary" type="button">Submit</button>
						<button id="pkcs12cancel" class="btn btn-primary" type="button">Cancel</button>
					</td>
				</tr>
			</table>
		</div>
		<div id="choosecert" title="Select a Certificate">
			<p>The query returned a chain of multiple certificates. Please select the one you'd like to use from the dropdown:</p>
			<p><select class="form-control" id="downloadedcerts">
			</select></p>
			<p class="text-center"><button onclick="getSelectedCert();" type="button" class="btn btn-primary">Submit</button></p>
			
		</div>
		<div id="template" title="Use Existing Cert as a Template">
			<div class="container-fluid">
				<div class="row">
					<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
						<select onchange="templateMethod(this);" class="form-control" id="templatemethod" >
							<option value="ssltls">SSL/TLS Download</option>
							<option value="starttls">STARTTLS Download</option>
							<option value="paste">Paste</option>
						</select>
					</div>
				</div>
				<div style="margin-top: 10px;" class="row">
					<div id="protocolcontain" class="col-lg-3 col-md-3 col-sm-3 col-xs-3">
						<select onchange="changeProtocol(this);" style="display: none;" class="form-control" id="starttls">
							<option value="smtp">SMTP</option>
							<option value="pop3">POP3</option>
							<option value="imap">IMAP</option>
							<option value="ftp">FTP</option>
							<option value="xmpp">XMPP</option>
							<option value="xmpp-server">XMPP-Server</option>
							<option value="irc">IRC</option>
							<option value="postgres">Postgres</option>
							<option value="mysql">MySQL</option>
							<option value="lmtp">LMTP</option>
							<option value="nntp">NNTP</option>
							<option value="sieve">Sieve</option>
							<option value="ldap">LDAP</option>
						</select>
						<select onchange="changeProtocol(this);" class="form-control" id="ssltls">
							<option value="https">HTTPS</option>
							<option value="smtps">SMTPS</option>
							<option value="pop3s">POP3S</option>
							<option value="imaps">IMAPS</option>
							<option value="ftps">FTPS</option>
							<option value="ldaps">LDAPS</option>
							<option value="other">Other</option>
						</select>
					</div>
					<div id="hostcontain" class="col-lg-5 col-md-5 col-sm-5 col-xs-5">
						<input id='hostname' type="text" placeholder="google.com" class="form-control" /> 
					</div>
					<div id="pastecontain" class="col-lg-12 col-md-12 col-sm-12 col-xs-12" style="display:none;">
						<textarea rows="5" class="form-control" style="white-space: pre; word-wrap: normal; overflow-wrap: normal; overflow-x: auto; font-family: Courier, monospace;" id="pastedcert"></textarea>
					</div>
					<div id="delimcontain" class="col-lg-1 col-md-1 col-sm-1 col-xs-1"><span style="font-size: 20px;">:</span></div>
					<div id="portcontain" class="col-lg-2 col-md-2 col-sm-2 col-xs-2">
						<input id="port" readonly type="text" placeholder="443" value="443" class="form-control" /> 
					</div>
				</div>
				<div style="margin-top: 10px;" class="row">
					<div class="col text-center">
						<button onclick="importCert();" type="button" class="btn btn-primary">Submit</button>
					</div>
				</div>
			</div>
		</div>
		<div class="modal fade" id="features" role="dialog">
			<div class="modal-dialog modal-lg">
				<div class="modal-content">
					<div class="modal-header">
						<button type="button" class="close" data-dismiss="modal">&times;</button>
						<h4 class="modal-title">Welcome</h4>
					</div>
					<div class="modal-body">
						<h3>Welcome to the new certificatetools.com UI. Here are a few things the new tool can do:</h3>
						<h4><a href="https://www.youtube.com/watch?v=O9-Ld_ceL0E">Check out my new YouTube video overview and demonstration of the site's features.</a></h4>
						<ul>
							<li>Generate certificate signing requests (CSR)</li>
							<li>Supports multiple common names and subject alternative names</li>
							<li>Supports elliptic curve cryptography</li>
							<li>Generate self-signed certificates</li>
							<li>Generate RSA Keys in multiple formats with optional encryption</li>
							<li>Import existing RSA keys by pasting or uploading</li>
							<li>Use an existing certificate as a template by pasting it or automatically downloading it via SSL or STARTTLS</li>
							<li>See all OpenSSL commands and configurations so that you can do everything offline</li>
							<li>Supports x509v3 extensions:</li>
								<ul>
									<li>Key Usage</li>
									<li>Extended Key Usage</li>
									<li>Basic Constraints</li>
									<li>Subject alternative Names</li>
								</ul>
							<li>Download keys and certificates in multiple formats including:</li>
								<ul>
									<li>PEM</li>
									<li>DER</li>
									<li>PKCS#12 (PFX)</li>
									<li>PKCS#7 (P7B)</li>
									<li>PKCS#1</li>
									<li>PKCS#8</li>
								</ul>
							<li>Create certificate authorities and optionally save them for later use</li>
							<li>Sign certificates with certificate authorities you've created</li>
						</ul>
					</div>
					<div class="modal-footer">
						<p class="text-center">
							Please report bugs by commenting below. All feedback is appreciated.<br /><br />
							<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
						</p>
					</div>
				</div>
			</div>
		</div>
		<script>
			$( function() {
				$( "#accordion" ).accordion({
					collapsible: true,
					active: false
				});
			} );
			$( function() {
				$( "#keyusagesection" ).accordion({
					collapsible: true,
					active: false
				});
			} );
			$( function() {
				$( "#extendedkeyusagesection" ).accordion({
					collapsible: true,
					active: false
				});
			} );
			$( function() {
				$( "#basicconstraintssection" ).accordion({
					collapsible: true,
					active: false
				});
			} );
			$( "#dialog" ).dialog({
				modal: true,
				autoOpen: false
			});
			$( "#pkcs12dialog" ).dialog({
				modal: true,
				autoOpen: false
			});
			$( "#capassword" ).dialog({
				modal: true,
				autoOpen: false
			});
			$( "#saveca" ).dialog({
				modal: true,
				autoOpen: false
			});
			$( "#choosecert" ).dialog({
				modal: true,
				autoOpen: false
			});
			if(hosted) {
				$('#features').modal('show');
			};
			$( function() {
				var browserwidth = document.body.offsetWidth;
				var width = 600;
				if(browserwidth < 400) {
					width = browserwidth;
				}
				$( "#template" ).dialog({
					modal: true,
					autoOpen: false,
					width: width + 'px'
				});
			});
			selectDefaultCurve();
			//alert(document.body.offsetWidth);
			addRemoveSubjectAttrs();
			var keymethod = document.getElementById("keymethod");
			changePrivateKeyMethod(keymethod);
			var signcert = document.getElementById('signcert');
			toggleSelfSign(signcert);
			var templatemethod = document.getElementById('templatemethod');
			templateMethod(templatemethod);
			togglePathLen(true);
			listCAs();
			populateSubject();
		</script>
		<form id="downloadtext"></form>
		<!-- Go to www.addthis.com/dashboard to customize your tools --> <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-56f6c2b8ba1be9a6"></script>
	</body>
</html>
