$ git clone https://socialnetwork.ion.nu/socialnetwork.git
commit 985057cf99de0cea793935e97c88aa0b6089c993
Author: Alicia <...>
Date:   Sun Jan 8 23:24:23 2017 +0100

    Expose private key and peers' public keys (in the form of the certificate used for the connection) for signing.

diff --git a/peer.c b/peer.c
index 09d416c..6cd23de 100644
--- a/peer.c
+++ b/peer.c
@@ -35,6 +35,7 @@ struct command
 };
 
 unsigned char peer_id[20];
+gnutls_privkey_t peer_privkey=0;
 static struct peer** peers=0;
 static unsigned int peercount=0;
 static struct command* commands=0;
@@ -240,6 +241,8 @@ void peer_init(const char* keypath)
     }
     size_t size=20;
     gnutls_x509_privkey_get_key_id(privkey, 0, peer_id, &size);
+    gnutls_privkey_init(&peer_privkey);
+    gnutls_privkey_import_x509(peer_privkey, privkey, 0);
   }
   // Register core commands
   peer_registercmd("getpeers", sendpeers);
@@ -262,13 +265,11 @@ static int checkcert(gnutls_session_t tls)
   unsigned int count;
   const gnutls_datum_t* certs=gnutls_certificate_get_peers(tls, &count);
   if(!count){return 1;}
-  gnutls_x509_crt_t cert;
-  gnutls_x509_crt_init(&cert);
-  gnutls_x509_crt_import(cert, certs, GNUTLS_X509_FMT_DER);
+  gnutls_x509_crt_init(&peer->cert);
+  gnutls_x509_crt_import(peer->cert, certs, GNUTLS_X509_FMT_DER);
   // Get the certificate's public key ID
   size_t size=20;
-  gnutls_x509_crt_get_key_id(cert, 0, peer->id, &size);
-  gnutls_x509_crt_deinit(cert);
+  gnutls_x509_crt_get_key_id(peer->cert, 0, peer->id, &size);
   // Make sure we're not connecting to ourselves. TODO: Make sure we're not connecting to someone else we're already connected to as well? (different addresses, same ID) may cause issues with reconnects and/or multiple sessions
   return !memcmp(peer->id, peer_id, 20);
 }
@@ -315,6 +316,7 @@ struct peer* peer_new(struct udpstream* stream, char server)
   peer->addrlen=sizeof(peer->addr);
   udpstream_getaddr(stream, &peer->addr, &peer->addrlen);
   memset(peer->id, 0, 20);
+  peer->cert=0;
   gnutls_init(&peer->tls, (server?GNUTLS_SERVER:GNUTLS_CLIENT)|GNUTLS_NONBLOCK);
   // Priority
   gnutls_priority_set_direct(peer->tls, "NORMAL", 0);
@@ -467,6 +469,7 @@ void peer_disconnect(struct peer* peer, char cleanly)
 {
   if(cleanly){gnutls_bye(peer->tls, GNUTLS_SHUT_WR);}
   gnutls_deinit(peer->tls);
+  if(peer->cert){gnutls_x509_crt_deinit(peer->cert);}
   udpstream_close(peer->stream);
   free(peer->cmdname);
   free(peer);
diff --git a/peer.h b/peer.h
index 987452d..e104462 100644
--- a/peer.h
+++ b/peer.h
@@ -14,6 +14,7 @@
     You should have received a copy of the GNU Affero General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+#include <stdint.h>
 #include <gnutls/gnutls.h>
 #include "udpstream.h"
 
@@ -29,12 +30,14 @@ struct peer
   struct sockaddr addr;
   socklen_t addrlen;
   unsigned char id[20]; // SHA-1 sum of public key (binary)
+  gnutls_x509_crt_t cert;
   // TODO: Account stuff?
 };
 // Macros for printing peer IDs in printf-family of functions
 #define PEERFMT "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
 #define PEERARG(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15],x[16],x[17],x[18],x[19]
 extern unsigned char peer_id[20];
+extern gnutls_privkey_t peer_privkey;
 
 extern void peer_registercmd(const char* name, void(*callback)(struct peer*,void*,unsigned int));
 extern void peer_init(const char* keypath);