<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />

OfferedPsks

public sealed class OfferedPsks
using Org.BouncyCastle.Tls.Crypto; using System; using System.Collections.Generic; using System.IO; namespace Org.BouncyCastle.Tls { public sealed class OfferedPsks { internal class BindersConfig { internal readonly TlsPsk[] m_psks; internal readonly short[] m_pskKeyExchangeModes; internal readonly TlsSecret[] m_earlySecrets; internal int m_bindersSize; internal BindersConfig(TlsPsk[] psks, short[] pskKeyExchangeModes, TlsSecret[] earlySecrets, int bindersSize) { m_psks = psks; m_pskKeyExchangeModes = pskKeyExchangeModes; m_earlySecrets = earlySecrets; m_bindersSize = bindersSize; } } internal class SelectedConfig { internal readonly int m_index; internal readonly TlsPsk m_psk; internal readonly short[] m_pskKeyExchangeModes; internal readonly TlsSecret m_earlySecret; internal SelectedConfig(int index, TlsPsk psk, short[] pskKeyExchangeModes, TlsSecret earlySecret) { m_index = index; m_psk = psk; m_pskKeyExchangeModes = pskKeyExchangeModes; m_earlySecret = earlySecret; } } private readonly IList<PskIdentity> m_identities; private readonly IList<byte[]> m_binders; private readonly int m_bindersSize; public IList<byte[]> Binders => m_binders; public int BindersSize => m_bindersSize; public IList<PskIdentity> Identities => m_identities; public OfferedPsks(IList<PskIdentity> identities) : this(identities, null, -1) { } private OfferedPsks(IList<PskIdentity> identities, IList<byte[]> binders, int bindersSize) { if (identities == null || identities.Count < 1) throw new ArgumentException("cannot be null or empty", "identities"); if (binders != null && identities.Count != binders.Count) throw new ArgumentException("must be the same length as 'identities' (or null)", "binders"); if (binders != null != bindersSize >= 0) throw new ArgumentException("must be >= 0 iff 'binders' are present", "bindersSize"); m_identities = identities; m_binders = binders; m_bindersSize = bindersSize; } public int GetIndexOfIdentity(PskIdentity pskIdentity) { int i = 0; for (int count = m_identities.Count; i < count; i++) { if (pskIdentity.Equals(m_identities[i])) return i; } return -1; } public void Encode(Stream output) { int num = 0; foreach (PskIdentity identity in m_identities) { num += identity.GetEncodedLength(); } TlsUtilities.CheckUint16(num); TlsUtilities.WriteUint16(num, output); foreach (PskIdentity identity2 in m_identities) { identity2.Encode(output); } if (m_binders != null) { int num2 = 0; foreach (byte[] binder in m_binders) { num2 += 1 + binder.Length; } TlsUtilities.CheckUint16(num2); TlsUtilities.WriteUint16(num2, output); foreach (byte[] binder2 in m_binders) { TlsUtilities.WriteOpaque8(binder2, output); } } } internal static void EncodeBinders(Stream output, TlsCrypto crypto, TlsHandshakeHash handshakeHash, BindersConfig bindersConfig) { TlsPsk[] psks = bindersConfig.m_psks; TlsSecret[] earlySecrets = bindersConfig.m_earlySecrets; int num = bindersConfig.m_bindersSize - 2; TlsUtilities.CheckUint16(num); TlsUtilities.WriteUint16(num, output); int num2 = 0; for (int i = 0; i < psks.Length; i++) { TlsPsk obj = psks[i]; TlsSecret earlySecret = earlySecrets[i]; bool isExternalPsk = true; int hashForPrf = TlsCryptoUtilities.GetHashForPrf(obj.PrfAlgorithm); TlsHash tlsHash = crypto.CreateHash(hashForPrf); handshakeHash.CopyBufferTo(new TlsHashSink(tlsHash)); byte[] transcriptHash = tlsHash.CalculateHash(); byte[] array = TlsUtilities.CalculatePskBinder(crypto, isExternalPsk, hashForPrf, earlySecret, transcriptHash); num2 += 1 + array.Length; TlsUtilities.WriteOpaque8(array, output); } if (num != num2) throw new TlsFatalAlert(80); } internal static int GetBindersSize(TlsPsk[] psks) { int num = 0; for (int i = 0; i < psks.Length; i++) { int hashForPrf = TlsCryptoUtilities.GetHashForPrf(psks[i].PrfAlgorithm); num += 1 + TlsCryptoUtilities.GetHashOutputSize(hashForPrf); } TlsUtilities.CheckUint16(num); return 2 + num; } public static OfferedPsks Parse(Stream input) { List<PskIdentity> list = new List<PskIdentity>(); int num = TlsUtilities.ReadUint16(input); if (num < 7) throw new TlsFatalAlert(50); MemoryStream memoryStream = new MemoryStream(TlsUtilities.ReadFully(num, input), false); do { PskIdentity item = PskIdentity.Parse(memoryStream); list.Add(item); } while (memoryStream.Position < memoryStream.Length); List<byte[]> list2 = new List<byte[]>(); int num2 = TlsUtilities.ReadUint16(input); if (num2 < 33) throw new TlsFatalAlert(50); MemoryStream memoryStream2 = new MemoryStream(TlsUtilities.ReadFully(num2, input), false); do { byte[] item2 = TlsUtilities.ReadOpaque8(memoryStream2, 32); list2.Add(item2); } while (memoryStream2.Position < memoryStream2.Length); return new OfferedPsks(list, list2, 2 + num2); } } }