2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS 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 3 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 License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <algorithms.h>
25 #include <gnutls_errors.h>
26 #include <x509/common.h>
28 /* signature algorithms;
30 struct gnutls_sign_entry
34 gnutls_sign_algorithm_t id
;
35 gnutls_pk_algorithm_t pk
;
36 gnutls_digest_algorithm_t mac
;
37 /* See RFC 5246 HashAlgorithm and SignatureAlgorithm
38 for values to use in aid struct. */
39 const sign_algorithm_st aid
;
41 typedef struct gnutls_sign_entry gnutls_sign_entry
;
43 #define TLS_SIGN_AID_UNKNOWN {255, 255}
44 static const sign_algorithm_st unknown_tls_aid
= TLS_SIGN_AID_UNKNOWN
;
46 static const gnutls_sign_entry sign_algorithms
[] = {
47 {"RSA-SHA1", SIG_RSA_SHA1_OID
, GNUTLS_SIGN_RSA_SHA1
, GNUTLS_PK_RSA
,
48 GNUTLS_MAC_SHA1
, {2, 1}},
49 {"RSA-SHA224", SIG_RSA_SHA224_OID
, GNUTLS_SIGN_RSA_SHA224
, GNUTLS_PK_RSA
,
50 GNUTLS_MAC_SHA224
, {3, 1}},
51 {"RSA-SHA256", SIG_RSA_SHA256_OID
, GNUTLS_SIGN_RSA_SHA256
, GNUTLS_PK_RSA
,
52 GNUTLS_MAC_SHA256
, {4, 1}},
53 {"RSA-SHA384", SIG_RSA_SHA384_OID
, GNUTLS_SIGN_RSA_SHA384
, GNUTLS_PK_RSA
,
54 GNUTLS_MAC_SHA384
, {5, 1}},
55 {"RSA-SHA512", SIG_RSA_SHA512_OID
, GNUTLS_SIGN_RSA_SHA512
, GNUTLS_PK_RSA
,
56 GNUTLS_MAC_SHA512
, {6, 1}},
57 {"RSA-RMD160", SIG_RSA_RMD160_OID
, GNUTLS_SIGN_RSA_RMD160
, GNUTLS_PK_RSA
,
58 GNUTLS_MAC_RMD160
, TLS_SIGN_AID_UNKNOWN
},
59 {"DSA-SHA1", SIG_DSA_SHA1_OID
, GNUTLS_SIGN_DSA_SHA1
, GNUTLS_PK_DSA
,
60 GNUTLS_MAC_SHA1
, {2, 2}},
61 {"DSA-SHA224", SIG_DSA_SHA224_OID
, GNUTLS_SIGN_DSA_SHA224
, GNUTLS_PK_DSA
,
62 GNUTLS_MAC_SHA224
, {3, 2}},
63 {"DSA-SHA256", SIG_DSA_SHA256_OID
, GNUTLS_SIGN_DSA_SHA256
, GNUTLS_PK_DSA
,
64 GNUTLS_MAC_SHA256
, {4, 2}},
65 {"RSA-MD5", SIG_RSA_MD5_OID
, GNUTLS_SIGN_RSA_MD5
, GNUTLS_PK_RSA
,
66 GNUTLS_MAC_MD5
, {1, 1}},
67 {"RSA-MD2", SIG_RSA_MD2_OID
, GNUTLS_SIGN_RSA_MD2
, GNUTLS_PK_RSA
,
68 GNUTLS_MAC_MD2
, TLS_SIGN_AID_UNKNOWN
},
69 {"ECDSA-SHA1", "1.2.840.10045.4.1", GNUTLS_SIGN_ECDSA_SHA1
, GNUTLS_PK_EC
, GNUTLS_MAC_SHA1
, {2, 3}},
70 {"ECDSA-SHA224", "1.2.840.10045.4.3.1", GNUTLS_SIGN_ECDSA_SHA224
, GNUTLS_PK_EC
, GNUTLS_MAC_SHA224
, {3, 3}},
71 {"ECDSA-SHA256", "1.2.840.10045.4.3.2", GNUTLS_SIGN_ECDSA_SHA256
, GNUTLS_PK_EC
, GNUTLS_MAC_SHA256
, {4, 3}},
72 {"ECDSA-SHA384", "1.2.840.10045.4.3.3", GNUTLS_SIGN_ECDSA_SHA384
, GNUTLS_PK_EC
, GNUTLS_MAC_SHA384
, {5, 3}},
73 {"ECDSA-SHA512", "1.2.840.10045.4.3.4", GNUTLS_SIGN_ECDSA_SHA512
, GNUTLS_PK_EC
, GNUTLS_MAC_SHA512
, {6, 3}},
74 {"GOST R 34.10-2001", SIG_GOST_R3410_2001_OID
, 0, 0, 0,
75 TLS_SIGN_AID_UNKNOWN
},
76 {"GOST R 34.10-94", SIG_GOST_R3410_94_OID
, 0, 0, 0, TLS_SIGN_AID_UNKNOWN
},
77 {0, 0, 0, 0, 0, TLS_SIGN_AID_UNKNOWN
}
80 #define GNUTLS_SIGN_LOOP(b) \
82 const gnutls_sign_entry *p; \
83 for(p = sign_algorithms; p->name != NULL; p++) { b ; } \
86 #define GNUTLS_SIGN_ALG_LOOP(a) \
87 GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } )
90 * gnutls_sign_get_name:
91 * @algorithm: is a sign algorithm
93 * Convert a #gnutls_sign_algorithm_t value to a string.
95 * Returns: a string that contains the name of the specified sign
96 * algorithm, or %NULL.
99 gnutls_sign_get_name (gnutls_sign_algorithm_t algorithm
)
101 gnutls_sign_algorithm_t sign
= algorithm
;
102 const char *ret
= NULL
;
105 GNUTLS_SIGN_ALG_LOOP (ret
= p
->name
);
113 * Get a list of supported public key signature algorithms.
115 * Returns: a (0)-terminated list of #gnutls_sign_algorithm_t
116 * integers indicating the available ciphers.
119 const gnutls_sign_algorithm_t
*
120 gnutls_sign_list (void)
122 static gnutls_sign_algorithm_t supported_sign
[MAX_ALGOS
] = {0};
124 if (supported_sign
[0] == 0)
128 GNUTLS_SIGN_LOOP (supported_sign
[i
++]=p
->id
);
129 supported_sign
[i
++]=0;
132 return supported_sign
;
136 * gnutls_sign_get_id:
137 * @name: is a sign algorithm name
139 * The names are compared in a case insensitive way.
141 * Returns: return a #gnutls_sign_algorithm_t value corresponding to
142 * the specified algorithm, or %GNUTLS_SIGN_UNKNOWN on error.
144 gnutls_sign_algorithm_t
145 gnutls_sign_get_id (const char *name
)
147 gnutls_sign_algorithm_t ret
= GNUTLS_SIGN_UNKNOWN
;
150 if (strcasecmp (p
->name
, name
) == 0)
161 gnutls_sign_algorithm_t
162 _gnutls_x509_oid2sign_algorithm (const char *oid
)
164 gnutls_sign_algorithm_t ret
= 0;
166 GNUTLS_SIGN_LOOP (if (p
->oid
&& strcmp (oid
, p
->oid
) == 0)
175 _gnutls_debug_log ("Unknown SIGN OID: '%s'\n", oid
);
176 return GNUTLS_SIGN_UNKNOWN
;
183 * @pk: is a public key algorithm
184 * @hash: a hash algorithm
186 * This function maps public key and hash algorithms combinations
187 * to signature algorithms.
189 * Returns: return a #gnutls_sign_algorithm_t value, or %GNUTLS_SIGN_UNKNOWN on error.
191 gnutls_sign_algorithm_t
192 gnutls_pk_to_sign (gnutls_pk_algorithm_t pk
, gnutls_digest_algorithm_t hash
)
194 gnutls_sign_algorithm_t ret
= 0;
196 GNUTLS_SIGN_LOOP (if (pk
== p
->pk
&& hash
== p
->mac
)
202 return GNUTLS_SIGN_UNKNOWN
;
207 _gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t pk
,
208 gnutls_digest_algorithm_t mac
)
210 gnutls_sign_algorithm_t sign
;
211 const char *ret
= NULL
;
213 sign
= gnutls_pk_to_sign (pk
, mac
);
214 if (sign
== GNUTLS_SIGN_UNKNOWN
)
217 GNUTLS_SIGN_ALG_LOOP (ret
= p
->oid
);
221 gnutls_digest_algorithm_t
222 _gnutls_sign_get_hash_algorithm (gnutls_sign_algorithm_t sign
)
224 gnutls_digest_algorithm_t ret
= GNUTLS_DIG_UNKNOWN
;
226 GNUTLS_SIGN_ALG_LOOP (ret
= p
->mac
);
231 gnutls_pk_algorithm_t
232 _gnutls_sign_get_pk_algorithm (gnutls_sign_algorithm_t sign
)
234 gnutls_pk_algorithm_t ret
= GNUTLS_PK_UNKNOWN
;
236 GNUTLS_SIGN_ALG_LOOP (ret
= p
->pk
);
241 gnutls_sign_algorithm_t
242 _gnutls_tls_aid_to_sign (const sign_algorithm_st
* aid
)
244 gnutls_sign_algorithm_t ret
= GNUTLS_SIGN_UNKNOWN
;
246 if (memcmp(aid
, &unknown_tls_aid
, sizeof(*aid
))==0)
249 GNUTLS_SIGN_LOOP (if (p
->aid
.hash_algorithm
== aid
->hash_algorithm
250 && p
->aid
.sign_algorithm
== aid
->sign_algorithm
)
260 /* Returns NULL if a valid AID is not found
262 const sign_algorithm_st
*
263 _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign
)
265 const sign_algorithm_st
* ret
= NULL
;
267 GNUTLS_SIGN_ALG_LOOP (ret
= &p
->aid
);
269 if (ret
!= NULL
&& memcmp(ret
, &unknown_tls_aid
, sizeof(*ret
))==0)