28 #include <gnutls/gnutls.h> 
   29 #include <gnutls/x509.h> 
   30 #define TLS_read(c, buf, size)  gnutls_record_recv(c->session, buf, size) 
   31 #define TLS_write(c, buf, size) gnutls_record_send(c->session, buf, size) 
   32 #define TLS_shutdown(c)         gnutls_bye(c->session, GNUTLS_SHUT_RDWR) 
   33 #define TLS_free(c) do { \ 
   35             gnutls_deinit(c->session); \ 
   37             gnutls_certificate_free_credentials(c->cred); \ 
   40 #include <openssl/bio.h> 
   41 #include <openssl/ssl.h> 
   42 #include <openssl/err.h> 
   43 #define TLS_read(c, buf, size)  SSL_read(c->ssl,  buf, size) 
   44 #define TLS_write(c, buf, size) SSL_write(c->ssl, buf, size) 
   45 #define TLS_shutdown(c)         SSL_shutdown(c->ssl) 
   46 #define TLS_free(c) do { \ 
   50             SSL_CTX_free(c->ctx); \ 
   64     gnutls_session_t session;
 
   65     gnutls_certificate_credentials_t cred;
 
   78 #define OFFSET(x) offsetof(TLSContext, x) 
   79 #define D AV_OPT_FLAG_DECODING_PARAM 
   80 #define E AV_OPT_FLAG_ENCODING_PARAM 
   84     {
"tls_verify", 
"Verify the peer certificate",         
OFFSET(verify),    
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = 
D|
E },
 
   87     {
"listen",     
"Listen for incoming connections",     
OFFSET(listen),    
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = 
D|
E },
 
  101     struct pollfd p = { c->
fd, 0, 0 };
 
  105     case GNUTLS_E_INTERRUPTED:
 
  107     case GNUTLS_E_WARNING_ALERT_RECEIVED:
 
  114     if (gnutls_record_get_direction(c->session))
 
  119     ret = SSL_get_error(c->ssl, ret);
 
  120     if (ret == SSL_ERROR_WANT_READ) {
 
  122     } 
else if (ret == SSL_ERROR_WANT_WRITE) {
 
  132         int n = poll(&p, 1, 100);
 
  145     const char *p = strchr(uri, 
'?');
 
  154         c->
verify = strtol(buf, &endptr, 10);
 
  171     char buf[200], host[200], opts[50] = 
"";
 
  173     struct addrinfo hints = { 0 }, *ai = NULL;
 
  174     const char *proxy_path;
 
  176     const char *p = strchr(uri, 
'?');
 
  183         snprintf(opts, 
sizeof(opts), 
"?listen=1");
 
  185     av_url_split(NULL, 0, NULL, 0, host, 
sizeof(host), &port, NULL, 0, uri);
 
  186     ff_url_join(buf, 
sizeof(buf), 
"tcp", NULL, host, port, 
"%s", opts);
 
  194     proxy_path = getenv(
"http_proxy");
 
  196                 proxy_path != NULL && 
av_strstart(proxy_path, 
"http://", NULL);
 
  199         char proxy_host[200], proxy_auth[200], dest[200];
 
  202                      proxy_host, 
sizeof(proxy_host), &proxy_port, NULL, 0,
 
  204         ff_url_join(dest, 
sizeof(dest), NULL, NULL, host, port, NULL);
 
  205         ff_url_join(buf, 
sizeof(buf), 
"httpproxy", proxy_auth, proxy_host,
 
  206                     proxy_port, 
"/%s", dest);
 
  216     gnutls_init(&c->session, c->
listen ? GNUTLS_SERVER : GNUTLS_CLIENT);
 
  217     if (!c->
listen && !numerichost)
 
  218         gnutls_server_name_set(c->session, GNUTLS_NAME_DNS, host, strlen(host));
 
  219     gnutls_certificate_allocate_credentials(&c->cred);
 
  222         ret = gnutls_certificate_set_x509_trust_file(c->cred, c->
ca_file, GNUTLS_X509_FMT_PEM);
 
  226 #if GNUTLS_VERSION_MAJOR >= 3 
  228         gnutls_certificate_set_x509_system_trust(c->cred);
 
  230     gnutls_certificate_set_verify_flags(c->cred, c->
verify ?
 
  231                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT : 0);
 
  233         ret = gnutls_certificate_set_x509_key_file(c->cred,
 
  235                                                    GNUTLS_X509_FMT_PEM);
 
  238                    "Unable to set cert/key files %s and %s: %s\n",
 
  245     gnutls_credentials_set(c->session, GNUTLS_CRD_CERTIFICATE, c->cred);
 
  246     gnutls_transport_set_ptr(c->session, (gnutls_transport_ptr_t)
 
  248     gnutls_priority_set_direct(c->session, 
"NORMAL", NULL);
 
  250         ret = gnutls_handshake(c->session);
 
  257         unsigned int status, cert_list_size;
 
  258         gnutls_x509_crt_t cert;
 
  259         const gnutls_datum_t *cert_list;
 
  260         if ((ret = gnutls_certificate_verify_peers2(c->session, &status)) < 0) {
 
  262                                     gnutls_strerror(ret));
 
  266         if (status & GNUTLS_CERT_INVALID) {
 
  271         if (gnutls_certificate_type_get(c->session) != GNUTLS_CRT_X509) {
 
  276         gnutls_x509_crt_init(&cert);
 
  277         cert_list = gnutls_certificate_get_peers(c->session, &cert_list_size);
 
  278         gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER);
 
  279         ret = gnutls_x509_crt_check_hostname(cert, host);
 
  280         gnutls_x509_crt_deinit(cert);
 
  283                    "The certificate's owner does not match hostname %s\n", host);
 
  289     c->ctx = SSL_CTX_new(c->
listen ? TLSv1_server_method() : TLSv1_client_method());
 
  297         if (!SSL_CTX_load_verify_locations(c->ctx, c->
ca_file, NULL))
 
  298             av_log(h, 
AV_LOG_ERROR, 
"SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL));
 
  302                c->
cert_file, ERR_error_string(ERR_get_error(), NULL));
 
  306     if (c->
key_file && !SSL_CTX_use_PrivateKey_file(c->ctx, c->
key_file, SSL_FILETYPE_PEM)) {
 
  308                c->
key_file, ERR_error_string(ERR_get_error(), NULL));
 
  315         SSL_CTX_set_verify(c->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
 
  316     c->ssl = SSL_new(c->ctx);
 
  322     SSL_set_fd(c->ssl, c->
fd);
 
  323     if (!c->
listen && !numerichost)
 
  324         SSL_set_tlsext_host_name(c->ssl, host);
 
  326         ret = c->
listen ? SSL_accept(c->ssl) : SSL_connect(c->ssl);
 
  351         int ret = TLS_read(c, buf, size);
 
  366         int ret = TLS_write(c, buf, size);
 
  395     .priv_data_class = &tls_class,