summaryrefslogtreecommitdiffstats
path: root/test/testutil/stanza.c
blob: 35967528f8312c4c918175a6d3f6d2a558b55b4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "internal/nelem.h"
#include "../testutil.h"
#include "tu_local.h"

int test_start_file(STANZA *s, const char *testfile)
{
    TEST_info("Reading %s", testfile);
    set_test_title(testfile);
    memset(s, 0, sizeof(*s));
    if (!TEST_ptr(s->fp = BIO_new_file(testfile, "r")))
        return 0;
    s->test_file = testfile;
    return 1;
}

int test_end_file(STANZA *s)
{
    TEST_info("Completed %d tests with %d errors and %d skipped",
              s->numtests, s->errors, s->numskip);
    BIO_free(s->fp);
    return 1;
}

/*
 * Read a PEM block.  Return 1 if okay, 0 on error.
 */
static int read_key(STANZA *s)
{
    char tmpbuf[128];

    if (s->key == NULL) {
        if (!TEST_ptr(s->key = BIO_new(BIO_s_mem())))
            return 0;
    } else if (!TEST_int_gt(BIO_reset(s->key), 0)) {
        return 0;
    }

    /* Read to PEM end line and place content in memory BIO */
    while (BIO_gets(s->fp, tmpbuf, sizeof(tmpbuf))) {
        s->curr++;
        if (!TEST_int_gt(BIO_puts(s->key, tmpbuf), 0))
            return 0;
        if (strncmp(tmpbuf, "-----END", 8) == 0)
            return 1;
    }
    TEST_error("Can't find key end");
    return 0;
}


/*
 * Delete leading and trailing spaces from a string
 */
static char *strip_spaces(char *p)
{
    char *q;

    /* Skip over leading spaces */
    while (*p && isspace(*p))
        p++;
    if (!*p)
        return NULL;

    for (q = p + strlen(p) - 1; q != p && isspace(*q); )
        *q-- = '\0';
    return *p ? p : NULL;
}

/*
 * Read next test stanza; return 1 if found, 0 on EOF or error.
 */
int test_readstanza(STANZA *s)
{
    PAIR *pp = s->pairs;
    char *p, *equals, *key, *value;

    for (s->numpairs = 0; BIO_gets(s->fp, s->buff, sizeof(s->buff)); ) {
        s->curr++;
        if (!TEST_ptr(p = strchr(s->buff, '\n'))) {
            TEST_info("Line %d too long", s->curr);
            return 0;
        }
        *p = '\0';

        /* Blank line marks end of tests. */
        if (s->buff[0] == '\0')
            break;

        /* Lines starting with a pound sign are ignored. */
        if (s->buff[0] == '#')
            continue;

        /* Parse into key=value */
        if (!TEST_ptr(equals = strchr(s->buff, '='))) {
            TEST_info("Missing = at line %d\n", s->curr);
            return 0;
        }
        *equals++ = '\0';
        if (!TEST_ptr(key = strip_spaces(s->buff))) {
            TEST_info("Empty field at line %d\n", s->curr);
            return 0;
        }
        if ((value = strip_spaces(equals)) == NULL)
            value = "";

        if (strcmp(key, "Title") == 0) {
            TEST_info("Starting \"%s\" tests at line %d", value, s->curr);
            continue;
        }

        if (s->numpairs == 0)
            s->start = s->curr;

        if (strcmp(key, "PrivateKey") == 0) {
            if (!read_key(s))
                return 0;
        }
        if (strcmp(key, "PublicKey") == 0) {
            if (!read_key(s))
                return 0;
        }

        if (!TEST_int_lt(s->numpairs++, TESTMAXPAIRS)
                || !TEST_ptr(pp->key = OPENSSL_strdup(key))
                || !TEST_ptr(pp->value = OPENSSL_strdup(value)))
            return 0;
        pp++;
    }

    /* If we read anything, return ok. */
    return 1;
}

void test_clearstanza(STANZA *s)
{
    PAIR *pp = s->pairs;
    int i = s->numpairs;

    for ( ; --i >= 0; pp++) {
        OPENSSL_free(pp->key);
        OPENSSL_free(pp->value);
    }
    s->numpairs = 0;
}