Synopsis: iked rejects ECDSA-384 signature authentication from macOS/iOS native
IKEv2 clients
Category: system
Environment:
System : OpenBSD 7.9 (amd64, GENERIC.MP, syspatches 001-034), iked
from base
Peer : macOS 26.6.2 (Tahoe), native IKEv2 client (NEIKEv2Provider),
configuration profile
with CertificateType=ECDSA384 and a P-384 client certificate
Description:
With a P-384 client certificate the Apple client authenticates with AUTH
method 10
(ECDSA-384, RFC 4754). It does not send r|s as 2x48 bytes; instead it pads
r and s with
leading zeros to 2x104 bytes (104 = maximum DER length of a P-384
signature), so the AUTH
data is 208 bytes long. Apple's own log shows
Authentication Protocol = ECDSA384
Authentication Data = {length = 208, bytes = 0x00000000 00000000
00000000 00000000 ... }
iked logs "ikev2_pld_auth: method ECDSA_384 length 208" and then
"ikev2_msg_authverify: authentication failed" and sends
AUTHENTICATION_FAILED.
The reason is the length check in sbin/iked/crypto.c, _dsa_verify_prepare():
if (*lenp < 64 || *lenp > 132 || *lenp % 2)
goto done;
which rejects the payload before BN_bin2bn() would strip the leading zeros.
strongSwan
accepts the same payload (it splits the data in half and lets BN_bin2bn()
handle it), which
is why Apple clients work with strongSwan but not with iked.
Apple's encoding is not RFC 4754 conformant, but the value is correct; the
numbers are only
zero-padded. Since the halves are DER-encoded afterwards and
EVP_DigestVerifyFinal() checks r
and s against the curve order anyway, the upper bound in the pre-check
seems to be a sanity
limit rather than a security control.
How-To-Repeat:
iked as responder with a P-384 server certificate and any client policy;
macOS 26 (or iOS 26)
with a configuration profile: com.apple.vpn.managed, VPNType IKEv2,
AuthenticationMethod
Certificate, CertificateType ECDSA384, P-384 client certificate (PKCS12
payload). IKE proposal
aes-256 / hmac-sha2-384 / ecp384. The IKE_AUTH request is rejected with
AUTHENTICATION_FAILED;
the server-side CRL/chain checks pass (ca_validate_cert ... ok).
Fix:
Relaxing the upper bound makes the client connect (tested with 512; even
lengths >= 64 are
still required and r/s are validated by libcrypto):
--- sbin/iked/crypto.c
+++ sbin/iked/crypto.c
@@ -1149,7 +1149,7 @@
* buffer (we cannot override the given buffer) and the caller
* has to free this buffer ('freeme').
*/
- if (*lenp < 64 || *lenp > 132 || *lenp % 2)
+ if (*lenp < 64 || *lenp > 512 || *lenp % 2)
goto done;
bnlen = (*lenp)/2;
/* sigp points to concatenation: r|s */
A stricter alternative would be to derive the expected size from the key's
curve and accept
any even length >= 2*n whose extra leading bytes are zero.
Sincerly yours,
Chris
etis GmbH
Christian Zöpfchen
Geschäftsführer
Metternichstr. 28 - 30
54292 Trier
Tel.: +496514936700
Fax: +4965149367099
E-Mail: [email protected]
WWW: www.etis-gmbh.de
Pflichtangaben: www.etis-gmbh.de/pflichtangaben
Unsere Preistabelle und allgemeinen Geschäftsbedingungen finden Sie auf unserer
Website.
Diese E-Mail enthält vertrauliche und/oder rechtlich geschützte Informationen.
Wenn Sie nicht der richtige Adressat sind oder diese E-Mail irrtümlich erhalten
haben, informieren Sie bitte sofort den Absender und vernichten Sie diese Mail.
Das unerlaubte Kopieren sowie die unbefugte Weitergabe dieser Mail ist nicht
gestattet.
This e-mail may contain confidential and/or privileged information. If you are
not the intended recipient (or have received this e-mail in error) please
notify the sender immediately and destroy this e-mail. Any unauthorized
copying, disclosure or distribution of the material in this e-mail is strictly
forbidden.