]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/auth/convkeys.c
show line numbers in dtracy type errors
[plan9front.git] / sys / src / cmd / auth / convkeys.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <libsec.h>
5 #include <authsrv.h>
6 #include "authcmdlib.h"
7
8 Authkey okey, nkey;
9
10 int     verb;
11 int     usepass;
12 int     convaes;
13
14 uchar   zeros[16];
15
16 int     convert(char**, int);
17 void    usage(void);
18
19 void
20 main(int argc, char *argv[])
21 {
22         Dir *d;
23         char *p, *file;
24         int fd, len;
25
26         ARGBEGIN{
27         case 'p':
28                 usepass = 1;
29                 break;
30         case 'v':
31                 verb = 1;
32                 break;
33         case 'a':
34                 convaes = 1;
35                 break;
36         default:
37                 usage();
38         }ARGEND
39
40         if(argc != 1)
41                 usage();
42         file = argv[0];
43
44         private();
45
46         /* get original key */
47         if(usepass){
48                 print("enter password file is encoded with\n");
49                 getpass(&okey, nil, 0, 1);
50         } else {
51                 getauthkey(&okey);
52         }
53         if(!verb){
54                 print("enter password to reencode with\n");
55                 getpass(&nkey, nil, 0, 1);
56         }
57
58         fd = open(file, ORDWR);
59         if(fd < 0)
60                 error("can't open %s: %r\n", file);
61         d = dirfstat(fd);
62         if(d == nil)
63                 error("can't stat %s: %r\n", file);
64         len = d->length;
65         p = malloc(len);
66         if(p == nil)
67                 error("out of memory");
68         if(read(fd, p, len) != len)
69                 error("can't read key file: %r\n");
70         len = convert(&p, len);
71         if(pwrite(fd, p, len, 0) != len)
72                 error("can't write key file: %r\n");
73         close(fd);
74         exits(nil);
75 }
76
77 int
78 badname(char *s)
79 {
80         int n;
81         Rune r;
82
83         for (; *s != '\0'; s += n) {
84                 n = chartorune(&r, s);
85                 if (r == Runeerror)
86                         return 1;
87         }
88         return 0;
89 }
90
91 int
92 convert(char **db, int len)
93 {
94         int i, nu, keydblen, keydboff, keydbaes;
95         char *p = *db;
96
97         keydblen = KEYDBLEN;
98         keydboff = KEYDBOFF;
99         keydbaes = len > 24 && memcmp(p, "AES KEYS", 8) == 0;
100         if(keydbaes){
101                 keydblen += AESKEYLEN;
102                 keydboff = 8+16;                /* signature[8] + iv[16] */
103         }
104
105         len -= keydboff;
106         if(len % keydblen){
107                 fprint(2, "%s: file odd length; not converting %d bytes\n", argv0, len % keydblen);
108                 len -= len % keydblen;
109         }
110         len += keydboff;
111
112         if(keydbaes){
113                 AESstate s;
114
115                 /* make sure we have aes key for decryption */
116                 if(memcmp(okey.aes, zeros, AESKEYLEN) == 0){
117                         fprint(2, "%s: no aes key in NVRAM\n", argv0);
118                         exits("no aes key");
119                 }
120                 setupAESstate(&s, okey.aes, AESKEYLEN, zeros);
121                 aesCBCdecrypt((uchar*)p+8, len-8, &s);
122         } else {
123                 DESstate s;
124                 uchar k[8];
125
126                 des56to64((uchar*)okey.des, k);
127                 setupDESstate(&s, k, zeros);
128                 desCBCdecrypt((uchar*)p, len, &s);
129         }
130
131         nu = 0;
132         for(i = keydboff; i < len; i += keydblen) {
133                 if (badname(&p[i])) {
134                         fprint(2, "%s: bad name %.30s... - aborting\n", argv0, &p[i]);
135                         exits("bad name");
136                 }
137                 nu++;
138         }
139
140         if(verb){
141                 for(i = keydboff; i < len; i += keydblen)
142                         print("%s\n", &p[i]);
143                 exits(nil);
144         }
145
146         if(convaes && !keydbaes){
147                 char *s, *d;
148
149                 keydboff = 8+16;
150                 keydblen += AESKEYLEN;
151                 len = keydboff + keydblen*nu;
152                 p = realloc(p, len);
153                 if(p == nil)
154                         error("out of memory");
155                 *db = p;
156                 s = p + KEYDBOFF + nu*KEYDBLEN;
157                 d = p + keydboff + nu*keydblen;
158                 for(i=0; i<nu; i++){
159                         s -= KEYDBLEN;
160                         d -= keydblen;
161                         memmove(d, s, KEYDBLEN);
162                         memset(d + KEYDBLEN, 0, keydblen-KEYDBLEN);
163                 }
164                 keydbaes = 1;
165         }
166
167         genrandom((uchar*)p, keydboff);
168         if(keydbaes){
169                 AESstate s;
170
171                 memmove(p, "AES KEYS", 8);
172                 setupAESstate(&s, nkey.aes, AESKEYLEN, zeros);
173                 aesCBCencrypt((uchar*)p+8, len-8, &s);
174         } else {
175                 DESstate s;
176                 uchar k[8];
177
178                 des56to64((uchar*)nkey.des, k);
179                 setupDESstate(&s, k, zeros);
180                 desCBCencrypt((uchar*)p, len, &s);
181         }
182         return len;
183 }
184
185 void
186 usage(void)
187 {
188         fprint(2, "usage: %s [-pva] keyfile\n", argv0);
189         exits("usage");
190 }