aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-06 16:22:53 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-06 16:22:53 +0000
commitd1e93089ddeb129ed8d37c55996959eb3dcad11c (patch)
tree73e04ccc9bd0f12d24e372c9d0c04f2251671746
parent2e032226d7571e9349735733dd195cac9da3d43a (diff)
downloadgnunet-d1e93089ddeb129ed8d37c55996959eb3dcad11c.tar.gz
gnunet-d1e93089ddeb129ed8d37c55996959eb3dcad11c.zip
-on the fly cert generation
-rw-r--r--src/gns/Makefile.am2
-rw-r--r--src/gns/gnunet-gns-proxy.c231
2 files changed, 219 insertions, 14 deletions
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
index 277d5e323..2991bd0c8 100644
--- a/src/gns/Makefile.am
+++ b/src/gns/Makefile.am
@@ -207,7 +207,7 @@ gnunet_gns_DEPENDENCIES = \
207 207
208gnunet_gns_proxy_SOURCES = \ 208gnunet_gns_proxy_SOURCES = \
209 gnunet-gns-proxy.c gns_proxy_proto.h 209 gnunet-gns-proxy.c gns_proxy_proto.h
210gnunet_gns_proxy_LDADD = -lmicrohttpd -lcurl \ 210gnunet_gns_proxy_LDADD = -lmicrohttpd -lcurl -lssl \
211 $(top_builddir)/src/gns/libgnunetgns.la \ 211 $(top_builddir)/src/gns/libgnunetgns.la \
212 $(top_builddir)/src/util/libgnunetutil.la \ 212 $(top_builddir)/src/util/libgnunetutil.la \
213 $(GN_LIBINTL) 213 $(GN_LIBINTL)
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 3c6943687..ab99f4596 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -27,6 +27,14 @@
27#include "gns_proxy_proto.h" 27#include "gns_proxy_proto.h"
28#include "gns.h" 28#include "gns.h"
29 29
30/** SSL **/
31#include <openssl/pem.h>
32#include <openssl/conf.h>
33#include <openssl/x509v3.h>
34#include <openssl/ssl.h>
35#include <openssl/err.h>
36#include <openssl/rand.h>
37
30#define GNUNET_GNS_PROXY_PORT 7777 38#define GNUNET_GNS_PROXY_PORT 7777
31 39
32/* MHD/cURL defines */ 40/* MHD/cURL defines */
@@ -43,6 +51,31 @@
43#define HTTPS_PORT 443 51#define HTTPS_PORT 443
44 52
45 53
54/**
55 * A structure for CA cert/key
56 */
57struct ProxyCA
58{
59 /* The certificate */
60 X509* cert;
61
62 /* The private key */
63 EVP_PKEY *key;
64};
65
66
67/**
68 * Structure for GNS certificates
69 */
70struct ProxyGNSCertificate
71{
72 /* The certificate */
73 X509* cert;
74
75 /* The private key */
76 EVP_PKEY *key;
77};
78
46 79
47/** 80/**
48 * A structure for socks requests 81 * A structure for socks requests
@@ -188,7 +221,10 @@ struct ProxyCurlTask
188}; 221};
189 222
190/* The port the proxy is running on (default 7777) */ 223/* The port the proxy is running on (default 7777) */
191unsigned long port = GNUNET_GNS_PROXY_PORT; 224static unsigned long port = GNUNET_GNS_PROXY_PORT;
225
226/* The CA file (pem) to use for the proxy CA */
227static char* cafile;
192 228
193/* The listen socket of the proxy */ 229/* The listen socket of the proxy */
194static struct GNUNET_NETWORK_Handle *lsock; 230static struct GNUNET_NETWORK_Handle *lsock;
@@ -226,6 +262,9 @@ static regex_t re_dotplus;
226/* The users local GNS zone hash */ 262/* The users local GNS zone hash */
227struct GNUNET_CRYPTO_ShortHashCode local_gns_zone; 263struct GNUNET_CRYPTO_ShortHashCode local_gns_zone;
228 264
265/* The CA for SSL certificate generation */
266struct ProxyCA *proxy_ca;
267
229/** 268/**
230 * Checks if name is in tld 269 * Checks if name is in tld
231 * 270 *
@@ -1021,9 +1060,6 @@ create_response (void *cls,
1021 char curlurl[512]; 1060 char curlurl[512];
1022 int ret = MHD_YES; 1061 int ret = MHD_YES;
1023 1062
1024 struct hostent *phost;
1025 char *ssl_ip;
1026
1027 struct ProxyCurlTask *ctask; 1063 struct ProxyCurlTask *ctask;
1028 1064
1029 if (0 != strcmp (meth, "GET")) 1065 if (0 != strcmp (meth, "GET"))
@@ -1474,6 +1510,148 @@ load_file (const char* filename)
1474 return buffer; 1510 return buffer;
1475} 1511}
1476 1512
1513/** SSL stuff **/
1514
1515/**
1516 * Get authority from file
1517 */
1518static X509*
1519load_cert_from_file (char* file)
1520{
1521 SSL_CTX *context = NULL;;
1522
1523 context = SSL_CTX_new (SSLv23_server_method ());
1524
1525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1526 "Reading cert file %s\n", file);
1527
1528 SSL_CTX_use_certificate_file (context, file, SSL_FILETYPE_PEM);
1529
1530 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1531 "Extracting\n");
1532
1533 return SSL_get_certificate (SSL_new (context));
1534
1535}
1536
1537
1538/**
1539 * Get authority from file
1540 */
1541static struct ProxyCA*
1542load_authority_from_file (char* file)
1543{
1544 struct ProxyCA *ca = NULL;
1545 SSL_CTX *context;
1546
1547 ca = GNUNET_malloc (sizeof (struct ProxyCA));
1548
1549 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1550 "Reading cert file %s\n", file);
1551 ca->cert = load_cert_from_file (file);
1552
1553 context = SSL_CTX_new (SSLv23_server_method ());
1554
1555 SSL_CTX_use_PrivateKey_file (context, file, SSL_FILETYPE_PEM);
1556
1557 ca->key = SSL_get_privatekey (SSL_new (context));
1558
1559 return ca;
1560
1561}
1562
1563
1564
1565static unsigned int
1566generate_serial ()
1567{
1568 unsigned int serial;
1569 RAND_bytes ((unsigned char*)&serial, sizeof (serial));
1570
1571 return serial;
1572}
1573
1574
1575/* The template certificate file */
1576char* template_cert_file;
1577
1578/* The template certificate */
1579X509 *template_certificate;
1580
1581
1582/**
1583 * Generate new certificate for specific name
1584 *
1585 */
1586static struct ProxyGNSCertificate*
1587generate_gns_certificate (const char *name, char *keyfilename, char *certfilename)
1588{
1589 X509_NAME *server_name = X509_get_subject_name (template_certificate);
1590 X509_NAME *issuer_name = X509_get_subject_name (proxy_ca->cert);
1591 X509 *request = X509_new ();
1592 int cn_nid = OBJ_txt2nid("CN");
1593 int cn_idx = X509_NAME_get_index_by_NID(server_name, cn_nid, -1);
1594 RSA *rsa = RSA_generate_key (1024, RSA_F4, NULL, NULL);
1595 EVP_PKEY *rsa_spec = EVP_PKEY_new();
1596 FILE* keyfile;
1597 FILE* certfile;
1598
1599 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Generating key\n");
1600
1601 EVP_PKEY_assign_RSA (rsa_spec, rsa);
1602
1603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Generating cert\n");
1604
1605 struct ProxyGNSCertificate *pgc =
1606 GNUNET_malloc (sizeof (struct ProxyGNSCertificate));
1607
1608 X509_NAME_delete_entry (server_name, cn_idx);
1609
1610 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding name\n");
1611 if (!X509_NAME_add_entry_by_txt (server_name, "CN",
1612 MBSTRING_UTF8, (const unsigned char*)name,
1613 -1, -1, 0))
1614 {
1615 return NULL;
1616 }
1617
1618 X509_set_version(request, 3);
1619 X509_set_subject_name(request, server_name);
1620 X509_set_issuer_name(request, issuer_name);
1621
1622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing\n");
1623 ASN1_INTEGER_set(X509_get_serialNumber(request), generate_serial());
1624 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing\n");
1625 X509_gmtime_adj(X509_get_notBefore(request), -365);
1626 X509_gmtime_adj(X509_get_notAfter(request), (long)60*60*24*365);
1627 X509_set_pubkey(request, rsa_spec);
1628 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing %d\n", proxy_ca->key);
1629 X509_sign(request, proxy_ca->key, EVP_sha1());
1630
1631 pgc->cert = request;
1632 pgc->key = rsa_spec;
1633
1634
1635
1636 keyfile = fopen (keyfilename, "w+");
1637 certfile = fopen (certfilename, "w+");
1638
1639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing to file %d\n", rsa_spec);
1640 PEM_write_PrivateKey (keyfile, rsa_spec,
1641 NULL, NULL, 0, NULL, NULL);
1642 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing to file %d\n", request);
1643 PEM_write_X509 (certfile, request);
1644
1645 fclose (keyfile);
1646 fclose (certfile);
1647
1648 return pgc;
1649
1650}
1651
1652
1653
1654
1477/** 1655/**
1478 * Adds a socket to an SSL MHD instance 1656 * Adds a socket to an SSL MHD instance
1479 * It is important the the domain name is 1657 * It is important the the domain name is
@@ -1484,11 +1662,18 @@ add_handle_to_ssl_mhd (struct GNUNET_NETWORK_Handle *h, char* domain)
1484{ 1662{
1485 struct MhdHttpList *hd = NULL; 1663 struct MhdHttpList *hd = NULL;
1486 1664
1487 static char *key_pem; 1665 char* key_pem;
1488 static char *cert_pem; 1666 char* cert_pem;
1667 char key_pem_file[1024];
1668 char cert_pem_file[1024];
1489 1669
1490 key_pem = load_file ("server.key"); 1670 sprintf (key_pem_file, "%s.key", domain);
1491 cert_pem = load_file ("server.pem"); 1671 sprintf (cert_pem_file, "%s.pem", domain);
1672
1673 generate_gns_certificate (domain, key_pem_file, cert_pem_file);
1674
1675 key_pem = load_file (key_pem_file);
1676 cert_pem = load_file (cert_pem_file);
1492 1677
1493 for (hd = mhd_httpd_head; hd != NULL; hd = hd->next) 1678 for (hd = mhd_httpd_head; hd != NULL; hd = hd->next)
1494 { 1679 {
@@ -1501,7 +1686,8 @@ add_handle_to_ssl_mhd (struct GNUNET_NETWORK_Handle *h, char* domain)
1501 /* Start new MHD */ 1686 /* Start new MHD */
1502 /* TODO: create cert, start SSL MHD */ 1687 /* TODO: create cert, start SSL MHD */
1503 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1688 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1504 "No previous SSL instance found... starting new one\n"); 1689 "No previous SSL instance found... starting new one for %s\n",
1690 domain);
1505 hd = GNUNET_malloc (sizeof (struct MhdHttpList)); 1691 hd = GNUNET_malloc (sizeof (struct MhdHttpList));
1506 hd->is_ssl = GNUNET_YES; 1692 hd->is_ssl = GNUNET_YES;
1507 strcpy (hd->domain, domain); 1693 strcpy (hd->domain, domain);
@@ -1898,7 +2084,7 @@ do_shutdown (void *cls,
1898 2084
1899 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2085 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1900 "Cleaning up cURL task\n"); 2086 "Cleaning up cURL task\n");
1901 2087
1902 if (ctask->curl != NULL) 2088 if (ctask->curl != NULL)
1903 curl_easy_cleanup (ctask->curl); 2089 curl_easy_cleanup (ctask->curl);
1904 ctask->curl = NULL; 2090 ctask->curl = NULL;
@@ -1952,7 +2138,7 @@ load_local_zone_key (const struct GNUNET_CONFIGURATION_Handle *cfg)
1952 struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename; 2138 struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename;
1953 2139
1954 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", 2140 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
1955 "ZONEKEY", &keyfile)) 2141 "ZONEKEY", &keyfile))
1956 { 2142 {
1957 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2143 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1958 "Unable to load zone key config value!\n"); 2144 "Unable to load zone key config value!\n");
@@ -1970,8 +2156,8 @@ load_local_zone_key (const struct GNUNET_CONFIGURATION_Handle *cfg)
1970 key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); 2156 key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
1971 GNUNET_CRYPTO_rsa_key_get_public (key, &pkey); 2157 GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
1972 GNUNET_CRYPTO_short_hash(&pkey, 2158 GNUNET_CRYPTO_short_hash(&pkey,
1973 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 2159 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1974 &local_gns_zone); 2160 &local_gns_zone);
1975 zone = &local_gns_zone; 2161 zone = &local_gns_zone;
1976 GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename); 2162 GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename);
1977 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2163 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1982,6 +2168,8 @@ load_local_zone_key (const struct GNUNET_CONFIGURATION_Handle *cfg)
1982 return GNUNET_YES; 2168 return GNUNET_YES;
1983} 2169}
1984 2170
2171
2172
1985/** 2173/**
1986 * Main function that will be run 2174 * Main function that will be run
1987 * 2175 *
@@ -1997,6 +2185,17 @@ run (void *cls, char *const *args, const char *cfgfile,
1997 struct sockaddr_in sa; 2185 struct sockaddr_in sa;
1998 struct MhdHttpList *hd; 2186 struct MhdHttpList *hd;
1999 2187
2188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2189 "Loading CA\n");
2190
2191 SSL_library_init ();
2192 SSL_load_error_strings ();
2193 proxy_ca = load_authority_from_file (cafile);
2194
2195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2196 "Loading Template\n");
2197 template_certificate = load_cert_from_file (template_cert_file);
2198
2000 compile_regex (&re_dotplus, (char*) RE_DOTPLUS); 2199 compile_regex (&re_dotplus, (char*) RE_DOTPLUS);
2001 2200
2002 gns_handle = GNUNET_GNS_connect (cfg); 2201 gns_handle = GNUNET_GNS_connect (cfg);
@@ -2105,6 +2304,12 @@ main (int argc, char *const *argv)
2105 {'p', "port", NULL, 2304 {'p', "port", NULL,
2106 gettext_noop ("listen on specified port"), 1, 2305 gettext_noop ("listen on specified port"), 1,
2107 &GNUNET_GETOPT_set_string, &port}, 2306 &GNUNET_GETOPT_set_string, &port},
2307 {'a', "authority", NULL,
2308 gettext_noop ("pem file to use as CA"), 1,
2309 &GNUNET_GETOPT_set_string, &cafile},
2310 {'t', "template", NULL,
2311 gettext_noop ("template certificate file to use"), 1,
2312 &GNUNET_GETOPT_set_string, &template_cert_file},
2108 GNUNET_GETOPT_OPTION_END 2313 GNUNET_GETOPT_OPTION_END
2109 }; 2314 };
2110 2315