public function sign() { $input = Input::all(); $rules = ['csr' => 'required', 'root_password' => 'required']; $v = Validator::make($input, $rules); if ($v->fails()) { return Redirect::route('certs-path')->withInput(Input::except('root_password'))->with('error', 'Please select a CSR and provide the Root CA password.'); } // Upload CSR $randomFileName = str_random(); Input::file('csr')->move($this->certDir, $randomFileName . '.csr'); $root_pw = Input::get('root_password'); // Check if CSR is valid and user is allowed to sign requests for the given domain $process = new Process("cd {$this->certDir} && LC_ALL=C openssl req -text -noout -in {$randomFileName}.csr | grep Subject | grep -o 'CN=.*' | cut -c 4-"); $process->run(); $csrDomain = trim($process->getOutput()); // Calculate domain string to check against users allowed domain pool $checkDomain = '*' . substr($csrDomain, strpos($csrDomain, '.')); if (!$csrDomain || !in_array($checkDomain, Auth::user()->domains)) { File::delete($this->certDir . $randomFileName . '.csr'); // cleanup return Redirect::route('certs-path')->withInput(Input::except('root_password'))->with('error', 'The provided CSR file is invalid or you are not allowed to create a certificate for the given domain.'); } // Sign CSR $sluggedDomain = Str::slug(str_replace('.', '_', $csrDomain)); $process = new Process("cd {$this->certDir} && openssl x509 -passin pass:{$root_pw} -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -days 365 -sha256 -req -in {$randomFileName}.csr -out {$randomFileName}.pem && openssl x509 -in {$randomFileName}.pem -out {$sluggedDomain}.crt"); $process->run(); // Remove CSR and PEM File::delete($this->certDir . $randomFileName . '.csr'); File::delete($this->certDir . $randomFileName . '.pem'); if (!$process->isSuccessful()) { return Redirect::route('certs-path')->withInput(Input::except('root_password'))->with('error', 'Could not sign certificate. Is the provided Root CA password correct? ' . nl2br($process->getErrorOutput())); } // Create database entry Cert::create(['user_id' => Auth::user()->id, 'domain' => $csrDomain, 'csr' => 1]); // Return signed certificate as download return Response::download($this->certDir . $sluggedDomain . '.crt'); }