1 /*----------------------------------------------------------------------------*/
2 /* Xymon monitor library. */
3 /* */
4 /* This is used to implement message digest functions (MD5, SHA1 etc.) */
5 /* */
6 /* Copyright (C) 2003-2011 Henrik Storner <henrik@hswn.dk> */
7 /* */
8 /* This program is released under the GNU General Public License (GPL), */
9 /* version 2. See the file "COPYING" for details. */
10 /* */
11 /*----------------------------------------------------------------------------*/
12
13 static char rcsid[] = "$Id: digest.c 8069 2019-07-23 15:29:06Z jccleaver $";
14
15 #include <sys/types.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19
20 #include "libxymon.h"
21
md5hash(char * input)22 char *md5hash(char *input)
23 {
24 /* We have a fast MD5 hash function, since that may be used a lot */
25
26 static struct digestctx_t *ctx = NULL;
27 unsigned char md_value[16];
28 static char md_string[2*16+1];
29 int i;
30 char *p;
31
32 if (!ctx) {
33 ctx = (digestctx_t *) malloc(sizeof(digestctx_t));
34 ctx->digestname = strdup("md5");
35 ctx->digesttype = D_MD5;
36 ctx->mdctx = (void *)malloc(myMD5_Size());
37 }
38
39 myMD5_Init(ctx->mdctx);
40 myMD5_Update(ctx->mdctx, input, strlen(input));
41 myMD5_Final(md_value, ctx->mdctx);
42
43 for(i = 0, p = md_string; (i < sizeof(md_value)); i++)
44 p += snprintf(p, (sizeof(md_string) - (md_string - p)), "%02x", md_value[i]);
45 *p = '\0';
46
47 return md_string;
48 }
49
50
digest_init(char * digest)51 digestctx_t *digest_init(char *digest)
52 {
53 struct digestctx_t *ctx = NULL;
54
55 if (strcmp(digest, "md5") == 0) {
56 /* Use the built in MD5 routines */
57 ctx = (digestctx_t *) malloc(sizeof(digestctx_t));
58 ctx->digestname = strdup(digest);
59 ctx->digesttype = D_MD5;
60 ctx->mdctx = (void *)malloc(myMD5_Size());
61 myMD5_Init(ctx->mdctx);
62 }
63 else if (strcmp(digest, "sha1") == 0) {
64 /* Use the built in SHA1 routines */
65 ctx = (digestctx_t *) malloc(sizeof(digestctx_t));
66 ctx->digestname = strdup(digest);
67 ctx->digesttype = D_SHA1;
68 ctx->mdctx = (void *)malloc(mySHA1_Size());
69 mySHA1_Init(ctx->mdctx);
70 }
71 else if (strcmp(digest, "rmd160") == 0) {
72 /* Use the built in RMD160 routines */
73 ctx = (digestctx_t *) malloc(sizeof(digestctx_t));
74 ctx->digestname = strdup(digest);
75 ctx->digesttype = D_RMD160;
76 ctx->mdctx = (void *)malloc(myRIPEMD160_Size());
77 myRIPEMD160_Init(ctx->mdctx);
78 }
79 else if (strcmp(digest, "sha512") == 0) {
80 /* Use the built in SHA-512 routines */
81 ctx = (digestctx_t *) malloc(sizeof(digestctx_t));
82 ctx->digestname = strdup(digest);
83 ctx->digesttype = D_SHA512;
84 ctx->mdctx = (void *)malloc(mySHA512_Size());
85 mySHA512_Init(ctx->mdctx);
86 }
87 else if (strcmp(digest, "sha256") == 0) {
88 /* Use the built in SHA-256 routines */
89 ctx = (digestctx_t *) malloc(sizeof(digestctx_t));
90 ctx->digestname = strdup(digest);
91 ctx->digesttype = D_SHA256;
92 ctx->mdctx = (void *)malloc(mySHA256_Size());
93 mySHA256_Init(ctx->mdctx);
94 }
95 else if (strcmp(digest, "sha224") == 0) {
96 /* Use the built in SHA-224 routines */
97 ctx = (digestctx_t *) malloc(sizeof(digestctx_t));
98 ctx->digestname = strdup(digest);
99 ctx->digesttype = D_SHA224;
100 ctx->mdctx = (void *)malloc(mySHA224_Size());
101 mySHA224_Init(ctx->mdctx);
102 }
103 else if (strcmp(digest, "sha384") == 0) {
104 /* Use the built in SHA-384 routines */
105 ctx = (digestctx_t *) malloc(sizeof(digestctx_t));
106 ctx->digestname = strdup(digest);
107 ctx->digesttype = D_SHA384;
108 ctx->mdctx = (void *)malloc(mySHA384_Size());
109 mySHA384_Init(ctx->mdctx);
110 }
111 else {
112 errprintf("digest_init failure: Cannot handle digest %s\n", digest);
113 return NULL;
114 }
115
116 return ctx;
117 }
118
119
digest_data(digestctx_t * ctx,unsigned char * buf,int buflen)120 int digest_data(digestctx_t *ctx, unsigned char *buf, int buflen)
121 {
122 switch (ctx->digesttype) {
123 case D_MD5:
124 myMD5_Update(ctx->mdctx, buf, buflen);
125 break;
126 case D_SHA1:
127 mySHA1_Update(ctx->mdctx, buf, buflen);
128 break;
129 case D_RMD160:
130 myRIPEMD160_Update(ctx->mdctx, buf, buflen);
131 break;
132 case D_SHA512:
133 mySHA512_Update(ctx->mdctx, buf, buflen);
134 break;
135 case D_SHA256:
136 mySHA256_Update(ctx->mdctx, buf, buflen);
137 break;
138 case D_SHA384:
139 mySHA384_Update(ctx->mdctx, buf, buflen);
140 break;
141 case D_SHA224:
142 mySHA224_Update(ctx->mdctx, buf, buflen);
143 break;
144 }
145
146 return 0;
147 }
148
149
digest_done(digestctx_t * ctx)150 char *digest_done(digestctx_t *ctx)
151 {
152 unsigned int md_len = 0;
153 unsigned char *md_value = NULL;
154 SBUF_DEFINE(md_string);
155 int i;
156 char *p;
157
158 switch (ctx->digesttype) {
159 case D_MD5:
160 /* Built in MD5 hash */
161 md_len = 16;
162 md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char));
163 SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char));
164 myMD5_Final(md_value, ctx->mdctx);
165 break;
166 case D_SHA1:
167 /* Built in SHA1 hash */
168 md_len = 20;
169 md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char));
170 SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char));
171 mySHA1_Final(md_value, ctx->mdctx);
172 break;
173 case D_RMD160:
174 /* Built in RMD160 hash */
175 md_len = 20;
176 md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char));
177 SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char));
178 myRIPEMD160_Final(md_value, ctx->mdctx);
179 break;
180 case D_SHA512:
181 /* Built in SHA-512 hash */
182 md_len = (512/8);
183 md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char));
184 SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char));
185 mySHA512_Final(md_value, ctx->mdctx);
186 break;
187 case D_SHA256:
188 /* Built in SHA-256 hash */
189 md_len = (256/8);
190 md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char));
191 SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char));
192 mySHA256_Final(md_value, ctx->mdctx);
193 break;
194 case D_SHA384:
195 /* Built in SHA-384 hash */
196 md_len = (384/8);
197 md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char));
198 SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char));
199 mySHA384_Final(md_value, ctx->mdctx);
200 break;
201 case D_SHA224:
202 /* Built in SHA-224 hash */
203 md_len = (224/8);
204 md_value = (unsigned char *)malloc(md_len*sizeof(unsigned char));
205 SBUF_MALLOC(md_string, (2*md_len + strlen(ctx->digestname) + 2)*sizeof(char));
206 mySHA224_Final(md_value, ctx->mdctx);
207 break;
208 }
209
210 snprintf(md_string, md_string_buflen, "%s:", ctx->digestname);
211 for(i = 0, p = md_string + strlen(md_string); (i < md_len); i++) p += snprintf(p, (md_string_buflen - (p - md_string)), "%02x", md_value[i]);
212 *p = '\0';
213
214 xfree(md_value);
215 xfree(ctx->digestname);
216 xfree(ctx->mdctx);
217 xfree(ctx);
218
219 return md_string;
220 }
221
222