new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / os_crypto / md5_sha1 / md5_sha1_op.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12
13 #include "md5_sha1_op.h"
14 #include "../md5/md5.h"
15 #include "../sha1/sha.h"
16 #include "headers/defs.h"
17
18
19 int OS_MD5_SHA1_File(const char *fname, const char *prefilter_cmd, os_md5 md5output, os_sha1 sha1output, int mode)
20 {
21     size_t n;
22     FILE *fp;
23     unsigned char buf[2048 + 2];
24     unsigned char sha1_digest[SHA_DIGEST_LENGTH];
25     unsigned char md5_digest[16];
26
27     SHA_CTX sha1_ctx;
28     MD5_CTX md5_ctx;
29
30     /* Clear the memory */
31     md5output[0] = '\0';
32     sha1output[0] = '\0';
33     buf[2048 + 1] = '\0';
34
35     /* Use prefilter_cmd if set */
36     if (prefilter_cmd == NULL) {
37         fp = fopen(fname, mode == OS_BINARY ? "rb" : "r");
38         if (!fp) {
39             return (-1);
40         }
41     } else {
42         char cmd[OS_MAXSTR];
43         size_t target_length = strlen(prefilter_cmd) + 1 + strlen(fname);
44         int res = snprintf(cmd, sizeof(cmd), "%s %s", prefilter_cmd, fname);
45         if (res < 0 || (unsigned int)res != target_length) {
46             return (-1);
47         }
48         fp = popen(cmd, "r");
49         if (!fp) {
50             return (-1);
51         }
52     }
53
54     /* Initialize both hashes */
55     MD5Init(&md5_ctx);
56     SHA1_Init(&sha1_ctx);
57
58     /* Update for each one */
59     while ((n = fread(buf, 1, 2048, fp)) > 0) {
60         buf[n] = '\0';
61         SHA1_Update(&sha1_ctx, buf, n);
62         MD5Update(&md5_ctx, buf, (unsigned)n);
63     }
64
65     SHA1_Final(&(sha1_digest[0]), &sha1_ctx);
66     MD5Final(md5_digest, &md5_ctx);
67
68     /* Set output for MD5 */
69     for (n = 0; n < 16; n++) {
70         snprintf(md5output, 3, "%02x", md5_digest[n]);
71         md5output += 2;
72     }
73
74     /* Set output for SHA-1 */
75     for (n = 0; n < SHA_DIGEST_LENGTH; n++) {
76         snprintf(sha1output, 3, "%02x", sha1_digest[n]);
77         sha1output += 2;
78     }
79
80     /* Close it */
81     if (prefilter_cmd == NULL) {
82         fclose(fp);
83     } else {
84         pclose(fp);
85     }
86
87     return (0);
88 }