diff options
Diffstat (limited to 'src/lib/libcrypto/evp/bio_ok.c')
-rw-r--r-- | src/lib/libcrypto/evp/bio_ok.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/lib/libcrypto/evp/bio_ok.c b/src/lib/libcrypto/evp/bio_ok.c index 101275d648..e6ff5f2cdb 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. |
@@ -130,6 +130,8 @@ 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,char *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,void (*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); |
@@ -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) |
@@ -428,6 +431,20 @@ static long ok_ctrl(BIO *b, int cmd, long num, char *ptr) | |||
428 | return(ret); | 431 | return(ret); |
429 | } | 432 | } |
430 | 433 | ||
434 | static long ok_callback_ctrl(BIO *b, int cmd, void (*fp)()) | ||
435 | { | ||
436 | long ret=1; | ||
437 | |||
438 | if (b->next_bio == NULL) return(0); | ||
439 | switch (cmd) | ||
440 | { | ||
441 | default: | ||
442 | ret=BIO_callback_ctrl(b->next_bio,cmd,fp); | ||
443 | break; | ||
444 | } | ||
445 | return(ret); | ||
446 | } | ||
447 | |||
431 | static void longswap(void *_ptr, int len) | 448 | static void longswap(void *_ptr, int len) |
432 | { | 449 | { |
433 | #ifndef L_ENDIAN | 450 | #ifndef L_ENDIAN |
@@ -451,12 +468,12 @@ static void sig_out(BIO* b) | |||
451 | if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return; | 468 | if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return; |
452 | 469 | ||
453 | EVP_DigestInit(md, md->digest); | 470 | EVP_DigestInit(md, md->digest); |
454 | RAND_bytes(&(md->md.base[0]), md->digest->md_size); | 471 | RAND_pseudo_bytes(&(md->md.base[0]), md->digest->md_size); |
455 | memcpy(&(ctx->buf[ctx->buf_len]), &(md->md.base[0]), md->digest->md_size); | 472 | memcpy(&(ctx->buf[ctx->buf_len]), &(md->md.base[0]), md->digest->md_size); |
456 | longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size); | 473 | longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size); |
457 | ctx->buf_len+= md->digest->md_size; | 474 | ctx->buf_len+= md->digest->md_size; |
458 | 475 | ||
459 | EVP_DigestUpdate(md, (unsigned char*)WELLKNOWN, strlen(WELLKNOWN)); | 476 | EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)); |
460 | md->digest->final(&(ctx->buf[ctx->buf_len]), &(md->md.base[0])); | 477 | md->digest->final(&(ctx->buf[ctx->buf_len]), &(md->md.base[0])); |
461 | ctx->buf_len+= md->digest->md_size; | 478 | ctx->buf_len+= md->digest->md_size; |
462 | ctx->blockout= 1; | 479 | ctx->blockout= 1; |
@@ -480,7 +497,7 @@ static void sig_in(BIO* b) | |||
480 | longswap(&(md->md.base[0]), md->digest->md_size); | 497 | longswap(&(md->md.base[0]), md->digest->md_size); |
481 | ctx->buf_off+= md->digest->md_size; | 498 | ctx->buf_off+= md->digest->md_size; |
482 | 499 | ||
483 | EVP_DigestUpdate(md, (unsigned char*)WELLKNOWN, strlen(WELLKNOWN)); | 500 | EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)); |
484 | md->digest->final(tmp, &(md->md.base[0])); | 501 | md->digest->final(tmp, &(md->md.base[0])); |
485 | ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0; | 502 | ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0; |
486 | ctx->buf_off+= md->digest->md_size; | 503 | ctx->buf_off+= md->digest->md_size; |