1 /*
2 * Copyright (c) 2008-2012, Novell Inc.
3 *
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
6 */
7
8 #include <sys/types.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13
14 #include "pool.h"
15 #include "util.h"
16 #include "chksum.h"
17
18 #include "md5.h"
19 #include "sha1.h"
20 #include "sha2.h"
21
22 struct ctxhandle {
23 Id type;
24 int done;
25 unsigned char result[64];
26 union {
27 MD5_CTX md5;
28 SHA1_CTX sha1;
29 SHA256_CTX sha256;
30 } c;
31 };
32
33 void *
solv_chksum_create(Id type)34 solv_chksum_create(Id type)
35 {
36 struct ctxhandle *h;
37 h = solv_calloc(1, sizeof(*h));
38 h->type = type;
39 switch(type)
40 {
41 case REPOKEY_TYPE_MD5:
42 solv_MD5_Init(&h->c.md5);
43 return h;
44 case REPOKEY_TYPE_SHA1:
45 solv_SHA1_Init(&h->c.sha1);
46 return h;
47 case REPOKEY_TYPE_SHA256:
48 solv_SHA256_Init(&h->c.sha256);
49 return h;
50 default:
51 break;
52 }
53 free(h);
54 return 0;
55 }
56
57 int
solv_chksum_len(Id type)58 solv_chksum_len(Id type)
59 {
60 switch (type)
61 {
62 case REPOKEY_TYPE_MD5:
63 return 16;
64 case REPOKEY_TYPE_SHA1:
65 return 20;
66 case REPOKEY_TYPE_SHA256:
67 return 32;
68 default:
69 return 0;
70 }
71 }
72
73 void *
solv_chksum_create_from_bin(Id type,const unsigned char * buf)74 solv_chksum_create_from_bin(Id type, const unsigned char *buf)
75 {
76 struct ctxhandle *h;
77 int l = solv_chksum_len(type);
78 if (buf == 0 || l == 0)
79 return 0;
80 h = solv_calloc(1, sizeof(*h));
81 h->type = type;
82 h->done = 1;
83 memcpy(h->result, buf, l);
84 return h;
85 }
86
87 void
solv_chksum_add(void * handle,const void * data,int len)88 solv_chksum_add(void *handle, const void *data, int len)
89 {
90 struct ctxhandle *h = handle;
91 if (h->done)
92 return;
93 switch(h->type)
94 {
95 case REPOKEY_TYPE_MD5:
96 solv_MD5_Update(&h->c.md5, (void *)data, len);
97 return;
98 case REPOKEY_TYPE_SHA1:
99 solv_SHA1_Update(&h->c.sha1, data, len);
100 return;
101 case REPOKEY_TYPE_SHA256:
102 solv_SHA256_Update(&h->c.sha256, data, len);
103 return;
104 default:
105 return;
106 }
107 }
108
109 const unsigned char *
solv_chksum_get(void * handle,int * lenp)110 solv_chksum_get(void *handle, int *lenp)
111 {
112 struct ctxhandle *h = handle;
113 if (h->done)
114 {
115 if (lenp)
116 *lenp = solv_chksum_len(h->type);
117 return h->result;
118 }
119 switch(h->type)
120 {
121 case REPOKEY_TYPE_MD5:
122 solv_MD5_Final(h->result, &h->c.md5);
123 h->done = 1;
124 if (lenp)
125 *lenp = 16;
126 return h->result;
127 case REPOKEY_TYPE_SHA1:
128 solv_SHA1_Final(&h->c.sha1, h->result);
129 h->done = 1;
130 if (lenp)
131 *lenp = 20;
132 return h->result;
133 case REPOKEY_TYPE_SHA256:
134 solv_SHA256_Final(h->result, &h->c.sha256);
135 h->done = 1;
136 if (lenp)
137 *lenp = 32;
138 return h->result;
139 default:
140 if (lenp)
141 *lenp = 0;
142 return 0;
143 }
144 }
145
146 Id
solv_chksum_get_type(void * handle)147 solv_chksum_get_type(void *handle)
148 {
149 struct ctxhandle *h = handle;
150 return h->type;
151 }
152
153 int
solv_chksum_isfinished(void * handle)154 solv_chksum_isfinished(void *handle)
155 {
156 struct ctxhandle *h = handle;
157 return h->done != 0;
158 }
159
160 const char *
solv_chksum_type2str(Id type)161 solv_chksum_type2str(Id type)
162 {
163 switch(type)
164 {
165 case REPOKEY_TYPE_MD5:
166 return "md5";
167 case REPOKEY_TYPE_SHA1:
168 return "sha1";
169 case REPOKEY_TYPE_SHA256:
170 return "sha256";
171 default:
172 return 0;
173 }
174 }
175
176 Id
solv_chksum_str2type(const char * str)177 solv_chksum_str2type(const char *str)
178 {
179 if (!strcasecmp(str, "md5"))
180 return REPOKEY_TYPE_MD5;
181 if (!strcasecmp(str, "sha") || !strcasecmp(str, "sha1"))
182 return REPOKEY_TYPE_SHA1;
183 if (!strcasecmp(str, "sha256"))
184 return REPOKEY_TYPE_SHA256;
185 return 0;
186 }
187
188 void *
solv_chksum_free(void * handle,unsigned char * cp)189 solv_chksum_free(void *handle, unsigned char *cp)
190 {
191 if (cp)
192 {
193 const unsigned char *res;
194 int l;
195 res = solv_chksum_get(handle, &l);
196 if (l && res)
197 memcpy(cp, res, l);
198 }
199 solv_free(handle);
200 return 0;
201 }
202
203