diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..318426e --- /dev/null +++ b/src/Makefile @@ -0,0 +1,3 @@ +all: in.tokend + +in.tokend: in.tokend.c xxtea.c \ No newline at end of file diff --git a/src/in.tokend.c b/src/in.tokend.c new file mode 100644 index 0000000..0d5e748 --- /dev/null +++ b/src/in.tokend.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "xxtea.h" + +#define itokenlen 3 + + +char const consonants[] = "bcdfghklmnprstvz"; +char const vowels[] = "aeiouy"; + +#define bubblebabble_len(n) (6*(((n)/2)+1)) + +/** Compute bubble babble for input buffer. + * + * The generated output will be of length 6*((inlen/2)+1), including the + * trailing NULL. + * + * Test vectors: + * `' (empty string) `xexax' + * `1234567890' `xesef-disof-gytuf-katof-movif-baxux' + * `Pineapple' `xigak-nyryk-humil-bosek-sonax' + */ +void +bubblebabble(char *out, char const *in, const size_t inlen) +{ + size_t pos = 0; + int seed = 1; + size_t i = 0; + + out[pos++] = 'x'; + while (1) { + unsigned char c; + + if (i == inlen) { + out[pos++] = vowels[seed % 6]; + out[pos++] = 'x'; + out[pos++] = vowels[seed / 6]; + break; + } + + c = in[i++]; + out[pos++] = vowels[(((c >> 6) & 3) + seed) % 6]; + out[pos++] = consonants[(c >> 2) & 15]; + out[pos++] = vowels[((c & 3) + (seed / 6)) % 6]; + if (i == inlen) { + break; + } + seed = ((seed * 5) + (c * 7) + in[i]) % 36; + + c = in[i++]; + out[pos++] = consonants[(c >> 4) & 15]; + out[pos++] = '-'; + out[pos++] = consonants[c & 15]; + } + + out[pos++] = 'x'; + out[pos] = '\0'; +} + +int +main(int argc, char *argv[]) +{ + char service[50]; + char token[80]; + uint32_t key[4]; + size_t tokenlen; + + /* This ought to be unpredictable enough for a contest */ + srand((int)time(NULL) * (int)getpid()); + + /* Read service name */ + { + size_t len; + int i; + + len = fread(service, 1, sizeof(service) - 1, stdin); + for (i = 0; (i < len) && isalnum(service[i]); i += 1); + service[i] = '\0'; + } + + /* Read in that service's key */ + { + FILE *f = fopen(service, "r"); + size_t len; + + if (! f) { + printf("Unregistered service"); + return 0; + } + + len = fread(&key, sizeof(uint32_t), 4, f); + fclose(f); + + if (4 != len) { + printf("Key file screwed up"); + return 0; + } + } + + /* Create the token */ + { + uint8_t crap[itokenlen]; + char digest[bubblebabble_len(itokenlen)]; + int i; + + /* Digest some random junk */ + for (i = 0; i < itokenlen; i += 1) { + crap[i] = (uint8_t)random(); + } + bubblebabble(digest, crap, itokenlen); + + /* Append digest to service name */ + tokenlen = (size_t)snprintf(token, sizeof(token), + "%s:%s", + service, digest); + } + + /* Encrypt the token */ + /* Note that now tokenlen is in uint32_ts, not chars! */ + { + tokenlen = (tokenlen + (tokenlen % 4)) / 4; + + tea_encode(key, (uint32_t *)token, tokenlen); + } + + /* Send it back */ + fwrite(token, tokenlen, sizeof(uint32_t), stdout); + + return 0; +} diff --git a/src/xxtea.c b/src/xxtea.c new file mode 100644 index 0000000..df121b2 --- /dev/null +++ b/src/xxtea.c @@ -0,0 +1,51 @@ +#include +#include + +#define DELTA 0x9e3779b9 +#define MX ((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(p&3)^e] ^ z)); + +void +btea(uint32_t *v, int n, uint32_t const k[4]) +{ + uint32_t y, z, sum; + unsigned p, rounds, e; + + if (n > 1) { /* Coding Part */ + rounds = 6 + 52/n; + sum = 0; + z = v[n-1]; + do { + sum += DELTA; + e = (sum >> 2) & 3; + for (p=0; p> 2) & 3; + for (p=n-1; p>0; p--) + z = v[p-1], y = v[p] -= MX; + z = v[n-1]; + y = v[0] -= MX; + } while ((sum -= DELTA) != 0); + } +} + +void +tea_encode(uint32_t const key[4], uint32_t *buf, size_t buflen) +{ + btea(buf, buflen, key); +} + +void +tea_decode(uint32_t const key[4], uint32_t *buf, size_t buflen) +{ + btea(buf, -buflen, key); +} + diff --git a/src/xxtea.h b/src/xxtea.h new file mode 100644 index 0000000..071a1ec --- /dev/null +++ b/src/xxtea.h @@ -0,0 +1,2 @@ +void tea_encode(uint32_t const key[4], uint32_t *buf, size_t buflen); +void tea_decode(uint32_t const key[4], uint32_t *buf, size_t buflen); diff --git a/template.html b/template.html deleted file mode 100644 index cf5e6a6..0000000 --- a/template.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - $title - - $hdr - - -

$title

- - $body - -