introduce authobj
authorEugene Crosser <crosser@average.org>
Wed, 6 Nov 2013 21:25:18 +0000 (01:25 +0400)
committerEugene Crosser <crosser@average.org>
Wed, 6 Nov 2013 21:25:18 +0000 (01:25 +0400)
Makefile.am
authobj.c [new file with mode: 0644]
authobj.h [new file with mode: 0644]
crypto.c
crypto.h
serial.c
serial.h

index 43c4263b0e535b76cc758526675b03a8760f66c2..68070791c2f024c6c835c1ed7bad07df75f1b71a 100644 (file)
@@ -3,10 +3,10 @@
 AUTOMAKE_OPTIONS = foreign
 ACLOCAL_AMFLAGS = -I m4
 
-noinst_HEADERS = pcsc_cr.h token.h crypto_if.h crypto.h serial.h
+noinst_HEADERS = pcsc_cr.h token.h crypto_if.h crypto.h serial.h authobj.h
 
 EXTRA_LTLIBRARIES = libpcsc_cr.la
-libpcsc_cr_la_SOURCES = serial.c crypto.c pcsc_cr.c ykneo.c
+libpcsc_cr_la_SOURCES = authobj.c serial.c crypto.c pcsc_cr.c ykneo.c
 EXTRA_libpcsc_cr_la_SOURCES = ossl_crypto.c tom_crypto.c
 libpcsc_cr_la_LIBADD = @CRYPTO_OBJS@
 libpcsc_cr_la_DEPENDENCIES = @CRYPTO_OBJS@
diff --git a/authobj.c b/authobj.c
new file mode 100644 (file)
index 0000000..ec92907
--- /dev/null
+++ b/authobj.c
@@ -0,0 +1,88 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <alloca.h>
+#include "serial.h"
+#include "crypto.h"
+#include "authobj.h"
+
+int make_authobj(const char *id, const char *pass, const char *nonce,
+               const unsigned char *secret, const int secsize,
+               const unsigned char *payload, const int paysize,
+               unsigned char *buffer, int *bufsize)
+{
+       unsigned char *data;
+       int datasize;
+       unsigned char datahash[HASHSIZE];
+       int datahashsize = HASHSIZE;
+       unsigned char *hmacdata;
+       int hmacdatasize;
+       unsigned char key[HASHSIZE];
+       int keysize = HASHSIZE;
+       serializer_t srl;
+
+       datasize = ((secsize + paysize + HASHSIZE * 4 * sizeof(short) - 1) /
+                       CBLKSIZE + 1) * CBLKSIZE;
+       data = alloca(datasize);
+       if (serial_init(&srl, data, datasize)) return -1;
+       if (serial_put(&srl, secret, secsize) != secsize) return -1;
+       if (serial_put(&srl, payload, paysize) != paysize) return -1;
+       if (hash(data, serial_size(&srl), datahash, &datahashsize))
+               return -1;
+       if (serial_put(&srl, datahash, datahashsize) != datahashsize)
+               return -1;
+       if (serial_put(&srl, NULL, 0) != 0) return -1;
+       datasize = ((serial_size(&srl) -1) / CBLKSIZE + 1) * CBLKSIZE;
+
+       hmacdatasize = ((strlen(id) + strlen(pass) + strlen(nonce) +
+                       4 * sizeof(short) - 1) / CBLKSIZE + 1) * CBLKSIZE;
+       hmacdata = alloca(hmacdatasize);
+       if (serial_init(&srl, hmacdata, hmacdatasize)) return -1;
+       if (serial_put(&srl, id, strlen(id)) != strlen(id)) return -1;
+       if (serial_put(&srl, pass, strlen(pass)) != strlen(pass)) return -1;
+       if (serial_put(&srl, nonce, strlen(nonce)) != strlen(nonce)) return -1;
+       if (serial_put(&srl, NULL, 0) != 0) return -1;
+       hmacdatasize = ((serial_size(&srl) -1) / CBLKSIZE + 1) * CBLKSIZE;
+
+       if (hmac(secret, secsize, hmacdata, hmacdatasize,
+               key, &keysize)) return -1;
+
+       if (*bufsize < datasize) return -1;
+       *bufsize = datasize;
+       if (encrypt(key, keysize, data, buffer, datasize)) return -1;
+
+       return 0;
+}
+
+int parse_authobj(const unsigned char *hmacdata, const int hmacdatasize,
+               const unsigned char *buffer, const int bufsize,
+               unsigned char *secret, int *secsize,
+               unsigned char *payload, int *paysize)
+{
+       int datasize = bufsize;
+       unsigned char *data = alloca(datasize);
+       serializer_t srl;
+       int tsize;
+       unsigned char myhash[HASHSIZE];
+       int myhashsize = HASHSIZE;
+       unsigned char theirhash[HASHSIZE];
+       int theirhashsize = HASHSIZE;
+
+       if (decrypt(hmacdata, hmacdatasize, buffer, data, datasize))
+               return -1;
+       if (serial_init(&srl, data, datasize)) return -1;
+       tsize = *secsize;
+       if ((*secsize = serial_get(&srl, secret, tsize)) > tsize) return -1;
+       tsize = *paysize;
+       if ((*paysize = serial_get(&srl, payload, tsize)) > tsize) return -1;
+       if (hash(data, serial_size(&srl), myhash, &myhashsize))
+               return -1;
+       if ((theirhashsize = serial_get(&srl, theirhash, theirhashsize)) != HASHSIZE)
+               return -1;
+       if ((myhashsize != theirhashsize) ||
+                               memcmp(myhash, theirhash, myhashsize))
+               return -1;
+       return 0;
+}
diff --git a/authobj.h b/authobj.h
new file mode 100644 (file)
index 0000000..c2da504
--- /dev/null
+++ b/authobj.h
@@ -0,0 +1,13 @@
+#ifndef _AUTHOBJ_H
+#define _AUTHOBJ_H
+
+int make_authobj(const char *id, const char *pass, const char *nonce,
+               const unsigned char *secret, const int secsize,
+               const unsigned char *payload, const int paysize,
+               unsigned char *buffer, int *bufsize);
+int parse_authobj(const unsigned char *hmacdata, const int hmacdatasize,
+               const unsigned char *buffer, const int bufsize,
+               unsigned char *secret, int *secsize,
+               unsigned char *payload, int *paysize);
+
+#endif
index c2d6c1471f349dfee3ba981e0997c5a809f296c0..6456932aaea06d7533775db27ff642be85588e44 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -21,14 +21,14 @@ static struct crypto_interface *ifs[] = {
 
 static int which = 0;
 
-int select_crypto_if(int ifno)
+int select_crypto_if(const int ifno)
 {
        if (ifno < 0 || ifno > MAX_IF) return -1;
        which = ifno;
        return 0;
 }
 
-const char *crypto_init(int ifno)
+const char *crypto_init(const int ifno)
 {
        if (ifno < 0 || ifno > MAX_IF) return (const char *)0;
        return ifs[ifno]->init();
@@ -36,7 +36,7 @@ const char *crypto_init(int ifno)
 
 #define INITIV {0}
 
-unsigned long encrypt(void *key, int keylen, void *pt, void *ct, int tlen)
+unsigned long encrypt(const void *key, const int keylen, const void *pt, void *ct, const int tlen)
 {
        unsigned char iv[16] = INITIV;
 
@@ -44,7 +44,7 @@ unsigned long encrypt(void *key, int keylen, void *pt, void *ct, int tlen)
        return ifs[which]->encrypt(key, keylen, iv, pt, ct, tlen);
 }
 
-unsigned long decrypt(void *key, int keylen, void *ct, void *pt, int tlen)
+unsigned long decrypt(const void *key, const int keylen, const void *ct, void *pt, const int tlen)
 {
        unsigned char iv[16] = INITIV;
 
@@ -52,19 +52,19 @@ unsigned long decrypt(void *key, int keylen, void *ct, void *pt, int tlen)
        return ifs[which]->decrypt(key, keylen, iv, ct, pt, tlen);
 }
 
-unsigned long hash(void *pt, int tlen, void *tag, int *taglen)
+unsigned long hash(const void *pt, const int tlen, void *tag, int *taglen)
 {
        assert(*taglen == 20);
        return ifs[which]->hash(pt, tlen, tag, taglen);
 }
 
-unsigned long hmac(void *key, int keylen, void *pt, int tlen, void *tag, int *taglen)
+unsigned long hmac(const void *key, const int keylen, const void *pt, const int tlen, void *tag, int *taglen)
 {
        assert(*taglen == 20);
        return ifs[which]->hmac(key, keylen, pt, tlen, tag, taglen);
 }
 
-const char *crypto_errstr(unsigned long err)
+const char *crypto_errstr(const unsigned long err)
 {
        return ifs[which]->errstr(err);
 }
index ad4cf63d2e00cb577bea3171c6072346742edf31..441202d1673d6b5724baef814b21730e4cda2ff9 100644 (file)
--- a/crypto.h
+++ b/crypto.h
@@ -1,14 +1,14 @@
 #ifndef _CRYPTO_H
 #define _CRYPTO_H
 
-int select_crypto_if(int ifno);
-const char *crypto_init(int ifno);
-unsigned long encrypt(void *key, int keylen, void *pt, void *ct, int tlen);
-unsigned long decrypt(void *key, int keylen, void *ct, void *pt, int tlen);
-unsigned long hash(void *pt, int tlen, void *tag, int *taglen);
-unsigned long hmac(void *key, int keylen, void *pt, int tlen,
+int select_crypto_if(const int ifno);
+const char *crypto_init(const int ifno);
+unsigned long encrypt(const void *key, const int keylen, const void *pt, void *ct, const int tlen);
+unsigned long decrypt(const void *key, const int keylen, const void *ct, void *pt, const int tlen);
+unsigned long hash(const void *pt, const int tlen, void *tag, int *taglen);
+unsigned long hmac(const void *key, const int keylen, const void *pt, const int tlen,
                        void *tag, int *taglen);
-const char *crypto_errstr(unsigned long err);
+const char *crypto_errstr(const unsigned long err);
 
 #define HASHSIZE 20
 #define CBLKSIZE 16
index 8debe3b8eed128c4c147c0810c7c6de20af68542..1aad7a10350058b2f8e35b46f99a9b78d6863fec 100644 (file)
--- a/serial.c
+++ b/serial.c
@@ -22,7 +22,7 @@ int serial_switch(serializer_t *srl, void *buffer, int size)
        return 0;
 }
 
-int serial_put(serializer_t *srl, void *item, int size)
+int serial_put(serializer_t *srl, const void *item, int size)
 {
        int left = srl->bufsize - (srl->cursor - srl->buffer);
        if (left < size + sizeof(short)) return left - sizeof(short);
index 5f8f1551874b08e0ffb6566af28597a1d6b4e4ec..a501fa81eed1807ab792a3d0ae7529965326f06f 100644 (file)
--- a/serial.h
+++ b/serial.h
@@ -9,7 +9,7 @@ typedef struct _serializer {
 
 int serial_init(serializer_t *srl, void *buffer, int size);
 int serial_switch(serializer_t *srl, void *buffer, int size);
-int serial_put(serializer_t *srl, void *item, int size);
+int serial_put(serializer_t *srl, const void *item, int size);
 int serial_get(serializer_t *srl, void *item, int bufsize);
 int serial_size(serializer_t *srl);