Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
belle-sip
Commits
8d901812
Commit
8d901812
authored
Mar 27, 2013
by
Simon Morlat
Browse files
add missing file
parent
81f0dada
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
233 additions
and
0 deletions
+233
-0
src/transports/tls_channel_polarssl.c
src/transports/tls_channel_polarssl.c
+233
-0
No files found.
src/transports/tls_channel_polarssl.c
0 → 100644
View file @
8d901812
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2013 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "belle_sip_internal.h"
#include "stream_channel.h"
#ifdef HAVE_POLARSSL
#include <polarssl/error.h>
/*************tls********/
static
int
tls_process_data
(
belle_sip_channel_t
*
obj
,
unsigned
int
revents
);
struct
belle_sip_tls_channel
{
belle_sip_stream_channel_t
base
;
ssl_context
sslctx
;
struct
sockaddr_storage
ss
;
socklen_t
socklen
;
int
socket_connected
;
};
static
void
tls_channel_close
(
belle_sip_tls_channel_t
*
obj
){
ssl_close_notify
(
&
obj
->
sslctx
);
stream_channel_close
((
belle_sip_stream_channel_t
*
)
obj
);
}
static
void
tls_channel_uninit
(
belle_sip_tls_channel_t
*
obj
){
belle_sip_socket_t
sock
=
belle_sip_source_get_socket
((
belle_sip_source_t
*
)
obj
);
if
(
sock
!=-
1
)
tls_channel_close
(
obj
);
}
static
int
tls_channel_send
(
belle_sip_channel_t
*
obj
,
const
void
*
buf
,
size_t
buflen
){
belle_sip_tls_channel_t
*
channel
=
(
belle_sip_tls_channel_t
*
)
obj
;
int
err
=
ssl_write
(
&
channel
->
sslctx
,
buf
,
buflen
);
if
(
err
<
0
){
belle_sip_error
(
"Channel [%p]: error in ssl_write()."
,
obj
);
}
return
err
;
}
static
int
tls_channel_recv
(
belle_sip_channel_t
*
obj
,
void
*
buf
,
size_t
buflen
){
belle_sip_tls_channel_t
*
channel
=
(
belle_sip_tls_channel_t
*
)
obj
;
int
err
=
ssl_read
(
&
channel
->
sslctx
,
buf
,
buflen
);
if
(
err
<
0
){
belle_sip_error
(
"Channel [%p]: error in ssl_read()."
,
obj
);
}
return
err
;
}
static
int
tls_channel_connect
(
belle_sip_channel_t
*
obj
,
const
struct
addrinfo
*
ai
){
int
err
=
stream_channel_connect
((
belle_sip_stream_channel_t
*
)
obj
,
ai
);
if
(
err
==
0
){
belle_sip_socket_t
sock
=
belle_sip_source_get_socket
((
belle_sip_source_t
*
)
obj
);
belle_sip_channel_set_socket
(
obj
,
sock
,(
belle_sip_source_func_t
)
tls_process_data
);
return
0
;
}
return
-
1
;
}
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN
(
belle_sip_tls_channel_t
,
belle_sip_stream_channel_t
)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES
(
belle_sip_tls_channel_t
);
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR
(
belle_sip_tls_channel_t
)
=
{
{
{
{
BELLE_SIP_VPTR_INIT
(
belle_sip_tls_channel_t
,
belle_sip_stream_channel_t
,
FALSE
),
(
belle_sip_object_destroy_t
)
tls_channel_uninit
,
NULL
,
NULL
},
"TLS"
,
1
,
/*is_reliable*/
tls_channel_connect
,
tls_channel_send
,
tls_channel_recv
,
(
void
(
*
)(
belle_sip_channel_t
*
))
tls_channel_close
}
}
};
static
int
tls_process_data
(
belle_sip_channel_t
*
obj
,
unsigned
int
revents
){
belle_sip_tls_channel_t
*
channel
=
(
belle_sip_tls_channel_t
*
)
obj
;
int
err
;
if
(
obj
->
state
==
BELLE_SIP_CHANNEL_CONNECTING
)
{
if
(
!
channel
->
socket_connected
&&
(
revents
&
BELLE_SIP_EVENT_WRITE
))
{
channel
->
socklen
=
sizeof
(
channel
->
ss
);
if
(
finalize_stream_connection
((
belle_sip_stream_channel_t
*
)
obj
,(
struct
sockaddr
*
)
&
channel
->
ss
,
&
channel
->
socklen
))
{
goto
process_error
;
}
belle_sip_source_set_events
((
belle_sip_source_t
*
)
channel
,
BELLE_SIP_EVENT_READ
|
BELLE_SIP_EVENT_ERROR
);
channel
->
socket_connected
=
1
;
belle_sip_message
(
"Channel [%p]: Connected at TCP level, now doing TLS handshake"
,
obj
);
}
err
=
ssl_handshake
(
&
channel
->
sslctx
);
if
(
err
==
0
){
belle_sip_message
(
"Channel [%p]: SSL handshake finished."
,
obj
);
belle_sip_channel_set_ready
(
obj
,(
struct
sockaddr
*
)
&
channel
->
ss
,
channel
->
socklen
);
}
else
if
(
err
==
POLARSSL_ERR_NET_WANT_READ
||
err
==
POLARSSL_ERR_NET_WANT_WRITE
){
belle_sip_message
(
"Channel [%p]: SSL handshake in progress..."
,
obj
);
}
else
{
char
tmp
[
128
];
error_strerror
(
err
,
tmp
,
sizeof
(
tmp
));
belle_sip_error
(
"Channel [%p]: SSL handlshake failed : %s"
,
obj
,
tmp
);
goto
process_error
;
}
}
else
if
(
obj
->
state
==
BELLE_SIP_CHANNEL_READY
)
{
belle_sip_channel_process_data
(
obj
,
revents
);
}
else
{
belle_sip_warning
(
"Unexpected event [%i], for channel [%p]"
,
revents
,
channel
);
}
return
BELLE_SIP_CONTINUE
;
process_error:
belle_sip_error
(
"Cannot connect to [%s://%s:%i]"
,
belle_sip_channel_get_transport_name
(
obj
),
obj
->
peer_name
,
obj
->
peer_port
);
channel_set_state
(
obj
,
BELLE_SIP_CHANNEL_ERROR
);
return
BELLE_SIP_STOP
;
}
static
int
polarssl_read
(
void
*
ctx
,
unsigned
char
*
buf
,
size_t
len
){
belle_sip_stream_channel_t
*
super
=
(
belle_sip_stream_channel_t
*
)
ctx
;
int
ret
=
stream_channel_recv
(
super
,
buf
,
len
);
if
(
ret
<
0
){
ret
=-
ret
;
if
(
ret
==
BELLESIP_EWOULDBLOCK
||
ret
==
BELLESIP_EINPROGRESS
||
ret
==
EINTR
)
return
POLARSSL_ERR_NET_WANT_READ
;
return
POLARSSL_ERR_NET_CONN_RESET
;
}
return
ret
;
}
static
int
polarssl_write
(
void
*
ctx
,
const
unsigned
char
*
buf
,
size_t
len
){
belle_sip_stream_channel_t
*
super
=
(
belle_sip_stream_channel_t
*
)
ctx
;
int
ret
=
stream_channel_send
(
super
,
buf
,
len
);
if
(
ret
<
0
){
ret
=-
ret
;
if
(
ret
==
BELLESIP_EWOULDBLOCK
||
ret
==
BELLESIP_EINPROGRESS
||
ret
==
EINTR
)
return
POLARSSL_ERR_NET_WANT_WRITE
;
return
POLARSSL_ERR_NET_CONN_RESET
;
}
return
ret
;
}
static
int
random_generator
(
void
*
ctx
,
unsigned
char
*
ptr
,
size_t
size
){
belle_sip_random_bytes
(
ptr
,
size
);
return
0
;
}
static
const
char
*
polarssl_certflags_to_string
(
char
*
buf
,
size_t
size
,
int
flags
){
int
i
=
0
;
memset
(
buf
,
0
,
size
);
size
--
;
if
(
i
<
size
&&
(
flags
&
BADCERT_EXPIRED
))
i
+=
snprintf
(
buf
+
i
,
size
-
i
,
"expired "
);
if
(
i
<
size
&&
(
flags
&
BADCERT_REVOKED
))
i
+=
snprintf
(
buf
+
i
,
size
-
i
,
"revoked "
);
if
(
i
<
size
&&
(
flags
&
BADCERT_CN_MISMATCH
))
i
+=
snprintf
(
buf
+
i
,
size
-
i
,
"CN-mismatch "
);
if
(
i
<
size
&&
(
flags
&
BADCERT_NOT_TRUSTED
))
i
+=
snprintf
(
buf
+
i
,
size
-
i
,
"not-trusted "
);
if
(
i
<
size
&&
(
flags
&
BADCERT_MISSING
))
i
+=
snprintf
(
buf
+
i
,
size
-
i
,
"missing "
);
if
(
i
<
size
&&
(
flags
&
BADCRL_NOT_TRUSTED
))
i
+=
snprintf
(
buf
+
i
,
size
-
i
,
"crl-not-trusted "
);
if
(
i
<
size
&&
(
flags
&
BADCRL_EXPIRED
))
i
+=
snprintf
(
buf
+
i
,
size
-
i
,
"crl-not-expired "
);
return
buf
;
}
static
int
belle_sip_ssl_verify
(
void
*
data
,
x509_cert
*
cert
,
int
depth
,
int
*
flags
){
belle_sip_tls_listening_point_t
*
lp
=
(
belle_sip_tls_listening_point_t
*
)
data
;
char
tmp
[
256
];
char
flags_str
[
128
];
x509parse_cert_info
(
tmp
,
sizeof
(
tmp
),
""
,
cert
);
belle_sip_message
(
"Found certificate depth=[%i], flags=[%s]:
\n
%s"
,
depth
,
polarssl_certflags_to_string
(
flags_str
,
sizeof
(
flags_str
),
*
flags
),
tmp
);
if
(
lp
->
verify_exceptions
==
BELLE_SIP_TLS_LISTENING_POINT_BADCERT_ANY_REASON
){
*
flags
=
0
;
}
else
if
(
lp
->
verify_exceptions
&
BELLE_SIP_TLS_LISTENING_POINT_BADCERT_CN_MISMATCH
){
*
flags
&=~
BADCERT_CN_MISMATCH
;
}
return
0
;
}
belle_sip_channel_t
*
belle_sip_channel_new_tls
(
belle_sip_tls_listening_point_t
*
lp
,
const
char
*
bindip
,
int
localport
,
const
char
*
peer_cname
,
const
char
*
dest
,
int
port
){
belle_sip_tls_channel_t
*
obj
=
belle_sip_object_new
(
belle_sip_tls_channel_t
);
belle_sip_stream_channel_t
*
super
=
(
belle_sip_stream_channel_t
*
)
obj
;
belle_sip_stream_channel_init_client
(
super
,((
belle_sip_listening_point_t
*
)
lp
)
->
stack
,
bindip
,
localport
,
peer_cname
,
dest
,
port
);
ssl_init
(
&
obj
->
sslctx
);
ssl_set_endpoint
(
&
obj
->
sslctx
,
SSL_IS_CLIENT
);
ssl_set_authmode
(
&
obj
->
sslctx
,
SSL_VERIFY_REQUIRED
);
ssl_set_bio
(
&
obj
->
sslctx
,
polarssl_read
,
obj
,
polarssl_write
,
obj
);
ssl_set_ca_chain
(
&
obj
->
sslctx
,
&
lp
->
root_ca
,
NULL
,
dest
);
ssl_set_rng
(
&
obj
->
sslctx
,
random_generator
,
NULL
);
ssl_set_verify
(
&
obj
->
sslctx
,
belle_sip_ssl_verify
,
lp
);
return
(
belle_sip_channel_t
*
)
obj
;
}
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment