<div dir="ltr">Hi Joshua,<div><br></div><div>I&#39;m glad you appreciated the effort!</div><div>I&#39;ve added just a couple of comments inline.<div class="gmail_extra"><br><div class="gmail_quote">2013/5/30 Joshua Colp <span dir="ltr">&lt;<a href="mailto:jcolp@digium.com" target="_blank">jcolp@digium.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Lorenzo Miniero wrote:<br>
<br>
&lt;snipped&gt;<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
1. First of all, from a configuration point of view, &#39;dtlsverify&#39;<br>
needs to be set to &#39;no&#39;. In fact, all certificates used in WebRTC calls<br>
from browsers are apparently generated on the fly or, anyway, self<br>
certificates, and so cannot be verified. Besides, I also just tested<br>
&#39;ALL:NULL:eNULL:aNULL&#39; as the &#39;dtlschipher&#39;: not sure whether or not<br>
this can be safely narrowed down. Not really a technical issue or<br>
anything that needs to be addressed in the code, but I thought it was<br>
important to point out, if only to notify this in related documentation<br>
files.<br>
</blockquote>
<br></div>
There is a wiki page detailing WebRTC and Asterisk, but it&#39;s from when nothing supported DTLS-SRTP. It could certainly be extended to include information about this. Of course since stuff is still in flux it&#39;ll probably become out of date quickly. Playing with a moving target, always fun.<div class="im">
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
2. Asterisk only enforces DTLS-SRTP when it receives<br>
UDP/TLS/RTP/SAVP(F) as the protocol to be used in the SDP, but both<br>
Chrome and Firefox negotiate RTP/SAVPF. According to RFC 5764, Asterisk<br>
is doing the right thing: anyway, UDP/TLS/RTP/SAVP(F) is a SHALL and not<br>
a MUST, and besides both browsers don&#39;t seem to &quot;digest&quot; it very well.<br>
This means that this needs to be addressed: I did it in the signalling<br>
gateway, others may do this somewhere else (e.g., directly in JavaScript<br>
after producing an offer and before passing an answer). Probably not<br>
needed in chan_sip.c as well, even though I&#39;m not sure how other<br>
DTLS-SRTP implementations behave in that sense.<br>
</blockquote>
<br></div>
Agreed, I&#39;d rather us not break spec. Hopefully the browsers will fix things up eventually and if not we can explore what to do then.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
3. Even when forced, through the proper &quot;DtlsSrtpKeyAgreement&quot;:true<br>
constraint, to negotiate DTLS-SRTP, Chrome also adds SDES crypto<br>
attributes as a fallback. As far as I&#39;ve understood from the chan_sip.c<br>
code, this could cause Asterisk to try and setup SRTP using both SDES<br>
(first) and DTLS (then), with potentially unpredictable results. I have<br>
not tested this, as in my signalling gateway I made sure that only the<br>
fingerprint attribute was left in the code, but this may be worth<br>
looking at. What was definitely needed in the Chrome case, though, was<br>
to add a fake crypto line in the reply anyway (e.g., a=crypto:1<br>
AES_CM_128_HMAC_SHA1_80<br>
inline:<u></u>BAADBAADBAADBAADBAADBAADBAADBA<u></u>ADBAADBAAD), as was explained in<br>
<a href="http://www.webrtc.org/interop" target="_blank">http://www.webrtc.org/interop</a> (note: this doesn&#39;t seem to be on that<br>
page anymore, so this may have been fixed, but older Chrome versions may<br>
still be affected). Again, I did this in the signalling gateway and not<br>
Asterisk, so probably not very important.<br>
</blockquote>
<br></div>
I&#39;m sure older ones are impacted but it&#39;ll probably change as things progress.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
4. Neither Chrome nor Asterisk provide any &#39;setup&#39; attribute when<br>
negotiating the DTLS fingerprint. According to RFC 5763, this is a MUST,<br>
and in fact Asterisk negotiates it instead: nevertheless, both browsers<br>
ignore it and don&#39;t negotiate the role there, but use a different<br>
approach. Specifically, Chrome uses ICE roles to determine<br>
passive/active DTLS parties (ICE-CONTROLLED is active), while Firefox<br>
assumes that the caller is going to take the DTLS passive role (DTLS<br>
server) and the callee the active one (DTLS client). As both approaches<br>
basically lead to the same thing, they are able to interact with each<br>
other. In order to get this working in Asterisk as well, I made sure<br>
that Asterisk was configured as AST_RTP_DTLS_SETUP_ACTIVE for the<br>
incoming calls, by adding a setup:passive attribute in the signalling<br>
gateway to have it comply with RFC 5763: in fact, as I anticipated I so<br>
far only tested calls from browsers to Asterisk. Nevertheless, using a<br>
similar approach for outgoing calls (i.e., making sure Asterisk is<br>
configured as passive when negotiating DTLS in a call it generates)<br>
should do the trick for those scenarios as well.<br>
</blockquote>
<br></div>
*nod* Configuring Asterisk as actpass and manipulating the SDP externally would do it. It will automatically change.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
5. An important aspect I needed to take care of was the right<br>
sequence of steps to accomplish, namely: i) ICE completion, ii) DTLS<br>
handshake, iii) RTP/RTCP packets flowing. This is what browsers expect,<br>
and what Asterisk failed to comply to: the DTLS handshake, for instance,<br>
is by default attempted when activating RTP (ast_rtp_activate in<br>
res_rtp_asterisk.c), which happens before ICE even starts to work, thus<br>
resulting in the handshake never starting at all. In order to fix this,<br>
I had to add, to res_rtp_engine.c, an .on_ice_complete callback<br>
triggered by PJNATH. This allowed the module to be aware when ICE<br>
completed for a specific RTP instance, so that&#39;s where I added a new<br>
point to start the DTLS handshake for both RTP and RTCP. I also added a<br>
&#39;dtlsdone&#39; variable to the RTP instance to keep track of when the DTLS<br>
handshake successfully completed: this was needed to prevent Asterisk<br>
from sending RTP/RTCP packets before time, as it seemed to confuse the<br>
browsers.<br>
</blockquote>
<br></div>
Seems like a sane enough change. If you can clean it up and submit it I&#39;ll take a gander.<div class="im"><br>
<br></div></blockquote><div><br></div><div><br></div><div style>Of course: I&#39;ll try and clean up the patch I have now, especially with respect to point 6, and submit it.</div><div style>Is it ok to use the same github repository I&#39;ve created for the Opus/VP8 patch, or would you rather have it submitted somewhere else?</div>
<div style><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
6. About the previous point, one more thing I found out is that<br>
both browsers expect DTLS to be used to set up both RTP *and* RTCP. This<br>
is needed because, as browsers (Chrome at least) mux RTP and RTCP on the<br>
same port, when talking to each other they just need a single DTLS<br>
handshake for the purpose. Asterisk doesn&#39;t mux them instead, and as<br>
this was causing calls to fail, I added some very ugly hacks to enforce<br>
this for RTCP as well. This means that I basically had to copy all the<br>
DTLS-related variables from ast_rtp to the ast_rtcp structure as well,<br>
and replicate the calls that were already there for RTP for RTCP as<br>
well. This code in particular is especially &quot;ugly&quot; to see right now, but<br>
it seems to work fine, meaning that at least it was the right way to go.<br>
</blockquote>
<br></div>
Yeah, muxing and ensuring both RTP and RTCP are set up as the browsers expect is certainly an ongoing issue. I don&#39;t think there&#39;s any way around what you have done though without going down the full muxing route.<div class="im">
<br>
<br></div></blockquote><div><br></div><div style>About this, by talking with Chrome developers on the discuss-webrtc Google group, I found out another issue related to the separate RTP and RTCP DTSL setup, which also explains why SRTCP doesn&#39;t work when using DTLS to exchange keys. The fact that muxing is not used, also implies that different keys are negotiated by the browsers via DTLS for RTP and RTCP: this doesn&#39;t happen for SDES, instead, where the SRTP keys are the same for both RTP and RTCP.</div>
<div style><br></div><div style>From what I&#39;ve understood, SRTP integration in Asterisk was conceived to have RTP and RTCP share the keys, so mostly for the SDES case, and this is why SRTCP packets Asterisk sends are discarded by the peer. I&#39;ve briefly tried looking in the code to see how difficult also allowing them to be different would be, but so far I couldn&#39;t find anything. I guess the easiest approach will be to have two completely separate SRTP contexts for the two protocols, a bit like I did for the DTLS-related stuff in the first place, but I&#39;m afraid this could mess up the code way beyond the benefit. Do you have any hint on where I could try and work to make this work in a way that is consistent with the current Asterisk code?</div>
<div style><br></div><div style> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
7. For Firefox in particular, I had to add some extra care. Firefox<br>
currently rejects with a &quot;401 Unauthorized&quot; error message all<br>
connectivity checks that arrive before it is aware of the peer<br>
credentials. Considering how PJNATH works (failing as soon as a 401 is<br>
received), this resulted in all candidate pairs to be disabled and the<br>
call to fail, because PJNATH would start generating checks before<br>
Firefox, in its code, was able to enforce the remote credentials. To fix<br>
this, the only thing I could think of was to &quot;hack&quot; PJNATH in order to<br>
have it retry whenever it got a 401 until a success arrived eventually.<br>
This is probably not the best way to take care of this, but it seems to<br>
work fine for now. Besides, I still also had to start the DTLS handshake<br>
after some time anyway (about 500ms) even when ICE was completed<br>
according to the PJNATH callback: in fact, in some cases there were<br>
issues with the DTLS handshake getting lost in Firefox (probably for the<br>
same reason as the 401). I reported this issue on the Mozilla WebRTC<br>
group<br>
(<a href="https://groups.google.com/forum/?fromgroups=#!topic/mozilla.dev.media/RxQe9WrY2Ao" target="_blank">https://groups.google.com/<u></u>forum/?fromgroups=#!topic/<u></u>mozilla.dev.media/RxQe9WrY2Ao</a>)<u></u>,<br>

<br>
but until this gets fixed this probably needs being taken care of.<br>
</blockquote>
<br></div>
Eep, I hope that Mozilla is able to get that straightened out... having to work around it in Asterisk and time stuff just right would be unfortunate.<br>
<br>
Nice work on figuring stuff out and getting it going! Thanks for the good words on the DTLS work too. It&#39;s unfortunate that Chrome and Firefox aren&#39;t more compliant with the spec, since it would have required less hacking from you.<br>

<br></blockquote><div><br></div><div style>Thanks! I&#39;ll try and make this into something more usable than a proof-of-concept excercise.</div><div style><br></div><div style>Cheers,</div><div style>Lorenzo</div><div style>
 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Cheers,<br>
<br>
-- Joshua Colp<br>
Digium, Inc. | Senior Software Developer<br>
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA<br>
Check us out at: <a href="http://www.digium.com" target="_blank">www.digium.com</a> &amp; <a href="http://www.asterisk.org" target="_blank">www.asterisk.org</a><br>
<br>
--<br>
______________________________<u></u>______________________________<u></u>_________<br>
-- Bandwidth and Colocation Provided by <a href="http://www.api-digital.com" target="_blank">http://www.api-digital.com</a> --<br>
<br>
asterisk-dev mailing list<br>
To UNSUBSCRIBE or update options visit:<br>
  <a href="http://lists.digium.com/mailman/listinfo/asterisk-dev" target="_blank">http://lists.digium.com/<u></u>mailman/listinfo/asterisk-dev</a><br>
</blockquote></div><br></div></div></div>