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