TLS not working; endpoint issue or server config?

Howdy -

I have a couple of local endpoints that can make calls fine through my cloud asterisk 22.1 server (Oracle/Ubuntu) over regular UDP. No problems there.

Now I am trying to enable TLS on my endpoints. I generated a cert on the server like this:

./ast_tls_cert -C 100.100.100.100 -O “MadeUpName” -d /etc/asterisk/keys -b 2048

…where 100.100.100.100 is the IP of my asterisk server. The endpoints are Grandstream HT801’s, both behind NAT at IP 123.123.123.123. They register fine, but when I place a call it doesn’t work. Console shows:

res_pjsip_session.c:946 handle_incoming_sdp: 42: Couldn't negotiate stream 0:audio-0:audio:sendrecv (nothing)

So apparently the endpoints and the server aren’t able to agree on a way to talk over TLS. Here are the registered endpoints:


mymachinename*CLI> pjsip show endpoints

....

 Endpoint:  25/25                                                Not in use    0 of 1
     InAuth:  25/25
        Aor:  25                                                 1
      Contact:  25/sips:25@123.123.123.123:57362;transport=TLS fdd14114de NonQual         nan

 Endpoint:  42/42                                                Not in use    0 of 1
     InAuth:  42/42
        Aor:  42                                                 1
      Contact:  42/sips:42@123.123.123.123:53742;transport=TLS 880ce4b4f4 NonQual         nan

The transports show up fine:

mymachinename*CLI> pjsip show transports

Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress....................>
==========================================================================================

Transport:  transport-tls-nat         tls      0      0  0.0.0.0:5061
Transport:  transport-udp-nat         udp      0      0  0.0.0.0:5060

Objects found: 2

mymachinename*CLI> pjsip show transport transport-tls-nat

Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress....................>
==========================================================================================

Transport:  transport-tls-nat         tls      0      0  0.0.0.0:5061

 ParameterName               : ParameterValue
 =============================================================
 allow_reload                : false
 allow_wildcard_certs        : No
 async_operations            : 1
 bind                        : 0.0.0.0:5061
 ca_list_file                :
 ca_list_path                :
 cert_file                   : /etc/asterisk/keys/asterisk.crt
 cipher                      :
 cos                         : 0
 domain                      :
 external_media_address      : 100.100.100.100
 external_signaling_address  : 100.100.100.100
 external_signaling_port     : 0
 local_net                   : 10.0.0.0/255.255.255.0
 method                      : tlsv1_2
 password                    :
 priv_key_file               : /etc/asterisk/keys/asterisk.key
 protocol                    : tls
 require_client_cert         : No
 symmetric_transport         : false
 tcp_keepalive_enable        : true
 tcp_keepalive_idle_time     : 30
 tcp_keepalive_interval_time : 1
 tcp_keepalive_probe_count   : 5
 tos                         : 0
 verify_client               : No
 verify_server               : No
 websocket_write_timeout     : 100

Here is pjsip.conf. Note: I have tried method=default, method=sslv23, and method=tlsv1_2. On the endpoints, I have enabled TLS and tried at that default state. I also tried method=tlsv1_2 in combination with the endpoints being forced to TLS 1.2 as well, to no sucess:

[transport-udp-nat]
type = transport
protocol = udp
bind = 0.0.0.0
local_net = 10.0.0.0/24
external_media_address=100.100.100.100
external_signaling_address=100.100.100.100

[transport-tls-nat]
type = transport
protocol = tls
bind = 0.0.0.0:5061
local_net = 10.0.0.0/24
external_media_address=100.100.100.100
external_signaling_address=100.100.100.100
cert_file=/etc/asterisk/keys/asterisk.crt
priv_key_file=/etc/asterisk/keys/asterisk.key
method=tlsv1_2

[my-endpoint](!)
type = endpoint
context = mycontext
allow = !all,g722,ulaw
trust_id_outbound = yes
device_state_busy_at = 1
dtmf_mode = rfc4733 ; works with HT801 rfc2833 setting
rewrite_contact = yes
force_rport = yes
rtp_symmetric = yes
direct_media = no
media_encryption=sdes

[auth-userpass](!)
type = auth
auth_type = userpass

[aor-single-reg](!)
type = aor
max_contacts = 1
remove_existing = yes

[42](my-endpoint)
auth = 42
aors = 42
callerid = Myname <42>
[42](auth-userpass)
password = 12345
username = 42
[42](aor-single-reg)
mailboxes = 42@mymail

[25](my-endpoint)
auth = 25
aors = 25
callerid = Othername <25>
[25](auth-userpass)
password = 12345
username = 25
[25](aor-single-reg)
mailboxes = 25@mymail

I will include the console debug output at the end of this post.

I have noticed an error when an endpoint registers for the first time:

[Feb 2 00:20:56] ERROR[4040]: pjproject: <?>: ssl0xb5ccd7535510 Error reading CA certificates from buffer

This error sounds pretty identical to this post, which didn’t seem to get anywhere. I couldn’t google anything on this. This can also be triggered if I start up asterisk and then connect with openssl. In case it’s useful, here is the openssl result, showing at least that the cert is used (but not sure if it reveals issues):

# openssl s_client -connect localhost:5061
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = 100.100.100.100, O = MadeUpName
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = 100.100.100.100, O = MadeUpName
verify error:num=21:unable to verify the first certificate
verify return:1
depth=0 CN = 100.100.100.100, O = MadeUpName
verify return:1
---
Certificate chain
 0 s:CN = 100.100.100.100, O = MadeUpName
   i:CN = Asterisk Private CA, O = MadeUpName
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Feb  1 02:39:30 2025 GMT; NotAfter: Feb  1 02:39:30 2026 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
<cert data redacted>
-----END CERTIFICATE-----
subject=CN = 100.100.100.100, O = MadeUpName
issuer=CN = Asterisk Private CA, O = MadeUpName
---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:DSA+SHA256:DSA+SHA384:DSA+SHA512
Shared Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:DSA+SHA256:DSA+SHA384:DSA+SHA512
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1513 bytes and written 398 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 1C40D7400958D1A4418A92D945E139259E78375CEBF7BFB2AF91D222BAB5197D
    Session-ID-ctx:
    Master-Key: D332F7D3007058B9CE6597E573DD2F146CB11B5EC9A4DA1F9BC2A13F84B91E7D75FB1D3B1A878F34F760D8A5910E2DF8
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1738456148
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
    Extended master secret: yes
---
closed
root@mymachine:/etc/asterisk#

Here is the PJSIP exchange from the console:


 <--- Received SIP request (1301 bytes) from TLS:123.123.123.123:53742 --->
INVITE sips:25@100.100.100.100:5061 SIP/2.0
Via: SIP/2.0/TLS 192.168.3.39:5061;branch=z9hG4bK1449350653;rport;alias
From: "Myname" <sips:42@100.100.100.100:5061>;tag=981065372
To: <sips:25@100.100.100.100:5061>
Call-ID: 1596987452-5061-13@BJC.BGI.D.DJ
CSeq: 80 INVITE
Contact: "Myname" <sips:42@192.168.3.39:5061;transport=tls>
Max-Forwards: 70
User-Agent: Grandstream HT801 1.0.57.1
Privacy: none
P-Preferred-Identity: "Myname" <sips:42@100.100.100.100:5061>
P-Access-Network-Info: IEEE-EUI-48;eui-48-addr=40-3F-8C-72-D3-98
P-Emergency-Info: IEEE-EUI-48;eui-48-addr=00-0B-82-B6-44-5D
Supported: replaces, path, timer, eventlist
Allow: INVITE, ACK, OPTIONS, CANCEL, BYE, SUBSCRIBE, NOTIFY, INFO, REFER, UPDATE
Content-Type: application/sdp
Accept: application/sdp, application/dtmf-relay
Content-Length:   474

v=0
o=42 8000 8000 IN IP4 192.168.3.39
s=SIP Call
c=IN IP4 192.168.3.39
t=0 0
m=audio 5004 RTP/AVP 0 8 4 18 2 97 123 9 101
a=sendrecv
a=rtpmap:0 PCMU/8000
a=ptime:20
a=rtpmap:8 PCMA/8000
a=rtpmap:4 G723/8000
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=no
a=rtpmap:2 G726-32/8000
a=rtpmap:97 iLBC/8000
a=fmtp:97 mode=20
a=rtpmap:123 opus/48000/2
a=fmtp:123 maxplaybackrate=16000
a=rtpmap:9 G722/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16,32-36,54

<--- Transmitting SIP response (490 bytes) to TLS:123.123.123.123:53742 --->
SIP/2.0 401 Unauthorized
Via: SIP/2.0/TLS 192.168.3.39:5061;rport=53742;received=123.123.123.123;branch=z9hG4bK1449350653;alias
Call-ID: 1596987452-5061-13@BJC.BGI.D.DJ
From: "Myname" <sips:42@100.100.100.100>;tag=981065372
To: <sips:25@100.100.100.100>;tag=z9hG4bK1449350653
CSeq: 80 INVITE
WWW-Authenticate: Digest realm="asterisk",nonce="1738452128/2e4a401bcbe5a84f1e312b26f1231147",opaque="77ca489d1de5a339",algorithm=MD5,qop="auth"
Server: Asterisk PBX 22.1.0
Content-Length:  0


<--- Received SIP request (300 bytes) from TLS:123.123.123.123:53742 --->
ACK sips:25@100.100.100.100:5061 SIP/2.0
Via: SIP/2.0/TLS 192.168.3.39:5061;branch=z9hG4bK1449350653;rport;alias
From: "Myname" <sips:42@100.100.100.100>;tag=981065372
To: <sips:25@100.100.100.100>;tag=z9hG4bK1449350653
Call-ID: 1596987452-5061-13@BJC.BGI.D.DJ
CSeq: 80 ACK
Content-Length: 0


<--- Received SIP request (1573 bytes) from TLS:123.123.123.123:53742 --->
INVITE sips:25@100.100.100.100:5061 SIP/2.0
Via: SIP/2.0/TLS 192.168.3.39:5061;branch=z9hG4bK297983083;rport;alias
From: "Myname" <sips:42@100.100.100.100:5061>;tag=981065372
To: <sips:25@100.100.100.100:5061>
Call-ID: 1596987452-5061-13@BJC.BGI.D.DJ
CSeq: 81 INVITE
Contact: "Myname" <sips:42@192.168.3.39:5061;transport=tls>
Authorization: Digest username="42", realm="asterisk", nonce="1738452128/2e4a401bcbe5a84f1e312b26f1231147", uri="sips:25@100.100.100.100:5061", response="0612ae92344ea5ae0dc12b2f0a9ffe3b", algorithm=MD5, cnonce="02065734", opaque="77ca489d1de5a339", qop=auth, nc=00000001
Max-Forwards: 70
User-Agent: Grandstream HT801 1.0.57.1
Privacy: none
P-Preferred-Identity: "Myname" <sips:42@100.100.100.100:5061>
P-Access-Network-Info: IEEE-EUI-48;eui-48-addr=40-3F-8C-72-D3-98
P-Emergency-Info: IEEE-EUI-48;eui-48-addr=00-0B-82-B6-44-5D
Supported: replaces, path, timer, eventlist
Allow: INVITE, ACK, OPTIONS, CANCEL, BYE, SUBSCRIBE, NOTIFY, INFO, REFER, UPDATE
Content-Type: application/sdp
Accept: application/sdp, application/dtmf-relay
Content-Length:   474

v=0
o=42 8000 8000 IN IP4 192.168.3.39
s=SIP Call
c=IN IP4 192.168.3.39
t=0 0
m=audio 5004 RTP/AVP 0 8 4 18 2 97 123 9 101
a=sendrecv
a=rtpmap:0 PCMU/8000
a=ptime:20
a=rtpmap:8 PCMA/8000
a=rtpmap:4 G723/8000
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=no
a=rtpmap:2 G726-32/8000
a=rtpmap:97 iLBC/8000
a=fmtp:97 mode=20
a=rtpmap:123 opus/48000/2
a=fmtp:123 maxplaybackrate=16000
a=rtpmap:9 G722/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16,32-36,54

<--- Transmitting SIP response (315 bytes) to TLS:123.123.123.123:53742 --->
SIP/2.0 100 Trying
Via: SIP/2.0/TLS 192.168.3.39:5061;rport=53742;received=123.123.123.123;branch=z9hG4bK297983083;alias
Call-ID: 1596987452-5061-13@BJC.BGI.D.DJ
From: "Myname" <sips:42@100.100.100.100>;tag=981065372
To: <sips:25@100.100.100.100>
CSeq: 81 INVITE
Server: Asterisk PBX 22.1.0
Content-Length:  0


[Feb  1 23:22:08] ERROR[3429]: res_pjsip_session.c:946 handle_incoming_sdp:  42: Couldn't negotiate stream 0:audio-0:audio:sendrecv (nothing)
<--- Transmitting SIP response (369 bytes) to TLS:123.123.123.123:53742 --->
SIP/2.0 488 Not Acceptable Here
Via: SIP/2.0/TLS 192.168.3.39:5061;rport=53742;received=123.123.123.123;branch=z9hG4bK297983083;alias
Call-ID: 1596987452-5061-13@BJC.BGI.D.DJ
From: "Myname" <sips:42@100.100.100.100>;tag=981065372
To: <sips:25@100.100.100.100>;tag=e4f4478e-0532-44bb-8cf3-341a179b2bf0
CSeq: 81 INVITE
Server: Asterisk PBX 22.1.0
Content-Length:  0


<--- Received SIP request (318 bytes) from TLS:123.123.123.123:53742 --->
ACK sips:25@100.100.100.100:5061 SIP/2.0
Via: SIP/2.0/TLS 192.168.3.39:5061;branch=z9hG4bK297983083;rport;alias
From: "Myname" <sips:42@100.100.100.100>;tag=981065372
To: <sips:25@100.100.100.100>;tag=e4f4478e-0532-44bb-8cf3-341a179b2bf0
Call-ID: 1596987452-5061-13@BJC.BGI.D.DJ
CSeq: 81 ACK
Content-Length: 0

Does it look like the endpoint is failing to start a secure session in that INVITE? I don’t quite know how to interpret all that, but if anyone has tips on where to start I’d appreciate it!

TLS encrypts the signaling, which is working. Media encryption is separate and uses SRTP. You have configured SRTP using SDES in Asterisk, but the INVITE from the remote side does not contain SRTP. Asterisk therefore rejects it.

1 Like

Thanks!

I found the config in the HT801 (“SRTP Mode”, disabled by default, d’oh).

It still wasn’t working, but I noticed in the logs:

[Feb 2 23:02:26] DEBUG[8436] sdp_srtp.c: No SRTP module loaded, can't setup SRTP session.

On the asterisk CLI I tried module load res_srtp.so and then it works.

Should I put res_srtp.so in /etc/asterisk/modules.conf?

Did I skip something during compilation?

Normally you should use autoload, rather than listing specific modules. It is quite likely that this isn’t the only modules you need but haven’t loaded.

1 Like

Aha. Indeed it was set to “no”. I based my config off the demo config and thought I had gone through everything relevant to customize, but clearly I had not. Thanks for the clue!

I do still see this the first time an endpoint connects, or if I connect via openssh manually to TCP port 5061:

[Feb 2 00:20:56] ERROR[4040]: pjproject: <?>: ssl0xb5ccd7535510 Error reading CA certificates from buffer

The endpoints work fine and SRTP is being used for the call as expected, no errors in the logs, etc. Anything to be concerned about? It only happens the first time a client connects.

Shot in the dark: perusing ssl_sock_ossl.c I see that at line 1527 it checks if cert exists and ssock->is_server, and once the internal if statements drop through, it falls to the block from 1571-1580, and generates the error string at line 1577.

Maybe it’s generating this error message by mistake?

Judging from the conditions at lines 1530 and 1532, perhaps line 1576 instead of being:

} else {

…should actually be:

} else if (cert->CA_file.slen > 0 || cert->CA_buf.slen > 0) {

Thoughts? I’m just having trouble understanding this error otherwise.

pjsip show transport transport-tls-nat

Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress....................>
==========================================================================================

Transport:  transport-tls-nat         tls      0      0  0.0.0.0:5061

 ParameterName               : ParameterValue
 =============================================================
 allow_reload                : false
 allow_wildcard_certs        : No
 async_operations            : 1
 bind                        : 0.0.0.0:5061
 ca_list_file                :
 ca_list_path                :
 cert_file                   : /etc/asterisk/keys/asterisk.crt
 cipher                      :
 cos                         : 0
 domain                      :
 external_media_address      : 100.100.100.100
 external_signaling_address  : 100.100.100.100
 external_signaling_port     : 0
 local_net                   : 10.0.0.0/255.255.255.0
 method                      : tlsv1_2
 password                    :
 priv_key_file               : /etc/asterisk/keys/asterisk.key
 protocol                    : tls
 require_client_cert         : No
 symmetric_transport         : false
 tcp_keepalive_enable        : true
 tcp_keepalive_idle_time     : 30
 tcp_keepalive_interval_time : 1
 tcp_keepalive_probe_count   : 5
 tos                         : 0
 verify_client               : No
 verify_server               : No
 websocket_write_timeout     : 100

That log line turns out to in fact be a bug and (AFAIK, in this case at least) is not indicative of any real problems.

And a pjproject developer has already fixed it: False-positive error message "Error reading CA certificates" ? · Issue #4290 · pjsip/pjproject · GitHub