Changeset 773 in openpam for trunk/t/t_rfc4648.c
- Timestamp:
- Mar 9, 2014, 11:49:08 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/t/t_rfc4648.c
r772 r773 34 34 #endif 35 35 36 #include <err .h>36 #include <errno.h> 37 37 #include <stdint.h> 38 38 #include <stdio.h> … … 45 45 #include "t.h" 46 46 47 /* 48 * Test vectors from RFC 4648 49 */ 50 static 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 }, 47 struct t_case { 48 const char *desc; 49 int (*func)(const char *, size_t, char *, size_t *); 50 const char *in; /* input string */ 51 size_t ilen; /* input length */ 52 const char *out; /* expected output string or NULL */ 53 size_t blen; /* initial value for olen or 0*/ 54 size_t olen; /* expected value for olen */ 55 int ret; /* expected return value */ 56 int err; /* expected errno if ret != 0 */ 57 }; 58 59 /* basic encoding / decoding */ 60 #define T_ENCODE_N(N, i, o) \ 61 { "base"#N"_enc("#i")", base##N##_enc, i, sizeof i - 1, \ 62 o, sizeof o, sizeof o, 0, 0 } 63 #define T_DECODE_N(N, i, o) \ 64 { "base"#N"_dec("#i")", base##N##_dec, i, sizeof i - 1, \ 65 o, sizeof o - 1, sizeof o - 1, 0, 0 } 66 #define T_ENCODE(p, b32, b64) \ 67 T_ENCODE_N(32, p, b32), T_ENCODE_N(64, p, b64) 68 #define T_DECODE(p, b32, b64) \ 69 T_DECODE_N(32, b32, p), T_DECODE_N(64, b64, p) 70 71 /* roundtrip encoding tests */ 72 #define T_ENCDEC(p, b32, b64) \ 73 T_ENCODE(p, b32, b64), T_DECODE(p, b32, b64) 74 75 /* decoding failure */ 76 #define T_DECODE_FAIL_N(N, i, e) \ 77 { "base"#N"_dec("#i")", base##N##_dec, i, sizeof i - 1, \ 78 NULL, 0, 0, -1, e } 79 #define T_DECODE_FAIL(e, b32, b64) \ 80 T_DECODE_FAIL_N(32, b32, e), T_DECODE_FAIL_N(64, b64, e) 81 82 /* input string shorter than input length */ 83 #define T_SHORT_INPUT_DEC(N, i) \ 84 { "base"#N"_dec (short input)", base##N##_dec, i, sizeof i + 2, \ 85 NULL, 0, base##N##_declen(sizeof i - 1), 0, 0 } 86 #define T_SHORT_INPUT() \ 87 T_SHORT_INPUT_DEC(32, "AAAAAAAA"), \ 88 T_SHORT_INPUT_DEC(64, "AAAA") 89 90 /* output string longer than output length */ 91 #define T_LONG_OUTPUT_ENC(N, i) \ 92 { "base"#N"_enc (long output)", base##N##_enc, i, sizeof i - 1, \ 93 NULL, 1, base##N##_enclen(sizeof i - 1) + 1, -1, ENOSPC } 94 #define T_LONG_OUTPUT_DEC(N, i) \ 95 { "base"#N"_dec (long output)", base##N##_dec, "AAAAAAAA", 8, \ 96 NULL, 1, base##N##_declen(sizeof i - 1), -1, ENOSPC } 97 #define T_LONG_OUTPUT() \ 98 T_LONG_OUTPUT_ENC(32, "foo"), \ 99 T_LONG_OUTPUT_DEC(32, "AAAAAAAA"), \ 100 T_LONG_OUTPUT_ENC(64, "foo"), \ 101 T_LONG_OUTPUT_DEC(64, "AAAA") 102 103 static struct t_case t_cases[] = { 104 /* test vectors from RFC 4648 */ 105 /* plain base32 base64 */ 106 T_ENCDEC("", "", ""), 107 T_ENCDEC("f", "MY======", "Zg=="), 108 T_ENCDEC("fo", "MZXQ====", "Zm8="), 109 T_ENCDEC("foo", "MZXW6===", "Zm9v"), 110 T_ENCDEC("foob", "MZXW6YQ=", "Zm9vYg=="), 111 T_ENCDEC("fooba", "MZXW6YTB", "Zm9vYmE="), 112 T_ENCDEC("foobar", "MZXW6YTBOI======", "Zm9vYmFy"), 113 114 /* zeroes */ 115 T_ENCDEC("\0\0\0", "AAAAA===", "AAAA"), 116 117 /* sloppy padding */ 118 T_DECODE("f", "MY=", "Zg="), 119 T_DECODE("f", "MY", "Zg"), 120 121 /* whitespace */ 122 /* plain base32 base64 */ 123 T_DECODE("tst", "ORZX I===", "dH N0"), 124 T_DECODE("tst", "ORZX\tI===", "dH\tN0"), 125 T_DECODE("tst", "ORZX\rI===", "dH\rN0"), 126 T_DECODE("tst", "ORZX\nI===", "dH\nN0"), 127 128 /* invalid character in data */ 129 T_DECODE_FAIL(EINVAL, "AA!AAAAAA", "AA!A"), 130 131 /* invalid character in padding */ 132 T_DECODE_FAIL(EINVAL, "AAAAA==!", "AA=!"), 133 134 /* padding with no data */ 135 T_DECODE_FAIL(EINVAL, "AAAAAAAA=", "AAAA="), 136 137 /* data after padding */ 138 T_DECODE_FAIL(EINVAL, "AA=A", "AA=A"), 139 140 /* padding in incorrect location */ 141 T_DECODE_FAIL(EINVAL, "A=", "A="), 142 143 /* various error conditions */ 144 T_SHORT_INPUT(), 145 T_LONG_OUTPUT(), 91 146 }; 92 147 … … 95 150 */ 96 151 static int 97 t_rfc4648_enc(const char *plain, const char *encoded, 98 int (*enc)(const char *, size_t, char *, size_t *)) 152 t_rfc4648(void *arg) 99 153 { 154 struct t_case *t = arg; 100 155 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 char *)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); 156 size_t len; 157 int ret; 158 159 len = t->blen ? t->blen : sizeof buf; 160 ret = t->func(t->in, t->ilen, buf, &len); 161 if (ret != t->ret) { 162 t_verbose("expected return code %d, got %d\n", 163 t->ret, ret); 164 return (0); 165 } 166 if (t->out && len != t->olen) { 167 t_verbose("expected output length %zu, got %zu\n", 168 t->olen, len); 169 return (0); 170 } 171 if (t->ret != 0 && errno != t->err) { 172 t_verbose("expected errno %d, got %d\n", 173 t->err, errno); 174 return (0); 175 } 176 if (t->ret == 0 && t->out && strncmp(buf, t->out, len) != 0) { 177 t_verbose("expected '%.*s' got '%.*s'\n", 178 (int)t->olen, t->out, (int)len, buf); 117 179 return (0); 118 180 } 119 181 return (1); 120 }121 122 /*123 * Encoding test wrapper for base 32124 */125 static int126 t_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 64135 */136 static int137 t_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 function146 */147 static int148 t_rfc4648_dec(const char *encoded, const char *plain,149 int (*dec)(const char *, size_t, char *, 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, 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 32174 */175 static int176 t_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 64185 */186 static int187 t_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 vector196 */197 static struct t_test *198 t_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 182 } 213 183 … … 218 188 t_prepare(int argc, char *argv[]) 219 189 { 220 struct t_test **plan, * *test;221 int n;190 struct t_test **plan, *tests; 191 int i, n; 222 192 223 193 (void)argc; 224 194 (void)argv; 225 n = sizeof t_ vectors / sizeof t_vectors[0];226 plan = calloc(n * 4 + 1, sizeof *plan);227 if (plan== NULL)195 n = sizeof t_cases / sizeof t_cases[0]; 196 if ((plan = calloc(n + 1, sizeof *plan)) == NULL || 197 (tests = calloc(n + 1, sizeof *tests)) == NULL) 228 198 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]); 199 for (i = 0; i < n; ++i) { 200 plan[i] = &tests[i]; 201 tests[i].func = t_rfc4648; 202 tests[i].desc = t_cases[i].desc; 203 tests[i].arg = &t_cases[i]; 235 204 } 236 205 return ((const struct t_test **)plan);
Note: See TracChangeset
for help on using the changeset viewer.