Skip to content

Commit

Permalink
A simple framework to deal with future security issues in libssl
Browse files Browse the repository at this point in the history
  • Loading branch information
arr2036 committed Apr 8, 2014
1 parent d1e9855 commit dd20d3f
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 22 deletions.
4 changes: 3 additions & 1 deletion src/include/radiusd.h
Expand Up @@ -426,7 +426,7 @@ typedef struct main_config_t {
#endif
int reject_delay;
bool status_server;
bool allow_vulnerable_openssl;
char const *allow_vulnerable_openssl;

int max_request_time;
int cleanup_delay;
Expand Down Expand Up @@ -587,6 +587,8 @@ void pairlist_free(PAIR_LIST **);
/* version.c */
int rad_check_lib_magic(uint64_t magic);
int ssl_check_consistency(void);
char const *ssl_version_by_num(uint64_t version);
char const *ssl_version_range(uint64_t low, uint64_t high);
char const *ssl_version(void);
void version(void);

Expand Down
2 changes: 1 addition & 1 deletion src/include/tls-h
Expand Up @@ -293,7 +293,7 @@ void cbtls_msg(int write_p, int msg_version, int content_type, void const *buf
int cbtls_verify(int ok, X509_STORE_CTX *ctx);

/* TLS */
int tls_global_init(bool allow_vulnerable);
int tls_global_init(char const *acknowledged);
tls_session_t *tls_new_session(fr_tls_server_conf_t *conf, REQUEST *request,
int client_cert);
tls_session_t *tls_new_client_session(fr_tls_server_conf_t *conf, int fd);
Expand Down
2 changes: 1 addition & 1 deletion src/main/mainconfig.c
Expand Up @@ -99,7 +99,7 @@ static const CONF_PARSER security_config[] = {
{ "max_attributes", PW_TYPE_INTEGER, 0, &fr_max_attributes, STRINGIFY(0) },
{ "reject_delay", PW_TYPE_INTEGER, 0, &mainconfig.reject_delay, STRINGIFY(0) },
{ "status_server", PW_TYPE_BOOLEAN, 0, &mainconfig.status_server, "no"},
{ "allow_vulnerable_openssl", PW_TYPE_BOOLEAN, 0, &mainconfig.allow_vulnerable_openssl, "no"},
{ "allow_vulnerable_openssl", PW_TYPE_STRING_PTR, 0, &mainconfig.allow_vulnerable_openssl, "no"},
{ NULL, -1, 0, NULL, NULL }
};

Expand Down
52 changes: 43 additions & 9 deletions src/main/tls.c
Expand Up @@ -50,6 +50,27 @@ USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
#include <openssl/ocsp.h>
#endif

typedef struct libssl_defect {
uint64_t high;
uint64_t low;

char const *id;
char const *name;
char const *comment;
} libssl_defect_t;

/* Record critical defects in libssl here (newest first)*/
static libssl_defect_t libssl_defects[] =
{
{
.low = 0x010001000, /* 1.0.1 */
.high = 0x010001060, /* 1.0.1f */
.id = "CVE-2014-0160",
.name = "Heartbleed",
.comment = "For more information see http://heartbleed.com"
}
};

/* record */
static void record_init(record_t *buf);
static void record_close(record_t *buf);
Expand Down Expand Up @@ -1913,26 +1934,39 @@ static void sess_free_vps(UNUSED void *parent, void *data_ptr,
*
* This should be called exactly once from main.
*/
int tls_global_init(bool allow_vulnerable)
int tls_global_init(char const *acknowledged)
{
long v;
uint64_t v;

SSL_load_error_strings(); /* readable error messages (examples show call before library_init) */
SSL_library_init(); /* initialize library */
#ifdef HAVE_OPENSSL_EVP_H
OpenSSL_add_all_algorithms(); /* required for SHA2 in OpenSSL < 0.9.8o and 1.0.0.a */
#endif

if (!allow_vulnerable) {
if ((strcmp(acknowledged, libssl_defects[0].id) != 0) && (strcmp(acknowledged, "yes") != 0)) {
bool bad = false;
size_t i;

/* Check for bad versions */
v = SSLeay();
v = (uint64_t) SSLeay();

for (i = 0; i < (sizeof(libssl_defects) / sizeof(*libssl_defects)); i++) {
libssl_defect_t *defect = &libssl_defects[i];

if ((v >= defect->low) && (v <= defect->high)) {
ERROR("Refusing to start with libssl version %s (in range %s)",
ssl_version(), ssl_version_range(defect->low, defect->high));
ERROR("Security advisory %s (%s)", defect->id, defect->name);
ERROR("%s", defect->comment);

/* 1.0.1 - 1.0.1f CVE-2014-0160 http://heartbleed.com */
if ((v >= 0x010001000) && (v < 0x010001070)) {
ERROR("Refusing to start with libssl version %s (in range 1.0.1 - 1.0.1f). "
"Security advisory CVE-2014-0160 (Heartbleed)", ssl_version());
ERROR("For more information see http://heartbleed.com");
bad = true;
}
}

if (bad) {
INFO("Once you have verified libssl has been correctly patched, "
"set security.allow_vulnerable_openssl = '%s'", libssl_defects[0].id);
return -1;
}
}
Expand Down
56 changes: 46 additions & 10 deletions src/main/version.c
Expand Up @@ -59,26 +59,62 @@ int ssl_check_consistency(void)
return 0;
}

/** Convert a version number to a text string
*
* @note Not thread safe.
*
* @param v version to convert.
* @return pointer to a static buffer containing the version string.
*/
char const *ssl_version_by_num(uint64_t v)
{
static char buffer[12];

snprintf(buffer, sizeof(buffer), "%i.%i.%i%c %i",
(int) ((0xff0000000 & v) >> 28),
(int) ((0x00ff00000 & v) >> 20),
(int) ((0x0000ff000 & v) >> 12),
(char)((0x000000ff0 & v) >> 4 ? (0x60 + ((0x000000ff0 & v) >> 4)) : ' '),
(int) ((0x00000000f & v)));

return buffer;
}

/** Convert two openssl version numbers into a range string
*
* @note Not thread safe.
*
* @param low version to convert.
* @param high version to convert.
* @return pointer to a static buffer containing the version range string.
*/
char const *ssl_version_range(uint64_t low, uint64_t high)
{
static char buffer[26];

strcat(buffer, ssl_version_by_num(low));
strcat(buffer, "-");
strcat(buffer, ssl_version_by_num(high));

return buffer;
}

/** Print the current linked version of Openssl
*
* Print the currently linked version of the OpenSSL library.
*
* @note Not thread safe.
*/
char const *ssl_version(void)
{
static char buffer[1024];
uint64_t v;
static char buffer[256];

/* OpenSSL represents the version as a 36bit unsigned integer */
v = (uint64_t) SSLeay();
uint64_t v = (uint64_t) SSLeay();

snprintf(buffer, sizeof(buffer), "%s 0x%.9" PRIx64 " (%i.%i.%i%c %i)",
snprintf(buffer, sizeof(buffer), "%s 0x%.9" PRIx64 " (%s)",
SSLeay_version(SSLEAY_VERSION), /* Not all builds include a useful version number */
v,
(int) ((0x0000000ff0000000 & v) >> 28),
(int) ((0x000000000ff00000 & v) >> 20),
(int) ((0x00000000000ff000 & v) >> 12),
(char)((0x0000000000000ff0 & v) >> 4 ? (0x60 + ((0x000000000000ff0 & v) >> 4)) : ' '),
(int) ((0x000000000000000f & v)));
ssl_version_by_num((uint64_t) v));

return buffer;
}
Expand Down

0 comments on commit dd20d3f

Please sign in to comment.