xref: /inferno-os/appl/cmd/idea.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement Idea;
2
3#
4# Copyright © 2002 Vita Nuova Holdings Limited.  All rights reserved.
5#
6
7include "sys.m";
8	sys: Sys;
9include "draw.m";
10include "bufio.m";
11	bufio: Bufio;
12	Iobuf: import bufio;
13include "keyring.m";
14	keyring: Keyring;
15
16Idea: module
17{
18	init: fn(nil: ref Draw->Context, argv: list of string);
19};
20
21decerr(s: string)
22{
23	sys->fprint(sys->fildes(2), "decrypt error: %s (wrong password ?)\n", s);
24	exit;
25}
26
27init(nil: ref Draw->Context, argv: list of string)
28{
29	sys = load Sys Sys->PATH;
30	stdin := sys->fildes(0);
31	stdout := sys->fildes(1);
32
33	bufio = load Bufio Bufio->PATH;
34	keyring = load Keyring Keyring->PATH;
35
36	obuf := array[8] of byte;
37	buf := array[8] of byte;
38	key := array[16] of byte;
39
40	argc := len argv;
41	if((argc != 3 && argc != 4) || (hd tl argv != "-e" && hd tl argv != "-d") || len hd tl tl argv != 16){
42		sys->fprint(sys->fildes(2), "usage: idea -[e | d] <16 char key> [inputfile]\n");
43		exit;
44	}
45	dec := hd tl argv == "-d";
46	if(argc == 4){
47		s := hd tl tl tl argv;
48		stdin = sys->open(s, Sys->OREAD);
49		if(stdin == nil){
50			sys->fprint(sys->fildes(2), "cannot open %s\n", s);
51			exit;
52		}
53		if(dec){
54			l := len s;
55			if(s[l-3: l] != ".id"){
56				sys->fprint(sys->fildes(2), "input file not a .id file\n");
57				exit;
58			}
59			s = s[0: l-3];
60		}
61		else
62			s += ".id";
63		stdout = sys->create(s, Sys->OWRITE, 8r666);
64		if(stdout == nil){
65			sys->fprint(sys->fildes(2), "cannot create %s\n", s);
66			exit;
67		}
68	}
69	for(i := 0; i < 16; i++)
70		key[i] = byte (hd tl tl argv)[i];
71	is := keyring->ideasetup(key, nil);
72	m := om := 0;
73	bin := bufio->fopen(stdin, Bufio->OREAD);
74	bout := bufio->fopen(stdout, Bufio->OWRITE);
75	for(;;){
76		n := bin.read(buf[m: ], 8-m);
77		if(n <= 0)
78			break;
79		m += n;
80		if(m == 8){
81			keyring->ideaecb(is, buf, 8, dec);
82			if(dec){	# leave last block around
83				if(om > 0)
84					bout.write(obuf, 8);
85				obuf[0: ] = buf[0: 8];
86				om = 8;
87			}
88			else
89				bout.write(buf, 8);
90			m = 0;
91		}
92	}
93	if(dec){
94		if(om != 8)
95			decerr("no last block");
96		if(m != 0)
97			decerr("last block not 8 bytes long");
98		m = int obuf[7];
99		if(m < 0 || m > 7)
100			decerr("bad modulus");
101		for(i = m; i < 8-1; i++)
102			if(obuf[i] != byte 0)
103				decerr("byte not 0");
104		bout.write(obuf, m);
105	}
106	else{
107		for(i = m; i < 8; i++)
108			buf[i] = byte 0;
109		buf[7] = byte m;
110		keyring->ideaecb(is, buf, 8, dec);
111		bout.write(buf, 8);
112	}
113	bout.flush();
114	bin.close();
115	bout.close();
116}
117