On Fri, Aug 15, 2014 at 13:06, Ted Unangst wrote:
> Instead, ressl should copy all parameters as necessary and
> free them. This does introduce an error case into formerly void
> functions, but I think that's ok. The alternative would be to use
> fixed arrays inside ressl_config, but that seems much worse.
Here's a complete diff.
(I think we should also zero the key memory if not null, but that's not
included in this change.)
Index: ressl.h
===================================================================
RCS file: /cvs/src/lib/libressl/ressl.h,v
retrieving revision 1.13
diff -u -p -r1.13 ressl.h
--- ressl.h 27 Aug 2014 10:46:53 -0000 1.13
+++ ressl.h 10 Sep 2014 20:23:46 -0000
@@ -31,15 +31,15 @@ const char *ressl_error(struct ressl *ct
struct ressl_config *ressl_config_new(void);
void ressl_config_free(struct ressl_config *config);
-void ressl_config_set_ca_file(struct ressl_config *config, char *ca_file);
-void ressl_config_set_ca_path(struct ressl_config *config, char *ca_path);
-void ressl_config_set_cert_file(struct ressl_config *config, char *cert_file);
-void ressl_config_set_cert_mem(struct ressl_config *config, char *cert,
+int ressl_config_set_ca_file(struct ressl_config *config, char *ca_file);
+int ressl_config_set_ca_path(struct ressl_config *config, char *ca_path);
+int ressl_config_set_cert_file(struct ressl_config *config, char *cert_file);
+int ressl_config_set_cert_mem(struct ressl_config *config, char *cert,
size_t len);
-void ressl_config_set_ciphers(struct ressl_config *config, char *ciphers);
+int ressl_config_set_ciphers(struct ressl_config *config, char *ciphers);
int ressl_config_set_ecdhcurve(struct ressl_config *config, const char *);
-void ressl_config_set_key_file(struct ressl_config *config, char *key_file);
-void ressl_config_set_key_mem(struct ressl_config *config, char *key,
+int ressl_config_set_key_file(struct ressl_config *config, char *key_file);
+int ressl_config_set_key_mem(struct ressl_config *config, char *key,
size_t len);
void ressl_config_set_verify_depth(struct ressl_config *config,
int verify_depth);
Index: ressl_config.c
===================================================================
RCS file: /cvs/src/lib/libressl/ressl_config.c,v
retrieving revision 1.8
diff -u -p -r1.8 ressl_config.c
--- ressl_config.c 27 Aug 2014 10:46:53 -0000 1.8
+++ ressl_config.c 10 Sep 2014 20:35:24 -0000
@@ -21,27 +21,55 @@
#include <ressl.h>
#include "ressl_internal.h"
-/*
- * Default configuration.
- */
-struct ressl_config ressl_config_default = {
- .ca_file = _PATH_SSL_CA_FILE,
- .ca_path = NULL,
- .ciphers = NULL,
- .ecdhcurve = NID_X9_62_prime256v1,
- .verify = 1,
- .verify_depth = 6,
-};
+#define SET_STRING(config, name, val) do { \
+ free(config->name); \
+ config->name = NULL; \
+ if (val != NULL) { \
+ if ((config->name = strdup(val)) == NULL) \
+ return -1; \
+ } \
+} while (0)
+
+#define SET_MEM(config, name, namelen, val, vallen) do { \
+ free(config->name); \
+ config->name = NULL; \
+ if (val != NULL) { \
+ if ((config->name = memdup(val, vallen)) == NULL) \
+ return -1; \
+ config->namelen = vallen; \
+ } \
+} while (0)
+
+static void *
+memdup(const void *in, size_t len)
+{
+ void *out;
+
+ if ((out = malloc(len)) == NULL)
+ return NULL;
+ memcpy(out, in, len);
+ return out;
+}
struct ressl_config *
ressl_config_new(void)
{
struct ressl_config *config;
- if ((config = malloc(sizeof(*config))) == NULL)
+ if ((config = calloc(1, sizeof(*config))) == NULL)
return (NULL);
- memcpy(config, &ressl_config_default, sizeof(*config));
+ /*
+ * Default configuration.
+ */
+ if (ressl_config_set_ca_file(config, _PATH_SSL_CA_FILE) != 0) {
+ ressl_config_free(config);
+ return (NULL);
+ }
+ ressl_config_verify(config);
+ ressl_config_set_verify_depth(config, 6);
+ /* ? use function ? */
+ config->ecdhcurve = NID_X9_62_prime256v1;
return (config);
}
@@ -49,38 +77,49 @@ ressl_config_new(void)
void
ressl_config_free(struct ressl_config *config)
{
+ free(config->ca_file);
+ free(config->ca_path);
+ free(config->cert_file);
+ free(config->cert_mem);
+ free(config->ciphers);
+ free(config->key_file);
+ free(config->key_mem);
free(config);
}
-void
+int
ressl_config_set_ca_file(struct ressl_config *config, char *ca_file)
{
- config->ca_file = ca_file;
+ SET_STRING(config, ca_file, ca_file);
+ return 0;
}
-void
+int
ressl_config_set_ca_path(struct ressl_config *config, char *ca_path)
{
- config->ca_path = ca_path;
+ SET_STRING(config, ca_path, ca_path);
+ return 0;
}
-void
+int
ressl_config_set_cert_file(struct ressl_config *config, char *cert_file)
{
- config->cert_file = cert_file;
+ SET_STRING(config, cert_file, cert_file);
+ return 0;
}
-void
+int
ressl_config_set_cert_mem(struct ressl_config *config, char *cert, size_t len)
{
- config->cert_mem = cert;
- config->cert_len = len;
+ SET_MEM(config, cert_mem, cert_len, cert, len);
+ return 0;
}
-void
+int
ressl_config_set_ciphers(struct ressl_config *config, char *ciphers)
{
- config->ciphers = ciphers;
+ SET_STRING(config, ciphers, ciphers);
+ return 0;
}
int
@@ -95,17 +134,18 @@ ressl_config_set_ecdhcurve(struct ressl_
return (0);
}
-void
+int
ressl_config_set_key_file(struct ressl_config *config, char *key_file)
{
- config->key_file = key_file;
+ SET_STRING(config, key_file, key_file);
+ return 0;
}
-void
+int
ressl_config_set_key_mem(struct ressl_config *config, char *key, size_t len)
{
- config->key_mem = key;
- config->key_len = len;
+ SET_MEM(config, key_mem, key_len, key, len);
+ return 0;
}
void
Index: ressl_internal.h
===================================================================
RCS file: /cvs/src/lib/libressl/ressl_internal.h,v
retrieving revision 1.10
diff -u -p -r1.10 ressl_internal.h
--- ressl_internal.h 27 Aug 2014 10:46:53 -0000 1.10
+++ ressl_internal.h 10 Sep 2014 20:27:51 -0000
@@ -26,14 +26,14 @@
#define _PATH_SSL_CA_FILE "/etc/ssl/cert.pem"
struct ressl_config {
- const char *ca_file;
- const char *ca_path;
- const char *cert_file;
+ char *ca_file;
+ char *ca_path;
+ char *cert_file;
char *cert_mem;
size_t cert_len;
- const char *ciphers;
+ char *ciphers;
int ecdhcurve;
- const char *key_file;
+ char *key_file;
char *key_mem;
size_t key_len;
int verify;