+
+typedef int (*tls_prio_func) (gnutls_session_t, const int *);
+
+static int
+gnutls_SetPriority (vlc_object_t *restrict obj, const char *restrict name,
+ tls_prio_func func, gnutls_session_t session,
+ const int *restrict values)
+{
+ int val = func (session, values);
+ if (val < 0)
+ {
+ msg_Err (obj, "cannot set %s priorities: %s", name,
+ gnutls_strerror (val));
+ return VLC_EGENERIC;
+ }
+ return VLC_SUCCESS;
+}
+
+
+static int
+gnutls_SessionPrioritize (vlc_object_t *obj, gnutls_session_t session)
+{
+ /* Note that ordering matters (on the client side) */
+ static const int protos[] =
+ {
+ GNUTLS_TLS1_1,
+ GNUTLS_TLS1_0,
+ GNUTLS_SSL3,
+ 0
+ };
+ static const int comps[] =
+ {
+ GNUTLS_COMP_DEFLATE,
+ GNUTLS_COMP_NULL,
+ 0
+ };
+ static const int macs[] =
+ {
+ GNUTLS_MAC_SHA1,
+ GNUTLS_MAC_RMD160, // RIPEMD
+ GNUTLS_MAC_MD5,
+ //GNUTLS_MAC_MD2,
+ //GNUTLS_MAC_NULL,
+ 0
+ };
+ static const int ciphers[] =
+ {
+ GNUTLS_CIPHER_AES_256_CBC,
+ GNUTLS_CIPHER_AES_128_CBC,
+ GNUTLS_CIPHER_3DES_CBC,
+ GNUTLS_CIPHER_ARCFOUR_128,
+ //GNUTLS_CIPHER_DES_CBC,
+ //GNUTLS_CIPHER_ARCFOUR_40,
+ //GNUTLS_CIPHER_RC2_40_CBC,
+ //GNUTLS_CIPHER_NULL,
+ 0
+ };
+ static const int kx[] =
+ {
+ GNUTLS_KX_DHE_RSA,
+ GNUTLS_KX_DHE_DSS,
+ GNUTLS_KX_RSA,
+ //GNUTLS_KX_RSA_EXPORT,
+ //GNUTLS_KX_DHE_PSK, TODO
+ //GNUTLS_KX_PSK, TODO
+ //GNUTLS_KX_SRP_RSA, TODO
+ //GNUTLS_KX_SRP_DSS, TODO
+ //GNUTLS_KX_SRP, TODO
+ //GNUTLS_KX_ANON_DH,
+ 0
+ };
+ static const int cert_types[] =
+ {
+ GNUTLS_CRT_X509,
+ //GNUTLS_CRT_OPENPGP, TODO
+ 0
+ };
+
+ int val = gnutls_set_default_priority (session);
+ if (val < 0)
+ {
+ msg_Err (obj, "cannot set default TLS priorities: %s",
+ gnutls_strerror (val));
+ return VLC_EGENERIC;
+ }
+
+ if (gnutls_SetPriority (obj, "protocols",
+ gnutls_protocol_set_priority, session, protos)
+ || gnutls_SetPriority (obj, "compression algorithms",
+ gnutls_compression_set_priority, session, comps)
+ || gnutls_SetPriority (obj, "MAC algorithms",
+ gnutls_mac_set_priority, session, macs)
+ || gnutls_SetPriority (obj, "ciphers",
+ gnutls_cipher_set_priority, session, ciphers)
+ || gnutls_SetPriority (obj, "key exchange algorithms",
+ gnutls_kx_set_priority, session, kx)
+ || gnutls_SetPriority (obj, "certificate types",
+ gnutls_certificate_type_set_priority, session,
+ cert_types))
+ return VLC_EGENERIC;
+
+ return VLC_SUCCESS;
+}
+
+