#include <string.h>
#include <library.h>
-#include <debug.h>
+#include <utils/debug.h>
#include <tls_socket.h>
-#include <utils/host.h>
+#include <networking/host.h>
#include <credentials/sets/mem_cred.h>
/**
static void usage(FILE *out, char *cmd)
{
fprintf(out, "usage:\n");
- fprintf(out, " %s --connect <address> --port <port> [--cert <file>]+ [--times <n>]\n", cmd);
+ fprintf(out, " %s --connect <address> --port <port> [--key <key] [--cert <file>]+ [--times <n>]\n", cmd);
fprintf(out, " %s --listen <address> --port <port> --key <key> [--cert <file>]+ [--times <n>]\n", cmd);
}
/**
- * Stream between stdio and TLS socket
+ * Check, as client, if we have a client certificate with private key
*/
-static int stream(int fd, tls_socket_t *tls)
+static identification_t *find_client_id()
{
- while (TRUE)
- {
- fd_set set;
- chunk_t data;
-
- FD_ZERO(&set);
- FD_SET(fd, &set);
- FD_SET(0, &set);
+ identification_t *client = NULL, *keyid;
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ public_key_t *pubkey;
+ private_key_t *privkey;
+ chunk_t chunk;
- if (select(fd + 1, &set, NULL, NULL, NULL) == -1)
- {
- return 1;
- }
- if (FD_ISSET(fd, &set))
- {
- if (!tls->read(tls, &data))
- {
- return 0;
- }
- if (data.len)
- {
- ignore_result(write(1, data.ptr, data.len));
- free(data.ptr);
- }
- }
- if (FD_ISSET(0, &set))
+ enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
+ CERT_X509, KEY_ANY, NULL, FALSE);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ pubkey = cert->get_public_key(cert);
+ if (pubkey)
{
- char buf[1024];
- ssize_t len;
-
- len = read(0, buf, sizeof(buf));
- if (len == 0)
- {
- return 0;
- }
- if (len > 0)
+ if (pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &chunk))
{
- if (!tls->write(tls, chunk_create(buf, len)))
+ keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
+ privkey = lib->credmgr->get_private(lib->credmgr,
+ pubkey->get_type(pubkey), keyid, NULL);
+ keyid->destroy(keyid);
+ if (privkey)
{
- DBG1(DBG_TLS, "TLS write error");
- return 1;
+ client = cert->get_subject(cert);
+ client = client->clone(client);
+ privkey->destroy(privkey);
}
}
+ pubkey->destroy(pubkey);
+ }
+ if (client)
+ {
+ break;
}
}
+ enumerator->destroy(enumerator);
+
+ return client;
}
/**
* Client routine
*/
-static int client(host_t *host, identification_t *server,
- int times, tls_cache_t *cache)
+static int run_client(host_t *host, identification_t *server,
+ identification_t *client, int times, tls_cache_t *cache)
{
tls_socket_t *tls;
int fd, res;
close(fd);
return 1;
}
- tls = tls_socket_create(FALSE, server, NULL, fd, cache);
+ tls = tls_socket_create(FALSE, server, client, fd, cache);
if (!tls)
{
close(fd);
return 1;
}
- res = stream(fd, tls);
+ res = tls->splice(tls, 0, 1) ? 0 : 1;
tls->destroy(tls);
close(fd);
if (res)
close(fd);
return 1;
}
- stream(cfd, tls);
+ tls->splice(tls, 0, 1);
DBG1(DBG_TLS, "%#H disconnected", host);
tls->destroy(tls);
}
char *address = NULL;
bool listen = FALSE;
int port = 0, times = -1, res;
- identification_t *server;
+ identification_t *server, *client;
tls_cache_t *cache;
host_t *host;
}
else
{
- res = client(host, server, times, cache);
+ client = find_client_id();
+ res = run_client(host, server, client, times, cache);
+ DESTROY_IF(client);
}
cache->destroy(cache);
host->destroy(host);
server->destroy(server);
return res;
}
-