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