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++;
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++;
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++;
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;
#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;
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));
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);
}
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);
#define MAX_ARGS 100
-#define PROTOCOL_VERSION "3"
+#define PROTOCOL_VERSION "4"
#define ANTI_FULL_VERSION "service_link " PROTOCOL_VERSION
struct rline;