/src/wget/lib/sha1-stream.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* sha1.c - Functions to compute SHA1 message digest of files or |
2 | | memory blocks according to the NIST specification FIPS-180-1. |
3 | | |
4 | | Copyright (C) 2000-2001, 2003-2006, 2008-2023 Free Software Foundation, Inc. |
5 | | |
6 | | This file is free software: you can redistribute it and/or modify |
7 | | it under the terms of the GNU Lesser General Public License as |
8 | | published by the Free Software Foundation; either version 2.1 of the |
9 | | License, or (at your option) any later version. |
10 | | |
11 | | This file is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU Lesser General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU Lesser General Public License |
17 | | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
18 | | |
19 | | /* Written by Scott G. Miller |
20 | | Credits: |
21 | | Robert Klep <robert@ilse.nl> -- Expansion function fix |
22 | | */ |
23 | | |
24 | | #include <config.h> |
25 | | |
26 | | /* Specification. */ |
27 | | #if HAVE_OPENSSL_SHA1 |
28 | | # define GL_OPENSSL_INLINE _GL_EXTERN_INLINE |
29 | | #endif |
30 | | #include "sha1.h" |
31 | | |
32 | | #include <stdlib.h> |
33 | | |
34 | | #if USE_UNLOCKED_IO |
35 | | # include "unlocked-io.h" |
36 | | #endif |
37 | | |
38 | | #include "af_alg.h" |
39 | | |
40 | 0 | #define BLOCKSIZE 32768 |
41 | | #if BLOCKSIZE % 64 != 0 |
42 | | # error "invalid BLOCKSIZE" |
43 | | #endif |
44 | | |
45 | | /* Compute SHA1 message digest for bytes read from STREAM. The |
46 | | resulting message digest number will be written into the 20 bytes |
47 | | beginning at RESBLOCK. */ |
48 | | int |
49 | | sha1_stream (FILE *stream, void *resblock) |
50 | 0 | { |
51 | 0 | switch (afalg_stream (stream, "sha1", resblock, SHA1_DIGEST_SIZE)) |
52 | 0 | { |
53 | 0 | case 0: return 0; |
54 | 0 | case -EIO: return 1; |
55 | 0 | } |
56 | | |
57 | 0 | char *buffer = malloc (BLOCKSIZE + 72); |
58 | 0 | if (!buffer) |
59 | 0 | return 1; |
60 | | |
61 | 0 | struct sha1_ctx ctx; |
62 | 0 | sha1_init_ctx (&ctx); |
63 | 0 | size_t sum; |
64 | | |
65 | | /* Iterate over full file contents. */ |
66 | 0 | while (1) |
67 | 0 | { |
68 | | /* We read the file in blocks of BLOCKSIZE bytes. One call of the |
69 | | computation function processes the whole buffer so that with the |
70 | | next round of the loop another block can be read. */ |
71 | 0 | size_t n; |
72 | 0 | sum = 0; |
73 | | |
74 | | /* Read block. Take care for partial reads. */ |
75 | 0 | while (1) |
76 | 0 | { |
77 | | /* Either process a partial fread() from this loop, |
78 | | or the fread() in afalg_stream may have gotten EOF. |
79 | | We need to avoid a subsequent fread() as EOF may |
80 | | not be sticky. For details of such systems, see: |
81 | | https://sourceware.org/bugzilla/show_bug.cgi?id=1190 */ |
82 | 0 | if (feof (stream)) |
83 | 0 | goto process_partial_block; |
84 | | |
85 | 0 | n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); |
86 | |
|
87 | 0 | sum += n; |
88 | |
|
89 | 0 | if (sum == BLOCKSIZE) |
90 | 0 | break; |
91 | | |
92 | 0 | if (n == 0) |
93 | 0 | { |
94 | | /* Check for the error flag IFF N == 0, so that we don't |
95 | | exit the loop after a partial read due to e.g., EAGAIN |
96 | | or EWOULDBLOCK. */ |
97 | 0 | if (ferror (stream)) |
98 | 0 | { |
99 | 0 | free (buffer); |
100 | 0 | return 1; |
101 | 0 | } |
102 | 0 | goto process_partial_block; |
103 | 0 | } |
104 | 0 | } |
105 | | |
106 | | /* Process buffer with BLOCKSIZE bytes. Note that |
107 | | BLOCKSIZE % 64 == 0 |
108 | | */ |
109 | 0 | sha1_process_block (buffer, BLOCKSIZE, &ctx); |
110 | 0 | } |
111 | | |
112 | 0 | process_partial_block:; |
113 | | |
114 | | /* Process any remaining bytes. */ |
115 | 0 | if (sum > 0) |
116 | 0 | sha1_process_bytes (buffer, sum, &ctx); |
117 | | |
118 | | /* Construct result in desired memory. */ |
119 | 0 | sha1_finish_ctx (&ctx, resblock); |
120 | 0 | free (buffer); |
121 | 0 | return 0; |
122 | 0 | } |
123 | | |
124 | | /* |
125 | | * Hey Emacs! |
126 | | * Local Variables: |
127 | | * coding: utf-8 |
128 | | * End: |
129 | | */ |