1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci#include <assert.h> 10e1051a39Sopenharmony_ci#include <errno.h> 11e1051a39Sopenharmony_ci#include <stdio.h> 12e1051a39Sopenharmony_ci#include <string.h> 13e1051a39Sopenharmony_ci#include <ctype.h> 14e1051a39Sopenharmony_ci 15e1051a39Sopenharmony_ci#include "internal/nelem.h" 16e1051a39Sopenharmony_ci#include "../testutil.h" 17e1051a39Sopenharmony_ci#include "tu_local.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ciint test_start_file(STANZA *s, const char *testfile) 20e1051a39Sopenharmony_ci{ 21e1051a39Sopenharmony_ci TEST_info("Reading %s", testfile); 22e1051a39Sopenharmony_ci set_test_title(testfile); 23e1051a39Sopenharmony_ci memset(s, 0, sizeof(*s)); 24e1051a39Sopenharmony_ci if (!TEST_ptr(s->fp = BIO_new_file(testfile, "r"))) 25e1051a39Sopenharmony_ci return 0; 26e1051a39Sopenharmony_ci s->test_file = testfile; 27e1051a39Sopenharmony_ci return 1; 28e1051a39Sopenharmony_ci} 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ciint test_end_file(STANZA *s) 31e1051a39Sopenharmony_ci{ 32e1051a39Sopenharmony_ci TEST_info("Completed %d tests with %d errors and %d skipped", 33e1051a39Sopenharmony_ci s->numtests, s->errors, s->numskip); 34e1051a39Sopenharmony_ci BIO_free(s->fp); 35e1051a39Sopenharmony_ci return 1; 36e1051a39Sopenharmony_ci} 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_ci/* 39e1051a39Sopenharmony_ci * Read a PEM block. Return 1 if okay, 0 on error. 40e1051a39Sopenharmony_ci */ 41e1051a39Sopenharmony_cistatic int read_key(STANZA *s) 42e1051a39Sopenharmony_ci{ 43e1051a39Sopenharmony_ci char tmpbuf[128]; 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ci if (s->key == NULL) { 46e1051a39Sopenharmony_ci if (!TEST_ptr(s->key = BIO_new(BIO_s_mem()))) 47e1051a39Sopenharmony_ci return 0; 48e1051a39Sopenharmony_ci } else if (!TEST_int_gt(BIO_reset(s->key), 0)) { 49e1051a39Sopenharmony_ci return 0; 50e1051a39Sopenharmony_ci } 51e1051a39Sopenharmony_ci 52e1051a39Sopenharmony_ci /* Read to PEM end line and place content in memory BIO */ 53e1051a39Sopenharmony_ci while (BIO_gets(s->fp, tmpbuf, sizeof(tmpbuf))) { 54e1051a39Sopenharmony_ci s->curr++; 55e1051a39Sopenharmony_ci if (!TEST_int_gt(BIO_puts(s->key, tmpbuf), 0)) 56e1051a39Sopenharmony_ci return 0; 57e1051a39Sopenharmony_ci if (strncmp(tmpbuf, "-----END", 8) == 0) 58e1051a39Sopenharmony_ci return 1; 59e1051a39Sopenharmony_ci } 60e1051a39Sopenharmony_ci TEST_error("Can't find key end"); 61e1051a39Sopenharmony_ci return 0; 62e1051a39Sopenharmony_ci} 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci/* 66e1051a39Sopenharmony_ci * Delete leading and trailing spaces from a string 67e1051a39Sopenharmony_ci */ 68e1051a39Sopenharmony_cistatic char *strip_spaces(char *p) 69e1051a39Sopenharmony_ci{ 70e1051a39Sopenharmony_ci char *q; 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci /* Skip over leading spaces */ 73e1051a39Sopenharmony_ci while (*p && isspace((unsigned char)*p)) 74e1051a39Sopenharmony_ci p++; 75e1051a39Sopenharmony_ci if (*p == '\0') 76e1051a39Sopenharmony_ci return NULL; 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ci for (q = p + strlen(p) - 1; q != p && isspace((unsigned char)*q); ) 79e1051a39Sopenharmony_ci *q-- = '\0'; 80e1051a39Sopenharmony_ci return *p ? p : NULL; 81e1051a39Sopenharmony_ci} 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci/* 84e1051a39Sopenharmony_ci * Read next test stanza; return 1 if found, 0 on EOF or error. 85e1051a39Sopenharmony_ci */ 86e1051a39Sopenharmony_ciint test_readstanza(STANZA *s) 87e1051a39Sopenharmony_ci{ 88e1051a39Sopenharmony_ci PAIR *pp = s->pairs; 89e1051a39Sopenharmony_ci char *p, *equals, *key; 90e1051a39Sopenharmony_ci const char *value; 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci for (s->numpairs = 0; BIO_gets(s->fp, s->buff, sizeof(s->buff)); ) { 93e1051a39Sopenharmony_ci s->curr++; 94e1051a39Sopenharmony_ci if (!TEST_ptr(p = strchr(s->buff, '\n'))) { 95e1051a39Sopenharmony_ci TEST_info("Line %d too long", s->curr); 96e1051a39Sopenharmony_ci return 0; 97e1051a39Sopenharmony_ci } 98e1051a39Sopenharmony_ci *p = '\0'; 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_ci /* Blank line marks end of tests. */ 101e1051a39Sopenharmony_ci if (s->buff[0] == '\0') 102e1051a39Sopenharmony_ci break; 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci /* Lines starting with a pound sign are ignored. */ 105e1051a39Sopenharmony_ci if (s->buff[0] == '#') 106e1051a39Sopenharmony_ci continue; 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_ci /* Parse into key=value */ 109e1051a39Sopenharmony_ci if (!TEST_ptr(equals = strchr(s->buff, '='))) { 110e1051a39Sopenharmony_ci TEST_info("Missing = at line %d\n", s->curr); 111e1051a39Sopenharmony_ci return 0; 112e1051a39Sopenharmony_ci } 113e1051a39Sopenharmony_ci *equals++ = '\0'; 114e1051a39Sopenharmony_ci if (!TEST_ptr(key = strip_spaces(s->buff))) { 115e1051a39Sopenharmony_ci TEST_info("Empty field at line %d\n", s->curr); 116e1051a39Sopenharmony_ci return 0; 117e1051a39Sopenharmony_ci } 118e1051a39Sopenharmony_ci if ((value = strip_spaces(equals)) == NULL) 119e1051a39Sopenharmony_ci value = ""; 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci if (strcmp(key, "Title") == 0) { 122e1051a39Sopenharmony_ci TEST_info("Starting \"%s\" tests at line %d", value, s->curr); 123e1051a39Sopenharmony_ci continue; 124e1051a39Sopenharmony_ci } 125e1051a39Sopenharmony_ci 126e1051a39Sopenharmony_ci if (s->numpairs == 0) 127e1051a39Sopenharmony_ci s->start = s->curr; 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ci if (strcmp(key, "PrivateKey") == 0) { 130e1051a39Sopenharmony_ci if (!read_key(s)) 131e1051a39Sopenharmony_ci return 0; 132e1051a39Sopenharmony_ci } 133e1051a39Sopenharmony_ci if (strcmp(key, "PublicKey") == 0) { 134e1051a39Sopenharmony_ci if (!read_key(s)) 135e1051a39Sopenharmony_ci return 0; 136e1051a39Sopenharmony_ci } 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci if (!TEST_int_lt(s->numpairs++, TESTMAXPAIRS) 139e1051a39Sopenharmony_ci || !TEST_ptr(pp->key = OPENSSL_strdup(key)) 140e1051a39Sopenharmony_ci || !TEST_ptr(pp->value = OPENSSL_strdup(value))) 141e1051a39Sopenharmony_ci return 0; 142e1051a39Sopenharmony_ci pp++; 143e1051a39Sopenharmony_ci } 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ci /* If we read anything, return ok. */ 146e1051a39Sopenharmony_ci return 1; 147e1051a39Sopenharmony_ci} 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_civoid test_clearstanza(STANZA *s) 150e1051a39Sopenharmony_ci{ 151e1051a39Sopenharmony_ci PAIR *pp = s->pairs; 152e1051a39Sopenharmony_ci int i = s->numpairs; 153e1051a39Sopenharmony_ci 154e1051a39Sopenharmony_ci for ( ; --i >= 0; pp++) { 155e1051a39Sopenharmony_ci OPENSSL_free(pp->key); 156e1051a39Sopenharmony_ci OPENSSL_free(pp->value); 157e1051a39Sopenharmony_ci } 158e1051a39Sopenharmony_ci s->numpairs = 0; 159e1051a39Sopenharmony_ci} 160