]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
botan: Pass n and e separately for RSA public keys
authorTobias Brunner <tobias@strongswan.org>
Mon, 27 Mar 2023 14:40:31 +0000 (16:40 +0200)
committerTobias Brunner <tobias@strongswan.org>
Thu, 30 Mar 2023 08:45:04 +0000 (10:45 +0200)
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).

src/libstrongswan/plugins/botan/botan_util.c

index dbd0c9f54aff969c4e2c4414d0e06508b6bc174a..76c3e65a693145ceed6acea9ec36173d8f76f94d 100644 (file)
@@ -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;
 }