Tizen 2.0 Release
[external/libgnutls26.git] / lib / gnutls_algorithms.c
1 /*
2  * Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3  * 2010 Free Software Foundation, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA
23  *
24  */
25
26 #include "gnutls_int.h"
27 #include "gnutls_algorithms.h"
28 #include "gnutls_errors.h"
29 #include "gnutls_cert.h"
30 #include <x509/common.h>
31
32
33 typedef struct
34 {
35   const char *name;
36   gnutls_sec_param_t sec_param;
37   int bits;                     /* security level */
38   int pk_bits;                  /* DH, RSA, SRP */
39   int dsa_bits;                 /* bits for DSA. Handled differently since
40                                  * choice of key size in DSA is political.
41                                  */
42   int subgroup_bits;            /* subgroup bits */
43   int ecc_bits;                 /* bits for ECC keys */
44 } gnutls_sec_params_entry;
45
46 static const gnutls_sec_params_entry sec_params[] = {
47   {"Weak", GNUTLS_SEC_PARAM_WEAK, 64, 816, 1024, 128, 128},
48   {"Low", GNUTLS_SEC_PARAM_LOW, 80, 1248, 2048, 160, 160},
49   {"Normal", GNUTLS_SEC_PARAM_NORMAL, 112, 2432, 3072, 224, 224},
50   {"High", GNUTLS_SEC_PARAM_HIGH, 128, 3248, 3072, 256, 256},
51   {"Ultra", GNUTLS_SEC_PARAM_ULTRA, 256, 15424, 3072, 512, 512},
52   {NULL, 0, 0, 0, 0, 0}
53 };
54
55 #define GNUTLS_SEC_PARAM_LOOP(b) \
56         { const gnutls_sec_params_entry *p; \
57                 for(p = sec_params; p->name != NULL; p++) { b ; } }
58
59
60 /* Cred type mappings to KX algorithms 
61  * FIXME: The mappings are not 1-1. Some KX such as SRP_RSA require
62  * more than one credentials type.
63  */
64 typedef struct
65 {
66   gnutls_kx_algorithm_t algorithm;
67   gnutls_credentials_type_t client_type;
68   gnutls_credentials_type_t server_type;        /* The type of credentials a server
69                                                  * needs to set */
70 } gnutls_cred_map;
71
72 static const gnutls_cred_map cred_mappings[] = {
73   {GNUTLS_KX_ANON_DH, GNUTLS_CRD_ANON, GNUTLS_CRD_ANON},
74   {GNUTLS_KX_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
75   {GNUTLS_KX_RSA_EXPORT, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
76   {GNUTLS_KX_DHE_DSS, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
77   {GNUTLS_KX_DHE_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
78   {GNUTLS_KX_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK},
79   {GNUTLS_KX_DHE_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK},
80   {GNUTLS_KX_SRP, GNUTLS_CRD_SRP, GNUTLS_CRD_SRP},
81   {GNUTLS_KX_SRP_RSA, GNUTLS_CRD_SRP, GNUTLS_CRD_CERTIFICATE},
82   {GNUTLS_KX_SRP_DSS, GNUTLS_CRD_SRP, GNUTLS_CRD_CERTIFICATE},
83   {0, 0, 0}
84 };
85
86 #define GNUTLS_KX_MAP_LOOP(b) \
87         const gnutls_cred_map *p; \
88                 for(p = cred_mappings; p->algorithm != 0; p++) { b ; }
89
90 #define GNUTLS_KX_MAP_ALG_LOOP_SERVER(a) \
91                         GNUTLS_KX_MAP_LOOP( if(p->server_type == type) { a; break; })
92
93 /* KX mappings to PK algorithms */
94 typedef struct
95 {
96   gnutls_kx_algorithm_t kx_algorithm;
97   gnutls_pk_algorithm_t pk_algorithm;
98   enum encipher_type encipher_type;     /* CIPHER_ENCRYPT if this algorithm is to be used
99                                          * for encryption, CIPHER_SIGN if signature only,
100                                          * CIPHER_IGN if this does not apply at all.
101                                          *
102                                          * This is useful to certificate cipher suites, which check
103                                          * against the certificate key usage bits.
104                                          */
105 } gnutls_pk_map;
106
107 /* This table maps the Key exchange algorithms to
108  * the certificate algorithms. Eg. if we have
109  * RSA algorithm in the certificate then we can
110  * use GNUTLS_KX_RSA or GNUTLS_KX_DHE_RSA.
111  */
112 static const gnutls_pk_map pk_mappings[] = {
113   {GNUTLS_KX_RSA, GNUTLS_PK_RSA, CIPHER_ENCRYPT},
114   {GNUTLS_KX_RSA_EXPORT, GNUTLS_PK_RSA, CIPHER_SIGN},
115   {GNUTLS_KX_DHE_RSA, GNUTLS_PK_RSA, CIPHER_SIGN},
116   {GNUTLS_KX_SRP_RSA, GNUTLS_PK_RSA, CIPHER_SIGN},
117   {GNUTLS_KX_DHE_DSS, GNUTLS_PK_DSA, CIPHER_SIGN},
118   {GNUTLS_KX_SRP_DSS, GNUTLS_PK_DSA, CIPHER_SIGN},
119   {0, 0, 0}
120 };
121
122 #define GNUTLS_PK_MAP_LOOP(b) \
123         const gnutls_pk_map *p; \
124                 for(p = pk_mappings; p->kx_algorithm != 0; p++) { b }
125
126 #define GNUTLS_PK_MAP_ALG_LOOP(a) \
127                         GNUTLS_PK_MAP_LOOP( if(p->kx_algorithm == kx_algorithm) { a; break; })
128
129
130
131 /* TLS Versions */
132
133 typedef struct
134 {
135   const char *name;
136   gnutls_protocol_t id;         /* gnutls internal version number */
137   int major;                    /* defined by the protocol */
138   int minor;                    /* defined by the protocol */
139   int supported;                /* 0 not supported, > 0 is supported */
140 } gnutls_version_entry;
141
142 static const gnutls_version_entry sup_versions[] = {
143   {"SSL3.0", GNUTLS_SSL3, 3, 0, 1},
144   {"TLS1.0", GNUTLS_TLS1, 3, 1, 1},
145   {"TLS1.1", GNUTLS_TLS1_1, 3, 2, 1},
146   {"TLS1.2", GNUTLS_TLS1_2, 3, 3, 1},
147   {0, 0, 0, 0, 0}
148 };
149
150 /* Keep the contents of this struct the same as the previous one. */
151 static const gnutls_protocol_t supported_protocols[] = {
152   GNUTLS_SSL3,
153   GNUTLS_TLS1,
154   GNUTLS_TLS1_1,
155   GNUTLS_TLS1_2,
156   0
157 };
158
159 #define GNUTLS_VERSION_LOOP(b) \
160         const gnutls_version_entry *p; \
161                 for(p = sup_versions; p->name != NULL; p++) { b ; }
162
163 #define GNUTLS_VERSION_ALG_LOOP(a) \
164         GNUTLS_VERSION_LOOP( if(p->id == version) { a; break; })
165
166 struct gnutls_cipher_entry
167 {
168   const char *name;
169   gnutls_cipher_algorithm_t id;
170   uint16_t blocksize;
171   uint16_t keysize;
172   cipher_type_t block;
173   uint16_t iv;
174   int export_flag;              /* 0 non export */
175 };
176 typedef struct gnutls_cipher_entry gnutls_cipher_entry;
177
178 /* Note that all algorithms are in CBC or STREAM modes. 
179  * Do not add any algorithms in other modes (avoid modified algorithms).
180  * View first: "The order of encryption and authentication for
181  * protecting communications" by Hugo Krawczyk - CRYPTO 2001
182  *
183  * Make sure to updated MAX_CIPHER_BLOCK_SIZE and MAX_CIPHER_KEY_SIZE as well.
184  */
185 static const gnutls_cipher_entry algorithms[] = {
186   {"AES-256-CBC", GNUTLS_CIPHER_AES_256_CBC, 16, 32, CIPHER_BLOCK, 16, 0},
187   {"AES-192-CBC", GNUTLS_CIPHER_AES_192_CBC, 16, 24, CIPHER_BLOCK, 16, 0},
188   {"AES-128-CBC", GNUTLS_CIPHER_AES_128_CBC, 16, 16, CIPHER_BLOCK, 16, 0},
189   {"3DES-CBC", GNUTLS_CIPHER_3DES_CBC, 8, 24, CIPHER_BLOCK, 8, 0},
190   {"DES-CBC", GNUTLS_CIPHER_DES_CBC, 8, 8, CIPHER_BLOCK, 8, 0},
191   {"ARCFOUR-128", GNUTLS_CIPHER_ARCFOUR_128, 1, 16, CIPHER_STREAM, 0, 0},
192   {"ARCFOUR-40", GNUTLS_CIPHER_ARCFOUR_40, 1, 5, CIPHER_STREAM, 0, 1},
193   {"RC2-40", GNUTLS_CIPHER_RC2_40_CBC, 8, 5, CIPHER_BLOCK, 8, 1},
194 #ifdef  ENABLE_CAMELLIA
195   {"CAMELLIA-256-CBC", GNUTLS_CIPHER_CAMELLIA_256_CBC, 16, 32, CIPHER_BLOCK,
196    16, 0},
197   {"CAMELLIA-128-CBC", GNUTLS_CIPHER_CAMELLIA_128_CBC, 16, 16, CIPHER_BLOCK,
198    16, 0},
199 #endif
200
201 #ifdef ENABLE_OPENPGP
202   {"IDEA-PGP-CFB", GNUTLS_CIPHER_IDEA_PGP_CFB, 8, 16, CIPHER_BLOCK, 8, 0},
203   {"3DES-PGP-CFB", GNUTLS_CIPHER_3DES_PGP_CFB, 8, 24, CIPHER_BLOCK, 8, 0},
204   {"CAST5-PGP-CFB", GNUTLS_CIPHER_CAST5_PGP_CFB, 8, 16, CIPHER_BLOCK, 8, 0},
205   {"BLOWFISH-PGP-CFB", GNUTLS_CIPHER_BLOWFISH_PGP_CFB, 8,
206    16 /*actually unlimited */ , CIPHER_BLOCK, 8, 0},
207   {"SAFER-SK128-PGP-CFB", GNUTLS_CIPHER_SAFER_SK128_PGP_CFB, 8, 16,
208    CIPHER_BLOCK, 8, 0},
209   {"AES-128-PGP-CFB", GNUTLS_CIPHER_AES128_PGP_CFB, 16, 16, CIPHER_BLOCK, 16,
210    0},
211   {"AES-192-PGP-CFB", GNUTLS_CIPHER_AES192_PGP_CFB, 16, 24, CIPHER_BLOCK, 16,
212    0},
213   {"AES-256-PGP-CFB", GNUTLS_CIPHER_AES256_PGP_CFB, 16, 32, CIPHER_BLOCK, 16,
214    0},
215   {"TWOFISH-PGP-CFB", GNUTLS_CIPHER_TWOFISH_PGP_CFB, 16, 16, CIPHER_BLOCK, 16,
216    0},
217 #endif
218   {"NULL", GNUTLS_CIPHER_NULL, 1, 0, CIPHER_STREAM, 0, 0},
219   {0, 0, 0, 0, 0, 0, 0}
220 };
221
222 /* Keep the contents of this struct the same as the previous one. */
223 static const gnutls_cipher_algorithm_t supported_ciphers[] = {
224   GNUTLS_CIPHER_AES_256_CBC,
225   GNUTLS_CIPHER_AES_128_CBC,
226   GNUTLS_CIPHER_3DES_CBC,
227   GNUTLS_CIPHER_DES_CBC,
228   GNUTLS_CIPHER_ARCFOUR_128,
229   GNUTLS_CIPHER_ARCFOUR_40,
230   GNUTLS_CIPHER_RC2_40_CBC,
231 #ifdef  ENABLE_CAMELLIA
232   GNUTLS_CIPHER_CAMELLIA_256_CBC,
233   GNUTLS_CIPHER_CAMELLIA_128_CBC,
234 #endif
235   GNUTLS_CIPHER_NULL,
236   0
237 };
238
239 #define GNUTLS_LOOP(b) \
240         const gnutls_cipher_entry *p; \
241                 for(p = algorithms; p->name != NULL; p++) { b ; }
242
243 #define GNUTLS_ALG_LOOP(a) \
244                         GNUTLS_LOOP( if(p->id == algorithm) { a; break; } )
245
246
247 struct gnutls_hash_entry
248 {
249   const char *name;
250   const char *oid;
251   gnutls_mac_algorithm_t id;
252   size_t key_size;              /* in case of mac */
253 };
254 typedef struct gnutls_hash_entry gnutls_hash_entry;
255
256 static const gnutls_hash_entry hash_algorithms[] = {
257   {"SHA1", HASH_OID_SHA1, GNUTLS_MAC_SHA1, 20},
258   {"MD5", HASH_OID_MD5, GNUTLS_MAC_MD5, 16},
259   {"SHA256", HASH_OID_SHA256, GNUTLS_MAC_SHA256, 32},
260   {"SHA384", HASH_OID_SHA384, GNUTLS_MAC_SHA384, 48},
261   {"SHA512", HASH_OID_SHA512, GNUTLS_MAC_SHA512, 64},
262   {"MD2", HASH_OID_MD2, GNUTLS_MAC_MD2, 0},     /* not used as MAC */
263   {"RIPEMD160", HASH_OID_RMD160, GNUTLS_MAC_RMD160, 20},
264   {"MAC-NULL", NULL, GNUTLS_MAC_NULL, 0},
265   {0, 0, 0, 0}
266 };
267
268 /* Keep the contents of this struct the same as the previous one. */
269 static const gnutls_mac_algorithm_t supported_macs[] = {
270   GNUTLS_MAC_SHA1,
271   GNUTLS_MAC_MD5,
272   GNUTLS_MAC_SHA256,
273   GNUTLS_MAC_SHA384,
274   GNUTLS_MAC_SHA512,
275   GNUTLS_MAC_MD2,
276   GNUTLS_MAC_RMD160,
277   GNUTLS_MAC_NULL,
278   0
279 };
280
281 #define GNUTLS_HASH_LOOP(b) \
282         const gnutls_hash_entry *p; \
283                 for(p = hash_algorithms; p->name != NULL; p++) { b ; }
284
285 #define GNUTLS_HASH_ALG_LOOP(a) \
286                         GNUTLS_HASH_LOOP( if(p->id == algorithm) { a; break; } )
287
288 /* Key Exchange Section */
289
290
291 extern mod_auth_st rsa_auth_struct;
292 extern mod_auth_st rsa_export_auth_struct;
293 extern mod_auth_st dhe_rsa_auth_struct;
294 extern mod_auth_st dhe_dss_auth_struct;
295 extern mod_auth_st anon_auth_struct;
296 extern mod_auth_st srp_auth_struct;
297 extern mod_auth_st psk_auth_struct;
298 extern mod_auth_st dhe_psk_auth_struct;
299 extern mod_auth_st srp_rsa_auth_struct;
300 extern mod_auth_st srp_dss_auth_struct;
301
302 struct gnutls_kx_algo_entry
303 {
304   const char *name;
305   gnutls_kx_algorithm_t algorithm;
306   mod_auth_st *auth_struct;
307   int needs_dh_params;
308   int needs_rsa_params;
309 };
310 typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry;
311
312 static const gnutls_kx_algo_entry _gnutls_kx_algorithms[] = {
313 #ifdef ENABLE_ANON
314   {"ANON-DH", GNUTLS_KX_ANON_DH, &anon_auth_struct, 1, 0},
315 #endif
316   {"RSA", GNUTLS_KX_RSA, &rsa_auth_struct, 0, 0},
317   {"RSA-EXPORT", GNUTLS_KX_RSA_EXPORT, &rsa_export_auth_struct, 0,
318    1 /* needs RSA params */ },
319   {"DHE-RSA", GNUTLS_KX_DHE_RSA, &dhe_rsa_auth_struct, 1, 0},
320   {"DHE-DSS", GNUTLS_KX_DHE_DSS, &dhe_dss_auth_struct, 1, 0},
321
322 #ifdef ENABLE_SRP
323   {"SRP-DSS", GNUTLS_KX_SRP_DSS, &srp_dss_auth_struct, 0, 0},
324   {"SRP-RSA", GNUTLS_KX_SRP_RSA, &srp_rsa_auth_struct, 0, 0},
325   {"SRP", GNUTLS_KX_SRP, &srp_auth_struct, 0, 0},
326 #endif
327 #ifdef ENABLE_PSK
328   {"PSK", GNUTLS_KX_PSK, &psk_auth_struct, 0, 0},
329   {"DHE-PSK", GNUTLS_KX_DHE_PSK, &dhe_psk_auth_struct,
330    1 /* needs DHE params */ , 0},
331 #endif
332   {0, 0, 0, 0, 0}
333 };
334
335 /* Keep the contents of this struct the same as the previous one. */
336 static const gnutls_kx_algorithm_t supported_kxs[] = {
337 #ifdef ENABLE_ANON
338   GNUTLS_KX_ANON_DH,
339 #endif
340   GNUTLS_KX_RSA,
341   GNUTLS_KX_RSA_EXPORT,
342   GNUTLS_KX_DHE_RSA,
343   GNUTLS_KX_DHE_DSS,
344 #ifdef ENABLE_SRP
345   GNUTLS_KX_SRP_DSS,
346   GNUTLS_KX_SRP_RSA,
347   GNUTLS_KX_SRP,
348 #endif
349 #ifdef ENABLE_PSK
350   GNUTLS_KX_PSK,
351   GNUTLS_KX_DHE_PSK,
352 #endif
353   0
354 };
355
356 #define GNUTLS_KX_LOOP(b) \
357         const gnutls_kx_algo_entry *p; \
358                 for(p = _gnutls_kx_algorithms; p->name != NULL; p++) { b ; }
359
360 #define GNUTLS_KX_ALG_LOOP(a) \
361                         GNUTLS_KX_LOOP( if(p->algorithm == algorithm) { a; break; } )
362
363
364
365 /* Cipher SUITES */
366 #define GNUTLS_CIPHER_SUITE_ENTRY( name, block_algorithm, kx_algorithm, mac_algorithm, min_version, max_version ) \
367         { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, min_version, max_version }
368
369 typedef struct
370 {
371   const char *name;
372   cipher_suite_st id;
373   gnutls_cipher_algorithm_t block_algorithm;
374   gnutls_kx_algorithm_t kx_algorithm;
375   gnutls_mac_algorithm_t mac_algorithm;
376   gnutls_protocol_t min_version;        /* this cipher suite is supported
377                                          * from 'version' and above;
378                                          */
379   gnutls_protocol_t max_version;        /* this cipher suite is not supported after that */
380 } gnutls_cipher_suite_entry;
381
382 /* RSA with NULL cipher and MD5 MAC
383  * for test purposes.
384  */
385 #define GNUTLS_RSA_NULL_MD5 { 0x00, 0x01 }
386 #define GNUTLS_RSA_NULL_SHA1 { 0x00, 0x02 }
387 #define GNUTLS_RSA_NULL_SHA256 { 0x00, 0x3B }
388
389 /* ANONymous cipher suites.
390  */
391
392 #define GNUTLS_ANON_DH_3DES_EDE_CBC_SHA1 { 0x00, 0x1B }
393 #define GNUTLS_ANON_DH_ARCFOUR_MD5 { 0x00, 0x18 }
394
395  /* rfc3268: */
396 #define GNUTLS_ANON_DH_AES_128_CBC_SHA1 { 0x00, 0x34 }
397 #define GNUTLS_ANON_DH_AES_256_CBC_SHA1 { 0x00, 0x3A }
398
399 /* rfc4132 */
400 #ifdef  ENABLE_CAMELLIA
401 #define GNUTLS_ANON_DH_CAMELLIA_128_CBC_SHA1 { 0x00,0x46 }
402 #define GNUTLS_ANON_DH_CAMELLIA_256_CBC_SHA1 { 0x00,0x89 }
403 #endif
404
405 #define GNUTLS_ANON_DH_AES_128_CBC_SHA256 { 0x00, 0x6C }
406 #define GNUTLS_ANON_DH_AES_256_CBC_SHA256 { 0x00, 0x6D }
407
408 /* PSK (not in TLS 1.0)
409  * draft-ietf-tls-psk:
410  */
411 #define GNUTLS_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8A }
412 #define GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8B }
413 #define GNUTLS_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x8C }
414 #define GNUTLS_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x8D }
415
416 #define GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8E }
417 #define GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8F }
418 #define GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x90 }
419 #define GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x91 }
420
421
422 /* SRP (rfc5054)
423  */
424 #define GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1A }
425 #define GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1B }
426 #define GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1 { 0xC0, 0x1C }
427
428 #define GNUTLS_SRP_SHA_AES_128_CBC_SHA1 { 0xC0, 0x1D }
429 #define GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1 { 0xC0, 0x1E }
430 #define GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1 { 0xC0, 0x1F }
431
432 #define GNUTLS_SRP_SHA_AES_256_CBC_SHA1 { 0xC0, 0x20 }
433 #define GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1 { 0xC0, 0x21 }
434 #define GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1 { 0xC0, 0x22 }
435
436 /* RSA
437  */
438 #define GNUTLS_RSA_ARCFOUR_SHA1 { 0x00, 0x05 }
439 #define GNUTLS_RSA_ARCFOUR_MD5 { 0x00, 0x04 }
440 #define GNUTLS_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x0A }
441
442 #define GNUTLS_RSA_EXPORT_ARCFOUR_40_MD5 { 0x00, 0x03 }
443
444 /* rfc3268:
445  */
446 #define GNUTLS_RSA_AES_128_CBC_SHA1 { 0x00, 0x2F }
447 #define GNUTLS_RSA_AES_256_CBC_SHA1 { 0x00, 0x35 }
448
449 /* rfc4132 */
450 #ifdef  ENABLE_CAMELLIA
451 #define GNUTLS_RSA_CAMELLIA_128_CBC_SHA1 { 0x00,0x41 }
452 #define GNUTLS_RSA_CAMELLIA_256_CBC_SHA1 { 0x00,0x84 }
453 #endif
454
455 #define GNUTLS_RSA_AES_128_CBC_SHA256 { 0x00, 0x3C }
456 #define GNUTLS_RSA_AES_256_CBC_SHA256 { 0x00, 0x3D }
457
458 /* DHE DSS
459  */
460
461 #define GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1 { 0x00, 0x13 }
462
463
464 /* draft-ietf-tls-56-bit-ciphersuites-01:
465  */
466 #define GNUTLS_DHE_DSS_ARCFOUR_SHA1 { 0x00, 0x66 }
467
468
469 /* rfc3268:
470  */
471 #define GNUTLS_DHE_DSS_AES_256_CBC_SHA1 { 0x00, 0x38 }
472 #define GNUTLS_DHE_DSS_AES_128_CBC_SHA1 { 0x00, 0x32 }
473
474 /* rfc4132 */
475 #ifdef  ENABLE_CAMELLIA
476 #define GNUTLS_DHE_DSS_CAMELLIA_128_CBC_SHA1 { 0x00,0x44 }
477 #define GNUTLS_DHE_DSS_CAMELLIA_256_CBC_SHA1 { 0x00,0x87 }
478 #endif
479
480 #define GNUTLS_DHE_DSS_AES_128_CBC_SHA256 { 0x00, 0x40 }
481 #define GNUTLS_DHE_DSS_AES_256_CBC_SHA256 { 0x00, 0x6A }
482
483 /* DHE RSA
484  */
485 #define GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x16 }
486
487 /* rfc3268:
488  */
489 #define GNUTLS_DHE_RSA_AES_128_CBC_SHA1 { 0x00, 0x33 }
490 #define GNUTLS_DHE_RSA_AES_256_CBC_SHA1 { 0x00, 0x39 }
491
492 /* rfc4132 */
493 #ifdef  ENABLE_CAMELLIA
494 #define GNUTLS_DHE_RSA_CAMELLIA_128_CBC_SHA1 { 0x00,0x45 }
495 #define GNUTLS_DHE_RSA_CAMELLIA_256_CBC_SHA1 { 0x00,0x88 }
496 #endif
497
498 #define GNUTLS_DHE_RSA_AES_128_CBC_SHA256 { 0x00, 0x67 }
499 #define GNUTLS_DHE_RSA_AES_256_CBC_SHA256 { 0x00, 0x6B }
500
501 /* Safe renegotiation */
502
503 #define CIPHER_SUITES_COUNT sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry)-1
504
505 static const gnutls_cipher_suite_entry cs_algorithms[] = {
506   /* ANON_DH */
507   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_ARCFOUR_MD5,
508                              GNUTLS_CIPHER_ARCFOUR_128,
509                              GNUTLS_KX_ANON_DH, GNUTLS_MAC_MD5,
510                              GNUTLS_SSL3, GNUTLS_VERSION_MAX),
511   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_3DES_EDE_CBC_SHA1,
512                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_ANON_DH,
513                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
514                              GNUTLS_VERSION_MAX),
515   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_128_CBC_SHA1,
516                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ANON_DH,
517                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
518                              GNUTLS_VERSION_MAX),
519   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_256_CBC_SHA1,
520                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ANON_DH,
521                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
522                              GNUTLS_VERSION_MAX),
523 #ifdef  ENABLE_CAMELLIA
524   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_CAMELLIA_128_CBC_SHA1,
525                              GNUTLS_CIPHER_CAMELLIA_128_CBC,
526                              GNUTLS_KX_ANON_DH,
527                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
528                              GNUTLS_VERSION_MAX),
529   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_CAMELLIA_256_CBC_SHA1,
530                              GNUTLS_CIPHER_CAMELLIA_256_CBC,
531                              GNUTLS_KX_ANON_DH,
532                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
533                              GNUTLS_VERSION_MAX),
534 #endif
535   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_128_CBC_SHA256,
536                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ANON_DH,
537                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
538                              GNUTLS_VERSION_MAX),
539   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_256_CBC_SHA256,
540                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ANON_DH,
541                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
542                              GNUTLS_VERSION_MAX),
543
544   /* PSK */
545   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_ARCFOUR_SHA1,
546                              GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_PSK,
547                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
548                              GNUTLS_VERSION_MAX),
549   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1,
550                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_PSK,
551                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
552                              GNUTLS_VERSION_MAX),
553   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_128_CBC_SHA1,
554                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_PSK,
555                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
556                              GNUTLS_VERSION_MAX),
557   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_256_CBC_SHA1,
558                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_PSK,
559                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
560                              GNUTLS_VERSION_MAX),
561
562   /* DHE-PSK */
563   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1,
564                              GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_DHE_PSK,
565                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
566                              GNUTLS_VERSION_MAX),
567   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1,
568                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_PSK,
569                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
570                              GNUTLS_VERSION_MAX),
571   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1,
572                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_PSK,
573                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
574                              GNUTLS_VERSION_MAX),
575   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1,
576                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_PSK,
577                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
578                              GNUTLS_VERSION_MAX),
579
580   /* SRP */
581   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1,
582                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP,
583                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
584                              GNUTLS_VERSION_MAX),
585   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_128_CBC_SHA1,
586                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP,
587                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
588                              GNUTLS_VERSION_MAX),
589   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_256_CBC_SHA1,
590                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP,
591                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
592                              GNUTLS_VERSION_MAX),
593
594   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1,
595                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_DSS,
596                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
597                              GNUTLS_VERSION_MAX),
598
599   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1,
600                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_RSA,
601                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
602                              GNUTLS_VERSION_MAX),
603
604   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1,
605                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_DSS,
606                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
607                              GNUTLS_VERSION_MAX),
608
609   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1,
610                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_RSA,
611                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
612                              GNUTLS_VERSION_MAX),
613
614   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1,
615                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_DSS,
616                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
617                              GNUTLS_VERSION_MAX),
618
619   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1,
620                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_RSA,
621                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
622                              GNUTLS_VERSION_MAX),
623
624   /* DHE_DSS */
625   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_ARCFOUR_SHA1,
626                              GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_KX_DHE_DSS,
627                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
628                              GNUTLS_VERSION_MAX),
629   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1,
630                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_DSS,
631                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
632                              GNUTLS_VERSION_MAX),
633   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_128_CBC_SHA1,
634                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_DSS,
635                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
636                              GNUTLS_VERSION_MAX),
637   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_256_CBC_SHA1,
638                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_DSS,
639                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
640                              GNUTLS_VERSION_MAX),
641 #ifdef  ENABLE_CAMELLIA
642   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_CAMELLIA_128_CBC_SHA1,
643                              GNUTLS_CIPHER_CAMELLIA_128_CBC,
644                              GNUTLS_KX_DHE_DSS,
645                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
646                              GNUTLS_VERSION_MAX),
647   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_CAMELLIA_256_CBC_SHA1,
648                              GNUTLS_CIPHER_CAMELLIA_256_CBC,
649                              GNUTLS_KX_DHE_DSS,
650                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
651                              GNUTLS_VERSION_MAX),
652 #endif
653   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_128_CBC_SHA256,
654                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_DSS,
655                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
656                              GNUTLS_VERSION_MAX),
657   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_256_CBC_SHA256,
658                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_DSS,
659                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
660                              GNUTLS_VERSION_MAX),
661   /* DHE_RSA */
662   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1,
663                              GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_RSA,
664                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
665                              GNUTLS_VERSION_MAX),
666   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_128_CBC_SHA1,
667                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_RSA,
668                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
669                              GNUTLS_VERSION_MAX),
670   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_256_CBC_SHA1,
671                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_RSA,
672                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
673                              GNUTLS_VERSION_MAX),
674 #ifdef  ENABLE_CAMELLIA
675   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_CAMELLIA_128_CBC_SHA1,
676                              GNUTLS_CIPHER_CAMELLIA_128_CBC,
677                              GNUTLS_KX_DHE_RSA,
678                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
679                              GNUTLS_VERSION_MAX),
680   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_CAMELLIA_256_CBC_SHA1,
681                              GNUTLS_CIPHER_CAMELLIA_256_CBC,
682                              GNUTLS_KX_DHE_RSA,
683                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
684                              GNUTLS_VERSION_MAX),
685 #endif
686   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_128_CBC_SHA256,
687                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_RSA,
688                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
689                              GNUTLS_VERSION_MAX),
690   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_256_CBC_SHA256,
691                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_RSA,
692                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
693                              GNUTLS_VERSION_MAX),
694   /* RSA-NULL */
695   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_MD5,
696                              GNUTLS_CIPHER_NULL,
697                              GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3,
698                              GNUTLS_VERSION_MAX),
699   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_SHA1,
700                              GNUTLS_CIPHER_NULL,
701                              GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3,
702                              GNUTLS_VERSION_MAX),
703   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_SHA256,
704                              GNUTLS_CIPHER_NULL,
705                              GNUTLS_KX_RSA, GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
706                              GNUTLS_VERSION_MAX),
707
708   /* RSA-EXPORT */
709   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_EXPORT_ARCFOUR_40_MD5,
710                              GNUTLS_CIPHER_ARCFOUR_40,
711                              GNUTLS_KX_RSA_EXPORT, GNUTLS_MAC_MD5,
712                              GNUTLS_SSL3, GNUTLS_TLS1_0),
713
714   /* RSA */
715   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_SHA1,
716                              GNUTLS_CIPHER_ARCFOUR_128,
717                              GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3,
718                              GNUTLS_VERSION_MAX),
719   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_MD5,
720                              GNUTLS_CIPHER_ARCFOUR_128,
721                              GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3,
722                              GNUTLS_VERSION_MAX),
723   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_3DES_EDE_CBC_SHA1,
724                              GNUTLS_CIPHER_3DES_CBC,
725                              GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3,
726                              GNUTLS_VERSION_MAX),
727   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_128_CBC_SHA1,
728                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_RSA,
729                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
730                              GNUTLS_VERSION_MAX),
731   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_256_CBC_SHA1,
732                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_RSA,
733                              GNUTLS_MAC_SHA1, GNUTLS_SSL3,
734                              GNUTLS_VERSION_MAX),
735 #ifdef  ENABLE_CAMELLIA
736   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_CAMELLIA_128_CBC_SHA1,
737                              GNUTLS_CIPHER_CAMELLIA_128_CBC, GNUTLS_KX_RSA,
738                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
739                              GNUTLS_VERSION_MAX),
740   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_CAMELLIA_256_CBC_SHA1,
741                              GNUTLS_CIPHER_CAMELLIA_256_CBC, GNUTLS_KX_RSA,
742                              GNUTLS_MAC_SHA1, GNUTLS_TLS1,
743                              GNUTLS_VERSION_MAX),
744 #endif
745   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_128_CBC_SHA256,
746                              GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_RSA,
747                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
748                              GNUTLS_VERSION_MAX),
749   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_256_CBC_SHA256,
750                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_RSA,
751                              GNUTLS_MAC_SHA256, GNUTLS_TLS1_2,
752                              GNUTLS_VERSION_MAX),
753   {0, {{0, 0}}, 0, 0, 0, 0, 0}
754 };
755
756 #define GNUTLS_CIPHER_SUITE_LOOP(b) \
757         const gnutls_cipher_suite_entry *p; \
758                 for(p = cs_algorithms; p->name != NULL; p++) { b ; }
759
760 #define GNUTLS_CIPHER_SUITE_ALG_LOOP(a) \
761                         GNUTLS_CIPHER_SUITE_LOOP( if( (p->id.suite[0] == suite->suite[0]) && (p->id.suite[1] == suite->suite[1])) { a; break; } )
762
763
764
765 /* Generic Functions */
766
767 int
768 _gnutls_mac_priority (gnutls_session_t session,
769                       gnutls_mac_algorithm_t algorithm)
770 {                               /* actually returns the priority */
771   unsigned int i;
772   for (i = 0; i < session->internals.priorities.mac.algorithms; i++)
773     {
774       if (session->internals.priorities.mac.priority[i] == algorithm)
775         return i;
776     }
777   return -1;
778 }
779
780 /**
781  * gnutls_mac_get_name:
782  * @algorithm: is a MAC algorithm
783  *
784  * Convert a #gnutls_mac_algorithm_t value to a string.
785  *
786  * Returns: a string that contains the name of the specified MAC
787  *   algorithm, or %NULL.
788  **/
789 const char *
790 gnutls_mac_get_name (gnutls_mac_algorithm_t algorithm)
791 {
792   const char *ret = NULL;
793
794   /* avoid prefix */
795   GNUTLS_HASH_ALG_LOOP (ret = p->name);
796
797   return ret;
798 }
799
800 /**
801  * gnutls_mac_get_id:
802  * @name: is a MAC algorithm name
803  *
804  * Convert a string to a #gnutls_mac_algorithm_t value.  The names are
805  * compared in a case insensitive way.
806  *
807  * Returns: a #gnutls_mac_algorithm_t id of the specified MAC
808  *   algorithm string, or %GNUTLS_MAC_UNKNOWN on failures.
809  **/
810 gnutls_mac_algorithm_t
811 gnutls_mac_get_id (const char *name)
812 {
813   gnutls_mac_algorithm_t ret = GNUTLS_MAC_UNKNOWN;
814
815   GNUTLS_HASH_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id);
816
817   return ret;
818 }
819
820 /**
821  * gnutls_mac_get_key_size:
822  * @algorithm: is an encryption algorithm
823  *
824  * Get size of MAC key.
825  *
826  * Returns: length (in bytes) of the given MAC key size, or 0 if the
827  *   given MAC algorithm is invalid.
828  **/
829 size_t
830 gnutls_mac_get_key_size (gnutls_mac_algorithm_t algorithm)
831 {
832   size_t ret = 0;
833
834   /* avoid prefix */
835   GNUTLS_HASH_ALG_LOOP (ret = p->key_size);
836
837   return ret;
838 }
839
840 /**
841  * gnutls_mac_list:
842  *
843  * Get a list of hash algorithms for use as MACs.  Note that not
844  * necessarily all MACs are supported in TLS cipher suites.  For
845  * example, MD2 is not supported as a cipher suite, but is supported
846  * for other purposes (e.g., X.509 signature verification or similar).
847  *
848  * Returns: Return a zero-terminated list of #gnutls_mac_algorithm_t
849  *   integers indicating the available MACs.
850  **/
851 const gnutls_mac_algorithm_t *
852 gnutls_mac_list (void)
853 {
854   return supported_macs;
855 }
856
857 const char *
858 _gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t algorithm)
859 {
860   const char *ret = NULL;
861
862   /* avoid prefix */
863   GNUTLS_HASH_ALG_LOOP (ret = p->oid);
864
865   return ret;
866 }
867
868 gnutls_mac_algorithm_t
869 _gnutls_x509_oid2mac_algorithm (const char *oid)
870 {
871   gnutls_mac_algorithm_t ret = 0;
872
873   GNUTLS_HASH_LOOP (if (p->oid && strcmp (oid, p->oid) == 0)
874                     {
875                     ret = p->id; break;}
876   );
877
878   if (ret == 0)
879     return GNUTLS_MAC_UNKNOWN;
880   return ret;
881 }
882
883
884 int
885 _gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm)
886 {
887   ssize_t ret = -1;
888   GNUTLS_HASH_ALG_LOOP (ret = p->id);
889   if (ret >= 0)
890     ret = 0;
891   else
892     ret = 1;
893   return ret;
894 }
895
896 /* CIPHER functions */
897
898 /**
899  * gnutls_cipher_get_block_size:
900  * @algorithm: is an encryption algorithm
901  *
902  * Get block size for encryption algorithm.
903  *
904  * Returns: block size for encryption algorithm.
905  *
906  * Since: 2.10.0
907  **/
908 int
909 gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm)
910 {
911   size_t ret = 0;
912   GNUTLS_ALG_LOOP (ret = p->blocksize);
913   return ret;
914
915 }
916
917  /* returns the priority */
918 int
919 _gnutls_cipher_priority (gnutls_session_t session,
920                          gnutls_cipher_algorithm_t algorithm)
921 {
922   unsigned int i;
923   for (i = 0; i < session->internals.priorities.cipher.algorithms; i++)
924     {
925       if (session->internals.priorities.cipher.priority[i] == algorithm)
926         return i;
927     }
928   return -1;
929 }
930
931
932 int
933 _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm)
934 {
935   size_t ret = 0;
936
937   GNUTLS_ALG_LOOP (ret = p->block);
938   return ret;
939
940 }
941
942 /**
943  * gnutls_cipher_get_key_size:
944  * @algorithm: is an encryption algorithm
945  *
946  * Get key size for cipher.
947  *
948  * Returns: length (in bytes) of the given cipher's key size, or 0 if
949  *   the given cipher is invalid.
950  **/
951 size_t
952 gnutls_cipher_get_key_size (gnutls_cipher_algorithm_t algorithm)
953 {                               /* In bytes */
954   size_t ret = 0;
955   GNUTLS_ALG_LOOP (ret = p->keysize);
956   return ret;
957
958 }
959
960 int
961 _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm)
962 {                               /* In bytes */
963   size_t ret = 0;
964   GNUTLS_ALG_LOOP (ret = p->iv);
965   return ret;
966
967 }
968
969 int
970 _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm)
971 {                               /* In bytes */
972   size_t ret = 0;
973   GNUTLS_ALG_LOOP (ret = p->export_flag);
974   return ret;
975
976 }
977
978 /**
979  * gnutls_cipher_get_name:
980  * @algorithm: is an encryption algorithm
981  *
982  * Convert a #gnutls_cipher_algorithm_t type to a string.
983  *
984  * Returns: a pointer to a string that contains the name of the
985  *   specified cipher, or %NULL.
986  **/
987 const char *
988 gnutls_cipher_get_name (gnutls_cipher_algorithm_t algorithm)
989 {
990   const char *ret = NULL;
991
992   /* avoid prefix */
993   GNUTLS_ALG_LOOP (ret = p->name);
994
995   return ret;
996 }
997
998 /**
999  * gnutls_cipher_get_id:
1000  * @name: is a MAC algorithm name
1001  *
1002  * The names are compared in a case insensitive way.
1003  *
1004  * Returns: return a #gnutls_cipher_algorithm_t value corresponding to
1005  *   the specified cipher, or %GNUTLS_CIPHER_UNKNOWN on error.
1006  **/
1007 gnutls_cipher_algorithm_t
1008 gnutls_cipher_get_id (const char *name)
1009 {
1010   gnutls_cipher_algorithm_t ret = GNUTLS_CIPHER_UNKNOWN;
1011
1012   GNUTLS_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id);
1013
1014   return ret;
1015 }
1016
1017 /**
1018  * gnutls_cipher_list:
1019  *
1020  * Get a list of supported cipher algorithms.  Note that not
1021  * necessarily all ciphers are supported as TLS cipher suites.  For
1022  * example, DES is not supported as a cipher suite, but is supported
1023  * for other purposes (e.g., PKCS#8 or similar).
1024  *
1025  * Returns: a zero-terminated list of #gnutls_cipher_algorithm_t
1026  *   integers indicating the available ciphers.
1027  *
1028  **/
1029 const gnutls_cipher_algorithm_t *
1030 gnutls_cipher_list (void)
1031 {
1032   return supported_ciphers;
1033 }
1034
1035 int
1036 _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm)
1037 {
1038   ssize_t ret = -1;
1039   GNUTLS_ALG_LOOP (ret = p->id);
1040   if (ret >= 0)
1041     ret = 0;
1042   else
1043     ret = 1;
1044   return ret;
1045 }
1046
1047 /* Key EXCHANGE functions */
1048 mod_auth_st *
1049 _gnutls_kx_auth_struct (gnutls_kx_algorithm_t algorithm)
1050 {
1051   mod_auth_st *ret = NULL;
1052   GNUTLS_KX_ALG_LOOP (ret = p->auth_struct);
1053   return ret;
1054
1055 }
1056
1057
1058 int
1059 _gnutls_kx_priority (gnutls_session_t session,
1060                      gnutls_kx_algorithm_t algorithm)
1061 {
1062   unsigned int i;
1063   for (i = 0; i < session->internals.priorities.kx.algorithms; i++)
1064     {
1065       if (session->internals.priorities.kx.priority[i] == algorithm)
1066         return i;
1067     }
1068   return -1;
1069 }
1070
1071 /**
1072  * gnutls_kx_get_name:
1073  * @algorithm: is a key exchange algorithm
1074  *
1075  * Convert a #gnutls_kx_algorithm_t value to a string.
1076  *
1077  * Returns: a pointer to a string that contains the name of the
1078  *   specified key exchange algorithm, or %NULL.
1079  **/
1080 const char *
1081 gnutls_kx_get_name (gnutls_kx_algorithm_t algorithm)
1082 {
1083   const char *ret = NULL;
1084
1085   /* avoid prefix */
1086   GNUTLS_KX_ALG_LOOP (ret = p->name);
1087
1088   return ret;
1089 }
1090
1091 /**
1092  * gnutls_kx_get_id:
1093  * @name: is a KX name
1094  *
1095  * Convert a string to a #gnutls_kx_algorithm_t value.  The names are
1096  * compared in a case insensitive way.
1097  *
1098  * Returns: an id of the specified KX algorithm, or %GNUTLS_KX_UNKNOWN
1099  *   on error.
1100  **/
1101 gnutls_kx_algorithm_t
1102 gnutls_kx_get_id (const char *name)
1103 {
1104   gnutls_cipher_algorithm_t ret = GNUTLS_KX_UNKNOWN;
1105
1106   GNUTLS_KX_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->algorithm);
1107
1108   return ret;
1109 }
1110
1111 /**
1112  * gnutls_kx_list:
1113  *
1114  * Get a list of supported key exchange algorithms.
1115  *
1116  * Returns: a zero-terminated list of #gnutls_kx_algorithm_t integers
1117  * indicating the available key exchange algorithms.
1118  **/
1119 const gnutls_kx_algorithm_t *
1120 gnutls_kx_list (void)
1121 {
1122   return supported_kxs;
1123 }
1124
1125 int
1126 _gnutls_kx_is_ok (gnutls_kx_algorithm_t algorithm)
1127 {
1128   ssize_t ret = -1;
1129   GNUTLS_KX_ALG_LOOP (ret = p->algorithm);
1130   if (ret >= 0)
1131     ret = 0;
1132   else
1133     ret = 1;
1134   return ret;
1135 }
1136
1137 int
1138 _gnutls_kx_needs_rsa_params (gnutls_kx_algorithm_t algorithm)
1139 {
1140   ssize_t ret = 0;
1141   GNUTLS_KX_ALG_LOOP (ret = p->needs_rsa_params);
1142   return ret;
1143 }
1144
1145 int
1146 _gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm)
1147 {
1148   ssize_t ret = 0;
1149   GNUTLS_KX_ALG_LOOP (ret = p->needs_dh_params);
1150   return ret;
1151 }
1152
1153
1154 /* Version */
1155 int
1156 _gnutls_version_priority (gnutls_session_t session, gnutls_protocol_t version)
1157 {                               /* actually returns the priority */
1158   unsigned int i;
1159
1160   for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
1161     {
1162       if (session->internals.priorities.protocol.priority[i] == version)
1163         return i;
1164     }
1165   return -1;
1166 }
1167
1168 gnutls_protocol_t
1169 _gnutls_version_lowest (gnutls_session_t session)
1170 {                               /* returns the lowest version supported */
1171   unsigned int i, min = 0xff;
1172
1173   for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
1174     {
1175       if (session->internals.priorities.protocol.priority[i] < min)
1176         min = session->internals.priorities.protocol.priority[i];
1177     }
1178
1179   if (min == 0xff)
1180     return GNUTLS_VERSION_UNKNOWN;      /* unknown version */
1181
1182   return min;
1183 }
1184
1185 gnutls_protocol_t
1186 _gnutls_version_max (gnutls_session_t session)
1187 {                               /* returns the maximum version supported */
1188   unsigned int i, max = 0x00;
1189
1190   for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
1191     {
1192       if (session->internals.priorities.protocol.priority[i] > max)
1193         max = session->internals.priorities.protocol.priority[i];
1194     }
1195
1196   if (max == 0x00)
1197     return GNUTLS_VERSION_UNKNOWN;      /* unknown version */
1198
1199   return max;
1200 }
1201
1202
1203 /**
1204  * gnutls_protocol_get_name:
1205  * @version: is a (gnutls) version number
1206  *
1207  * Convert a #gnutls_protocol_t value to a string.
1208  *
1209  * Returns: a string that contains the name of the specified TLS
1210  *   version (e.g., "TLS1.0"), or %NULL.
1211  **/
1212 const char *
1213 gnutls_protocol_get_name (gnutls_protocol_t version)
1214 {
1215   const char *ret = NULL;
1216
1217   /* avoid prefix */
1218   GNUTLS_VERSION_ALG_LOOP (ret = p->name);
1219   return ret;
1220 }
1221
1222 /**
1223  * gnutls_protocol_get_id:
1224  * @name: is a protocol name
1225  *
1226  * The names are compared in a case insensitive way.
1227  *
1228  * Returns: an id of the specified protocol, or
1229  * %GNUTLS_VERSION_UNKNOWN on error.
1230  **/
1231 gnutls_protocol_t
1232 gnutls_protocol_get_id (const char *name)
1233 {
1234   gnutls_protocol_t ret = GNUTLS_VERSION_UNKNOWN;
1235
1236   GNUTLS_VERSION_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id);
1237
1238   return ret;
1239 }
1240
1241 /**
1242  * gnutls_protocol_list:
1243  *
1244  * Get a list of supported protocols, e.g. SSL 3.0, TLS 1.0 etc.
1245  *
1246  * Returns: a zero-terminated list of #gnutls_protocol_t integers
1247  * indicating the available protocols.
1248  *
1249  **/
1250 const gnutls_protocol_t *
1251 gnutls_protocol_list (void)
1252 {
1253   return supported_protocols;
1254 }
1255
1256 int
1257 _gnutls_version_get_minor (gnutls_protocol_t version)
1258 {
1259   int ret = -1;
1260
1261   GNUTLS_VERSION_ALG_LOOP (ret = p->minor);
1262   return ret;
1263 }
1264
1265 gnutls_protocol_t
1266 _gnutls_version_get (int major, int minor)
1267 {
1268   int ret = -1;
1269
1270   GNUTLS_VERSION_LOOP (if ((p->major == major) && (p->minor == minor))
1271                        ret = p->id);
1272   return ret;
1273 }
1274
1275 int
1276 _gnutls_version_get_major (gnutls_protocol_t version)
1277 {
1278   int ret = -1;
1279
1280   GNUTLS_VERSION_ALG_LOOP (ret = p->major);
1281   return ret;
1282 }
1283
1284 /* Version Functions */
1285
1286 int
1287 _gnutls_version_is_supported (gnutls_session_t session,
1288                               const gnutls_protocol_t version)
1289 {
1290   int ret = 0;
1291
1292   GNUTLS_VERSION_ALG_LOOP (ret = p->supported);
1293   if (ret == 0)
1294     return 0;
1295
1296   if (_gnutls_version_priority (session, version) < 0)
1297     return 0;                   /* disabled by the user */
1298   else
1299     return 1;
1300 }
1301
1302
1303 /* This function determines if the version specified has a
1304    cipher-suite selected PRF hash function instead of the old
1305    hardcoded MD5+SHA1. */
1306 int
1307 _gnutls_version_has_selectable_prf (gnutls_protocol_t version)
1308 {
1309   return version == GNUTLS_TLS1_2;
1310 }
1311
1312 /* This function determines if the version specified has selectable
1313    signature/hash functions for certificate authentification. */
1314 int
1315 _gnutls_version_has_selectable_sighash (gnutls_protocol_t version)
1316 {
1317   return version == GNUTLS_TLS1_2;
1318 }
1319
1320 /* This function determines if the version specified has support for
1321    TLS extensions. */
1322 int
1323 _gnutls_version_has_extensions (gnutls_protocol_t version)
1324 {
1325   switch (version)
1326     {
1327     case GNUTLS_TLS1_0:
1328     case GNUTLS_TLS1_1:
1329     case GNUTLS_TLS1_2:
1330       return 1;
1331     default:
1332       return 0;
1333     }
1334 }
1335
1336 /* This function determines if the version specified has explicit IVs
1337    (for CBC attack prevention). */
1338 int
1339 _gnutls_version_has_explicit_iv (gnutls_protocol_t version)
1340 {
1341   switch (version)
1342     {
1343     case GNUTLS_TLS1_1:
1344     case GNUTLS_TLS1_2:
1345       return 1;
1346     default:
1347       return 0;
1348     }
1349 }
1350
1351 /* This function determines if the version specified can have
1352    non-minimal padding. */
1353 int
1354 _gnutls_version_has_variable_padding (gnutls_protocol_t version)
1355 {
1356   switch (version)
1357     {
1358     case GNUTLS_TLS1_0:
1359     case GNUTLS_TLS1_1:
1360     case GNUTLS_TLS1_2:
1361       return 1;
1362     default:
1363       return 0;
1364     }
1365 }
1366
1367 /* Type to KX mappings */
1368 gnutls_kx_algorithm_t
1369 _gnutls_map_kx_get_kx (gnutls_credentials_type_t type, int server)
1370 {
1371   gnutls_kx_algorithm_t ret = -1;
1372
1373   if (server)
1374     {
1375       GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1376     }
1377   else
1378     {
1379       GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1380     }
1381   return ret;
1382 }
1383
1384 gnutls_credentials_type_t
1385 _gnutls_map_kx_get_cred (gnutls_kx_algorithm_t algorithm, int server)
1386 {
1387   gnutls_credentials_type_t ret = -1;
1388   if (server)
1389     {
1390       GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret =
1391                           p->server_type);
1392     }
1393   else
1394     {
1395       GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret =
1396                           p->client_type);
1397     }
1398
1399   return ret;
1400 }
1401
1402
1403 /* Cipher Suite's functions */
1404 gnutls_cipher_algorithm_t
1405 _gnutls_cipher_suite_get_cipher_algo (const cipher_suite_st * suite)
1406 {
1407   int ret = 0;
1408   GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->block_algorithm);
1409   return ret;
1410 }
1411
1412 gnutls_protocol_t
1413 _gnutls_cipher_suite_is_version_supported (const cipher_suite_st * suite,
1414                                            gnutls_protocol_t version)
1415 {
1416   int ret = 0;
1417   GNUTLS_CIPHER_SUITE_ALG_LOOP ((version >= p->min_version
1418                                  && version <= p->max_version) ? (ret =
1419                                                                   1) : (ret =
1420                                                                         0));
1421   return ret;
1422 }
1423
1424 gnutls_kx_algorithm_t
1425 _gnutls_cipher_suite_get_kx_algo (const cipher_suite_st * suite)
1426 {
1427   int ret = 0;
1428
1429   GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->kx_algorithm);
1430   return ret;
1431
1432 }
1433
1434 gnutls_mac_algorithm_t
1435 _gnutls_cipher_suite_get_mac_algo (const cipher_suite_st * suite)
1436 {                               /* In bytes */
1437   int ret = 0;
1438   GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->mac_algorithm);
1439   return ret;
1440
1441 }
1442
1443 const char *
1444 _gnutls_cipher_suite_get_name (cipher_suite_st * suite)
1445 {
1446   const char *ret = NULL;
1447
1448   /* avoid prefix */
1449   GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->name + sizeof ("GNUTLS_") - 1);
1450
1451   return ret;
1452 }
1453
1454 /**
1455  * gnutls_cipher_suite_get_name:
1456  * @kx_algorithm: is a Key exchange algorithm
1457  * @cipher_algorithm: is a cipher algorithm
1458  * @mac_algorithm: is a MAC algorithm
1459  *
1460  * Note that the full cipher suite name must be prepended by TLS or
1461  * SSL depending of the protocol in use.
1462  *
1463  * Returns: a string that contains the name of a TLS cipher suite,
1464  * specified by the given algorithms, or %NULL.
1465  **/
1466 const char *
1467 gnutls_cipher_suite_get_name (gnutls_kx_algorithm_t kx_algorithm,
1468                               gnutls_cipher_algorithm_t cipher_algorithm,
1469                               gnutls_mac_algorithm_t mac_algorithm)
1470 {
1471   const char *ret = NULL;
1472
1473   /* avoid prefix */
1474   GNUTLS_CIPHER_SUITE_LOOP (if (kx_algorithm == p->kx_algorithm &&
1475                                 cipher_algorithm == p->block_algorithm &&
1476                                 mac_algorithm == p->mac_algorithm)
1477                             ret = p->name + sizeof ("GNUTLS_") - 1);
1478
1479   return ret;
1480 }
1481
1482 /**
1483  * gnutls_cipher_suite_info:
1484  * @idx: index of cipher suite to get information about, starts on 0.
1485  * @cs_id: output buffer with room for 2 bytes, indicating cipher suite value
1486  * @kx: output variable indicating key exchange algorithm, or %NULL.
1487  * @cipher: output variable indicating cipher, or %NULL.
1488  * @mac: output variable indicating MAC algorithm, or %NULL.
1489  * @version: output variable indicating TLS protocol version, or %NULL.
1490  *
1491  * Get information about supported cipher suites.  Use the function
1492  * iteratively to get information about all supported cipher suites.
1493  * Call with idx=0 to get information about first cipher suite, then
1494  * idx=1 and so on until the function returns NULL.
1495  *
1496  * Returns: the name of @idx cipher suite, and set the information
1497  * about the cipher suite in the output variables.  If @idx is out of
1498  * bounds, %NULL is returned.
1499  **/
1500 const char *
1501 gnutls_cipher_suite_info (size_t idx,
1502                           char *cs_id,
1503                           gnutls_kx_algorithm_t * kx,
1504                           gnutls_cipher_algorithm_t * cipher,
1505                           gnutls_mac_algorithm_t * mac,
1506                           gnutls_protocol_t * min_version)
1507 {
1508   if (idx >= CIPHER_SUITES_COUNT)
1509     return NULL;
1510
1511   if (cs_id)
1512     memcpy (cs_id, cs_algorithms[idx].id.suite, 2);
1513   if (kx)
1514     *kx = cs_algorithms[idx].kx_algorithm;
1515   if (cipher)
1516     *cipher = cs_algorithms[idx].block_algorithm;
1517   if (mac)
1518     *mac = cs_algorithms[idx].mac_algorithm;
1519   if (min_version)
1520     *min_version = cs_algorithms[idx].min_version;
1521
1522   return cs_algorithms[idx].name + sizeof ("GNU") - 1;
1523 }
1524
1525
1526 static inline int
1527 _gnutls_cipher_suite_is_ok (cipher_suite_st * suite)
1528 {
1529   size_t ret;
1530   const char *name = NULL;
1531
1532   GNUTLS_CIPHER_SUITE_ALG_LOOP (name = p->name);
1533   if (name != NULL)
1534     ret = 0;
1535   else
1536     ret = 1;
1537   return ret;
1538
1539 }
1540
1541 #define SWAP(x, y) memcpy(tmp,x,size); \
1542                    memcpy(x,y,size); \
1543                    memcpy(y,tmp,size);
1544
1545 #define MAX_ELEM_SIZE 4
1546 static inline int
1547 _gnutls_partition (gnutls_session_t session, void *_base,
1548                    size_t nmemb, size_t size,
1549                    int (*compar) (gnutls_session_t,
1550                                   const void *, const void *))
1551 {
1552   uint8_t *base = _base;
1553   uint8_t tmp[MAX_ELEM_SIZE];
1554   uint8_t ptmp[MAX_ELEM_SIZE];
1555   unsigned int pivot;
1556   unsigned int i, j;
1557   unsigned int full;
1558
1559   i = pivot = 0;
1560   j = full = (nmemb - 1) * size;
1561
1562   memcpy (ptmp, &base[0], size);        /* set pivot item */
1563
1564   while (i < j)
1565     {
1566       while ((compar (session, &base[i], ptmp) <= 0) && (i < full))
1567         {
1568           i += size;
1569         }
1570       while ((compar (session, &base[j], ptmp) >= 0) && (j > 0))
1571         j -= size;
1572
1573       if (i < j)
1574         {
1575           SWAP (&base[j], &base[i]);
1576         }
1577     }
1578
1579   if (j > pivot)
1580     {
1581       SWAP (&base[pivot], &base[j]);
1582       pivot = j;
1583     }
1584   else if (i < pivot)
1585     {
1586       SWAP (&base[pivot], &base[i]);
1587       pivot = i;
1588     }
1589   return pivot / size;
1590 }
1591
1592 static void
1593 _gnutls_qsort (gnutls_session_t session, void *_base, size_t nmemb,
1594                size_t size, int (*compar) (gnutls_session_t, const void *,
1595                                            const void *))
1596 {
1597   unsigned int pivot;
1598   char *base = _base;
1599   size_t snmemb = nmemb;
1600
1601 #ifdef DEBUG
1602   if (size > MAX_ELEM_SIZE)
1603     {
1604       gnutls_assert ();
1605       _gnutls_debug_log ("QSORT BUG\n");
1606       exit (1);
1607     }
1608 #endif
1609
1610   if (snmemb <= 1)
1611     return;
1612   pivot = _gnutls_partition (session, _base, nmemb, size, compar);
1613
1614   _gnutls_qsort (session, base, pivot < nmemb ? pivot + 1 : pivot, size,
1615                  compar);
1616   _gnutls_qsort (session, &base[(pivot + 1) * size], nmemb - pivot - 1,
1617                  size, compar);
1618 }
1619
1620
1621 /* a compare function for KX algorithms (using priorities). 
1622  * For use with qsort 
1623  */
1624 static int
1625 _gnutls_compare_algo (gnutls_session_t session, const void *i_A1,
1626                       const void *i_A2)
1627 {
1628   gnutls_kx_algorithm_t kA1 =
1629     _gnutls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A1);
1630   gnutls_kx_algorithm_t kA2 =
1631     _gnutls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A2);
1632   gnutls_cipher_algorithm_t cA1 =
1633     _gnutls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A1);
1634   gnutls_cipher_algorithm_t cA2 =
1635     _gnutls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A2);
1636   gnutls_mac_algorithm_t mA1 =
1637     _gnutls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A1);
1638   gnutls_mac_algorithm_t mA2 =
1639     _gnutls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A2);
1640
1641   int p1 = (_gnutls_kx_priority (session, kA1) + 1) * 64;
1642   int p2 = (_gnutls_kx_priority (session, kA2) + 1) * 64;
1643   p1 += (_gnutls_cipher_priority (session, cA1) + 1) * 8;
1644   p2 += (_gnutls_cipher_priority (session, cA2) + 1) * 8;
1645   p1 += _gnutls_mac_priority (session, mA1);
1646   p2 += _gnutls_mac_priority (session, mA2);
1647
1648   if (p1 > p2)
1649     {
1650       return 1;
1651     }
1652   else
1653     {
1654       if (p1 == p2)
1655         {
1656           return 0;
1657         }
1658       return -1;
1659     }
1660 }
1661
1662 #ifdef SORT_DEBUG
1663 static void
1664 _gnutls_bsort (gnutls_session_t session, void *_base, size_t nmemb,
1665                size_t size, int (*compar) (gnutls_session_t, const void *,
1666                                            const void *))
1667 {
1668   unsigned int i, j;
1669   int full = nmemb * size;
1670   char *base = _base;
1671   char tmp[MAX_ELEM_SIZE];
1672
1673   for (i = 0; i < full; i += size)
1674     {
1675       for (j = 0; j < full; j += size)
1676         {
1677           if (compar (session, &base[i], &base[j]) < 0)
1678             {
1679               SWAP (&base[j], &base[i]);
1680             }
1681         }
1682     }
1683
1684 }
1685 #endif
1686
1687 int
1688 _gnutls_supported_ciphersuites_sorted (gnutls_session_t session,
1689                                        cipher_suite_st ** ciphers)
1690 {
1691
1692 #ifdef SORT_DEBUG
1693   unsigned int i;
1694 #endif
1695   int count;
1696
1697   count = _gnutls_supported_ciphersuites (session, ciphers);
1698   if (count <= 0)
1699     {
1700       gnutls_assert ();
1701       return count;
1702     }
1703 #ifdef SORT_DEBUG
1704   _gnutls_debug_log ("Unsorted: \n");
1705   for (i = 0; i < count; i++)
1706     _gnutls_debug_log ("\t%d: %s\n", i,
1707                        _gnutls_cipher_suite_get_name ((*ciphers)[i]));
1708 #endif
1709
1710   _gnutls_qsort (session, *ciphers, count,
1711                  sizeof (cipher_suite_st), _gnutls_compare_algo);
1712
1713 #ifdef SORT_DEBUG
1714   _gnutls_debug_log ("Sorted: \n");
1715   for (i = 0; i < count; i++)
1716     _gnutls_debug_log ("\t%d: %s\n", i,
1717                        _gnutls_cipher_suite_get_name ((*ciphers)[i]));
1718 #endif
1719
1720   return count;
1721 }
1722
1723 int
1724 _gnutls_supported_ciphersuites (gnutls_session_t session,
1725                                 cipher_suite_st ** _ciphers)
1726 {
1727
1728   unsigned int i, ret_count, j;
1729   unsigned int count = CIPHER_SUITES_COUNT;
1730   cipher_suite_st *tmp_ciphers;
1731   cipher_suite_st *ciphers;
1732   gnutls_protocol_t version;
1733
1734   if (count == 0)
1735     {
1736       return 0;
1737     }
1738
1739   tmp_ciphers = gnutls_malloc (count * sizeof (cipher_suite_st));
1740   if (tmp_ciphers == NULL)
1741     return GNUTLS_E_MEMORY_ERROR;
1742
1743   ciphers = gnutls_malloc (count * sizeof (cipher_suite_st));
1744   if (ciphers == NULL)
1745     {
1746       gnutls_free (tmp_ciphers);
1747       return GNUTLS_E_MEMORY_ERROR;
1748     }
1749
1750   version = gnutls_protocol_get_version (session);
1751
1752   for (i = 0; i < count; i++)
1753     {
1754       memcpy (&tmp_ciphers[i], &cs_algorithms[i].id,
1755               sizeof (cipher_suite_st));
1756     }
1757
1758   for (i = j = 0; i < count; i++)
1759     {
1760       /* remove private cipher suites, if requested.
1761        */
1762       if (tmp_ciphers[i].suite[0] == 0xFF &&
1763           session->internals.enable_private == 0)
1764         continue;
1765
1766       /* remove cipher suites which do not support the
1767        * protocol version used.
1768        */
1769       if (_gnutls_cipher_suite_is_version_supported (&tmp_ciphers[i], version)
1770           == 0)
1771         continue;
1772
1773       if (_gnutls_kx_priority
1774           (session, _gnutls_cipher_suite_get_kx_algo (&tmp_ciphers[i])) < 0)
1775         continue;
1776       if (_gnutls_mac_priority
1777           (session, _gnutls_cipher_suite_get_mac_algo (&tmp_ciphers[i])) < 0)
1778         continue;
1779       if (_gnutls_cipher_priority
1780           (session,
1781            _gnutls_cipher_suite_get_cipher_algo (&tmp_ciphers[i])) < 0)
1782         continue;
1783
1784       memcpy (&ciphers[j], &tmp_ciphers[i], sizeof (cipher_suite_st));
1785       j++;
1786     }
1787
1788   ret_count = j;
1789
1790 #if 0                           /* expensive */
1791   if (ret_count > 0 && ret_count != count)
1792     {
1793       ciphers =
1794         gnutls_realloc_fast (ciphers, ret_count * sizeof (cipher_suite_st));
1795     }
1796   else
1797     {
1798       if (ret_count != count)
1799         {
1800           gnutls_free (ciphers);
1801           ciphers = NULL;
1802         }
1803     }
1804 #endif
1805
1806   gnutls_free (tmp_ciphers);
1807
1808   /* This function can no longer return 0 cipher suites.
1809    * It returns an error code instead.
1810    */
1811   if (ret_count == 0)
1812     {
1813       gnutls_assert ();
1814       gnutls_free (ciphers);
1815       return GNUTLS_E_NO_CIPHER_SUITES;
1816     }
1817   *_ciphers = ciphers;
1818   return ret_count;
1819 }
1820
1821 /**
1822  * gnutls_certificate_type_get_name:
1823  * @type: is a certificate type
1824  *
1825  * Convert a #gnutls_certificate_type_t type to a string.
1826  *
1827  * Returns: a string that contains the name of the specified
1828  *   certificate type, or %NULL in case of unknown types.
1829  **/
1830 const char *
1831 gnutls_certificate_type_get_name (gnutls_certificate_type_t type)
1832 {
1833   const char *ret = NULL;
1834
1835   if (type == GNUTLS_CRT_X509)
1836     ret = "X.509";
1837   if (type == GNUTLS_CRT_OPENPGP)
1838     ret = "OPENPGP";
1839
1840   return ret;
1841 }
1842
1843 /**
1844  * gnutls_certificate_type_get_id:
1845  * @name: is a certificate type name
1846  *
1847  * The names are compared in a case insensitive way.
1848  *
1849  * Returns: a #gnutls_certificate_type_t for the specified in a
1850  *   string certificate type, or %GNUTLS_CRT_UNKNOWN on error.
1851  **/
1852 gnutls_certificate_type_t
1853 gnutls_certificate_type_get_id (const char *name)
1854 {
1855   gnutls_certificate_type_t ret = GNUTLS_CRT_UNKNOWN;
1856
1857   if (strcasecmp (name, "X.509") == 0 || strcasecmp (name, "X509") == 0)
1858     return GNUTLS_CRT_X509;
1859   if (strcasecmp (name, "OPENPGP") == 0)
1860     return GNUTLS_CRT_OPENPGP;
1861
1862   return ret;
1863 }
1864
1865 static const gnutls_certificate_type_t supported_certificate_types[] = {
1866   GNUTLS_CRT_X509,
1867   GNUTLS_CRT_OPENPGP,
1868   0
1869 };
1870
1871 /**
1872  * gnutls_certificate_type_list:
1873  *
1874  * Get a list of certificate types.  Note that to be able to use
1875  * OpenPGP certificates, you must link to libgnutls-extra and call
1876  * gnutls_global_init_extra().
1877  *
1878  * Returns: a zero-terminated list of #gnutls_certificate_type_t
1879  *   integers indicating the available certificate types.
1880  **/
1881 const gnutls_certificate_type_t *
1882 gnutls_certificate_type_list (void)
1883 {
1884   return supported_certificate_types;
1885 }
1886
1887 /* returns the gnutls_pk_algorithm_t which is compatible with
1888  * the given gnutls_kx_algorithm_t.
1889  */
1890 gnutls_pk_algorithm_t
1891 _gnutls_map_pk_get_pk (gnutls_kx_algorithm_t kx_algorithm)
1892 {
1893   gnutls_pk_algorithm_t ret = -1;
1894
1895   GNUTLS_PK_MAP_ALG_LOOP (ret = p->pk_algorithm) return ret;
1896 }
1897
1898 /* Returns the encipher type for the given key exchange algorithm.
1899  * That one of CIPHER_ENCRYPT, CIPHER_SIGN, CIPHER_IGN.
1900  *
1901  * ex. GNUTLS_KX_RSA requires a certificate able to encrypt... so returns CIPHER_ENCRYPT.
1902  */
1903 enum encipher_type
1904 _gnutls_kx_encipher_type (gnutls_kx_algorithm_t kx_algorithm)
1905 {
1906   int ret = CIPHER_IGN;
1907   GNUTLS_PK_MAP_ALG_LOOP (ret = p->encipher_type) return ret;
1908
1909 }
1910
1911 /* signature algorithms;
1912  */
1913 struct gnutls_sign_entry
1914 {
1915   const char *name;
1916   const char *oid;
1917   gnutls_sign_algorithm_t id;
1918   gnutls_pk_algorithm_t pk;
1919   gnutls_mac_algorithm_t mac;
1920   /* See RFC 5246 HashAlgorithm and SignatureAlgorithm
1921      for values to use in aid struct. */
1922   const sign_algorithm_st aid;
1923 };
1924 typedef struct gnutls_sign_entry gnutls_sign_entry;
1925
1926 #define TLS_SIGN_AID_UNKNOWN {255, 255}
1927 static const sign_algorithm_st unknown_tls_aid = TLS_SIGN_AID_UNKNOWN;
1928
1929 static const gnutls_sign_entry sign_algorithms[] = {
1930   {"RSA-SHA1", SIG_RSA_SHA1_OID, GNUTLS_SIGN_RSA_SHA1, GNUTLS_PK_RSA,
1931    GNUTLS_MAC_SHA1, {2, 1}},
1932   {"RSA-SHA224", SIG_RSA_SHA224_OID, GNUTLS_SIGN_RSA_SHA224, GNUTLS_PK_RSA,
1933    GNUTLS_MAC_SHA224, {3, 1}},
1934   {"RSA-SHA256", SIG_RSA_SHA256_OID, GNUTLS_SIGN_RSA_SHA256, GNUTLS_PK_RSA,
1935    GNUTLS_MAC_SHA256, {4, 1}},
1936   {"RSA-SHA384", SIG_RSA_SHA384_OID, GNUTLS_SIGN_RSA_SHA384, GNUTLS_PK_RSA,
1937    GNUTLS_MAC_SHA384, {5, 1}},
1938   {"RSA-SHA512", SIG_RSA_SHA512_OID, GNUTLS_SIGN_RSA_SHA512, GNUTLS_PK_RSA,
1939    GNUTLS_MAC_SHA512, {6, 1}},
1940   {"RSA-RMD160", SIG_RSA_RMD160_OID, GNUTLS_SIGN_RSA_RMD160, GNUTLS_PK_RSA,
1941    GNUTLS_MAC_RMD160, TLS_SIGN_AID_UNKNOWN},
1942   {"DSA-SHA1", SIG_DSA_SHA1_OID, GNUTLS_SIGN_DSA_SHA1, GNUTLS_PK_DSA,
1943    GNUTLS_MAC_SHA1, {2, 2}},
1944   {"DSA-SHA224", SIG_DSA_SHA224_OID, GNUTLS_SIGN_DSA_SHA224, GNUTLS_PK_DSA,
1945    GNUTLS_MAC_SHA224, {3, 2}},
1946   {"DSA-SHA256", SIG_DSA_SHA256_OID, GNUTLS_SIGN_DSA_SHA256, GNUTLS_PK_DSA,
1947    GNUTLS_MAC_SHA256, {4, 2}},
1948   {"RSA-MD5", SIG_RSA_MD5_OID, GNUTLS_SIGN_RSA_MD5, GNUTLS_PK_RSA,
1949    GNUTLS_MAC_MD5, {1, 1}},
1950   {"RSA-MD2", SIG_RSA_MD2_OID, GNUTLS_SIGN_RSA_MD2, GNUTLS_PK_RSA,
1951    GNUTLS_MAC_MD2, TLS_SIGN_AID_UNKNOWN},
1952   {"GOST R 34.10-2001", SIG_GOST_R3410_2001_OID, 0, 0, 0,
1953    TLS_SIGN_AID_UNKNOWN},
1954   {"GOST R 34.10-94", SIG_GOST_R3410_94_OID, 0, 0, 0, TLS_SIGN_AID_UNKNOWN},
1955   {0, 0, 0, 0, 0, TLS_SIGN_AID_UNKNOWN}
1956 };
1957
1958 /* Keep the contents of this struct the same as the previous one. */
1959 static const gnutls_sign_algorithm_t supported_sign[] = {
1960   GNUTLS_SIGN_RSA_SHA1,
1961   GNUTLS_SIGN_RSA_SHA224,
1962   GNUTLS_SIGN_RSA_SHA256,
1963   GNUTLS_SIGN_RSA_SHA384,
1964   GNUTLS_SIGN_RSA_SHA512,
1965   GNUTLS_SIGN_RSA_RMD160,
1966   GNUTLS_SIGN_DSA_SHA1,
1967   GNUTLS_SIGN_DSA_SHA224,
1968   GNUTLS_SIGN_DSA_SHA256,
1969   GNUTLS_SIGN_RSA_MD5,
1970   GNUTLS_SIGN_RSA_MD2,
1971   0
1972 };
1973
1974 #define GNUTLS_SIGN_LOOP(b) \
1975   do {                                                                 \
1976     const gnutls_sign_entry *p;                                        \
1977     for(p = sign_algorithms; p->name != NULL; p++) { b ; }             \
1978   } while (0)
1979
1980 #define GNUTLS_SIGN_ALG_LOOP(a) \
1981   GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } )
1982
1983 /**
1984  * gnutls_sign_algorithm_get_name:
1985  * @sign: is a sign algorithm
1986  *
1987  * Convert a #gnutls_sign_algorithm_t value to a string.
1988  *
1989  * Returns: a string that contains the name of the specified sign
1990  *   algorithm, or %NULL.
1991  **/
1992 const char *
1993 gnutls_sign_algorithm_get_name (gnutls_sign_algorithm_t sign)
1994 {
1995   const char *ret = NULL;
1996
1997   /* avoid prefix */
1998   GNUTLS_SIGN_ALG_LOOP (ret = p->name);
1999
2000   return ret;
2001 }
2002
2003 /**
2004  * gnutls_sign_list:
2005  *
2006  * Get a list of supported public key signature algorithms.
2007  *
2008  * Returns: a zero-terminated list of #gnutls_sign_algorithm_t
2009  *   integers indicating the available ciphers.
2010  *
2011  **/
2012 const gnutls_sign_algorithm_t *
2013 gnutls_sign_list (void)
2014 {
2015   return supported_sign;
2016 }
2017
2018 /**
2019  * gnutls_sign_get_id:
2020  * @name: is a MAC algorithm name
2021  *
2022  * The names are compared in a case insensitive way.
2023  *
2024  * Returns: return a #gnutls_sign_algorithm_t value corresponding to
2025  *   the specified cipher, or %GNUTLS_SIGN_UNKNOWN on error.
2026  **/
2027 gnutls_sign_algorithm_t
2028 gnutls_sign_get_id (const char *name)
2029 {
2030   gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
2031
2032   GNUTLS_SIGN_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id);
2033
2034   return ret;
2035
2036 }
2037
2038 /**
2039  * gnutls_sign_get_name:
2040  * @algorithm: is a public key signature algorithm
2041  *
2042  * Convert a #gnutls_sign_algorithm_t value to a string.
2043  *
2044  * Returns: a pointer to a string that contains the name of the
2045  *   specified public key signature algorithm, or %NULL.
2046  *
2047  * Since: 2.6.0
2048  **/
2049 const char *
2050 gnutls_sign_get_name (gnutls_sign_algorithm_t algorithm)
2051 {
2052   const char *ret = "SIGN_UNKNOWN";
2053
2054   GNUTLS_SIGN_LOOP (if (p->id == algorithm) ret = p->name);
2055
2056   return ret;
2057 }
2058
2059 gnutls_sign_algorithm_t
2060 _gnutls_x509_oid2sign_algorithm (const char *oid)
2061 {
2062   gnutls_sign_algorithm_t ret = 0;
2063
2064   GNUTLS_SIGN_LOOP (if (p->oid && strcmp (oid, p->oid) == 0)
2065                     {
2066                     ret = p->id; break;}
2067   );
2068
2069   if (ret == 0)
2070     {
2071       _gnutls_x509_log ("Unknown SIGN OID: '%s'\n", oid);
2072       return GNUTLS_SIGN_UNKNOWN;
2073     }
2074   return ret;
2075 }
2076
2077 gnutls_sign_algorithm_t
2078 _gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk, gnutls_mac_algorithm_t mac)
2079 {
2080   gnutls_sign_algorithm_t ret = 0;
2081
2082   GNUTLS_SIGN_LOOP (if (pk == p->pk && mac == p->mac)
2083                     {
2084                     ret = p->id; break;}
2085   );
2086
2087   if (ret == 0)
2088     return GNUTLS_SIGN_UNKNOWN;
2089   return ret;
2090 }
2091
2092 const char *
2093 _gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t pk,
2094                           gnutls_mac_algorithm_t mac)
2095 {
2096   gnutls_sign_algorithm_t sign;
2097   const char *ret = NULL;
2098
2099   sign = _gnutls_x509_pk_to_sign (pk, mac);
2100   if (sign == GNUTLS_SIGN_UNKNOWN)
2101     return NULL;
2102
2103   GNUTLS_SIGN_ALG_LOOP (ret = p->oid);
2104   return ret;
2105 }
2106
2107 gnutls_mac_algorithm_t
2108 _gnutls_sign_get_hash_algorithm (gnutls_sign_algorithm_t sign)
2109 {
2110   gnutls_mac_algorithm_t ret = GNUTLS_DIG_UNKNOWN;
2111
2112   GNUTLS_SIGN_ALG_LOOP (ret = p->mac);
2113
2114   return ret;
2115 }
2116
2117 gnutls_pk_algorithm_t
2118 _gnutls_sign_get_pk_algorithm (gnutls_sign_algorithm_t sign)
2119 {
2120   gnutls_pk_algorithm_t ret = GNUTLS_PK_UNKNOWN;
2121
2122   GNUTLS_SIGN_ALG_LOOP (ret = p->pk);
2123
2124   return ret;
2125 }
2126
2127 gnutls_sign_algorithm_t
2128 _gnutls_tls_aid_to_sign (const sign_algorithm_st * aid)
2129 {
2130   gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
2131
2132   if (memcmp(aid, &unknown_tls_aid, sizeof(*aid))==0)
2133     return ret;
2134
2135   GNUTLS_SIGN_LOOP (if (p->aid.hash_algorithm == aid->hash_algorithm
2136                         && p->aid.sign_algorithm == aid->sign_algorithm)
2137                     {
2138                       ret = p->id; break;
2139                     }
2140   );
2141
2142
2143   return ret;
2144 }
2145
2146 /* Returns NULL if a valid AID is not found
2147  */
2148 const sign_algorithm_st*
2149 _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign)
2150 {
2151   const sign_algorithm_st * ret = NULL;
2152
2153   GNUTLS_SIGN_ALG_LOOP (ret = &p->aid);
2154
2155   if (ret != NULL && memcmp(ret, &unknown_tls_aid, sizeof(*ret))==0)
2156     return NULL;
2157
2158   return ret;
2159 }
2160
2161
2162
2163 /* pk algorithms;
2164  */
2165 struct gnutls_pk_entry
2166 {
2167   const char *name;
2168   const char *oid;
2169   gnutls_pk_algorithm_t id;
2170 };
2171 typedef struct gnutls_pk_entry gnutls_pk_entry;
2172
2173 static const gnutls_pk_entry pk_algorithms[] = {
2174   /* having duplicate entries is ok, as long as the one
2175    * we want to return OID from is first */
2176   {"UNKNOWN", NULL, GNUTLS_PK_UNKNOWN},
2177   {"RSA", PK_PKIX1_RSA_OID, GNUTLS_PK_RSA},
2178   {"RSA (X.509)", PK_X509_RSA_OID, GNUTLS_PK_RSA},      /* some certificates use this OID for RSA */
2179   {"RSA (MD5)", SIG_RSA_MD5_OID, GNUTLS_PK_RSA},        /* some other broken certificates set RSA with MD5 as an indicator of RSA */
2180   {"RSA (SHA1)", SIG_RSA_SHA1_OID, GNUTLS_PK_RSA},      /* some other broken certificates set RSA with SHA1 as an indicator of RSA */
2181   {"DSA", PK_DSA_OID, GNUTLS_PK_DSA},
2182   {"GOST R 34.10-2001", PK_GOST_R3410_2001_OID, GNUTLS_PK_UNKNOWN},
2183   {"GOST R 34.10-94", PK_GOST_R3410_94_OID, GNUTLS_PK_UNKNOWN},
2184   {0, 0, 0}
2185 };
2186
2187 /**
2188  * gnutls_pk_algorithm_get_name:
2189  * @algorithm: is a pk algorithm
2190  *
2191  * Convert a #gnutls_pk_algorithm_t value to a string.
2192  *
2193  * Returns: a string that contains the name of the specified public
2194  *   key algorithm, or %NULL.
2195  **/
2196 const char *
2197 gnutls_pk_algorithm_get_name (gnutls_pk_algorithm_t algorithm)
2198 {
2199   const char *ret = NULL;
2200   const gnutls_pk_entry *p;
2201
2202   for (p = pk_algorithms; p->name != NULL; p++)
2203     if (p->id == algorithm)
2204       {
2205         ret = p->name;
2206         break;
2207       }
2208
2209   return ret;
2210 }
2211
2212 /**
2213  * gnutls_pk_list:
2214  *
2215  * Get a list of supported public key algorithms.
2216  *
2217  * Returns: a zero-terminated list of #gnutls_pk_algorithm_t integers
2218  *   indicating the available ciphers.
2219  *
2220  * Since: 2.6.0
2221  **/
2222 const gnutls_pk_algorithm_t *
2223 gnutls_pk_list (void)
2224 {
2225   static const gnutls_pk_algorithm_t supported_pks[] = {
2226     GNUTLS_PK_RSA,
2227     GNUTLS_PK_DSA,
2228     /* GNUTLS_PK_DH is not returned because it is not
2229      * a real public key algorithm. I.e. cannot be used
2230      * as a public key algorithm of a certificate.
2231      */
2232     0
2233   };
2234
2235   return supported_pks;
2236 }
2237
2238 /**
2239  * gnutls_pk_get_id:
2240  * @name: is a string containing a public key algorithm name.
2241  *
2242  * Convert a string to a #gnutls_pk_algorithm_t value.  The names are
2243  * compared in a case insensitive way.  For example,
2244  * gnutls_pk_get_id("RSA") will return %GNUTLS_PK_RSA.
2245  *
2246  * Returns: a #gnutls_pk_algorithm_t id of the specified public key
2247  *   algorithm string, or %GNUTLS_PK_UNKNOWN on failures.
2248  *
2249  * Since: 2.6.0
2250  **/
2251 gnutls_pk_algorithm_t
2252 gnutls_pk_get_id (const char *name)
2253 {
2254   gnutls_pk_algorithm_t ret = GNUTLS_PK_UNKNOWN;
2255   const gnutls_pk_entry *p;
2256
2257   for (p = pk_algorithms; p->name != NULL; p++)
2258     if (name && strcmp (p->name, name) == 0)
2259       {
2260         ret = p->id;
2261         break;
2262       }
2263
2264   return ret;
2265 }
2266
2267 /**
2268  * gnutls_pk_get_name:
2269  * @algorithm: is a public key algorithm
2270  *
2271  * Convert a #gnutls_pk_algorithm_t value to a string.
2272  *
2273  * Returns: a pointer to a string that contains the name of the
2274  *   specified public key algorithm, or %NULL.
2275  *
2276  * Since: 2.6.0
2277  **/
2278 const char *
2279 gnutls_pk_get_name (gnutls_pk_algorithm_t algorithm)
2280 {
2281   const char *ret = "Unknown";
2282   const gnutls_pk_entry *p;
2283
2284   for (p = pk_algorithms; p->name != NULL; p++)
2285     if (algorithm == p->id)
2286       {
2287         ret = p->name;
2288         break;
2289       }
2290
2291   return ret;
2292 }
2293
2294 gnutls_pk_algorithm_t
2295 _gnutls_x509_oid2pk_algorithm (const char *oid)
2296 {
2297   gnutls_pk_algorithm_t ret = GNUTLS_PK_UNKNOWN;
2298   const gnutls_pk_entry *p;
2299
2300   for (p = pk_algorithms; p->name != NULL; p++)
2301     if (p->oid && strcmp (p->oid, oid) == 0)
2302       {
2303         ret = p->id;
2304         break;
2305       }
2306
2307   return ret;
2308 }
2309
2310 const char *
2311 _gnutls_x509_pk_to_oid (gnutls_pk_algorithm_t algorithm)
2312 {
2313   const char *ret = NULL;
2314   const gnutls_pk_entry *p;
2315
2316   for (p = pk_algorithms; p->name != NULL; p++)
2317     if (p->id == algorithm)
2318       {
2319         ret = p->oid;
2320         break;
2321       }
2322
2323   return ret;
2324 }
2325
2326 /**
2327  * gnutls_sec_param_to_pk_bits:
2328  * @algo: is a public key algorithm
2329  * @param: is a security parameter
2330  *
2331  * When generating private and public key pairs a difficult question
2332  * is which size of "bits" the modulus will be in RSA and the group size
2333  * in DSA. The easy answer is 1024, which is also wrong. This function
2334  * will convert a human understandable security parameter to an
2335  * appropriate size for the specific algorithm.
2336  *
2337  * Returns: The number of bits, or zero.
2338  *
2339  **/
2340 unsigned int
2341 gnutls_sec_param_to_pk_bits (gnutls_pk_algorithm_t algo,
2342                              gnutls_sec_param_t param)
2343 {
2344   unsigned int ret = 0;
2345
2346   /* handle DSA differently */
2347   if (algo == GNUTLS_PK_DSA)
2348     {
2349       GNUTLS_SEC_PARAM_LOOP (if (p->sec_param == param)
2350                              {
2351                              ret = p->dsa_bits; break;}
2352       );
2353       return ret;
2354     }
2355
2356   GNUTLS_SEC_PARAM_LOOP (if (p->sec_param == param)
2357                          {
2358                          ret = p->pk_bits; break;}
2359   );
2360
2361   return ret;
2362 }
2363
2364 /* Returns the corresponding size for subgroup bits (q),
2365  * given the group bits (p).
2366  */
2367 unsigned int
2368 _gnutls_pk_bits_to_subgroup_bits (unsigned int pk_bits)
2369 {
2370   unsigned int ret = 0;
2371
2372   GNUTLS_SEC_PARAM_LOOP (if (p->pk_bits >= pk_bits)
2373                          {
2374                          ret = p->subgroup_bits; break;}
2375   );
2376
2377   return ret;
2378 }
2379
2380 /**
2381  * gnutls_sec_param_get_name:
2382  * @param: is a security parameter
2383  *
2384  * Convert a #gnutls_sec_param_t value to a string.
2385  *
2386  * Returns: a pointer to a string that contains the name of the
2387  *   specified public key algorithm, or %NULL.
2388  *
2389  **/
2390 const char *
2391 gnutls_sec_param_get_name (gnutls_sec_param_t param)
2392 {
2393   const char *ret = "Unknown";
2394
2395   GNUTLS_SEC_PARAM_LOOP (if (p->sec_param == param)
2396                          {
2397                          ret = p->name; break;}
2398   );
2399
2400   return ret;
2401 }
2402
2403 /**
2404  * gnutls_pk_bits_to_sec_param:
2405  * @algo: is a public key algorithm
2406  * @bits: is the number of bits
2407  *
2408  * This is the inverse of gnutls_sec_param_to_pk_bits(). Given an algorithm
2409  * and the number of bits, it will return the security parameter. This is
2410  * a rough indication.
2411  *
2412  * Returns: The security parameter.
2413  *
2414  **/
2415 gnutls_sec_param_t
2416 gnutls_pk_bits_to_sec_param (gnutls_pk_algorithm_t algo, unsigned int bits)
2417 {
2418   gnutls_sec_param_t ret = GNUTLS_SEC_PARAM_WEAK;
2419
2420   GNUTLS_SEC_PARAM_LOOP (if (p->pk_bits > bits)
2421                          {
2422                          break;}
2423                          ret = p->sec_param;);
2424
2425   return ret;
2426 }