1 /* compat.c - Various compatibility functions
2 * Copyright 2011, 2012 Gergely Nagy <algernon@balabit.hu>
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "config.h"
18
19 #if WITH_OPENSSL
20
21 #include "compat.h"
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <openssl/md5.h>
26
27 struct _GChecksum
28 {
29 GChecksumType type;
30 char hex_digest[33];
31
32 MD5_CTX context;
33 };
34
35 GChecksum *
g_checksum_new(GChecksumType checksum_type)36 g_checksum_new (GChecksumType checksum_type)
37 {
38 GChecksum *chk;
39
40 if (checksum_type != G_CHECKSUM_MD5)
41 {
42 errno = ENOSYS;
43 return NULL;
44 }
45
46 chk = calloc (1, sizeof (GChecksum));
47 chk->type = checksum_type;
48
49 MD5_Init (&chk->context);
50
51 return chk;
52 }
53
54 void
g_checksum_free(GChecksum * checksum)55 g_checksum_free (GChecksum *checksum)
56 {
57 if (checksum)
58 free (checksum);
59 }
60
61 void
g_checksum_update(GChecksum * checksum,const unsigned char * data,ssize_t length)62 g_checksum_update (GChecksum *checksum,
63 const unsigned char *data,
64 ssize_t length)
65 {
66 size_t l = length;
67
68 if (!checksum || !data || length == 0)
69 {
70 errno = EINVAL;
71 return;
72 }
73 errno = 0;
74
75 if (length < 0)
76 l = strlen ((const char *)data);
77
78 MD5_Update (&checksum->context, (const void *)data, l);
79 }
80
81 const char *
g_checksum_get_string(GChecksum * checksum)82 g_checksum_get_string (GChecksum *checksum)
83 {
84 unsigned char digest[16];
85 static const char hex[16] =
86 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
87 'a', 'b', 'c', 'd', 'e', 'f'};
88 int i;
89
90 if (!checksum)
91 {
92 errno = EINVAL;
93 return NULL;
94 }
95
96 MD5_Final (digest, &checksum->context);
97
98 for (i = 0; i < 16; i++)
99 {
100 checksum->hex_digest[2 * i] = hex[(digest[i] & 0xf0) >> 4];
101 checksum->hex_digest[2 * i + 1] = hex[digest[i] & 0x0f];
102 }
103 checksum->hex_digest[32] = '\0';
104
105 return checksum->hex_digest;
106 }
107
108 #endif /* WITH_OPENSSL */
109