From 0ef8cd2349236febd8d862fb358b6eaa31a64ade Mon Sep 17 00:00:00 2001 From: Don Anderson Date: Mon, 24 Aug 2015 21:18:05 -0400 Subject: WT-1822. Add test to ensure that error codes returned by decrypt during a wiredtiger_open are returned by wiredtiger_open. This requires a special config argument to be passed to the rotn encryptor. --- ext/encryptors/rotn/rotn_encrypt.c | 90 +++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 12 deletions(-) (limited to 'ext') diff --git a/ext/encryptors/rotn/rotn_encrypt.c b/ext/encryptors/rotn/rotn_encrypt.c index 503dcae83a7..372f8c6356b 100644 --- a/ext/encryptors/rotn/rotn_encrypt.c +++ b/ext/encryptors/rotn/rotn_encrypt.c @@ -68,7 +68,7 @@ typedef struct { WT_ENCRYPTOR encryptor; /* Must come first */ - WT_EXTENSION_API *wt_api; /* Extension API */ + WT_EXTENSION_API *wtext; /* Extension API */ int rot_N; /* rotN value */ char *keyid; /* Saved keyid */ @@ -76,6 +76,7 @@ typedef struct { u_char *shift_forw; /* Encrypt shift data from secretkey */ u_char *shift_back; /* Decrypt shift data from secretkey */ size_t shift_len; /* Length of shift* byte arrays */ + int force_error; /* Force a decrypt error for testing */ } ROTN_ENCRYPTOR; /*! [WT_ENCRYPTOR initialization structure] */ @@ -83,6 +84,22 @@ typedef struct { #define CHKSUM_LEN 4 #define IV_LEN 16 +/* + * rotn_error -- + * Display an error from this module in a standard way. + */ +static int +rotn_error(ROTN_ENCRYPTOR *encryptor, WT_SESSION *session, int err, + const char *msg) +{ + WT_EXTENSION_API *wtext; + + wtext = encryptor->wtext; + wtext->err_printf(wtext, session, "rotn encryption: %s: %s", + msg, wtext->strerror(wtext, NULL, err)); + return (err); +} + /* * make_cksum -- * This is where one would call a checksum function on the encrypted @@ -220,14 +237,19 @@ rotn_decrypt(WT_ENCRYPTOR *encryptor, WT_SESSION *session, (void)session; /* Unused */ + /* + * For certain tests, force an error we can recognize. + */ + if (rotn_encryptor->force_error) + return (-1000); + /* * Make sure it is big enough. */ mylen = src_len - (CHKSUM_LEN + IV_LEN); - if (dst_len < mylen) { - fprintf(stderr, "Rotate: ENOMEM ERROR\n"); - return (ENOMEM); - } + if (dst_len < mylen) + return (rotn_error(rotn_encryptor, session, + ENOMEM, "decrypt buffer not big enough")); /* * !!! Most implementations would verify the checksum here. @@ -286,7 +308,7 @@ rotn_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session, const ROTN_ENCRYPTOR *orig; ROTN_ENCRYPTOR *rotn_encryptor; WT_CONFIG_ITEM keyid, secret; - WT_EXTENSION_API *wt_api; + WT_EXTENSION_API *wtext; size_t i, len; int ret, keyid_val; u_char base; @@ -295,7 +317,7 @@ rotn_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session, keyid_val = 0; orig = (const ROTN_ENCRYPTOR *)encryptor; - wt_api = orig->wt_api; + wtext = orig->wtext; if ((rotn_encryptor = calloc(1, sizeof(ROTN_ENCRYPTOR))) == NULL) return (errno); @@ -305,7 +327,7 @@ rotn_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session, /* * Stash the keyid from the configuration string. */ - if ((ret = wt_api->config_get(wt_api, session, encrypt_config, + if ((ret = wtext->config_get(wtext, session, encrypt_config, "keyid", &keyid)) == 0 && keyid.len != 0) { /* * In this demonstration, we expect keyid to be a number. @@ -327,7 +349,7 @@ rotn_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session, * We stash the secret key from the configuration string * and build some shift bytes to make encryption/decryption easy. */ - if ((ret = wt_api->config_get(wt_api, session, encrypt_config, + if ((ret = wtext->config_get(wtext, session, encrypt_config, "secretkey", &secret)) == 0 && secret.len != 0) { len = secret.len; if ((rotn_encryptor->secretkey = malloc(len + 1)) == NULL || @@ -396,6 +418,49 @@ rotn_terminate(WT_ENCRYPTOR *encryptor, WT_SESSION *session) } /*! [WT_ENCRYPTOR terminate] */ +static int +rotn_configure(ROTN_ENCRYPTOR *rotn_encryptor, WT_CONFIG_ARG *config) +{ + WT_CONFIG_ITEM k, v; + WT_CONFIG_PARSER *config_parser; + WT_EXTENSION_API *wtext; /* Extension API */ + int ret, t_ret; + + wtext = rotn_encryptor->wtext; + + /* Get the configuration string. */ + if ((ret = wtext->config_get(wtext, NULL, config, "config", &v)) != 0) + return (rotn_error(rotn_encryptor, NULL, ret, + "WT_EXTENSION_API.config_get")); + + /* Step through the list of configuration options. */ + if ((ret = wtext->config_parser_open( + wtext, NULL, v.str, v.len, &config_parser)) != 0) + return (rotn_error(rotn_encryptor, NULL, ret, + "WT_EXTENSION_API.config_parser_open")); + + while ((ret = config_parser->next(config_parser, &k, &v)) == 0) { + if (strncmp("rotn_force_error", k.str, k.len) == 0 && + strlen("rotn_force_error") == k.len) { + rotn_encryptor->force_error = v.val == 0 ? 0 : 1; + continue; + } + else { + (void)config_parser->close(config_parser); + return (rotn_error(rotn_encryptor, NULL, EINVAL, + "unknown config key")); + } + } + if ((t_ret = config_parser->close(config_parser)) != 0) + return (rotn_error(rotn_encryptor, NULL, t_ret, + "WT_CONFIG_PARSER.close")); + if (ret != WT_NOTFOUND) + return (rotn_error(rotn_encryptor, NULL, ret, + "WT_CONFIG_PARSER.next")); + + return (0); +} + /*! [WT_ENCRYPTOR initialization function] */ /* * wiredtiger_extension_init -- @@ -405,8 +470,7 @@ int wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config) { ROTN_ENCRYPTOR *rotn_encryptor; - - (void)config; /* Unused parameters */ + int ret; if ((rotn_encryptor = calloc(1, sizeof(ROTN_ENCRYPTOR))) == NULL) return (errno); @@ -423,8 +487,10 @@ wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config) rotn_encryptor->encryptor.sizing = rotn_sizing; rotn_encryptor->encryptor.customize = rotn_customize; rotn_encryptor->encryptor.terminate = rotn_terminate; + rotn_encryptor->wtext = connection->get_extension_api(connection); - rotn_encryptor->wt_api = connection->get_extension_api(connection); + if ((ret = rotn_configure(rotn_encryptor, config)) != 0) + return (ret); /* Load the encryptor */ return (connection->add_encryptor( -- cgit v1.2.1