-static void clear_test(EVP_TEST *t)
-{
- OPENSSL_free(t->expected_err);
- t->expected_err = NULL;
- OPENSSL_free(t->func);
- t->func = NULL;
- OPENSSL_free(t->reason);
- t->reason = NULL;
- /* Text literal. */
- t->err = NULL;
-}
-
-/*
- * Check for errors in the test structure; return 1 if okay, else 0.
- */
-static int check_test_error(EVP_TEST *t)
-{
- unsigned long err;
- const char *func;
- const char *reason;
-
- if (t->err == NULL && t->expected_err == NULL)
- return 1;
- if (t->err != NULL && t->expected_err == NULL) {
- if (t->aux_err != NULL) {
- TEST_info("Above error from the test at %s:%d "
- "(%s) unexpected error %s",
- current_test_file, t->start_line, t->aux_err, t->err);
- } else {
- TEST_info("Above error from the test at %s:%d "
- "unexpected error %s",
- current_test_file, t->start_line, t->err);
- }
- clear_test(t);
- return 0;
- }
- if (t->err == NULL && t->expected_err != NULL) {
- TEST_info("Test line %d: succeeded expecting %s",
- t->start_line, t->expected_err);
- return 0;
- }
-
- if (strcmp(t->err, t->expected_err) != 0) {
- TEST_info("Test line %d: expecting %s got %s",
- t->start_line, t->expected_err, t->err);
- return 0;
- }
-
- if (t->func == NULL && t->reason == NULL)
- return 1;
-
- if (t->func == NULL || t->reason == NULL) {
- TEST_info("Test line %d: missing function or reason code",
- t->start_line);
- return 0;
- }
-
- err = ERR_peek_error();
- if (err == 0) {
- TEST_info("Test line %d, expected error \"%s:%s\" not set",
- t->start_line, t->func, t->reason);
- return 0;
- }
-
- func = ERR_func_error_string(err);
- reason = ERR_reason_error_string(err);
- if (func == NULL && reason == NULL) {
- TEST_info("Test line %d: expected error \"%s:%s\","
- " no strings available. Skipping...\n",
- t->start_line, t->func, t->reason);
- return 1;
- }
-
- if (strcmp(func, t->func) == 0 && strcmp(reason, t->reason) == 0)
- return 1;
-
- TEST_info("Test line %d: expected error \"%s:%s\", got \"%s:%s\"",
- t->start_line, t->func, t->reason, func, reason);
-
- return 0;
-}
-
-/*
- * Setup a new test, run any existing test. Log a message and return 0
- * on error.
- */
-static int run_and_get_next(EVP_TEST *t, const EVP_TEST_METHOD *tmeth)
-{
- /* If we already have a test set up run it */
- if (t->meth) {
- t->ntests++;
- if (t->skip) {
- /*TEST_info("Line %d skipped %s test", t->start_line, t->meth->name);
- */
- t->nskip++;
- } else {
- /* run the test */
- if (t->err == NULL && t->meth->run_test(t) != 1) {
- TEST_info("Line %d error %s", t->start_line, t->meth->name);
- return 0;
- }
- if (!check_test_error(t)) {
- test_openssl_errors();
- t->errors++;
- }
- }
- /* clean it up */
- ERR_clear_error();
- if (t->data != NULL) {
- t->meth->cleanup(t);
- OPENSSL_free(t->data);
- t->data = NULL;
- }
- clear_test(t);
- }
- t->meth = tmeth;
- return 1;
-}
-
-static int find_key(EVP_PKEY **ppk, const char *name, KEY_LIST *lst)
-{
- for (; lst; lst = lst->next) {
- if (strcmp(lst->name, name) == 0) {
- if (ppk)
- *ppk = lst->key;
- return 1;
- }
- }
- return 0;
-}
-
-static void free_key_list(KEY_LIST *lst)
-{
- while (lst != NULL) {
- KEY_LIST *ltmp;
-
- EVP_PKEY_free(lst->key);
- OPENSSL_free(lst->name);
- ltmp = lst->next;
- OPENSSL_free(lst);
- lst = ltmp;
- }
-}
-
-static int check_unsupported()
-{
- long err = ERR_peek_error();
-
- if (ERR_GET_LIB(err) == ERR_LIB_EVP
- && ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM) {
- ERR_clear_error();
- return 1;
- }
-#ifndef OPENSSL_NO_EC
- /*
- * If EC support is enabled we should catch also EC_R_UNKNOWN_GROUP as an
- * hint to an unsupported algorithm/curve (e.g. if binary EC support is
- * disabled).
- */
- if (ERR_GET_LIB(err) == ERR_LIB_EC
- && ERR_GET_REASON(err) == EC_R_UNKNOWN_GROUP) {
- ERR_clear_error();
- return 1;
- }
-#endif /* OPENSSL_NO_EC */
- return 0;
-}
-
-
-static int read_key(EVP_TEST *t)
-{
- char tmpbuf[80];
-
- if (t->key == NULL) {
- if (!TEST_ptr(t->key = BIO_new(BIO_s_mem())))
- return 0;
- } else if (!TEST_int_gt(BIO_reset(t->key), 0)) {
- return 0;
- }
-
- /* Read to PEM end line and place content in memory BIO */
- while (BIO_gets(t->in, tmpbuf, sizeof(tmpbuf))) {
- t->line++;
- if (!TEST_int_gt(BIO_puts(t->key, tmpbuf), 0))
- return 0;
- if (strncmp(tmpbuf, "-----END", 8) == 0)
- return 1;
- }
- TEST_error("Can't find key end");
- return 0;
-}
-
-/*
- * Parse a line into the current test |t|. Return 0 on error.
- */
-static int parse_test_line(EVP_TEST *t, char *buf)
-{
- char *keyword = NULL, *value = NULL;
- int add_key = 0;
- KEY_LIST **lst = NULL, *key = NULL;
- EVP_PKEY *pk = NULL;
- const EVP_TEST_METHOD *tmeth = NULL;
-
- if (!parse_line(&keyword, &value, buf))
- return 1;
- if (strcmp(keyword, "PrivateKey") == 0) {
- if (!read_key(t))
- return 0;
- pk = PEM_read_bio_PrivateKey(t->key, NULL, 0, NULL);
- if (pk == NULL && !check_unsupported()) {
- TEST_info("Error reading private key %s", value);
- ERR_print_errors_fp(stderr);
- return 0;
- }
- lst = &private_keys;
- add_key = 1;
- }
- if (strcmp(keyword, "PublicKey") == 0) {
- if (!read_key(t))
- return 0;
- pk = PEM_read_bio_PUBKEY(t->key, NULL, 0, NULL);
- if (pk == NULL && !check_unsupported()) {
- TEST_info("Error reading public key %s", value);
- ERR_print_errors_fp(stderr);
- return 0;
- }
- lst = &public_keys;
- add_key = 1;
- }
- /* If we have a key add to list */
- if (add_key) {
- if (find_key(NULL, value, *lst)) {
- TEST_info("Duplicate key %s", value);
- return 0;
- }
- if (!TEST_ptr(key = OPENSSL_malloc(sizeof(*key)))
- || !TEST_ptr(key->name = OPENSSL_strdup(value)))
- return 0;
- key->key = pk;
- key->next = *lst;
- *lst = key;
- return 1;
- }
-
- /* See if keyword corresponds to a test start */
- if ((tmeth = evp_find_test(keyword)) != NULL) {
- if (!run_and_get_next(t, tmeth))
- return 0;
- t->start_line = t->line;
- t->skip = 0;
- if (!tmeth->init(t, value)) {
- TEST_info("Unknown %s: %s", keyword, value);
- return 0;
- }
- return 1;
- }
- if (t->skip)
- return 1;
- if (strcmp(keyword, "Title") == 0) {
- TEST_info("Starting %s tests", value);
- set_test_title(value);
- } else if (strcmp(keyword, "Result") == 0) {
- if (t->expected_err != NULL) {
- TEST_info("Line %d: multiple result lines", t->line);
- return 0;
- }
- if (!TEST_ptr(t->expected_err = OPENSSL_strdup(value)))
- return 0;
- } else if (strcmp(keyword, "Function") == 0) {
- if (t->func != NULL) {
- TEST_info("Line %d: multiple function lines\n", t->line);
- return 0;
- }
- if (!TEST_ptr(t->func = OPENSSL_strdup(value)))
- return 0;
- } else if (strcmp(keyword, "Reason") == 0) {
- if (t->reason != NULL) {
- TEST_info("Line %d: multiple reason lines", t->line);
- return 0;
- }
- if (!TEST_ptr(t->reason = OPENSSL_strdup(value)))
- return 0;
- } else {
- /* Must be test specific line: try to parse it */
- int rv = t->meth == NULL ? 0 : t->meth->parse(t, keyword, value);
-
- if (rv == 0) {
- TEST_info("Line %d: unknown keyword %s", t->line, keyword);
- return 0;
- }
- if (rv < 0) {
- TEST_info("Line %d: error processing keyword %s\n",
- t->line, keyword);
- return 0;
- }
- }
- return 1;
-}