aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/tls/gnutls_algorithms.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/tls/gnutls_algorithms.c')
-rw-r--r--src/daemon/https/tls/gnutls_algorithms.c469
1 files changed, 0 insertions, 469 deletions
diff --git a/src/daemon/https/tls/gnutls_algorithms.c b/src/daemon/https/tls/gnutls_algorithms.c
index 02be3637..876d860c 100644
--- a/src/daemon/https/tls/gnutls_algorithms.c
+++ b/src/daemon/https/tls/gnutls_algorithms.c
@@ -54,15 +54,6 @@ static const MHD_gnutls_cred_map MHD_gtls_cred_mappings[] = {
54 {MHD_GNUTLS_KX_DHE_RSA, 54 {MHD_GNUTLS_KX_DHE_RSA,
55 MHD_GNUTLS_CRD_CERTIFICATE, 55 MHD_GNUTLS_CRD_CERTIFICATE,
56 MHD_GNUTLS_CRD_CERTIFICATE}, 56 MHD_GNUTLS_CRD_CERTIFICATE},
57 {MHD_GNUTLS_KX_SRP,
58 MHD_GNUTLS_CRD_SRP,
59 MHD_GNUTLS_CRD_SRP},
60 {MHD_GNUTLS_KX_SRP_RSA,
61 MHD_GNUTLS_CRD_SRP,
62 MHD_GNUTLS_CRD_CERTIFICATE},
63 {MHD_GNUTLS_KX_SRP_DSS,
64 MHD_GNUTLS_CRD_SRP,
65 MHD_GNUTLS_CRD_CERTIFICATE},
66 {0, 57 {0,
67 0, 58 0,
68 0} 59 0}
@@ -423,17 +414,6 @@ static const MHD_gtls_kx_algo_entry_t MHD_gtls_kx_algorithms[] = {
423 &MHD_gtls_dhe_dss_auth_struct, 414 &MHD_gtls_dhe_dss_auth_struct,
424 1, 415 1,
425 0}, 416 0},
426
427#ifdef ENABLE_SRP
428 {"SRP-DSS", MHD_GNUTLS_KX_SRP_DSS, &srp_dss_auth_struct, 0, 0},
429 {"SRP-RSA", MHD_GNUTLS_KX_SRP_RSA, &srp_rsa_auth_struct, 0, 0},
430 {"SRP", MHD_GNUTLS_KX_SRP, &srp_auth_struct, 0, 0},
431#endif
432#ifdef ENABLE_PSK
433 {"PSK", GNUTLS_KX_PSK, &psk_auth_struct, 0, 0},
434 {"DHE-PSK", GNUTLS_KX_DHE_PSK, &dhe_psk_auth_struct,
435 1 /* needs DHE params */ , 0},
436#endif
437 {0, 417 {0,
438 0, 418 0,
439 0, 419 0,
@@ -448,15 +428,6 @@ static const enum MHD_GNUTLS_KeyExchangeAlgorithm MHD_gtls_supported_kxs[] =
448 MHD_GNUTLS_KX_RSA_EXPORT, 428 MHD_GNUTLS_KX_RSA_EXPORT,
449 MHD_GNUTLS_KX_DHE_RSA, 429 MHD_GNUTLS_KX_DHE_RSA,
450 MHD_GNUTLS_KX_DHE_DSS, 430 MHD_GNUTLS_KX_DHE_DSS,
451#ifdef ENABLE_SRP
452 MHD_GNUTLS_KX_SRP_DSS,
453 MHD_GNUTLS_KX_SRP_RSA,
454 MHD_GNUTLS_KX_SRP,
455#endif
456#ifdef ENABLE_PSK
457 GNUTLS_KX_PSK,
458 GNUTLS_KX_DHE_PSK,
459#endif
460 0 431 0
461}; 432};
462 433
@@ -728,105 +699,6 @@ MHD_gtls_mac_priority (MHD_gtls_session_t session,
728 return -1; 699 return -1;
729} 700}
730 701
731/**
732 * MHD__gnutls_mac_get_name - Returns a string with the name of the specified mac algorithm
733 * @algorithm: is a MAC algorithm
734 *
735 * Returns: a string that contains the name of the specified MAC
736 * algorithm, or %NULL.
737 **/
738const char *
739MHD__gnutls_mac_get_name (enum MHD_GNUTLS_HashAlgorithm algorithm)
740{
741 const char *ret = NULL;
742
743 /* avoid prefix */
744 GNUTLS_HASH_ALG_LOOP (ret = p->name);
745
746 return ret;
747}
748
749/**
750 * MHD_gtls_mac_get_id - Returns the gnutls id of the specified in string algorithm
751 * @algorithm: is a MAC algorithm name
752 *
753 * Returns: an %enum MHD_GNUTLS_HashAlgorithmid of the specified in a string
754 * MAC algorithm, or %GNUTLS_MAC_UNKNOWN on failures. The names are
755 * compared in a case insensitive way.
756 **/
757enum MHD_GNUTLS_HashAlgorithm
758MHD_gtls_mac_get_id (const char *name)
759{
760 enum MHD_GNUTLS_HashAlgorithm ret = MHD_GNUTLS_MAC_UNKNOWN;
761
762 GNUTLS_HASH_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id)
763 ;
764
765 return ret;
766}
767
768/**
769 * MHD__gnutls_mac_get_key_size - Returns the length of the MAC's key size
770 * @algorithm: is an encryption algorithm
771 *
772 * Returns: length (in bytes) of the given MAC key size, or 0 if the
773 * given MAC algorithm is invalid.
774 *
775 **/
776size_t
777MHD__gnutls_mac_get_key_size (enum MHD_GNUTLS_HashAlgorithm algorithm)
778{
779 size_t ret = 0;
780
781 /* avoid prefix */
782 GNUTLS_HASH_ALG_LOOP (ret = p->key_size);
783
784 return ret;
785}
786
787/**
788 * MHD_gtls_mac_list:
789 *
790 * Get a list of hash algorithms for use as MACs. Note that not
791 * necessarily all MACs are supported in TLS cipher suites. For
792 * example, MD2 is not supported as a cipher suite, but is supported
793 * for other purposes (e.g., X.509 signature verification or similar).
794 *
795 * Returns: Return a zero-terminated list of %enum MHD_GNUTLS_HashAlgorithm
796 * integers indicating the available MACs.
797 **/
798const enum MHD_GNUTLS_HashAlgorithm *
799MHD_gtls_mac_list (void)
800{
801 return MHD_gtls_supported_macs;
802}
803
804const char *
805MHD_gtls_x509_mac_to_oid (enum MHD_GNUTLS_HashAlgorithm algorithm)
806{
807 const char *ret = NULL;
808
809 /* avoid prefix */
810 GNUTLS_HASH_ALG_LOOP (ret = p->oid);
811
812 return ret;
813}
814
815enum MHD_GNUTLS_HashAlgorithm
816MHD_gtls_x509_oid2mac_algorithm (const char *oid)
817{
818 enum MHD_GNUTLS_HashAlgorithm ret = 0;
819
820 GNUTLS_HASH_LOOP (if (p->oid && strcmp (oid, p->oid) == 0)
821 {
822 ret = p->id; break;}
823 )
824 ;
825
826 if (ret == 0)
827 return MHD_GNUTLS_MAC_UNKNOWN;
828 return ret;
829}
830 702
831int 703int
832MHD_gnutls_mac_is_ok (enum MHD_GNUTLS_HashAlgorithm algorithm) 704MHD_gnutls_mac_is_ok (enum MHD_GNUTLS_HashAlgorithm algorithm)
@@ -840,20 +712,6 @@ MHD_gnutls_mac_is_ok (enum MHD_GNUTLS_HashAlgorithm algorithm)
840 return ret; 712 return ret;
841} 713}
842 714
843/* Compression Functions */
844int
845MHD_gtls_compression_priority (MHD_gtls_session_t session,
846 enum MHD_GNUTLS_CompressionMethod algorithm)
847{ /* actually returns the priority */
848 unsigned int i;
849 for (i = 0; i < session->internals.priorities.compression.num_algorithms;
850 i++)
851 {
852 if (session->internals.priorities.compression.priority[i] == algorithm)
853 return i;
854 }
855 return -1;
856}
857 715
858/** 716/**
859 * MHD__gnutls_compression_get_name - Returns a string with the name of the specified compression algorithm 717 * MHD__gnutls_compression_get_name - Returns a string with the name of the specified compression algorithm
@@ -897,21 +755,6 @@ MHD_gtls_compression_get_id (const char *name)
897 return ret; 755 return ret;
898} 756}
899 757
900/**
901 * MHD_gtls_compression_list:
902 *
903 * Get a list of compression methods. Note that to be able to use LZO
904 * compression, you must link to libgnutls-extra and call
905 * MHD_gnutls_global_init_extra().
906 *
907 * Returns: a zero-terminated list of %enum MHD_GNUTLS_CompressionMethod
908 * integers indicating the available compression methods.
909 **/
910const enum MHD_GNUTLS_CompressionMethod *
911MHD_gtls_compression_list (void)
912{
913 return MHD_gtls_supported_compressions;
914}
915 758
916/* return the tls number of the specified algorithm */ 759/* return the tls number of the specified algorithm */
917int 760int
@@ -1048,62 +891,6 @@ MHD_gtls_cipher_get_export_flag (enum MHD_GNUTLS_CipherAlgorithm algorithm)
1048 891
1049} 892}
1050 893
1051/**
1052 * MHD__gnutls_cipher_get_name - Returns a string with the name of the specified cipher algorithm
1053 * @algorithm: is an encryption algorithm
1054 *
1055 * Returns: a pointer to a string that contains the name of the
1056 * specified cipher, or %NULL.
1057 **/
1058const char *
1059MHD__gnutls_cipher_get_name (enum MHD_GNUTLS_CipherAlgorithm algorithm)
1060{
1061 const char *ret = NULL;
1062
1063 /* avoid prefix */
1064 GNUTLS_ALG_LOOP (ret = p->name);
1065
1066 return ret;
1067}
1068
1069/**
1070 * MHD_gtls_cipher_get_id - Returns the gnutls id of the specified in string algorithm
1071 * @algorithm: is a MAC algorithm name
1072 *
1073 * The names are compared in a case insensitive way.
1074 *
1075 * Returns: an id of the specified cipher, or %GNUTLS_CIPHER_UNKNOWN
1076 * on error.
1077 *
1078 **/
1079enum MHD_GNUTLS_CipherAlgorithm
1080MHD_gtls_cipher_get_id (const char *name)
1081{
1082 enum MHD_GNUTLS_CipherAlgorithm ret = MHD_GNUTLS_CIPHER_UNKNOWN;
1083
1084 GNUTLS_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id)
1085 ;
1086
1087 return ret;
1088}
1089
1090/**
1091 * MHD_gtls_cipher_list:
1092 *
1093 * Get a list of supported cipher algorithms. Note that not
1094 * necessarily all ciphers are supported as TLS cipher suites. For
1095 * example, DES is not supported as a cipher suite, but is supported
1096 * for other purposes (e.g., PKCS#8 or similar).
1097 *
1098 * Returns: a zero-terminated list of %enum MHD_GNUTLS_CipherAlgorithm
1099 * integers indicating the available ciphers.
1100 *
1101 **/
1102const enum MHD_GNUTLS_CipherAlgorithm *
1103MHD_gtls_cipher_list (void)
1104{
1105 return MHD_gtls_supported_ciphers;
1106}
1107 894
1108int 895int
1109MHD_gtls_cipher_is_ok (enum MHD_GNUTLS_CipherAlgorithm algorithm) 896MHD_gtls_cipher_is_ok (enum MHD_GNUTLS_CipherAlgorithm algorithm)
@@ -1140,57 +927,6 @@ MHD_gtls_kx_priority (MHD_gtls_session_t session,
1140 return -1; 927 return -1;
1141} 928}
1142 929
1143/**
1144 * MHD__gnutls_kx_get_name - Returns a string with the name of the specified key exchange algorithm
1145 * @algorithm: is a key exchange algorithm
1146 *
1147 * Returns: a pointer to a string that contains the name of the
1148 * specified key exchange algorithm, or %NULL.
1149 **/
1150const char *
1151MHD__gnutls_kx_get_name (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm)
1152{
1153 const char *ret = NULL;
1154
1155 /* avoid prefix */
1156 GNUTLS_KX_ALG_LOOP (ret = p->name);
1157
1158 return ret;
1159}
1160
1161/**
1162 * MHD_gtls_kx_get_id - Returns the gnutls id of the specified in string algorithm
1163 * @algorithm: is a KX name
1164 *
1165 * The names are compared in a case insensitive way.
1166 *
1167 * Returns: an id of the specified KX algorithm, or
1168 * %GNUTLS_KX_UNKNOWN on error.
1169 **/
1170enum MHD_GNUTLS_KeyExchangeAlgorithm
1171MHD_gtls_kx_get_id (const char *name)
1172{
1173 enum MHD_GNUTLS_CipherAlgorithm ret = MHD_GNUTLS_KX_UNKNOWN;
1174
1175 GNUTLS_KX_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->algorithm)
1176 ;
1177
1178 return ret;
1179}
1180
1181/**
1182 * MHD_gtls_kx_list:
1183 *
1184 * Get a list of supported key exchange algorithms.
1185 *
1186 * Returns: a zero-terminated list of %enum MHD_GNUTLS_KeyExchangeAlgorithm integers
1187 * indicating the available key exchange algorithms.
1188 **/
1189const enum MHD_GNUTLS_KeyExchangeAlgorithm *
1190MHD_gtls_kx_list (void)
1191{
1192 return MHD_gtls_supported_kxs;
1193}
1194 930
1195int 931int
1196MHD_gtls_kx_is_ok (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm) 932MHD_gtls_kx_is_ok (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm)
@@ -1241,28 +977,6 @@ MHD_gtls_version_priority (MHD_gtls_session_t session,
1241 return -1; 977 return -1;
1242} 978}
1243 979
1244enum MHD_GNUTLS_Protocol
1245MHD_gtls_version_lowest (MHD_gtls_session_t session)
1246{ /* returns the lowest version supported */
1247 unsigned int i, min = 0xff;
1248
1249 if (session->internals.priorities.protocol.priority == NULL)
1250 {
1251 return MHD_GNUTLS_PROTOCOL_VERSION_UNKNOWN;
1252 }
1253 else
1254 for (i = 0; i < session->internals.priorities.protocol.num_algorithms;
1255 i++)
1256 {
1257 if (session->internals.priorities.protocol.priority[i] < min)
1258 min = session->internals.priorities.protocol.priority[i];
1259 }
1260
1261 if (min == 0xff)
1262 return MHD_GNUTLS_PROTOCOL_VERSION_UNKNOWN; /* unknown version */
1263
1264 return min;
1265}
1266 980
1267enum MHD_GNUTLS_Protocol 981enum MHD_GNUTLS_Protocol
1268MHD_gtls_version_max (MHD_gtls_session_t session) 982MHD_gtls_version_max (MHD_gtls_session_t session)
@@ -1287,58 +1001,6 @@ MHD_gtls_version_max (MHD_gtls_session_t session)
1287 return max; 1001 return max;
1288} 1002}
1289 1003
1290/**
1291 * MHD__gnutls_protocol_get_name - Returns a string with the name of the specified SSL/TLS version
1292 * @version: is a (gnutls) version number
1293 *
1294 * Returns: a string that contains the name of the specified TLS
1295 * version (e.g., "TLS 1.0"), or %NULL.
1296 **/
1297const char *
1298MHD__gnutls_protocol_get_name (enum MHD_GNUTLS_Protocol version)
1299{
1300 const char *ret = NULL;
1301
1302 /* avoid prefix */
1303 GNUTLS_VERSION_ALG_LOOP (ret = p->name);
1304 return ret;
1305}
1306
1307/**
1308 * MHD_gtls_protocol_get_id - Returns the gnutls id of the specified in string protocol
1309 * @algorithm: is a protocol name
1310 *
1311 * The names are compared in a case insensitive way.
1312 *
1313 * Returns: an id of the specified protocol, or
1314 * %GNUTLS_VERSION_UNKNOWN on error.
1315 **/
1316enum MHD_GNUTLS_Protocol
1317MHD_gtls_protocol_get_id (const char *name)
1318{
1319 enum MHD_GNUTLS_Protocol ret = MHD_GNUTLS_PROTOCOL_VERSION_UNKNOWN;
1320
1321 GNUTLS_VERSION_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id)
1322 ;
1323
1324 return ret;
1325}
1326
1327/**
1328 * MHD_gtls_protocol_list:
1329 *
1330 * Get a list of supported protocols, e.g. SSL 3.0, TLS 1.0 etc.
1331 *
1332 * Returns: a zero-terminated list of %enum MHD_GNUTLS_Protocol integers
1333 * indicating the available protocols.
1334 *
1335 **/
1336const enum MHD_GNUTLS_Protocol *
1337MHD_gtls_protocol_list (void)
1338{
1339 return MHD_gtls_supported_protocols;
1340}
1341
1342int 1004int
1343MHD_gtls_version_get_minor (enum MHD_GNUTLS_Protocol version) 1005MHD_gtls_version_get_minor (enum MHD_GNUTLS_Protocol version)
1344{ 1006{
@@ -1386,23 +1048,6 @@ MHD_gtls_version_is_supported (MHD_gtls_session_t session,
1386 return 1; 1048 return 1;
1387} 1049}
1388 1050
1389/* Type to KX mappings */
1390enum MHD_GNUTLS_KeyExchangeAlgorithm
1391MHD_gtls_map_kx_get_kx (enum MHD_GNUTLS_CredentialsType type, int server)
1392{
1393 enum MHD_GNUTLS_KeyExchangeAlgorithm ret = -1;
1394
1395 if (server)
1396 {
1397 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1398 }
1399 else
1400 {
1401 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1402 }
1403 return ret;
1404}
1405
1406enum MHD_GNUTLS_CredentialsType 1051enum MHD_GNUTLS_CredentialsType
1407MHD_gtls_map_kx_get_cred (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm, 1052MHD_gtls_map_kx_get_cred (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm,
1408 int server) 1053 int server)
@@ -1807,62 +1452,12 @@ MHD_gtls_supported_compression_methods (MHD_gtls_session_t session,
1807 return j; 1452 return j;
1808} 1453}
1809 1454
1810/**
1811 * MHD__gnutls_certificate_type_get_name - Returns a string with the name of the specified certificate type
1812 * @type: is a certificate type
1813 *
1814 * Returns: a string (or %NULL) that contains the name of the
1815 * specified certificate type.
1816 **/
1817const char *
1818MHD__gnutls_certificate_type_get_name (enum MHD_GNUTLS_CertificateType type)
1819{
1820 const char *ret = NULL;
1821
1822 if (type == MHD_GNUTLS_CRT_X509)
1823 ret = "X.509";
1824 return ret;
1825}
1826
1827/**
1828 * MHD_gtls_certificate_type_get_id - Returns the gnutls id of the specified in string type
1829 * @name: is a certificate type name
1830 *
1831 * The names are compared in a case insensitive way.
1832 *
1833 * Returns: an id of the specified in a string certificate type, or
1834 * %GNUTLS_CRT_UNKNOWN on error.
1835 **/
1836enum MHD_GNUTLS_CertificateType
1837MHD_gtls_certificate_type_get_id (const char *name)
1838{
1839 enum MHD_GNUTLS_CertificateType ret = MHD_GNUTLS_CRT_UNKNOWN;
1840
1841 if (strcasecmp (name, "X.509") == 0 || strcasecmp (name, "X509") == 0)
1842 return MHD_GNUTLS_CRT_X509;
1843 return ret;
1844}
1845
1846static const enum MHD_GNUTLS_CertificateType 1455static const enum MHD_GNUTLS_CertificateType
1847 MHD_gtls_supported_certificate_types[] = 1456 MHD_gtls_supported_certificate_types[] =
1848{ MHD_GNUTLS_CRT_X509, 1457{ MHD_GNUTLS_CRT_X509,
1849 0 1458 0
1850}; 1459};
1851 1460
1852/**
1853 * MHD_gtls_certificate_type_list:
1854 *
1855 * Get a list of certificate types.
1856 *
1857 * Returns: a zero-terminated list of %enum MHD_GNUTLS_CertificateType
1858 * integers indicating the available certificate types.
1859 *
1860 **/
1861const enum MHD_GNUTLS_CertificateType *
1862MHD_gtls_certificate_type_list (void)
1863{
1864 return MHD_gtls_supported_certificate_types;
1865}
1866 1461
1867/* returns the enum MHD_GNUTLS_PublicKeyAlgorithm which is compatible with 1462/* returns the enum MHD_GNUTLS_PublicKeyAlgorithm which is compatible with
1868 * the given enum MHD_GNUTLS_KeyExchangeAlgorithm. 1463 * the given enum MHD_GNUTLS_KeyExchangeAlgorithm.
@@ -1942,55 +1537,6 @@ static const MHD_gnutls_sign_entry MHD_gtls_sign_algorithms[] = {
1942#define GNUTLS_SIGN_ALG_LOOP(a) \ 1537#define GNUTLS_SIGN_ALG_LOOP(a) \
1943 GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } ) 1538 GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } )
1944 1539
1945MHD_gnutls_sign_algorithm_t
1946MHD_gtls_x509_oid2sign_algorithm (const char *oid)
1947{
1948 MHD_gnutls_sign_algorithm_t ret = 0;
1949
1950 GNUTLS_SIGN_LOOP (if (strcmp (oid, p->oid) == 0)
1951 {
1952 ret = p->id; break;}
1953 );
1954
1955 if (ret == 0)
1956 {
1957 MHD__gnutls_x509_log ("Unknown SIGN OID: '%s'\n", oid);
1958 return GNUTLS_SIGN_UNKNOWN;
1959 }
1960 return ret;
1961}
1962
1963MHD_gnutls_sign_algorithm_t
1964MHD_gtls_x509_pk_to_sign (enum MHD_GNUTLS_PublicKeyAlgorithm pk,
1965 enum MHD_GNUTLS_HashAlgorithm mac)
1966{
1967 MHD_gnutls_sign_algorithm_t ret = 0;
1968
1969 GNUTLS_SIGN_LOOP (if (pk == p->pk && mac == p->mac)
1970 {
1971 ret = p->id; break;}
1972 );
1973
1974 if (ret == 0)
1975 return GNUTLS_SIGN_UNKNOWN;
1976 return ret;
1977}
1978
1979const char *
1980MHD_gtls_x509_sign_to_oid (enum MHD_GNUTLS_PublicKeyAlgorithm pk,
1981 enum MHD_GNUTLS_HashAlgorithm mac)
1982{
1983 MHD_gnutls_sign_algorithm_t sign;
1984 const char *ret = NULL;
1985
1986 sign = MHD_gtls_x509_pk_to_sign (pk, mac);
1987 if (sign == GNUTLS_SIGN_UNKNOWN)
1988 return NULL;
1989
1990 GNUTLS_SIGN_ALG_LOOP (ret = p->oid);
1991 return ret;
1992}
1993
1994/* pk algorithms; 1540/* pk algorithms;
1995 */ 1541 */
1996struct MHD_gnutls_pk_entry 1542struct MHD_gnutls_pk_entry
@@ -2032,18 +1578,3 @@ MHD_gtls_x509_oid2pk_algorithm (const char *oid)
2032 return ret; 1578 return ret;
2033} 1579}
2034 1580
2035const char *
2036MHD_gtls_x509_pk_to_oid (enum MHD_GNUTLS_PublicKeyAlgorithm algorithm)
2037{
2038 const char *ret = NULL;
2039 const MHD_gnutls_pk_entry *p;
2040
2041 for (p = MHD_gtls_pk_algorithms; p->name != NULL; p++)
2042 if (p->id == algorithm)
2043 {
2044 ret = p->oid;
2045 break;
2046 }
2047
2048 return ret;
2049}