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