Browse Source

clean-up a bit

* more `const` correctness
* take `LTC_NO_FILE` into account
* only declare `extern` variables where they're required
* ensure keys don't contain stale data
* ensure input arguments are valid
* add `CRYPT_PW_CTX_MISSING` error code
* fix documentation

Signed-off-by: Steffen Jaeckel <[email protected]>
Steffen Jaeckel 3 years ago
parent
commit
4e46f823df

+ 2 - 1
src/headers/tomcrypt.h

@@ -72,7 +72,8 @@ enum {
    CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
    CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
    CRYPT_PK_INVALID_PADDING, /* Invalid padding on input */
    CRYPT_PK_INVALID_PADDING, /* Invalid padding on input */
 
 
-   CRYPT_HASH_OVERFLOW      /* Hash applied to too many bits */
+   CRYPT_HASH_OVERFLOW,     /* Hash applied to too many bits */
+   CRYPT_PW_CTX_MISSING,    /* Password context to decrypt key file is missing */
 };
 };
 
 
 #include "tomcrypt_cfg.h"
 #include "tomcrypt_cfg.h"

+ 4 - 4
src/headers/tomcrypt_misc.h

@@ -160,12 +160,12 @@ int padding_depad(const unsigned char *data, unsigned long *length, unsigned lon
 #endif  /* LTC_PADDING */
 #endif  /* LTC_PADDING */
 
 
 #ifdef LTC_PEM
 #ifdef LTC_PEM
-int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, password_ctx *pw_ctx);
-int pem_decode_pkcs(const void *buf, unsigned long len, ltc_pka_key *k, password_ctx *pw_ctx);
+int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx);
+int pem_decode_pkcs(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx);
 
 
 #ifdef LTC_SSH
 #ifdef LTC_SSH
-int pem_decode_openssh_filehandle(FILE *f, ltc_pka_key *k, password_ctx *pw_ctx);
-int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, password_ctx *pw_ctx);
+int pem_decode_openssh_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx);
+int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx);
 #endif
 #endif
 
 
 #endif /* LTC_PEM */
 #endif /* LTC_PEM */

+ 4 - 7
src/headers/tomcrypt_private.h

@@ -306,13 +306,6 @@ struct pem_headers {
    struct password *pw;
    struct password *pw;
 };
 };
 
 
-extern const struct pem_header_id pem_std_headers[];
-extern const unsigned long pem_std_headers_num;
-extern const struct str pem_proc_type_encrypted;
-extern const struct str pem_dek_info_start;
-extern const struct dek_info_from_str pem_dek_infos[];
-extern const unsigned long pem_dek_infos_num;
-
 struct bufp {
 struct bufp {
    /* `end` points to one byte after the last
    /* `end` points to one byte after the last
     * element of the allocated buffer
     * element of the allocated buffer
@@ -325,7 +318,9 @@ struct bufp {
 struct get_char {
 struct get_char {
    int (*get)(struct get_char*);
    int (*get)(struct get_char*);
    union {
    union {
+#ifndef LTC_NO_FILE
       FILE *f;
       FILE *f;
+#endif /* LTC_NO_FILE */
       struct bufp buf;
       struct bufp buf;
    };
    };
    struct str unget_buf;
    struct str unget_buf;
@@ -342,7 +337,9 @@ int pbes_decrypt(const pbes_arg  *arg, unsigned char *dec_data, unsigned long *d
 int pbes1_extract(const ltc_asn1_list *s, pbes_arg *res);
 int pbes1_extract(const ltc_asn1_list *s, pbes_arg *res);
 int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res);
 int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res);
 
 
+#ifndef LTC_NO_FILE
 int pem_get_char_from_file(struct get_char *g);
 int pem_get_char_from_file(struct get_char *g);
+#endif /* LTC_NO_FILE */
 int pem_get_char_from_buf(struct get_char *g);
 int pem_get_char_from_buf(struct get_char *g);
 int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_char *g);
 int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_char *g);
 
 

+ 2 - 0
src/misc/error_to_string.c

@@ -51,6 +51,8 @@ static const char * const err_2_str[] =
    "Invalid padding.",
    "Invalid padding.",
 
 
    "Hash applied to too many bits.",
    "Hash applied to too many bits.",
+
+   "Password context to decrypt key file is missing.",
 };
 };
 
 
 /**
 /**

+ 14 - 5
src/misc/pem/pem_pkcs.c

@@ -9,6 +9,9 @@
 
 
 #ifdef LTC_PEM
 #ifdef LTC_PEM
 
 
+extern const struct pem_header_id pem_std_headers[];
+extern const unsigned long pem_std_headers_num;
+
 static int s_decrypt_pem(unsigned char *pem, unsigned long *l, const struct pem_headers *hdr)
 static int s_decrypt_pem(unsigned char *pem, unsigned long *l, const struct pem_headers *hdr)
 {
 {
    unsigned char iv[MAXBLOCKSIZE], key[MAXBLOCKSIZE];
    unsigned char iv[MAXBLOCKSIZE], key[MAXBLOCKSIZE];
@@ -58,7 +61,7 @@ typedef struct {
    pkcs8_import fn;
    pkcs8_import fn;
 } p8_import_st;
 } p8_import_st;
 
 
-static int s_decode(struct get_char *g, ltc_pka_key *k, password_ctx *pw_ctx)
+static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx)
 {
 {
    unsigned char *pem = NULL;
    unsigned char *pem = NULL;
    unsigned long w, l, n;
    unsigned long w, l, n;
@@ -66,6 +69,7 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, password_ctx *pw_ctx)
    struct pem_headers hdr = { 0 };
    struct pem_headers hdr = { 0 };
    struct password pw;
    struct password pw;
    ltc_asn1_list *p8_asn1 = NULL;
    ltc_asn1_list *p8_asn1 = NULL;
+   XMEMSET(k, 0, sizeof(*k));
    w = LTC_PEM_READ_BUFSIZE * 2;
    w = LTC_PEM_READ_BUFSIZE * 2;
 retry:
 retry:
    pem = XREALLOC(pem, w);
    pem = XREALLOC(pem, w);
@@ -132,8 +136,10 @@ retry:
       }
       }
       goto cleanup;
       goto cleanup;
    } else if (hdr.encrypted) {
    } else if (hdr.encrypted) {
-      LTC_ARGCHK(pw_ctx           != NULL);
-      LTC_ARGCHK(pw_ctx->callback != NULL);
+      if ((pw_ctx == NULL) || (pw_ctx->callback == NULL)) {
+         err = CRYPT_PW_CTX_MISSING;
+         goto cleanup;
+      }
 
 
       hdr.pw = &pw;
       hdr.pw = &pw;
       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)) {
@@ -181,7 +187,8 @@ cleanup:
    return err;
    return err;
 }
 }
 
 
-int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, password_ctx *pw_ctx)
+#ifndef LTC_NO_FILE
+int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx)
 {
 {
    LTC_ARGCHK(f != NULL);
    LTC_ARGCHK(f != NULL);
    LTC_ARGCHK(k != NULL);
    LTC_ARGCHK(k != NULL);
@@ -190,10 +197,12 @@ int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, password_ctx *pw_ctx)
       return s_decode(&g, k, pw_ctx);
       return s_decode(&g, k, pw_ctx);
    }
    }
 }
 }
+#endif /* LTC_NO_FILE */
 
 
-int pem_decode_pkcs(const void *buf, unsigned long len, ltc_pka_key *k, password_ctx *pw_ctx)
+int pem_decode_pkcs(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx)
 {
 {
    LTC_ARGCHK(buf != NULL);
    LTC_ARGCHK(buf != NULL);
+   LTC_ARGCHK(len != 0);
    LTC_ARGCHK(k != NULL);
    LTC_ARGCHK(k != NULL);
    {
    {
       struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.buf, buf, len) };
       struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.buf, buf, len) };

+ 7 - 0
src/misc/pem/pem_read.c

@@ -9,10 +9,17 @@
 
 
 #ifdef LTC_PEM
 #ifdef LTC_PEM
 
 
+extern const struct str pem_proc_type_encrypted;
+extern const struct str pem_dek_info_start;
+extern const struct dek_info_from_str pem_dek_infos[];
+extern const unsigned long pem_dek_infos_num;
+
+#ifndef LTC_NO_FILE
 int pem_get_char_from_file(struct get_char *g)
 int pem_get_char_from_file(struct get_char *g)
 {
 {
    return getc(g->f);
    return getc(g->f);
 }
 }
+#endif /* LTC_NO_FILE */
 
 
 int pem_get_char_from_buf(struct get_char *g)
 int pem_get_char_from_buf(struct get_char *g)
 {
 {

+ 21 - 10
src/misc/pem/pem_ssh.c

@@ -344,13 +344,14 @@ static const struct pem_header_id pem_openssh =
      .has_more_headers = 0
      .has_more_headers = 0
    };
    };
 
 
-static int s_decode_openssh(struct get_char *g, ltc_pka_key *k, password_ctx *pw_ctx)
+static int s_decode_openssh(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx)
 {
 {
    unsigned char *pem = NULL, *p, *privkey = NULL;
    unsigned char *pem = NULL, *p, *privkey = NULL;
    unsigned long w, l, privkey_len;
    unsigned long w, l, privkey_len;
    int err;
    int err;
    struct pem_headers hdr = { .id = &pem_openssh };
    struct pem_headers hdr = { .id = &pem_openssh };
    struct kdf_options opts = { 0 };
    struct kdf_options opts = { 0 };
+   XMEMSET(k, 0, sizeof(*k));
    w = LTC_PEM_READ_BUFSIZE * 2;
    w = LTC_PEM_READ_BUFSIZE * 2;
 retry:
 retry:
    pem = XREALLOC(pem, w);
    pem = XREALLOC(pem, w);
@@ -378,9 +379,8 @@ retry:
    }
    }
 
 
    if (XSTRCMP(opts.name, "none") != 0) {
    if (XSTRCMP(opts.name, "none") != 0) {
-      /* hard-coded pass for demo keys */
-      if (!pw_ctx || !pw_ctx->callback) {
-         err = CRYPT_INVALID_ARG;
+      if ((pw_ctx == NULL) || (pw_ctx->callback == NULL)) {
+         err = CRYPT_PW_CTX_MISSING;
          goto cleanup;
          goto cleanup;
       }
       }
       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)) {
@@ -411,16 +411,27 @@ cleanup:
    return err;
    return err;
 }
 }
 
 
-int pem_decode_openssh_filehandle(FILE *f, ltc_pka_key *k, password_ctx *pw_ctx)
+#ifndef LTC_NO_FILE
+int pem_decode_openssh_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx)
 {
 {
-   struct get_char g = { .get = pem_get_char_from_file, .f = f };
-   return s_decode_openssh(&g, k, pw_ctx);
+   LTC_ARGCHK(f != NULL);
+   LTC_ARGCHK(k != NULL);
+   {
+      struct get_char g = { .get = pem_get_char_from_file, .f = f };
+      return s_decode_openssh(&g, k, pw_ctx);
+   }
 }
 }
+#endif /* LTC_NO_FILE */
 
 
-int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, password_ctx *pw_ctx)
+int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx)
 {
 {
-   struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.buf, buf, len) };
-   return s_decode_openssh(&g, k, pw_ctx);
+   LTC_ARGCHK(buf != NULL);
+   LTC_ARGCHK(len != 0);
+   LTC_ARGCHK(k != NULL);
+   {
+      struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.buf, buf, len) };
+      return s_decode_openssh(&g, k, pw_ctx);
+   }
 }
 }
 
 
 #endif /* defined(LTC_PEM_SSH) */
 #endif /* defined(LTC_PEM_SSH) */

+ 4 - 2
src/pk/asn1/pkcs8/pkcs8_decode_flexi.c

@@ -48,8 +48,10 @@ int pkcs8_decode_flexi(const unsigned char  *in,  unsigned long inlen,
           LTC_ASN1_IS_TYPE(l->child->next, LTC_ASN1_OCTET_STRING)) {
           LTC_ASN1_IS_TYPE(l->child->next, LTC_ASN1_OCTET_STRING)) {
          ltc_asn1_list *lalgoid = l->child->child;
          ltc_asn1_list *lalgoid = l->child->child;
 
 
-         LTC_ARGCHK(pw_ctx           != NULL);
-         LTC_ARGCHK(pw_ctx->callback != NULL);
+         if ((pw_ctx == NULL) || (pw_ctx->callback == NULL)) {
+            err = CRYPT_PW_CTX_MISSING;
+            goto LBL_DONE;
+         }
 
 
          if (pbes1_extract(lalgoid, &pbes) == CRYPT_OK) {
          if (pbes1_extract(lalgoid, &pbes) == CRYPT_OK) {
             /* Successfully extracted PBES1 parameters */
             /* Successfully extracted PBES1 parameters */

+ 1 - 1
src/pk/rsa/rsa_key.c

@@ -81,7 +81,7 @@ void rsa_shrink_key(rsa_key *key)
 
 
 /**
 /**
   Init an RSA key
   Init an RSA key
-  @param key   The RSA key to free
+  @param key   The RSA key to initialize
   @return CRYPT_OK if successful
   @return CRYPT_OK if successful
 */
 */
 int rsa_init(rsa_key *key)
 int rsa_init(rsa_key *key)