Guile: Fix `x509-certificate-dn-oid' and related functions.
[gnutls.git] / lib / gnutls_algorithms.c
blob7ec696e2536b3c909dd9516c0f3aae01f7c44766
1 /*
2 * Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
25 #include "gnutls_int.h"
26 #include "gnutls_algorithms.h"
27 #include "gnutls_errors.h"
28 #include "gnutls_cert.h"
29 #include <x509/common.h>
31 /* Cred type mappings to KX algorithms
32 * FIXME: The mappings are not 1-1. Some KX such as SRP_RSA require
33 * more than one credentials type.
35 typedef struct
37 gnutls_kx_algorithm_t algorithm;
38 gnutls_credentials_type_t client_type;
39 gnutls_credentials_type_t server_type; /* The type of credentials a server
40 * needs to set */
41 } gnutls_cred_map;
43 static const gnutls_cred_map cred_mappings[] = {
44 {GNUTLS_KX_ANON_DH, GNUTLS_CRD_ANON, GNUTLS_CRD_ANON},
45 {GNUTLS_KX_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
46 {GNUTLS_KX_RSA_EXPORT, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
47 {GNUTLS_KX_DHE_DSS, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
48 {GNUTLS_KX_DHE_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
49 {GNUTLS_KX_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK},
50 {GNUTLS_KX_DHE_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK},
51 {GNUTLS_KX_SRP, GNUTLS_CRD_SRP, GNUTLS_CRD_SRP},
52 {GNUTLS_KX_SRP_RSA, GNUTLS_CRD_SRP, GNUTLS_CRD_CERTIFICATE},
53 {GNUTLS_KX_SRP_DSS, GNUTLS_CRD_SRP, GNUTLS_CRD_CERTIFICATE},
54 {0, 0, 0}
57 #define GNUTLS_KX_MAP_LOOP(b) \
58 const gnutls_cred_map *p; \
59 for(p = cred_mappings; p->algorithm != 0; p++) { b ; }
61 #define GNUTLS_KX_MAP_ALG_LOOP_SERVER(a) \
62 GNUTLS_KX_MAP_LOOP( if(p->server_type == type) { a; break; })
64 #define GNUTLS_KX_MAP_ALG_LOOP_CLIENT(a) \
65 GNUTLS_KX_MAP_LOOP( if(p->client_type == type) { a; break; })
67 /* KX mappings to PK algorithms */
68 typedef struct
70 gnutls_kx_algorithm_t kx_algorithm;
71 gnutls_pk_algorithm_t pk_algorithm;
72 enum encipher_type encipher_type; /* CIPHER_ENCRYPT if this algorithm is to be used
73 * for encryption, CIPHER_SIGN if signature only,
74 * CIPHER_IGN if this does not apply at all.
76 * This is useful to certificate cipher suites, which check
77 * against the certificate key usage bits.
79 } gnutls_pk_map;
81 /* This table maps the Key exchange algorithms to
82 * the certificate algorithms. Eg. if we have
83 * RSA algorithm in the certificate then we can
84 * use GNUTLS_KX_RSA or GNUTLS_KX_DHE_RSA.
86 static const gnutls_pk_map pk_mappings[] = {
87 {GNUTLS_KX_RSA, GNUTLS_PK_RSA, CIPHER_ENCRYPT},
88 {GNUTLS_KX_RSA_EXPORT, GNUTLS_PK_RSA, CIPHER_SIGN},
89 {GNUTLS_KX_DHE_RSA, GNUTLS_PK_RSA, CIPHER_SIGN},
90 {GNUTLS_KX_SRP_RSA, GNUTLS_PK_RSA, CIPHER_SIGN},
91 {GNUTLS_KX_DHE_DSS, GNUTLS_PK_DSA, CIPHER_SIGN},
92 {GNUTLS_KX_SRP_DSS, GNUTLS_PK_DSA, CIPHER_SIGN},
93 {0, 0, 0}
96 #define GNUTLS_PK_MAP_LOOP(b) \
97 const gnutls_pk_map *p; \
98 for(p = pk_mappings; p->kx_algorithm != 0; p++) { b }
100 #define GNUTLS_PK_MAP_ALG_LOOP(a) \
101 GNUTLS_PK_MAP_LOOP( if(p->kx_algorithm == kx_algorithm) { a; break; })
105 /* TLS Versions */
107 typedef struct
109 const char *name;
110 gnutls_protocol_t id; /* gnutls internal version number */
111 int major; /* defined by the protocol */
112 int minor; /* defined by the protocol */
113 int supported; /* 0 not supported, > 0 is supported */
114 } gnutls_version_entry;
116 static const gnutls_version_entry sup_versions[] = {
117 {"SSL 3.0", GNUTLS_SSL3, 3, 0, 1},
118 {"TLS 1.0", GNUTLS_TLS1, 3, 1, 1},
119 {"TLS 1.1", GNUTLS_TLS1_1, 3, 2, 1},
120 {"TLS 1.2", GNUTLS_TLS1_2, 3, 3, 1},
121 {0, 0, 0, 0, 0}
124 /* Keep the contents of this struct the same as the previous one. */
125 static const gnutls_protocol_t supported_protocols[] = {
126 GNUTLS_SSL3,
127 GNUTLS_TLS1,
128 GNUTLS_TLS1_1,
129 GNUTLS_TLS1_2,
133 #define GNUTLS_VERSION_LOOP(b) \
134 const gnutls_version_entry *p; \
135 for(p = sup_versions; p->name != NULL; p++) { b ; }
137 #define GNUTLS_VERSION_ALG_LOOP(a) \
138 GNUTLS_VERSION_LOOP( if(p->id == version) { a; break; })
141 struct gnutls_cipher_entry
143 const char *name;
144 gnutls_cipher_algorithm_t id;
145 uint16_t blocksize;
146 uint16_t keysize;
147 cipher_type_t block;
148 uint16_t iv;
149 int export_flag; /* 0 non export */
151 typedef struct gnutls_cipher_entry gnutls_cipher_entry;
153 /* Note that all algorithms are in CBC or STREAM modes.
154 * Do not add any algorithms in other modes (avoid modified algorithms).
155 * View first: "The order of encryption and authentication for
156 * protecting communications" by Hugo Krawczyk - CRYPTO 2001
158 static const gnutls_cipher_entry algorithms[] = {
159 {"AES 256 CBC", GNUTLS_CIPHER_AES_256_CBC, 16, 32, CIPHER_BLOCK, 16, 0},
160 {"AES 128 CBC", GNUTLS_CIPHER_AES_128_CBC, 16, 16, CIPHER_BLOCK, 16, 0},
161 {"3DES 168 CBC", GNUTLS_CIPHER_3DES_CBC, 8, 24, CIPHER_BLOCK, 8, 0},
162 {"DES CBC", GNUTLS_CIPHER_DES_CBC, 8, 8, CIPHER_BLOCK, 8, 0},
163 {"ARCFOUR 128", GNUTLS_CIPHER_ARCFOUR_128, 1, 16, CIPHER_STREAM, 0, 0},
164 {"ARCFOUR 40", GNUTLS_CIPHER_ARCFOUR_40, 1, 5, CIPHER_STREAM, 0, 1},
165 {"RC2 40", GNUTLS_CIPHER_RC2_40_CBC, 8, 5, CIPHER_BLOCK, 8, 1},
166 {"NULL", GNUTLS_CIPHER_NULL, 1, 0, CIPHER_STREAM, 0, 0},
167 {0, 0, 0, 0, 0, 0, 0}
170 /* Keep the contents of this struct the same as the previous one. */
171 static const gnutls_cipher_algorithm_t supported_ciphers[] = {
172 GNUTLS_CIPHER_AES_256_CBC,
173 GNUTLS_CIPHER_AES_128_CBC,
174 GNUTLS_CIPHER_3DES_CBC,
175 GNUTLS_CIPHER_DES_CBC,
176 GNUTLS_CIPHER_ARCFOUR_128,
177 GNUTLS_CIPHER_ARCFOUR_40,
178 GNUTLS_CIPHER_RC2_40_CBC,
179 GNUTLS_CIPHER_NULL,
183 #define GNUTLS_LOOP(b) \
184 const gnutls_cipher_entry *p; \
185 for(p = algorithms; p->name != NULL; p++) { b ; }
187 #define GNUTLS_ALG_LOOP(a) \
188 GNUTLS_LOOP( if(p->id == algorithm) { a; break; } )
191 struct gnutls_hash_entry
193 const char *name;
194 const char *oid;
195 gnutls_mac_algorithm_t id;
197 typedef struct gnutls_hash_entry gnutls_hash_entry;
199 static const gnutls_hash_entry hash_algorithms[] = {
200 {"SHA", HASH_OID_SHA1, GNUTLS_MAC_SHA1},
201 {"MD5", HASH_OID_MD5, GNUTLS_MAC_MD5},
202 {"SHA256", HASH_OID_SHA256, GNUTLS_MAC_SHA256},
203 {"SHA384", HASH_OID_SHA384, GNUTLS_MAC_SHA384},
204 {"SHA512", HASH_OID_SHA512, GNUTLS_MAC_SHA512},
205 {"MD2", HASH_OID_MD2, GNUTLS_MAC_MD2},
206 {"RIPEMD160", HASH_OID_RMD160, GNUTLS_MAC_RMD160},
207 {"NULL", NULL, GNUTLS_MAC_NULL},
208 {0, 0, 0}
211 /* Keep the contents of this struct the same as the previous one. */
212 static const gnutls_mac_algorithm_t supported_macs[] = {
213 GNUTLS_MAC_SHA1,
214 GNUTLS_MAC_MD5,
215 GNUTLS_MAC_SHA256,
216 GNUTLS_MAC_SHA384,
217 GNUTLS_MAC_SHA512,
218 GNUTLS_MAC_MD2,
219 GNUTLS_MAC_RMD160,
220 GNUTLS_MAC_NULL,
224 #define GNUTLS_HASH_LOOP(b) \
225 const gnutls_hash_entry *p; \
226 for(p = hash_algorithms; p->name != NULL; p++) { b ; }
228 #define GNUTLS_HASH_ALG_LOOP(a) \
229 GNUTLS_HASH_LOOP( if(p->id == algorithm) { a; break; } )
232 /* Compression Section */
233 #define GNUTLS_COMPRESSION_ENTRY(name, id, wb, ml, cl) \
234 { #name, name, id, wb, ml, cl}
237 #define MAX_COMP_METHODS 5
238 const int _gnutls_comp_algorithms_size = MAX_COMP_METHODS;
240 /* the compression entry is defined in gnutls_algorithms.h */
242 gnutls_compression_entry _gnutls_compression_algorithms[MAX_COMP_METHODS] = {
243 GNUTLS_COMPRESSION_ENTRY (GNUTLS_COMP_NULL, 0x00, 0, 0, 0),
244 #ifdef HAVE_LIBZ
245 /* draft-ietf-tls-compression-02 */
246 GNUTLS_COMPRESSION_ENTRY (GNUTLS_COMP_DEFLATE, 0x01, 15, 8, 3),
247 #endif
248 {0, 0, 0, 0, 0, 0}
251 static const gnutls_compression_method_t supported_compressions[] = {
252 #ifdef USE_LZO
253 GNUTLS_COMP_LZO,
254 #endif
255 #ifdef HAVE_LIBZ
256 GNUTLS_COMP_DEFLATE,
257 #endif
258 GNUTLS_COMP_NULL,
262 #define GNUTLS_COMPRESSION_LOOP(b) \
263 const gnutls_compression_entry *p; \
264 for(p = _gnutls_compression_algorithms; p->name != NULL; p++) { b ; }
265 #define GNUTLS_COMPRESSION_ALG_LOOP(a) \
266 GNUTLS_COMPRESSION_LOOP( if(p->id == algorithm) { a; break; } )
267 #define GNUTLS_COMPRESSION_ALG_LOOP_NUM(a) \
268 GNUTLS_COMPRESSION_LOOP( if(p->num == num) { a; break; } )
271 /* Key Exchange Section */
274 extern mod_auth_st rsa_auth_struct;
275 extern mod_auth_st rsa_export_auth_struct;
276 extern mod_auth_st dhe_rsa_auth_struct;
277 extern mod_auth_st dhe_dss_auth_struct;
278 extern mod_auth_st anon_auth_struct;
279 extern mod_auth_st srp_auth_struct;
280 extern mod_auth_st psk_auth_struct;
281 extern mod_auth_st dhe_psk_auth_struct;
282 extern mod_auth_st srp_rsa_auth_struct;
283 extern mod_auth_st srp_dss_auth_struct;
285 struct gnutls_kx_algo_entry
287 const char *name;
288 gnutls_kx_algorithm_t algorithm;
289 mod_auth_st *auth_struct;
290 int needs_dh_params;
291 int needs_rsa_params;
293 typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry;
295 static const gnutls_kx_algo_entry _gnutls_kx_algorithms[] = {
296 #ifdef ENABLE_ANON
297 {"Anon DH", GNUTLS_KX_ANON_DH, &anon_auth_struct, 1, 0},
298 #endif
299 {"RSA", GNUTLS_KX_RSA, &rsa_auth_struct, 0, 0},
300 {"RSA EXPORT", GNUTLS_KX_RSA_EXPORT, &rsa_export_auth_struct, 0,
301 1 /* needs RSA params */ },
302 {"DHE RSA", GNUTLS_KX_DHE_RSA, &dhe_rsa_auth_struct, 1, 0},
303 {"DHE DSS", GNUTLS_KX_DHE_DSS, &dhe_dss_auth_struct, 1, 0},
305 #ifdef ENABLE_SRP
306 {"SRP DSS", GNUTLS_KX_SRP_DSS, &srp_dss_auth_struct, 0, 0},
307 {"SRP RSA", GNUTLS_KX_SRP_RSA, &srp_rsa_auth_struct, 0, 0},
308 {"SRP", GNUTLS_KX_SRP, &srp_auth_struct, 0, 0},
309 #endif
310 #ifdef ENABLE_PSK
311 {"PSK", GNUTLS_KX_PSK, &psk_auth_struct, 0, 0},
312 {"DHE PSK", GNUTLS_KX_DHE_PSK, &dhe_psk_auth_struct,
313 1 /* needs DHE params */ , 0},
314 #endif
315 {0, 0, 0, 0, 0}
318 /* Keep the contents of this struct the same as the previous one. */
319 static const gnutls_kx_algorithm_t supported_kxs[] = {
320 #ifdef ENABLE_ANON
321 GNUTLS_KX_ANON_DH,
322 #endif
323 GNUTLS_KX_RSA,
324 GNUTLS_KX_RSA_EXPORT,
325 GNUTLS_KX_DHE_RSA,
326 GNUTLS_KX_DHE_DSS,
327 #ifdef ENABLE_SRP
328 GNUTLS_KX_SRP_DSS,
329 GNUTLS_KX_SRP_RSA,
330 GNUTLS_KX_SRP,
331 #endif
332 #ifdef ENABLE_PSK
333 GNUTLS_KX_PSK,
334 GNUTLS_KX_DHE_PSK,
335 #endif
339 #define GNUTLS_KX_LOOP(b) \
340 const gnutls_kx_algo_entry *p; \
341 for(p = _gnutls_kx_algorithms; p->name != NULL; p++) { b ; }
343 #define GNUTLS_KX_ALG_LOOP(a) \
344 GNUTLS_KX_LOOP( if(p->algorithm == algorithm) { a; break; } )
348 /* Cipher SUITES */
349 #define GNUTLS_CIPHER_SUITE_ENTRY( name, block_algorithm, kx_algorithm, mac_algorithm, version ) \
350 { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, version }
352 typedef struct
354 const char *name;
355 cipher_suite_st id;
356 gnutls_cipher_algorithm_t block_algorithm;
357 gnutls_kx_algorithm_t kx_algorithm;
358 gnutls_mac_algorithm_t mac_algorithm;
359 gnutls_protocol_t version; /* this cipher suite is supported
360 * from 'version' and above;
362 } gnutls_cipher_suite_entry;
364 /* RSA with NULL cipher and MD5 MAC
365 * for test purposes.
367 #define GNUTLS_RSA_NULL_MD5 { 0x00, 0x01 }
370 /* ANONymous cipher suites.
373 #define GNUTLS_ANON_DH_3DES_EDE_CBC_SHA1 { 0x00, 0x1B }
374 #define GNUTLS_ANON_DH_ARCFOUR_MD5 { 0x00, 0x18 }
376 /* rfc3268: */
377 #define GNUTLS_ANON_DH_AES_128_CBC_SHA1 { 0x00, 0x34 }
378 #define GNUTLS_ANON_DH_AES_256_CBC_SHA1 { 0x00, 0x3A }
380 /* PSK (not in TLS 1.0)
381 * draft-ietf-tls-psk:
383 #define GNUTLS_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8A }
384 #define GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8B }
385 #define GNUTLS_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x8C }
386 #define GNUTLS_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x8D }
388 #define GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8E }
389 #define GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8F }
390 #define GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x90 }
391 #define GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x91 }
394 /* SRP (not in TLS 1.0)
395 * draft-ietf-tls-srp-14:
397 #define GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1A }
398 #define GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1B }
399 #define GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1 { 0xC0, 0x1C }
401 #define GNUTLS_SRP_SHA_AES_128_CBC_SHA1 { 0xC0, 0x1D }
402 #define GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1 { 0xC0, 0x1E }
403 #define GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1 { 0xC0, 0x1F }
405 #define GNUTLS_SRP_SHA_AES_256_CBC_SHA1 { 0xC0, 0x20 }
406 #define GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1 { 0xC0, 0x21 }
407 #define GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1 { 0xC0, 0x22 }
409 /* RSA
411 #define GNUTLS_RSA_ARCFOUR_SHA1 { 0x00, 0x05 }
412 #define GNUTLS_RSA_ARCFOUR_MD5 { 0x00, 0x04 }
413 #define GNUTLS_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x0A }
415 #define GNUTLS_RSA_EXPORT_ARCFOUR_40_MD5 { 0x00, 0x03 }
417 /* rfc3268:
419 #define GNUTLS_RSA_AES_128_CBC_SHA1 { 0x00, 0x2F }
420 #define GNUTLS_RSA_AES_256_CBC_SHA1 { 0x00, 0x35 }
422 /* DHE DSS
425 #define GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1 { 0x00, 0x13 }
428 /* draft-ietf-tls-56-bit-ciphersuites-01:
430 #define GNUTLS_DHE_DSS_ARCFOUR_SHA1 { 0x00, 0x66 }
433 /* rfc3268:
435 #define GNUTLS_DHE_DSS_AES_256_CBC_SHA1 { 0x00, 0x38 }
436 #define GNUTLS_DHE_DSS_AES_128_CBC_SHA1 { 0x00, 0x32 }
438 /* DHE RSA
440 #define GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x16 }
442 /* rfc3268:
444 #define GNUTLS_DHE_RSA_AES_128_CBC_SHA1 { 0x00, 0x33 }
445 #define GNUTLS_DHE_RSA_AES_256_CBC_SHA1 { 0x00, 0x39 }
447 #define CIPHER_SUITES_COUNT sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry)-1
449 static const gnutls_cipher_suite_entry cs_algorithms[] = {
450 /* ANON_DH */
451 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_ARCFOUR_MD5,
452 GNUTLS_CIPHER_ARCFOUR_128,
453 GNUTLS_KX_ANON_DH, GNUTLS_MAC_MD5,
454 GNUTLS_SSL3),
455 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_3DES_EDE_CBC_SHA1,
456 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_ANON_DH,
457 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
458 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_128_CBC_SHA1,
459 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ANON_DH,
460 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
461 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_256_CBC_SHA1,
462 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ANON_DH,
463 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
465 /* PSK */
466 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_ARCFOUR_SHA1,
467 GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_PSK,
468 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
469 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1,
470 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_PSK,
471 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
472 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_128_CBC_SHA1,
473 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_PSK,
474 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
475 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_256_CBC_SHA1,
476 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_PSK,
477 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
479 /* DHE-PSK */
480 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1,
481 GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_DHE_PSK,
482 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
483 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1,
484 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_PSK,
485 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
486 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1,
487 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_PSK,
488 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
489 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1,
490 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_PSK,
491 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
493 /* SRP */
494 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1,
495 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP,
496 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
497 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_128_CBC_SHA1,
498 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP,
499 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
500 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_256_CBC_SHA1,
501 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP,
502 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
504 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1,
505 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_DSS,
506 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
508 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1,
509 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_RSA,
510 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
512 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1,
513 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_DSS,
514 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
516 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1,
517 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_RSA,
518 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
520 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1,
521 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_DSS,
522 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
524 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1,
525 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_RSA,
526 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
528 /* DHE_DSS */
529 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_ARCFOUR_SHA1,
530 GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_KX_DHE_DSS,
531 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
532 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1,
533 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_DSS,
534 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
535 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_128_CBC_SHA1,
536 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_DSS,
537 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
538 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_256_CBC_SHA1,
539 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_DSS,
540 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
541 /* DHE_RSA */
542 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1,
543 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_RSA,
544 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
545 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_128_CBC_SHA1,
546 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_RSA,
547 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
548 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_256_CBC_SHA1,
549 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_RSA,
550 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
551 /* RSA */
552 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_MD5,
553 GNUTLS_CIPHER_NULL,
554 GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3),
556 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_EXPORT_ARCFOUR_40_MD5,
557 GNUTLS_CIPHER_ARCFOUR_40,
558 GNUTLS_KX_RSA_EXPORT, GNUTLS_MAC_MD5,
559 GNUTLS_SSL3),
561 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_SHA1,
562 GNUTLS_CIPHER_ARCFOUR_128,
563 GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3),
564 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_MD5,
565 GNUTLS_CIPHER_ARCFOUR_128,
566 GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3),
567 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_3DES_EDE_CBC_SHA1,
568 GNUTLS_CIPHER_3DES_CBC,
569 GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3),
570 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_128_CBC_SHA1,
571 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_RSA,
572 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
573 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_256_CBC_SHA1,
574 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_RSA,
575 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
576 {0, {{0, 0}}, 0, 0, 0, 0}
579 #define GNUTLS_CIPHER_SUITE_LOOP(b) \
580 const gnutls_cipher_suite_entry *p; \
581 for(p = cs_algorithms; p->name != NULL; p++) { b ; }
583 #define GNUTLS_CIPHER_SUITE_ALG_LOOP(a) \
584 GNUTLS_CIPHER_SUITE_LOOP( if( (p->id.suite[0] == suite->suite[0]) && (p->id.suite[1] == suite->suite[1])) { a; break; } )
588 /* Generic Functions */
590 inline int
591 _gnutls_mac_priority (gnutls_session_t session,
592 gnutls_mac_algorithm_t algorithm)
593 { /* actually returns the priority */
594 unsigned int i;
595 for (i = 0; i < session->internals.mac_algorithm_priority.algorithms; i++)
597 if (session->internals.mac_algorithm_priority.priority[i] == algorithm)
598 return i;
600 return -1;
604 * gnutls_mac_get_name - Returns a string with the name of the specified mac algorithm
605 * @algorithm: is a MAC algorithm
607 * Returns a string that contains the name
608 * of the specified MAC algorithm or NULL.
610 const char *
611 gnutls_mac_get_name (gnutls_mac_algorithm_t algorithm)
613 const char *ret = NULL;
615 /* avoid prefix */
616 GNUTLS_HASH_ALG_LOOP (ret = p->name);
618 return ret;
622 * gnutls_mac_list:
624 * Get a list of hash algorithms for use as MACs. Note that not
625 * necessarily all MACs are supported in TLS cipher suites. For
626 * example, MD2 is not supported as a cipher suite, but is supported
627 * for other purposes (e.g., X.509 signature verification or similar).
629 * Returns: Return a zero-terminated list of %gnutls_mac_algorithm_t
630 * integers indicating the available MACs.
633 const gnutls_mac_algorithm_t *
634 gnutls_mac_list (void)
636 return supported_macs;
639 const char *
640 _gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t algorithm)
642 const char *ret = NULL;
644 /* avoid prefix */
645 GNUTLS_HASH_ALG_LOOP (ret = p->oid);
647 return ret;
650 gnutls_mac_algorithm_t
651 _gnutls_x509_oid2mac_algorithm (const char *oid)
653 gnutls_mac_algorithm_t ret = 0;
655 GNUTLS_HASH_LOOP (if (p->oid && strcmp (oid, p->oid) == 0)
657 ret = p->id; break;}
660 if (ret == 0)
661 return GNUTLS_MAC_UNKNOWN;
662 return ret;
667 _gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm)
669 ssize_t ret = -1;
670 GNUTLS_HASH_ALG_LOOP (ret = p->id);
671 if (ret >= 0)
672 ret = 0;
673 else
674 ret = 1;
675 return ret;
678 /* Compression Functions */
679 inline int
680 _gnutls_compression_priority (gnutls_session_t session,
681 gnutls_compression_method_t algorithm)
682 { /* actually returns the priority */
683 unsigned int i;
684 for (i = 0;
685 i < session->internals.compression_method_priority.algorithms; i++)
687 if (session->internals.
688 compression_method_priority.priority[i] == algorithm)
689 return i;
691 return -1;
695 * gnutls_compression_get_name - Returns a string with the name of the specified compression algorithm
696 * @algorithm: is a Compression algorithm
698 * Returns a pointer to a string that contains the name
699 * of the specified compression algorithm or NULL.
701 const char *
702 gnutls_compression_get_name (gnutls_compression_method_t algorithm)
704 const char *ret = NULL;
706 /* avoid prefix */
707 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->name + sizeof ("GNUTLS_COMP_") - 1);
709 return ret;
713 * gnutls_compression_list:
715 * Get a list of compression methods. Note that to be able to use LZO
716 * compression, you must link to libgnutls-extra and call
717 * gnutls_global_init_extra().
719 * Returns: Return a zero-terminated list of
720 * %gnutls_compression_method_t integers indicating the available
721 * compression methods.
723 const gnutls_compression_method_t *
724 gnutls_compression_list (void)
726 return supported_compressions;
729 /* return the tls number of the specified algorithm */
731 _gnutls_compression_get_num (gnutls_compression_method_t algorithm)
733 int ret = -1;
735 /* avoid prefix */
736 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->num);
738 return ret;
742 _gnutls_compression_get_wbits (gnutls_compression_method_t algorithm)
744 int ret = -1;
745 /* avoid prefix */
746 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->window_bits);
747 return ret;
751 _gnutls_compression_get_mem_level (gnutls_compression_method_t algorithm)
753 int ret = -1;
754 /* avoid prefix */
755 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->mem_level);
756 return ret;
760 _gnutls_compression_get_comp_level (gnutls_compression_method_t algorithm)
762 int ret = -1;
763 /* avoid prefix */
764 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->comp_level);
765 return ret;
768 /* returns the gnutls internal ID of the TLS compression
769 * method num
771 gnutls_compression_method_t
772 _gnutls_compression_get_id (int num)
774 gnutls_compression_method_t ret = -1;
776 /* avoid prefix */
777 GNUTLS_COMPRESSION_ALG_LOOP_NUM (ret = p->id);
779 return ret;
783 _gnutls_compression_is_ok (gnutls_compression_method_t algorithm)
785 ssize_t ret = -1;
786 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->id);
787 if (ret >= 0)
788 ret = 0;
789 else
790 ret = 1;
791 return ret;
796 /* CIPHER functions */
798 _gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm)
800 size_t ret = 0;
801 GNUTLS_ALG_LOOP (ret = p->blocksize);
802 return ret;
806 /* returns the priority */
807 inline int
808 _gnutls_cipher_priority (gnutls_session_t session,
809 gnutls_cipher_algorithm_t algorithm)
811 unsigned int i;
812 for (i = 0;
813 i < session->internals.cipher_algorithm_priority.algorithms; i++)
815 if (session->internals.
816 cipher_algorithm_priority.priority[i] == algorithm)
817 return i;
819 return -1;
824 _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm)
826 size_t ret = 0;
828 GNUTLS_ALG_LOOP (ret = p->block);
829 return ret;
834 * gnutls_cipher_get_key_size - Returns the length of the cipher's key size
835 * @algorithm: is an encryption algorithm
837 * Returns the length (in bytes) of the given cipher's key size.
838 * Returns 0 if the given cipher is invalid.
841 size_t
842 gnutls_cipher_get_key_size (gnutls_cipher_algorithm_t algorithm)
843 { /* In bytes */
844 size_t ret = 0;
845 GNUTLS_ALG_LOOP (ret = p->keysize);
846 return ret;
851 _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm)
852 { /* In bytes */
853 size_t ret = 0;
854 GNUTLS_ALG_LOOP (ret = p->iv);
855 return ret;
860 _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm)
861 { /* In bytes */
862 size_t ret = 0;
863 GNUTLS_ALG_LOOP (ret = p->export_flag);
864 return ret;
869 * gnutls_cipher_get_name - Returns a string with the name of the specified cipher algorithm
870 * @algorithm: is an encryption algorithm
872 * Returns a pointer to a string that contains the name
873 * of the specified cipher or NULL.
875 const char *
876 gnutls_cipher_get_name (gnutls_cipher_algorithm_t algorithm)
878 const char *ret = NULL;
880 /* avoid prefix */
881 GNUTLS_ALG_LOOP (ret = p->name);
883 return ret;
887 * gnutls_cipher_list:
889 * Get a list of supported cipher algorithms. Note that not
890 * necessarily all ciphers are supported as TLS cipher suites. For
891 * example, DES is not supported as a cipher suite, but is supported
892 * for other purposes (e.g., PKCS#8 or similar).
894 * Returns: Return a zero-terminated list of
895 * %gnutls_cipher_algorithm_t integers indicating the available
896 * ciphers.
899 const gnutls_cipher_algorithm_t *
900 gnutls_cipher_list (void)
902 return supported_ciphers;
906 _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm)
908 ssize_t ret = -1;
909 GNUTLS_ALG_LOOP (ret = p->id);
910 if (ret >= 0)
911 ret = 0;
912 else
913 ret = 1;
914 return ret;
917 /* Key EXCHANGE functions */
918 mod_auth_st *
919 _gnutls_kx_auth_struct (gnutls_kx_algorithm_t algorithm)
921 mod_auth_st *ret = NULL;
922 GNUTLS_KX_ALG_LOOP (ret = p->auth_struct);
923 return ret;
928 inline int
929 _gnutls_kx_priority (gnutls_session_t session,
930 gnutls_kx_algorithm_t algorithm)
932 unsigned int i;
933 for (i = 0; i < session->internals.kx_algorithm_priority.algorithms; i++)
935 if (session->internals.kx_algorithm_priority.priority[i] == algorithm)
936 return i;
938 return -1;
942 * gnutls_kx_get_name - Returns a string with the name of the specified key exchange algorithm
943 * @algorithm: is a key exchange algorithm
945 * Returns a pointer to a string that contains the name
946 * of the specified key exchange algorithm or NULL.
948 const char *
949 gnutls_kx_get_name (gnutls_kx_algorithm_t algorithm)
951 const char *ret = NULL;
953 /* avoid prefix */
954 GNUTLS_KX_ALG_LOOP (ret = p->name);
956 return ret;
960 * gnutls_kx_list:
962 * Get a list of supported key exchange algorithms.
964 * Returns: Return a zero-terminated list of %gnutls_kx_algorithm_t
965 * integers indicating the available key exchange algorithms.
968 const gnutls_kx_algorithm_t *
969 gnutls_kx_list (void)
971 return supported_kxs;
975 _gnutls_kx_is_ok (gnutls_kx_algorithm_t algorithm)
977 ssize_t ret = -1;
978 GNUTLS_KX_ALG_LOOP (ret = p->algorithm);
979 if (ret >= 0)
980 ret = 0;
981 else
982 ret = 1;
983 return ret;
987 _gnutls_kx_needs_rsa_params (gnutls_kx_algorithm_t algorithm)
989 ssize_t ret = 0;
990 GNUTLS_KX_ALG_LOOP (ret = p->needs_rsa_params);
991 return ret;
995 _gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm)
997 ssize_t ret = 0;
998 GNUTLS_KX_ALG_LOOP (ret = p->needs_dh_params);
999 return ret;
1003 /* Version */
1005 _gnutls_version_priority (gnutls_session_t session, gnutls_protocol_t version)
1006 { /* actually returns the priority */
1007 unsigned int i;
1009 if (session->internals.protocol_priority.priority == NULL)
1011 gnutls_assert ();
1012 return -1;
1015 for (i = 0; i < session->internals.protocol_priority.algorithms; i++)
1017 if (session->internals.protocol_priority.priority[i] == version)
1018 return i;
1020 return -1;
1023 gnutls_protocol_t
1024 _gnutls_version_lowest (gnutls_session_t session)
1025 { /* returns the lowest version supported */
1026 unsigned int i, min = 0xff;
1028 if (session->internals.protocol_priority.priority == NULL)
1030 return GNUTLS_VERSION_UNKNOWN;
1032 else
1033 for (i = 0; i < session->internals.protocol_priority.algorithms; i++)
1035 if (session->internals.protocol_priority.priority[i] < min)
1036 min = session->internals.protocol_priority.priority[i];
1039 if (min == 0xff)
1040 return GNUTLS_VERSION_UNKNOWN; /* unknown version */
1042 return min;
1045 gnutls_protocol_t
1046 _gnutls_version_max (gnutls_session_t session)
1047 { /* returns the maximum version supported */
1048 unsigned int i, max = 0x00;
1050 if (session->internals.protocol_priority.priority == NULL)
1052 return GNUTLS_VERSION_UNKNOWN;
1054 else
1055 for (i = 0; i < session->internals.protocol_priority.algorithms; i++)
1057 if (session->internals.protocol_priority.priority[i] > max)
1058 max = session->internals.protocol_priority.priority[i];
1061 if (max == 0x00)
1062 return GNUTLS_VERSION_UNKNOWN; /* unknown version */
1064 return max;
1069 * gnutls_protocol_get_name - Returns a string with the name of the specified SSL/TLS version
1070 * @version: is a (gnutls) version number
1072 * Returns a string that contains the name
1073 * of the specified TLS version or NULL.
1075 const char *
1076 gnutls_protocol_get_name (gnutls_protocol_t version)
1078 const char *ret = NULL;
1080 /* avoid prefix */
1081 GNUTLS_VERSION_ALG_LOOP (ret = p->name);
1082 return ret;
1086 * gnutls_protocol_list:
1088 * Get a list of supported protocols, e.g. SSL 3.0, TLS 1.0 etc.
1090 * Returns: Return a zero-terminated list of %gnutls_protocol_t
1091 * integers indicating the available protocols.
1094 const gnutls_protocol_t *
1095 gnutls_protocol_list (void)
1097 return supported_protocols;
1101 _gnutls_version_get_minor (gnutls_protocol_t version)
1103 int ret = -1;
1105 GNUTLS_VERSION_ALG_LOOP (ret = p->minor);
1106 return ret;
1109 gnutls_protocol_t
1110 _gnutls_version_get (int major, int minor)
1112 int ret = -1;
1114 GNUTLS_VERSION_LOOP (if ((p->major == major) && (p->minor == minor))
1115 ret = p->id);
1116 return ret;
1120 _gnutls_version_get_major (gnutls_protocol_t version)
1122 int ret = -1;
1124 GNUTLS_VERSION_ALG_LOOP (ret = p->major);
1125 return ret;
1128 /* Version Functions */
1131 _gnutls_version_is_supported (gnutls_session_t session,
1132 const gnutls_protocol_t version)
1134 int ret = 0;
1136 GNUTLS_VERSION_ALG_LOOP (ret = p->supported);
1137 if (ret == 0)
1138 return 0;
1140 if (_gnutls_version_priority (session, version) < 0)
1141 return 0; /* disabled by the user */
1142 else
1143 return 1;
1146 /* Type to KX mappings */
1147 gnutls_kx_algorithm_t
1148 _gnutls_map_kx_get_kx (gnutls_credentials_type_t type, int server)
1150 gnutls_kx_algorithm_t ret = -1;
1152 if (server)
1154 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1156 else
1158 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1160 return ret;
1163 gnutls_credentials_type_t
1164 _gnutls_map_kx_get_cred (gnutls_kx_algorithm_t algorithm, int server)
1166 gnutls_credentials_type_t ret = -1;
1167 if (server)
1169 GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret =
1170 p->server_type);
1172 else
1174 GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret =
1175 p->client_type);
1178 return ret;
1182 /* Cipher Suite's functions */
1183 gnutls_cipher_algorithm_t
1184 _gnutls_cipher_suite_get_cipher_algo (const cipher_suite_st * suite)
1186 int ret = 0;
1187 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->block_algorithm);
1188 return ret;
1191 gnutls_protocol_t
1192 _gnutls_cipher_suite_get_version (const cipher_suite_st * suite)
1194 int ret = 0;
1195 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->version);
1196 return ret;
1199 gnutls_kx_algorithm_t
1200 _gnutls_cipher_suite_get_kx_algo (const cipher_suite_st * suite)
1202 int ret = 0;
1204 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->kx_algorithm);
1205 return ret;
1209 gnutls_mac_algorithm_t
1210 _gnutls_cipher_suite_get_mac_algo (const cipher_suite_st * suite)
1211 { /* In bytes */
1212 int ret = 0;
1213 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->mac_algorithm);
1214 return ret;
1218 const char *
1219 _gnutls_cipher_suite_get_name (cipher_suite_st * suite)
1221 const char *ret = NULL;
1223 /* avoid prefix */
1224 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->name + sizeof ("GNUTLS_") - 1);
1226 return ret;
1230 * gnutls_cipher_suite_get_name - Returns a string with the name of the specified cipher suite
1231 * @kx_algorithm: is a Key exchange algorithm
1232 * @cipher_algorithm: is a cipher algorithm
1233 * @mac_algorithm: is a MAC algorithm
1235 * Returns a string that contains the name of a TLS
1236 * cipher suite, specified by the given algorithms, or NULL.
1238 * Note that the full cipher suite name must be prepended
1239 * by TLS or SSL depending of the protocol in use.
1242 const char *
1243 gnutls_cipher_suite_get_name (gnutls_kx_algorithm_t
1244 kx_algorithm,
1245 gnutls_cipher_algorithm_t
1246 cipher_algorithm,
1247 gnutls_mac_algorithm_t mac_algorithm)
1249 const char *ret = NULL;
1251 /* avoid prefix */
1252 GNUTLS_CIPHER_SUITE_LOOP (if (kx_algorithm == p->kx_algorithm &&
1253 cipher_algorithm == p->block_algorithm &&
1254 mac_algorithm == p->mac_algorithm)
1255 ret = p->name + sizeof ("GNUTLS_") - 1);
1257 return ret;
1261 * gnutls_cipher_suite_info:
1262 * @idx: index of cipher suite to get information about, starts on 0.
1263 * @cs_id: output buffer with room for 2 bytes, indicating cipher suite value
1264 * @kx: output variable indicating key exchange algorithm, or %NULL.
1265 * @cipher: output variable indicating cipher, or %NULL.
1266 * @mac: output variable indicating MAC algorithm, or %NULL.
1267 * @version: output variable indicating TLS protocol version, or %NULL.
1269 * Get information about supported cipher suites. Use the function
1270 * iteratively to get information about all supported cipher suites.
1271 * Call with idx=0 to get information about first cipher suite, then
1272 * idx=1 and so on until the function returns NULL.
1274 * Returns: Returns the name of @idx cipher suite, and set the
1275 * information about the cipher suite in the output variables. If
1276 * @idx is out of bounds, %NULL is returned.
1278 const char *
1279 gnutls_cipher_suite_info (size_t idx,
1280 char *cs_id,
1281 gnutls_kx_algorithm_t *kx,
1282 gnutls_cipher_algorithm_t *cipher,
1283 gnutls_mac_algorithm_t *mac,
1284 gnutls_protocol_t *version)
1286 if (idx >= CIPHER_SUITES_COUNT)
1287 return NULL;
1289 if (cs_id)
1290 memcpy (cs_id, cs_algorithms[idx].id.suite, 2);
1291 if (kx)
1292 *kx = cs_algorithms[idx].kx_algorithm;
1293 if (cipher)
1294 *cipher = cs_algorithms[idx].block_algorithm;
1295 if (mac)
1296 *mac = cs_algorithms[idx].mac_algorithm;
1297 if (version)
1298 *version = cs_algorithms[idx].version;
1300 return cs_algorithms[idx].name + sizeof ("GNU") - 1;
1304 inline static int
1305 _gnutls_cipher_suite_is_ok (cipher_suite_st * suite)
1307 size_t ret;
1308 const char *name = NULL;
1310 GNUTLS_CIPHER_SUITE_ALG_LOOP (name = p->name);
1311 if (name != NULL)
1312 ret = 0;
1313 else
1314 ret = 1;
1315 return ret;
1319 #define SWAP(x, y) memcpy(tmp,x,size); \
1320 memcpy(x,y,size); \
1321 memcpy(y,tmp,size);
1323 #define MAX_ELEM_SIZE 4
1324 inline static int
1325 _gnutls_partition (gnutls_session_t session, void *_base,
1326 size_t nmemb, size_t size,
1327 int (*compar) (gnutls_session_t,
1328 const void *, const void *))
1330 uint8_t *base = _base;
1331 uint8_t tmp[MAX_ELEM_SIZE];
1332 uint8_t ptmp[MAX_ELEM_SIZE];
1333 unsigned int pivot;
1334 unsigned int i, j;
1335 unsigned int full;
1337 i = pivot = 0;
1338 j = full = (nmemb - 1) * size;
1340 memcpy (ptmp, &base[0], size); /* set pivot item */
1342 while (i < j)
1344 while ((compar (session, &base[i], ptmp) <= 0) && (i < full))
1346 i += size;
1348 while ((compar (session, &base[j], ptmp) >= 0) && (j > 0))
1349 j -= size;
1351 if (i < j)
1353 SWAP (&base[j], &base[i]);
1357 if (j > pivot)
1359 SWAP (&base[pivot], &base[j]);
1360 pivot = j;
1362 else if (i < pivot)
1364 SWAP (&base[pivot], &base[i]);
1365 pivot = i;
1367 return pivot / size;
1370 static void
1371 _gnutls_qsort (gnutls_session_t session, void *_base, size_t nmemb,
1372 size_t size, int (*compar) (gnutls_session_t, const void *,
1373 const void *))
1375 unsigned int pivot;
1376 char *base = _base;
1377 size_t snmemb = nmemb;
1379 #ifdef DEBUG
1380 if (size > MAX_ELEM_SIZE)
1382 gnutls_assert ();
1383 _gnutls_debug_log ("QSORT BUG\n");
1384 exit (1);
1386 #endif
1388 if (snmemb <= 1)
1389 return;
1390 pivot = _gnutls_partition (session, _base, nmemb, size, compar);
1392 _gnutls_qsort (session, base, pivot < nmemb ? pivot + 1 : pivot, size,
1393 compar);
1394 _gnutls_qsort (session, &base[(pivot + 1) * size], nmemb - pivot - 1,
1395 size, compar);
1399 /* a compare function for KX algorithms (using priorities).
1400 * For use with qsort
1402 static int
1403 _gnutls_compare_algo (gnutls_session_t session, const void *i_A1,
1404 const void *i_A2)
1406 gnutls_kx_algorithm_t kA1 =
1407 _gnutls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A1);
1408 gnutls_kx_algorithm_t kA2 =
1409 _gnutls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A2);
1410 gnutls_cipher_algorithm_t cA1 =
1411 _gnutls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A1);
1412 gnutls_cipher_algorithm_t cA2 =
1413 _gnutls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A2);
1414 gnutls_mac_algorithm_t mA1 =
1415 _gnutls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A1);
1416 gnutls_mac_algorithm_t mA2 =
1417 _gnutls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A2);
1419 int p1 = (_gnutls_kx_priority (session, kA1) + 1) * 64;
1420 int p2 = (_gnutls_kx_priority (session, kA2) + 1) * 64;
1421 p1 += (_gnutls_cipher_priority (session, cA1) + 1) * 8;
1422 p2 += (_gnutls_cipher_priority (session, cA2) + 1) * 8;
1423 p1 += _gnutls_mac_priority (session, mA1);
1424 p2 += _gnutls_mac_priority (session, mA2);
1426 if (p1 > p2)
1428 return 1;
1430 else
1432 if (p1 == p2)
1434 return 0;
1436 return -1;
1440 #ifdef SORT_DEBUG
1441 static void
1442 _gnutls_bsort (gnutls_session_t session, void *_base, size_t nmemb,
1443 size_t size, int (*compar) (gnutls_session_t, const void *,
1444 const void *))
1446 unsigned int i, j;
1447 int full = nmemb * size;
1448 char *base = _base;
1449 char tmp[MAX_ELEM_SIZE];
1451 for (i = 0; i < full; i += size)
1453 for (j = 0; j < full; j += size)
1455 if (compar (session, &base[i], &base[j]) < 0)
1457 SWAP (&base[j], &base[i]);
1463 #endif
1466 _gnutls_supported_ciphersuites_sorted (gnutls_session_t session,
1467 cipher_suite_st ** ciphers)
1470 #ifdef SORT_DEBUG
1471 unsigned int i;
1472 #endif
1473 int count;
1475 count = _gnutls_supported_ciphersuites (session, ciphers);
1476 if (count <= 0)
1478 gnutls_assert ();
1479 return count;
1481 #ifdef SORT_DEBUG
1482 _gnutls_debug_log ("Unsorted: \n");
1483 for (i = 0; i < count; i++)
1484 _gnutls_debug_log ("\t%d: %s\n", i,
1485 _gnutls_cipher_suite_get_name ((*ciphers)[i]));
1486 #endif
1488 _gnutls_qsort (session, *ciphers, count,
1489 sizeof (cipher_suite_st), _gnutls_compare_algo);
1491 #ifdef SORT_DEBUG
1492 _gnutls_debug_log ("Sorted: \n");
1493 for (i = 0; i < count; i++)
1494 _gnutls_debug_log ("\t%d: %s\n", i,
1495 _gnutls_cipher_suite_get_name ((*ciphers)[i]));
1496 #endif
1498 return count;
1502 _gnutls_supported_ciphersuites (gnutls_session_t session,
1503 cipher_suite_st ** _ciphers)
1506 unsigned int i, ret_count, j;
1507 unsigned int count = CIPHER_SUITES_COUNT;
1508 cipher_suite_st *tmp_ciphers;
1509 cipher_suite_st *ciphers;
1510 gnutls_protocol_t version;
1512 if (count == 0)
1514 return 0;
1517 tmp_ciphers = gnutls_alloca (count * sizeof (cipher_suite_st));
1518 if (tmp_ciphers == NULL)
1519 return GNUTLS_E_MEMORY_ERROR;
1521 ciphers = gnutls_malloc (count * sizeof (cipher_suite_st));
1522 if (ciphers == NULL)
1524 gnutls_afree (tmp_ciphers);
1525 return GNUTLS_E_MEMORY_ERROR;
1528 version = gnutls_protocol_get_version (session);
1530 for (i = 0; i < count; i++)
1532 memcpy (&tmp_ciphers[i], &cs_algorithms[i].id,
1533 sizeof (cipher_suite_st));
1536 for (i = j = 0; i < count; i++)
1538 /* remove private cipher suites, if requested.
1540 if (tmp_ciphers[i].suite[0] == 0xFF &&
1541 session->internals.enable_private == 0)
1542 continue;
1544 /* remove cipher suites which do not support the
1545 * protocol version used.
1547 if (_gnutls_cipher_suite_get_version (&tmp_ciphers[i]) > version)
1548 continue;
1550 if (_gnutls_kx_priority
1551 (session, _gnutls_cipher_suite_get_kx_algo (&tmp_ciphers[i])) < 0)
1552 continue;
1553 if (_gnutls_mac_priority
1554 (session, _gnutls_cipher_suite_get_mac_algo (&tmp_ciphers[i])) < 0)
1555 continue;
1556 if (_gnutls_cipher_priority
1557 (session,
1558 _gnutls_cipher_suite_get_cipher_algo (&tmp_ciphers[i])) < 0)
1559 continue;
1561 memcpy (&ciphers[j], &tmp_ciphers[i], sizeof (cipher_suite_st));
1562 j++;
1565 ret_count = j;
1567 #if 0 /* expensive */
1568 if (ret_count > 0 && ret_count != count)
1570 ciphers =
1571 gnutls_realloc_fast (ciphers, ret_count * sizeof (cipher_suite_st));
1573 else
1575 if (ret_count != count)
1577 gnutls_free (ciphers);
1578 ciphers = NULL;
1581 #endif
1583 gnutls_afree (tmp_ciphers);
1585 /* This function can no longer return 0 cipher suites.
1586 * It returns an error code instead.
1588 if (ret_count == 0)
1590 gnutls_assert ();
1591 gnutls_free (ciphers);
1592 return GNUTLS_E_NO_CIPHER_SUITES;
1594 *_ciphers = ciphers;
1595 return ret_count;
1599 /* For compression */
1601 #define MIN_PRIVATE_COMP_ALGO 0xEF
1603 /* returns the TLS numbers of the compression methods we support
1605 #define SUPPORTED_COMPRESSION_METHODS session->internals.compression_method_priority.algorithms
1607 _gnutls_supported_compression_methods (gnutls_session_t session,
1608 uint8_t ** comp)
1610 unsigned int i, j;
1612 *comp = gnutls_malloc (sizeof (uint8_t) * SUPPORTED_COMPRESSION_METHODS);
1613 if (*comp == NULL)
1614 return GNUTLS_E_MEMORY_ERROR;
1616 for (i = j = 0; i < SUPPORTED_COMPRESSION_METHODS; i++)
1618 int tmp = _gnutls_compression_get_num (session->internals.
1619 compression_method_priority.
1620 priority[i]);
1622 /* remove private compression algorithms, if requested.
1624 if (tmp == -1 || (tmp >= MIN_PRIVATE_COMP_ALGO &&
1625 session->internals.enable_private == 0))
1627 gnutls_assert ();
1628 continue;
1631 (*comp)[j] = (uint8_t) tmp;
1632 j++;
1635 if (j == 0)
1637 gnutls_assert ();
1638 gnutls_free (*comp);
1639 *comp = NULL;
1640 return GNUTLS_E_NO_COMPRESSION_ALGORITHMS;
1642 return j;
1646 * gnutls_certificate_type_get_name - Returns a string with the name of the specified certificate type
1647 * @type: is a certificate type
1649 * Returns a string (or NULL) that contains the name
1650 * of the specified certificate type.
1652 const char *
1653 gnutls_certificate_type_get_name (gnutls_certificate_type_t type)
1655 const char *ret = NULL;
1657 if (type == GNUTLS_CRT_X509)
1658 ret = "X.509";
1659 if (type == GNUTLS_CRT_OPENPGP)
1660 ret = "OPENPGP";
1662 return ret;
1665 static const gnutls_certificate_type_t supported_certificate_types[] = {
1666 GNUTLS_CRT_X509,
1667 GNUTLS_CRT_OPENPGP,
1672 * gnutls_certificate_type_list:
1674 * Get a list of certificate types. Note that to be able to use
1675 * OpenPGP certificates, you must link to libgnutls-extra and call
1676 * gnutls_global_init_extra().
1678 * Returns: Return a zero-terminated list of
1679 * %gnutls_certificate_type_t integers indicating the available
1680 * certificate types.
1683 const gnutls_certificate_type_t *
1684 gnutls_certificate_type_list (void)
1686 return supported_certificate_types;
1689 /* returns the gnutls_pk_algorithm_t which is compatible with
1690 * the given gnutls_kx_algorithm_t.
1692 gnutls_pk_algorithm_t
1693 _gnutls_map_pk_get_pk (gnutls_kx_algorithm_t kx_algorithm)
1695 gnutls_pk_algorithm_t ret = -1;
1697 GNUTLS_PK_MAP_ALG_LOOP (ret = p->pk_algorithm) return ret;
1700 /* Returns the encipher type for the given key exchange algorithm.
1701 * That one of CIPHER_ENCRYPT, CIPHER_SIGN, CIPHER_IGN.
1703 * ex. GNUTLS_KX_RSA requires a certificate able to encrypt... so returns CIPHER_ENCRYPT.
1705 enum encipher_type
1706 _gnutls_kx_encipher_type (gnutls_kx_algorithm_t kx_algorithm)
1708 int ret = CIPHER_IGN;
1709 GNUTLS_PK_MAP_ALG_LOOP (ret = p->encipher_type) return ret;
1713 /* signature algorithms;
1715 struct gnutls_sign_entry
1717 const char *name;
1718 const char *oid;
1719 gnutls_sign_algorithm_t id;
1720 gnutls_pk_algorithm_t pk;
1721 gnutls_mac_algorithm_t mac;
1723 typedef struct gnutls_sign_entry gnutls_sign_entry;
1725 static const gnutls_sign_entry sign_algorithms[] = {
1726 {"RSA-SHA", SIG_RSA_SHA1_OID, GNUTLS_SIGN_RSA_SHA1, GNUTLS_PK_RSA,
1727 GNUTLS_MAC_SHA1},
1728 {"RSA-SHA256", SIG_RSA_SHA256_OID, GNUTLS_SIGN_RSA_SHA256, GNUTLS_PK_RSA,
1729 GNUTLS_MAC_SHA256},
1730 {"RSA-SHA384", SIG_RSA_SHA384_OID, GNUTLS_SIGN_RSA_SHA384, GNUTLS_PK_RSA,
1731 GNUTLS_MAC_SHA384},
1732 {"RSA-SHA512", SIG_RSA_SHA512_OID, GNUTLS_SIGN_RSA_SHA512, GNUTLS_PK_RSA,
1733 GNUTLS_MAC_SHA512},
1734 {"RSA-RMD160", SIG_RSA_RMD160_OID, GNUTLS_SIGN_RSA_RMD160, GNUTLS_PK_RSA,
1735 GNUTLS_MAC_RMD160},
1736 {"DSA-SHA", SIG_DSA_SHA1_OID, GNUTLS_SIGN_DSA_SHA1, GNUTLS_PK_DSA,
1737 GNUTLS_MAC_SHA1},
1738 {"RSA-MD5", SIG_RSA_MD5_OID, GNUTLS_SIGN_RSA_MD5, GNUTLS_PK_RSA,
1739 GNUTLS_MAC_MD5},
1740 {"RSA-MD2", SIG_RSA_MD2_OID, GNUTLS_SIGN_RSA_MD2, GNUTLS_PK_RSA,
1741 GNUTLS_MAC_MD2},
1742 {"GOST R 34.10-2001", SIG_GOST_R3410_2001_OID, 0, 0, 0},
1743 {"GOST R 34.10-94", SIG_GOST_R3410_94_OID, 0, 0, 0},
1744 {0, 0, 0, 0, 0}
1747 #define GNUTLS_SIGN_LOOP(b) \
1748 do { \
1749 const gnutls_sign_entry *p; \
1750 for(p = sign_algorithms; p->name != NULL; p++) { b ; } \
1751 } while (0)
1753 #define GNUTLS_SIGN_ALG_LOOP(a) \
1754 GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } )
1759 * gnutls_sign_algorithm_get_name - Returns a string with the name of the specified sign algorithm
1760 * @algorithm: is a sign algorithm
1762 * Returns a string that contains the name
1763 * of the specified sign algorithm or NULL.
1765 const char *
1766 gnutls_sign_algorithm_get_name (gnutls_sign_algorithm_t sign)
1768 const char *ret = NULL;
1770 /* avoid prefix */
1771 GNUTLS_SIGN_ALG_LOOP (ret = p->name);
1773 return ret;
1776 gnutls_sign_algorithm_t
1777 _gnutls_x509_oid2sign_algorithm (const char *oid)
1779 gnutls_sign_algorithm_t ret = 0;
1781 GNUTLS_SIGN_LOOP (if (strcmp (oid, p->oid) == 0)
1783 ret = p->id; break;}
1786 if (ret == 0)
1788 _gnutls_x509_log ("Unknown SIGN OID: '%s'\n", oid);
1789 return GNUTLS_SIGN_UNKNOWN;
1791 return ret;
1794 gnutls_sign_algorithm_t
1795 _gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk, gnutls_mac_algorithm_t mac)
1797 gnutls_sign_algorithm_t ret = 0;
1799 GNUTLS_SIGN_LOOP (if (pk == p->pk && mac == p->mac)
1801 ret = p->id; break;}
1804 if (ret == 0)
1805 return GNUTLS_SIGN_UNKNOWN;
1806 return ret;
1809 const char *
1810 _gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t pk,
1811 gnutls_mac_algorithm_t mac)
1813 gnutls_sign_algorithm_t sign;
1814 const char *ret = NULL;
1816 sign = _gnutls_x509_pk_to_sign (pk, mac);
1817 if (sign == GNUTLS_SIGN_UNKNOWN)
1818 return NULL;
1820 GNUTLS_SIGN_ALG_LOOP (ret = p->oid);
1821 return ret;
1825 /* pk algorithms;
1827 struct gnutls_pk_entry
1829 const char *name;
1830 const char *oid;
1831 gnutls_pk_algorithm_t id;
1833 typedef struct gnutls_pk_entry gnutls_pk_entry;
1835 static const gnutls_pk_entry pk_algorithms[] = {
1836 {"RSA", PK_PKIX1_RSA_OID, GNUTLS_PK_RSA},
1837 {"DSA", PK_DSA_OID, GNUTLS_PK_DSA},
1838 {"GOST R 34.10-2001", PK_GOST_R3410_2001_OID, 0},
1839 {"GOST R 34.10-94", PK_GOST_R3410_94_OID, 0},
1840 {0, 0, 0}
1844 * gnutls_pk_algorithm_get_name - Returns a string with the name of the specified public key algorithm
1845 * @algorithm: is a pk algorithm
1847 * Returns a string that contains the name
1848 * of the specified public key algorithm or NULL.
1850 const char *
1851 gnutls_pk_algorithm_get_name (gnutls_pk_algorithm_t algorithm)
1853 const char *ret = NULL;
1854 const gnutls_pk_entry *p;
1856 for (p = pk_algorithms; p->name != NULL; p++)
1857 if (p->id && p->id == algorithm)
1859 ret = p->name;
1860 break;
1863 return ret;
1866 gnutls_pk_algorithm_t
1867 _gnutls_x509_oid2pk_algorithm (const char *oid)
1869 gnutls_pk_algorithm_t ret = GNUTLS_PK_UNKNOWN;
1870 const gnutls_pk_entry *p;
1872 for (p = pk_algorithms; p->name != NULL; p++)
1873 if (strcmp (p->oid, oid) == 0)
1875 ret = p->id;
1876 break;
1879 return ret;
1882 const char *
1883 _gnutls_x509_pk_to_oid (gnutls_pk_algorithm_t algorithm)
1885 const char *ret = NULL;
1886 const gnutls_pk_entry *p;
1888 for (p = pk_algorithms; p->name != NULL; p++)
1889 if (p->id == algorithm)
1891 ret = p->oid;
1892 break;
1895 return ret;