Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
f24d92ba
Commit
f24d92ba
authored
May 28, 2015
by
Rodger Combs
Committed by
Michael Niedermayer
May 29, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavf/tls: Support Secure Transport
Signed-off-by:
Michael Niedermayer
<
michaelni@gmx.at
>
parent
bedb5d58
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
413 additions
and
7 deletions
+413
-7
Changelog
Changelog
+1
-0
configure
configure
+11
-3
Makefile
libavformat/Makefile
+1
-0
allformats.c
libavformat/allformats.c
+1
-0
avio.c
libavformat/avio.c
+3
-1
tls.h
libavformat/tls.h
+1
-1
tls_securetransport.c
libavformat/tls_securetransport.c
+393
-0
version.h
libavformat/version.h
+2
-2
No files found.
Changelog
View file @
f24d92ba
...
...
@@ -23,6 +23,7 @@ version <next>:
- VP9 high bit-depth and extended colorspaces decoding support
- WebPAnimEncoder API when available for encoding and muxing WebP
- Direct3D11-accelerated decoding
- Support Secure Transport
version 2.6:
...
...
configure
View file @
f24d92ba
...
...
@@ -276,6 +276,8 @@ External library support:
--enable-openssl enable openssl, needed for https support
if gnutls is not used [no]
--disable-sdl disable sdl [autodetect]
--disable-securetransport disable Secure Transport, needed for TLS support
on OSX if openssl and gnutls are not used [autodetect]
--enable-x11grab enable X11 grabbing (legacy) [no]
--disable-xlib disable xlib [autodetect]
--disable-zlib disable zlib [autodetect]
...
...
@@ -1424,6 +1426,7 @@ EXTERNAL_LIBRARY_LIST="
opengl
openssl
sdl
securetransport
x11grab
xlib
zlib
...
...
@@ -2636,9 +2639,10 @@ sctp_protocol_deps="struct_sctp_event_subscribe"
sctp_protocol_select
=
"network"
srtp_protocol_select
=
"rtp_protocol"
tcp_protocol_select
=
"network"
tls_gnutls_protocol_deps
=
"gnutls"
tls_openssl_protocol_deps
=
"openssl !tls_gnutls_protocol"
tls_protocol_deps_any
=
"tls_gnutls_protocol tls_openssl_protocol"
tls_securetransport_protocol_deps
=
"securetransport"
tls_gnutls_protocol_deps
=
"gnutls !tls_securetransport_protocol"
tls_openssl_protocol_deps
=
"openssl !tls_securetransport_protocol !tls_gnutls_protocol"
tls_protocol_deps_any
=
"tls_securetransport_protocol tls_gnutls_protocol tls_openssl_protocol"
tls_protocol_select
=
"tcp_protocol"
udp_protocol_select
=
"network"
udplite_protocol_select
=
"network"
...
...
@@ -5213,6 +5217,10 @@ if ! disabled sdl; then
fi
enabled sdl
&&
add_cflags
$sdl_cflags
&&
add_extralibs
$sdl_libs
disabled securetransport
||
{
check_func SecIdentityCreate
"-Wl,-framework,CoreFoundation -Wl,-framework,Security"
&&
check_lib2 Security/SecureTransport.h SSLCreateContext
"-Wl,-framework,CoreFoundation -Wl,-framework,Security"
&&
enable
securetransport
;
}
makeinfo
--version
>
/dev/null 2>&1
&&
enable
makeinfo
||
disable makeinfo
enabled makeinfo
&&
(
makeinfo
--version
|
\
grep
-q
'makeinfo (GNU texinfo) 5'
>
/dev/null 2>&1
)
\
...
...
libavformat/Makefile
View file @
f24d92ba
...
...
@@ -523,6 +523,7 @@ OBJS-$(CONFIG_SUBFILE_PROTOCOL) += subfile.o
OBJS-$(CONFIG_TCP_PROTOCOL)
+=
tcp.o
OBJS-$(CONFIG_TLS_GNUTLS_PROTOCOL)
+=
tls_gnutls.o
tls.o
OBJS-$(CONFIG_TLS_OPENSSL_PROTOCOL)
+=
tls_openssl.o
tls.o
OBJS-$(CONFIG_TLS_SECURETRANSPORT_PROTOCOL)
+=
tls_securetransport.o
tls.o
OBJS-$(CONFIG_UDP_PROTOCOL)
+=
udp.o
OBJS-$(CONFIG_UDPLITE_PROTOCOL)
+=
udp.o
OBJS-$(CONFIG_UNIX_PROTOCOL)
+=
unix.o
...
...
libavformat/allformats.c
View file @
f24d92ba
...
...
@@ -377,6 +377,7 @@ void av_register_all(void)
REGISTER_PROTOCOL
(
SRTP
,
srtp
);
REGISTER_PROTOCOL
(
SUBFILE
,
subfile
);
REGISTER_PROTOCOL
(
TCP
,
tcp
);
REGISTER_PROTOCOL
(
TLS_SECURETRANSPORT
,
tls_securetransport
);
REGISTER_PROTOCOL
(
TLS_GNUTLS
,
tls_gnutls
);
REGISTER_PROTOCOL
(
TLS_OPENSSL
,
tls_openssl
);
REGISTER_PROTOCOL
(
UDP
,
udp
);
...
...
libavformat/avio.c
View file @
f24d92ba
...
...
@@ -263,7 +263,9 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags,
*
puc
=
NULL
;
if
(
av_strstart
(
filename
,
"https:"
,
NULL
))
av_log
(
NULL
,
AV_LOG_WARNING
,
"https protocol not found, recompile with openssl or gnutls enabled.
\n
"
);
av_log
(
NULL
,
AV_LOG_WARNING
,
"https protocol not found, recompile with "
"openssl, gnutls,
\n
"
"or securetransport enabled.
\n
"
);
return
AVERROR_PROTOCOL_NOT_FOUND
;
}
...
...
libavformat/tls.h
View file @
f24d92ba
...
...
@@ -26,7 +26,7 @@
#include "url.h"
#include "libavutil/opt.h"
#define CONFIG_TLS_PROTOCOL (CONFIG_TLS_GNUTLS_PROTOCOL | CONFIG_TLS_OPENSSL_PROTOCOL)
#define CONFIG_TLS_PROTOCOL (CONFIG_TLS_GNUTLS_PROTOCOL | CONFIG_TLS_OPENSSL_PROTOCOL
| CONFIG_TLS_SECURETRANSPORT_PROTOCOL
)
typedef
struct
TLSShared
{
char
*
ca_file
;
...
...
libavformat/tls_securetransport.c
0 → 100644
View file @
f24d92ba
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpeg; if not, write to the Free Software * Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <errno.h>
#include "avformat.h"
#include "internal.h"
#include "network.h"
#include "os_support.h"
#include "url.h"
#include "tls.h"
#include "libavcodec/internal.h"
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include <Security/Security.h>
#include <Security/SecureTransport.h>
#include <CoreFoundation/CoreFoundation.h>
// We use a private API call here; it's good enough for WebKit.
SecIdentityRef
SecIdentityCreate
(
CFAllocatorRef
allocator
,
SecCertificateRef
certificate
,
SecKeyRef
privateKey
);
#define ioErr -36
typedef
struct
TLSContext
{
const
AVClass
*
class
;
TLSShared
tls_shared
;
SSLContextRef
ssl_context
;
CFArrayRef
ca_array
;
int
lastErr
;
}
TLSContext
;
static
int
print_tls_error
(
URLContext
*
h
,
int
ret
)
{
TLSContext
*
c
=
h
->
priv_data
;
switch
(
ret
)
{
case
errSSLWouldBlock
:
break
;
case
errSSLXCertChainInvalid
:
av_log
(
h
,
AV_LOG_ERROR
,
"Invalid certificate chain
\n
"
);
return
AVERROR
(
EIO
);
case
ioErr
:
return
c
->
lastErr
;
default:
av_log
(
h
,
AV_LOG_ERROR
,
"IO Error: %i
\n
"
,
ret
);
return
AVERROR
(
EIO
);
}
return
AVERROR
(
EIO
);
}
static
int
import_pem
(
URLContext
*
h
,
char
*
path
,
CFArrayRef
*
array
)
{
AVIOContext
*
s
=
NULL
;
CFDataRef
data
=
NULL
;
int64_t
ret
=
0
;
char
*
buf
=
NULL
;
SecExternalFormat
format
=
kSecFormatPEMSequence
;
SecExternalFormat
type
=
kSecItemTypeAggregate
;
CFStringRef
pathStr
=
CFStringCreateWithCString
(
NULL
,
path
,
0x08000100
);
if
(
!
pathStr
)
{
ret
=
AVERROR
(
ENOMEM
);
goto
end
;
}
if
((
ret
=
avio_open2
(
&
s
,
path
,
AVIO_FLAG_READ
,
&
h
->
interrupt_callback
,
NULL
))
<
0
)
goto
end
;
if
((
ret
=
avio_size
(
s
))
<
0
)
goto
end
;
if
(
ret
==
0
)
{
ret
=
AVERROR_INVALIDDATA
;
goto
end
;
}
if
(
!
(
buf
=
av_malloc
(
ret
)))
{
ret
=
AVERROR
(
ENOMEM
);
goto
end
;
}
if
((
ret
=
avio_read
(
s
,
buf
,
ret
))
<
0
)
goto
end
;
data
=
CFDataCreate
(
kCFAllocatorDefault
,
buf
,
ret
);
if
(
SecItemImport
(
data
,
pathStr
,
&
format
,
&
type
,
0
,
NULL
,
NULL
,
array
)
!=
noErr
||
!
array
)
{
ret
=
AVERROR_UNKNOWN
;
goto
end
;
}
if
(
CFArrayGetCount
(
*
array
)
==
0
)
{
ret
=
AVERROR_INVALIDDATA
;
goto
end
;
}
end:
av_free
(
buf
);
if
(
pathStr
)
CFRelease
(
pathStr
);
if
(
data
)
CFRelease
(
data
);
if
(
s
)
avio_close
(
s
);
return
ret
;
}
static
int
load_ca
(
URLContext
*
h
)
{
TLSContext
*
c
=
h
->
priv_data
;
int
ret
=
0
;
CFArrayRef
array
=
NULL
;
if
((
ret
=
import_pem
(
h
,
c
->
tls_shared
.
ca_file
,
&
array
))
<
0
)
goto
end
;
if
(
!
(
c
->
ca_array
=
CFRetain
(
array
)))
{
ret
=
AVERROR
(
ENOMEM
);
goto
end
;
}
end:
if
(
array
)
CFRelease
(
array
);
return
ret
;
}
static
int
load_cert
(
URLContext
*
h
)
{
TLSContext
*
c
=
h
->
priv_data
;
int
ret
=
0
;
CFArrayRef
certArray
=
NULL
;
CFArrayRef
keyArray
=
NULL
;
SecIdentityRef
id
=
NULL
;
CFMutableArrayRef
outArray
=
NULL
;
if
((
ret
=
import_pem
(
h
,
c
->
tls_shared
.
cert_file
,
&
certArray
))
<
0
)
goto
end
;
if
((
ret
=
import_pem
(
h
,
c
->
tls_shared
.
key_file
,
&
keyArray
))
<
0
)
goto
end
;
if
(
!
(
id
=
SecIdentityCreate
(
kCFAllocatorDefault
,
(
SecCertificateRef
)
CFArrayGetValueAtIndex
(
certArray
,
0
),
(
SecKeyRef
)
CFArrayGetValueAtIndex
(
keyArray
,
0
))))
{
ret
=
AVERROR_UNKNOWN
;
goto
end
;
}
if
(
!
(
outArray
=
CFArrayCreateMutableCopy
(
kCFAllocatorDefault
,
0
,
certArray
)))
{
ret
=
AVERROR
(
ENOMEM
);
goto
end
;
}
CFArraySetValueAtIndex
(
outArray
,
0
,
id
);
SSLSetCertificate
(
c
->
ssl_context
,
outArray
);
end:
if
(
certArray
)
CFRelease
(
certArray
);
if
(
keyArray
)
CFRelease
(
keyArray
);
if
(
outArray
)
CFRelease
(
outArray
);
if
(
id
)
CFRelease
(
id
);
return
ret
;
}
static
OSStatus
tls_read_cb
(
SSLConnectionRef
connection
,
void
*
data
,
size_t
*
dataLength
)
{
URLContext
*
h
=
(
URLContext
*
)
connection
;
TLSContext
*
c
=
h
->
priv_data
;
int
read
=
ffurl_read_complete
(
c
->
tls_shared
.
tcp
,
data
,
*
dataLength
);
if
(
read
<=
0
)
{
*
dataLength
=
0
;
switch
(
AVUNERROR
(
read
))
{
case
ENOENT
:
case
0
:
return
errSSLClosedGraceful
;
case
ECONNRESET
:
return
errSSLClosedAbort
;
case
EAGAIN
:
return
errSSLWouldBlock
;
default:
c
->
lastErr
=
read
;
return
ioErr
;
}
}
else
{
*
dataLength
=
read
;
return
noErr
;
}
}
static
OSStatus
tls_write_cb
(
SSLConnectionRef
connection
,
const
void
*
data
,
size_t
*
dataLength
)
{
URLContext
*
h
=
(
URLContext
*
)
connection
;
TLSContext
*
c
=
h
->
priv_data
;
int
written
=
ffurl_write
(
c
->
tls_shared
.
tcp
,
data
,
*
dataLength
);
if
(
written
<=
0
)
{
*
dataLength
=
0
;
switch
(
AVUNERROR
(
written
))
{
case
EAGAIN
:
return
errSSLWouldBlock
;
default:
c
->
lastErr
=
written
;
return
ioErr
;
}
}
else
{
*
dataLength
=
written
;
return
noErr
;
}
}
static
int
tls_close
(
URLContext
*
h
)
{
TLSContext
*
c
=
h
->
priv_data
;
if
(
c
->
ssl_context
)
{
SSLClose
(
c
->
ssl_context
);
CFRelease
(
c
->
ssl_context
);
}
if
(
c
->
ca_array
)
CFRelease
(
c
->
ca_array
);
if
(
c
->
tls_shared
.
tcp
)
ffurl_close
(
c
->
tls_shared
.
tcp
);
return
0
;
}
#define CHECK_ERROR(func, ...) do { \
OSStatus status = func(__VA_ARGS__); \
if (status != noErr) { \
ret = AVERROR_UNKNOWN; \
av_log(h, AV_LOG_ERROR, #func ": Error %i\n", (int)status); \
goto fail; \
} \
} while (0)
static
int
tls_open
(
URLContext
*
h
,
const
char
*
uri
,
int
flags
,
AVDictionary
**
options
)
{
TLSContext
*
c
=
h
->
priv_data
;
TLSShared
*
s
=
&
c
->
tls_shared
;
int
ret
;
if
((
ret
=
ff_tls_open_underlying
(
s
,
h
,
uri
,
options
))
<
0
)
goto
fail
;
c
->
ssl_context
=
SSLCreateContext
(
NULL
,
s
->
listen
?
kSSLServerSide
:
kSSLClientSide
,
kSSLStreamType
);
if
(
!
c
->
ssl_context
)
{
av_log
(
h
,
AV_LOG_ERROR
,
"Unable to create SSL context
\n
"
);
ret
=
AVERROR
(
ENOMEM
);
goto
fail
;
}
if
(
s
->
ca_file
)
{
if
((
ret
=
load_ca
(
h
))
<
0
)
goto
fail
;
CHECK_ERROR
(
SSLSetSessionOption
,
c
->
ssl_context
,
kSSLSessionOptionBreakOnServerAuth
,
true
);
}
if
(
s
->
cert_file
)
if
((
ret
=
load_cert
(
h
))
<
0
)
goto
fail
;
if
(
s
->
verify
)
CHECK_ERROR
(
SSLSetPeerDomainName
,
c
->
ssl_context
,
s
->
host
,
strlen
(
s
->
host
));
CHECK_ERROR
(
SSLSetIOFuncs
,
c
->
ssl_context
,
tls_read_cb
,
tls_write_cb
);
CHECK_ERROR
(
SSLSetConnection
,
c
->
ssl_context
,
h
);
while
(
1
)
{
OSStatus
status
=
SSLHandshake
(
c
->
ssl_context
);
if
(
status
==
errSSLServerAuthCompleted
)
{
SecTrustRef
peerTrust
;
SecTrustResultType
trustResult
;
if
(
!
s
->
verify
)
continue
;
if
(
SSLCopyPeerTrust
(
c
->
ssl_context
,
&
peerTrust
)
!=
noErr
)
{
ret
=
AVERROR
(
ENOMEM
);
goto
fail
;
}
if
(
SecTrustSetAnchorCertificates
(
peerTrust
,
c
->
ca_array
)
!=
noErr
)
{
ret
=
AVERROR_UNKNOWN
;
goto
fail
;
}
if
(
SecTrustEvaluate
(
peerTrust
,
&
trustResult
)
!=
noErr
)
{
ret
=
AVERROR_UNKNOWN
;
goto
fail
;
}
if
(
trustResult
==
kSecTrustResultProceed
||
trustResult
==
kSecTrustResultUnspecified
)
{
// certificate is trusted
status
=
errSSLWouldBlock
;
// so we call SSLHandshake again
}
else
if
(
trustResult
==
kSecTrustResultRecoverableTrustFailure
)
{
// not trusted, for some reason other than being expired
status
=
errSSLXCertChainInvalid
;
}
else
{
// cannot use this certificate (fatal)
status
=
errSSLBadCert
;
}
if
(
peerTrust
)
CFRelease
(
peerTrust
);
}
if
(
status
==
noErr
)
break
;
av_log
(
h
,
AV_LOG_ERROR
,
"Unable to negotiate TLS/SSL session: %i
\n
"
,
(
int
)
status
);
ret
=
AVERROR
(
EIO
);
goto
fail
;
}
return
0
;
fail:
tls_close
(
h
);
return
ret
;
}
static
int
map_ssl_error
(
OSStatus
status
,
size_t
processed
)
{
switch
(
status
)
{
case
noErr
:
return
processed
;
case
errSSLClosedGraceful
:
case
errSSLClosedNoNotify
:
return
0
;
default:
return
(
int
)
status
;
}
}
static
int
tls_read
(
URLContext
*
h
,
uint8_t
*
buf
,
int
size
)
{
TLSContext
*
c
=
h
->
priv_data
;
size_t
processed
;
int
ret
=
map_ssl_error
(
SSLRead
(
c
->
ssl_context
,
buf
,
size
,
&
processed
),
processed
);
if
(
ret
>
0
)
return
ret
;
if
(
ret
==
0
)
return
AVERROR_EOF
;
return
print_tls_error
(
h
,
ret
);
}
static
int
tls_write
(
URLContext
*
h
,
const
uint8_t
*
buf
,
int
size
)
{
TLSContext
*
c
=
h
->
priv_data
;
size_t
processed
;
int
ret
=
map_ssl_error
(
SSLWrite
(
c
->
ssl_context
,
buf
,
size
,
&
processed
),
processed
);
if
(
ret
>
0
)
return
ret
;
if
(
ret
==
0
)
return
AVERROR_EOF
;
return
print_tls_error
(
h
,
ret
);
}
static
const
AVOption
options
[]
=
{
TLS_COMMON_OPTIONS
(
TLSContext
,
tls_shared
),
{
NULL
}
};
static
const
AVClass
tls_class
=
{
.
class_name
=
"tls"
,
.
item_name
=
av_default_item_name
,
.
option
=
options
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
URLProtocol
ff_tls_securetransport_protocol
=
{
.
name
=
"tls"
,
.
url_open2
=
tls_open
,
.
url_read
=
tls_read
,
.
url_write
=
tls_write
,
.
url_close
=
tls_close
,
.
priv_data_size
=
sizeof
(
TLSContext
),
.
flags
=
URL_PROTOCOL_FLAG_NETWORK
,
.
priv_data_class
=
&
tls_class
,
};
libavformat/version.h
View file @
f24d92ba
...
...
@@ -30,8 +30,8 @@
#include "libavutil/version.h"
#define LIBAVFORMAT_VERSION_MAJOR 56
#define LIBAVFORMAT_VERSION_MINOR 3
3
#define LIBAVFORMAT_VERSION_MICRO 10
1
#define LIBAVFORMAT_VERSION_MINOR 3
4
#define LIBAVFORMAT_VERSION_MICRO 10
0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
...
...
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