瀏覽代碼

Revert "Move password buffer into the library"

This reverts commit d840323bc1d3bc35bc72271e55ffa644f02b4582
Steffen Jaeckel 1 年之前
父節點
當前提交
02cb0c4957

+ 13 - 10
demos/openssh-privkey.c

@@ -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)

+ 0 - 4
src/headers/tomcrypt_custom.h

@@ -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

+ 8 - 3
src/headers/tomcrypt_pk.h

@@ -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;

+ 10 - 9
src/headers/tomcrypt_private.h

@@ -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;

+ 0 - 3
src/misc/crypt/crypt.c

@@ -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) " "

+ 1 - 1
src/misc/pbes/pbes.c

@@ -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;

+ 7 - 4
src/misc/pem/pem_pkcs.c

@@ -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;

+ 3 - 4
src/misc/pem/pem_ssh.c

@@ -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);

+ 7 - 5
src/pk/asn1/pkcs8/pkcs8_decode_flexi.c

@@ -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);

+ 3 - 5
tests/ecc_test.c

@@ -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) {

+ 3 - 5
tests/ed25519_test.c

@@ -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)

+ 6 - 10
tests/pem_test.c

@@ -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)

+ 3 - 5
tests/rsa_test.c

@@ -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)

+ 5 - 8
tests/x25519_test.c

@@ -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;