ec929071a7c723a02bb71786c8464f3f3f4b6fc3
[pam_pcsc_cr.git] / authobj.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 #include <stdio.h>
5 #include <string.h>
6 #include <alloca.h>
7 #include "serial.h"
8 #include "crypto.h"
9 #include "authobj.h"
10
11 int make_authobj(const char *id, const char *pass, const char *nonce,
12                 const unsigned char *secret, const int secsize,
13                 const unsigned char *payload, const int paysize,
14                 unsigned char *buffer, int *bufsize)
15 {
16         unsigned char *data;
17         int datasize;
18         unsigned char datahash[HASHSIZE];
19         int datahashsize = HASHSIZE;
20         unsigned char *hmacdata;
21         int hmacdatasize;
22         unsigned char key[HASHSIZE];
23         int keysize = HASHSIZE;
24         serializer_t srl;
25
26         datasize = ((secsize + paysize + HASHSIZE * 4 * sizeof(short) - 1) /
27                         CBLKSIZE + 1) * CBLKSIZE;
28         data = alloca(datasize);
29         if (serial_init(&srl, data, datasize)) return -1;
30         if (serial_put(&srl, secret, secsize) != secsize) return -1;
31         if (serial_put(&srl, payload, paysize) != paysize) return -1;
32         if (hash(data, serial_size(&srl), datahash, &datahashsize))
33                 return -1;
34         if (serial_put(&srl, datahash, datahashsize) != datahashsize)
35                 return -1;
36         if (serial_put(&srl, NULL, 0) != 0) return -1;
37         datasize = ((serial_size(&srl) -1) / CBLKSIZE + 1) * CBLKSIZE;
38
39         hmacdatasize = ((strlen(id) + strlen(pass) + strlen(nonce) +
40                         4 * sizeof(short) - 1) / CBLKSIZE + 1) * CBLKSIZE;
41         hmacdata = alloca(hmacdatasize);
42         if (serial_init(&srl, hmacdata, hmacdatasize)) return -1;
43         if (serial_put(&srl, id, strlen(id)) != strlen(id)) return -1;
44         if (serial_put(&srl, pass, strlen(pass)) != strlen(pass)) return -1;
45         if (serial_put(&srl, nonce, strlen(nonce)) != strlen(nonce)) return -1;
46         if (serial_put(&srl, NULL, 0) != 0) return -1;
47         hmacdatasize = ((serial_size(&srl) -1) / CBLKSIZE + 1) * CBLKSIZE;
48
49         if (hmac(secret, secsize, hmacdata, hmacdatasize,
50                 key, &keysize)) return -1;
51
52         if (*bufsize < datasize) return -1;
53         *bufsize = datasize;
54         if (encrypt(key, keysize, data, buffer, datasize)) return -1;
55
56         return 0;
57 }
58
59 int parse_authobj(const unsigned char *hmacdata, const int hmacdatasize,
60                 const unsigned char *buffer, const int bufsize,
61                 unsigned char *secret, int *secsize,
62                 unsigned char *payload, int *paysize)
63 {
64         int datasize = bufsize;
65         unsigned char *data = alloca(datasize);
66         serializer_t srl;
67         int tsize;
68         unsigned char myhash[HASHSIZE];
69         int myhashsize = HASHSIZE;
70         unsigned char theirhash[HASHSIZE];
71         int theirhashsize = HASHSIZE;
72
73         if (decrypt(hmacdata, hmacdatasize, buffer, data, datasize))
74                 return -1;
75         if (serial_init(&srl, data, datasize)) return -1;
76         tsize = *secsize;
77         if ((*secsize = serial_get(&srl, secret, tsize)) > tsize) return -1;
78         tsize = *paysize;
79         if ((*paysize = serial_get(&srl, payload, tsize)) > tsize) return -1;
80         if (hash(data, serial_size(&srl), myhash, &myhashsize))
81                 return -1;
82         if ((theirhashsize = serial_get(&srl, theirhash, theirhashsize)) != HASHSIZE)
83                 return -1;
84         if ((myhashsize != theirhashsize) ||
85                                 memcmp(myhash, theirhash, myhashsize))
86                 return -1;
87         return 0;
88 }