Skip to content

Commit 0c76ed5

Browse files
committed
Reworked decryption to be more generic.
1 parent 08b4fb7 commit 0c76ed5

16 files changed

Lines changed: 119 additions & 84 deletions

NtApiDotNet/NtApiDotNet.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@
322322
<Compile Include="Win32\SafeHandles\SafeLsaLogonHandle.cs" />
323323
<Compile Include="Utilities\ASN1\DERParser.cs" />
324324
<Compile Include="Win32\Security\Authentication\ASN1AuthenticationToken.cs" />
325+
<Compile Include="Win32\Security\Authentication\AuthenticationKey.cs" />
325326
<Compile Include="Win32\Security\Authentication\GSSAPIUtils.cs" />
326327
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosAPReplyEncryptedPart.cs" />
327328
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosAuthorizationDataPACDevice.cs" />
@@ -354,7 +355,7 @@
354355
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosErrorAuthenticationToken.cs" />
355356
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosTGTRequestAuthenticationToken.cs" />
356357
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosAuthenticationToken.cs" />
357-
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosKey.cs" />
358+
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosAuthenticationKey.cs" />
358359
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosTGTReplyAuthenticationToken.cs" />
359360
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosTicket.cs" />
360361
<Compile Include="Win32\Security\Authentication\Kerberos\KerberosUtils.cs" />
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2020 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using System.Text;
19+
using System.Threading.Tasks;
20+
21+
namespace NtApiDotNet.Win32.Security.Authentication
22+
{
23+
/// <summary>
24+
/// Base class which represents an authentication key.
25+
/// </summary>
26+
public abstract class AuthenticationKey
27+
{
28+
}
29+
}

NtApiDotNet/Win32/Security/Authentication/AuthenticationToken.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using NtApiDotNet.Win32.Security.Authentication.Kerberos;
1717
using NtApiDotNet.Win32.Security.Authentication.Negotiate;
1818
using NtApiDotNet.Win32.Security.Authentication.Ntlm;
19+
using System.Collections.Generic;
1920

2021
namespace NtApiDotNet.Win32.Security.Authentication
2122
{
@@ -26,6 +27,16 @@ public class AuthenticationToken
2627
{
2728
private readonly byte[] _data;
2829

30+
/// <summary>
31+
/// Decrypt the Authentication Token using a keyset.
32+
/// </summary>
33+
/// <param name="keyset">The set of keys to decrypt the </param>
34+
/// <returns>The decrypted token, or the same token if nothing could be decrypted.</returns>
35+
public virtual AuthenticationToken Decrypt(IEnumerable<AuthenticationKey> keyset)
36+
{
37+
return this;
38+
}
39+
2940
/// <summary>
3041
/// Convert the authentication token to a byte array.
3142
/// </summary>

NtApiDotNet/Win32/Security/Authentication/Kerberos/KerberosAPReplyAuthenticationToken.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
// limitations under the License.
1414

1515
using NtApiDotNet.Utilities.ASN1;
16+
using System.Collections.Generic;
1617
using System.IO;
18+
using System.Linq;
1719
using System.Text;
1820

1921
namespace NtApiDotNet.Win32.Security.Authentication.Kerberos
@@ -52,10 +54,11 @@ public override string Format()
5254
/// </summary>
5355
/// <param name="keyset">The set of keys to decrypt the </param>
5456
/// <returns>The decrypted token, or the same token if nothing could be decrypted.</returns>
55-
public override KerberosAuthenticationToken Decrypt(KerberosKeySet keyset)
57+
public override AuthenticationToken Decrypt(IEnumerable<AuthenticationKey> keyset)
5658
{
5759
KerberosEncryptedData encrypted_part = null;
58-
if (EncryptedPart.Decrypt(keyset, string.Empty, new KerberosPrincipalName(), KeyUsage.ApRepEncryptedPart, out byte[] auth_decrypt))
60+
KerberosKeySet tmp_keyset = new KerberosKeySet(keyset.OfType<KerberosAuthenticationKey>());
61+
if (EncryptedPart.Decrypt(tmp_keyset, string.Empty, new KerberosPrincipalName(), KeyUsage.ApRepEncryptedPart, out byte[] auth_decrypt))
5962
{
6063
if (!KerberosAPReplyEncryptedPart.Parse(EncryptedPart, auth_decrypt, out encrypted_part))
6164
{

NtApiDotNet/Win32/Security/Authentication/Kerberos/KerberosAPReplyEncryptedPart.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class KerberosAPReplyEncryptedPart : KerberosEncryptedData
3535
/// <summary>
3636
/// Subkey.
3737
/// </summary>
38-
public KerberosKey SubKey { get; private set; }
38+
public KerberosAuthenticationKey SubKey { get; private set; }
3939
/// <summary>
4040
/// Sequence number.
4141
/// </summary>
@@ -99,7 +99,7 @@ internal static bool Parse(KerberosEncryptedData orig_data, byte[] decrypted, ou
9999
case 2:
100100
if (!next.HasChildren())
101101
return false;
102-
ret.SubKey = KerberosKey.Parse(next.Children[0], string.Empty, new KerberosPrincipalName());
102+
ret.SubKey = KerberosAuthenticationKey.Parse(next.Children[0], string.Empty, new KerberosPrincipalName());
103103
break;
104104
case 3:
105105
ret.SequenceNumber = next.ReadChildInteger();

NtApiDotNet/Win32/Security/Authentication/Kerberos/KerberosAPRequestAuthenticationToken.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
using NtApiDotNet.Utilities.ASN1;
1616
using System;
17+
using System.Collections.Generic;
1718
using System.IO;
19+
using System.Linq;
1820
using System.Text;
1921

2022
namespace NtApiDotNet.Win32.Security.Authentication.Kerberos
@@ -90,19 +92,19 @@ public override string Format()
9092
/// </summary>
9193
/// <param name="keyset">The set of keys to decrypt the </param>
9294
/// <returns>The decrypted token, or the same token if nothing could be decrypted.</returns>
93-
public override KerberosAuthenticationToken Decrypt(KerberosKeySet keyset)
95+
public override AuthenticationToken Decrypt(IEnumerable<AuthenticationKey> keyset)
9496
{
9597
KerberosEncryptedData authenticator = null;
9698

97-
KerberosKeySet tmp_keys = new KerberosKeySet(keyset);
99+
KerberosKeySet tmp_keys = new KerberosKeySet(keyset.OfType<KerberosAuthenticationKey>());
98100
if (!Ticket.Decrypt(tmp_keys, KeyUsage.AsRepTgsRepTicket, out KerberosTicket ticket))
99101
{
100102
ticket = null;
101103
}
102104

103105
if (Authenticator.Decrypt(tmp_keys, Ticket.Realm, Ticket.ServerName, KeyUsage.ApReqAuthSubKey, out byte[] auth_decrypt))
104106
{
105-
if (!KerberosAuthenticator.Parse(Ticket, Authenticator, auth_decrypt, keyset, out authenticator))
107+
if (!KerberosAuthenticator.Parse(Ticket, Authenticator, auth_decrypt, tmp_keys, out authenticator))
106108
{
107109
authenticator = null;
108110
}

NtApiDotNet/Win32/Security/Authentication/Kerberos/KerberosKey.cs renamed to NtApiDotNet/Win32/Security/Authentication/Kerberos/KerberosAuthenticationKey.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace NtApiDotNet.Win32.Security.Authentication.Kerberos
2626
/// <summary>
2727
/// A single kerberos key.
2828
/// </summary>
29-
public sealed class KerberosKey
29+
public sealed class KerberosAuthenticationKey : AuthenticationKey
3030
{
3131
private readonly byte[] _key;
3232

@@ -73,7 +73,7 @@ public sealed class KerberosKey
7373
/// <param name="components">The name components for the key.</param>
7474
/// <param name="timestamp">Timestamp when key was created.</param>
7575
/// <param name="version">Key Version Number (KVNO).</param>
76-
public KerberosKey(KerberosEncryptionType key_encryption, byte[] key, KerberosNameType name_type,
76+
public KerberosAuthenticationKey(KerberosEncryptionType key_encryption, byte[] key, KerberosNameType name_type,
7777
string realm, string[] components, DateTime timestamp, uint version)
7878
{
7979
KeyEncryption = key_encryption;
@@ -95,7 +95,7 @@ public KerberosKey(KerberosEncryptionType key_encryption, byte[] key, KerberosNa
9595
/// <param name="components">The name components for the key.</param>
9696
/// <param name="timestamp">Timestamp when key was created.</param>
9797
/// <param name="version">Key Version Number (KVNO).</param>
98-
public KerberosKey(KerberosEncryptionType key_encryption, byte[] key, KerberosNameType name_type,
98+
public KerberosAuthenticationKey(KerberosEncryptionType key_encryption, byte[] key, KerberosNameType name_type,
9999
string realm, IEnumerable<string> components, DateTime timestamp, uint version)
100100
{
101101
KeyEncryption = key_encryption;
@@ -116,7 +116,7 @@ public KerberosKey(KerberosEncryptionType key_encryption, byte[] key, KerberosNa
116116
/// <param name="principal">Principal for key, in form TYPE/name@realm.</param>
117117
/// <param name="timestamp">Timestamp when key was created.</param>
118118
/// <param name="version">Key Version Number (KVNO).</param>
119-
public KerberosKey(KerberosEncryptionType key_encryption, byte[] key, KerberosNameType name_type,
119+
public KerberosAuthenticationKey(KerberosEncryptionType key_encryption, byte[] key, KerberosNameType name_type,
120120
string principal, DateTime timestamp, uint version)
121121
: this(key_encryption, key, name_type, GetRealm(principal),
122122
GetComponents(principal), timestamp, version)
@@ -132,7 +132,7 @@ public KerberosKey(KerberosEncryptionType key_encryption, byte[] key, KerberosNa
132132
/// <param name="principal">Principal for key, in form TYPE/name@realm.</param>
133133
/// <param name="timestamp">Timestamp when key was created.</param>
134134
/// <param name="version">Key Version Number (KVNO).</param>
135-
public KerberosKey(KerberosEncryptionType key_encryption, string key, KerberosNameType name_type,
135+
public KerberosAuthenticationKey(KerberosEncryptionType key_encryption, string key, KerberosNameType name_type,
136136
string principal, DateTime timestamp, uint version)
137137
: this(key_encryption, GetKey(key), name_type, principal, timestamp, version)
138138
{
@@ -150,7 +150,7 @@ public KerberosKey(KerberosEncryptionType key_encryption, string key, KerberosNa
150150
/// <param name="salt">Salt for the key.</param>
151151
/// <param name="version">Key Version Number (KVNO).</param>
152152
/// <returns></returns>
153-
public static KerberosKey DeriveKey(KerberosEncryptionType key_encryption, string password,
153+
public static KerberosAuthenticationKey DeriveKey(KerberosEncryptionType key_encryption, string password,
154154
int iterations, KerberosNameType name_type, string principal, string salt, uint version)
155155
{
156156
if (principal is null)
@@ -178,10 +178,10 @@ public static KerberosKey DeriveKey(KerberosEncryptionType key_encryption, strin
178178
throw new ArgumentException($"Unsupported key type {key_encryption}", nameof(key_encryption));
179179
}
180180

181-
return new KerberosKey(key_encryption, key, name_type, principal, DateTime.Now, version);
181+
return new KerberosAuthenticationKey(key_encryption, key, name_type, principal, DateTime.Now, version);
182182
}
183183

184-
internal static KerberosKey Parse(DERValue value, string realm, KerberosPrincipalName name)
184+
internal static KerberosAuthenticationKey Parse(DERValue value, string realm, KerberosPrincipalName name)
185185
{
186186
if (!value.CheckSequence())
187187
throw new InvalidDataException();
@@ -206,7 +206,7 @@ internal static KerberosKey Parse(DERValue value, string realm, KerberosPrincipa
206206

207207
if (enc_type == 0 || key == null)
208208
throw new InvalidDataException();
209-
return new KerberosKey(enc_type, key, name.NameType, realm, name.Names.ToArray(), DateTime.Now, 0);
209+
return new KerberosAuthenticationKey(enc_type, key, name.NameType, realm, name.Names.ToArray(), DateTime.Now, 0);
210210
}
211211

212212
private static string MakeSalt(string salt, string principal)

NtApiDotNet/Win32/Security/Authentication/Kerberos/KerberosAuthenticationToken.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,6 @@ public static KerberosAuthenticationToken Parse(byte[] data)
5959
}
6060
#endregion
6161

62-
#region Public Methods
63-
/// <summary>
64-
/// Decrypt the Authentication Token using a keyset.
65-
/// </summary>
66-
/// <param name="keyset">The set of keys to decrypt the </param>
67-
/// <returns>The decrypted token, or the same token if nothing could be decrypted.</returns>
68-
public virtual KerberosAuthenticationToken Decrypt(KerberosKeySet keyset)
69-
{
70-
return this;
71-
}
72-
#endregion
73-
7462
#region Internal Static Methods
7563
/// <summary>
7664
/// Try and parse data into an Kerberos authentication token.

NtApiDotNet/Win32/Security/Authentication/Kerberos/KerberosAuthenticator.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public class KerberosAuthenticator : KerberosEncryptedData
5252
/// <summary>
5353
/// Subkey.
5454
/// </summary>
55-
public KerberosKey SubKey { get; private set; }
55+
public KerberosAuthenticationKey SubKey { get; private set; }
5656
/// <summary>
5757
/// Sequence number.
5858
/// </summary>
@@ -149,7 +149,7 @@ internal static bool Parse(KerberosTicket orig_ticket, KerberosEncryptedData ori
149149
case 6:
150150
if (!next.HasChildren())
151151
return false;
152-
ret.SubKey = KerberosKey.Parse(next.Children[0], orig_ticket.Realm, orig_ticket.ServerName);
152+
ret.SubKey = KerberosAuthenticationKey.Parse(next.Children[0], orig_ticket.Realm, orig_ticket.ServerName);
153153
break;
154154
case 7:
155155
ret.SequenceNumber = next.ReadChildInteger();
@@ -166,7 +166,7 @@ internal static bool Parse(KerberosTicket orig_ticket, KerberosEncryptedData ori
166166

167167
if (ret.Checksum is KerberosChecksumGSSApi gssapi && gssapi.Credentials != null)
168168
{
169-
KerberosKeySet tmp_keyset = new KerberosKeySet(keyset.AsEnumerable() ?? new KerberosKey[0]);
169+
KerberosKeySet tmp_keyset = new KerberosKeySet(keyset.AsEnumerable() ?? new KerberosAuthenticationKey[0]);
170170
if (ret.SubKey != null)
171171
{
172172
tmp_keyset.Add(ret.SubKey);

NtApiDotNet/Win32/Security/Authentication/Kerberos/KerberosCredential.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using NtApiDotNet.Utilities.ASN1;
1616
using System.Collections.Generic;
1717
using System.IO;
18+
using System.Linq;
1819
using System.Text;
1920

2021
namespace NtApiDotNet.Win32.Security.Authentication.Kerberos
@@ -63,10 +64,10 @@ public override string Format()
6364
/// </summary>
6465
/// <param name="keyset">The set of keys to decrypt the </param>
6566
/// <returns>The decrypted token, or the same token if nothing could be decrypted.</returns>
66-
public override KerberosAuthenticationToken Decrypt(KerberosKeySet keyset)
67+
public override AuthenticationToken Decrypt(IEnumerable<AuthenticationKey> keyset)
6768
{
6869
KerberosEncryptedData encdata = null;
69-
KerberosKeySet tmp_keys = new KerberosKeySet(keyset);
70+
KerberosKeySet tmp_keys = new KerberosKeySet(keyset.OfType<KerberosAuthenticationKey>());
7071
List<KerberosTicket> dec_tickets = new List<KerberosTicket>();
7172
bool decrypted_ticket = false;
7273
foreach (var ticket in Tickets)

0 commit comments

Comments
 (0)