Log(LogInformation, "base", "Writing private key to '" + keyfile + "'.");
- BIO *bio = BIO_new(BIO_s_file());
- BIO_write_filename(bio, const_cast<char *>(keyfile.CStr()));
+ BIO *bio = BIO_new_file(const_cast<char *>(keyfile.CStr()), "w");
PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL);
BIO_free(bio);
chmod(keyfile.CStr(), 0600);
#endif /* _WIN32 */
- X509_REQ *req = X509_REQ_new();
-
- if (!req)
- return 0;
-
EVP_PKEY *key = EVP_PKEY_new();
EVP_PKEY_assign_RSA(key, rsa);
if (!certfile.IsEmpty()) {
- X509 *cert = X509_new();
- ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
- X509_gmtime_adj(X509_get_notBefore(cert), 0);
- X509_gmtime_adj(X509_get_notAfter(cert), 365 * 24 * 60 * 60 * 30);
- X509_set_pubkey(cert, key);
+ X509_NAME *subject = X509_NAME_new();
+ X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0);
+
+ X509 *cert = CreateCert(key, subject, subject, key, ca);
+
+ X509_NAME_free(subject);
- X509_NAME *name = X509_get_subject_name(cert);
- X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0);
- X509_set_issuer_name(cert, name);
-
- if (ca) {
- X509_EXTENSION *ext;
- X509V3_CTX ctx;
- X509V3_set_ctx_nodb(&ctx);
- X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
- ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, const_cast<char *>("critical,CA:TRUE"));
-
- if (ext)
- X509_add_ext(cert, ext, -1);
-
- X509_EXTENSION_free(ext);
- }
-
-
- X509_sign(cert, key, EVP_sha1());
-
Log(LogInformation, "base", "Writing X509 certificate to '" + certfile + "'.");
-
+
bio = BIO_new(BIO_s_file());
BIO_write_filename(bio, const_cast<char *>(certfile.CStr()));
PEM_write_bio_X509(bio, cert);
BIO_free(bio);
-
+
X509_free(cert);
}
if (!csrfile.IsEmpty()) {
+ X509_REQ *req = X509_REQ_new();
+
+ if (!req)
+ return 0;
+
X509_REQ_set_version(req, 0);
X509_REQ_set_pubkey(req, key);
return 1;
}
+X509 *CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, bool ca, const String& serialfile)
+{
+ X509 *cert = X509_new();
+ ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
+ X509_gmtime_adj(X509_get_notBefore(cert), 0);
+ X509_gmtime_adj(X509_get_notAfter(cert), 365 * 24 * 60 * 60 * 30);
+ X509_set_pubkey(cert, pubkey);
+
+ X509_set_subject_name(cert, subject);
+ X509_set_issuer_name(cert, issuer);
+
+ if (ca) {
+ X509_EXTENSION *ext;
+ X509V3_CTX ctx;
+ X509V3_set_ctx_nodb(&ctx);
+ X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
+ ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, const_cast<char *>("critical,CA:TRUE"));
+
+ if (ext)
+ X509_add_ext(cert, ext, -1);
+
+ X509_EXTENSION_free(ext);
+ }
+
+ X509_sign(cert, cakey, EVP_sha1());
+
+ return cert;
+}
+
String SHA256(const String& s)
{
std::ostringstream msgbuf;
String I2_BASE_API GetCertificateCN(const shared_ptr<X509>& certificate);
shared_ptr<X509> I2_BASE_API GetX509Certificate(const String& pemfile);
int I2_BASE_API MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile = String(), const String& certfile = String(), bool ca = false);
+X509 * I2_BASE_API CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, bool ca, const String& serialfile = String());
String I2_BASE_API SHA256(const String& s);
class I2_BASE_API openssl_error : virtual public std::exception, virtual public boost::exception { };
set(cli_SOURCES
featureenablecommand.cpp featuredisablecommand.cpp featurelistcommand.cpp
objectlistcommand.cpp
- pkinewcacommand.cpp pkinewcertcommand.cpp
+ pkinewcacommand.cpp pkinewcertcommand.cpp pkisigncsrcommand.cpp
daemoncommand.cpp
)
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#include "cli/pkisigncsrcommand.hpp"
+#include "base/logger_fwd.hpp"
+#include "base/clicommand.hpp"
+#include "base/tlsutility.hpp"
+#include "base/application.hpp"
+
+using namespace icinga;
+namespace po = boost::program_options;
+
+REGISTER_CLICOMMAND("pki/sign-csr", PKISignCSRCommand);
+
+String PKISignCSRCommand::GetDescription(void) const
+{
+ return "Reads a Certificate Signing Request from stdin and prints a signed certificate on stdout.";
+}
+
+String PKISignCSRCommand::GetShortDescription(void) const
+{
+ return "signs a CSR";
+}
+
+void PKISignCSRCommand::InitParameters(boost::program_options::options_description& visibleDesc,
+ boost::program_options::options_description& hiddenDesc,
+ ArgumentCompletionDescription& argCompletionDesc) const
+{
+ /* Command doesn't support any parameters. */
+}
+
+/**
+ * The entry point for the "pki sign-csr" CLI command.
+ *
+ * @returns An exit status.
+ */
+int PKISignCSRCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
+{
+ BIO *csrbio = BIO_new_fp(stdin, BIO_NOCLOSE);
+ X509_REQ *req;
+ PEM_read_bio_X509_REQ(csrbio, &req, NULL, NULL);
+ BIO_free(csrbio);
+
+ String cadir = Application::GetLocalStateDir() + "/lib/icinga2/ca";
+
+ String cakeyfile = cadir + "/ca.key";
+
+ RSA *rsa;
+
+ BIO *cakeybio = BIO_new_file(const_cast<char *>(cakeyfile.CStr()), "r");
+ rsa = PEM_read_bio_RSAPrivateKey(cakeybio, NULL, NULL, NULL);
+ BIO_free(cakeybio);
+
+ String cacertfile = cadir + "/ca.crt";
+
+ BIO *cacertbio = BIO_new_file(const_cast<char *>(cacertfile.CStr()), "r");
+ X509 *cacert = PEM_read_bio_X509(cacertbio, NULL, NULL, NULL);
+ BIO_free(cacertbio);
+
+ EVP_PKEY *privkey = EVP_PKEY_new();
+ EVP_PKEY_assign_RSA(privkey, rsa);
+
+ EVP_PKEY *pubkey = X509_REQ_get_pubkey(req);
+
+ X509 *cert = CreateCert(pubkey, X509_REQ_get_subject_name(req), X509_get_subject_name(cacert), privkey, false);
+
+ X509_free(cacert);
+
+ BIO *certbio = BIO_new_fp(stdout, BIO_NOCLOSE);
+ PEM_write_bio_X509(certbio, cert);
+ BIO_free(certbio);
+
+ return 0;
+}
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#ifndef PKISIGNCSRCOMMAND_H
+#define PKISIGNCSRCOMMAND_H
+
+#include "base/qstring.hpp"
+#include "base/clicommand.hpp"
+
+namespace icinga
+{
+
+/**
+ * The "pki sign-csr" command.
+ *
+ * @ingroup cli
+ */
+class PKISignCSRCommand : public CLICommand
+{
+public:
+ DECLARE_PTR_TYPEDEFS(PKISignCSRCommand);
+
+ virtual String GetDescription(void) const;
+ virtual String GetShortDescription(void) const;
+ virtual void InitParameters(boost::program_options::options_description& visibleDesc,
+ boost::program_options::options_description& hiddenDesc,
+ ArgumentCompletionDescription& argCompletionDesc) const;
+ virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
+
+};
+
+}
+
+#endif /* PKISIGNCSRCOMMAND_H */