diff options
Diffstat (limited to 'src/cmd/secstore/SConn.c')
| -rw-r--r-- | src/cmd/secstore/SConn.c | 213 |
1 files changed, 0 insertions, 213 deletions
diff --git a/src/cmd/secstore/SConn.c b/src/cmd/secstore/SConn.c deleted file mode 100644 index 7a8654ac..00000000 --- a/src/cmd/secstore/SConn.c +++ /dev/null @@ -1,213 +0,0 @@ -#include <u.h> -#include <libc.h> -#include <mp.h> -#include <libsec.h> -#include "SConn.h" - -extern int verbose; - -typedef struct ConnState { - uchar secret[SHA1dlen]; - ulong seqno; - RC4state rc4; -} ConnState; - -typedef struct SS{ - int fd; // file descriptor for read/write of encrypted data - int alg; // if nonzero, "alg sha rc4_128" - ConnState in, out; -} SS; - -static int -SC_secret(SConn *conn, uchar *sigma, int direction) -{ - SS *ss = (SS*)(conn->chan); - int nsigma = conn->secretlen; - - if(direction != 0){ - hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->out.secret, nil); - hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->in.secret, nil); - }else{ - hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->out.secret, nil); - hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->in.secret, nil); - } - setupRC4state(&ss->in.rc4, ss->in.secret, 16); // restrict to 128 bits - setupRC4state(&ss->out.rc4, ss->out.secret, 16); - ss->alg = 1; - return 0; -} - -static void -hash(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen]) -{ - DigestState sha; - uchar seq[4]; - - seq[0] = seqno>>24; - seq[1] = seqno>>16; - seq[2] = seqno>>8; - seq[3] = seqno; - memset(&sha, 0, sizeof sha); - sha1(secret, SHA1dlen, nil, &sha); - sha1(data, len, nil, &sha); - sha1(seq, 4, d, &sha); -} - -static int -verify(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen]) -{ - DigestState sha; - uchar seq[4]; - uchar digest[SHA1dlen]; - - seq[0] = seqno>>24; - seq[1] = seqno>>16; - seq[2] = seqno>>8; - seq[3] = seqno; - memset(&sha, 0, sizeof sha); - sha1(secret, SHA1dlen, nil, &sha); - sha1(data, len, nil, &sha); - sha1(seq, 4, digest, &sha); - return memcmp(d, digest, SHA1dlen); -} - -static int -SC_read(SConn *conn, uchar *buf, int n) -{ - SS *ss = (SS*)(conn->chan); - uchar count[2], digest[SHA1dlen]; - int len, nr; - - if(read(ss->fd, count, 2) != 2 || (count[0]&0x80) == 0){ - snprint((char*)buf,n,"!SC_read invalid count"); - return -1; - } - len = (count[0]&0x7f)<<8 | count[1]; // SSL-style count; no pad - if(ss->alg){ - len -= SHA1dlen; - if(len <= 0 || readn(ss->fd, digest, SHA1dlen) != SHA1dlen){ - snprint((char*)buf,n,"!SC_read missing sha1"); - return -1; - } - if(len > n || readn(ss->fd, buf, len) != len){ - snprint((char*)buf,n,"!SC_read missing data"); - return -1; - } - rc4(&ss->in.rc4, digest, SHA1dlen); - rc4(&ss->in.rc4, buf, len); - if(verify(ss->in.secret, buf, len, ss->in.seqno, digest) != 0){ - snprint((char*)buf,n,"!SC_read integrity check failed"); - return -1; - } - }else{ - if(len <= 0 || len > n){ - snprint((char*)buf,n,"!SC_read implausible record length"); - return -1; - } - if( (nr = readn(ss->fd, buf, len)) != len){ - snprint((char*)buf,n,"!SC_read expected %d bytes, but got %d", len, nr); - return -1; - } - } - ss->in.seqno++; - return len; -} - -static int -SC_write(SConn *conn, uchar *buf, int n) -{ - SS *ss = (SS*)(conn->chan); - uchar count[2], digest[SHA1dlen], enc[Maxmsg+1]; - int len; - - if(n <= 0 || n > Maxmsg+1){ - werrstr("!SC_write invalid n %d", n); - return -1; - } - len = n; - if(ss->alg) - len += SHA1dlen; - count[0] = 0x80 | len>>8; - count[1] = len; - if(write(ss->fd, count, 2) != 2){ - werrstr("!SC_write invalid count"); - return -1; - } - if(ss->alg){ - hash(ss->out.secret, buf, n, ss->out.seqno, digest); - rc4(&ss->out.rc4, digest, SHA1dlen); - memcpy(enc, buf, n); - rc4(&ss->out.rc4, enc, n); - if(write(ss->fd, digest, SHA1dlen) != SHA1dlen || - write(ss->fd, enc, n) != n){ - werrstr("!SC_write error on send"); - return -1; - } - }else{ - if(write(ss->fd, buf, n) != n){ - werrstr("!SC_write error on send"); - return -1; - } - } - ss->out.seqno++; - return n; -} - -static void -SC_free(SConn *conn) -{ - SS *ss = (SS*)(conn->chan); - - close(ss->fd); - free(ss); - free(conn); -} - -SConn* -newSConn(int fd) -{ - SS *ss; - SConn *conn; - - if(fd < 0) - return nil; - ss = (SS*)emalloc(sizeof(*ss)); - conn = (SConn*)emalloc(sizeof(*conn)); - ss->fd = fd; - ss->alg = 0; - conn->chan = (void*)ss; - conn->secretlen = SHA1dlen; - conn->free = SC_free; - conn->secret = SC_secret; - conn->read = SC_read; - conn->write = SC_write; - return conn; -} - -void -writerr(SConn *conn, char *s) -{ - char buf[Maxmsg]; - - snprint(buf, Maxmsg, "!%s", s); - conn->write(conn, (uchar*)buf, strlen(buf)); -} - -int -readstr(SConn *conn, char *s) -{ - int n; - - n = conn->read(conn, (uchar*)s, Maxmsg); - if(n >= 0){ - s[n] = 0; - if(s[0] == '!'){ - memmove(s, s+1, n); - n = -1; - } - }else{ - strcpy(s, "read error"); - } - return n; -} - |
