/** * test_content - test a CSR for deficiencies * * This function is to be used when testing uploaded CSRs for flaws and errors. * It will test for: * - common text-patterns * - that the key meets the required key-length * - that it is a normal CSR (previous point will fail if it is a 'bogus' CSR * - that the auth_url is derived from the supplied CSR */ function test_content($content, $auth_url) { $testres = true; /* check for start */ $start = substr($content, 0, strlen("-----BEGIN CERTIFICATE REQUEST-----")); $end = substr($content, -(strlen("-----END CERTIFICATE REQUEST-----") + 1), -1); /* test start and ending of certificate */ if (strcmp("-----BEGIN CERTIFICATE REQUEST-----", $start) !== 0 && strcmp("-----END CERTIFICATE REQUEST-----", $end) !== 0) { Framework::error_output("malformed CSR. Please upload a proper CSR to the system."); return false; } /* test type. IGTF will soon change the charter to *not* issue DSA * certificates */ if (get_algorithm($content) !== "rsa") { Framework::error_output("Will only accept RSA keys!"); return false; } /* * test length of pubkey */ $length = Config::get_config('min_key_length'); if (csr_pubkey_length($content) < $length) { Framework::error_output("Uploaded key is not long enough. Please download a proper keyscript and try again."); return false; } /* * test CSR to blacklist. It is safe to call exec as we have tested the * content of the CSR. */ $cmd = "echo \"{$content}\" | openssl-vulnkey -"; exec($cmd, $output, $return_val); switch ($return_val) { case 0: /* key is not blacklisted */ break; case 1: Framework::error_output("Uploaded CSR is blacklisted!"); return false; case 127: Logger::log_event(LOG_ERR, __FILE__ . ":" . __LINE__ . " openssl-vulnkey not installed"); break; default: Logger::log_event(LOG_DEBUG, __FILE__ . ":" . __LINE__ . " Unknown return ({$return_val}) value from shell"); break; } /* * test authenticity of auth_url */ $hash = pubkey_hash($content, true); if (substr($hash, 0, ConfusaConstants::$AUTH_KEY_LENGTH) != $auth_url) { Framework::error_output("Uploaded key ({$hash}) and auth_url ({$auth_url}) does not match"); return false; } return true; }
public function getCert($key) { $res = MDB2Wrapper::execute("SELECT cert FROM cert_cache WHERE auth_key=? AND cert_owner=? AND valid_untill > current_timestamp()", array('text', 'text'), array($key, $this->person->getX509ValidCN())); if (count($res) == 1) { $msg = "Sending certificate with hash " . pubkey_hash($res[0]['cert'], false) . " "; $msg .= " and auth-token {$key} to user from ip " . $_SERVER['REMOTE_ADDR']; Logger::log_event(LOG_NOTICE, $msg); return new Certificate($res[0]['cert']); } else { $msg = "Error in getting certificate, got " . count($res) . " results\n"; $cn = stripslashes($this->person->getX509ValidCN()); $msg .= "Queried for key {$key} and CN {$cn}\n"; throw new DBQueryException($msg); } }
/** * ship the CSR to the CA and let it sign the request * * @param $request The XML signing request */ public function processSigningRequest($request) { $doc = DOMDocument::loadXML($request); if ($doc === FALSE) { $this->errorBadRequest("Could not parse the given XML string!\n"); } $check = $doc->relaxNGValidate('schema/signingRequest.rng'); if ($check === FALSE) { $this->errorBadRequest("Could not validate the XML request, see " . "/api/schema/signingRequest.rng for its schema!\n"); } $csrNodes = $doc->getElementsByTagName("csr"); $csrNode = $csrNodes->item(0); $csr = $csrNode->textContent; $emailsNodes = $doc->getElementsByTagName("emails"); $emailsNode = $emailsNodes->item(0); $emailsNodeElCount = $emailsNode->childNodes->length; if ($emailsNodeElCount > 0) { $emailNodes = $doc->getElementsByTagName("email"); for ($i = 0; $i < $emailsNodeElCount; $i++) { $emailNode = $emailNodes->item($i); $this->person->regCertEmail(Input::sanitizeEmail($emailNode->textContent)); } } $regCertEmails = $this->person->getRegCertEmails(); if (empty($regCertEmails)) { $msg = "The supplied mail address does not match any federation " . "federation attribute!"; $this->errorBadRequest($msg); exit(1); } /* FIXME: Adapt to the new API once it exists */ require_once 'csr_lib.php'; $auth_key = pubkey_hash($csr, TRUE); if (!test_content($csr, $auth_key)) { $msg = "The CSR you posted appears to be malformed!\n"; $this->errorBadRequest($msg); } try { require_once 'CSR_PKCS10.php'; $csr = new CSR_PKCS10($csr); $this->ca->signKey($csr); } catch (ConfusaGenException $cge) { $this->errorUncaughtException($cge); } header("HTTP/1.1 202 Accepted"); /* FIXME: include the actual status here */ echo "status=Accepted\n"; exit(0); }
private function parse_file() { if (!$this->parsed && $this->file_ok) { if ($this->file_ok() && isset($this->filename)) { $fd = fopen($this->filename, 'r'); $fsize = filesize($_FILES[$this->open_file]['tmp_name']); if ($this->mem) { $this->fcont = fread($fd, $fsize); fclose($fd); } else { $this->fcont = $fd; } $fuptr = $this->test_func; /* truncate the pubkey_hash to the length defined in the config script */ $hash = pubkey_hash($this->fcont, true); $auth_url = substr($hash, 0, ConfusaConstants::$AUTH_KEY_LENGTH); $this->file_ok = $fuptr($this->fcont, $auth_url); } else { $this->fcont = null; } $this->parsed = true; } }