Skip to content

Commit 40deb49

Browse files
committed
Merge pull request #120 from acv/ssl-refactor
Split out SSL init from https_get
2 parents 0f3734f + b20a49a commit 40deb49

File tree

4 files changed

+117
-43
lines changed

4 files changed

+117
-43
lines changed

src/conf.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ typedef enum {
100100
oProxyPort,
101101
oSSLPeerVerification,
102102
oSSLCertPath,
103+
oSSLAllowedCipherList,
103104
} OpCodes;
104105

105106
/** @internal
@@ -142,6 +143,7 @@ static const struct {
142143
{ "proxyport", oProxyPort },
143144
{ "sslpeerverification", oSSLPeerVerification },
144145
{ "sslcertpath", oSSLCertPath },
146+
{ "sslallowedcipherlist", oSSLAllowedCipherList },
145147
{ NULL, oBadOption },
146148
};
147149

@@ -193,6 +195,7 @@ config_init(void)
193195
config.proxy_port = 0;
194196
config.ssl_certs = safe_strdup(DEFAULT_AUTHSERVSSLCERTPATH);
195197
config.ssl_verify = DEFAULT_AUTHSERVSSLPEERVER;
198+
config.ssl_cipher_list = NULL;
196199
}
197200

198201
/**
@@ -738,13 +741,6 @@ config_read(const char *filename)
738741
case oHTTPDPassword:
739742
config.httpdpassword = safe_strdup(p1);
740743
break;
741-
case oBadOption:
742-
debug(LOG_ERR, "Bad option on line %d "
743-
"in %s.", linenum,
744-
filename);
745-
debug(LOG_ERR, "Exiting...");
746-
exit(-1);
747-
break;
748744
case oCheckInterval:
749745
sscanf(p1, "%d", &config.checkinterval);
750746
break;
@@ -778,6 +774,21 @@ config_read(const char *filename)
778774
debug(LOG_WARNING, "SSLPeerVerification is set but no SSL compiled in. Ignoring!");
779775
#endif
780776
break;
777+
case oSSLAllowedCipherList:
778+
config.ssl_cipher_list = safe_strdup(p1);
779+
#ifndef USE_CYASSL
780+
debug(LOG_WARNING, "SSLAllowedCipherList is set but no SSL compiled in. Ignoring!");
781+
#endif
782+
break;
783+
case oBadOption:
784+
/* FALL THROUGH */
785+
default:
786+
debug(LOG_ERR, "Bad option on line %d "
787+
"in %s.", linenum,
788+
filename);
789+
debug(LOG_ERR, "Exiting...");
790+
exit(-1);
791+
break;
781792
}
782793
}
783794
}

src/conf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ typedef struct {
171171
verification */
172172
int ssl_verify; /**< @brief boolean, whether to enable
173173
auth server certificate verification */
174+
char *ssl_cipher_list; /**< @brief List of SSL ciphers allowed. Optional. */
174175
t_firewall_ruleset *rulesets; /**< @brief firewall rules */
175176
t_trusted_mac *trustedmaclist; /**< @brief list of trusted macs */
176177
} s_config;

src/simple_http.c

Lines changed: 84 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@
4444
#include <cyassl/ctaocrypt/error-crypt.h>
4545
#endif
4646

47-
int http_get(const int sockfd, char *buf) {
47+
#ifdef USE_CYASSL
48+
static CYASSL_CTX *get_cyassl_ctx(void);
49+
#endif
50+
51+
52+
int
53+
http_get(const int sockfd, char *buf) {
4854

4955
ssize_t numbytes;
5056
size_t totalbytes;
@@ -119,8 +125,78 @@ int http_get(const int sockfd, char *buf) {
119125

120126
#ifdef USE_CYASSL
121127

128+
static CYASSL_CTX *cyassl_ctx = NULL;
129+
static pthread_mutex_t cyassl_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
130+
131+
#define LOCK_CYASSL_CTX() do { \
132+
debug(LOG_DEBUG, "Locking CyaSSL Context"); \
133+
pthread_mutex_lock(&cyassl_ctx_mutex); \
134+
debug(LOG_DEBUG, "CyaSSL Context locked"); \
135+
} while (0)
136+
137+
#define UNLOCK_CYASSL_CTX() do { \
138+
debug(LOG_DEBUG, "Unlocking CyaSSL Context"); \
139+
pthread_mutex_unlock(&cyassl_ctx_mutex); \
140+
debug(LOG_DEBUG, "CyaSSL Context unlocked"); \
141+
} while (0)
142+
143+
144+
static CYASSL_CTX *
145+
get_cyassl_ctx(void)
146+
{
147+
int err;
148+
CYASSL_CTX *ret;
149+
s_config *config = config_get_config();
150+
151+
LOCK_CYASSL_CTX();
152+
153+
if (NULL == cyassl_ctx) {
154+
CyaSSL_Init();
155+
/* Create the CYASSL_CTX */
156+
/* Allow TLSv1.0 up to TLSv1.2 */
157+
if ( (cyassl_ctx = CyaSSL_CTX_new(CyaTLSv1_client_method())) == NULL){
158+
debug(LOG_ERR, "Could not create CYASSL context.");
159+
return NULL;
160+
}
161+
162+
if (config->ssl_cipher_list) {
163+
debug(LOG_INFO, "Setting SSL cipher list to [%s]", config->ssl_cipher_list);
164+
err = CyaSSL_CTX_set_cipher_list(cyassl_ctx, config->ssl_cipher_list);
165+
if (SSL_SUCCESS != err) {
166+
debug(LOG_ERR, "Could not load SSL cipher list (error %d)", err);
167+
return NULL;
168+
}
169+
}
170+
171+
if (config->ssl_verify) {
172+
/* Use trusted certs */
173+
/* Note: CyaSSL requires that the certificates are named by their hash values */
174+
debug(LOG_INFO, "Loading SSL certificates from %s", config->ssl_certs);
175+
err = CyaSSL_CTX_load_verify_locations(cyassl_ctx, NULL, config->ssl_certs);
176+
if (err != SSL_SUCCESS) {
177+
debug(LOG_ERR, "Could not load SSL certificates (error %d)", err);
178+
if (err == ASN_UNKNOWN_OID_E) {
179+
debug(LOG_ERR, "Error is ASN_UNKNOWN_OID_E - try compiling cyassl/wolfssl with --enable-ecc");
180+
} else {
181+
debug(LOG_ERR, "Make sure that SSLCertPath points to the correct path in the config file");
182+
debug(LOG_ERR, "Or disable certificate loading with 'SSLPeerVerification No'.");
183+
}
184+
return NULL;
185+
}
186+
} else {
187+
CyaSSL_CTX_set_verify(cyassl_ctx, SSL_VERIFY_NONE, 0);
188+
debug(LOG_INFO, "Disabling SSL certificate verification!");
189+
}
190+
}
191+
192+
ret = cyassl_ctx;
193+
UNLOCK_CYASSL_CTX();
194+
return ret;
195+
}
122196

123-
int https_get(const int sockfd, char *buf, const char* hostname) {
197+
198+
int
199+
https_get(const int sockfd, char *buf, const char* hostname) {
124200

125201
ssize_t numbytes;
126202
size_t totalbytes;
@@ -134,43 +210,18 @@ int https_get(const int sockfd, char *buf, const char* hostname) {
134210
s_config *config;
135211
config = config_get_config();
136212

137-
CyaSSL_Init();
138-
139-
CYASSL_CTX* ctx;
140-
/* Create the CYASSL_CTX */
141-
/* Allow SSLv3 up to TLSv1.2 */
142-
if ( (ctx = CyaSSL_CTX_new(CyaSSLv23_client_method())) == NULL){
143-
debug(LOG_ERR, "Could not create CYASSL context.");
144-
return -1;
145-
}
146-
147-
if (config->ssl_verify) {
148-
/* Use trusted certs */
149-
/* Note: CyaSSL requires that the certificates are named by their hash values */
150-
int err = CyaSSL_CTX_load_verify_locations(ctx, NULL, config->ssl_certs);
151-
if (err != SSL_SUCCESS) {
152-
debug(LOG_ERR, "Could not load SSL certificates (error %d)", err);
153-
if (err == ASN_UNKNOWN_OID_E) {
154-
debug(LOG_ERR, "Error is ASN_UNKNOWN_OID_E - try compiling cyassl/wolfssl with --enable-ecc");
155-
} else {
156-
debug(LOG_ERR, "Make sure that SSLCertPath points to the correct path in the config file");
157-
debug(LOG_ERR, "Or disable certificate loading with 'SSLPeerVerification No'.");
158-
}
159-
return -1;
160-
}
161-
debug(LOG_INFO, "Loading SSL certificates from %s", config->ssl_certs);
162-
} else {
163-
CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
164-
debug(LOG_INFO, "Disabling SSL certificate verification!");
165-
}
213+
CYASSL_CTX* ctx = get_cyassl_ctx();
214+
if (NULL == ctx) {
215+
debug(LOG_ERR, "Could not get CyaSSL Context!");
216+
return -1;
217+
}
166218

167219
if (sockfd == -1) {
168220
/* Could not connect to server */
169221
debug(LOG_ERR, "Could not open socket to server!");
170222
return -1;
171223
}
172224

173-
174225
/* Create CYASSL object */
175226
CYASSL* ssl;
176227
if( (ssl = CyaSSL_new(ctx)) == NULL) {
@@ -204,7 +255,7 @@ int https_get(const int sockfd, char *buf, const char* hostname) {
204255
memset(buf, 0, buflen);
205256

206257
debug(LOG_DEBUG, "Reading response");
207-
numbytes = totalbytes = 0;
258+
totalbytes = 0;
208259
done = 0;
209260
do {
210261
FD_ZERO(&readfds);
@@ -257,8 +308,6 @@ int https_get(const int sockfd, char *buf, const char* hostname) {
257308
debug(LOG_DEBUG, "HTTP Response from Server: [%s]", buf);
258309

259310
CyaSSL_free(ssl);
260-
CyaSSL_CTX_free(ctx);
261-
CyaSSL_Cleanup();
262311

263312
return totalbytes;
264313
}

wifidog.conf

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ ClientTimeout 5
185185
#
186186
# SSLPeerVerification Yes
187187

188-
189188
# Parameter: SSLCertPath
190189
# Default: /etc/ssl/certs/
191190
# Optional
@@ -204,6 +203,20 @@ ClientTimeout 5
204203
#
205204
# SSLCertPath /etc/ssl/certs/
206205

206+
# Parameter: SSLAllowedCipherList
207+
# Default: all ciphers supported
208+
# Optional
209+
#
210+
# Which cipher suite to allow. Note that CyaSSL will ignore cipher
211+
# suites that use algorithms that aren't compiled in or cipher
212+
# suites *WITH ERRORS IN THEIR NAMES*.
213+
#
214+
# Please see CyaSSL documentation for allowed values, format is a
215+
# string where the ciphers are separated by colons (:) with no
216+
# spaces. Ciphers are ordered from most desirable to least desirable.
217+
#
218+
# SSLAllowedCipherList ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:AES128-SHA:AES256-SHA
219+
207220
# Parameter: TrustedMACList
208221
# Default: none
209222
# Optional

0 commit comments

Comments
 (0)