~ubuntu-branches/ubuntu/saucy/clamav/saucy-backports

« back to all changes in this revision

Viewing changes to libclamav/conv.c

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2014-07-15 01:08:10 UTC
  • mfrom: (0.35.47 sid)
  • Revision ID: package-import@ubuntu.com-20140715010810-ru66ek4fun2iseba
Tags: 0.98.4+dfsg-2~ubuntu13.10.1
No-change backport to saucy (LP: #1341962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
 
3
 *
 
4
 *  Author: Shawn Webb
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License version 2 as
 
8
 *  published by the Free Software Foundation.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
18
 *  MA 02110-1301, USA.
 
19
 */
 
20
 
 
21
#if HAVE_CONF_H
 
22
#include "clamav-config.h"
 
23
#endif
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
 
 
29
#ifdef HAVE_UNISTD_H
 
30
#include <unistd.h>
 
31
#endif
 
32
 
 
33
#include <math.h>
 
34
 
 
35
#include <sys/types.h>
 
36
 
 
37
#include <openssl/bio.h>
 
38
#include <openssl/evp.h>
 
39
 
 
40
#include "libclamav/conv.h"
 
41
#include "libclamav/crypto.h"
 
42
 
 
43
/** Get the expected decoded length of a base64-encoded string
 
44
 * @param[in] data Base64-encoded string
 
45
 * @param[in] len length of the string
 
46
 * @return The expected decoded length of the base64-encoded string
 
47
 */
 
48
static size_t base64_len(const char *data, size_t len)
 
49
{
 
50
    int padding=0;
 
51
    size_t i;
 
52
 
 
53
    if (!len)
 
54
        return 0;
 
55
 
 
56
    for (i=len-1; i > 0 && data[i] == '='; i--)
 
57
        padding++;
 
58
 
 
59
    return (size_t)((3*len)/4 - padding);
 
60
}
 
61
 
 
62
/** Decode a base64-encoded string
 
63
 * @param[in] data The base64-encoded string
 
64
 * @param[in] len Length of the base64-encoded string
 
65
 * @param[out] obuf If obuf is not set to NULL, store the decoded data in obuf. Otherwise, the decoded data is stored in a dynamically-allocated buffer.
 
66
 * @param[out] olen The length of the decoded data
 
67
 * @return The base64-decoded data
 
68
 */
 
69
void *cl_base64_decode(char *data, size_t len, void *obuf, size_t *olen)
 
70
{
 
71
    BIO *bio, *b64;
 
72
    void *buf, *ret;
 
73
 
 
74
    buf = (obuf) ? obuf : malloc(base64_len(data, len)+1);
 
75
    if (!(buf))
 
76
        return NULL;
 
77
 
 
78
    b64 = BIO_new(BIO_f_base64());
 
79
    if (!(b64)) {
 
80
        if (!(obuf))
 
81
            free(buf);
 
82
 
 
83
        return NULL;
 
84
    }
 
85
 
 
86
    bio = BIO_new_mem_buf(data, len);
 
87
    if (!(bio)) {
 
88
        BIO_free(b64);
 
89
        if (!(obuf))
 
90
            free(buf);
 
91
 
 
92
        return NULL;
 
93
    }
 
94
 
 
95
    bio = BIO_push(b64, bio);
 
96
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
 
97
 
 
98
    *olen = BIO_read(bio, buf, base64_len(data, len));
 
99
 
 
100
    BIO_free_all(bio);
 
101
 
 
102
    return buf;
 
103
}
 
104
 
 
105
/** Base64-encode data
 
106
 * @param[in] data The data to be encoded
 
107
 * @param[in] len The length of the data
 
108
 * @return A pointer to the base64-encoded data. The data is stored in a dynamically-allocated buffer.
 
109
 */
 
110
char *cl_base64_encode(void *data, size_t len)
 
111
{
 
112
    BIO *bio, *b64;
 
113
    char *buf, *p;
 
114
    size_t elen;
 
115
 
 
116
    b64 = BIO_new(BIO_f_base64());
 
117
    bio = BIO_new(BIO_s_mem());
 
118
 
 
119
    bio = BIO_push(b64, bio);
 
120
    BIO_write(bio, data, len);
 
121
 
 
122
    BIO_flush(bio);
 
123
    elen = (size_t)BIO_get_mem_data(bio, &buf);
 
124
 
 
125
    /* Ensure we're dealing with a NULL-terminated string */
 
126
    p = (char *)malloc(elen+1);
 
127
    memcpy((void *)p, (void *)buf, elen);
 
128
    p[elen] = 0x00;
 
129
    buf = p;
 
130
 
 
131
    BIO_free_all(bio);
 
132
 
 
133
    return buf;
 
134
}
 
135
 
 
136
#if defined(CONV_SELF_TEST)
 
137
 
 
138
int main(int argc, char *argv[])
 
139
{
 
140
    char *plaintext, *encoded, *decoded;
 
141
    unsigned char *sha_plaintext, *sha_decoded;
 
142
    size_t len;
 
143
    int ret=0;
 
144
    unsigned int shalen;
 
145
 
 
146
    initialize_crypto();
 
147
 
 
148
    plaintext = (argv[1]) ? argv[1] : "Hello. This is dog";
 
149
    sha_plaintext = sha256(plaintext, strlen(plaintext), NULL, NULL);
 
150
    if (!(sha_plaintext)) {
 
151
        fprintf(stderr, "Could not generate sha256 of plaintext\n");
 
152
        return 1;
 
153
    }
 
154
 
 
155
    encoded = base64_encode(plaintext, strlen(plaintext));
 
156
    if (!(encoded)) {
 
157
        fprintf(stderr, "Could not base64 encode plaintest\n");
 
158
        return 1;
 
159
    }
 
160
    fprintf(stderr, "Base64 encoded: %s\n", encoded);
 
161
 
 
162
    decoded = base64_decode(encoded, strlen(encoded), NULL, &len);
 
163
    if (!(decoded)) {
 
164
        fprintf(stderr, "Could not base64 decoded string\n");
 
165
        return 1;
 
166
    }
 
167
 
 
168
    sha_decoded = sha256(decoded, len, NULL, &shalen);
 
169
    if (!(sha_decoded)) {
 
170
        fprintf(stderr, "Could not generate sha256 of decoded data\n");
 
171
        return 1;
 
172
    }
 
173
 
 
174
    if (memcmp(sha_plaintext, sha_decoded, shalen)) {
 
175
        fprintf(stderr, "Decoded does not match plaintext: %s\n", decoded);
 
176
        ret = 1;
 
177
    }
 
178
 
 
179
    free(sha_decoded);
 
180
    free(sha_plaintext);
 
181
    free(encoded);
 
182
    free(decoded);
 
183
 
 
184
    cleanup_crypto();
 
185
 
 
186
    return ret;
 
187
}
 
188
 
 
189
#endif