Skip to content

Commit d9a8e8d

Browse files
joaoladeiraextjoao.ladeira
andauthored
Feature/bouncy castle update (#1398)
* [BouncyCastleUpdate] Initial rework. * [BouncyCastleUpdate] Reverting tests. * [BouncyCastleUpdate] Fixing tests. * [BouncyCastleUpdate] Cleaning up. * [BouncyCastleUpdate] Cleaning up. * [BouncyCastleUpdate] Add support to ECDSA and RSA. * [BouncyCastleUpdate] Cleaning up. * [BouncyCastleUpdate] PR suggestions. --------- Co-authored-by: joao.ladeira <[email protected]>
1 parent 0899e3c commit d9a8e8d

File tree

11 files changed

+602
-758
lines changed

11 files changed

+602
-758
lines changed

src/SIPSorcery.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
<ItemGroup>
2020
<PackageReference Include="Concentus" Version="2.2.2" />
21-
<PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
21+
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />
2222
<PackageReference Include="DnsClient" Version="1.8.0" />
2323
<PackageReference Include="SIPSorcery.WebSocketSharp" Version="0.0.1" />
2424
<PackageReference Include="SIPSorceryMedia.Abstractions" Version="8.0.10" />

src/net/DtlsSrtp/DtlsSrtpClient.cs

Lines changed: 74 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515

1616
using System;
1717
using System.Collections;
18+
using System.Collections.Generic;
1819
using Microsoft.Extensions.Logging;
1920
using Org.BouncyCastle.Crypto;
20-
using Org.BouncyCastle.Crypto.Tls;
2121
using Org.BouncyCastle.Security;
22-
using Org.BouncyCastle.Utilities;
22+
using Org.BouncyCastle.Tls;
23+
using Org.BouncyCastle.Tls.Crypto;
2324
using SIPSorcery.Sys;
2425

2526
namespace SIPSorcery.Net
@@ -35,24 +36,14 @@ internal DtlsSrtpTlsAuthentication(DtlsSrtpClient client)
3536
this.mContext = client.TlsContext;
3637
}
3738

38-
public virtual void NotifyServerCertificate(Certificate serverCertificate)
39+
public virtual void NotifyServerCertificate(TlsServerCertificate serverCertificate)
3940
{
4041
mClient.ServerCertificate = serverCertificate;
4142
}
4243

4344
public virtual TlsCredentials GetClientCredentials(CertificateRequest certificateRequest)
4445
{
45-
byte[] certificateTypes = certificateRequest.CertificateTypes;
46-
if (certificateTypes == null || !Arrays.Contains(certificateTypes, ClientCertificateType.rsa_sign) || !Arrays.Contains(certificateTypes, ClientCertificateType.ecdsa_sign))
47-
{
48-
return null;
49-
}
50-
51-
return DtlsUtils.LoadSignerCredentials(mContext,
52-
certificateRequest.SupportedSignatureAlgorithms,
53-
SignatureAlgorithm.ecdsa,
54-
mClient.mCertificateChain,
55-
mClient.mPrivateKey);
46+
return DtlsUtils.LoadSignerCredentials(mContext, certificateRequest.SupportedSignatureAlgorithms, mClient.mCertificateChain, mClient.mPrivateKey);
5647
}
5748

5849
public TlsCredentials GetClientCredentials(TlsContext context, CertificateRequest certificateRequest)
@@ -67,18 +58,19 @@ public class DtlsSrtpClient : DefaultTlsClient, IDtlsSrtpPeer
6758

6859
internal Certificate mCertificateChain = null;
6960
internal AsymmetricKeyParameter mPrivateKey = null;
61+
bool mIsEcdsaCertificate = false;
7062

7163
internal TlsClientContext TlsContext
7264
{
73-
get { return mContext; }
65+
get { return m_context; }
7466
}
7567

7668
protected internal TlsSession mSession;
7769

7870
public bool ForceUseExtendedMasterSecret { get; set; } = true;
7971

8072
//Received from server
81-
public Certificate ServerCertificate { get; internal set; }
73+
public TlsServerCertificate ServerCertificate { get; internal set; }
8274

8375
public RTCDtlsFingerprint Fingerprint { get; private set; }
8476

@@ -89,7 +81,6 @@ internal TlsClientContext TlsContext
8981
private byte[] srtpMasterServerKey;
9082
private byte[] srtpMasterClientSalt;
9183
private byte[] srtpMasterServerSalt;
92-
private byte[] masterSecret = null;
9384

9485
// Policies
9586
private SrtpPolicy srtpPolicy;
@@ -103,36 +94,29 @@ internal TlsClientContext TlsContext
10394
/// </summary>
10495
public event Action<AlertLevelsEnum, AlertTypesEnum, string> OnAlert;
10596

106-
public DtlsSrtpClient() :
107-
this(null, null, null)
108-
{
109-
}
97+
public DtlsSrtpClient(TlsCrypto crypto)
98+
: this(crypto, null, null, null) { }
11099

111-
public DtlsSrtpClient(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) :
112-
this(DtlsUtils.LoadCertificateChain(certificate), DtlsUtils.LoadPrivateKeyResource(certificate))
113-
{
114-
}
100+
public DtlsSrtpClient(TlsCrypto crypto, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate)
101+
: this(crypto, DtlsUtils.LoadCertificateChain(crypto, certificate), DtlsUtils.LoadPrivateKeyResource(certificate)) { }
115102

116-
public DtlsSrtpClient(string certificatePath, string keyPath) :
117-
this(new string[] { certificatePath }, keyPath)
118-
{
119-
}
103+
public DtlsSrtpClient(TlsCrypto crypto, string certificatePath, string keyPath)
104+
: this(crypto, new string[] { certificatePath }, keyPath) { }
120105

121-
public DtlsSrtpClient(string[] certificatesPath, string keyPath) :
122-
this(DtlsUtils.LoadCertificateChain(certificatesPath), DtlsUtils.LoadPrivateKeyResource(keyPath))
123-
{
124-
}
106+
public DtlsSrtpClient(TlsCrypto crypto, string[] certificatesPath, string keyPath)
107+
: this(crypto, DtlsUtils.LoadCertificateChain(crypto, certificatesPath), DtlsUtils.LoadPrivateKeyResource(keyPath)) { }
125108

126-
public DtlsSrtpClient(Certificate certificateChain, AsymmetricKeyParameter privateKey) :
127-
this(certificateChain, privateKey, null)
128-
{
129-
}
109+
public DtlsSrtpClient(TlsCrypto crypto, Certificate certificateChain, AsymmetricKeyParameter privateKey)
110+
: this(crypto, certificateChain, privateKey, null) { }
111+
112+
public DtlsSrtpClient(TlsCrypto crypto, UseSrtpData clientSrtpData)
113+
: this(crypto, null, null, clientSrtpData) { }
130114

131-
public DtlsSrtpClient(Certificate certificateChain, AsymmetricKeyParameter privateKey, UseSrtpData clientSrtpData)
115+
public DtlsSrtpClient(TlsCrypto crypto, Certificate certificateChain, AsymmetricKeyParameter privateKey, UseSrtpData clientSrtpData) : base(crypto)
132116
{
133117
if (certificateChain == null && privateKey == null)
134118
{
135-
(certificateChain, privateKey) = DtlsUtils.CreateSelfSignedTlsCert();
119+
(certificateChain, privateKey) = DtlsUtils.CreateSelfSignedTlsCert(crypto);
136120
}
137121

138122
if (clientSrtpData == null)
@@ -154,33 +138,61 @@ public DtlsSrtpClient(Certificate certificateChain, AsymmetricKeyParameter priva
154138
//Generate FingerPrint
155139
var certificate = mCertificateChain.GetCertificateAt(0);
156140
Fingerprint = certificate != null ? DtlsUtils.Fingerprint(certificate) : null;
141+
142+
//TODO: We should be able to support both ECDSA and RSA schemes, search in the certificate chain if both are supported and not just in the first one.
143+
// Check if the certificate is ECDSA or RSA based on the OID
144+
this.mIsEcdsaCertificate = certificate.SigAlgOid.StartsWith("1.2.840.10045.4.3"); // OID prefix for ECDSA
157145
}
158146

159-
public DtlsSrtpClient(UseSrtpData clientSrtpData) : this(null, null, clientSrtpData)
160-
{ }
147+
public override void Init(TlsClientContext context)
148+
{
149+
base.Init(context);
161150

162-
public override IDictionary GetClientExtensions()
151+
if (this.mIsEcdsaCertificate)
152+
{
153+
m_cipherSuites = new int[]
154+
{
155+
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, // 0xC02B
156+
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, // 0xC009
157+
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, // 0xC00A
158+
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, // 0xCCA9
159+
};
160+
}
161+
else
162+
{
163+
m_cipherSuites = new int[]
164+
{
165+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // 0xC02F
166+
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, // 0xCCA8
167+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, // 0xC013
168+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA // 0xC014
169+
};
170+
}
171+
}
172+
173+
public override IDictionary<int, byte[]> GetClientExtensions()
163174
{
164175
var clientExtensions = base.GetClientExtensions();
165-
if (TlsSRTPUtils.GetUseSrtpExtension(clientExtensions) == null)
176+
if (TlsSrpUtilities.GetSrpExtension(clientExtensions) == null)
166177
{
167178
if (clientExtensions == null)
168179
{
169-
clientExtensions = new Hashtable();
180+
clientExtensions = new Hashtable() as IDictionary<int, byte[]>;
170181
}
171182

172-
TlsSRTPUtils.AddUseSrtpExtension(clientExtensions, clientSrtpData);
183+
TlsSrtpUtilities.AddUseSrtpExtension(clientExtensions, clientSrtpData);
173184
}
174185
return clientExtensions;
175186
}
176187

177-
public override void ProcessServerExtensions(IDictionary clientExtensions)
188+
189+
public override void ProcessServerExtensions(IDictionary<int, byte[]> serverExtensions)
178190
{
179-
base.ProcessServerExtensions(clientExtensions);
191+
base.ProcessServerExtensions(serverExtensions);
180192

181193
// set to some reasonable default value
182194
int chosenProfile = SrtpProtectionProfile.SRTP_AES128_CM_HMAC_SHA1_80;
183-
UseSrtpData clientSrtpData = TlsSRTPUtils.GetUseSrtpExtension(clientExtensions);
195+
clientSrtpData = TlsSrtpUtilities.GetUseSrtpExtension(serverExtensions);
184196

185197
foreach (int profile in clientSrtpData.ProtectionProfiles)
186198
{
@@ -242,10 +254,6 @@ public override void NotifyHandshakeComplete()
242254
{
243255
base.NotifyHandshakeComplete();
244256

245-
//Copy master Secret (will be inaccessible after this call)
246-
masterSecret = new byte[mContext.SecurityParameters.MasterSecret != null ? mContext.SecurityParameters.MasterSecret.Length : 0];
247-
Buffer.BlockCopy(mContext.SecurityParameters.MasterSecret, 0, masterSecret, 0, masterSecret.Length);
248-
249257
//Prepare Srtp Keys (we must to it here because master key will be cleared after that)
250258
PrepareSrtpSharedSecret();
251259
}
@@ -267,7 +275,7 @@ protected virtual byte[] GetKeyingMaterial(string asciiLabel, byte[] context_val
267275
throw new ArgumentException("must have length less than 2^16 (or be null)", "context_value");
268276
}
269277

270-
SecurityParameters sp = mContext.SecurityParameters;
278+
SecurityParameters sp = m_context.SecurityParameters;
271279
if (!sp.IsExtendedMasterSecret && RequiresExtendedMasterSecret())
272280
{
273281
/*
@@ -307,7 +315,7 @@ protected virtual byte[] GetKeyingMaterial(string asciiLabel, byte[] context_val
307315
throw new InvalidOperationException("error in calculation of seed for export");
308316
}
309317

310-
return TlsUtilities.PRF(mContext, sp.MasterSecret, asciiLabel, seed, length);
318+
return TlsUtilities.Prf(sp, sp.MasterSecret, asciiLabel, seed, length).Extract();
311319
}
312320

313321
public override bool RequiresExtendedMasterSecret()
@@ -369,22 +377,22 @@ protected virtual void PrepareSrtpSharedSecret()
369377
Buffer.BlockCopy(sharedSecret, (2 * keyLen + saltLen), srtpMasterServerSalt, 0, saltLen);
370378
}
371379

372-
public override ProtocolVersion ClientVersion
380+
protected override ProtocolVersion[] GetSupportedVersions()
373381
{
374-
get { return ProtocolVersion.DTLSv12; }
375-
}
376-
377-
public override ProtocolVersion MinimumVersion
378-
{
379-
get { return ProtocolVersion.DTLSv10; }
382+
return new ProtocolVersion[]
383+
{
384+
ProtocolVersion.DTLSv10,
385+
ProtocolVersion.DTLSv12
386+
//TODO: Add support for newer CipherSuites in order for us to support the newer ProtocolVersion.DTLSv13.
387+
};
380388
}
381389

382390
public override TlsSession GetSessionToResume()
383391
{
384392
return this.mSession;
385393
}
386394

387-
public override void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause)
395+
public override void NotifyAlertRaised(short alertLevel, short alertDescription, string message, Exception cause)
388396
{
389397
string description = null;
390398
if (message != null)
@@ -413,22 +421,22 @@ public override void NotifyServerVersion(ProtocolVersion serverVersion)
413421

414422
public Certificate GetRemoteCertificate()
415423
{
416-
return ServerCertificate;
424+
return ServerCertificate.Certificate;
417425
}
418426

419-
public override void NotifyAlertReceived(byte alertLevel, byte alertDescription)
427+
public override void NotifyAlertReceived(short alertLevel, short alertDescription)
420428
{
421429
string description = AlertDescription.GetText(alertDescription);
422430

423431
AlertLevelsEnum level = AlertLevelsEnum.Warning;
424432
AlertTypesEnum alertType = AlertTypesEnum.unknown;
425433

426-
if (Enum.IsDefined(typeof(AlertLevelsEnum), alertLevel))
434+
if (Enum.IsDefined(typeof(AlertLevelsEnum), checked((byte)alertLevel)))
427435
{
428436
level = (AlertLevelsEnum)alertLevel;
429437
}
430438

431-
if (Enum.IsDefined(typeof(AlertTypesEnum), alertDescription))
439+
if (Enum.IsDefined(typeof(AlertTypesEnum), checked((byte)alertDescription)))
432440
{
433441
alertType = (AlertTypesEnum)alertDescription;
434442
}

0 commit comments

Comments
 (0)