- add sat_chksum_type2str() and sat_chksum_str2type() and use them
[platform/upstream/libsolv.git] / src / chksum.c
1 #include <sys/types.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6
7 #include "pool.h"
8 #include "util.h"
9 #include "chksum.h"
10
11 #include "md5.h"
12 #include "sha1.h"
13 #include "sha2.h"
14
15 struct ctxhandle {
16   Id type;
17   int done;
18   unsigned char result[64];
19   union {
20     MD5_CTX md5;
21     SHA1_CTX sha1;
22     SHA256_CTX sha256;
23   } c;
24 };
25
26 void *
27 sat_chksum_create(Id type)
28 {
29   struct ctxhandle *h;
30   h = sat_calloc(1, sizeof(*h));
31   h->type = type;
32   switch(type)
33     {
34     case REPOKEY_TYPE_MD5:
35       sat_MD5_Init(&h->c.md5);
36       return h;
37     case REPOKEY_TYPE_SHA1:
38       sat_SHA1_Init(&h->c.sha1);
39       return h;
40     case REPOKEY_TYPE_SHA256:
41       sat_SHA256_Init(&h->c.sha256);
42       return h;
43     default:
44       break;
45     }
46   free(h);
47   return 0;
48 }
49
50 void *
51 sat_chksum_create_from_bin(Id type, const unsigned char *buf)
52 {
53   struct ctxhandle *h;
54   int l = sat_chksum_len(type);
55   if (buf == 0 || l == 0)
56     return 0;
57   h = sat_calloc(1, sizeof(*h));
58   h->type = type;
59   h->done = 1;
60   memcpy(h->result, buf, l);
61   return h;
62 }
63
64 void
65 sat_chksum_add(void *handle, const void *data, int len)
66 {
67   struct ctxhandle *h = handle;
68   if (h->done)
69     return;
70   switch(h->type)
71     {
72     case REPOKEY_TYPE_MD5:
73       sat_MD5_Update(&h->c.md5, (void *)data, len);
74       return;
75     case REPOKEY_TYPE_SHA1:
76       sat_SHA1_Update(&h->c.sha1, data, len);
77       return;
78     case REPOKEY_TYPE_SHA256:
79       sat_SHA256_Update(&h->c.sha256, data, len);
80       return;
81     default:
82       return;
83     }
84 }
85
86 const unsigned char *
87 sat_chksum_get(void *handle, int *lenp)
88 {
89   struct ctxhandle *h = handle;
90   if (h->done)
91     {
92       if (lenp)
93         *lenp = sat_chksum_len(h->type);
94       return h->result;
95     }
96   switch(h->type)
97     {
98     case REPOKEY_TYPE_MD5:
99       sat_MD5_Final(h->result, &h->c.md5);
100       h->done = 1;
101       if (lenp)
102         *lenp = 16;
103       return h->result;
104     case REPOKEY_TYPE_SHA1:
105       sat_SHA1_Final(&h->c.sha1, h->result);
106       h->done = 1;
107       if (lenp)
108         *lenp = 20;
109       return h->result;
110     case REPOKEY_TYPE_SHA256:
111       sat_SHA256_Final(h->result, &h->c.sha256);
112       h->done = 1;
113       if (lenp)
114         *lenp = 32;
115       return h->result;
116     default:
117       if (lenp)
118         *lenp = 0;
119       return 0;
120     }
121 }
122
123 Id
124 sat_chksum_get_type(void *handle)
125 {
126   struct ctxhandle *h = handle;
127   return h->type;
128 }
129
130 const char *
131 sat_chksum_type2str(Id type)
132 {
133   switch(type)
134     {
135     case REPOKEY_TYPE_MD5:
136       return "md5";
137     case REPOKEY_TYPE_SHA1:
138       return "sha1";
139     case REPOKEY_TYPE_SHA256:
140       return "sha256";
141     default:
142       return 0;
143     }
144 }
145
146 Id
147 sat_chksum_str2type(const char *str)
148 {
149   if (!strcasecmp(str, "md5"))
150     return REPOKEY_TYPE_MD5;
151   if (!strcasecmp(str, "sha") || !strcasecmp(str, "sha1"))
152     return REPOKEY_TYPE_SHA1;
153   if (!strcasecmp(str, "sha256"))
154     return REPOKEY_TYPE_SHA256;
155   return 0;
156 }
157
158 void *
159 sat_chksum_free(void *handle, unsigned char *cp)
160 {
161   if (cp)
162     {
163       const unsigned char *res;
164       int l;
165       res = sat_chksum_get(handle, &l);
166       if (l && res)
167         memcpy(cp, res, l);
168     }
169   sat_free(handle);
170   return 0;
171 }
172