From 06b7a7e416247e4d17f5e9953be2a321855e4178 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Mon, 2 Jun 2025 17:30:58 +0200 Subject: [PATCH 1/9] Extract static function as `x509_get_pka()` Signed-off-by: Steffen Jaeckel --- src/headers/tomcrypt_private.h | 2 ++ src/misc/pem/pem_pkcs.c | 30 ++------------------------ src/pk/asn1/x509/x509_get_pka.c | 38 +++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 src/pk/asn1/x509/x509_get_pka.c diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index fee3c84dd..e33e88de6 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -697,6 +697,8 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i enum ltc_oid_id algorithm, void *public_key, unsigned long *public_key_len, ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); +int x509_get_pka(ltc_asn1_list *pub, enum ltc_pka_id *pka); + int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2); #endif /* LTC_DER */ diff --git a/src/misc/pem/pem_pkcs.c b/src/misc/pem/pem_pkcs.c index e99f29ea0..fc9f63965 100644 --- a/src/misc/pem/pem_pkcs.c +++ b/src/misc/pem/pem_pkcs.c @@ -41,32 +41,6 @@ static int s_decrypt_pem(unsigned char *asn1_cert, unsigned long *asn1_len, cons return err; } -static int s_get_pka(ltc_asn1_list *pub, enum ltc_pka_id *pka) -{ - der_flexi_check flexi_should[4]; - ltc_asn1_list *seqid, *id; - enum ltc_oid_id oid_id; - int err; - unsigned long n = 0; - LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &seqid); - LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_BIT_STRING, NULL); - LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); - if ((err = der_flexi_sequence_cmp(pub, flexi_should)) != CRYPT_OK) { - return err; - } - n = 0; - LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OBJECT_IDENTIFIER, &id); - LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); - err = der_flexi_sequence_cmp(seqid, flexi_should); - if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) { - return err; - } - if ((err = pk_get_oid_from_asn1(id, &oid_id)) != CRYPT_OK) { - return err; - } - return pk_get_pka_id(oid_id, pka); -} - typedef int (*import_fn)(const unsigned char *, unsigned long, void*); static const import_fn s_import_x509_fns[LTC_PKA_NUM] = { @@ -90,7 +64,7 @@ static int s_import_x509(unsigned char *asn1_cert, unsigned long asn1_len, ltc_p if ((err = x509_decode_spki(asn1_cert, asn1_len, &d, &spki)) != CRYPT_OK) { return err; } - err = s_get_pka(spki, &pka); + err = x509_get_pka(spki, &pka); der_free_sequence_flexi(d); if (err != CRYPT_OK) { return err; @@ -171,7 +145,7 @@ static int s_extract_pka(unsigned char *asn1_cert, unsigned long asn1_len, enum if ((err = der_decode_sequence_flexi(asn1_cert, &asn1_len, &pub)) != CRYPT_OK) { return err; } - err = s_get_pka(pub, pka); + err = x509_get_pka(pub, pka); der_sequence_free(pub); return err; } diff --git a/src/pk/asn1/x509/x509_get_pka.c b/src/pk/asn1/x509/x509_get_pka.c new file mode 100644 index 000000000..23a12edd7 --- /dev/null +++ b/src/pk/asn1/x509/x509_get_pka.c @@ -0,0 +1,38 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x509_get_pka.c + Extract the PKA from an X.509 cert, Steffen Jaeckel +*/ + +#ifdef LTC_DER + +int x509_get_pka(ltc_asn1_list *pub, enum ltc_pka_id *pka) +{ + der_flexi_check flexi_should[4]; + ltc_asn1_list *seqid, *id = NULL; + enum ltc_oid_id oid_id; + int err; + unsigned long n = 0; + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &seqid); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_BIT_STRING, NULL); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); + if ((err = der_flexi_sequence_cmp(pub, flexi_should)) != CRYPT_OK) { + return err; + } + n = 0; + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OBJECT_IDENTIFIER, &id); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); + err = der_flexi_sequence_cmp(seqid, flexi_should); + if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) { + return err; + } + if ((err = pk_get_oid_from_asn1(id, &oid_id)) != CRYPT_OK) { + return err; + } + return pk_get_pka_id(oid_id, pka); +} + +#endif /* LTC_DER */ From 002a6c8330484e556dd578d123fd37d6fb265bb6 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 4 Jun 2025 15:28:57 +0200 Subject: [PATCH 2/9] Export static function as `x509_import_spki()` Signed-off-by: Steffen Jaeckel --- src/headers/tomcrypt_private.h | 1 + src/misc/pem/pem_pkcs.c | 41 +-------------------- src/pk/asn1/x509/x509_import_spki.c | 56 +++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 40 deletions(-) create mode 100644 src/pk/asn1/x509/x509_import_spki.c diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index e33e88de6..e7df4027b 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -698,6 +698,7 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); int x509_get_pka(ltc_asn1_list *pub, enum ltc_pka_id *pka); +int x509_import_spki(const unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, ltc_asn1_list **root); int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2); diff --git a/src/misc/pem/pem_pkcs.c b/src/misc/pem/pem_pkcs.c index fc9f63965..d3db284cd 100644 --- a/src/misc/pem/pem_pkcs.c +++ b/src/misc/pem/pem_pkcs.c @@ -41,45 +41,6 @@ static int s_decrypt_pem(unsigned char *asn1_cert, unsigned long *asn1_len, cons return err; } -typedef int (*import_fn)(const unsigned char *, unsigned long, void*); - -static const import_fn s_import_x509_fns[LTC_PKA_NUM] = { -#ifdef LTC_MRSA - [LTC_PKA_RSA] = (import_fn)rsa_import_x509, -#endif -#ifdef LTC_MECC - [LTC_PKA_EC] = (import_fn)ecc_import_x509, -#endif -#ifdef LTC_CURVE25519 - [LTC_PKA_X25519] = (import_fn)x25519_import_x509, - [LTC_PKA_ED25519] = (import_fn)ed25519_import_x509, -#endif -}; - -static int s_import_x509(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k) -{ - enum ltc_pka_id pka = LTC_PKA_UNDEF; - ltc_asn1_list *d, *spki; - int err; - if ((err = x509_decode_spki(asn1_cert, asn1_len, &d, &spki)) != CRYPT_OK) { - return err; - } - err = x509_get_pka(spki, &pka); - der_free_sequence_flexi(d); - if (err != CRYPT_OK) { - return err; - } - if (pka < 0 - || pka > LTC_ARRAY_SIZE(s_import_x509_fns) - || s_import_x509_fns[pka] == NULL) { - return CRYPT_PK_INVALID_TYPE; - } - if ((err = s_import_x509_fns[pka](asn1_cert, asn1_len, &k->u)) == CRYPT_OK) { - k->id = pka; - } - return err; -} - static int s_import_pkcs8(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, const password_ctx *pw_ctx) { int err; @@ -198,7 +159,7 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c err = s_import_pkcs8(asn1_cert, asn1_len, k, pw_ctx); goto cleanup; } else if (hdr.id->flags == pf_x509) { - err = s_import_x509(asn1_cert, asn1_len, k); + err = x509_import_spki(asn1_cert, asn1_len, k, NULL); goto cleanup; } else if ((hdr.id->flags & pf_public) && hdr.id->pka == LTC_PKA_UNDEF) { if ((err = s_extract_pka(asn1_cert, asn1_len, &pka)) != CRYPT_OK) { diff --git a/src/pk/asn1/x509/x509_import_spki.c b/src/pk/asn1/x509/x509_import_spki.c new file mode 100644 index 000000000..1e7f3b2ce --- /dev/null +++ b/src/pk/asn1/x509/x509_import_spki.c @@ -0,0 +1,56 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x509_import_spki.c + Import the SubjectPublicKeyInfo of an X.509 cert, Steffen Jaeckel +*/ + +#ifdef LTC_DER + +typedef int (*import_fn)(const unsigned char *, unsigned long, void*); + +static const import_fn s_import_x509_fns[LTC_PKA_NUM] = { +#ifdef LTC_MRSA + [LTC_PKA_RSA] = (import_fn)rsa_import_x509, +#endif +#ifdef LTC_MECC + [LTC_PKA_EC] = (import_fn)ecc_import_x509, +#endif +#ifdef LTC_CURVE25519 + [LTC_PKA_X25519] = (import_fn)x25519_import_x509, + [LTC_PKA_ED25519] = (import_fn)ed25519_import_x509, +#endif +}; + +int x509_import_spki(const unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, ltc_asn1_list **root) +{ + enum ltc_pka_id pka = LTC_PKA_UNDEF; + ltc_asn1_list *d, *spki; + int err; + if ((err = x509_decode_spki(asn1_cert, asn1_len, &d, &spki)) != CRYPT_OK) { + return err; + } + if ((err = x509_get_pka(spki, &pka)) != CRYPT_OK) { + goto err_out; + } + if (pka < 0 + || pka > LTC_ARRAY_SIZE(s_import_x509_fns) + || s_import_x509_fns[pka] == NULL) { + err = CRYPT_PK_INVALID_TYPE; + goto err_out; + } + if ((err = s_import_x509_fns[pka](asn1_cert, asn1_len, &k->u)) == CRYPT_OK) { + k->id = pka; + } +err_out: + if (err == CRYPT_OK && root) { + *root = d; + d = NULL; + } + der_free_sequence_flexi(d); + return err; +} + +#endif /* LTC_DER */ From 7e78899af64ea22e435adb7c4f31e3660da8cb2f Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 4 Jun 2025 15:30:21 +0200 Subject: [PATCH 3/9] Re-factor `s_import_pkcs8()` Signed-off-by: Steffen Jaeckel --- src/misc/pem/pem_pkcs.c | 75 ++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/src/misc/pem/pem_pkcs.c b/src/misc/pem/pem_pkcs.c index d3db284cd..7d726645c 100644 --- a/src/misc/pem/pem_pkcs.c +++ b/src/misc/pem/pem_pkcs.c @@ -41,55 +41,50 @@ static int s_decrypt_pem(unsigned char *asn1_cert, unsigned long *asn1_len, cons return err; } -static int s_import_pkcs8(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, const password_ctx *pw_ctx) -{ - int err; - enum ltc_oid_id pka; - ltc_asn1_list *alg_id, *priv_key; - ltc_asn1_list *p8_asn1 = NULL; - if ((err = pkcs8_decode_flexi(asn1_cert, asn1_len, pw_ctx, &p8_asn1)) != CRYPT_OK) { - goto cleanup; - } - if ((err = pkcs8_get_children(p8_asn1, &pka, &alg_id, &priv_key)) != CRYPT_OK) { - goto cleanup; - } - switch (pka) { +typedef int (*pkcs8_import_fn)(ltc_asn1_list *, ltc_asn1_list *, void*); + +static const struct { + enum ltc_pka_id id; + pkcs8_import_fn fn; +} s_import_pkcs8_map[LTC_OID_NUM] = { #ifdef LTC_MDH - case LTC_OID_DH: - err = dh_import_pkcs8_asn1(alg_id, priv_key, &k->u.dh); - k->id = LTC_PKA_DH; - break; + [LTC_OID_DH] = { LTC_PKA_DH, (pkcs8_import_fn)dh_import_pkcs8_asn1 }, #endif #ifdef LTC_MDSA - case LTC_OID_DSA: - err = dsa_import_pkcs8_asn1(alg_id, priv_key, &k->u.dsa); - k->id = LTC_PKA_DSA; - break; + [LTC_OID_DSA] = { LTC_PKA_DSA, (pkcs8_import_fn)dsa_import_pkcs8_asn1 }, #endif #ifdef LTC_MRSA - case LTC_OID_RSA: - err = rsa_import_pkcs8_asn1(alg_id, priv_key, &k->u.rsa); - k->id = LTC_PKA_RSA; - break; + [LTC_OID_RSA] = { LTC_PKA_RSA, (pkcs8_import_fn)rsa_import_pkcs8_asn1 }, #endif #ifdef LTC_MECC - case LTC_OID_EC: - err = ecc_import_pkcs8_asn1(alg_id, priv_key, &k->u.ecc); - k->id = LTC_PKA_EC; - break; + [LTC_OID_EC] = { LTC_PKA_EC, (pkcs8_import_fn)ecc_import_pkcs8_asn1 }, #endif #ifdef LTC_CURVE25519 - case LTC_OID_X25519: - err = x25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.x25519); - k->id = LTC_PKA_X25519; - break; - case LTC_OID_ED25519: - err = ed25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.ed25519); - k->id = LTC_PKA_ED25519; - break; + [LTC_OID_X25519] = { LTC_PKA_X25519, (pkcs8_import_fn)x25519_import_pkcs8_asn1 }, + [LTC_OID_ED25519] = { LTC_PKA_ED25519, (pkcs8_import_fn)ed25519_import_pkcs8_asn1 }, #endif - default: - err = CRYPT_PK_INVALID_TYPE; +}; + +static int s_import_pkcs8(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, const password_ctx *pw_ctx) +{ + int err; + enum ltc_oid_id oid_id; + ltc_asn1_list *alg_id, *priv_key; + ltc_asn1_list *p8_asn1 = NULL; + if ((err = pkcs8_decode_flexi(asn1_cert, asn1_len, pw_ctx, &p8_asn1)) != CRYPT_OK) { + goto cleanup; + } + if ((err = pkcs8_get_children(p8_asn1, &oid_id, &alg_id, &priv_key)) != CRYPT_OK) { + goto cleanup; + } + if (oid_id < 0 + || oid_id > LTC_ARRAY_SIZE(s_import_pkcs8_map) + || s_import_pkcs8_map[oid_id].fn == NULL) { + err = CRYPT_PK_INVALID_TYPE; + goto cleanup; + } + if ((err = s_import_pkcs8_map[oid_id].fn(alg_id, priv_key, &k->u)) == CRYPT_OK) { + k->id = s_import_pkcs8_map[oid_id].id; } cleanup: @@ -111,6 +106,8 @@ static int s_extract_pka(unsigned char *asn1_cert, unsigned long asn1_len, enum return err; } +typedef int (*import_fn)(const unsigned char *, unsigned long, void*); + static const import_fn s_import_openssl_fns[LTC_PKA_NUM] = { #ifdef LTC_MRSA [LTC_PKA_RSA] = (import_fn)rsa_import, From c9b609a0b75dc3af7b2e88e4178ce3b3a00bd2de Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Mon, 16 Jun 2025 14:26:24 +0200 Subject: [PATCH 4/9] Extend `der_flexi_sequence_cmp()` To be able to do a bit more, add an optional handler callback function. Additional to that, also make it possible to mark elements as optional. Signed-off-by: Steffen Jaeckel --- src/headers/tomcrypt_private.h | 24 ++++++++++++++----- .../der/sequence/der_flexi_sequence_cmp.c | 11 ++++++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index e7df4027b..ce27eb385 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -651,17 +651,29 @@ int der_printable_value_decode(int v); unsigned long der_utf8_charsize(const wchar_t c); -typedef struct { +typedef int (*der_flexi_handler)(const ltc_asn1_list*, void*); + +typedef struct der_flexi_check { ltc_asn1_type t; + int optional; ltc_asn1_list **pp; + der_flexi_handler handler; + void *userdata; } der_flexi_check; -#define LTC_SET_DER_FLEXI_CHECK(list, index, Type, P) \ - do { \ - int LTC_SDFC_temp##__LINE__ = (index); \ - list[LTC_SDFC_temp##__LINE__].t = Type; \ - list[LTC_SDFC_temp##__LINE__].pp = P; \ +#define LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, P, Opt, Hndl, Udata) \ + do { \ + int LTC_SDFC_temp##__LINE__ = (index); \ + list[LTC_SDFC_temp##__LINE__].t = Type; \ + list[LTC_SDFC_temp##__LINE__].pp = P; \ + list[LTC_SDFC_temp##__LINE__].optional = Opt; \ + list[LTC_SDFC_temp##__LINE__].handler = (der_flexi_handler)Hndl; \ + list[LTC_SDFC_temp##__LINE__].userdata = Udata; \ } while (0) +#define LTC_SET_DER_FLEXI_CHECK(list, index, Type, P) LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, P, 0, NULL, NULL) +#define LTC_SET_DER_FLEXI_CHECK_OPT(list, index, Type, P) LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, P, 1, NULL, NULL) +#define LTC_SET_DER_FLEXI_HANDLER(list, index, Type, Hndl, Udata) LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, NULL, 0, Hndl, Udata) +#define LTC_SET_DER_FLEXI_HANDLER_OPT(list, index, Type, Hndl, Udata) LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, NULL, 1, Hndl, Udata) extern const ltc_asn1_type der_asn1_tag_to_type_map[]; diff --git a/src/pk/asn1/der/sequence/der_flexi_sequence_cmp.c b/src/pk/asn1/der/sequence/der_flexi_sequence_cmp.c index 026eb504a..535483f59 100644 --- a/src/pk/asn1/der/sequence/der_flexi_sequence_cmp.c +++ b/src/pk/asn1/der/sequence/der_flexi_sequence_cmp.c @@ -24,11 +24,20 @@ int der_flexi_sequence_cmp(const ltc_asn1_list *flexi, der_flexi_check *check) return CRYPT_INVALID_PACKET; } cur = flexi->child; - while(check->t != LTC_ASN1_EOL) { + while(check->t != LTC_ASN1_EOL && cur) { if (!LTC_ASN1_IS_TYPE(cur, check->t)) { + if (check->optional) { + check++; + continue; + } return CRYPT_INVALID_PACKET; } if (check->pp != NULL) *check->pp = cur; + else if (check->handler) { + int err = check->handler(cur, check->userdata); + if (err != CRYPT_OK) + return err; + } cur = cur->next; check++; } From d77afd6a6813f01d3e867a8954bd47551e175e9e Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 2 Sep 2025 14:41:36 +0200 Subject: [PATCH 5/9] Use `rsa_init()` to initialize an `rsa_key` (and you should do that too) Signed-off-by: Steffen Jaeckel --- tests/pkcs_1_eme_test.c | 3 +-- tests/pkcs_1_emsa_test.c | 3 +-- tests/pkcs_1_oaep_test.c | 3 +-- tests/pkcs_1_pss_test.c | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/pkcs_1_eme_test.c b/tests/pkcs_1_eme_test.c index ca540360b..9e818ace6 100644 --- a/tests/pkcs_1_eme_test.c +++ b/tests/pkcs_1_eme_test.c @@ -24,8 +24,7 @@ int pkcs_1_eme_test(void) for (i = 0; i < LTC_ARRAY_SIZE(testcases_eme); ++i) { testcase_t* t = &testcases_eme[i]; rsa_key k, *key = &k; - DOX(ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL), t->name); + DOX(rsa_init(key), t->name); DOX(ltc_mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name); DOX(ltc_mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name); diff --git a/tests/pkcs_1_emsa_test.c b/tests/pkcs_1_emsa_test.c index ba66f079a..43fb112ae 100644 --- a/tests/pkcs_1_emsa_test.c +++ b/tests/pkcs_1_emsa_test.c @@ -21,8 +21,7 @@ int pkcs_1_emsa_test(void) for (i = 0; i < LTC_ARRAY_SIZE(testcases_emsa); ++i) { testcase_t* t = &testcases_emsa[i]; rsa_key k, *key = &k; - DOX(ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL), t->name); + DOX(rsa_init(key), t->name); DOX(ltc_mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name); DOX(ltc_mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name); diff --git a/tests/pkcs_1_oaep_test.c b/tests/pkcs_1_oaep_test.c index 1cb6ca128..76157c2c0 100644 --- a/tests/pkcs_1_oaep_test.c +++ b/tests/pkcs_1_oaep_test.c @@ -24,8 +24,7 @@ int pkcs_1_oaep_test(void) for (i = 0; i < LTC_ARRAY_SIZE(testcases_oaep); ++i) { testcase_t* t = &testcases_oaep[i]; rsa_key k, *key = &k; - DOX(ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL), t->name); + DOX(rsa_init(key), t->name); DOX(ltc_mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name); DOX(ltc_mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name); diff --git a/tests/pkcs_1_pss_test.c b/tests/pkcs_1_pss_test.c index a62e53ff0..a86e473ac 100644 --- a/tests/pkcs_1_pss_test.c +++ b/tests/pkcs_1_pss_test.c @@ -24,8 +24,7 @@ int pkcs_1_pss_test(void) for (i = 0; i < LTC_ARRAY_SIZE(testcases_pss); ++i) { testcase_t* t = &testcases_pss[i]; rsa_key k, *key = &k; - DOX(ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL), t->name); + DOX(rsa_init(key), t->name); DOX(ltc_mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name); DOX(ltc_mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name); From 9abf12305a41df9256fa312a1f32ab1515eb9c3b Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 2 Sep 2025 17:25:03 +0200 Subject: [PATCH 6/9] Add SubjectPublicKeyInfo support to `dsa_import()` Signed-off-by: Steffen Jaeckel --- src/pk/asn1/x509/x509_import_spki.c | 3 + src/pk/dsa/dsa_import.c | 101 +++++++++++++++++++--------- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/src/pk/asn1/x509/x509_import_spki.c b/src/pk/asn1/x509/x509_import_spki.c index 1e7f3b2ce..8b360852e 100644 --- a/src/pk/asn1/x509/x509_import_spki.c +++ b/src/pk/asn1/x509/x509_import_spki.c @@ -15,6 +15,9 @@ static const import_fn s_import_x509_fns[LTC_PKA_NUM] = { #ifdef LTC_MRSA [LTC_PKA_RSA] = (import_fn)rsa_import_x509, #endif +#ifdef LTC_MDSA + [LTC_PKA_DSA] = (import_fn)dsa_import, +#endif #ifdef LTC_MECC [LTC_PKA_EC] = (import_fn)ecc_import_x509, #endif diff --git a/src/pk/dsa/dsa_import.c b/src/pk/dsa/dsa_import.c index d2c2d49ec..3db1afd32 100644 --- a/src/pk/dsa/dsa_import.c +++ b/src/pk/dsa/dsa_import.c @@ -28,6 +28,69 @@ int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key) return err; } +static int s_dsa_import_y(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + return der_decode_integer(in, inlen, key->y); +} + +LTC_INLINE static int s_dsa_set_params(dsa_key *key, ltc_asn1_list *params) +{ + LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL); + LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL); + LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL); + return 3; +} + +static int s_dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + int err; + unsigned char* tmpbuf = NULL; + ltc_asn1_list params[3]; + unsigned long tmpbuf_len = inlen, len; + + len = s_dsa_set_params(key, params); + + tmpbuf = XCALLOC(1, tmpbuf_len); + if (tmpbuf == NULL) { + return CRYPT_MEM; + } + + err = x509_decode_subject_public_key_info(in, inlen, + LTC_OID_DSA, tmpbuf, &tmpbuf_len, + LTC_ASN1_SEQUENCE, params, &len); + if (err != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = s_dsa_import_y(tmpbuf, tmpbuf_len, key)) != CRYPT_OK) { + goto LBL_ERR; + } + + key->type = PK_PUBLIC; +LBL_ERR: + XFREE(tmpbuf); + return err; +} + +static int s_dsa_import_x509(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + int err; + ltc_asn1_list params[3]; + unsigned long len; + + len = s_dsa_set_params(key, params); + + if ((err = x509_decode_public_key_from_certificate(in, inlen, + LTC_OID_DSA, + LTC_ASN1_SEQUENCE, params, &len, + (public_key_decode_cb)s_dsa_import_y, key)) == CRYPT_OK) { + key->type = PK_PUBLIC; + return CRYPT_OK; + } + + return err; +} + /** Import a DSA key @param in The binary packet to import from @@ -38,7 +101,6 @@ int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key) int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) { int err, stat; - unsigned char* tmpbuf = NULL; unsigned char flags[1]; LTC_ARGCHK(in != NULL); @@ -86,35 +148,14 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) } } - if (dsa_import_pkcs1(in, inlen, key) != CRYPT_OK) { - ltc_asn1_list params[3]; - unsigned long tmpbuf_len = inlen, len; - - LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL); - LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL); - LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL); - len = 3; - - tmpbuf = XCALLOC(1, tmpbuf_len); - if (tmpbuf == NULL) { - return CRYPT_MEM; - } - - err = x509_decode_subject_public_key_info(in, inlen, - LTC_OID_DSA, tmpbuf, &tmpbuf_len, - LTC_ASN1_SEQUENCE, params, &len); - if (err != CRYPT_OK) { - XFREE(tmpbuf); - goto LBL_ERR; - } - - if ((err = der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) { - XFREE(tmpbuf); - goto LBL_ERR; - } - - key->type = PK_PUBLIC; - XFREE(tmpbuf); + if (dsa_import_pkcs1(in, inlen, key) == CRYPT_OK) { + goto LBL_OK; + } + if (s_dsa_import_spki(in, inlen, key) == CRYPT_OK) { + goto LBL_OK; + } + if ((err = s_dsa_import_x509(in, inlen, key)) != CRYPT_OK) { + goto LBL_ERR; } LBL_OK: From ea672df7a3b16b9c1e182c13e755c96016fad69e Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 11 Sep 2025 12:25:58 +0200 Subject: [PATCH 7/9] Put realloc logic into `pem_read()` Signed-off-by: Steffen Jaeckel --- src/headers/tomcrypt_private.h | 31 +++++-- src/misc/pem/pem_pkcs.c | 15 ++-- src/misc/pem/pem_read.c | 156 +++++++++++++++++++++------------ src/misc/pem/pem_ssh.c | 19 ++-- 4 files changed, 141 insertions(+), 80 deletions(-) diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index ce27eb385..58b7e435e 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -352,19 +352,40 @@ struct bufp { }; #define SET_BUFP(n, d, l) n.start = (char*)d, n.work = (char*)d, n.end = (char*)d + l + 1 +#define UPDATE_BUFP(n, d, w, l) n.start = (char*)d, n.work = (char*)d + w, n.end = (char*)d + l + 1 -struct get_char { +struct get_char; +struct get_char_api { int (*get)(struct get_char*); +}; + +struct get_char { + struct get_char_api api; union { #ifndef LTC_NO_FILE - FILE *f; + struct { + FILE *f; + } f; #endif /* LTC_NO_FILE */ struct bufp buf; } data; struct str unget_buf; char unget_buf_[LTC_PEM_DECODE_BUFSZ]; int prev_get; + unsigned long total_read; }; + +#define pem_get_char_init(b, l) { \ + .api = get_char_buffer_api, \ + SET_BUFP(.data.buf, (b), (l)), \ + .total_read = 0, \ +} + +#define pem_get_char_init_filehandle(fi) { \ + .api = get_char_filehandle_api, \ + .data.f.f = (fi), \ + .total_read = 0, \ +} #endif /* others */ @@ -387,10 +408,10 @@ int pem_decrypt(unsigned char *data, unsigned long *datalen, const struct blockcipher_info *info, enum padding_type padding); #ifndef LTC_NO_FILE -int pem_get_char_from_file(struct get_char *g); +extern const struct get_char_api get_char_filehandle_api; #endif /* LTC_NO_FILE */ -int pem_get_char_from_buf(struct get_char *g); -int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, struct get_char *g); +extern const struct get_char_api get_char_buffer_api; +int pem_read(void **dest, unsigned long *len, struct pem_headers *hdr, struct get_char *g); #endif /* tomcrypt_pk.h */ diff --git a/src/misc/pem/pem_pkcs.c b/src/misc/pem/pem_pkcs.c index 7d726645c..17aa47705 100644 --- a/src/misc/pem/pem_pkcs.c +++ b/src/misc/pem/pem_pkcs.c @@ -127,21 +127,16 @@ static const import_fn s_import_openssl_fns[LTC_PKA_NUM] = { static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx) { unsigned char *asn1_cert = NULL; - unsigned long w, asn1_len, n; + unsigned long w = 0, asn1_len, n; int err = CRYPT_ERROR; struct pem_headers hdr = { 0 }; struct password pw = { 0 }; enum ltc_pka_id pka; XMEMSET(k, 0, sizeof(*k)); - w = LTC_PEM_READ_BUFSIZE * 2; -retry: - asn1_cert = XREALLOC(asn1_cert, w); for (n = 0; n < pem_std_headers_num; ++n) { hdr.id = &pem_std_headers[n]; - err = pem_read(asn1_cert, &w, &hdr, g); - if (err == CRYPT_BUFFER_OVERFLOW) { - goto retry; - } else if (err == CRYPT_OK) { + err = pem_read((void**)&asn1_cert, &w, &hdr, g); + if (err == CRYPT_OK) { break; } else if (err != CRYPT_UNKNOWN_PEM) { goto cleanup; @@ -204,7 +199,7 @@ int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_c LTC_ARGCHK(f != NULL); LTC_ARGCHK(k != NULL); { - struct get_char g = { .get = pem_get_char_from_file, .data.f = f }; + struct get_char g = pem_get_char_init_filehandle(f); return s_decode(&g, k, pw_ctx); } } @@ -216,7 +211,7 @@ int pem_decode_pkcs(const void *buf, unsigned long len, ltc_pka_key *k, const pa LTC_ARGCHK(len != 0); LTC_ARGCHK(k != NULL); { - struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.data.buf, buf, len) }; + struct get_char g = pem_get_char_init(buf, len); return s_decode(&g, k, pw_ctx); } } diff --git a/src/misc/pem/pem_read.c b/src/misc/pem/pem_read.c index abefff924..bbc61cb0d 100644 --- a/src/misc/pem/pem_read.c +++ b/src/misc/pem/pem_read.c @@ -17,14 +17,76 @@ extern const struct str pem_dek_info_start; extern const struct blockcipher_info pem_dek_infos[]; extern const unsigned long pem_dek_infos_num; +static LTC_INLINE unsigned long s_bufp_alloc_len(struct bufp *buf) +{ + if (buf->start == NULL || buf->end == NULL) + return 0; + return buf->end - buf->start - 1; +} + +static LTC_INLINE unsigned long s_bufp_used_len(struct bufp *buf) +{ + if (buf->start == NULL || buf->end == NULL) + return 0; + return buf->work - buf->start; +} + +static LTC_INLINE int s_bufp_grow(struct bufp *buf) +{ + int err = CRYPT_OK; + void *ret; + unsigned long alloc_len = s_bufp_alloc_len(buf), realloc_len; + unsigned long work_offset = s_bufp_used_len(buf); + if (alloc_len == 0) + realloc_len = LTC_PEM_READ_BUFSIZE; + else + realloc_len = alloc_len * 2; + if (realloc_len < alloc_len) + return CRYPT_OVERFLOW; + ret = XREALLOC(buf->start, realloc_len); + if (ret == NULL) { + err = CRYPT_MEM; + } else { + UPDATE_BUFP((*buf), ret, work_offset, realloc_len); + } + return err; +} + +static LTC_INLINE int s_bufp_fits(struct bufp *buf, unsigned long to_write) +{ + char *d = buf->work; + char *e = buf->end; + char *w = d + to_write; + if (d == NULL || w < d || w > e) + return 0; + return 1; +} + +static LTC_INLINE int s_bufp_add(struct bufp *buf, const void *src, unsigned long len) +{ + int err; + if (!s_bufp_fits(buf, len)) { + if ((err = s_bufp_grow(buf)) != CRYPT_OK) { + return err; + } + } + XMEMCPY(buf->work, src, len); + buf->work += len; + return CRYPT_OK; +} + #ifndef LTC_NO_FILE -int pem_get_char_from_file(struct get_char *g) +static int s_pem_get_char_from_file(struct get_char *g) { - return getc(g->data.f); + return getc(g->data.f.f); } + +const struct get_char_api get_char_filehandle_api = { + .get = s_pem_get_char_from_file, +}; #endif /* LTC_NO_FILE */ -int pem_get_char_from_buf(struct get_char *g) +static int s_pem_get_char_from_buf(struct get_char *g) { int ret; if (g->data.buf.work == g->data.buf.end) { @@ -35,6 +97,10 @@ int pem_get_char_from_buf(struct get_char *g) return ret; } +const struct get_char_api get_char_buffer_api = { + .get = s_pem_get_char_from_buf, +}; + static void s_unget_line(char *buf, unsigned long buflen, struct get_char *g) { if (buflen > sizeof(g->unget_buf_)) @@ -81,7 +147,7 @@ static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, while(blen < *buflen || search_for_start) { wr = blen < *buflen ? blen : *buflen - 1; c_ = g->prev_get; - g->prev_get = g->get(g); + g->prev_get = g->api.get(g); if (g->prev_get == '\n') { buf[wr] = '\0'; if (c_ == '\r') { @@ -89,6 +155,7 @@ static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, } s_tts(buf, &wr); *buflen = wr; + g->total_read++; return buf; } if (g->prev_get == -1 || g->prev_get == '\0') { @@ -99,30 +166,21 @@ static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, } buf[wr] = g->prev_get; blen++; + g->total_read++; } return NULL; } -LTC_INLINE static char* s_get_first_line(char *buf, unsigned long *buflen, struct get_char *g) +static LTC_INLINE char* s_get_first_line(char *buf, unsigned long *buflen, struct get_char *g) { return s_get_line_i(buf, buflen, g, 1); } -LTC_INLINE static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g) +static LTC_INLINE char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g) { return s_get_line_i(buf, buflen, g, 0); } -static LTC_INLINE int s_fits_buf(void *dest, unsigned long to_write, void *end) -{ - unsigned char *d = dest; - unsigned char *e = end; - unsigned char *w = d + to_write; - if (w < d || w > e) - return 0; - return 1; -} - static int s_pem_decode_headers(struct pem_headers *hdr, struct get_char *g) { char buf[LTC_PEM_DECODE_BUFSZ], *alg_start; @@ -190,31 +248,29 @@ static int s_pem_decode_headers(struct pem_headers *hdr, struct get_char *g) return CRYPT_OK; } -int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, struct get_char *g) +int pem_read(void **dest, unsigned long *len, struct pem_headers *hdr, struct get_char *g) { - char buf[LTC_PEM_DECODE_BUFSZ]; - char *wpem = asn1_cert; - char *end = wpem + *asn1_len; + char line[LTC_PEM_DECODE_BUFSZ]; + struct bufp b_ = {0}, *b = &b_; const char pem_start[] = "----"; - unsigned long slen, linelen; + unsigned long slen; int err, hdr_ok = 0; - int would_overflow = 0; unsigned char empty_lines = 0; g->prev_get = 0; do { - linelen = sizeof(buf); - if (s_get_first_line(buf, &linelen, g) == NULL) { + slen = sizeof(line); + if (s_get_first_line(line, &slen, g) == NULL) { if (g->prev_get == -1) return CRYPT_NOP; else return CRYPT_INVALID_PACKET; } - if (linelen < sizeof(pem_start) - 1) + if (slen < sizeof(pem_start) - 1) continue; - } while(XMEMCMP(buf, pem_start, sizeof(pem_start) - 1) != 0); - if (hdr->id->start.len != linelen || XMEMCMP(buf, hdr->id->start.p, hdr->id->start.len)) { - s_unget_line(buf, linelen, g); + } while(XMEMCMP(line, pem_start, sizeof(pem_start) - 1) != 0); + if (hdr->id->start.len != slen || XMEMCMP(line, hdr->id->start.p, hdr->id->start.len)) { + s_unget_line(line, slen, g); return CRYPT_UNKNOWN_PEM; } @@ -223,9 +279,9 @@ int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, return err; /* Read the base64 encoded part of the PEM */ - slen = sizeof(buf); - while (s_get_line(buf, &slen, g)) { - if (slen == hdr->id->end.len && !XMEMCMP(buf, hdr->id->end.p, slen)) { + slen = sizeof(line); + while (s_get_line(line, &slen, g)) { + if (slen == hdr->id->end.len && !XMEMCMP(line, hdr->id->end.p, slen)) { hdr_ok = 1; break; } @@ -234,34 +290,26 @@ int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, break; empty_lines++; } - if (!would_overflow && s_fits_buf(wpem, slen, end)) { - XMEMCPY(wpem, buf, slen); - } else { - would_overflow = 1; + if ((err = s_bufp_add(b, line, slen)) != CRYPT_OK) { + goto error_out; } - wpem += slen; - slen = sizeof(buf); + slen = sizeof(line); } - if (!hdr_ok) - return CRYPT_INVALID_PACKET; - - if (would_overflow || !s_fits_buf(wpem, 1, end)) { - /* NUL termination */ - wpem++; - /* prevent a wrap-around */ - if (wpem < (char*)asn1_cert) - return CRYPT_OVERFLOW; - *asn1_len = wpem - (char*)asn1_cert; - return CRYPT_BUFFER_OVERFLOW; + if (!hdr_ok) { + err = CRYPT_INVALID_PACKET; + } else { + slen = s_bufp_alloc_len(b); + err = base64_strict_decode(b->start, s_bufp_used_len(b), (void*)b->start, &slen); } + if (err == CRYPT_OK) { + *dest = b->start; + *len = slen; - *asn1_len = wpem - (char*)asn1_cert; - *wpem++ = '\0'; - - if ((err = base64_strict_decode(asn1_cert, *asn1_len, asn1_cert, asn1_len)) != CRYPT_OK) { - return err; + } else { +error_out: + XFREE(b->start); } - return CRYPT_OK; + return err; } #endif /* LTC_PEM */ diff --git a/src/misc/pem/pem_ssh.c b/src/misc/pem/pem_ssh.c index 77fa87be9..d4de0865a 100644 --- a/src/misc/pem/pem_ssh.c +++ b/src/misc/pem/pem_ssh.c @@ -712,20 +712,15 @@ static const unsigned long pem_openssh_num = LTC_ARRAY_SIZE(pem_openssh); 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, *tag; - unsigned long n, w, l, privkey_len, taglen; + unsigned long n, w = 0, l, privkey_len, taglen; int err; struct pem_headers hdr; struct kdf_options opts = { 0 }; XMEMSET(k, 0, sizeof(*k)); - w = LTC_PEM_READ_BUFSIZE * 2; -retry: - pem = XREALLOC(pem, w); for (n = 0; n < pem_openssh_num; ++n) { hdr.id = &pem_openssh[n]; - err = pem_read(pem, &w, &hdr, g); - if (err == CRYPT_BUFFER_OVERFLOW) { - goto retry; - } else if (err == CRYPT_OK) { + err = pem_read((void**)&pem, &w, &hdr, g); + if (err == CRYPT_OK) { break; } else if (err != CRYPT_UNKNOWN_PEM) { goto cleanup; @@ -791,7 +786,9 @@ static int s_decode_openssh(struct get_char *g, ltc_pka_key *k, const password_c zeromem(privkey, privkey_len); XFREE(privkey); } - XFREE(pem); + if (pem) { + XFREE(pem); + } return err; } @@ -801,7 +798,7 @@ int pem_decode_openssh_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *p LTC_ARGCHK(f != NULL); LTC_ARGCHK(k != NULL); { - struct get_char g = { .get = pem_get_char_from_file, .data.f = f }; + struct get_char g = pem_get_char_init_filehandle(f); return s_decode_openssh(&g, k, pw_ctx); } } @@ -841,7 +838,7 @@ int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, const LTC_ARGCHK(len != 0); LTC_ARGCHK(k != NULL); { - struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.data.buf, buf, len) }; + struct get_char g = pem_get_char_init(buf, len); return s_decode_openssh(&g, k, pw_ctx); } } From e2918971fa39a6ebfa1e4229e060f12041e4143f Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 3 Oct 2025 10:39:07 +0200 Subject: [PATCH 8/9] Re-order PEM headers to prepare for X.509 APIs Signed-off-by: Steffen Jaeckel --- src/misc/pem/pem.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/misc/pem/pem.c b/src/misc/pem/pem.c index 632515914..1e8cc0132 100644 --- a/src/misc/pem/pem.c +++ b/src/misc/pem/pem.c @@ -10,6 +10,13 @@ #ifdef LTC_PEM const struct pem_header_id pem_std_headers[] = { + { + /* X.509 Certificates */ + SET_CSTR(.start, "-----BEGIN CERTIFICATE-----"), + SET_CSTR(.end, "-----END CERTIFICATE-----"), + .has_more_headers = no, + .flags = pf_x509, + }, { /* PKCS#8 encrypted */ SET_CSTR(.start, "-----BEGIN ENCRYPTED PRIVATE KEY-----"), @@ -24,13 +31,6 @@ const struct pem_header_id pem_std_headers[] = { .has_more_headers = no, .flags = pf_pkcs8, }, - { - /* X.509 Certificates */ - SET_CSTR(.start, "-----BEGIN CERTIFICATE-----"), - SET_CSTR(.end, "-----END CERTIFICATE-----"), - .has_more_headers = no, - .flags = pf_x509, - }, { /* Regular (plain) public keys */ SET_CSTR(.start, "-----BEGIN PUBLIC KEY-----"), From 369650ccd3418f7d5a75e71dc08ed517008caf95 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 16 Oct 2025 10:30:51 +0200 Subject: [PATCH 9/9] Update makefiles --- libtomcrypt_VS2008.vcproj | 8 ++++++++ makefile.mingw | 7 ++++--- makefile.msvc | 7 ++++--- makefile.unix | 7 ++++--- makefile_include.mk | 7 ++++--- sources.cmake | 2 ++ 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj index 66375779f..200dc670a 100644 --- a/libtomcrypt_VS2008.vcproj +++ b/libtomcrypt_VS2008.vcproj @@ -2281,6 +2281,14 @@ RelativePath="src\pk\asn1\x509\x509_encode_subject_public_key_info.c" > + + + +