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 int 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 * 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 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 * 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 147 solv_chksum_get_type(void *handle) 148 { 149 struct ctxhandle *h = handle; 150 return h->type; 151 } 152 153 int 154 solv_chksum_isfinished(void *handle) 155 { 156 struct ctxhandle *h = handle; 157 return h->done != 0; 158 } 159 160 const char * 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 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 * 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