1 /* This bit implements a simple API for using the SRP library over sockets. */
8 #include <sys/socket.h>
17 #define MSG_WAITALL 0x100 /* somehow not defined on my box */
21 /* This is called by the client with a connected socket, username, and
22 passphrase. pass can be NULL in which case the user is queried. */
24 int tsrp_client_authenticate(int s, char *user, char *pass, TSRP_SESSION *tsrp)
27 unsigned char username[MAXUSERLEN + 1], sbuf[MAXSALTLEN];
28 unsigned char msgbuf[MAXPARAMLEN + 1], bbuf[MAXPARAMLEN];
29 unsigned char passbuf[128], *skey;
31 struct t_preconf *tcp; /* @@@ should go away */
32 struct t_num salt, *A, B;
34 /* Send the username. */
41 memcpy(msgbuf + 1, user, i);
42 if (send(s, msgbuf, i + 1, 0) < 0) {
45 memcpy(username, user, i);
48 /* Get the prime index and salt. */
50 i = recv(s, msgbuf, 2, MSG_WAITALL);
55 if (index <= 0 || index > t_getprecount()) {
58 tcp = t_getpreparam(index - 1);
60 if (salt.len > MAXSALTLEN) {
64 i = recv(s, sbuf, salt.len, MSG_WAITALL);
69 /* @@@ t_clientopen() needs a variant that takes the index */
71 tc = t_clientopen(username, &tcp->modulus, &tcp->generator, &salt);
76 /* Calculate A and send it to the server. */
78 A = t_clientgenexp(tc);
79 msgbuf[0] = A->len - 1; /* len is max 256 */
80 memcpy(msgbuf + 1, A->data, A->len);
81 if (send(s, msgbuf, A->len + 1, 0) < 0) {
85 /* Ask the user for the passphrase. */
88 t_getpass(passbuf, sizeof(passbuf), "Enter password:");
91 t_clientpasswd(tc, pass);
93 /* Get B from the server. */
95 i = recv(s, msgbuf, 1, 0);
99 B.len = msgbuf[0] + 1;
101 i = recv(s, bbuf, B.len, MSG_WAITALL);
106 /* Compute the session key. */
108 skey = t_clientgetkey(tc, &B);
113 /* Send the response. */
115 if (send(s, t_clientresponse(tc), RESPONSE_LEN, 0) < 0) {
119 /* Get the server's response. */
121 i = recv(s, msgbuf, RESPONSE_LEN, MSG_WAITALL);
125 if (t_clientverify(tc, msgbuf) != 0) {
129 /* All done. Now copy the key and clean up. */
132 memcpy(tsrp->username, username, strlen(username) + 1);
133 memcpy(tsrp->key, skey, SESSION_KEY_LEN);
140 /* This is called by the server with a connected socket. */
142 int tsrp_server_authenticate(int s, TSRP_SESSION *tsrp)
145 unsigned char username[MAXUSERLEN], *skey;
146 unsigned char msgbuf[MAXPARAMLEN + 1], abuf[MAXPARAMLEN];
150 /* Get the username. */
152 i = recv(s, msgbuf, 1, 0);
157 i = recv(s, username, j, MSG_WAITALL);
163 ts = t_serveropen(username);
168 /* Send the prime index and the salt. */
170 msgbuf[0] = ts->index; /* max 256 primes... */
173 memcpy(msgbuf + 2, ts->s.data, i);
174 if (send(s, msgbuf, i + 2, 0) < 0) {
178 /* Calculate B while we're waiting. */
180 B = t_servergenexp(ts);
182 /* Get A from the client. */
184 i = recv(s, msgbuf, 1, 0);
188 A.len = msgbuf[0] + 1;
190 i = recv(s, abuf, A.len, MSG_WAITALL);
197 msgbuf[0] = B->len - 1;
198 memcpy(msgbuf + 1, B->data, B->len);
199 if (send(s, msgbuf, B->len + 1, 0) < 0) {
203 /* Calculate the session key while we're waiting. */
205 skey = t_servergetkey(ts, &A);
210 /* Get the response from the client. */
212 i = recv(s, msgbuf, RESPONSE_LEN, MSG_WAITALL);
216 if (t_serververify(ts, msgbuf) != 0) {
220 /* Client authenticated. Now authenticate ourselves to the client. */
222 if (send(s, t_serverresponse(ts), RESPONSE_LEN, 0) < 0) {
226 /* Copy the key and clean up. */
229 memcpy(tsrp->username, username, strlen(username) + 1);
230 memcpy(tsrp->key, skey, SESSION_KEY_LEN);