Revert "Move password buffer into the library"

This reverts commit d840323bc1d3bc35bc72271e55ffa644f02b4582
This commit is contained in:
Steffen Jaeckel 2023-10-19 11:55:11 +02:00
parent 9db30dfdc5
commit 02cb0c4957
14 changed files with 69 additions and 76 deletions

View file

@ -29,11 +29,15 @@ static void die_(int err, int line)
#define die(i) do { die_(i, __LINE__); } while(0)
#define DIE(s, ...) do { print_err("%3d: " s "\n", __LINE__, ##__VA_ARGS__); exit(EXIT_FAILURE); } while(0)
static int getpassword(const char *prompt, char *pass, unsigned long *len)
static char* getpassword(const char *prompt, size_t maxlen)
{
char *wr, *end, *pass = XCALLOC(1, maxlen + 1);
struct termios tio;
tcflag_t c_lflag;
unsigned long maxlen = *len, wr = 0;
if (pass == NULL)
return NULL;
wr = pass;
end = pass + maxlen;
tcgetattr(0, &tio);
c_lflag = tio.c_lflag;
@ -42,25 +46,24 @@ static int getpassword(const char *prompt, char *pass, unsigned long *len)
printf("%s", prompt);
fflush(stdout);
while (1) {
while (pass < end) {
int c = getchar();
if (c == '\r' || c == '\n' || c == -1)
break;
if (wr < maxlen)
pass[wr] = c;
wr++;
*wr++ = c;
}
*len = wr;
tio.c_lflag = c_lflag;
tcsetattr(0, TCSAFLUSH, &tio);
printf("\n");
return wr <= maxlen;
return pass;
}
static int password_get(void *p, unsigned long *l, void *u)
static int password_get(void **p, unsigned long *l, void *u)
{
(void)u;
return getpassword("Enter passphrase: ", p, l);
*p = getpassword("Enter passphrase: ", 256);
*l = strlen(*p);
return 0;
}
static void print(ltc_pka_key *k)

View file

@ -627,10 +627,6 @@
#define LTC_PBES
#endif
#if defined(LTC_PEM) || defined(LTC_PKCS_8) && !defined(LTC_MAX_PASSWORD_LEN)
#define LTC_MAX_PASSWORD_LEN 256
#endif
#if defined(LTC_CLEAN_STACK)
/* if you're sure that you want to use it, remove the line below */
#error LTC_CLEAN_STACK is considered as broken

View file

@ -5,12 +5,17 @@ typedef struct {
/**
Callback function that is called when a password is required.
@param str Pointer to where the password shall be stored.
@param len [in/out] The max length resp. resulting length of the password.
Please be aware that the library takes ownership of the pointer that is
returned to the library via `str`.
`str` shall be allocated via the same function as `XMALLOC` points to.
The data will be zeroed and `XFREE`'d as soon as it isn't required anymore.
@param str Pointer to pointer where the password will be stored.
@param len Pointer to the length of the password.
@param userdata `userdata` that was passed in the `password_ctx` struct.
@return CRYPT_OK on success
*/
int (*callback)(void *str, unsigned long *len, void *userdata);
int (*callback)(void **str, unsigned long *len, void *userdata);
/** Opaque `userdata` pointer passed when the callback is called */
void *userdata;
} password_ctx;

View file

@ -83,18 +83,11 @@ typedef struct {
unsigned long blocklen;
} pbes_properties;
struct password {
/* usually a `char*` but could also contain binary data
* so use a `void*` + length to be on the safe side.
*/
unsigned char pw[LTC_MAX_PASSWORD_LEN];
unsigned long l;
};
typedef struct
{
pbes_properties type;
struct password pwd;
void *pwd;
unsigned long pwdlen;
ltc_asn1_list *enc_data;
ltc_asn1_list *salt;
ltc_asn1_list *iv;
@ -266,6 +259,14 @@ enum cipher_mode {
cm_none, cm_cbc, cm_cfb, cm_ctr, cm_ofb, cm_stream, cm_gcm
};
struct password {
/* usually a `char*` but could also contain binary data
* so use a `void*` + length to be on the safe side.
*/
void *pw;
unsigned long l;
};
struct blockcipher_info {
const char *name;
const char *algo;

View file

@ -470,9 +470,6 @@ const char *crypt_build_settings =
" PBES1 "
" PBES2 "
#endif
#if defined(LTC_MAX_PASSWORD_LEN)
" " NAME_VALUE(LTC_MAX_PASSWORD_LEN) " "
#endif
#if defined(LTC_PEM)
" PEM "
" " NAME_VALUE(LTC_PEM_DECODE_BUFSZ) " "

View file

@ -50,7 +50,7 @@ int pbes_decrypt(const pbes_arg *arg, unsigned char *dec_data, unsigned long *d
if (klen > sizeof(k)) return CRYPT_INVALID_ARG;
if ((err = arg->type.kdf(arg->pwd.pw, arg->pwd.l, arg->salt->data, arg->salt->size, arg->iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR;
if ((err = arg->type.kdf(arg->pwd, arg->pwdlen, arg->salt->data, arg->salt->size, arg->iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR;
if ((err = cbc_start(cid, iv, k, keylen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR;
if ((err = cbc_decrypt(arg->enc_data->data, dec_data, arg->enc_data->size, &cbc)) != CRYPT_OK) goto LBL_ERROR;
if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR;

View file

@ -25,6 +25,9 @@ static int s_decrypt_pem(unsigned char *pem, unsigned long *l, const struct pem_
if (hdr->info.keylen > sizeof(key)) {
return CRYPT_BUFFER_OVERFLOW;
}
if (!hdr->pw->pw) {
return CRYPT_INVALID_ARG;
}
ivlen = sizeof(iv);
if ((err = base16_decode(hdr->info.iv, XSTRLEN(hdr->info.iv), iv, &ivlen)) != CRYPT_OK) {
@ -199,7 +202,7 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c
unsigned long w, l, n;
int err = CRYPT_ERROR;
struct pem_headers hdr = { 0 };
struct password pw = { 0 };
struct password pw;
enum ltc_pka_id pka;
XMEMSET(k, 0, sizeof(*k));
w = LTC_PEM_READ_BUFSIZE * 2;
@ -238,8 +241,7 @@ retry:
}
hdr.pw = &pw;
hdr.pw->l = LTC_MAX_PASSWORD_LEN;
if (pw_ctx->callback(hdr.pw->pw, &hdr.pw->l, pw_ctx->userdata)) {
if (pw_ctx->callback(&hdr.pw->pw, &hdr.pw->l, pw_ctx->userdata)) {
err = CRYPT_ERROR;
goto cleanup;
}
@ -264,7 +266,8 @@ retry:
cleanup:
if (hdr.pw) {
zeromem(hdr.pw->pw, sizeof(hdr.pw->pw));
zeromem(hdr.pw->pw, hdr.pw->l);
XFREE(hdr.pw->pw);
}
XFREE(pem);
return err;

View file

@ -570,8 +570,7 @@ retry:
err = CRYPT_PW_CTX_MISSING;
goto cleanup;
}
opts.pw.l = LTC_MAX_PASSWORD_LEN;
if (pw_ctx->callback(opts.pw.pw, &opts.pw.l, pw_ctx->userdata)) {
if (pw_ctx->callback(&opts.pw.pw, &opts.pw.l, pw_ctx->userdata)) {
err = CRYPT_ERROR;
goto cleanup;
}
@ -590,8 +589,8 @@ retry:
}
cleanup:
if (opts.pw.l) {
zeromem(&opts.pw, sizeof(opts.pw));
if (opts.pw.pw) {
XFREE(opts.pw.pw);
}
if (privkey) {
zeromem(privkey, privkey_len);

View file

@ -23,11 +23,13 @@ int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
unsigned char *dec_data = NULL;
ltc_asn1_list *l = NULL;
int err;
pbes_arg pbes = { 0 };
pbes_arg pbes;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(decoded_list != NULL);
XMEMSET(&pbes, 0, sizeof(pbes));
*decoded_list = NULL;
if ((err = der_decode_sequence_flexi(in, &len, &l)) == CRYPT_OK) {
/* the following "if" detects whether it is encrypted or not */
@ -61,8 +63,7 @@ int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
goto LBL_DONE;
}
pbes.pwd.l = LTC_MAX_PASSWORD_LEN;
if (pw_ctx->callback(pbes.pwd.pw, &pbes.pwd.l, pw_ctx->userdata)) {
if (pw_ctx->callback(&pbes.pwd, &pbes.pwdlen, pw_ctx->userdata)) {
err = CRYPT_ERROR;
goto LBL_DONE;
}
@ -94,8 +95,9 @@ int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
LBL_DONE:
if (l) der_free_sequence_flexi(l);
if (pbes.pwd.l) {
zeromem(&pbes.pwd, sizeof(pbes.pwd));
if (pbes.pwd) {
zeromem(pbes.pwd, pbes.pwdlen);
XFREE(pbes.pwd);
}
if (dec_data) {
zeromem(dec_data, dec_size);

View file

@ -660,14 +660,12 @@ static int s_ecc_new_api(void)
}
static int password_get(void *p, unsigned long *l, void *u)
static int password_get(void **p, unsigned long *l, void *u)
{
int ret = *l < 6;
LTC_UNUSED_PARAM(u);
if (!ret)
XMEMCPY(p, "secret", 6);
*p = strdup("secret");
*l = 6;
return ret;
return 0;
}
static int s_ecc_import_export(void) {

View file

@ -16,14 +16,12 @@ static void xor_shuffle(unsigned char *buf, unsigned long size, unsigned char ch
buf[i] ^= change;
}
static int password_get(void *p, unsigned long *l, void *u)
static int password_get(void **p, unsigned long *l, void *u)
{
int ret = *l < 6;
LTC_UNUSED_PARAM(u);
if (!ret)
XMEMCPY(p, "123456", 6);
*p = strdup("123456");
*l = 6;
return ret;
return 0;
}
static int s_rfc_8410_10_test(void)

View file

@ -6,14 +6,12 @@
#ifdef LTC_SSH
static int password_get_ssh(void *p, unsigned long *l, void *u)
static int password_get_ssh(void **p, unsigned long *l, void *u)
{
int ret = *l < 6;
LTC_UNUSED_PARAM(u);
if (!ret)
XMEMCPY(p, "abc123", 6);
*p = strdup("abc123");
*l = 6;
return ret;
return 0;
}
static int s_pem_decode_ssh(const void *in, unsigned long inlen, void *key)
{
@ -30,14 +28,12 @@ static int s_pem_decode_ssh_f(FILE *f, void *key)
#endif
static int password_get(void *p, unsigned long *l, void *u)
static int password_get(void **p, unsigned long *l, void *u)
{
int ret = *l < 6;
LTC_UNUSED_PARAM(u);
if (!ret)
XMEMCPY(p, "secret", 6);
*p = strdup("secret");
*l = 6;
return ret;
return 0;
}
#if defined(LTC_MDSA)

View file

@ -432,14 +432,12 @@ static int s_rsa_import_x509(const void *in, unsigned long inlen, void *key)
}
#if defined(LTC_MD2) && defined(LTC_MD5) && defined(LTC_RC2)
static int password_get(void *p, unsigned long *l, void *u)
static int password_get(void **p, unsigned long *l, void *u)
{
int ret = *l < 6;
LTC_UNUSED_PARAM(u);
if (!ret)
XMEMCPY(p, "secret", 6);
*p = strdup("secret");
*l = 6;
return ret;
return 0;
}
static int s_rsa_import_pkcs8(const void *in, unsigned long inlen, void *key)

View file

@ -139,14 +139,11 @@ static int s_rfc_8410_10_test(void)
return CRYPT_OK;
}
static int password_get(void *p, unsigned long *l, void *u)
static int password_get(void **p, unsigned long *l, void *u)
{
unsigned long sl = strlen(u);
int ret = *l < sl;
if (!ret)
XMEMCPY(p, u, sl);
*l = sl;
return ret;
*p = strdup(u);
*l = strlen(*p);
return 0;
}
static int s_x25519_pkcs8_test(void)
@ -165,7 +162,7 @@ static int s_x25519_pkcs8_test(void)
/* `openssl genpkey -algorithm x25519 -pass stdin` */
{
"MC4CAQAwBQYDK2VuBCIEIEAInaUdx+fQFfghpCzw/WdItRT3+FnPSkrU9TcIZTZW",
""
NULL
},
};
unsigned n;