24 #include <gnutls/gnutls.h>
25 #include <gnutls/dtls.h>
26 #include <gnutls/x509.h>
38 #ifndef GNUTLS_VERSION_NUMBER
39 #define GNUTLS_VERSION_NUMBER LIBGNUTLS_VERSION_NUMBER
42 #if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00
44 GCRY_THREAD_OPTION_PTHREAD_IMPL;
47 #define MAX_MD_SIZE 64
51 size_t required_sz = out_sz - 1;
57 ret = gnutls_x509_privkey_export(
key, GNUTLS_X509_FMT_PEM,
out, &required_sz);
59 if (
ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
61 "TLS: Buffer size %zu is not enough to store private key PEM (need %zu)\n",
62 out_sz, required_sz + 1);
65 out[required_sz] =
'\0';
71 size_t required_sz = out_sz - 1;
77 ret = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM,
out, &required_sz);
79 if (
ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
81 "TLS: Buffer size %zu is not enough to store certificate PEM (need %zu)\n",
82 out_sz, required_sz + 1);
85 out[required_sz] =
'\0';
92 size_t n =
sizeof(
md);
96 ret = gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256,
md, &n);
99 gnutls_strerror(
ret));
105 for (
int i = 0;
i < n - 1;
i++)
112 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)
115 AVBPrint key_bp, crt_bp;
116 gnutls_x509_crt_t crt =
NULL;
117 gnutls_x509_privkey_t
key =
NULL;
135 ret = gnutls_x509_privkey_init(&
key);
141 ret = gnutls_x509_crt_init(&crt);
147 tmp.data = key_bp.str;
148 tmp.size = key_bp.len;
149 ret = gnutls_x509_privkey_import(
key, &
tmp, GNUTLS_X509_FMT_PEM);
155 tmp.data = crt_bp.str;
156 tmp.size = crt_bp.len;
157 ret = gnutls_x509_crt_import(crt, &
tmp, GNUTLS_X509_FMT_PEM);
183 gnutls_x509_crt_deinit(crt);
185 gnutls_x509_privkey_deinit(
key);
193 ret = gnutls_x509_privkey_init(
key);
199 ret = gnutls_x509_privkey_generate(*
key, GNUTLS_PK_ECDSA,
200 gnutls_sec_param_to_pk_bits(GNUTLS_PK_ECDSA, GNUTLS_SEC_PARAM_MEDIUM), 0);
209 gnutls_x509_privkey_deinit(*
key);
219 unsigned char buf[8];
220 const char *dn =
"CN=lavf";
222 ret = gnutls_x509_crt_init(crt);
228 ret = gnutls_x509_crt_set_version(*crt, 3);
241 ret = gnutls_x509_crt_set_serial(*crt, buf,
sizeof(buf));
247 ret = gnutls_x509_crt_set_activation_time(*crt, time(
NULL));
253 ret = gnutls_x509_crt_set_expiration_time(*crt, time(
NULL) + 365 * 24 * 60 * 60);
259 ret = gnutls_x509_crt_set_dn(*crt, dn,
NULL);
265 ret = gnutls_x509_crt_set_issuer_dn(*crt, dn,
NULL);
271 ret = gnutls_x509_crt_set_key(*crt,
key);
277 ret = gnutls_x509_crt_sign2(*crt, *crt,
key, GNUTLS_DIG_SHA256, 0);
290 gnutls_x509_crt_deinit(*crt);
299 gnutls_x509_crt_t crt =
NULL;
300 gnutls_x509_privkey_t
key =
NULL;
327 gnutls_x509_crt_deinit(crt);
329 gnutls_x509_privkey_deinit(
key);
336 gnutls_certificate_credentials_t
cred;
348 #if HAVE_THREADS && GNUTLS_VERSION_NUMBER < 0x020b00
349 if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
350 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
352 gnutls_global_init();
359 gnutls_global_deinit();
381 ret = gnutls_srtp_get_keys(
c->session, dtls_srtp_materials, materials_sz,
NULL,
NULL,
NULL,
NULL);
395 case GNUTLS_E_INTERRUPTED:
396 #ifdef GNUTLS_E_PREMATURE_TERMINATION
397 case GNUTLS_E_PREMATURE_TERMINATION:
400 case GNUTLS_E_WARNING_ALERT_RECEIVED:
420 if (
c->need_shutdown)
421 gnutls_bye(
c->session, GNUTLS_SHUT_WR);
423 gnutls_deinit(
c->session);
425 gnutls_certificate_free_credentials(
c->cred);
426 if (!
s->external_sock)
433 void *buf,
size_t len)
440 if (
s->is_dtls &&
s->listen && !
c->dest_addr_len) {
465 const void *buf,
size_t len)
490 struct pollfd pfd = { .fd = sockfd, .events = POLLIN, .revents = 0 };
495 ret = poll(&pfd, 1, ms);
516 ret = gnutls_handshake(
c->session);
517 if (gnutls_error_is_fatal(
ret)) {
531 uint16_t gnutls_flags = 0;
532 gnutls_x509_crt_t cert =
NULL;
533 gnutls_x509_privkey_t pkey =
NULL;
538 if (!
s->external_sock) {
544 gnutls_flags |= GNUTLS_DATAGRAM;
547 gnutls_flags |= GNUTLS_SERVER;
549 gnutls_flags |= GNUTLS_CLIENT;
550 gnutls_init(&
c->session, gnutls_flags);
551 if (!
s->listen && !
s->numerichost)
552 gnutls_server_name_set(
c->session, GNUTLS_NAME_DNS,
s->host, strlen(
s->host));
553 gnutls_certificate_allocate_credentials(&
c->cred);
555 ret = gnutls_certificate_set_x509_trust_file(
c->cred,
s->ca_file, GNUTLS_X509_FMT_PEM);
559 #if GNUTLS_VERSION_NUMBER >= 0x030020
561 gnutls_certificate_set_x509_system_trust(
c->cred);
563 gnutls_certificate_set_verify_flags(
c->cred,
s->verify ?
564 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT : 0);
565 if (
s->cert_file &&
s->key_file) {
566 ret = gnutls_certificate_set_x509_key_file(
c->cred,
567 s->cert_file,
s->key_file,
568 GNUTLS_X509_FMT_PEM);
571 "Unable to set cert/key files %s and %s: %s\n",
572 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);
587 }
else if (
s->cert_buf ||
s->key_buf) {
591 if (
s->listen && !
s->cert_file && !
s->cert_buf && !
s->key_file && !
s->key_buf) {
602 ret = gnutls_certificate_set_x509_key(
c->cred, &cert, 1, pkey);
609 gnutls_credentials_set(
c->session, GNUTLS_CRD_CERTIFICATE,
c->cred);
612 gnutls_transport_set_ptr(
c->session,
c);
616 gnutls_dtls_set_mtu(
c->session,
s->mtu);
618 gnutls_set_default_priority(
c->session);
621 ret = gnutls_srtp_set_profile(
c->session, GNUTLS_SRTP_AES128_CM_HMAC_SHA1_80);
629 if (!
s->external_sock) {
634 c->need_shutdown = 1;
636 unsigned int status, cert_list_size;
637 gnutls_x509_crt_t cert;
638 const gnutls_datum_t *cert_list;
639 if ((
ret = gnutls_certificate_verify_peers2(
c->session, &
status)) < 0) {
641 gnutls_strerror(
ret));
645 if (
status & GNUTLS_CERT_INVALID) {
650 if (gnutls_certificate_type_get(
c->session) != GNUTLS_CRT_X509) {
655 gnutls_x509_crt_init(&cert);
656 cert_list = gnutls_certificate_get_peers(
c->session, &cert_list_size);
657 gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER);
658 ret = gnutls_x509_crt_check_hostname(cert,
s->host);
659 gnutls_x509_crt_deinit(cert);
662 "The certificate's owner does not match hostname %s\n",
s->host);
671 gnutls_x509_crt_deinit(cert);
673 gnutls_x509_privkey_deinit(pkey);
695 ret = gnutls_record_recv(
c->session, buf,
size);
712 ret = gnutls_record_send(
c->session, buf,
size);