Commit 328e8c07c7 for strongswan.org

commit 328e8c07c74770c1355bde7ca3c35652fecbd8db
Author: Tobias Brunner <tobias@strongswan.org>
Date:   Wed Oct 7 08:31:26 2026 +0200

    public-key: Add optional parameters when en-/decoding subjectPublicKeyInfo

    This allows using this also for ECDSA where the curve is encoded as
    parameters.

diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c
index 202b38b700..665d2293b6 100644
--- a/src/libstrongswan/asn1/asn1.c
+++ b/src/libstrongswan/asn1/asn1.c
@@ -682,6 +682,10 @@ int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters
 					*parameters = blob;
 				}
 			}
+			else if (parameters)
+			{
+				*parameters = chunk_empty;
+			}
 		}
 	}
 	return alg;
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
index a26ef306ac..3852b2882d 100644
--- a/src/libstrongswan/credentials/keys/public_key.c
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -120,12 +120,19 @@ bool public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint)
 /**
  * See header.
  */
-chunk_t public_key_info_encode(chunk_t pubkey, int oid)
+chunk_t public_key_info_encode(chunk_t pubkey, int oid, chunk_t *params)
 {
-	return asn1_wrap(ASN1_SEQUENCE, "mm",
-						asn1_algorithmIdentifier(oid),
-						asn1_bitstring("c", pubkey)
-					 );
+	chunk_t algid;
+
+	if (params)
+	{
+		algid = asn1_algorithmIdentifier_params(oid, chunk_clone(*params));
+	}
+	else
+	{
+		algid = asn1_algorithmIdentifier(oid);
+	}
+	return asn1_wrap(ASN1_SEQUENCE, "mm", algid, asn1_bitstring("c", pubkey));
 }

 /**
@@ -143,7 +150,8 @@ static const asn1Object_t pkinfoObjects[] = {
 /**
  * See header.
  */
-key_type_t public_key_info_decode(chunk_t spki, chunk_t *pubkey)
+key_type_t public_key_info_decode(chunk_t spki, chunk_t *pubkey,
+								  chunk_t *params)
 {
 	asn1_parser_t *parser;
 	int oid = OID_UNKNOWN;
@@ -158,7 +166,7 @@ key_type_t public_key_info_decode(chunk_t spki, chunk_t *pubkey)
 		{
 			case PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM:
 				oid = asn1_parse_algorithmIdentifier(object,
-							parser->get_level(parser)+1, NULL);
+							parser->get_level(parser)+1, params);
 				break;
 			case PKINFO_SUBJECT_PUBLIC_KEY:
 				if (pubkey)
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
index 6d73b25994..5e066f5580 100644
--- a/src/libstrongswan/credentials/keys/public_key.h
+++ b/src/libstrongswan/credentials/keys/public_key.h
@@ -266,20 +266,24 @@ bool public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint);
 /**
  * ASN.1 encoding of public key info
  *
- * @param pubkey		public key blob
+ * @param pubkey		public key blob (cloned)
  * @param oid			OID of the public key type
- * @return				ASN.1 encoded public key info blob
+ * @param params		optional algorithm identifier parameters (cloned)
+ * @return				ASN.1 encoded public key info blob (allocated)
  */
-chunk_t public_key_info_encode(chunk_t pubkey, int oid);
+chunk_t public_key_info_encode(chunk_t pubkey, int oid, chunk_t *params);

 /**
  * ASN.1 decoding of public key info
  *
  * @param spki			ASN.1 encoded subjectPublicKeyInfo
- * @param pubkey		unwrapped public key blob
+ * @param[out] pubkey	unwrapped public key blob (points into \p spki)
+ * @param[out] params	algorithm identifier parameters (optional, points
+ *						into \p spki)
  * @return				type of the key (KEY_ANY if failure)
  */
-key_type_t public_key_info_decode(chunk_t spki, chunk_t *pubkey);
+key_type_t public_key_info_decode(chunk_t spki, chunk_t *pubkey,
+								  chunk_t *params);

 /**
  * Return OID for a given key type
diff --git a/src/libstrongswan/plugins/botan/botan_util_keys.c b/src/libstrongswan/plugins/botan/botan_util_keys.c
index 9ee7076eee..710d992cfa 100644
--- a/src/libstrongswan/plugins/botan/botan_util_keys.c
+++ b/src/libstrongswan/plugins/botan/botan_util_keys.c
@@ -137,9 +137,9 @@ public_key_t *botan_public_key_load(key_type_t type, va_list args)
 	{
 		if (type == KEY_ANY)
 		{
-			type = public_key_info_decode(blob, NULL);
+			type = public_key_info_decode(blob, NULL, NULL);
 		}
-		else if (type != public_key_info_decode(blob, NULL))
+		else if (type != public_key_info_decode(blob, NULL, NULL))
 		{	/* reject inconsistent request */
 			type = KEY_ANY;
 		}
diff --git a/src/libstrongswan/plugins/curve25519/curve25519_private_key.c b/src/libstrongswan/plugins/curve25519/curve25519_private_key.c
index 9c4ebec905..f30a4b1cd5 100644
--- a/src/libstrongswan/plugins/curve25519/curve25519_private_key.c
+++ b/src/libstrongswan/plugins/curve25519/curve25519_private_key.c
@@ -133,7 +133,7 @@ METHOD(private_key_t, get_public_key, public_key_t*,
 	public_key_t *public;
 	chunk_t pubkey;

-	pubkey = public_key_info_encode(this->pubkey, OID_ED25519);
+	pubkey = public_key_info_encode(this->pubkey, OID_ED25519, NULL);
 	public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED25519,
 								BUILD_BLOB_ASN1_DER, pubkey, BUILD_END);
 	free(pubkey.ptr);
diff --git a/src/libstrongswan/plugins/curve25519/curve25519_public_key.c b/src/libstrongswan/plugins/curve25519/curve25519_public_key.c
index 1f74590591..1fb6dca21e 100644
--- a/src/libstrongswan/plugins/curve25519/curve25519_public_key.c
+++ b/src/libstrongswan/plugins/curve25519/curve25519_public_key.c
@@ -159,7 +159,7 @@ METHOD(public_key_t, get_encoding, bool,
 {
 	bool success = TRUE;

-	*encoding = public_key_info_encode(this->pubkey, OID_ED25519);
+	*encoding = public_key_info_encode(this->pubkey, OID_ED25519, NULL);

 	if (type != PUBKEY_SPKI_ASN1_DER)
 	{
@@ -340,7 +340,7 @@ bool curve25519_public_key_fingerprint(chunk_t pubkey,
 			key = chunk_clone(pubkey);
 			break;
 		case KEYID_PUBKEY_INFO_SHA1:
-			key = public_key_info_encode(pubkey, OID_ED25519);
+			key = public_key_info_encode(pubkey, OID_ED25519, NULL);
 			break;
 		default:
 			return FALSE;
diff --git a/src/libstrongswan/plugins/ml/ml_dsa_public_key.c b/src/libstrongswan/plugins/ml/ml_dsa_public_key.c
index bd3131bc88..6d2e217c6a 100644
--- a/src/libstrongswan/plugins/ml/ml_dsa_public_key.c
+++ b/src/libstrongswan/plugins/ml/ml_dsa_public_key.c
@@ -465,7 +465,8 @@ bool ml_dsa_fingerprint(chunk_t pubkey, key_type_t type,
 			encoding = chunk_clone(pubkey);
 			break;
 		case KEYID_PUBKEY_INFO_SHA1:
-			encoding = public_key_info_encode(pubkey, key_type_to_oid(type));
+			encoding = public_key_info_encode(pubkey, key_type_to_oid(type),
+											  NULL);
 			break;
 		default:
 			return FALSE;
@@ -511,7 +512,7 @@ METHOD(public_key_t, get_encoding, bool,
 	int oid;

 	oid = key_type_to_oid(this->type);
-	*encoding = public_key_info_encode(this->pubkey, oid);
+	*encoding = public_key_info_encode(this->pubkey, oid, NULL);

 	if (type != PUBKEY_SPKI_ASN1_DER)
 	{
@@ -615,7 +616,7 @@ public_key_t *ml_dsa_public_key_load(key_type_t type, va_list args)
 				continue;
 			case BUILD_BLOB_ASN1_DER:
 				pkcs1 = va_arg(args, chunk_t);
-				pkcs1_type = public_key_info_decode(pkcs1, &blob);
+				pkcs1_type = public_key_info_decode(pkcs1, &blob, NULL);
 				if (type != KEY_ANY && type != pkcs1_type)
 				{
 					return NULL;
diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
index e0a26833e2..8d6f921c8c 100644
--- a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
+++ b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
@@ -32,7 +32,7 @@ static public_key_t *parse_public_key(chunk_t blob)
 	chunk_t pubkey;
 	key_type_t type;

-	type = public_key_info_decode(blob, &pubkey);
+	type = public_key_info_decode(blob, &pubkey, NULL);

 	switch (type)
 	{
diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.c
index 070c92a3de..3f192bf9bf 100644
--- a/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.c
+++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.c
@@ -137,7 +137,8 @@ bool wolfssl_ml_dsa_fingerprint(MlDsaKey *key, key_type_t type,
 			encoding = chunk_clone(pubkey);
 			break;
 		case KEYID_PUBKEY_INFO_SHA1:
-			encoding = public_key_info_encode(pubkey, key_type_to_oid(type));
+			encoding = public_key_info_encode(pubkey, key_type_to_oid(type),
+											  NULL);
 			break;
 		default:
 			goto end;
@@ -198,7 +199,7 @@ METHOD(public_key_t, get_encoding, bool,
 	}

 	oid = key_type_to_oid(this->type);
-	*encoding = public_key_info_encode(pubkey, oid);
+	*encoding = public_key_info_encode(pubkey, oid, NULL);
 	success = TRUE;

 	if (type != PUBKEY_SPKI_ASN1_DER)
@@ -326,7 +327,7 @@ public_key_t *wolfssl_ml_dsa_public_key_load(key_type_t type, va_list args)
 				continue;
 			case BUILD_BLOB_ASN1_DER:
 				pkcs1 = va_arg(args, chunk_t);
-				pkcs1_type = public_key_info_decode(pkcs1, &blob);
+				pkcs1_type = public_key_info_decode(pkcs1, &blob, NULL);
 				if (type != KEY_ANY && type != pkcs1_type)
 				{
 					return NULL;