/*
- * $Id$
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
*/
-#include "config.h"
+#include "squid.h"
#include "helpers/defines.h"
-#include "ssl/gadgets.h"
-#include "ssl/crtd_message.h"
#include "ssl/certificate_db.h"
+#include "ssl/crtd_message.h"
-#if HAVE_CSTRING
#include <cstring>
-#endif
-#if HAVE_SSTREAM
-#include <sstream>
-#endif
-#if HAVE_IOSTREAM
#include <iostream>
-#endif
-#if HAVE_STDEXCEPT
+#include <sstream>
#include <stdexcept>
-#endif
-#if HAVE_STRING
#include <string>
-#endif
#if HAVE_GETOPT_H
#include <getopt.h>
#endif
Create new private key and certificate request for "host.dom".
Sign new request by received certificate and private key.
-usage: ssl_crtd -c -s ssl_store_path\n -n new_serial_number
+usage: ssl_crtd -c -s ssl_store_path\n
-c Init ssl db directories and exit.
- -n new_serial_number HEX serial number to use when initializing db.
- The default value of serial number is
- the number of seconds since Epoch minus 1200000000
-usage: ssl_crtd -g -s ssl_store_path
- -g Show current serial number and exit.
\endverbatim
*/
-#define CERT_BEGIN_STR "-----BEGIN CERTIFICATE"
static const char *const B_KBYTES_STR = "KB";
static const char *const B_MBYTES_STR = "MB";
static const char *const B_GBYTES_STR = "GB";
char const * number_end = value;
while ((*number_end >= '0' && *number_end <= '9')) {
- number_end++;
+ ++number_end;
}
std::string number(number_begin, number_end - number_begin);
"-----END RSA PRIVATE KEY-----\n"
"\tCreate new private key and certificate request for \"host.dom\"\n"
"\tSign new request by received certificate and private key.\n"
- "usage: ssl_crtd -c -s ssl_store_path -n new_serial_number\n"
- "\t-c Init ssl db directories and exit.\n"
- "\t-n new_serial_number HEX serial number to use when initializing db.\n"
- "\t The default value of serial number is\n"
- "\t the number of seconds since Epoch minus 1200000000\n"
- "usage: ssl_crtd -g -s ssl_store_path\n"
- "\t-g Show current serial number and exit.";
+ "usage: ssl_crtd -c -s ssl_store_path\n"
+ "\t-c Init ssl db directories and exit.\n";
std::cerr << help_string << std::endl;
}
\ingroup ssl_crtd
* Proccess new request message.
*/
-static bool proccessNewRequest(Ssl::CrtdMessage const & request_message, std::string const & db_path, size_t max_db_size, size_t fs_block_size)
+static bool proccessNewRequest(Ssl::CrtdMessage & request_message, std::string const & db_path, size_t max_db_size, size_t fs_block_size)
{
- Ssl::CrtdMessage::BodyParams map;
- std::string body_part;
- request_message.parseBody(map, body_part);
-
- Ssl::CrtdMessage::BodyParams::iterator i = map.find(Ssl::CrtdMessage::param_host);
- if (i == map.end())
- throw std::runtime_error("Cannot find \"" + Ssl::CrtdMessage::param_host + "\" parameter in request message.");
- std::string host = i->second;
+ Ssl::CertificateProperties certProperties;
+ std::string error;
+ if (!request_message.parseRequest(certProperties, error))
+ throw std::runtime_error("Error while parsing the crtd request: " + error);
Ssl::CertificateDb db(db_path, max_db_size, fs_block_size);
Ssl::X509_Pointer cert;
Ssl::EVP_PKEY_Pointer pkey;
- Ssl::X509_Pointer certToMimic;
-
- const char *s;
- std::string cert_subject;
- if ((s = strstr(body_part.c_str(), CERT_BEGIN_STR))) {
- s += strlen(CERT_BEGIN_STR);
- if ((s = strstr(s, CERT_BEGIN_STR))) {
- Ssl::readCertFromMemory(certToMimic, s);
- if (certToMimic.get()) {
- char buf[1024];
- cert_subject = X509_NAME_oneline(X509_get_subject_name(certToMimic.get()), buf, sizeof(buf));
- }
- }
- }
-
- if (cert_subject.empty())
- cert_subject = "/CN=" + host;
-
- i = map.find(Ssl::CrtdMessage::param_SetValidAfter);
- if (i != map.end() && strcasecmp(i->second.c_str(), "on") == 0)
- cert_subject.append("+SetValidAfter=on");
-
- i = map.find(Ssl::CrtdMessage::param_SetValidBefore);
- if (i != map.end() && strcasecmp(i->second.c_str(), "on") == 0)
- cert_subject.append("+SetValidBefore=on");
-
- i = map.find(Ssl::CrtdMessage::param_SetCommonName);
- if (i != map.end()) {
- cert_subject.append("+SetCommonName=");
- cert_subject.append(i->second);
- }
+ std::string &cert_subject = certProperties.dbKey();
db.find(cert_subject, cert, pkey);
- if (cert.get() && certToMimic.get()) {
- if (!Ssl::ssl_match_certificates(cert.get(), certToMimic.get())) {
+ if (cert.get()) {
+ if (!Ssl::certificateMatchesProperties(cert.get(), certProperties)) {
// The certificate changed (renewed or other reason).
// Generete a new one with the updated fields.
cert.reset(NULL);
pkey.reset(NULL);
+ db.purgeCert(cert_subject);
}
}
if (!cert || !pkey) {
- Ssl::X509_Pointer certToSign;
- Ssl::EVP_PKEY_Pointer pkeyToSign;
- Ssl::readCertAndPrivateKeyFromMemory(certToSign, pkeyToSign, body_part.c_str());
-
- Ssl::BIGNUM_Pointer serial(db.getCurrentSerialNumber());
-
- if (certToMimic.get()) {
- Ssl::generateSslCertificate(certToMimic, certToSign, pkeyToSign, cert, pkey, serial.get(), map);
- }
- else
- if (!Ssl::generateSslCertificateAndPrivateKey(host.c_str(), certToSign, pkeyToSign, cert, pkey, serial.get()))
- throw std::runtime_error("Cannot create ssl certificate or private key.");
+ if (!Ssl::generateSslCertificate(cert, pkey, certProperties))
+ throw std::runtime_error("Cannot create ssl certificate or private key.");
if (!db.addCertAndPrivateKey(cert, pkey, cert_subject) && db.IsEnabledDiskStore())
throw std::runtime_error("Cannot add certificate to db.");
if (!Ssl::writeCertAndPrivateKeyToMemory(cert, pkey, bufferToWrite))
throw std::runtime_error("Cannot write ssl certificate or/and private key to memory.");
- Ssl::CrtdMessage response_message;
+ Ssl::CrtdMessage response_message(Ssl::CrtdMessage::REPLY);
response_message.setCode("OK");
response_message.setBody(bufferToWrite);
int main(int argc, char *argv[])
{
try {
- int serial = (getCurrentTime() - 1200000000);
size_t max_db_size = 0;
size_t fs_block_size = 2048;
- char c;
+ int8_t c;
bool create_new_db = false;
- bool show_sn = false;
std::string db_path;
// proccess options.
while ((c = getopt(argc, argv, "dcghvs:M:b:n:")) != -1) {
case 's':
db_path = optarg;
break;
- case 'n': {
- std::stringstream sn_stream(optarg);
- sn_stream >> std::hex >> serial;
- break;
- }
case 'M':
if (!parseBytesOptionValue(&max_db_size, optarg)) {
throw std::runtime_error("Error when parsing -M options value");
case 'c':
create_new_db = true;
break;
- case 'g':
- show_sn = true;
- break;
case 'h':
usage();
exit(0);
if (create_new_db) {
std::cout << "Initialization SSL db..." << std::endl;
- Ssl::CertificateDb::create(db_path, serial);
+ Ssl::CertificateDb::create(db_path);
std::cout << "Done" << std::endl;
exit(0);
}
- if (show_sn) {
- Ssl::CertificateDb db(db_path, 4096, 0);
- std::cout << db.getSNString() << std::endl;
- exit(0);
- }
{
- Ssl::CertificateDb::check(db_path, max_db_size);
+ Ssl::CertificateDb::check(db_path, max_db_size, fs_block_size);
}
+ // Initialize SSL subsystem
+ SSL_load_error_strings();
+ SSLeay_add_ssl_algorithms();
// proccess request.
for (;;) {
char request[HELPER_INPUT_BUFFER];
- Ssl::CrtdMessage request_message;
+ Ssl::CrtdMessage request_message(Ssl::CrtdMessage::REQUEST);
Ssl::CrtdMessage::ParseResult parse_result = Ssl::CrtdMessage::INCOMPLETE;
while (parse_result == Ssl::CrtdMessage::INCOMPLETE) {
}
return 0;
}
+