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