Add ERR_set_error_data for compatibility.

rust-openssl, rather than using Rust's existing error types, exposes the
OpenSSL error queue as the error type in its public callback types.
Supporting a simplified version of ERR_set_error_data is simple enough,
so it's easiest just to add this function.

Unlike OpenSSL's, we don't attempt to support non-string error data. We
also don't try to retain borrowed pointers. If the caller did not pass
ownership, make a copy internally.

Change-Id: I909eebc2867ab1f3b9975546a106ee1f762bf516
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50625
Reviewed-by: Adam Langley <agl@google.com>
fips-20220613
David Benjamin 3 years ago committed by Adam Langley
parent cd0b767492
commit 731d6cbef9
  1. 16
      crypto/err/err.c
  2. 11
      crypto/err/err_test.cc
  3. 21
      include/openssl/err.h

@ -745,6 +745,22 @@ void ERR_add_error_dataf(const char *format, ...) {
err_set_error_data(buf);
}
void ERR_set_error_data(char *data, int flags) {
if (!(flags & ERR_FLAG_STRING)) {
// We do not support non-string error data.
assert(0);
return;
}
if (flags & ERR_FLAG_MALLOCED) {
err_set_error_data(data);
} else {
char *copy = OPENSSL_strdup(data);
if (copy != NULL) {
err_set_error_data(copy);
}
}
}
int ERR_set_mark(void) {
ERR_STATE *const state = err_get_state();

@ -75,6 +75,17 @@ TEST(ErrTest, PutError) {
EXPECT_EQ(1, ERR_GET_LIB(packed_error));
EXPECT_EQ(2, ERR_GET_REASON(packed_error));
EXPECT_STREQ("testing", data);
ERR_put_error(1, 0 /* unused */, 2, "test", 4);
ERR_set_error_data(const_cast<char *>("testing"), ERR_FLAG_STRING);
packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
EXPECT_STREQ("testing", data);
ERR_put_error(1, 0 /* unused */, 2, "test", 4);
bssl::UniquePtr<char> str(OPENSSL_strdup("testing"));
ERR_set_error_data(str.release(), ERR_FLAG_STRING | ERR_FLAG_MALLOCED);
packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
EXPECT_STREQ("testing", data);
}
TEST(ErrTest, ClearError) {

@ -183,6 +183,11 @@ OPENSSL_EXPORT uint32_t ERR_get_error_line(const char **file, int *line);
// can be printed. This is always set if |data| is non-NULL.
#define ERR_FLAG_STRING 1
// ERR_FLAG_MALLOCED is passed into |ERR_set_error_data| to indicate that |data|
// was allocated with |OPENSSL_malloc|. It is never returned from
// |ERR_get_error_line_data|.
#define ERR_FLAG_MALLOCED 2
// ERR_get_error_line_data acts like |ERR_get_error_line|, but also returns the
// error-specific data pointer and flags. The flags are a bitwise-OR of
// |ERR_FLAG_*| values. The error-specific data is owned by the error queue
@ -408,9 +413,10 @@ OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf);
// ERR_GET_FUNC returns zero. BoringSSL errors do not report a function code.
#define ERR_GET_FUNC(packed_error) 0
// ERR_TXT_STRING is provided for compatibility with code that assumes that
// it's using OpenSSL.
// ERR_TXT_* are provided for compatibility with code that assumes that it's
// using OpenSSL.
#define ERR_TXT_STRING ERR_FLAG_STRING
#define ERR_TXT_MALLOCED ERR_FLAG_MALLOCED
// Private functions.
@ -444,6 +450,17 @@ OPENSSL_EXPORT void ERR_add_error_data(unsigned count, ...);
OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...)
OPENSSL_PRINTF_FORMAT_FUNC(1, 2);
// ERR_set_error_data sets the data on the most recent error to |data|, which
// must be a NUL-terminated string. |flags| must contain |ERR_FLAG_STRING|. If
// |flags| contains |ERR_FLAG_MALLOCED|, this function takes ownership of
// |data|, which must have been allocated with |OPENSSL_malloc|. Otherwise, it
// saves a copy of |data|.
//
// Note this differs from OpenSSL which, when |ERR_FLAG_MALLOCED| is unset,
// saves the pointer as-is and requires it remain valid for the lifetime of the
// address space.
OPENSSL_EXPORT void ERR_set_error_data(char *data, int flags);
// ERR_NUM_ERRORS is one more than the limit of the number of errors in the
// queue.
#define ERR_NUM_ERRORS 16

Loading…
Cancel
Save