* disable the certificate DB disk cache if -s and -M command line options are omitted.
E.g. with this you can change squid.conf from:
sslcrtd_program security_file_certgen -s /var/lib/ssl_db -M 32MB
...to...
sslcrtd_program security_file_certgen
...and it will operate without the disk cache, generating certs fresh every time.
* Remove Ssl::CertificateDb::IsEnabledDiskStore()
Make the CertificateDb temporary objects dynamically allocated instead.
* Do command line checks in main() not the CertificateDb object.
This avoids a risky constructor exception and simplifies validity testing of parameters.
* Update man(8) documentation
The helper version is now 1.1. A minor version bump since it is being kept compatible with
installations using 1.0 properly but new feature available.
Also simplify the command line SYNOPSIS and incomplete mention of sslcrtd_* squid.conf directives.
size_full(aDb_path + "/" + size_file),
max_db_size(aMax_db_size),
fs_block_size((aFs_block_size ? aFs_block_size : 2048)),
- dbLock(db_full),
- enabled_disk_store(true) {
- if (db_path.empty() && !max_db_size)
- enabled_disk_store = false;
- else if ((db_path.empty() && max_db_size) || (!db_path.empty() && !max_db_size))
- throw std::runtime_error("security_file_certgen is missing the required parameter. There should be -s and -M parameters together.");
-}
+ dbLock(db_full)
+{}
bool
Ssl::CertificateDb::find(std::string const &key, const Security::CertPointer &expectedOrig, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey)
return true;
}
-bool Ssl::CertificateDb::IsEnabledDiskStore() const {
- return enabled_disk_store;
-}
-
bool
Ssl::CertificateDb::WriteEntry(const std::string &filename, const Security::CertPointer &cert, const Security::PrivateKeyPointer &pkey, const Security::CertPointer &orig)
{
/// Save certificate to disk.
bool addCertAndPrivateKey(std::string const & useKey, const Security::CertPointer & cert, const Security::PrivateKeyPointer & pkey, const Security::CertPointer &orig);
- bool IsEnabledDiskStore() const; ///< Check enabled of dist store.
-
/// Create and initialize a database under the db_path
static void Create(std::string const & db_path);
/// Check the database stored under the db_path.
const size_t max_db_size; ///< Max size of db.
const size_t fs_block_size; ///< File system block size.
mutable Lock dbLock; ///< protects the database file
-
- bool enabled_disk_store; ///< The storage on the disk is enabled.
};
} // namespace Ssl
.SH NAME
security_file_certgen \- SSL certificate generator for Squid.
.PP
-Version 1.0
+Version 1.1
.
.SH SYNOPSIS
.if !'po4a'hide' .B security_file_certgen
-.if !'po4a'hide' .B [\-dhv]
-.br
-.if !'po4a'hide' .B security_file_certgen
-.if !'po4a'hide' .B "[\-d] \-s "
+.if !'po4a'hide' .B "[\-cdhv] [\-s "
directory
-.if !'po4a'hide' .B "[\-M "
+.if !'po4a'hide' .B "\-M "
size
.if !'po4a'hide' .B "] [\-b "
fs_block_size
.if !'po4a'hide' .B ]
-.br
-.if !'po4a'hide' .B security_file_certgen
-.if !'po4a'hide' .B "[\-d] \-c \-s "
-directory
.
.SH DESCRIPTION
.B security_file_certgen
is an installed binary.
.PP
Because the generation and signing of SSL certificates takes time
-Squid must use external process to handle the work.
+Squid can use this helper as an external process to handle the work.
.
-This process generates new SSL certificates and uses a disk cache of certificates
-to improve response times on repeated requests.
Communication occurs via TCP sockets bound to the loopback interface.
.
+This helper can use a disk cache of certificates to improve response
+times on repeated requests. It can also operate without a cache,
+generating new certificates on every request.
+.
.SH OPTIONS
.if !'po4a'hide' .TP 12
.if !'po4a'hide' .B \-b fs_block_size
File system block size in bytes. Needed for processing natural size of certificate on disk.
-Default value is 2048 bytes. The following suffixes are accepted: B, KB, MB, GB.
-When no suffix is set, B is assumed.
+Default value is 2048 bytes.
+The following suffixes are accepted:
+.B B, KB, MB, GB.
+When no suffix is set,
+.B B
+is assumed.
.
.if !'po4a'hide' .TP
.if !'po4a'hide' .B \-c
Initialize the SSL storage database and exit. Requires the
.B \-s
-option to determine the storage location being created.
+and
+.B \-M
+options to determine the storage location and size being created.
.
.if !'po4a'hide' .TP
.if !'po4a'hide' .B \-d
.
.if !'po4a'hide' .TP
.if !'po4a'hide' .B \-s directory
-Directory path of SSL storage database.
+Directory path of SSL storage database. Requires the
+.B \-M
+option.
.
.if !'po4a'hide' .TP
.if !'po4a'hide' .B \-M size
.
.PP
Certificates are stored in this database in signed form.
-After any change to the signing CA in squid.conf be sure to erase and re-initialize the certificate database.
+After any change to the signing CA in squid.conf be sure to erase and reinitialize the certificate database.
.
.PP
.B Certificate chaining
.
.PP
-The version 1.0 of this helper will not add chained intermediate CA certificates.
+The versions 1.0 to 1.1 of this helper will not add chained intermediate CA certificates.
The client must have a full chain of trust from the root CA all the way
down to the end certificate generated by this program.
.
.
.SH CONFIGURATION
.PP
-Before this helper can be used the storage area for new certificates must be initialized manually.
+Before this helper can be used with disk storage, the storage area for new certificates must be initialized manually.
This is done from the command line using the
.B \-c
parameter.
.PP
For example:
.if !'po4a'hide' .RS
-.if !'po4a'hide' .B @DEFAULT_SSL_CRTD@ \-c \-s @DEFAULT_SSL_DB_DIR@
+.if !'po4a'hide' .B @DEFAULT_SSL_CRTD@ \-c \-s @DEFAULT_SSL_DB_DIR@ \-M 4MB
.if !'po4a'hide' .RE
.
.PP
.PP
For simple configuration the helper defaults can be used.
Only HTTP listening port options are required to enable generation and set the signing CA certificate.
-For Example:
+.
+.PP
+For example:
.if !'po4a'hide' .RS
.if !'po4a'hide' .B http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=@SYSCONFDIR@/ssl_cert/example.com.pem
.if !'po4a'hide' .RE
.
.PP
-For more customized configuration the helper certificate storage directory location and size can be altered with the
-.B sslcrtd_program
+For more customized configuration, the helper certificate storage directory location and size can be altered with the
+.B sslcrtd_program
+configuration directive. The number of helper processes running can be configured with the
+and
+.B ssl_crtd_children
configuration directive.
+.
+.PP
For example:
.if !'po4a'hide' .RS
.if !'po4a'hide' .B sslcrtd_program @DEFAULT_SSL_CRTD@ \-s @DEFAULT_SSL_DB_DIR@ \-M 4MB
.if !'po4a'hide' .B sslcrtd_children 5
.if !'po4a'hide' .RE
.
+.PP
+To operate without disk storage, the helper should be configured explicitly without the
+.B \-s
+and
+.B \-M
+parameters.
+.
+.PP
+For example:
+.if !'po4a'hide' .RS
+.if !'po4a'hide' .B sslcrtd_program @DEFAULT_SSL_CRTD@
+.if !'po4a'hide' .RE
+.
.SH AUTHOR
This program was written by
.if !'po4a'hide' .I Christos Tsantilas <christos@chtsanti.net>
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);
+ // TODO: create a DB object only once, instead re-allocating here on every call.
+ std::unique_ptr<Ssl::CertificateDb> db;
+ if (!db_path.empty())
+ db.reset(new Ssl::CertificateDb(db_path, max_db_size, fs_block_size));
Security::CertPointer cert;
Security::PrivateKeyPointer pkey;
bool dbFailed = false;
try {
- db.find(certKey, certProperties.mimicCert, cert, pkey);
+ if (db)
+ db->find(certKey, certProperties.mimicCert, cert, pkey);
+
} catch (std::runtime_error &err) {
dbFailed = true;
error = err.what();
if (!Ssl::generateSslCertificate(cert, pkey, certProperties))
throw std::runtime_error("Cannot create ssl certificate or private key.");
- if (!dbFailed && db.IsEnabledDiskStore()) {
- try {
- if (!db.addCertAndPrivateKey(certKey, cert, pkey, certProperties.mimicCert)) {
- dbFailed = true;
- error = "Cannot add certificate to db.";
- }
- } catch (const std::runtime_error &err) {
- dbFailed = true;
- error = err.what();
- }
+ try {
+ /* XXX: this !dbFailed condition prevents the helper fixing DB issues
+ by adding cleanly generated certs. Which is not consistent with other
+ data caches used by Squid - they purge broken entries and allow clean
+ entries to later try and fix the issue.
+ We leave it in place now only to avoid breaking existing installations
+ behaviour with version 1.x of the helper.
+
+ TODO: remove the !dbFailed condition when fixing the CertificateDb
+ object lifecycle and formally altering the helper behaviour.
+ */
+ if (!dbFailed && db && !db->addCertAndPrivateKey(certKey, cert, pkey, certProperties.mimicCert))
+ throw std::runtime_error("Cannot add certificate to db.");
+
+ } catch (const std::runtime_error &err) {
+ dbFailed = true;
+ error = err.what();
}
}
db_path = optarg;
break;
case 'M':
+ // use of -M without -s is probably an admin mistake, so make it an error
+ if (db_path.empty()) {
+ throw std::runtime_error("Error -M option requires an -s parameter be set first.");
+ }
if (!parseBytesOptionValue(&max_db_size, optarg)) {
throw std::runtime_error("Error when parsing -M options value");
}
}
}
+ // when -s is used, -M is required
+ if (!db_path.empty() && max_db_size == 0)
+ throw std::runtime_error("security_file_certgen -s requires an -M parameter");
+
if (create_new_db) {
+ // when -c is used, -s is required (implying also -M, which is checked above)
+ if (db_path.empty())
+ throw std::runtime_error("security_file_certgen is missing the required parameter. There should be -s and -M parameters when -c is used.");
+
std::cout << "Initialization SSL db..." << std::endl;
Ssl::CertificateDb::Create(db_path);
std::cout << "Done" << std::endl;
exit(EXIT_SUCCESS);
}
- if (fs_block_size == 0) {
- struct statvfs sfs;
-
- if (xstatvfs(db_path.c_str(), &sfs)) {
- fs_block_size = 2048;
- } else {
- fs_block_size = sfs.f_frsize;
- // Sanity check; make sure we have a meaningful value.
- if (fs_block_size < 512)
- fs_block_size = 2048;
+ // only do filesystem checks when a path (-s) is given
+ if (!db_path.empty()) {
+ if (fs_block_size == 0) {
+ struct statvfs sfs;
+
+ if (xstatvfs(db_path.c_str(), &sfs)) {
+ fs_block_size = 2048;
+ } else {
+ fs_block_size = sfs.f_frsize;
+ // Sanity check; make sure we have a meaningful value.
+ if (fs_block_size < 512)
+ fs_block_size = 2048;
+ }
}
- }
-
- {
Ssl::CertificateDb::Check(db_path, max_db_size, fs_block_size);
}
+
// Initialize SSL subsystem
SSL_load_error_strings();
SSLeay_add_ssl_algorithms();