36 #include <Security/Security.h>
37 #include <Security/SecureTransport.h>
38 #include <CoreFoundation/CoreFoundation.h>
41 SecIdentityRef
SecIdentityCreate(CFAllocatorRef allocator, SecCertificateRef certificate, SecKeyRef privateKey);
56 case errSSLWouldBlock:
58 case errSSLXCertChainInvalid:
72 #if !HAVE_SECITEMIMPORT
79 SecExternalFormat
format = kSecFormatPEMSequence;
80 SecExternalFormat
type = kSecItemTypeAggregate;
81 CFStringRef pathStr = CFStringCreateWithCString(
NULL, path, 0x08000100);
108 data = CFDataCreate(kCFAllocatorDefault, buf, ret);
110 if (SecItemImport(data, pathStr, &format, &type,
111 0,
NULL,
NULL, array) != noErr || !array) {
116 if (CFArrayGetCount(*array) == 0) {
142 if (!(c->
ca_array = CFRetain(array))) {
157 CFArrayRef certArray =
NULL;
158 CFArrayRef keyArray =
NULL;
159 SecIdentityRef
id =
NULL;
160 CFMutableArrayRef outArray =
NULL;
169 (SecCertificateRef)CFArrayGetValueAtIndex(certArray, 0),
170 (SecKeyRef)CFArrayGetValueAtIndex(keyArray, 0)))) {
175 if (!(outArray = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certArray))) {
180 CFArraySetValueAtIndex(outArray, 0,
id);
186 CFRelease(certArray);
196 static OSStatus
tls_read_cb(SSLConnectionRef connection,
void *
data,
size_t *dataLength)
200 size_t requested = *dataLength;
207 return errSSLClosedGraceful;
209 return errSSLClosedAbort;
211 return errSSLWouldBlock;
218 if (read < requested)
219 return errSSLWouldBlock;
225 static OSStatus
tls_write_cb(SSLConnectionRef connection,
const void *
data,
size_t *dataLength)
234 return errSSLWouldBlock;
240 *dataLength = written;
259 #define CHECK_ERROR(func, ...) do { \
260 OSStatus status = func(__VA_ARGS__); \
261 if (status != noErr) { \
262 ret = AVERROR_UNKNOWN; \
263 av_log(h, AV_LOG_ERROR, #func ": Error %i\n", (int)status); \
277 c->
ssl_context = SSLCreateContext(
NULL, s->
listen ? kSSLServerSide : kSSLClientSide, kSSLStreamType);
297 if (status == errSSLServerAuthCompleted) {
298 SecTrustRef peerTrust;
299 SecTrustResultType trustResult;
303 if (SSLCopyPeerTrust(c->
ssl_context, &peerTrust) != noErr) {
308 if (SecTrustSetAnchorCertificates(peerTrust, c->
ca_array) != noErr) {
313 if (SecTrustEvaluate(peerTrust, &trustResult) != noErr) {
318 if (trustResult == kSecTrustResultProceed ||
319 trustResult == kSecTrustResultUnspecified) {
321 status = errSSLWouldBlock;
322 }
else if (trustResult == kSecTrustResultRecoverableTrustFailure) {
324 status = errSSLXCertChainInvalid;
327 status = errSSLBadCert;
331 CFRelease(peerTrust);
333 if (status == noErr) {
335 }
else if (status != errSSLWouldBlock) {
353 case errSSLClosedGraceful:
354 case errSSLClosedNoNotify:
356 case errSSLWouldBlock:
367 size_t available = 0, processed = 0;
369 SSLGetBufferedReadSize(c->
ssl_context, &available);
371 size =
FFMIN(available, size);
372 ret = SSLRead(c->
ssl_context, buf, size, &processed);
384 size_t processed = 0;
385 int ret = SSLWrite(c->
ssl_context, buf, size, &processed);
421 .priv_data_class = &tls_class,
static const AVClass tls_class
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static int tls_get_file_handle(URLContext *h)
int64_t avio_size(AVIOContext *s)
Get the filesize.
static const char * format[]
#define URL_PROTOCOL_FLAG_NETWORK
#define CHECK_ERROR(func,...)
ptrdiff_t const GLvoid * data
#define LIBAVUTIL_VERSION_INT
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
Write size bytes from buf to the resource accessed by h.
AVIOInterruptCB interrupt_callback
const char * av_default_item_name(void *ptr)
Return the context name.
#define AVIO_FLAG_READ
read-only
static int tls_close(URLContext *h)
static int print_tls_error(URLContext *h, int ret)
static OSStatus tls_write_cb(SSLConnectionRef connection, const void *data, size_t *dataLength)
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
const URLProtocol ff_tls_protocol
miscellaneous OS support macros and functions.
static av_cold int end(AVCodecContext *avctx)
#define AVERROR_EOF
End of file.
static int load_ca(URLContext *h)
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * protocol_whitelist
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
static int tls_read(URLContext *h, uint8_t *buf, int size)
static int import_pem(URLContext *h, char *path, CFArrayRef *array)
#define TLS_COMMON_OPTIONS(pstruct, options_field)
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
static int map_ssl_error(OSStatus status, size_t processed)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
const char * protocol_blacklist
Describe the class of an AVClass context structure.
SSLContextRef ssl_context
int ffio_open_whitelist(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist)
static const AVOption options[]
int ffurl_close(URLContext *h)
common internal api header.
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
static int tls_write(URLContext *h, const uint8_t *buf, int size)
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
static OSStatus tls_read_cb(SSLConnectionRef connection, void *data, size_t *dataLength)
SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, SecCertificateRef certificate, SecKeyRef privateKey)
unbuffered private I/O API
static int array[MAX_W *MAX_W]
static int load_cert(URLContext *h)
int ffurl_read(URLContext *h, unsigned char *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf...