diff --git a/src/lib/crypto.cpp b/src/lib/crypto.cpp index a9a33b696..765018739 100644 --- a/src/lib/crypto.cpp +++ b/src/lib/crypto.cpp @@ -48,69 +48,3 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "config.h" - -#ifdef HAVE_SYS_CDEFS_H -#include -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: crypto.c,v 1.36 2014/02/17 07:39:19 agc Exp $"); -#endif - -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include -#include - -#include -#include - -#include "types.h" -#include "crypto/common.h" -#include "crypto.h" -#include "fingerprint.h" -#include "pgp-key.h" -#include "utils.h" - -bool -pgp_generate_seckey(const rnp_keygen_crypto_params_t &crypto, - pgp_key_pkt_t & seckey, - bool primary, - pgp_version_t pgp_version) -{ - /* populate pgp key structure */ - seckey = {}; -#if defined(ENABLE_CRYPTO_REFRESH) - seckey.version = pgp_version; -#else - seckey.version = PGP_V4; -#endif - seckey.creation_time = crypto.ctx->time(); - seckey.alg = crypto.key_alg; - seckey.material = pgp::KeyMaterial::create(crypto.key_alg); - if (!seckey.material) { - RNP_LOG("Unsupported key algorithm: %d", crypto.key_alg); - return false; - } - seckey.tag = primary ? PGP_PKT_SECRET_KEY : PGP_PKT_SECRET_SUBKEY; - - if (!seckey.material->generate(crypto)) { - return false; - } - - seckey.sec_protection.s2k.usage = PGP_S2KU_NONE; - /* fill the sec_data/sec_len */ - if (encrypt_secret_key(&seckey, NULL, crypto.ctx->rng)) { - RNP_LOG("failed to fill sec_data"); - return false; - } - return true; -} diff --git a/src/lib/crypto.h b/src/lib/crypto.h index 47346f0f0..b8301938a 100644 --- a/src/lib/crypto.h +++ b/src/lib/crypto.h @@ -59,49 +59,4 @@ #include "crypto/common.h" #include -/* raw key generation */ -bool pgp_generate_seckey(const rnp_keygen_crypto_params_t ¶ms, - pgp_key_pkt_t & seckey, - bool primary, - pgp_version_t pgp_version = PGP_V4); - -/** generate a new primary key - * - * @param desc keygen description - * @param merge_defaults true if you want defaults to be set for unset - * keygen description parameters. - * @param primary_sec pointer to store the generated secret key, must not be NULL - * @param primary_pub pointer to store the generated public key, must not be NULL - * @return true if successful, false otherwise. - **/ -bool pgp_generate_primary_key(rnp_keygen_primary_desc_t &desc, - bool merge_defaults, - pgp_key_t & primary_sec, - pgp_key_t & primary_pub, - pgp_key_store_format_t secformat); - -/** generate a new subkey - * - * @param desc keygen description - * @param merge_defaults true if you want defaults to be set for unset - * keygen description parameters. - * @param primary_sec pointer to the primary secret key that will own this - * subkey, must not be NULL - * @param primary_pub pointer to the primary public key that will own this - * subkey, must not be NULL - * @param subkey_sec pointer to store the generated secret key, must not be NULL - * @param subkey_pub pointer to store the generated public key, must not be NULL - * @param password_provider the password provider that will be used to - * decrypt the primary key, may be NULL if primary key is unlocked - * @return true if successful, false otherwise. - **/ -bool pgp_generate_subkey(rnp_keygen_subkey_desc_t & desc, - bool merge_defaults, - pgp_key_t & primary_sec, - pgp_key_t & primary_pub, - pgp_key_t & subkey_sec, - pgp_key_t & subkey_pub, - const pgp_password_provider_t &password_provider, - pgp_key_store_format_t secformat); - #endif /* CRYPTO_H_ */ diff --git a/src/lib/generate-key.cpp b/src/lib/generate-key.cpp index 8a8dd18ca..f8b159266 100644 --- a/src/lib/generate-key.cpp +++ b/src/lib/generate-key.cpp @@ -22,579 +22,3 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include - -#include -#include -#include -#include "crypto.h" -#include "pgp-key.h" -#include "defaults.h" -#include "utils.h" - -static const uint8_t DEFAULT_SYMMETRIC_ALGS[] = { - PGP_SA_AES_256, PGP_SA_AES_192, PGP_SA_AES_128}; -static const uint8_t DEFAULT_HASH_ALGS[] = { - PGP_HASH_SHA256, PGP_HASH_SHA384, PGP_HASH_SHA512, PGP_HASH_SHA224}; -static const uint8_t DEFAULT_COMPRESS_ALGS[] = { - PGP_C_ZLIB, PGP_C_BZIP2, PGP_C_ZIP, PGP_C_NONE}; -#if defined(ENABLE_CRYPTO_REFRESH) -static const uint8_t DEFAULT_AEAD_ALGS[] = {PGP_AEAD_OCB}; -#endif - -static const id_str_pair pubkey_alg_map[] = { - {PGP_PKA_RSA, "RSA (Encrypt or Sign)"}, - {PGP_PKA_RSA_ENCRYPT_ONLY, "RSA Encrypt-Only"}, - {PGP_PKA_RSA_SIGN_ONLY, "RSA Sign-Only"}, - {PGP_PKA_ELGAMAL, "Elgamal (Encrypt-Only)"}, - {PGP_PKA_DSA, "DSA"}, - {PGP_PKA_ECDH, "ECDH"}, - {PGP_PKA_ECDSA, "ECDSA"}, - {PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN, "Reserved (formerly Elgamal Encrypt or Sign"}, - {PGP_PKA_RESERVED_DH, "Reserved for Diffie-Hellman (X9.42)"}, - {PGP_PKA_EDDSA, "EdDSA"}, - {PGP_PKA_SM2, "SM2"}, -#if defined(ENABLE_CRYPTO_REFRESH) - {PGP_PKA_ED25519, "ED25519"}, - {PGP_PKA_X25519, "X25519"}, -#endif -#if defined(ENABLE_PQC) - {PGP_PKA_KYBER768_X25519, "ML-KEM-768_X25519"}, - //{PGP_PKA_KYBER1024_X448, "Kyber-X448"}, - {PGP_PKA_KYBER768_P256, "ML-KEM-768_P256"}, - {PGP_PKA_KYBER1024_P384, "ML-KEM-1024_P384"}, - {PGP_PKA_KYBER768_BP256, "ML-KEM-768_BP256"}, - {PGP_PKA_KYBER1024_BP384, "ML-KEM-1024_BP384"}, - {PGP_PKA_DILITHIUM3_ED25519, "ML-DSA-65_ED25519"}, - //{PGP_PKA_DILITHIUM5_ED448, "Dilithium-ED448"}, - {PGP_PKA_DILITHIUM3_P256, "ML-DSA-65_P256"}, - {PGP_PKA_DILITHIUM5_P384, "ML-DSA-87_P384"}, - {PGP_PKA_DILITHIUM3_BP256, "ML-DSA-65_BP256"}, - {PGP_PKA_DILITHIUM5_BP384, "ML-DSA-87_BP384"}, - {PGP_PKA_SPHINCSPLUS_SHA2, "SLH-DSA-SHA2"}, - {PGP_PKA_SPHINCSPLUS_SHAKE, "SLH-DSA-SHAKE"}, - {PGP_PKA_PRIVATE00, "Private/Experimental"}, - {PGP_PKA_PRIVATE01, "Private/Experimental"}, - {PGP_PKA_PRIVATE02, "Private/Experimental"}, - {PGP_PKA_PRIVATE03, "Private/Experimental"}, - {PGP_PKA_PRIVATE04, "Private/Experimental"}, - {PGP_PKA_PRIVATE06, "Private/Experimental"}, - {PGP_PKA_PRIVATE08, "Private/Experimental"}, - {PGP_PKA_PRIVATE10, "Private/Experimental"}, -#else - {PGP_PKA_PRIVATE00, "Private/Experimental"}, - {PGP_PKA_PRIVATE01, "Private/Experimental"}, - {PGP_PKA_PRIVATE02, "Private/Experimental"}, - {PGP_PKA_PRIVATE03, "Private/Experimental"}, - {PGP_PKA_PRIVATE04, "Private/Experimental"}, - {PGP_PKA_PRIVATE05, "Private/Experimental"}, - {PGP_PKA_PRIVATE06, "Private/Experimental"}, - {PGP_PKA_PRIVATE07, "Private/Experimental"}, - {PGP_PKA_PRIVATE08, "Private/Experimental"}, - {PGP_PKA_PRIVATE09, "Private/Experimental"}, - {PGP_PKA_PRIVATE10, "Private/Experimental"}, -#endif - {0, NULL}}; - -static bool -load_generated_g10_key(pgp_key_t * dst, - pgp_key_pkt_t * newkey, - pgp_key_t * primary_key, - pgp_key_t * pubkey, - rnp::SecurityContext &ctx) -{ - // this should generally be zeroed - assert(dst->type() == 0); - // if a primary is provided, make sure it's actually a primary key - assert(!primary_key || primary_key->is_primary()); - // if a pubkey is provided, make sure it's actually a public key - assert(!pubkey || pubkey->is_public()); - // G10 always needs pubkey here - assert(pubkey); - - // this would be better on the stack but the key store does not allow it - std::unique_ptr key_store(new (std::nothrow) rnp::KeyStore(ctx)); - if (!key_store) { - return false; - } - /* Write g10 seckey */ - rnp::MemoryDest memdst(NULL, 0); - if (!g10_write_seckey(&memdst.dst(), newkey, NULL, ctx)) { - RNP_LOG("failed to write generated seckey"); - return false; - } - - std::vector key_ptrs; /* holds primary and pubkey, when used */ - // if this is a subkey, add the primary in first - if (primary_key) { - key_ptrs.push_back(primary_key); - } - // G10 needs the pubkey for copying some attributes (key version, creation time, etc) - key_ptrs.push_back(pubkey); - - rnp::MemorySource memsrc(memdst.memory(), memdst.writeb(), false); - rnp::KeyProvider prov(rnp_key_provider_key_ptr_list, &key_ptrs); - if (!key_store.get()->load_g10(memsrc.src(), &prov)) { - return false; - } - if (key_store.get()->key_count() != 1) { - return false; - } - // if a primary key is provided, it should match the sub with regards to type - assert(!primary_key || (primary_key->is_secret() == key_store->keys.front().is_secret())); - *dst = pgp_key_t(key_store->keys.front()); - return true; -} - -static uint8_t -pk_alg_default_flags(pgp_pubkey_alg_t alg) -{ - // just use the full capabilities as the ultimate fallback - return pgp_pk_alg_capabilities(alg); -} - -// TODO: Similar as pgp_pick_hash_alg but different enough to -// keep another version. This will be changed when refactoring crypto -static void -adjust_hash_alg(rnp_keygen_crypto_params_t &crypto) -{ - if (!crypto.hash_alg) { - crypto.hash_alg = (pgp_hash_alg_t) DEFAULT_HASH_ALGS[0]; - } - - if ((crypto.key_alg != PGP_PKA_DSA) && (crypto.key_alg != PGP_PKA_ECDSA)) { - return; - } - - pgp_hash_alg_t min_hash = (crypto.key_alg == PGP_PKA_ECDSA) ? - ecdsa_get_min_hash(crypto.ecc.curve) : - dsa_get_min_hash(crypto.dsa.q_bitlen); - - if (rnp::Hash::size(crypto.hash_alg) < rnp::Hash::size(min_hash)) { - crypto.hash_alg = min_hash; - } -} - -static void -keygen_merge_crypto_defaults(rnp_keygen_crypto_params_t &crypto) -{ - // default to RSA - if (!crypto.key_alg) { - crypto.key_alg = PGP_PKA_RSA; - } - - switch (crypto.key_alg) { - case PGP_PKA_RSA: - if (!crypto.rsa.modulus_bit_len) { - crypto.rsa.modulus_bit_len = DEFAULT_RSA_NUMBITS; - } - break; - - case PGP_PKA_SM2: - if (!crypto.hash_alg) { - crypto.hash_alg = PGP_HASH_SM3; - } - if (!crypto.ecc.curve) { - crypto.ecc.curve = PGP_CURVE_SM2_P_256; - } - break; - - case PGP_PKA_ECDH: - case PGP_PKA_ECDSA: { - if (!crypto.hash_alg) { - crypto.hash_alg = (pgp_hash_alg_t) DEFAULT_HASH_ALGS[0]; - } - break; - } - - case PGP_PKA_EDDSA: - if (!crypto.ecc.curve) { - crypto.ecc.curve = PGP_CURVE_ED25519; - } - break; - - case PGP_PKA_DSA: { - if (!crypto.dsa.p_bitlen) { - crypto.dsa.p_bitlen = DSA_DEFAULT_P_BITLEN; - } - if (!crypto.dsa.q_bitlen) { - crypto.dsa.q_bitlen = dsa_choose_qsize_by_psize(crypto.dsa.p_bitlen); - } - break; - } - default: - break; - } - - adjust_hash_alg(crypto); -} - -static bool -validate_keygen_primary(const rnp_keygen_primary_desc_t &desc) -{ - /* Confirm that the specified pk alg can certify. - * gpg requires this, though the RFC only says that a V4 primary - * key SHOULD be a key capable of certification. - */ - if (!(pgp_pk_alg_capabilities(desc.crypto.key_alg) & PGP_KF_CERTIFY)) { - RNP_LOG("primary key alg (%d) must be able to sign", desc.crypto.key_alg); - return false; - } - - // check key flags - if (!desc.cert.key_flags) { - // these are probably not *technically* required - RNP_LOG("key flags are required"); - return false; - } else if (desc.cert.key_flags & ~pgp_pk_alg_capabilities(desc.crypto.key_alg)) { - // check the flags against the alg capabilities - RNP_LOG("usage not permitted for pk algorithm"); - return false; - } - // require a userid - if (!desc.cert.userid[0]) { - RNP_LOG("userid is required for primary key"); - return false; - } - return true; -} - -static uint32_t -get_numbits(const rnp_keygen_crypto_params_t *crypto) -{ - switch (crypto->key_alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - return crypto->rsa.modulus_bit_len; - case PGP_PKA_ECDSA: - case PGP_PKA_ECDH: - case PGP_PKA_EDDSA: - case PGP_PKA_SM2: { - if (const ec_curve_desc_t *curve = get_curve_desc(crypto->ecc.curve)) { - return curve->bitlen; - } else { - return 0; - } - } -#if defined(ENABLE_CRYPTO_REFRESH) - case PGP_PKA_ED25519: - return 255; - case PGP_PKA_X25519: - return 255; -#endif - case PGP_PKA_DSA: - return crypto->dsa.p_bitlen; - case PGP_PKA_ELGAMAL: - case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - return crypto->elgamal.key_bitlen; -#if defined(ENABLE_PQC) - case PGP_PKA_KYBER768_X25519: - FALLTHROUGH_STATEMENT; - // TODO add case PGP_PKA_KYBER1024_X448: FALLTHROUGH_STATEMENT; - case PGP_PKA_KYBER768_P256: - FALLTHROUGH_STATEMENT; - case PGP_PKA_KYBER1024_P384: - FALLTHROUGH_STATEMENT; - case PGP_PKA_KYBER768_BP256: - FALLTHROUGH_STATEMENT; - case PGP_PKA_KYBER1024_BP384: - return pgp_kyber_ecdh_composite_public_key_t::encoded_size(crypto->key_alg) * 8; - case PGP_PKA_DILITHIUM3_ED25519: - FALLTHROUGH_STATEMENT; - // TODO: add case PGP_PKA_DILITHIUM5_ED448: FALLTHROUGH_STATEMENT; - case PGP_PKA_DILITHIUM3_P256: - FALLTHROUGH_STATEMENT; - case PGP_PKA_DILITHIUM5_P384: - FALLTHROUGH_STATEMENT; - case PGP_PKA_DILITHIUM3_BP256: - FALLTHROUGH_STATEMENT; - case PGP_PKA_DILITHIUM5_BP384: - return pgp_dilithium_exdsa_composite_public_key_t::encoded_size(crypto->key_alg) * 8; - case PGP_PKA_SPHINCSPLUS_SHA2: - FALLTHROUGH_STATEMENT; - case PGP_PKA_SPHINCSPLUS_SHAKE: - return sphincsplus_pubkey_size(crypto->sphincsplus.param) * 8; -#endif - default: - return 0; - } -} - -static void -set_default_user_prefs(pgp_user_prefs_t &prefs) -{ - if (prefs.symm_algs.empty()) { - prefs.set_symm_algs( - std::vector(DEFAULT_SYMMETRIC_ALGS, - DEFAULT_SYMMETRIC_ALGS + ARRAY_SIZE(DEFAULT_SYMMETRIC_ALGS))); - } - if (prefs.hash_algs.empty()) { - prefs.set_hash_algs(std::vector( - DEFAULT_HASH_ALGS, DEFAULT_HASH_ALGS + ARRAY_SIZE(DEFAULT_HASH_ALGS))); - } - if (prefs.z_algs.empty()) { - prefs.set_z_algs(std::vector( - DEFAULT_COMPRESS_ALGS, DEFAULT_COMPRESS_ALGS + ARRAY_SIZE(DEFAULT_COMPRESS_ALGS))); - } -#if defined(ENABLE_CRYPTO_REFRESH) - if (prefs.aead_prefs.empty()) { - std::vector algs; - for (auto aead_alg : DEFAULT_AEAD_ALGS) { - for (auto sym_alg : prefs.symm_algs) { - algs.push_back(sym_alg); - algs.push_back(aead_alg); - } - } - prefs.set_aead_prefs(algs); - } -#endif -} - -static void -keygen_primary_merge_defaults(rnp_keygen_primary_desc_t &desc) -{ - keygen_merge_crypto_defaults(desc.crypto); - set_default_user_prefs(desc.cert.prefs); - - if (!desc.cert.key_flags) { - // set some default key flags if none are provided - desc.cert.key_flags = pk_alg_default_flags(desc.crypto.key_alg); - } - if (desc.cert.userid.empty()) { - char uid[MAX_ID_LENGTH] = {0}; - snprintf(uid, - sizeof(uid), - "%s %d-bit key <%s@localhost>", - id_str_pair::lookup(pubkey_alg_map, desc.crypto.key_alg), - get_numbits(&desc.crypto), - getenv_logname()); - desc.cert.userid = uid; - } -} - -#if defined(ENABLE_PQC) -static bool -pgp_check_key_hash_requirements(rnp_keygen_crypto_params_t &crypto) -{ - switch (crypto.key_alg) { - case PGP_PKA_SPHINCSPLUS_SHA2: - FALLTHROUGH_STATEMENT; - case PGP_PKA_SPHINCSPLUS_SHAKE: - if (!sphincsplus_hash_allowed( - crypto.key_alg, crypto.sphincsplus.param, crypto.hash_alg)) { - return false; - } - break; - case PGP_PKA_DILITHIUM3_ED25519: - FALLTHROUGH_STATEMENT; - // TODO: add case PGP_PKA_DILITHIUM5_ED448: FALLTHROUGH_STATEMENT; - case PGP_PKA_DILITHIUM3_P256: - FALLTHROUGH_STATEMENT; - case PGP_PKA_DILITHIUM5_P384: - FALLTHROUGH_STATEMENT; - case PGP_PKA_DILITHIUM3_BP256: - FALLTHROUGH_STATEMENT; - case PGP_PKA_DILITHIUM5_BP384: - if (!dilithium_hash_allowed(crypto.hash_alg)) { - return false; - } - break; - default: - break; - } - return true; -} -#endif - -bool -pgp_generate_primary_key(rnp_keygen_primary_desc_t &desc, - bool merge_defaults, - pgp_key_t & primary_sec, - pgp_key_t & primary_pub, - pgp_key_store_format_t secformat) -{ - // validate args - if (primary_sec.type() || primary_pub.type()) { - RNP_LOG("invalid parameters (should be zeroed)"); - return false; - } - - try { - // merge some defaults in, if requested - if (merge_defaults) { - keygen_primary_merge_defaults(desc); - } - // now validate the keygen fields - if (!validate_keygen_primary(desc)) { - return false; - } - -#if defined(ENABLE_PQC) - // check hash requirements - if (!pgp_check_key_hash_requirements(desc.crypto)) { - RNP_LOG("invalid hash algorithm for the chosen key"); - return false; - } -#endif - - // generate the raw key and fill tag/secret fields - pgp_key_pkt_t secpkt; - if (!pgp_generate_seckey(desc.crypto, secpkt, true, desc.pgp_version)) { - return false; - } - - pgp_key_t sec(secpkt); - pgp_key_t pub(secpkt, true); -#if defined(ENABLE_CRYPTO_REFRESH) - // for v6 packets, a direct-key sig is mandatory. - if (sec.version() == PGP_V6) { - sec.add_direct_sig(desc.cert, desc.crypto.hash_alg, *desc.crypto.ctx, &pub); - } -#endif - sec.add_uid_cert(desc.cert, desc.crypto.hash_alg, *desc.crypto.ctx, &pub); - - switch (secformat) { - case PGP_KEY_STORE_GPG: - case PGP_KEY_STORE_KBX: - primary_sec = std::move(sec); - primary_pub = std::move(pub); - break; - case PGP_KEY_STORE_G10: - primary_pub = std::move(pub); - if (!load_generated_g10_key( - &primary_sec, &secpkt, NULL, &primary_pub, *desc.crypto.ctx)) { - RNP_LOG("failed to load generated key"); - return false; - } - break; - default: - RNP_LOG("invalid format"); - return false; - } - } catch (const std::exception &e) { - RNP_LOG("Failure: %s", e.what()); - return false; - } - - /* mark it as valid */ - primary_pub.mark_valid(); - primary_sec.mark_valid(); - /* refresh key's data */ - return primary_pub.refresh_data(*desc.crypto.ctx) && - primary_sec.refresh_data(*desc.crypto.ctx); -} - -static bool -validate_keygen_subkey(rnp_keygen_subkey_desc_t &desc) -{ - if (!desc.binding.key_flags) { - RNP_LOG("key flags are required"); - return false; - } else if (desc.binding.key_flags & ~pgp_pk_alg_capabilities(desc.crypto.key_alg)) { - // check the flags against the alg capabilities - RNP_LOG("usage not permitted for pk algorithm"); - return false; - } - return true; -} - -static void -keygen_subkey_merge_defaults(rnp_keygen_subkey_desc_t &desc) -{ - keygen_merge_crypto_defaults(desc.crypto); - if (!desc.binding.key_flags) { - // set some default key flags if none are provided - desc.binding.key_flags = pk_alg_default_flags(desc.crypto.key_alg); - } -} - -bool -pgp_generate_subkey(rnp_keygen_subkey_desc_t & desc, - bool merge_defaults, - pgp_key_t & primary_sec, - pgp_key_t & primary_pub, - pgp_key_t & subkey_sec, - pgp_key_t & subkey_pub, - const pgp_password_provider_t &password_provider, - pgp_key_store_format_t secformat) -{ - // validate args - if (!primary_sec.is_primary() || !primary_pub.is_primary() || !primary_sec.is_secret() || - !primary_pub.is_public()) { - RNP_LOG("invalid parameters"); - return false; - } - if (subkey_sec.type() || subkey_pub.type()) { - RNP_LOG("invalid parameters (should be zeroed)"); - return false; - } - - // merge some defaults in, if requested - if (merge_defaults) { - keygen_subkey_merge_defaults(desc); - } - - // now validate the keygen fields - if (!validate_keygen_subkey(desc)) { - return false; - } - -#if defined(ENABLE_PQC) - // check hash requirements - if (!pgp_check_key_hash_requirements(desc.crypto)) { - RNP_LOG("invalid hash algorithm for the chosen key"); - return false; - } -#endif - - try { - /* decrypt the primary seckey if needed (for signatures) */ - rnp::KeyLocker primlock(primary_sec); - if (primary_sec.encrypted() && - !primary_sec.unlock(password_provider, PGP_OP_ADD_SUBKEY)) { - RNP_LOG("Failed to unlock primary key."); - return false; - } - /* generate the raw subkey */ - pgp_key_pkt_t secpkt; - if (!pgp_generate_seckey(desc.crypto, secpkt, false, desc.pgp_version)) { - return false; - } - pgp_key_pkt_t pubpkt = pgp_key_pkt_t(secpkt, true); - pgp_key_t sec(secpkt, primary_sec); - pgp_key_t pub(pubpkt, primary_pub); - /* add binding */ - primary_sec.add_sub_binding( - sec, pub, desc.binding, desc.crypto.hash_alg, *desc.crypto.ctx); - /* copy to the result */ - subkey_pub = std::move(pub); - switch (secformat) { - case PGP_KEY_STORE_GPG: - case PGP_KEY_STORE_KBX: - subkey_sec = std::move(sec); - break; - case PGP_KEY_STORE_G10: - if (!load_generated_g10_key( - &subkey_sec, &secpkt, &primary_sec, &subkey_pub, *desc.crypto.ctx)) { - RNP_LOG("failed to load generated key"); - return false; - } - break; - default: - RNP_LOG("invalid format"); - return false; - } - - subkey_pub.mark_valid(); - subkey_sec.mark_valid(); - return subkey_pub.refresh_data(&primary_pub, *desc.crypto.ctx) && - subkey_sec.refresh_data(&primary_sec, *desc.crypto.ctx); - } catch (const std::exception &e) { - RNP_LOG("Subkey generation failed: %s", e.what()); - return false; - } -} diff --git a/src/lib/key_material.cpp b/src/lib/key_material.cpp index 7138460ad..518f226bf 100644 --- a/src/lib/key_material.cpp +++ b/src/lib/key_material.cpp @@ -326,13 +326,6 @@ KeyMaterial::finish_generate() return true; } -bool -KeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - RNP_LOG("key generation not implemented for PK alg: %d", alg_); - return false; -} - bool KeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -567,21 +560,6 @@ RSAKeyMaterial::write_secret(pgp_packet_body_t &pkt) const pkt.add(key_.u); } -bool -RSAKeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - /* We do not generate PGP_PKA_RSA_ENCRYPT_ONLY or PGP_PKA_RSA_SIGN_ONLY keys */ - if (alg_ != PGP_PKA_RSA) { - RNP_LOG("Unsupported algorithm for key generation: %d", alg_); - return false; - } - if (rsa_generate(¶ms.ctx->rng, &key_, params.rsa.modulus_bit_len)) { - RNP_LOG("failed to generate RSA key"); - return false; - } - return finish_generate(); -} - bool RSAKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -763,16 +741,6 @@ DSAKeyMaterial::write_secret(pgp_packet_body_t &pkt) const pkt.add(key_.x); } -bool -DSAKeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - if (dsa_generate(¶ms.ctx->rng, &key_, params.dsa.p_bitlen, params.dsa.q_bitlen)) { - RNP_LOG("failed to generate DSA key"); - return false; - } - return finish_generate(); -} - bool DSAKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -928,21 +896,6 @@ EGKeyMaterial::write_secret(pgp_packet_body_t &pkt) const pkt.add(key_.x); } -bool -EGKeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - /* We do not generate PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN keys */ - if (alg_ != PGP_PKA_ELGAMAL) { - RNP_LOG("Unsupported algorithm for key generation: %d", alg_); - return false; - } - if (elgamal_generate(¶ms.ctx->rng, &key_, params.elgamal.key_bitlen)) { - RNP_LOG("failed to generate ElGamal key"); - return false; - } - return finish_generate(); -} - bool EGKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -1099,21 +1052,6 @@ ECKeyMaterial::write_secret(pgp_packet_body_t &pkt) const pkt.add(key_.x); } -bool -ECKeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - if (!curve_supported(params.ecc.curve)) { - RNP_LOG("EC generate: curve %d is not supported.", params.ecc.curve); - return false; - } - if (ec_generate(¶ms.ctx->rng, &key_, alg_, params.ecc.curve)) { - RNP_LOG("failed to generate EC key"); - return false; - } - key_.curve = params.ecc.curve; - return finish_generate(); -} - bool ECKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -1263,27 +1201,6 @@ ECDHKeyMaterial::write(pgp_packet_body_t &pkt) const pkt.add_byte(key_.key_wrap_alg); } -bool -ECDHKeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - if (!ecdh_set_params(&key_, params.ecc.curve)) { - RNP_LOG("Unsupported curve [ID=%d]", params.ecc.curve); - return false; - } - /* Special case for x25519*/ - if (params.ecc.curve == PGP_CURVE_25519) { - if (x25519_generate(¶ms.ctx->rng, &key_)) { - RNP_LOG("failed to generate x25519 key"); - return false; - } - key_.curve = params.ecc.curve; - return finish_generate(); - ; - } - /* Fallback to default EC generation for other cases */ - return ECKeyMaterial::generate(params); -} - bool ECDHKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -1371,16 +1288,6 @@ EDDSAKeyMaterial::clone() return std::unique_ptr(new EDDSAKeyMaterial(*this)); } -bool -EDDSAKeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - if (eddsa_generate(¶ms.ctx->rng, &key_)) { - RNP_LOG("failed to generate EDDSA key"); - return false; - } - return finish_generate(); -} - bool EDDSAKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -1574,16 +1481,6 @@ Ed25519KeyMaterial::write_secret(pgp_packet_body_t &pkt) const pkt.add(key_.priv); } -bool -Ed25519KeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - if (generate_ed25519_native(¶ms.ctx->rng, key_.priv, key_.pub)) { - RNP_LOG("failed to generate ED25519 key"); - return false; - } - return finish_generate(); -} - bool Ed25519KeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -1710,16 +1607,6 @@ X25519KeyMaterial::write_secret(pgp_packet_body_t &pkt) const pkt.add(key_.priv); } -bool -X25519KeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - if (generate_x25519_native(¶ms.ctx->rng, key_.priv, key_.pub)) { - RNP_LOG("failed to generate X25519 key"); - return false; - } - return finish_generate(); -} - bool X25519KeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -1847,16 +1734,6 @@ MlkemEcdhKeyMaterial::write_secret(pgp_packet_body_t &pkt) const pkt.add(key_.priv.get_encoded()); } -bool -MlkemEcdhKeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - if (pgp_kyber_ecdh_composite_key_t::gen_keypair(¶ms.ctx->rng, &key_, alg_)) { - RNP_LOG("failed to generate MLKEM-ECDH-composite key for PK alg %d", alg_); - return false; - } - return finish_generate(); -} - bool MlkemEcdhKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -1976,16 +1853,6 @@ DilithiumEccKeyMaterial::write_secret(pgp_packet_body_t &pkt) const pkt.add(key_.priv.get_encoded()); } -bool -DilithiumEccKeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - if (pgp_dilithium_exdsa_composite_key_t::gen_keypair(¶ms.ctx->rng, &key_, alg_)) { - RNP_LOG("failed to generate mldsa-ecdsa/eddsa-composite key for PK alg %d", alg_); - return false; - } - return finish_generate(); -} - bool DilithiumEccKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { @@ -2123,16 +1990,6 @@ SlhdsaKeyMaterial::write_secret(pgp_packet_body_t &pkt) const pkt.add(key_.priv.get_encoded()); } -bool -SlhdsaKeyMaterial::generate(const rnp_keygen_crypto_params_t ¶ms) -{ - if (pgp_sphincsplus_generate(¶ms.ctx->rng, &key_, params.sphincsplus.param, alg_)) { - RNP_LOG("failed to generate SLH-DSA key for PK alg %d", alg_); - return false; - } - return finish_generate(); -} - bool SlhdsaKeyMaterial::generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) { diff --git a/src/lib/key_material.hpp b/src/lib/key_material.hpp index 2965a76c1..ffcb065f8 100644 --- a/src/lib/key_material.hpp +++ b/src/lib/key_material.hpp @@ -30,10 +30,9 @@ #include "types.h" #include "defaults.h" -typedef struct pgp_packet_body_t pgp_packet_body_t; -typedef struct rnp_keygen_crypto_params_t rnp_keygen_crypto_params_t; -typedef struct pgp_encrypted_material_t pgp_encrypted_material_t; -typedef struct pgp_signature_material_t pgp_signature_material_t; +typedef struct pgp_packet_body_t pgp_packet_body_t; +typedef struct pgp_encrypted_material_t pgp_encrypted_material_t; +typedef struct pgp_signature_material_t pgp_signature_material_t; namespace pgp { @@ -209,7 +208,6 @@ class KeyMaterial { virtual bool parse_secret(pgp_packet_body_t &pkt) noexcept = 0; virtual void write(pgp_packet_body_t &pkt) const = 0; virtual void write_secret(pgp_packet_body_t &pkt) const = 0; - virtual bool generate(const rnp_keygen_crypto_params_t ¶ms); virtual bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms); virtual rnp_result_t encrypt(rnp::SecurityContext & ctx, pgp_encrypted_material_t &out, @@ -259,7 +257,6 @@ class RSAKeyMaterial : public KeyMaterial { bool parse_secret(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; void write_secret(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t encrypt(rnp::SecurityContext & ctx, pgp_encrypted_material_t &out, @@ -306,7 +303,6 @@ class DSAKeyMaterial : public KeyMaterial { bool parse_secret(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; void write_secret(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t verify(const rnp::SecurityContext & ctx, const pgp_signature_material_t & sig, @@ -345,7 +341,6 @@ class EGKeyMaterial : public KeyMaterial { bool parse_secret(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; void write_secret(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t encrypt(rnp::SecurityContext & ctx, pgp_encrypted_material_t &out, @@ -386,7 +381,6 @@ class ECKeyMaterial : public KeyMaterial { bool parse_secret(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; void write_secret(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; void set_secret(const mpi &x); size_t bits() const noexcept override; @@ -427,7 +421,6 @@ class ECDHKeyMaterial : public ECKeyMaterial { bool parse(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t encrypt(rnp::SecurityContext & ctx, pgp_encrypted_material_t &out, @@ -454,7 +447,6 @@ class EDDSAKeyMaterial : public ECKeyMaterial { : ECKeyMaterial(PGP_PKA_EDDSA, key, secret){}; std::unique_ptr clone() override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t verify(const rnp::SecurityContext & ctx, const pgp_signature_material_t & sig, @@ -509,7 +501,6 @@ class Ed25519KeyMaterial : public KeyMaterial { bool parse_secret(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; void write_secret(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t verify(const rnp::SecurityContext & ctx, const pgp_signature_material_t & sig, @@ -541,7 +532,6 @@ class X25519KeyMaterial : public KeyMaterial { bool parse_secret(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; void write_secret(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t encrypt(rnp::SecurityContext & ctx, pgp_encrypted_material_t &out, @@ -577,7 +567,6 @@ class MlkemEcdhKeyMaterial : public KeyMaterial { bool parse_secret(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; void write_secret(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t encrypt(rnp::SecurityContext & ctx, pgp_encrypted_material_t &out, @@ -612,7 +601,6 @@ class DilithiumEccKeyMaterial : public KeyMaterial { bool parse_secret(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; void write_secret(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t verify(const rnp::SecurityContext & ctx, const pgp_signature_material_t & sig, @@ -644,7 +632,6 @@ class SlhdsaKeyMaterial : public KeyMaterial { bool parse_secret(pgp_packet_body_t &pkt) noexcept override; void write(pgp_packet_body_t &pkt) const override; void write_secret(pgp_packet_body_t &pkt) const override; - bool generate(const rnp_keygen_crypto_params_t ¶ms) override; bool generate(rnp::SecurityContext &ctx, const KeyParams ¶ms) override; rnp_result_t verify(const rnp::SecurityContext & ctx, const pgp_signature_material_t & sig, diff --git a/src/lib/types.h b/src/lib/types.h index 8f8cb380f..e433f54fa 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -410,52 +410,6 @@ typedef struct pgp_user_prefs_t { void merge_defaults(pgp_version_t version = PGP_V4); } pgp_user_prefs_t; -struct rnp_keygen_ecc_params_t { - pgp_curve_t curve; -}; - -struct rnp_keygen_rsa_params_t { - uint32_t modulus_bit_len; -}; - -struct rnp_keygen_dsa_params_t { - size_t p_bitlen; - size_t q_bitlen; -}; - -struct rnp_keygen_elgamal_params_t { - size_t key_bitlen; -}; - -#if defined(ENABLE_PQC) -struct rnp_keygen_sphincsplus_params_t { - sphincsplus_parameter_t param; -}; -#endif - -/* structure used to hold context of key generation */ -namespace rnp { -class SecurityContext; -} - -typedef struct rnp_keygen_crypto_params_t { - // Asymmetric algorithm that user requested key for - pgp_pubkey_alg_t key_alg; - // Hash to be used for key signature - pgp_hash_alg_t hash_alg; - // Pointer to security context - rnp::SecurityContext *ctx; - union { - struct rnp_keygen_ecc_params_t ecc; - struct rnp_keygen_rsa_params_t rsa; - struct rnp_keygen_dsa_params_t dsa; - struct rnp_keygen_elgamal_params_t elgamal; -#if defined(ENABLE_PQC) - struct rnp_keygen_sphincsplus_params_t sphincsplus; -#endif - }; -} rnp_keygen_crypto_params_t; - typedef struct rnp_selfsig_cert_info_t { std::string userid; /* userid, required */ uint8_t key_flags{}; /* key flags */ @@ -477,18 +431,6 @@ typedef struct rnp_selfsig_binding_info_t { uint32_t key_expiration; } rnp_selfsig_binding_info_t; -typedef struct rnp_keygen_primary_desc_t { - rnp_keygen_crypto_params_t crypto{}; - rnp_selfsig_cert_info_t cert{}; - pgp_version_t pgp_version = PGP_V4; -} rnp_keygen_primary_desc_t; - -typedef struct rnp_keygen_subkey_desc_t { - rnp_keygen_crypto_params_t crypto; - rnp_selfsig_binding_info_t binding; - pgp_version_t pgp_version = PGP_V4; -} rnp_keygen_subkey_desc_t; - typedef struct rnp_key_protection_params_t { pgp_symm_alg_t symm_alg; pgp_cipher_mode_t cipher_mode;