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);
88 &
h->interrupt_callback,
NULL,
89 h->protocol_whitelist,
h->protocol_blacklist)) < 0)
108 data = CFDataCreate(kCFAllocatorDefault, buf, ret);
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;
162 if ((ret =
import_pem(
h,
c->tls_shared.cert_file, &certArray)) < 0)
165 if ((ret =
import_pem(
h,
c->tls_shared.key_file, &keyArray)) < 0)
169 (SecCertificateRef)CFArrayGetValueAtIndex(certArray, 0),
170 (SecKeyRef)CFArrayGetValueAtIndex(keyArray, 0)))) {
175 if (!(outArray = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certArray))) {
180 CFArraySetValueAtIndex(outArray, 0,
id);
182 SSLSetCertificate(
c->ssl_context, outArray);
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;
236 c->lastErr = written;
240 *dataLength = written;
248 if (
c->ssl_context) {
249 SSLClose(
c->ssl_context);
250 CFRelease(
c->ssl_context);
253 CFRelease(
c->ca_array);
258 #define CHECK_ERROR(func, ...) do { \
259 OSStatus status = func(__VA_ARGS__); \
260 if (status != noErr) { \
261 ret = AVERROR_UNKNOWN; \
262 av_log(h, AV_LOG_ERROR, #func ": Error %i\n", (int)status); \
276 c->ssl_context = SSLCreateContext(
NULL,
s->listen ? kSSLServerSide : kSSLClientSide, kSSLStreamType);
277 if (!
c->ssl_context) {
286 if (
s->ca_file || !
s->verify)
287 CHECK_ERROR(SSLSetSessionOption,
c->ssl_context, kSSLSessionOptionBreakOnServerAuth,
true);
291 CHECK_ERROR(SSLSetPeerDomainName,
c->ssl_context,
s->host, strlen(
s->host));
295 OSStatus status = SSLHandshake(
c->ssl_context);
296 if (status == errSSLServerAuthCompleted) {
297 SecTrustRef peerTrust;
298 SecTrustResultType trustResult;
302 if (SSLCopyPeerTrust(
c->ssl_context, &peerTrust) != noErr) {
307 if (SecTrustSetAnchorCertificates(peerTrust,
c->ca_array) != noErr) {
312 if (SecTrustEvaluate(peerTrust, &trustResult) != noErr) {
317 if (trustResult == kSecTrustResultProceed ||
318 trustResult == kSecTrustResultUnspecified) {
320 status = errSSLWouldBlock;
321 }
else if (trustResult == kSecTrustResultRecoverableTrustFailure) {
323 status = errSSLXCertChainInvalid;
326 status = errSSLBadCert;
330 CFRelease(peerTrust);
332 if (status == noErr) {
334 }
else if (status != errSSLWouldBlock) {
352 case errSSLClosedGraceful:
353 case errSSLClosedNoNotify:
355 case errSSLWouldBlock:
366 size_t available = 0, processed = 0;
368 SSLGetBufferedReadSize(
c->ssl_context, &available);
371 ret = SSLRead(
c->ssl_context, buf,
size, &processed);
383 size_t processed = 0;
384 int ret = SSLWrite(
c->ssl_context, buf,
size, &processed);
static const char *const format[]
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.
int ffurl_get_short_seek(URLContext *h)
Return the current short seek threshold value for this URL.
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
Write size bytes from buf to the resource accessed by h.
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
#define AVIO_FLAG_READ
read-only
int64_t avio_size(AVIOContext *s)
Get the filesize.
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
int ffio_open_whitelist(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist)
#define flags(name, subs,...)
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AVERROR_EOF
End of file.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
#define LIBAVUTIL_VERSION_INT
common internal api header.
common internal API header
miscellaneous OS support macros and functions.
Describe the class of an AVClass context structure.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
SSLContextRef ssl_context
static int array[MAX_W *MAX_W]
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
#define TLS_COMMON_OPTIONS(pstruct, options_field)
static OSStatus tls_read_cb(SSLConnectionRef connection, void *data, size_t *dataLength)
static int load_ca(URLContext *h)
static int import_pem(URLContext *h, char *path, CFArrayRef *array)
static int tls_close(URLContext *h)
static const AVClass tls_class
static OSStatus tls_write_cb(SSLConnectionRef connection, const void *data, size_t *dataLength)
const URLProtocol ff_tls_protocol
static const AVOption options[]
static int map_ssl_error(OSStatus status, size_t processed)
static int tls_read(URLContext *h, uint8_t *buf, int size)
SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, SecCertificateRef certificate, SecKeyRef privateKey)
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
static int load_cert(URLContext *h)
static int tls_get_short_seek(URLContext *h)
static int tls_write(URLContext *h, const uint8_t *buf, int size)
static int print_tls_error(URLContext *h, int ret)
#define CHECK_ERROR(func,...)
static int tls_get_file_handle(URLContext *h)
unbuffered private I/O API
#define URL_PROTOCOL_FLAG_NETWORK