Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
4dcdc8c4
Commit
4dcdc8c4
authored
Jul 23, 2011
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Big cleanup of TLS interface
parent
378456a6
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
369 additions
and
420 deletions
+369
-420
include/vlc_common.h
include/vlc_common.h
+0
-4
include/vlc_network.h
include/vlc_network.h
+2
-2
include/vlc_tls.h
include/vlc_tls.h
+38
-36
modules/access/http.c
modules/access/http.c
+5
-5
modules/misc/gnutls.c
modules/misc/gnutls.c
+243
-295
src/libvlccore.sym
src/libvlccore.sym
+2
-2
src/network/httpd.c
src/network/httpd.c
+17
-17
src/network/tls.c
src/network/tls.c
+62
-59
No files found.
include/vlc_common.h
View file @
4dcdc8c4
...
...
@@ -344,10 +344,6 @@ typedef int (*httpd_handler_callback_t)( httpd_handler_sys_t *, httpd_handler_t
typedef
struct
httpd_redirect_t
httpd_redirect_t
;
typedef
struct
httpd_stream_t
httpd_stream_t
;
/* TLS support */
typedef
struct
tls_server_t
tls_server_t
;
typedef
struct
tls_session_t
tls_session_t
;
/* Hashing */
typedef
struct
md5_s
md5_t
;
...
...
include/vlc_network.h
View file @
4dcdc8c4
...
...
@@ -146,8 +146,8 @@ VLC_API int net_SetCSCov( int fd, int sendcov, int recvcov );
struct
virtual_socket_t
{
void
*
p_sys
;
int
(
*
pf_recv
)
(
void
*
,
void
*
,
in
t
);
int
(
*
pf_send
)
(
void
*
,
const
void
*
,
in
t
);
int
(
*
pf_recv
)
(
void
*
,
void
*
,
size_
t
);
int
(
*
pf_send
)
(
void
*
,
const
void
*
,
size_
t
);
};
VLC_API
ssize_t
net_Read
(
vlc_object_t
*
p_this
,
int
fd
,
const
v_socket_t
*
,
void
*
p_data
,
size_t
i_data
,
bool
b_retry
);
...
...
include/vlc_tls.h
View file @
4dcdc8c4
/*****************************************************************************
*
tls.c
: Transport Layer Security API
*
vlc_tls.h
: Transport Layer Security API
*****************************************************************************
* Copyright (C) 2004-2007 the VideoLAN team
* $Id$
*
* Authors: Rémi Denis-Courmont <rem # videolan.org>
* Copyright (C) 2004-2011 Rémi Denis-Courmont
* Copyright (C) 2005-2006 the VideoLAN team
*
* 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
...
...
@@ -31,52 +29,56 @@
# include <vlc_network.h>
typedef
struct
tls_server_sys_t
tls_server
_sys_t
;
typedef
struct
vlc_tls_sys
vlc_tls
_sys_t
;
struct
tls_server_t
typedef
struct
vlc_tls
{
VLC_COMMON_MEMBERS
module_t
*
p_module
;
tls_server_sys_t
*
p_sys
;
union
{
module_t
*
module
;
/**< Plugin handle (client) */
void
(
*
close
)
(
struct
vlc_tls
*
);
/**< Close callback (server) */
}
u
;
vlc_tls_sys_t
*
sys
;
int
(
*
pf_add_CA
)
(
tls_server_t
*
,
const
char
*
);
int
(
*
pf_add_CRL
)
(
tls_server_t
*
,
const
char
*
);
struct
virtual_socket_t
sock
;
int
(
*
handshake
)
(
struct
vlc_tls
*
);
}
vlc_tls_t
;
tls_session_t
*
(
*
pf_open
)
(
tls_server_t
*
);
void
(
*
pf_close
)
(
tls_server_t
*
,
tls_session_t
*
);
}
;
VLC_API
vlc_tls_t
*
vlc_tls_ClientCreate
(
vlc_object_t
*
,
int
fd
,
const
char
*
hostname
);
VLC_API
void
vlc_tls_ClientDelete
(
vlc_tls_t
*
)
;
typedef
struct
tls_session_sys_t
tls_session_sys_t
;
/* NOTE: It is assumed that a->sock.p_sys = a */
# define tls_Send( a, b, c ) (((vlc_tls_t *)a)->sock.pf_send (a, b, c))
struct
tls_session_t
{
VLC_COMMON_MEMBERS
# define tls_Recv( a, b, c ) (((vlc_tls_t *)a)->sock.pf_recv (a, b, c))
module_t
*
p_module
;
tls_session_sys_t
*
p_sys
;
struct
virtual_socket_t
sock
;
void
(
*
pf_set_fd
)
(
tls_session_t
*
,
int
);
int
(
*
pf_handshake
)
(
tls_session_t
*
);
};
typedef
struct
vlc_tls_creds_sys
vlc_tls_creds_sys_t
;
/** TLS (server-side) credentials */
typedef
struct
vlc_tls_creds
{
VLC_COMMON_MEMBERS
tls_server_t
*
tls_ServerCreate
(
vlc_object_t
*
,
const
char
*
,
const
char
*
);
void
tls_ServerDelete
(
tls_server_t
*
);
int
tls_ServerAddCA
(
tls_server_t
*
srv
,
const
char
*
path
);
int
tls_ServerAddCRL
(
tls_server_t
*
srv
,
const
char
*
path
);
module_t
*
module
;
vlc_tls_creds_sys_t
*
sys
;
tls_session_t
*
tls_ServerSessionCreate
(
tls_server_t
*
,
int
fd
);
int
tls_ServerSessionHandshake
(
tls_session_t
*
);
void
tls_ServerSessionDelete
(
tls_session_t
*
);
int
(
*
add_CA
)
(
struct
vlc_tls_creds
*
,
const
char
*
path
);
int
(
*
add_CRL
)
(
struct
vlc_tls_creds
*
,
const
char
*
path
);
VLC_API
tls_session_t
*
tls_ClientCreate
(
vlc_object_t
*
,
int
,
const
char
*
);
VLC_API
void
tls_ClientDelete
(
tls_session_t
*
)
;
vlc_tls_t
*
(
*
open
)
(
struct
vlc_tls_creds
*
,
int
fd
);
}
vlc_tls_creds_t
;
/* NOTE: It is assumed that a->sock.p_sys = a */
# define tls_Send( a, b, c ) (((tls_session_t *)a)->sock.pf_send (a, b, c ))
vlc_tls_creds_t
*
vlc_tls_ServerCreate
(
vlc_object_t
*
,
const
char
*
cert
,
const
char
*
key
);
void
vlc_tls_ServerDelete
(
vlc_tls_creds_t
*
);
int
vlc_tls_ServerAddCA
(
vlc_tls_creds_t
*
srv
,
const
char
*
path
);
int
vlc_tls_ServerAddCRL
(
vlc_tls_creds_t
*
srv
,
const
char
*
path
);
# define tls_Recv( a, b, c ) (((tls_session_t *)a)->sock.pf_recv (a, b, c ))
vlc_tls_t
*
vlc_tls_ServerSessionCreate
(
vlc_tls_creds_t
*
,
int
fd
);
int
vlc_tls_ServerSessionHandshake
(
vlc_tls_t
*
);
void
vlc_tls_ServerSessionDelete
(
vlc_tls_t
*
);
#endif
modules/access/http.c
View file @
4dcdc8c4
...
...
@@ -142,8 +142,8 @@ struct access_sys_t
{
int
fd
;
bool
b_error
;
tls_session_t
*
p_tls
;
v_socket_t
*
p_vs
;
vlc_tls_t
*
p_tls
;
v_socket_t
*
p_vs
;
/* From uri */
vlc_url_t
url
;
...
...
@@ -1195,8 +1195,8 @@ static int Connect( access_t *p_access, uint64_t i_tell )
}
/* TLS/SSL handshake */
p_sys
->
p_tls
=
tls_ClientCreate
(
VLC_OBJECT
(
p_access
),
p_sys
->
fd
,
p_sys
->
url
.
psz_host
);
p_sys
->
p_tls
=
vlc_
tls_ClientCreate
(
VLC_OBJECT
(
p_access
),
p_sys
->
fd
,
p_sys
->
url
.
psz_host
);
if
(
p_sys
->
p_tls
==
NULL
)
{
msg_Err
(
p_access
,
"cannot establish HTTP/TLS session"
);
...
...
@@ -1621,7 +1621,7 @@ static void Disconnect( access_t *p_access )
if
(
p_sys
->
p_tls
!=
NULL
)
{
tls_ClientDelete
(
p_sys
->
p_tls
);
vlc_
tls_ClientDelete
(
p_sys
->
p_tls
);
p_sys
->
p_tls
=
NULL
;
p_sys
->
p_vs
=
NULL
;
}
...
...
modules/misc/gnutls.c
View file @
4dcdc8c4
/*****************************************************************************
* gnutls.c
*****************************************************************************
* Copyright (C) 2004-2006 Rémi Denis-Courmont
* $Id$
*
* Authors: Rémi Denis-Courmont <rem # videolan.org>
* Copyright (C) 2004-2011 Rémi Denis-Courmont
*
* 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
...
...
@@ -65,8 +62,8 @@
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static
int
OpenClient
(
vlc_
object_t
*
);
static
void
CloseClient
(
vlc_
object
_t
*
);
static
int
OpenClient
(
vlc_
tls_t
*
,
int
,
const
char
*
);
static
void
CloseClient
(
vlc_
tls
_t
*
);
static
int
OpenServer
(
vlc_object_t
*
);
static
void
CloseServer
(
vlc_object_t
*
);
...
...
@@ -192,45 +189,41 @@ static int gnutls_Error (vlc_object_t *obj, int val)
}
return
-
1
;
}
#define gnutls_Error(o, val) gnutls_Error(VLC_OBJECT(o), val)
struct
tls_session_sys_t
struct
vlc_tls_sys
{
gnutls_session_t
session
;
char
*
psz_hostname
;
bool
b_handshaked
;
gnutls_certificate_credentials_t
x509_cred
;
char
*
hostname
;
bool
handshaked
;
};
/**
* Sends data through a TLS session.
*/
static
int
gnutls_Send
(
void
*
p_session
,
const
void
*
buf
,
int
i_length
)
static
int
gnutls_Send
(
void
*
opaque
,
const
void
*
buf
,
size_t
length
)
{
int
val
;
tls_session_sys_t
*
p_sys
;
p_sys
=
(
tls_session_sys_t
*
)(((
tls_session_t
*
)
p_session
)
->
p_sys
);
vlc_tls_t
*
session
=
opaque
;
vlc_tls_sys_t
*
sys
=
session
->
sys
;
val
=
gnutls_record_send
(
p_sys
->
session
,
buf
,
i_length
);
return
(
val
<
0
)
?
gnutls_Error
(
(
vlc_object_t
*
)
p_
session
,
val
)
:
val
;
int
val
=
gnutls_record_send
(
sys
->
session
,
buf
,
length
);
return
(
val
<
0
)
?
gnutls_Error
(
session
,
val
)
:
val
;
}
/**
* Receives data through a TLS session.
*/
static
int
gnutls_Recv
(
void
*
p_session
,
void
*
buf
,
int
i_length
)
static
int
gnutls_Recv
(
void
*
opaque
,
void
*
buf
,
size_t
length
)
{
int
val
;
tls_session_sys_t
*
p_sys
;
p_sys
=
(
tls_session_sys_t
*
)(((
tls_session_t
*
)
p_session
)
->
p_sys
);
vlc_tls_t
*
session
=
opaque
;
vlc_tls_sys_t
*
sys
=
session
->
sys
;
val
=
gnutls_record_recv
(
p_sys
->
session
,
buf
,
i_length
);
return
(
val
<
0
)
?
gnutls_Error
(
(
vlc_object_t
*
)
p_
session
,
val
)
:
val
;
int
val
=
gnutls_record_recv
(
sys
->
session
,
buf
,
length
);
return
(
val
<
0
)
?
gnutls_Error
(
session
,
val
)
:
val
;
}
...
...
@@ -241,30 +234,28 @@ gnutls_Recv( void *p_session, void *buf, int i_length )
* 1 if more would-be blocking recv is needed,
* 2 if more would-be blocking send is required.
*/
static
int
gnutls_ContinueHandshake
(
tls_session_t
*
p_session
)
static
int
gnutls_ContinueHandshake
(
vlc_tls_t
*
session
)
{
tls_session_sys_t
*
p_sys
=
p_session
->
p_
sys
;
vlc_tls_sys_t
*
sys
=
session
->
sys
;
int
val
;
#ifdef WIN32
WSASetLastError
(
0
);
WSASetLastError
(
0
);
#endif
val
=
gnutls_handshake
(
p_sys
->
session
);
if
(
(
val
==
GNUTLS_E_AGAIN
)
||
(
val
==
GNUTLS_E_INTERRUPTED
)
)
return
1
+
gnutls_record_get_direction
(
p_sys
->
session
);
val
=
gnutls_handshake
(
sys
->
session
);
if
((
val
==
GNUTLS_E_AGAIN
)
||
(
val
==
GNUTLS_E_INTERRUPTED
)
)
return
1
+
gnutls_record_get_direction
(
sys
->
session
);
if
(
val
<
0
)
if
(
val
<
0
)
{
#ifdef WIN32
msg_Dbg
(
p_session
,
"Winsock error %d"
,
WSAGetLastError
(
)
);
msg_Dbg
(
session
,
"Winsock error %d"
,
WSAGetLastError
()
);
#endif
msg_Err
(
p_session
,
"TLS handshake error: %s"
,
gnutls_strerror
(
val
)
);
msg_Err
(
session
,
"TLS handshake error: %s"
,
gnutls_strerror
(
val
));
return
-
1
;
}
p_sys
->
b_
handshaked
=
true
;
sys
->
handshaked
=
true
;
return
0
;
}
...
...
@@ -291,111 +282,99 @@ static const error_msg_t cert_errors[] =
};
static
int
gnutls_HandshakeAndValidate
(
tls_session_t
*
session
)
static
int
gnutls_HandshakeAndValidate
(
vlc_tls_t
*
session
)
{
int
val
=
gnutls_ContinueHandshake
(
session
);
if
(
val
)
return
val
;
vlc_tls_sys_t
*
sys
=
session
->
sys
;
tls_session_sys_t
*
p_sys
=
(
tls_session_sys_t
*
)(
session
->
p_sys
);
int
val
=
gnutls_ContinueHandshake
(
session
);
if
(
val
)
return
val
;
/* certificates chain verification */
unsigned
status
;
val
=
gnutls_certificate_verify_peers2
(
p_sys
->
session
,
&
status
);
if
(
val
)
val
=
gnutls_certificate_verify_peers2
(
sys
->
session
,
&
status
);
if
(
val
)
{
msg_Err
(
session
,
"Certificate verification failed: %s"
,
gnutls_strerror
(
val
)
);
msg_Err
(
session
,
"Certificate verification failed: %s"
,
gnutls_strerror
(
val
)
);
return
-
1
;
}
if
(
status
)
if
(
status
)
{
msg_Err
(
session
,
"TLS session: access denied"
);
for
(
const
error_msg_t
*
e
=
cert_errors
;
e
->
flag
;
e
++
)
msg_Err
(
session
,
"TLS session: access denied"
);
for
(
const
error_msg_t
*
e
=
cert_errors
;
e
->
flag
;
e
++
)
{
if
(
status
&
e
->
flag
)
if
(
status
&
e
->
flag
)
{
msg_Err
(
session
,
"%s"
,
e
->
msg
);
msg_Err
(
session
,
"%s"
,
e
->
msg
);
status
&=
~
e
->
flag
;
}
}
if
(
status
)
msg_Err
(
session
,
"unknown certificate error (you found a bug in VLC)"
);
if
(
status
)
msg_Err
(
session
,
"unknown certificate error (you found a bug in VLC)"
);
return
-
1
;
}
/* certificate (host)name verification */
const
gnutls_datum_t
*
data
;
data
=
gnutls_certificate_get_peers
(
p_
sys
->
session
,
&
(
unsigned
){
0
});
if
(
data
==
NULL
)
data
=
gnutls_certificate_get_peers
(
sys
->
session
,
&
(
unsigned
){
0
});
if
(
data
==
NULL
)
{
msg_Err
(
session
,
"Peer certificate not available"
);
msg_Err
(
session
,
"Peer certificate not available"
);
return
-
1
;
}
gnutls_x509_crt_t
cert
;
val
=
gnutls_x509_crt_init
(
&
cert
);
if
(
val
)
val
=
gnutls_x509_crt_init
(
&
cert
);
if
(
val
)
{
msg_Err
(
session
,
"x509 fatal error: %s"
,
gnutls_strerror
(
val
)
);
msg_Err
(
session
,
"x509 fatal error: %s"
,
gnutls_strerror
(
val
)
);
return
-
1
;
}
val
=
gnutls_x509_crt_import
(
cert
,
data
,
GNUTLS_X509_FMT_DER
);
if
(
val
)
val
=
gnutls_x509_crt_import
(
cert
,
data
,
GNUTLS_X509_FMT_DER
);
if
(
val
)
{
msg_Err
(
session
,
"Certificate import error: %s"
,
gnutls_strerror
(
val
)
);
msg_Err
(
session
,
"Certificate import error: %s"
,
gnutls_strerror
(
val
)
);
goto
error
;
}
if
(
p_sys
->
psz_
hostname
!=
NULL
&&
!
gnutls_x509_crt_check_hostname
(
cert
,
p_sys
->
psz_hostname
)
)
if
(
sys
->
hostname
!=
NULL
&&
!
gnutls_x509_crt_check_hostname
(
cert
,
sys
->
hostname
)
)
{
msg_Err
(
session
,
"Certificate does not match
\"
%s
\"
"
,
p_sys
->
psz_hostname
);
msg_Err
(
session
,
"Certificate does not match
\"
%s
\"
"
,
sys
->
hostname
);
goto
error
;
}
if
(
gnutls_x509_crt_get_expiration_time
(
cert
)
<
time
(
NULL
)
)
time_t
now
;
time
(
&
now
);
if
(
gnutls_x509_crt_get_expiration_time
(
cert
)
<
now
)
{
msg_Err
(
session
,
"Certificate expired"
);
msg_Err
(
session
,
"Certificate expired"
);
goto
error
;
}
if
(
gnutls_x509_crt_get_activation_time
(
cert
)
>
time
(
NULL
)
)
if
(
gnutls_x509_crt_get_activation_time
(
cert
)
>
now
)
{
msg_Err
(
session
,
"Certificate not yet valid"
);
goto
error
;
}
gnutls_x509_crt_deinit
(
cert
);
msg_Dbg
(
session
,
"TLS/x509 certificate verified"
);
gnutls_x509_crt_deinit
(
cert
);
msg_Dbg
(
session
,
"TLS/x509 certificate verified"
);
return
0
;
error:
gnutls_x509_crt_deinit
(
cert
);
gnutls_x509_crt_deinit
(
cert
);
return
-
1
;
}
/**
* Sets the operating system file descriptor backend for the TLS sesison.
*
* @param fd stream socket already connected with the peer.
*/
static
void
gnutls_SetFD
(
tls_session_t
*
p_session
,
int
fd
)
{
gnutls_transport_set_ptr
(
p_session
->
p_sys
->
session
,
(
gnutls_transport_ptr_t
)(
intptr_t
)
fd
);
}
static
int
gnutls_SessionPrioritize
(
vlc_object_t
*
obj
,
gnutls_session_t
session
)
{
...
...
@@ -530,7 +509,8 @@ gnutls_Addx509File( vlc_object_t *p_this,
psz_path
,
gnutls_strerror
(
res
));
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_this
,
"added x509 credentials (%s)"
,
psz_path
);
msg_Dbg
(
p_this
,
"added %d %s(s) from %s"
,
res
,
b_priv
?
"key"
:
"certificate"
,
psz_path
);
return
VLC_SUCCESS
;
}
...
...
@@ -551,7 +531,7 @@ error:
#ifdef WIN32
static
int
gnutls_loadOSCAList
(
vlc_object_t
*
p_this
,
gnutls_loadOSCAList
(
vlc_object_t
*
p_this
,
gnutls_certificate_credentials
cred
)
{
HCERTSTORE
hCertStore
=
CertOpenSystemStoreA
((
HCRYPTPROV
)
NULL
,
"ROOT"
);
...
...
@@ -581,49 +561,36 @@ gnutls_loadOSCAList( vlc_object_t *p_this,
}
#endif
/** TLS client session data */
typedef
struct
tls_client_sys_t
{
struct
tls_session_sys_t
session
;
gnutls_certificate_credentials_t
x509_cred
;
}
tls_client_sys_t
;
/**
* Initializes a client-side TLS session.
*/
static
int
OpenClient
(
vlc_
object_t
*
obj
)
static
int
OpenClient
(
vlc_
tls_t
*
session
,
int
fd
,
const
char
*
hostname
)
{
tls_session_t
*
p_session
=
(
tls_session_t
*
)
obj
;
int
i_val
;
if
(
gnutls_Init
(
obj
))
if
(
gnutls_Init
(
VLC_OBJECT
(
session
)))
return
VLC_EGENERIC
;
tls_client_sys_t
*
p_sys
=
malloc
(
sizeof
(
*
p_
sys
));
if
(
p_sys
==
NULL
)
vlc_tls_sys_t
*
sys
=
malloc
(
sizeof
(
*
sys
));
if
(
unlikely
(
sys
==
NULL
)
)
{
gnutls_Deinit
(
obj
);
gnutls_Deinit
(
VLC_OBJECT
(
session
)
);
return
VLC_ENOMEM
;
}
p_session
->
p_sys
=
&
p_sys
->
session
;
p_session
->
sock
.
p_sys
=
p_session
;
p_session
->
sock
.
pf_send
=
gnutls_Send
;
p_session
->
sock
.
pf_recv
=
gnutls_Recv
;
p_session
->
pf_set_fd
=
gnutls_SetFD
;
p_sys
->
session
.
b_handshaked
=
false
;
session
->
sys
=
sys
;
session
->
sock
.
p_sys
=
session
;
session
->
sock
.
pf_send
=
gnutls_Send
;
session
->
sock
.
pf_recv
=
gnutls_Recv
;
sys
->
handshaked
=
false
;
i
_val
=
gnutls_certificate_allocate_credentials
(
&
p_
sys
->
x509_cred
);
if
(
i_
val
!=
0
)
i
nt
val
=
gnutls_certificate_allocate_credentials
(
&
sys
->
x509_cred
);
if
(
val
!=
0
)
{
msg_Err
(
obj
,
"cannot allocate X509 credentials: %s"
,
gnutls_strerror
(
i_
val
));
msg_Err
(
session
,
"cannot allocate X509 credentials: %s"
,
gnutls_strerror
(
val
));
goto
error
;
}
char
*
userdir
=
config_GetUserDir
(
VLC_DATA_DIR
);
char
*
userdir
=
config_GetUserDir
(
VLC_DATA_DIR
);
if
(
userdir
!=
NULL
)
{
char
path
[
strlen
(
userdir
)
+
sizeof
(
"/ssl/private"
)];
...
...
@@ -631,102 +598,102 @@ static int OpenClient (vlc_object_t *obj)
vlc_mkdir
(
path
,
0755
);
sprintf
(
path
,
"%s/ssl/certs"
,
userdir
);
gnutls_Addx509Directory
(
VLC_OBJECT
(
p_session
),
p_sys
->
x509_cred
,
path
,
false
);
gnutls_Addx509Directory
(
VLC_OBJECT
(
session
),
sys
->
x509_cred
,
path
,
false
);
sprintf
(
path
,
"%s/ssl/private"
,
userdir
);
gnutls_Addx509Directory
(
VLC_OBJECT
(
p_session
),
p_sys
->
x509_cred
,
path
,
true
);
gnutls_Addx509Directory
(
VLC_OBJECT
(
session
),
sys
->
x509_cred
,
path
,
true
);
free
(
userdir
);
}
#ifdef WIN32
gnutls_loadOSCAList
(
VLC_OBJECT
(
session
),
sys
->
x509_cred
);
#else
const
char
*
confdir
=
config_GetConfDir
();
{
char
path
[
strlen
(
confdir
)
+
sizeof
(
"/ssl/certs/ca-certificates.crt"
)];
sprintf
(
path
,
"%s/ssl/certs/ca-certificates.crt"
,
confdir
);
#ifdef WIN32
gnutls_loadOSCAList
(
VLC_OBJECT
(
p_session
),
p_sys
->
x509_cred
);
#else
gnutls_Addx509File
(
VLC_OBJECT
(
p_session
),
p_sys
->
x509_cred
,
path
,
false
);
#endif
gnutls_Addx509File
(
VLC_OBJECT
(
session
),
sys
->
x509_cred
,
path
,
false
);
}
p_session
->
pf_handshake
=
gnutls_HandshakeAndValidate
;
/*p_session->pf_handshake = gnutls_ContinueHandshake;*/
#endif
session
->
handshake
=
gnutls_HandshakeAndValidate
;
/*session->_handshake = gnutls_ContinueHandshake;*/
i_val
=
gnutls_init
(
&
p_sys
->
session
.
session
,
GNUTLS_CLIENT
);
if
(
i_
val
!=
0
)
val
=
gnutls_init
(
&
sys
->
session
,
GNUTLS_CLIENT
);
if
(
val
!=
0
)
{
msg_Err
(
obj
,
"cannot initialize TLS session: %s"
,
gnutls_strerror
(
i_
val
));
gnutls_certificate_free_credentials
(
p_
sys
->
x509_cred
);
msg_Err
(
session
,
"cannot initialize TLS session: %s"
,
gnutls_strerror
(
val
));
gnutls_certificate_free_credentials
(
sys
->
x509_cred
);
goto
error
;
}
if
(
gnutls_SessionPrioritize
(
VLC_OBJECT
(
p_session
),
p_sys
->
session
.
session
))
if
(
gnutls_SessionPrioritize
(
VLC_OBJECT
(
session
),
sys
->
session
))
goto
s_error
;
/* minimum DH prime bits */
gnutls_dh_set_prime_bits
(
p_sys
->
session
.
session
,
1024
);
gnutls_dh_set_prime_bits
(
sys
->
session
,
1024
);
i_val
=
gnutls_credentials_set
(
p_sys
->
session
.
session
,
GNUTLS_CRD_CERTIFICATE
,
p_sys
->
x509_cred
);
if
(
i_val
<
0
)
val
=
gnutls_credentials_set
(
sys
->
session
,
GNUTLS_CRD_CERTIFICATE
,
sys
->
x509_cred
);
if
(
val
<
0
)
{
msg_Err
(
obj
,
"cannot set TLS session credentials: %s"
,
gnutls_strerror
(
i_
val
));
msg_Err
(
session
,
"cannot set TLS session credentials: %s"
,
gnutls_strerror
(
val
));
goto
s_error
;
}
char
*
servername
=
var_GetNonEmptyString
(
p_session
,
"tls-server-name"
);
if
(
servername
==
NULL
)
msg_Err
(
p_session
,
"server name missing for TLS session"
);
/* server name */
if
(
likely
(
hostname
!=
NULL
))
{
/* fill Server Name Indication */
gnutls_server_name_set
(
sys
->
session
,
GNUTLS_NAME_DNS
,
hostname
,
strlen
(
hostname
));
/* keep hostname to match CNAME after handshake */
sys
->
hostname
=
strdup
(
hostname
);
if
(
unlikely
(
sys
->
hostname
==
NULL
))
goto
s_error
;
}
else
gnutls_server_name_set
(
p_sys
->
session
.
session
,
GNUTLS_NAME_DNS
,
servername
,
strlen
(
servername
));
p_sys
->
session
.
psz_hostname
=
servername
;
sys
->
hostname
=
NULL
;
gnutls_transport_set_ptr
(
sys
->
session
,
(
gnutls_transport_ptr_t
)(
intptr_t
)
fd
);
return
VLC_SUCCESS
;
s_error:
gnutls_deinit
(
p_sys
->
session
.
session
);
gnutls_certificate_free_credentials
(
p_
sys
->
x509_cred
);
gnutls_deinit
(
sys
->
session
);
gnutls_certificate_free_credentials
(
sys
->
x509_cred
);
error:
gnutls_Deinit
(
obj
);
free
(
p_
sys
);
gnutls_Deinit
(
VLC_OBJECT
(
session
)
);
free
(
sys
);
return
VLC_EGENERIC
;
}
static
void
CloseClient
(
vlc_
object_t
*
obj
)
static
void
CloseClient
(
vlc_
tls_t
*
session
)
{
tls_session_t
*
client
=
(
tls_session_t
*
)
obj
;
tls_client_sys_t
*
p_sys
=
(
tls_client_sys_t
*
)(
client
->
p_sys
);
vlc_tls_sys_t
*
sys
=
session
->
sys
;
if
(
p_sys
->
session
.
b_
handshaked
)
gnutls_bye
(
p_sys
->
session
.
session
,
GNUTLS_SHUT_WR
);
gnutls_deinit
(
p_sys
->
session
.
session
);
if
(
sys
->
handshaked
)
gnutls_bye
(
sys
->
session
,
GNUTLS_SHUT_WR
);
gnutls_deinit
(
sys
->
session
);
/* credentials must be free'd *after* gnutls_deinit() */
gnutls_certificate_free_credentials
(
p_
sys
->
x509_cred
);
gnutls_certificate_free_credentials
(
sys
->
x509_cred
);
gnutls_Deinit
(
obj
);
free
(
p_sys
->
session
.
psz_
hostname
);
free
(
p_
sys
);
gnutls_Deinit
(
VLC_OBJECT
(
session
)
);
free
(
sys
->
hostname
);
free
(
sys
);
}
/**
* Server-side TLS
*/
struct
tls_server_sys_t
struct
vlc_tls_creds_sys
{
gnutls_certificate_credentials_t
x509_cred
;
gnutls_dh_params_t
dh_params
;
int
(
*
pf_handshake
)
(
tls_session
_t
*
);
int
(
*
handshake
)
(
vlc_tls
_t
*
);
};
...
...
@@ -734,88 +701,79 @@ struct tls_server_sys_t
* Terminates TLS session and releases session data.
* You still have to close the socket yourself.
*/
static
void
gnutls_SessionClose
(
tls_server_t
*
p_server
,
tls_session_t
*
p_session
)
static
void
gnutls_SessionClose
(
vlc_tls_t
*
session
)
{
tls_session_sys_t
*
p_sys
=
p_session
->
p_sys
;
(
void
)
p_server
;
vlc_tls_sys_t
*
sys
=
session
->
sys
;
if
(
p_sys
->
b_handshaked
)
gnutls_bye
(
p_sys
->
session
,
GNUTLS_SHUT_WR
);
gnutls_deinit
(
p_sys
->
session
);
if
(
sys
->
handshaked
)
gnutls_bye
(
sys
->
session
,
GNUTLS_SHUT_WR
);
gnutls_deinit
(
sys
->
session
);
vlc_object_release
(
p_session
);
free
(
p_sys
);
vlc_object_release
(
session
);
free
(
sys
);
}
/**
* Initializes a server-side TLS session.
*/
static
tls_session_t
*
gnutls_ServerSessionPrepare
(
tls_server_t
*
p_server
)
static
vlc_tls_t
*
gnutls_SessionOpen
(
vlc_tls_creds_t
*
server
,
int
fd
)
{
tls_session_t
*
p_session
;
tls_server_sys_t
*
p_server_sys
;
gnutls_session_t
session
;
int
i_val
;
vlc_tls_creds_sys_t
*
ssys
=
server
->
sys
;
int
val
;
p_session
=
vlc_object_create
(
p_server
,
sizeof
(
struct
tls_session_t
)
);
if
(
p_session
==
NULL
)
vlc_tls_t
*
session
=
vlc_object_create
(
server
,
sizeof
(
*
session
)
);
if
(
unlikely
(
session
==
NULL
)
)
return
NULL
;
p_session
->
p_sys
=
malloc
(
sizeof
(
struct
tls_session_sys_t
)
);
if
(
p_session
->
p_sys
==
NULL
)
vlc_tls_sys_t
*
sys
=
malloc
(
sizeof
(
*
session
->
sys
)
);
if
(
unlikely
(
sys
==
NULL
)
)
{
vlc_object_release
(
p_session
);
vlc_object_release
(
session
);
return
NULL
;
}
p_server_sys
=
p_server
->
p_sys
;
p_session
->
sock
.
p_sys
=
p_session
;
p_session
->
sock
.
pf_send
=
gnutls_Send
;
p_session
->
sock
.
pf_recv
=
gnutls_Recv
;
p_session
->
pf_set_fd
=
gnutls_SetFD
;
p_session
->
pf_handshake
=
p_server_sys
->
pf_handshake
;
session
->
sys
=
sys
;
session
->
sock
.
p_sys
=
session
;
session
->
sock
.
pf_send
=
gnutls_Send
;
session
->
sock
.
pf_recv
=
gnutls_Recv
;
session
->
handshake
=
ssys
->
handshake
;
session
->
u
.
close
=
gnutls_SessionClose
;
sys
->
handshaked
=
false
;
sys
->
hostname
=
NULL
;
p_session
->
p_sys
->
b_handshaked
=
false
;
p_session
->
p_sys
->
psz_hostname
=
NULL
;
i_val
=
gnutls_init
(
&
session
,
GNUTLS_SERVER
);
if
(
i_val
!=
0
)
val
=
gnutls_init
(
&
sys
->
session
,
GNUTLS_SERVER
);
if
(
val
!=
0
)
{
msg_Err
(
p_server
,
"cannot initialize TLS session: %s"
,
gnutls_strerror
(
i_val
)
);
goto
error
;
msg_Err
(
server
,
"cannot initialize TLS session: %s"
,
gnutls_strerror
(
val
));
free
(
sys
);
vlc_object_release
(
session
);
return
NULL
;
}
p_session
->
p_sys
->
session
=
session
;
if
(
gnutls_SessionPrioritize
(
VLC_OBJECT
(
p_session
),
session
))
{
gnutls_deinit
(
session
);
if
(
gnutls_SessionPrioritize
(
VLC_OBJECT
(
server
),
sys
->
session
))
goto
error
;
}
i_val
=
gnutls_credentials_set
(
session
,
GNUTLS_CRD_CERTIFICATE
,
p_server_sys
->
x509_cred
);
if
(
i_val
<
0
)
val
=
gnutls_credentials_set
(
sys
->
session
,
GNUTLS_CRD_CERTIFICATE
,
ssys
->
x509_cred
);
if
(
val
<
0
)
{
msg_Err
(
p_server
,
"cannot set TLS session credentials: %s"
,
gnutls_strerror
(
i_val
)
);
gnutls_deinit
(
session
);
msg_Err
(
server
,
"cannot set TLS session credentials: %s"
,
gnutls_strerror
(
val
));
goto
error
;
}
if
(
p_session
->
pf_handshake
==
gnutls_HandshakeAndValidate
)
gnutls_certificate_server_set_request
(
session
,
GNUTLS_CERT_REQUIRE
);
if
(
session
->
handshake
==
gnutls_HandshakeAndValidate
)
gnutls_certificate_server_set_request
(
sys
->
session
,
GNUTLS_CERT_REQUIRE
);
return
p_session
;
gnutls_transport_set_ptr
(
sys
->
session
,
(
gnutls_transport_ptr_t
)(
intptr_t
)
fd
);
return
session
;
error:
free
(
p_session
->
p_sys
);
vlc_object_release
(
p_session
);
gnutls_SessionClose
(
session
);
return
NULL
;
}
...
...
@@ -823,34 +781,29 @@ error:
/**
* Adds one or more certificate authorities.
*
* @param
psz_
ca_path (Unicode) path to an x509 certificates list.
* @param ca_path (Unicode) path to an x509 certificates list.
*
* @return -1 on error, 0 on success.
*/
static
int
gnutls_ServerAddCA
(
tls_server_t
*
p_server
,
const
char
*
psz_ca_path
)
static
int
gnutls_ServerAddCA
(
vlc_tls_creds_t
*
server
,
const
char
*
ca_path
)
{
tls_server_sys_t
*
p_sys
;
char
*
psz_local_path
;
int
val
;
p_sys
=
(
tls_server_sys_t
*
)(
p_server
->
p_sys
);
vlc_tls_creds_sys_t
*
sys
=
server
->
sys
;
char
*
local_path
=
ToLocale
(
ca_path
);
psz_local_path
=
ToLocale
(
psz_ca_path
);
val
=
gnutls_certificate_set_x509_trust_file
(
p_sys
->
x509_cred
,
psz_local_path
,
GNUTLS_X509_FMT_PEM
);
LocaleFree
(
psz_local_path
);
if
(
val
<
0
)
int
val
=
gnutls_certificate_set_x509_trust_file
(
sys
->
x509_cred
,
local_path
,
GNUTLS_X509_FMT_PEM
);
LocaleFree
(
local_path
);
if
(
val
<
0
)
{
msg_Err
(
p_server
,
"cannot add trusted CA (%s): %s"
,
psz_
ca_path
,
gnutls_strerror
(
val
)
);
msg_Err
(
server
,
"cannot add trusted CA (%s): %s"
,
ca_path
,
gnutls_strerror
(
val
)
);
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_server
,
" %d trusted CA added (%s)"
,
val
,
psz_ca_path
);
msg_Dbg
(
server
,
" %d trusted CA added (%s)"
,
val
,
ca_path
);
/* enables peer's certificate verification */
p_sys
->
pf_
handshake
=
gnutls_HandshakeAndValidate
;
sys
->
handshake
=
gnutls_HandshakeAndValidate
;
return
VLC_SUCCESS
;
}
...
...
@@ -859,28 +812,26 @@ gnutls_ServerAddCA( tls_server_t *p_server, const char *psz_ca_path )
/**
* Adds a certificates revocation list to be sent to TLS clients.
*
* @param
psz_
crl_path (Unicode) path of the CRL file.
* @param crl_path (Unicode) path of the CRL file.
*
* @return -1 on error, 0 on success.
*/
static
int
gnutls_ServerAddCRL
(
tls_server_t
*
p_server
,
const
char
*
psz_crl_path
)
static
int
gnutls_ServerAddCRL
(
vlc_tls_creds_t
*
server
,
const
char
*
crl_path
)
{
int
val
;
char
*
psz_local_path
=
ToLocale
(
psz_crl_path
);
vlc_tls_creds_sys_t
*
sys
=
server
->
sys
;
char
*
local_path
=
ToLocale
(
crl_path
);
val
=
gnutls_certificate_set_x509_crl_file
(
((
tls_server_sys_t
*
)
(
p_server
->
p_sys
))
->
x509_cred
,
psz_local_path
,
GNUTLS_X509_FMT_PEM
);
LocaleFree
(
psz_local_path
);
if
(
val
<
0
)
int
val
=
gnutls_certificate_set_x509_crl_file
(
sys
->
x509_cred
,
local_path
,
GNUTLS_X509_FMT_PEM
);
LocaleFree
(
local_path
);
if
(
val
<
0
)
{
msg_Err
(
p_server
,
"cannot add CRL (%s): %s"
,
psz_
crl_path
,
gnutls_strerror
(
val
)
);
msg_Err
(
server
,
"cannot add CRL (%s): %s"
,
crl_path
,
gnutls_strerror
(
val
)
);
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_server
,
"%d CRL added (%s)"
,
val
,
psz_crl_path
);
msg_Dbg
(
server
,
"%d CRL added (%s)"
,
val
,
crl_path
);
return
VLC_SUCCESS
;
}
...
...
@@ -890,8 +841,7 @@ gnutls_ServerAddCRL( tls_server_t *p_server, const char *psz_crl_path )
*/
static
int
OpenServer
(
vlc_object_t
*
obj
)
{
tls_server_t
*
p_server
=
(
tls_server_t
*
)
obj
;
tls_server_sys_t
*
p_sys
;
vlc_tls_creds_t
*
server
=
(
vlc_tls_creds_t
*
)
obj
;
int
val
;
if
(
gnutls_Init
(
obj
))
...
...
@@ -899,52 +849,49 @@ static int OpenServer (vlc_object_t *obj)
msg_Dbg
(
obj
,
"creating TLS server"
);
p_sys
=
(
tls_server_sys_t
*
)
malloc
(
sizeof
(
struct
tls_server_sys_t
)
);
if
(
p_sys
==
NULL
)
vlc_tls_creds_sys_t
*
sys
=
malloc
(
sizeof
(
*
sys
)
);
if
(
unlikely
(
sys
==
NULL
)
)
return
VLC_ENOMEM
;
p_server
->
p_sys
=
p_sys
;
p_server
->
pf_add_CA
=
gnutls_ServerAddCA
;
p_server
->
pf_add_CRL
=
gnutls_ServerAddCRL
;
p_server
->
pf_open
=
gnutls_ServerSessionPrepare
;
p_server
->
pf_close
=
gnutls_SessionClose
;
server
->
sys
=
sys
;
server
->
add_CA
=
gnutls_ServerAddCA
;
server
->
add_CRL
=
gnutls_ServerAddCRL
;
server
->
open
=
gnutls_SessionOpen
;
/* No certificate validation by default */
p_sys
->
pf_
handshake
=
gnutls_ContinueHandshake
;
sys
->
handshake
=
gnutls_ContinueHandshake
;
/* Sets server's credentials */
val
=
gnutls_certificate_allocate_credentials
(
&
p_sys
->
x509_cred
);
if
(
val
!=
0
)
val
=
gnutls_certificate_allocate_credentials
(
&
sys
->
x509_cred
);
if
(
val
!=
0
)
{
msg_Err
(
p_
server
,
"cannot allocate X509 credentials: %s"
,
gnutls_strerror
(
val
)
);
msg_Err
(
server
,
"cannot allocate X509 credentials: %s"
,
gnutls_strerror
(
val
)
);
goto
error
;
}
char
*
psz_cert_path
=
var_GetNonEmptyString
(
obj
,
"tls-x509-cert"
);
char
*
psz_key_path
=
var_GetNonEmptyString
(
obj
,
"tls-x509-key"
);
const
char
*
psz_local_cert
=
ToLocale
(
psz_cert_path
);
const
char
*
psz_local_key
=
ToLocale
(
psz_key_path
);
val
=
gnutls_certificate_set_x509_key_file
(
p_sys
->
x509_cred
,
psz_local_cert
,
psz_local_key
,
GNUTLS_X509_FMT_PEM
);
LocaleFree
(
psz_local_key
);
free
(
psz_key_path
);
LocaleFree
(
psz_local_cert
);
free
(
psz_cert_path
);
char
*
cert_path
=
var_GetNonEmptyString
(
obj
,
"tls-x509-cert"
);
char
*
key_path
=
var_GetNonEmptyString
(
obj
,
"tls-x509-key"
);
const
char
*
lcert
=
ToLocale
(
cert_path
);
const
char
*
lkey
=
ToLocale
(
key_path
);
val
=
gnutls_certificate_set_x509_key_file
(
sys
->
x509_cred
,
lcert
,
lkey
,
GNUTLS_X509_FMT_PEM
);
LocaleFree
(
lkey
);
LocaleFree
(
lcert
);
free
(
key_path
);
free
(
cert_path
);
if
(
val
<
0
)
if
(
val
<
0
)
{
msg_Err
(
p_
server
,
"cannot set certificate chain or private key: %s"
,
gnutls_strerror
(
val
)
);
gnutls_certificate_free_credentials
(
p_sys
->
x509_cred
);
msg_Err
(
server
,
"cannot set certificate chain or private key: %s"
,
gnutls_strerror
(
val
)
);
gnutls_certificate_free_credentials
(
sys
->
x509_cred
);
goto
error
;
}
/* FIXME:
* - support other ciper suites
* - support other cip
h
er suites
*/
val
=
gnutls_dh_params_init
(
&
p_
sys
->
dh_params
);
val
=
gnutls_dh_params_init
(
&
sys
->
dh_params
);
if
(
val
>=
0
)
{
const
gnutls_datum_t
data
=
{
...
...
@@ -952,36 +899,37 @@ static int OpenServer (vlc_object_t *obj)
.
size
=
sizeof
(
dh_params
)
-
1
,
};
val
=
gnutls_dh_params_import_pkcs3
(
p_
sys
->
dh_params
,
&
data
,
val
=
gnutls_dh_params_import_pkcs3
(
sys
->
dh_params
,
&
data
,
GNUTLS_X509_FMT_PEM
);
if
(
val
==
0
)
gnutls_certificate_set_dh_params
(
p_
sys
->
x509_cred
,
p_
sys
->
dh_params
);
gnutls_certificate_set_dh_params
(
sys
->
x509_cred
,
sys
->
dh_params
);
}
if
(
val
<
0
)
{
msg_Err
(
p_
server
,
"cannot initialize DHE cipher suites: %s"
,
msg_Err
(
server
,
"cannot initialize DHE cipher suites: %s"
,
gnutls_strerror
(
val
));
}
return
VLC_SUCCESS
;
error:
free
(
p_
sys
);
free
(
sys
);
return
VLC_EGENERIC
;
}
/**
* Destroys a TLS server object.
*/
static
void
CloseServer
(
vlc_object_t
*
p_server
)
static
void
CloseServer
(
vlc_object_t
*
obj
)
{
tls_server_sys_t
*
p_sys
=
((
tls_server_t
*
)
p_server
)
->
p_sys
;
vlc_tls_creds_t
*
server
=
(
vlc_tls_creds_t
*
)
obj
;
vlc_tls_creds_sys_t
*
sys
=
server
->
sys
;
/* all sessions depending on the server are now deinitialized */
gnutls_certificate_free_credentials
(
p_
sys
->
x509_cred
);
gnutls_dh_params_deinit
(
p_
sys
->
dh_params
);
free
(
p_
sys
);
gnutls_certificate_free_credentials
(
sys
->
x509_cred
);
gnutls_dh_params_deinit
(
sys
->
dh_params
);
free
(
sys
);
gnutls_Deinit
(
p_server
);
gnutls_Deinit
(
obj
);
}
src/libvlccore.sym
View file @
4dcdc8c4
...
...
@@ -436,8 +436,8 @@ subpicture_Update
subpicture_region_ChainDelete
subpicture_region_Delete
subpicture_region_New
tls_ClientCreate
tls_ClientDelete
vlc_
tls_ClientCreate
vlc_
tls_ClientDelete
ToCharset
ToLocale
ToLocaleDup
...
...
src/network/httpd.c
View file @
4dcdc8c4
...
...
@@ -108,7 +108,7 @@ struct httpd_host_t
httpd_client_t
**
client
;
/* TLS data */
tls_server
_t
*
p_tls
;
vlc_tls_creds
_t
*
p_tls
;
};
...
...
@@ -180,7 +180,7 @@ struct httpd_client_t
httpd_message_t
answer
;
/* httpd -> client */
/* TLS data */
tls_session
_t
*
p_tls
;
vlc_tls
_t
*
p_tls
;
};
...
...
@@ -982,7 +982,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
{
httpd_t
*
httpd
;
httpd_host_t
*
host
;
tls_server
_t
*
p_tls
;
vlc_tls_creds
_t
*
p_tls
;
char
*
psz_host
;
int
i
;
...
...
@@ -1043,20 +1043,20 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
/* determine TLS configuration */
if
(
psz_cert
!=
NULL
)
{
p_tls
=
tls_ServerCreate
(
p_this
,
psz_cert
,
psz_key
);
p_tls
=
vlc_
tls_ServerCreate
(
p_this
,
psz_cert
,
psz_key
);
if
(
p_tls
==
NULL
)
{
msg_Err
(
p_this
,
"TLS initialization error"
);
goto
error
;
}
if
(
(
psz_ca
!=
NULL
)
&&
tls_ServerAddCA
(
p_tls
,
psz_ca
)
)
if
(
(
psz_ca
!=
NULL
)
&&
vlc_
tls_ServerAddCA
(
p_tls
,
psz_ca
)
)
{
msg_Err
(
p_this
,
"TLS CA error"
);
goto
error
;
}
if
(
(
psz_crl
!=
NULL
)
&&
tls_ServerAddCRL
(
p_tls
,
psz_crl
)
)
if
(
(
psz_crl
!=
NULL
)
&&
vlc_
tls_ServerAddCRL
(
p_tls
,
psz_crl
)
)
{
msg_Err
(
p_this
,
"TLS CRL error"
);
goto
error
;
...
...
@@ -1132,7 +1132,7 @@ error:
}
if
(
p_tls
!=
NULL
)
tls_ServerDelete
(
p_tls
);
vlc_
tls_ServerDelete
(
p_tls
);
return
NULL
;
}
...
...
@@ -1184,7 +1184,7 @@ void httpd_HostDelete( httpd_host_t *host )
}
if
(
host
->
p_tls
!=
NULL
)
tls_ServerDelete
(
host
->
p_tls
);
vlc_
tls_ServerDelete
(
host
->
p_tls
);
net_ListenClose
(
host
->
fds
);
free
(
host
->
psz_hostname
);
...
...
@@ -1429,7 +1429,7 @@ static void httpd_ClientClean( httpd_client_t *cl )
if
(
cl
->
fd
>=
0
)
{
if
(
cl
->
p_tls
!=
NULL
)
tls_ServerSessionDelete
(
cl
->
p_tls
);
vlc_
tls_ServerSessionDelete
(
cl
->
p_tls
);
net_Close
(
cl
->
fd
);
cl
->
fd
=
-
1
;
}
...
...
@@ -1441,7 +1441,7 @@ static void httpd_ClientClean( httpd_client_t *cl )
cl
->
p_buffer
=
NULL
;
}
static
httpd_client_t
*
httpd_ClientNew
(
int
fd
,
tls_session
_t
*
p_tls
,
mtime_t
now
)
static
httpd_client_t
*
httpd_ClientNew
(
int
fd
,
vlc_tls
_t
*
p_tls
,
mtime_t
now
)
{
httpd_client_t
*
cl
=
malloc
(
sizeof
(
httpd_client_t
)
);
...
...
@@ -1460,7 +1460,7 @@ static httpd_client_t *httpd_ClientNew( int fd, tls_session_t *p_tls, mtime_t no
static
ssize_t
httpd_NetRecv
(
httpd_client_t
*
cl
,
uint8_t
*
p
,
size_t
i_len
)
{
tls_session
_t
*
p_tls
;
vlc_tls
_t
*
p_tls
;
ssize_t
val
;
p_tls
=
cl
->
p_tls
;
...
...
@@ -1474,7 +1474,7 @@ ssize_t httpd_NetRecv (httpd_client_t *cl, uint8_t *p, size_t i_len)
static
ssize_t
httpd_NetSend
(
httpd_client_t
*
cl
,
const
uint8_t
*
p
,
size_t
i_len
)
{
tls_session
_t
*
p_tls
;
vlc_tls
_t
*
p_tls
;
ssize_t
val
;
p_tls
=
cl
->
p_tls
;
...
...
@@ -2015,7 +2015,7 @@ static void httpd_ClientSend( httpd_client_t *cl )
static
void
httpd_ClientTlsHsIn
(
httpd_client_t
*
cl
)
{
switch
(
tls_ServerSessionHandshake
(
cl
->
p_tls
)
)
switch
(
vlc_
tls_ServerSessionHandshake
(
cl
->
p_tls
)
)
{
case
0
:
cl
->
i_state
=
HTTPD_CLIENT_RECEIVING
;
...
...
@@ -2033,7 +2033,7 @@ static void httpd_ClientTlsHsIn( httpd_client_t *cl )
static
void
httpd_ClientTlsHsOut
(
httpd_client_t
*
cl
)
{
switch
(
tls_ServerSessionHandshake
(
cl
->
p_tls
)
)
switch
(
vlc_
tls_ServerSessionHandshake
(
cl
->
p_tls
)
)
{
case
0
:
cl
->
i_state
=
HTTPD_CLIENT_RECEIVING
;
...
...
@@ -2533,12 +2533,12 @@ static void* httpd_HostThread( void *data )
setsockopt
(
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
(
int
){
1
},
sizeof
(
int
));
tls_session
_t
*
p_tls
;
vlc_tls
_t
*
p_tls
;
if
(
host
->
p_tls
!=
NULL
)
{
p_tls
=
tls_ServerSessionCreate
(
host
->
p_tls
,
fd
);
switch
(
tls_ServerSessionHandshake
(
p_tls
)
)
p_tls
=
vlc_
tls_ServerSessionCreate
(
host
->
p_tls
,
fd
);
switch
(
vlc_
tls_ServerSessionHandshake
(
p_tls
)
)
{
case
-
1
:
msg_Err
(
host
,
"Rejecting TLS connection"
);
...
...
src/network/tls.c
View file @
4dcdc8c4
...
...
@@ -46,14 +46,12 @@
*
* @return NULL on error.
*/
tls_server
_t
*
tls_ServerCreate
(
vlc_object_t
*
obj
,
const
char
*
cert_path
,
const
char
*
key_path
)
vlc_tls_creds
_t
*
vlc_
tls_ServerCreate
(
vlc_object_t
*
obj
,
const
char
*
cert_path
,
const
char
*
key_path
)
{
tls_server_t
*
srv
;
srv
=
(
tls_server_t
*
)
vlc_custom_create
(
obj
,
sizeof
(
*
srv
),
"tls server"
);
if
(
srv
==
NULL
)
vlc_tls_creds_t
*
srv
=
vlc_custom_create
(
obj
,
sizeof
(
*
srv
),
"tls creds"
);
if
(
unlikely
(
srv
==
NULL
))
return
NULL
;
var_Create
(
srv
,
"tls-x509-cert"
,
VLC_VAR_STRING
);
...
...
@@ -68,8 +66,8 @@ tls_ServerCreate (vlc_object_t *obj, const char *cert_path,
var_SetString
(
srv
,
"tls-x509-key"
,
key_path
);
}
srv
->
p_
module
=
module_need
(
srv
,
"tls server"
,
NULL
,
false
);
if
(
srv
->
p_
module
==
NULL
)
srv
->
module
=
module_need
(
srv
,
"tls server"
,
NULL
,
false
);
if
(
srv
->
module
==
NULL
)
{
msg_Err
(
srv
,
"TLS server plugin not available"
);
vlc_object_release
(
srv
);
...
...
@@ -82,15 +80,15 @@ tls_ServerCreate (vlc_object_t *obj, const char *cert_path,
/**
* Releases data allocated with
tls_ServerCreate
.
* Releases data allocated with
vlc_tls_ServerCreate()
.
* @param srv TLS server object to be destroyed, or NULL
*/
void
tls_ServerDelete
(
tls_server
_t
*
srv
)
void
vlc_tls_ServerDelete
(
vlc_tls_creds
_t
*
srv
)
{
if
(
srv
==
NULL
)
return
;
module_unneed
(
srv
,
srv
->
p_
module
);
module_unneed
(
srv
,
srv
->
module
);
vlc_object_release
(
srv
);
}
...
...
@@ -99,9 +97,9 @@ void tls_ServerDelete (tls_server_t *srv)
* Adds one or more certificate authorities from a file.
* @return -1 on error, 0 on success.
*/
int
tls_ServerAddCA
(
tls_server
_t
*
srv
,
const
char
*
path
)
int
vlc_tls_ServerAddCA
(
vlc_tls_creds
_t
*
srv
,
const
char
*
path
)
{
return
srv
->
pf_
add_CA
(
srv
,
path
);
return
srv
->
add_CA
(
srv
,
path
);
}
...
...
@@ -109,37 +107,54 @@ int tls_ServerAddCA (tls_server_t *srv, const char *path)
* Adds one or more certificate revocation list from a file.
* @return -1 on error, 0 on success.
*/
int
tls_ServerAddCRL
(
tls_server
_t
*
srv
,
const
char
*
path
)
int
vlc_tls_ServerAddCRL
(
vlc_tls_creds
_t
*
srv
,
const
char
*
path
)
{
return
srv
->
pf_
add_CRL
(
srv
,
path
);
return
srv
->
add_CRL
(
srv
,
path
);
}
tls_session_t
*
tls_ServerSessionCreate
(
tls_server
_t
*
srv
,
int
fd
)
vlc_tls_t
*
vlc_tls_ServerSessionCreate
(
vlc_tls_creds
_t
*
srv
,
int
fd
)
{
tls_session_t
*
ses
=
srv
->
pf_open
(
srv
);
if
(
ses
!=
NULL
)
ses
->
pf_set_fd
(
ses
,
fd
);
return
ses
;
return
srv
->
open
(
srv
,
fd
);
}
void
tls_ServerSessionDelete
(
tls_session
_t
*
ses
)
void
vlc_tls_ServerSessionDelete
(
vlc_tls
_t
*
ses
)
{
tls_server_t
*
srv
=
(
tls_server_t
*
)(
ses
->
p_parent
);
srv
->
pf_close
(
srv
,
ses
);
ses
->
u
.
close
(
ses
);
}
int
tls_ServerSessionHandshake
(
tls_session
_t
*
ses
)
int
vlc_tls_ServerSessionHandshake
(
vlc_tls
_t
*
ses
)
{
int
val
=
ses
->
pf_
handshake
(
ses
);
int
val
=
ses
->
handshake
(
ses
);
if
(
val
<
0
)
tls_ServerSessionDelete
(
ses
);
vlc_
tls_ServerSessionDelete
(
ses
);
return
val
;
}
/*** TLS client session ***/
/* TODO: cache certificates for the whole VLC instance lifetime */
static
int
tls_client_start
(
void
*
func
,
va_list
ap
)
{
int
(
*
activate
)
(
vlc_tls_t
*
,
int
fd
,
const
char
*
hostname
)
=
func
;
vlc_tls_t
*
session
=
va_arg
(
ap
,
vlc_tls_t
*
);
int
fd
=
va_arg
(
ap
,
int
);
const
char
*
hostname
=
va_arg
(
ap
,
const
char
*
);
return
activate
(
session
,
fd
,
hostname
);
}
static
void
tls_client_stop
(
void
*
func
,
va_list
ap
)
{
void
(
*
deactivate
)
(
vlc_tls_t
*
)
=
func
;
vlc_tls_t
*
session
=
va_arg
(
ap
,
vlc_tls_t
*
);
deactivate
(
session
);
}
/**
* Allocates a client's TLS credentials and shakes hands through the network.
* This is a blocking network operation.
...
...
@@ -150,61 +165,49 @@ int tls_ServerSessionHandshake (tls_session_t *ses)
*
* @return NULL on error.
**/
tls_session
_t
*
tls_ClientCreate
(
vlc_object_t
*
obj
,
int
fd
,
const
char
*
psz_
hostname
)
vlc_tls
_t
*
vlc_tls_ClientCreate
(
vlc_object_t
*
obj
,
int
fd
,
const
char
*
hostname
)
{
tls_session_t
*
cl
;
int
val
;
cl
=
(
tls_session_t
*
)
vlc_custom_create
(
obj
,
sizeof
(
*
cl
),
"tls client"
);
if
(
cl
==
NULL
)
vlc_tls_t
*
cl
=
vlc_custom_create
(
obj
,
sizeof
(
*
cl
),
"tls client"
);
if
(
unlikely
(
cl
==
NULL
))
return
NULL
;
var_Create
(
cl
,
"tls-server-name"
,
VLC_VAR_STRING
);
if
(
psz_hostname
!=
NULL
)
{
msg_Dbg
(
cl
,
"requested server name: %s"
,
psz_hostname
);
var_SetString
(
cl
,
"tls-server-name"
,
psz_hostname
);
}
else
msg_Dbg
(
cl
,
"requested anonymous server"
);
cl
->
p_module
=
module_need
(
cl
,
"tls client"
,
NULL
,
false
);
if
(
cl
->
p_module
==
NULL
)
cl
->
u
.
module
=
vlc_module_load
(
cl
,
"tls client"
,
NULL
,
false
,
tls_client_start
,
cl
,
fd
,
hostname
);
if
(
cl
->
u
.
module
==
NULL
)
{
msg_Err
(
cl
,
"TLS client plugin not available"
);
vlc_object_release
(
cl
);
return
NULL
;
}
cl
->
pf_set_fd
(
cl
,
fd
);
/* TODO: do this directly in the TLS plugin */
int
val
;
do
val
=
cl
->
pf_
handshake
(
cl
);
val
=
cl
->
handshake
(
cl
);
while
(
val
>
0
);
if
(
val
=
=
0
)
if
(
val
!
=
0
)
{
msg_Dbg
(
cl
,
"TLS client session initialized"
);
return
cl
;
msg_Err
(
cl
,
"TLS client session handshake error"
);
vlc_module_unload
(
cl
->
u
.
module
,
tls_client_stop
,
cl
);
vlc_object_release
(
cl
);
return
NULL
;
}
msg_Err
(
cl
,
"TLS client session handshake error"
);
module_unneed
(
cl
,
cl
->
p_module
);
vlc_object_release
(
cl
);
return
NULL
;
msg_Dbg
(
cl
,
"TLS client session initialized"
);
return
cl
;
}
/**
* Releases data allocated with
tls_ClientCreate
.
* Releases data allocated with
vlc_tls_ClientCreate()
.
* It is your job to close the underlying socket.
*/
void
tls_ClientDelete
(
tls_session
_t
*
cl
)
void
vlc_tls_ClientDelete
(
vlc_tls
_t
*
cl
)
{
if
(
cl
==
NULL
)
return
;
module_unneed
(
cl
,
cl
->
p_module
);
vlc_module_unload
(
cl
->
u
.
module
,
tls_client_stop
,
cl
);
vlc_object_release
(
cl
);
}
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