1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "authcmdlib.h"
5
6 /*
7 * compute the key verification checksum
8 */
9 void
checksum(char key[],char csum[])10 checksum(char key[], char csum[]) {
11 uchar buf[8];
12
13 memset(buf, 0, 8);
14 encrypt(key, buf, 8);
15 sprint(csum, "C %.2ux%.2ux%.2ux%.2ux", buf[0], buf[1], buf[2], buf[3]);
16 }
17
18 /*
19 * compute the proper response. We encrypt the ascii of
20 * challenge number, with trailing binary zero fill.
21 * This process was derived empirically.
22 * this was copied from inet's guard.
23 */
24 char *
netresp(char * key,long chal,char * answer)25 netresp(char *key, long chal, char *answer)
26 {
27 uchar buf[8];
28
29 memset(buf, 0, 8);
30 snprint((char *)buf, sizeof buf, "%lud", chal);
31 if(encrypt(key, buf, 8) < 0)
32 error("can't encrypt response");
33 chal = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3];
34 sprint(answer, "%.8lux", chal);
35
36 return answer;
37 }
38
39 char *
netdecimal(char * answer)40 netdecimal(char *answer)
41 {
42 int i;
43
44 for(i = 0; answer[i]; i++)
45 switch(answer[i]){
46 case 'a': case 'b': case 'c':
47 answer[i] = '2';
48 break;
49 case 'd': case 'e': case 'f':
50 answer[i] = '3';
51 break;
52 }
53 return answer;
54 }
55
56 int
netcheck(void * key,long chal,char * response)57 netcheck(void *key, long chal, char *response)
58 {
59 char answer[32], *p;
60 int i;
61
62 if(smartcheck(key, chal, response))
63 return 1;
64
65 if(p = strchr(response, '\n'))
66 *p = '\0';
67 netresp(key, chal, answer);
68
69 /*
70 * check for hex response -- securenet mode 1 or 5
71 */
72 for(i = 0; response[i]; i++)
73 if(response[i] >= 'A' && response[i] <= 'Z')
74 response[i] -= 'A' - 'a';
75 if(strcmp(answer, response) == 0)
76 return 1;
77
78 /*
79 * check for decimal response -- securenet mode 0 or 4
80 */
81 return strcmp(netdecimal(answer), response) == 0;
82 }
83
84 int
smartcheck(void * key,long chal,char * response)85 smartcheck(void *key, long chal, char *response)
86 {
87 uchar buf[2*8];
88 int i, c, cslo, cshi;
89
90 snprint((char*)buf, sizeof buf, "%lud ", chal);
91 cslo = 0x52;
92 cshi = cslo;
93 for(i = 0; i < 8; i++){
94 c = buf[i];
95 if(c >= '0' && c <= '9')
96 c -= '0';
97 cslo += c;
98 if(cslo > 0xff)
99 cslo -= 0xff;
100 cshi += cslo;
101 if(cshi > 0xff)
102 cshi -= 0xff;
103 buf[i] = c | (cshi & 0xf0);
104 }
105
106 encrypt(key, buf, 8);
107 for(i = 0; i < 8; i++)
108 if(response[i] != buf[i] % 10 + '0')
109 return 0;
110 return 1;
111 }
112