mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-10-01 04:03:18 +03:00
407 lines
13 KiB
C
407 lines
13 KiB
C
/*
|
|
* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation
|
|
*
|
|
* Author: Nikos Mavrogiannopoulos
|
|
*
|
|
* This file is part of GNUTLS.
|
|
*
|
|
* The GNUTLS library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation; either version 2.1 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
* USA
|
|
*
|
|
*/
|
|
|
|
/* Here lies the code of the gnutls_*_set_priority() functions.
|
|
*/
|
|
|
|
#include "gnutls_int.h"
|
|
#include "gnutls_algorithms.h"
|
|
#include "gnutls_errors.h"
|
|
#include <gnutls_num.h>
|
|
|
|
#define MAX_ELEMENTS 48
|
|
|
|
/**
|
|
* MHD_gnutls_cipher_set_priority - Sets the priority on the ciphers supported by gnutls.
|
|
* @session: is a #mhd_gtls_session_t structure.
|
|
* @list: is a 0 terminated list of enum MHD_GNUTLS_CipherAlgorithm elements.
|
|
*
|
|
* Sets the priority on the ciphers supported by gnutls.
|
|
* Priority is higher for elements specified before others.
|
|
* After specifying the ciphers you want, you must append a 0.
|
|
* Note that the priority is set on the client. The server does
|
|
* not use the algorithm's priority except for disabling
|
|
* algorithms that were not specified.
|
|
*
|
|
* Returns 0 on success.
|
|
*
|
|
**/
|
|
int
|
|
MHD_gnutls_cipher_set_priority (mhd_gtls_session_t session, const int *list)
|
|
{
|
|
int num = 0, i;
|
|
|
|
while (list[num] != 0)
|
|
num++;
|
|
if (num > MAX_ALGOS)
|
|
num = MAX_ALGOS;
|
|
session->internals.priorities.cipher.num_algorithms = num;
|
|
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
session->internals.priorities.cipher.priority[i] = list[i];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
inline static int
|
|
_set_priority (mhd_gtls_priority_st * st, const int *list)
|
|
{
|
|
int num = 0, i;
|
|
|
|
while (list[num] != 0)
|
|
num++;
|
|
if (num > MAX_ALGOS)
|
|
num = MAX_ALGOS;
|
|
st->num_algorithms = num;
|
|
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
st->priority[i] = list[i];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* MHD_gnutls_kx_set_priority - Sets the priority on the key exchange algorithms supported by gnutls.
|
|
* @session: is a #mhd_gtls_session_t structure.
|
|
* @list: is a 0 terminated list of enum MHD_GNUTLS_KeyExchangeAlgorithm elements.
|
|
*
|
|
* Sets the priority on the key exchange algorithms supported by gnutls.
|
|
* Priority is higher for elements specified before others.
|
|
* After specifying the algorithms you want, you must append a 0.
|
|
* Note that the priority is set on the client. The server does
|
|
* not use the algorithm's priority except for disabling
|
|
* algorithms that were not specified.
|
|
*
|
|
* Returns 0 on success.
|
|
*
|
|
**/
|
|
int
|
|
MHD_gnutls_kx_set_priority (mhd_gtls_session_t session, const int *list)
|
|
{
|
|
return _set_priority (&session->internals.priorities.kx, list);
|
|
}
|
|
|
|
/**
|
|
* MHD_gnutls_mac_set_priority - Sets the priority on the mac algorithms supported by gnutls.
|
|
* @session: is a #mhd_gtls_session_t structure.
|
|
* @list: is a 0 terminated list of enum MHD_GNUTLS_HashAlgorithm elements.
|
|
*
|
|
* Sets the priority on the mac algorithms supported by gnutls.
|
|
* Priority is higher for elements specified before others.
|
|
* After specifying the algorithms you want, you must append a 0.
|
|
* Note that the priority is set on the client. The server does
|
|
* not use the algorithm's priority except for disabling
|
|
* algorithms that were not specified.
|
|
*
|
|
* Returns 0 on success.
|
|
*
|
|
**/
|
|
int
|
|
MHD_gnutls_mac_set_priority (mhd_gtls_session_t session, const int *list)
|
|
{
|
|
return _set_priority (&session->internals.priorities.mac, list);
|
|
}
|
|
|
|
/**
|
|
* MHD_gnutls_compression_set_priority - Sets the priority on the compression algorithms supported by gnutls.
|
|
* @session: is a #mhd_gtls_session_t structure.
|
|
* @list: is a 0 terminated list of enum MHD_GNUTLS_CompressionMethod elements.
|
|
*
|
|
* Sets the priority on the compression algorithms supported by gnutls.
|
|
* Priority is higher for elements specified before others.
|
|
* After specifying the algorithms you want, you must append a 0.
|
|
* Note that the priority is set on the client. The server does
|
|
* not use the algorithm's priority except for disabling
|
|
* algorithms that were not specified.
|
|
*
|
|
* TLS 1.0 does not define any compression algorithms except
|
|
* NULL. Other compression algorithms are to be considered
|
|
* as gnutls extensions.
|
|
*
|
|
* Returns 0 on success.
|
|
*
|
|
**/
|
|
int
|
|
MHD_gnutls_compression_set_priority (mhd_gtls_session_t session,
|
|
const int *list)
|
|
{
|
|
return _set_priority (&session->internals.priorities.compression, list);
|
|
}
|
|
|
|
/**
|
|
* MHD_gnutls_protocol_set_priority - Sets the priority on the protocol versions supported by gnutls.
|
|
* @session: is a #mhd_gtls_session_t structure.
|
|
* @list: is a 0 terminated list of enum MHD_GNUTLS_Protocol elements.
|
|
*
|
|
* Sets the priority on the protocol versions supported by gnutls.
|
|
* This function actually enables or disables protocols. Newer protocol
|
|
* versions always have highest priority.
|
|
*
|
|
* Returns 0 on success.
|
|
*
|
|
**/
|
|
int
|
|
MHD_gnutls_protocol_set_priority (mhd_gtls_session_t session, const int *list)
|
|
{
|
|
int ret;
|
|
|
|
ret = _set_priority (&session->internals.priorities.protocol, list);
|
|
/* set the current version to the first in the chain.
|
|
* This will be overridden later.
|
|
*/
|
|
mhd_gtls_set_current_version (session, list[0]);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* MHD_gnutls_certificate_type_set_priority - Sets the priority on the certificate types supported by gnutls.
|
|
* @session: is a #mhd_gtls_session_t structure.
|
|
* @list: is a 0 terminated list of enum MHD_GNUTLS_CertificateType elements.
|
|
*
|
|
* Sets the priority on the certificate types supported by gnutls.
|
|
* Priority is higher for elements specified before others.
|
|
* After specifying the types you want, you must append a 0.
|
|
* Note that the certificate type priority is set on the client.
|
|
* The server does not use the cert type priority except for disabling
|
|
* types that were not specified.
|
|
*
|
|
* Returns 0 on success.
|
|
*
|
|
**/
|
|
int
|
|
MHD_gnutls_certificate_type_set_priority (mhd_gtls_session_t session,
|
|
const int *list)
|
|
{
|
|
#if ENABLE_OPENPGP
|
|
return _set_priority (&session->internals.priorities.cert_type, list);
|
|
#else
|
|
|
|
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
|
|
|
|
#endif
|
|
}
|
|
|
|
static const int mhd_gtls_protocol_priority[] = { MHD_GNUTLS_TLS1_1,
|
|
MHD_GNUTLS_TLS1_0,
|
|
MHD_GNUTLS_SSL3,
|
|
0
|
|
};
|
|
|
|
static const int mhd_gtls_cipher_priority_secure256[] =
|
|
{ MHD_GNUTLS_CIPHER_AES_256_CBC,
|
|
0
|
|
};
|
|
|
|
static const int mhd_gtls_kx_priority_secure[] = { MHD_GNUTLS_KX_RSA,
|
|
0
|
|
};
|
|
|
|
static const int mhd_gtls_mac_priority_secure[] = { MHD_GNUTLS_MAC_SHA1,
|
|
0
|
|
};
|
|
|
|
static int mhd_gtls_cert_type_priority[] = { MHD_GNUTLS_CRT_X509,
|
|
0
|
|
};
|
|
|
|
static const int mhd_gtls_comp_priority[] = { MHD_GNUTLS_COMP_NULL,
|
|
0
|
|
};
|
|
|
|
typedef void (rmadd_func) (mhd_gtls_priority_st * priority_list, int alg);
|
|
|
|
/**
|
|
* MHD_gnutls_priority_set - Sets priorities for the cipher suites supported by gnutls.
|
|
* @session: is a #mhd_gtls_session_t structure.
|
|
* @priority: is a #gnutls_priority_t structure.
|
|
*
|
|
* Sets the priorities to use on the ciphers, key exchange methods,
|
|
* macs and compression methods.
|
|
*
|
|
* On success 0 is returned.
|
|
*
|
|
**/
|
|
int
|
|
MHD_gnutls_priority_set (mhd_gtls_session_t session,
|
|
gnutls_priority_t priority)
|
|
{
|
|
if (priority == NULL)
|
|
{
|
|
gnutls_assert ();
|
|
return GNUTLS_E_NO_CIPHER_SUITES;
|
|
}
|
|
|
|
memcpy (&session->internals.priorities, priority,
|
|
sizeof (struct MHD_gtls_priority_st));
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* MHD_tls_set_default_priority - Sets priorities for the cipher suites supported by gnutls.
|
|
* @priority_cache: is a #gnutls_prioritity_t structure.
|
|
* @priorities: is a string describing priorities
|
|
* @err_pos: In case of an error this will have the position in the string the error occured
|
|
*
|
|
* Sets priorities for the ciphers, key exchange methods, macs and
|
|
* compression methods. This is to avoid using the
|
|
* gnutls_*_priority() functions.
|
|
*
|
|
* The #priorities option allows you to specify a semi-colon
|
|
* separated list of the cipher priorities to enable.
|
|
*
|
|
* Unless the first keyword is "NONE" the defaults are:
|
|
* Protocols: TLS1.1, TLS1.0, and SSL3.0.
|
|
* Compression: NULL.
|
|
* Certificate types: X.509, OpenPGP.
|
|
*
|
|
* You can also use predefined sets of ciphersuites: "PERFORMANCE"
|
|
* all the "secure" ciphersuites are enabled, limited to 128 bit
|
|
* ciphers and sorted by terms of speed performance.
|
|
*
|
|
* "NORMAL" option enables all "secure" ciphersuites. The 256-bit ciphers
|
|
* are included as a fallback only. The ciphers are sorted by security margin.
|
|
*
|
|
* "SECURE128" flag enables all "secure" ciphersuites with ciphers up to
|
|
* 128 bits, sorted by security margin.
|
|
*
|
|
* "SECURE256" flag enables all "secure" ciphersuites including the 256 bit
|
|
* ciphers, sorted by security margin.
|
|
*
|
|
* "EXPORT" all the ciphersuites are enabled, including the
|
|
* low-security 40 bit ciphers.
|
|
*
|
|
* "NONE" nothing is enabled. This disables even protocols and
|
|
* compression methods.
|
|
*
|
|
* Special keywords:
|
|
* '!' or '-' appended with an algorithm will remove this algorithm.
|
|
* '+' appended with an algorithm will add this algorithm.
|
|
* '%COMPAT' will enable compatibility features for a server.
|
|
*
|
|
* To avoid collisions in order to specify a compression algorithm in
|
|
* this string you have to prefix it with "COMP-", protocol versions
|
|
* with "VERS-" and certificate types with "CTYPE-". All other
|
|
* algorithms don't need a prefix.
|
|
*
|
|
* For key exchange algorithms when in NORMAL or SECURE levels the
|
|
* perfect forward secrecy algorithms take precendence of the other
|
|
* protocols. In all cases all the supported key exchange algorithms
|
|
* are enabled (except for the RSA-EXPORT which is only enabled in
|
|
* EXPORT level).
|
|
*
|
|
* Note that although one can select very long key sizes (such as 256 bits)
|
|
* for symmetric algorithms, to actually increase security the public key
|
|
* algorithms have to use longer key sizes as well.
|
|
*
|
|
* Examples: "NORMAL:!AES-128-CBC",
|
|
* "EXPORT:!VERS-TLS1.0:+COMP-DEFLATE:+CTYPE-OPENPGP",
|
|
* "NONE:+VERS-TLS1.0:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL", "NORMAL",
|
|
* "NORMAL:%COMPAT".
|
|
*
|
|
* Returns: On syntax error GNUTLS_E_INVALID_REQUEST is returned and
|
|
* 0 on success.
|
|
**/
|
|
int
|
|
MHD_tls_set_default_priority (gnutls_priority_t * priority_cache,
|
|
const char *priorities, const char **err_pos)
|
|
{
|
|
*priority_cache = gnutls_calloc (1, sizeof (struct MHD_gtls_priority_st));
|
|
if (*priority_cache == NULL)
|
|
{
|
|
gnutls_assert ();
|
|
return GNUTLS_E_MEMORY_ERROR;
|
|
}
|
|
|
|
/* set mode to "SECURE256" */
|
|
_set_priority (&(*priority_cache)->protocol, mhd_gtls_protocol_priority);
|
|
_set_priority (&(*priority_cache)->cipher,
|
|
mhd_gtls_cipher_priority_secure256);
|
|
_set_priority (&(*priority_cache)->kx, mhd_gtls_kx_priority_secure);
|
|
_set_priority (&(*priority_cache)->mac, mhd_gtls_mac_priority_secure);
|
|
_set_priority (&(*priority_cache)->cert_type, mhd_gtls_cert_type_priority);
|
|
_set_priority (&(*priority_cache)->compression, mhd_gtls_comp_priority);
|
|
|
|
(*priority_cache)->no_padding = 0;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* MHD_gnutls_priority_deinit - Deinitialize the priorities cache for the cipher suites supported by gnutls.
|
|
* @priority_cache: is a #gnutls_prioritity_t structure.
|
|
*
|
|
* Deinitializes the priority cache.
|
|
*
|
|
**/
|
|
void
|
|
MHD_gnutls_priority_deinit (gnutls_priority_t priority_cache)
|
|
{
|
|
gnutls_free (priority_cache);
|
|
}
|
|
|
|
/**
|
|
* MHD_gnutls_priority_set_direct - Sets priorities for the cipher suites supported by gnutls.
|
|
* @session: is a #mhd_gtls_session_t structure.
|
|
* @priorities: is a string describing priorities
|
|
* @err_pos: In case of an error this will have the position in the string the error occured
|
|
*
|
|
* Sets the priorities to use on the ciphers, key exchange methods,
|
|
* macs and compression methods. This function avoids keeping a
|
|
* priority cache and is used to directly set string priorities to a
|
|
* TLS session. For documentation check the MHD_tls_set_default_priority().
|
|
*
|
|
* On syntax error GNUTLS_E_INVALID_REQUEST is returned and 0 on success.
|
|
*
|
|
**/
|
|
int
|
|
MHD_gnutls_priority_set_direct (mhd_gtls_session_t session,
|
|
const char *priorities, const char **err_pos)
|
|
{
|
|
gnutls_priority_t prio;
|
|
int ret;
|
|
|
|
ret = MHD_tls_set_default_priority (&prio, priorities, err_pos);
|
|
if (ret < 0)
|
|
{
|
|
gnutls_assert ();
|
|
return ret;
|
|
}
|
|
|
|
ret = MHD_gnutls_priority_set (session, prio);
|
|
if (ret < 0)
|
|
{
|
|
gnutls_assert ();
|
|
return ret;
|
|
}
|
|
|
|
MHD_gnutls_priority_deinit (prio);
|
|
|
|
return 0;
|
|
}
|