summaryrefslogtreecommitdiff
path: root/trust/test-pem.c
diff options
context:
space:
mode:
Diffstat (limited to 'trust/test-pem.c')
-rw-r--r--trust/test-pem.c341
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);
+}