Skip to content

Commit

Permalink
v0.8.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan Eissing committed Sep 1, 2017
1 parent 52646a8 commit 99d2474
Show file tree
Hide file tree
Showing 24 changed files with 231 additions and 75 deletions.
9 changes: 6 additions & 3 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
v0.8.1
----------------------------------------------------------------------------------------------------
* New directive ```MDPrivateKeys``` to specify the type and parameter to private key generation.
Currently only 'RSA' is supported as type with an option number of bits >= 2048 as parameter.
Simple test cases for config handling added.
* Private RSA keys are now generated with 2048 bits by default. Use ```MDPrivateKeyBits``` for
higher security.
* New directive ```MDPrivateKeyBits``` to specify the number of bits to use when generating
private keys. Can be set globally or of a particular managed domain.


v0.8.0
----------------------------------------------------------------------------------------------------
* IMPORTANT: store format change. The following changes will be made to an existing md store on
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#

AC_PREREQ([2.69])
AC_INIT([mod_md], [0.8.0], [stefan.eissing@greenbytes.de])
AC_INIT([mod_md], [0.8.1], [stefan.eissing@greenbytes.de])

LT_PREREQ([2.2.6])
LT_INIT()
Expand Down
10 changes: 10 additions & 0 deletions mod_md.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@
B2FB5A541F570AAA00856773 /* pkey.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = pkey.pem; sourceTree = "<group>"; };
B2FB5A551F570AAA00856773 /* httpd.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = httpd.json; sourceTree = "<group>"; };
B2FB5A561F570AAA00856773 /* md_store.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = md_store.json; sourceTree = "<group>"; };
B2FC60711F5972C4005B7D9E /* test_015.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test_015.conf; sourceTree = "<group>"; };
B2FC60721F597306005B7D9E /* test_016a.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test_016a.conf; sourceTree = "<group>"; };
B2FC60731F597352005B7D9E /* test_016b.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test_016b.conf; sourceTree = "<group>"; };
B2FC60741F597352005B7D9E /* test_016c.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test_016c.conf; sourceTree = "<group>"; };
B2FC60751F597352005B7D9E /* test_016d.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test_016d.conf; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXGroup section */
Expand Down Expand Up @@ -228,6 +233,11 @@
B262F6DE1EFCFE1100D396A1 /* test_012.conf */,
75EDD0871F15064A003CBD39 /* test_013.conf */,
75EAB2611F41BBEB00277D33 /* test_014.conf.in */,
B2FC60711F5972C4005B7D9E /* test_015.conf */,
B2FC60721F597306005B7D9E /* test_016a.conf */,
B2FC60731F597352005B7D9E /* test_016b.conf */,
B2FC60741F597352005B7D9E /* test_016c.conf */,
B2FC60751F597352005B7D9E /* test_016d.conf */,
);
path = test_conf_validate;
sourceTree = "<group>";
Expand Down
10 changes: 5 additions & 5 deletions src/md.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ struct md_cert_t;
struct md_pkey_t;
struct md_store_t;
struct md_srv_conf_t;
struct md_pkey_spec_t;

#define MD_TLSSNI01_DNS_SUFFIX ".acme.invalid"
#define MD_PKEY_BITS_DEFAULT 2048U
#define MD_PKEY_RSA_BITS_DEF 2048U

typedef enum {
MD_S_UNKNOWN, /* MD has not been analysed yet */
Expand Down Expand Up @@ -72,7 +73,7 @@ struct md_t {

int transitive; /* != 0 iff VirtualHost names/aliases are auto-added */
int drive_mode; /* mode of obtaining credentials */
unsigned int pkey_bits; /* number of bits used when generating private keys */
struct md_pkey_spec_t *pkey_spec;/* specification for generating new private keys */
int must_staple; /* certificates should set the OCSP Must Staple extension */
apr_interval_time_t renew_norm; /* if > 0, normalized cert lifetime */
apr_interval_time_t renew_window;/* time before expiration that starts renewal */
Expand All @@ -95,6 +96,7 @@ struct md_t {

#define MD_KEY_ACCOUNT "account"
#define MD_KEY_AGREEMENT "agreement"
#define MD_KEY_BITS "bits"
#define MD_KEY_CA "ca"
#define MD_KEY_CA_URL "ca-url"
#define MD_KEY_CERT "cert"
Expand All @@ -116,7 +118,7 @@ struct md_t {
#define MD_KEY_KEYAUTHZ "keyAuthorization"
#define MD_KEY_LOCATION "location"
#define MD_KEY_NAME "name"
#define MD_KEY_PKEY_BITS "privkey-bits"
#define MD_KEY_PKEY "privkey"
#define MD_KEY_PROTO "proto"
#define MD_KEY_REGISTRATION "registration"
#define MD_KEY_RENEW_NORM "renew-norm"
Expand Down Expand Up @@ -209,8 +211,6 @@ md_t *md_create_empty(apr_pool_t *p);
*/
md_t *md_create(apr_pool_t *p, struct apr_array_header_t *domains);

unsigned int md_get_pkey_bits(const md_t *md);

/**
* Deep copy an md record into another pool.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/md_acme.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ apr_status_t md_acme_find_acct(md_acme_t *acme, struct md_store_t *store, apr_po
* new account is the one used by the acme instance afterwards, on success.
*/
apr_status_t md_acme_create_acct(md_acme_t *acme, apr_pool_t *p, apr_array_header_t *contacts,
const char *agreement, unsigned int pkey_bits);
const char *agreement);

apr_status_t md_acme_acct_save(struct md_store_t *store, apr_pool_t *p, md_acme_t *acme,
struct md_acme_acct_t *acct, struct md_pkey_t *acct_key);
Expand Down
13 changes: 8 additions & 5 deletions src/md_acme_acct.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,12 +322,12 @@ static apr_status_t acct_upd(md_acme_t *acme, apr_pool_t *p,
}

static apr_status_t acct_register(md_acme_t *acme, apr_pool_t *p,
apr_array_header_t *contacts, const char *agreement,
unsigned int pkey_bits)
apr_array_header_t *contacts, const char *agreement)
{
apr_status_t rv;
md_pkey_t *pkey;
const char *err = NULL, *uri;
md_pkey_spec_t spec;
int i;

md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "create new account");
Expand All @@ -348,7 +348,10 @@ static apr_status_t acct_register(md_acme_t *acme, apr_pool_t *p,
}
}

if (APR_SUCCESS == (rv = md_pkey_gen_rsa(&pkey, acme->p, pkey_bits))
spec.type = MD_PKEY_TYPE_RSA;
spec.params.rsa.bits = MD_ACME_ACCT_PKEY_BITS;

if (APR_SUCCESS == (rv = md_pkey_gen(&pkey, acme->p, &spec))
&& APR_SUCCESS == (rv = acct_make(&acme->acct, p, acme->url, NULL, contacts))) {
acct_ctx_t ctx;

Expand Down Expand Up @@ -527,9 +530,9 @@ apr_status_t md_acme_find_acct(md_acme_t *acme, md_store_t *store, apr_pool_t *p
}

apr_status_t md_acme_create_acct(md_acme_t *acme, apr_pool_t *p, apr_array_header_t *contacts,
const char *agreement, unsigned int pkey_bits)
const char *agreement)
{
return acct_register(acme, p, contacts, agreement, pkey_bits);
return acct_register(acme, p, contacts, agreement);
}

/**************************************************************************************************/
Expand Down
4 changes: 4 additions & 0 deletions src/md_acme_acct.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ struct md_acme_acct_t {
#define MD_FN_ACCOUNT "account.json"
#define MD_FN_ACCT_KEY "account.pem"

/* ACME account private keys are always RSA and have that many bits. Since accounts
* are expected to live long, better err on the safe side. */
#define MD_ACME_ACCT_PKEY_BITS 3072

#endif /* md_acme_acct_h */
12 changes: 6 additions & 6 deletions src/md_acme_authz.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static apr_status_t setup_key_authz(md_acme_authz_cha_t *cha, md_acme_authz_t *a

static apr_status_t cha_http_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz,
md_acme_t *acme, md_store_t *store,
unsigned int pkey_bits, apr_pool_t *p)
md_pkey_spec_t *key_spec, apr_pool_t *p)
{
const char *data;
apr_status_t rv;
Expand Down Expand Up @@ -349,7 +349,7 @@ static apr_status_t setup_cha_dns(const char **pdns, md_acme_authz_cha_t *cha, a

static apr_status_t cha_tls_sni_01_setup(md_acme_authz_cha_t *cha, md_acme_authz_t *authz,
md_acme_t *acme, md_store_t *store,
unsigned int pkey_bits, apr_pool_t *p)
md_pkey_spec_t *key_spec, apr_pool_t *p)
{
md_cert_t *cha_cert;
md_pkey_t *cha_key;
Expand All @@ -367,7 +367,7 @@ static apr_status_t cha_tls_sni_01_setup(md_acme_authz_cha_t *cha, md_acme_authz
if ((APR_SUCCESS == rv && !md_cert_covers_domain(cha_cert, cha_dns))
|| APR_STATUS_IS_ENOENT(rv)) {

if (APR_SUCCESS != (rv = md_pkey_gen_rsa(&cha_key, p, pkey_bits))) {
if (APR_SUCCESS != (rv = md_pkey_gen(&cha_key, p, key_spec))) {
md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: create tls-sni-01 challgenge key",
authz->domain);
goto out;
Expand Down Expand Up @@ -408,7 +408,7 @@ static apr_status_t cha_tls_sni_01_setup(md_acme_authz_cha_t *cha, md_acme_authz

typedef apr_status_t cha_starter(md_acme_authz_cha_t *cha, md_acme_authz_t *authz,
md_acme_t *acme, md_store_t *store,
unsigned int pkey_bits, apr_pool_t *p);
md_pkey_spec_t *key_spec, apr_pool_t *p);

typedef struct {
const char *name;
Expand Down Expand Up @@ -453,7 +453,7 @@ static apr_status_t find_type(void *baton, size_t index, md_json_t *json)

apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, md_acme_t *acme, md_store_t *store,
apr_array_header_t *challenges,
unsigned int pkey_bits, apr_pool_t *p)
md_pkey_spec_t *key_spec, apr_pool_t *p)
{
apr_status_t rv;
int i;
Expand Down Expand Up @@ -489,7 +489,7 @@ apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, md_acme_t *acme, md_s

for (i = 0; i < CHA_TYPES_LEN; ++i) {
if (!apr_strnatcasecmp(CHA_TYPES[i].name, fctx.accepted->type)) {
return CHA_TYPES[i].start(fctx.accepted, authz, acme, store, pkey_bits, p);
return CHA_TYPES[i].start(fctx.accepted, authz, acme, store, key_spec, p);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/md_acme_authz.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct md_acme_t;
struct md_acme_acct_t;
struct md_json_t;
struct md_store_t;
struct md_pkey_spec_t;

typedef struct md_acme_challenge_t md_acme_challenge_t;

Expand Down Expand Up @@ -68,7 +69,7 @@ apr_status_t md_acme_authz_update(md_acme_authz_t *authz, struct md_acme_t *acme

apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, struct md_acme_t *acme,
struct md_store_t *store, apr_array_header_t *challenges,
unsigned int pkey_bits, apr_pool_t *p);
struct md_pkey_spec_t *key_spec, apr_pool_t *p);
apr_status_t md_acme_authz_del(md_acme_authz_t *authz, struct md_acme_t *acme,
struct md_store_t *store, apr_pool_t *p);

Expand Down
6 changes: 3 additions & 3 deletions src/md_acme_drive.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static apr_status_t ad_set_acct(md_proto_driver_t *d)
}

if (APR_SUCCESS == (rv = md_acme_create_acct(ad->acme, d->p, md->contacts,
md->ca_agreement, md_get_pkey_bits(d->md)))
md->ca_agreement))
&& APR_SUCCESS == (rv = md_acme_acct_save_staged(ad->acme, d->store, md, d->p))) {
md->ca_account = MD_ACME_ACCT_STAGED;
update = 1;
Expand Down Expand Up @@ -272,7 +272,7 @@ static apr_status_t ad_start_challenges(md_proto_driver_t *d)

case MD_ACME_AUTHZ_S_PENDING:
rv = md_acme_authz_respond(authz, ad->acme, d->store, ad->ca_challenges,
md_get_pkey_bits(d->md), d->p);
d->md->pkey_spec, d->p);
changed = 1;
break;

Expand Down Expand Up @@ -475,7 +475,7 @@ static apr_status_t ad_setup_certificate(md_proto_driver_t *d)

rv = md_pkey_load(d->store, MD_SG_STAGING, ad->md->name, &privkey, d->p);
if (APR_STATUS_IS_ENOENT(rv)) {
if (APR_SUCCESS == (rv = md_pkey_gen_rsa(&privkey, d->p, md_get_pkey_bits(d->md)))) {
if (APR_SUCCESS == (rv = md_pkey_gen(&privkey, d->p, d->md->pkey_spec))) {
rv = md_pkey_save(d->store, d->p, MD_SG_STAGING, ad->md->name, privkey, 1);
}
md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, "%s: generate privkey", ad->md->name);
Expand Down
3 changes: 1 addition & 2 deletions src/md_cmd_acme.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ static apr_status_t cmd_acme_newreg(md_cmd_ctx *ctx, const md_cmd_t *cmd)
return usage(cmd, "newreg needs at least one contact email as argument");
}

if (APR_SUCCESS == (rv = md_acme_create_acct(ctx->acme, ctx->p, contacts,
ctx->tos, MD_PKEY_BITS_DEFAULT))) {
if (APR_SUCCESS == (rv = md_acme_create_acct(ctx->acme, ctx->p, contacts, ctx->tos))) {
md_acme_save(ctx->acme, ctx->store, ctx->p);
fprintf(stdout, "registered: %s\n", md_acme_get_acct(ctx->acme, ctx->p));
}
Expand Down
23 changes: 7 additions & 16 deletions src/md_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "md_json.h"
#include "md.h"
#include "md_crypt.h"
#include "md_log.h"
#include "md_store.h"
#include "md_util.h"
Expand Down Expand Up @@ -229,7 +230,7 @@ md_t *md_clone(apr_pool_t *p, const md_t *src)
md->name = apr_pstrdup(p, src->name);
md->drive_mode = src->drive_mode;
md->domains = md_array_str_compact(p, src->domains, 0);
md->pkey_bits = src->pkey_bits;
md->pkey_spec = src->pkey_spec;
md->renew_norm = src->renew_norm;
md->renew_window = src->renew_window;
md->contacts = md_array_str_clone(p, src->contacts);
Expand All @@ -255,7 +256,7 @@ md_t *md_merge(apr_pool_t *p, const md_t *add, const md_t *base)
n->ca_proto = add->ca_proto? add->ca_proto : base->ca_proto;
n->ca_agreement = add->ca_agreement? add->ca_agreement : base->ca_agreement;
n->drive_mode = (add->drive_mode != MD_DRIVE_DEFAULT)? add->drive_mode : base->drive_mode;
n->pkey_bits = (add->pkey_bits > 0)? add->pkey_bits : base->pkey_bits;
n->pkey_spec = add->pkey_spec? add->pkey_spec : base->pkey_spec;
n->renew_norm = (add->renew_norm > 0)? add->renew_norm : base->renew_norm;
n->renew_window = (add->renew_window > 0)? add->renew_window : base->renew_window;
n->transitive = (add->transitive >= 0)? add->transitive : base->transitive;
Expand All @@ -268,14 +269,6 @@ md_t *md_merge(apr_pool_t *p, const md_t *add, const md_t *base)
return n;
}

unsigned int md_get_pkey_bits(const md_t *md)
{
if (md->pkey_bits > 0 && md->pkey_bits < UINT_MAX) {
return (unsigned int)md->pkey_bits;
}
return MD_PKEY_BITS_DEFAULT;
}

/**************************************************************************************************/
/* format conversion */

Expand All @@ -295,8 +288,8 @@ md_json_t *md_to_json(const md_t *md, apr_pool_t *p)
if (md->cert_url) {
md_json_sets(md->cert_url, json, MD_KEY_CERT, MD_KEY_URL, NULL);
}
if (md->pkey_bits > 0) {
md_json_setl((long)md->pkey_bits, json, MD_KEY_CERT, MD_KEY_PKEY_BITS, NULL);
if (md->pkey_spec) {
md_json_setj(md_pkey_spec_to_json(md->pkey_spec, p), json, MD_KEY_PKEY, NULL);
}
md_json_setl(md->state, json, MD_KEY_STATE, NULL);
md_json_setl(md->drive_mode, json, MD_KEY_DRIVE_MODE, NULL);
Expand Down Expand Up @@ -330,7 +323,6 @@ md_json_t *md_to_json(const md_t *md, apr_pool_t *p)
md_t *md_from_json(md_json_t *json, apr_pool_t *p)
{
const char *s;
long l;
md_t *md = md_create_empty(p);
if (md) {
md->name = md_json_dups(p, json, MD_KEY_NAME, NULL);
Expand All @@ -341,9 +333,8 @@ md_t *md_from_json(md_json_t *json, apr_pool_t *p)
md->ca_url = md_json_dups(p, json, MD_KEY_CA, MD_KEY_URL, NULL);
md->ca_agreement = md_json_dups(p, json, MD_KEY_CA, MD_KEY_AGREEMENT, NULL);
md->cert_url = md_json_dups(p, json, MD_KEY_CERT, MD_KEY_URL, NULL);
l = md_json_getl(json, MD_KEY_CERT, MD_KEY_PKEY_BITS, NULL);
if (l > 0 && l < INT_MAX) {
md->pkey_bits = (unsigned int)l;
if (md_json_has_key(json, MD_KEY_PKEY, MD_KEY_TYPE, NULL)) {
md->pkey_spec = md_pkey_spec_from_json(md_json_getj(json, MD_KEY_PKEY, NULL), p);
}
md->state = (md_state_t)md_json_getl(json, MD_KEY_STATE, NULL);
md->drive_mode = (int)md_json_getl(json, MD_KEY_DRIVE_MODE, NULL);
Expand Down
Loading

0 comments on commit 99d2474

Please sign in to comment.