summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/evp/bio_ok.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/evp/bio_ok.c')
-rw-r--r--src/lib/libcrypto/evp/bio_ok.c97
1 files changed, 60 insertions, 37 deletions
diff --git a/src/lib/libcrypto/evp/bio_ok.c b/src/lib/libcrypto/evp/bio_ok.c
index 101275d648..3cbc6e7848 100644
--- a/src/lib/libcrypto/evp/bio_ok.c
+++ b/src/lib/libcrypto/evp/bio_ok.c
@@ -67,7 +67,7 @@
67 and everything was OK. BUT if user types wrong password 67 and everything was OK. BUT if user types wrong password
68 BIO_f_cipher outputs only garbage and my function crashes. Yes 68 BIO_f_cipher outputs only garbage and my function crashes. Yes
69 I can and I should fix my function, but BIO_f_cipher is 69 I can and I should fix my function, but BIO_f_cipher is
70 easy way to add encryption support to many exisiting applications 70 easy way to add encryption support to many existing applications
71 and it's hard to debug and fix them all. 71 and it's hard to debug and fix them all.
72 72
73 So I wanted another BIO which would catch the incorrect passwords and 73 So I wanted another BIO which would catch the incorrect passwords and
@@ -80,10 +80,10 @@
80 1) you must somehow separate checksum from actual data. 80 1) you must somehow separate checksum from actual data.
81 2) you need lot's of memory when reading the file, because you 81 2) you need lot's of memory when reading the file, because you
82 must read to the end of the file and verify the checksum before 82 must read to the end of the file and verify the checksum before
83 leting the application to read the data. 83 letting the application to read the data.
84 84
85 BIO_f_reliable tries to solve both problems, so that you can 85 BIO_f_reliable tries to solve both problems, so that you can
86 read and write arbitraly long streams using only fixed amount 86 read and write arbitrary long streams using only fixed amount
87 of memory. 87 of memory.
88 88
89 BIO_f_reliable splits data stream into blocks. Each block is prefixed 89 BIO_f_reliable splits data stream into blocks. Each block is prefixed
@@ -91,7 +91,7 @@
91 several Kbytes of memory to buffer single block before verifying 91 several Kbytes of memory to buffer single block before verifying
92 it's digest. 92 it's digest.
93 93
94 BIO_f_reliable goes futher and adds several important capabilities: 94 BIO_f_reliable goes further and adds several important capabilities:
95 95
96 1) the digest of the block is computed over the whole stream 96 1) the digest of the block is computed over the whole stream
97 -- so nobody can rearrange the blocks or remove or replace them. 97 -- so nobody can rearrange the blocks or remove or replace them.
@@ -110,7 +110,7 @@
110 and then compare the digest output. 110 and then compare the digest output.
111 111
112 Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I 112 Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I
113 initialy wrote and tested this code on x86 machine and wrote the 113 initially wrote and tested this code on x86 machine and wrote the
114 digests out in machine-dependent order :( There are people using 114 digests out in machine-dependent order :( There are people using
115 this code and I cannot change this easily without making existing 115 this code and I cannot change this easily without making existing
116 data files unreadable. 116 data files unreadable.
@@ -125,11 +125,13 @@
125#include <openssl/evp.h> 125#include <openssl/evp.h>
126#include <openssl/rand.h> 126#include <openssl/rand.h>
127 127
128static int ok_write(BIO *h,char *buf,int num); 128static int ok_write(BIO *h, const char *buf, int num);
129static int ok_read(BIO *h,char *buf,int size); 129static int ok_read(BIO *h, char *buf, int size);
130static long ok_ctrl(BIO *h,int cmd,long arg1,char *arg2); 130static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
131static int ok_new(BIO *h); 131static int ok_new(BIO *h);
132static int ok_free(BIO *data); 132static int ok_free(BIO *data);
133static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
134
133static void sig_out(BIO* b); 135static void sig_out(BIO* b);
134static void sig_in(BIO* b); 136static void sig_in(BIO* b);
135static void block_out(BIO* b); 137static void block_out(BIO* b);
@@ -160,7 +162,7 @@ typedef struct ok_struct
160 EVP_MD_CTX md; 162 EVP_MD_CTX md;
161 int blockout; /* output block is ready */ 163 int blockout; /* output block is ready */
162 int sigio; /* must process signature */ 164 int sigio; /* must process signature */
163 char buf[IOBS]; 165 unsigned char buf[IOBS];
164 } BIO_OK_CTX; 166 } BIO_OK_CTX;
165 167
166static BIO_METHOD methods_ok= 168static BIO_METHOD methods_ok=
@@ -173,6 +175,7 @@ static BIO_METHOD methods_ok=
173 ok_ctrl, 175 ok_ctrl,
174 ok_new, 176 ok_new,
175 ok_free, 177 ok_free,
178 ok_callback_ctrl,
176 }; 179 };
177 180
178BIO_METHOD *BIO_f_reliable(void) 181BIO_METHOD *BIO_f_reliable(void)
@@ -184,7 +187,7 @@ static int ok_new(BIO *bi)
184 { 187 {
185 BIO_OK_CTX *ctx; 188 BIO_OK_CTX *ctx;
186 189
187 ctx=(BIO_OK_CTX *)Malloc(sizeof(BIO_OK_CTX)); 190 ctx=(BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX));
188 if (ctx == NULL) return(0); 191 if (ctx == NULL) return(0);
189 192
190 ctx->buf_len=0; 193 ctx->buf_len=0;
@@ -196,6 +199,8 @@ static int ok_new(BIO *bi)
196 ctx->blockout= 0; 199 ctx->blockout= 0;
197 ctx->sigio=1; 200 ctx->sigio=1;
198 201
202 EVP_MD_CTX_init(&ctx->md);
203
199 bi->init=0; 204 bi->init=0;
200 bi->ptr=(char *)ctx; 205 bi->ptr=(char *)ctx;
201 bi->flags=0; 206 bi->flags=0;
@@ -205,8 +210,9 @@ static int ok_new(BIO *bi)
205static int ok_free(BIO *a) 210static int ok_free(BIO *a)
206 { 211 {
207 if (a == NULL) return(0); 212 if (a == NULL) return(0);
213 EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md);
208 memset(a->ptr,0,sizeof(BIO_OK_CTX)); 214 memset(a->ptr,0,sizeof(BIO_OK_CTX));
209 Free(a->ptr); 215 OPENSSL_free(a->ptr);
210 a->ptr=NULL; 216 a->ptr=NULL;
211 a->init=0; 217 a->init=0;
212 a->flags=0; 218 a->flags=0;
@@ -284,7 +290,7 @@ static int ok_read(BIO *b, char *out, int outl)
284 return(ret); 290 return(ret);
285 } 291 }
286 292
287static int ok_write(BIO *b, char *in, int inl) 293static int ok_write(BIO *b, const char *in, int inl)
288 { 294 {
289 int ret=0,n,i; 295 int ret=0,n,i;
290 BIO_OK_CTX *ctx; 296 BIO_OK_CTX *ctx;
@@ -342,7 +348,7 @@ static int ok_write(BIO *b, char *in, int inl)
342 return(ret); 348 return(ret);
343 } 349 }
344 350
345static long ok_ctrl(BIO *b, int cmd, long num, char *ptr) 351static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
346 { 352 {
347 BIO_OK_CTX *ctx; 353 BIO_OK_CTX *ctx;
348 EVP_MD *md; 354 EVP_MD *md;
@@ -350,7 +356,7 @@ static long ok_ctrl(BIO *b, int cmd, long num, char *ptr)
350 long ret=1; 356 long ret=1;
351 int i; 357 int i;
352 358
353 ctx=(BIO_OK_CTX *)b->ptr; 359 ctx=b->ptr;
354 360
355 switch (cmd) 361 switch (cmd)
356 { 362 {
@@ -408,14 +414,14 @@ static long ok_ctrl(BIO *b, int cmd, long num, char *ptr)
408 ret=(long)ctx->cont; 414 ret=(long)ctx->cont;
409 break; 415 break;
410 case BIO_C_SET_MD: 416 case BIO_C_SET_MD:
411 md=(EVP_MD *)ptr; 417 md=ptr;
412 EVP_DigestInit(&(ctx->md),md); 418 EVP_DigestInit_ex(&ctx->md, md, NULL);
413 b->init=1; 419 b->init=1;
414 break; 420 break;
415 case BIO_C_GET_MD: 421 case BIO_C_GET_MD:
416 if (b->init) 422 if (b->init)
417 { 423 {
418 ppmd=(const EVP_MD **)ptr; 424 ppmd=ptr;
419 *ppmd=ctx->md.digest; 425 *ppmd=ctx->md.digest;
420 } 426 }
421 else 427 else
@@ -428,6 +434,20 @@ static long ok_ctrl(BIO *b, int cmd, long num, char *ptr)
428 return(ret); 434 return(ret);
429 } 435 }
430 436
437static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
438 {
439 long ret=1;
440
441 if (b->next_bio == NULL) return(0);
442 switch (cmd)
443 {
444 default:
445 ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
446 break;
447 }
448 return(ret);
449 }
450
431static void longswap(void *_ptr, int len) 451static void longswap(void *_ptr, int len)
432{ 452{
433#ifndef L_ENDIAN 453#ifndef L_ENDIAN
@@ -445,19 +465,22 @@ static void sig_out(BIO* b)
445 BIO_OK_CTX *ctx; 465 BIO_OK_CTX *ctx;
446 EVP_MD_CTX *md; 466 EVP_MD_CTX *md;
447 467
448 ctx=(BIO_OK_CTX *)b->ptr; 468 ctx=b->ptr;
449 md= &(ctx->md); 469 md=&ctx->md;
450 470
451 if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return; 471 if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return;
452 472
453 EVP_DigestInit(md, md->digest); 473 EVP_DigestInit_ex(md, md->digest, NULL);
454 RAND_bytes(&(md->md.base[0]), md->digest->md_size); 474 /* FIXME: there's absolutely no guarantee this makes any sense at all,
455 memcpy(&(ctx->buf[ctx->buf_len]), &(md->md.base[0]), md->digest->md_size); 475 * particularly now EVP_MD_CTX has been restructured.
476 */
477 RAND_pseudo_bytes(md->md_data, md->digest->md_size);
478 memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
456 longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size); 479 longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
457 ctx->buf_len+= md->digest->md_size; 480 ctx->buf_len+= md->digest->md_size;
458 481
459 EVP_DigestUpdate(md, (unsigned char*)WELLKNOWN, strlen(WELLKNOWN)); 482 EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
460 md->digest->final(&(ctx->buf[ctx->buf_len]), &(md->md.base[0])); 483 EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
461 ctx->buf_len+= md->digest->md_size; 484 ctx->buf_len+= md->digest->md_size;
462 ctx->blockout= 1; 485 ctx->blockout= 1;
463 ctx->sigio= 0; 486 ctx->sigio= 0;
@@ -470,18 +493,18 @@ static void sig_in(BIO* b)
470 unsigned char tmp[EVP_MAX_MD_SIZE]; 493 unsigned char tmp[EVP_MAX_MD_SIZE];
471 int ret= 0; 494 int ret= 0;
472 495
473 ctx=(BIO_OK_CTX *)b->ptr; 496 ctx=b->ptr;
474 md= &(ctx->md); 497 md=&ctx->md;
475 498
476 if(ctx->buf_len- ctx->buf_off < 2* md->digest->md_size) return; 499 if(ctx->buf_len- ctx->buf_off < 2* md->digest->md_size) return;
477 500
478 EVP_DigestInit(md, md->digest); 501 EVP_DigestInit_ex(md, md->digest, NULL);
479 memcpy(&(md->md.base[0]), &(ctx->buf[ctx->buf_off]), md->digest->md_size); 502 memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
480 longswap(&(md->md.base[0]), md->digest->md_size); 503 longswap(md->md_data, md->digest->md_size);
481 ctx->buf_off+= md->digest->md_size; 504 ctx->buf_off+= md->digest->md_size;
482 505
483 EVP_DigestUpdate(md, (unsigned char*)WELLKNOWN, strlen(WELLKNOWN)); 506 EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
484 md->digest->final(tmp, &(md->md.base[0])); 507 EVP_DigestFinal_ex(md, tmp, NULL);
485 ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0; 508 ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
486 ctx->buf_off+= md->digest->md_size; 509 ctx->buf_off+= md->digest->md_size;
487 if(ret == 1) 510 if(ret == 1)
@@ -506,15 +529,15 @@ static void block_out(BIO* b)
506 EVP_MD_CTX *md; 529 EVP_MD_CTX *md;
507 unsigned long tl; 530 unsigned long tl;
508 531
509 ctx=(BIO_OK_CTX *)b->ptr; 532 ctx=b->ptr;
510 md= &(ctx->md); 533 md=&ctx->md;
511 534
512 tl= ctx->buf_len- OK_BLOCK_BLOCK; 535 tl= ctx->buf_len- OK_BLOCK_BLOCK;
513 tl= swapem(tl); 536 tl= swapem(tl);
514 memcpy(ctx->buf, &tl, OK_BLOCK_BLOCK); 537 memcpy(ctx->buf, &tl, OK_BLOCK_BLOCK);
515 tl= swapem(tl); 538 tl= swapem(tl);
516 EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl); 539 EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
517 md->digest->final(&(ctx->buf[ctx->buf_len]), &(md->md.base[0])); 540 EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
518 ctx->buf_len+= md->digest->md_size; 541 ctx->buf_len+= md->digest->md_size;
519 ctx->blockout= 1; 542 ctx->blockout= 1;
520 } 543 }
@@ -526,15 +549,15 @@ static void block_in(BIO* b)
526 long tl= 0; 549 long tl= 0;
527 unsigned char tmp[EVP_MAX_MD_SIZE]; 550 unsigned char tmp[EVP_MAX_MD_SIZE];
528 551
529 ctx=(BIO_OK_CTX *)b->ptr; 552 ctx=b->ptr;
530 md= &(ctx->md); 553 md=&ctx->md;
531 554
532 memcpy(&tl, ctx->buf, OK_BLOCK_BLOCK); 555 memcpy(&tl, ctx->buf, OK_BLOCK_BLOCK);
533 tl= swapem(tl); 556 tl= swapem(tl);
534 if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return; 557 if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return;
535 558
536 EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl); 559 EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
537 md->digest->final(tmp, &(md->md.base[0])); 560 EVP_DigestFinal_ex(md, tmp, NULL);
538 if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0) 561 if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0)
539 { 562 {
540 /* there might be parts from next block lurking around ! */ 563 /* there might be parts from next block lurking around ! */