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 /* 66 * Delete leading and trailing spaces from a string 67 */ 68 static char *strip_spaces(char *p) 69 { 70 char *q; 71 72 /* Skip over leading spaces */ 73 while (*p && isspace((unsigned char)*p)) 74 p++; 75 if (*p == '\0') 76 return NULL; 77 78 for (q = p + strlen(p) - 1; q != p && isspace((unsigned char)*q); ) 79 *q-- = '\0'; 80 return *p ? p : NULL; 81 } 82 83 /* 84 * Read next test stanza; return 1 if found, 0 on EOF or error. 85 */ 86 int test_readstanza(STANZA *s) 87 { 88 PAIR *pp = s->pairs; 89 char *p, *equals, *key; 90 const char *value; 91 static char buff[131072]; 92 93 for (s->numpairs = 0; BIO_gets(s->fp, buff, sizeof(buff)); ) { 94 s->curr++; 95 if (!TEST_ptr(p = strchr(buff, '\n'))) { 96 TEST_info("Line %d too long", s->curr); 97 return 0; 98 } 99 *p = '\0'; 100 101 /* Blank line marks end of tests. */ 102 if (buff[0] == '\0') 103 break; 104 105 /* Lines starting with a pound sign are ignored. */ 106 if (buff[0] == '#') 107 continue; 108 109 /* Parse into key=value */ 110 if (!TEST_ptr(equals = strchr(buff, '='))) { 111 TEST_info("Missing = at line %d\n", s->curr); 112 return 0; 113 } 114 *equals++ = '\0'; 115 if (!TEST_ptr(key = strip_spaces(buff))) { 116 TEST_info("Empty field at line %d\n", s->curr); 117 return 0; 118 } 119 if ((value = strip_spaces(equals)) == NULL) 120 value = ""; 121 122 if (strcmp(key, "Title") == 0) { 123 TEST_info("Starting \"%s\" tests at line %d", value, s->curr); 124 continue; 125 } 126 127 if (s->numpairs == 0) 128 s->start = s->curr; 129 130 if (strcmp(key, "PrivateKey") == 0 131 || strcmp(key, "PublicKey") == 0 132 || strcmp(key, "ParamKey") == 0) { 133 if (!read_key(s)) 134 return 0; 135 } 136 137 if (!TEST_int_lt(s->numpairs++, TESTMAXPAIRS) 138 || !TEST_ptr(pp->key = OPENSSL_strdup(key)) 139 || !TEST_ptr(pp->value = OPENSSL_strdup(value))) 140 return 0; 141 pp++; 142 } 143 144 /* If we read anything, return ok. */ 145 return 1; 146 } 147 148 void test_clearstanza(STANZA *s) 149 { 150 PAIR *pp = s->pairs; 151 int i = s->numpairs; 152 153 for ( ; --i >= 0; pp++) { 154 OPENSSL_free(pp->key); 155 OPENSSL_free(pp->value); 156 } 157 s->numpairs = 0; 158 } 159