diff options
Diffstat (limited to 'src/lib/libcrypto/evp/bio_ok.c')
-rw-r--r-- | src/lib/libcrypto/evp/bio_ok.c | 97 |
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 | ||
128 | static int ok_write(BIO *h,char *buf,int num); | 128 | static int ok_write(BIO *h, const char *buf, int num); |
129 | static int ok_read(BIO *h,char *buf,int size); | 129 | static int ok_read(BIO *h, char *buf, int size); |
130 | static long ok_ctrl(BIO *h,int cmd,long arg1,char *arg2); | 130 | static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2); |
131 | static int ok_new(BIO *h); | 131 | static int ok_new(BIO *h); |
132 | static int ok_free(BIO *data); | 132 | static int ok_free(BIO *data); |
133 | static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); | ||
134 | |||
133 | static void sig_out(BIO* b); | 135 | static void sig_out(BIO* b); |
134 | static void sig_in(BIO* b); | 136 | static void sig_in(BIO* b); |
135 | static void block_out(BIO* b); | 137 | static 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 | ||
166 | static BIO_METHOD methods_ok= | 168 | static 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 | ||
178 | BIO_METHOD *BIO_f_reliable(void) | 181 | BIO_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) | |||
205 | static int ok_free(BIO *a) | 210 | static 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 | ||
287 | static int ok_write(BIO *b, char *in, int inl) | 293 | static 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 | ||
345 | static long ok_ctrl(BIO *b, int cmd, long num, char *ptr) | 351 | static 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 | ||
437 | static 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 | |||
431 | static void longswap(void *_ptr, int len) | 451 | static 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 ! */ |