Fossil SCM

Use the dedicated certs table for server certificate cache. Only attempt to use client certificate if one was actually specified for a cert bundle. Assume client key is in same file as certificate if one wasn't explicitly specified.

jan 2011-04-02 13:40 UTC jan-clientcert
Commit c44bb083e9a10219ad8f5bc1b0ef00238abc87d0
1 file changed +37 -22
+37 -22
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -238,39 +238,45 @@
238238
X509_free(cert);
239239
return 0;
240240
}
241241
242242
/*
243
-** Save certificate to global config.
243
+** Save certificate to global certificate/key store.
244244
*/
245245
void ssl_save_certificate(X509 *cert){
246246
BIO *mem;
247
- char *zCert, *zHost;
247
+ char *zCert;
248248
249249
mem = BIO_new(BIO_s_mem());
250250
PEM_write_bio_X509(mem, cert);
251251
BIO_write(mem, "", 1); // null-terminate mem buffer
252252
BIO_get_mem_data(mem, &zCert);
253
- zHost = mprintf("cert:%s", g.urlName);
254
- db_set(zHost, zCert, 1);
255
- free(zHost);
253
+ db_swap_connections();
254
+ create_cert_table_if_not_exist();
255
+ db_begin_transaction();
256
+ db_multi_exec("REPLACE INTO certs(name,type,filepath) "
257
+ "VALUES(%Q,'scert',%Q)", g.urlName, zCert);
258
+ db_end_transaction(0);
259
+ db_swap_connections();
256260
BIO_free(mem);
257261
}
258262
259263
/*
260
-** Get certificate for g.urlName from global config.
264
+** Get certificate for g.urlName from global certificate/key store.
261265
** Return NULL if no certificate found.
262266
*/
263267
X509 *ssl_get_certificate(void){
264
- char *zHost, *zCert;
268
+ char *zCert;
265269
BIO *mem;
266270
X509 *cert;
267271
268
- zHost = mprintf("cert:%s", g.urlName);
269
- zCert = db_get(zHost, NULL);
270
- free(zHost);
271
- if ( zCert==NULL )
272
+ db_swap_connections();
273
+ create_cert_table_if_not_exist();
274
+ zCert = db_text(0, "SELECT filepath FROM certs WHERE name=%Q"
275
+ " AND type='scert'", g.urlName);
276
+ db_swap_connections();
277
+ if( zCert==NULL )
272278
return NULL;
273279
mem = BIO_new(BIO_s_mem());
274280
BIO_puts(mem, zCert);
275281
cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
276282
free(zCert);
@@ -331,11 +337,11 @@
331337
free(zName);
332338
zBundleName = strdup(g.urlCertBundle);
333339
}else{
334340
db_swap_connections();
335341
zBundleName = db_text(0, "SELECT value FROM global_config"
336
- " WHERE name='certbundle:%q'", g.urlName);
342
+ " WHERE name='certbundle:%q'", g.urlName);
337343
db_swap_connections();
338344
}
339345
if( !zBundleName ){
340346
/* No cert bundle specified on command line or found cached for URL */
341347
return;
@@ -366,23 +372,32 @@
366372
" AND type='ckey'", zBundleName);
367373
certfile = db_text(0, "SELECT filepath FROM certs WHERE name=%Q"
368374
" AND type='ccert'", zBundleName);
369375
db_swap_connections();
370376
371
- if( SSL_CTX_use_certificate_file(sslCtx, certfile, SSL_FILETYPE_PEM)<=0 ){
372
- fossil_fatal("SSL: Unable to open client certificate in %s.", certfile);
373
- }
374
- if( SSL_CTX_use_PrivateKey_file(sslCtx, keyfile, SSL_FILETYPE_PEM)<=0 ){
375
- fossil_fatal("SSL: Unable to open client key in %s.", keyfile);
377
+ if( certfile ){
378
+ /* If a client certificate is explicitly specified, but a key is not, then
379
+ ** assume the key is in the same file as the certificate.
380
+ */
381
+ if( !keyfile ){
382
+ keyfile = certfile;
383
+ }
384
+ if( SSL_CTX_use_certificate_file(sslCtx, certfile, SSL_FILETYPE_PEM)<=0 ){
385
+ fossil_fatal("SSL: Unable to open client certificate in %s.", certfile);
386
+ }
387
+ if( SSL_CTX_use_PrivateKey_file(sslCtx, keyfile, SSL_FILETYPE_PEM)<=0 ){
388
+ fossil_fatal("SSL: Unable to open client key in %s.", keyfile);
389
+ }
390
+ if( certfile && keyfile && !SSL_CTX_check_private_key(sslCtx) ){
391
+ fossil_fatal("SSL: Private key does not match the certificate public "
392
+ "key.");
393
+ }
376394
}
377395
378
- if( !SSL_CTX_check_private_key(sslCtx) ){
379
- fossil_fatal("SSL: Private key does not match the certificate public "
380
- "key.");
396
+ if( keyfile != certfile ){
397
+ free(keyfile);
381398
}
382
-
383
- free(keyfile);
384399
free(certfile);
385400
free(capath);
386401
free(cafile);
387402
}
388403
#endif /* FOSSIL_ENABLE_SSL */
389404
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -238,39 +238,45 @@
238 X509_free(cert);
239 return 0;
240 }
241
242 /*
243 ** Save certificate to global config.
244 */
245 void ssl_save_certificate(X509 *cert){
246 BIO *mem;
247 char *zCert, *zHost;
248
249 mem = BIO_new(BIO_s_mem());
250 PEM_write_bio_X509(mem, cert);
251 BIO_write(mem, "", 1); // null-terminate mem buffer
252 BIO_get_mem_data(mem, &zCert);
253 zHost = mprintf("cert:%s", g.urlName);
254 db_set(zHost, zCert, 1);
255 free(zHost);
 
 
 
 
256 BIO_free(mem);
257 }
258
259 /*
260 ** Get certificate for g.urlName from global config.
261 ** Return NULL if no certificate found.
262 */
263 X509 *ssl_get_certificate(void){
264 char *zHost, *zCert;
265 BIO *mem;
266 X509 *cert;
267
268 zHost = mprintf("cert:%s", g.urlName);
269 zCert = db_get(zHost, NULL);
270 free(zHost);
271 if ( zCert==NULL )
 
 
272 return NULL;
273 mem = BIO_new(BIO_s_mem());
274 BIO_puts(mem, zCert);
275 cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
276 free(zCert);
@@ -331,11 +337,11 @@
331 free(zName);
332 zBundleName = strdup(g.urlCertBundle);
333 }else{
334 db_swap_connections();
335 zBundleName = db_text(0, "SELECT value FROM global_config"
336 " WHERE name='certbundle:%q'", g.urlName);
337 db_swap_connections();
338 }
339 if( !zBundleName ){
340 /* No cert bundle specified on command line or found cached for URL */
341 return;
@@ -366,23 +372,32 @@
366 " AND type='ckey'", zBundleName);
367 certfile = db_text(0, "SELECT filepath FROM certs WHERE name=%Q"
368 " AND type='ccert'", zBundleName);
369 db_swap_connections();
370
371 if( SSL_CTX_use_certificate_file(sslCtx, certfile, SSL_FILETYPE_PEM)<=0 ){
372 fossil_fatal("SSL: Unable to open client certificate in %s.", certfile);
373 }
374 if( SSL_CTX_use_PrivateKey_file(sslCtx, keyfile, SSL_FILETYPE_PEM)<=0 ){
375 fossil_fatal("SSL: Unable to open client key in %s.", keyfile);
 
 
 
 
 
 
 
 
 
 
 
 
376 }
377
378 if( !SSL_CTX_check_private_key(sslCtx) ){
379 fossil_fatal("SSL: Private key does not match the certificate public "
380 "key.");
381 }
382
383 free(keyfile);
384 free(certfile);
385 free(capath);
386 free(cafile);
387 }
388 #endif /* FOSSIL_ENABLE_SSL */
389
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -238,39 +238,45 @@
238 X509_free(cert);
239 return 0;
240 }
241
242 /*
243 ** Save certificate to global certificate/key store.
244 */
245 void ssl_save_certificate(X509 *cert){
246 BIO *mem;
247 char *zCert;
248
249 mem = BIO_new(BIO_s_mem());
250 PEM_write_bio_X509(mem, cert);
251 BIO_write(mem, "", 1); // null-terminate mem buffer
252 BIO_get_mem_data(mem, &zCert);
253 db_swap_connections();
254 create_cert_table_if_not_exist();
255 db_begin_transaction();
256 db_multi_exec("REPLACE INTO certs(name,type,filepath) "
257 "VALUES(%Q,'scert',%Q)", g.urlName, zCert);
258 db_end_transaction(0);
259 db_swap_connections();
260 BIO_free(mem);
261 }
262
263 /*
264 ** Get certificate for g.urlName from global certificate/key store.
265 ** Return NULL if no certificate found.
266 */
267 X509 *ssl_get_certificate(void){
268 char *zCert;
269 BIO *mem;
270 X509 *cert;
271
272 db_swap_connections();
273 create_cert_table_if_not_exist();
274 zCert = db_text(0, "SELECT filepath FROM certs WHERE name=%Q"
275 " AND type='scert'", g.urlName);
276 db_swap_connections();
277 if( zCert==NULL )
278 return NULL;
279 mem = BIO_new(BIO_s_mem());
280 BIO_puts(mem, zCert);
281 cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
282 free(zCert);
@@ -331,11 +337,11 @@
337 free(zName);
338 zBundleName = strdup(g.urlCertBundle);
339 }else{
340 db_swap_connections();
341 zBundleName = db_text(0, "SELECT value FROM global_config"
342 " WHERE name='certbundle:%q'", g.urlName);
343 db_swap_connections();
344 }
345 if( !zBundleName ){
346 /* No cert bundle specified on command line or found cached for URL */
347 return;
@@ -366,23 +372,32 @@
372 " AND type='ckey'", zBundleName);
373 certfile = db_text(0, "SELECT filepath FROM certs WHERE name=%Q"
374 " AND type='ccert'", zBundleName);
375 db_swap_connections();
376
377 if( certfile ){
378 /* If a client certificate is explicitly specified, but a key is not, then
379 ** assume the key is in the same file as the certificate.
380 */
381 if( !keyfile ){
382 keyfile = certfile;
383 }
384 if( SSL_CTX_use_certificate_file(sslCtx, certfile, SSL_FILETYPE_PEM)<=0 ){
385 fossil_fatal("SSL: Unable to open client certificate in %s.", certfile);
386 }
387 if( SSL_CTX_use_PrivateKey_file(sslCtx, keyfile, SSL_FILETYPE_PEM)<=0 ){
388 fossil_fatal("SSL: Unable to open client key in %s.", keyfile);
389 }
390 if( certfile && keyfile && !SSL_CTX_check_private_key(sslCtx) ){
391 fossil_fatal("SSL: Private key does not match the certificate public "
392 "key.");
393 }
394 }
395
396 if( keyfile != certfile ){
397 free(keyfile);
 
398 }
 
 
399 free(certfile);
400 free(capath);
401 free(cafile);
402 }
403 #endif /* FOSSIL_ENABLE_SSL */
404

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button