Merge pull request #41 from dmacvicar/master
[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 _Chksum {
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 Chksum *
34 solv_chksum_create(Id type)
35 {
36   Chksum *chk;
37   chk = solv_calloc(1, sizeof(*chk));
38   chk->type = type;
39   switch(type)
40     {
41     case REPOKEY_TYPE_MD5:
42       solv_MD5_Init(&chk->c.md5);
43       return chk;
44     case REPOKEY_TYPE_SHA1:
45       solv_SHA1_Init(&chk->c.sha1);
46       return chk;
47     case REPOKEY_TYPE_SHA256:
48       solv_SHA256_Init(&chk->c.sha256);
49       return chk;
50     default:
51       break;
52     }
53   free(chk);
54   return 0;
55 }
56
57 Chksum *
58 solv_chksum_create_clone(Chksum *chk)
59 {
60   return solv_memdup(chk, sizeof(*chk));
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 Chksum *
80 solv_chksum_create_from_bin(Id type, const unsigned char *buf)
81 {
82   Chksum *chk;
83   int l = solv_chksum_len(type);
84   if (buf == 0 || l == 0)
85     return 0;
86   chk = solv_calloc(1, sizeof(*chk));
87   chk->type = type;
88   chk->done = 1;
89   memcpy(chk->result, buf, l);
90   return chk;
91 }
92
93 void
94 solv_chksum_add(Chksum *chk, const void *data, int len)
95 {
96   if (chk->done)
97     return;
98   switch(chk->type)
99     {
100     case REPOKEY_TYPE_MD5:
101       solv_MD5_Update(&chk->c.md5, (void *)data, len);
102       return;
103     case REPOKEY_TYPE_SHA1:
104       solv_SHA1_Update(&chk->c.sha1, data, len);
105       return;
106     case REPOKEY_TYPE_SHA256:
107       solv_SHA256_Update(&chk->c.sha256, data, len);
108       return;
109     default:
110       return;
111     }
112 }
113
114 const unsigned char *
115 solv_chksum_get(Chksum *chk, int *lenp)
116 {
117   if (chk->done)
118     {
119       if (lenp)
120         *lenp = solv_chksum_len(chk->type);
121       return chk->result;
122     }
123   switch(chk->type)
124     {
125     case REPOKEY_TYPE_MD5:
126       solv_MD5_Final(chk->result, &chk->c.md5);
127       chk->done = 1;
128       if (lenp)
129         *lenp = 16;
130       return chk->result;
131     case REPOKEY_TYPE_SHA1:
132       solv_SHA1_Final(&chk->c.sha1, chk->result);
133       chk->done = 1;
134       if (lenp)
135         *lenp = 20;
136       return chk->result;
137     case REPOKEY_TYPE_SHA256:
138       solv_SHA256_Final(chk->result, &chk->c.sha256);
139       chk->done = 1;
140       if (lenp)
141         *lenp = 32;
142       return chk->result;
143     default:
144       if (lenp)
145         *lenp = 0;
146       return 0;
147     }
148 }
149
150 Id
151 solv_chksum_get_type(Chksum *chk)
152 {
153   return chk->type;
154 }
155
156 int
157 solv_chksum_isfinished(Chksum *chk)
158 {
159   return chk->done != 0;
160 }
161
162 const char *
163 solv_chksum_type2str(Id type)
164 {
165   switch(type)
166     {
167     case REPOKEY_TYPE_MD5:
168       return "md5";
169     case REPOKEY_TYPE_SHA1:
170       return "sha1";
171     case REPOKEY_TYPE_SHA256:
172       return "sha256";
173     default:
174       return 0;
175     }
176 }
177
178 Id
179 solv_chksum_str2type(const char *str)
180 {
181   if (!strcasecmp(str, "md5"))
182     return REPOKEY_TYPE_MD5;
183   if (!strcasecmp(str, "sha") || !strcasecmp(str, "sha1"))
184     return REPOKEY_TYPE_SHA1;
185   if (!strcasecmp(str, "sha256"))
186     return REPOKEY_TYPE_SHA256;
187   return 0;
188 }
189
190 void *
191 solv_chksum_free(Chksum *chk, unsigned char *cp)
192 {
193   if (cp)
194     {
195       const unsigned char *res;
196       int l;
197       res = solv_chksum_get(chk, &l);
198       if (l && res)
199         memcpy(cp, res, l);
200     }
201   solv_free(chk);
202   return 0;
203 }
204