195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (c) 2014, Google Inc.
295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Permission to use, copy, modify, and/or distribute this software for any
495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * purpose with or without fee is hereby granted, provided that the above
595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copyright notice and this permission notice appear in all copies.
695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <stdio.h>
1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
17a70c75cfc0ca32a43985e3f24d737ca9cafcb910David Benjamin#include <openssl/crypto.h>
1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h>
1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h>
2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
22c44d2f4cb8a892a603edbbe710fa82bcd30f9cb5David Benjaminstatic int test_overflow(void) {
2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  unsigned i;
2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  for (i = 0; i < ERR_NUM_ERRORS*2; i++) {
2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    ERR_put_error(1, 2, 3, "test", 1);
2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  for (i = 0; i < ERR_NUM_ERRORS - 1; i++) {
3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (ERR_get_error() == 0) {
3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      fprintf(stderr, "ERR_get_error failed at %u\n", i);
3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      return 0;
3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (ERR_get_error() != 0) {
3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    fprintf(stderr, "ERR_get_error more than the expected number of values.\n");
3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return 0;
3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return 1;
4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
44c44d2f4cb8a892a603edbbe710fa82bcd30f9cb5David Benjaminstatic int test_put_error(void) {
4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  uint32_t packed_error;
4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  int line, flags;
4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  const char *file;
4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  char *data;
4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (ERR_get_error() != 0) {
5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    fprintf(stderr, "ERR_get_error returned value before an error was added.\n");
5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return 0;
5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  ERR_put_error(1, 2, 3, "test", 4);
5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  ERR_add_error_data(1, "testing");
5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (strcmp(file, "test") != 0 ||
6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      line != 4 ||
6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      (flags & ERR_FLAG_STRING) == 0 ||
6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      (flags & ERR_FLAG_MALLOCED) == 0 ||
6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      ERR_GET_LIB(packed_error) != 1 ||
6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      ERR_GET_FUNC(packed_error) != 2 ||
6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      ERR_GET_REASON(packed_error) != 3 ||
6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      strcmp(data, "testing") != 0) {
6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    fprintf(stderr, "Bad error data returned.\n");
6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return 0;
6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  OPENSSL_free(data);
7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return 1;
7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
76c44d2f4cb8a892a603edbbe710fa82bcd30f9cb5David Benjaminstatic int test_clear_error(void) {
7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (ERR_get_error() != 0) {
7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    fprintf(stderr, "ERR_get_error returned value before an error was added.\n");
7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return 0;
8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  ERR_put_error(1, 2, 3, "test", 4);
8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  ERR_clear_error();
8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (ERR_get_error() != 0) {
8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    fprintf(stderr, "Error remained after clearing.\n");
8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return 0;
8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return 1;
9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
93c44d2f4cb8a892a603edbbe710fa82bcd30f9cb5David Benjaminstatic int test_print(void) {
9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  size_t i;
9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  char buf[256];
9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  uint32_t packed_error;
9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  ERR_put_error(1, 2, 3, "test", 4);
9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  ERR_add_error_data(1, "testing");
10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  packed_error = ERR_get_error();
10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  for (i = 0; i <= sizeof(buf); i++) {
10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    ERR_error_string_n(packed_error, buf, i);
10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return 1;
10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
109c44d2f4cb8a892a603edbbe710fa82bcd30f9cb5David Benjaminstatic int test_release(void) {
11003d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley  ERR_put_error(1, 2, 3, "test", 4);
11103d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley  ERR_remove_thread_state(NULL);
112f476d30debeb6e4f3e71ad6c4cbbfb592c9ed39eAdam Langley  return 1;
11303d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley}
11403d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley
115c44d2f4cb8a892a603edbbe710fa82bcd30f9cb5David Benjaminint main(void) {
116a70c75cfc0ca32a43985e3f24d737ca9cafcb910David Benjamin  CRYPTO_library_init();
117a70c75cfc0ca32a43985e3f24d737ca9cafcb910David Benjamin
11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (!test_overflow() ||
11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      !test_put_error() ||
12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      !test_clear_error() ||
12103d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley      !test_print() ||
12203d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley      !test_release()) {
12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return 1;
12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  printf("PASS\n");
12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return 0;
12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
129