24 #include <gnutls/gnutls.h>
25 #include <gnutls/dtls.h>
26 #include <gnutls/x509.h>
28 #include "config_components.h"
41 #ifndef GNUTLS_VERSION_NUMBER
42 #define GNUTLS_VERSION_NUMBER LIBGNUTLS_VERSION_NUMBER
45 #if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00
47 GCRY_THREAD_OPTION_PTHREAD_IMPL;
50 #define MAX_MD_SIZE 64
54 size_t required_sz = out_sz - 1;
60 ret = gnutls_x509_privkey_export(
key, GNUTLS_X509_FMT_PEM,
out, &required_sz);
62 if (
ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
64 "TLS: Buffer size %zu is not enough to store private key PEM (need %zu)\n",
65 out_sz, required_sz + 1);
68 out[required_sz] =
'\0';
74 size_t required_sz = out_sz - 1;
80 ret = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM,
out, &required_sz);
82 if (
ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
84 "TLS: Buffer size %zu is not enough to store certificate PEM (need %zu)\n",
85 out_sz, required_sz + 1);
88 out[required_sz] =
'\0';
95 size_t n =
sizeof(
md);
99 ret = gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256,
md, &n);
102 gnutls_strerror(
ret));
108 for (
int i = 0;
i < n - 1;
i++)
115 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)
118 AVBPrint key_bp, crt_bp;
119 gnutls_x509_crt_t crt =
NULL;
120 gnutls_x509_privkey_t
key =
NULL;
138 ret = gnutls_x509_privkey_init(&
key);
144 ret = gnutls_x509_crt_init(&crt);
150 tmp.data = key_bp.str;
151 tmp.size = key_bp.len;
152 ret = gnutls_x509_privkey_import(
key, &
tmp, GNUTLS_X509_FMT_PEM);
158 tmp.data = crt_bp.str;
159 tmp.size = crt_bp.len;
160 ret = gnutls_x509_crt_import(crt, &
tmp, GNUTLS_X509_FMT_PEM);
186 gnutls_x509_crt_deinit(crt);
188 gnutls_x509_privkey_deinit(
key);
196 ret = gnutls_x509_privkey_init(
key);
202 ret = gnutls_x509_privkey_generate(*
key, GNUTLS_PK_ECDSA,
203 GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP256R1), 0);
212 gnutls_x509_privkey_deinit(*
key);
222 unsigned char buf[8];
223 const char *dn =
"CN=lavf";
225 ret = gnutls_x509_crt_init(crt);
231 ret = gnutls_x509_crt_set_version(*crt, 3);
244 ret = gnutls_x509_crt_set_serial(*crt, buf,
sizeof(buf));
250 ret = gnutls_x509_crt_set_activation_time(*crt, time(
NULL));
256 ret = gnutls_x509_crt_set_expiration_time(*crt, time(
NULL) + 365 * 24 * 60 * 60);
262 ret = gnutls_x509_crt_set_dn(*crt, dn,
NULL);
268 ret = gnutls_x509_crt_set_issuer_dn(*crt, dn,
NULL);
274 ret = gnutls_x509_crt_set_key(*crt,
key);
280 ret = gnutls_x509_crt_sign2(*crt, *crt,
key, GNUTLS_DIG_SHA256, 0);
293 gnutls_x509_crt_deinit(*crt);
302 gnutls_x509_crt_t crt =
NULL;
303 gnutls_x509_privkey_t
key =
NULL;
330 gnutls_x509_crt_deinit(crt);
332 gnutls_x509_privkey_deinit(
key);
339 gnutls_certificate_credentials_t
cred;
351 #if HAVE_THREADS && GNUTLS_VERSION_NUMBER < 0x020b00
352 if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
353 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
355 gnutls_global_init();
362 gnutls_global_deinit();
384 ret = gnutls_srtp_get_keys(
c->session, dtls_srtp_materials, materials_sz,
NULL,
NULL,
NULL,
NULL);
398 case GNUTLS_E_INTERRUPTED:
399 #ifdef GNUTLS_E_PREMATURE_TERMINATION
400 case GNUTLS_E_PREMATURE_TERMINATION:
403 case GNUTLS_E_WARNING_ALERT_RECEIVED:
423 if (
c->need_shutdown)
424 gnutls_bye(
c->session, GNUTLS_SHUT_WR);
426 gnutls_deinit(
c->session);
428 gnutls_certificate_free_credentials(
c->cred);
429 if (!
s->external_sock)
436 void *buf,
size_t len)
443 #if CONFIG_UDP_PROTOCOL
444 if (
s->is_dtls &&
s->listen && !
c->dest_addr_len) {
470 const void *buf,
size_t len)
495 struct pollfd pfd = { .fd = sockfd, .events = POLLIN, .revents = 0 };
500 ret = poll(&pfd, 1, ms);
521 ret = gnutls_handshake(
c->session);
522 if (gnutls_error_is_fatal(
ret)) {
536 uint16_t gnutls_flags = 0;
537 gnutls_x509_crt_t cert =
NULL;
538 gnutls_x509_privkey_t pkey =
NULL;
539 int have_cert_pkey = 0;
544 if (!
s->external_sock) {
547 }
else if (!
s->host) {
552 gnutls_certificate_allocate_credentials(&
c->cred);
554 ret = gnutls_certificate_set_x509_trust_file(
c->cred,
s->ca_file, GNUTLS_X509_FMT_PEM);
558 #if GNUTLS_VERSION_NUMBER >= 0x030020
560 gnutls_certificate_set_x509_system_trust(
c->cred);
562 gnutls_certificate_set_verify_flags(
c->cred,
s->verify ?
563 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT : 0);
564 if (
s->cert_file &&
s->key_file) {
565 ret = gnutls_certificate_set_x509_key_file(
c->cred,
566 s->cert_file,
s->key_file,
567 GNUTLS_X509_FMT_PEM);
570 "Unable to set cert/key files %s and %s: %s\n",
571 s->cert_file,
s->key_file, gnutls_strerror(
ret));
576 }
else if (
s->cert_file ||
s->key_file) {
578 }
else if (
s->cert_buf &&
s->key_buf) {
579 gnutls_datum_t cert_data = { .data =
s->cert_buf, .size = strlen(
s->cert_buf)};
580 gnutls_datum_t pkey_data = { .data =
s->key_buf, .size = strlen(
s->key_buf)};
581 ret = gnutls_certificate_set_x509_key_mem(
c->cred, &cert_data, &pkey_data, GNUTLS_X509_FMT_PEM);
588 }
else if (
s->cert_buf ||
s->key_buf) {
592 if (
s->listen && !
s->cert_file && !
s->cert_buf && !
s->key_file && !
s->key_buf) {
603 ret = gnutls_certificate_set_x509_key(
c->cred, &cert, 1, pkey);
614 gnutls_flags |= GNUTLS_DATAGRAM;
617 gnutls_flags |= GNUTLS_SERVER;
619 gnutls_flags |= GNUTLS_CLIENT;
620 #if GNUTLS_VERSION_NUMBER >= 0x030500
622 gnutls_flags |= GNUTLS_FORCE_CLIENT_CERT;
626 gnutls_init(&
c->session, gnutls_flags);
628 if (!
s->listen && !
s->numerichost)
629 gnutls_server_name_set(
c->session, GNUTLS_NAME_DNS,
s->host, strlen(
s->host));
630 gnutls_credentials_set(
c->session, GNUTLS_CRD_CERTIFICATE,
c->cred);
633 gnutls_transport_set_ptr(
c->session,
c);
637 gnutls_dtls_set_mtu(
c->session,
s->mtu);
639 gnutls_set_default_priority(
c->session);
642 ret = gnutls_srtp_set_profile(
c->session, GNUTLS_SRTP_AES128_CM_HMAC_SHA1_80);
650 if (!
s->external_sock) {
655 c->need_shutdown = 1;
657 unsigned int status, cert_list_size;
658 gnutls_x509_crt_t cert;
659 const gnutls_datum_t *cert_list;
660 if ((
ret = gnutls_certificate_verify_peers2(
c->session, &
status)) < 0) {
662 gnutls_strerror(
ret));
666 if (
status & GNUTLS_CERT_INVALID) {
671 if (gnutls_certificate_type_get(
c->session) != GNUTLS_CRT_X509) {
676 gnutls_x509_crt_init(&cert);
677 cert_list = gnutls_certificate_get_peers(
c->session, &cert_list_size);
678 gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER);
679 ret = gnutls_x509_crt_check_hostname(cert,
s->host);
680 gnutls_x509_crt_deinit(cert);
683 "The certificate's owner does not match hostname %s\n",
s->host);
692 gnutls_x509_crt_deinit(cert);
694 gnutls_x509_privkey_deinit(pkey);
716 ret = gnutls_record_recv(
c->session, buf,
size);
735 const size_t mtu_size = gnutls_dtls_get_data_mtu(
c->session);
739 ret = gnutls_record_send(
c->session, buf,
size);