Tests: using platform-dependent crypto
0x5ECF4ULT opened this issue · 8 comments
Describe the bug
Tests.Kerberos.NET
runs a few tests using unsupported crypto. The problem is that this makes the tests platform-dependent. This issue documents problematic operations.
To Reproduce
Please watch #334. Ported tests dropping soon-ish(tm).
Expected behavior
Varies. I expect a perfectly fine test to succeed. Some tests are supposed to fail but aren't covered.
Additional context
Bug found in the course of porting the tests to Linux.
This is the stacktrace for RestrictionType_ApOptions. The culprit lies in a ticket containing delegation.
System.PlatformNotSupportedException: A crypto implementation of MD4 does not exist for Unix
at Kerberos.NET.Crypto.CryptoPal.PlatformNotSupported(String algorithm) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/Pal/CryptoPal.cs:line 95
at Kerberos.NET.Crypto.LinuxCryptoPal.Md4() in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/Pal/Linux/LinuxCryptoPal.cs:line 22
at Kerberos.NET.Crypto.RC4Transformer.MD4(ReadOnlyMemory`1 key) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/RC4/RC4Transformer.cs:line 168
at Kerberos.NET.Crypto.RC4Transformer.String2Key(KerberosKey key) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/RC4/RC4Transformer.cs:line 38
at Kerberos.NET.Crypto.KerberosKey.<>c__DisplayClass45_0.<GetKey>b__0(EncryptionType etype) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/KerberosKey.cs:line 224
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Kerberos.NET.Crypto.KerberosKey.GetKey(KerberosCryptoTransformer transformer) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/KerberosKey.cs:line 224
at Kerberos.NET.Crypto.RC4Transformer.Decrypt(ReadOnlyMemory`1 ciphertext, KerberosKey key, KeyUsage usage) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/RC4/RC4Transformer.cs:line 82
at Kerberos.NET.Entities.KrbEncryptedData.Decrypt[T](KerberosKey key, KeyUsage usage, Func`2 func) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Entities/Krb/KrbEncryptedData.cs:line 37
at Kerberos.NET.Crypto.DecryptedKrbApReq.Decrypt(KerberosKey ticketEncryptingKey) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/DecryptedKrbApReq.cs:line 75
at Kerberos.NET.Crypto.DecryptedKrbApReq.Decrypt(KeyTable keytab) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/DecryptedKrbApReq.cs:line 70
at Kerberos.NET.Entities.ContextToken.DecryptApReq(KrbApReq token, KeyTable keytab) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Entities/SpNego/ContextToken.cs:line 35
at Kerberos.NET.Entities.KerberosContextToken.DecryptApReq(KeyTable keys) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Entities/SpNego/KerberosContextToken.cs:line 26
at Kerberos.NET.Entities.NegotiateContextToken.DecryptApReq(KeyTable keys) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Entities/SpNego/NegotiateContextToken.cs:line 42
at Kerberos.NET.KerberosValidator.Validate(ReadOnlyMemory`1 requestBytes) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/KerberosValidator.cs:line 70
at Kerberos.NET.KerberosAuthenticator.Authenticate(ReadOnlyMemory`1 token) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/KerberosAuthenticator.cs:line 73
at Kerberos.NET.KerberosAuthenticator.Authenticate(Byte[] token) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/KerberosAuthenticator.cs:line 69
at Tests.Kerberos.NET.AuthorizationsTests.GenerateAuthZ() in /home/.../RiderProjects/Kerberos.NET/Tests/Tests.Kerberos.NET/KrbApReq/AuthorizationsTests.cs:line 27
at Tests.Kerberos.NET.AuthorizationsTests.RestrictionType_ApOptions() in /home/.../RiderProjects/Kerberos.NET/Tests/Tests.Kerberos.NET/KrbApReq/AuthorizationsTests.cs:line 113
Inside the testdata there is a certificate called testuser.pfx
. This test should not fail on a system that doesn't support the used crypto.
System.PlatformNotSupportedException: A crypto implementation of DH-MODP-14 does not exist for Unix
at Kerberos.NET.Crypto.CryptoPal.PlatformNotSupported(String algorithm) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/Pal/CryptoPal.cs:line 95
at Kerberos.NET.Crypto.LinuxCryptoPal.DiffieHellmanModp14() in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/Pal/Linux/LinuxCryptoPal.cs:line 55
at Kerberos.NET.Credentials.KerberosAsymmetricCredential.StartKeyAgreement() in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Credentials/KerberosAsymmetricCredential.cs:line 131
at Kerberos.NET.Credentials.KerberosAsymmetricCredential.TransformKdcReq(KrbKdcReq req) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Credentials/KerberosAsymmetricCredential.cs:line 203
at Kerberos.NET.Entities.KrbAsReq.CreateAsReq(KerberosCredential credential, AuthenticationOptions options) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Entities/Krb/KrbAsReq.cs:line 78
at Kerberos.NET.Client.KerberosClient.RequestTgt(KerberosCredential credential) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Client/KerberosClient.cs:line 1194
at Kerberos.NET.Client.KerberosClient.AuthenticateCredential(KerberosCredential credential) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Client/KerberosClient.cs:line 374
at Kerberos.NET.Client.KerberosClient.Authenticate(KerberosCredential credential) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Client/KerberosClient.cs:line 357
at Tests.Kerberos.NET.KdcListenerTestBase.RequestAndValidateTicketsWithCaches(KdcListener listener, String user, String password, String overrideKdc, KeyTable keytab, String s4u, Boolean encodeNego, Boolean caching, Boolean includePac, X509Certificate2 cert, String spn, KeyAgreementAlgorithm keyAgreement, Boolean allowWeakCrypto, Boolean useWeakCrypto, Boolean mutualAuth, KrbTicket s4uTicket, Boolean useKrb5TicketCache) in /home/.../RiderProjects/Kerberos.NET/Tests/Tests.Kerberos.NET/End2End/KdcListenerTestBase.cs:line 229
at Tests.Kerberos.NET.KdcListenerTestBase.RequestAndValidateTickets(KdcListener listener, String user, String password, String overrideKdc, KeyTable keytab, String s4u, Boolean encodeNego, Boolean caching, Boolean includePac, X509Certificate2 cert, String spn, KeyAgreementAlgorithm keyAgreement, Boolean allowWeakCrypto, Boolean useWeakCrypto, Boolean mutualAuth, KrbTicket s4uTicket) in /home/.../RiderProjects/Kerberos.NET/Tests/Tests.Kerberos.NET/End2End/KdcListenerTestBase.cs:line 134
at Tests.Kerberos.NET.ClientToKdcE2ETests.E2E_PKINIT() in /home/.../RiderProjects/Kerberos.NET/Tests/Tests.Kerberos.NET/End2End/ClientToKdcE2ETests.cs:line 106
The same problem applies to E2E_PKINIT_Modp2_Fails
, E2E_PKINIT_Synchronous
and AsReqPreAuth_PkinitCertificateAccessible
.
Another location is in NdrTests.cs, where tests using either GeneratePacContainingClaims
or GeneratePacWithoutClaims
through GeneratePac
fail. Here is an example stacktrace for NdrLogonInfoRoundtrip
:
System.PlatformNotSupportedException: A crypto implementation of MD4 does not exist for Unix
at Kerberos.NET.Crypto.CryptoPal.PlatformNotSupported(String algorithm) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/Pal/CryptoPal.cs:line 95
at Kerberos.NET.Crypto.LinuxCryptoPal.Md4() in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/Pal/Linux/LinuxCryptoPal.cs:line 22
at Kerberos.NET.Crypto.RC4Transformer.MD4(ReadOnlyMemory`1 key) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/RC4/RC4Transformer.cs:line 168
at Kerberos.NET.Crypto.RC4Transformer.String2Key(KerberosKey key) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/RC4/RC4Transformer.cs:line 38
at Kerberos.NET.Crypto.KerberosKey.<>c__DisplayClass45_0.<GetKey>b__0(EncryptionType etype) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/KerberosKey.cs:line 224
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Kerberos.NET.Crypto.KerberosKey.GetKey(KerberosCryptoTransformer transformer) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/KerberosKey.cs:line 224
at Kerberos.NET.Crypto.RC4Transformer.Decrypt(ReadOnlyMemory`1 ciphertext, KerberosKey key, KeyUsage usage) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/RC4/RC4Transformer.cs:line 82
at Kerberos.NET.Entities.KrbEncryptedData.Decrypt[T](KerberosKey key, KeyUsage usage, Func`2 func) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Entities/Krb/KrbEncryptedData.cs:line 37
at Kerberos.NET.Crypto.DecryptedKrbApReq.Decrypt(KerberosKey ticketEncryptingKey) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/DecryptedKrbApReq.cs:line 75
at Kerberos.NET.Crypto.DecryptedKrbApReq.Decrypt(KeyTable keytab) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Crypto/DecryptedKrbApReq.cs:line 70
at Kerberos.NET.Entities.ContextToken.DecryptApReq(KrbApReq token, KeyTable keytab) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Entities/SpNego/ContextToken.cs:line 35
at Kerberos.NET.Entities.KerberosContextToken.DecryptApReq(KeyTable keys) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Entities/SpNego/KerberosContextToken.cs:line 26
at Kerberos.NET.Entities.NegotiateContextToken.DecryptApReq(KeyTable keys) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/Entities/SpNego/NegotiateContextToken.cs:line 42
at Kerberos.NET.KerberosValidator.Validate(ReadOnlyMemory`1 requestBytes) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/KerberosValidator.cs:line 70
at Kerberos.NET.KerberosValidator.Validate(Byte[] requestBytes) in /home/.../RiderProjects/Kerberos.NET/Kerberos.NET/KerberosValidator.cs:line 58
at Tests.Kerberos.NET.NdrTests.GeneratePacContainingClaims() in /home/.../RiderProjects/Kerberos.NET/Tests/Tests.Kerberos.NET/Pac/NdrTests.cs:line 66
at Tests.Kerberos.NET.NdrTests.GeneratePac(Boolean includeClaims) in /home/.../RiderProjects/Kerberos.NET/Tests/Tests.Kerberos.NET/Pac/NdrTests.cs:line 42
at Tests.Kerberos.NET.NdrTests.NdrLogonInfoRoundtrip() in /home/.../RiderProjects/Kerberos.NET/Tests/Tests.Kerberos.NET/Pac/NdrTests.cs:line 197
We have a bug tracking the request to change these values. It hasn't been a high priority unfortunately. #148
Is it okay to keep this issue open to document the creds in question?
Oh, yes, definitely.
I'll join the problem. KerberosKey generation also does not work for me in Linux.
Framework: .Net 8
OS: Alpine 3.19 in Container
I'm trying to generate a key using:
var keys = new[] {
new KerberosKey(
"P@ssw0rd*",
new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "DOMAIN.SRV", new[] { "HTTP/SERVER.domain.srv" }),
host: "SERVER.domain.srv",
etype: EncryptionType.AES128_CTS_HMAC_SHA1_96)};
var krb = new KerberosAuthenticator(new KerberosValidator(keys[0]));
var identity = krb.Authenticate(authHeader[0].Replace("Negotiate ", ""));
Then I get the same error:
{System.PlatformNotSupportedException: A crypto implementation of MD4 does not exist for Unix
at Kerberos.NET.Crypto.CryptoPal.PlatformNotSupported(String algorithm) in D:\a\1\s\Kerberos.NET\Crypto\Pal\CryptoPal.cs:line 95
at Kerberos.NET.Crypto.LinuxCryptoPal.Md4() in D:\a\1\s\Kerberos.NET\Crypto\Pal\Linux\LinuxCryptoPal.cs:line 22
at Kerberos.NET.Crypto.RC4Transformer.MD4(ReadOnlyMemory`1 key) in D:\a\1\s\Kerberos.NET\Crypto\RC4\RC4Transformer.cs:line 168
at Kerberos.NET.Crypto.RC4Transformer.String2Key(KerberosKey key) in D:\a\1\s\Kerberos.NET\Crypto\RC4\RC4Transformer.cs:line 38
at Kerberos.NET.Crypto.KerberosKey.<>c__DisplayClass45_0.<GetKey>b__0(EncryptionType etype) in D:\a\1\s\Kerberos.NET\Crypto\KerberosKey.cs:line 224
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Kerberos.NET.Crypto.KerberosKey.GetKey(KerberosCryptoTransformer transformer) in D:\a\1\s\Kerberos.NET\Crypto\KerberosKey.cs:line 224
at Kerberos.NET.Crypto.RC4Transformer.Decrypt(ReadOnlyMemory`1 ciphertext, KerberosKey key, KeyUsage usage) in D:\a\1\s\Kerberos.NET\Crypto\RC4\RC4Transformer.cs:line 82
at Kerberos.NET.Entities.KrbEncryptedData.Decrypt[T](KerberosKey key, KeyUsage usage, Func`2 func) in D:\a\1\s\Kerberos.NET\Entities\Krb\KrbEncryptedData.cs:line 34
at Kerberos.NET.Crypto.DecryptedKrbApReq.Decrypt(KerberosKey ticketEncryptingKey) in D:\a\1\s\Kerberos.NET\Crypto\DecryptedKrbApReq.cs:line 75
at Kerberos.NET.Crypto.DecryptedKrbApReq.Decrypt(KeyTable keytab) in D:\a\1\s\Kerberos.NET\Crypto\DecryptedKrbApReq.cs:line 70
at Kerberos.NET.Entities.ContextToken.DecryptApReq(KrbApReq token, KeyTable keytab) in D:\a\1\s\Kerberos.NET\Entities\SpNego\ContextToken.cs:line 43
at Kerberos.NET.Entities.KerberosContextToken.DecryptApReq(KeyTable keys) in D:\a\1\s\Kerberos.NET\Entities\SpNego\KerberosContextToken.cs:line 38
at Kerberos.NET.Entities.NegotiateContextToken.DecryptApReq(KeyTable keys) in D:\a\1\s\Kerberos.NET\Entities\SpNego\NegotiateContextToken.cs:line 38
at Kerberos.NET.KerberosValidator.Validate(ReadOnlyMemory`1 requestBytes) in D:\a\1\s\Kerberos.NET\KerberosValidator.cs:line 70
at Kerberos.NET.KerberosAuthenticator.Authenticate(ReadOnlyMemory`1 token) in D:\a\1\s\Kerberos.NET\KerberosAuthenticator.cs:line 73
at Kerberos.NET.KerberosAuthenticator.Authenticate(Byte[] token) in D:\a\1\s\Kerberos.NET\KerberosAuthenticator.cs:line 69
at Kerberos.NET.KerberosAuthenticator.Authenticate(String token) in D:\a\1\s\Kerberos.NET\KerberosAuthenticator.cs:line 65
at TestKerberos2.MiddleWare.Invoke(HttpContext context) in C:\Users\user\source\repos\TestKerberos2\TestKerberos2\MiddleWare.cs:line 45}
In this case, decryption of tickets using keytab is successful.
I tried to revert MD4 to Unix myself, but it didn't help:
- Installed the openssl package
- Applied the fix from the article dotnet/runtime#67353 (comment)
If my problem is not related to the current one, I can create a separate issuse.