]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Add initial support for protocol version 4.
authorChris Porter <redacted>
Fri, 22 Feb 2008 20:10:53 +0000 (20:10 +0000)
committerChris Porter <redacted>
Fri, 22 Feb 2008 20:10:53 +0000 (20:10 +0000)
nterface/esockets.c
nterface/esockets.h
nterface/nterfacer.c
nterface/nterfacer.h

index 6b5465b2095dac6b3f3247649ec7671db7c8563f..a37e7a1ed82aeb0cc797814fb2ff760151d68b87 100644 (file)
@@ -245,7 +245,7 @@ int crypto_newblock(struct esocket *sock, unsigned char *block) {
     if(memcmp(block, digest, 16)) /* mac error */
       return 1;
 
-    hmacsha256_init(&sock->clienthmac, sock->clientkey, 32);
+    hmacsha256_init(&sock->clienthmac, sock->clienthmackey, 32);
     seqno_update(&sock->clienthmac, sock->clientseqno);
     sock->clientseqno++;
 
@@ -482,7 +482,7 @@ int esocket_write(struct esocket *sock, char *buffer, int bytes) {
       newbuf[bytes + i] = i;
     bytes+=padding;
 
-    hmacsha256_init(&hmac, sock->serverkey, 32);
+    hmacsha256_init(&hmac, sock->serverhmackey, 32);
     seqno_update(&hmac, sock->serverseqno);
     sock->serverseqno++;
 
@@ -528,19 +528,46 @@ int esocket_write_line(struct esocket *sock, char *format, ...) {
   return esocket_write(sock, nbuf, len);
 }
 
+static void derive_key(unsigned char *out, unsigned char *key, u_int64_t seqno, unsigned char *extra, int extralen) {
+  hmacsha256 hmac;
+
+  hmacsha256_init(&hmac, key, 32);
+  seqno_update(&hmac, seqno);
+  hmacsha256_update(&hmac, extra, extralen);
+
+  hmacsha256_final(&hmac, out);
+}
+
+void rekey_esocket(struct esocket *sock, unsigned char *serveriv, unsigned char *clientiv) {
+  unsigned char key[32];
+  char hexout[65];
+
+  derive_key(key, sock->serverrawkey, sock->serverkeyno, ":SKEY", 5);
+  sock->servercrypto = rijndaelcbc_init(key, 256, serveriv, 0);
+  derive_key(sock->serverhmackey, sock->serverrawkey, sock->serverkeyno, ":SHMAC", 6);
+  sock->serverkeyno++;
+
+  derive_key(key, sock->clientrawkey, sock->clientkeyno, ":CKEY", 5);
+  sock->clientcrypto = rijndaelcbc_init(key, 256, clientiv, 1);
+  derive_key(sock->clienthmackey, sock->clientrawkey, sock->clientkeyno, ":CHMAC", 6);
+  sock->clientkeyno++;
+}
+
 void switch_buffer_mode(struct esocket *sock, unsigned char *serverkey, unsigned char *serveriv, unsigned char *clientkey, unsigned char *clientiv) {
-  memcpy(sock->serverkey, serverkey, 32);
-  memcpy(sock->clientkey, clientkey, 32);
+  memcpy(sock->serverrawkey, serverkey, 32);
+  memcpy(sock->clientrawkey, clientkey, 32);
 
   sock->in.mode = PARSE_CRYPTO;
 
   sock->clientseqno = 0;
   sock->serverseqno = 0;
 
-  sock->servercrypto = rijndaelcbc_init(serverkey, 256, serveriv, 0);
-  sock->clientcrypto = rijndaelcbc_init(clientkey, 256, clientiv, 1);
+  sock->clientkeyno = 0;
+  sock->serverkeyno = 0;
+
+  rekey_esocket(sock, serveriv, clientiv);
 
-  hmacsha256_init(&sock->clienthmac, sock->clientkey, 32);
+  hmacsha256_init(&sock->clienthmac, sock->clienthmackey, 32);
   seqno_update(&sock->clienthmac, sock->clientseqno);
 
   sock->clientseqno++;
index 4be28148da0467caa2e15546b9682a23be74cbbf..5f2ee84e117c936c598f1b1cff2f7cbc4066c428 100644 (file)
@@ -100,10 +100,11 @@ typedef struct esocket {
   unsigned short token;
   void *tag;
 
-  unsigned char clientkey[32];
-  unsigned char serverkey[32];
-  u_int64_t clientseqno;
-  u_int64_t serverseqno;
+  unsigned char clientrawkey[32], serverrawkey[32];
+  unsigned char clienthmackey[32], serverhmackey[32];
+  u_int64_t clientseqno, serverseqno;
+  u_int64_t clientkeyno, serverkeyno;
+
   hmacsha256 clienthmac;
   rijndaelcbc *clientcrypto;
   rijndaelcbc *servercrypto;
index 174970785932a73c161dbf5ba95bbc8268ab8c6e..880ae3cef4b57f605df970b00c4f58a2da9b79c6 100644 (file)
@@ -25,7 +25,7 @@
 #include "nterfacer.h"
 #include "logging.h"
 
-MODULE_VERSION("1.1");
+MODULE_VERSION("1.1p" PROTOCOL_VERSION);
 
 struct service_node *tree = NULL;
 struct esocket_events nterfacer_events;
@@ -392,7 +392,7 @@ void nterfacer_accept_event(struct esocket *socket) {
   esocket_write_line(newsocket, "nterfacer " PROTOCOL_VERSION);
 }
 
-void derive_key(unsigned char *out, char *password, char *segment, unsigned char *noncea, unsigned char *nonceb) {
+void derive_key(unsigned char *out, char *password, char *segment, unsigned char *noncea, unsigned char *nonceb, unsigned char *extra, int extralen) {
   SHA256_CTX c;
   SHA256_Init(&c);
   SHA256_Update(&c, (unsigned char *)password, strlen(password));
@@ -402,6 +402,8 @@ void derive_key(unsigned char *out, char *password, char *segment, unsigned char
   SHA256_Update(&c, noncea, 16);
   SHA256_Update(&c, (unsigned char *)":", 1);
   SHA256_Update(&c, nonceb, 16);
+  SHA256_Update(&c, (unsigned char *)":", 1);
+  SHA256_Update(&c, extra, extralen);
   SHA256_Final(out, &c);
 
   SHA256_Init(&c);
@@ -478,20 +480,17 @@ int nterfacer_line_event(struct esocket *sock, char *newline) {
       }
 
       if(!strncasecmp(newline, socket->response, sizeof(socket->response))) {
-        int ret;
+        unsigned char theirkey[32], ourkey[32];
+
+        derive_key(ourkey, socket->permit->password->content, socket->challenge, socket->ournonce, theirnonce, "SERVER", 6);
 
+        derive_key(theirkey, socket->permit->password->content, socket->response, theirnonce, socket->ournonce, "CLIENT", 6);
         nterface_log(nrl, NL_INFO, "Authed: %s", socket->permit->hostname->content);
         socket->status = SS_AUTHENTICATED;
-        ret = esocket_write_line(sock, "Oauth");
-        if(!ret) {
-          unsigned char theirkey[32], ourkey[32];
-          derive_key(ourkey, socket->permit->password->content, socket->challenge, socket->ournonce, theirnonce);
-          derive_key(theirkey, socket->permit->password->content, socket->response, theirnonce, socket->ournonce);
+        switch_buffer_mode(sock, ourkey, socket->iv, theirkey, theiriv);
 
-          switch_buffer_mode(sock, ourkey, socket->iv, theirkey, theiriv);
-        } else {
+        if(esocket_write_line(sock, "Oauth"))
           return BUF_ERROR;
-        }
       } else {
         nterface_log(nrl, NL_INFO, "Bad CR drop: %s", socket->permit->hostname->content);
         
index 9c913bb431e2f2d07985d7e0cf2148e4e9a631b7..93db79d109382f59fcd95ffdf9672636a5e712ac 100644 (file)
@@ -23,7 +23,7 @@
 
 #define MAX_ARGS 100
 
-#define PROTOCOL_VERSION "3"
+#define PROTOCOL_VERSION "4"
 #define ANTI_FULL_VERSION "service_link " PROTOCOL_VERSION
 
 struct rline;