diff options
Diffstat (limited to 'trust/test-pem.c')
-rw-r--r-- | trust/test-pem.c | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/trust/test-pem.c b/trust/test-pem.c new file mode 100644 index 0000000..0c7d60a --- /dev/null +++ b/trust/test-pem.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2012 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Stef Walter <stefw@gnome.org> + */ + +#include "config.h" +#include "test.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "compat.h" +#include "pem.h" + +struct { + const char *input; + struct { + const char *type; + const char *data; + unsigned int length; + } output[8]; +} success_fixtures[] = { + { + /* one block */ + "-----BEGIN BLOCK1-----\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n" + "-----END BLOCK1-----", + { + { + "BLOCK1", + "\x69\x83\x4d\x5e\xab\x21\x95\x5c\x42\x76\x8f\x10\x7c\xa7\x97\x87" + "\x71\x94\xcd\xdf\xf2\x9f\x82\xd8\x21\x58\x10\xaf\x1e\x1a", + 30, + }, + { + NULL, + } + } + }, + + { + /* one block, with header */ + "-----BEGIN BLOCK1-----\n" + "Header1: value1 \n" + " Header2: value2\n" + "\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n" + "-----END BLOCK1-----", + { + { + "BLOCK1", + "\x69\x83\x4d\x5e\xab\x21\x95\x5c\x42\x76\x8f\x10\x7c\xa7\x97\x87" + "\x71\x94\xcd\xdf\xf2\x9f\x82\xd8\x21\x58\x10\xaf\x1e\x1a", + 30, + }, + { + NULL, + } + } + }, + + { + /* two blocks, junk data */ + "-----BEGIN BLOCK1-----\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n" + "-----END BLOCK1-----\n" + "blah blah\n" + "-----BEGIN TWO-----\n" + "oy5L157C671HyJMCf9FiK9prvPZfSch6V4EoUfylFoI1Bq6SbL53kg==\n" + "-----END TWO-----\n" + "trailing data", + { + { + "BLOCK1", + "\x69\x83\x4d\x5e\xab\x21\x95\x5c\x42\x76\x8f\x10\x7c\xa7\x97\x87" + "\x71\x94\xcd\xdf\xf2\x9f\x82\xd8\x21\x58\x10\xaf\x1e\x1a", + 30, + }, + { + "TWO", + "\xa3\x2e\x4b\xd7\x9e\xc2\xeb\xbd\x47\xc8\x93\x02\x7f\xd1\x62\x2b" + "\xda\x6b\xbc\xf6\x5f\x49\xc8\x7a\x57\x81\x28\x51\xfc\xa5\x16\x82" + "\x35\x06\xae\x92\x6c\xbe\x77\x92", + 40 + }, + { + NULL, + } + } + }, + + { + NULL, + } +}; + +typedef struct { + int input_index; + int output_index; + int parsed; +} Closure; + +static void +on_parse_pem_success (const char *type, + const unsigned char *contents, + size_t length, + void *user_data) +{ + Closure *cl = user_data; + + assert_num_eq (success_fixtures[cl->input_index].output[cl->output_index].length, length); + assert (memcmp (success_fixtures[cl->input_index].output[cl->output_index].data, contents, + success_fixtures[cl->input_index].output[cl->output_index].length) == 0); + + cl->output_index++; + cl->parsed++; +} + +static void +test_pem_success (void) +{ + Closure cl; + int ret; + int i; + int j; + + for (i = 0; success_fixtures[i].input != NULL; i++) { + cl.input_index = i; + cl.output_index = 0; + cl.parsed = 0; + + ret = p11_pem_parse (success_fixtures[i].input, strlen (success_fixtures[i].input), + on_parse_pem_success, &cl); + + assert (success_fixtures[i].output[cl.output_index].type == NULL); + + /* Count number of outputs, return from p11_pem_parse() should match */ + for (j = 0; success_fixtures[i].output[j].type != NULL; j++); + assert_num_eq (j, ret); + assert_num_eq (ret, cl.parsed); + } +} + +const char *failure_fixtures[] = { + /* too short at end of opening line */ + "-----BEGIN BLOCK1---\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n" + "-----END BLOCK1-----", + + /* truncated */ + "-----BEGIN BLOCK1---", + + /* no ending */ + "-----BEGIN BLOCK1-----\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n", + + /* wrong ending */ + "-----BEGIN BLOCK1-----\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n" + "-----END BLOCK2-----", + + /* wrong ending */ + "-----BEGIN BLOCK1-----\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n" + "-----END INVALID-----", + + /* too short at end of ending line */ + "-----BEGIN BLOCK1-----\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n" + "-----END BLOCK1---", + + /* invalid base64 data */ + "-----BEGIN BLOCK1-----\n" + "!!!!NNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n" + "-----END BLOCK1-----", + + NULL, +}; + +static void +on_parse_pem_failure (const char *type, + const unsigned char *contents, + size_t length, + void *user_data) +{ + assert (false && "not reached"); +} + +static void +test_pem_failure (void) +{ + int ret; + int i; + + for (i = 0; failure_fixtures[i] != NULL; i++) { + ret = p11_pem_parse (failure_fixtures[i], strlen (failure_fixtures[i]), + on_parse_pem_failure, NULL); + assert_num_eq (0, ret); + } +} + +typedef struct { + const char *input; + size_t length; + const char *type; + const char *output; +} WriteFixture; + +static WriteFixture write_fixtures[] = { + { + "\x69\x83\x4d\x5e\xab\x21\x95\x5c\x42\x76\x8f\x10\x7c\xa7\x97\x87" + "\x71\x94\xcd\xdf\xf2\x9f\x82\xd8\x21\x58\x10\xaf\x1e\x1a", + 30, "BLOCK1", + "-----BEGIN BLOCK1-----\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrx4a\n" + "-----END BLOCK1-----\n", + }, + { + "\x50\x31\x31\x2d\x4b\x49\x54\x0a\x0a\x50\x72\x6f\x76\x69\x64\x65" + "\x73\x20\x61\x20\x77\x61\x79\x20\x74\x6f\x20\x6c\x6f\x61\x64\x20" + "\x61\x6e\x64\x20\x65\x6e\x75\x6d\x65\x72\x61\x74\x65\x20\x50\x4b" + "\x43\x53\x23\x31\x31\x20\x6d\x6f\x64\x75\x6c\x65\x73\x2e\x20\x50" + "\x72\x6f\x76\x69\x64\x65\x73\x20\x61\x20\x73\x74\x61\x6e\x64\x61" + "\x72\x64\x0a\x63\x6f\x6e\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e" + "\x20\x73\x65\x74\x75\x70\x20\x66\x6f\x72\x20\x69\x6e\x73\x74\x61" + "\x6c\x6c\x69\x6e\x67\x20\x50\x4b\x43\x53\x23\x31\x31\x20\x6d\x6f" + "\x64\x75\x6c\x65\x73\x20\x69\x6e\x20\x73\x75\x63\x68\x20\x61\x20" + "\x77\x61\x79\x20\x74\x68\x61\x74\x20\x74\x68\x65\x79\x27\x72\x65" + "\x0a\x64\x69\x73\x63\x6f\x76\x65\x72\x61\x62\x6c\x65\x2e\x0a\x0a" + "\x41\x6c\x73\x6f\x20\x73\x6f\x6c\x76\x65\x73\x20\x70\x72\x6f\x62" + "\x6c\x65\x6d\x73\x20\x77\x69\x74\x68\x20\x63\x6f\x6f\x72\x64\x69" + "\x6e\x61\x74\x69\x6e\x67\x20\x74\x68\x65\x20\x75\x73\x65\x20\x6f" + "\x66\x20\x50\x4b\x43\x53\x23\x31\x31\x20\x62\x79\x20\x64\x69\x66" + "\x66\x65\x72\x65\x6e\x74\x0a\x63\x6f\x6d\x70\x6f\x6e\x65\x6e\x74" + "\x73\x20\x6f\x72\x20\x6c\x69\x62\x72\x61\x72\x69\x65\x73\x20\x6c" + "\x69\x76\x69\x6e\x67\x20\x69\x6e\x20\x74\x68\x65\x20\x73\x61\x6d" + "\x65\x20\x70\x72\x6f\x63\x65\x73\x73\x2e\x0a", + 299, "LONG TYPE WITH SPACES", + "-----BEGIN LONG TYPE WITH SPACES-----\n" + "UDExLUtJVAoKUHJvdmlkZXMgYSB3YXkgdG8gbG9hZCBhbmQgZW51bWVyYXRlIFBL\n" + "Q1MjMTEgbW9kdWxlcy4gUHJvdmlkZXMgYSBzdGFuZGFyZApjb25maWd1cmF0aW9u\n" + "IHNldHVwIGZvciBpbnN0YWxsaW5nIFBLQ1MjMTEgbW9kdWxlcyBpbiBzdWNoIGEg\n" + "d2F5IHRoYXQgdGhleSdyZQpkaXNjb3ZlcmFibGUuCgpBbHNvIHNvbHZlcyBwcm9i\n" + "bGVtcyB3aXRoIGNvb3JkaW5hdGluZyB0aGUgdXNlIG9mIFBLQ1MjMTEgYnkgZGlm\n" + "ZmVyZW50CmNvbXBvbmVudHMgb3IgbGlicmFyaWVzIGxpdmluZyBpbiB0aGUgc2Ft\n" + "ZSBwcm9jZXNzLgo=\n" + "-----END LONG TYPE WITH SPACES-----\n" + }, + { + "\x69\x83\x4d\x5e\xab\x21\x95\x5c\x42\x76\x8f\x10\x7c\xa7\x97\x87" + "\x71\x94\xcd\xdf\xf2\x9f\x82\xd8\x21\x58\x10\xaf", + 28, "BLOCK1", + "-----BEGIN BLOCK1-----\n" + "aYNNXqshlVxCdo8QfKeXh3GUzd/yn4LYIVgQrw==\n" + "-----END BLOCK1-----\n", + }, + { + NULL, + } +}; + +static void +on_parse_written (const char *type, + const unsigned char *contents, + size_t length, + void *user_data) +{ + WriteFixture *fixture = user_data; + + assert_str_eq (fixture->type, type); + assert_num_eq (fixture->length, length); + assert (memcmp (contents, fixture->input, length) == 0); +} + +static void +test_pem_write (void) +{ + WriteFixture *fixture; + p11_buffer buf; + unsigned int count; + int i; + + for (i = 0; write_fixtures[i].input != NULL; i++) { + fixture = write_fixtures + i; + + if (!p11_buffer_init_null (&buf, 0)) + assert_not_reached (); + + if (!p11_pem_write ((unsigned char *)fixture->input, + fixture->length, + fixture->type, &buf)) + assert_not_reached (); + assert_str_eq (fixture->output, buf.data); + assert_num_eq (strlen (fixture->output), buf.len); + + count = p11_pem_parse (buf.data, buf.len, on_parse_written, fixture); + assert_num_eq (1, count); + + p11_buffer_uninit (&buf); + } +} + +int +main (int argc, + char *argv[]) +{ + p11_test (test_pem_success, "/pem/success"); + p11_test (test_pem_failure, "/pem/failure"); + p11_test (test_pem_write, "/pem/write"); + return p11_test_run (argc, argv); +} |