1515
1616using System ;
1717using System . Collections ;
18+ using System . Collections . Generic ;
1819using Microsoft . Extensions . Logging ;
1920using Org . BouncyCastle . Crypto ;
20- using Org . BouncyCastle . Crypto . Tls ;
2121using Org . BouncyCastle . Security ;
22- using Org . BouncyCastle . Utilities ;
22+ using Org . BouncyCastle . Tls ;
23+ using Org . BouncyCastle . Tls . Crypto ;
2324using SIPSorcery . Sys ;
2425
2526namespace 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