mirror of https://github.com/Icinga/icinga2.git
parent
425dbba35b
commit
c1b92756b5
|
@ -253,8 +253,7 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
||||||
|
|
||||||
Log(LogInformation, "base", "Writing private key to '" + keyfile + "'.");
|
Log(LogInformation, "base", "Writing private key to '" + keyfile + "'.");
|
||||||
|
|
||||||
BIO *bio = BIO_new(BIO_s_file());
|
BIO *bio = BIO_new_file(const_cast<char *>(keyfile.CStr()), "w");
|
||||||
BIO_write_filename(bio, const_cast<char *>(keyfile.CStr()));
|
|
||||||
PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL);
|
PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL);
|
||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
|
|
||||||
|
@ -262,40 +261,16 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
||||||
chmod(keyfile.CStr(), 0600);
|
chmod(keyfile.CStr(), 0600);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
X509_REQ *req = X509_REQ_new();
|
|
||||||
|
|
||||||
if (!req)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
EVP_PKEY *key = EVP_PKEY_new();
|
EVP_PKEY *key = EVP_PKEY_new();
|
||||||
EVP_PKEY_assign_RSA(key, rsa);
|
EVP_PKEY_assign_RSA(key, rsa);
|
||||||
|
|
||||||
if (!certfile.IsEmpty()) {
|
if (!certfile.IsEmpty()) {
|
||||||
X509 *cert = X509_new();
|
X509_NAME *subject = X509_NAME_new();
|
||||||
ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
|
X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0);
|
||||||
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 *name = X509_get_subject_name(cert);
|
X509 *cert = CreateCert(key, subject, subject, key, ca);
|
||||||
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_NAME_free(subject);
|
||||||
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 + "'.");
|
Log(LogInformation, "base", "Writing X509 certificate to '" + certfile + "'.");
|
||||||
|
|
||||||
|
@ -308,6 +283,11 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!csrfile.IsEmpty()) {
|
if (!csrfile.IsEmpty()) {
|
||||||
|
X509_REQ *req = X509_REQ_new();
|
||||||
|
|
||||||
|
if (!req)
|
||||||
|
return 0;
|
||||||
|
|
||||||
X509_REQ_set_version(req, 0);
|
X509_REQ_set_version(req, 0);
|
||||||
X509_REQ_set_pubkey(req, key);
|
X509_REQ_set_pubkey(req, key);
|
||||||
|
|
||||||
|
@ -331,6 +311,35 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
||||||
return 1;
|
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)
|
String SHA256(const String& s)
|
||||||
{
|
{
|
||||||
std::ostringstream msgbuf;
|
std::ostringstream msgbuf;
|
||||||
|
|
|
@ -39,6 +39,7 @@ void I2_BASE_API AddCRLToSSLContext(const shared_ptr<SSL_CTX>& context, const St
|
||||||
String I2_BASE_API GetCertificateCN(const shared_ptr<X509>& certificate);
|
String I2_BASE_API GetCertificateCN(const shared_ptr<X509>& certificate);
|
||||||
shared_ptr<X509> I2_BASE_API GetX509Certificate(const String& pemfile);
|
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);
|
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);
|
String I2_BASE_API SHA256(const String& s);
|
||||||
|
|
||||||
class I2_BASE_API openssl_error : virtual public std::exception, virtual public boost::exception { };
|
class I2_BASE_API openssl_error : virtual public std::exception, virtual public boost::exception { };
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
set(cli_SOURCES
|
set(cli_SOURCES
|
||||||
featureenablecommand.cpp featuredisablecommand.cpp featurelistcommand.cpp
|
featureenablecommand.cpp featuredisablecommand.cpp featurelistcommand.cpp
|
||||||
objectlistcommand.cpp
|
objectlistcommand.cpp
|
||||||
pkinewcacommand.cpp pkinewcertcommand.cpp
|
pkinewcacommand.cpp pkinewcertcommand.cpp pkisigncsrcommand.cpp
|
||||||
daemoncommand.cpp
|
daemoncommand.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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 */
|
Loading…
Reference in New Issue