/** * Generates a CSR for one or more domains. * * @since 1.0.0 * @access public * * @param resource $key_resource The private key resource for the CSR. * @param array $domains Array of domains the CSR should be created for. * @param array $dn Array of CSR settings. It should have the array keys * 'ST' (for country), 'C' (for two-letter country code) * and 'O' (for organization name). * @return string|WP_Error The generated CSR if successful or an error object otherwise. */ public function generate_csr($key_resource, $domains, $dn = array()) { $filesystem = Util::get_filesystem(); $status = Util::maybe_create_letsencrypt_certificates_dir(); if (is_wp_error($status)) { return $status; } $san = implode(',', array_map(array($this, 'dnsify'), $domains)); $output = 'HOME = . RANDFILE = $ENV::HOME/.rnd [ req ] default_bits = 2048 default_keyfile = privkey.pem distinguished_name = req_distinguished_name req_extensions = v3_req [ req_distinguished_name ] countryName = Country Name (2 letter code) [ v3_req ] basicConstraints = CA:FALSE subjectAltName = ' . $san . ' keyUsage = nonRepudiation, digitalSignature, keyEncipherment'; $tmp_config_path = tempnam(sys_get_temp_dir(), 'wpenc'); if (false === $filesystem->put_contents($tmp_config_path, $output)) { return new WP_Error('csr_cannot_write_tmp_file', __('Could not write CSR configuration to temporary file. Please check your filesystem permissions.', 'wp-encrypt')); } $dn = wp_parse_args($dn, array('CN' => $this->domain, 'ST' => 'United States of America', 'C' => 'US', 'O' => 'Unknown')); $dn = apply_filters('wp_encrypt_csr_dn', $dn, $this->domain); $csr = openssl_csr_new($dn, $key_resource, array('config' => $tmp_config_path, 'digest_alg' => 'sha256')); if (false === $csr) { $filesystem->delete($tmp_config_path); return new WP_Error('csr_cannot_generate', sprintf(__('Could not generate CSR. Original error message: %s', 'wp-encrypt'), openssl_error_string())); } if (false === openssl_csr_export($csr, $csr)) { $filesystem->delete($tmp_config_path); return new WP_Error('csr_cannot_export', sprintf(__('Could not export CSR. Original error message: %s', 'wp-encrypt'), openssl_error_string())); } $filesystem->delete($tmp_config_path); if (false === $filesystem->put_contents($this->path . '/last.csr', $csr)) { return new WP_Error('csr_cannot_write', sprintf(__('Could not write CSR into file <code>%s</code>. Please check your filesystem permissions.', 'wp-encrypt'), $this->path . '/last.csr')); } preg_match('#REQUEST-----(.*)-----END#s', $csr, $matches); return trim($matches[1]); }
/** * Generates the public and private key. * * @since 1.0.0 * @access public * * @return bool|WP_Error True if successful, an error object otherwise. */ public function generate() { $filesystem = Util::get_filesystem(); $status = Util::maybe_create_letsencrypt_certificates_dir(); if (is_wp_error($status)) { return $status; } $res = openssl_pkey_new(array('private_key_type' => OPENSSL_KEYTYPE_RSA, 'private_key_bits' => 4096)); if (false === $res) { return new WP_Error('private_key_cannot_generate', sprintf(__('Could not generate private key. Original error message: %s', 'wp-encrypt'), openssl_error_string())); } if (false === openssl_pkey_export($res, $private_key)) { return new WP_Error('private_key_cannot_export', sprintf(__('Could not export private key. Original error message: %s', 'wp-encrypt'), openssl_error_string())); } $this->private_key = $private_key; $this->private_key_resource = $res; $details = $this->get_private_details(); if (is_wp_error($details)) { return $details; } $this->public_key = $details['key']; if (!$filesystem->is_dir($this->path)) { $filesystem->mkdir($this->path, 0700, true); if (!$filesystem->is_dir($this->path)) { return new WP_Error('private_key_cannot_create_dir', sprintf(__('Could not create directory <code>%s</code> for private key. Please check your filesystem permissions.', 'wp-encrypt'), $this->path)); } } if (false === $filesystem->put_contents($this->path . '/' . self::PRIVATE_NAME, $this->private_key)) { return new WP_Error('private_key_cannot_write', sprintf(__('Could not write private key into file <code>%s</code>. Please check your filesystem permissions.', 'wp-encrypt'), $this->path . '/' . self::PRIVATE_NAME)); } if (false === $filesystem->put_contents($this->path . '/' . self::PUBLIC_NAME, $this->public_key)) { return new WP_Error('public_key_cannot_write', sprintf(__('Could not write public key into file <code>%s</code>. Please check your filesystem permissions.', 'wp-encrypt'), $this->path . '/' . self::PUBLIC_NAME)); } return true; }