gnutls_algorithms.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
00003  *
00004  * Author: Nikos Mavrogiannopoulos
00005  *
00006  * This file is part of GNUTLS.
00007  *
00008  * The GNUTLS library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00021  * USA
00022  *
00023  */
00024 
00025 #include "gnutls_int.h"
00026 #include "gnutls_algorithms.h"
00027 #include "gnutls_errors.h"
00028 #include "gnutls_cert.h"
00029 /* x509 */
00030 #include "common.h"
00031 
00032 /* Cred type mappings to KX algorithms
00033  * FIXME: The mappings are not 1-1. Some KX such as SRP_RSA require
00034  * more than one credentials type.
00035  */
00036 typedef struct
00037 {
00038   enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm;
00039   enum MHD_GNUTLS_CredentialsType client_type;
00040   enum MHD_GNUTLS_CredentialsType server_type;  /* The type of credentials a server
00041                                                  * needs to set */
00042 } MHD_gnutls_cred_map;
00043 
00044 static const MHD_gnutls_cred_map MHD_gtls_cred_mappings[] = {
00045   {MHD_GNUTLS_KX_RSA,
00046    MHD_GNUTLS_CRD_CERTIFICATE,
00047    MHD_GNUTLS_CRD_CERTIFICATE},
00048   {MHD_GNUTLS_KX_RSA_EXPORT,
00049    MHD_GNUTLS_CRD_CERTIFICATE,
00050    MHD_GNUTLS_CRD_CERTIFICATE},
00051   {0,
00052    0,
00053    0}
00054 };
00055 
00056 #define GNUTLS_KX_MAP_LOOP(b) \
00057         const MHD_gnutls_cred_map *p; \
00058                 for(p = MHD_gtls_cred_mappings; p->algorithm != 0; p++) { b ; }
00059 
00060 #define GNUTLS_KX_MAP_ALG_LOOP_SERVER(a) \
00061                         GNUTLS_KX_MAP_LOOP( if(p->server_type == type) { a; break; })
00062 
00063 #define GNUTLS_KX_MAP_ALG_LOOP_CLIENT(a) \
00064                         GNUTLS_KX_MAP_LOOP( if(p->client_type == type) { a; break; })
00065 
00066 /* KX mappings to PK algorithms */
00067 typedef struct
00068 {
00069   enum MHD_GNUTLS_KeyExchangeAlgorithm kx_algorithm;
00070   enum MHD_GNUTLS_PublicKeyAlgorithm pk_algorithm;
00071   enum encipher_type encipher_type;     /* CIPHER_ENCRYPT if this algorithm is to be used
00072                                          * for encryption, CIPHER_SIGN if signature only,
00073                                          * CIPHER_IGN if this does not apply at all.
00074                                          *
00075                                          * This is useful to certificate cipher suites, which check
00076                                          * against the certificate key usage bits.
00077                                          */
00078 } MHD_gnutls_pk_map;
00079 
00080 /* This table maps the Key exchange algorithms to
00081  * the certificate algorithms. Eg. if we have
00082  * RSA algorithm in the certificate then we can
00083  * use GNUTLS_KX_RSA or GNUTLS_KX_DHE_RSA.
00084  */
00085 static const MHD_gnutls_pk_map MHD_gtls_pk_mappings[] = {
00086   {MHD_GNUTLS_KX_RSA,
00087    MHD_GNUTLS_PK_RSA,
00088    CIPHER_ENCRYPT},
00089   {MHD_GNUTLS_KX_RSA_EXPORT,
00090    MHD_GNUTLS_PK_RSA,
00091    CIPHER_SIGN},
00092   {0,
00093    0,
00094    0}
00095 };
00096 
00097 #define GNUTLS_PK_MAP_LOOP(b) \
00098         const MHD_gnutls_pk_map *p; \
00099                 for(p = MHD_gtls_pk_mappings; p->kx_algorithm != 0; p++) { b }
00100 
00101 #define GNUTLS_PK_MAP_ALG_LOOP(a) \
00102                         GNUTLS_PK_MAP_LOOP( if(p->kx_algorithm == kx_algorithm) { a; break; })
00103 
00104 /* TLS Versions */
00105 
00106 typedef struct
00107 {
00108   const char *name;
00109   enum MHD_GNUTLS_Protocol id;  /* gnutls internal version number */
00110   int major;                    /* defined by the protocol */
00111   int minor;                    /* defined by the protocol */
00112   int supported;                /* 0 not supported, > 0 is supported */
00113 } MHD_gnutls_version_entry;
00114 
00115 static const MHD_gnutls_version_entry MHD_gtls_sup_versions[] = {
00116   {"SSL3.0",
00117    MHD_GNUTLS_PROTOCOL_SSL3,
00118    3,
00119    0,
00120    1},
00121   {"TLS1.0",
00122    MHD_GNUTLS_PROTOCOL_TLS1_0,
00123    3,
00124    1,
00125    1},
00126   {"TLS1.1",
00127    MHD_GNUTLS_PROTOCOL_TLS1_1,
00128    3,
00129    2,
00130    1},
00131   {"TLS1.2",
00132    MHD_GNUTLS_PROTOCOL_TLS1_2,
00133    3,
00134    3,
00135    1},
00136   {0,
00137    0,
00138    0,
00139    0,
00140    0}
00141 };
00142 
00143 /* Keep the contents of this struct the same as the previous one. */
00144 static const enum MHD_GNUTLS_Protocol MHD_gtls_supported_protocols[] =
00145 { MHD_GNUTLS_PROTOCOL_SSL3,
00146   MHD_GNUTLS_PROTOCOL_TLS1_0,
00147   MHD_GNUTLS_PROTOCOL_TLS1_1,
00148   MHD_GNUTLS_PROTOCOL_TLS1_2,
00149   0
00150 };
00151 
00152 #define GNUTLS_VERSION_LOOP(b) \
00153         const MHD_gnutls_version_entry *p; \
00154                 for(p = MHD_gtls_sup_versions; p->name != NULL; p++) { b ; }
00155 
00156 #define GNUTLS_VERSION_ALG_LOOP(a) \
00157                         GNUTLS_VERSION_LOOP( if(p->id == version) { a; break; })
00158 
00159 struct MHD_gnutls_cipher_entry
00160 {
00161   const char *name;
00162   enum MHD_GNUTLS_CipherAlgorithm id;
00163   uint16_t blocksize;
00164   uint16_t keysize;
00165   cipher_type_t block;
00166   uint16_t iv;
00167   int export_flag;              /* 0 non export */
00168 };
00169 typedef struct MHD_gnutls_cipher_entry MHD_gnutls_cipher_entry;
00170 
00171 /* Note that all algorithms are in CBC or STREAM modes.
00172  * Do not add any algorithms in other modes (avoid modified algorithms).
00173  * View first: "The order of encryption and authentication for
00174  * protecting communications" by Hugo Krawczyk - CRYPTO 2001
00175  */
00176 static const MHD_gnutls_cipher_entry MHD_gtls_algorithms[] = {
00177   {"AES-256-CBC",
00178    MHD_GNUTLS_CIPHER_AES_256_CBC,
00179    16,
00180    32,
00181    CIPHER_BLOCK,
00182    16,
00183    0},
00184   {"AES-128-CBC",
00185    MHD_GNUTLS_CIPHER_AES_128_CBC,
00186    16,
00187    16,
00188    CIPHER_BLOCK,
00189    16,
00190    0},
00191   {"3DES-CBC",
00192    MHD_GNUTLS_CIPHER_3DES_CBC,
00193    8,
00194    24,
00195    CIPHER_BLOCK,
00196    8,
00197    0},
00198   {"ARCFOUR-128",
00199    MHD_GNUTLS_CIPHER_ARCFOUR_128,
00200    1,
00201    16,
00202    CIPHER_STREAM,
00203    0,
00204    0},
00205   {"NULL",
00206    MHD_GNUTLS_CIPHER_NULL,
00207    1,
00208    0,
00209    CIPHER_STREAM,
00210    0,
00211    0},
00212   {0,
00213    0,
00214    0,
00215    0,
00216    0,
00217    0,
00218    0}
00219 };
00220 
00221 /* Keep the contents of this struct the same as the previous one. */
00222 static const enum MHD_GNUTLS_CipherAlgorithm MHD_gtls_supported_ciphers[] =
00223 { MHD_GNUTLS_CIPHER_AES_256_CBC,
00224   MHD_GNUTLS_CIPHER_AES_128_CBC,
00225   MHD_GNUTLS_CIPHER_3DES_CBC,
00226   MHD_GNUTLS_CIPHER_ARCFOUR_128,
00227   MHD_GNUTLS_CIPHER_NULL,
00228   0
00229 };
00230 
00231 #define GNUTLS_LOOP(b) \
00232         const MHD_gnutls_cipher_entry *p; \
00233                 for(p = MHD_gtls_algorithms; p->name != NULL; p++) { b ; }
00234 
00235 #define GNUTLS_ALG_LOOP(a) \
00236                         GNUTLS_LOOP( if(p->id == algorithm) { a; break; } )
00237 
00238 struct MHD_gnutls_hash_entry
00239 {
00240   const char *name;
00241   const char *oid;
00242   enum MHD_GNUTLS_HashAlgorithm id;
00243   size_t key_size;              /* in case of mac */
00244 };
00245 typedef struct MHD_gnutls_hash_entry MHD_gnutls_hash_entry;
00246 
00247 static const MHD_gnutls_hash_entry MHD_gtls_hash_algorithms[] = {
00248   {"SHA1",
00249    HASH_OID_SHA1,
00250    MHD_GNUTLS_MAC_SHA1,
00251    20},
00252   {"MD5",
00253    HASH_OID_MD5,
00254    MHD_GNUTLS_MAC_MD5,
00255    16},
00256   {"SHA256",
00257    HASH_OID_SHA256,
00258    MHD_GNUTLS_MAC_SHA256,
00259    32},
00260   {"NULL",
00261    NULL,
00262    MHD_GNUTLS_MAC_NULL,
00263    0},
00264   {0,
00265    0,
00266    0,
00267    0}
00268 };
00269 
00270 /* Keep the contents of this struct the same as the previous one. */
00271 static const enum MHD_GNUTLS_HashAlgorithm MHD_gtls_supported_macs[] =
00272 { MHD_GNUTLS_MAC_SHA1,
00273   MHD_GNUTLS_MAC_MD5,
00274   MHD_GNUTLS_MAC_SHA256,
00275   MHD_GNUTLS_MAC_NULL,
00276   0
00277 };
00278 
00279 #define GNUTLS_HASH_LOOP(b) \
00280         const MHD_gnutls_hash_entry *p; \
00281                 for(p = MHD_gtls_hash_algorithms; p->name != NULL; p++) { b ; }
00282 
00283 #define GNUTLS_HASH_ALG_LOOP(a) \
00284                         GNUTLS_HASH_LOOP( if(p->id == algorithm) { a; break; } )
00285 
00286 /* Compression Section */
00287 #define GNUTLS_COMPRESSION_ENTRY(name, id, wb, ml, cl) \
00288         { #name, name, id, wb, ml, cl}
00289 
00290 #define MAX_COMP_METHODS 5
00291 const int MHD__gnutls_comp_algorithms_size = MAX_COMP_METHODS;
00292 
00293 /* the compression entry is defined in MHD_gnutls_algorithms.h */
00294 
00295 MHD_gnutls_compression_entry
00296   MHD__gnutls_compression_algorithms[MAX_COMP_METHODS] =
00297 {
00298   GNUTLS_COMPRESSION_ENTRY (MHD_GNUTLS_COMP_NULL, 0x00, 0, 0, 0),
00299   {
00300   0, 0, 0, 0, 0, 0}
00301 };
00302 
00303 static const enum MHD_GNUTLS_CompressionMethod
00304   MHD_gtls_supported_compressions[] =
00305 {
00306   MHD_GNUTLS_COMP_NULL,
00307   0
00308 };
00309 
00310 #define GNUTLS_COMPRESSION_LOOP(b) \
00311         const MHD_gnutls_compression_entry *p; \
00312                 for(p = MHD__gnutls_compression_algorithms; p->name != NULL; p++) { b ; }
00313 #define GNUTLS_COMPRESSION_ALG_LOOP(a) \
00314                         GNUTLS_COMPRESSION_LOOP( if(p->id == algorithm) { a; break; } )
00315 #define GNUTLS_COMPRESSION_ALG_LOOP_NUM(a) \
00316                         GNUTLS_COMPRESSION_LOOP( if(p->num == num) { a; break; } )
00317 
00318 /* Key Exchange Section */
00319 extern MHD_gtls_mod_auth_st MHD_gtls_rsa_auth_struct;
00320 extern MHD_gtls_mod_auth_st MHD_rsa_export_auth_struct;
00321 extern MHD_gtls_mod_auth_st MHD_gtls_dhe_rsa_auth_struct;
00322 extern MHD_gtls_mod_auth_st MHD_gtls_dhe_dss_auth_struct;
00323 extern MHD_gtls_mod_auth_st srp_auth_struct;
00324 extern MHD_gtls_mod_auth_st psk_auth_struct;
00325 extern MHD_gtls_mod_auth_st dhe_psk_auth_struct;
00326 extern MHD_gtls_mod_auth_st srp_rsa_auth_struct;
00327 extern MHD_gtls_mod_auth_st srp_dss_auth_struct;
00328 
00329 typedef struct MHD_gtls_kx_algo_entry
00330 {
00331   const char *name;
00332   enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm;
00333   MHD_gtls_mod_auth_st *auth_struct;
00334   int needs_dh_params;
00335   int needs_rsa_params;
00336 } MHD_gtls_kx_algo_entry_t;
00337 
00338 static const MHD_gtls_kx_algo_entry_t MHD_gtls_kx_algorithms[] = {
00339   {"RSA",
00340    MHD_GNUTLS_KX_RSA,
00341    &MHD_gtls_rsa_auth_struct,
00342    0,
00343    0},
00344   {"RSA-EXPORT",
00345    MHD_GNUTLS_KX_RSA_EXPORT,
00346    &MHD_rsa_export_auth_struct,
00347    0,
00348    1 /* needs RSA params */ },
00349   {0,
00350    0,
00351    0,
00352    0,
00353    0}
00354 };
00355 
00356 /* Keep the contents of this struct the same as the previous one. */
00357 static const enum MHD_GNUTLS_KeyExchangeAlgorithm MHD_gtls_supported_kxs[] =
00358 {
00359   MHD_GNUTLS_KX_RSA,
00360   MHD_GNUTLS_KX_RSA_EXPORT,
00361   0
00362 };
00363 
00364 #define GNUTLS_KX_LOOP(b) \
00365         const MHD_gtls_kx_algo_entry_t *p; \
00366                 for(p = MHD_gtls_kx_algorithms; p->name != NULL; p++) { b ; }
00367 
00368 #define GNUTLS_KX_ALG_LOOP(a) \
00369                         GNUTLS_KX_LOOP( if(p->algorithm == algorithm) { a; break; } )
00370 
00371 /* Cipher SUITES */
00372 #define GNUTLS_CIPHER_SUITE_ENTRY( name, block_algorithm, kx_algorithm, mac_algorithm, version ) \
00373         { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, version }
00374 
00375 typedef struct
00376 {
00377   const char *name;
00378   cipher_suite_st id;
00379   enum MHD_GNUTLS_CipherAlgorithm block_algorithm;
00380   enum MHD_GNUTLS_KeyExchangeAlgorithm kx_algorithm;
00381   enum MHD_GNUTLS_HashAlgorithm mac_algorithm;
00382   enum MHD_GNUTLS_Protocol version;     /* this cipher suite is supported
00383                                          * from 'version' and above;
00384                                          */
00385 } MHD_gtls_cipher_suite_entry;
00386 
00387 /* RSA with NULL cipher and MD5 MAC
00388  * for test purposes.
00389  */
00390 #define GNUTLS_RSA_NULL_MD5 { 0x00, 0x01 }
00391 
00392 /* PSK (not in TLS 1.0)
00393  * draft-ietf-tls-psk:
00394  */
00395 #define GNUTLS_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8A }
00396 #define GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8B }
00397 #define GNUTLS_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x8C }
00398 #define GNUTLS_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x8D }
00399 
00400 #define GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8E }
00401 #define GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8F }
00402 #define GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x90 }
00403 #define GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x91 }
00404 
00405 /* SRP (rfc5054)
00406  */
00407 #define GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1A }
00408 #define GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1B }
00409 #define GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1 { 0xC0, 0x1C }
00410 
00411 #define GNUTLS_SRP_SHA_AES_128_CBC_SHA1 { 0xC0, 0x1D }
00412 #define GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1 { 0xC0, 0x1E }
00413 #define GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1 { 0xC0, 0x1F }
00414 
00415 #define GNUTLS_SRP_SHA_AES_256_CBC_SHA1 { 0xC0, 0x20 }
00416 #define GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1 { 0xC0, 0x21 }
00417 #define GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1 { 0xC0, 0x22 }
00418 
00419 /* RSA
00420  */
00421 #define GNUTLS_RSA_ARCFOUR_SHA1 { 0x00, 0x05 }
00422 #define GNUTLS_RSA_ARCFOUR_MD5 { 0x00, 0x04 }
00423 #define GNUTLS_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x0A }
00424 
00425 /* rfc3268:
00426  */
00427 #define GNUTLS_RSA_AES_128_CBC_SHA1 { 0x00, 0x2F }
00428 #define GNUTLS_RSA_AES_256_CBC_SHA1 { 0x00, 0x35 }
00429 
00430 /* rfc4132 */
00431 #define GNUTLS_RSA_CAMELLIA_128_CBC_SHA1 { 0x00,0x41 }
00432 #define GNUTLS_RSA_CAMELLIA_256_CBC_SHA1 { 0x00,0x84 }
00433 
00434 /* DHE DSS
00435  */
00436 
00437 #define GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1 { 0x00, 0x13 }
00438 
00439 /* draft-ietf-tls-56-bit-ciphersuites-01:
00440  */
00441 #define GNUTLS_DHE_DSS_ARCFOUR_SHA1 { 0x00, 0x66 }
00442 
00443 /* rfc3268:
00444  */
00445 #define GNUTLS_DHE_DSS_AES_256_CBC_SHA1 { 0x00, 0x38 }
00446 #define GNUTLS_DHE_DSS_AES_128_CBC_SHA1 { 0x00, 0x32 }
00447 
00448 /* rfc4132 */
00449 #define GNUTLS_DHE_DSS_CAMELLIA_128_CBC_SHA1 { 0x00,0x44 }
00450 #define GNUTLS_DHE_DSS_CAMELLIA_256_CBC_SHA1 { 0x00,0x87 }
00451 
00452 /* DHE RSA
00453  */
00454 #define GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x16 }
00455 
00456 /* rfc3268:
00457  */
00458 #define GNUTLS_DHE_RSA_AES_128_CBC_SHA1 { 0x00, 0x33 }
00459 #define GNUTLS_DHE_RSA_AES_256_CBC_SHA1 { 0x00, 0x39 }
00460 
00461 /* rfc4132 */
00462 #define GNUTLS_DHE_RSA_CAMELLIA_128_CBC_SHA1 { 0x00,0x45 }
00463 #define GNUTLS_DHE_RSA_CAMELLIA_256_CBC_SHA1 { 0x00,0x88 }
00464 
00465 #define CIPHER_SUITES_COUNT sizeof(MHD_gtls_cs_algorithms)/sizeof(MHD_gtls_cipher_suite_entry)-1
00466 
00467 static const MHD_gtls_cipher_suite_entry MHD_gtls_cs_algorithms[] = {
00468   /* RSA */
00469   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_MD5,
00470                              MHD_GNUTLS_CIPHER_NULL,
00471                              MHD_GNUTLS_KX_RSA, MHD_GNUTLS_MAC_MD5,
00472                              MHD_GNUTLS_PROTOCOL_SSL3),
00473   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_SHA1,
00474                              MHD_GNUTLS_CIPHER_ARCFOUR_128,
00475                              MHD_GNUTLS_KX_RSA, MHD_GNUTLS_MAC_SHA1,
00476                              MHD_GNUTLS_PROTOCOL_SSL3),
00477   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_MD5,
00478                              MHD_GNUTLS_CIPHER_ARCFOUR_128,
00479                              MHD_GNUTLS_KX_RSA, MHD_GNUTLS_MAC_MD5,
00480                              MHD_GNUTLS_PROTOCOL_SSL3),
00481   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_3DES_EDE_CBC_SHA1,
00482                              MHD_GNUTLS_CIPHER_3DES_CBC,
00483                              MHD_GNUTLS_KX_RSA, MHD_GNUTLS_MAC_SHA1,
00484                              MHD_GNUTLS_PROTOCOL_SSL3),
00485   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_128_CBC_SHA1,
00486                              MHD_GNUTLS_CIPHER_AES_128_CBC, MHD_GNUTLS_KX_RSA,
00487                              MHD_GNUTLS_MAC_SHA1, MHD_GNUTLS_PROTOCOL_SSL3),
00488   GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_256_CBC_SHA1,
00489                              MHD_GNUTLS_CIPHER_AES_256_CBC, MHD_GNUTLS_KX_RSA,
00490                              MHD_GNUTLS_MAC_SHA1, MHD_GNUTLS_PROTOCOL_SSL3),
00491   {0,
00492    {
00493     {0,
00494      0}},
00495    0,
00496    0,
00497    0,
00498    0}
00499 };
00500 
00501 #define GNUTLS_CIPHER_SUITE_LOOP(b) \
00502         const MHD_gtls_cipher_suite_entry *p; \
00503                 for(p = MHD_gtls_cs_algorithms; p->name != NULL; p++) { b ; }
00504 
00505 #define GNUTLS_CIPHER_SUITE_ALG_LOOP(a) \
00506                         GNUTLS_CIPHER_SUITE_LOOP( if( (p->id.suite[0] == suite->suite[0]) && (p->id.suite[1] == suite->suite[1])) { a; break; } )
00507 
00508 /* Generic Functions */
00509 
00510 int
00511 MHD_gtls_mac_priority (MHD_gtls_session_t session,
00512                        enum MHD_GNUTLS_HashAlgorithm algorithm)
00513 {                               /* actually returns the priority */
00514   unsigned int i;
00515   for (i = 0; i < session->internals.priorities.mac.num_algorithms; i++)
00516     {
00517       if (session->internals.priorities.mac.priority[i] == algorithm)
00518         return i;
00519     }
00520   return -1;
00521 }
00522 
00523 
00524 int
00525 MHD_gnutls_mac_is_ok (enum MHD_GNUTLS_HashAlgorithm algorithm)
00526 {
00527   ssize_t ret = -1;
00528   GNUTLS_HASH_ALG_LOOP (ret = p->id);
00529   if (ret >= 0)
00530     ret = 0;
00531   else
00532     ret = 1;
00533   return ret;
00534 }
00535 
00536 
00544 const char *
00545 MHD_gtls_compression_get_name (enum MHD_GNUTLS_CompressionMethod algorithm)
00546 {
00547   const char *ret = NULL;
00548 
00549   /* avoid prefix */
00550   GNUTLS_COMPRESSION_ALG_LOOP (ret = p->name + sizeof ("GNUTLS_COMP_") - 1);
00551 
00552   return ret;
00553 }
00554 
00565 enum MHD_GNUTLS_CompressionMethod
00566 MHD_gtls_compression_get_id (const char *name)
00567 {
00568   enum MHD_GNUTLS_CompressionMethod ret = MHD_GNUTLS_COMP_UNKNOWN;
00569 
00570   GNUTLS_COMPRESSION_LOOP (if
00571                            (strcasecmp
00572                             (p->name + sizeof ("GNUTLS_COMP_") - 1,
00573                              name) == 0) ret = p->id)
00574     ;
00575 
00576   return ret;
00577 }
00578 
00579 
00580 /* return the tls number of the specified algorithm */
00581 int
00582 MHD_gtls_compression_get_num (enum MHD_GNUTLS_CompressionMethod algorithm)
00583 {
00584   int ret = -1;
00585 
00586   /* avoid prefix */
00587   GNUTLS_COMPRESSION_ALG_LOOP (ret = p->num);
00588 
00589   return ret;
00590 }
00591 
00592 int
00593 MHD_gtls_compression_get_wbits (enum MHD_GNUTLS_CompressionMethod algorithm)
00594 {
00595   int ret = -1;
00596   /* avoid prefix */
00597   GNUTLS_COMPRESSION_ALG_LOOP (ret = p->window_bits);
00598   return ret;
00599 }
00600 
00601 int
00602 MHD_gtls_compression_get_mem_level (enum MHD_GNUTLS_CompressionMethod
00603                                     algorithm)
00604 {
00605   int ret = -1;
00606   /* avoid prefix */
00607   GNUTLS_COMPRESSION_ALG_LOOP (ret = p->mem_level);
00608   return ret;
00609 }
00610 
00611 int
00612 MHD_gtls_compression_get_comp_level (enum MHD_GNUTLS_CompressionMethod
00613                                      algorithm)
00614 {
00615   int ret = -1;
00616   /* avoid prefix */
00617   GNUTLS_COMPRESSION_ALG_LOOP (ret = p->comp_level);
00618   return ret;
00619 }
00620 
00621 /* returns the gnutls internal ID of the TLS compression
00622  * method num
00623  */
00624 enum MHD_GNUTLS_CompressionMethod
00625 MHD_gtls_compression_get_id_from_int (int num)
00626 {
00627   enum MHD_GNUTLS_CompressionMethod ret = -1;
00628 
00629   /* avoid prefix */
00630   GNUTLS_COMPRESSION_ALG_LOOP_NUM (ret = p->id);
00631 
00632   return ret;
00633 }
00634 
00635 int
00636 MHD_gtls_compression_is_ok (enum MHD_GNUTLS_CompressionMethod algorithm)
00637 {
00638   ssize_t ret = -1;
00639   GNUTLS_COMPRESSION_ALG_LOOP (ret = p->id);
00640   if (ret >= 0)
00641     ret = 0;
00642   else
00643     ret = 1;
00644   return ret;
00645 }
00646 
00647 /* CIPHER functions */
00648 int
00649 MHD_gtls_cipher_get_block_size (enum MHD_GNUTLS_CipherAlgorithm algorithm)
00650 {
00651   size_t ret = 0;
00652   GNUTLS_ALG_LOOP (ret = p->blocksize);
00653   return ret;
00654 
00655 }
00656 
00657 /* returns the priority */
00658 int
00659 MHD_gtls_cipher_priority (MHD_gtls_session_t session,
00660                           enum MHD_GNUTLS_CipherAlgorithm algorithm)
00661 {
00662   unsigned int i;
00663   for (i = 0; i < session->internals.priorities.cipher.num_algorithms; i++)
00664     {
00665       if (session->internals.priorities.cipher.priority[i] == algorithm)
00666         return i;
00667     }
00668   return -1;
00669 }
00670 
00671 int
00672 MHD_gtls_cipher_is_block (enum MHD_GNUTLS_CipherAlgorithm algorithm)
00673 {
00674   size_t ret = 0;
00675 
00676   GNUTLS_ALG_LOOP (ret = p->block);
00677   return ret;
00678 
00679 }
00680 
00688 size_t
00689 MHD__gnutls_cipher_get_key_size (enum MHD_GNUTLS_CipherAlgorithm algorithm)
00690 {                               /* In bytes */
00691   size_t ret = 0;
00692   GNUTLS_ALG_LOOP (ret = p->keysize);
00693   return ret;
00694 
00695 }
00696 
00697 int
00698 MHD_gtls_cipher_get_iv_size (enum MHD_GNUTLS_CipherAlgorithm algorithm)
00699 {                               /* In bytes */
00700   size_t ret = 0;
00701   GNUTLS_ALG_LOOP (ret = p->iv);
00702   return ret;
00703 
00704 }
00705 
00706 int
00707 MHD_gtls_cipher_get_export_flag (enum MHD_GNUTLS_CipherAlgorithm algorithm)
00708 {                               /* In bytes */
00709   size_t ret = 0;
00710   GNUTLS_ALG_LOOP (ret = p->export_flag);
00711   return ret;
00712 
00713 }
00714 
00715 
00716 int
00717 MHD_gtls_cipher_is_ok (enum MHD_GNUTLS_CipherAlgorithm algorithm)
00718 {
00719   ssize_t ret = -1;
00720   GNUTLS_ALG_LOOP (ret = p->id);
00721   if (ret >= 0)
00722     ret = 0;
00723   else
00724     ret = 1;
00725   return ret;
00726 }
00727 
00728 /* Key EXCHANGE functions */
00729 MHD_gtls_mod_auth_st *
00730 MHD_gtls_kx_auth_struct (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm)
00731 {
00732   MHD_gtls_mod_auth_st *ret = NULL;
00733   GNUTLS_KX_ALG_LOOP (ret = p->auth_struct);
00734   return ret;
00735 
00736 }
00737 
00738 int
00739 MHD_gtls_kx_priority (MHD_gtls_session_t session,
00740                       enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm)
00741 {
00742   unsigned int i;
00743   for (i = 0; i < session->internals.priorities.kx.num_algorithms; i++)
00744     {
00745       if (session->internals.priorities.kx.priority[i] == algorithm)
00746         return i;
00747     }
00748   return -1;
00749 }
00750 
00751 
00752 int
00753 MHD_gtls_kx_is_ok (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm)
00754 {
00755   ssize_t ret = -1;
00756   GNUTLS_KX_ALG_LOOP (ret = p->algorithm);
00757   if (ret >= 0)
00758     ret = 0;
00759   else
00760     ret = 1;
00761   return ret;
00762 }
00763 
00764 int
00765 MHD_gtls_kx_needs_rsa_params (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm)
00766 {
00767   ssize_t ret = 0;
00768   GNUTLS_KX_ALG_LOOP (ret = p->needs_rsa_params);
00769   return ret;
00770 }
00771 
00772 int
00773 MHD_gtls_kx_needs_dh_params (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm)
00774 {
00775   ssize_t ret = 0;
00776   GNUTLS_KX_ALG_LOOP (ret = p->needs_dh_params);
00777   return ret;
00778 }
00779 
00780 /* Version */
00781 int
00782 MHD_gtls_version_priority (MHD_gtls_session_t session,
00783                            enum MHD_GNUTLS_Protocol version)
00784 {                               /* actually returns the priority */
00785   unsigned int i;
00786 
00787   if (session->internals.priorities.protocol.priority == NULL)
00788     {
00789       MHD_gnutls_assert ();
00790       return -1;
00791     }
00792 
00793   for (i = 0; i < session->internals.priorities.protocol.num_algorithms; i++)
00794     {
00795       if (session->internals.priorities.protocol.priority[i] == version)
00796         return i;
00797     }
00798   return -1;
00799 }
00800 
00801 
00802 enum MHD_GNUTLS_Protocol
00803 MHD_gtls_version_max (MHD_gtls_session_t session)
00804 {                               /* returns the maximum version supported */
00805   unsigned int i, max = 0x00;
00806 
00807   if (session->internals.priorities.protocol.priority == NULL)
00808     {
00809       return MHD_GNUTLS_PROTOCOL_VERSION_UNKNOWN;
00810     }
00811   else
00812     for (i = 0; i < session->internals.priorities.protocol.num_algorithms;
00813          i++)
00814       {
00815         if (session->internals.priorities.protocol.priority[i] > max)
00816           max = session->internals.priorities.protocol.priority[i];
00817       }
00818 
00819   if (max == 0x00)
00820     return MHD_GNUTLS_PROTOCOL_VERSION_UNKNOWN; /* unknown version */
00821 
00822   return max;
00823 }
00824 
00825 int
00826 MHD_gtls_version_get_minor (enum MHD_GNUTLS_Protocol version)
00827 {
00828   int ret = -1;
00829 
00830   GNUTLS_VERSION_ALG_LOOP (ret = p->minor);
00831   return ret;
00832 }
00833 
00834 enum MHD_GNUTLS_Protocol
00835 MHD_gtls_version_get (int major, int minor)
00836 {
00837   int ret = -1;
00838 
00839   GNUTLS_VERSION_LOOP (if ((p->major == major) && (p->minor == minor))
00840                        ret = p->id)
00841     ;
00842   return ret;
00843 }
00844 
00845 int
00846 MHD_gtls_version_get_major (enum MHD_GNUTLS_Protocol version)
00847 {
00848   int ret = -1;
00849 
00850   GNUTLS_VERSION_ALG_LOOP (ret = p->major);
00851   return ret;
00852 }
00853 
00854 /* Version Functions */
00855 
00856 int
00857 MHD_gtls_version_is_supported (MHD_gtls_session_t session,
00858                                const enum MHD_GNUTLS_Protocol version)
00859 {
00860   int ret = 0;
00861 
00862   GNUTLS_VERSION_ALG_LOOP (ret = p->supported);
00863   if (ret == 0)
00864     return 0;
00865 
00866   if (MHD_gtls_version_priority (session, version) < 0)
00867     return 0;                   /* disabled by the user */
00868   else
00869     return 1;
00870 }
00871 
00872 enum MHD_GNUTLS_CredentialsType
00873 MHD_gtls_map_kx_get_cred (enum MHD_GNUTLS_KeyExchangeAlgorithm algorithm,
00874                           int server)
00875 {
00876   enum MHD_GNUTLS_CredentialsType ret = -1;
00877   if (server)
00878     {
00879       GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret = p->server_type)
00880         ;
00881     }
00882   else
00883     {
00884       GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret = p->client_type)
00885         ;
00886     }
00887 
00888   return ret;
00889 }
00890 
00891 /* Cipher Suite's functions */
00892 enum MHD_GNUTLS_CipherAlgorithm
00893 MHD_gtls_cipher_suite_get_cipher_algo (const cipher_suite_st * suite)
00894 {
00895   int ret = 0;
00896   GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->block_algorithm);
00897   return ret;
00898 }
00899 
00900 enum MHD_GNUTLS_Protocol
00901 MHD_gtls_cipher_suite_get_version (const cipher_suite_st * suite)
00902 {
00903   int ret = 0;
00904   GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->version);
00905   return ret;
00906 }
00907 
00908 enum MHD_GNUTLS_KeyExchangeAlgorithm
00909 MHD_gtls_cipher_suite_get_kx_algo (const cipher_suite_st * suite)
00910 {
00911   int ret = 0;
00912 
00913   GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->kx_algorithm);
00914   return ret;
00915 
00916 }
00917 
00918 enum MHD_GNUTLS_HashAlgorithm
00919 MHD_gtls_cipher_suite_get_mac_algo (const cipher_suite_st * suite)
00920 {                               /* In bytes */
00921   int ret = 0;
00922   GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->mac_algorithm);
00923   return ret;
00924 
00925 }
00926 
00927 const char *
00928 MHD_gtls_cipher_suite_get_name (cipher_suite_st * suite)
00929 {
00930   const char *ret = NULL;
00931 
00932   /* avoid prefix */
00933   GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->name + sizeof ("GNUTLS_") - 1);
00934 
00935   return ret;
00936 }
00937 
00938 static inline int
00939 MHD__gnutls_cipher_suite_is_ok (cipher_suite_st * suite)
00940 {
00941   size_t ret;
00942   const char *name = NULL;
00943 
00944   GNUTLS_CIPHER_SUITE_ALG_LOOP (name = p->name);
00945   if (name != NULL)
00946     ret = 0;
00947   else
00948     ret = 1;
00949   return ret;
00950 
00951 }
00952 
00953 #define SWAP(x, y) memcpy(tmp,x,size); \
00954                    memcpy(x,y,size); \
00955                    memcpy(y,tmp,size);
00956 
00957 #define MAX_ELEM_SIZE 4
00958 static inline int
00959 MHD__gnutls_partition (MHD_gtls_session_t session,
00960                        void *_base,
00961                        size_t nmemb,
00962                        size_t size,
00963                        int (*compar) (MHD_gtls_session_t,
00964                                       const void *, const void *))
00965 {
00966   uint8_t *base = _base;
00967   uint8_t tmp[MAX_ELEM_SIZE];
00968   uint8_t ptmp[MAX_ELEM_SIZE];
00969   unsigned int pivot;
00970   unsigned int i, j;
00971   unsigned int full;
00972 
00973   i = pivot = 0;
00974   j = full = (nmemb - 1) * size;
00975 
00976   memcpy (ptmp, &base[0], size);        /* set pivot item */
00977 
00978   while (i < j)
00979     {
00980       while ((compar (session, &base[i], ptmp) <= 0) && (i < full))
00981         {
00982           i += size;
00983         }
00984       while ((compar (session, &base[j], ptmp) >= 0) && (j > 0))
00985         j -= size;
00986 
00987       if (i < j)
00988         {
00989           SWAP (&base[j], &base[i]);
00990         }
00991     }
00992 
00993   if (j > pivot)
00994     {
00995       SWAP (&base[pivot], &base[j]);
00996       pivot = j;
00997     }
00998   else if (i < pivot)
00999     {
01000       SWAP (&base[pivot], &base[i]);
01001       pivot = i;
01002     }
01003   return pivot / size;
01004 }
01005 
01006 static void
01007 MHD__gnutls_qsort (MHD_gtls_session_t session,
01008                    void *_base,
01009                    size_t nmemb,
01010                    size_t size,
01011                    int (*compar) (MHD_gtls_session_t, const void *,
01012                                   const void *))
01013 {
01014   unsigned int pivot;
01015   char *base = _base;
01016   size_t snmemb = nmemb;
01017 
01018   if (snmemb <= 1)
01019     return;
01020   pivot = MHD__gnutls_partition (session, _base, nmemb, size, compar);
01021 
01022   MHD__gnutls_qsort (session, base, pivot < nmemb ? pivot + 1
01023                      : pivot, size, compar);
01024   MHD__gnutls_qsort (session, &base[(pivot + 1) * size], nmemb - pivot - 1,
01025                      size, compar);
01026 }
01027 
01028 /* a compare function for KX algorithms (using priorities).
01029  * For use with qsort
01030  */
01031 static int
01032 MHD__gnutls_compare_algo (MHD_gtls_session_t session,
01033                           const void *i_A1, const void *i_A2)
01034 {
01035   enum MHD_GNUTLS_KeyExchangeAlgorithm kA1 =
01036     MHD_gtls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A1);
01037   enum MHD_GNUTLS_KeyExchangeAlgorithm kA2 =
01038     MHD_gtls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A2);
01039   enum MHD_GNUTLS_CipherAlgorithm cA1 =
01040     MHD_gtls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A1);
01041   enum MHD_GNUTLS_CipherAlgorithm cA2 =
01042     MHD_gtls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A2);
01043   enum MHD_GNUTLS_HashAlgorithm mA1 =
01044     MHD_gtls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A1);
01045   enum MHD_GNUTLS_HashAlgorithm mA2 =
01046     MHD_gtls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A2);
01047 
01048   int p1 = (MHD_gtls_kx_priority (session, kA1) + 1) * 64;
01049   int p2 = (MHD_gtls_kx_priority (session, kA2) + 1) * 64;
01050   p1 += (MHD_gtls_cipher_priority (session, cA1) + 1) * 8;
01051   p2 += (MHD_gtls_cipher_priority (session, cA2) + 1) * 8;
01052   p1 += MHD_gtls_mac_priority (session, mA1);
01053   p2 += MHD_gtls_mac_priority (session, mA2);
01054 
01055   if (p1 > p2)
01056     {
01057       return 1;
01058     }
01059   else
01060     {
01061       if (p1 == p2)
01062         {
01063           return 0;
01064         }
01065       return -1;
01066     }
01067 }
01068 
01069 int
01070 MHD_gtls_supported_ciphersuites_sorted (MHD_gtls_session_t session,
01071                                         cipher_suite_st ** ciphers)
01072 {
01073 
01074   int count;
01075 
01076   count = MHD_gtls_supported_ciphersuites (session, ciphers);
01077   if (count <= 0)
01078     {
01079       MHD_gnutls_assert ();
01080       return count;
01081     }
01082   MHD__gnutls_qsort (session, *ciphers, count, sizeof (cipher_suite_st),
01083                      MHD__gnutls_compare_algo);
01084 
01085   return count;
01086 }
01087 
01088 int
01089 MHD_gtls_supported_ciphersuites (MHD_gtls_session_t session,
01090                                  cipher_suite_st ** _ciphers)
01091 {
01092 
01093   unsigned int i, ret_count, j;
01094   unsigned int count = CIPHER_SUITES_COUNT;
01095   cipher_suite_st *tmp_ciphers;
01096   cipher_suite_st *ciphers;
01097   enum MHD_GNUTLS_Protocol version;
01098 
01099   if (count == 0)
01100     {
01101       return 0;
01102     }
01103 
01104   tmp_ciphers = MHD_gnutls_alloca (count * sizeof (cipher_suite_st));
01105   if (tmp_ciphers == NULL)
01106     return GNUTLS_E_MEMORY_ERROR;
01107 
01108   ciphers = MHD_gnutls_malloc (count * sizeof (cipher_suite_st));
01109   if (ciphers == NULL)
01110     {
01111       MHD_gnutls_afree (tmp_ciphers);
01112       return GNUTLS_E_MEMORY_ERROR;
01113     }
01114 
01115   version = MHD__gnutls_protocol_get_version (session);
01116 
01117   for (i = 0; i < count; i++)
01118     {
01119       memcpy (&tmp_ciphers[i], &MHD_gtls_cs_algorithms[i].id,
01120               sizeof (cipher_suite_st));
01121     }
01122 
01123   for (i = j = 0; i < count; i++)
01124     {
01125       /* remove private cipher suites, if requested.
01126        */
01127       if (tmp_ciphers[i].suite[0] == 0xFF)
01128         continue;
01129 
01130       /* remove cipher suites which do not support the
01131        * protocol version used.
01132        */
01133       if (MHD_gtls_cipher_suite_get_version (&tmp_ciphers[i]) > version)
01134         continue;
01135 
01136       if (MHD_gtls_kx_priority (session,
01137                                 MHD_gtls_cipher_suite_get_kx_algo
01138                                 (&tmp_ciphers[i])) < 0)
01139         continue;
01140       if (MHD_gtls_mac_priority (session,
01141                                  MHD_gtls_cipher_suite_get_mac_algo
01142                                  (&tmp_ciphers[i])) < 0)
01143         continue;
01144       if (MHD_gtls_cipher_priority (session,
01145                                     MHD_gtls_cipher_suite_get_cipher_algo
01146                                     (&tmp_ciphers[i])) < 0)
01147         continue;
01148 
01149       memcpy (&ciphers[j], &tmp_ciphers[i], sizeof (cipher_suite_st));
01150       j++;
01151     }
01152 
01153   ret_count = j;
01154 
01155   MHD_gnutls_afree (tmp_ciphers);
01156 
01157   /* This function can no longer return 0 cipher suites.
01158    * It returns an error code instead.
01159    */
01160   if (ret_count == 0)
01161     {
01162       MHD_gnutls_assert ();
01163       MHD_gnutls_free (ciphers);
01164       return GNUTLS_E_NO_CIPHER_SUITES;
01165     }
01166   *_ciphers = ciphers;
01167   return ret_count;
01168 }
01169 
01170 /* For compression  */
01171 
01172 #define MIN_PRIVATE_COMP_ALGO 0xEF
01173 
01174 /* returns the TLS numbers of the compression methods we support
01175  */
01176 #define SUPPORTED_COMPRESSION_METHODS session->internals.priorities.compression.num_algorithms
01177 int
01178 MHD_gtls_supported_compression_methods (MHD_gtls_session_t session,
01179                                         uint8_t ** comp)
01180 {
01181   unsigned int i, j;
01182 
01183   *comp =
01184     MHD_gnutls_malloc (sizeof (uint8_t) * SUPPORTED_COMPRESSION_METHODS);
01185   if (*comp == NULL)
01186     return GNUTLS_E_MEMORY_ERROR;
01187 
01188   for (i = j = 0; i < SUPPORTED_COMPRESSION_METHODS; i++)
01189     {
01190       int tmp =
01191         MHD_gtls_compression_get_num (session->internals.priorities.
01192                                       compression.priority[i]);
01193 
01194       /* remove private compression algorithms, if requested.
01195        */
01196       if (tmp == -1 || (tmp >= MIN_PRIVATE_COMP_ALGO))
01197         {
01198           MHD_gnutls_assert ();
01199           continue;
01200         }
01201 
01202       (*comp)[j] = (uint8_t) tmp;
01203       j++;
01204     }
01205 
01206   if (j == 0)
01207     {
01208       MHD_gnutls_assert ();
01209       MHD_gnutls_free (*comp);
01210       *comp = NULL;
01211       return GNUTLS_E_NO_COMPRESSION_ALGORITHMS;
01212     }
01213   return j;
01214 }
01215 
01216 static const enum MHD_GNUTLS_CertificateType
01217   MHD_gtls_supported_certificate_types[] =
01218 { MHD_GNUTLS_CRT_X509,
01219   0
01220 };
01221 
01222 
01223 /* returns the enum MHD_GNUTLS_PublicKeyAlgorithm which is compatible with
01224  * the given enum MHD_GNUTLS_KeyExchangeAlgorithm.
01225  */
01226 enum MHD_GNUTLS_PublicKeyAlgorithm
01227 MHD_gtls_map_pk_get_pk (enum MHD_GNUTLS_KeyExchangeAlgorithm kx_algorithm)
01228 {
01229   enum MHD_GNUTLS_PublicKeyAlgorithm ret = -1;
01230 
01231   GNUTLS_PK_MAP_ALG_LOOP (ret = p->pk_algorithm) return ret;
01232 }
01233 
01234 /* Returns the encipher type for the given key exchange algorithm.
01235  * That one of CIPHER_ENCRYPT, CIPHER_SIGN, CIPHER_IGN.
01236  *
01237  * ex. GNUTLS_KX_RSA requires a certificate able to encrypt... so returns CIPHER_ENCRYPT.
01238  */
01239 enum encipher_type
01240 MHD_gtls_kx_encipher_type (enum MHD_GNUTLS_KeyExchangeAlgorithm kx_algorithm)
01241 {
01242   int ret = CIPHER_IGN;
01243   GNUTLS_PK_MAP_ALG_LOOP (ret = p->encipher_type) return ret;
01244 
01245 }
01246 
01247 /* signature algorithms;
01248  */
01249 struct MHD_gnutls_sign_entry
01250 {
01251   const char *name;
01252   const char *oid;
01253   MHD_gnutls_sign_algorithm_t id;
01254   enum MHD_GNUTLS_PublicKeyAlgorithm pk;
01255   enum MHD_GNUTLS_HashAlgorithm mac;
01256 };
01257 typedef struct MHD_gnutls_sign_entry MHD_gnutls_sign_entry;
01258 
01259 static const MHD_gnutls_sign_entry MHD_gtls_sign_algorithms[] = {
01260   {"RSA-SHA",
01261    SIG_RSA_SHA1_OID,
01262    GNUTLS_SIGN_RSA_SHA1,
01263    MHD_GNUTLS_PK_RSA,
01264    MHD_GNUTLS_MAC_SHA1},
01265   {"RSA-SHA256",
01266    SIG_RSA_SHA256_OID,
01267    GNUTLS_SIGN_RSA_SHA256,
01268    MHD_GNUTLS_PK_RSA,
01269    MHD_GNUTLS_MAC_SHA256},
01270   {"RSA-MD5",
01271    SIG_RSA_MD5_OID,
01272    GNUTLS_SIGN_RSA_MD5,
01273    MHD_GNUTLS_PK_RSA,
01274    MHD_GNUTLS_MAC_MD5},
01275   {"GOST R 34.10-2001",
01276    SIG_GOST_R3410_2001_OID,
01277    0,
01278    0,
01279    0},
01280   {"GOST R 34.10-94",
01281    SIG_GOST_R3410_94_OID,
01282    0,
01283    0,
01284    0},
01285   {0,
01286    0,
01287    0,
01288    0,
01289    0}
01290 };
01291 
01292 #define GNUTLS_SIGN_LOOP(b) \
01293   do {                                                                 \
01294     const MHD_gnutls_sign_entry *p;                                            \
01295     for(p = MHD_gtls_sign_algorithms; p->name != NULL; p++) { b ; }            \
01296   } while (0)
01297 
01298 #define GNUTLS_SIGN_ALG_LOOP(a) \
01299   GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } )
01300 
01301 /* pk algorithms;
01302  */
01303 struct MHD_gnutls_pk_entry
01304 {
01305   const char *name;
01306   const char *oid;
01307   enum MHD_GNUTLS_PublicKeyAlgorithm id;
01308 };
01309 typedef struct MHD_gnutls_pk_entry MHD_gnutls_pk_entry;
01310 
01311 static const MHD_gnutls_pk_entry MHD_gtls_pk_algorithms[] = {
01312   {"RSA",
01313    PK_PKIX1_RSA_OID,
01314    MHD_GNUTLS_PK_RSA},
01315   {"GOST R 34.10-2001",
01316    PK_GOST_R3410_2001_OID,
01317    0},
01318   {"GOST R 34.10-94",
01319    PK_GOST_R3410_94_OID,
01320    0},
01321   {0,
01322    0,
01323    0}
01324 };
01325 
01326 enum MHD_GNUTLS_PublicKeyAlgorithm
01327 MHD_gtls_x509_oid2pk_algorithm (const char *oid)
01328 {
01329   enum MHD_GNUTLS_PublicKeyAlgorithm ret = MHD_GNUTLS_PK_UNKNOWN;
01330   const MHD_gnutls_pk_entry *p;
01331 
01332   for (p = MHD_gtls_pk_algorithms; p->name != NULL; p++)
01333     if (strcmp (p->oid, oid) == 0)
01334       {
01335         ret = p->id;
01336         break;
01337       }
01338 
01339   return ret;
01340 }

Generated on Fri Feb 27 18:31:19 2009 for GNU libmicrohttpd by  doxygen 1.5.7.1