source: openpam/trunk/t/t_rfc4648.c @ 769

Last change on this file since 769 was 769, checked in by Dag-Erling Smørgrav, 7 years ago

Add tests for base{32,64}_decode(). Both are broken.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.5 KB
Line 
1/*-
2 * Copyright (c) 2013-2014 Universitetet i Oslo
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote
14 *    products derived from this software without specific prior written
15 *    permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $Id: t_rfc4648.c 769 2014-03-06 12:32:29Z des $
30 */
31
32#ifdef HAVE_CONFIG_H
33# include "config.h"
34#endif
35
36#include <err.h>
37#include <stdint.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <unistd.h>
42
43#include <security/oath.h>
44
45#include "t.h"
46
47/*
48 * Test vectors from RFC 4648
49 */
50static struct t_vector {
51        const char *plain;
52/*      const char *base16; */
53        const char *base32;
54        const char *base64;
55} t_vectors[] = {
56        {
57                .plain  = "",
58                .base32 = "",
59                .base64 = "",
60        },
61        {
62                .plain  = "f",
63                .base32 = "MY======",
64                .base64 = "Zg=="
65        },
66        {
67                .plain  = "fo",
68                .base32 = "MZXQ====",
69                .base64 = "Zm8=",
70        },
71        {
72                .plain  = "foo",
73                .base32 = "MZXW6===",
74                .base64 = "Zm9v",
75        },
76        {
77                .plain  = "foob",
78                .base32 = "MZXW6YQ=",
79                .base64 = "Zm9vYg==",
80        },
81        {
82                .plain  = "fooba",
83                .base32 = "MZXW6YTB",
84                .base64 = "Zm9vYmE=",
85        },
86        {
87                .plain  = "foobar",
88                .base32 = "MZXW6YTBOI======",
89                .base64 = "Zm9vYmFy",
90        },
91};
92
93/*
94 * Encoding test function
95 */
96static int
97t_rfc4648_enc(const char *plain, const char *encoded,
98    int (*enc)(const uint8_t *, size_t, char *, size_t *))
99{
100        char buf[64];
101        size_t blen, ilen, olen;
102
103        blen = sizeof buf;
104        ilen = strlen(plain);
105        olen = strlen(encoded) + 1;
106        if (enc((const uint8_t *)plain, ilen, buf, &blen) != 0) {
107                t_verbose("encoding failed\n");
108                return (0);
109        }
110        if (blen != olen) {
111                t_verbose("expected '%.*s' got '%.*s'\n", (int)olen, encoded, (int)blen, buf);
112                t_verbose("expected %zu B got %zu B\n", olen, blen);
113                return (0);
114        }
115        if (strncmp(buf, encoded, blen) != 0) {
116                t_verbose("expected '%.*s' got '%.*s'\n", (int)olen, encoded, (int)blen, buf);
117                return (0);
118        }
119        return (1);
120}
121
122/*
123 * Encoding test wrapper for base 32
124 */
125static int
126t_base32_enc(void *arg)
127{
128        struct t_vector *tv = (struct t_vector *)arg;
129
130        return (t_rfc4648_enc(tv->plain, tv->base32, base32_enc));
131}
132
133/*
134 * Encoding test wrapper for base 64
135 */
136static int
137t_base64_enc(void *arg)
138{
139        struct t_vector *tv = (struct t_vector *)arg;
140
141        return (t_rfc4648_enc(tv->plain, tv->base64, base64_enc));
142}
143
144/*
145 * Decoding test function
146 */
147static int
148t_rfc4648_dec(const char *encoded, const char *plain,
149    int (*dec)(const char *, size_t, uint8_t *, size_t *))
150{
151        char buf[64];
152        size_t blen, ilen, olen;
153
154        blen = sizeof buf;
155        ilen = strlen(encoded);
156        olen = strlen(plain);
157        if (dec(encoded, ilen, (uint8_t *)buf, &blen) != 0) {
158                t_verbose("encoding failed\n");
159                return (0);
160        }
161        if (blen != olen) {
162                t_verbose("expected %zu B got %zu B\n", olen, blen);
163                return (0);
164        }
165        if (strncmp(buf, plain, blen) != 0) {
166                t_verbose("expected '%.*s' got '%.*s'\n", (int)olen, plain, (int)blen, buf);
167                return (0);
168        }
169        return (1);
170}
171
172/*
173 * Decoding test wrapper for base 32
174 */
175static int
176t_base32_dec(void *arg)
177{
178        struct t_vector *tv = (struct t_vector *)arg;
179
180        return (t_rfc4648_dec(tv->base32, tv->plain, base32_dec));
181}
182
183/*
184 * Decoding test wrapper for base 64
185 */
186static int
187t_base64_dec(void *arg)
188{
189        struct t_vector *tv = (struct t_vector *)arg;
190
191        return (t_rfc4648_dec(tv->base64, tv->plain, base64_dec));
192}
193
194/*
195 * Generate a test case for a given test vector
196 */
197static struct t_test *
198t_create_test(int (*func)(void *), const char *name, struct t_vector *tv)
199{
200        struct t_test *test;
201        char *desc;
202
203        if ((test = calloc(1, sizeof *test)) == NULL)
204                return (NULL);
205        test->func = func;
206        if ((desc = calloc(1, strlen(name) + strlen(tv->plain) + 5)) == NULL)
207                return (NULL);
208        sprintf(desc, "%s(\"%s\")", name, tv->plain);
209        test->desc = desc;
210        test->arg = tv;
211        return (test);
212}
213
214/*
215 * Generate the test plan
216 */
217const struct t_test **
218t_prepare(int argc, char *argv[])
219{
220        struct t_test **plan, **test;
221        int n;
222
223        (void)argc;
224        (void)argv;
225        n = sizeof t_vectors / sizeof t_vectors[0];
226        plan = calloc(n * 4 + 1, sizeof *plan);
227        if (plan == NULL)
228                return (NULL);
229        test = plan;
230        for (int i = 0; i < n; ++i) {
231                *test++ = t_create_test(t_base32_enc, "BASE32ENC", &t_vectors[i]);
232                *test++ = t_create_test(t_base32_dec, "BASE32DEC", &t_vectors[i]);
233                *test++ = t_create_test(t_base64_enc, "BASE64ENC", &t_vectors[i]);
234                *test++ = t_create_test(t_base64_dec, "BASE64DEC", &t_vectors[i]);
235        }
236        return ((const struct t_test **)plan);
237}
238
239/*
240 * Cleanup
241 */
242void
243t_cleanup(void)
244{
245}
Note: See TracBrowser for help on using the repository browser.