From: Tobias Brunner Date: Mon, 27 Mar 2023 14:40:31 +0000 (+0200) Subject: botan: Pass n and e separately for RSA public keys X-Git-Tag: 5.9.11dr2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e73e9d3e94bad1c3785308bac2224a98d7528bb;p=thirdparty%2Fstrongswan.git botan: Pass n and e separately for RSA public keys Some encoders, like those provided by the dnskey and sshkey plugins, require these separately when encoding keys. Also fixes the type for the ASN.1 encoding (which is a subjectPublicKeyInfo structure) depending on the key type. This worked fine for PEM encoding as the pem plugin doesn't care what the actual type of the key is (which is encoded in the SPKI structure), but other plugins do (e.g. the sshkey plugin). --- diff --git a/src/libstrongswan/plugins/botan/botan_util.c b/src/libstrongswan/plugins/botan/botan_util.c index dbd0c9f54a..76c3e65a69 100644 --- a/src/libstrongswan/plugins/botan/botan_util.c +++ b/src/libstrongswan/plugins/botan/botan_util.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Tobias Brunner + * Copyright (C) 2018-2023 Tobias Brunner * Copyright (C) 2018 Andreas Steffen * * Copyright (C) 2018 René Korthaus @@ -80,13 +80,45 @@ const char *botan_get_hash(hash_algorithm_t hash) } } +/** + * Encode the given RSA public key parameter as chunk. + */ +static bool encode_rsa_field(botan_pubkey_t pubkey, const char *name, + chunk_t *chunk) +{ + botan_mp_t val = NULL; + size_t len = 0; + + if (botan_mp_init(&val) || + botan_pubkey_get_field(val, pubkey, name) || + botan_mp_num_bytes(val, &len) || !len) + { + botan_mp_destroy(val); + return FALSE; + } + + *chunk = chunk_alloc(len); + if (botan_mp_to_bin(val, chunk->ptr)) + { + botan_mp_destroy(val); + chunk_free(chunk); + return FALSE; + } + botan_mp_destroy(val); + return TRUE; +} + /* * Described in header */ bool botan_get_encoding(botan_pubkey_t pubkey, cred_encoding_type_t type, chunk_t *encoding) { - bool success = TRUE; + chunk_t asn1_encoding, n = chunk_empty, e = chunk_empty; + cred_encoding_part_t part = CRED_PART_END; + char algo[8]; + size_t len = sizeof(algo); + bool success = FALSE; encoding->len = 0; if (botan_pubkey_export(pubkey, NULL, &encoding->len, @@ -104,15 +136,43 @@ bool botan_get_encoding(botan_pubkey_t pubkey, cred_encoding_type_t type, return FALSE; } - if (type != PUBKEY_SPKI_ASN1_DER) + if (type == PUBKEY_SPKI_ASN1_DER) + { + return TRUE; + } + + asn1_encoding = *encoding; + if (botan_pubkey_algo_name(pubkey, algo, &len)) { - chunk_t asn1_encoding = *encoding; + chunk_free(&asn1_encoding); + return FALSE; + } + if (streq(algo, "RSA") && + encode_rsa_field(pubkey, "n", &n) && + encode_rsa_field(pubkey, "e", &e)) + { success = lib->encoding->encode(lib->encoding, type, NULL, encoding, - CRED_PART_ECDSA_PUB_ASN1_DER, - asn1_encoding, CRED_PART_END); - chunk_free(&asn1_encoding); + CRED_PART_RSA_PUB_ASN1_DER, asn1_encoding, + CRED_PART_RSA_MODULUS, n, + CRED_PART_RSA_PUB_EXP, e, CRED_PART_END); + } + else + { + if (streq(algo, "ECDSA")) + { + part = CRED_PART_ECDSA_PUB_ASN1_DER; + } + else if (streq(algo, "Ed25519")) + { + part = CRED_PART_EDDSA_PUB_ASN1_DER; + } + success = lib->encoding->encode(lib->encoding, type, NULL, encoding, + part, asn1_encoding, CRED_PART_END); } + chunk_free(&asn1_encoding); + chunk_free(&n); + chunk_free(&e); return success; }