1 /*
2 ** Copyright 2003-2007 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5 
6 #include "config.h"
7 #include "tlspasswordcache.h"
8 
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 #include <md5/md5.h>
14 
15 #define PASSFILEFORMAT 1
16 
17 #if HAVE_OPENSSL097
18 #include <openssl/ssl.h>
19 #include <openssl/err.h>
20 #include <openssl/rand.h>
21 
sslerror(EVP_CIPHER_CTX * ctx,const char * pfix)22 static void sslerror(EVP_CIPHER_CTX *ctx, const char *pfix)
23 {
24         char errmsg[256];
25         int errnum=ERR_get_error();
26 
27         ERR_error_string_n(errnum, errmsg, sizeof(errmsg)-1);
28 
29 	fprintf(stderr, "%s: %s\n", pfix, errmsg);
30 }
31 
32 
33 #endif
34 
35 #if HAVE_GCRYPT
36 
37 #include <gcrypt.h>
38 
39 #define RAND_pseudo_bytes(a,b) (gcry_create_nonce((a),(b)), 0)
40 
41 typedef struct {
42 	enum gcry_cipher_algos algo;
43 	enum gcry_cipher_modes mode;
44 } EVP_CIPHER;
45 
46 #define EVP_MAX_IV_LENGTH 256
47 
EVP_des_cbc()48 const EVP_CIPHER *EVP_des_cbc()
49 {
50 	static const EVP_CIPHER des_cbc={GCRY_CIPHER_DES,
51 					 GCRY_CIPHER_MODE_CBC};
52 
53 	return &des_cbc;
54 }
55 
56 typedef struct {
57 	const EVP_CIPHER *cipher;
58 	gcry_error_t err;
59 	gcry_cipher_hd_t handle;
60 
61 	int padding;
62 	char *blkbuf;
63 	size_t blksize;
64 
65 	size_t blkptr;
66 
67 } EVP_CIPHER_CTX;
68 
sslerror(EVP_CIPHER_CTX * ctx,const char * pfix)69 static void sslerror(EVP_CIPHER_CTX *ctx, const char *pfix)
70 {
71 	fprintf(stderr, "%s: %s\n", pfix, gcry_strerror(ctx->err));
72 }
73 
EVP_CIPHER_CTX_init(EVP_CIPHER_CTX * ctx)74 static void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
75 {
76 	memset(ctx, 0, sizeof(*ctx));
77 }
78 
EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX * ctx)79 static void EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *ctx)
80 {
81 	if (ctx->handle)
82 	{
83 		gcry_cipher_close(ctx->handle);
84 		ctx->handle=NULL;
85 	}
86 
87 	if (ctx->blkbuf)
88 	{
89 		free(ctx->blkbuf);
90 		ctx->blkbuf=NULL;
91 	}
92 }
93 
EVP_CIPHER_iv_length(const EVP_CIPHER * cipher)94 static int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
95 {
96 	size_t l=0;
97 
98 	gcry_cipher_algo_info(cipher->algo, GCRYCTL_GET_BLKLEN, NULL, &l);
99 	return l;
100 }
101 
EVP_CIPHER_key_length(const EVP_CIPHER * cipher)102 static int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
103 {
104 	size_t l=0;
105 
106 	gcry_cipher_algo_info(cipher->algo, GCRYCTL_GET_KEYLEN, NULL, &l);
107 	return l;
108 }
109 
EVP_EncryptInit_ex(EVP_CIPHER_CTX * ctx,const EVP_CIPHER * cipher,void * impl,unsigned char * key,unsigned char * iv)110 static int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
111 			      void *impl, unsigned char *key, unsigned char *iv)
112 {
113 	EVP_CIPHER_CTX_cleanup(ctx);
114 	ctx->cipher=cipher;
115 	ctx->err=gcry_cipher_open(&ctx->handle,
116 				  cipher->algo,
117 				  cipher->mode, 0);
118 
119 	if (!ctx->err)
120 		ctx->err=gcry_cipher_setkey(ctx->handle, key,
121 					    EVP_CIPHER_key_length(cipher));
122 
123 	if (!ctx->err)
124 		ctx->err=gcry_cipher_setiv(ctx->handle, iv,
125 					   (ctx->blksize=
126 					    EVP_CIPHER_iv_length(cipher)));
127 
128 	if (!ctx->err)
129 		if ((ctx->blkbuf=malloc(ctx->blksize)) == NULL)
130 			ctx->err=gpg_err_code_from_errno(errno);
131 
132 	ctx->blkptr=0;
133 	ctx->padding=1;
134 
135 	return ctx->err == 0;
136 }
137 
EVP_EncryptUpdate(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl,unsigned char * in,int inl)138 static int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
139 			     int *outl, unsigned char *in, int inl)
140 {
141 	*outl=0;
142 
143 	while (inl > 0)
144 	{
145 		size_t cp= (size_t)inl < (ctx->blksize - ctx->blkptr)
146 			? (size_t)inl:(ctx->blksize - ctx->blkptr);
147 
148 		if (ctx->blkptr == 0 && inl > ctx->blksize*2)
149 		{
150 			cp=(inl / ctx->blksize - 1) * ctx->blksize;
151 
152 			if ((ctx->err=gcry_cipher_encrypt(ctx->handle,
153 							  out, cp,
154 							  in, cp))
155 			    != 0)
156 				return 0;
157 
158 			out += cp;
159 			*outl += cp;
160 			in += cp;
161 			inl -= cp;
162 			continue;
163 		}
164 
165 		memcpy(ctx->blkbuf + ctx->blkptr, in, cp);
166 
167 		in += cp;
168 		inl -= cp;
169 
170 		ctx->blkptr += cp;
171 
172 		if (ctx->blkptr == ctx->blksize)
173 		{
174 			if ((ctx->err=gcry_cipher_encrypt(ctx->handle,
175 							  out, ctx->blksize,
176 							  ctx->blkbuf,
177 							  ctx->blksize)) != 0)
178 				return 0;
179 			out += ctx->blksize;
180 			*outl += ctx->blksize;
181 			ctx->blkptr=0;
182 		}
183 	}
184 	return 1;
185 }
186 
EVP_EncryptFinal_ex(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl)187 static int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out,
188 			       int *outl)
189 {
190 	if (ctx->padding)
191 	{
192 		unsigned char pad=ctx->blksize - ctx->blkptr;
193 
194 		*outl=0;
195 
196 		if (pad == 0)
197 			pad=ctx->blksize;
198 
199 		do
200 		{
201 			int n_outl;
202 
203 			if (!EVP_EncryptUpdate(ctx, out, &n_outl, &pad, 1))
204 				return 0;
205 
206 			out += n_outl;
207 			*outl += n_outl;
208 		}
209 		while (ctx->blkptr);
210 	}
211 	else if (ctx->blksize != ctx->blkptr)
212 	{
213 		ctx->err=GPG_ERR_BAD_DATA;
214 		return 0;
215 	}
216 
217 	return 1;
218 }
219 
EVP_DecryptInit_ex(EVP_CIPHER_CTX * ctx,const EVP_CIPHER * type,void * impl,unsigned char * key,unsigned char * iv)220 static int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
221 			      void *impl, unsigned char *key,
222 			      unsigned char *iv)
223 {
224 	return EVP_EncryptInit_ex(ctx, type, impl, key, iv);
225 }
226 
EVP_DecryptUpdate(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl,unsigned char * in,int inl)227 static int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
228 			     int *outl, unsigned char *in, int inl)
229 {
230 	*outl=0;
231 
232 	while (inl > 0)
233 	{
234 		size_t cp;
235 
236 		if (ctx->blkptr == 0 && inl > ctx->blksize * 3)
237 		{
238 			cp=(inl / ctx->blksize - 2) * ctx->blksize;
239 
240 			if ((ctx->err=gcry_cipher_decrypt(ctx->handle,
241 							  out, cp,
242 							  in, cp))
243 			    != 0)
244 				return 0;
245 
246 			out += cp;
247 			*outl += cp;
248 			in += cp;
249 			inl -= cp;
250 			continue;
251 		}
252 
253 		if (ctx->blkptr == ctx->blksize)
254 		{
255 			if ((ctx->err=gcry_cipher_decrypt(ctx->handle,
256 							  out, ctx->blksize,
257 							  ctx->blkbuf,
258 							  ctx->blksize)) != 0)
259 				return 0;
260 			out += ctx->blksize;
261 			*outl += ctx->blksize;
262 			ctx->blkptr=0;
263 		}
264 
265 		cp= (size_t)inl < (ctx->blksize - ctx->blkptr)
266 			? (size_t)inl:(ctx->blksize - ctx->blkptr);
267 
268 		memcpy(ctx->blkbuf + ctx->blkptr, in, cp);
269 
270 		in += cp;
271 		inl -= cp;
272 
273 		ctx->blkptr += cp;
274 
275 	}
276 	return 1;
277 }
278 
EVP_DecryptFinal_ex(EVP_CIPHER_CTX * ctx,unsigned char * outm,int * outl)279 static int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
280 			       int *outl)
281 {
282 	unsigned char lastval;
283 	int cnt;
284 
285 	if (ctx->blkptr != ctx->blksize)
286 	{
287 		ctx->err=GPG_ERR_BAD_DATA;
288 		return 0;
289 	}
290 
291 	if ((ctx->err=gcry_cipher_decrypt(ctx->handle,
292 					  ctx->blkbuf,
293 					  ctx->blksize,
294 					  NULL, 0)) != 0)
295 		return 0;
296 
297 	if (ctx->padding)
298 	{
299 		lastval=ctx->blkbuf[ctx->blksize-1];
300 
301 		if (lastval > 0 && lastval <= ctx->blksize)
302 		{
303 			char n;
304 
305 			for (n=0; n<lastval; n++)
306 				if (ctx->blkbuf[ctx->blksize-1-n] != lastval)
307 					lastval=0;
308 		}
309 		else
310 			lastval=0;
311 
312 		if (!lastval)
313 		{
314 			ctx->err=GPG_ERR_BAD_DATA;
315 			return 0;
316 		}
317 	}
318 	else
319 	{
320 		lastval=0;
321 	}
322 
323 	cnt=ctx->blksize-lastval;
324 	if (cnt)
325 		memcpy(outm, ctx->blkbuf, cnt);
326 	*outl=cnt;
327 	return 1;
328 }
329 
330 
331 #define HAVE_OPENSSL097 1
332 #endif
333 
334 #if HAVE_OPENSSL097
335 
336 #if BUFSIZ < 8192
337 #undef BUFSIZ
338 #define BUFSIZ 8192
339 #endif
340 
tlspassword_init()341 int tlspassword_init()
342 {
343 	return 1;
344 }
345 
346 static int save_string(EVP_CIPHER_CTX *,
347 		       const char *, char *,
348 		       int (*)(const char *, size_t, void *),
349 		       void *);
350 
tlspassword_save(const char * const * urls,const char * const * pwds,const char * mpw,int (* writefunc)(const char *,size_t,void *),void * writefuncarg)351 int tlspassword_save( const char * const *urls,
352 		      const char * const *pwds,
353 		      const char *mpw,
354 		      int (*writefunc)(const char *, size_t, void *),
355 		      void *writefuncarg)
356 {
357 	char buf[BUFSIZ];
358 	char *p;
359 	int l;
360 	int wl;
361 
362 	unsigned char iv1_buf[16];
363 	unsigned char iv2_buf[16];
364 	MD5_DIGEST md5_password;
365 	int iv_len, key_len;
366 	EVP_CIPHER_CTX ctx;
367 	const EVP_CIPHER *des=EVP_des_cbc();
368 
369 	md5_digest(mpw, strlen(mpw), md5_password);
370 
371 	EVP_CIPHER_CTX_init(&ctx);
372 	iv_len=EVP_CIPHER_iv_length(des);
373 	key_len=EVP_CIPHER_key_length(des);
374 
375 	if (RAND_pseudo_bytes(iv1_buf, sizeof(iv1_buf)) < 0 ||
376 	    RAND_pseudo_bytes(iv2_buf, sizeof(iv2_buf)) < 0)
377 	{
378 		fprintf(stderr,
379 			"tlspassword_save: internal error - "
380 			"RAND_pseudo_bytes() failed.\n");
381 		EVP_CIPHER_CTX_cleanup(&ctx);
382 		errno=EIO;
383 		return -1;
384 	}
385 
386 	if (iv_len + key_len > sizeof(iv1_buf)
387 	    || iv_len + key_len != sizeof(iv2_buf)
388 	    || key_len != sizeof(md5_password)/2)
389 	{
390 		fprintf(stderr,
391 			"tlspassword_save: internal error - "
392 			"unexpected key sizes.\n");
393 		EVP_CIPHER_CTX_cleanup(&ctx);
394 		errno=EIO;
395 		return -1;
396 	}
397 
398 	p=buf+3;
399 
400 	if (!EVP_EncryptInit_ex(&ctx, des, NULL,
401 				(unsigned char *)md5_password,
402 				iv1_buf) ||
403 	    !EVP_EncryptUpdate(&ctx, (unsigned char *)p, &l,
404 			       (unsigned char *)md5_password + key_len,
405 			       sizeof(md5_password)-key_len) ||
406 	    !EVP_EncryptUpdate(&ctx, (unsigned char *)(p += l), &l,
407 			       iv2_buf,
408 			       iv_len + key_len) ||
409 	    !EVP_EncryptFinal_ex(&ctx, (unsigned char *)(p += l), &l))
410 
411 	{
412 		sslerror(&ctx, "EVP_EncryptInit_ex");
413 		EVP_CIPHER_CTX_cleanup(&ctx);
414 		errno=EIO;
415 		return -1;
416 	}
417 
418 	p += l;
419 
420 	wl= p - buf - 3;
421 
422 	buf[0]=PASSFILEFORMAT;
423 	buf[1]= wl / 256;
424 	buf[2]= wl % 256;
425 
426 	l=(*writefunc)(buf, 3, writefuncarg);
427 
428 	if (l == 0)
429 		l=(*writefunc)((const char *)iv1_buf, iv_len, writefuncarg);
430 
431 	if (l == 0)
432 		l=(*writefunc)(buf+3, wl, writefuncarg);
433 
434 	if (l)
435 		return l;
436 
437 #if 0
438 	{
439 		int i;
440 
441 		printf("KEY: ");
442 
443 		for (i=0; i<key_len + iv_len; i++)
444 			printf("%02X", (int)(unsigned char)iv2_buf[i]);
445 		printf("\n");
446 	}
447 #endif
448 
449 	if (!EVP_EncryptInit_ex(&ctx, des, NULL,
450 				(unsigned char *)&iv2_buf,
451 				(unsigned char *)&iv2_buf + key_len))
452 	{
453 		sslerror(&ctx, "EVP_EncryptInit_ex");
454 		EVP_CIPHER_CTX_cleanup(&ctx);
455 		errno=EIO;
456 		return -1;
457 	}
458 
459 	for (l=0; urls[l]; l++)
460 	{
461 		int n=save_string(&ctx, urls[l], buf, writefunc, writefuncarg);
462 
463 		if (n)
464 			return n;
465 
466 		n=save_string(&ctx, pwds[l], buf, writefunc, writefuncarg);
467 
468 		if (n)
469 			return n;
470 	}
471 
472 	if (!EVP_EncryptFinal_ex(&ctx, (unsigned char *)buf, &l))
473 	{
474 		sslerror(&ctx, "EVP_EncryptInit_ex");
475 		EVP_CIPHER_CTX_cleanup(&ctx);
476 		errno=EIO;
477 		return -1;
478 	}
479 
480 	if (l)
481 		l=(*writefunc)(buf, l, writefuncarg);
482 
483 	EVP_CIPHER_CTX_cleanup(&ctx);
484 	return l;
485 }
486 
save_string(EVP_CIPHER_CTX * ctx,const char * str,char * buf,int (* writefunc)(const char *,size_t,void *),void * writefuncarg)487 static int save_string(EVP_CIPHER_CTX *ctx,
488 		       const char *str, char *buf,
489 		       int (*writefunc)(const char *, size_t, void *),
490 		       void *writefuncarg)
491 {
492 	int l;
493 	size_t len=strlen(str);
494 	unsigned char b[2];
495 
496 	if (len >= 256 * 256)
497 	{
498 		fprintf(stderr,
499 			"tlspassword_save: internal error - "
500 			"key sizes too large.\n");
501 		errno=EINVAL;
502 		return -1;
503 	}
504 
505 	b[0]=len / 256;
506 	b[1]=len % 256;
507 
508 	if (!EVP_EncryptUpdate(ctx, (unsigned char *)buf, &l, b, 2))
509 	{
510 		sslerror(ctx, "EVP_EncryptUpdate");
511 		return -1;
512 	}
513 
514 	if (l)
515 	{
516 		l=(*writefunc)(buf, l, writefuncarg);
517 
518 		if (l)
519 			return l;
520 	}
521 
522 	while (len)
523 	{
524 		size_t n=len;
525 
526 		if (n > BUFSIZ / 4)
527 			n=BUFSIZ/4;
528 
529 		if (!EVP_EncryptUpdate(ctx, (unsigned char *)buf, &l,
530 				       (unsigned char *)str, n))
531 		{
532 			sslerror(ctx, "EVP_EncryptUpdate");
533 			return -1;
534 		}
535 
536 		if (l)
537 		{
538 			l=(*writefunc)(buf, l, writefuncarg);
539 
540 			if (l)
541 				return l;
542 		}
543 
544 		str += n;
545 		len -= n;
546 	}
547 
548 	return 0;
549 }
550 
551 struct tempstring_list {
552 	struct tempstring_list *next;
553 	char *url;
554 	char *pw;
555 };
556 
557 struct tlspassword_readinfo {
558 	char buf[BUFSIZ / 2];
559 	char *bufptr;
560 	size_t bufleft;
561 
562 	int (*readfunc)(char *, size_t, void *);
563 	void *readfuncarg;
564 
565 	struct tempstring_list *tl_list, *tl_last;
566 
567 	int (*readhandler)(struct tlspassword_readinfo *, char *, int);
568 
569 	unsigned int stringhi;
570 	char *stringptr;
571 	size_t stringleft;
572 	size_t nstrings;
573 };
574 
575 
tlspassword_read(struct tlspassword_readinfo * p,char * buf,size_t nbytes)576 static int tlspassword_read(struct tlspassword_readinfo *p,
577 			    char *buf,
578 			    size_t nbytes)
579 {
580 	while (nbytes)
581 	{
582 		size_t c;
583 
584 		if (p->bufleft == 0)
585 		{
586 			int n= (*p->readfunc)(p->buf, sizeof(p->buf),
587 					      p->readfuncarg);
588 
589 			if (n <= 0)
590 				return -1;
591 			p->bufptr=p->buf;
592 			p->bufleft=n;
593 		}
594 
595 		c=nbytes;
596 
597 		if (c > p->bufleft)
598 			c=p->bufleft;
599 
600 		memcpy(buf, p->bufptr, c);
601 		p->bufptr += c;
602 		p->bufleft -= c;
603 		nbytes -= c;
604 	}
605 
606 	return 0;
607 }
608 
tlspassword_readcleanup(struct tlspassword_readinfo * p)609 static void tlspassword_readcleanup(struct tlspassword_readinfo *p)
610 {
611 	while (p->tl_list)
612 	{
613 		struct tempstring_list *t=p->tl_list;
614 
615 		p->tl_list=t->next;
616 		if (t->url)
617 			free(t->url);
618 		if (t->pw)
619 			free(t->pw);
620 		free(t);
621 	}
622 }
623 
624 static int read_stringhi(struct tlspassword_readinfo *, char *, int);
625 
tlspassword_load(int (* callback)(char *,size_t,void *),void * callback_arg,const char * mpw,void (* readfunc)(const char * const *,const char * const *,void *),void * readfunc_arg)626 int tlspassword_load( int (*callback)(char *, size_t, void *),
627 		      void *callback_arg,
628 
629 		      const char *mpw,
630 
631 		      void (*readfunc)(const char * const *,
632 				       const char * const *,
633 				       void *),
634 		      void *readfunc_arg)
635 {
636 	char buf[BUFSIZ];
637 	int outl;
638 	char *p;
639 
640 	MD5_DIGEST md5_password;
641 	int iv_len, key_len;
642 	EVP_CIPHER_CTX ctx;
643 	const EVP_CIPHER *des=EVP_des_cbc();
644 	struct tlspassword_readinfo readinfo;
645 	char header[3];
646 	size_t l;
647 	char iv1_buf[EVP_MAX_IV_LENGTH];
648 	struct tempstring_list *tl;
649 	const char **urls, **pws;
650 
651 	readinfo.bufleft=0;
652 	readinfo.readfunc=callback;
653 	readinfo.readfuncarg=callback_arg;
654 	readinfo.tl_list=NULL;
655 	readinfo.tl_last=NULL;
656 
657 	md5_digest(mpw, strlen(mpw), md5_password);
658 
659 	EVP_CIPHER_CTX_init(&ctx);
660 	iv_len=EVP_CIPHER_iv_length(des);
661 	key_len=EVP_CIPHER_key_length(des);
662 
663 	if (tlspassword_read(&readinfo, header, 3) ||
664 	    tlspassword_read(&readinfo, iv1_buf, iv_len))
665 	{
666 		EVP_CIPHER_CTX_cleanup(&ctx);
667 		return -1;
668 	}
669 	if (header[0] != PASSFILEFORMAT)
670 	{
671 		errno=EINVAL;
672 		EVP_CIPHER_CTX_cleanup(&ctx);
673 		return -1;
674 	}
675 
676 	if ((l=(size_t)(unsigned char)header[1] * 256
677 	     + (unsigned char)header[2]) > sizeof(buf) / 4)
678 	{
679 		errno=EINVAL;
680 		EVP_CIPHER_CTX_cleanup(&ctx);
681 		return -1;
682 	}
683 
684 	if (tlspassword_read(&readinfo, buf, l))
685 		return -1;
686 
687 	p=buf + sizeof(buf)/2;
688 	if (!EVP_DecryptInit_ex(&ctx, des, NULL,
689 				(unsigned char *)md5_password,
690 				(unsigned char *)&iv1_buf) ||
691 	    !EVP_DecryptUpdate(&ctx, (unsigned char *)p, &outl,
692 			       (unsigned char *)buf, l) ||
693 	    !EVP_DecryptFinal_ex(&ctx, (unsigned char *)(p += outl), &outl))
694 	{
695 		errno=EINVAL;
696 		EVP_CIPHER_CTX_cleanup(&ctx);
697 		return -1;
698 	}
699 
700 	p += outl;
701 
702 	if (p - (buf +sizeof(buf)/2) != sizeof(md5_password) + iv_len
703 	    || memcmp(buf + sizeof(buf)/2, (char *)(&md5_password) + key_len,
704 		      sizeof(md5_password)-key_len))
705 	{
706 		errno=EINVAL;
707 		EVP_CIPHER_CTX_cleanup(&ctx);
708 		return -1;
709 	}
710 
711 #if 0
712 	{
713 		int i;
714 
715 		printf("KEY: ");
716 
717 		for (i=0; i<key_len + iv_len; i++)
718 			printf("%02X", (int)(unsigned char)(p-iv_len-key_len)[i]);
719 		printf("\n");
720 	}
721 #endif
722 
723 	if (!EVP_DecryptInit_ex(&ctx, des, NULL,
724 				(unsigned char *)(p-iv_len-key_len),
725 				(unsigned char *)(p-iv_len)))
726 	{
727 		errno=EINVAL;
728 		EVP_CIPHER_CTX_cleanup(&ctx);
729 		return -1;
730 	}
731 
732 	readinfo.nstrings=0;
733 	readinfo.readhandler= &read_stringhi;
734 	for (;;)
735 	{
736 		if (readinfo.bufleft == 0)
737 		{
738 			outl= (*readinfo.readfunc)(readinfo.buf,
739 						   sizeof(readinfo.buf),
740 						   readinfo.readfuncarg);
741 
742 			if (outl == 0)
743 				break;
744 
745 			if (outl < 0)
746 			{
747 				tlspassword_readcleanup(&readinfo);
748 				errno=EINVAL;
749 				EVP_CIPHER_CTX_cleanup(&ctx);
750 				return -1;
751 			}
752 
753 			readinfo.bufptr=readinfo.buf;
754 			readinfo.bufleft=outl;
755 		}
756 
757 		if (!EVP_DecryptUpdate(&ctx, (unsigned char *)buf, &outl,
758 				       (unsigned char *)
759 				       readinfo.bufptr, readinfo.bufleft))
760 		{
761 			tlspassword_readcleanup(&readinfo);
762 			errno=EINVAL;
763 			EVP_CIPHER_CTX_cleanup(&ctx);
764 			return -1;
765 		}
766 		readinfo.bufleft=0;
767 
768 		p=buf;
769 		while (outl)
770 		{
771 			int n= (*readinfo.readhandler)(&readinfo, p, outl);
772 
773 			if (n < 0)
774 			{
775 				tlspassword_readcleanup(&readinfo);
776 				EVP_CIPHER_CTX_cleanup(&ctx);
777 				return -1;
778 			}
779 
780 			p += n;
781 			outl -= n;
782 		}
783 	}
784 
785 	if (!EVP_DecryptFinal_ex(&ctx, (unsigned char *)buf, &outl))
786 	{
787 		tlspassword_readcleanup(&readinfo);
788 		errno=EINVAL;
789 		EVP_CIPHER_CTX_cleanup(&ctx);
790 		return -1;
791 	}
792 
793 	p=buf;
794 	while (outl)
795 	{
796 		int n= (*readinfo.readhandler)(&readinfo, p, outl);
797 
798 		if (n < 0)
799 		{
800 			tlspassword_readcleanup(&readinfo);
801 			errno=EINVAL;
802 			EVP_CIPHER_CTX_cleanup(&ctx);
803 			return -1;
804 		}
805 
806 		p += n;
807 		outl -= n;
808 	}
809 
810 	if (readinfo.tl_list && readinfo.tl_list->pw == NULL)
811 		/* Odd # of strings -- no good */
812 	{
813 		tlspassword_readcleanup(&readinfo);
814 		errno=EINVAL;
815 		EVP_CIPHER_CTX_cleanup(&ctx);
816 		return (-1);
817 	}
818 
819 	if ((urls=malloc((readinfo.nstrings+1) * sizeof(char *))) == NULL ||
820 	    (pws=malloc((readinfo.nstrings+1) * sizeof(char *))) == NULL)
821 	{
822 		if (urls)
823 			free(urls);
824 
825 		tlspassword_readcleanup(&readinfo);
826 		EVP_CIPHER_CTX_cleanup(&ctx);
827 		return (-1);
828 	}
829 
830 	l=0;
831 	for (tl=readinfo.tl_list; tl; tl=tl->next)
832 	{
833 		urls[l]=tl->url;
834 		pws[l]=tl->pw;
835 		l++;
836 	}
837 
838 	urls[l]=NULL;
839 	pws[l]=NULL;
840 
841 	(*readfunc)(urls, pws, readfunc_arg);
842 
843 	free(urls);
844 	free(pws);
845 
846 	tlspassword_readcleanup(&readinfo);
847 	EVP_CIPHER_CTX_cleanup(&ctx);
848 	return 0;
849 }
850 
851 static int read_stringlo(struct tlspassword_readinfo *info,
852 			 char *p, int n);
853 
854 static int read_string(struct tlspassword_readinfo *info,
855 		       char *p, int n);
856 
read_stringhi(struct tlspassword_readinfo * info,char * p,int n)857 static int read_stringhi(struct tlspassword_readinfo *info,
858 			 char *p, int n)
859 {
860 	info->stringhi=(unsigned char)*p;
861 	info->stringhi *= 256;
862 
863 	info->readhandler=read_stringlo;
864 	return 1;
865 }
866 
read_stringlo(struct tlspassword_readinfo * info,char * p,int n)867 static int read_stringlo(struct tlspassword_readinfo *info,
868 			 char *p, int n)
869 {
870 	struct tempstring_list *t;
871 
872 	info->readhandler=read_string;
873 	info->stringleft=info->stringhi + (unsigned char)*p;
874 
875 	if (info->tl_last &&
876 	    info->tl_last->pw == NULL) /* This string is the pw */
877 	{
878 		info->tl_last->pw=malloc(info->stringleft+1);
879 		if (!info->tl_last->pw)
880 			return -1;
881 
882 		info->stringptr=info->tl_last->pw;
883 		return 1;
884 	}
885 
886 	if ((t=(struct tempstring_list *)malloc(sizeof(struct tempstring_list))
887 	     ) == NULL || (t->url=malloc(info->stringleft+1)) == NULL)
888 	{
889 		if (t) free(t);
890 		return -1;
891 	}
892 
893 	if (info->tl_last)
894 		info->tl_last->next=t;
895 	else
896 		info->tl_list=t;
897 	info->tl_last=t;
898 	info->stringptr=t->url;
899 	t->next=NULL;
900 	t->pw=NULL;
901 	++info->nstrings;
902 	return 1;
903 }
904 
read_string(struct tlspassword_readinfo * info,char * p,int n)905 static int read_string(struct tlspassword_readinfo *info, char *p, int n)
906 {
907 	if (n > info->stringleft)
908 		n=info->stringleft;
909 
910 	memcpy(info->stringptr, p, n);
911 	info->stringptr += n;
912 	info->stringleft -= n;
913 
914 	if (info->stringleft == 0)
915 	{
916 		info->readhandler=read_stringhi;
917 		*info->stringptr=0;
918 	}
919 
920 	return n;
921 }
922 
923 #else
924 
925 
tlspassword_init()926 int tlspassword_init()
927 {
928 	return 0;
929 }
930 
931 
tlspassword_save(const char * const * urls,const char * const * pwds,const char * mpw,int (* writefunc)(const char *,size_t,void *),void * writefuncarg)932 int tlspassword_save( const char * const *urls,
933 		      const char * const *pwds,
934 		      const char *mpw,
935 		      int (*writefunc)(const char *, size_t, void *),
936 		      void *writefuncarg)
937 {
938 	errno=EIO;
939 	return -1;
940 }
941 
tlspassword_load(int (* readfunc)(char *,size_t,void *),void * readfuncarg,const char * mpw,void (* callback)(const char * const *,const char * const *,void *),void * callback_arg)942 int tlspassword_load( int (*readfunc)(char *, size_t, void *),
943 		      void *readfuncarg,
944 
945 		      const char *mpw,
946 		      void (*callback)(const char * const *,
947 				       const char * const *,
948 				       void *),
949 		      void *callback_arg)
950 {
951 	errno=EIO;
952 	return -1;
953 }
954 #endif
955