14 unsigned char hash[HASHSIZE];
17 static struct _hash_obj
18 make_challenge(const char *uid, const char *pass, const char *nonce)
20 struct _hash_obj ho = {0};
23 int datasize = strlen(uid) + strlen(pass) + strlen(nonce) +
25 unsigned char *data = alloca(datasize);
26 int hashsize = sizeof(ho.hash);
28 serial_init(&srl, data, datasize);
29 if (serial_put(&srl, uid, strlen(uid)) != strlen(uid)) {
30 ho.err = "challenge: serialization of uid failed";
31 } else if (serial_put(&srl, pass, strlen(pass)) != strlen(pass)) {
32 ho.err = "challenge: serialization of pass failed";
33 } else if (serial_put(&srl, nonce, strlen(nonce)) != strlen(nonce)) {
34 ho.err = "challenge: serialization of nonce failed";
35 } else if (serial_put(&srl, NULL, 0) != 0) {
36 ho.err = "challenge: serialization of terminator failed";
39 if ((rc = hash(data, serial_size(&srl), &ho.hash, &hashsize))) {
40 ho.err = crypto_errstr(rc);
41 } else if (hashsize != sizeof(ho.hash)) {
42 ho.err = "challenge: hash size is wrong";
45 memset(data, 0, datasize);
49 static struct _hash_obj
50 make_key(const unsigned char *challenge, const int challengesize,
51 const unsigned char *secret, const int secsize)
53 struct _hash_obj ho = {0};
55 int keysize = sizeof(ho.hash);
57 if ((rc = hmac(secret, secsize, challenge, challengesize,
58 &ho.hash, &keysize))) {
59 ho.err = crypto_errstr(rc);
60 } else if (keysize != sizeof(ho.hash)) {
61 ho.err = "make_key: hash size is wrong";
66 static struct _hash_obj
67 fetch_key(const unsigned char *challenge, const int challengesize)
69 struct _hash_obj ho = {0};
71 int keysize = sizeof(ho.hash);
73 if ((rc = pcsc_cr(challenge, challengesize, ho.hash, &keysize))) {
74 ho.err = pcsc_errstr(rc);
79 static struct _auth_obj
80 make_authobj(const unsigned char *key, const int keysize,
81 const unsigned char *secret, const int secsize,
82 const unsigned char *payload, const int paysize)
84 struct _auth_obj ao = {0};
88 unsigned char datahash[HASHSIZE];
89 int datahashsize = HASHSIZE;
92 datasize = ((secsize + paysize + HASHSIZE + 4 * sizeof(short) - 1) /
93 CBLKSIZE + 1) * CBLKSIZE;
94 data = alloca(datasize);
95 serial_init(&srl, data, datasize);
96 if (serial_put(&srl, secret, secsize) != secsize) {
97 ao.err = "authobj: serialization of secret failed";
98 } else if (serial_put(&srl, payload, paysize) != paysize) {
99 ao.err = "authobj: serialization of payload failed";
100 } else if ((rc = hash(data, serial_size(&srl),
101 datahash, &datahashsize))) {
102 ao.err = crypto_errstr(rc);
103 } else if (serial_put(&srl, datahash, datahashsize) != datahashsize) {
104 ao.err = "authobj: serialization of hash failed";
105 } else if (serial_put(&srl, NULL, 0) != 0) {
106 ao.err = "authobj: serialization of terminator failed";
111 int osize = ((serial_size(&srl) -1) / CBLKSIZE + 1) * CBLKSIZE;
113 if ((ao.buffer = malloc(osize)) == NULL) {
114 ao.err = "authobj: malloc failed";
115 } else if ((lrc = encrypt(key, CBLKSIZE, data,
116 ao.buffer, osize))) {
117 ao.err = crypto_errstr(lrc);
119 ao.authobj = ao.buffer;
124 memset(data, 0, datasize);
128 static int parse_authobj(const unsigned char *key, const int keysize,
129 const unsigned char *buffer, const int bufsize,
130 unsigned char *secret, int *secsize,
131 unsigned char *payload, int *paysize)
133 int datasize = bufsize;
134 unsigned char *data = alloca(datasize);
137 unsigned char myhash[HASHSIZE];
138 int myhashsize = HASHSIZE;
139 unsigned char theirhash[HASHSIZE];
140 int theirhashsize = HASHSIZE;
142 if (decrypt(key, CBLKSIZE, buffer, data, datasize))
144 serial_init(&srl, data, datasize);
146 *secsize = serial_get(&srl, secret, tsize);
147 if (*secsize > tsize || *secsize <= 0) return 1;
149 *paysize = serial_get(&srl, payload, tsize);
150 if (*paysize > tsize || *paysize <= 0) return 1;
151 if (hash(data, serial_size(&srl), myhash, &myhashsize))
153 theirhashsize = serial_get(&srl, theirhash, theirhashsize);
154 if (theirhashsize != HASHSIZE) return 1;
155 if ((myhashsize != theirhashsize) ||
156 memcmp(myhash, theirhash, myhashsize))
161 struct _auth_obj new_authobj(const char *userid, const char *password,
163 const unsigned char *secret, const int secsize,
164 const unsigned char *payload, const int paysize)
166 struct _auth_obj ao = {0};
167 struct _hash_obj ho_chal, ho_key;
169 ho_chal = make_challenge(userid, password, nonce);
171 ao.err = ho_chal.err;
174 ho_key = make_key(ho_chal.hash, sizeof(ho_chal.hash), secret, secsize);
179 ao = make_authobj(ho_key.hash, sizeof(ho_key.hash),
180 secret, secsize, payload, paysize);
181 memset(&ho_chal, 0, sizeof(ho_chal));
182 memset(&ho_key, 0, sizeof(ho_key));
186 struct _auth_obj verify_authobj(const char *userid, const char *password,
187 const char *oldnonce, const char *newnonce,
188 const unsigned char *authobj, const int authsize)
190 struct _auth_obj ao = {0};
191 struct _hash_obj ho_chal, ho_key;
193 ho_chal = make_challenge(userid, password, oldnonce);
195 ao.err = ho_chal.err;
198 ho_key = fetch_key(ho_chal.hash, sizeof(ho_chal.hash));
203 memset(&ho_chal, 0, sizeof(ho_chal));
204 memset(&ho_key, 0, sizeof(ho_key));
208 struct _auth_obj reload_authobj(const char *userid, const char *password,
209 const char *oldnonce, const char *newnonce,
210 const unsigned char *authobj, const int authsize,
211 const unsigned char *payload, const int paysize)
213 struct _auth_obj ao = {0};
214 struct _hash_obj ho_chal, ho_key;
216 ho_chal = make_challenge(userid, password, oldnonce);
218 ao.err = ho_chal.err;
221 ho_key = fetch_key(ho_chal.hash, sizeof(ho_chal.hash));
226 memset(&ho_chal, 0, sizeof(ho_chal));
227 memset(&ho_key, 0, sizeof(ho_key));