summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2019-01-02 10:45:36 +0100
committerYves-Alexis Perez <corsac@debian.org>2019-01-02 11:07:05 +0100
commit918094fde55fa0dbfd59a5f88d576efb513a88db (patch)
tree61e31656c60a6cc928c50cd633568043673e2cbd /src
parent69bc96f6b0b388d35e983f8d27224fa49d92918c (diff)
downloadvyos-strongswan-918094fde55fa0dbfd59a5f88d576efb513a88db.tar.gz
vyos-strongswan-918094fde55fa0dbfd59a5f88d576efb513a88db.zip
New upstream version 5.7.2
Diffstat (limited to 'src')
-rw-r--r--src/_copyright/_copyright.c2
-rw-r--r--src/charon-cmd/charon-cmd.c9
-rw-r--r--src/charon-systemd/charon-systemd.c16
-rw-r--r--src/conftest/hooks/set_proposal_number.c2
-rw-r--r--src/ipsec/_ipsec.82
-rw-r--r--src/libcharon/bus/bus.c5
-rw-r--r--src/libcharon/bus/bus.h4
-rw-r--r--src/libcharon/bus/listeners/listener.h4
-rw-r--r--src/libcharon/plugins/bypass_lan/bypass_lan_listener.c26
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_socket.c10
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius.c12
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_accounting.c59
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_accounting.h10
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_provider.c32
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_provider.h11
-rw-r--r--src/libcharon/plugins/ha/ha_attribute.c13
-rw-r--r--src/libcharon/plugins/ha/ha_dispatcher.c4
-rw-r--r--src/libcharon/plugins/ha/ha_ike.c6
-rw-r--r--src/libcharon/plugins/ha/ha_message.c2
-rw-r--r--src/libcharon/plugins/ha/ha_message.h2
-rw-r--r--src/libcharon/plugins/ha/ha_segments.c7
-rw-r--r--src/libcharon/plugins/ha/ha_segments.h7
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c17
-rw-r--r--src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c27
-rw-r--r--src/libcharon/plugins/vici/libvici.h8
-rw-r--r--src/libcharon/plugins/vici/vici_config.c7
-rw-r--r--src/libcharon/processing/jobs/adopt_children_job.c52
-rw-r--r--src/libcharon/sa/child_sa.c4
-rw-r--r--src/libcharon/sa/ike_sa.c45
-rw-r--r--src/libcharon/sa/ike_sa.h17
-rw-r--r--src/libcharon/sa/ike_sa_manager.c2
-rw-r--r--src/libcharon/sa/ikev1/phase1.c3
-rw-r--r--src/libcharon/sa/ikev1/task_manager_v1.c134
-rw-r--r--src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c1
-rw-r--r--src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c1
-rw-r--r--src/libcharon/sa/ikev1/tasks/quick_mode.c9
-rw-r--r--src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c97
-rw-r--r--src/libcharon/sa/ikev2/task_manager_v2.c227
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_delete.c24
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_init.c16
-rw-r--r--src/libcharon/sa/task_manager.h19
-rw-r--r--src/libcharon/tests/suites/test_child_rekey.c46
-rw-r--r--src/libimcv/imv/data.sql44
-rw-r--r--src/libimcv/plugins/imc_swima/strongswan.org__strongSwan-5-7-2.swidtag (renamed from src/libimcv/plugins/imc_swima/strongswan.org__strongSwan-5-7-1.swidtag)4
-rw-r--r--src/libimcv/plugins/imv_attestation/imv_attestation_agent.c2
-rw-r--r--src/libpttls/pt_tls_client.c1
-rw-r--r--src/libstrongswan/credentials/auth_cfg.c1
-rw-r--r--src/libstrongswan/credentials/builder.c1
-rw-r--r--src/libstrongswan/credentials/builder.h2
-rw-r--r--src/libstrongswan/credentials/keys/private_key.h13
-rw-r--r--src/libstrongswan/credentials/keys/public_key.c2
-rw-r--r--src/libstrongswan/credentials/keys/signature_params.c50
-rw-r--r--src/libstrongswan/credentials/keys/signature_params.h19
-rw-r--r--src/libstrongswan/crypto/mac.h4
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords_static.c24
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords_static.h2
-rw-r--r--src/libstrongswan/plugins/agent/agent_private_key.c133
-rw-r--r--src/libstrongswan/plugins/botan/Makefile.am4
-rw-r--r--src/libstrongswan/plugins/botan/Makefile.in13
-rw-r--r--src/libstrongswan/plugins/botan/botan_aead.c (renamed from src/libstrongswan/plugins/botan/botan_gcm.c)219
-rw-r--r--src/libstrongswan/plugins/botan/botan_aead.h (renamed from src/libstrongswan/plugins/botan/botan_gcm.h)17
-rw-r--r--src/libstrongswan/plugins/botan/botan_crypter.c6
-rw-r--r--src/libstrongswan/plugins/botan/botan_ec_public_key.c19
-rw-r--r--src/libstrongswan/plugins/botan/botan_ed_private_key.c279
-rw-r--r--src/libstrongswan/plugins/botan/botan_ed_private_key.h63
-rw-r--r--src/libstrongswan/plugins/botan/botan_ed_public_key.c202
-rw-r--r--src/libstrongswan/plugins/botan/botan_ed_public_key.h51
-rw-r--r--src/libstrongswan/plugins/botan/botan_plugin.c77
-rw-r--r--src/libstrongswan/plugins/botan/botan_rsa_private_key.c24
-rw-r--r--src/libstrongswan/plugins/botan/botan_rsa_public_key.c66
-rw-r--r--src/libstrongswan/plugins/botan/botan_util.c35
-rw-r--r--src/libstrongswan/plugins/botan/botan_util.h12
-rw-r--r--src/libstrongswan/plugins/botan/botan_util_keys.c38
-rw-r--r--src/libstrongswan/plugins/curve25519/curve25519_public_key.c110
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c4
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c6
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c6
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c6
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c7
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_database.c10
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.am5
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.in11
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crl.c21
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ed_private_key.c356
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ed_private_key.h58
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ed_public_key.c304
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ed_public_key.h38
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c53
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rng.c11
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c7
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c7
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.c8
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.h4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_x509.c14
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.c256
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.h37
-rw-r--r--src/libstrongswan/plugins/sshkey/sshkey_builder.c35
-rw-r--r--src/libstrongswan/plugins/sshkey/sshkey_encoder.c38
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.am1
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors.h2
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/chacha20poly1305.c40
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/curve25519.c2
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/curve448.c43
-rw-r--r--src/libstrongswan/settings/settings_lexer.c898
-rw-r--r--src/libstrongswan/settings/settings_lexer.l5
-rw-r--r--src/libstrongswan/tests/Makefile.am1
-rw-r--r--src/libstrongswan/tests/Makefile.in19
-rw-r--r--src/libstrongswan/tests/suites/test_ed25519.c84
-rw-r--r--src/libstrongswan/tests/suites/test_ed448.c654
-rw-r--r--src/libstrongswan/tests/suites/test_rsa.c2
-rw-r--r--src/libstrongswan/tests/suites/test_signature_params.c61
-rw-r--r--src/libstrongswan/tests/tests.h1
-rw-r--r--src/libstrongswan/utils/chunk.h2
-rw-r--r--src/libstrongswan/utils/leak_detective.c42
-rw-r--r--src/libtpmtss/plugins/tpm/tpm_private_key.c10
-rw-r--r--src/libtpmtss/tpm_tss.h12
-rw-r--r--src/libtpmtss/tpm_tss_trousers.c7
-rw-r--r--src/libtpmtss/tpm_tss_tss2_v1.c137
-rw-r--r--src/libtpmtss/tpm_tss_tss2_v2.c133
-rw-r--r--src/pki/commands/acert.c5
-rw-r--r--src/pki/commands/issue.c5
-rw-r--r--src/pki/commands/req.c5
-rw-r--r--src/pki/commands/self.c5
-rw-r--r--src/pki/commands/signcrl.c6
-rw-r--r--src/pki/pki.c28
-rw-r--r--src/pki/pki.h3
-rw-r--r--src/pool/pool.c2
-rw-r--r--src/pt-tls-client/pt-tls-client.1.in4
-rw-r--r--src/scepclient/scepclient.c9
-rwxr-xr-xsrc/sec-updater/sec-updater.sh58
-rw-r--r--src/starter/keywords.c24
-rw-r--r--src/starter/keywords.h2
-rw-r--r--src/starter/parser/lexer.c868
-rw-r--r--src/starter/parser/lexer.l5
-rw-r--r--src/stroke/stroke_keywords.c26
-rw-r--r--src/stroke/stroke_keywords.h2
-rw-r--r--src/sw-collector/sw-collector.c3
-rw-r--r--src/swanctl/commands/load_all.c5
-rw-r--r--src/swanctl/commands/load_authorities.c11
-rw-r--r--src/swanctl/commands/load_conns.c20
-rw-r--r--src/swanctl/commands/load_creds.c20
-rw-r--r--src/swanctl/commands/load_pools.c5
-rw-r--r--src/swanctl/commands/rekey.c2
-rw-r--r--src/swanctl/commands/terminate.c2
-rw-r--r--src/swanctl/swanctl.c44
-rw-r--r--src/swanctl/swanctl.h52
147 files changed, 5780 insertions, 1444 deletions
diff --git a/src/_copyright/_copyright.c b/src/_copyright/_copyright.c
index 806f78062..038e60e87 100644
--- a/src/_copyright/_copyright.c
+++ b/src/_copyright/_copyright.c
@@ -84,11 +84,9 @@ main(int argc, char *argv[])
case 'h': /* help */
printf("%s\n", usage);
exit(0);
- break;
case 'v': /* version */
printf("%s strongSwan "VERSION"\n", me);
exit(0);
- break;
case '?':
default:
errflg = 1;
diff --git a/src/charon-cmd/charon-cmd.c b/src/charon-cmd/charon-cmd.c
index 1293ec4c0..e85e21d5c 100644
--- a/src/charon-cmd/charon-cmd.c
+++ b/src/charon-cmd/charon-cmd.c
@@ -348,6 +348,9 @@ int main(int argc, char *argv[])
{
exit(SS_RC_INITIALIZATION_FAILED);
}
+ /* register this again after loading plugins to avoid issues with libraries
+ * that register atexit() handlers */
+ atexit(libcharon_deinit);
if (!lib->caps->drop(lib->caps))
{
exit(SS_RC_INITIALIZATION_FAILED);
@@ -358,9 +361,6 @@ int main(int argc, char *argv[])
creds = cmd_creds_create();
atexit(cleanup_creds);
- /* handle all arguments */
- handle_arguments(argc, argv, FALSE);
-
if (uname(&utsname) != 0)
{
memset(&utsname, 0, sizeof(utsname));
@@ -369,6 +369,9 @@ int main(int argc, char *argv[])
VERSION, utsname.sysname, utsname.release, utsname.machine);
lib->plugins->status(lib->plugins, LEVEL_CTRL);
+ /* handle all arguments */
+ handle_arguments(argc, argv, FALSE);
+
/* add handler for SEGV and ILL,
* INT, TERM and HUP are handled by sigwaitinfo() in run() */
action.sa_handler = segv_handler;
diff --git a/src/charon-systemd/charon-systemd.c b/src/charon-systemd/charon-systemd.c
index d06c26974..7d4465ebf 100644
--- a/src/charon-systemd/charon-systemd.c
+++ b/src/charon-systemd/charon-systemd.c
@@ -322,6 +322,7 @@ int main(int argc, char *argv[])
{
struct sigaction action;
struct utsname utsname;
+ int status = SS_RC_INITIALIZATION_FAILED;
dbg = dbg_stderr;
@@ -345,16 +346,15 @@ int main(int argc, char *argv[])
sd_notifyf(0, "STATUS=integrity check of charon-systemd failed");
return SS_RC_INITIALIZATION_FAILED;
}
- atexit(libcharon_deinit);
if (!libcharon_init())
{
sd_notifyf(0, "STATUS=libcharon initialization failed");
- return SS_RC_INITIALIZATION_FAILED;
+ goto error;
}
if (!lookup_uid_gid())
{
sd_notifyf(0, "STATUS=unknown uid/gid");
- return SS_RC_INITIALIZATION_FAILED;
+ goto error;
}
/* we registered the journal logger as custom logger, which gets its
* settings from <ns>.customlog.journal, let it fallback to <ns>.journal */
@@ -370,14 +370,14 @@ int main(int argc, char *argv[])
lib->settings->get_str(lib->settings, "%s.load", PLUGINS, lib->ns)))
{
sd_notifyf(0, "STATUS=charon initialization failed");
- return SS_RC_INITIALIZATION_FAILED;
+ goto error;
}
lib->plugins->status(lib->plugins, LEVEL_CTRL);
if (!lib->caps->drop(lib->caps))
{
sd_notifyf(0, "STATUS=dropping capabilities failed");
- return SS_RC_INITIALIZATION_FAILED;
+ goto error;
}
/* add handler for SEGV and ILL,
@@ -401,5 +401,9 @@ int main(int argc, char *argv[])
sd_notifyf(0, "STATUS=charon-systemd running, strongSwan %s, %s %s, %s",
VERSION, utsname.sysname, utsname.release, utsname.machine);
- return run();
+ status = run();
+
+error:
+ libcharon_deinit();
+ return status;
}
diff --git a/src/conftest/hooks/set_proposal_number.c b/src/conftest/hooks/set_proposal_number.c
index dd814ad15..3fa53680c 100644
--- a/src/conftest/hooks/set_proposal_number.c
+++ b/src/conftest/hooks/set_proposal_number.c
@@ -122,7 +122,7 @@ METHOD(listener_t, message, bool,
enumerator->destroy(enumerator);
}
sa = sa_payload_create_from_proposals_v2(updated);
- list->destroy_offset(list, offsetof(proposal_t, destroy));
+ DESTROY_OFFSET_IF(list, offsetof(proposal_t, destroy));
updated->destroy_offset(updated, offsetof(proposal_t, destroy));
message->add_payload(message, (payload_t*)sa);
}
diff --git a/src/ipsec/_ipsec.8 b/src/ipsec/_ipsec.8
index 143342ecb..d49d6cdf6 100644
--- a/src/ipsec/_ipsec.8
+++ b/src/ipsec/_ipsec.8
@@ -1,4 +1,4 @@
-.TH IPSEC 8 "2013-10-29" "5.7.0rc2" "strongSwan"
+.TH IPSEC 8 "2013-10-29" "5.7.2dr1" "strongSwan"
.
.SH NAME
.
diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c
index f4c01c22e..b7348f0f9 100644
--- a/src/libcharon/bus/bus.c
+++ b/src/libcharon/bus/bus.c
@@ -575,7 +575,7 @@ METHOD(bus_t, message, void,
METHOD(bus_t, ike_keys, void,
private_bus_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh,
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
- ike_sa_t *rekey, shared_key_t *shared)
+ ike_sa_t *rekey, shared_key_t *shared, auth_method_t method)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -591,7 +591,8 @@ METHOD(bus_t, ike_keys, void,
}
entry->calling++;
keep = entry->listener->ike_keys(entry->listener, ike_sa, dh, dh_other,
- nonce_i, nonce_r, rekey, shared);
+ nonce_i, nonce_r, rekey, shared,
+ method);
entry->calling--;
if (!keep)
{
diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h
index df75683be..8a97e8dfc 100644
--- a/src/libcharon/bus/bus.h
+++ b/src/libcharon/bus/bus.h
@@ -353,10 +353,12 @@ struct bus_t {
* @param nonce_r responder's nonce
* @param rekey IKE_SA we are rekeying, if any (IKEv2 only)
* @param shared shared key used for key derivation (IKEv1-PSK only)
+ * @param method auth method for key derivation (IKEv1-non-PSK only)
*/
void (*ike_keys)(bus_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh,
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
- ike_sa_t *rekey, shared_key_t *shared);
+ ike_sa_t *rekey, shared_key_t *shared,
+ auth_method_t method);
/**
* IKE_SA derived keys hook.
diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h
index 06057eb73..0f3b8578a 100644
--- a/src/libcharon/bus/listeners/listener.h
+++ b/src/libcharon/bus/listeners/listener.h
@@ -88,11 +88,13 @@ struct listener_t {
* @param nonce_r responder's nonce
* @param rekey IKE_SA we are rekeying, if any (IKEv2 only)
* @param shared shared key used for key derivation (IKEv1-PSK only)
+ * @param method auth method for key derivation (IKEv1-non-PSK only)
* @return TRUE to stay registered, FALSE to unregister
*/
bool (*ike_keys)(listener_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh,
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
- ike_sa_t *rekey, shared_key_t *shared);
+ ike_sa_t *rekey, shared_key_t *shared,
+ auth_method_t method);
/**
* Hook called with derived IKE_SA keys.
diff --git a/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c b/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c
index 644cff029..1abbf7731 100644
--- a/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c
+++ b/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c
@@ -64,6 +64,7 @@ typedef struct {
private_bypass_lan_listener_t *listener;
host_t *net;
uint8_t mask;
+ char *iface;
child_cfg_t *cfg;
} bypass_policy_t;
@@ -85,6 +86,7 @@ static void bypass_policy_destroy(bypass_policy_t *this)
ts->destroy(ts);
}
this->net->destroy(this->net);
+ free(this->iface);
free(this);
}
@@ -126,6 +128,7 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
enumerator_t *enumerator;
hashtable_t *seen;
bypass_policy_t *found, *lookup;
+ traffic_selector_t *ts;
host_t *net;
uint8_t mask;
char *iface;
@@ -146,6 +149,7 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
INIT(lookup,
.net = net->clone(net),
.mask = mask,
+ .iface = strdupnull(iface),
);
found = seen->put(seen, lookup, lookup);
if (found)
@@ -160,7 +164,6 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
.mode = MODE_PASS,
};
child_cfg_t *cfg;
- traffic_selector_t *ts;
char name[128];
ts = traffic_selector_create_from_subnet(net->clone(net), mask,
@@ -176,6 +179,7 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
INIT(found,
.net = net->clone(net),
.mask = mask,
+ .iface = strdupnull(iface),
.cfg = cfg,
);
this->policies->put(this->policies, found, found);
@@ -186,11 +190,29 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
enumerator = this->policies->create_enumerator(this->policies);
while (enumerator->enumerate(enumerator, NULL, &lookup))
{
- if (!seen->get(seen, lookup))
+ found = seen->get(seen, lookup);
+ if (!found)
{
this->policies->remove_at(this->policies, enumerator);
bypass_policy_destroy(lookup);
}
+ else if (!streq(lookup->iface, found->iface))
+ { /* if the subnet is on multiple interfaces, we only get the last
+ * one (hopefully, they are enumerated in a consistent order) */
+ ts = traffic_selector_create_from_subnet(
+ lookup->net->clone(lookup->net),
+ lookup->mask, 0, 0, 65535);
+ DBG1(DBG_IKE, "interface change for bypass policy for %R (from %s "
+ "to %s)", ts, lookup->iface, found->iface);
+ ts->destroy(ts);
+ free(lookup->iface);
+ lookup->iface = strdupnull(found->iface);
+ /* there is currently no API to update shunts, so we remove and
+ * reinstall it to update the route */
+ charon->shunts->uninstall(charon->shunts, "bypass-lan",
+ lookup->cfg->get_name(lookup->cfg));
+ charon->shunts->install(charon->shunts, "bypass-lan", lookup->cfg);
+ }
}
enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c
index 1e208d094..ecd92f2ef 100644
--- a/src/libcharon/plugins/dhcp/dhcp_socket.c
+++ b/src/libcharon/plugins/dhcp/dhcp_socket.c
@@ -489,6 +489,16 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
offer = host_create_from_chunk(AF_INET,
chunk_from_thing(dhcp->your_address), 0);
+ if (offer->is_anyaddr(offer))
+ {
+ server = host_create_from_chunk(AF_INET,
+ chunk_from_thing(dhcp->server_address), 0);
+ DBG1(DBG_CFG, "ignoring DHCP OFFER %+H from %H", offer, server);
+ server->destroy(server);
+ offer->destroy(offer);
+ return;
+ }
+
this->mutex->lock(this->mutex);
enumerator = this->discover->create_enumerator(this->discover);
while (enumerator->enumerate(enumerator, &transaction))
diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c
index fbbf6da83..ae1371b45 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2017 Tobias Brunner
+ * Copyright (C) 2012-2018 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
*
@@ -156,7 +156,7 @@ void eap_radius_build_attributes(radius_message_t *request)
{
ike_sa_t *ike_sa;
host_t *host;
- char buf[40], *station_id_fmt;;
+ char buf[40], *station_id_fmt, *session_id;
uint32_t value;
chunk_t chunk;
@@ -202,6 +202,14 @@ void eap_radius_build_attributes(radius_message_t *request)
host = ike_sa->get_other_host(ike_sa);
snprintf(buf, sizeof(buf), station_id_fmt, host);
request->add(request, RAT_CALLING_STATION_ID, chunk_from_str(buf));
+
+ session_id = eap_radius_accounting_session_id(ike_sa);
+ if (session_id)
+ {
+ request->add(request, RAT_ACCT_SESSION_ID,
+ chunk_from_str(session_id));
+ free(session_id);
+ }
}
}
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
index 92611492b..ecb2083c9 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2017 Tobias Brunner
+ * Copyright (C) 2015-2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2012 Martin Willi
@@ -17,6 +17,7 @@
*/
#include "eap_radius_accounting.h"
+#include "eap_radius_provider.h"
#include "eap_radius_plugin.h"
#include <time.h>
@@ -461,6 +462,37 @@ static void add_ike_sa_parameters(private_eap_radius_accounting_t *this,
}
/**
+ * Add any unclaimed IP addresses to the message
+ */
+static void add_unclaimed_ips(radius_message_t *message, ike_sa_t *ike_sa)
+{
+ eap_radius_provider_t *provider;
+ enumerator_t *enumerator;
+ host_t *vip;
+
+ provider = eap_radius_provider_get();
+ enumerator = provider->clear_unclaimed(provider,
+ ike_sa->get_unique_id(ike_sa));
+ while (enumerator->enumerate(enumerator, &vip))
+ {
+ switch (vip->get_family(vip))
+ {
+ case AF_INET:
+ message->add(message, RAT_FRAMED_IP_ADDRESS,
+ vip->get_address(vip));
+ break;
+ case AF_INET6:
+ message->add(message, RAT_FRAMED_IPV6_ADDRESS,
+ vip->get_address(vip));
+ break;
+ default:
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
* Add the Class attributes received in the Access-Accept message to the
* RADIUS accounting message
*/
@@ -790,6 +822,7 @@ static void send_stop(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa)
chunk_create(entry->sid, strlen(entry->sid)));
add_class_attributes(message, entry);
add_ike_sa_parameters(this, message, ike_sa);
+ add_unclaimed_ips(message, ike_sa);
value = htonl(entry->usage.bytes.sent);
message->add(message, RAT_ACCT_OUTPUT_OCTETS, chunk_from_thing(value));
@@ -816,7 +849,6 @@ static void send_stop(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa)
value = htonl(time_monotonic(NULL) - entry->created);
message->add(message, RAT_ACCT_SESSION_TIME, chunk_from_thing(value));
-
value = htonl(entry->cause);
message->add(message, RAT_ACCT_TERMINATE_CAUSE, chunk_from_thing(value));
@@ -1070,8 +1102,27 @@ eap_radius_accounting_t *eap_radius_accounting_create()
return &this->public;
}
-/**
- * See header
+/*
+ * Described in header
+ */
+char *eap_radius_accounting_session_id(ike_sa_t *ike_sa)
+{
+ entry_t *entry;
+ char *sid = NULL;
+
+ if (singleton)
+ {
+ singleton->mutex->lock(singleton->mutex);
+ entry = get_or_create_entry(singleton, ike_sa->get_id(ike_sa),
+ ike_sa->get_unique_id(ike_sa));
+ sid = strdup(entry->sid);
+ singleton->mutex->unlock(singleton->mutex);
+ }
+ return sid;
+}
+
+/*
+ * Described in header
*/
void eap_radius_accounting_start_interim(ike_sa_t *ike_sa, uint32_t interval)
{
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.h b/src/libcharon/plugins/eap_radius/eap_radius_accounting.h
index dc1edcf54..1fe1107ea 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.h
+++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Tobias Brunner
+ * Copyright (C) 2017-2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2012 Martin Willi
@@ -50,6 +50,14 @@ struct eap_radius_accounting_t {
eap_radius_accounting_t *eap_radius_accounting_create();
/**
+ * Get the Accounting session ID for the given IKE_SA.
+ *
+ * @param ike_sa IKE_SA for which to determine the session ID
+ * @return allocated session ID
+ */
+char *eap_radius_accounting_session_id(ike_sa_t *ike_sa);
+
+/**
* Schedule Accounting interim updates for the given IKE_SA.
*
* @param ike_sa IKE_SA to send updates for
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_provider.c b/src/libcharon/plugins/eap_radius/eap_radius_provider.c
index 8188bb764..defabb782 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_provider.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_provider.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2013 Martin Willi
* Copyright (C) 2013 revosec AG
*
@@ -131,7 +134,7 @@ static entry_t* get_or_create_entry(hashtable_t *hashtable, uintptr_t id)
}
/**
- * Put an entry to hashtable, or destroy it ife empty
+ * Put an entry to hashtable, or destroy it if empty
*/
static void put_or_destroy_entry(hashtable_t *hashtable, entry_t *entry)
{
@@ -494,6 +497,24 @@ METHOD(eap_radius_provider_t, add_attribute, void,
this->listener.mutex->unlock(this->listener.mutex);
}
+METHOD(eap_radius_provider_t, clear_unclaimed, enumerator_t*,
+ private_eap_radius_provider_t *this, uint32_t id)
+{
+ entry_t *entry;
+
+ this->listener.mutex->lock(this->listener.mutex);
+ entry = this->listener.unclaimed->remove(this->listener.unclaimed,
+ (void*)(uintptr_t)id);
+ this->listener.mutex->unlock(this->listener.mutex);
+ if (!entry)
+ {
+ return enumerator_create_empty();
+ }
+ return enumerator_create_cleaner(
+ entry->addrs->create_enumerator(entry->addrs),
+ (void*)destroy_entry, entry);
+}
+
METHOD(eap_radius_provider_t, destroy, void,
private_eap_radius_provider_t *this)
{
@@ -523,6 +544,7 @@ eap_radius_provider_t *eap_radius_provider_create()
},
.add_framed_ip = _add_framed_ip,
.add_attribute = _add_attribute,
+ .clear_unclaimed = _clear_unclaimed,
.destroy = _destroy,
},
.listener = {
@@ -539,6 +561,14 @@ eap_radius_provider_t *eap_radius_provider_create()
},
);
+ if (lib->settings->get_bool(lib->settings,
+ "%s.plugins.eap-radius.accounting", FALSE, lib->ns))
+ {
+ /* if RADIUS accounting is enabled, keep unclaimed IPs around until
+ * the Accounting-Stop message is sent */
+ this->listener.public.message = NULL;
+ }
+
charon->bus->add_listener(charon->bus, &this->listener.public);
singleton = &this->public;
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_provider.h b/src/libcharon/plugins/eap_radius/eap_radius_provider.h
index 80971bddb..9f1121ca3 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_provider.h
+++ b/src/libcharon/plugins/eap_radius/eap_radius_provider.h
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2013 Martin Willi
* Copyright (C) 2013 revosec AG
*
@@ -56,6 +59,14 @@ struct eap_radius_provider_t {
configuration_attribute_type_t type, chunk_t data);
/**
+ * Clears any unclaimed IP addresses and attributes for the given IKE_SA.
+ *
+ * @param id IKE_SA unique identifier
+ * @return enumerator over unclaimed IP addresses, if any
+ */
+ enumerator_t *(*clear_unclaimed)(eap_radius_provider_t *this, uint32_t id);
+
+ /**
* Destroy a eap_radius_provider_t.
*/
void (*destroy)(eap_radius_provider_t *this);
diff --git a/src/libcharon/plugins/ha/ha_attribute.c b/src/libcharon/plugins/ha/ha_attribute.c
index 34d6efc48..2553fd014 100644
--- a/src/libcharon/plugins/ha/ha_attribute.c
+++ b/src/libcharon/plugins/ha/ha_attribute.c
@@ -159,13 +159,13 @@ static pool_t* get_pool(private_ha_attribute_t *this, char *name)
}
/**
- * Check if we are responsible for a bit in our bitmask
+ * Check if we are responsible for an offset
*/
-static bool responsible_for(private_ha_attribute_t *this, int bit)
+static bool responsible_for(private_ha_attribute_t *this, int offset)
{
u_int segment;
- segment = this->kernel->get_segment_int(this->kernel, bit);
+ segment = offset % this->segments->count(this->segments) + 1;
return this->segments->is_active(this->segments, segment);
}
@@ -175,7 +175,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
{
enumerator_t *enumerator;
pool_t *pool = NULL;
- int offset = -1, byte, bit;
+ int offset = -1, tmp_offset, byte, bit;
host_t *address;
char *name;
@@ -199,10 +199,11 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
{
for (bit = 0; bit < 8; bit++)
{
+ tmp_offset = byte * 8 + bit;
if (!(pool->mask[byte] & 1 << bit) &&
- responsible_for(this, bit))
+ responsible_for(this, tmp_offset))
{
- offset = byte * 8 + bit;
+ offset = tmp_offset;
pool->mask[byte] |= 1 << bit;
break;
}
diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c
index 4e3803892..ab845317f 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -138,6 +138,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
chunk_t dh_local = chunk_empty, dh_remote = chunk_empty, psk = chunk_empty;
host_t *other = NULL;
bool ok = FALSE;
+ auth_method_t method = AUTH_RSA;
enumerator = message->create_attribute_enumerator(message);
while (enumerator->enumerate(enumerator, &attribute, &value))
@@ -197,6 +198,8 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
case HA_ALG_DH:
dh_grp = value.u16;
break;
+ case HA_AUTH_METHOD:
+ method = value.u16;
default:
break;
}
@@ -238,7 +241,6 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
{
keymat_v1_t *keymat_v1 = (keymat_v1_t*)ike_sa->get_keymat(ike_sa);
shared_key_t *shared = NULL;
- auth_method_t method = AUTH_RSA;
if (psk.len)
{
diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c
index 2854ab76d..aae402d50 100644
--- a/src/libcharon/plugins/ha/ha_ike.c
+++ b/src/libcharon/plugins/ha/ha_ike.c
@@ -73,7 +73,7 @@ static ike_extension_t copy_extension(ike_sa_t *ike_sa, ike_extension_t ext)
METHOD(listener_t, ike_keys, bool,
private_ha_ike_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh,
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey,
- shared_key_t *shared)
+ shared_key_t *shared, auth_method_t method)
{
ha_message_t *m;
chunk_t secret;
@@ -141,6 +141,10 @@ METHOD(listener_t, ike_keys, bool,
{
m->add_attribute(m, HA_PSK, shared->get_key(shared));
}
+ else
+ {
+ m->add_attribute(m, HA_AUTH_METHOD, method);
+ }
}
m->add_attribute(m, HA_REMOTE_ADDR, ike_sa->get_other_host(ike_sa));
diff --git a/src/libcharon/plugins/ha/ha_message.c b/src/libcharon/plugins/ha/ha_message.c
index 7891b1654..28b7b0d5b 100644
--- a/src/libcharon/plugins/ha/ha_message.c
+++ b/src/libcharon/plugins/ha/ha_message.c
@@ -240,6 +240,7 @@ METHOD(ha_message_t, add_attribute, void,
case HA_OUTBOUND_CPI:
case HA_SEGMENT:
case HA_ESN:
+ case HA_AUTH_METHOD:
{
uint16_t val;
@@ -463,6 +464,7 @@ METHOD(enumerator_t, attribute_enumerate, bool,
case HA_OUTBOUND_CPI:
case HA_SEGMENT:
case HA_ESN:
+ case HA_AUTH_METHOD:
{
if (this->buf.len < sizeof(uint16_t))
{
diff --git a/src/libcharon/plugins/ha/ha_message.h b/src/libcharon/plugins/ha/ha_message.h
index 3e43dc8dc..3c0058d99 100644
--- a/src/libcharon/plugins/ha/ha_message.h
+++ b/src/libcharon/plugins/ha/ha_message.h
@@ -156,6 +156,8 @@ enum ha_message_attribute_t {
HA_PSK,
/** chunk_t, IV for next IKEv1 message */
HA_IV,
+ /** uint16_t, auth_method_t for IKEv1 key derivation */
+ HA_AUTH_METHOD,
};
/**
diff --git a/src/libcharon/plugins/ha/ha_segments.c b/src/libcharon/plugins/ha/ha_segments.c
index 0a407f9ef..153534915 100644
--- a/src/libcharon/plugins/ha/ha_segments.c
+++ b/src/libcharon/plugins/ha/ha_segments.c
@@ -433,6 +433,12 @@ METHOD(ha_segments_t, is_active, bool,
return (this->active & SEGMENTS_BIT(segment)) != 0;
}
+METHOD(ha_segments_t, count, u_int,
+ private_ha_segments_t *this)
+{
+ return this->count;
+}
+
METHOD(ha_segments_t, destroy, void,
private_ha_segments_t *this)
{
@@ -459,6 +465,7 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel,
.deactivate = _deactivate,
.handle_status = _handle_status,
.is_active = _is_active,
+ .count = _count,
.destroy = _destroy,
},
.socket = socket,
diff --git a/src/libcharon/plugins/ha/ha_segments.h b/src/libcharon/plugins/ha/ha_segments.h
index 10d5812c6..bc96a8d3e 100644
--- a/src/libcharon/plugins/ha/ha_segments.h
+++ b/src/libcharon/plugins/ha/ha_segments.h
@@ -83,6 +83,13 @@ struct ha_segments_t {
bool (*is_active)(ha_segments_t *this, u_int segment);
/**
+ * Return the number of segments
+ *
+ * @return number of segments
+ */
+ u_int (*count)(ha_segments_t *this);
+
+ /**
* Destroy a ha_segments_t.
*/
void (*destroy)(ha_segments_t *this);
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
index 1292e0895..40fff7e05 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -2257,6 +2257,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
uint32_t replay_esn_len = 0;
kernel_ipsec_del_sa_t del = { 0 };
status_t status = FAILED;
+ traffic_selector_t *ts;
char markstr[32] = "";
/* if IPComp is used, we first update the IPComp SA */
@@ -2360,10 +2361,26 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
if (!id->src->ip_equals(id->src, data->new_src))
{
host2xfrm(data->new_src, &sa->saddr);
+
+ ts = selector2ts(&sa->sel, TRUE);
+ if (ts && ts->is_host(ts, id->src))
+ {
+ ts->set_address(ts, data->new_src);
+ ts2subnet(ts, &sa->sel.saddr, &sa->sel.prefixlen_s);
+ }
+ DESTROY_IF(ts);
}
if (!id->dst->ip_equals(id->dst, data->new_dst))
{
host2xfrm(data->new_dst, &sa->id.daddr);
+
+ ts = selector2ts(&sa->sel, FALSE);
+ if (ts && ts->is_host(ts, id->dst))
+ {
+ ts->set_address(ts, data->new_dst);
+ ts2subnet(ts, &sa->sel.daddr, &sa->sel.prefixlen_d);
+ }
+ DESTROY_IF(ts);
}
rta = XFRM_RTA(out_hdr, struct xfrm_usersa_info);
diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index dbe409a62..37170a310 100644
--- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Tobias Brunner
+ * Copyright (C) 2008-2018 Tobias Brunner
* Copyright (C) 2008 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
@@ -1287,20 +1287,27 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this,
return;
}
- index = response.x_policy->sadb_x_policy_id;
- this->mutex->lock(this->mutex);
- if (this->policies->find_first(this->policies, policy_entry_match_byindex,
- (void**)&policy, index) &&
- policy->used_by->get_first(policy->used_by, (void**)&sa) == SUCCESS)
+ if (response.x_sa2)
{
- reqid = sa->sa->cfg.reqid;
+ reqid = response.x_sa2->sadb_x_sa2_reqid;
}
else
{
- DBG1(DBG_KNL, "received an SADB_ACQUIRE with policy id %d but no "
- "matching policy found", index);
+ index = response.x_policy->sadb_x_policy_id;
+ this->mutex->lock(this->mutex);
+ if (this->policies->find_first(this->policies, policy_entry_match_byindex,
+ (void**)&policy, index) &&
+ policy->used_by->get_first(policy->used_by, (void**)&sa) == SUCCESS)
+ {
+ reqid = sa->sa->cfg.reqid;
+ }
+ else
+ {
+ DBG1(DBG_KNL, "received an SADB_ACQUIRE with policy id %d but no "
+ "matching policy found", index);
+ }
+ this->mutex->unlock(this->mutex);
}
- this->mutex->unlock(this->mutex);
src_ts = sadb_address2ts(response.src);
dst_ts = sadb_address2ts(response.dst);
diff --git a/src/libcharon/plugins/vici/libvici.h b/src/libcharon/plugins/vici/libvici.h
index d69597881..964752f53 100644
--- a/src/libcharon/plugins/vici/libvici.h
+++ b/src/libcharon/plugins/vici/libvici.h
@@ -86,6 +86,10 @@
#include <stdio.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* Opaque vici connection contex.
*/
@@ -465,4 +469,8 @@ void vici_init();
*/
void vici_deinit();
+#ifdef __cplusplus
+}
+#endif
+
#endif /** LIBVICI_H_ @}*/
diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c
index 10c62dc89..ace7a4528 100644
--- a/src/libcharon/plugins/vici/vici_config.c
+++ b/src/libcharon/plugins/vici/vici_config.c
@@ -733,7 +733,7 @@ CALLBACK(parse_ts, bool,
if (host_create_from_range(buf, &lower, &upper))
{
type = (lower->get_family(lower) == AF_INET) ?
- TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE;
+ TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE;
ts = traffic_selector_create_from_bytes(proto, type,
lower->get_address(lower), from,
upper->get_address(upper), to);
@@ -2494,7 +2494,10 @@ CALLBACK(config_sn, bool,
if (peer.mediated_by)
{
cfg.mediated_by = peer.mediated_by;
- cfg.peer_id = peer.peer_id->clone(peer.peer_id);
+ if (peer.peer_id)
+ {
+ cfg.peer_id = peer.peer_id->clone(peer.peer_id);
+ }
}
#endif /* ME */
peer_cfg = peer_cfg_create(name, ike_cfg, &cfg);
diff --git a/src/libcharon/processing/jobs/adopt_children_job.c b/src/libcharon/processing/jobs/adopt_children_job.c
index 998af0d3f..e2a7f6b20 100644
--- a/src/libcharon/processing/jobs/adopt_children_job.c
+++ b/src/libcharon/processing/jobs/adopt_children_job.c
@@ -53,6 +53,36 @@ METHOD(job_t, destroy, void,
free(this);
}
+METHOD(adopt_children_job_t, queue_task, void,
+ private_adopt_children_job_t *this, task_t *task)
+{
+ array_insert_create(&this->tasks, ARRAY_TAIL, task);
+}
+
+/**
+ * Adopt child-creating tasks from the given IKE_SA
+ */
+static u_int adopt_child_tasks(private_adopt_children_job_t *this,
+ ike_sa_t *ike_sa, task_queue_t queue)
+{
+ enumerator_t *tasks;
+ task_t *task;
+ u_int count = 0;
+
+ tasks = ike_sa->create_task_enumerator(ike_sa, queue);
+ while (tasks->enumerate(tasks, &task))
+ {
+ if (task->get_type(task) == TASK_QUICK_MODE)
+ {
+ ike_sa->remove_task(ike_sa, tasks);
+ queue_task(this, task);
+ count++;
+ }
+ }
+ tasks->destroy(tasks);
+ return count;
+}
+
METHOD(job_t, execute, job_requeue_t,
private_adopt_children_job_t *this)
{
@@ -65,6 +95,7 @@ METHOD(job_t, execute, job_requeue_t,
ike_sa_t *ike_sa;
child_sa_t *child_sa;
uint32_t unique;
+ u_int tasks = 0;
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->id);
if (ike_sa)
@@ -127,11 +158,17 @@ METHOD(job_t, execute, job_requeue_t,
* it does trigger an assign_vips(FALSE) event, so we also
* trigger one below */
ike_sa->clear_virtual_ips(ike_sa, FALSE);
- if (children->get_count(children) || vips->get_count(vips))
+
+ tasks += adopt_child_tasks(this, ike_sa, TASK_QUEUE_ACTIVE);
+ tasks += adopt_child_tasks(this, ike_sa, TASK_QUEUE_QUEUED);
+
+ if (children->get_count(children) || tasks ||
+ vips->get_count(vips))
{
DBG1(DBG_IKE, "detected reauth of existing IKE_SA, "
- "adopting %d children and %d virtual IPs",
- children->get_count(children), vips->get_count(vips));
+ "adopting %d children, %d child tasks, and %d "
+ "virtual IPs", children->get_count(children),
+ tasks, vips->get_count(vips));
}
if (ike_sa->get_state(ike_sa) == IKE_PASSIVE)
{
@@ -152,7 +189,8 @@ METHOD(job_t, execute, job_requeue_t,
charon->ike_sa_manager->checkin(
charon->ike_sa_manager, ike_sa);
}
- if (children->get_count(children) || vips->get_count(vips))
+ if (children->get_count(children) || tasks ||
+ vips->get_count(vips))
{
break;
}
@@ -237,12 +275,6 @@ METHOD(job_t, get_priority, job_priority_t,
return JOB_PRIO_HIGH;
}
-METHOD(adopt_children_job_t, queue_task, void,
- private_adopt_children_job_t *this, task_t *task)
-{
- array_insert_create(&this->tasks, ARRAY_TAIL, task);
-}
-
/**
* See header
*/
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index c33398bee..bdc96a4bc 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -978,7 +978,7 @@ static void prepare_sa_cfg(private_child_sa_t *this, ipsec_sa_cfg_t *my_sa,
}
/**
- * Install inbound policie(s): in, fwd
+ * Install inbound policies: in, fwd
*/
static status_t install_policies_inbound(private_child_sa_t *this,
host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
@@ -1012,7 +1012,7 @@ static status_t install_policies_inbound(private_child_sa_t *this,
}
/**
- * Install outbound policie(s): out, [fwd]
+ * Install outbound policies: out, [fwd]
*/
static status_t install_policies_outbound(private_child_sa_t *this,
host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c
index a4ad866d3..3d576a0e8 100644
--- a/src/libcharon/sa/ike_sa.c
+++ b/src/libcharon/sa/ike_sa.c
@@ -1996,8 +1996,7 @@ static status_t reestablish_children(private_ike_sa_t *this, ike_sa_t *new,
/* adopt any active or queued CHILD-creating tasks */
if (status != DESTROY_ME)
{
- task_manager_t *other_tasks = ((private_ike_sa_t*)new)->task_manager;
- other_tasks->adopt_child_tasks(other_tasks, this->task_manager);
+ new->adopt_child_tasks(new, &this->public);
if (new->get_state(new) == IKE_CREATED)
{
status = new->initiate(new, NULL, 0, NULL, NULL);
@@ -2404,7 +2403,9 @@ METHOD(ike_sa_t, retransmit, status_t,
}
case IKE_DELETING:
DBG1(DBG_IKE, "proper IKE_SA delete failed, peer not responding");
- if (has_condition(this, COND_REAUTHENTICATING))
+ if (has_condition(this, COND_REAUTHENTICATING) &&
+ !lib->settings->get_bool(lib->settings,
+ "%s.make_before_break", FALSE, lib->ns))
{
DBG1(DBG_IKE, "delete during reauthentication failed, "
"trying to reestablish IKE_SA anyway");
@@ -2719,6 +2720,12 @@ METHOD(ike_sa_t, create_task_enumerator, enumerator_t*,
return this->task_manager->create_task_enumerator(this->task_manager, queue);
}
+METHOD(ike_sa_t, remove_task, void,
+ private_ike_sa_t *this, enumerator_t *enumerator)
+{
+ return this->task_manager->remove_task(this->task_manager, enumerator);
+}
+
METHOD(ike_sa_t, flush_queue, void,
private_ike_sa_t *this, task_queue_t queue)
{
@@ -2737,6 +2744,36 @@ METHOD(ike_sa_t, queue_task_delayed, void,
this->task_manager->queue_task_delayed(this->task_manager, task, delay);
}
+/**
+ * Migrate and queue child-creating tasks from another IKE_SA
+ */
+static void migrate_child_tasks(private_ike_sa_t *this, ike_sa_t *other,
+ task_queue_t queue)
+{
+ enumerator_t *enumerator;
+ task_t *task;
+
+ enumerator = other->create_task_enumerator(other, queue);
+ while (enumerator->enumerate(enumerator, &task))
+ {
+ if (task->get_type(task) == TASK_CHILD_CREATE ||
+ task->get_type(task) == TASK_QUICK_MODE)
+ {
+ other->remove_task(other, enumerator);
+ task->migrate(task, &this->public);
+ queue_task(this, task);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(ike_sa_t, adopt_child_tasks, void,
+ private_ike_sa_t *this, ike_sa_t *other)
+{
+ migrate_child_tasks(this, other, TASK_QUEUE_ACTIVE);
+ migrate_child_tasks(this, other, TASK_QUEUE_QUEUED);
+}
+
METHOD(ike_sa_t, inherit_pre, void,
private_ike_sa_t *this, ike_sa_t *other_public)
{
@@ -3052,9 +3089,11 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
.create_attribute_enumerator = _create_attribute_enumerator,
.set_kmaddress = _set_kmaddress,
.create_task_enumerator = _create_task_enumerator,
+ .remove_task = _remove_task,
.flush_queue = _flush_queue,
.queue_task = _queue_task,
.queue_task_delayed = _queue_task_delayed,
+ .adopt_child_tasks = _adopt_child_tasks,
#ifdef ME
.act_as_mediation_server = _act_as_mediation_server,
.get_server_reflexive_host = _get_server_reflexive_host,
diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h
index c1d3e1d7a..be480eac8 100644
--- a/src/libcharon/sa/ike_sa.h
+++ b/src/libcharon/sa/ike_sa.h
@@ -1125,6 +1125,16 @@ struct ike_sa_t {
enumerator_t* (*create_task_enumerator)(ike_sa_t *this, task_queue_t queue);
/**
+ * Remove the task the given enumerator points to.
+ *
+ * @note This should be used with caution, in partciular, for tasks in the
+ * active and passive queues.
+ *
+ * @param enumerator enumerator created with the method above
+ */
+ void (*remove_task)(ike_sa_t *this, enumerator_t *enumerator);
+
+ /**
* Flush a task queue, cancelling all tasks in it.
*
* @param queue queue type to flush
@@ -1148,6 +1158,13 @@ struct ike_sa_t {
void (*queue_task_delayed)(ike_sa_t *this, task_t *task, uint32_t delay);
/**
+ * Adopt child creating tasks from the given IKE_SA.
+ *
+ * @param other other IKE_SA to adopt tasks from
+ */
+ void (*adopt_child_tasks)(ike_sa_t *this, ike_sa_t *other);
+
+ /**
* Inherit required attributes to new SA before rekeying.
*
* Some properties of the SA must be applied before starting IKE_SA
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index c50c70860..3bac4b109 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -1967,6 +1967,8 @@ static void adopt_children_and_vips(ike_sa_t *old, ike_sa_t *new)
}
enumerator->destroy(enumerator);
+ new->adopt_child_tasks(new, old);
+
enumerator = old->create_virtual_ip_enumerator(old, FALSE);
while (enumerator->enumerate(enumerator, &vip))
{
diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c
index b99d75142..ac2899f11 100644
--- a/src/libcharon/sa/ikev1/phase1.c
+++ b/src/libcharon/sa/ikev1/phase1.c
@@ -251,7 +251,8 @@ METHOD(phase1_t, derive_keys, bool,
return FALSE;
}
charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, this->dh_value,
- this->nonce_i, this->nonce_r, NULL, shared_key);
+ this->nonce_i, this->nonce_r, NULL, shared_key,
+ method);
DESTROY_IF(shared_key);
return TRUE;
}
diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c
index 5f6c3bbe8..f76471e78 100644
--- a/src/libcharon/sa/ikev1/task_manager_v1.c
+++ b/src/libcharon/sa/ikev1/task_manager_v1.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2016 Tobias Brunner
+ * Copyright (C) 2007-2018 Tobias Brunner
* Copyright (C) 2007-2011 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
*
@@ -544,20 +544,20 @@ METHOD(task_manager_t, initiate, status_t,
new_mid = TRUE;
break;
}
- if (!mode_config_expected(this) &&
- activate_task(this, TASK_QUICK_MODE))
+ if (activate_task(this, TASK_ISAKMP_DPD))
{
- exchange = QUICK_MODE;
+ exchange = INFORMATIONAL_V1;
new_mid = TRUE;
break;
}
- if (activate_task(this, TASK_INFORMATIONAL))
+ if (!mode_config_expected(this) &&
+ activate_task(this, TASK_QUICK_MODE))
{
- exchange = INFORMATIONAL_V1;
+ exchange = QUICK_MODE;
new_mid = TRUE;
break;
}
- if (activate_task(this, TASK_ISAKMP_DPD))
+ if (activate_task(this, TASK_INFORMATIONAL))
{
exchange = INFORMATIONAL_V1;
new_mid = TRUE;
@@ -1121,7 +1121,15 @@ static status_t process_request(private_task_manager_t *this,
}
}
else
- { /* We don't send a response, so don't retransmit one if we get
+ {
+ if (this->responding.retransmitted > 1)
+ {
+ packet_t *packet = NULL;
+ array_get(this->responding.packets, 0, &packet);
+ charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_CLEARED,
+ packet);
+ }
+ /* We don't send a response, so don't retransmit one if we get
* the same message again. */
clear_packets(this->responding.packets);
}
@@ -1883,39 +1891,6 @@ METHOD(task_manager_t, adopt_tasks, void,
}
}
-/**
- * Migrates child-creating tasks from src to dst
- */
-static void migrate_child_tasks(private_task_manager_t *this,
- linked_list_t *src, linked_list_t *dst)
-{
- enumerator_t *enumerator;
- task_t *task;
-
- enumerator = src->create_enumerator(src);
- while (enumerator->enumerate(enumerator, &task))
- {
- if (task->get_type(task) == TASK_QUICK_MODE)
- {
- src->remove_at(src, enumerator);
- task->migrate(task, this->ike_sa);
- dst->insert_last(dst, task);
- }
- }
- enumerator->destroy(enumerator);
-}
-
-METHOD(task_manager_t, adopt_child_tasks, void,
- private_task_manager_t *this, task_manager_t *other_public)
-{
- private_task_manager_t *other = (private_task_manager_t*)other_public;
-
- /* move active child tasks from other to this */
- migrate_child_tasks(this, other->active_tasks, this->queued_tasks);
- /* do the same for queued tasks */
- migrate_child_tasks(this, other->queued_tasks, this->queued_tasks);
-}
-
METHOD(task_manager_t, busy, bool,
private_task_manager_t *this)
{
@@ -1976,19 +1951,86 @@ METHOD(task_manager_t, reset, void,
}
}
+/**
+ * Data for a task queue enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ task_queue_t queue;
+ enumerator_t *inner;
+} task_enumerator_t;
+
+METHOD(enumerator_t, task_enumerator_destroy, void,
+ task_enumerator_t *this)
+{
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+METHOD(enumerator_t, task_enumerator_enumerate, bool,
+ task_enumerator_t *this, va_list args)
+{
+ task_t **task;
+
+ VA_ARGS_VGET(args, task);
+ return this->inner->enumerate(this->inner, task);
+}
+
METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
private_task_manager_t *this, task_queue_t queue)
{
+ task_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = enumerator_enumerate_default,
+ .venumerate = _task_enumerator_enumerate,
+ .destroy = _task_enumerator_destroy,
+ },
+ .queue = queue,
+ );
switch (queue)
{
case TASK_QUEUE_ACTIVE:
- return this->active_tasks->create_enumerator(this->active_tasks);
+ enumerator->inner = this->active_tasks->create_enumerator(
+ this->active_tasks);
+ break;
+ case TASK_QUEUE_PASSIVE:
+ enumerator->inner = this->passive_tasks->create_enumerator(
+ this->passive_tasks);
+ break;
+ case TASK_QUEUE_QUEUED:
+ enumerator->inner = this->queued_tasks->create_enumerator(
+ this->queued_tasks);
+ break;
+ default:
+ enumerator->inner = enumerator_create_empty();
+ break;
+ }
+ return &enumerator->public;
+}
+
+METHOD(task_manager_t, remove_task, void,
+ private_task_manager_t *this, enumerator_t *enumerator_public)
+{
+ task_enumerator_t *enumerator = (task_enumerator_t*)enumerator_public;
+
+ switch (enumerator->queue)
+ {
+ case TASK_QUEUE_ACTIVE:
+ this->active_tasks->remove_at(this->active_tasks,
+ enumerator->inner);
+ break;
case TASK_QUEUE_PASSIVE:
- return this->passive_tasks->create_enumerator(this->passive_tasks);
+ this->passive_tasks->remove_at(this->passive_tasks,
+ enumerator->inner);
+ break;
case TASK_QUEUE_QUEUED:
- return this->queued_tasks->create_enumerator(this->queued_tasks);
+ this->queued_tasks->remove_at(this->queued_tasks,
+ enumerator->inner);
+ break;
default:
- return enumerator_create_empty();
+ break;
}
}
@@ -2039,9 +2081,9 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
.get_mid = _get_mid,
.reset = _reset,
.adopt_tasks = _adopt_tasks,
- .adopt_child_tasks = _adopt_child_tasks,
.busy = _busy,
.create_task_enumerator = _create_task_enumerator,
+ .remove_task = _remove_task,
.flush = _flush,
.flush_queue = _flush_queue,
.destroy = _destroy,
diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c b/src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c
index 7dbbdc92f..b652d926f 100644
--- a/src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c
+++ b/src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c
@@ -287,7 +287,6 @@ METHOD(task_t, process_i, status_t,
default:
return FAILED;
}
- break;
}
case AGGRESSIVE:
{
diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c b/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c
index 58f856e3f..566bfe83a 100644
--- a/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c
+++ b/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c
@@ -605,7 +605,6 @@ METHOD(task_t, process_i, status_t,
default:
return FAILED;
}
- break;
}
case AGGRESSIVE:
{
diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c
index 007e94d96..b0a42b8bd 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_mode.c
+++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c
@@ -1110,14 +1110,17 @@ METHOD(task_t, process_r, status_t,
this->tsi = select_ts(this, FALSE, tsi);
this->tsr = select_ts(this, TRUE, tsr);
}
- tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
- tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
if (!this->config || !this->tsi || !this->tsr ||
this->mode != this->config->get_mode(this->config))
{
- DBG1(DBG_IKE, "no matching CHILD_SA config found");
+ DBG1(DBG_IKE, "no matching CHILD_SA config found for "
+ "%#R === %#R", tsi, tsr);
+ tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
+ tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
return send_notify(this, INVALID_ID_INFORMATION);
}
+ tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
+ tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
if (this->config->has_option(this->config, OPT_IPCOMP))
{
diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
index 1fcef03cc..97d33a89e 100644
--- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
+++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
@@ -111,6 +111,40 @@ static bool build_signature_auth_data(chunk_t *auth_data,
}
/**
+ * Check if the given scheme is supported by the key and, if so, add it to the
+ * first array (we add the scheme supported by the key in case the parameters
+ * are different)
+ */
+static void add_scheme_if_supported(array_t *selected, array_t *supported,
+ signature_params_t *config)
+{
+ signature_params_t *sup;
+ int i;
+
+ if (!supported)
+ {
+ array_insert(selected, ARRAY_TAIL, signature_params_clone(config));
+ return;
+ }
+
+ for (i = 0; i < array_count(supported); i++)
+ {
+ array_get(supported, i, &sup);
+ if (signature_params_comply(sup, config))
+ {
+ array_insert(selected, ARRAY_TAIL, signature_params_clone(sup));
+ return;
+ }
+ }
+}
+
+CALLBACK(destroy_scheme, void,
+ signature_params_t *params, int idx, void *user)
+{
+ signature_params_destroy(params);
+}
+
+/**
* Selects possible signature schemes based on our configuration, the other
* peer's capabilities and the private key
*/
@@ -123,10 +157,32 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
auth_rule_t rule;
key_type_t key_type;
bool have_config = FALSE;
- array_t *selected;
+ array_t *supported = NULL, *selected;
selected = array_create(0, 0);
key_type = private->get_type(private);
+
+ if (private->supported_signature_schemes)
+ {
+ enumerator = private->supported_signature_schemes(private);
+ while (enumerator->enumerate(enumerator, &config))
+ {
+ if (keymat->hash_algorithm_supported(keymat,
+ hasher_from_signature_scheme(config->scheme,
+ config->params)))
+ {
+ array_insert_create(&supported, ARRAY_TAIL,
+ signature_params_clone(config));
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!supported)
+ {
+ return selected;
+ }
+ }
+
enumerator = auth->create_enumerator(auth);
while (enumerator->enumerate(enumerator, &rule, &config))
{
@@ -134,21 +190,32 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
{
continue;
}
- have_config = TRUE;
if (key_type == key_type_from_signature_scheme(config->scheme) &&
keymat->hash_algorithm_supported(keymat,
hasher_from_signature_scheme(config->scheme,
config->params)))
{
- array_insert(selected, ARRAY_TAIL, signature_params_clone(config));
+ add_scheme_if_supported(selected, supported, config);
}
+ have_config = TRUE;
}
enumerator->destroy(enumerator);
- if (!have_config)
+ if (have_config)
{
- /* if no specific configuration, find schemes appropriate for the key
- * and supported by the other peer */
+ array_destroy_function(supported, destroy_scheme, NULL);
+ }
+ else
+ {
+ /* if we have no config, return either whatever schemes the key (and
+ * peer) support or.. */
+ if (supported)
+ {
+ array_destroy(selected);
+ return supported;
+ }
+
+ /* ...find schemes appropriate for the key and supported by the peer */
enumerator = signature_schemes_for_key(key_type,
private->get_keysize(private));
while (enumerator->enumerate(enumerator, &config))
@@ -207,12 +274,6 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
return selected;
}
-CALLBACK(destroy_scheme, void,
- signature_params_t *params, int idx, void *user)
-{
- signature_params_destroy(params);
-}
-
/**
* Adds the given auth data to the message, either in an AUTH payload or
* a NO_PPK_AUTH notify.
@@ -310,9 +371,9 @@ static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
if (params->scheme == SIGN_RSA_EMSA_PSS)
{
rsa_pss_params_t *pss = params->params;
- DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N_%N %s", id,
- signature_scheme_names, params->scheme,
- hash_algorithm_short_names_upper, pss->hash,
+ DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N_%N_SALT_%zd "
+ "%s", id, signature_scheme_names, params->scheme,
+ hash_algorithm_short_names_upper, pss->hash, pss->salt_len,
status == SUCCESS ? "successful" : "failed");
}
else
@@ -586,9 +647,9 @@ METHOD(authenticator_t, process, status_t,
else if (params->scheme == SIGN_RSA_EMSA_PSS)
{
rsa_pss_params_t *pss = params->params;
- DBG1(DBG_IKE, "authentication of '%Y' with %N_%N successful",
- id, signature_scheme_names, params->scheme,
- hash_algorithm_short_names_upper, pss->hash);
+ DBG1(DBG_IKE, "authentication of '%Y' with %N_%N_SALT_%zd "
+ "successful", id, signature_scheme_names, params->scheme,
+ hash_algorithm_short_names_upper, pss->hash, pss->salt_len);
}
else
{
diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c
index 910c77a2d..e9142d79b 100644
--- a/src/libcharon/sa/ikev2/task_manager_v2.c
+++ b/src/libcharon/sa/ikev2/task_manager_v2.c
@@ -1459,6 +1459,59 @@ static bool looks_like_mid_sync(private_task_manager_t *this, message_t *msg,
}
/**
+ * Check whether we should reject the given request message
+ */
+static inline bool reject_request(private_task_manager_t *this,
+ message_t *msg)
+{
+ ike_sa_state_t state;
+ exchange_type_t type;
+ ike_sa_id_t *ike_sa_id;
+ bool reject = FALSE;
+
+ state = this->ike_sa->get_state(this->ike_sa);
+ type = msg->get_exchange_type(msg);
+
+ /* reject initial messages if not received in specific states */
+ switch (type)
+ {
+ case IKE_SA_INIT:
+ reject = state != IKE_CREATED;
+ break;
+ case IKE_AUTH:
+ reject = state != IKE_CONNECTING;
+ break;
+ default:
+ break;
+ }
+
+ if (!reject)
+ {
+ switch (state)
+ {
+ /* after rekeying we only expect a DELETE in an INFORMATIONAL */
+ case IKE_REKEYED:
+ reject = type != INFORMATIONAL;
+ break;
+ /* also reject requests for half-open IKE_SAs as initiator */
+ case IKE_CREATED:
+ case IKE_CONNECTING:
+ ike_sa_id = this->ike_sa->get_id(this->ike_sa);
+ reject = ike_sa_id->is_initiator(ike_sa_id);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (reject)
+ {
+ DBG1(DBG_IKE, "ignoring %N in IKE_SA state %N", exchange_type_names,
+ type, ike_sa_state_names, state);
+ }
+ return reject;
+}
+/**
* Check if a message with message ID 0 looks like it is used to synchronize
* the message IDs and we are prepared to process it.
*
@@ -1483,8 +1536,6 @@ METHOD(task_manager_t, process_message, status_t,
status_t status;
uint32_t mid;
bool schedule_delete_job = FALSE;
- ike_sa_state_t state;
- exchange_type_t type;
charon->bus->message(charon->bus, msg, TRUE, FALSE);
status = parse_message(this, msg);
@@ -1517,24 +1568,14 @@ METHOD(task_manager_t, process_message, status_t,
/* add a timeout if peer does not establish it completely */
schedule_delete_job = TRUE;
}
- this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
- time_monotonic(NULL));
mid = msg->get_message_id(msg);
if (msg->get_request(msg))
{
if (mid == this->responding.mid || (mid == 0 && is_mid_sync(this, msg)))
{
- /* reject initial messages if not received in specific states,
- * after rekeying we only expect a DELETE in an INFORMATIONAL */
- type = msg->get_exchange_type(msg);
- state = this->ike_sa->get_state(this->ike_sa);
- if ((type == IKE_SA_INIT && state != IKE_CREATED) ||
- (type == IKE_AUTH && state != IKE_CONNECTING) ||
- (state == IKE_REKEYED && type != INFORMATIONAL))
+ if (reject_request(this, msg))
{
- DBG1(DBG_IKE, "ignoring %N in IKE_SA state %N",
- exchange_type_names, type, ike_sa_state_names, state);
return FAILED;
}
if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
@@ -1544,6 +1585,11 @@ METHOD(task_manager_t, process_message, status_t,
status = handle_fragment(this, &this->responding.defrag, msg);
if (status != SUCCESS)
{
+ if (status == NEED_MORE)
+ {
+ this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
+ time_monotonic(NULL));
+ }
return status;
}
charon->bus->message(charon->bus, msg, TRUE, TRUE);
@@ -1554,6 +1600,8 @@ METHOD(task_manager_t, process_message, status_t,
switch (process_request(this, msg))
{
case SUCCESS:
+ this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
+ time_monotonic(NULL));
this->responding.mid++;
break;
case NEED_MORE:
@@ -1570,10 +1618,17 @@ METHOD(task_manager_t, process_message, status_t,
status = handle_fragment(this, &this->responding.defrag, msg);
if (status != SUCCESS)
{
+ if (status == NEED_MORE)
+ {
+ this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
+ time_monotonic(NULL));
+ }
return status;
}
DBG1(DBG_IKE, "received retransmit of request with ID %d, "
"retransmitting response", mid);
+ this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
+ time_monotonic(NULL));
charon->bus->alert(charon->bus, ALERT_RETRANSMIT_RECEIVE, msg);
send_packets(this, this->responding.packets,
msg->get_destination(msg), msg->get_source(msg));
@@ -1603,6 +1658,11 @@ METHOD(task_manager_t, process_message, status_t,
status = handle_fragment(this, &this->initiating.defrag, msg);
if (status != SUCCESS)
{
+ if (status == NEED_MORE)
+ {
+ this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
+ time_monotonic(NULL));
+ }
return status;
}
charon->bus->message(charon->bus, msg, TRUE, TRUE);
@@ -1615,6 +1675,8 @@ METHOD(task_manager_t, process_message, status_t,
flush(this);
return DESTROY_ME;
}
+ this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND,
+ time_monotonic(NULL));
}
else
{
@@ -2014,61 +2076,6 @@ METHOD(task_manager_t, adopt_tasks, void,
}
}
-/**
- * Migrates child-creating tasks from other to this
- */
-static void migrate_child_tasks(private_task_manager_t *this,
- private_task_manager_t *other,
- task_queue_t queue)
-{
- enumerator_t *enumerator;
- array_t *array;
- task_t *task;
-
- switch (queue)
- {
- case TASK_QUEUE_ACTIVE:
- array = other->active_tasks;
- break;
- case TASK_QUEUE_QUEUED:
- array = other->queued_tasks;
- break;
- default:
- return;
- }
-
- enumerator = array_create_enumerator(array);
- while (enumerator->enumerate(enumerator, &task))
- {
- queued_task_t *queued = NULL;
-
- if (queue == TASK_QUEUE_QUEUED)
- {
- queued = (queued_task_t*)task;
- task = queued->task;
- }
- if (task->get_type(task) == TASK_CHILD_CREATE)
- {
- array_remove_at(array, enumerator);
- task->migrate(task, this->ike_sa);
- queue_task(this, task);
- free(queued);
- }
- }
- enumerator->destroy(enumerator);
-}
-
-METHOD(task_manager_t, adopt_child_tasks, void,
- private_task_manager_t *this, task_manager_t *other_public)
-{
- private_task_manager_t *other = (private_task_manager_t*)other_public;
-
- /* move active child tasks from other to this */
- migrate_child_tasks(this, other, TASK_QUEUE_ACTIVE);
- /* do the same for queued tasks */
- migrate_child_tasks(this, other, TASK_QUEUE_QUEUED);
-}
-
METHOD(task_manager_t, busy, bool,
private_task_manager_t *this)
{
@@ -2124,17 +2131,39 @@ METHOD(task_manager_t, reset, void,
this->reset = TRUE;
}
-CALLBACK(filter_queued, bool,
- void *unused, enumerator_t *orig, va_list args)
-{
+/**
+ * Data for a task queue enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ task_queue_t queue;
+ enumerator_t *inner;
queued_task_t *queued;
+} task_enumerator_t;
+
+METHOD(enumerator_t, task_enumerator_destroy, void,
+ task_enumerator_t *this)
+{
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+METHOD(enumerator_t, task_enumerator_enumerate, bool,
+ task_enumerator_t *this, va_list args)
+{
task_t **task;
VA_ARGS_VGET(args, task);
-
- if (orig->enumerate(orig, &queued))
+ if (this->queue == TASK_QUEUE_QUEUED)
+ {
+ if (this->inner->enumerate(this->inner, &this->queued))
+ {
+ *task = this->queued->task;
+ return TRUE;
+ }
+ }
+ else if (this->inner->enumerate(this->inner, task))
{
- *task = queued->task;
return TRUE;
}
return FALSE;
@@ -2143,18 +2172,54 @@ CALLBACK(filter_queued, bool,
METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
private_task_manager_t *this, task_queue_t queue)
{
+ task_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = enumerator_enumerate_default,
+ .venumerate = _task_enumerator_enumerate,
+ .destroy = _task_enumerator_destroy,
+ },
+ .queue = queue,
+ );
switch (queue)
{
case TASK_QUEUE_ACTIVE:
- return array_create_enumerator(this->active_tasks);
+ enumerator->inner = array_create_enumerator(this->active_tasks);
+ break;
case TASK_QUEUE_PASSIVE:
- return array_create_enumerator(this->passive_tasks);
+ enumerator->inner = array_create_enumerator(this->passive_tasks);
+ break;
case TASK_QUEUE_QUEUED:
- return enumerator_create_filter(
- array_create_enumerator(this->queued_tasks),
- filter_queued, NULL, NULL);
+ enumerator->inner = array_create_enumerator(this->queued_tasks);
+ break;
default:
- return enumerator_create_empty();
+ enumerator->inner = enumerator_create_empty();
+ break;
+ }
+ return &enumerator->public;
+}
+
+METHOD(task_manager_t, remove_task, void,
+ private_task_manager_t *this, enumerator_t *enumerator_public)
+{
+ task_enumerator_t *enumerator = (task_enumerator_t*)enumerator_public;
+
+ switch (enumerator->queue)
+ {
+ case TASK_QUEUE_ACTIVE:
+ array_remove_at(this->active_tasks, enumerator->inner);
+ break;
+ case TASK_QUEUE_PASSIVE:
+ array_remove_at(this->passive_tasks, enumerator->inner);
+ break;
+ case TASK_QUEUE_QUEUED:
+ array_remove_at(this->queued_tasks, enumerator->inner);
+ free(enumerator->queued);
+ enumerator->queued = NULL;
+ break;
+ default:
+ break;
}
}
@@ -2204,9 +2269,9 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
.get_mid = _get_mid,
.reset = _reset,
.adopt_tasks = _adopt_tasks,
- .adopt_child_tasks = _adopt_child_tasks,
.busy = _busy,
.create_task_enumerator = _create_task_enumerator,
+ .remove_task = _remove_task,
.flush = _flush,
.flush_queue = _flush_queue,
.destroy = _destroy,
diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c
index 6c8b29018..0e3711898 100644
--- a/src/libcharon/sa/ikev2/tasks/child_delete.c
+++ b/src/libcharon/sa/ikev2/tasks/child_delete.c
@@ -174,6 +174,11 @@ static void install_outbound(private_child_delete_t *this,
linked_list_t *my_ts, *other_ts;
status_t status;
+ if (!spi)
+ {
+ return;
+ }
+
child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol,
spi, FALSE);
if (!child_sa)
@@ -312,7 +317,7 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
child_sa_t *child_sa;
child_cfg_t *child_cfg;
protocol_id_t protocol;
- uint32_t spi, reqid, rekey_spi;
+ uint32_t spi, reqid;
action_t action;
status_t status = SUCCESS;
time_t now, expire;
@@ -335,11 +340,7 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
}
else
{
- rekey_spi = child_sa->get_rekey_spi(child_sa);
- if (rekey_spi)
- {
- install_outbound(this, protocol, rekey_spi);
- }
+ install_outbound(this, protocol, child_sa->get_rekey_spi(child_sa));
/* for rekeyed CHILD_SAs we uninstall the outbound SA but don't
* immediately destroy it, by default, so we can process delayed
* packets */
@@ -459,6 +460,17 @@ METHOD(task_t, build_i, status_t,
this->spi = child_sa->get_spi(child_sa, TRUE);
}
+ if (this->expired && child_sa->get_state(child_sa) == CHILD_REKEYED)
+ { /* the peer was expected to delete this SA, but if we send a DELETE
+ * we might cause a collision there if the CREATE_CHILD_SA response
+ * is delayed (the peer wouldn't know if we deleted this SA due to an
+ * expire or because of a forced delete by the user and might then
+ * ignore the CREATE_CHILD_SA response once it arrives) */
+ child_sa->set_state(child_sa, CHILD_DELETED);
+ install_outbound(this, this->protocol,
+ child_sa->get_rekey_spi(child_sa));
+ }
+
if (child_sa->get_state(child_sa) == CHILD_DELETED)
{ /* DELETEs for this CHILD_SA were already exchanged, but it was not yet
* destroyed to allow delayed packets to get processed */
diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c
index 307d99264..b570904e2 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_init.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_init.c
@@ -773,7 +773,7 @@ static bool derive_keys(private_ike_init_t *this,
return FALSE;
}
charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, chunk_empty,
- nonce_i, nonce_r, this->old_sa, NULL);
+ nonce_i, nonce_r, this->old_sa, NULL, AUTH_NONE);
return TRUE;
}
@@ -890,6 +890,20 @@ METHOD(task_t, pre_process_i, status_t,
switch (type)
{
+ case COOKIE:
+ {
+ chunk_t cookie;
+
+ cookie = notify->get_notification_data(notify);
+ if (chunk_equals(cookie, this->cookie))
+ {
+ DBG1(DBG_IKE, "ignore response with duplicate COOKIE "
+ "notify");
+ enumerator->destroy(enumerator);
+ return FAILED;
+ }
+ break;
+ }
case REDIRECT:
{
identification_t *gateway;
diff --git a/src/libcharon/sa/task_manager.h b/src/libcharon/sa/task_manager.h
index 9545da4f3..c357d5035 100644
--- a/src/libcharon/sa/task_manager.h
+++ b/src/libcharon/sa/task_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2016 Tobias Brunner
+ * Copyright (C) 2013-2018 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
*
@@ -228,13 +228,6 @@ struct task_manager_t {
void (*adopt_tasks) (task_manager_t *this, task_manager_t *other);
/**
- * Migrate all active or queued CHILD_SA-creating tasks from other to this.
- *
- * @param other manager which gives away its tasks
- */
- void (*adopt_child_tasks) (task_manager_t *this, task_manager_t *other);
-
- /**
* Increment a message ID counter, in- or outbound.
*
* If a message is processed outside of the manager, this call increments
@@ -285,6 +278,16 @@ struct task_manager_t {
task_queue_t queue);
/**
+ * Remove the task the given enumerator points to.
+ *
+ * @note This should be used with caution, in partciular, for tasks in the
+ * active and passive queues.
+ *
+ * @param enumerator enumerator created with the method above
+ */
+ void (*remove_task)(task_manager_t *this, enumerator_t *enumerator);
+
+ /**
* Flush all tasks, regardless of the queue.
*/
void (*flush)(task_manager_t *this);
diff --git a/src/libcharon/tests/suites/test_child_rekey.c b/src/libcharon/tests/suites/test_child_rekey.c
index 51d577cd8..b9f6ea0bc 100644
--- a/src/libcharon/tests/suites/test_child_rekey.c
+++ b/src/libcharon/tests/suites/test_child_rekey.c
@@ -370,8 +370,8 @@ END_TEST
/**
* Check that the responder handles hard expires properly while waiting for the
- * delete after a rekeying (e.g. if the initiator of the rekeying fails to
- * delete the CHILD_SA for some reason).
+ * delete after a rekeying (e.g. if the rekey settings are tight or the
+ * CREATE_CHILD_SA response is delayed).
*/
START_TEST(test_regular_responder_handle_hard_expire)
{
@@ -405,28 +405,22 @@ START_TEST(test_regular_responder_handle_hard_expire)
/* we don't expect this to get called anymore */
assert_hook_not_called(child_rekey);
- /* this is similar to a regular delete collision */
- assert_single_payload(OUT, PLV2_DELETE);
+ /* this is similar to a regular delete collision, but we don't actually
+ * want to send a delete back as that might conflict with a delayed
+ * CREATE_CHILD_SA response */
call_ikesa(b, delete_child_sa, PROTO_ESP, 2, TRUE);
- assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
- assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
- /* since the SAs expired they would not actually be installed in the kernel
- * anymore and since we have not yet installed a new outbound SA this
- * will result in dropped packets and possibly acquires */
- assert_ipsec_sas_installed(b, 1, 2, 4);
+ assert_child_sa_count(b, 1);
+ assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
+ /* the expire causes the outbound SA to get installed */
+ assert_ipsec_sas_installed(b, 3, 4);
/* INFORMATIONAL { D } --> */
+ assert_no_jobs_scheduled();
assert_single_payload(IN, PLV2_DELETE);
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
- assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
- assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
- assert_ipsec_sas_installed(b, 1, 2, 4);
- /* <-- INFORMATIONAL { D } */
- assert_single_payload(IN, PLV2_DELETE);
- exchange_test_helper->process_message(exchange_test_helper, a, NULL);
- assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
- assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
- assert_ipsec_sas_installed(a, 1, 2, 3, 4);
+ assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
+ assert_ipsec_sas_installed(b, 3, 4);
+ assert_scheduler();
/* <-- INFORMATIONAL { } */
assert_jobs_scheduled(1);
assert_message_empty(IN);
@@ -436,23 +430,11 @@ START_TEST(test_regular_responder_handle_hard_expire)
assert_child_sa_count(a, 2);
assert_ipsec_sas_installed(a, 1, 3, 4);
assert_scheduler();
- /* INFORMATIONAL { } --> */
- assert_jobs_scheduled(1);
- assert_message_empty(IN);
- exchange_test_helper->process_message(exchange_test_helper, b, NULL);
- assert_child_sa_state(b, 2, CHILD_DELETED, CHILD_OUTBOUND_NONE);
- assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
- assert_child_sa_count(b, 2);
- assert_ipsec_sas_installed(b, 2, 3, 4);
- assert_scheduler();
- /* simulate the execution of the scheduled jobs */
+ /* simulate the execution of the scheduled job */
destroy_rekeyed(a, 1);
assert_child_sa_count(a, 1);
assert_ipsec_sas_installed(a, 3, 4);
- destroy_rekeyed(b, 2);
- assert_child_sa_count(b, 1);
- assert_ipsec_sas_installed(b, 3, 4);
/* child_rekey/child_updown */
assert_hook();
diff --git a/src/libimcv/imv/data.sql b/src/libimcv/imv/data.sql
index 5d5283620..3f8b4c957 100644
--- a/src/libimcv/imv/data.sql
+++ b/src/libimcv/imv/data.sql
@@ -574,6 +574,24 @@ INSERT INTO products ( /* 96 */
'Ubuntu 18.04 x86_64'
);
+INSERT INTO products ( /* 97 */
+ name
+) VALUES (
+ 'Debian 9.5 i686'
+);
+
+INSERT INTO products ( /* 98 */
+ name
+) VALUES (
+ 'Debian 9.5 x86_64'
+);
+
+INSERT INTO products ( /* 99 */
+ name
+) VALUES (
+ 'Debian 9.6 x86_64'
+);
+
/* Directories */
INSERT INTO directories ( /* 1 */
@@ -671,7 +689,7 @@ INSERT INTO files ( /* 1 */
INSERT INTO files ( /* 2 */
name, dir
) VALUES (
- 'libcrypto.so.1.0.0', 11
+ 'libcrypto.so.1.1', 11
);
INSERT INTO files ( /* 3 */
@@ -683,7 +701,7 @@ INSERT INTO files ( /* 3 */
INSERT INTO files ( /* 4 */
name, dir
) VALUES (
- 'libssl.so.1.0.0', 11
+ 'libssl.so.1.1', 11
);
INSERT INTO files ( /* 5 */
@@ -1147,6 +1165,12 @@ INSERT INTO groups_product_defaults (
INSERT INTO groups_product_defaults (
group_id, product_id
) VALUES (
+ 4, 97
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
5, 2
);
@@ -1267,6 +1291,18 @@ INSERT INTO groups_product_defaults (
INSERT INTO groups_product_defaults (
group_id, product_id
) VALUES (
+ 5, 98
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
+ 5, 99
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
6, 9
);
@@ -1665,13 +1701,13 @@ INSERT INTO policies ( /* 11 */
INSERT INTO policies ( /* 12 */
type, name, file, rec_fail, rec_noresult
) VALUES (
- 6, 'Measure /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0', 2, 2, 2
+ 6, 'Measure /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1', 2, 2, 2
);
INSERT INTO policies ( /* 13 */
type, name, file, rec_fail, rec_noresult
) VALUES (
- 6, 'Measure /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0', 4, 2, 2
+ 6, 'Measure /usr/lib/x86_64-linux-gnu/libssl.so.1.1', 4, 2, 2
);
INSERT INTO policies ( /* 14 */
diff --git a/src/libimcv/plugins/imc_swima/strongswan.org__strongSwan-5-7-1.swidtag b/src/libimcv/plugins/imc_swima/strongswan.org__strongSwan-5-7-2.swidtag
index 6ca455dac..77f00e036 100644
--- a/src/libimcv/plugins/imc_swima/strongswan.org__strongSwan-5-7-1.swidtag
+++ b/src/libimcv/plugins/imc_swima/strongswan.org__strongSwan-5-7-2.swidtag
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<SoftwareIdentity
name="strongSwan"
- tagId="strongSwan-5-7-1"
- version="5.7.1" versionScheme="alphanumeric"
+ tagId="strongSwan-5-7-2"
+ version="5.7.2" versionScheme="alphanumeric"
xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd">
<Entity
name="strongSwan Project"
diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_agent.c b/src/libimcv/plugins/imv_attestation/imv_attestation_agent.c
index 89ba86930..51bcdc410 100644
--- a/src/libimcv/plugins/imv_attestation/imv_attestation_agent.c
+++ b/src/libimcv/plugins/imv_attestation/imv_attestation_agent.c
@@ -249,8 +249,6 @@ static TNC_Result receive_msg(private_imv_attestation_agent_t *this,
os_name.len, os_name.ptr);
}
break;
-
- break;
}
case IETF_ATTR_STRING_VERSION:
{
diff --git a/src/libpttls/pt_tls_client.c b/src/libpttls/pt_tls_client.c
index 265a4a09a..f86f13dcc 100644
--- a/src/libpttls/pt_tls_client.c
+++ b/src/libpttls/pt_tls_client.c
@@ -231,7 +231,6 @@ static status_t do_sasl(private_pt_tls_client_t *this, sasl_mechanism_t *sasl)
reader->destroy(reader);
return FAILED;
}
- break;
case PT_TLS_SASL_RESULT_MECH_FAILURE:
case PT_TLS_SASL_RESULT_FAILURE:
/* non-fatal failure, try again */
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index 278c67405..b04627e63 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -551,6 +551,7 @@ static signature_params_t *create_rsa_pss_constraint(char *token)
.scheme = SIGN_RSA_EMSA_PSS,
.params = &pss,
};
+ rsa_pss_params_set_salt_len(&pss, 0);
params = signature_params_clone(&pss_params);
}
return params;
diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c
index 0239ee17e..61dfbbcad 100644
--- a/src/libstrongswan/credentials/builder.c
+++ b/src/libstrongswan/credentials/builder.c
@@ -73,6 +73,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
"BUILD_SAFE_PRIMES",
"BUILD_SHARES",
"BUILD_THRESHOLD",
+ "BUILD_EDDSA_PUB",
"BUILD_EDDSA_PRIV_ASN1_DER",
"BUILD_END",
);
diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h
index 7928ef487..b283bd166 100644
--- a/src/libstrongswan/credentials/builder.h
+++ b/src/libstrongswan/credentials/builder.h
@@ -156,6 +156,8 @@ enum builder_part_t {
BUILD_SHARES,
/** minimum number of participating private key shares */
BUILD_THRESHOLD,
+ /** EdDSA public key blob */
+ BUILD_EDDSA_PUB,
/** DER encoded ASN.1 EdDSA private key */
BUILD_EDDSA_PRIV_ASN1_DER,
/** end of variable argument builder list */
diff --git a/src/libstrongswan/credentials/keys/private_key.h b/src/libstrongswan/credentials/keys/private_key.h
index d7cfdd74d..5cf8641ad 100644
--- a/src/libstrongswan/credentials/keys/private_key.h
+++ b/src/libstrongswan/credentials/keys/private_key.h
@@ -40,6 +40,19 @@ struct private_key_t {
key_type_t (*get_type)(private_key_t *this);
/**
+ * Get signature schemes supported by this key.
+ *
+ * This is useful for keys that only support certain hash algorithms or
+ * require specific parameters for RSA/PSS signatures.
+ *
+ * @note Implementing this method is optional. If multiple schemes are
+ * returned, they should be ordered by decreasing preference.
+ *
+ * @return enumerator over signature_params_t*
+ */
+ enumerator_t *(*supported_signature_schemes)(private_key_t *this);
+
+ /**
* Create a signature over a chunk of data.
*
* @param scheme signature scheme to use
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
index 89fa9b348..3ef6981f6 100644
--- a/src/libstrongswan/credentials/keys/public_key.c
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -250,7 +250,7 @@ int signature_scheme_to_oid(signature_scheme_t scheme)
#define PSS_PARAMS(bits) static rsa_pss_params_t pss_params_sha##bits = { \
.hash = HASH_SHA##bits, \
.mgf1_hash = HASH_SHA##bits, \
- .salt_len = RSA_PSS_SALT_LEN_DEFAULT, \
+ .salt_len = HASH_SIZE_SHA##bits, \
}
PSS_PARAMS(256);
diff --git a/src/libstrongswan/credentials/keys/signature_params.c b/src/libstrongswan/credentials/keys/signature_params.c
index 8f42fb940..d89bd2c96 100644
--- a/src/libstrongswan/credentials/keys/signature_params.c
+++ b/src/libstrongswan/credentials/keys/signature_params.c
@@ -18,22 +18,43 @@
#include <asn1/oid.h>
#include <asn1/asn1_parser.h>
-/**
- * Determine the salt length in case it is not configured
+/*
+ * Described in header
*/
-static ssize_t rsa_pss_salt_length(rsa_pss_params_t *pss)
+bool rsa_pss_params_set_salt_len(rsa_pss_params_t *params, size_t modbits)
{
- ssize_t salt_len = pss->salt_len;
+ size_t hash_len;
- if (salt_len <= RSA_PSS_SALT_LEN_DEFAULT)
+ if (params->salt_len < 0)
{
- salt_len = hasher_hash_size(pss->hash);
- if (!salt_len)
+ hash_len = hasher_hash_size(params->hash);
+ if (!hash_len)
+ {
+ return FALSE;
+ }
+
+ switch (params->salt_len)
{
- return -1;
+ case RSA_PSS_SALT_LEN_DEFAULT:
+ params->salt_len = hash_len;
+ break;
+ case RSA_PSS_SALT_LEN_MAX:
+ if (modbits)
+ {
+ /* emBits = modBits - 1 */
+ modbits -= 1;
+ /* emLen = ceil(emBits/8) */
+ modbits = (modbits+7) / BITS_PER_BYTE;
+ /* account for 0x01 separator in DB, 0xbc trailing byte */
+ params->salt_len = max(0, (ssize_t)(modbits - hash_len - 2));
+ break;
+ }
+ return FALSE;
+ default:
+ return FALSE;
}
}
- return salt_len;
+ return TRUE;
}
/**
@@ -68,8 +89,7 @@ static bool compare_params(signature_params_t *a, signature_params_t *b,
return pss_a->hash == pss_b->hash &&
pss_a->mgf1_hash == pss_b->mgf1_hash &&
- (!strict ||
- rsa_pss_salt_length(pss_a) == rsa_pss_salt_length(pss_b));
+ (!strict || pss_a->salt_len == pss_b->salt_len);
}
default:
break;
@@ -328,7 +348,6 @@ end:
bool rsa_pss_params_build(rsa_pss_params_t *params, chunk_t *asn1)
{
chunk_t hash = chunk_empty, mgf = chunk_empty, slen = chunk_empty;
- ssize_t salt_len;
int alg;
if (params->hash != HASH_SHA1)
@@ -351,16 +370,15 @@ bool rsa_pss_params_build(rsa_pss_params_t *params, chunk_t *asn1)
mgf = asn1_algorithmIdentifier_params(OID_MGF1,
asn1_algorithmIdentifier(alg));
}
- salt_len = rsa_pss_salt_length(params);
- if (salt_len < 0)
+ if (params->salt_len < 0)
{
chunk_free(&hash);
chunk_free(&mgf);
return FALSE;
}
- else if (salt_len != HASH_SIZE_SHA1)
+ else if (params->salt_len != HASH_SIZE_SHA1)
{
- slen = asn1_integer("m", asn1_integer_from_uint64(salt_len));
+ slen = asn1_integer("m", asn1_integer_from_uint64(params->salt_len));
}
*asn1 = asn1_wrap(ASN1_SEQUENCE, "mmm",
hash.len ? asn1_wrap(ASN1_CONTEXT_C_0, "m", hash) : chunk_empty,
diff --git a/src/libstrongswan/credentials/keys/signature_params.h b/src/libstrongswan/credentials/keys/signature_params.h
index 6934c5e88..b4169a829 100644
--- a/src/libstrongswan/credentials/keys/signature_params.h
+++ b/src/libstrongswan/credentials/keys/signature_params.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Tobias Brunner
+ * Copyright (C) 2017-2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -100,11 +100,15 @@ struct rsa_pss_params_t {
hash_algorithm_t hash;
/** Hash for the MGF1 function */
hash_algorithm_t mgf1_hash;
- /** Salt length, use RSA_PSS_SALT_LEN_DEFAULT for length equal to hash */
+ /** Salt length, use the constants below for special lengths resolved
+ * via rsa_pss_params_set_salt_len() */
ssize_t salt_len;
/** Salt value, for unit tests (not all implementations support this) */
chunk_t salt;
+/** Use a salt length equal to the length of the hash */
#define RSA_PSS_SALT_LEN_DEFAULT -1
+/** Use the maximum salt length depending on the hash and key length */
+#define RSA_PSS_SALT_LEN_MAX -2
};
/**
@@ -126,4 +130,15 @@ bool rsa_pss_params_parse(chunk_t asn1, int level0, rsa_pss_params_t *params);
*/
bool rsa_pss_params_build(rsa_pss_params_t *params, chunk_t *asn1);
+/**
+ * Determine and set the salt length for the given params in case constants
+ * are used
+ *
+ * @param params parameters to update
+ * @param modbits RSA modulus length in bits (required if RSA_PSS_SALT_LEN_MAX
+ * is used)
+ * @return salt length to use, negative on error
+ */
+bool rsa_pss_params_set_salt_len(rsa_pss_params_t *params, size_t modbits);
+
#endif /** SIGNATURE_PARAMS_H_ @}*/
diff --git a/src/libstrongswan/crypto/mac.h b/src/libstrongswan/crypto/mac.h
index 50dc4c73a..97cb7e352 100644
--- a/src/libstrongswan/crypto/mac.h
+++ b/src/libstrongswan/crypto/mac.h
@@ -39,12 +39,12 @@ struct mac_t {
*
* If out is NULL, no result is given back. A next call will
* append the data to already supplied data. If out is not NULL,
- * the mac of all apended data is calculated, written to out and the
+ * the MAC of all appended data is calculated, written to out and the
* internal state is reset.
*
* @param data chunk of data to authenticate
* @param out pointer where the generated bytes will be written
- * @return TRUE if mac generated successfully
+ * @return TRUE if MAC generated successfully
*/
bool (*get_mac)(mac_t *this, chunk_t data,
uint8_t *out) __attribute__((warn_unused_result));
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords_static.c b/src/libstrongswan/crypto/proposal/proposal_keywords_static.c
index cad94aa82..a078d3b30 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords_static.c
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.c
@@ -1,4 +1,4 @@
-/* C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.1 */
/* Command-line: /usr/bin/gperf -N proposal_get_token_static -m 10 -C -G -c -t -D */
/* Computed positions: -k'1,5-7,10,15,$' */
@@ -26,7 +26,7 @@
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
-error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
#endif
@@ -74,9 +74,7 @@ inline
#endif
#endif
static unsigned int
-hash (str, len)
- register const char *str;
- register unsigned int len;
+hash (register const char *str, register size_t len)
{
static const unsigned char asso_values[] =
{
@@ -107,7 +105,7 @@ hash (str, len)
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251
};
- register int hval = len;
+ register unsigned int hval = len;
switch (hval)
{
@@ -320,22 +318,14 @@ static const short lookup[] =
143
};
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
const struct proposal_token *
-proposal_get_token_static (str, len)
- register const char *str;
- register unsigned int len;
+proposal_get_token_static (register const char *str, register size_t len)
{
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- register int key = hash (str, len);
+ register unsigned int key = hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
register int index = lookup[key];
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords_static.h b/src/libstrongswan/crypto/proposal/proposal_keywords_static.h
index 1345f36bb..a0beec0bb 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords_static.h
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.h
@@ -19,7 +19,7 @@
#include "proposal_keywords.h"
const proposal_token_t* proposal_get_token_static(register const char *str,
- register unsigned len);
+ register size_t len);
#endif /* PROPOSAL_KEYWORDS_STATIC_H_ */
diff --git a/src/libstrongswan/plugins/agent/agent_private_key.c b/src/libstrongswan/plugins/agent/agent_private_key.c
index 77c29916c..db87affc9 100644
--- a/src/libstrongswan/plugins/agent/agent_private_key.c
+++ b/src/libstrongswan/plugins/agent/agent_private_key.c
@@ -82,6 +82,14 @@ enum agent_msg_type_t {
};
/**
+ * Flags for signatures
+ */
+enum agent_signature_flags_t {
+ SSH_AGENT_FLAG_SHA2_256 = 2,
+ SSH_AGENT_FLAG_SHA2_512 = 4,
+};
+
+/**
* read a byte from a blob
*/
static u_char read_byte(chunk_t *blob)
@@ -217,12 +225,35 @@ static bool read_key(private_agent_private_key_t *this, public_key_t *pubkey)
}
static bool scheme_supported(private_agent_private_key_t *this,
- signature_scheme_t scheme)
+ signature_scheme_t scheme, uint32_t *flags,
+ char **prefix)
{
switch (this->pubkey->get_type(this->pubkey))
{
case KEY_RSA:
- return scheme == SIGN_RSA_EMSA_PKCS1_SHA1;
+ switch (scheme)
+ {
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ *prefix = "ssh-rsa";
+ return TRUE;
+ case SIGN_RSA_EMSA_PKCS1_SHA2_256:
+ *flags |= SSH_AGENT_FLAG_SHA2_256;
+ *prefix = "rsa-sha2-256";
+ return TRUE;
+ case SIGN_RSA_EMSA_PKCS1_SHA2_512:
+ *flags |= SSH_AGENT_FLAG_SHA2_512;
+ *prefix = "rsa-sha2-512";
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+ case KEY_ED25519:
+ *prefix = "ssh-ed25519";
+ return scheme == SIGN_ED25519;
+ case KEY_ED448:
+ *prefix = "ssh-ed448";
+ return scheme == SIGN_ED448;
case KEY_ECDSA:
return scheme == SIGN_ECDSA_256 ||
scheme == SIGN_ECDSA_384 ||
@@ -236,11 +267,12 @@ METHOD(private_key_t, sign, bool,
private_agent_private_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t *signature)
{
- uint32_t len, flags;
- char buf[2048];
+ key_type_t type;
+ uint32_t len, flags = 0;
+ char buf[2048], *prefix = NULL;
chunk_t blob;
- if (!scheme_supported(this, scheme))
+ if (!scheme_supported(this, scheme, &flags, &prefix))
{
DBG1(DBG_LIB, "signature scheme %N not supported by ssh-agent",
signature_scheme_names, scheme);
@@ -272,7 +304,7 @@ METHOD(private_key_t, sign, bool,
return FALSE;
}
- flags = htonl(0);
+ flags = htonl(flags);
if (write(this->socket, &flags, sizeof(flags)) != sizeof(flags))
{
DBG1(DBG_LIB, "writing to ssh-agent failed");
@@ -290,9 +322,15 @@ METHOD(private_key_t, sign, bool,
}
/* parse length */
blob = read_string(&blob);
- /* check sig type */
- if (chunk_equals(read_string(&blob), chunk_from_str("ssh-rsa")))
- { /* for RSA the signature has no special encoding */
+ /* verify type */
+ if (prefix && !chunk_equals(read_string(&blob), chunk_from_str(prefix)))
+ {
+ DBG1(DBG_LIB, "ssh-agent didn't return requested %s signature", prefix);
+ return FALSE;
+ }
+ type = this->pubkey->get_type(this->pubkey);
+ if (type == KEY_RSA || type == KEY_ED25519 || type == KEY_ED448)
+ { /* for RSA/EdDSA, the signature has no special encoding */
blob = read_string(&blob);
if (blob.len)
{
@@ -301,7 +339,7 @@ METHOD(private_key_t, sign, bool,
}
}
else
- { /* anything else is treated as ECSDA for now */
+ { /* parse ECDSA signatures */
blob = read_string(&blob);
if (blob.len)
{
@@ -340,6 +378,80 @@ METHOD(private_key_t, get_keysize, int,
return this->pubkey->get_keysize(this->pubkey);
}
+/**
+ * Private data for RSA scheme enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ int index;
+ bool reverse;
+} scheme_enumerator_t;
+
+static signature_params_t rsa_schemes[] = {
+ { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_256 },
+ { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_512 },
+};
+
+METHOD(enumerator_t, enumerate_rsa_scheme, bool,
+ scheme_enumerator_t *this, va_list args)
+{
+ signature_params_t **params;
+
+ VA_ARGS_VGET(args, params);
+
+ if ((this->reverse && --this->index >= 0) ||
+ (!this->reverse && ++this->index < countof(rsa_schemes)))
+ {
+ *params = &rsa_schemes[this->index];
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Create an enumerator for the supported RSA signature schemes
+ */
+static enumerator_t *create_rsa_enumerator(private_agent_private_key_t *this)
+{
+ scheme_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = enumerator_enumerate_default,
+ .venumerate = _enumerate_rsa_scheme,
+ .destroy = (void*)free,
+ },
+ .index = -1,
+ .reverse = FALSE,
+ );
+ /* propose SHA-512 first for larger keys */
+ if (get_keysize(this) > 3072)
+ {
+ enumerator->index = countof(rsa_schemes);
+ enumerator->reverse = TRUE;
+ }
+ return &enumerator->public;
+}
+
+METHOD(private_key_t, supported_signature_schemes, enumerator_t*,
+ private_agent_private_key_t *this)
+{
+ key_type_t type = get_type(this);
+
+ switch (type)
+ {
+ case KEY_RSA:
+ return create_rsa_enumerator(this);
+ case KEY_ED25519:
+ case KEY_ED448:
+ case KEY_ECDSA:
+ return signature_schemes_for_key(type, get_keysize(this));
+ default:
+ break;
+ }
+ return enumerator_create_empty();
+}
+
METHOD(private_key_t, get_public_key, public_key_t*,
private_agent_private_key_t *this)
{
@@ -413,6 +525,7 @@ agent_private_key_t *agent_private_key_open(key_type_t type, va_list args)
.public = {
.key = {
.get_type = _get_type,
+ .supported_signature_schemes = _supported_signature_schemes,
.sign = _sign,
.decrypt = _decrypt,
.get_keysize = _get_keysize,
diff --git a/src/libstrongswan/plugins/botan/Makefile.am b/src/libstrongswan/plugins/botan/Makefile.am
index c1160145a..30d3e601c 100644
--- a/src/libstrongswan/plugins/botan/Makefile.am
+++ b/src/libstrongswan/plugins/botan/Makefile.am
@@ -23,9 +23,11 @@ libstrongswan_botan_la_SOURCES = \
botan_ec_diffie_hellman.h botan_ec_diffie_hellman.c \
botan_ec_public_key.h botan_ec_public_key.c \
botan_ec_private_key.h botan_ec_private_key.c \
+ botan_ed_public_key.h botan_ed_public_key.c \
+ botan_ed_private_key.h botan_ed_private_key.c \
botan_util.h botan_util.c \
botan_util_keys.h botan_util_keys.c \
- botan_gcm.h botan_gcm.c \
+ botan_aead.h botan_aead.c \
botan_x25519.h botan_x25519.c
libstrongswan_botan_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/botan/Makefile.in b/src/libstrongswan/plugins/botan/Makefile.in
index ef9f88610..3bb3e22f4 100644
--- a/src/libstrongswan/plugins/botan/Makefile.in
+++ b/src/libstrongswan/plugins/botan/Makefile.in
@@ -142,8 +142,9 @@ am_libstrongswan_botan_la_OBJECTS = botan_plugin.lo botan_rng.lo \
botan_hasher.lo botan_hmac.lo botan_crypter.lo \
botan_rsa_public_key.lo botan_rsa_private_key.lo \
botan_diffie_hellman.lo botan_ec_diffie_hellman.lo \
- botan_ec_public_key.lo botan_ec_private_key.lo botan_util.lo \
- botan_util_keys.lo botan_gcm.lo botan_x25519.lo
+ botan_ec_public_key.lo botan_ec_private_key.lo \
+ botan_ed_public_key.lo botan_ed_private_key.lo botan_util.lo \
+ botan_util_keys.lo botan_aead.lo botan_x25519.lo
libstrongswan_botan_la_OBJECTS = $(am_libstrongswan_botan_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -478,9 +479,11 @@ libstrongswan_botan_la_SOURCES = \
botan_ec_diffie_hellman.h botan_ec_diffie_hellman.c \
botan_ec_public_key.h botan_ec_public_key.c \
botan_ec_private_key.h botan_ec_private_key.c \
+ botan_ed_public_key.h botan_ed_public_key.c \
+ botan_ed_private_key.h botan_ed_private_key.c \
botan_util.h botan_util.c \
botan_util_keys.h botan_util_keys.c \
- botan_gcm.h botan_gcm.c \
+ botan_aead.h botan_aead.c \
botan_x25519.h botan_x25519.c
libstrongswan_botan_la_LDFLAGS = -module -avoid-version
@@ -574,12 +577,14 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_aead.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_crypter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_diffie_hellman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ec_diffie_hellman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ec_private_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ec_public_key.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_gcm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ed_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_ed_public_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_hasher.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_hmac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/botan_plugin.Plo@am__quote@
diff --git a/src/libstrongswan/plugins/botan/botan_gcm.c b/src/libstrongswan/plugins/botan/botan_aead.c
index 7e0fc1468..40006ae77 100644
--- a/src/libstrongswan/plugins/botan/botan_gcm.c
+++ b/src/libstrongswan/plugins/botan/botan_aead.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2018 Atanas Filyanov
* Rohde & Schwarz Cybersecurity GmbH
*
@@ -21,23 +24,28 @@
* THE SOFTWARE.
*/
-#include "botan_gcm.h"
+#include "botan_aead.h"
#include <botan/build.h>
-#ifdef BOTAN_HAS_AES
-#ifdef BOTAN_HAS_AEAD_GCM
+#if (defined(BOTAN_HAS_AES) && \
+ (defined(BOTAN_HAS_AEAD_GCM) || defined(BOTAN_HAS_AEAD_CCM))) || \
+ defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
#include <crypto/iv/iv_gen_seq.h>
#include <botan/ffi.h>
/**
- * as defined in RFC 4106
+ * As defined in RFC 4106 (GCM) and RFC 7634 (ChaPoly)
*/
-#define IV_LEN 8
-#define SALT_LEN 4
-#define NONCE_LEN (IV_LEN + SALT_LEN)
+#define IV_LEN 8
+#define SALT_LEN 4
+#define CHAPOLY_KEY_LEN 32
+/**
+ * As defined in RFC 4309
+ */
+#define CCM_SALT_LEN 3
typedef struct private_aead_t private_aead_t;
@@ -56,7 +64,7 @@ struct private_aead_t {
/**
* Salt value
*/
- char salt[SALT_LEN];
+ chunk_t salt;
/**
* Size of the integrity check value
@@ -77,15 +85,12 @@ struct private_aead_t {
/**
* Do the actual en/decryption
*/
-static bool crypt(private_aead_t *this, chunk_t data, chunk_t assoc, chunk_t iv,
- u_char *out, uint32_t init_flag)
+static bool do_crypt(private_aead_t *this, chunk_t data, chunk_t assoc,
+ chunk_t iv, u_char *out, uint32_t init_flag)
{
botan_cipher_t cipher;
- uint8_t nonce[NONCE_LEN];
size_t output_written = 0, input_consumed = 0;
-
- memcpy(nonce, this->salt, SALT_LEN);
- memcpy(nonce + SALT_LEN, iv.ptr, IV_LEN);
+ chunk_t nonce;
if (botan_cipher_init(&cipher, this->cipher_name, init_flag))
{
@@ -105,7 +110,9 @@ static bool crypt(private_aead_t *this, chunk_t data, chunk_t assoc, chunk_t iv,
return FALSE;
}
- if (botan_cipher_start(cipher, nonce, NONCE_LEN))
+ nonce = chunk_cata("cc", this->salt, iv);
+
+ if (botan_cipher_start(cipher, nonce.ptr, nonce.len))
{
botan_cipher_destroy(cipher);
return FALSE;
@@ -149,7 +156,8 @@ METHOD(aead_t, encrypt, bool,
*encrypted = chunk_alloc(plain.len + this->icv_size);
out = encrypted->ptr;
}
- return crypt(this, plain, assoc, iv, out, BOTAN_CIPHER_INIT_FLAG_ENCRYPT);
+ return do_crypt(this, plain, assoc, iv, out,
+ BOTAN_CIPHER_INIT_FLAG_ENCRYPT);
}
METHOD(aead_t, decrypt, bool,
@@ -170,8 +178,8 @@ METHOD(aead_t, decrypt, bool,
*plain = chunk_alloc(encrypted.len);
out = plain->ptr;
}
- return crypt(this, encrypted, assoc, iv, out,
- BOTAN_CIPHER_INIT_FLAG_DECRYPT);
+ return do_crypt(this, encrypted, assoc, iv, out,
+ BOTAN_CIPHER_INIT_FLAG_DECRYPT);
}
METHOD(aead_t, get_block_size, size_t,
@@ -201,7 +209,7 @@ METHOD(aead_t, get_iv_gen, iv_gen_t*,
METHOD(aead_t, get_key_size, size_t,
private_aead_t *this)
{
- return this->key.len + SALT_LEN;
+ return this->key.len + this->salt.len;
}
METHOD(aead_t, set_key, bool,
@@ -211,7 +219,7 @@ METHOD(aead_t, set_key, bool,
{
return FALSE;
}
- memcpy(this->salt, key.ptr + key.len - SALT_LEN, SALT_LEN);
+ memcpy(this->salt.ptr, key.ptr + key.len - this->salt.len, this->salt.len);
memcpy(this->key.ptr, key.ptr, this->key.len);
return TRUE;
}
@@ -220,15 +228,82 @@ METHOD(aead_t, destroy, void,
private_aead_t *this)
{
chunk_clear(&this->key);
+ chunk_clear(&this->salt);
this->iv_gen->destroy(this->iv_gen);
free(this);
}
+#ifdef BOTAN_HAS_AES
+#if defined(BOTAN_HAS_AEAD_GCM) || defined(BOTAN_HAS_AEAD_GCM)
+
+static struct {
+ encryption_algorithm_t algo;
+ size_t key_size;
+ char *name;
+ size_t icv_size;
+} aes_modes[] = {
+ { ENCR_AES_GCM_ICV8, 16, "AES-128/GCM(8)", 8 },
+ { ENCR_AES_GCM_ICV8, 24, "AES-192/GCM(8)", 8 },
+ { ENCR_AES_GCM_ICV8, 32, "AES-256/GCM(8)", 8 },
+ { ENCR_AES_GCM_ICV12, 16, "AES-128/GCM(12)", 12 },
+ { ENCR_AES_GCM_ICV12, 24, "AES-192/GCM(12)", 12 },
+ { ENCR_AES_GCM_ICV12, 32, "AES-256/GCM(12)", 12 },
+ { ENCR_AES_GCM_ICV16, 16, "AES-128/GCM(16)", 16 },
+ { ENCR_AES_GCM_ICV16, 24, "AES-192/GCM(16)", 16 },
+ { ENCR_AES_GCM_ICV16, 32, "AES-256/GCM(16)", 16 },
+ { ENCR_AES_CCM_ICV8, 16, "AES-128/CCM(8,4)", 8 },
+ { ENCR_AES_CCM_ICV8, 24, "AES-192/CCM(8,4)", 8 },
+ { ENCR_AES_CCM_ICV8, 32, "AES-256/CCM(8,4)", 8 },
+ { ENCR_AES_CCM_ICV12, 16, "AES-128/CCM(12,4)", 12 },
+ { ENCR_AES_CCM_ICV12, 24, "AES-192/CCM(12,4)", 12 },
+ { ENCR_AES_CCM_ICV12, 32, "AES-256/CCM(12,4)", 12 },
+ { ENCR_AES_CCM_ICV16, 16, "AES-128/CCM(16,4)", 16 },
+ { ENCR_AES_CCM_ICV16, 24, "AES-192/CCM(16,4)", 16 },
+ { ENCR_AES_CCM_ICV16, 32, "AES-256/CCM(16,4)", 16 },
+};
+
+/**
+ * Determine the cipher name and ICV size for the given algorithm and key size
+ */
+static bool determine_aes_params(private_aead_t *this,
+ encryption_algorithm_t algo, size_t key_size)
+{
+ int i;
+
+ for (i = 0; i < countof(aes_modes); i++)
+ {
+ if (aes_modes[i].algo == algo &&
+ aes_modes[i].key_size == key_size)
+ {
+ this->cipher_name = aes_modes[i].name;
+ this->icv_size = aes_modes[i].icv_size;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+#endif
+#endif
+
+/**
+ * Check the given salt size, set it if not set
+ */
+static bool check_salt_size(size_t expected, size_t *salt_size)
+{
+ if (*salt_size)
+ {
+ return *salt_size == expected;
+ }
+ *salt_size = expected;
+ return TRUE;
+}
+
/*
* Described in header
*/
-aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size,
- size_t salt_size)
+aead_t *botan_aead_create(encryption_algorithm_t algo, size_t key_size,
+ size_t salt_size)
{
private_aead_t *this;
@@ -246,88 +321,68 @@ aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size,
},
);
- if (salt_size && salt_size != SALT_LEN)
- {
- /* currently not supported */
- free(this);
- return NULL;
- }
-
switch (algo)
{
+#ifdef BOTAN_HAS_AES
+#ifdef BOTAN_HAS_AEAD_GCM
case ENCR_AES_GCM_ICV8:
- switch (key_size)
+ case ENCR_AES_GCM_ICV12:
+ case ENCR_AES_GCM_ICV16:
+ if (!key_size)
{
- case 0:
- key_size = 16;
- /* FALL */
- case 16:
- this->cipher_name = "AES-128/GCM(8)";
- break;
- case 24:
- this->cipher_name = "AES-192/GCM(8)";
- break;
- case 32:
- this->cipher_name = "AES-256/GCM(8)";
- break;
- default:
- free(this);
- return NULL;
+ key_size = 16;
+ }
+ if (!check_salt_size(SALT_LEN, &salt_size) ||
+ !determine_aes_params(this, algo, key_size))
+ {
+ free(this);
+ return NULL;
}
- this->icv_size = 8;
break;
- case ENCR_AES_GCM_ICV12:
- switch (key_size)
+#endif
+#ifdef BOTAN_HAS_AEAD_CCM
+ case ENCR_AES_CCM_ICV8:
+ case ENCR_AES_CCM_ICV12:
+ case ENCR_AES_CCM_ICV16:
+ if (!key_size)
{
- case 0:
- key_size = 16;
- /* FALL */
- case 16:
- this->cipher_name = "AES-128/GCM(12)";
- break;
- case 24:
- this->cipher_name = "AES-192/GCM(12)";
- break;
- case 32:
- this->cipher_name = "AES-256/GCM(12)";
- break;
- default:
- free(this);
- return NULL;
+ key_size = 16;
+ }
+ if (!check_salt_size(CCM_SALT_LEN, &salt_size) ||
+ !determine_aes_params(this, algo, key_size))
+ {
+ free(this);
+ return NULL;
}
- this->icv_size = 12;
break;
- case ENCR_AES_GCM_ICV16:
- switch (key_size)
+#endif
+#endif
+#ifdef BOTAN_HAS_AEAD_CHACHA20_POLY1305
+ case ENCR_CHACHA20_POLY1305:
+ if (!key_size)
+ {
+ key_size = CHAPOLY_KEY_LEN;
+ }
+ if (key_size != CHAPOLY_KEY_LEN ||
+ !check_salt_size(SALT_LEN, &salt_size))
{
- case 0:
- key_size = 16;
- /* FALL */
- case 16:
- this->cipher_name = "AES-128/GCM";
- break;
- case 24:
- this->cipher_name = "AES-192/GCM";
- break;
- case 32:
- this->cipher_name = "AES-256/GCM";
- break;
- default:
- free(this);
- return NULL;
+ free(this);
+ return NULL;
}
+ this->cipher_name = "ChaCha20Poly1305";
this->icv_size = 16;
break;
+#endif
default:
free(this);
return NULL;
}
this->key = chunk_alloc(key_size);
+ this->salt = chunk_alloc(salt_size);
this->iv_gen = iv_gen_seq_create();
return &this->public;
}
#endif
-#endif
diff --git a/src/libstrongswan/plugins/botan/botan_gcm.h b/src/libstrongswan/plugins/botan/botan_aead.h
index b2053cb4d..00a2ba4bc 100644
--- a/src/libstrongswan/plugins/botan/botan_gcm.h
+++ b/src/libstrongswan/plugins/botan/botan_aead.h
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2018 Atanas Filyanov
* Rohde & Schwarz Cybersecurity GmbH
*
@@ -22,14 +25,14 @@
*/
/**
- * Implements the aead_t interface using Botan in GCM mode.
+ * Implements the aead_t interface using Botan.
*
- * @defgroup botan_gcm botan_gcm
+ * @defgroup botan_aead botan_aead
* @{ @ingroup botan_p
*/
-#ifndef BOTAN_GCM_H_
-#define BOTAN_GCM_H_
+#ifndef BOTAN_AEAD_H_
+#define BOTAN_AEAD_H_
#include <crypto/aead.h>
@@ -41,7 +44,7 @@
* @param salt_size size of implicit salt length
* @return aead_t object, NULL if not supported
*/
-aead_t *botan_gcm_create(encryption_algorithm_t algo, size_t key_size,
- size_t salt_size);
+aead_t *botan_aead_create(encryption_algorithm_t algo, size_t key_size,
+ size_t salt_size);
-#endif /** BOTAN_GCM_H_ @}*/
+#endif /** BOTAN_AEAD_H_ @}*/
diff --git a/src/libstrongswan/plugins/botan/botan_crypter.c b/src/libstrongswan/plugins/botan/botan_crypter.c
index 002be6ea8..3ec5c4d5e 100644
--- a/src/libstrongswan/plugins/botan/botan_crypter.c
+++ b/src/libstrongswan/plugins/botan/botan_crypter.c
@@ -25,6 +25,10 @@
#include "botan_crypter.h"
+#include <botan/build.h>
+
+#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_MODE_CBC)
+
#include <botan/ffi.h>
typedef struct private_botan_crypter_t private_botan_crypter_t;
@@ -189,3 +193,5 @@ botan_crypter_t *botan_crypter_create(encryption_algorithm_t algo,
this->key = chunk_alloc(key_size);
return &this->public;
}
+
+#endif
diff --git a/src/libstrongswan/plugins/botan/botan_ec_public_key.c b/src/libstrongswan/plugins/botan/botan_ec_public_key.c
index 4c85dbcec..095ae3f20 100644
--- a/src/libstrongswan/plugins/botan/botan_ec_public_key.c
+++ b/src/libstrongswan/plugins/botan/botan_ec_public_key.c
@@ -69,9 +69,7 @@ static bool verify_signature(private_botan_ec_public_key_t *this,
const char* hash_and_padding, int signature_format, size_t keylen,
chunk_t data, chunk_t signature)
{
- botan_pk_op_verify_t verify_op;
chunk_t sig = signature;
- bool valid = FALSE;
if (signature_format == SIG_FORMAT_DER_SEQUENCE)
{
@@ -104,22 +102,7 @@ static bool verify_signature(private_botan_ec_public_key_t *this,
memcpy(sig.ptr + (keylen - r.len), r.ptr, r.len);
memcpy(sig.ptr + keylen + (keylen - s.len), s.ptr, s.len);
}
-
- if (botan_pk_op_verify_create(&verify_op, this->key, hash_and_padding, 0))
- {
- return FALSE;
- }
-
- if (botan_pk_op_verify_update(verify_op, data.ptr, data.len))
- {
- botan_pk_op_verify_destroy(verify_op);
- return FALSE;
- }
-
- valid = !(botan_pk_op_verify_finish(verify_op, sig.ptr, sig.len));
-
- botan_pk_op_verify_destroy(verify_op);
- return valid;
+ return botan_verify_signature(this->key, hash_and_padding, data, sig);
}
METHOD(public_key_t, get_type, key_type_t,
diff --git a/src/libstrongswan/plugins/botan/botan_ed_private_key.c b/src/libstrongswan/plugins/botan/botan_ed_private_key.c
new file mode 100644
index 000000000..3f0f54222
--- /dev/null
+++ b/src/libstrongswan/plugins/botan/botan_ed_private_key.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "botan_ed_private_key.h"
+#include "botan_ed_public_key.h"
+#include "botan_util.h"
+
+#include <botan/build.h>
+
+#ifdef BOTAN_HAS_ED25519
+
+#include <asn1/asn1.h>
+#include <utils/debug.h>
+
+typedef struct private_private_key_t private_private_key_t;
+
+#define ED25519_KEY_LEN 32
+
+/**
+ * Private data
+ */
+struct private_private_key_t {
+
+ /**
+ * Public interface
+ */
+ private_key_t public;
+
+ /**
+ * Botan private key object
+ */
+ botan_privkey_t key;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(private_key_t, sign, bool,
+ private_private_key_t *this, signature_scheme_t scheme,
+ void *params, chunk_t data, chunk_t *signature)
+{
+ switch (scheme)
+ {
+ case SIGN_ED25519:
+ return botan_get_signature(this->key, "Pure", data, signature);
+ default:
+ DBG1(DBG_LIB, "signature scheme %N not supported via botan",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+METHOD(private_key_t, decrypt, bool,
+ private_private_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1(DBG_LIB, "EdDSA private key decryption not implemented");
+ return FALSE;
+}
+
+METHOD(private_key_t, get_keysize, int,
+ private_private_key_t *this)
+{
+ return ED25519_KEY_LEN * 8;
+}
+
+METHOD(private_key_t, get_type, key_type_t,
+ private_private_key_t *this)
+{
+ return KEY_ED25519;
+}
+
+METHOD(private_key_t, get_public_key, public_key_t*,
+ private_private_key_t *this)
+{
+ botan_pubkey_t pubkey;
+
+ if (botan_privkey_export_pubkey(&pubkey, this->key))
+ {
+ return NULL;
+ }
+ return botan_ed_public_key_adopt(pubkey);
+}
+
+METHOD(private_key_t, get_fingerprint, bool,
+ private_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *fingerprint)
+{
+ botan_pubkey_t pubkey;
+ bool success = FALSE;
+
+ /* check the cache before doing the export */
+ if (lib->encoding->get_cache(lib->encoding, type, this, fingerprint))
+ {
+ return TRUE;
+ }
+
+ if (botan_privkey_export_pubkey(&pubkey, this->key))
+ {
+ return FALSE;
+ }
+ success = botan_get_fingerprint(pubkey, this, type, fingerprint);
+ botan_pubkey_destroy(pubkey);
+ return success;
+}
+
+METHOD(private_key_t, get_encoding, bool,
+ private_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
+{
+ return botan_get_privkey_encoding(this->key, type, encoding);
+}
+
+METHOD(private_key_t, get_ref, private_key_t*,
+ private_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
+METHOD(private_key_t, destroy, void,
+ private_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ lib->encoding->clear_cache(lib->encoding, this);
+ botan_privkey_destroy(this->key);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_private_key_t *create_empty()
+{
+ private_private_key_t *this;
+
+ INIT(this,
+ .public = {
+ .get_type = _get_type,
+ .sign = _sign,
+ .decrypt = _decrypt,
+ .get_keysize = _get_keysize,
+ .get_public_key = _get_public_key,
+ .equals = private_key_equals,
+ .belongs_to = private_key_belongs_to,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = private_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .ref = 1,
+ );
+
+ return this;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *botan_ed_private_key_adopt(botan_privkey_t key)
+{
+ private_private_key_t *this;
+
+ this = create_empty();
+ this->key = key;
+
+ return &this->public;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *botan_ed_private_key_gen(key_type_t type, va_list args)
+{
+ private_private_key_t *this;
+ botan_rng_t rng;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_KEY_SIZE:
+ /* just ignore the key size */
+ va_arg(args, u_int);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ if (botan_rng_init(&rng, "system"))
+ {
+ return NULL;
+ }
+
+ this = create_empty();
+
+ if (botan_privkey_create(&this->key, "Ed25519", NULL, rng))
+ {
+ DBG1(DBG_LIB, "EdDSA private key generation failed");
+ botan_rng_destroy(rng);
+ free(this);
+ return NULL;
+ }
+
+ botan_rng_destroy(rng);
+ return &this->public;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *botan_ed_private_key_load(key_type_t type, va_list args)
+{
+ private_private_key_t *this;
+ chunk_t key = chunk_empty;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_EDDSA_PRIV_ASN1_DER:
+ key = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ /* PKCS#8-encoded keys are handled generically, so we only handle the
+ * explicit case */
+ if (asn1_unwrap(&key, &key) != ASN1_OCTET_STRING ||
+ key.len != ED25519_KEY_LEN)
+ {
+ return NULL;
+ }
+
+ this = create_empty();
+
+ if (botan_privkey_load_ed25519(&this->key, key.ptr))
+ {
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+#endif
diff --git a/src/libstrongswan/plugins/botan/botan_ed_private_key.h b/src/libstrongswan/plugins/botan/botan_ed_private_key.h
new file mode 100644
index 000000000..f7f32e8f3
--- /dev/null
+++ b/src/libstrongswan/plugins/botan/botan_ed_private_key.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @defgroup botan_ed_private_key botan_ed_private_key
+ * @{ @ingroup botan_p
+ */
+
+#ifndef BOTAN_ED_PRIVATE_KEY_H_
+#define BOTAN_ED_PRIVATE_KEY_H_
+
+#include <botan/ffi.h>
+
+#include <credentials/builder.h>
+#include <credentials/keys/private_key.h>
+
+/**
+ * Generate an EdDSA private key using Botan.
+ *
+ * @param type type of the key, must be KEY_ED25519
+ * @param args builder_part_t argument list
+ * @return generated key, NULL on failure
+ */
+private_key_t *botan_ed_private_key_gen(key_type_t type, va_list args);
+
+/**
+ * Load an EdDSA private key using Botan.
+ *
+ * @param type type of the key, must be KEY_ED25519
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+private_key_t *botan_ed_private_key_load(key_type_t type, va_list args);
+
+/**
+ * Load an EdDSA private key by adopting a botan_privkey_t object.
+ *
+ * @param key private key object (adopted)
+ * @return loaded key, NULL on failure
+ */
+private_key_t *botan_ed_private_key_adopt(botan_privkey_t key);
+
+#endif /** BOTAN_ED_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/botan/botan_ed_public_key.c b/src/libstrongswan/plugins/botan/botan_ed_public_key.c
new file mode 100644
index 000000000..41d2baae8
--- /dev/null
+++ b/src/libstrongswan/plugins/botan/botan_ed_public_key.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "botan_ed_public_key.h"
+#include "botan_util.h"
+
+#include <botan/build.h>
+
+#ifdef BOTAN_HAS_ED25519
+
+#include <utils/debug.h>
+
+typedef struct private_public_key_t private_public_key_t;
+
+/**
+ * Private data
+ */
+struct private_public_key_t {
+
+ /**
+ * Public interface
+ */
+ public_key_t public;
+
+ /**
+ * Botan public key object
+ */
+ botan_pubkey_t key;
+
+ /**
+ * Reference counter
+ */
+ refcount_t ref;
+};
+
+METHOD(public_key_t, get_type, key_type_t,
+ private_public_key_t *this)
+{
+ return KEY_ED25519;
+}
+
+METHOD(public_key_t, get_keysize, int,
+ private_public_key_t *this)
+{
+ return ED25519_KEY_LEN * 8;
+}
+
+METHOD(public_key_t, verify, bool,
+ private_public_key_t *this, signature_scheme_t scheme,
+ void *params, chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_ED25519:
+ return botan_verify_signature(this->key, "Pure", data, signature);
+ default:
+ DBG1(DBG_LIB, "signature scheme %N not supported via botan",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+METHOD(public_key_t, encrypt, bool,
+ private_public_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1(DBG_LIB, "EdDSA public key encryption not implemented");
+ return FALSE;
+}
+
+METHOD(public_key_t, get_fingerprint, bool,
+ private_public_key_t *this, cred_encoding_type_t type,
+ chunk_t *fingerprint)
+{
+ return botan_get_fingerprint(this->key, this, type, fingerprint);
+}
+
+METHOD(public_key_t, get_encoding, bool,
+ private_public_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
+{
+ return botan_get_encoding(this->key, type, encoding);
+}
+
+METHOD(public_key_t, get_ref, public_key_t*,
+ private_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
+METHOD(public_key_t, destroy, void,
+ private_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ lib->encoding->clear_cache(lib->encoding, this);
+ botan_pubkey_destroy(this->key);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_public_key_t *create_empty()
+{
+ private_public_key_t *this;
+
+ INIT(this,
+ .public = {
+ .get_type = _get_type,
+ .verify = _verify,
+ .encrypt = _encrypt,
+ .get_keysize = _get_keysize,
+ .equals = public_key_equals,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = public_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .ref = 1,
+ );
+
+ return this;
+}
+
+/*
+ * Described in header
+ */
+public_key_t *botan_ed_public_key_adopt(botan_pubkey_t key)
+{
+ private_public_key_t *this;
+
+ this = create_empty();
+ this->key = key;
+
+ return &this->public;
+}
+
+/*
+ * Described in header
+ */
+public_key_t *botan_ed_public_key_load(key_type_t type, va_list args)
+{
+ private_public_key_t *this;
+ chunk_t key = chunk_empty;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_EDDSA_PUB:
+ key = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ /* ASN.1-encoded keys are handled generically, so we only handle the
+ * explicit case */
+ if (key.len != ED25519_KEY_LEN)
+ {
+ return NULL;
+ }
+
+ this = create_empty();
+
+ if (botan_pubkey_load_ed25519(&this->key, key.ptr))
+ {
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+#endif
diff --git a/src/libstrongswan/plugins/botan/botan_ed_public_key.h b/src/libstrongswan/plugins/botan/botan_ed_public_key.h
new file mode 100644
index 000000000..0f44b1afb
--- /dev/null
+++ b/src/libstrongswan/plugins/botan/botan_ed_public_key.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef BOTAN_ED_PUBLIC_KEY_H_
+#define BOTAN_ED_PUBLIC_KEY_H_
+
+#include <botan/ffi.h>
+
+#include <credentials/builder.h>
+#include <credentials/keys/public_key.h>
+
+#define ED25519_KEY_LEN 32
+
+/**
+ * Load an EdDSA public key by adopting a botan_pubkey_t object.
+ *
+ * @param key public key object (adopted)
+ * @return loaded key, NULL on failure
+ */
+public_key_t *botan_ed_public_key_adopt(botan_pubkey_t key);
+
+/**
+ * Load an EdDSA public key using Botan.
+ *
+ * @param type type of the key, must be KEY_ED25519
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+public_key_t *botan_ed_public_key_load(key_type_t type, va_list args);
+
+#endif /** BOTAN_ED_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/botan/botan_plugin.c b/src/libstrongswan/plugins/botan/botan_plugin.c
index fd8e5f5a6..f045ba074 100644
--- a/src/libstrongswan/plugins/botan/botan_plugin.c
+++ b/src/libstrongswan/plugins/botan/botan_plugin.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2018 René Korthaus
@@ -36,7 +37,9 @@
#include "botan_ec_diffie_hellman.h"
#include "botan_ec_public_key.h"
#include "botan_ec_private_key.h"
-#include "botan_gcm.h"
+#include "botan_ed_public_key.h"
+#include "botan_ed_private_key.h"
+#include "botan_aead.h"
#include "botan_util_keys.h"
#include "botan_x25519.h"
@@ -101,6 +104,7 @@ METHOD(plugin_t, get_features, int,
#endif
/* crypters */
+#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_MODE_CBC)
PLUGIN_REGISTER(CRYPTER, botan_crypter_create),
#ifdef BOTAN_HAS_AES
#ifdef BOTAN_HAS_MODE_CBC
@@ -108,17 +112,43 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
#endif
+#endif
+#endif
+
+ /* AEAD */
+#if (defined(BOTAN_HAS_AES) && \
+ (defined(BOTAN_HAS_AEAD_GCM) || defined(BOTAN_HAS_AEAD_CCM))) || \
+ defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
+ PLUGIN_REGISTER(AEAD, botan_aead_create),
+#ifdef BOTAN_HAS_AES
#ifdef BOTAN_HAS_AEAD_GCM
- /* AES GCM */
- PLUGIN_REGISTER(AEAD, botan_gcm_create),
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 16),
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24),
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 32),
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 16),
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 24),
PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 32),
#endif
+ #ifdef BOTAN_HAS_AEAD_CCM
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 32),
+ #endif
+#endif
+#ifdef BOTAN_HAS_AEAD_CHACHA20_POLY1305
+ PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32),
#endif
+#endif
+
/* hashers */
PLUGIN_REGISTER(HASHER, botan_hasher_create),
#ifdef BOTAN_HAS_MD5
@@ -135,6 +165,13 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(HASHER, HASH_SHA384),
PLUGIN_PROVIDE(HASHER, HASH_SHA512),
#endif
+#ifdef BOTAN_HAS_SHA3
+ PLUGIN_PROVIDE(HASHER, HASH_SHA3_224),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA3_256),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA3_384),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA3_512),
+#endif
+
/* prfs */
#ifdef BOTAN_HAS_HMAC
PLUGIN_REGISTER(PRF, botan_hmac_prf_create),
@@ -168,7 +205,8 @@ METHOD(plugin_t, get_features, int,
#endif /* BOTAN_HAS_HMAC */
/* generic key loaders */
-#if defined (BOTAN_HAS_RSA) || defined(BOTAN_HAS_ECDSA)
+#if defined (BOTAN_HAS_RSA) || defined(BOTAN_HAS_ECDSA) || \
+ defined(BOTAN_HAS_ED25519)
PLUGIN_REGISTER(PUBKEY, botan_public_key_load, TRUE),
PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
#ifdef BOTAN_HAS_RSA
@@ -177,6 +215,9 @@ METHOD(plugin_t, get_features, int,
#ifdef BOTAN_HAS_ECDSA
PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
#endif
+#ifdef BOTAN_HAS_ED25519
+ PLUGIN_PROVIDE(PUBKEY, KEY_ED25519),
+#endif
PLUGIN_REGISTER(PRIVKEY, botan_private_key_load, TRUE),
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
#ifdef BOTAN_HAS_RSA
@@ -185,6 +226,9 @@ METHOD(plugin_t, get_features, int,
#ifdef BOTAN_HAS_ECDSA
PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
#endif
+#ifdef BOTAN_HAS_ED25519
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519),
+#endif
#endif
/* RSA */
#ifdef BOTAN_HAS_RSA
@@ -218,6 +262,16 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512),
#endif
+#ifdef BOTAN_HAS_SHA3
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_224),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_256),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_384),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA3_512),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_224),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_256),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_384),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA3_512),
+#endif
#endif
#ifdef BOTAN_HAS_EMSA_PSSR
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
@@ -272,6 +326,21 @@ METHOD(plugin_t, get_features, int,
#endif /* BOTAN_HAS_EMSA1 */
#endif /* BOTAN_HAS_ECDSA */
+#ifdef BOTAN_HAS_ED25519
+ /* EdDSA private/public key loading */
+ PLUGIN_REGISTER(PUBKEY, botan_ed_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ED25519),
+ PLUGIN_REGISTER(PRIVKEY, botan_ed_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519),
+ PLUGIN_REGISTER(PRIVKEY_GEN, botan_ed_private_key_gen, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED25519),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED25519),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED25519),
+ /* register a pro forma identity hasher, never instantiated */
+ PLUGIN_REGISTER(HASHER, return_null),
+ PLUGIN_PROVIDE(HASHER, HASH_IDENTITY),
+#endif
+
/* random numbers */
#if BOTAN_HAS_SYSTEM_RNG
#if BOTAN_HAS_HMAC_DRBG
diff --git a/src/libstrongswan/plugins/botan/botan_rsa_private_key.c b/src/libstrongswan/plugins/botan/botan_rsa_private_key.c
index bb723ff95..02820b297 100644
--- a/src/libstrongswan/plugins/botan/botan_rsa_private_key.c
+++ b/src/libstrongswan/plugins/botan/botan_rsa_private_key.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2018 René Korthaus
@@ -84,13 +85,8 @@ bool botan_emsa_pss_identifier(rsa_pss_params_t *params, char *id, size_t len)
{
return FALSE;
}
-
- if (params->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
- {
- return snprintf(id, len, "EMSA-PSS(%s,MGF1,%zd)", hash,
- params->salt_len) < len;
- }
- return snprintf(id, len, "EMSA-PSS(%s,MGF1)", hash) < len;
+ return snprintf(id, len, "EMSA-PSS(%s,MGF1,%zd)", hash,
+ params->salt_len) < len;
}
/**
@@ -140,6 +136,18 @@ METHOD(private_key_t, sign, bool,
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
return botan_get_signature(this->key, "EMSA_PKCS1(SHA-512)", data,
signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_224:
+ return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(224))", data,
+ signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_256:
+ return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(256))", data,
+ signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_384:
+ return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(384))", data,
+ signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_512:
+ return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(512))", data,
+ signature);
case SIGN_RSA_EMSA_PSS:
return build_emsa_pss_signature(this, params, data, signature);
default:
@@ -617,7 +625,7 @@ botan_rsa_private_key_t *botan_rsa_private_key_load(key_type_t type,
if (n.ptr && e.ptr && d.ptr)
{
- botan_mp_t n_mp, e_mp, d_mp, p_mp, q_mp;
+ botan_mp_t n_mp, e_mp, d_mp, p_mp = NULL, q_mp = NULL;
if (!chunk_to_botan_mp(n, &n_mp))
{
diff --git a/src/libstrongswan/plugins/botan/botan_rsa_public_key.c b/src/libstrongswan/plugins/botan/botan_rsa_public_key.c
index c6e2e8861..244caa585 100644
--- a/src/libstrongswan/plugins/botan/botan_rsa_public_key.c
+++ b/src/libstrongswan/plugins/botan/botan_rsa_public_key.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2018 René Korthaus
@@ -69,33 +70,6 @@ struct private_botan_rsa_public_key_t {
bool botan_emsa_pss_identifier(rsa_pss_params_t *params, char *id, size_t len);
/**
- * Verify RSA signature
- */
-static bool verify_rsa_signature(private_botan_rsa_public_key_t *this,
- const char* hash_and_padding, chunk_t data,
- chunk_t signature)
-{
- botan_pk_op_verify_t verify_op;
- bool valid = FALSE;
-
- if (botan_pk_op_verify_create(&verify_op, this->key, hash_and_padding, 0))
- {
- return FALSE;
- }
-
- if (botan_pk_op_verify_update(verify_op, data.ptr, data.len))
- {
- botan_pk_op_verify_destroy(verify_op);
- return FALSE;
- }
-
- valid = !botan_pk_op_verify_finish(verify_op, signature.ptr, signature.len);
-
- botan_pk_op_verify_destroy(verify_op);
- return valid;
-}
-
-/**
* Verification of an EMSA PSS signature described in PKCS#1
*/
static bool verify_emsa_pss_signature(private_botan_rsa_public_key_t *this,
@@ -109,7 +83,7 @@ static bool verify_emsa_pss_signature(private_botan_rsa_public_key_t *this,
{
return FALSE;
}
- return verify_rsa_signature(this, hash_and_padding, data, signature);
+ return botan_verify_signature(this->key, hash_and_padding, data, signature);
}
METHOD(public_key_t, get_type, key_type_t,
@@ -125,23 +99,35 @@ METHOD(public_key_t, verify, bool,
switch (scheme)
{
case SIGN_RSA_EMSA_PKCS1_NULL:
- return verify_rsa_signature(this, "EMSA_PKCS1(Raw)", data,
- signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(Raw)", data,
+ signature);
case SIGN_RSA_EMSA_PKCS1_SHA1:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-1)", data,
- signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-1)", data,
+ signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_224:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-224)",
- data, signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-224)",
+ data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_256:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-256)",
- data, signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-256)",
+ data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_384:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-384)",
- data, signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-384)",
+ data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
- return verify_rsa_signature(this, "EMSA_PKCS1(SHA-512)",
- data, signature);
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-512)",
+ data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_224:
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(224)",
+ data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_256:
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(256))",
+ data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_384:
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(384))",
+ data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA3_512:
+ return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(512))",
+ data, signature);
case SIGN_RSA_EMSA_PSS:
return verify_emsa_pss_signature(this, params, data, signature);
default:
diff --git a/src/libstrongswan/plugins/botan/botan_util.c b/src/libstrongswan/plugins/botan/botan_util.c
index 5e18405d7..f5728e43e 100644
--- a/src/libstrongswan/plugins/botan/botan_util.c
+++ b/src/libstrongswan/plugins/botan/botan_util.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2018 René Korthaus
@@ -67,6 +68,14 @@ const char *botan_get_hash(hash_algorithm_t hash)
return "SHA-384";
case HASH_SHA512:
return "SHA-512";
+ case HASH_SHA3_224:
+ return "SHA-3(224)";
+ case HASH_SHA3_256:
+ return "SHA-3(256)";
+ case HASH_SHA3_384:
+ return "SHA-3(384)";
+ case HASH_SHA3_512:
+ return "SHA-3(512)";
default:
return NULL;
}
@@ -252,6 +261,32 @@ bool botan_get_signature(botan_privkey_t key, const char *scheme,
/*
* Described in header
*/
+bool botan_verify_signature(botan_pubkey_t key, const char *scheme,
+ chunk_t data, chunk_t signature)
+{
+ botan_pk_op_verify_t verify_op;
+ bool valid = FALSE;
+
+ if (botan_pk_op_verify_create(&verify_op, key, scheme, 0))
+ {
+ return FALSE;
+ }
+
+ if (botan_pk_op_verify_update(verify_op, data.ptr, data.len))
+ {
+ botan_pk_op_verify_destroy(verify_op);
+ return FALSE;
+ }
+
+ valid = !botan_pk_op_verify_finish(verify_op, signature.ptr, signature.len);
+
+ botan_pk_op_verify_destroy(verify_op);
+ return valid;
+}
+
+/*
+ * Described in header
+ */
bool botan_dh_key_derivation(botan_privkey_t key, chunk_t pub, chunk_t *secret)
{
botan_pk_op_ka_t ka;
diff --git a/src/libstrongswan/plugins/botan/botan_util.h b/src/libstrongswan/plugins/botan/botan_util.h
index 08830356e..7fb74ec5d 100644
--- a/src/libstrongswan/plugins/botan/botan_util.h
+++ b/src/libstrongswan/plugins/botan/botan_util.h
@@ -101,6 +101,18 @@ bool botan_get_signature(botan_privkey_t key, const char *scheme,
chunk_t data, chunk_t *signature);
/**
+ * Verify the given signature using the provided data and key with the specified
+ * signature scheme (hash/padding).
+ *
+ * @param key private key object
+ * @param scheme hash/padding algorithm
+ * @param data signed data
+ * @param signature signature to verify
+ */
+bool botan_verify_signature(botan_pubkey_t key, const char* scheme,
+ chunk_t data, chunk_t signature);
+
+/**
* Do the Diffie-Hellman key derivation using the given private key and public
* value.
*
diff --git a/src/libstrongswan/plugins/botan/botan_util_keys.c b/src/libstrongswan/plugins/botan/botan_util_keys.c
index 176c2caf9..dc4031491 100644
--- a/src/libstrongswan/plugins/botan/botan_util_keys.c
+++ b/src/libstrongswan/plugins/botan/botan_util_keys.c
@@ -24,6 +24,8 @@
#include "botan_util_keys.h"
#include "botan_ec_public_key.h"
#include "botan_ec_private_key.h"
+#include "botan_ed_public_key.h"
+#include "botan_ed_private_key.h"
#include "botan_rsa_public_key.h"
#include "botan_rsa_private_key.h"
@@ -104,15 +106,27 @@ public_key_t *botan_public_key_load(key_type_t type, va_list args)
return NULL;
}
+#ifdef BOTAN_HAS_RSA
if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
{
this = (public_key_t*)botan_rsa_public_key_adopt(pubkey);
}
- else if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
+ else
+#endif
+#ifdef BOTAN_HAS_ECDSA
+ if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
{
this = (public_key_t*)botan_ec_public_key_adopt(pubkey);
}
else
+#endif
+#ifdef BOTAN_HAS_ED25519
+ if (streq(name, "Ed25519") && (type == KEY_ANY || type == KEY_ED25519))
+ {
+ this = botan_ed_public_key_adopt(pubkey);
+ }
+ else
+#endif
{
botan_pubkey_destroy(pubkey);
}
@@ -120,6 +134,7 @@ public_key_t *botan_public_key_load(key_type_t type, va_list args)
return this;
}
+#ifdef BOTAN_HAS_ECDSA
/**
* Determine the curve OID from a PKCS#8 structure
*/
@@ -139,6 +154,7 @@ static int determine_ec_oid(chunk_t pkcs8)
}
return oid;
}
+#endif
/*
* Described in header
@@ -151,7 +167,6 @@ private_key_t *botan_private_key_load(key_type_t type, va_list args)
chunk_t blob = chunk_empty;
botan_rng_t rng;
char *name;
- int oid;
while (TRUE)
{
@@ -188,20 +203,35 @@ private_key_t *botan_private_key_load(key_type_t type, va_list args)
botan_pubkey_destroy(pubkey);
if (!name)
{
+ botan_privkey_destroy(key);
return NULL;
}
+
+#ifdef BOTAN_HAS_RSA
if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
{
this = (private_key_t*)botan_rsa_private_key_adopt(key);
}
- else if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
+ else
+#endif
+#ifdef BOTAN_HAS_ECDSA
+ if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
{
- oid = determine_ec_oid(blob);
+ int oid = determine_ec_oid(blob);
if (oid != OID_UNKNOWN)
{
this = (private_key_t*)botan_ec_private_key_adopt(key, oid);
}
}
+ else
+#endif
+#ifdef BOTAN_HAS_ED25519
+ if (streq(name, "Ed25519") && (type == KEY_ANY || type == KEY_ED25519))
+ {
+ this = botan_ed_private_key_adopt(key);
+ }
+#endif
+
if (!this)
{
botan_privkey_destroy(key);
diff --git a/src/libstrongswan/plugins/curve25519/curve25519_public_key.c b/src/libstrongswan/plugins/curve25519/curve25519_public_key.c
index 1d4dec565..dfc1df4d0 100644
--- a/src/libstrongswan/plugins/curve25519/curve25519_public_key.c
+++ b/src/libstrongswan/plugins/curve25519/curve25519_public_key.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2018 Tobias Brunner
* Copyright (C) 2016 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
@@ -48,6 +49,13 @@ METHOD(public_key_t, get_type, key_type_t,
return KEY_ED25519;
}
+/* L = 2^252+27742317777372353535851937790883648493 in little-endian form */
+static chunk_t curve25519_order = chunk_from_chars(
+ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
+ 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10);
+
METHOD(public_key_t, verify, bool,
private_curve25519_public_key_t *this, signature_scheme_t scheme,
void *params, chunk_t data, chunk_t signature)
@@ -93,6 +101,20 @@ METHOD(public_key_t, verify, bool,
{
return FALSE;
}
+ /* make sure 0 <= s < L, as per RFC 8032, section 5.1.7 to prevent signature
+ * malleability. Due to the three-bit check above (forces s < 2^253) there
+ * is not that much room, but adding L once works with most signatures */
+ for (i = 31; ; i--)
+ {
+ if (sig[i+32] < curve25519_order.ptr[i])
+ {
+ break;
+ }
+ else if (sig[i+32] > curve25519_order.ptr[i] || i == 0)
+ {
+ return FALSE;
+ }
+ }
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
if (!hasher)
@@ -200,22 +222,68 @@ static const asn1Object_t pubkeyObjects[] = {
#define ED25519_SUBJECT_PUBLIC_KEY 2
/**
+ * Parse the ASN.1-encoded subjectPublicKeyInfo
+ */
+static bool parse_public_key_info(private_curve25519_public_key_t *this,
+ chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ bool success = FALSE;
+ int objectID, oid;
+
+ parser = asn1_parser_create(pubkeyObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM:
+ {
+ oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser) + 1, NULL);
+ if (oid != OID_ED25519)
+ {
+ goto end;
+ }
+ break;
+ }
+ case ED25519_SUBJECT_PUBLIC_KEY:
+ {
+ /* encoded as an ASN1 BIT STRING */
+ if (object.len != 1 + ED25519_KEY_LEN)
+ {
+ goto end;
+ }
+ this->pubkey = chunk_clone(chunk_skip(object, 1));
+ break;
+ }
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
* See header.
*/
curve25519_public_key_t *curve25519_public_key_load(key_type_t type,
va_list args)
{
private_curve25519_public_key_t *this;
- chunk_t blob = chunk_empty, object;
- asn1_parser_t *parser;
- bool success = FALSE;
- int objectID, oid;
+ chunk_t asn1 = chunk_empty, blob = chunk_empty;
while (TRUE)
{
switch (va_arg(args, builder_part_t))
{
case BUILD_BLOB_ASN1_DER:
+ asn1 = va_arg(args, chunk_t);
+ continue;
+ case BUILD_EDDSA_PUB:
blob = va_arg(args, chunk_t);
continue;
case BUILD_END:
@@ -244,39 +312,11 @@ curve25519_public_key_t *curve25519_public_key_load(key_type_t type,
.ref = 1,
);
- parser = asn1_parser_create(pubkeyObjects, blob);
-
- while (parser->iterate(parser, &objectID, &object))
+ if (blob.len == ED25519_KEY_LEN)
{
- switch (objectID)
- {
- case ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM:
- {
- oid = asn1_parse_algorithmIdentifier(object,
- parser->get_level(parser) + 1, NULL);
- if (oid != OID_ED25519)
- {
- goto end;
- }
- break;
- }
- case ED25519_SUBJECT_PUBLIC_KEY:
- {
- /* encoded as an ASN1 BIT STRING */
- if (object.len != 1 + ED25519_KEY_LEN)
- {
- goto end;
- }
- this->pubkey = chunk_clone(chunk_skip(object, 1));
- break;
- }
- }
+ this->pubkey = chunk_clone(blob);
}
- success = parser->success(parser);
-
-end:
- parser->destroy(parser);
- if (!success)
+ else if (!asn1.len || !parse_public_key_info(this, asn1))
{
destroy(this);
return NULL;
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
index 45fba242b..6946e4576 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
@@ -43,10 +43,12 @@ struct private_gcrypt_plugin_t {
gcrypt_plugin_t public;
};
+#if GCRYPT_VERSION_NUMBER < 0x010600
/**
* Define gcrypt multi-threading callbacks as gcry_threads_pthread
*/
GCRY_THREAD_OPTION_PTHREAD_IMPL;
+#endif
METHOD(plugin_t, get_name, char*,
private_gcrypt_plugin_t *this)
@@ -163,7 +165,9 @@ plugin_t *gcrypt_plugin_create()
{
private_gcrypt_plugin_t *this;
+#if GCRYPT_VERSION_NUMBER < 0x010600
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+#endif
if (!gcry_check_version(GCRYPT_VERSION))
{
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
index c06f43348..394b87c27 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
@@ -187,11 +187,7 @@ static bool sign_pkcs1(private_gcrypt_rsa_private_key_t *this,
}
else
{
- u_int slen = hasher_hash_size(hash_algorithm);
- if (pss->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
- {
- slen = pss->salt_len;
- }
+ u_int slen = pss->salt_len;
err = gcry_sexp_build(&in, NULL,
"(data(flags pss)(salt-length %u)(hash %s %b))",
slen, hash_name, hash.len, hash.ptr);
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
index 9e2ac1287..bbfa5e298 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
@@ -139,11 +139,7 @@ static bool verify_pkcs1(private_gcrypt_rsa_public_key_t *this,
if (pss)
{
- u_int slen = hasher_hash_size(algorithm);
- if (pss->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
- {
- slen = pss->salt_len;
- }
+ u_int slen = pss->salt_len;
err = gcry_sexp_build(&in, NULL,
"(data(flags pss)(salt-length %u)(hash %s %b))",
slen, hash_name, hash.len, hash.ptr);
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
index a255a40ab..2d2d5c6fb 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
@@ -393,15 +393,11 @@ static bool build_emsa_pss_signature(private_gmp_rsa_private_key_t *this,
goto error;
}
- salt.len = hash.len;
+ salt.len = params->salt_len;
if (params->salt.len)
{
salt = params->salt;
}
- else if (params->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
- {
- salt.len = params->salt_len;
- }
if (emlen < (hash.len + salt.len + 2))
{ /* too long */
goto error;
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
index 9b5ee67fa..f9bd1d314 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
@@ -205,12 +205,7 @@ static bool verify_emsa_pss_signature(private_gmp_rsa_public_key_t *this,
{
goto error;
}
- /* determine salt length */
- salt.len = hash.len;
- if (params->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
- {
- salt.len = params->salt_len;
- }
+ salt.len = params->salt_len;
/* verify general structure of EM */
maskbits = (8 * em.len) - embits;
if (em.len < (hash.len + salt.len + 2) || em.ptr[em.len-1] != 0xbc ||
diff --git a/src/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c
index d7e35d9fd..90f8185b0 100644
--- a/src/libstrongswan/plugins/mysql/mysql_database.c
+++ b/src/libstrongswan/plugins/mysql/mysql_database.c
@@ -131,9 +131,13 @@ typedef struct {
*/
static void conn_release(private_mysql_database_t *this, conn_t *conn)
{
- this->mutex->lock(this->mutex);
- conn->in_use = FALSE;
- this->mutex->unlock(this->mutex);
+ /* do not release the connection while transactions are using it */
+ if (!this->transaction->get(this->transaction))
+ {
+ this->mutex->lock(this->mutex);
+ conn->in_use = FALSE;
+ this->mutex->unlock(this->mutex);
+ }
}
/**
diff --git a/src/libstrongswan/plugins/openssl/Makefile.am b/src/libstrongswan/plugins/openssl/Makefile.am
index 9287f788a..d484092e7 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.am
+++ b/src/libstrongswan/plugins/openssl/Makefile.am
@@ -29,7 +29,10 @@ libstrongswan_openssl_la_SOURCES = \
openssl_pkcs12.c openssl_pkcs12.h \
openssl_rng.c openssl_rng.h \
openssl_hmac.c openssl_hmac.h \
- openssl_gcm.c openssl_gcm.h
+ openssl_gcm.c openssl_gcm.h \
+ openssl_x_diffie_hellman.c openssl_x_diffie_hellman.h \
+ openssl_ed_private_key.c openssl_ed_private_key.h \
+ openssl_ed_public_key.c openssl_ed_public_key.h
libstrongswan_openssl_la_LDFLAGS = -module -avoid-version
libstrongswan_openssl_la_LIBADD = $(OPENSSL_LIB)
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index 79be2e670..da04d17cf 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -145,7 +145,8 @@ am_libstrongswan_openssl_la_OBJECTS = openssl_plugin.lo \
openssl_ec_diffie_hellman.lo openssl_ec_private_key.lo \
openssl_ec_public_key.lo openssl_x509.lo openssl_crl.lo \
openssl_pkcs7.lo openssl_pkcs12.lo openssl_rng.lo \
- openssl_hmac.lo openssl_gcm.lo
+ openssl_hmac.lo openssl_gcm.lo openssl_x_diffie_hellman.lo \
+ openssl_ed_private_key.lo openssl_ed_public_key.lo
libstrongswan_openssl_la_OBJECTS = \
$(am_libstrongswan_openssl_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -487,7 +488,10 @@ libstrongswan_openssl_la_SOURCES = \
openssl_pkcs12.c openssl_pkcs12.h \
openssl_rng.c openssl_rng.h \
openssl_hmac.c openssl_hmac.h \
- openssl_gcm.c openssl_gcm.h
+ openssl_gcm.c openssl_gcm.h \
+ openssl_x_diffie_hellman.c openssl_x_diffie_hellman.h \
+ openssl_ed_private_key.c openssl_ed_private_key.h \
+ openssl_ed_public_key.c openssl_ed_public_key.h
libstrongswan_openssl_la_LDFLAGS = -module -avoid-version
libstrongswan_openssl_la_LIBADD = $(OPENSSL_LIB)
@@ -586,6 +590,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_diffie_hellman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_private_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_public_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ed_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ed_public_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_gcm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_hasher.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_hmac.Plo@am__quote@
@@ -598,6 +604,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_sha1_prf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_util.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_x509.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_x_diffie_hellman.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c
index bb5f20dcf..3e7490dc6 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crl.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crl.c
@@ -57,6 +57,9 @@ static inline void X509_CRL_get0_signature(const X509_CRL *crl, ASN1_BIT_STRING
#define X509_REVOKED_get0_serialNumber(r) ({ (r)->serialNumber; })
#define X509_REVOKED_get0_revocationDate(r) ({ (r)->revocationDate; })
#define X509_CRL_get0_extensions(c) ({ (c)->crl->extensions; })
+#define ASN1_STRING_get0_data(a) ASN1_STRING_data(a)
+#define X509_CRL_get0_lastUpdate(c) X509_CRL_get_lastUpdate(c)
+#define X509_CRL_get0_nextUpdate(c) X509_CRL_get_nextUpdate(c)
#endif
typedef struct private_openssl_crl_t private_openssl_crl_t;
@@ -193,7 +196,7 @@ METHOD(enumerator_t, crl_enumerate, bool,
if (ASN1_STRING_type(crlrsn) == V_ASN1_ENUMERATED &&
ASN1_STRING_length(crlrsn) == 1)
{
- *reason = *ASN1_STRING_data(crlrsn);
+ *reason = *ASN1_STRING_get0_data(crlrsn);
}
ASN1_STRING_free(crlrsn);
}
@@ -288,7 +291,11 @@ METHOD(certificate_t, issued_by, bool,
chunk_t fingerprint, tbs;
public_key_t *key;
x509_t *x509;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ const ASN1_BIT_STRING *sig;
+#else
ASN1_BIT_STRING *sig;
+#endif
bool valid;
if (issuer->get_type(issuer) != CERT_X509)
@@ -509,7 +516,7 @@ static bool parse_extensions(private_openssl_crl_t *this)
bool ok;
int i, num;
X509_EXTENSION *ext;
- STACK_OF(X509_EXTENSION) *extensions;
+ const STACK_OF(X509_EXTENSION) *extensions;
extensions = X509_CRL_get0_extensions(this->crl);
if (extensions)
@@ -564,7 +571,11 @@ static bool parse_crl(private_openssl_crl_t *this)
{
const unsigned char *ptr = this->encoding.ptr;
chunk_t sig_scheme;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ const X509_ALGOR *alg;
+#else
X509_ALGOR *alg;
+#endif
this->crl = d2i_X509_CRL(NULL, &ptr, this->encoding.len);
if (!this->crl)
@@ -573,7 +584,7 @@ static bool parse_crl(private_openssl_crl_t *this)
}
X509_CRL_get0_signature(this->crl, NULL, &alg);
- sig_scheme = openssl_i2chunk(X509_ALGOR, alg);
+ sig_scheme = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
INIT(this->scheme);
if (!signature_params_parse(sig_scheme, 0, this->scheme))
{
@@ -588,8 +599,8 @@ static bool parse_crl(private_openssl_crl_t *this)
{
return FALSE;
}
- this->thisUpdate = openssl_asn1_to_time(X509_CRL_get_lastUpdate(this->crl));
- this->nextUpdate = openssl_asn1_to_time(X509_CRL_get_nextUpdate(this->crl));
+ this->thisUpdate = openssl_asn1_to_time(X509_CRL_get0_lastUpdate(this->crl));
+ this->nextUpdate = openssl_asn1_to_time(X509_CRL_get0_nextUpdate(this->crl));
return parse_extensions(this);
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ed_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ed_private_key.c
new file mode 100644
index 000000000..b5bc9b868
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ed_private_key.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <openssl/evp.h>
+
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
+
+#include "openssl_ed_private_key.h"
+
+#include <utils/debug.h>
+
+typedef struct private_private_key_t private_private_key_t;
+
+/**
+ * Private data
+ */
+struct private_private_key_t {
+
+ /**
+ * Public interface
+ */
+ private_key_t public;
+
+ /**
+ * Key object
+ */
+ EVP_PKEY *key;
+
+ /**
+ * Key type
+ */
+ key_type_t type;
+
+ /**
+ * TRUE if the key is from an OpenSSL ENGINE and might not be readable
+ */
+ bool engine;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * We can't include asn1.h, declare function prototype directly
+ */
+int asn1_unwrap(chunk_t*, chunk_t*);
+
+/* from ed public key */
+int openssl_ed_key_type(key_type_t type);
+int openssl_ed_keysize(key_type_t type);
+bool openssl_ed_fingerprint(EVP_PKEY *key, cred_encoding_type_t type, chunk_t *fp);
+
+METHOD(private_key_t, sign, bool,
+ private_private_key_t *this, signature_scheme_t scheme,
+ void *params, chunk_t data, chunk_t *signature)
+{
+ EVP_MD_CTX *ctx;
+ bool success = FALSE;
+
+ if ((this->type == KEY_ED25519 && scheme != SIGN_ED25519) ||
+ (this->type == KEY_ED448 && scheme != SIGN_ED448))
+ {
+ DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
+ signature_scheme_names, scheme, key_type_names, this->type);
+ return FALSE;
+ }
+
+ ctx = EVP_MD_CTX_new();
+ if (!ctx ||
+ EVP_DigestSignInit(ctx, NULL, NULL, NULL, this->key) <= 0)
+ {
+ goto error;
+ }
+
+ if (EVP_DigestSign(ctx, NULL, &signature->len, data.ptr, data.len) <= 0)
+ {
+ goto error;
+ }
+
+ *signature = chunk_alloc(signature->len);
+
+ if (EVP_DigestSign(ctx, signature->ptr, &signature->len,
+ data.ptr, data.len) <= 0)
+ {
+ goto error;
+ }
+
+ success = TRUE;
+
+error:
+ EVP_MD_CTX_free(ctx);
+ return success;
+}
+
+METHOD(private_key_t, decrypt, bool,
+ private_private_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1(DBG_LIB, "EdDSA private key decryption not implemented");
+ return FALSE;
+}
+
+METHOD(private_key_t, get_keysize, int,
+ private_private_key_t *this)
+{
+ return openssl_ed_keysize(this->type);
+}
+
+METHOD(private_key_t, get_type, key_type_t,
+ private_private_key_t *this)
+{
+ return this->type;
+}
+
+METHOD(private_key_t, get_public_key, public_key_t*,
+ private_private_key_t *this)
+{
+ public_key_t *public;
+ chunk_t key;
+
+ if (!EVP_PKEY_get_raw_public_key(this->key, NULL, &key.len))
+ {
+ return FALSE;
+ }
+ key = chunk_alloca(key.len);
+ if (!EVP_PKEY_get_raw_public_key(this->key, key.ptr, &key.len))
+ {
+ return FALSE;
+ }
+ public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, this->type,
+ BUILD_EDDSA_PUB, key, BUILD_END);
+ return public;
+}
+
+METHOD(private_key_t, get_fingerprint, bool,
+ private_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *fingerprint)
+{
+ return openssl_ed_fingerprint(this->key, type, fingerprint);
+}
+
+METHOD(private_key_t, get_encoding, bool,
+ private_private_key_t *this, cred_encoding_type_t type, chunk_t *encoding)
+{
+ u_char *p;
+
+ if (this->engine)
+ {
+ return FALSE;
+ }
+
+ switch (type)
+ {
+ case PRIVKEY_ASN1_DER:
+ case PRIVKEY_PEM:
+ {
+ bool success = TRUE;
+
+ *encoding = chunk_alloc(i2d_PrivateKey(this->key, NULL));
+ p = encoding->ptr;
+ i2d_PrivateKey(this->key, &p);
+
+ if (type == PRIVKEY_PEM)
+ {
+ chunk_t asn1_encoding = *encoding;
+
+ success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM,
+ NULL, encoding, CRED_PART_EDDSA_PRIV_ASN1_DER,
+ asn1_encoding, CRED_PART_END);
+ chunk_clear(&asn1_encoding);
+ }
+ return success;
+ }
+ default:
+ return FALSE;
+ }
+}
+
+METHOD(private_key_t, get_ref, private_key_t*,
+ private_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
+METHOD(private_key_t, destroy, void,
+ private_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ lib->encoding->clear_cache(lib->encoding, this->key);
+ EVP_PKEY_free(this->key);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_private_key_t *create_internal(key_type_t type, EVP_PKEY *key)
+{
+ private_private_key_t *this;
+
+ INIT(this,
+ .public = {
+ .get_type = _get_type,
+ .sign = _sign,
+ .decrypt = _decrypt,
+ .get_keysize = _get_keysize,
+ .get_public_key = _get_public_key,
+ .equals = private_key_equals,
+ .belongs_to = private_key_belongs_to,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = private_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .type = type,
+ .key = key,
+ .ref = 1,
+ );
+
+ return this;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *openssl_ed_private_key_create(EVP_PKEY *key, bool engine)
+{
+ private_private_key_t *this;
+ key_type_t type;
+
+ switch (EVP_PKEY_base_id(key))
+ {
+ case EVP_PKEY_X25519:
+ type = KEY_ED25519;
+ break;
+ case EVP_PKEY_X448:
+ type = KEY_ED448;
+ break;
+ default:
+ EVP_PKEY_free(key);
+ return NULL;
+ }
+
+ this = create_internal(type, key);
+ this->engine = engine;
+ return &this->public;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *openssl_ed_private_key_gen(key_type_t type, va_list args)
+{
+ private_private_key_t *this;
+ EVP_PKEY_CTX *ctx;
+ EVP_PKEY *key = NULL;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_KEY_SIZE:
+ /* just ignore the key size */
+ va_arg(args, u_int);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ ctx = EVP_PKEY_CTX_new_id(openssl_ed_key_type(type), NULL);
+ if (!ctx ||
+ EVP_PKEY_keygen_init(ctx) <= 0 ||
+ EVP_PKEY_keygen(ctx, &key) <= 0)
+ {
+ DBG1(DBG_LIB, "generating %N key failed", key_type_names, type);
+ EVP_PKEY_CTX_free(ctx);
+ return NULL;
+ }
+ EVP_PKEY_CTX_free(ctx);
+
+ this = create_internal(type, key);
+ return &this->public;
+}
+
+/*
+ * Described in header
+ */
+private_key_t *openssl_ed_private_key_load(key_type_t type, va_list args)
+{
+ private_private_key_t *this;
+ chunk_t blob = chunk_empty, priv = chunk_empty;
+ EVP_PKEY *key = NULL;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_BLOB_ASN1_DER:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_EDDSA_PRIV_ASN1_DER:
+ priv = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ if (priv.len)
+ {
+ /* unwrap octet string */
+ if (asn1_unwrap(&priv, &priv) == 0x04 && priv.len)
+ {
+ key = EVP_PKEY_new_raw_private_key(openssl_ed_key_type(type), NULL,
+ priv.ptr, priv.len);
+ }
+ }
+ else if (blob.len)
+ {
+ key = d2i_PrivateKey(openssl_ed_key_type(type), NULL,
+ (const u_char**)&blob.ptr, blob.len);
+ }
+ if (!key)
+ {
+ return NULL;
+ }
+ this = create_internal(type, key);
+ return &this->public;
+}
+
+#endif /* OPENSSL_NO_ECDSA */
diff --git a/src/libstrongswan/plugins/openssl/openssl_ed_private_key.h b/src/libstrongswan/plugins/openssl/openssl_ed_private_key.h
new file mode 100644
index 000000000..ce9071348
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ed_private_key.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup openssl_ed_private_key openssl_ed_private_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_ED_PRIVATE_KEY_H_
+#define OPENSSL_ED_PRIVATE_KEY_H_
+
+#include <openssl/evp.h>
+
+#include <credentials/builder.h>
+#include <credentials/keys/private_key.h>
+
+/**
+ * Generate an EdDSA private key using OpenSSL.
+ *
+ * @param type type of the key, must be KEY_ED25519 or KEY_ED448
+ * @param args builder_part_t argument list
+ * @return generated key, NULL on failure
+ */
+private_key_t *openssl_ed_private_key_gen(key_type_t type, va_list args);
+
+/**
+ * Load an EdDSA private key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
+ *
+ * @param type type of the key, must be KEY_ED25519 or KEY_ED448
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+private_key_t *openssl_ed_private_key_load(key_type_t type, va_list args);
+
+/**
+ * Wrap an EVP_PKEY object of type EVP_PKEY_ED25519/448
+ *
+ * @param key EVP_PKEY object (adopted)
+ * @param engine whether the key was loaded via an engine
+ * @return loaded key, NULL on failure
+ */
+private_key_t *openssl_ed_private_key_create(EVP_PKEY *key, bool engine);
+
+#endif /** OPENSSL_ED_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_ed_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ed_public_key.c
new file mode 100644
index 000000000..2daddc57e
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ed_public_key.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <openssl/evp.h>
+
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
+
+#include <openssl/x509.h>
+
+#include "openssl_ed_public_key.h"
+
+#include <utils/debug.h>
+
+typedef struct private_public_key_t private_public_key_t;
+
+/**
+ * Private data
+ */
+struct private_public_key_t {
+
+ /**
+ * Public interface
+ */
+ public_key_t public;
+
+ /**
+ * Key object
+ */
+ EVP_PKEY *key;
+
+ /**
+ * Key type
+ */
+ key_type_t type;
+
+ /**
+ * Reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * Map a key type to an EVP key type
+ */
+int openssl_ed_key_type(key_type_t type)
+{
+ switch (type)
+ {
+ case KEY_ED25519:
+ return EVP_PKEY_ED25519;
+ case KEY_ED448:
+ return EVP_PKEY_ED448;
+ default:
+ return 0;
+ }
+}
+
+/**
+ * Map a key type to a key size
+ */
+int openssl_ed_keysize(key_type_t type)
+{
+ switch (type)
+ {
+ case KEY_ED25519:
+ return 32 * 8;
+ case KEY_ED448:
+ return 57 * 8;
+ default:
+ return 0;
+ }
+}
+
+METHOD(public_key_t, get_type, key_type_t,
+ private_public_key_t *this)
+{
+ return this->type;
+}
+
+METHOD(public_key_t, verify, bool,
+ private_public_key_t *this, signature_scheme_t scheme,
+ void *params, chunk_t data, chunk_t signature)
+{
+ EVP_MD_CTX *ctx;
+
+ if ((this->type == KEY_ED25519 && scheme != SIGN_ED25519) ||
+ (this->type == KEY_ED448 && scheme != SIGN_ED448))
+ {
+ DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
+ signature_scheme_names, scheme, key_type_names, this->type);
+ return FALSE;
+ }
+
+ ctx = EVP_MD_CTX_new();
+ if (!ctx ||
+ EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, this->key) <= 0 ||
+ EVP_DigestVerify(ctx, signature.ptr, signature.len,
+ data.ptr, data.len) <= 0)
+ {
+ EVP_MD_CTX_free(ctx);
+ return FALSE;
+ }
+ EVP_MD_CTX_free(ctx);
+ return TRUE;
+}
+
+METHOD(public_key_t, encrypt, bool,
+ private_public_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1(DBG_LIB, "encryption scheme %N not supported", encryption_scheme_names,
+ scheme);
+ return FALSE;
+}
+
+METHOD(public_key_t, get_keysize, int,
+ private_public_key_t *this)
+{
+ return openssl_ed_keysize(this->type);
+}
+
+/**
+ * Calculate fingerprint from an EdDSA key, also used in ed private key.
+ */
+bool openssl_ed_fingerprint(EVP_PKEY *key, cred_encoding_type_t type,
+ chunk_t *fp)
+{
+ hasher_t *hasher;
+ chunk_t blob;
+ u_char *p;
+
+ if (lib->encoding->get_cache(lib->encoding, type, key, fp))
+ {
+ return TRUE;
+ }
+ switch (type)
+ {
+ case KEYID_PUBKEY_SHA1:
+ if (!EVP_PKEY_get_raw_public_key(key, NULL, &blob.len))
+ {
+ return FALSE;
+ }
+ blob = chunk_alloca(blob.len);
+ if (!EVP_PKEY_get_raw_public_key(key, blob.ptr, &blob.len))
+ {
+ return FALSE;
+ }
+ break;
+ case KEYID_PUBKEY_INFO_SHA1:
+ blob = chunk_alloca(i2d_PUBKEY(key, NULL));
+ p = blob.ptr;
+ i2d_PUBKEY(key, &p);
+ break;
+ default:
+ return FALSE;
+ }
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher || !hasher->allocate_hash(hasher, blob, fp))
+ {
+ DBG1(DBG_LIB, "SHA1 not supported, fingerprinting failed");
+ DESTROY_IF(hasher);
+ return FALSE;
+ }
+ hasher->destroy(hasher);
+ lib->encoding->cache(lib->encoding, type, key, *fp);
+ return TRUE;
+}
+
+METHOD(public_key_t, get_fingerprint, bool,
+ private_public_key_t *this, cred_encoding_type_t type, chunk_t *fingerprint)
+{
+ return openssl_ed_fingerprint(this->key, type, fingerprint);
+}
+
+METHOD(public_key_t, get_encoding, bool,
+ private_public_key_t *this, cred_encoding_type_t type, chunk_t *encoding)
+{
+ bool success = TRUE;
+ u_char *p;
+
+ *encoding = chunk_alloc(i2d_PUBKEY(this->key, NULL));
+ p = encoding->ptr;
+ i2d_PUBKEY(this->key, &p);
+
+ if (type != PUBKEY_SPKI_ASN1_DER)
+ {
+ chunk_t asn1_encoding = *encoding;
+
+ success = lib->encoding->encode(lib->encoding, type,
+ NULL, encoding, CRED_PART_EDDSA_PUB_ASN1_DER,
+ asn1_encoding, CRED_PART_END);
+ chunk_clear(&asn1_encoding);
+ }
+ return success;
+}
+
+METHOD(public_key_t, get_ref, public_key_t*,
+ private_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
+METHOD(public_key_t, destroy, void,
+ private_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ lib->encoding->clear_cache(lib->encoding, this->key);
+ EVP_PKEY_free(this->key);
+ free(this);
+ }
+}
+
+/**
+ * Generic private constructor
+ */
+static private_public_key_t *create_empty(key_type_t type)
+{
+ private_public_key_t *this;
+
+ INIT(this,
+ .public = {
+ .get_type = _get_type,
+ .verify = _verify,
+ .encrypt = _encrypt,
+ .get_keysize = _get_keysize,
+ .equals = public_key_equals,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = public_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .type = type,
+ .ref = 1,
+ );
+
+ return this;
+}
+
+/*
+ * Described in header
+ */
+public_key_t *openssl_ed_public_key_load(key_type_t type, va_list args)
+{
+ private_public_key_t *this;
+ chunk_t blob = chunk_empty, pub = chunk_empty;
+ EVP_PKEY *key = NULL;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_BLOB_ASN1_DER:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_EDDSA_PUB:
+ pub = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ if (pub.len)
+ {
+ key = EVP_PKEY_new_raw_public_key(openssl_ed_key_type(type), NULL,
+ pub.ptr, pub.len);
+ }
+ else if (blob.len)
+ {
+ key = d2i_PUBKEY(NULL, (const u_char**)&blob.ptr, blob.len);
+ if (key && EVP_PKEY_base_id(key) != openssl_ed_key_type(type))
+ {
+ EVP_PKEY_free(key);
+ return NULL;
+ }
+ }
+ if (!key)
+ {
+ return NULL;
+ }
+ this = create_empty(type);
+ this->key = key;
+ return &this->public;
+}
+
+#endif /* OPENSSL_VERSION_NUMBER */
diff --git a/src/libstrongswan/plugins/openssl/openssl_ed_public_key.h b/src/libstrongswan/plugins/openssl/openssl_ed_public_key.h
new file mode 100644
index 000000000..c4e1ba3ed
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ed_public_key.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup openssl_ed_public_key openssl_ed_public_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_ED_PUBLIC_KEY_H_
+#define OPENSSL_ED_PUBLIC_KEY_H_
+
+#include <credentials/builder.h>
+#include <credentials/keys/public_key.h>
+
+/**
+ * Load an EdDSA public key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
+ *
+ * @param type type of the key, must be KEY_ED25519 or KEY_ED448
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+public_key_t *openssl_ed_public_key_load(key_type_t type, va_list args);
+
+#endif /** OPENSSL_ED_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index 8b0a7c5c7..cbeb6c3b7 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2016 Tobias Brunner
+ * Copyright (C) 2008-2018 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
*
@@ -47,6 +47,9 @@
#include "openssl_rng.h"
#include "openssl_hmac.h"
#include "openssl_gcm.h"
+#include "openssl_x_diffie_hellman.h"
+#include "openssl_ed_public_key.h"
+#include "openssl_ed_private_key.h"
#ifndef FIPS_MODE
#define FIPS_MODE 0
@@ -307,6 +310,11 @@ static private_key_t *openssl_private_key_load(key_type_t type, va_list args)
case EVP_PKEY_EC:
return openssl_ec_private_key_create(key, FALSE);
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
+ case EVP_PKEY_ED25519:
+ case EVP_PKEY_ED448:
+ return openssl_ed_private_key_create(key, FALSE);
+#endif /* OPENSSL_VERSION_NUMBER */
default:
EVP_PKEY_free(key);
break;
@@ -370,7 +378,7 @@ static private_key_t *openssl_private_key_connect(key_type_t type,
#ifndef OPENSSL_NO_ENGINE
char *engine_id = NULL;
char keyname[BUF_LEN];
- chunk_t keyid = chunk_empty;;
+ chunk_t keyid = chunk_empty;
EVP_PKEY *key;
ENGINE *engine;
int slot = -1;
@@ -395,7 +403,7 @@ static private_key_t *openssl_private_key_connect(key_type_t type,
}
break;
}
- if (!keyid.len || keyid.len > 40)
+ if (!keyid.len)
{
return NULL;
}
@@ -405,7 +413,7 @@ static private_key_t *openssl_private_key_connect(key_type_t type,
{
snprintf(keyname, sizeof(keyname), "%d:", slot);
}
- if (sizeof(keyname) - strlen(keyname) <= keyid.len * 4 / 3 + 1)
+ if (sizeof(keyname) - strlen(keyname) <= keyid.len * 2 + 1)
{
return NULL;
}
@@ -428,21 +436,21 @@ static private_key_t *openssl_private_key_connect(key_type_t type,
ENGINE_free(engine);
return NULL;
}
+ ENGINE_free(engine);
if (!login(engine, keyid))
{
DBG1(DBG_LIB, "login to engine '%s' failed", engine_id);
- ENGINE_free(engine);
+ ENGINE_finish(engine);
return NULL;
}
key = ENGINE_load_private_key(engine, keyname, NULL, NULL);
+ ENGINE_finish(engine);
if (!key)
{
DBG1(DBG_LIB, "failed to load private key with ID '%s' from "
"engine '%s'", keyname, engine_id);
- ENGINE_free(engine);
return NULL;
}
- ENGINE_free(engine);
switch (EVP_PKEY_base_id(key))
{
@@ -454,6 +462,11 @@ static private_key_t *openssl_private_key_connect(key_type_t type,
case EVP_PKEY_EC:
return openssl_ec_private_key_create(key, TRUE);
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
+ case EVP_PKEY_ED25519:
+ case EVP_PKEY_ED448:
+ return openssl_ed_private_key_create(key, TRUE);
+#endif /* OPENSSL_VERSION_NUMBER */
default:
EVP_PKEY_free(key);
break;
@@ -594,7 +607,7 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(DH, ECP_384_BP),
PLUGIN_PROVIDE(DH, ECP_512_BP),
PLUGIN_PROVIDE(DH, ECP_224_BP),
-#endif
+#endif /* OPENSSL_NO_ECDH */
#ifndef OPENSSL_NO_DH
/* MODP DH groups */
PLUGIN_REGISTER(DH, openssl_diffie_hellman_create),
@@ -699,6 +712,30 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521),
#endif
#endif /* OPENSSL_NO_ECDSA */
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
+ PLUGIN_REGISTER(DH, openssl_x_diffie_hellman_create),
+ /* available since 1.1.0a, but we require 1.1.1 features */
+ PLUGIN_PROVIDE(DH, CURVE_25519),
+ /* available since 1.1.1 */
+ PLUGIN_PROVIDE(DH, CURVE_448),
+ /* EdDSA private/public key loading */
+ PLUGIN_REGISTER(PUBKEY, openssl_ed_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ED25519),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ED448),
+ PLUGIN_REGISTER(PRIVKEY, openssl_ed_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ED448),
+ PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ed_private_key_gen, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED25519),
+ PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED448),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED25519),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED448),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED25519),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED448),
+ /* register a pro forma identity hasher, never instantiated */
+ PLUGIN_REGISTER(HASHER, return_null),
+ PLUGIN_PROVIDE(HASHER, HASH_IDENTITY),
+#endif /* OPENSSL_VERSION_NUMBER && !OPENSSL_NO_EC */
/* generic key loader */
PLUGIN_REGISTER(PRIVKEY, openssl_private_key_load, TRUE),
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
diff --git a/src/libstrongswan/plugins/openssl/openssl_rng.c b/src/libstrongswan/plugins/openssl/openssl_rng.c
index a25b6b4b6..d3993749f 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rng.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rng.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2012-2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2012 Aleksandr Grinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,7 +27,6 @@
#include <utils/debug.h>
#include <openssl/rand.h>
-#include <openssl/err.h>
#include "openssl_rng.h"
@@ -49,6 +51,13 @@ struct private_openssl_rng_t {
METHOD(rng_t, get_bytes, bool,
private_openssl_rng_t *this, size_t bytes, uint8_t *buffer)
{
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
+ if (this->quality > RNG_WEAK)
+ { /* use a separate DRBG for data we want to keep private, compared
+ * to e.g. nonces */
+ return RAND_priv_bytes((char*)buffer, bytes) == 1;
+ }
+#endif
return RAND_bytes((char*)buffer, bytes) == 1;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
index 401a51a0b..8a9fdfe25 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -103,13 +103,8 @@ static bool build_signature(private_openssl_rsa_private_key_t *this,
if (pss)
{
const EVP_MD *mgf1md = openssl_get_md(pss->mgf1_hash);
- int slen = EVP_MD_size(md);
- if (pss->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
- {
- slen = pss->salt_len;
- }
if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
- EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, slen) <= 0 ||
+ EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, pss->salt_len) <= 0 ||
EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md) <= 0)
{
goto error;
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
index 20bf30ae9..38b4eda35 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
@@ -95,13 +95,8 @@ static bool verify_signature(private_openssl_rsa_public_key_t *this,
if (pss)
{
const EVP_MD *mgf1md = openssl_get_md(pss->mgf1_hash);
- int slen = EVP_MD_size(md);
- if (pss->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
- {
- slen = pss->salt_len;
- }
if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
- EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, slen) <= 0 ||
+ EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, pss->salt_len) <= 0 ||
EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md) <= 0)
{
goto error;
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c
index b7f969f73..f99dcd6b1 100644
--- a/src/libstrongswan/plugins/openssl/openssl_util.c
+++ b/src/libstrongswan/plugins/openssl/openssl_util.c
@@ -26,6 +26,7 @@
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define OBJ_get0_data(o) ((o)->data)
#define OBJ_length(o) ((o)->length)
+#define ASN1_STRING_get0_data(a) ASN1_STRING_data((ASN1_STRING*)a)
#endif
/**
@@ -164,11 +165,12 @@ chunk_t openssl_asn1_obj2chunk(ASN1_OBJECT *asn1)
/**
* Described in header.
*/
-chunk_t openssl_asn1_str2chunk(ASN1_STRING *asn1)
+chunk_t openssl_asn1_str2chunk(const ASN1_STRING *asn1)
{
if (asn1)
{
- return chunk_create(ASN1_STRING_data(asn1), ASN1_STRING_length(asn1));
+ return chunk_create((u_char*)ASN1_STRING_get0_data(asn1),
+ ASN1_STRING_length(asn1));
}
return chunk_empty;
}
@@ -212,7 +214,7 @@ int openssl_asn1_known_oid(ASN1_OBJECT *obj)
/**
* Described in header.
*/
-time_t openssl_asn1_to_time(ASN1_TIME *time)
+time_t openssl_asn1_to_time(const ASN1_TIME *time)
{
chunk_t chunk;
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.h b/src/libstrongswan/plugins/openssl/openssl_util.h
index 80e557fa8..4afe76bf2 100644
--- a/src/libstrongswan/plugins/openssl/openssl_util.h
+++ b/src/libstrongswan/plugins/openssl/openssl_util.h
@@ -109,7 +109,7 @@ chunk_t openssl_asn1_obj2chunk(ASN1_OBJECT *asn1);
* @param asn1 asn1 string to convert
* @return chunk, pointing into asn1 string
*/
-chunk_t openssl_asn1_str2chunk(ASN1_STRING *asn1);
+chunk_t openssl_asn1_str2chunk(const ASN1_STRING *asn1);
/**
* Convert an openssl X509_NAME to a identification_t of type ID_DER_ASN1_DN.
@@ -133,7 +133,7 @@ int openssl_asn1_known_oid(ASN1_OBJECT *obj);
* @param time openssl ASN1_TIME
* @returns time_t, 0 on error
*/
-time_t openssl_asn1_to_time(ASN1_TIME *time);
+time_t openssl_asn1_to_time(const ASN1_TIME *time);
/**
* Compatibility macros
diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c
index fae2d678f..fe21b0221 100644
--- a/src/libstrongswan/plugins/openssl/openssl_x509.c
+++ b/src/libstrongswan/plugins/openssl/openssl_x509.c
@@ -389,7 +389,11 @@ METHOD(certificate_t, issued_by, bool,
public_key_t *key;
bool valid;
x509_t *x509 = (x509_t*)issuer;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ const ASN1_BIT_STRING *sig;
+#else
ASN1_BIT_STRING *sig;
+#endif
chunk_t tbs;
if (&this->public.x509.interface == issuer)
@@ -993,7 +997,7 @@ static bool parse_subjectKeyIdentifier_ext(private_openssl_x509_t *this,
*/
static bool parse_extensions(private_openssl_x509_t *this)
{
- STACK_OF(X509_EXTENSION) *extensions;
+ const STACK_OF(X509_EXTENSION) *extensions;
int i, num;
/* unless we see a keyUsage extension we are compliant with RFC 4945 */
@@ -1077,7 +1081,11 @@ static bool parse_certificate(private_openssl_x509_t *this)
hasher_t *hasher;
chunk_t chunk, sig_scheme, sig_scheme_tbs;
ASN1_OBJECT *oid;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ const X509_ALGOR *alg;
+#else
X509_ALGOR *alg;
+#endif
this->x509 = d2i_X509(NULL, &ptr, this->encoding.len);
if (!this->x509)
@@ -1135,9 +1143,9 @@ static bool parse_certificate(private_openssl_x509_t *this)
/* while X509_ALGOR_cmp() is declared in the headers of older OpenSSL
* versions, at least on Ubuntu 14.04 it is not actually defined */
X509_get0_signature(NULL, &alg, this->x509);
- sig_scheme = openssl_i2chunk(X509_ALGOR, alg);
+ sig_scheme = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
alg = X509_get0_tbs_sigalg(this->x509);
- sig_scheme_tbs = openssl_i2chunk(X509_ALGOR, alg);
+ sig_scheme_tbs = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
if (!chunk_equals(sig_scheme, sig_scheme_tbs))
{
free(sig_scheme_tbs.ptr);
diff --git a/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.c
new file mode 100644
index 000000000..37943f5bf
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <openssl/evp.h>
+
+/* basic support for X25519 was added with 1.1.0a, but we require features (e.g.
+ * to load the keys) that were only added with 1.1.1 */
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_ECDH)
+
+#include "openssl_x_diffie_hellman.h"
+
+#include <utils/debug.h>
+
+typedef struct private_diffie_hellman_t private_diffie_hellman_t;
+
+/**
+ * Private data
+ */
+struct private_diffie_hellman_t {
+ /**
+ * Public interface.
+ */
+ diffie_hellman_t public;
+
+ /**
+ * Diffie Hellman group number.
+ */
+ diffie_hellman_group_t group;
+
+ /**
+ * Private (public) key
+ */
+ EVP_PKEY *key;
+
+ /**
+ * Shared secret
+ */
+ chunk_t shared_secret;
+
+ /**
+ * True if shared secret is computed
+ */
+ bool computed;
+};
+
+/**
+ * Map a DH group to a key type
+ */
+static int map_key_type(diffie_hellman_group_t group)
+{
+ switch (group)
+ {
+ case CURVE_25519:
+ return EVP_PKEY_X25519;
+ case CURVE_448:
+ return EVP_PKEY_X448;
+ default:
+ return 0;
+ }
+}
+
+/**
+ * Compute the shared secret
+ */
+static bool compute_shared_key(private_diffie_hellman_t *this, EVP_PKEY *pub,
+ chunk_t *shared_secret)
+{
+ EVP_PKEY_CTX *ctx;
+ bool success = FALSE;
+
+ ctx = EVP_PKEY_CTX_new(this->key, NULL);
+ if (!ctx)
+ {
+ return FALSE;
+ }
+
+ if (EVP_PKEY_derive_init(ctx) <= 0)
+ {
+ goto error;
+ }
+
+ if (EVP_PKEY_derive_set_peer(ctx, pub) <= 0)
+ {
+ goto error;
+ }
+
+ if (EVP_PKEY_derive(ctx, NULL, &shared_secret->len) <= 0)
+ {
+ goto error;
+ }
+
+ *shared_secret = chunk_alloc(shared_secret->len);
+
+ if (EVP_PKEY_derive(ctx, shared_secret->ptr, &shared_secret->len) <= 0)
+ {
+ goto error;
+ }
+
+ success = TRUE;
+
+error:
+ EVP_PKEY_CTX_free(ctx);
+ return success;
+}
+
+METHOD(diffie_hellman_t, set_other_public_value, bool,
+ private_diffie_hellman_t *this, chunk_t value)
+{
+ EVP_PKEY *pub;
+
+ if (!diffie_hellman_verify_value(this->group, value))
+ {
+ return FALSE;
+ }
+
+ pub = EVP_PKEY_new_raw_public_key(map_key_type(this->group), NULL,
+ value.ptr, value.len);
+ if (!pub)
+ {
+ DBG1(DBG_LIB, "%N public value is malformed",
+ diffie_hellman_group_names, this->group);
+ return FALSE;
+ }
+
+ chunk_clear(&this->shared_secret);
+
+ if (!compute_shared_key(this, pub, &this->shared_secret))
+ {
+ DBG1(DBG_LIB, "%N shared secret computation failed",
+ diffie_hellman_group_names, this->group);
+ EVP_PKEY_free(pub);
+ return FALSE;
+ }
+ this->computed = TRUE;
+ EVP_PKEY_free(pub);
+ return TRUE;
+}
+
+METHOD(diffie_hellman_t, get_my_public_value, bool,
+ private_diffie_hellman_t *this, chunk_t *value)
+{
+ size_t len;
+
+ if (!EVP_PKEY_get_raw_public_key(this->key, NULL, &len))
+ {
+ return FALSE;
+ }
+
+ *value = chunk_alloc(len);
+
+ if (!EVP_PKEY_get_raw_public_key(this->key, value->ptr, &value->len))
+ {
+ chunk_free(value);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(diffie_hellman_t, set_private_value, bool,
+ private_diffie_hellman_t *this, chunk_t value)
+{
+ EVP_PKEY_free(this->key);
+ this->key = EVP_PKEY_new_raw_private_key(map_key_type(this->group), NULL,
+ value.ptr, value.len);
+ if (!this->key)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(diffie_hellman_t, get_shared_secret, bool,
+ private_diffie_hellman_t *this, chunk_t *secret)
+{
+ if (!this->computed)
+ {
+ return FALSE;
+ }
+ *secret = chunk_clone(this->shared_secret);
+ return TRUE;
+}
+
+METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
+ private_diffie_hellman_t *this)
+{
+ return this->group;
+}
+
+METHOD(diffie_hellman_t, destroy, void,
+ private_diffie_hellman_t *this)
+{
+ EVP_PKEY_free(this->key);
+ chunk_clear(&this->shared_secret);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+diffie_hellman_t *openssl_x_diffie_hellman_create(diffie_hellman_group_t group)
+{
+ private_diffie_hellman_t *this;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *key = NULL;
+
+ switch (group)
+ {
+ case CURVE_25519:
+ ctx = EVP_PKEY_CTX_new_id(NID_X25519, NULL);
+ break;
+ case CURVE_448:
+ ctx = EVP_PKEY_CTX_new_id(NID_X448, NULL);
+ break;
+ default:
+ break;
+ }
+
+ if (!ctx ||
+ EVP_PKEY_keygen_init(ctx) <= 0 ||
+ EVP_PKEY_keygen(ctx, &key) <= 0)
+ {
+ DBG1(DBG_LIB, "generating key for %N failed",
+ diffie_hellman_group_names, group);
+ EVP_PKEY_CTX_free(ctx);
+ return NULL;
+ }
+ EVP_PKEY_CTX_free(ctx);
+
+ INIT(this,
+ .public = {
+ .get_shared_secret = _get_shared_secret,
+ .set_other_public_value = _set_other_public_value,
+ .get_my_public_value = _get_my_public_value,
+ .set_private_value = _set_private_value,
+ .get_dh_group = _get_dh_group,
+ .destroy = _destroy,
+ },
+ .group = group,
+ .key = key,
+ );
+ return &this->public;
+}
+
+#endif /* OPENSSL_NO_ECDH */
diff --git a/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.h
new file mode 100644
index 000000000..e28f38d15
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * Implementation of the X25519/X448 Diffie-Hellman algorithm using OpenSSL.
+ *
+ * @defgroup openssl_x_diffie_hellman openssl_x_diffie_hellman
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_X_DIFFIE_HELLMAN_H_
+#define OPENSSL_X_DIFFIE_HELLMAN_H_
+
+#include <library.h>
+
+/**
+ * Creates a new diffie_hellman_t object.
+ *
+ * @param group Diffie Hellman group number to use
+ * @return object, NULL if not supported
+ */
+diffie_hellman_t *openssl_x_diffie_hellman_create(diffie_hellman_group_t group);
+
+#endif /** OPENSSL_X_DIFFIE_HELLMAN_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/sshkey/sshkey_builder.c b/src/libstrongswan/plugins/sshkey/sshkey_builder.c
index eab6559b3..934514249 100644
--- a/src/libstrongswan/plugins/sshkey/sshkey_builder.c
+++ b/src/libstrongswan/plugins/sshkey/sshkey_builder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 Tobias Brunner
+ * Copyright (C) 2013-2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -89,6 +89,34 @@ static sshkey_public_key_t *parse_public_key(chunk_t blob)
return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
}
+ else if (chunk_equals(format, chunk_from_str("ssh-ed25519")))
+ {
+ chunk_t blob;
+
+ if (!reader->read_data32(reader, &blob))
+ {
+ DBG1(DBG_LIB, "invalid Ed25519 key in SSH key");
+ reader->destroy(reader);
+ return NULL;
+ }
+ reader->destroy(reader);
+ return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED25519,
+ BUILD_EDDSA_PUB, blob, BUILD_END);
+ }
+ else if (chunk_equals(format, chunk_from_str("ssh-ed448")))
+ {
+ chunk_t blob;
+
+ if (!reader->read_data32(reader, &blob))
+ {
+ DBG1(DBG_LIB, "invalid Ed448 key in SSH key");
+ reader->destroy(reader);
+ return NULL;
+ }
+ reader->destroy(reader);
+ return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
+ BUILD_EDDSA_PUB, blob, BUILD_END);
+ }
else if (format.len > strlen(ECDSA_PREFIX) &&
strpfx(format.ptr, ECDSA_PREFIX))
{
@@ -140,8 +168,9 @@ static sshkey_public_key_t *load_from_stream(FILE *file)
char line[1024], *token;
while (!public && fgets(line, sizeof(line), file))
- { /* the format is: ssh-rsa|ecdsa-... <key(base64)> <identifier> */
- if (!strpfx(line, "ssh-rsa") && !strpfx(line, ECDSA_PREFIX))
+ { /* the format is: ssh-<key-type> <key(base64)> <identifier> */
+ if (!strpfx(line, "ssh-rsa") && !strpfx(line, ECDSA_PREFIX) &&
+ !strpfx(line, "ssh-ed25519") && !strpfx(line, "ssh-ed448"))
{
continue;
}
diff --git a/src/libstrongswan/plugins/sshkey/sshkey_encoder.c b/src/libstrongswan/plugins/sshkey/sshkey_encoder.c
index 9f5f8bd1f..ed35fc010 100644
--- a/src/libstrongswan/plugins/sshkey/sshkey_encoder.c
+++ b/src/libstrongswan/plugins/sshkey/sshkey_encoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2013-2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -72,6 +72,42 @@ static bool build_public_key(chunk_t *encoding, va_list args)
writer->destroy(writer);
return TRUE;
}
+ else if (cred_encoding_args(args, CRED_PART_EDDSA_PUB_ASN1_DER, &n,
+ CRED_PART_END))
+ {
+ chunk_t alg;
+ char *prefix;
+ int oid;
+
+ /* parse subjectPublicKeyInfo */
+ if (asn1_unwrap(&n, &n) != ASN1_SEQUENCE)
+ {
+ return FALSE;
+ }
+ oid = asn1_parse_algorithmIdentifier(n, 1, NULL);
+ switch (oid)
+ {
+ case OID_ED25519:
+ prefix = "ssh-ed25519";
+ break;
+ case OID_ED448:
+ prefix = "ssh-ed448";
+ break;
+ default:
+ return FALSE;
+ }
+ if (asn1_unwrap(&n, &alg) != ASN1_SEQUENCE ||
+ asn1_unwrap(&n, &n) != ASN1_BIT_STRING || !n.len)
+ {
+ return FALSE;
+ }
+ writer = bio_writer_create(0);
+ writer->write_data32(writer, chunk_from_str(prefix));
+ writer->write_data32(writer, chunk_skip(n, 1));
+ *encoding = chunk_to_base64(writer->get_buf(writer), NULL);
+ writer->destroy(writer);
+ return TRUE;
+ }
else if (cred_encoding_args(args, CRED_PART_ECDSA_PUB_ASN1_DER, &n,
CRED_PART_END))
{
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.am b/src/libstrongswan/plugins/test_vectors/Makefile.am
index c4d9f2fc5..3d34cf7c9 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.am
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.am
@@ -49,6 +49,7 @@ libstrongswan_test_vectors_la_SOURCES = \
test_vectors/ecp.c \
test_vectors/ecpbp.c \
test_vectors/curve25519.c \
+ test_vectors/curve448.c \
test_vectors/rng.c
libstrongswan_test_vectors_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in
index 7f6c319c6..ed3ae0f40 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.in
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.in
@@ -156,7 +156,8 @@ am_libstrongswan_test_vectors_la_OBJECTS = test_vectors_plugin.lo \
test_vectors/sha3_shake.lo test_vectors/fips_prf.lo \
test_vectors/modp.lo test_vectors/modpsub.lo \
test_vectors/ecp.lo test_vectors/ecpbp.lo \
- test_vectors/curve25519.lo test_vectors/rng.lo
+ test_vectors/curve25519.lo test_vectors/curve448.lo \
+ test_vectors/rng.lo
libstrongswan_test_vectors_la_OBJECTS = \
$(am_libstrongswan_test_vectors_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -518,6 +519,7 @@ libstrongswan_test_vectors_la_SOURCES = \
test_vectors/ecp.c \
test_vectors/ecpbp.c \
test_vectors/curve25519.c \
+ test_vectors/curve448.c \
test_vectors/rng.c
libstrongswan_test_vectors_la_LDFLAGS = -module -avoid-version
@@ -680,6 +682,8 @@ test_vectors/ecpbp.lo: test_vectors/$(am__dirstamp) \
test_vectors/$(DEPDIR)/$(am__dirstamp)
test_vectors/curve25519.lo: test_vectors/$(am__dirstamp) \
test_vectors/$(DEPDIR)/$(am__dirstamp)
+test_vectors/curve448.lo: test_vectors/$(am__dirstamp) \
+ test_vectors/$(DEPDIR)/$(am__dirstamp)
test_vectors/rng.lo: test_vectors/$(am__dirstamp) \
test_vectors/$(DEPDIR)/$(am__dirstamp)
@@ -710,6 +714,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/chacha20_xof.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/chacha20poly1305.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/curve25519.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/curve448.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/des.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/ecp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/ecpbp.Plo@am__quote@
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors.h b/src/libstrongswan/plugins/test_vectors/test_vectors.h
index 7ab965a82..7c8ac0c6e 100644
--- a/src/libstrongswan/plugins/test_vectors/test_vectors.h
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors.h
@@ -116,6 +116,7 @@ TEST_VECTOR_AEAD(aes_gcm23)
TEST_VECTOR_AEAD(chacha20poly1305_1)
TEST_VECTOR_AEAD(chacha20poly1305_2)
TEST_VECTOR_AEAD(chacha20poly1305_3)
+TEST_VECTOR_AEAD(chacha20poly1305_4)
TEST_VECTOR_SIGNER(aes_xcbc_s1)
TEST_VECTOR_SIGNER(aes_xcbc_s2)
@@ -305,3 +306,4 @@ TEST_VECTOR_DH(ecp384bp)
TEST_VECTOR_DH(ecp512bp)
TEST_VECTOR_DH(curve25519_1)
TEST_VECTOR_DH(curve25519_2)
+TEST_VECTOR_DH(curve448_1)
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/chacha20poly1305.c b/src/libstrongswan/plugins/test_vectors/test_vectors/chacha20poly1305.c
index 21726cbbb..dcbfe5ca3 100644
--- a/src/libstrongswan/plugins/test_vectors/test_vectors/chacha20poly1305.c
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/chacha20poly1305.c
@@ -16,10 +16,40 @@
#include <crypto/crypto_tester.h>
/**
- * From draft-irtf-cfrg-chacha20-poly1305
+ * From RFC 7539
*/
aead_test_vector_t chacha20poly1305_1 = {
.alg = ENCR_CHACHA20_POLY1305, .key_size = 32, .salt_size = 4,
+ .len = 114, .alen = 12,
+ .key = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\x07\x00\x00\x00",
+ .iv = "\x40\x41\x42\x43\x44\x45\x46\x47",
+ .adata = "\x50\x51\x52\x53\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7",
+ .plain = "\x4c\x61\x64\x69\x65\x73\x20\x61\x6e\x64\x20\x47\x65\x6e\x74\x6c"
+ "\x65\x6d\x65\x6e\x20\x6f\x66\x20\x74\x68\x65\x20\x63\x6c\x61\x73"
+ "\x73\x20\x6f\x66\x20\x27\x39\x39\x3a\x20\x49\x66\x20\x49\x20\x63"
+ "\x6f\x75\x6c\x64\x20\x6f\x66\x66\x65\x72\x20\x79\x6f\x75\x20\x6f"
+ "\x6e\x6c\x79\x20\x6f\x6e\x65\x20\x74\x69\x70\x20\x66\x6f\x72\x20"
+ "\x74\x68\x65\x20\x66\x75\x74\x75\x72\x65\x2c\x20\x73\x75\x6e\x73"
+ "\x63\x72\x65\x65\x6e\x20\x77\x6f\x75\x6c\x64\x20\x62\x65\x20\x69"
+ "\x74\x2e",
+ .cipher = "\xd3\x1a\x8d\x34\x64\x8e\x60\xdb\x7b\x86\xaf\xbc\x53\xef\x7e\xc2"
+ "\xa4\xad\xed\x51\x29\x6e\x08\xfe\xa9\xe2\xb5\xa7\x36\xee\x62\xd6"
+ "\x3d\xbe\xa4\x5e\x8c\xa9\x67\x12\x82\xfa\xfb\x69\xda\x92\x72\x8b"
+ "\x1a\x71\xde\x0a\x9e\x06\x0b\x29\x05\xd6\xa5\xb6\x7e\xcd\x3b\x36"
+ "\x92\xdd\xbd\x7f\x2d\x77\x8b\x8c\x98\x03\xae\xe3\x28\x09\x1b\x58"
+ "\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc"
+ "\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b"
+ "\x61\x16\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60"
+ "\x06\x91",
+};
+
+/**
+ * Additional test vector from RFC 7539
+ */
+aead_test_vector_t chacha20poly1305_2 = {
+ .alg = ENCR_CHACHA20_POLY1305, .key_size = 32, .salt_size = 4,
.len = 265, .alen = 12,
.key = "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0"
"\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0"
@@ -64,9 +94,9 @@ aead_test_vector_t chacha20poly1305_1 = {
};
/**
- * ESP example from draft-ietf-ipsecme-chacha20-poly1305-06
+ * ESP example from RFC 7634
*/
-aead_test_vector_t chacha20poly1305_2 = {
+aead_test_vector_t chacha20poly1305_3 = {
.alg = ENCR_CHACHA20_POLY1305, .key_size = 32, .salt_size = 4,
.len = 88, .alen = 8,
.key = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
@@ -90,9 +120,9 @@ aead_test_vector_t chacha20poly1305_2 = {
};
/**
- * IKEv2 example from draft-ietf-ipsecme-chacha20-poly1305-06
+ * IKEv2 example from RFC 7634
*/
-aead_test_vector_t chacha20poly1305_3 = {
+aead_test_vector_t chacha20poly1305_4 = {
.alg = ENCR_CHACHA20_POLY1305, .key_size = 32, .salt_size = 4,
.len = 13, .alen = 32,
.key = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/curve25519.c b/src/libstrongswan/plugins/test_vectors/test_vectors/curve25519.c
index 676fcfc5a..23c024a37 100644
--- a/src/libstrongswan/plugins/test_vectors/test_vectors/curve25519.c
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/curve25519.c
@@ -16,7 +16,7 @@
#include <crypto/crypto_tester.h>
/**
- * From RFC 8037
+ * From RFC 7748
*/
dh_test_vector_t curve25519_1 = {
.group = CURVE_25519, .priv_len = 32, .pub_len = 32, .shared_len = 32,
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/curve448.c b/src/libstrongswan/plugins/test_vectors/test_vectors/curve448.c
new file mode 100644
index 000000000..fccbb808a
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/curve448.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <crypto/crypto_tester.h>
+
+/**
+ * From RFC 7748
+ */
+dh_test_vector_t curve448_1 = {
+ .group = CURVE_448, .priv_len = 56, .pub_len = 56, .shared_len = 56,
+ .priv_a = "\x9a\x8f\x49\x25\xd1\x51\x9f\x57\x75\xcf\x46\xb0\x4b\x58\x00\xd4"
+ "\xee\x9e\xe8\xba\xe8\xbc\x55\x65\xd4\x98\xc2\x8d\xd9\xc9\xba\xf5"
+ "\x74\xa9\x41\x97\x44\x89\x73\x91\x00\x63\x82\xa6\xf1\x27\xab\x1d"
+ "\x9a\xc2\xd8\xc0\xa5\x98\x72\x6b",
+ .priv_b = "\x1c\x30\x6a\x7a\xc2\xa0\xe2\xe0\x99\x0b\x29\x44\x70\xcb\xa3\x39"
+ "\xe6\x45\x37\x72\xb0\x75\x81\x1d\x8f\xad\x0d\x1d\x69\x27\xc1\x20"
+ "\xbb\x5e\xe8\x97\x2b\x0d\x3e\x21\x37\x4c\x9c\x92\x1b\x09\xd1\xb0"
+ "\x36\x6f\x10\xb6\x51\x73\x99\x2d",
+ .pub_a = "\x9b\x08\xf7\xcc\x31\xb7\xe3\xe6\x7d\x22\xd5\xae\xa1\x21\x07\x4a"
+ "\x27\x3b\xd2\xb8\x3d\xe0\x9c\x63\xfa\xa7\x3d\x2c\x22\xc5\xd9\xbb"
+ "\xc8\x36\x64\x72\x41\xd9\x53\xd4\x0c\x5b\x12\xda\x88\x12\x0d\x53"
+ "\x17\x7f\x80\xe5\x32\xc4\x1f\xa0",
+ .pub_b = "\x3e\xb7\xa8\x29\xb0\xcd\x20\xf5\xbc\xfc\x0b\x59\x9b\x6f\xec\xcf"
+ "\x6d\xa4\x62\x71\x07\xbd\xb0\xd4\xf3\x45\xb4\x30\x27\xd8\xb9\x72"
+ "\xfc\x3e\x34\xfb\x42\x32\xa1\x3c\xa7\x06\xdc\xb5\x7a\xec\x3d\xae"
+ "\x07\xbd\xc1\xc6\x7b\xf3\x36\x09",
+ .shared = "\x07\xff\xf4\x18\x1a\xc6\xcc\x95\xec\x1c\x16\xa9\x4a\x0f\x74\xd1"
+ "\x2d\xa2\x32\xce\x40\xa7\x75\x52\x28\x1d\x28\x2b\xb6\x0c\x0b\x56"
+ "\xfd\x24\x64\xc3\x35\x54\x39\x36\x52\x1c\x24\x40\x30\x85\xd5\x9a"
+ "\x44\x9a\x50\x37\x51\x4a\x87\x9d",
+};
diff --git a/src/libstrongswan/settings/settings_lexer.c b/src/libstrongswan/settings/settings_lexer.c
index c29dfa57b..a88a58f0e 100644
--- a/src/libstrongswan/settings/settings_lexer.c
+++ b/src/libstrongswan/settings/settings_lexer.c
@@ -7,7 +7,6 @@
/* A lexical scanner generated by flex */
/* %not-for-header */
-
/* %if-c-only */
/* %if-not-reentrant */
/* %endif */
@@ -17,7 +16,7 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 0
+#define YY_FLEX_SUBMINOR_VERSION 4
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -26,9 +25,230 @@
/* %endif */
/* %if-c-only */
-
+#ifdef yy_create_buffer
+#define settings_parser__create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer settings_parser__create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define settings_parser__delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer settings_parser__delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define settings_parser__scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer settings_parser__scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define settings_parser__scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string settings_parser__scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define settings_parser__scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes settings_parser__scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define settings_parser__init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer settings_parser__init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define settings_parser__flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer settings_parser__flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define settings_parser__load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state settings_parser__load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define settings_parser__switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer settings_parser__switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define settings_parser_push_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state settings_parser_push_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define settings_parser_pop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state settings_parser_pop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define settings_parser_ensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack settings_parser_ensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define settings_parser_lex_ALREADY_DEFINED
+#else
+#define yylex settings_parser_lex
+#endif
+
+#ifdef yyrestart
+#define settings_parser_restart_ALREADY_DEFINED
+#else
+#define yyrestart settings_parser_restart
+#endif
+
+#ifdef yylex_init
+#define settings_parser_lex_init_ALREADY_DEFINED
+#else
+#define yylex_init settings_parser_lex_init
+#endif
+
+#ifdef yylex_init_extra
+#define settings_parser_lex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra settings_parser_lex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define settings_parser_lex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy settings_parser_lex_destroy
+#endif
+
+#ifdef yyget_debug
+#define settings_parser_get_debug_ALREADY_DEFINED
+#else
+#define yyget_debug settings_parser_get_debug
+#endif
+
+#ifdef yyset_debug
+#define settings_parser_set_debug_ALREADY_DEFINED
+#else
+#define yyset_debug settings_parser_set_debug
+#endif
+
+#ifdef yyget_extra
+#define settings_parser_get_extra_ALREADY_DEFINED
+#else
+#define yyget_extra settings_parser_get_extra
+#endif
+
+#ifdef yyset_extra
+#define settings_parser_set_extra_ALREADY_DEFINED
+#else
+#define yyset_extra settings_parser_set_extra
+#endif
+
+#ifdef yyget_in
+#define settings_parser_get_in_ALREADY_DEFINED
+#else
+#define yyget_in settings_parser_get_in
+#endif
+
+#ifdef yyset_in
+#define settings_parser_set_in_ALREADY_DEFINED
+#else
+#define yyset_in settings_parser_set_in
+#endif
+
+#ifdef yyget_out
+#define settings_parser_get_out_ALREADY_DEFINED
+#else
+#define yyget_out settings_parser_get_out
+#endif
+
+#ifdef yyset_out
+#define settings_parser_set_out_ALREADY_DEFINED
+#else
+#define yyset_out settings_parser_set_out
+#endif
+
+#ifdef yyget_leng
+#define settings_parser_get_leng_ALREADY_DEFINED
+#else
+#define yyget_leng settings_parser_get_leng
+#endif
+
+#ifdef yyget_text
+#define settings_parser_get_text_ALREADY_DEFINED
+#else
+#define yyget_text settings_parser_get_text
+#endif
+
+#ifdef yyget_lineno
+#define settings_parser_get_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno settings_parser_get_lineno
+#endif
+
+#ifdef yyset_lineno
+#define settings_parser_set_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno settings_parser_set_lineno
+#endif
+
+#ifdef yyget_column
+#define settings_parser_get_column_ALREADY_DEFINED
+#else
+#define yyget_column settings_parser_get_column
+#endif
+
+#ifdef yyset_column
+#define settings_parser_set_column_ALREADY_DEFINED
+#else
+#define yyset_column settings_parser_set_column
+#endif
+
+#ifdef yywrap
+#define settings_parser_wrap_ALREADY_DEFINED
+#else
+#define yywrap settings_parser_wrap
+#endif
+
/* %endif */
+#ifdef yyget_lval
+#define settings_parser_get_lval_ALREADY_DEFINED
+#else
+#define yyget_lval settings_parser_get_lval
+#endif
+
+#ifdef yyset_lval
+#define settings_parser_set_lval_ALREADY_DEFINED
+#else
+#define yyset_lval settings_parser_set_lval
+#endif
+
+#ifdef yyalloc
+#define settings_parser_alloc_ALREADY_DEFINED
+#else
+#define yyalloc settings_parser_alloc
+#endif
+
+#ifdef yyrealloc
+#define settings_parser_realloc_ALREADY_DEFINED
+#else
+#define yyrealloc settings_parser_realloc
+#endif
+
+#ifdef yyfree
+#define settings_parser_free_ALREADY_DEFINED
+#else
+#define yyfree settings_parser_free
+#endif
+
/* %if-c-only */
/* %endif */
@@ -108,50 +328,39 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
/* %endif */
+/* begin standard C++ headers. */
/* %if-c++-only */
/* %endif */
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
#else
-#define yyconst
+#define yynoreturn
#endif
/* %not-for-header */
-
/* Returned upon end-of-file. */
#define YY_NULL 0
/* %ok-for-header */
/* %not-for-header */
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
*/
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
/* %ok-for-header */
/* %if-reentrant */
@@ -183,20 +392,16 @@ typedef void* yyscan_t;
* definition of BEGIN.
*/
#define BEGIN yyg->yy_start = 1 + 2 *
-
/* Translate the current start state into a value that can be later handed
* to BEGIN to return to the state. The YYSTATE alias is for lex
* compatibility.
*/
#define YY_START ((yyg->yy_start - 1) / 2)
#define YYSTATE YY_START
-
/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE settings_parser_restart(yyin ,yyscanner )
-
+#define YY_NEW_FILE yyrestart( yyin , yyscanner )
#define YY_END_OF_BUFFER_CHAR 0
/* Size of default input buffer. */
@@ -237,10 +442,10 @@ typedef size_t yy_size_t;
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
-
+
/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
* access to the local variable yy_act. Since yyless() is a macro, it would break
- * existing scanners that call yyless() from OUTSIDE settings_parser_lex.
+ * existing scanners that call yyless() from OUTSIDE yylex.
* One obvious solution it to make yy_act a global. I tried that, and saw
* a 5% performance hit in a non-yylineno scanner, because yy_act is
* normally declared as a register variable-- so it is not worth it.
@@ -273,7 +478,6 @@ typedef size_t yy_size_t;
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
-
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
#ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -293,7 +497,7 @@ struct yy_buffer_state
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
- yy_size_t yy_buf_size;
+ int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
@@ -321,7 +525,7 @@ struct yy_buffer_state
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@@ -338,7 +542,7 @@ struct yy_buffer_state
* possible backing-up.
*
* When we actually see the EOF, we change the status to "new"
- * (via settings_parser_restart()), so that the user can continue scanning by
+ * (via yyrestart()), so that the user can continue scanning by
* just pointing yyin at a new input file.
*/
#define YY_BUFFER_EOF_PENDING 2
@@ -348,7 +552,6 @@ struct yy_buffer_state
/* %if-c-only Standard (non-C++) definition */
/* %not-for-header */
-
/* %if-not-reentrant */
/* %endif */
/* %ok-for-header */
@@ -364,7 +567,6 @@ struct yy_buffer_state
#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
: NULL)
-
/* Same as previous macro, but useful when we know that the buffer stack is not
* NULL or when we need an lvalue. For internal use only.
*/
@@ -374,57 +576,52 @@ struct yy_buffer_state
/* %if-not-reentrant */
/* %not-for-header */
-
/* %ok-for-header */
/* %endif */
-void settings_parser_restart (FILE *input_file ,yyscan_t yyscanner );
-void settings_parser__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE settings_parser__create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void settings_parser__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void settings_parser__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void settings_parser_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void settings_parser_pop_buffer_state (yyscan_t yyscanner );
-
-static void settings_parser_ensure_buffer_stack (yyscan_t yyscanner );
-static void settings_parser__load_buffer_state (yyscan_t yyscanner );
-static void settings_parser__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
-#define YY_FLUSH_BUFFER settings_parser__flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+static void yyensure_buffer_stack ( yyscan_t yyscanner );
+static void yy_load_buffer_state ( yyscan_t yyscanner );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
-YY_BUFFER_STATE settings_parser__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE settings_parser__scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE settings_parser__scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
/* %endif */
-void *settings_parser_alloc (yy_size_t ,yyscan_t yyscanner );
-void *settings_parser_realloc (void *,yy_size_t ,yyscan_t yyscanner );
-void settings_parser_free (void * ,yyscan_t yyscanner );
-
-#define yy_new_buffer settings_parser__create_buffer
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
+#define yy_new_buffer yy_create_buffer
#define yy_set_interactive(is_interactive) \
{ \
if ( ! YY_CURRENT_BUFFER ){ \
- settings_parser_ensure_buffer_stack (yyscanner); \
+ yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- settings_parser__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
}
-
#define yy_set_bol(at_bol) \
{ \
if ( ! YY_CURRENT_BUFFER ){\
- settings_parser_ensure_buffer_stack (yyscanner); \
+ yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- settings_parser__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
-
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
@@ -434,8 +631,7 @@ void settings_parser_free (void * ,yyscan_t yyscanner );
#define YY_SKIP_YYWRAP
#define FLEX_DEBUG
-
-typedef unsigned char YY_CHAR;
+typedef flex_uint8_t YY_CHAR;
typedef int yy_state_type;
@@ -445,13 +641,10 @@ typedef int yy_state_type;
/* %if-c-only Standard (non-C++) definition */
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-#if defined(__GNUC__) && __GNUC__ >= 3
-__attribute__((__noreturn__))
-#endif
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner);
+static int yy_get_next_buffer ( yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
/* %endif */
@@ -461,12 +654,11 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\
- yyleng = (size_t) (yy_cp - yy_bp); \
+ yyleng = (int) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
yyg->yy_c_buf_p = yy_cp;
-
/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
#define YY_NUM_RULES 39
#define YY_END_OF_BUFFER 40
@@ -477,7 +669,7 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[85] =
+static const flex_int16_t yy_accept[85] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40, 12, 2, 3, 2, 11, 1, 7, 6, 8,
@@ -490,7 +682,7 @@ static yyconst flex_int16_t yy_accept[85] =
0, 10, 10, 0
} ;
-static yyconst YY_CHAR yy_ec[256] =
+static const YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
@@ -522,14 +714,14 @@ static yyconst YY_CHAR yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst YY_CHAR yy_meta[24] =
+static const YY_CHAR yy_meta[24] =
{ 0,
1, 2, 3, 4, 5, 6, 5, 7, 8, 7,
9, 10, 1, 1, 1, 1, 1, 1, 1, 1,
1, 7, 5
} ;
-static yyconst flex_uint16_t yy_base[103] =
+static const flex_int16_t yy_base[103] =
{ 0,
0, 0, 23, 0, 45, 67, 89, 111, 49, 50,
124, 0, 133, 335, 55, 335, 60, 335, 335, 335,
@@ -545,7 +737,7 @@ static yyconst flex_uint16_t yy_base[103] =
314, 324
} ;
-static yyconst flex_int16_t yy_def[103] =
+static const flex_int16_t yy_def[103] =
{ 0,
84, 1, 84, 3, 85, 85, 86, 86, 87, 87,
84, 88, 84, 84, 84, 84, 89, 84, 84, 84,
@@ -561,7 +753,7 @@ static yyconst flex_int16_t yy_def[103] =
84, 84
} ;
-static yyconst flex_uint16_t yy_nxt[359] =
+static const flex_int16_t yy_nxt[359] =
{ 0,
12, 13, 14, 15, 13, 16, 17, 18, 19, 20,
21, 12, 12, 12, 12, 22, 12, 12, 12, 12,
@@ -604,7 +796,7 @@ static yyconst flex_uint16_t yy_nxt[359] =
84, 84, 84, 84, 84, 84, 84, 84
} ;
-static yyconst flex_int16_t yy_chk[359] =
+static const flex_int16_t yy_chk[359] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -648,18 +840,18 @@ static yyconst flex_int16_t yy_chk[359] =
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[40] =
+static const flex_int32_t yy_rule_can_match_eol[40] =
{ 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
};
-static yyconst flex_int16_t yy_rule_linenum[39] =
+static const flex_int16_t yy_rule_linenum[39] =
{ 0,
- 66, 67, 68, 70, 71, 73, 74, 76, 81, 86,
- 91, 96, 102, 103, 104, 106, 108, 113, 120, 121,
- 123, 144, 150, 157, 160, 180, 183, 186, 189, 195,
- 196, 198, 218, 219, 220, 221, 222, 223
+ 71, 72, 73, 75, 76, 78, 79, 81, 86, 91,
+ 96, 101, 107, 108, 109, 111, 113, 118, 125, 126,
+ 128, 149, 155, 162, 165, 185, 188, 191, 194, 200,
+ 201, 203, 223, 224, 225, 226, 227, 228
} ;
/* The intent behind this definition is that it'll catch
@@ -694,9 +886,13 @@ bool settings_parser_open_next_file(parser_helper_t *ctx);
static void include_files(parser_helper_t *ctx);
+#line 890 "settings/settings_lexer.c"
/* use start conditions stack */
/* do not declare unneeded functions */
#define YY_NO_INPUT 1
+/* do not include unistd.h as it might conflict with our scanner states */
+#define YY_NO_UNISTD_H 1
+/* due to that disable interactive mode, which requires isatty() */
/* don't use global variables, and interact properly with bison */
/* maintain the line number */
/* don't generate a default rule */
@@ -712,7 +908,7 @@ static void include_files(parser_helper_t *ctx);
/* state used to scan quoted strings */
/* pattern for section/key names */
-#line 716 "settings/settings_lexer.c"
+#line 912 "settings/settings_lexer.c"
#define INITIAL 0
#define ref 1
@@ -751,7 +947,7 @@ struct yyguts_t
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char;
int yy_n_chars;
- yy_size_t yyleng_r;
+ int yyleng_r;
char *yy_c_buf_p;
int yy_init;
int yy_start;
@@ -775,7 +971,7 @@ struct yyguts_t
/* %if-c-only */
-static int yy_init_globals (yyscan_t yyscanner );
+static int yy_init_globals ( yyscan_t yyscanner );
/* %endif */
@@ -785,9 +981,9 @@ static int yy_init_globals (yyscan_t yyscanner );
* from bison output in section 1.*/
# define yylval yyg->yylval_r
-int settings_parser_lex_init (yyscan_t* scanner);
+int yylex_init (yyscan_t* scanner);
-int settings_parser_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
/* %endif */
@@ -796,41 +992,41 @@ int settings_parser_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
-int settings_parser_lex_destroy (yyscan_t yyscanner );
+int yylex_destroy ( yyscan_t yyscanner );
-int settings_parser_get_debug (yyscan_t yyscanner );
+int yyget_debug ( yyscan_t yyscanner );
-void settings_parser_set_debug (int debug_flag ,yyscan_t yyscanner );
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
-YY_EXTRA_TYPE settings_parser_get_extra (yyscan_t yyscanner );
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
-void settings_parser_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
-FILE *settings_parser_get_in (yyscan_t yyscanner );
+FILE *yyget_in ( yyscan_t yyscanner );
-void settings_parser_set_in (FILE * _in_str ,yyscan_t yyscanner );
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
-FILE *settings_parser_get_out (yyscan_t yyscanner );
+FILE *yyget_out ( yyscan_t yyscanner );
-void settings_parser_set_out (FILE * _out_str ,yyscan_t yyscanner );
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
-yy_size_t settings_parser_get_leng (yyscan_t yyscanner );
+ int yyget_leng ( yyscan_t yyscanner );
-char *settings_parser_get_text (yyscan_t yyscanner );
+char *yyget_text ( yyscan_t yyscanner );
-int settings_parser_get_lineno (yyscan_t yyscanner );
+int yyget_lineno ( yyscan_t yyscanner );
-void settings_parser_set_lineno (int _line_number ,yyscan_t yyscanner );
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
-int settings_parser_get_column (yyscan_t yyscanner );
+int yyget_column ( yyscan_t yyscanner );
-void settings_parser_set_column (int _column_no ,yyscan_t yyscanner );
+void yyset_column ( int _column_no , yyscan_t yyscanner );
/* %if-bison-bridge */
-YYSTYPE * settings_parser_get_lval (yyscan_t yyscanner );
+YYSTYPE * yyget_lval ( yyscan_t yyscanner );
-void settings_parser_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
/* %endif */
@@ -840,17 +1036,16 @@ void settings_parser_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int settings_parser_wrap (yyscan_t yyscanner );
+extern "C" int yywrap ( yyscan_t yyscanner );
#else
-extern int settings_parser_wrap (yyscan_t yyscanner );
+extern int yywrap ( yyscan_t yyscanner );
#endif
#endif
/* %not-for-header */
-
#ifndef YY_NO_UNPUT
- static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
+ static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner);
#endif
/* %ok-for-header */
@@ -858,21 +1053,20 @@ extern int settings_parser_wrap (yyscan_t yyscanner );
/* %endif */
#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
#endif
#ifndef YY_NO_INPUT
/* %if-c-only Standard (non-C++) definition */
/* %not-for-header */
-
#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
+static int yyinput ( yyscan_t yyscanner );
#else
-static int input (yyscan_t yyscanner );
+static int input ( yyscan_t yyscanner );
#endif
/* %ok-for-header */
@@ -881,11 +1075,11 @@ static int input (yyscan_t yyscanner );
/* %if-c-only */
- static void yy_push_state (int _new_state ,yyscan_t yyscanner);
+ static void yy_push_state ( int _new_state , yyscan_t yyscanner);
- static void yy_pop_state (yyscan_t yyscanner );
+ static void yy_pop_state ( yyscan_t yyscanner );
- static int yy_top_state (yyscan_t yyscanner );
+ static int yy_top_state ( yyscan_t yyscanner );
/* %endif */
@@ -905,7 +1099,7 @@ static int input (yyscan_t yyscanner );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
/* %endif */
/* %if-c++-only C++ definition */
/* %endif */
@@ -920,7 +1114,7 @@ static int input (yyscan_t yyscanner );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- size_t n; \
+ int n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -933,7 +1127,7 @@ static int input (yyscan_t yyscanner );
else \
{ \
errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
{ \
if( errno != EINTR) \
{ \
@@ -974,11 +1168,9 @@ static int input (yyscan_t yyscanner );
/* %if-tables-serialization structures and prototypes */
/* %not-for-header */
-
/* %ok-for-header */
/* %not-for-header */
-
/* %tables-yydmap generated elements */
/* %endif */
/* end tables serialization structures and prototypes */
@@ -992,10 +1184,10 @@ static int input (yyscan_t yyscanner );
#define YY_DECL_IS_OURS 1
/* %if-c-only Standard (non-C++) definition */
-extern int settings_parser_lex \
- (YYSTYPE * yylval_param ,yyscan_t yyscanner);
+extern int yylex \
+ (YYSTYPE * yylval_param , yyscan_t yyscanner);
-#define YY_DECL int settings_parser_lex \
+#define YY_DECL int yylex \
(YYSTYPE * yylval_param , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only C++ definition */
@@ -1019,7 +1211,6 @@ extern int settings_parser_lex \
YY_USER_ACTION
/* %not-for-header */
-
/** The main scanner function which does all the work.
*/
YY_DECL
@@ -1057,20 +1248,20 @@ YY_DECL
/* %endif */
if ( ! YY_CURRENT_BUFFER ) {
- settings_parser_ensure_buffer_stack (yyscanner);
+ yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- settings_parser__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- settings_parser__load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
{
/* %% [7.0] user's declarations go here */
-#line 64 "settings/settings_lexer.l"
+#line 69 "settings/settings_lexer.l"
-#line 1074 "settings/settings_lexer.c"
+#line 1265 "settings/settings_lexer.c"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@@ -1100,22 +1291,18 @@ yy_match:
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 85 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 335 );
+ while ( yy_current_state != 84 );
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
yy_find_action:
/* %% [10.0] code to find the action number goes here */
yy_act = yy_accept[yy_current_state];
- if ( yy_act == 0 )
- { /* have to back up */
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- yy_act = yy_accept[yy_current_state];
- }
YY_DO_BEFORE_ACTION;
@@ -1123,10 +1310,10 @@ yy_find_action:
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
{
- yy_size_t yyl;
+ int yyl;
for ( yyl = 0; yyl < yyleng; ++yyl )
if ( yytext[yyl] == '\n' )
-
+
do{ yylineno++;
yycolumn=0;
}while(0)
@@ -1164,40 +1351,40 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
-#line 66 "settings/settings_lexer.l"
+#line 71 "settings/settings_lexer.l"
/* eat comments */
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 67 "settings/settings_lexer.l"
+#line 72 "settings/settings_lexer.l"
/* eat whitespace */
YY_BREAK
case 3:
/* rule 3 can match eol */
YY_RULE_SETUP
-#line 68 "settings/settings_lexer.l"
+#line 73 "settings/settings_lexer.l"
/* eat newlines and comments at the end of a line */
YY_BREAK
case 4:
-#line 71 "settings/settings_lexer.l"
+#line 76 "settings/settings_lexer.l"
case 5:
YY_RULE_SETUP
-#line 71 "settings/settings_lexer.l"
+#line 76 "settings/settings_lexer.l"
return yytext[0];
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 73 "settings/settings_lexer.l"
+#line 78 "settings/settings_lexer.l"
return DOT;
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 74 "settings/settings_lexer.l"
+#line 79 "settings/settings_lexer.l"
return COMMA;
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 76 "settings/settings_lexer.l"
+#line 81 "settings/settings_lexer.l"
{
yy_push_state(ref, yyscanner);
return COLON;
@@ -1205,7 +1392,7 @@ YY_RULE_SETUP
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 81 "settings/settings_lexer.l"
+#line 86 "settings/settings_lexer.l"
{
yy_push_state(val, yyscanner);
return yytext[0];
@@ -1218,7 +1405,7 @@ YY_LINENO_REWIND_TO(yy_cp - 1);
yyg->yy_c_buf_p = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
-#line 86 "settings/settings_lexer.l"
+#line 91 "settings/settings_lexer.l"
{
yyextra->string_init(yyextra);
yy_push_state(inc, yyscanner);
@@ -1226,7 +1413,7 @@ YY_RULE_SETUP
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 91 "settings/settings_lexer.l"
+#line 96 "settings/settings_lexer.l"
{
PARSER_DBG1(yyextra, "unexpected string detected");
return STRING_ERROR;
@@ -1234,7 +1421,7 @@ YY_RULE_SETUP
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 96 "settings/settings_lexer.l"
+#line 101 "settings/settings_lexer.l"
{
yylval->s = strdup(yytext);
return NAME;
@@ -1243,28 +1430,28 @@ YY_RULE_SETUP
case 13:
YY_RULE_SETUP
-#line 102 "settings/settings_lexer.l"
+#line 107 "settings/settings_lexer.l"
/* eat comments */
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 103 "settings/settings_lexer.l"
+#line 108 "settings/settings_lexer.l"
/* eat whitespace */
YY_BREAK
case 15:
/* rule 15 can match eol */
YY_RULE_SETUP
-#line 104 "settings/settings_lexer.l"
+#line 109 "settings/settings_lexer.l"
/* eat newlines and comments at the end of a line */
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 106 "settings/settings_lexer.l"
+#line 111 "settings/settings_lexer.l"
return COMMA;
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 108 "settings/settings_lexer.l"
+#line 113 "settings/settings_lexer.l"
{
yylval->s = strdup(yytext);
return NAME;
@@ -1272,7 +1459,7 @@ YY_RULE_SETUP
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 113 "settings/settings_lexer.l"
+#line 118 "settings/settings_lexer.l"
{
unput(yytext[0]);
yy_pop_state(yyscanner);
@@ -1282,20 +1469,20 @@ YY_RULE_SETUP
case 19:
YY_RULE_SETUP
-#line 120 "settings/settings_lexer.l"
+#line 125 "settings/settings_lexer.l"
/* just ignore these */
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 121 "settings/settings_lexer.l"
+#line 126 "settings/settings_lexer.l"
YY_BREAK
case YY_STATE_EOF(val):
-#line 122 "settings/settings_lexer.l"
+#line 127 "settings/settings_lexer.l"
case 21:
/* rule 21 can match eol */
YY_RULE_SETUP
-#line 123 "settings/settings_lexer.l"
+#line 128 "settings/settings_lexer.l"
{
if (*yytext)
{
@@ -1319,7 +1506,7 @@ YY_RULE_SETUP
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 144 "settings/settings_lexer.l"
+#line 149 "settings/settings_lexer.l"
{
yyextra->string_init(yyextra);
yy_push_state(str, yyscanner);
@@ -1328,7 +1515,7 @@ YY_RULE_SETUP
/* same as above, but allow more characters */
case 23:
YY_RULE_SETUP
-#line 150 "settings/settings_lexer.l"
+#line 155 "settings/settings_lexer.l"
{
yylval->s = strdup(yytext);
return NAME;
@@ -1338,16 +1525,16 @@ YY_RULE_SETUP
case 24:
YY_RULE_SETUP
-#line 157 "settings/settings_lexer.l"
+#line 162 "settings/settings_lexer.l"
/* just ignore these */
YY_BREAK
/* we allow all characters except #, } and spaces, they can be escaped */
case YY_STATE_EOF(inc):
-#line 159 "settings/settings_lexer.l"
+#line 164 "settings/settings_lexer.l"
case 25:
/* rule 25 can match eol */
YY_RULE_SETUP
-#line 160 "settings/settings_lexer.l"
+#line 165 "settings/settings_lexer.l"
{
if (*yytext)
{
@@ -1371,28 +1558,28 @@ YY_RULE_SETUP
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 180 "settings/settings_lexer.l"
+#line 185 "settings/settings_lexer.l"
{ /* string include */
yy_push_state(str, yyscanner);
}
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 183 "settings/settings_lexer.l"
+#line 188 "settings/settings_lexer.l"
{
yyextra->string_add(yyextra, yytext);
}
YY_BREAK
case 28:
YY_RULE_SETUP
-#line 186 "settings/settings_lexer.l"
+#line 191 "settings/settings_lexer.l"
{
yyextra->string_add(yyextra, yytext+1);
}
YY_BREAK
case 29:
YY_RULE_SETUP
-#line 189 "settings/settings_lexer.l"
+#line 194 "settings/settings_lexer.l"
{
yyextra->string_add(yyextra, yytext);
}
@@ -1401,17 +1588,17 @@ YY_RULE_SETUP
case 30:
YY_RULE_SETUP
-#line 195 "settings/settings_lexer.l"
+#line 200 "settings/settings_lexer.l"
/* just ignore these */
YY_BREAK
case 31:
-#line 197 "settings/settings_lexer.l"
+#line 202 "settings/settings_lexer.l"
YY_RULE_SETUP
case YY_STATE_EOF(str):
-#line 197 "settings/settings_lexer.l"
+#line 202 "settings/settings_lexer.l"
case 32:
YY_RULE_SETUP
-#line 198 "settings/settings_lexer.l"
+#line 203 "settings/settings_lexer.l"
{
if (!streq(yytext, "\""))
{
@@ -1434,34 +1621,34 @@ YY_RULE_SETUP
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 218 "settings/settings_lexer.l"
+#line 223 "settings/settings_lexer.l"
yyextra->string_add(yyextra, "\n");
YY_BREAK
case 34:
YY_RULE_SETUP
-#line 219 "settings/settings_lexer.l"
+#line 224 "settings/settings_lexer.l"
yyextra->string_add(yyextra, "\r");
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 220 "settings/settings_lexer.l"
+#line 225 "settings/settings_lexer.l"
yyextra->string_add(yyextra, "\t");
YY_BREAK
case 36:
/* rule 36 can match eol */
YY_RULE_SETUP
-#line 221 "settings/settings_lexer.l"
+#line 226 "settings/settings_lexer.l"
/* merge lines that end with escaped EOL characters */
YY_BREAK
case 37:
YY_RULE_SETUP
-#line 222 "settings/settings_lexer.l"
+#line 227 "settings/settings_lexer.l"
yyextra->string_add(yyextra, yytext+1);
YY_BREAK
case 38:
/* rule 38 can match eol */
YY_RULE_SETUP
-#line 223 "settings/settings_lexer.l"
+#line 228 "settings/settings_lexer.l"
{
yyextra->string_add(yyextra, yytext);
}
@@ -1469,7 +1656,7 @@ YY_RULE_SETUP
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(ref):
-#line 228 "settings/settings_lexer.l"
+#line 233 "settings/settings_lexer.l"
{
settings_parser_pop_buffer_state(yyscanner);
if (!settings_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
@@ -1480,10 +1667,10 @@ case YY_STATE_EOF(ref):
YY_BREAK
case 39:
YY_RULE_SETUP
-#line 236 "settings/settings_lexer.l"
+#line 241 "settings/settings_lexer.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 1487 "settings/settings_lexer.c"
+#line 1674 "settings/settings_lexer.c"
case YY_END_OF_BUFFER:
{
@@ -1499,7 +1686,7 @@ YY_FATAL_ERROR( "flex scanner jammed" );
/* We're scanning a new file or input source. It's
* possible that this happened because the user
* just pointed yyin at a new source and called
- * settings_parser_lex(). If so, then we have to assure
+ * yylex(). If so, then we have to assure
* consistency between YY_CURRENT_BUFFER and our
* globals. Here is the right place to do so, because
* this is the first action (other than possibly a
@@ -1553,7 +1740,8 @@ YY_FATAL_ERROR( "flex scanner jammed" );
else
{
/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
- yy_cp = yyg->yy_c_buf_p;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
goto yy_find_action;
}
}
@@ -1564,7 +1752,7 @@ YY_FATAL_ERROR( "flex scanner jammed" );
{
yyg->yy_did_buffer_switch_on_eof = 0;
- if ( settings_parser_wrap(yyscanner ) )
+ if ( yywrap( yyscanner ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
@@ -1618,12 +1806,11 @@ YY_FATAL_ERROR( "flex scanner jammed" );
} /* end of action switch */
} /* end of scanning one token */
} /* end of user's declarations */
-} /* end of settings_parser_lex */
+} /* end of yylex */
/* %ok-for-header */
/* %if-c++-only */
/* %not-for-header */
-
/* %ok-for-header */
/* %endif */
@@ -1644,7 +1831,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
char *source = yyg->yytext_ptr;
- yy_size_t number_to_move, i;
+ int number_to_move, i;
int ret_val;
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -1673,7 +1860,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -1686,7 +1873,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{
- yy_size_t num_to_read =
+ int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -1700,7 +1887,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( b->yy_is_our_buffer )
{
- yy_size_t new_size = b->yy_buf_size * 2;
+ int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
@@ -1709,11 +1896,12 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
- settings_parser_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
+ b->yy_ch_buf = NULL;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
@@ -1741,7 +1929,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- settings_parser_restart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
}
else
@@ -1755,12 +1943,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) settings_parser_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
}
yyg->yy_n_chars += number_to_move;
@@ -1776,7 +1967,6 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* %if-c-only */
/* %not-for-header */
-
static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
@@ -1802,9 +1992,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 85 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
}
return yy_current_state;
@@ -1836,9 +2026,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 85 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
yy_is_jam = (yy_current_state == 84);
(void)yyg;
@@ -1864,7 +2054,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
- yy_size_t number_to_move = yyg->yy_n_chars + 2;
+ int number_to_move = yyg->yy_n_chars + 2;
char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
char *source =
@@ -1876,7 +2066,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
yy_cp += (int) (dest - source);
yy_bp += (int) (dest - source);
YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+ yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
YY_FATAL_ERROR( "flex scanner push-back overflow" );
@@ -1928,7 +2118,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{ /* need more input */
- yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) )
@@ -1945,14 +2135,14 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
*/
/* Reset buffer status. */
- settings_parser_restart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
/*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( settings_parser_wrap(yyscanner ) )
- return EOF;
+ if ( yywrap( yyscanner ) )
+ return 0;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
@@ -1976,7 +2166,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* %% [19.0] update BOL and yylineno */
if ( c == '\n' )
-
+
do{ yylineno++;
yycolumn=0;
}while(0)
@@ -1994,7 +2184,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
* @note This function does not reset the start condition to @c INITIAL .
*/
/* %if-c-only */
- void settings_parser_restart (FILE * input_file , yyscan_t yyscanner)
+ void yyrestart (FILE * input_file , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2002,13 +2192,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( ! YY_CURRENT_BUFFER ){
- settings_parser_ensure_buffer_stack (yyscanner);
+ yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- settings_parser__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- settings_parser__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- settings_parser__load_buffer_state(yyscanner );
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
+ yy_load_buffer_state( yyscanner );
}
/* %if-c++-only */
@@ -2019,7 +2209,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
* @param yyscanner The scanner object.
*/
/* %if-c-only */
- void settings_parser__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2028,10 +2218,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* TODO. We should be able to replace this entire function body
* with
- * settings_parser_pop_buffer_state();
- * settings_parser_push_buffer_state(new_buffer);
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
*/
- settings_parser_ensure_buffer_stack (yyscanner);
+ yyensure_buffer_stack (yyscanner);
if ( YY_CURRENT_BUFFER == new_buffer )
return;
@@ -2044,18 +2234,18 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
}
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- settings_parser__load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
/* We don't actually know whether we did this switch during
- * EOF (settings_parser_wrap()) processing, but the only time this flag
- * is looked at is after settings_parser_wrap() is called, so it's safe
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
* to go ahead and always set it.
*/
yyg->yy_did_buffer_switch_on_eof = 1;
}
/* %if-c-only */
-static void settings_parser__load_buffer_state (yyscan_t yyscanner)
+static void yy_load_buffer_state (yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2078,29 +2268,29 @@ static void settings_parser__load_buffer_state (yyscan_t yyscanner)
* @return the allocated buffer state.
*/
/* %if-c-only */
- YY_BUFFER_STATE settings_parser__create_buffer (FILE * file, int size , yyscan_t yyscanner)
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
{
YY_BUFFER_STATE b;
- b = (YY_BUFFER_STATE) settings_parser_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in settings_parser__create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
- b->yy_buf_size = (yy_size_t)size;
+ b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
- b->yy_ch_buf = (char *) settings_parser_alloc(b->yy_buf_size + 2 ,yyscanner );
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in settings_parser__create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_is_our_buffer = 1;
- settings_parser__init_buffer(b,file ,yyscanner);
+ yy_init_buffer( b, file , yyscanner);
return b;
}
@@ -2109,11 +2299,11 @@ static void settings_parser__load_buffer_state (yyscan_t yyscanner)
/* %endif */
/** Destroy the buffer.
- * @param b a buffer created with settings_parser__create_buffer()
+ * @param b a buffer created with yy_create_buffer()
* @param yyscanner The scanner object.
*/
/* %if-c-only */
- void settings_parser__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2127,17 +2317,17 @@ static void settings_parser__load_buffer_state (yyscan_t yyscanner)
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- settings_parser_free((void *) b->yy_ch_buf ,yyscanner );
+ yyfree( (void *) b->yy_ch_buf , yyscanner );
- settings_parser_free((void *) b ,yyscanner );
+ yyfree( (void *) b , yyscanner );
}
/* Initializes or reinitializes a buffer.
* This function is sometimes called more than once on the same buffer,
- * such as during a settings_parser_restart() or at EOF.
+ * such as during a yyrestart() or at EOF.
*/
/* %if-c-only */
- static void settings_parser__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2146,7 +2336,7 @@ static void settings_parser__load_buffer_state (yyscan_t yyscanner)
int oerrno = errno;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- settings_parser__flush_buffer(b ,yyscanner);
+ yy_flush_buffer( b , yyscanner);
/* %if-c-only */
b->yy_input_file = file;
@@ -2155,8 +2345,8 @@ static void settings_parser__load_buffer_state (yyscan_t yyscanner)
/* %endif */
b->yy_fill_buffer = 1;
- /* If b is the current buffer, then settings_parser__init_buffer was _probably_
- * called from settings_parser_restart() or through yy_get_next_buffer.
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
* In that case, we don't want to reset the lineno or column.
*/
if (b != YY_CURRENT_BUFFER){
@@ -2166,7 +2356,7 @@ static void settings_parser__load_buffer_state (yyscan_t yyscanner)
/* %if-c-only */
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+ b->yy_is_interactive = 0;
/* %endif */
/* %if-c++-only */
@@ -2179,7 +2369,7 @@ static void settings_parser__load_buffer_state (yyscan_t yyscanner)
* @param yyscanner The scanner object.
*/
/* %if-c-only */
- void settings_parser__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2203,7 +2393,7 @@ static void settings_parser__load_buffer_state (yyscan_t yyscanner)
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == YY_CURRENT_BUFFER )
- settings_parser__load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
/* %if-c-or-c++ */
@@ -2214,7 +2404,7 @@ static void settings_parser__load_buffer_state (yyscan_t yyscanner)
* @param yyscanner The scanner object.
*/
/* %if-c-only */
-void settings_parser_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2223,9 +2413,9 @@ void settings_parser_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yy
if (new_buffer == NULL)
return;
- settings_parser_ensure_buffer_stack(yyscanner);
+ yyensure_buffer_stack(yyscanner);
- /* This block is copied from settings_parser__switch_to_buffer. */
+ /* This block is copied from yy_switch_to_buffer. */
if ( YY_CURRENT_BUFFER )
{
/* Flush out information for old buffer. */
@@ -2239,8 +2429,8 @@ void settings_parser_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yy
yyg->yy_buffer_stack_top++;
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- /* copied from settings_parser__switch_to_buffer. */
- settings_parser__load_buffer_state(yyscanner );
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
/* %endif */
@@ -2251,7 +2441,7 @@ void settings_parser_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yy
* @param yyscanner The scanner object.
*/
/* %if-c-only */
-void settings_parser_pop_buffer_state (yyscan_t yyscanner)
+void yypop_buffer_state (yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2260,13 +2450,13 @@ void settings_parser_pop_buffer_state (yyscan_t yyscanner)
if (!YY_CURRENT_BUFFER)
return;
- settings_parser__delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
YY_CURRENT_BUFFER_LVALUE = NULL;
if (yyg->yy_buffer_stack_top > 0)
--yyg->yy_buffer_stack_top;
if (YY_CURRENT_BUFFER) {
- settings_parser__load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
}
@@ -2277,7 +2467,7 @@ void settings_parser_pop_buffer_state (yyscan_t yyscanner)
* Guarantees space for at least one push.
*/
/* %if-c-only */
-static void settings_parser_ensure_buffer_stack (yyscan_t yyscanner)
+static void yyensure_buffer_stack (yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2291,15 +2481,15 @@ static void settings_parser_ensure_buffer_stack (yyscan_t yyscanner)
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
- num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
- yyg->yy_buffer_stack = (struct yy_buffer_state**)settings_parser_alloc
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in settings_parser_ensure_buffer_stack()" );
-
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
yyg->yy_buffer_stack_max = num_to_alloc;
yyg->yy_buffer_stack_top = 0;
return;
@@ -2311,12 +2501,12 @@ static void settings_parser_ensure_buffer_stack (yyscan_t yyscanner)
yy_size_t grow_size = 8 /* arbitrary grow size */;
num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)settings_parser_realloc
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
(yyg->yy_buffer_stack,
num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in settings_parser_ensure_buffer_stack()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
/* zero only the new slots.*/
memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -2330,9 +2520,9 @@ static void settings_parser_ensure_buffer_stack (yyscan_t yyscanner)
* @param base the character buffer
* @param size the size in bytes of the character buffer
* @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE settings_parser__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
@@ -2340,73 +2530,73 @@ YY_BUFFER_STATE settings_parser__scan_buffer (char * base, yy_size_t size , yy
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
- return 0;
+ return NULL;
- b = (YY_BUFFER_STATE) settings_parser_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in settings_parser__scan_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
+ b->yy_input_file = NULL;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- settings_parser__switch_to_buffer(b ,yyscanner );
+ yy_switch_to_buffer( b , yyscanner );
return b;
}
/* %endif */
/* %if-c-only */
-/** Setup the input buffer state to scan a string. The next call to settings_parser_lex() will
+/** Setup the input buffer state to scan a string. The next call to yylex() will
* scan from a @e copy of @a str.
* @param yystr a NUL-terminated string to scan
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
- * settings_parser__scan_bytes() instead.
+ * yy_scan_bytes() instead.
*/
-YY_BUFFER_STATE settings_parser__scan_string (yyconst char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
{
- return settings_parser__scan_bytes(yystr,strlen(yystr) ,yyscanner);
+ return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
}
/* %endif */
/* %if-c-only */
-/** Setup the input buffer state to scan the given bytes. The next call to settings_parser_lex() will
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
* scan from a @e copy of @a bytes.
* @param yybytes the byte buffer to scan
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE settings_parser__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) settings_parser_alloc(n ,yyscanner );
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n , yyscanner );
if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in settings_parser__scan_bytes()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
for ( i = 0; i < _yybytes_len; ++i )
buf[i] = yybytes[i];
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = settings_parser__scan_buffer(buf,n ,yyscanner);
+ b = yy_scan_buffer( buf, n , yyscanner);
if ( ! b )
- YY_FATAL_ERROR( "bad buffer in settings_parser__scan_bytes()" );
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
/* It's okay to grow etc. this buffer, and we should throw it
* away when we're done.
@@ -2429,13 +2619,14 @@ YY_BUFFER_STATE settings_parser__scan_bytes (yyconst char * yybytes, yy_size_t
yy_size_t new_size;
yyg->yy_start_stack_depth += YY_START_STACK_INCR;
- new_size = yyg->yy_start_stack_depth * sizeof( int );
+ new_size = (yy_size_t) yyg->yy_start_stack_depth * sizeof( int );
if ( ! yyg->yy_start_stack )
- yyg->yy_start_stack = (int *) settings_parser_alloc(new_size ,yyscanner );
+ yyg->yy_start_stack = (int *) yyalloc( new_size , yyscanner );
else
- yyg->yy_start_stack = (int *) settings_parser_realloc((void *) yyg->yy_start_stack,new_size ,yyscanner );
+ yyg->yy_start_stack = (int *) yyrealloc(
+ (void *) yyg->yy_start_stack, new_size , yyscanner );
if ( ! yyg->yy_start_stack )
YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
@@ -2474,11 +2665,11 @@ YY_BUFFER_STATE settings_parser__scan_bytes (yyconst char * yybytes, yy_size_t
#endif
/* %if-c-only */
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- (void) fprintf( stderr, "%s\n", msg );
+ fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
/* %endif */
@@ -2510,7 +2701,7 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
/** Get the user-defined data for this scanner.
* @param yyscanner The scanner object.
*/
-YY_EXTRA_TYPE settings_parser_get_extra (yyscan_t yyscanner)
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyextra;
@@ -2521,10 +2712,10 @@ YY_EXTRA_TYPE settings_parser_get_extra (yyscan_t yyscanner)
/** Get the current line number.
* @param yyscanner The scanner object.
*/
-int settings_parser_get_lineno (yyscan_t yyscanner)
+int yyget_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2534,10 +2725,10 @@ int settings_parser_get_lineno (yyscan_t yyscanner)
/** Get the current column number.
* @param yyscanner The scanner object.
*/
-int settings_parser_get_column (yyscan_t yyscanner)
+int yyget_column (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2547,7 +2738,7 @@ int settings_parser_get_column (yyscan_t yyscanner)
/** Get the input stream.
* @param yyscanner The scanner object.
*/
-FILE *settings_parser_get_in (yyscan_t yyscanner)
+FILE *yyget_in (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyin;
@@ -2556,7 +2747,7 @@ FILE *settings_parser_get_in (yyscan_t yyscanner)
/** Get the output stream.
* @param yyscanner The scanner object.
*/
-FILE *settings_parser_get_out (yyscan_t yyscanner)
+FILE *yyget_out (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyout;
@@ -2565,7 +2756,7 @@ FILE *settings_parser_get_out (yyscan_t yyscanner)
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-yy_size_t settings_parser_get_leng (yyscan_t yyscanner)
+int yyget_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
@@ -2575,7 +2766,7 @@ yy_size_t settings_parser_get_leng (yyscan_t yyscanner)
* @param yyscanner The scanner object.
*/
-char *settings_parser_get_text (yyscan_t yyscanner)
+char *yyget_text (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yytext;
@@ -2587,7 +2778,7 @@ char *settings_parser_get_text (yyscan_t yyscanner)
* @param user_defined The data to be associated with this scanner.
* @param yyscanner The scanner object.
*/
-void settings_parser_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyextra = user_defined ;
@@ -2599,13 +2790,13 @@ void settings_parser_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner
* @param _line_number line number
* @param yyscanner The scanner object.
*/
-void settings_parser_set_lineno (int _line_number , yyscan_t yyscanner)
+void yyset_lineno (int _line_number , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- YY_FATAL_ERROR( "settings_parser_set_lineno called with no buffer" );
+ YY_FATAL_ERROR( "yyset_lineno called with no buffer" );
yylineno = _line_number;
}
@@ -2614,13 +2805,13 @@ void settings_parser_set_lineno (int _line_number , yyscan_t yyscanner)
* @param _column_no column number
* @param yyscanner The scanner object.
*/
-void settings_parser_set_column (int _column_no , yyscan_t yyscanner)
+void yyset_column (int _column_no , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* column is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- YY_FATAL_ERROR( "settings_parser_set_column called with no buffer" );
+ YY_FATAL_ERROR( "yyset_column called with no buffer" );
yycolumn = _column_no;
}
@@ -2629,27 +2820,27 @@ void settings_parser_set_column (int _column_no , yyscan_t yyscanner)
* input buffer.
* @param _in_str A readable stream.
* @param yyscanner The scanner object.
- * @see settings_parser__switch_to_buffer
+ * @see yy_switch_to_buffer
*/
-void settings_parser_set_in (FILE * _in_str , yyscan_t yyscanner)
+void yyset_in (FILE * _in_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyin = _in_str ;
}
-void settings_parser_set_out (FILE * _out_str , yyscan_t yyscanner)
+void yyset_out (FILE * _out_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyout = _out_str ;
}
-int settings_parser_get_debug (yyscan_t yyscanner)
+int yyget_debug (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yy_flex_debug;
}
-void settings_parser_set_debug (int _bdebug , yyscan_t yyscanner)
+void yyset_debug (int _bdebug , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_flex_debug = _bdebug ;
@@ -2662,13 +2853,13 @@ void settings_parser_set_debug (int _bdebug , yyscan_t yyscanner)
/* %if-bison-bridge */
-YYSTYPE * settings_parser_get_lval (yyscan_t yyscanner)
+YYSTYPE * yyget_lval (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yylval;
}
-void settings_parser_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yylval = yylval_param;
@@ -2678,20 +2869,18 @@ void settings_parser_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
/* User-visible API */
-/* settings_parser_lex_init is special because it creates the scanner itself, so it is
+/* yylex_init is special because it creates the scanner itself, so it is
* the ONLY reentrant function that doesn't take the scanner as the last argument.
* That's why we explicitly handle the declaration, instead of using our macros.
*/
-
-int settings_parser_lex_init(yyscan_t* ptr_yy_globals)
-
+int yylex_init(yyscan_t* ptr_yy_globals)
{
if (ptr_yy_globals == NULL){
errno = EINVAL;
return 1;
}
- *ptr_yy_globals = (yyscan_t) settings_parser_alloc ( sizeof( struct yyguts_t ), NULL );
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
@@ -2704,39 +2893,37 @@ int settings_parser_lex_init(yyscan_t* ptr_yy_globals)
return yy_init_globals ( *ptr_yy_globals );
}
-/* settings_parser_lex_init_extra has the same functionality as settings_parser_lex_init, but follows the
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
* convention of taking the scanner as the last argument. Note however, that
* this is a *pointer* to a scanner, as it will be allocated by this call (and
* is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to settings_parser_alloc in
+ * The user defined value in the first argument will be available to yyalloc in
* the yyextra field.
*/
-
-int settings_parser_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
+int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
{
struct yyguts_t dummy_yyguts;
- settings_parser_set_extra (yy_user_defined, &dummy_yyguts);
+ yyset_extra (yy_user_defined, &dummy_yyguts);
if (ptr_yy_globals == NULL){
errno = EINVAL;
return 1;
}
-
- *ptr_yy_globals = (yyscan_t) settings_parser_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
return 1;
}
-
+
/* By setting to 0xAA, we expose bugs in
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- settings_parser_set_extra (yy_user_defined, *ptr_yy_globals);
-
+
+ yyset_extra (yy_user_defined, *ptr_yy_globals);
+
return yy_init_globals ( *ptr_yy_globals );
}
@@ -2747,13 +2934,13 @@ static int yy_init_globals (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Initialization is the same as for the non-reentrant scanner.
- * This function is called from settings_parser_lex_destroy(), so don't allocate here.
+ * This function is called from yylex_destroy(), so don't allocate here.
*/
- yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack = NULL;
yyg->yy_buffer_stack_top = 0;
yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_c_buf_p = NULL;
yyg->yy_init = 0;
yyg->yy_start = 0;
@@ -2766,45 +2953,45 @@ static int yy_init_globals (yyscan_t yyscanner)
yyin = stdin;
yyout = stdout;
#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
+ yyin = NULL;
+ yyout = NULL;
#endif
/* For future reference: Set errno on error, since we are called by
- * settings_parser_lex_init()
+ * yylex_init()
*/
return 0;
}
/* %endif */
/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
-/* settings_parser_lex_destroy is for both reentrant and non-reentrant scanners. */
-int settings_parser_lex_destroy (yyscan_t yyscanner)
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
- settings_parser__delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
YY_CURRENT_BUFFER_LVALUE = NULL;
- settings_parser_pop_buffer_state(yyscanner);
+ yypop_buffer_state(yyscanner);
}
/* Destroy the stack itself. */
- settings_parser_free(yyg->yy_buffer_stack ,yyscanner);
+ yyfree(yyg->yy_buffer_stack , yyscanner);
yyg->yy_buffer_stack = NULL;
/* Destroy the start condition stack. */
- settings_parser_free(yyg->yy_start_stack ,yyscanner );
+ yyfree( yyg->yy_start_stack , yyscanner );
yyg->yy_start_stack = NULL;
/* Reset the globals. This is important in a non-reentrant scanner so the next time
- * settings_parser_lex() is called, initialization will occur. */
+ * yylex() is called, initialization will occur. */
yy_init_globals( yyscanner);
/* %if-reentrant */
/* Destroy the main struct (reentrant only). */
- settings_parser_free ( yyscanner , yyscanner );
+ yyfree ( yyscanner , yyscanner );
yyscanner = NULL;
/* %endif */
return 0;
@@ -2816,7 +3003,7 @@ int settings_parser_lex_destroy (yyscan_t yyscanner)
*/
#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
@@ -2828,7 +3015,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yysca
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
{
int n;
for ( n = 0; s[n]; ++n )
@@ -2838,14 +3025,14 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
}
#endif
-void *settings_parser_alloc (yy_size_t size , yyscan_t yyscanner)
+void *yyalloc (yy_size_t size , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- return (void *) malloc( size );
+ return malloc(size);
}
-void *settings_parser_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
@@ -2857,14 +3044,14 @@ void *settings_parser_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
- return (void *) realloc( (char *) ptr, size );
+ return realloc(ptr, size);
}
-void settings_parser_free (void * ptr , yyscan_t yyscanner)
+void yyfree (void * ptr , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- free( (char *) ptr ); /* see settings_parser_realloc() for (char *) cast */
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
}
/* %if-tables-serialization definitions */
@@ -2874,8 +3061,7 @@ void settings_parser_free (void * ptr , yyscan_t yyscanner)
/* %ok-for-header */
-#line 236 "settings/settings_lexer.l"
-
+#line 241 "settings/settings_lexer.l"
/**
diff --git a/src/libstrongswan/settings/settings_lexer.l b/src/libstrongswan/settings/settings_lexer.l
index 19ab8d7b2..e8c2b9884 100644
--- a/src/libstrongswan/settings/settings_lexer.l
+++ b/src/libstrongswan/settings/settings_lexer.l
@@ -32,6 +32,11 @@ static void include_files(parser_helper_t *ctx);
/* do not declare unneeded functions */
%option noinput noyywrap
+/* do not include unistd.h as it might conflict with our scanner states */
+%option nounistd
+/* due to that disable interactive mode, which requires isatty() */
+%option never-interactive
+
/* don't use global variables, and interact properly with bison */
%option reentrant bison-bridge
diff --git a/src/libstrongswan/tests/Makefile.am b/src/libstrongswan/tests/Makefile.am
index 5737e7a17..d4cac5a3b 100644
--- a/src/libstrongswan/tests/Makefile.am
+++ b/src/libstrongswan/tests/Makefile.am
@@ -58,6 +58,7 @@ libstrongswan_tests_SOURCES = tests.h tests.c \
suites/test_mgf1.c \
suites/test_ntru.c \
suites/test_ed25519.c \
+ suites/test_ed448.c \
suites/test_signature_params.c
libstrongswan_tests_CFLAGS = \
diff --git a/src/libstrongswan/tests/Makefile.in b/src/libstrongswan/tests/Makefile.in
index c5b943572..664c84f3f 100644
--- a/src/libstrongswan/tests/Makefile.in
+++ b/src/libstrongswan/tests/Makefile.in
@@ -163,6 +163,7 @@ am_libstrongswan_tests_OBJECTS = libstrongswan_tests-tests.$(OBJEXT) \
suites/libstrongswan_tests-test_mgf1.$(OBJEXT) \
suites/libstrongswan_tests-test_ntru.$(OBJEXT) \
suites/libstrongswan_tests-test_ed25519.$(OBJEXT) \
+ suites/libstrongswan_tests-test_ed448.$(OBJEXT) \
suites/libstrongswan_tests-test_signature_params.$(OBJEXT)
libstrongswan_tests_OBJECTS = $(am_libstrongswan_tests_OBJECTS)
libstrongswan_tests_DEPENDENCIES = \
@@ -548,6 +549,7 @@ libstrongswan_tests_SOURCES = tests.h tests.c \
suites/test_mgf1.c \
suites/test_ntru.c \
suites/test_ed25519.c \
+ suites/test_ed448.c \
suites/test_signature_params.c
libstrongswan_tests_CFLAGS = \
@@ -708,6 +710,8 @@ suites/libstrongswan_tests-test_ntru.$(OBJEXT): \
suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
suites/libstrongswan_tests-test_ed25519.$(OBJEXT): \
suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+suites/libstrongswan_tests-test_ed448.$(OBJEXT): \
+ suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
suites/libstrongswan_tests-test_signature_params.$(OBJEXT): \
suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
@@ -740,6 +744,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/libstrongswan_tests-test_crypto_factory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/libstrongswan_tests-test_ecdsa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/libstrongswan_tests-test_ed25519.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/libstrongswan_tests-test_ed448.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/libstrongswan_tests-test_enum.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/libstrongswan_tests-test_enumerator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/libstrongswan_tests-test_fetch_http.Po@am__quote@
@@ -1359,6 +1364,20 @@ suites/libstrongswan_tests-test_ed25519.obj: suites/test_ed25519.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstrongswan_tests_CFLAGS) $(CFLAGS) -c -o suites/libstrongswan_tests-test_ed25519.obj `if test -f 'suites/test_ed25519.c'; then $(CYGPATH_W) 'suites/test_ed25519.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_ed25519.c'; fi`
+suites/libstrongswan_tests-test_ed448.o: suites/test_ed448.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstrongswan_tests_CFLAGS) $(CFLAGS) -MT suites/libstrongswan_tests-test_ed448.o -MD -MP -MF suites/$(DEPDIR)/libstrongswan_tests-test_ed448.Tpo -c -o suites/libstrongswan_tests-test_ed448.o `test -f 'suites/test_ed448.c' || echo '$(srcdir)/'`suites/test_ed448.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/libstrongswan_tests-test_ed448.Tpo suites/$(DEPDIR)/libstrongswan_tests-test_ed448.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_ed448.c' object='suites/libstrongswan_tests-test_ed448.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstrongswan_tests_CFLAGS) $(CFLAGS) -c -o suites/libstrongswan_tests-test_ed448.o `test -f 'suites/test_ed448.c' || echo '$(srcdir)/'`suites/test_ed448.c
+
+suites/libstrongswan_tests-test_ed448.obj: suites/test_ed448.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstrongswan_tests_CFLAGS) $(CFLAGS) -MT suites/libstrongswan_tests-test_ed448.obj -MD -MP -MF suites/$(DEPDIR)/libstrongswan_tests-test_ed448.Tpo -c -o suites/libstrongswan_tests-test_ed448.obj `if test -f 'suites/test_ed448.c'; then $(CYGPATH_W) 'suites/test_ed448.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_ed448.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/libstrongswan_tests-test_ed448.Tpo suites/$(DEPDIR)/libstrongswan_tests-test_ed448.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_ed448.c' object='suites/libstrongswan_tests-test_ed448.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstrongswan_tests_CFLAGS) $(CFLAGS) -c -o suites/libstrongswan_tests-test_ed448.obj `if test -f 'suites/test_ed448.c'; then $(CYGPATH_W) 'suites/test_ed448.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_ed448.c'; fi`
+
suites/libstrongswan_tests-test_signature_params.o: suites/test_signature_params.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstrongswan_tests_CFLAGS) $(CFLAGS) -MT suites/libstrongswan_tests-test_signature_params.o -MD -MP -MF suites/$(DEPDIR)/libstrongswan_tests-test_signature_params.Tpo -c -o suites/libstrongswan_tests-test_signature_params.o `test -f 'suites/test_signature_params.c' || echo '$(srcdir)/'`suites/test_signature_params.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/libstrongswan_tests-test_signature_params.Tpo suites/$(DEPDIR)/libstrongswan_tests-test_signature_params.Po
diff --git a/src/libstrongswan/tests/suites/test_ed25519.c b/src/libstrongswan/tests/suites/test_ed25519.c
index 86cbb1bc0..c52b90885 100644
--- a/src/libstrongswan/tests/suites/test_ed25519.c
+++ b/src/libstrongswan/tests/suites/test_ed25519.c
@@ -24,10 +24,12 @@ struct sig_test_t {
chunk_t pubkey;
chunk_t msg;
chunk_t sig;
+ chunk_t fp_pk;
+ chunk_t fp_spki;
};
/**
- * Ed25519 Test Vectors from draft-irtf-cfrg-eddsa
+ * Ed25519 Test Vectors from RFC 8032
*/
static sig_test_t sig_tests[] = {
/* Test 1 */
@@ -51,7 +53,13 @@ static sig_test_t sig_tests[] = {
0x01, 0x55, 0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b, 0xd2, 0x5b,
0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24, 0x65, 0x51, 0x41, 0x43,
- 0x8e, 0x7a, 0x10, 0x0b)
+ 0x8e, 0x7a, 0x10, 0x0b),
+ chunk_from_chars(
+ 0x5b, 0x27, 0xaa, 0x55, 0x89, 0x17, 0x97, 0x70, 0xe4, 0x75,
+ 0x75, 0xb1, 0x62, 0xa1, 0xde, 0xd9, 0x7b, 0x8b, 0xfc, 0x6d),
+ chunk_from_chars(
+ 0xa5, 0x66, 0xbe, 0x19, 0x84, 0x01, 0x73, 0x41, 0x3a, 0x61,
+ 0x04, 0x83, 0x50, 0xef, 0xf2, 0x3e, 0x8f, 0xe2, 0x22, 0x66),
},
/* Test 2 */
{ chunk_from_chars(
@@ -75,7 +83,13 @@ static sig_test_t sig_tests[] = {
0x69, 0xda, 0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c, 0x38, 0x7b,
0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee, 0xb0, 0x0d, 0x29, 0x16,
- 0x12, 0xbb, 0x0c, 0x00)
+ 0x12, 0xbb, 0x0c, 0x00),
+ chunk_from_chars(
+ 0x13, 0xf7, 0x72, 0x66, 0x9e, 0x15, 0x2a, 0xe6, 0xa6, 0x2a,
+ 0x60, 0xa3, 0x48, 0x8a, 0x6f, 0x29, 0x7d, 0x06, 0x13, 0xdd),
+ chunk_from_chars(
+ 0xbd, 0xae, 0x41, 0xeb, 0x5d, 0xbf, 0x88, 0xb9, 0xdf, 0x18,
+ 0xda, 0xbb, 0x2d, 0xee, 0xa9, 0x1a, 0x4e, 0x03, 0x38, 0xe4),
},
/* Test 3 */
{ chunk_from_chars(
@@ -99,7 +113,13 @@ static sig_test_t sig_tests[] = {
0xc3, 0xac, 0x18, 0xff, 0x9b, 0x53, 0x8d, 0x16, 0xf2, 0x90,
0xae, 0x67, 0xf7, 0x60, 0x98, 0x4d, 0xc6, 0x59, 0x4a, 0x7c,
0x15, 0xe9, 0x71, 0x6e, 0xd2, 0x8d, 0xc0, 0x27, 0xbe, 0xce,
- 0xea, 0x1e, 0xc4, 0x0a)
+ 0xea, 0x1e, 0xc4, 0x0a),
+ chunk_from_chars(
+ 0x88, 0xc7, 0x64, 0xc8, 0xbe, 0x44, 0x37, 0x4a, 0x7d, 0x2f,
+ 0x5d, 0x84, 0x72, 0x1f, 0x8e, 0x32, 0x5e, 0x5b, 0xd6, 0x4c),
+ chunk_from_chars(
+ 0xad, 0x01, 0x30, 0xb1, 0x2b, 0x48, 0x62, 0x9b, 0xb9, 0xad,
+ 0xea, 0x92, 0x1f, 0xfe, 0xd2, 0x9a, 0x42, 0xf0, 0xad, 0xe6),
},
/* Test 1024 */
{ chunk_from_chars(
@@ -235,7 +255,13 @@ static sig_test_t sig_tests[] = {
0xc3, 0x50, 0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45,
0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b, 0x5e, 0x8f,
0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6, 0xac, 0x00, 0xa9, 0x70,
- 0x4a, 0x18, 0x8a, 0x03)
+ 0x4a, 0x18, 0x8a, 0x03),
+ chunk_from_chars(
+ 0x11, 0x2d, 0xb3, 0x08, 0x97, 0x6e, 0x38, 0x8f, 0x5f, 0x5e,
+ 0xb0, 0xae, 0x8f, 0x5f, 0x59, 0x1d, 0xff, 0x74, 0xf4, 0x44),
+ chunk_from_chars(
+ 0xcb, 0x36, 0xcc, 0x6a, 0x82, 0x2c, 0x49, 0x40, 0xfb, 0x08,
+ 0x04, 0xf6, 0x3a, 0x4f, 0x20, 0x2b, 0xe5, 0x73, 0x43, 0x2f),
},
/* Test SHA(abc) */
{ chunk_from_chars(
@@ -265,7 +291,13 @@ static sig_test_t sig_tests[] = {
0xb5, 0x89, 0x09, 0x35, 0x1f, 0xc9, 0xac, 0x90, 0xb3, 0xec,
0xfd, 0xfb, 0xc7, 0xc6, 0x64, 0x31, 0xe0, 0x30, 0x3d, 0xca,
0x17, 0x9c, 0x13, 0x8a, 0xc1, 0x7a, 0xd9, 0xbe, 0xf1, 0x17,
- 0x73, 0x31, 0xa7, 0x04)
+ 0x73, 0x31, 0xa7, 0x04),
+ chunk_from_chars(
+ 0x26, 0x4c, 0xa5, 0x7f, 0x89, 0x6d, 0x64, 0x81, 0xd1, 0x87,
+ 0xe9, 0x89, 0x47, 0x29, 0x5a, 0xfe, 0xe3, 0x6d, 0x82, 0x44),
+ chunk_from_chars(
+ 0x27, 0x88, 0xfc, 0x14, 0xb1, 0xcd, 0xd0, 0x24, 0xd5, 0x9d,
+ 0x31, 0x65, 0x59, 0x63, 0x69, 0xcf, 0xaf, 0x50, 0x10, 0xe7),
}
};
@@ -273,24 +305,34 @@ START_TEST(test_ed25519_sign)
{
private_key_t *key;
public_key_t *pubkey, *public;
- chunk_t sig, encoding;
+ chunk_t sig, encoding, fp;
/* load private key */
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED25519,
BUILD_BLOB_ASN1_DER, sig_tests[_i].key, BUILD_END);
ck_assert(key != NULL);
ck_assert(key->get_encoding(key, PRIVKEY_ASN1_DER, &encoding));
- ck_assert(chunk_equals(encoding, sig_tests[_i].key));
+ ck_assert_chunk_eq(encoding, sig_tests[_i].key);
chunk_free(&encoding);
+ ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp));
+ ck_assert_chunk_eq(sig_tests[_i].fp_pk, fp);
+ ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &fp));
+ ck_assert_chunk_eq(sig_tests[_i].fp_spki, fp);
+
/* load public key */
pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED25519,
BUILD_BLOB_ASN1_DER, sig_tests[_i].pubkey, BUILD_END);
ck_assert(pubkey != NULL);
ck_assert(pubkey->get_encoding(pubkey, PUBKEY_SPKI_ASN1_DER, &encoding));
- ck_assert(chunk_equals(encoding, sig_tests[_i].pubkey));
+ ck_assert_chunk_eq(encoding, sig_tests[_i].pubkey);
chunk_free(&encoding);
+ ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp));
+ ck_assert_chunk_eq(sig_tests[_i].fp_pk, fp);
+ ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_INFO_SHA1, &fp));
+ ck_assert_chunk_eq(sig_tests[_i].fp_spki, fp);
+
/* compare public keys */
public = key->get_public_key(key);
ck_assert(public != NULL);
@@ -299,7 +341,7 @@ START_TEST(test_ed25519_sign)
/* sign */
ck_assert(key->sign(key, SIGN_ED25519, NULL, sig_tests[_i].msg, &sig));
ck_assert(sig.len == 64);
- ck_assert(chunk_equals(sig, sig_tests[_i].sig));
+ ck_assert_chunk_eq(sig, sig_tests[_i].sig);
/* verify */
ck_assert(pubkey->verify(pubkey, SIGN_ED25519, NULL, sig_tests[_i].msg,
@@ -364,7 +406,7 @@ START_TEST(test_ed25519_gen)
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp_pub));
ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp_pub));
ck_assert(fp_pub.ptr != NULL);
- ck_assert(chunk_equals(fp_pub, fp_priv));
+ ck_assert_chunk_eq(fp_pub, fp_priv);
/* clone public key */
pubkey2 = pubkey->get_ref(pubkey);
@@ -429,6 +471,16 @@ static chunk_t zero_pk = chunk_from_chars(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00);
+/* sig_tests[0].sig with s+L */
+static chunk_t malleable_sig = chunk_from_chars(
+ 0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72, 0x90, 0x86,
+ 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a, 0x84, 0x87, 0x7f, 0x1e,
+ 0xb8, 0xe5, 0xd9, 0x74, 0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49,
+ 0x01, 0x55, 0x4c, 0x8c, 0x78, 0x72, 0xaa, 0x06, 0x4e, 0x04,
+ 0x9d, 0xbb, 0x30, 0x13, 0xfb, 0xf2, 0x93, 0x80, 0xd2, 0x5b,
+ 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24, 0x65, 0x51, 0x41, 0x43,
+ 0x8e, 0x7a, 0x10, 0x1b);
+
START_TEST(test_ed25519_fail)
{
private_key_t *key;
@@ -479,6 +531,16 @@ START_TEST(test_ed25519_fail)
ck_assert(!pubkey->verify(pubkey, SIGN_ED25519, NULL, chunk_empty,
chunk_empty));
+ /* RFC 8032, section 5.1.7 requires that 0 <= s < L to prevent signature
+ * malleability. Only a warning because Botan and OpenSSL are both
+ * vulnerable to this. */
+ if (pubkey->verify(pubkey, SIGN_ED25519, NULL, sig_tests[0].msg,
+ malleable_sig))
+ {
+ warn("Ed25519 signature verification is vulnerable to malleable "
+ "signatures");
+ }
+
/* malformed signature */
sig = chunk_create(sig1, 64);
memcpy(sig1, sig_tests[0].sig.ptr, 64);
diff --git a/src/libstrongswan/tests/suites/test_ed448.c b/src/libstrongswan/tests/suites/test_ed448.c
new file mode 100644
index 000000000..288da19a0
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_ed448.c
@@ -0,0 +1,654 @@
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <time.h>
+
+typedef struct sig_test_t sig_test_t;
+
+struct sig_test_t {
+ chunk_t key;
+ chunk_t pubkey;
+ chunk_t msg;
+ chunk_t sig;
+ chunk_t fp_pk;
+ chunk_t fp_spki;
+};
+
+/**
+ * Ed448 Test Vectors from RFC 8032
+ */
+static sig_test_t sig_tests[] = {
+ /* Blank */
+ { chunk_from_chars(
+ 0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
+ 0x6c,0x82,0xa5,0x62,0xcb,0x80,0x8d,0x10,0xd6,0x32,0xbe,0x89,0xc8,0x51,0x3e,0xbf,
+ 0x6c,0x92,0x9f,0x34,0xdd,0xfa,0x8c,0x9f,0x63,0xc9,0x96,0x0e,0xf6,0xe3,0x48,0xa3,
+ 0x52,0x8c,0x8a,0x3f,0xcc,0x2f,0x04,0x4e,0x39,0xa3,0xfc,0x5b,0x94,0x49,0x2f,0x8f,
+ 0x03,0x2e,0x75,0x49,0xa2,0x00,0x98,0xf9,0x5b),
+ chunk_from_chars(
+ 0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x5f,0xd7,0x44,0x9b,
+ 0x59,0xb4,0x61,0xfd,0x2c,0xe7,0x87,0xec,0x61,0x6a,0xd4,0x6a,0x1d,0xa1,0x34,0x24,
+ 0x85,0xa7,0x0e,0x1f,0x8a,0x0e,0xa7,0x5d,0x80,0xe9,0x67,0x78,0xed,0xf1,0x24,0x76,
+ 0x9b,0x46,0xc7,0x06,0x1b,0xd6,0x78,0x3d,0xf1,0xe5,0x0f,0x6c,0xd1,0xfa,0x1a,0xbe,
+ 0xaf,0xe8,0x25,0x61,0x80),
+ { NULL, 0 },
+ chunk_from_chars(
+ 0x53,0x3a,0x37,0xf6,0xbb,0xe4,0x57,0x25,0x1f,0x02,0x3c,0x0d,0x88,0xf9,0x76,0xae,
+ 0x2d,0xfb,0x50,0x4a,0x84,0x3e,0x34,0xd2,0x07,0x4f,0xd8,0x23,0xd4,0x1a,0x59,0x1f,
+ 0x2b,0x23,0x3f,0x03,0x4f,0x62,0x82,0x81,0xf2,0xfd,0x7a,0x22,0xdd,0xd4,0x7d,0x78,
+ 0x28,0xc5,0x9b,0xd0,0xa2,0x1b,0xfd,0x39,0x80,0xff,0x0d,0x20,0x28,0xd4,0xb1,0x8a,
+ 0x9d,0xf6,0x3e,0x00,0x6c,0x5d,0x1c,0x2d,0x34,0x5b,0x92,0x5d,0x8d,0xc0,0x0b,0x41,
+ 0x04,0x85,0x2d,0xb9,0x9a,0xc5,0xc7,0xcd,0xda,0x85,0x30,0xa1,0x13,0xa0,0xf4,0xdb,
+ 0xb6,0x11,0x49,0xf0,0x5a,0x73,0x63,0x26,0x8c,0x71,0xd9,0x58,0x08,0xff,0x2e,0x65,
+ 0x26,0x00),
+ chunk_from_chars(
+ 0x6d,0xe0,0x8a,0x72,0x35,0x1e,0xf1,0xad,0xeb,0xca,0x2c,0xd7,0xf1,0xfd,0xa6,0x91,
+ 0x54,0xad,0xfa,0x4f),
+ chunk_from_chars(
+ 0x1b,0x7a,0x47,0x56,0x91,0xb8,0x41,0x33,0x0d,0x2e,0x4d,0xa5,0xe6,0x13,0xb9,0x89,
+ 0xda,0xce,0xc5,0x8e),
+ },
+ /* 1 octet */
+ { chunk_from_chars(
+ 0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
+ 0xc4,0xea,0xb0,0x5d,0x35,0x70,0x07,0xc6,0x32,0xf3,0xdb,0xb4,0x84,0x89,0x92,0x4d,
+ 0x55,0x2b,0x08,0xfe,0x0c,0x35,0x3a,0x0d,0x4a,0x1f,0x00,0xac,0xda,0x2c,0x46,0x3a,
+ 0xfb,0xea,0x67,0xc5,0xe8,0xd2,0x87,0x7c,0x5e,0x3b,0xc3,0x97,0xa6,0x59,0x94,0x9e,
+ 0xf8,0x02,0x1e,0x95,0x4e,0x0a,0x12,0x27,0x4e),
+ chunk_from_chars(
+ 0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x43,0xba,0x28,0xf4,
+ 0x30,0xcd,0xff,0x45,0x6a,0xe5,0x31,0x54,0x5f,0x7e,0xcd,0x0a,0xc8,0x34,0xa5,0x5d,
+ 0x93,0x58,0xc0,0x37,0x2b,0xfa,0x0c,0x6c,0x67,0x98,0xc0,0x86,0x6a,0xea,0x01,0xeb,
+ 0x00,0x74,0x28,0x02,0xb8,0x43,0x8e,0xa4,0xcb,0x82,0x16,0x9c,0x23,0x51,0x60,0x62,
+ 0x7b,0x4c,0x3a,0x94,0x80),
+ chunk_from_chars(
+ 0x03),
+ chunk_from_chars(
+ 0x26,0xb8,0xf9,0x17,0x27,0xbd,0x62,0x89,0x7a,0xf1,0x5e,0x41,0xeb,0x43,0xc3,0x77,
+ 0xef,0xb9,0xc6,0x10,0xd4,0x8f,0x23,0x35,0xcb,0x0b,0xd0,0x08,0x78,0x10,0xf4,0x35,
+ 0x25,0x41,0xb1,0x43,0xc4,0xb9,0x81,0xb7,0xe1,0x8f,0x62,0xde,0x8c,0xcd,0xf6,0x33,
+ 0xfc,0x1b,0xf0,0x37,0xab,0x7c,0xd7,0x79,0x80,0x5e,0x0d,0xbc,0xc0,0xaa,0xe1,0xcb,
+ 0xce,0xe1,0xaf,0xb2,0xe0,0x27,0xdf,0x36,0xbc,0x04,0xdc,0xec,0xbf,0x15,0x43,0x36,
+ 0xc1,0x9f,0x0a,0xf7,0xe0,0xa6,0x47,0x29,0x05,0xe7,0x99,0xf1,0x95,0x3d,0x2a,0x0f,
+ 0xf3,0x34,0x8a,0xb2,0x1a,0xa4,0xad,0xaf,0xd1,0xd2,0x34,0x44,0x1c,0xf8,0x07,0xc0,
+ 0x3a,0x00),
+ chunk_from_chars(
+ 0x74,0xa7,0x4b,0x23,0x69,0x98,0x17,0x46,0x1f,0xca,0xcf,0x84,0xf7,0xc6,0x3e,0x05,
+ 0x2a,0x1b,0xf9,0xb8),
+ chunk_from_chars(
+ 0xf6,0x76,0xf7,0x63,0x82,0x2b,0x53,0x5c,0x61,0x9c,0xfa,0x4a,0x59,0x7d,0xdd,0xae,
+ 0x13,0x34,0xf0,0xb1),
+ },
+ /* 11 octets */
+ { chunk_from_chars(
+ 0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
+ 0xcd,0x23,0xd2,0x4f,0x71,0x42,0x74,0xe7,0x44,0x34,0x32,0x37,0xb9,0x32,0x90,0xf5,
+ 0x11,0xf6,0x42,0x5f,0x98,0xe6,0x44,0x59,0xff,0x20,0x3e,0x89,0x85,0x08,0x3f,0xfd,
+ 0xf6,0x05,0x00,0x55,0x3a,0xbc,0x0e,0x05,0xcd,0x02,0x18,0x4b,0xdb,0x89,0xc4,0xcc,
+ 0xd6,0x7e,0x18,0x79,0x51,0x26,0x7e,0xb3,0x28),
+ chunk_from_chars(
+ 0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0xdc,0xea,0x9e,0x78,
+ 0xf3,0x5a,0x1b,0xf3,0x49,0x9a,0x83,0x1b,0x10,0xb8,0x6c,0x90,0xaa,0xc0,0x1c,0xd8,
+ 0x4b,0x67,0xa0,0x10,0x9b,0x55,0xa3,0x6e,0x93,0x28,0xb1,0xe3,0x65,0xfc,0xe1,0x61,
+ 0xd7,0x1c,0xe7,0x13,0x1a,0x54,0x3e,0xa4,0xcb,0x5f,0x7e,0x9f,0x1d,0x8b,0x00,0x69,
+ 0x64,0x47,0x00,0x14,0x00),
+ chunk_from_chars(
+ 0x0c,0x3e,0x54,0x40,0x74,0xec,0x63,0xb0,0x26,0x5e,0x0c),
+ chunk_from_chars(
+ 0x1f,0x0a,0x88,0x88,0xce,0x25,0xe8,0xd4,0x58,0xa2,0x11,0x30,0x87,0x9b,0x84,0x0a,
+ 0x90,0x89,0xd9,0x99,0xaa,0xba,0x03,0x9e,0xaf,0x3e,0x3a,0xfa,0x09,0x0a,0x09,0xd3,
+ 0x89,0xdb,0xa8,0x2c,0x4f,0xf2,0xae,0x8a,0xc5,0xcd,0xfb,0x7c,0x55,0xe9,0x4d,0x5d,
+ 0x96,0x1a,0x29,0xfe,0x01,0x09,0x94,0x1e,0x00,0xb8,0xdb,0xde,0xea,0x6d,0x3b,0x05,
+ 0x10,0x68,0xdf,0x72,0x54,0xc0,0xcd,0xc1,0x29,0xcb,0xe6,0x2d,0xb2,0xdc,0x95,0x7d,
+ 0xbb,0x47,0xb5,0x1f,0xd3,0xf2,0x13,0xfb,0x86,0x98,0xf0,0x64,0x77,0x42,0x50,0xa5,
+ 0x02,0x89,0x61,0xc9,0xbf,0x8f,0xfd,0x97,0x3f,0xe5,0xd5,0xc2,0x06,0x49,0x2b,0x14,
+ 0x0e,0x00),
+ chunk_from_chars(
+ 0x3b,0x56,0x55,0xa4,0xce,0x4c,0xec,0x67,0x77,0x9c,0x9f,0xeb,0xfe,0x6f,0x38,0xba,
+ 0x88,0xc2,0x25,0x10),
+ chunk_from_chars(
+ 0x71,0xcb,0xf2,0xb7,0x1b,0x3b,0x77,0xcb,0xd6,0x41,0x05,0x02,0x72,0x31,0xa6,0x91,
+ 0x27,0x3f,0xe5,0x51),
+ },
+ /* 12 octets */
+ { chunk_from_chars(
+ 0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
+ 0x25,0x8c,0xdd,0x4a,0xda,0x32,0xed,0x9c,0x9f,0xf5,0x4e,0x63,0x75,0x6a,0xe5,0x82,
+ 0xfb,0x8f,0xab,0x2a,0xc7,0x21,0xf2,0xc8,0xe6,0x76,0xa7,0x27,0x68,0x51,0x3d,0x93,
+ 0x9f,0x63,0xdd,0xdb,0x55,0x60,0x91,0x33,0xf2,0x9a,0xdf,0x86,0xec,0x99,0x29,0xdc,
+ 0xcb,0x52,0xc1,0xc5,0xfd,0x2f,0xf7,0xe2,0x1b),
+ chunk_from_chars(
+ 0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x3b,0xa1,0x6d,0xa0,
+ 0xc6,0xf2,0xcc,0x1f,0x30,0x18,0x77,0x40,0x75,0x6f,0x5e,0x79,0x8d,0x6b,0xc5,0xfc,
+ 0x01,0x5d,0x7c,0x63,0xcc,0x95,0x10,0xee,0x3f,0xd4,0x4a,0xdc,0x24,0xd8,0xe9,0x68,
+ 0xb6,0xe4,0x6e,0x6f,0x94,0xd1,0x9b,0x94,0x53,0x61,0x72,0x6b,0xd7,0x5e,0x14,0x9e,
+ 0xf0,0x98,0x17,0xf5,0x80),
+ chunk_from_chars(
+ 0x64,0xa6,0x5f,0x3c,0xde,0xdc,0xdd,0x66,0x81,0x1e,0x29,0x15),
+ chunk_from_chars(
+ 0x7e,0xee,0xab,0x7c,0x4e,0x50,0xfb,0x79,0x9b,0x41,0x8e,0xe5,0xe3,0x19,0x7f,0xf6,
+ 0xbf,0x15,0xd4,0x3a,0x14,0xc3,0x43,0x89,0xb5,0x9d,0xd1,0xa7,0xb1,0xb8,0x5b,0x4a,
+ 0xe9,0x04,0x38,0xac,0xa6,0x34,0xbe,0xa4,0x5e,0x3a,0x26,0x95,0xf1,0x27,0x0f,0x07,
+ 0xfd,0xcd,0xf7,0xc6,0x2b,0x8e,0xfe,0xaf,0x00,0xb4,0x5c,0x2c,0x96,0xba,0x45,0x7e,
+ 0xb1,0xa8,0xbf,0x07,0x5a,0x3d,0xb2,0x8e,0x5c,0x24,0xf6,0xb9,0x23,0xed,0x4a,0xd7,
+ 0x47,0xc3,0xc9,0xe0,0x3c,0x70,0x79,0xef,0xb8,0x7c,0xb1,0x10,0xd3,0xa9,0x98,0x61,
+ 0xe7,0x20,0x03,0xcb,0xae,0x6d,0x6b,0x8b,0x82,0x7e,0x4e,0x6c,0x14,0x30,0x64,0xff,
+ 0x3c,0x00),
+ chunk_from_chars(
+ 0x56,0x8e,0xad,0x67,0xa7,0x83,0x78,0xfe,0x8f,0xaf,0xa7,0x87,0x2e,0xc8,0x95,0xa0,
+ 0xde,0x05,0x37,0x4c),
+ chunk_from_chars(
+ 0xed,0x1b,0xe5,0xa1,0x97,0x23,0x59,0x4d,0x86,0x6b,0x6b,0xef,0xfb,0x81,0xe4,0x8e,
+ 0xf7,0x42,0xe0,0x81),
+ },
+ /* 13 octets */
+ { chunk_from_chars(
+ 0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
+ 0x7e,0xf4,0xe8,0x45,0x44,0x23,0x67,0x52,0xfb,0xb5,0x6b,0x8f,0x31,0xa2,0x3a,0x10,
+ 0xe4,0x28,0x14,0xf5,0xf5,0x5c,0xa0,0x37,0xcd,0xcc,0x11,0xc6,0x4c,0x9a,0x3b,0x29,
+ 0x49,0xc1,0xbb,0x60,0x70,0x03,0x14,0x61,0x17,0x32,0xa6,0xc2,0xfe,0xa9,0x8e,0xeb,
+ 0xc0,0x26,0x6a,0x11,0xa9,0x39,0x70,0x10,0x0e),
+ chunk_from_chars(
+ 0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0xb3,0xda,0x07,0x9b,
+ 0x0a,0xa4,0x93,0xa5,0x77,0x20,0x29,0xf0,0x46,0x7b,0xae,0xbe,0xe5,0xa8,0x11,0x2d,
+ 0x9d,0x3a,0x22,0x53,0x23,0x61,0xda,0x29,0x4f,0x7b,0xb3,0x81,0x5c,0x5d,0xc5,0x9e,
+ 0x17,0x6b,0x4d,0x9f,0x38,0x1c,0xa0,0x93,0x8e,0x13,0xc6,0xc0,0x7b,0x17,0x4b,0xe6,
+ 0x5d,0xfa,0x57,0x8e,0x80),
+ chunk_from_chars(
+ 0x64,0xa6,0x5f,0x3c,0xde,0xdc,0xdd,0x66,0x81,0x1e,0x29,0x15,0xe7),
+ chunk_from_chars(
+ 0x6a,0x12,0x06,0x6f,0x55,0x33,0x1b,0x6c,0x22,0xac,0xd5,0xd5,0xbf,0xc5,0xd7,0x12,
+ 0x28,0xfb,0xda,0x80,0xae,0x8d,0xec,0x26,0xbd,0xd3,0x06,0x74,0x3c,0x50,0x27,0xcb,
+ 0x48,0x90,0x81,0x0c,0x16,0x2c,0x02,0x74,0x68,0x67,0x5e,0xcf,0x64,0x5a,0x83,0x17,
+ 0x6c,0x0d,0x73,0x23,0xa2,0xcc,0xde,0x2d,0x80,0xef,0xe5,0xa1,0x26,0x8e,0x8a,0xca,
+ 0x1d,0x6f,0xbc,0x19,0x4d,0x3f,0x77,0xc4,0x49,0x86,0xeb,0x4a,0xb4,0x17,0x79,0x19,
+ 0xad,0x8b,0xec,0x33,0xeb,0x47,0xbb,0xb5,0xfc,0x6e,0x28,0x19,0x6f,0xd1,0xca,0xf5,
+ 0x6b,0x4e,0x7e,0x0b,0xa5,0x51,0x92,0x34,0xd0,0x47,0x15,0x5a,0xc7,0x27,0xa1,0x05,
+ 0x31,0x00),
+ chunk_from_chars(
+ 0x6e,0xb1,0xb6,0x33,0x76,0xa8,0x0f,0x84,0x26,0x23,0xfb,0xaa,0x9e,0xaa,0x1d,0x8d,
+ 0x6d,0xa5,0x75,0x4e),
+ chunk_from_chars(
+ 0xfa,0x2f,0xeb,0xff,0x13,0xc0,0xee,0xd0,0x3b,0xc6,0xf2,0x7d,0xb8,0x61,0xe5,0x9d,
+ 0x16,0x53,0xb1,0x11),
+ },
+ /* 64 octets */
+ { chunk_from_chars(
+ 0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
+ 0xd6,0x5d,0xf3,0x41,0xad,0x13,0xe0,0x08,0x56,0x76,0x88,0xba,0xed,0xda,0x8e,0x9d,
+ 0xcd,0xc1,0x7d,0xc0,0x24,0x97,0x4e,0xa5,0xb4,0x22,0x7b,0x65,0x30,0xe3,0x39,0xbf,
+ 0xf2,0x1f,0x99,0xe6,0x8c,0xa6,0x96,0x8f,0x3c,0xca,0x6d,0xfe,0x0f,0xb9,0xf4,0xfa,
+ 0xb4,0xfa,0x13,0x5d,0x55,0x42,0xea,0x3f,0x01),
+ chunk_from_chars(
+ 0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0xdf,0x97,0x05,0xf5,
+ 0x8e,0xdb,0xab,0x80,0x2c,0x7f,0x83,0x63,0xcf,0xe5,0x56,0x0a,0xb1,0xc6,0x13,0x2c,
+ 0x20,0xa9,0xf1,0xdd,0x16,0x34,0x83,0xa2,0x6f,0x8a,0xc5,0x3a,0x39,0xd6,0x80,0x8b,
+ 0xf4,0xa1,0xdf,0xbd,0x26,0x1b,0x09,0x9b,0xb0,0x3b,0x3f,0xb5,0x09,0x06,0xcb,0x28,
+ 0xbd,0x8a,0x08,0x1f,0x00),
+ chunk_from_chars(
+ 0xbd,0x0f,0x6a,0x37,0x47,0xcd,0x56,0x1b,0xdd,0xdf,0x46,0x40,0xa3,0x32,0x46,0x1a,
+ 0x4a,0x30,0xa1,0x2a,0x43,0x4c,0xd0,0xbf,0x40,0xd7,0x66,0xd9,0xc6,0xd4,0x58,0xe5,
+ 0x51,0x22,0x04,0xa3,0x0c,0x17,0xd1,0xf5,0x0b,0x50,0x79,0x63,0x1f,0x64,0xeb,0x31,
+ 0x12,0x18,0x2d,0xa3,0x00,0x58,0x35,0x46,0x11,0x13,0x71,0x8d,0x1a,0x5e,0xf9,0x44),
+ chunk_from_chars(
+ 0x55,0x4b,0xc2,0x48,0x08,0x60,0xb4,0x9e,0xab,0x85,0x32,0xd2,0xa5,0x33,0xb7,0xd5,
+ 0x78,0xef,0x47,0x3e,0xeb,0x58,0xc9,0x8b,0xb2,0xd0,0xe1,0xce,0x48,0x8a,0x98,0xb1,
+ 0x8d,0xfd,0xe9,0xb9,0xb9,0x07,0x75,0xe6,0x7f,0x47,0xd4,0xa1,0xc3,0x48,0x20,0x58,
+ 0xef,0xc9,0xf4,0x0d,0x2c,0xa0,0x33,0xa0,0x80,0x1b,0x63,0xd4,0x5b,0x3b,0x72,0x2e,
+ 0xf5,0x52,0xba,0xd3,0xb4,0xcc,0xb6,0x67,0xda,0x35,0x01,0x92,0xb6,0x1c,0x50,0x8c,
+ 0xf7,0xb6,0xb5,0xad,0xad,0xc2,0xc8,0xd9,0xa4,0x46,0xef,0x00,0x3f,0xb0,0x5c,0xba,
+ 0x5f,0x30,0xe8,0x8e,0x36,0xec,0x27,0x03,0xb3,0x49,0xca,0x22,0x9c,0x26,0x70,0x83,
+ 0x39,0x00),
+ chunk_from_chars(
+ 0x2b,0xb0,0xd4,0x29,0xb8,0x51,0x3f,0xb5,0x9d,0x07,0xd0,0xb0,0x1f,0x4a,0x39,0x25,
+ 0x33,0xae,0x3e,0x64),
+ chunk_from_chars(
+ 0x79,0xbb,0x37,0xe4,0x2a,0xf9,0x58,0xb7,0xa4,0x58,0x18,0x88,0x4b,0x82,0x8f,0xfb,
+ 0x9c,0x74,0xce,0x9d),
+ },
+ /* 256 octets */
+ { chunk_from_chars(
+ 0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
+ 0x2e,0xc5,0xfe,0x3c,0x17,0x04,0x5a,0xbd,0xb1,0x36,0xa5,0xe6,0xa9,0x13,0xe3,0x2a,
+ 0xb7,0x5a,0xe6,0x8b,0x53,0xd2,0xfc,0x14,0x9b,0x77,0xe5,0x04,0x13,0x2d,0x37,0x56,
+ 0x9b,0x7e,0x76,0x6b,0xa7,0x4a,0x19,0xbd,0x61,0x62,0x34,0x3a,0x21,0xc8,0x59,0x0a,
+ 0xa9,0xce,0xbc,0xa9,0x01,0x4c,0x63,0x6d,0xf5),
+ chunk_from_chars(
+ 0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x79,0x75,0x6f,0x01,
+ 0x4d,0xcf,0xe2,0x07,0x9f,0x5d,0xd9,0xe7,0x18,0xbe,0x41,0x71,0xe2,0xef,0x24,0x86,
+ 0xa0,0x8f,0x25,0x18,0x6f,0x6b,0xff,0x43,0xa9,0x93,0x6b,0x9b,0xfe,0x12,0x40,0x2b,
+ 0x08,0xae,0x65,0x79,0x8a,0x3d,0x81,0xe2,0x2e,0x9e,0xc8,0x0e,0x76,0x90,0x86,0x2e,
+ 0xf3,0xd4,0xed,0x3a,0x00),
+ chunk_from_chars(
+ 0x15,0x77,0x75,0x32,0xb0,0xbd,0xd0,0xd1,0x38,0x9f,0x63,0x6c,0x5f,0x6b,0x9b,0xa7,
+ 0x34,0xc9,0x0a,0xf5,0x72,0x87,0x7e,0x2d,0x27,0x2d,0xd0,0x78,0xaa,0x1e,0x56,0x7c,
+ 0xfa,0x80,0xe1,0x29,0x28,0xbb,0x54,0x23,0x30,0xe8,0x40,0x9f,0x31,0x74,0x50,0x41,
+ 0x07,0xec,0xd5,0xef,0xac,0x61,0xae,0x75,0x04,0xda,0xbe,0x2a,0x60,0x2e,0xde,0x89,
+ 0xe5,0xcc,0xa6,0x25,0x7a,0x7c,0x77,0xe2,0x7a,0x70,0x2b,0x3a,0xe3,0x9f,0xc7,0x69,
+ 0xfc,0x54,0xf2,0x39,0x5a,0xe6,0xa1,0x17,0x8c,0xab,0x47,0x38,0xe5,0x43,0x07,0x2f,
+ 0xc1,0xc1,0x77,0xfe,0x71,0xe9,0x2e,0x25,0xbf,0x03,0xe4,0xec,0xb7,0x2f,0x47,0xb6,
+ 0x4d,0x04,0x65,0xaa,0xea,0x4c,0x7f,0xad,0x37,0x25,0x36,0xc8,0xba,0x51,0x6a,0x60,
+ 0x39,0xc3,0xc2,0xa3,0x9f,0x0e,0x4d,0x83,0x2b,0xe4,0x32,0xdf,0xa9,0xa7,0x06,0xa6,
+ 0xe5,0xc7,0xe1,0x9f,0x39,0x79,0x64,0xca,0x42,0x58,0x00,0x2f,0x7c,0x05,0x41,0xb5,
+ 0x90,0x31,0x6d,0xbc,0x56,0x22,0xb6,0xb2,0xa6,0xfe,0x7a,0x4a,0xbf,0xfd,0x96,0x10,
+ 0x5e,0xca,0x76,0xea,0x7b,0x98,0x81,0x6a,0xf0,0x74,0x8c,0x10,0xdf,0x04,0x8c,0xe0,
+ 0x12,0xd9,0x01,0x01,0x5a,0x51,0xf1,0x89,0xf3,0x88,0x81,0x45,0xc0,0x36,0x50,0xaa,
+ 0x23,0xce,0x89,0x4c,0x3b,0xd8,0x89,0xe0,0x30,0xd5,0x65,0x07,0x1c,0x59,0xf4,0x09,
+ 0xa9,0x98,0x1b,0x51,0x87,0x8f,0xd6,0xfc,0x11,0x06,0x24,0xdc,0xbc,0xde,0x0b,0xf7,
+ 0xa6,0x9c,0xcc,0xe3,0x8f,0xab,0xdf,0x86,0xf3,0xbe,0xf6,0x04,0x48,0x19,0xde,0x11),
+ chunk_from_chars(
+ 0xc6,0x50,0xdd,0xbb,0x06,0x01,0xc1,0x9c,0xa1,0x14,0x39,0xe1,0x64,0x0d,0xd9,0x31,
+ 0xf4,0x3c,0x51,0x8e,0xa5,0xbe,0xa7,0x0d,0x3d,0xcd,0xe5,0xf4,0x19,0x1f,0xe5,0x3f,
+ 0x00,0xcf,0x96,0x65,0x46,0xb7,0x2b,0xcc,0x7d,0x58,0xbe,0x2b,0x9b,0xad,0xef,0x28,
+ 0x74,0x39,0x54,0xe3,0xa4,0x4a,0x23,0xf8,0x80,0xe8,0xd4,0xf1,0xcf,0xce,0x2d,0x7a,
+ 0x61,0x45,0x2d,0x26,0xda,0x05,0x89,0x6f,0x0a,0x50,0xda,0x66,0xa2,0x39,0xa8,0xa1,
+ 0x88,0xb6,0xd8,0x25,0xb3,0x30,0x5a,0xd7,0x7b,0x73,0xfb,0xac,0x08,0x36,0xec,0xc6,
+ 0x09,0x87,0xfd,0x08,0x52,0x7c,0x1a,0x8e,0x80,0xd5,0x82,0x3e,0x65,0xca,0xfe,0x2a,
+ 0x3d,0x00),
+ chunk_from_chars(
+ 0xfc,0x02,0xc5,0x25,0x74,0x09,0x8f,0xbb,0xaf,0x8c,0xad,0x02,0x14,0x9d,0xef,0x0d,
+ 0x94,0xb7,0x96,0x5f),
+ chunk_from_chars(
+ 0x63,0x03,0x8e,0x1f,0xcc,0x69,0x1e,0x2f,0x9d,0xb3,0x57,0x0f,0xad,0xbc,0x01,0x35,
+ 0x63,0xdb,0x06,0xba),
+ },
+ /* 1023 octets */
+ { chunk_from_chars(
+ 0x30,0x47,0x02,0x01,0x00,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x04,0x3b,0x04,0x39,
+ 0x87,0x2d,0x09,0x37,0x80,0xf5,0xd3,0x73,0x0d,0xf7,0xc2,0x12,0x66,0x4b,0x37,0xb8,
+ 0xa0,0xf2,0x4f,0x56,0x81,0x0d,0xaa,0x83,0x82,0xcd,0x4f,0xa3,0xf7,0x76,0x34,0xec,
+ 0x44,0xdc,0x54,0xf1,0xc2,0xed,0x9b,0xea,0x86,0xfa,0xfb,0x76,0x32,0xd8,0xbe,0x19,
+ 0x9e,0xa1,0x65,0xf5,0xad,0x55,0xdd,0x9c,0xe8),
+ chunk_from_chars(
+ 0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0xa8,0x1b,0x2e,0x8a,
+ 0x70,0xa5,0xac,0x94,0xff,0xdb,0xcc,0x9b,0xad,0xfc,0x3f,0xeb,0x08,0x01,0xf2,0x58,
+ 0x57,0x8b,0xb1,0x14,0xad,0x44,0xec,0xe1,0xec,0x0e,0x79,0x9d,0xa0,0x8e,0xff,0xb8,
+ 0x1c,0x5d,0x68,0x5c,0x0c,0x56,0xf6,0x4e,0xec,0xae,0xf8,0xcd,0xf1,0x1c,0xc3,0x87,
+ 0x37,0x83,0x8c,0xf4,0x00),
+ chunk_from_chars(
+ 0x6d,0xdf,0x80,0x2e,0x1a,0xae,0x49,0x86,0x93,0x5f,0x7f,0x98,0x1b,0xa3,0xf0,0x35,
+ 0x1d,0x62,0x73,0xc0,0xa0,0xc2,0x2c,0x9c,0x0e,0x83,0x39,0x16,0x8e,0x67,0x54,0x12,
+ 0xa3,0xde,0xbf,0xaf,0x43,0x5e,0xd6,0x51,0x55,0x80,0x07,0xdb,0x43,0x84,0xb6,0x50,
+ 0xfc,0xc0,0x7e,0x3b,0x58,0x6a,0x27,0xa4,0xf7,0xa0,0x0a,0xc8,0xa6,0xfe,0xc2,0xcd,
+ 0x86,0xae,0x4b,0xf1,0x57,0x0c,0x41,0xe6,0xa4,0x0c,0x93,0x1d,0xb2,0x7b,0x2f,0xaa,
+ 0x15,0xa8,0xce,0xdd,0x52,0xcf,0xf7,0x36,0x2c,0x4e,0x6e,0x23,0xda,0xec,0x0f,0xbc,
+ 0x3a,0x79,0xb6,0x80,0x6e,0x31,0x6e,0xfc,0xc7,0xb6,0x81,0x19,0xbf,0x46,0xbc,0x76,
+ 0xa2,0x60,0x67,0xa5,0x3f,0x29,0x6d,0xaf,0xdb,0xdc,0x11,0xc7,0x7f,0x77,0x77,0xe9,
+ 0x72,0x66,0x0c,0xf4,0xb6,0xa9,0xb3,0x69,0xa6,0x66,0x5f,0x02,0xe0,0xcc,0x9b,0x6e,
+ 0xdf,0xad,0x13,0x6b,0x4f,0xab,0xe7,0x23,0xd2,0x81,0x3d,0xb3,0x13,0x6c,0xfd,0xe9,
+ 0xb6,0xd0,0x44,0x32,0x2f,0xee,0x29,0x47,0x95,0x2e,0x03,0x1b,0x73,0xab,0x5c,0x60,
+ 0x33,0x49,0xb3,0x07,0xbd,0xc2,0x7b,0xc6,0xcb,0x8b,0x8b,0xbd,0x7b,0xd3,0x23,0x21,
+ 0x9b,0x80,0x33,0xa5,0x81,0xb5,0x9e,0xad,0xeb,0xb0,0x9b,0x3c,0x4f,0x3d,0x22,0x77,
+ 0xd4,0xf0,0x34,0x36,0x24,0xac,0xc8,0x17,0x80,0x47,0x28,0xb2,0x5a,0xb7,0x97,0x17,
+ 0x2b,0x4c,0x5c,0x21,0xa2,0x2f,0x9c,0x78,0x39,0xd6,0x43,0x00,0x23,0x2e,0xb6,0x6e,
+ 0x53,0xf3,0x1c,0x72,0x3f,0xa3,0x7f,0xe3,0x87,0xc7,0xd3,0xe5,0x0b,0xdf,0x98,0x13,
+ 0xa3,0x0e,0x5b,0xb1,0x2c,0xf4,0xcd,0x93,0x0c,0x40,0xcf,0xb4,0xe1,0xfc,0x62,0x25,
+ 0x92,0xa4,0x95,0x88,0x79,0x44,0x94,0xd5,0x6d,0x24,0xea,0x4b,0x40,0xc8,0x9f,0xc0,
+ 0x59,0x6c,0xc9,0xeb,0xb9,0x61,0xc8,0xcb,0x10,0xad,0xde,0x97,0x6a,0x5d,0x60,0x2b,
+ 0x1c,0x3f,0x85,0xb9,0xb9,0xa0,0x01,0xed,0x3c,0x6a,0x4d,0x3b,0x14,0x37,0xf5,0x20,
+ 0x96,0xcd,0x19,0x56,0xd0,0x42,0xa5,0x97,0xd5,0x61,0xa5,0x96,0xec,0xd3,0xd1,0x73,
+ 0x5a,0x8d,0x57,0x0e,0xa0,0xec,0x27,0x22,0x5a,0x2c,0x4a,0xaf,0xf2,0x63,0x06,0xd1,
+ 0x52,0x6c,0x1a,0xf3,0xca,0x6d,0x9c,0xf5,0xa2,0xc9,0x8f,0x47,0xe1,0xc4,0x6d,0xb9,
+ 0xa3,0x32,0x34,0xcf,0xd4,0xd8,0x1f,0x2c,0x98,0x53,0x8a,0x09,0xeb,0xe7,0x69,0x98,
+ 0xd0,0xd8,0xfd,0x25,0x99,0x7c,0x7d,0x25,0x5c,0x6d,0x66,0xec,0xe6,0xfa,0x56,0xf1,
+ 0x11,0x44,0x95,0x0f,0x02,0x77,0x95,0xe6,0x53,0x00,0x8f,0x4b,0xd7,0xca,0x2d,0xee,
+ 0x85,0xd8,0xe9,0x0f,0x3d,0xc3,0x15,0x13,0x0c,0xe2,0xa0,0x03,0x75,0xa3,0x18,0xc7,
+ 0xc3,0xd9,0x7b,0xe2,0xc8,0xce,0x5b,0x6d,0xb4,0x1a,0x62,0x54,0xff,0x26,0x4f,0xa6,
+ 0x15,0x5b,0xae,0xe3,0xb0,0x77,0x3c,0x0f,0x49,0x7c,0x57,0x3f,0x19,0xbb,0x4f,0x42,
+ 0x40,0x28,0x1f,0x0b,0x1f,0x4f,0x7b,0xe8,0x57,0xa4,0xe5,0x9d,0x41,0x6c,0x06,0xb4,
+ 0xc5,0x0f,0xa0,0x9e,0x18,0x10,0xdd,0xc6,0xb1,0x46,0x7b,0xae,0xac,0x5a,0x36,0x68,
+ 0xd1,0x1b,0x6e,0xca,0xa9,0x01,0x44,0x00,0x16,0xf3,0x89,0xf8,0x0a,0xcc,0x4d,0xb9,
+ 0x77,0x02,0x5e,0x7f,0x59,0x24,0x38,0x8c,0x7e,0x34,0x0a,0x73,0x2e,0x55,0x44,0x40,
+ 0xe7,0x65,0x70,0xf8,0xdd,0x71,0xb7,0xd6,0x40,0xb3,0x45,0x0d,0x1f,0xd5,0xf0,0x41,
+ 0x0a,0x18,0xf9,0xa3,0x49,0x4f,0x70,0x7c,0x71,0x7b,0x79,0xb4,0xbf,0x75,0xc9,0x84,
+ 0x00,0xb0,0x96,0xb2,0x16,0x53,0xb5,0xd2,0x17,0xcf,0x35,0x65,0xc9,0x59,0x74,0x56,
+ 0xf7,0x07,0x03,0x49,0x7a,0x07,0x87,0x63,0x82,0x9b,0xc0,0x1b,0xb1,0xcb,0xc8,0xfa,
+ 0x04,0xea,0xdc,0x9a,0x6e,0x3f,0x66,0x99,0x58,0x7a,0x9e,0x75,0xc9,0x4e,0x5b,0xab,
+ 0x00,0x36,0xe0,0xb2,0xe7,0x11,0x39,0x2c,0xff,0x00,0x47,0xd0,0xd6,0xb0,0x5b,0xd2,
+ 0xa5,0x88,0xbc,0x10,0x97,0x18,0x95,0x42,0x59,0xf1,0xd8,0x66,0x78,0xa5,0x79,0xa3,
+ 0x12,0x0f,0x19,0xcf,0xb2,0x96,0x3f,0x17,0x7a,0xeb,0x70,0xf2,0xd4,0x84,0x48,0x26,
+ 0x26,0x2e,0x51,0xb8,0x02,0x71,0x27,0x20,0x68,0xef,0x5b,0x38,0x56,0xfa,0x85,0x35,
+ 0xaa,0x2a,0x88,0xb2,0xd4,0x1f,0x2a,0x0e,0x2f,0xda,0x76,0x24,0xc2,0x85,0x02,0x72,
+ 0xac,0x4a,0x2f,0x56,0x1f,0x8f,0x2f,0x7a,0x31,0x8b,0xfd,0x5c,0xaf,0x96,0x96,0x14,
+ 0x9e,0x4a,0xc8,0x24,0xad,0x34,0x60,0x53,0x8f,0xdc,0x25,0x42,0x1b,0xee,0xc2,0xcc,
+ 0x68,0x18,0x16,0x2d,0x06,0xbb,0xed,0x0c,0x40,0xa3,0x87,0x19,0x23,0x49,0xdb,0x67,
+ 0xa1,0x18,0xba,0xda,0x6c,0xd5,0xab,0x01,0x40,0xee,0x27,0x32,0x04,0xf6,0x28,0xaa,
+ 0xd1,0xc1,0x35,0xf7,0x70,0x27,0x9a,0x65,0x1e,0x24,0xd8,0xc1,0x4d,0x75,0xa6,0x05,
+ 0x9d,0x76,0xb9,0x6a,0x6f,0xd8,0x57,0xde,0xf5,0xe0,0xb3,0x54,0xb2,0x7a,0xb9,0x37,
+ 0xa5,0x81,0x5d,0x16,0xb5,0xfa,0xe4,0x07,0xff,0x18,0x22,0x2c,0x6d,0x1e,0xd2,0x63,
+ 0xbe,0x68,0xc9,0x5f,0x32,0xd9,0x08,0xbd,0x89,0x5c,0xd7,0x62,0x07,0xae,0x72,0x64,
+ 0x87,0x56,0x7f,0x9a,0x67,0xda,0xd7,0x9a,0xbe,0xc3,0x16,0xf6,0x83,0xb1,0x7f,0x2d,
+ 0x02,0xbf,0x07,0xe0,0xac,0x8b,0x5b,0xc6,0x16,0x2c,0xf9,0x46,0x97,0xb3,0xc2,0x7c,
+ 0xd1,0xfe,0xa4,0x9b,0x27,0xf2,0x3b,0xa2,0x90,0x18,0x71,0x96,0x25,0x06,0x52,0x0c,
+ 0x39,0x2d,0xa8,0xb6,0xad,0x0d,0x99,0xf7,0x01,0x3f,0xbc,0x06,0xc2,0xc1,0x7a,0x56,
+ 0x95,0x00,0xc8,0xa7,0x69,0x64,0x81,0xc1,0xcd,0x33,0xe9,0xb1,0x4e,0x40,0xb8,0x2e,
+ 0x79,0xa5,0xf5,0xdb,0x82,0x57,0x1b,0xa9,0x7b,0xae,0x3a,0xd3,0xe0,0x47,0x95,0x15,
+ 0xbb,0x0e,0x2b,0x0f,0x3b,0xfc,0xd1,0xfd,0x33,0x03,0x4e,0xfc,0x62,0x45,0xed,0xdd,
+ 0x7e,0xe2,0x08,0x6d,0xda,0xe2,0x60,0x0d,0x8c,0xa7,0x3e,0x21,0x4e,0x8c,0x2b,0x0b,
+ 0xdb,0x2b,0x04,0x7c,0x6a,0x46,0x4a,0x56,0x2e,0xd7,0x7b,0x73,0xd2,0xd8,0x41,0xc4,
+ 0xb3,0x49,0x73,0x55,0x12,0x57,0x71,0x3b,0x75,0x36,0x32,0xef,0xba,0x34,0x81,0x69,
+ 0xab,0xc9,0x0a,0x68,0xf4,0x26,0x11,0xa4,0x01,0x26,0xd7,0xcb,0x21,0xb5,0x86,0x95,
+ 0x56,0x81,0x86,0xf7,0xe5,0x69,0xd2,0xff,0x0f,0x9e,0x74,0x5d,0x04,0x87,0xdd,0x2e,
+ 0xb9,0x97,0xca,0xfc,0x5a,0xbf,0x9d,0xd1,0x02,0xe6,0x2f,0xf6,0x6c,0xba,0x87),
+ chunk_from_chars(
+ 0xe3,0x01,0x34,0x5a,0x41,0xa3,0x9a,0x4d,0x72,0xff,0xf8,0xdf,0x69,0xc9,0x80,0x75,
+ 0xa0,0xcc,0x08,0x2b,0x80,0x2f,0xc9,0xb2,0xb6,0xbc,0x50,0x3f,0x92,0x6b,0x65,0xbd,
+ 0xdf,0x7f,0x4c,0x8f,0x1c,0xb4,0x9f,0x63,0x96,0xaf,0xc8,0xa7,0x0a,0xbe,0x6d,0x8a,
+ 0xef,0x0d,0xb4,0x78,0xd4,0xc6,0xb2,0x97,0x00,0x76,0xc6,0xa0,0x48,0x4f,0xe7,0x6d,
+ 0x76,0xb3,0xa9,0x76,0x25,0xd7,0x9f,0x1c,0xe2,0x40,0xe7,0xc5,0x76,0x75,0x0d,0x29,
+ 0x55,0x28,0x28,0x6f,0x71,0x9b,0x41,0x3d,0xe9,0xad,0xa3,0xe8,0xeb,0x78,0xed,0x57,
+ 0x36,0x03,0xce,0x30,0xd8,0xbb,0x76,0x17,0x85,0xdc,0x30,0xdb,0xc3,0x20,0x86,0x9e,
+ 0x1a,0x00),
+ chunk_from_chars(
+ 0x89,0x30,0xb4,0x62,0xe0,0x28,0x45,0xf1,0x37,0xc0,0x0e,0x47,0xfe,0x64,0x3d,0x07,
+ 0x02,0x7b,0x66,0xec),
+ chunk_from_chars(
+ 0xc1,0x6c,0x19,0x0e,0x3e,0xe9,0x2c,0x5e,0xd0,0x35,0x19,0x93,0x77,0x2c,0xd6,0x38,
+ 0xf0,0xbc,0xe1,0x62),
+ },
+};
+
+START_TEST(test_ed448_sign)
+{
+ private_key_t *key;
+ public_key_t *pubkey, *public;
+ chunk_t sig, encoding, fp;
+
+ /* load private key */
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
+ BUILD_BLOB_ASN1_DER, sig_tests[_i].key, BUILD_END);
+ ck_assert(key != NULL);
+ ck_assert(key->get_encoding(key, PRIVKEY_ASN1_DER, &encoding));
+ ck_assert_chunk_eq(encoding, sig_tests[_i].key);
+ chunk_free(&encoding);
+
+ ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp));
+ ck_assert_chunk_eq(sig_tests[_i].fp_pk, fp);
+ ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &fp));
+ ck_assert_chunk_eq(sig_tests[_i].fp_spki, fp);
+
+ /* load public key */
+ pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
+ BUILD_BLOB_ASN1_DER, sig_tests[_i].pubkey, BUILD_END);
+ ck_assert(pubkey != NULL);
+ ck_assert(pubkey->get_encoding(pubkey, PUBKEY_SPKI_ASN1_DER, &encoding));
+ ck_assert_chunk_eq(encoding, sig_tests[_i].pubkey);
+ chunk_free(&encoding);
+
+ ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp));
+ ck_assert_chunk_eq(sig_tests[_i].fp_pk, fp);
+ ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_INFO_SHA1, &fp));
+ ck_assert_chunk_eq(sig_tests[_i].fp_spki, fp);
+
+ /* compare public keys */
+ public = key->get_public_key(key);
+ ck_assert(public != NULL);
+ ck_assert(public->equals(public, pubkey));
+
+ /* sign */
+ ck_assert(key->sign(key, SIGN_ED448, NULL, sig_tests[_i].msg, &sig));
+ ck_assert_chunk_eq(sig, sig_tests[_i].sig);
+
+ /* verify */
+ ck_assert(pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[_i].msg,
+ sig_tests[_i].sig));
+
+ /* cleanup */
+ key->destroy(key);
+ pubkey->destroy(pubkey);
+ public->destroy(public);
+ chunk_free(&sig);
+}
+END_TEST
+
+START_TEST(test_ed448_gen)
+{
+ private_key_t *key, *key2;
+ public_key_t *pubkey, *pubkey2;
+ chunk_t msg = chunk_from_str("Ed448"), sig, encoding, fp_priv, fp_pub;
+
+ /* generate private key */
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
+ BUILD_KEY_SIZE, 456, BUILD_END);
+ ck_assert(key != NULL);
+ ck_assert(key->get_type(key) == KEY_ED448);
+ ck_assert(key->get_keysize(key) == 456);
+ ck_assert(!key->get_encoding(key, PRIVKEY_PGP, &encoding));
+ ck_assert(key->get_encoding(key, PRIVKEY_PEM, &encoding));
+ ck_assert(encoding.ptr != NULL);
+ ck_assert(strstr(encoding.ptr, "PRIVATE KEY"));
+ chunk_free(&encoding);
+
+ /* clone private key */
+ key2 = key->get_ref(key);
+ ck_assert(key2);
+ key2->destroy(key2);
+
+ /* decryption not supported */
+ ck_assert(!key->decrypt(key, ENCRYPT_UNKNOWN, msg, NULL));
+
+ /* wrong signature scheme */
+ ck_assert(!key->sign(key, SIGN_ED25519, NULL, msg, &sig));
+
+ /* correct signature scheme*/
+ ck_assert(key->sign(key, SIGN_ED448, NULL, msg, &sig));
+
+ /* export public key */
+ pubkey = key->get_public_key(key);
+ ck_assert(pubkey != NULL);
+ ck_assert(pubkey->get_type(pubkey) == KEY_ED448);
+ ck_assert(pubkey->get_keysize(pubkey) == 456);
+ ck_assert(pubkey->get_encoding(pubkey, PUBKEY_PEM, &encoding));
+ ck_assert(encoding.ptr != NULL);
+ ck_assert(strstr(encoding.ptr, "PUBLIC KEY"));
+ chunk_free(&encoding);
+
+ /* generate and compare public and private key fingerprints */
+ ck_assert(!key->get_fingerprint(key, KEYID_PGPV4, &fp_priv));
+ ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp_priv));
+ ck_assert(key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp_priv));
+ ck_assert(fp_priv.ptr != NULL);
+ ck_assert(!pubkey->get_fingerprint(pubkey, KEYID_PGPV4, &fp_pub));
+ ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp_pub));
+ ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp_pub));
+ ck_assert(fp_pub.ptr != NULL);
+ ck_assert_chunk_eq(fp_pub, fp_priv);
+
+ /* clone public key */
+ pubkey2 = pubkey->get_ref(pubkey);
+ ck_assert(pubkey2 != NULL);
+ pubkey2->destroy(pubkey2);
+
+ /* encryption not supported */
+ ck_assert(!pubkey->encrypt(pubkey, ENCRYPT_UNKNOWN, msg, NULL));
+
+ /* verify with wrong signature scheme */
+ ck_assert(!pubkey->verify(pubkey, SIGN_ED25519, NULL, msg, sig));
+
+ /* verify with correct signature scheme */
+ ck_assert(pubkey->verify(pubkey, SIGN_ED448, NULL, msg, sig));
+
+ /* cleanup */
+ key->destroy(key);
+ pubkey->destroy(pubkey);
+ chunk_free(&sig);
+}
+END_TEST
+
+START_TEST(test_ed448_speed)
+{
+ private_key_t *key;
+ public_key_t *pubkey;
+ chunk_t msg = chunk_from_str("Hello Ed448"), sig;
+ int i, count = 500;
+
+#ifdef HAVE_CLOCK_GETTIME
+ struct timespec start, stop;
+ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start);
+#endif
+
+ for (i = 0; i < count; i++)
+ {
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
+ BUILD_KEY_SIZE, 456, BUILD_END);
+ ck_assert(key != NULL);
+ ck_assert(key->sign(key, SIGN_ED448, NULL, msg, &sig));
+ pubkey = key->get_public_key(key);
+ ck_assert(pubkey != NULL);
+ ck_assert(pubkey->verify(pubkey, SIGN_ED448, NULL, msg, sig));
+ key->destroy(key);
+ pubkey->destroy(pubkey);
+ chunk_free(&sig);
+ }
+
+#ifdef HAVE_CLOCK_GETTIME
+ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &stop);
+ DBG0(DBG_LIB, "%d Ed448 keys and signatures in %d ms\n", count,
+ (stop.tv_nsec - start.tv_nsec) / 1000000 +
+ (stop.tv_sec - start.tv_sec) * 1000);
+#endif
+}
+END_TEST
+
+static chunk_t zero_pk = chunk_from_chars(
+ 0x30,0x43,0x30,0x05,0x06,0x03,0x2b,0x65,0x71,0x03,0x3a,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00);
+
+/* sig_tests[0].sig with s+L, note that only the 9 most significant bits are 0 */
+static chunk_t malleable_sig = chunk_from_chars(
+ 0x53,0x3a,0x37,0xf6,0xbb,0xe4,0x57,0x25,0x1f,0x02,0x3c,0x0d,0x88,0xf9,0x76,0xae,
+ 0x2d,0xfb,0x50,0x4a,0x84,0x3e,0x34,0xd2,0x07,0x4f,0xd8,0x23,0xd4,0x1a,0x59,0x1f,
+ 0x2b,0x23,0x3f,0x03,0x4f,0x62,0x82,0x81,0xf2,0xfd,0x7a,0x22,0xdd,0xd4,0x7d,0x78,
+ 0x28,0xc5,0x9b,0xd0,0xa2,0x1b,0xfd,0x39,0x80,0xf2,0x52,0x78,0xd3,0x66,0x74,0x03,
+ 0xc1,0x4b,0xce,0xc5,0xf9,0xcf,0xde,0x99,0x55,0xeb,0xc8,0x33,0x3c,0x0a,0xe7,0x8f,
+ 0xc8,0x6e,0x51,0x83,0x17,0xc5,0xc7,0xcd,0xda,0x85,0x30,0xa1,0x13,0xa0,0xf4,0xdb,
+ 0xb6,0x11,0x49,0xf0,0x5a,0x73,0x63,0x26,0x8c,0x71,0xd9,0x58,0x08,0xff,0x2e,0x65,
+ 0x66,0x00);
+
+START_TEST(test_ed448_fail)
+{
+ private_key_t *key;
+ public_key_t *pubkey;
+ chunk_t blob, sig;
+ uint8_t sig1[114];
+
+ /* Invalid private key format */
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
+ BUILD_BLOB_ASN1_DER, chunk_empty, BUILD_END);
+ ck_assert(key == NULL);
+
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
+ BUILD_EDDSA_PRIV_ASN1_DER, chunk_empty, BUILD_END);
+ ck_assert(key == NULL);
+
+ blob = chunk_from_chars(0x04, 0x01, 0x9d);
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ED448,
+ BUILD_EDDSA_PRIV_ASN1_DER, blob, BUILD_END);
+ ck_assert(key == NULL);
+
+ /* Invalid public key format */
+ pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
+ BUILD_BLOB_ASN1_DER, chunk_empty, BUILD_END);
+ ck_assert(pubkey == NULL);
+
+ blob = chunk_from_chars(0x30, 0x0b, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
+ 0x71, 0x03, 0x02, 0x00, 0xd7);
+ pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
+ BUILD_BLOB_ASN1_DER, blob, BUILD_END);
+ ck_assert(pubkey == NULL);
+
+ blob = chunk_from_chars(0x30, 0x0b, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x00,
+ 0x71, 0x03, 0x02, 0x00, 0xd7);
+ pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
+ BUILD_BLOB_ASN1_DER, blob, BUILD_END);
+ ck_assert(pubkey == NULL);
+
+ pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
+ BUILD_KEY_SIZE, 456, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
+ ck_assert(pubkey == NULL);
+
+ /* Invalid signature format */
+ pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
+ BUILD_BLOB_ASN1_DER, sig_tests[0].pubkey, BUILD_END);
+ ck_assert(pubkey != NULL);
+
+ ck_assert(!pubkey->verify(pubkey, SIGN_ED448, NULL, chunk_empty,
+ chunk_empty));
+
+ /* RFC 8032, section 5.2.7 requires that 0 <= s < L to prevent signature
+ * malleability. Only a warning because OpenSSL is vulnerable to this. */
+ if (pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[0].msg,
+ malleable_sig))
+ {
+ warn("Ed448 signature verification is vulnerable to malleable "
+ "signatures");
+ }
+
+ /* malformed signature */
+ sig = chunk_from_thing(sig1);
+ memcpy(sig1, sig_tests[0].sig.ptr, sig_tests[0].sig.len);
+ sig1[113] |= 0xFF;
+ ck_assert(!pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[0].msg,
+ sig));
+
+ /* wrong signature */
+ memcpy(sig1, sig_tests[0].sig.ptr, sig_tests[0].sig.len);
+ sig1[0] = 0xe4;
+ ck_assert(!pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[0].msg,
+ sig));
+
+ /* detect all-zeroes public key */
+ pubkey->destroy(pubkey);
+ pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED448,
+ BUILD_BLOB_ASN1_DER, zero_pk, BUILD_END);
+ ck_assert(pubkey != NULL);
+ ck_assert(!pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[0].msg,
+ sig));
+ pubkey->destroy(pubkey);
+}
+END_TEST
+
+Suite *ed448_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("ed448");
+
+ tc = tcase_create("ed448_sign");
+ tcase_add_loop_test(tc, test_ed448_sign, 0, countof(sig_tests));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("ed448_gen");
+ tcase_add_test(tc, test_ed448_gen);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("ed448_fail");
+ tcase_add_test(tc, test_ed448_fail);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("ed448_speed");
+ test_case_set_timeout(tc, 10);
+ tcase_add_test(tc, test_ed448_speed);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/tests/suites/test_rsa.c b/src/libstrongswan/tests/suites/test_rsa.c
index e6dc7744a..a71fa0ce5 100644
--- a/src/libstrongswan/tests/suites/test_rsa.c
+++ b/src/libstrongswan/tests/suites/test_rsa.c
@@ -40,7 +40,7 @@ static signature_scheme_t schemes[] = {
static rsa_pss_params_t default_pss_params = {
.hash = HASH_SHA256,
.mgf1_hash = HASH_SHA256,
- .salt_len = RSA_PSS_SALT_LEN_DEFAULT,
+ .salt_len = HASH_SIZE_SHA256,
};
/**
diff --git a/src/libstrongswan/tests/suites/test_signature_params.c b/src/libstrongswan/tests/suites/test_signature_params.c
index 38cb5803f..cbf1a2861 100644
--- a/src/libstrongswan/tests/suites/test_signature_params.c
+++ b/src/libstrongswan/tests/suites/test_signature_params.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Tobias Brunner
+ * Copyright (C) 2017-2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -138,27 +138,27 @@ static struct {
0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,
0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0xa2,0x03,
0x02,0x01,0x20),
- { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA256, }},
/* default salt length: SHA-1 */
{ chunk_from_chars(0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x00),
- { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA1, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA1, }},
/* default salt length: SHA-224 */
{ chunk_from_chars(0x30,0x23,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x16,0xa0,
0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,
0xa2,0x03,0x02,0x01,0x1c),
- { .hash = HASH_SHA224, .mgf1_hash = HASH_SHA1, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ { .hash = HASH_SHA224, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA224, }},
/* default salt length: SHA-384 */
{ chunk_from_chars(0x30,0x23,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x16,0xa0,
0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,
0xa2,0x03,0x02,0x01,0x30),
- { .hash = HASH_SHA384, .mgf1_hash = HASH_SHA1, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ { .hash = HASH_SHA384, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA384, }},
/* SHA-512 */
{ chunk_from_chars(0x30,0x41,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x34,0xa0,
0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,
0xa1,0x1c,0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x08,0x30,
0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0xa2,0x03,
0x02,0x01,0x40),
- { .hash = HASH_SHA512, .mgf1_hash = HASH_SHA512, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ { .hash = HASH_SHA512, .mgf1_hash = HASH_SHA512, .salt_len = HASH_SIZE_SHA512, }},
/* SHA-256, no salt */
{ chunk_from_chars(0x30,0x41,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0a,0x30,0x34,0xa0,
0x0f,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,
@@ -199,6 +199,8 @@ rsa_pss_params_t rsa_pss_build_invalid_tests[] = {
{ .hash = HASH_UNKNOWN, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA1, },
/* invalid mgf */
{ .hash = HASH_SHA256, .mgf1_hash = HASH_UNKNOWN, .salt_len = HASH_SIZE_SHA256, },
+ /* undetermined salt */
+ { .hash = HASH_UNKNOWN, .mgf1_hash = HASH_SHA1, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, },
};
START_TEST(test_rsa_pss_params_build_invalid)
@@ -209,6 +211,49 @@ START_TEST(test_rsa_pss_params_build_invalid)
}
END_TEST
+
+static struct {
+ ssize_t expected;
+ size_t modbits;
+ rsa_pss_params_t params;
+} rsa_pss_salt_len_tests[] = {
+ { HASH_SIZE_SHA256, 0,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ { HASH_SIZE_SHA256, 3072,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_DEFAULT, }},
+ { -1, 0,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_MAX, }},
+ { 0, 256,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_MAX, }},
+ { 350, 3071,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_MAX, }},
+ { 350, 3072,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_MAX, }},
+ { 350, 3073,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_MAX, }},
+ { 478, 4096,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = RSA_PSS_SALT_LEN_MAX, }},
+ { 10, 0,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = 10, }},
+ { 10, 3072,
+ { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = 10, }},
+};
+
+START_TEST(test_rsa_pss_params_set_salt_len)
+{
+ if (rsa_pss_params_set_salt_len(&rsa_pss_salt_len_tests[_i].params,
+ rsa_pss_salt_len_tests[_i].modbits))
+ {
+ ck_assert_int_eq(rsa_pss_salt_len_tests[_i].expected,
+ rsa_pss_salt_len_tests[_i].params.salt_len);
+ }
+ else
+ {
+ ck_assert(rsa_pss_salt_len_tests[_i].expected < 0);
+ }
+}
+END_TEST
+
static rsa_pss_params_t rsa_pss_params_sha1 = { .hash = HASH_SHA1, .mgf1_hash = HASH_SHA1, .salt_len = HASH_SIZE_SHA1, };
static rsa_pss_params_t rsa_pss_params_sha256 = { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA256, };
static rsa_pss_params_t rsa_pss_params_sha256_mgf1 = { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA512, .salt_len = HASH_SIZE_SHA256, };
@@ -430,6 +475,10 @@ Suite *signature_params_suite_create()
tcase_add_loop_test(tc, test_rsa_pss_params_build_invalid, 0, countof(rsa_pss_build_invalid_tests));
suite_add_tcase(s, tc);
+ tc = tcase_create("rsa/pss salt len");
+ tcase_add_loop_test(tc, test_rsa_pss_params_set_salt_len, 0, countof(rsa_pss_salt_len_tests));
+ suite_add_tcase(s, tc);
+
tc = tcase_create("params compare");
tcase_add_loop_test(tc, test_params_compare, 0, countof(params_compare_tests));
tcase_add_test(tc, test_params_compare_null);
diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h
index 9fc38d480..26ff161a4 100644
--- a/src/libstrongswan/tests/tests.h
+++ b/src/libstrongswan/tests/tests.h
@@ -52,5 +52,6 @@ TEST_SUITE_DEPEND(mgf1_sha256_suite_create, XOF, XOF_MGF1_SHA256)
TEST_SUITE_DEPEND(ntru_suite_create, DH, NTRU_112_BIT)
TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://")
TEST_SUITE_DEPEND(ed25519_suite_create, PRIVKEY_GEN, KEY_ED25519)
+TEST_SUITE_DEPEND(ed448_suite_create, PRIVKEY_GEN, KEY_ED448)
TEST_SUITE(signature_params_suite_create)
diff --git a/src/libstrongswan/utils/chunk.h b/src/libstrongswan/utils/chunk.h
index e60cd8ad0..0dbe9dc80 100644
--- a/src/libstrongswan/utils/chunk.h
+++ b/src/libstrongswan/utils/chunk.h
@@ -332,7 +332,7 @@ static inline bool chunk_equals_ptr(chunk_t *a, chunk_t *b)
}
/**
- * Increment a chunk, as it would reprensent a network order integer.
+ * Increment a chunk, as it would represent a network order integer.
*
* @param chunk chunk to increment
* @return TRUE if an overflow occurred
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c
index efeb0f478..63b7453f3 100644
--- a/src/libstrongswan/utils/leak_detective.c
+++ b/src/libstrongswan/utils/leak_detective.c
@@ -582,6 +582,16 @@ static char *whitelist[] = {
"OPENSSL_init_crypto",
"CRYPTO_THREAD_lock_new",
"ERR_add_error_data",
+ "ERR_set_mark",
+ "ENGINE_load_builtin_engines",
+ "OPENSSL_load_builtin_modules",
+ "CONF_modules_load_file",
+ "CONF_module_add",
+ "RAND_DRBG_bytes",
+ "RAND_DRBG_generate",
+ "RAND_DRBG_get0_master",
+ "RAND_DRBG_get0_private",
+ "RAND_DRBG_get0_public",
/* OpenSSL libssl */
"SSL_COMP_get_compression_methods",
/* NSPR */
@@ -619,6 +629,7 @@ static char *whitelist[] = {
"botan_privkey_create_ecdsa",
"botan_privkey_create_ecdh",
"botan_privkey_load_ecdh",
+ "botan_privkey_load",
};
/**
@@ -673,7 +684,8 @@ static int print_traces(private_leak_detective_t *this,
int leaks = 0;
memory_header_t *hdr;
enumerator_t *enumerator;
- hashtable_t *entries;
+ hashtable_t *entries, *ignored = NULL;
+ backtrace_t *bt;
struct {
/** associated backtrace */
backtrace_t *backtrace;
@@ -688,15 +700,32 @@ static int print_traces(private_leak_detective_t *this,
entries = hashtable_create((hashtable_hash_t)hash,
(hashtable_equals_t)equals, 1024);
+ if (whitelisted)
+ {
+ ignored = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 1024);
+ }
+
lock->lock(lock);
for (hdr = first_header.next; hdr != NULL; hdr = hdr->next)
{
- if (whitelisted &&
- hdr->backtrace->contains_function(hdr->backtrace,
- whitelist, countof(whitelist)))
+ if (whitelisted)
{
- (*whitelisted)++;
- continue;
+ bt = ignored->get(ignored, hdr->backtrace);
+ if (!bt)
+ {
+ if (hdr->backtrace->contains_function(hdr->backtrace, whitelist,
+ countof(whitelist)))
+ {
+ bt = hdr->backtrace;
+ ignored->put(ignored, bt, bt);
+ }
+ }
+ if (bt)
+ {
+ (*whitelisted)++;
+ continue;
+ }
}
entry = entries->get(entries, hdr->backtrace);
if (entry)
@@ -720,6 +749,7 @@ static int print_traces(private_leak_detective_t *this,
leaks++;
}
lock->unlock(lock);
+ DESTROY_IF(ignored);
enumerator = entries->create_enumerator(entries);
while (enumerator->enumerate(enumerator, NULL, &entry))
diff --git a/src/libtpmtss/plugins/tpm/tpm_private_key.c b/src/libtpmtss/plugins/tpm/tpm_private_key.c
index 3b7582ae3..d946fbe56 100644
--- a/src/libtpmtss/plugins/tpm/tpm_private_key.c
+++ b/src/libtpmtss/plugins/tpm/tpm_private_key.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2017 Andreas Steffen
+ * Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2017-2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -75,6 +76,12 @@ METHOD(private_key_t, get_keysize, int,
return this->pubkey->get_keysize(this->pubkey);
}
+METHOD(private_key_t, supported_signature_schemes, enumerator_t*,
+ private_tpm_private_key_t *this)
+{
+ return this->tpm->supported_signature_schemes(this->tpm, this->handle);
+}
+
METHOD(private_key_t, sign, bool,
private_tpm_private_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t *signature)
@@ -201,6 +208,7 @@ tpm_private_key_t *tpm_private_key_connect(key_type_t type, va_list args)
.sign = _sign,
.decrypt = _decrypt,
.get_keysize = _get_keysize,
+ .supported_signature_schemes = _supported_signature_schemes,
.get_public_key = _get_public_key,
.equals = private_key_equals,
.belongs_to = private_key_belongs_to,
diff --git a/src/libtpmtss/tpm_tss.h b/src/libtpmtss/tpm_tss.h
index 11e4a7c15..aab7a4d6c 100644
--- a/src/libtpmtss/tpm_tss.h
+++ b/src/libtpmtss/tpm_tss.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2016 Andreas Steffen
+ * Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2016-2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -80,6 +81,15 @@ struct tpm_tss_t {
chunk_t (*get_public)(tpm_tss_t *this, uint32_t handle);
/**
+ * Return signature schemes supported by the given key (TPM 2.0 only)
+ *
+ * @param handle key object handle
+ * @return enumerator over signature_params_t*
+ */
+ enumerator_t *(*supported_signature_schemes)(tpm_tss_t *this,
+ uint32_t handle);
+
+ /**
* Retrieve the current value of a PCR register in a given PCR bank
*
* @param pcr_num PCR number
diff --git a/src/libtpmtss/tpm_tss_trousers.c b/src/libtpmtss/tpm_tss_trousers.c
index 81e542d02..937373354 100644
--- a/src/libtpmtss/tpm_tss_trousers.c
+++ b/src/libtpmtss/tpm_tss_trousers.c
@@ -390,6 +390,12 @@ METHOD(tpm_tss_t, get_public, chunk_t,
return aik_pubkey;
}
+METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*,
+ private_tpm_tss_trousers_t *this, uint32_t handle)
+{
+ return enumerator_create_empty();
+}
+
METHOD(tpm_tss_t, read_pcr, bool,
private_tpm_tss_trousers_t *this, uint32_t pcr_num, chunk_t *pcr_value,
hash_algorithm_t alg)
@@ -642,6 +648,7 @@ tpm_tss_t *tpm_tss_trousers_create()
.get_version_info = _get_version_info,
.generate_aik = _generate_aik,
.get_public = _get_public,
+ .supported_signature_schemes = _supported_signature_schemes,
.read_pcr = _read_pcr,
.extend_pcr = _extend_pcr,
.quote = _quote,
diff --git a/src/libtpmtss/tpm_tss_tss2_v1.c b/src/libtpmtss/tpm_tss_tss2_v1.c
index 9ed2798f7..f904442ed 100644
--- a/src/libtpmtss/tpm_tss_tss2_v1.c
+++ b/src/libtpmtss/tpm_tss_tss2_v1.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2018 Tobias Brunner
* Copyright (C) 2016-2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
@@ -24,9 +25,9 @@
#include <tpm20.h>
-#ifdef TSS2_TCTI_TABRMD_V1
+#ifdef TSS2_TCTI_TABRMD
#include <tcti/tcti-tabrmd.h>
-#endif /* TSS2_TCTI_TABRMD_V1 */
+#endif /* TSS2_TCTI_TABRMD */
#ifdef TSS2_TCTI_SOCKET
#include <tcti_socket.h>
@@ -68,6 +69,12 @@ struct private_tpm_tss_tss2_t {
* List of supported algorithms
*/
TPM_ALG_ID supported_algs[TPM_PT_ALGORITHM_SET];
+
+ /**
+ * Is TPM FIPS 186-4 compliant ?
+ */
+ bool fips_186_4;
+
};
/**
@@ -153,6 +160,7 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
TPMS_TAGGED_PROPERTY tp;
TPMI_YES_NO more_data;
TPM_ALG_ID alg;
+ bool fips_140_2 = FALSE;
uint32_t rval, i, offset, revision = 0, year = 0;
size_t len = BUF_LEN;
char buf[BUF_LEN], manufacturer[5], vendor_string[17];
@@ -193,12 +201,25 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
offset = 4 * (tp.property - TPM_PT_VENDOR_STRING_1);
htoun32(vendor_string + offset, tp.value);
break;
+ case TPM_PT_MODES:
+ if (tp.value & TPMA_MODES_FIPS_140_2)
+ {
+ this->fips_186_4 = fips_140_2 = TRUE;
+ }
+ break;
default:
break;
}
}
- DBG2(DBG_PTS, "%s manufacturer: %s (%s) rev: %05.2f %u", LABEL, manufacturer,
- vendor_string, (float)revision/100, year);
+
+ if (!fips_140_2)
+ {
+ this->fips_186_4 = lib->settings->get_bool(lib->settings,
+ "%s.plugins.tpm.fips_186_4", FALSE, lib->ns);
+ }
+ DBG2(DBG_PTS, "%s manufacturer: %s (%s) rev: %05.2f %u %s", LABEL,
+ manufacturer, vendor_string, (float)revision/100, year,
+ fips_140_2 ? "FIPS 140-2" : (this->fips_186_4 ? "FIPS 186-4" : ""));
/* get supported algorithms */
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ALGS,
@@ -400,7 +421,7 @@ METHOD(tpm_tss_t, get_version_info, chunk_t,
}
/**
- * read the public key portion of a TSS 2.0 AIK key from NVRAM
+ * read the public key portion of a TSS 2.0 key from NVRAM
*/
bool read_public(private_tpm_tss_tss2_t *this, TPMI_DH_OBJECT handle,
TPM2B_PUBLIC *public)
@@ -450,9 +471,9 @@ METHOD(tpm_tss_t, get_public, chunk_t,
}
aik_blob = chunk_create((u_char*)&public, sizeof(public));
- DBG3(DBG_LIB, "%s AIK public key blob: %B", LABEL, &aik_blob);
+ DBG3(DBG_LIB, "%s public key blob: %B", LABEL, &aik_blob);
- /* convert TSS 2.0 AIK public key blot into PKCS#1 format */
+ /* convert TSS 2.0 public key blot into PKCS#1 format */
switch (public.t.publicArea.type)
{
case TPM_ALG_RSA:
@@ -469,12 +490,12 @@ METHOD(tpm_tss_t, get_public, chunk_t,
aik_modulus = chunk_create(rsa->t.buffer, rsa->t.size);
aik_exponent = chunk_from_chars(0x01, 0x00, 0x01);
- /* subjectPublicKeyInfo encoding of AIK RSA key */
+ /* subjectPublicKeyInfo encoding of RSA public key */
if (!lib->encoding->encode(lib->encoding, PUBKEY_SPKI_ASN1_DER,
NULL, &aik_pubkey, CRED_PART_RSA_MODULUS, aik_modulus,
CRED_PART_RSA_PUB_EXP, aik_exponent, CRED_PART_END))
{
- DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of AIK key "
+ DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of public key "
"failed", LABEL);
return chunk_empty;
}
@@ -505,7 +526,7 @@ METHOD(tpm_tss_t, get_public, chunk_t,
pos += ecc->x.t.size;
/* copy y coordinate of ECC point */
memcpy(pos, ecc->y.t.buffer, ecc->y.t.size);
- /* subjectPublicKeyInfo encoding of AIK ECC key */
+ /* subjectPublicKeyInfo encoding of ECC public key */
aik_pubkey = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_EC_PUBLICKEY),
@@ -515,14 +536,101 @@ METHOD(tpm_tss_t, get_public, chunk_t,
break;
}
default:
- DBG1(DBG_PTS, "%s unsupported AIK key type", LABEL);
+ DBG1(DBG_PTS, "%s unsupported key type", LABEL);
return chunk_empty;
}
- DBG1(DBG_PTS, "AIK signature algorithm is %N with %N hash",
+ DBG1(DBG_PTS, "signature algorithm is %N with %N hash",
tpm_alg_id_names, sig_alg, tpm_alg_id_names, digest_alg);
return aik_pubkey;
}
+METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*,
+ private_tpm_tss_tss2_t *this, uint32_t handle)
+{
+ TPM2B_PUBLIC public = { { 0, } };
+ hash_algorithm_t digest;
+ signature_params_t supported_scheme;
+
+ if (!read_public(this, handle, &public))
+ {
+ return enumerator_create_empty();
+ }
+
+ switch (public.t.publicArea.type)
+ {
+ case TPM_ALG_RSA:
+ {
+ TPMS_RSA_PARMS *rsa;
+ TPMT_RSA_SCHEME *scheme;
+
+ rsa = &public.t.publicArea.parameters.rsaDetail;
+ scheme = &rsa->scheme;
+ digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg);
+
+ switch (scheme->scheme)
+ {
+ case TPM_ALG_RSAPSS:
+ {
+ ssize_t salt_len;
+
+ salt_len = this->fips_186_4 ? RSA_PSS_SALT_LEN_DEFAULT :
+ RSA_PSS_SALT_LEN_MAX;
+ rsa_pss_params_t pss_params = {
+ .hash = digest,
+ .mgf1_hash = digest,
+ .salt_len = salt_len,
+ };
+ supported_scheme = (signature_params_t){
+ .scheme = SIGN_RSA_EMSA_PSS,
+ .params = &pss_params,
+ };
+ if (!rsa_pss_params_set_salt_len(&pss_params, rsa->keyBits))
+ {
+ return enumerator_create_empty();
+ }
+ break;
+ }
+ case TPM_ALG_RSASSA:
+ supported_scheme = (signature_params_t){
+ .scheme = signature_scheme_from_oid(
+ hasher_signature_algorithm_to_oid(digest,
+ KEY_RSA)),
+ };
+ break;
+ default:
+ return enumerator_create_empty();
+ }
+ break;
+ }
+ case TPM_ALG_ECC:
+ {
+ TPMT_ECC_SCHEME *scheme;
+
+ scheme = &public.t.publicArea.parameters.eccDetail.scheme;
+ digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg);
+
+ switch (scheme->scheme)
+ {
+ case TPM_ALG_ECDSA:
+ supported_scheme = (signature_params_t){
+ .scheme = signature_scheme_from_oid(
+ hasher_signature_algorithm_to_oid(digest,
+ KEY_ECDSA)),
+ };
+ break;
+ default:
+ return enumerator_create_empty();
+ }
+ break;
+ }
+ default:
+ DBG1(DBG_PTS, "%s unsupported key type", LABEL);
+ return enumerator_create_empty();
+ }
+ return enumerator_create_single(signature_params_clone(&supported_scheme),
+ (void*)signature_params_destroy);
+}
+
/**
* Configure a PCR Selection assuming a maximum of 24 registers
*/
@@ -809,7 +917,7 @@ METHOD(tpm_tss_t, quote, bool,
DBG1(DBG_PTS, "%s unsupported %N signature algorithm",
LABEL, tpm_alg_id_names, sig.sigAlg);
return FALSE;
- };
+ }
DBG2(DBG_PTS, "PCR digest algorithm is %N", tpm_alg_id_names, hash_alg);
pcr_digest_alg = hash_alg_from_tpm_alg_id(hash_alg);
@@ -1036,7 +1144,7 @@ METHOD(tpm_tss_t, sign, bool,
DBG1(DBG_PTS, "%s unsupported %N signature scheme",
LABEL, signature_scheme_names, scheme);
return FALSE;
- };
+ }
return TRUE;
}
@@ -1174,6 +1282,7 @@ tpm_tss_t *tpm_tss_tss2_create()
.get_version_info = _get_version_info,
.generate_aik = _generate_aik,
.get_public = _get_public,
+ .supported_signature_schemes = _supported_signature_schemes,
.read_pcr = _read_pcr,
.extend_pcr = _extend_pcr,
.quote = _quote,
diff --git a/src/libtpmtss/tpm_tss_tss2_v2.c b/src/libtpmtss/tpm_tss_tss2_v2.c
index 7cb0d48a9..6bbbce238 100644
--- a/src/libtpmtss/tpm_tss_tss2_v2.c
+++ b/src/libtpmtss/tpm_tss_tss2_v2.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2018 Tobias Brunner
* Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
@@ -64,6 +65,12 @@ struct private_tpm_tss_tss2_t {
* List of supported algorithms
*/
TPM2_ALG_ID supported_algs[TPM2_PT_ALGORITHM_SET];
+
+ /**
+ * Is TPM FIPS 186-4 compliant ?
+ */
+ bool fips_186_4;
+
};
/**
@@ -152,6 +159,7 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
TPMS_TAGGED_PROPERTY tp;
TPMI_YES_NO more_data;
TPM2_ALG_ID alg;
+ bool fips_140_2 = FALSE;
uint32_t rval, i, offset, revision = 0, year = 0;
size_t len = BUF_LEN;
char buf[BUF_LEN], manufacturer[5], vendor_string[17];
@@ -193,12 +201,25 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
offset = 4 * (tp.property - TPM2_PT_VENDOR_STRING_1);
htoun32(vendor_string + offset, tp.value);
break;
+ case TPM2_PT_MODES:
+ if (tp.value & TPMA_MODES_FIPS_140_2)
+ {
+ this->fips_186_4 = fips_140_2 = TRUE;
+ }
+ break;
default:
break;
}
}
- DBG2(DBG_PTS, "%s manufacturer: %s (%s) rev: %05.2f %u", LABEL, manufacturer,
- vendor_string, (float)revision/100, year);
+
+ if (!fips_140_2)
+ {
+ this->fips_186_4 = lib->settings->get_bool(lib->settings,
+ "%s.plugins.tpm.fips_186_4", FALSE, lib->ns);
+ }
+ DBG2(DBG_PTS, "%s manufacturer: %s (%s) rev: %05.2f %u %s", LABEL,
+ manufacturer, vendor_string, (float)revision/100, year,
+ fips_140_2 ? "FIPS 140-2" : (this->fips_186_4 ? "FIPS 186-4" : ""));
/* get supported algorithms */
rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM2_CAP_ALGS,
@@ -360,7 +381,7 @@ METHOD(tpm_tss_t, get_version_info, chunk_t,
}
/**
- * read the public key portion of a TSS 2.0 AIK key from NVRAM
+ * read the public key portion of a TSS 2.0 key from NVRAM
*/
bool read_public(private_tpm_tss_tss2_t *this, TPMI_DH_OBJECT handle,
TPM2B_PUBLIC *public)
@@ -404,9 +425,9 @@ METHOD(tpm_tss_t, get_public, chunk_t,
}
aik_blob = chunk_create((u_char*)&public, sizeof(public));
- DBG3(DBG_LIB, "%s AIK public key blob: %B", LABEL, &aik_blob);
+ DBG3(DBG_LIB, "%s public key blob: %B", LABEL, &aik_blob);
- /* convert TSS 2.0 AIK public key blot into PKCS#1 format */
+ /* convert TSS 2.0 public key blot into PKCS#1 format */
switch (public.publicArea.type)
{
case TPM2_ALG_RSA:
@@ -423,12 +444,12 @@ METHOD(tpm_tss_t, get_public, chunk_t,
aik_modulus = chunk_create(rsa->buffer, rsa->size);
aik_exponent = chunk_from_chars(0x01, 0x00, 0x01);
- /* subjectPublicKeyInfo encoding of AIK RSA key */
+ /* subjectPublicKeyInfo encoding of RSA public key */
if (!lib->encoding->encode(lib->encoding, PUBKEY_SPKI_ASN1_DER,
NULL, &aik_pubkey, CRED_PART_RSA_MODULUS, aik_modulus,
CRED_PART_RSA_PUB_EXP, aik_exponent, CRED_PART_END))
{
- DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of AIK key "
+ DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of public key "
"failed", LABEL);
return chunk_empty;
}
@@ -459,7 +480,7 @@ METHOD(tpm_tss_t, get_public, chunk_t,
pos += ecc->x.size;
/* copy y coordinate of ECC point */
memcpy(pos, ecc->y.buffer, ecc->y.size);
- /* subjectPublicKeyInfo encoding of AIK ECC key */
+ /* subjectPublicKeyInfo encoding of ECC public key */
aik_pubkey = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_EC_PUBLICKEY),
@@ -469,14 +490,101 @@ METHOD(tpm_tss_t, get_public, chunk_t,
break;
}
default:
- DBG1(DBG_PTS, "%s unsupported AIK key type", LABEL);
+ DBG1(DBG_PTS, "%s unsupported key type", LABEL);
return chunk_empty;
}
- DBG1(DBG_PTS, "AIK signature algorithm is %N with %N hash",
+ DBG1(DBG_PTS, "signature algorithm is %N with %N hash",
tpm_alg_id_names, sig_alg, tpm_alg_id_names, digest_alg);
return aik_pubkey;
}
+METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*,
+ private_tpm_tss_tss2_t *this, uint32_t handle)
+{
+ TPM2B_PUBLIC public = { 0, };
+ hash_algorithm_t digest;
+ signature_params_t supported_scheme;
+
+ if (!read_public(this, handle, &public))
+ {
+ return enumerator_create_empty();
+ }
+
+ switch (public.publicArea.type)
+ {
+ case TPM2_ALG_RSA:
+ {
+ TPMS_RSA_PARMS *rsa;
+ TPMT_RSA_SCHEME *scheme;
+
+ rsa = &public.publicArea.parameters.rsaDetail;
+ scheme = &rsa->scheme;
+ digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg);
+
+ switch (scheme->scheme)
+ {
+ case TPM2_ALG_RSAPSS:
+ {
+ ssize_t salt_len;
+
+ salt_len = this->fips_186_4 ? RSA_PSS_SALT_LEN_DEFAULT :
+ RSA_PSS_SALT_LEN_MAX;
+ rsa_pss_params_t pss_params = {
+ .hash = digest,
+ .mgf1_hash = digest,
+ .salt_len = salt_len,
+ };
+ supported_scheme = (signature_params_t){
+ .scheme = SIGN_RSA_EMSA_PSS,
+ .params = &pss_params,
+ };
+ if (!rsa_pss_params_set_salt_len(&pss_params, rsa->keyBits))
+ {
+ return enumerator_create_empty();
+ }
+ break;
+ }
+ case TPM2_ALG_RSASSA:
+ supported_scheme = (signature_params_t){
+ .scheme = signature_scheme_from_oid(
+ hasher_signature_algorithm_to_oid(digest,
+ KEY_RSA)),
+ };
+ break;
+ default:
+ return enumerator_create_empty();
+ }
+ break;
+ }
+ case TPM2_ALG_ECC:
+ {
+ TPMT_ECC_SCHEME *scheme;
+
+ scheme = &public.publicArea.parameters.eccDetail.scheme;
+ digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg);
+
+ switch (scheme->scheme)
+ {
+ case TPM2_ALG_ECDSA:
+ supported_scheme = (signature_params_t){
+ .scheme = signature_scheme_from_oid(
+ hasher_signature_algorithm_to_oid(digest,
+ KEY_ECDSA)),
+ };
+ break;
+ default:
+ return enumerator_create_empty();
+ }
+ break;
+ }
+ default:
+ DBG1(DBG_PTS, "%s unsupported key type", LABEL);
+ return enumerator_create_empty();
+ }
+ return enumerator_create_single(signature_params_clone(&supported_scheme),
+ (void*)signature_params_destroy);
+}
+
/**
* Configure a PCR Selection assuming a maximum of 24 registers
*/
@@ -729,7 +837,7 @@ METHOD(tpm_tss_t, quote, bool,
DBG1(DBG_PTS, "%s unsupported %N signature algorithm",
LABEL, tpm_alg_id_names, sig.sigAlg);
return FALSE;
- };
+ }
DBG2(DBG_PTS, "PCR digest algorithm is %N", tpm_alg_id_names, hash_alg);
pcr_digest_alg = hash_alg_from_tpm_alg_id(hash_alg);
@@ -940,7 +1048,7 @@ METHOD(tpm_tss_t, sign, bool,
DBG1(DBG_PTS, "%s unsupported %N signature scheme",
LABEL, signature_scheme_names, scheme);
return FALSE;
- };
+ }
return TRUE;
}
@@ -1061,6 +1169,7 @@ tpm_tss_t *tpm_tss_tss2_create()
.get_version_info = _get_version_info,
.generate_aik = _generate_aik,
.get_public = _get_public,
+ .supported_signature_schemes = _supported_signature_schemes,
.read_pcr = _read_pcr,
.extend_pcr = _extend_pcr,
.quote = _quote,
diff --git a/src/pki/commands/acert.c b/src/pki/commands/acert.c
index d1ea5c65e..4cbe06c9e 100644
--- a/src/pki/commands/acert.c
+++ b/src/pki/commands/acert.c
@@ -228,6 +228,11 @@ static int acert()
goto end;
}
scheme = get_signature_scheme(private, digest, pss);
+ if (!scheme)
+ {
+ error = "no signature scheme found";
+ goto end;
+ }
ac = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509_AC,
diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c
index 1ccbca89f..b117fa171 100644
--- a/src/pki/commands/issue.c
+++ b/src/pki/commands/issue.c
@@ -536,6 +536,11 @@ static int issue()
chunk_from_chars(ASN1_SEQUENCE, 0));
}
scheme = get_signature_scheme(private, digest, pss);
+ if (!scheme)
+ {
+ error = "no signature scheme found";
+ goto end;
+ }
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_SIGNING_KEY, private, BUILD_SIGNING_CERT, ca,
diff --git a/src/pki/commands/req.c b/src/pki/commands/req.c
index cfddbc455..8f5380a4a 100644
--- a/src/pki/commands/req.c
+++ b/src/pki/commands/req.c
@@ -168,6 +168,11 @@ static int req()
goto end;
}
scheme = get_signature_scheme(private, digest, pss);
+ if (!scheme)
+ {
+ error = "no signature scheme found";
+ goto end;
+ }
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
BUILD_SIGNING_KEY, private,
diff --git a/src/pki/commands/self.c b/src/pki/commands/self.c
index 6f7adef0f..a08ee9931 100644
--- a/src/pki/commands/self.c
+++ b/src/pki/commands/self.c
@@ -378,6 +378,11 @@ static int self()
rng->destroy(rng);
}
scheme = get_signature_scheme(private, digest, pss);
+ if (!scheme)
+ {
+ error = "no signature scheme found";
+ goto end;
+ }
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_SIGNING_KEY, private, BUILD_PUBLIC_KEY, public,
diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c
index ca208a5cf..a399d21be 100644
--- a/src/pki/commands/signcrl.c
+++ b/src/pki/commands/signcrl.c
@@ -399,6 +399,12 @@ static int sign_crl()
chunk_increment(crl_serial);
scheme = get_signature_scheme(private, digest, pss);
+ if (!scheme)
+ {
+ error = "no signature scheme found";
+ goto error;
+ }
+
enumerator = enumerator_create_filter(list->create_enumerator(list),
filter, NULL, NULL);
crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
diff --git a/src/pki/pki.c b/src/pki/pki.c
index ec60f7d42..d03e96f9b 100644
--- a/src/pki/pki.c
+++ b/src/pki/pki.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2017 Tobias Brunner
+ * Copyright (C) 2012-2018 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
*
@@ -264,7 +264,30 @@ static hash_algorithm_t get_default_digest(private_key_t *private)
signature_params_t *get_signature_scheme(private_key_t *private,
hash_algorithm_t digest, bool pss)
{
- signature_params_t *scheme;
+ signature_params_t *scheme, *selected = NULL;
+ enumerator_t *enumerator;
+
+ if (private->supported_signature_schemes)
+ {
+ enumerator = private->supported_signature_schemes(private);
+ while (enumerator->enumerate(enumerator, &scheme))
+ {
+ if (private->get_type(private) == KEY_RSA &&
+ pss != (scheme->scheme == SIGN_RSA_EMSA_PSS))
+ {
+ continue;
+ }
+ if (digest == HASH_UNKNOWN ||
+ digest == hasher_from_signature_scheme(scheme->scheme,
+ scheme->params))
+ {
+ selected = signature_params_clone(scheme);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return selected;
+ }
if (digest == HASH_UNKNOWN)
{
@@ -281,6 +304,7 @@ signature_params_t *get_signature_scheme(private_key_t *private,
.scheme = SIGN_RSA_EMSA_PSS,
.params = &pss_params,
};
+ rsa_pss_params_set_salt_len(&pss_params, 0);
scheme = signature_params_clone(&pss_scheme);
}
else
diff --git a/src/pki/pki.h b/src/pki/pki.h
index 3f0793cfd..3976c33b7 100644
--- a/src/pki/pki.h
+++ b/src/pki/pki.h
@@ -65,7 +65,8 @@ void set_file_mode(FILE *stream, cred_encoding_type_t enc);
* @param digest hash algorithm (if HASH_UNKNOWN a default is determined
* based on the key)
* @param pss use PSS padding for RSA keys
- * @return allocated signature scheme and parameters
+ * @return allocated signature scheme and parameters (NULL if none
+ * found)
*/
signature_params_t *get_signature_scheme(private_key_t *private,
hash_algorithm_t digest, bool pss);
diff --git a/src/pool/pool.c b/src/pool/pool.c
index b755365ec..ba1889dd8 100644
--- a/src/pool/pool.c
+++ b/src/pool/pool.c
@@ -710,7 +710,6 @@ static enumerator_t *create_lease_query(char *filter, array_t **to_free)
default:
fprintf(stderr, "invalid filter string.\n");
exit(EXIT_FAILURE);
- break;
}
}
query = db->query(db,
@@ -1142,7 +1141,6 @@ static void do_args(int argc, char *argv[])
default:
usage();
exit(EXIT_FAILURE);
- break;
}
break;
}
diff --git a/src/pt-tls-client/pt-tls-client.1.in b/src/pt-tls-client/pt-tls-client.1.in
index 3e14cbe37..6bd3c642e 100644
--- a/src/pt-tls-client/pt-tls-client.1.in
+++ b/src/pt-tls-client/pt-tls-client.1.in
@@ -1,4 +1,4 @@
-.TH PT-TLS-CLIENT 1 "2017-07-15" "@PACKAGE_VERSION@" "strongSwan"
+.TH PT-TLS-CLIENT 1 "2018-11-20" "@PACKAGE_VERSION@" "strongSwan"
.
.SH "NAME"
.
@@ -9,7 +9,7 @@ pt-tls-client \- Simple client using PT-TLS to collect integrity information
.SY "pt-tls-client"
.BI \-\-connect
.IR hostname |\fIaddress
-.OP \-\-port hex
+.OP \-\-port port
.RB [ \-\-certid
.IR hex |\fB\-\-cert
.IR file ]+
diff --git a/src/scepclient/scepclient.c b/src/scepclient/scepclient.c
index 83079f3d8..754393455 100644
--- a/src/scepclient/scepclient.c
+++ b/src/scepclient/scepclient.c
@@ -455,6 +455,7 @@ int main(int argc, char **argv)
/* distinguished name for requested certificate, ASCII format */
char *distinguishedName = NULL;
+ char default_distinguished_name[BUF_LEN];
/* challenge password */
char challenge_password_buffer[MAX_PASSWORD_LENGTH];
@@ -1105,16 +1106,16 @@ int main(int argc, char **argv)
{
if (distinguishedName == NULL)
{
- char buf[BUF_LEN];
- int n = sprintf(buf, DEFAULT_DN);
+ int n = sprintf(default_distinguished_name, DEFAULT_DN);
/* set the common name to the hostname */
- if (gethostname(buf + n, BUF_LEN - n) || strlen(buf) == n)
+ if (gethostname(default_distinguished_name + n, BUF_LEN - n) ||
+ strlen(default_distinguished_name) == n)
{
exit_scepclient("no hostname defined, use "
"--dn <distinguished name> option");
}
- distinguishedName = buf;
+ distinguishedName = default_distinguished_name;
}
DBG2(DBG_APP, "dn: '%s'", distinguishedName);
diff --git a/src/sec-updater/sec-updater.sh b/src/sec-updater/sec-updater.sh
index ca7b89841..16e561459 100755
--- a/src/sec-updater/sec-updater.sh
+++ b/src/sec-updater/sec-updater.sh
@@ -4,11 +4,11 @@ DIR="/etc/pts"
DISTS_DIR="$DIR/dists"
DATE=`date +%Y%m%d-%H%M`
UBUNTU="http://security.ubuntu.com/ubuntu"
-UBUNTU_VERSIONS="xenial"
+UBUNTU_VERSIONS="bionic xenial"
UBUNTU_DIRS="main multiverse restricted universe"
UBUNTU_ARCH="binary-amd64"
DEBIAN="http://security.debian.org"
-DEBIAN_VERSIONS="jessie wheezy"
+DEBIAN_VERSIONS="stretch jessie wheezy"
DEBIAN_DIRS="main contrib non-free"
DEBIAN_ARCH="binary-amd64 binary-armhf"
RASPIAN="http://archive.raspberrypi.org/debian"
@@ -48,8 +48,14 @@ do
mkdir -p $v-updates/$a
for d in $DEBIAN_DIRS
do
- wget -nv $DEBIAN/dists/$v/updates/$d/$a/Packages.bz2 -O $v-updates/$a/Packages-$d.bz2
- bunzip2 -f $v-updates/$a/Packages-$d.bz2
+ if [ $v = "stretch" ]
+ then
+ wget -nv $DEBIAN/dists/$v/updates/$d/$a/Packages.xz -O $v-updates/$a/Packages-$d.xz
+ unxz -f $v-updates/$a/Packages-$d.xz
+ else
+ wget -nv $DEBIAN/dists/$v/updates/$d/$a/Packages.bz2 -O $v-updates/$a/Packages-$d.bz2
+ bunzip2 -f $v-updates/$a/Packages-$d.bz2
+ fi
done
done
done
@@ -71,6 +77,28 @@ done
# Run sec-updater in distribution information
+for f in bionic-security/binary-amd64/*
+do
+ echo "security: $f"
+ $CMD --os "Ubuntu 18.04" --arch "x86_64" --file $f --security \
+ --uri $UBUNTU >> $CMD_LOG 2>&1
+ if [ $? -eq 0 ]
+ then
+ DEL_LOG=0
+ fi
+done
+
+for f in bionic-updates/binary-amd64/*
+do
+ echo "updates: $f"
+ $CMD --os "Ubuntu 18.04" --arch "x86_64" --file $f \
+ --uri $UBUNTU >> $CMD_LOG 2>&1
+ if [ $? -eq 0 ]
+ then
+ DEL_LOG=0
+ fi
+done
+
for f in xenial-security/binary-amd64/*
do
echo "security: $f"
@@ -93,6 +121,17 @@ do
fi
done
+for f in stretch-updates/binary-amd64/*
+do
+ echo "security: $f"
+ $CMD --os "Debian 9.0" --arch "x86_64" --file $f --security \
+ --uri $DEBIAN >> $CMD_LOG 2>&1
+ if [ $? -eq 0 ]
+ then
+ DEL_LOG=0
+ fi
+done
+
for f in jessie-updates/binary-amd64/*
do
echo "security: $f"
@@ -115,6 +154,17 @@ do
fi
done
+for f in stretch-updates/binary-armhf/*
+do
+ echo "security: $f"
+ $CMD --os "Debian 9.0" --arch "armhf" --file $f --security \
+ --uri $DEBIAN >> $CMD_LOG 2>&1
+ if [ $? -eq 0 ]
+ then
+ DEL_LOG=0
+ fi
+done
+
for f in jessie-updates/binary-armhf/*
do
echo "security: $f"
diff --git a/src/starter/keywords.c b/src/starter/keywords.c
index a8f50169a..f4da67e8a 100644
--- a/src/starter/keywords.c
+++ b/src/starter/keywords.c
@@ -1,4 +1,4 @@
-/* C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.1 */
/* Command-line: /usr/bin/gperf -m 10 -C -G -D -t */
/* Computed positions: -k'2-3,6,$' */
@@ -26,7 +26,7 @@
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
-error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
#endif
@@ -70,9 +70,7 @@ inline
#endif
#endif
static unsigned int
-hash (str, len)
- register const char *str;
- register unsigned int len;
+hash (register const char *str, register size_t len)
{
static const unsigned short asso_values[] =
{
@@ -103,7 +101,7 @@ hash (str, len)
258, 258, 258, 258, 258, 258, 258, 258, 258, 258,
258, 258, 258, 258, 258, 258
};
- register int hval = len;
+ register unsigned int hval = len;
switch (hval)
{
@@ -296,22 +294,14 @@ static const short lookup[] =
138, -1, -1, -1, -1, -1, -1, 139
};
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
const struct kw_entry *
-in_word_set (str, len)
- register const char *str;
- register unsigned int len;
+in_word_set (register const char *str, register size_t len)
{
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- register int key = hash (str, len);
+ register unsigned int key = hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
register int index = lookup[key];
diff --git a/src/starter/keywords.h b/src/starter/keywords.h
index d017134d9..c987f187d 100644
--- a/src/starter/keywords.h
+++ b/src/starter/keywords.h
@@ -197,7 +197,7 @@ struct kw_entry_t {
};
#ifndef IN_GPERF_GENERATED_FILE
-const kw_entry_t *in_word_set(register const char*, register unsigned);
+const kw_entry_t *in_word_set(register const char*, register size_t);
#endif
#endif /* _KEYWORDS_H_ */
diff --git a/src/starter/parser/lexer.c b/src/starter/parser/lexer.c
index ff7c75bb7..9fb25e1ee 100644
--- a/src/starter/parser/lexer.c
+++ b/src/starter/parser/lexer.c
@@ -7,7 +7,6 @@
/* A lexical scanner generated by flex */
/* %not-for-header */
-
/* %if-c-only */
/* %if-not-reentrant */
/* %endif */
@@ -17,7 +16,7 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 0
+#define YY_FLEX_SUBMINOR_VERSION 4
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -26,9 +25,230 @@
/* %endif */
/* %if-c-only */
-
+#ifdef yy_create_buffer
+#define conf_parser__create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer conf_parser__create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define conf_parser__delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer conf_parser__delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define conf_parser__scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer conf_parser__scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define conf_parser__scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string conf_parser__scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define conf_parser__scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes conf_parser__scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define conf_parser__init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer conf_parser__init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define conf_parser__flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer conf_parser__flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define conf_parser__load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state conf_parser__load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define conf_parser__switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer conf_parser__switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define conf_parser_push_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state conf_parser_push_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define conf_parser_pop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state conf_parser_pop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define conf_parser_ensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack conf_parser_ensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define conf_parser_lex_ALREADY_DEFINED
+#else
+#define yylex conf_parser_lex
+#endif
+
+#ifdef yyrestart
+#define conf_parser_restart_ALREADY_DEFINED
+#else
+#define yyrestart conf_parser_restart
+#endif
+
+#ifdef yylex_init
+#define conf_parser_lex_init_ALREADY_DEFINED
+#else
+#define yylex_init conf_parser_lex_init
+#endif
+
+#ifdef yylex_init_extra
+#define conf_parser_lex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra conf_parser_lex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define conf_parser_lex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy conf_parser_lex_destroy
+#endif
+
+#ifdef yyget_debug
+#define conf_parser_get_debug_ALREADY_DEFINED
+#else
+#define yyget_debug conf_parser_get_debug
+#endif
+
+#ifdef yyset_debug
+#define conf_parser_set_debug_ALREADY_DEFINED
+#else
+#define yyset_debug conf_parser_set_debug
+#endif
+
+#ifdef yyget_extra
+#define conf_parser_get_extra_ALREADY_DEFINED
+#else
+#define yyget_extra conf_parser_get_extra
+#endif
+
+#ifdef yyset_extra
+#define conf_parser_set_extra_ALREADY_DEFINED
+#else
+#define yyset_extra conf_parser_set_extra
+#endif
+
+#ifdef yyget_in
+#define conf_parser_get_in_ALREADY_DEFINED
+#else
+#define yyget_in conf_parser_get_in
+#endif
+
+#ifdef yyset_in
+#define conf_parser_set_in_ALREADY_DEFINED
+#else
+#define yyset_in conf_parser_set_in
+#endif
+
+#ifdef yyget_out
+#define conf_parser_get_out_ALREADY_DEFINED
+#else
+#define yyget_out conf_parser_get_out
+#endif
+
+#ifdef yyset_out
+#define conf_parser_set_out_ALREADY_DEFINED
+#else
+#define yyset_out conf_parser_set_out
+#endif
+
+#ifdef yyget_leng
+#define conf_parser_get_leng_ALREADY_DEFINED
+#else
+#define yyget_leng conf_parser_get_leng
+#endif
+
+#ifdef yyget_text
+#define conf_parser_get_text_ALREADY_DEFINED
+#else
+#define yyget_text conf_parser_get_text
+#endif
+
+#ifdef yyget_lineno
+#define conf_parser_get_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno conf_parser_get_lineno
+#endif
+
+#ifdef yyset_lineno
+#define conf_parser_set_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno conf_parser_set_lineno
+#endif
+
+#ifdef yyget_column
+#define conf_parser_get_column_ALREADY_DEFINED
+#else
+#define yyget_column conf_parser_get_column
+#endif
+
+#ifdef yyset_column
+#define conf_parser_set_column_ALREADY_DEFINED
+#else
+#define yyset_column conf_parser_set_column
+#endif
+
+#ifdef yywrap
+#define conf_parser_wrap_ALREADY_DEFINED
+#else
+#define yywrap conf_parser_wrap
+#endif
+
/* %endif */
+#ifdef yyget_lval
+#define conf_parser_get_lval_ALREADY_DEFINED
+#else
+#define yyget_lval conf_parser_get_lval
+#endif
+
+#ifdef yyset_lval
+#define conf_parser_set_lval_ALREADY_DEFINED
+#else
+#define yyset_lval conf_parser_set_lval
+#endif
+
+#ifdef yyalloc
+#define conf_parser_alloc_ALREADY_DEFINED
+#else
+#define yyalloc conf_parser_alloc
+#endif
+
+#ifdef yyrealloc
+#define conf_parser_realloc_ALREADY_DEFINED
+#else
+#define yyrealloc conf_parser_realloc
+#endif
+
+#ifdef yyfree
+#define conf_parser_free_ALREADY_DEFINED
+#else
+#define yyfree conf_parser_free
+#endif
+
/* %if-c-only */
/* %endif */
@@ -108,50 +328,39 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
/* %endif */
+/* begin standard C++ headers. */
/* %if-c++-only */
/* %endif */
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
#else
-#define yyconst
+#define yynoreturn
#endif
/* %not-for-header */
-
/* Returned upon end-of-file. */
#define YY_NULL 0
/* %ok-for-header */
/* %not-for-header */
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
*/
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
/* %ok-for-header */
/* %if-reentrant */
@@ -183,20 +392,16 @@ typedef void* yyscan_t;
* definition of BEGIN.
*/
#define BEGIN yyg->yy_start = 1 + 2 *
-
/* Translate the current start state into a value that can be later handed
* to BEGIN to return to the state. The YYSTATE alias is for lex
* compatibility.
*/
#define YY_START ((yyg->yy_start - 1) / 2)
#define YYSTATE YY_START
-
/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE conf_parser_restart(yyin ,yyscanner )
-
+#define YY_NEW_FILE yyrestart( yyin , yyscanner )
#define YY_END_OF_BUFFER_CHAR 0
/* Size of default input buffer. */
@@ -237,10 +442,10 @@ typedef size_t yy_size_t;
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
-
+
/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
* access to the local variable yy_act. Since yyless() is a macro, it would break
- * existing scanners that call yyless() from OUTSIDE conf_parser_lex.
+ * existing scanners that call yyless() from OUTSIDE yylex.
* One obvious solution it to make yy_act a global. I tried that, and saw
* a 5% performance hit in a non-yylineno scanner, because yy_act is
* normally declared as a register variable-- so it is not worth it.
@@ -273,7 +478,6 @@ typedef size_t yy_size_t;
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
-
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
#ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -293,7 +497,7 @@ struct yy_buffer_state
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
- yy_size_t yy_buf_size;
+ int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
@@ -321,7 +525,7 @@ struct yy_buffer_state
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@@ -338,7 +542,7 @@ struct yy_buffer_state
* possible backing-up.
*
* When we actually see the EOF, we change the status to "new"
- * (via conf_parser_restart()), so that the user can continue scanning by
+ * (via yyrestart()), so that the user can continue scanning by
* just pointing yyin at a new input file.
*/
#define YY_BUFFER_EOF_PENDING 2
@@ -348,7 +552,6 @@ struct yy_buffer_state
/* %if-c-only Standard (non-C++) definition */
/* %not-for-header */
-
/* %if-not-reentrant */
/* %endif */
/* %ok-for-header */
@@ -364,7 +567,6 @@ struct yy_buffer_state
#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
: NULL)
-
/* Same as previous macro, but useful when we know that the buffer stack is not
* NULL or when we need an lvalue. For internal use only.
*/
@@ -374,57 +576,52 @@ struct yy_buffer_state
/* %if-not-reentrant */
/* %not-for-header */
-
/* %ok-for-header */
/* %endif */
-void conf_parser_restart (FILE *input_file ,yyscan_t yyscanner );
-void conf_parser__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE conf_parser__create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void conf_parser__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void conf_parser__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void conf_parser_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void conf_parser_pop_buffer_state (yyscan_t yyscanner );
-
-static void conf_parser_ensure_buffer_stack (yyscan_t yyscanner );
-static void conf_parser__load_buffer_state (yyscan_t yyscanner );
-static void conf_parser__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
-#define YY_FLUSH_BUFFER conf_parser__flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+static void yyensure_buffer_stack ( yyscan_t yyscanner );
+static void yy_load_buffer_state ( yyscan_t yyscanner );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
-YY_BUFFER_STATE conf_parser__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE conf_parser__scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE conf_parser__scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
/* %endif */
-void *conf_parser_alloc (yy_size_t ,yyscan_t yyscanner );
-void *conf_parser_realloc (void *,yy_size_t ,yyscan_t yyscanner );
-void conf_parser_free (void * ,yyscan_t yyscanner );
-
-#define yy_new_buffer conf_parser__create_buffer
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
+#define yy_new_buffer yy_create_buffer
#define yy_set_interactive(is_interactive) \
{ \
if ( ! YY_CURRENT_BUFFER ){ \
- conf_parser_ensure_buffer_stack (yyscanner); \
+ yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- conf_parser__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
}
-
#define yy_set_bol(at_bol) \
{ \
if ( ! YY_CURRENT_BUFFER ){\
- conf_parser_ensure_buffer_stack (yyscanner); \
+ yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- conf_parser__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
-
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
@@ -434,8 +631,7 @@ void conf_parser_free (void * ,yyscan_t yyscanner );
#define YY_SKIP_YYWRAP
#define FLEX_DEBUG
-
-typedef unsigned char YY_CHAR;
+typedef flex_uint8_t YY_CHAR;
typedef int yy_state_type;
@@ -445,13 +641,10 @@ typedef int yy_state_type;
/* %if-c-only Standard (non-C++) definition */
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-#if defined(__GNUC__) && __GNUC__ >= 3
-__attribute__((__noreturn__))
-#endif
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner);
+static int yy_get_next_buffer ( yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
/* %endif */
@@ -461,12 +654,11 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\
- yyleng = (size_t) (yy_cp - yy_bp); \
+ yyleng = (int) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
yyg->yy_c_buf_p = yy_cp;
-
/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
#define YY_NUM_RULES 26
#define YY_END_OF_BUFFER 27
@@ -477,7 +669,7 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[80] =
+static const flex_int16_t yy_accept[80] =
{ 0,
0, 0, 0, 0, 0, 0, 27, 12, 3, 5,
11, 4, 6, 12, 12, 2, 12, 12, 17, 13,
@@ -489,7 +681,7 @@ static yyconst flex_int16_t yy_accept[80] =
0, 1, 10, 10, 0, 0, 0, 7, 0
} ;
-static yyconst YY_CHAR yy_ec[256] =
+static const YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
@@ -521,14 +713,14 @@ static yyconst YY_CHAR yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst YY_CHAR yy_meta[28] =
+static const YY_CHAR yy_meta[28] =
{ 0,
1, 2, 3, 1, 2, 4, 2, 5, 1, 6,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1
} ;
-static yyconst flex_uint16_t yy_base[91] =
+static const flex_int16_t yy_base[91] =
{ 0,
0, 16, 41, 50, 4, 5, 101, 0, 24, 184,
184, 0, 184, 92, 79, 32, 16, 83, 0, 184,
@@ -541,7 +733,7 @@ static yyconst flex_uint16_t yy_base[91] =
125, 131, 137, 143, 149, 154, 159, 165, 171, 177
} ;
-static yyconst flex_int16_t yy_def[91] =
+static const flex_int16_t yy_def[91] =
{ 0,
80, 80, 81, 81, 82, 82, 79, 83, 79, 79,
79, 84, 79, 83, 83, 79, 83, 83, 85, 79,
@@ -554,7 +746,7 @@ static yyconst flex_int16_t yy_def[91] =
79, 79, 79, 79, 79, 79, 79, 79, 79, 79
} ;
-static yyconst flex_uint16_t yy_nxt[212] =
+static const flex_int16_t yy_nxt[212] =
{ 0,
79, 9, 10, 79, 9, 11, 12, 13, 14, 24,
24, 79, 79, 25, 25, 52, 15, 16, 10, 53,
@@ -582,7 +774,7 @@ static yyconst flex_uint16_t yy_nxt[212] =
79
} ;
-static yyconst flex_int16_t yy_chk[212] =
+static const flex_int16_t yy_chk[212] =
{ 0,
0, 1, 1, 0, 1, 1, 1, 1, 1, 5,
6, 0, 0, 5, 6, 48, 1, 2, 2, 48,
@@ -611,16 +803,16 @@ static yyconst flex_int16_t yy_chk[212] =
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[27] =
+static const flex_int32_t yy_rule_can_match_eol[27] =
{ 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 1, 0, };
-static yyconst flex_int16_t yy_rule_linenum[26] =
+static const flex_int16_t yy_rule_linenum[26] =
{ 0,
- 60, 61, 62, 63, 65, 67, 68, 69, 70, 72,
- 77, 82, 90, 109, 112, 115, 118, 124, 126, 145,
- 146, 147, 148, 149, 150
+ 65, 66, 67, 68, 70, 72, 73, 74, 75, 77,
+ 82, 87, 95, 114, 117, 120, 123, 129, 131, 150,
+ 151, 152, 153, 154, 155
} ;
/* The intent behind this definition is that it'll catch
@@ -656,9 +848,13 @@ bool conf_parser_open_next_file(parser_helper_t *ctx);
static void include_files(parser_helper_t *ctx);
+#line 852 "parser/lexer.c"
/* use start conditions stack */
/* do not declare unneeded functions */
#define YY_NO_INPUT 1
+/* do not include unistd.h as it might conflict with our scanner states */
+#define YY_NO_UNISTD_H 1
+/* due to that disable interactive mode, which requires isatty() */
/* don't use global variables, and interact properly with bison */
/* maintain the line number */
/* don't generate a default rule */
@@ -669,7 +865,7 @@ static void include_files(parser_helper_t *ctx);
/* state used to scan quoted strings */
-#line 673 "parser/lexer.c"
+#line 869 "parser/lexer.c"
#define INITIAL 0
#define inc 1
@@ -706,7 +902,7 @@ struct yyguts_t
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char;
int yy_n_chars;
- yy_size_t yyleng_r;
+ int yyleng_r;
char *yy_c_buf_p;
int yy_init;
int yy_start;
@@ -730,7 +926,7 @@ struct yyguts_t
/* %if-c-only */
-static int yy_init_globals (yyscan_t yyscanner );
+static int yy_init_globals ( yyscan_t yyscanner );
/* %endif */
@@ -740,9 +936,9 @@ static int yy_init_globals (yyscan_t yyscanner );
* from bison output in section 1.*/
# define yylval yyg->yylval_r
-int conf_parser_lex_init (yyscan_t* scanner);
+int yylex_init (yyscan_t* scanner);
-int conf_parser_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
/* %endif */
@@ -751,41 +947,41 @@ int conf_parser_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
-int conf_parser_lex_destroy (yyscan_t yyscanner );
+int yylex_destroy ( yyscan_t yyscanner );
-int conf_parser_get_debug (yyscan_t yyscanner );
+int yyget_debug ( yyscan_t yyscanner );
-void conf_parser_set_debug (int debug_flag ,yyscan_t yyscanner );
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
-YY_EXTRA_TYPE conf_parser_get_extra (yyscan_t yyscanner );
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
-void conf_parser_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
-FILE *conf_parser_get_in (yyscan_t yyscanner );
+FILE *yyget_in ( yyscan_t yyscanner );
-void conf_parser_set_in (FILE * _in_str ,yyscan_t yyscanner );
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
-FILE *conf_parser_get_out (yyscan_t yyscanner );
+FILE *yyget_out ( yyscan_t yyscanner );
-void conf_parser_set_out (FILE * _out_str ,yyscan_t yyscanner );
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
-yy_size_t conf_parser_get_leng (yyscan_t yyscanner );
+ int yyget_leng ( yyscan_t yyscanner );
-char *conf_parser_get_text (yyscan_t yyscanner );
+char *yyget_text ( yyscan_t yyscanner );
-int conf_parser_get_lineno (yyscan_t yyscanner );
+int yyget_lineno ( yyscan_t yyscanner );
-void conf_parser_set_lineno (int _line_number ,yyscan_t yyscanner );
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
-int conf_parser_get_column (yyscan_t yyscanner );
+int yyget_column ( yyscan_t yyscanner );
-void conf_parser_set_column (int _column_no ,yyscan_t yyscanner );
+void yyset_column ( int _column_no , yyscan_t yyscanner );
/* %if-bison-bridge */
-YYSTYPE * conf_parser_get_lval (yyscan_t yyscanner );
+YYSTYPE * yyget_lval ( yyscan_t yyscanner );
-void conf_parser_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
/* %endif */
@@ -795,17 +991,16 @@ void conf_parser_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int conf_parser_wrap (yyscan_t yyscanner );
+extern "C" int yywrap ( yyscan_t yyscanner );
#else
-extern int conf_parser_wrap (yyscan_t yyscanner );
+extern int yywrap ( yyscan_t yyscanner );
#endif
#endif
/* %not-for-header */
-
#ifndef YY_NO_UNPUT
- static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
+ static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner);
#endif
/* %ok-for-header */
@@ -813,21 +1008,20 @@ extern int conf_parser_wrap (yyscan_t yyscanner );
/* %endif */
#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
#endif
#ifndef YY_NO_INPUT
/* %if-c-only Standard (non-C++) definition */
/* %not-for-header */
-
#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
+static int yyinput ( yyscan_t yyscanner );
#else
-static int input (yyscan_t yyscanner );
+static int input ( yyscan_t yyscanner );
#endif
/* %ok-for-header */
@@ -836,11 +1030,11 @@ static int input (yyscan_t yyscanner );
/* %if-c-only */
- static void yy_push_state (int _new_state ,yyscan_t yyscanner);
+ static void yy_push_state ( int _new_state , yyscan_t yyscanner);
- static void yy_pop_state (yyscan_t yyscanner );
+ static void yy_pop_state ( yyscan_t yyscanner );
- static int yy_top_state (yyscan_t yyscanner );
+ static int yy_top_state ( yyscan_t yyscanner );
/* %endif */
@@ -860,7 +1054,7 @@ static int input (yyscan_t yyscanner );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
/* %endif */
/* %if-c++-only C++ definition */
/* %endif */
@@ -875,7 +1069,7 @@ static int input (yyscan_t yyscanner );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- size_t n; \
+ int n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -888,7 +1082,7 @@ static int input (yyscan_t yyscanner );
else \
{ \
errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
{ \
if( errno != EINTR) \
{ \
@@ -929,11 +1123,9 @@ static int input (yyscan_t yyscanner );
/* %if-tables-serialization structures and prototypes */
/* %not-for-header */
-
/* %ok-for-header */
/* %not-for-header */
-
/* %tables-yydmap generated elements */
/* %endif */
/* end tables serialization structures and prototypes */
@@ -947,10 +1139,10 @@ static int input (yyscan_t yyscanner );
#define YY_DECL_IS_OURS 1
/* %if-c-only Standard (non-C++) definition */
-extern int conf_parser_lex \
- (YYSTYPE * yylval_param ,yyscan_t yyscanner);
+extern int yylex \
+ (YYSTYPE * yylval_param , yyscan_t yyscanner);
-#define YY_DECL int conf_parser_lex \
+#define YY_DECL int yylex \
(YYSTYPE * yylval_param , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only C++ definition */
@@ -977,7 +1169,6 @@ extern int conf_parser_lex \
YY_USER_ACTION
/* %not-for-header */
-
/** The main scanner function which does all the work.
*/
YY_DECL
@@ -1015,20 +1206,20 @@ YY_DECL
/* %endif */
if ( ! YY_CURRENT_BUFFER ) {
- conf_parser_ensure_buffer_stack (yyscanner);
+ yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- conf_parser__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- conf_parser__load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
{
/* %% [7.0] user's declarations go here */
-#line 58 "parser/lexer.l"
+#line 63 "parser/lexer.l"
-#line 1032 "parser/lexer.c"
+#line 1223 "parser/lexer.c"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@@ -1059,22 +1250,18 @@ yy_match:
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 80 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 184 );
+ while ( yy_current_state != 79 );
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
yy_find_action:
/* %% [10.0] code to find the action number goes here */
yy_act = yy_accept[yy_current_state];
- if ( yy_act == 0 )
- { /* have to back up */
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- yy_act = yy_accept[yy_current_state];
- }
YY_DO_BEFORE_ACTION;
@@ -1082,10 +1269,10 @@ yy_find_action:
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
{
- yy_size_t yyl;
+ int yyl;
for ( yyl = 0; yyl < yyleng; ++yyl )
if ( yytext[yyl] == '\n' )
-
+
do{ yylineno++;
yycolumn=0;
}while(0)
@@ -1126,48 +1313,48 @@ case 1:
yyg->yy_c_buf_p = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
-#line 60 "parser/lexer.l"
+#line 65 "parser/lexer.l"
/* eat legacy version delcaration */
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 61 "parser/lexer.l"
+#line 66 "parser/lexer.l"
return SPACES;
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 62 "parser/lexer.l"
+#line 67 "parser/lexer.l"
/* eat other whitespace */
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 63 "parser/lexer.l"
+#line 68 "parser/lexer.l"
/* eat comments */
YY_BREAK
case 5:
/* rule 5 can match eol */
YY_RULE_SETUP
-#line 65 "parser/lexer.l"
+#line 70 "parser/lexer.l"
return NEWLINE;
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 67 "parser/lexer.l"
+#line 72 "parser/lexer.l"
return EQ;
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 68 "parser/lexer.l"
+#line 73 "parser/lexer.l"
return CONFIG_SETUP;
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 69 "parser/lexer.l"
+#line 74 "parser/lexer.l"
return CONN;
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 70 "parser/lexer.l"
+#line 75 "parser/lexer.l"
return CA;
YY_BREAK
case 10:
@@ -1177,7 +1364,7 @@ YY_LINENO_REWIND_TO(yy_cp - 1);
yyg->yy_c_buf_p = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
-#line 72 "parser/lexer.l"
+#line 77 "parser/lexer.l"
{
yyextra->string_init(yyextra);
yy_push_state(inc, yyscanner);
@@ -1185,7 +1372,7 @@ YY_RULE_SETUP
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 77 "parser/lexer.l"
+#line 82 "parser/lexer.l"
{
yyextra->string_init(yyextra);
yy_push_state(str, yyscanner);
@@ -1193,7 +1380,7 @@ YY_RULE_SETUP
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 82 "parser/lexer.l"
+#line 87 "parser/lexer.l"
{
yylval->s = strdup(yytext);
return STRING;
@@ -1202,11 +1389,11 @@ YY_RULE_SETUP
/* we allow all characters except # and spaces, they can be escaped */
case YY_STATE_EOF(inc):
-#line 89 "parser/lexer.l"
+#line 94 "parser/lexer.l"
case 13:
/* rule 13 can match eol */
YY_RULE_SETUP
-#line 90 "parser/lexer.l"
+#line 95 "parser/lexer.l"
{
if (*yytext)
{
@@ -1229,28 +1416,28 @@ YY_RULE_SETUP
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 109 "parser/lexer.l"
+#line 114 "parser/lexer.l"
{ /* string include */
yy_push_state(str, yyscanner);
}
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 112 "parser/lexer.l"
+#line 117 "parser/lexer.l"
{
yyextra->string_add(yyextra, yytext);
}
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 115 "parser/lexer.l"
+#line 120 "parser/lexer.l"
{
yyextra->string_add(yyextra, yytext+1);
}
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 118 "parser/lexer.l"
+#line 123 "parser/lexer.l"
{
yyextra->string_add(yyextra, yytext);
}
@@ -1258,13 +1445,13 @@ YY_RULE_SETUP
case 18:
-#line 125 "parser/lexer.l"
+#line 130 "parser/lexer.l"
YY_RULE_SETUP
case YY_STATE_EOF(str):
-#line 125 "parser/lexer.l"
+#line 130 "parser/lexer.l"
case 19:
YY_RULE_SETUP
-#line 126 "parser/lexer.l"
+#line 131 "parser/lexer.l"
{
if (!streq(yytext, "\""))
{
@@ -1287,41 +1474,41 @@ YY_RULE_SETUP
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 145 "parser/lexer.l"
+#line 150 "parser/lexer.l"
yyextra->string_add(yyextra, "\n");
YY_BREAK
case 21:
YY_RULE_SETUP
-#line 146 "parser/lexer.l"
+#line 151 "parser/lexer.l"
yyextra->string_add(yyextra, "\r");
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 147 "parser/lexer.l"
+#line 152 "parser/lexer.l"
yyextra->string_add(yyextra, "\t");
YY_BREAK
case 23:
/* rule 23 can match eol */
YY_RULE_SETUP
-#line 148 "parser/lexer.l"
+#line 153 "parser/lexer.l"
/* merge lines that end with EOL characters */
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 149 "parser/lexer.l"
+#line 154 "parser/lexer.l"
yyextra->string_add(yyextra, yytext+1);
YY_BREAK
case 25:
/* rule 25 can match eol */
YY_RULE_SETUP
-#line 150 "parser/lexer.l"
+#line 155 "parser/lexer.l"
{
yyextra->string_add(yyextra, yytext);
}
YY_BREAK
case YY_STATE_EOF(INITIAL):
-#line 155 "parser/lexer.l"
+#line 160 "parser/lexer.l"
{
conf_parser_pop_buffer_state(yyscanner);
if (!conf_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
@@ -1332,10 +1519,10 @@ case YY_STATE_EOF(INITIAL):
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 163 "parser/lexer.l"
+#line 168 "parser/lexer.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 1339 "parser/lexer.c"
+#line 1526 "parser/lexer.c"
case YY_END_OF_BUFFER:
{
@@ -1351,7 +1538,7 @@ YY_FATAL_ERROR( "flex scanner jammed" );
/* We're scanning a new file or input source. It's
* possible that this happened because the user
* just pointed yyin at a new source and called
- * conf_parser_lex(). If so, then we have to assure
+ * yylex(). If so, then we have to assure
* consistency between YY_CURRENT_BUFFER and our
* globals. Here is the right place to do so, because
* this is the first action (other than possibly a
@@ -1405,7 +1592,8 @@ YY_FATAL_ERROR( "flex scanner jammed" );
else
{
/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
- yy_cp = yyg->yy_c_buf_p;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
goto yy_find_action;
}
}
@@ -1416,7 +1604,7 @@ YY_FATAL_ERROR( "flex scanner jammed" );
{
yyg->yy_did_buffer_switch_on_eof = 0;
- if ( conf_parser_wrap(yyscanner ) )
+ if ( yywrap( yyscanner ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
@@ -1470,12 +1658,11 @@ YY_FATAL_ERROR( "flex scanner jammed" );
} /* end of action switch */
} /* end of scanning one token */
} /* end of user's declarations */
-} /* end of conf_parser_lex */
+} /* end of yylex */
/* %ok-for-header */
/* %if-c++-only */
/* %not-for-header */
-
/* %ok-for-header */
/* %endif */
@@ -1496,7 +1683,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
char *source = yyg->yytext_ptr;
- yy_size_t number_to_move, i;
+ int number_to_move, i;
int ret_val;
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -1525,7 +1712,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -1538,7 +1725,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{
- yy_size_t num_to_read =
+ int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -1552,7 +1739,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( b->yy_is_our_buffer )
{
- yy_size_t new_size = b->yy_buf_size * 2;
+ int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
@@ -1561,11 +1748,12 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
- conf_parser_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
+ b->yy_ch_buf = NULL;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
@@ -1593,7 +1781,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- conf_parser_restart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
}
else
@@ -1607,12 +1795,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) conf_parser_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
}
yyg->yy_n_chars += number_to_move;
@@ -1628,7 +1819,6 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* %if-c-only */
/* %not-for-header */
-
static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
@@ -1655,9 +1845,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 80 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
}
return yy_current_state;
@@ -1689,9 +1879,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 80 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
yy_is_jam = (yy_current_state == 79);
(void)yyg;
@@ -1717,7 +1907,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
- yy_size_t number_to_move = yyg->yy_n_chars + 2;
+ int number_to_move = yyg->yy_n_chars + 2;
char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
char *source =
@@ -1729,7 +1919,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
yy_cp += (int) (dest - source);
yy_bp += (int) (dest - source);
YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+ yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
YY_FATAL_ERROR( "flex scanner push-back overflow" );
@@ -1781,7 +1971,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{ /* need more input */
- yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) )
@@ -1798,14 +1988,14 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
*/
/* Reset buffer status. */
- conf_parser_restart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
/*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( conf_parser_wrap(yyscanner ) )
- return EOF;
+ if ( yywrap( yyscanner ) )
+ return 0;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
@@ -1830,7 +2020,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* %% [19.0] update BOL and yylineno */
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol )
-
+
do{ yylineno++;
yycolumn=0;
}while(0)
@@ -1848,7 +2038,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
* @note This function does not reset the start condition to @c INITIAL .
*/
/* %if-c-only */
- void conf_parser_restart (FILE * input_file , yyscan_t yyscanner)
+ void yyrestart (FILE * input_file , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -1856,13 +2046,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( ! YY_CURRENT_BUFFER ){
- conf_parser_ensure_buffer_stack (yyscanner);
+ yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- conf_parser__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- conf_parser__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- conf_parser__load_buffer_state(yyscanner );
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
+ yy_load_buffer_state( yyscanner );
}
/* %if-c++-only */
@@ -1873,7 +2063,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
* @param yyscanner The scanner object.
*/
/* %if-c-only */
- void conf_parser__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -1882,10 +2072,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* TODO. We should be able to replace this entire function body
* with
- * conf_parser_pop_buffer_state();
- * conf_parser_push_buffer_state(new_buffer);
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
*/
- conf_parser_ensure_buffer_stack (yyscanner);
+ yyensure_buffer_stack (yyscanner);
if ( YY_CURRENT_BUFFER == new_buffer )
return;
@@ -1898,18 +2088,18 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
}
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- conf_parser__load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
/* We don't actually know whether we did this switch during
- * EOF (conf_parser_wrap()) processing, but the only time this flag
- * is looked at is after conf_parser_wrap() is called, so it's safe
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
* to go ahead and always set it.
*/
yyg->yy_did_buffer_switch_on_eof = 1;
}
/* %if-c-only */
-static void conf_parser__load_buffer_state (yyscan_t yyscanner)
+static void yy_load_buffer_state (yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -1932,29 +2122,29 @@ static void conf_parser__load_buffer_state (yyscan_t yyscanner)
* @return the allocated buffer state.
*/
/* %if-c-only */
- YY_BUFFER_STATE conf_parser__create_buffer (FILE * file, int size , yyscan_t yyscanner)
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
{
YY_BUFFER_STATE b;
- b = (YY_BUFFER_STATE) conf_parser_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in conf_parser__create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
- b->yy_buf_size = (yy_size_t)size;
+ b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
- b->yy_ch_buf = (char *) conf_parser_alloc(b->yy_buf_size + 2 ,yyscanner );
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in conf_parser__create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_is_our_buffer = 1;
- conf_parser__init_buffer(b,file ,yyscanner);
+ yy_init_buffer( b, file , yyscanner);
return b;
}
@@ -1963,11 +2153,11 @@ static void conf_parser__load_buffer_state (yyscan_t yyscanner)
/* %endif */
/** Destroy the buffer.
- * @param b a buffer created with conf_parser__create_buffer()
+ * @param b a buffer created with yy_create_buffer()
* @param yyscanner The scanner object.
*/
/* %if-c-only */
- void conf_parser__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -1981,17 +2171,17 @@ static void conf_parser__load_buffer_state (yyscan_t yyscanner)
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- conf_parser_free((void *) b->yy_ch_buf ,yyscanner );
+ yyfree( (void *) b->yy_ch_buf , yyscanner );
- conf_parser_free((void *) b ,yyscanner );
+ yyfree( (void *) b , yyscanner );
}
/* Initializes or reinitializes a buffer.
* This function is sometimes called more than once on the same buffer,
- * such as during a conf_parser_restart() or at EOF.
+ * such as during a yyrestart() or at EOF.
*/
/* %if-c-only */
- static void conf_parser__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2000,7 +2190,7 @@ static void conf_parser__load_buffer_state (yyscan_t yyscanner)
int oerrno = errno;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- conf_parser__flush_buffer(b ,yyscanner);
+ yy_flush_buffer( b , yyscanner);
/* %if-c-only */
b->yy_input_file = file;
@@ -2009,8 +2199,8 @@ static void conf_parser__load_buffer_state (yyscan_t yyscanner)
/* %endif */
b->yy_fill_buffer = 1;
- /* If b is the current buffer, then conf_parser__init_buffer was _probably_
- * called from conf_parser_restart() or through yy_get_next_buffer.
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
* In that case, we don't want to reset the lineno or column.
*/
if (b != YY_CURRENT_BUFFER){
@@ -2020,7 +2210,7 @@ static void conf_parser__load_buffer_state (yyscan_t yyscanner)
/* %if-c-only */
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+ b->yy_is_interactive = 0;
/* %endif */
/* %if-c++-only */
@@ -2033,7 +2223,7 @@ static void conf_parser__load_buffer_state (yyscan_t yyscanner)
* @param yyscanner The scanner object.
*/
/* %if-c-only */
- void conf_parser__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2057,7 +2247,7 @@ static void conf_parser__load_buffer_state (yyscan_t yyscanner)
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == YY_CURRENT_BUFFER )
- conf_parser__load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
/* %if-c-or-c++ */
@@ -2068,7 +2258,7 @@ static void conf_parser__load_buffer_state (yyscan_t yyscanner)
* @param yyscanner The scanner object.
*/
/* %if-c-only */
-void conf_parser_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2077,9 +2267,9 @@ void conf_parser_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscan
if (new_buffer == NULL)
return;
- conf_parser_ensure_buffer_stack(yyscanner);
+ yyensure_buffer_stack(yyscanner);
- /* This block is copied from conf_parser__switch_to_buffer. */
+ /* This block is copied from yy_switch_to_buffer. */
if ( YY_CURRENT_BUFFER )
{
/* Flush out information for old buffer. */
@@ -2093,8 +2283,8 @@ void conf_parser_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscan
yyg->yy_buffer_stack_top++;
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- /* copied from conf_parser__switch_to_buffer. */
- conf_parser__load_buffer_state(yyscanner );
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
/* %endif */
@@ -2105,7 +2295,7 @@ void conf_parser_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscan
* @param yyscanner The scanner object.
*/
/* %if-c-only */
-void conf_parser_pop_buffer_state (yyscan_t yyscanner)
+void yypop_buffer_state (yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2114,13 +2304,13 @@ void conf_parser_pop_buffer_state (yyscan_t yyscanner)
if (!YY_CURRENT_BUFFER)
return;
- conf_parser__delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
YY_CURRENT_BUFFER_LVALUE = NULL;
if (yyg->yy_buffer_stack_top > 0)
--yyg->yy_buffer_stack_top;
if (YY_CURRENT_BUFFER) {
- conf_parser__load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
}
@@ -2131,7 +2321,7 @@ void conf_parser_pop_buffer_state (yyscan_t yyscanner)
* Guarantees space for at least one push.
*/
/* %if-c-only */
-static void conf_parser_ensure_buffer_stack (yyscan_t yyscanner)
+static void yyensure_buffer_stack (yyscan_t yyscanner)
/* %endif */
/* %if-c++-only */
/* %endif */
@@ -2145,15 +2335,15 @@ static void conf_parser_ensure_buffer_stack (yyscan_t yyscanner)
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
- num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
- yyg->yy_buffer_stack = (struct yy_buffer_state**)conf_parser_alloc
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in conf_parser_ensure_buffer_stack()" );
-
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
yyg->yy_buffer_stack_max = num_to_alloc;
yyg->yy_buffer_stack_top = 0;
return;
@@ -2165,12 +2355,12 @@ static void conf_parser_ensure_buffer_stack (yyscan_t yyscanner)
yy_size_t grow_size = 8 /* arbitrary grow size */;
num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)conf_parser_realloc
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
(yyg->yy_buffer_stack,
num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in conf_parser_ensure_buffer_stack()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
/* zero only the new slots.*/
memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -2184,9 +2374,9 @@ static void conf_parser_ensure_buffer_stack (yyscan_t yyscanner)
* @param base the character buffer
* @param size the size in bytes of the character buffer
* @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE conf_parser__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
@@ -2194,73 +2384,73 @@ YY_BUFFER_STATE conf_parser__scan_buffer (char * base, yy_size_t size , yyscan
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
- return 0;
+ return NULL;
- b = (YY_BUFFER_STATE) conf_parser_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in conf_parser__scan_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
+ b->yy_input_file = NULL;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- conf_parser__switch_to_buffer(b ,yyscanner );
+ yy_switch_to_buffer( b , yyscanner );
return b;
}
/* %endif */
/* %if-c-only */
-/** Setup the input buffer state to scan a string. The next call to conf_parser_lex() will
+/** Setup the input buffer state to scan a string. The next call to yylex() will
* scan from a @e copy of @a str.
* @param yystr a NUL-terminated string to scan
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
- * conf_parser__scan_bytes() instead.
+ * yy_scan_bytes() instead.
*/
-YY_BUFFER_STATE conf_parser__scan_string (yyconst char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
{
- return conf_parser__scan_bytes(yystr,strlen(yystr) ,yyscanner);
+ return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
}
/* %endif */
/* %if-c-only */
-/** Setup the input buffer state to scan the given bytes. The next call to conf_parser_lex() will
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
* scan from a @e copy of @a bytes.
* @param yybytes the byte buffer to scan
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE conf_parser__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) conf_parser_alloc(n ,yyscanner );
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n , yyscanner );
if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in conf_parser__scan_bytes()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
for ( i = 0; i < _yybytes_len; ++i )
buf[i] = yybytes[i];
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = conf_parser__scan_buffer(buf,n ,yyscanner);
+ b = yy_scan_buffer( buf, n , yyscanner);
if ( ! b )
- YY_FATAL_ERROR( "bad buffer in conf_parser__scan_bytes()" );
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
/* It's okay to grow etc. this buffer, and we should throw it
* away when we're done.
@@ -2283,13 +2473,14 @@ YY_BUFFER_STATE conf_parser__scan_bytes (yyconst char * yybytes, yy_size_t _yy
yy_size_t new_size;
yyg->yy_start_stack_depth += YY_START_STACK_INCR;
- new_size = yyg->yy_start_stack_depth * sizeof( int );
+ new_size = (yy_size_t) yyg->yy_start_stack_depth * sizeof( int );
if ( ! yyg->yy_start_stack )
- yyg->yy_start_stack = (int *) conf_parser_alloc(new_size ,yyscanner );
+ yyg->yy_start_stack = (int *) yyalloc( new_size , yyscanner );
else
- yyg->yy_start_stack = (int *) conf_parser_realloc((void *) yyg->yy_start_stack,new_size ,yyscanner );
+ yyg->yy_start_stack = (int *) yyrealloc(
+ (void *) yyg->yy_start_stack, new_size , yyscanner );
if ( ! yyg->yy_start_stack )
YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
@@ -2328,11 +2519,11 @@ YY_BUFFER_STATE conf_parser__scan_bytes (yyconst char * yybytes, yy_size_t _yy
#endif
/* %if-c-only */
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- (void) fprintf( stderr, "%s\n", msg );
+ fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
/* %endif */
@@ -2364,7 +2555,7 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
/** Get the user-defined data for this scanner.
* @param yyscanner The scanner object.
*/
-YY_EXTRA_TYPE conf_parser_get_extra (yyscan_t yyscanner)
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyextra;
@@ -2375,10 +2566,10 @@ YY_EXTRA_TYPE conf_parser_get_extra (yyscan_t yyscanner)
/** Get the current line number.
* @param yyscanner The scanner object.
*/
-int conf_parser_get_lineno (yyscan_t yyscanner)
+int yyget_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2388,10 +2579,10 @@ int conf_parser_get_lineno (yyscan_t yyscanner)
/** Get the current column number.
* @param yyscanner The scanner object.
*/
-int conf_parser_get_column (yyscan_t yyscanner)
+int yyget_column (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2401,7 +2592,7 @@ int conf_parser_get_column (yyscan_t yyscanner)
/** Get the input stream.
* @param yyscanner The scanner object.
*/
-FILE *conf_parser_get_in (yyscan_t yyscanner)
+FILE *yyget_in (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyin;
@@ -2410,7 +2601,7 @@ FILE *conf_parser_get_in (yyscan_t yyscanner)
/** Get the output stream.
* @param yyscanner The scanner object.
*/
-FILE *conf_parser_get_out (yyscan_t yyscanner)
+FILE *yyget_out (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyout;
@@ -2419,7 +2610,7 @@ FILE *conf_parser_get_out (yyscan_t yyscanner)
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-yy_size_t conf_parser_get_leng (yyscan_t yyscanner)
+int yyget_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
@@ -2429,7 +2620,7 @@ yy_size_t conf_parser_get_leng (yyscan_t yyscanner)
* @param yyscanner The scanner object.
*/
-char *conf_parser_get_text (yyscan_t yyscanner)
+char *yyget_text (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yytext;
@@ -2441,7 +2632,7 @@ char *conf_parser_get_text (yyscan_t yyscanner)
* @param user_defined The data to be associated with this scanner.
* @param yyscanner The scanner object.
*/
-void conf_parser_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyextra = user_defined ;
@@ -2453,13 +2644,13 @@ void conf_parser_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
* @param _line_number line number
* @param yyscanner The scanner object.
*/
-void conf_parser_set_lineno (int _line_number , yyscan_t yyscanner)
+void yyset_lineno (int _line_number , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- YY_FATAL_ERROR( "conf_parser_set_lineno called with no buffer" );
+ YY_FATAL_ERROR( "yyset_lineno called with no buffer" );
yylineno = _line_number;
}
@@ -2468,13 +2659,13 @@ void conf_parser_set_lineno (int _line_number , yyscan_t yyscanner)
* @param _column_no column number
* @param yyscanner The scanner object.
*/
-void conf_parser_set_column (int _column_no , yyscan_t yyscanner)
+void yyset_column (int _column_no , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* column is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- YY_FATAL_ERROR( "conf_parser_set_column called with no buffer" );
+ YY_FATAL_ERROR( "yyset_column called with no buffer" );
yycolumn = _column_no;
}
@@ -2483,27 +2674,27 @@ void conf_parser_set_column (int _column_no , yyscan_t yyscanner)
* input buffer.
* @param _in_str A readable stream.
* @param yyscanner The scanner object.
- * @see conf_parser__switch_to_buffer
+ * @see yy_switch_to_buffer
*/
-void conf_parser_set_in (FILE * _in_str , yyscan_t yyscanner)
+void yyset_in (FILE * _in_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyin = _in_str ;
}
-void conf_parser_set_out (FILE * _out_str , yyscan_t yyscanner)
+void yyset_out (FILE * _out_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyout = _out_str ;
}
-int conf_parser_get_debug (yyscan_t yyscanner)
+int yyget_debug (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yy_flex_debug;
}
-void conf_parser_set_debug (int _bdebug , yyscan_t yyscanner)
+void yyset_debug (int _bdebug , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_flex_debug = _bdebug ;
@@ -2516,13 +2707,13 @@ void conf_parser_set_debug (int _bdebug , yyscan_t yyscanner)
/* %if-bison-bridge */
-YYSTYPE * conf_parser_get_lval (yyscan_t yyscanner)
+YYSTYPE * yyget_lval (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yylval;
}
-void conf_parser_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yylval = yylval_param;
@@ -2532,20 +2723,18 @@ void conf_parser_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
/* User-visible API */
-/* conf_parser_lex_init is special because it creates the scanner itself, so it is
+/* yylex_init is special because it creates the scanner itself, so it is
* the ONLY reentrant function that doesn't take the scanner as the last argument.
* That's why we explicitly handle the declaration, instead of using our macros.
*/
-
-int conf_parser_lex_init(yyscan_t* ptr_yy_globals)
-
+int yylex_init(yyscan_t* ptr_yy_globals)
{
if (ptr_yy_globals == NULL){
errno = EINVAL;
return 1;
}
- *ptr_yy_globals = (yyscan_t) conf_parser_alloc ( sizeof( struct yyguts_t ), NULL );
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
@@ -2558,39 +2747,37 @@ int conf_parser_lex_init(yyscan_t* ptr_yy_globals)
return yy_init_globals ( *ptr_yy_globals );
}
-/* conf_parser_lex_init_extra has the same functionality as conf_parser_lex_init, but follows the
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
* convention of taking the scanner as the last argument. Note however, that
* this is a *pointer* to a scanner, as it will be allocated by this call (and
* is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to conf_parser_alloc in
+ * The user defined value in the first argument will be available to yyalloc in
* the yyextra field.
*/
-
-int conf_parser_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
+int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
{
struct yyguts_t dummy_yyguts;
- conf_parser_set_extra (yy_user_defined, &dummy_yyguts);
+ yyset_extra (yy_user_defined, &dummy_yyguts);
if (ptr_yy_globals == NULL){
errno = EINVAL;
return 1;
}
-
- *ptr_yy_globals = (yyscan_t) conf_parser_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
return 1;
}
-
+
/* By setting to 0xAA, we expose bugs in
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- conf_parser_set_extra (yy_user_defined, *ptr_yy_globals);
-
+
+ yyset_extra (yy_user_defined, *ptr_yy_globals);
+
return yy_init_globals ( *ptr_yy_globals );
}
@@ -2601,13 +2788,13 @@ static int yy_init_globals (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Initialization is the same as for the non-reentrant scanner.
- * This function is called from conf_parser_lex_destroy(), so don't allocate here.
+ * This function is called from yylex_destroy(), so don't allocate here.
*/
- yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack = NULL;
yyg->yy_buffer_stack_top = 0;
yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_c_buf_p = NULL;
yyg->yy_init = 0;
yyg->yy_start = 0;
@@ -2620,45 +2807,45 @@ static int yy_init_globals (yyscan_t yyscanner)
yyin = stdin;
yyout = stdout;
#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
+ yyin = NULL;
+ yyout = NULL;
#endif
/* For future reference: Set errno on error, since we are called by
- * conf_parser_lex_init()
+ * yylex_init()
*/
return 0;
}
/* %endif */
/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
-/* conf_parser_lex_destroy is for both reentrant and non-reentrant scanners. */
-int conf_parser_lex_destroy (yyscan_t yyscanner)
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
- conf_parser__delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
YY_CURRENT_BUFFER_LVALUE = NULL;
- conf_parser_pop_buffer_state(yyscanner);
+ yypop_buffer_state(yyscanner);
}
/* Destroy the stack itself. */
- conf_parser_free(yyg->yy_buffer_stack ,yyscanner);
+ yyfree(yyg->yy_buffer_stack , yyscanner);
yyg->yy_buffer_stack = NULL;
/* Destroy the start condition stack. */
- conf_parser_free(yyg->yy_start_stack ,yyscanner );
+ yyfree( yyg->yy_start_stack , yyscanner );
yyg->yy_start_stack = NULL;
/* Reset the globals. This is important in a non-reentrant scanner so the next time
- * conf_parser_lex() is called, initialization will occur. */
+ * yylex() is called, initialization will occur. */
yy_init_globals( yyscanner);
/* %if-reentrant */
/* Destroy the main struct (reentrant only). */
- conf_parser_free ( yyscanner , yyscanner );
+ yyfree ( yyscanner , yyscanner );
yyscanner = NULL;
/* %endif */
return 0;
@@ -2670,7 +2857,7 @@ int conf_parser_lex_destroy (yyscan_t yyscanner)
*/
#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
@@ -2682,7 +2869,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yysca
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
{
int n;
for ( n = 0; s[n]; ++n )
@@ -2692,14 +2879,14 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
}
#endif
-void *conf_parser_alloc (yy_size_t size , yyscan_t yyscanner)
+void *yyalloc (yy_size_t size , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- return (void *) malloc( size );
+ return malloc(size);
}
-void *conf_parser_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
@@ -2711,14 +2898,14 @@ void *conf_parser_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
- return (void *) realloc( (char *) ptr, size );
+ return realloc(ptr, size);
}
-void conf_parser_free (void * ptr , yyscan_t yyscanner)
+void yyfree (void * ptr , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- free( (char *) ptr ); /* see conf_parser_realloc() for (char *) cast */
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
}
/* %if-tables-serialization definitions */
@@ -2728,8 +2915,7 @@ void conf_parser_free (void * ptr , yyscan_t yyscanner)
/* %ok-for-header */
-#line 163 "parser/lexer.l"
-
+#line 168 "parser/lexer.l"
/**
diff --git a/src/starter/parser/lexer.l b/src/starter/parser/lexer.l
index fb23a0f93..b81d6ce74 100644
--- a/src/starter/parser/lexer.l
+++ b/src/starter/parser/lexer.l
@@ -33,6 +33,11 @@ static void include_files(parser_helper_t *ctx);
/* do not declare unneeded functions */
%option noinput noyywrap
+/* do not include unistd.h as it might conflict with our scanner states */
+%option nounistd
+/* due to that disable interactive mode, which requires isatty() */
+%option never-interactive
+
/* don't use global variables, and interact properly with bison */
%option reentrant bison-bridge
diff --git a/src/stroke/stroke_keywords.c b/src/stroke/stroke_keywords.c
index 17a3663fe..33d735164 100644
--- a/src/stroke/stroke_keywords.c
+++ b/src/stroke/stroke_keywords.c
@@ -1,4 +1,4 @@
-/* C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.1 */
/* Command-line: /usr/bin/gperf -m 10 -D -C -G -t */
/* Computed positions: -k'1,5,7' */
@@ -26,7 +26,7 @@
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
-error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
#endif
@@ -69,9 +69,7 @@ inline
#endif
#endif
static unsigned int
-hash (str, len)
- register const char *str;
- register unsigned int len;
+hash (register const char *str, register size_t len)
{
static const unsigned char asso_values[] =
{
@@ -102,7 +100,7 @@ hash (str, len)
60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
60, 60, 60, 60, 60, 60
};
- register int hval = len;
+ register unsigned int hval = len;
switch (hval)
{
@@ -175,7 +173,7 @@ static const struct stroke_token wordlist[] =
{"resetcounters", STROKE_COUNTERS_RESET}
};
-static const short lookup[] =
+static const signed char lookup[] =
{
-1, -1, -1, 0, 1, 2, -1, 3, -1, 4, -1, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
@@ -184,22 +182,14 @@ static const short lookup[] =
-1, 46, -1, 47
};
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
const struct stroke_token *
-in_word_set (str, len)
- register const char *str;
- register unsigned int len;
+in_word_set (register const char *str, register size_t len)
{
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- register int key = hash (str, len);
+ register unsigned int key = hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
register int index = lookup[key];
diff --git a/src/stroke/stroke_keywords.h b/src/stroke/stroke_keywords.h
index 4e0b66b3d..fa86ccb47 100644
--- a/src/stroke/stroke_keywords.h
+++ b/src/stroke/stroke_keywords.h
@@ -74,6 +74,6 @@ typedef enum {
typedef struct stroke_token stroke_token_t;
extern const stroke_token_t* in_word_set(register const char *str,
- register unsigned len);
+ register size_t len);
#endif /* _STROKE_KEYWORDS_H_ */
diff --git a/src/sw-collector/sw-collector.c b/src/sw-collector/sw-collector.c
index f8229a192..5453eeb60 100644
--- a/src/sw-collector/sw-collector.c
+++ b/src/sw-collector/sw-collector.c
@@ -27,7 +27,7 @@
#include "sw_collector_history.h"
#include "sw_collector_rest_api.h"
#include "sw_collector_dpkg.h"
-#
+
#include <library.h>
#include <utils/debug.h>
#include <utils/lexparser.h>
@@ -165,7 +165,6 @@ static collector_op_t do_args(int argc, char *argv[], bool *full_tags,
case 'h':
usage();
exit(SUCCESS);
- break;
case 'C':
op = COLLECTOR_OP_CHECK;
continue;
diff --git a/src/swanctl/commands/load_all.c b/src/swanctl/commands/load_all.c
index 26f043a6a..d0032467a 100644
--- a/src/swanctl/commands/load_all.c
+++ b/src/swanctl/commands/load_all.c
@@ -31,7 +31,7 @@ static int load_all(vici_conn_t *conn)
bool clear = FALSE, noprompt = FALSE;
command_format_options_t format = COMMAND_FORMAT_NONE;
settings_t *cfg;
- char *arg, *file = SWANCTL_CONF;
+ char *arg, *file = NULL;
int ret = 0;
while (TRUE)
@@ -63,10 +63,9 @@ static int load_all(vici_conn_t *conn)
break;
}
- cfg = settings_create(file);
+ cfg = load_swanctl_conf(file);
if (!cfg)
{
- fprintf(stderr, "parsing '%s' failed\n", file);
return EINVAL;
}
diff --git a/src/swanctl/commands/load_authorities.c b/src/swanctl/commands/load_authorities.c
index 61682a386..a4e1f46d3 100644
--- a/src/swanctl/commands/load_authorities.c
+++ b/src/swanctl/commands/load_authorities.c
@@ -55,8 +55,9 @@ static bool add_file_key_value(vici_req_t *req, char *key, char *value)
else
{
path = buf;
- snprintf(path, PATH_MAX, "%s%s%s",
- SWANCTL_X509CADIR, DIRECTORY_SEPARATOR, value);
+ snprintf(path, PATH_MAX, "%s%s%s%s%s", swanctl_dir,
+ DIRECTORY_SEPARATOR, SWANCTL_X509CADIR,
+ DIRECTORY_SEPARATOR, value);
}
map = chunk_map(path, FALSE);
@@ -83,7 +84,6 @@ static bool add_key_values(vici_req_t *req, enumerator_t *enumerator)
char *key, *value;
bool ret = TRUE;
-
while (enumerator->enumerate(enumerator, &key, &value))
{
if (streq(key, "cacert"))
@@ -310,7 +310,7 @@ static int load_authorities(vici_conn_t *conn)
{
command_format_options_t format = COMMAND_FORMAT_NONE;
settings_t *cfg;
- char *arg, *file = SWANCTL_CONF;
+ char *arg, *file = NULL;
int ret;
while (TRUE)
@@ -336,10 +336,9 @@ static int load_authorities(vici_conn_t *conn)
break;
}
- cfg = settings_create(file);
+ cfg = load_swanctl_conf(file);
if (!cfg)
{
- fprintf(stderr, "parsing '%s' failed\n", file);
return EINVAL;
}
diff --git a/src/swanctl/commands/load_conns.c b/src/swanctl/commands/load_conns.c
index dad03945d..de23816fb 100644
--- a/src/swanctl/commands/load_conns.c
+++ b/src/swanctl/commands/load_conns.c
@@ -120,20 +120,23 @@ static bool add_file_list_key(vici_req_t *req, char *key, char *value)
{
if (streq(key, "certs"))
{
- snprintf(buf, sizeof(buf), "%s%s%s",
- SWANCTL_X509DIR, DIRECTORY_SEPARATOR, token);
+ snprintf(buf, sizeof(buf), "%s%s%s%s%s", swanctl_dir,
+ DIRECTORY_SEPARATOR, SWANCTL_X509DIR,
+ DIRECTORY_SEPARATOR, token);
token = buf;
}
else if (streq(key, "cacerts"))
{
- snprintf(buf, sizeof(buf), "%s%s%s",
- SWANCTL_X509CADIR, DIRECTORY_SEPARATOR, token);
+ snprintf(buf, sizeof(buf), "%s%s%s%s%s", swanctl_dir,
+ DIRECTORY_SEPARATOR, SWANCTL_X509CADIR,
+ DIRECTORY_SEPARATOR, token);
token = buf;
}
else if (streq(key, "pubkeys"))
{
- snprintf(buf, sizeof(buf), "%s%s%s",
- SWANCTL_PUBKEYDIR, DIRECTORY_SEPARATOR, token);
+ snprintf(buf, sizeof(buf), "%s%s%s%s%s", swanctl_dir,
+ DIRECTORY_SEPARATOR, SWANCTL_PUBKEYDIR,
+ DIRECTORY_SEPARATOR, token);
token = buf;
}
}
@@ -425,7 +428,7 @@ static int load_conns(vici_conn_t *conn)
{
command_format_options_t format = COMMAND_FORMAT_NONE;
settings_t *cfg;
- char *arg, *file = SWANCTL_CONF;
+ char *arg, *file = NULL;
int ret;
while (TRUE)
@@ -451,10 +454,9 @@ static int load_conns(vici_conn_t *conn)
break;
}
- cfg = settings_create(file);
+ cfg = load_swanctl_conf(file);
if (!cfg)
{
- fprintf(stderr, "parsing '%s' failed\n", file);
return EINVAL;
}
diff --git a/src/swanctl/commands/load_creds.c b/src/swanctl/commands/load_creds.c
index a9e352f7e..9a38b5d1e 100644
--- a/src/swanctl/commands/load_creds.c
+++ b/src/swanctl/commands/load_creds.c
@@ -106,10 +106,13 @@ static void load_certs(load_ctx_t *ctx, char *type_str, char *dir)
x509_flag_t flag;
struct stat st;
chunk_t *map;
- char *path;
+ char *path, buf[PATH_MAX];
vici_cert_info_from_str(type_str, &type, &flag);
+ snprintf(buf, sizeof(buf), "%s%s%s", swanctl_dir, DIRECTORY_SEPARATOR, dir);
+ dir = buf;
+
enumerator = enumerator_create_directory(dir);
if (enumerator)
{
@@ -428,7 +431,10 @@ static void load_keys(load_ctx_t *ctx, char *type, char *dir)
enumerator_t *enumerator;
struct stat st;
chunk_t *map;
- char *path, *rel;
+ char *path, *rel, buf[PATH_MAX];
+
+ snprintf(buf, sizeof(buf), "%s%s%s", swanctl_dir, DIRECTORY_SEPARATOR, dir);
+ dir = buf;
enumerator = enumerator_create_directory(dir);
if (enumerator)
@@ -535,7 +541,10 @@ static void load_containers(load_ctx_t *ctx, char *type, char *dir)
enumerator_t *enumerator;
struct stat st;
chunk_t *map;
- char *path, *rel;
+ char *path, *rel, buf[PATH_MAX];
+
+ snprintf(buf, sizeof(buf), "%s%s%s", swanctl_dir, DIRECTORY_SEPARATOR, dir);
+ dir = buf;
enumerator = enumerator_create_directory(dir);
if (enumerator)
@@ -946,7 +955,7 @@ static int load_creds(vici_conn_t *conn)
bool clear = FALSE, noprompt = FALSE;
command_format_options_t format = COMMAND_FORMAT_NONE;
settings_t *cfg;
- char *arg, *file = SWANCTL_CONF;
+ char *arg, *file = NULL;
int ret;
while (TRUE)
@@ -978,10 +987,9 @@ static int load_creds(vici_conn_t *conn)
break;
}
- cfg = settings_create(file);
+ cfg = load_swanctl_conf(file);
if (!cfg)
{
- fprintf(stderr, "parsing '%s' failed\n", file);
return EINVAL;
}
diff --git a/src/swanctl/commands/load_pools.c b/src/swanctl/commands/load_pools.c
index ec9508efb..0ff6827e1 100644
--- a/src/swanctl/commands/load_pools.c
+++ b/src/swanctl/commands/load_pools.c
@@ -251,7 +251,7 @@ static int load_pools(vici_conn_t *conn)
{
command_format_options_t format = COMMAND_FORMAT_NONE;
settings_t *cfg;
- char *arg, *file = SWANCTL_CONF;
+ char *arg, *file = NULL;
int ret;
while (TRUE)
@@ -277,10 +277,9 @@ static int load_pools(vici_conn_t *conn)
break;
}
- cfg = settings_create(file);
+ cfg = load_swanctl_conf(file);
if (!cfg)
{
- fprintf(stderr, "parsing '%s' failed\n", file);
return EINVAL;
}
diff --git a/src/swanctl/commands/rekey.c b/src/swanctl/commands/rekey.c
index f44ecaa3c..65a402029 100644
--- a/src/swanctl/commands/rekey.c
+++ b/src/swanctl/commands/rekey.c
@@ -118,7 +118,7 @@ static void __attribute__ ((constructor))reg()
{
command_register((command_t) {
rekey, 'R', "rekey", "rekey an SA",
- {"--child <name> | --ike <name | --child-id <id> | --ike-id <id>",
+ {"--child <name> | --ike <name> | --child-id <id> | --ike-id <id>",
"[--reauth] [--raw|--pretty]"},
{
{"help", 'h', 0, "show usage information"},
diff --git a/src/swanctl/commands/terminate.c b/src/swanctl/commands/terminate.c
index bce404a54..2309843b2 100644
--- a/src/swanctl/commands/terminate.c
+++ b/src/swanctl/commands/terminate.c
@@ -150,7 +150,7 @@ static void __attribute__ ((constructor))reg()
{
command_register((command_t) {
terminate, 't', "terminate", "terminate a connection",
- {"--child <name> | --ike <name | --child-id <id> | --ike-id <id>",
+ {"--child <name> | --ike <name> | --child-id <id> | --ike-id <id>",
"[--timeout <s>] [--raw|--pretty]"},
{
{"help", 'h', 0, "show usage information"},
diff --git a/src/swanctl/swanctl.c b/src/swanctl/swanctl.c
index dc5af79a7..cfc82f9d7 100644
--- a/src/swanctl/swanctl.c
+++ b/src/swanctl/swanctl.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2018 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2014 Martin Willi
* Copyright (C) 2014 revosec AG
*
@@ -13,17 +16,55 @@
* for more details.
*/
+#include "swanctl.h"
#include "command.h"
#include <unistd.h>
#include <library.h>
+/*
+ * Described in header
+ */
+char *swanctl_dir;
+
+/*
+ * Described in header
+ */
+settings_t *load_swanctl_conf(char *file)
+{
+ settings_t *cfg;
+ char buf[PATH_MAX];
+
+ if (!file)
+ {
+ if (!strlen(swanctl_dir))
+ {
+ free(swanctl_dir);
+ swanctl_dir = strdup(getcwd(buf, sizeof(buf)));
+ }
+ file = buf;
+ snprintf(buf, sizeof(buf), "%s%s%s", swanctl_dir,
+ DIRECTORY_SEPARATOR, SWANCTL_CONF);
+ }
+
+ cfg = settings_create(file);
+ if (!cfg)
+ {
+ fprintf(stderr, "parsing '%s' failed\n", file);
+ return NULL;
+ }
+ free(swanctl_dir);
+ swanctl_dir = path_dirname(file);
+ return cfg;
+}
+
/**
* Cleanup library atexit()
*/
static void cleanup()
{
+ free(swanctl_dir);
lib->processor->cancel(lib->processor);
library_deinit();
}
@@ -49,6 +90,9 @@ int main(int argc, char *argv[])
{
exit(SS_RC_INITIALIZATION_FAILED);
}
+
+ swanctl_dir = strdup(getenv("SWANCTL_DIR") ?: SWANCTLDIR);
+
dbg_default_set_level(0);
lib->processor->set_threads(lib->processor, 4);
dbg_default_set_level(1);
diff --git a/src/swanctl/swanctl.h b/src/swanctl/swanctl.h
index eac1fc6d0..f0c334f7e 100644
--- a/src/swanctl/swanctl.h
+++ b/src/swanctl/swanctl.h
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2014 Martin Willi
- * Copyright (C) 2014 revosec AG
- *
- * Copyright (C) 2016 Tobias Brunner
+ * Copyright (C) 2016-2018 Tobias Brunner
* Copyright (C) 2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
@@ -25,74 +25,90 @@
#ifndef SWANCTL_H_
#define SWANCTL_H_
+#include <settings/settings.h>
+
+/**
+ * Base directory for credentials and config
+ */
+char *swanctl_dir;
+
/**
* Configuration file for connections, etc.
*/
-#define SWANCTL_CONF SWANCTLDIR "/swanctl.conf"
+#define SWANCTL_CONF "swanctl.conf"
/**
* Directory for X.509 end entity certs
*/
-#define SWANCTL_X509DIR SWANCTLDIR "/x509"
+#define SWANCTL_X509DIR "x509"
/**
* Directory for X.509 CA certs
*/
-#define SWANCTL_X509CADIR SWANCTLDIR "/x509ca"
+#define SWANCTL_X509CADIR "x509ca"
/**
* Directory for X.509 Attribute Authority certs
*/
-#define SWANCTL_X509AADIR SWANCTLDIR "/x509aa"
+#define SWANCTL_X509AADIR "x509aa"
/**
* Directory for X.509 OCSP Signer certs
*/
-#define SWANCTL_X509OCSPDIR SWANCTLDIR "/x509ocsp"
+#define SWANCTL_X509OCSPDIR "x509ocsp"
/**
* Directory for X.509 CRLs
*/
-#define SWANCTL_X509CRLDIR SWANCTLDIR "/x509crl"
+#define SWANCTL_X509CRLDIR "x509crl"
/**
* Directory for X.509 Attribute certificates
*/
-#define SWANCTL_X509ACDIR SWANCTLDIR "/x509ac"
+#define SWANCTL_X509ACDIR "x509ac"
/**
* Directory for raw public keys
*/
-#define SWANCTL_PUBKEYDIR SWANCTLDIR "/pubkey"
+#define SWANCTL_PUBKEYDIR "pubkey"
/**
* Directory for private keys
*/
-#define SWANCTL_PRIVATEDIR SWANCTLDIR "/private"
+#define SWANCTL_PRIVATEDIR "private"
/**
* Directory for RSA private keys
*/
-#define SWANCTL_RSADIR SWANCTLDIR "/rsa"
+#define SWANCTL_RSADIR "rsa"
/**
* Directory for ECDSA private keys
*/
-#define SWANCTL_ECDSADIR SWANCTLDIR "/ecdsa"
+#define SWANCTL_ECDSADIR "ecdsa"
/**
* Directory for BLISS private keys
*/
-#define SWANCTL_BLISSDIR SWANCTLDIR "/bliss"
+#define SWANCTL_BLISSDIR "bliss"
/**
* Directory for PKCS#8 encoded private keys
*/
-#define SWANCTL_PKCS8DIR SWANCTLDIR "/pkcs8"
+#define SWANCTL_PKCS8DIR "pkcs8"
/**
* Directory for PKCS#12 containers
*/
-#define SWANCTL_PKCS12DIR SWANCTLDIR "/pkcs12"
+#define SWANCTL_PKCS12DIR "pkcs12"
+
+/**
+ * Load swanctl.conf, optionally from a custom path. Sets the base dir relative
+ * to that file.
+ *
+ * @param file optional custom path to swanctl.conf, NULL to use default
+ * @return settings, or NULL if loading failed
+ */
+settings_t *load_swanctl_conf(char *file);
#endif /** SWANCTL_H_ @}*/