also save/restore pool pos in repodata load callback
[platform/upstream/libsolv.git] / src / chksum.c
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 *
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 void *
58 solv_chksum_create_clone(void *handle)
59 {
60   return solv_memdup(handle, sizeof(struct ctxhandle));
61 }
62
63 int
64 solv_chksum_len(Id type)
65 {
66   switch (type)
67     {   
68     case REPOKEY_TYPE_MD5:
69       return 16; 
70     case REPOKEY_TYPE_SHA1:
71       return 20; 
72     case REPOKEY_TYPE_SHA256:
73       return 32; 
74     default:
75       return 0;
76     }   
77 }
78
79 void *
80 solv_chksum_create_from_bin(Id type, const unsigned char *buf)
81 {
82   struct ctxhandle *h;
83   int l = solv_chksum_len(type);
84   if (buf == 0 || l == 0)
85     return 0;
86   h = solv_calloc(1, sizeof(*h));
87   h->type = type;
88   h->done = 1;
89   memcpy(h->result, buf, l);
90   return h;
91 }
92
93 void
94 solv_chksum_add(void *handle, const void *data, int len)
95 {
96   struct ctxhandle *h = handle;
97   if (h->done)
98     return;
99   switch(h->type)
100     {
101     case REPOKEY_TYPE_MD5:
102       solv_MD5_Update(&h->c.md5, (void *)data, len);
103       return;
104     case REPOKEY_TYPE_SHA1:
105       solv_SHA1_Update(&h->c.sha1, data, len);
106       return;
107     case REPOKEY_TYPE_SHA256:
108       solv_SHA256_Update(&h->c.sha256, data, len);
109       return;
110     default:
111       return;
112     }
113 }
114
115 const unsigned char *
116 solv_chksum_get(void *handle, int *lenp)
117 {
118   struct ctxhandle *h = handle;
119   if (h->done)
120     {
121       if (lenp)
122         *lenp = solv_chksum_len(h->type);
123       return h->result;
124     }
125   switch(h->type)
126     {
127     case REPOKEY_TYPE_MD5:
128       solv_MD5_Final(h->result, &h->c.md5);
129       h->done = 1;
130       if (lenp)
131         *lenp = 16;
132       return h->result;
133     case REPOKEY_TYPE_SHA1:
134       solv_SHA1_Final(&h->c.sha1, h->result);
135       h->done = 1;
136       if (lenp)
137         *lenp = 20;
138       return h->result;
139     case REPOKEY_TYPE_SHA256:
140       solv_SHA256_Final(h->result, &h->c.sha256);
141       h->done = 1;
142       if (lenp)
143         *lenp = 32;
144       return h->result;
145     default:
146       if (lenp)
147         *lenp = 0;
148       return 0;
149     }
150 }
151
152 Id
153 solv_chksum_get_type(void *handle)
154 {
155   struct ctxhandle *h = handle;
156   return h->type;
157 }
158
159 int
160 solv_chksum_isfinished(void *handle)
161 {
162   struct ctxhandle *h = handle;
163   return h->done != 0;
164 }
165
166 const char *
167 solv_chksum_type2str(Id type)
168 {
169   switch(type)
170     {
171     case REPOKEY_TYPE_MD5:
172       return "md5";
173     case REPOKEY_TYPE_SHA1:
174       return "sha1";
175     case REPOKEY_TYPE_SHA256:
176       return "sha256";
177     default:
178       return 0;
179     }
180 }
181
182 Id
183 solv_chksum_str2type(const char *str)
184 {
185   if (!strcasecmp(str, "md5"))
186     return REPOKEY_TYPE_MD5;
187   if (!strcasecmp(str, "sha") || !strcasecmp(str, "sha1"))
188     return REPOKEY_TYPE_SHA1;
189   if (!strcasecmp(str, "sha256"))
190     return REPOKEY_TYPE_SHA256;
191   return 0;
192 }
193
194 void *
195 solv_chksum_free(void *handle, unsigned char *cp)
196 {
197   if (cp)
198     {
199       const unsigned char *res;
200       int l;
201       res = solv_chksum_get(handle, &l);
202       if (l && res)
203         memcpy(cp, res, l);
204     }
205   solv_free(handle);
206   return 0;
207 }
208