Go to the documentation of this file.
24 #include <gnutls/gnutls.h>
25 #include <gnutls/dtls.h>
26 #include <gnutls/x509.h>
39 #ifndef GNUTLS_VERSION_NUMBER
40 #define GNUTLS_VERSION_NUMBER LIBGNUTLS_VERSION_NUMBER
43 #if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00
45 GCRY_THREAD_OPTION_PTHREAD_IMPL;
48 #define MAX_MD_SIZE 64
52 size_t required_sz = out_sz - 1;
58 ret = gnutls_x509_privkey_export(
key, GNUTLS_X509_FMT_PEM,
out, &required_sz);
60 if (
ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
62 "TLS: Buffer size %zu is not enough to store private key PEM (need %zu)\n",
63 out_sz, required_sz + 1);
66 out[required_sz] =
'\0';
72 size_t required_sz = out_sz - 1;
78 ret = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM,
out, &required_sz);
80 if (
ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
82 "TLS: Buffer size %zu is not enough to store certificate PEM (need %zu)\n",
83 out_sz, required_sz + 1);
86 out[required_sz] =
'\0';
93 size_t n =
sizeof(
md);
97 ret = gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256,
md, &n);
100 gnutls_strerror(
ret));
106 for (
int i = 0;
i < n - 1;
i++)
113 int ff_ssl_read_key_cert(
char *key_url,
char *crt_url,
char *key_buf,
size_t key_sz,
char *crt_buf,
size_t crt_sz,
char **fingerprint)
116 AVBPrint key_bp, crt_bp;
117 gnutls_x509_crt_t crt =
NULL;
118 gnutls_x509_privkey_t
key =
NULL;
136 ret = gnutls_x509_privkey_init(&
key);
142 ret = gnutls_x509_crt_init(&crt);
148 tmp.data = key_bp.str;
149 tmp.size = key_bp.len;
150 ret = gnutls_x509_privkey_import(
key, &
tmp, GNUTLS_X509_FMT_PEM);
156 tmp.data = crt_bp.str;
157 tmp.size = crt_bp.len;
158 ret = gnutls_x509_crt_import(crt, &
tmp, GNUTLS_X509_FMT_PEM);
184 gnutls_x509_crt_deinit(crt);
186 gnutls_x509_privkey_deinit(
key);
194 ret = gnutls_x509_privkey_init(
key);
200 ret = gnutls_x509_privkey_generate(*
key, GNUTLS_PK_ECDSA,
201 gnutls_sec_param_to_pk_bits(GNUTLS_PK_ECDSA, GNUTLS_SEC_PARAM_MEDIUM), 0);
210 gnutls_x509_privkey_deinit(*
key);
220 unsigned char buf[8];
221 const char *dn =
"CN=lavf";
223 ret = gnutls_x509_crt_init(crt);
229 ret = gnutls_x509_crt_set_version(*crt, 3);
242 ret = gnutls_x509_crt_set_serial(*crt, buf,
sizeof(buf));
248 ret = gnutls_x509_crt_set_activation_time(*crt, time(
NULL));
254 ret = gnutls_x509_crt_set_expiration_time(*crt, time(
NULL) + 365 * 24 * 60 * 60);
260 ret = gnutls_x509_crt_set_dn(*crt, dn,
NULL);
266 ret = gnutls_x509_crt_set_issuer_dn(*crt, dn,
NULL);
272 ret = gnutls_x509_crt_set_key(*crt,
key);
278 ret = gnutls_x509_crt_sign2(*crt, *crt,
key, GNUTLS_DIG_SHA256, 0);
291 gnutls_x509_crt_deinit(*crt);
300 gnutls_x509_crt_t crt =
NULL;
301 gnutls_x509_privkey_t
key =
NULL;
328 gnutls_x509_crt_deinit(crt);
330 gnutls_x509_privkey_deinit(
key);
337 gnutls_certificate_credentials_t
cred;
349 #if HAVE_THREADS && GNUTLS_VERSION_NUMBER < 0x020b00
350 if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
351 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
353 gnutls_global_init();
360 gnutls_global_deinit();
382 ret = gnutls_srtp_get_keys(
c->session, dtls_srtp_materials, materials_sz,
NULL,
NULL,
NULL,
NULL);
396 case GNUTLS_E_INTERRUPTED:
397 #ifdef GNUTLS_E_PREMATURE_TERMINATION
398 case GNUTLS_E_PREMATURE_TERMINATION:
401 case GNUTLS_E_WARNING_ALERT_RECEIVED:
421 if (
c->need_shutdown)
422 gnutls_bye(
c->session, GNUTLS_SHUT_WR);
424 gnutls_deinit(
c->session);
426 gnutls_certificate_free_credentials(
c->cred);
427 if (!
s->external_sock)
434 void *buf,
size_t len)
441 if (
s->is_dtls &&
s->listen && !
c->dest_addr_len) {
466 const void *buf,
size_t len)
491 struct pollfd pfd = { .fd = sockfd, .events = POLLIN, .revents = 0 };
496 ret = poll(&pfd, 1, ms);
517 ret = gnutls_handshake(
c->session);
518 if (gnutls_error_is_fatal(
ret)) {
532 uint16_t gnutls_flags = 0;
533 gnutls_x509_crt_t cert =
NULL;
534 gnutls_x509_privkey_t pkey =
NULL;
539 if (!
s->external_sock) {
542 }
else if (!
s->host) {
560 gnutls_flags |= GNUTLS_DATAGRAM;
563 gnutls_flags |= GNUTLS_SERVER;
565 gnutls_flags |= GNUTLS_CLIENT;
566 gnutls_init(&
c->session, gnutls_flags);
567 if (!
s->listen && !
s->numerichost)
568 gnutls_server_name_set(
c->session, GNUTLS_NAME_DNS,
s->host, strlen(
s->host));
569 gnutls_certificate_allocate_credentials(&
c->cred);
571 ret = gnutls_certificate_set_x509_trust_file(
c->cred,
s->ca_file, GNUTLS_X509_FMT_PEM);
575 #if GNUTLS_VERSION_NUMBER >= 0x030020
577 gnutls_certificate_set_x509_system_trust(
c->cred);
579 gnutls_certificate_set_verify_flags(
c->cred,
s->verify ?
580 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT : 0);
581 if (
s->cert_file &&
s->key_file) {
582 ret = gnutls_certificate_set_x509_key_file(
c->cred,
583 s->cert_file,
s->key_file,
584 GNUTLS_X509_FMT_PEM);
587 "Unable to set cert/key files %s and %s: %s\n",
588 s->cert_file,
s->key_file, gnutls_strerror(
ret));
592 }
else if (
s->cert_file ||
s->key_file) {
594 }
else if (
s->cert_buf &&
s->key_buf) {
595 gnutls_datum_t cert_data = { .data =
s->cert_buf, .size = strlen(
s->cert_buf)};
596 gnutls_datum_t pkey_data = { .data =
s->key_buf, .size = strlen(
s->key_buf)};
597 ret = gnutls_certificate_set_x509_key_mem(
c->cred, &cert_data, &pkey_data, GNUTLS_X509_FMT_PEM);
603 }
else if (
s->cert_buf ||
s->key_buf) {
607 if (
s->listen && !
s->cert_file && !
s->cert_buf && !
s->key_file && !
s->key_buf) {
618 ret = gnutls_certificate_set_x509_key(
c->cred, &cert, 1, pkey);
625 gnutls_credentials_set(
c->session, GNUTLS_CRD_CERTIFICATE,
c->cred);
628 gnutls_transport_set_ptr(
c->session,
c);
632 gnutls_dtls_set_mtu(
c->session,
s->mtu);
634 gnutls_set_default_priority(
c->session);
637 ret = gnutls_srtp_set_profile(
c->session, GNUTLS_SRTP_AES128_CM_HMAC_SHA1_80);
645 if (!
s->external_sock) {
650 c->need_shutdown = 1;
652 unsigned int status, cert_list_size;
653 gnutls_x509_crt_t cert;
654 const gnutls_datum_t *cert_list;
655 if ((
ret = gnutls_certificate_verify_peers2(
c->session, &
status)) < 0) {
657 gnutls_strerror(
ret));
661 if (
status & GNUTLS_CERT_INVALID) {
666 if (gnutls_certificate_type_get(
c->session) != GNUTLS_CRT_X509) {
671 gnutls_x509_crt_init(&cert);
672 cert_list = gnutls_certificate_get_peers(
c->session, &cert_list_size);
673 gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER);
674 ret = gnutls_x509_crt_check_hostname(cert,
s->host);
675 gnutls_x509_crt_deinit(cert);
678 "The certificate's owner does not match hostname %s\n",
s->host);
687 gnutls_x509_crt_deinit(cert);
689 gnutls_x509_privkey_deinit(pkey);
711 ret = gnutls_record_recv(
c->session, buf,
size);
730 const size_t mtu_size = gnutls_dtls_get_data_mtu(
c->session);
734 ret = gnutls_record_send(
c->session, buf,
size);
void ff_gnutls_init(void)
#define AV_LOG_WARNING
Something somehow does not look correct.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static int gnutls_x509_fingerprint(gnutls_x509_crt_t cert, char **fingerprint)
int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
#define URL_PROTOCOL_FLAG_NETWORK
static ssize_t gnutls_url_pull(gnutls_transport_ptr_t transport, void *buf, size_t len)
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
#define AVERROR_EOF
End of file.
static int ffurl_write(URLContext *h, const uint8_t *buf, int size)
Write size bytes from buf to the resource accessed by h.
int ff_ssl_read_key_cert(char *key_url, char *crt_url, char *key_buf, size_t key_sz, char *crt_buf, size_t crt_sz, char **fingerprint)
static int print_tls_error(URLContext *h, int ret)
int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
static const AVClass tls_class
int ff_tls_set_external_socket(URLContext *h, URLContext *sock)
#define AV_LOG_VERBOSE
Detailed information.
static int tls_write(URLContext *h, const uint8_t *buf, int size)
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
static int ff_mutex_unlock(AVMutex *mutex)
gnutls_certificate_credentials_t cred
#define TLS_COMMON_OPTIONS(pstruct, options_field)
static int gnutls_gen_certificate(gnutls_x509_privkey_t key, gnutls_x509_crt_t *crt, char **fingerprint)
int ffurl_get_short_seek(void *urlcontext)
Return the current short seek threshold value for this URL.
static AVMutex gnutls_mutex
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
static int crt_to_pem_string(gnutls_x509_crt_t crt, char *out, size_t out_sz)
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static const AVClass dtls_class
static int tls_close(URLContext *h)
int ff_udp_set_remote_addr(URLContext *h, const struct sockaddr *dest_addr, socklen_t dest_addr_len, int do_connect)
This function is identical to ff_udp_set_remote_url, except that it takes a sockaddr directly.
#define LIBAVUTIL_VERSION_INT
Describe the class of an AVClass context structure.
const char * av_default_item_name(void *ptr)
Return the context name.
void ff_udp_get_last_recv_addr(URLContext *h, struct sockaddr_storage *addr, socklen_t *addr_len)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
static int pkey_to_pem_string(gnutls_x509_privkey_t key, char *out, size_t out_sz)
int ff_url_read_all(const char *url, AVBPrint *bp)
Read all data from the given URL url and store it in the given buffer bp.
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
#define i(width, name, range_min, range_max)
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
#define AV_MUTEX_INITIALIZER
static int gnutls_gen_private_key(gnutls_x509_privkey_t *key)
static int tls_get_file_handle(URLContext *h)
static ssize_t gnutls_url_push(gnutls_transport_ptr_t transport, const void *buf, size_t len)
static int ff_mutex_lock(AVMutex *mutex)
struct sockaddr_storage dest_addr
static int tls_handshake(URLContext *h)
static int tls_get_short_seek(URLContext *h)
static int dtls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
const URLProtocol ff_tls_protocol
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, 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...
void av_bprintf(AVBPrint *buf, const char *fmt,...)
const URLProtocol ff_dtls_protocol
static const AVOption options[]
static int gnutls_pull_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
char * av_strdup(const char *s)
Duplicate a string.
#define MAX_CERTIFICATE_SIZE
Maximum size limit of a certificate and private key size.
static int tls_read(URLContext *h, uint8_t *buf, int size)
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
void ff_gnutls_deinit(void)
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
static int ffurl_read(URLContext *h, uint8_t *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf.