corrected copyright notices
[gnutls.git] / lib / algorithms / sign.c
blob823846664dd2e6b6075bf272d6d09b264dfc8127
1 /*
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
32 const char *name;
33 const char *oid;
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_DIG_SHA1, {2, 1}},
49 {"RSA-SHA224", SIG_RSA_SHA224_OID, GNUTLS_SIGN_RSA_SHA224, GNUTLS_PK_RSA,
50 GNUTLS_DIG_SHA224, {3, 1}},
51 {"RSA-SHA256", SIG_RSA_SHA256_OID, GNUTLS_SIGN_RSA_SHA256, GNUTLS_PK_RSA,
52 GNUTLS_DIG_SHA256, {4, 1}},
53 {"RSA-SHA384", SIG_RSA_SHA384_OID, GNUTLS_SIGN_RSA_SHA384, GNUTLS_PK_RSA,
54 GNUTLS_DIG_SHA384, {5, 1}},
55 {"RSA-SHA512", SIG_RSA_SHA512_OID, GNUTLS_SIGN_RSA_SHA512, GNUTLS_PK_RSA,
56 GNUTLS_DIG_SHA512, {6, 1}},
57 {"RSA-RMD160", SIG_RSA_RMD160_OID, GNUTLS_SIGN_RSA_RMD160, GNUTLS_PK_RSA,
58 GNUTLS_DIG_RMD160, TLS_SIGN_AID_UNKNOWN},
59 {"DSA-SHA1", SIG_DSA_SHA1_OID, GNUTLS_SIGN_DSA_SHA1, GNUTLS_PK_DSA,
60 GNUTLS_DIG_SHA1, {2, 2}},
61 {"DSA-SHA224", SIG_DSA_SHA224_OID, GNUTLS_SIGN_DSA_SHA224, GNUTLS_PK_DSA,
62 GNUTLS_DIG_SHA224, {3, 2}},
63 {"DSA-SHA256", SIG_DSA_SHA256_OID, GNUTLS_SIGN_DSA_SHA256, GNUTLS_PK_DSA,
64 GNUTLS_DIG_SHA256, {4, 2}},
65 {"RSA-MD5", SIG_RSA_MD5_OID, GNUTLS_SIGN_RSA_MD5, GNUTLS_PK_RSA,
66 GNUTLS_DIG_MD5, {1, 1}},
67 {"RSA-MD2", SIG_RSA_MD2_OID, GNUTLS_SIGN_RSA_MD2, GNUTLS_PK_RSA,
68 GNUTLS_DIG_MD2, TLS_SIGN_AID_UNKNOWN},
69 {"ECDSA-SHA1", "1.2.840.10045.4.1", GNUTLS_SIGN_ECDSA_SHA1, GNUTLS_PK_EC, GNUTLS_DIG_SHA1, {2, 3}},
70 {"ECDSA-SHA224", "1.2.840.10045.4.3.1", GNUTLS_SIGN_ECDSA_SHA224, GNUTLS_PK_EC, GNUTLS_DIG_SHA224, {3, 3}},
71 {"ECDSA-SHA256", "1.2.840.10045.4.3.2", GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_PK_EC, GNUTLS_DIG_SHA256, {4, 3}},
72 {"ECDSA-SHA384", "1.2.840.10045.4.3.3", GNUTLS_SIGN_ECDSA_SHA384, GNUTLS_PK_EC, GNUTLS_DIG_SHA384, {5, 3}},
73 {"ECDSA-SHA512", "1.2.840.10045.4.3.4", GNUTLS_SIGN_ECDSA_SHA512, GNUTLS_PK_EC, GNUTLS_DIG_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) \
81 do { \
82 const gnutls_sign_entry *p; \
83 for(p = sign_algorithms; p->name != NULL; p++) { b ; } \
84 } while (0)
86 #define GNUTLS_SIGN_ALG_LOOP(a) \
87 GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } )
89 /**
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.
97 **/
98 const char *
99 gnutls_sign_get_name (gnutls_sign_algorithm_t algorithm)
101 gnutls_sign_algorithm_t sign = algorithm;
102 const char *ret = NULL;
104 /* avoid prefix */
105 GNUTLS_SIGN_ALG_LOOP (ret = p->name);
107 return ret;
111 * gnutls_sign_is_secure:
112 * @algorithm: is a sign algorithm
114 * Returns: Non-zero if the provided signature algorithm is considered to be secure.
116 int
117 gnutls_sign_is_secure (gnutls_sign_algorithm_t algorithm)
119 gnutls_sign_algorithm_t sign = algorithm;
120 gnutls_digest_algorithm_t dig = GNUTLS_DIG_UNKNOWN;
122 /* avoid prefix */
123 GNUTLS_SIGN_ALG_LOOP (dig = p->mac);
125 if (dig != GNUTLS_DIG_UNKNOWN)
126 return _gnutls_digest_is_secure(dig);
128 return 0;
132 * gnutls_sign_list:
134 * Get a list of supported public key signature algorithms.
136 * Returns: a (0)-terminated list of #gnutls_sign_algorithm_t
137 * integers indicating the available ciphers.
140 const gnutls_sign_algorithm_t *
141 gnutls_sign_list (void)
143 static gnutls_sign_algorithm_t supported_sign[MAX_ALGOS] = {0};
145 if (supported_sign[0] == 0)
147 int i = 0;
149 GNUTLS_SIGN_LOOP (supported_sign[i++]=p->id);
150 supported_sign[i++]=0;
153 return supported_sign;
157 * gnutls_sign_get_id:
158 * @name: is a sign algorithm name
160 * The names are compared in a case insensitive way.
162 * Returns: return a #gnutls_sign_algorithm_t value corresponding to
163 * the specified algorithm, or %GNUTLS_SIGN_UNKNOWN on error.
165 gnutls_sign_algorithm_t
166 gnutls_sign_get_id (const char *name)
168 gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
170 GNUTLS_SIGN_LOOP (
171 if (strcasecmp (p->name, name) == 0)
173 ret = p->id;
174 break;
178 return ret;
182 gnutls_sign_algorithm_t
183 _gnutls_x509_oid2sign_algorithm (const char *oid)
185 gnutls_sign_algorithm_t ret = 0;
187 GNUTLS_SIGN_LOOP (if (p->oid && strcmp (oid, p->oid) == 0)
189 ret = p->id;
190 break;
194 if (ret == 0)
196 _gnutls_debug_log ("Unknown SIGN OID: '%s'\n", oid);
197 return GNUTLS_SIGN_UNKNOWN;
199 return ret;
203 * gnutls_pk_to_sign:
204 * @pk: is a public key algorithm
205 * @hash: a hash algorithm
207 * This function maps public key and hash algorithms combinations
208 * to signature algorithms.
210 * Returns: return a #gnutls_sign_algorithm_t value, or %GNUTLS_SIGN_UNKNOWN on error.
212 gnutls_sign_algorithm_t
213 gnutls_pk_to_sign (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
215 gnutls_sign_algorithm_t ret = 0;
217 GNUTLS_SIGN_LOOP (if (pk == p->pk && hash == p->mac)
219 ret = p->id; break;}
222 if (ret == 0)
223 return GNUTLS_SIGN_UNKNOWN;
224 return ret;
227 const char *
228 _gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t pk,
229 gnutls_digest_algorithm_t mac)
231 gnutls_sign_algorithm_t sign;
232 const char *ret = NULL;
234 sign = gnutls_pk_to_sign (pk, mac);
235 if (sign == GNUTLS_SIGN_UNKNOWN)
236 return NULL;
238 GNUTLS_SIGN_ALG_LOOP (ret = p->oid);
239 return ret;
243 * gnutls_sign_get_hash_algorithm:
244 * @sign: is a signature algorithm
246 * This function returns the digest algorithm corresponding to
247 * the given signature algorithms.
249 * Since: 3.1.1
251 * Returns: return a #gnutls_digest_algorithm_t value, or %GNUTLS_DIG_UNKNOWN on error.
253 gnutls_digest_algorithm_t
254 gnutls_sign_get_hash_algorithm (gnutls_sign_algorithm_t sign)
256 gnutls_digest_algorithm_t ret = GNUTLS_DIG_UNKNOWN;
258 GNUTLS_SIGN_ALG_LOOP (ret = p->mac);
260 return ret;
264 * gnutls_sign_get_pk_algorithm:
265 * @sign: is a signature algorithm
267 * This function returns the public key algorithm corresponding to
268 * the given signature algorithms.
270 * Since: 3.1.1
272 * Returns: return a #gnutls_pk_algorithm_t value, or %GNUTLS_PK_UNKNOWN on error.
274 gnutls_pk_algorithm_t
275 gnutls_sign_get_pk_algorithm (gnutls_sign_algorithm_t sign)
277 gnutls_pk_algorithm_t ret = GNUTLS_PK_UNKNOWN;
279 GNUTLS_SIGN_ALG_LOOP (ret = p->pk);
281 return ret;
284 gnutls_sign_algorithm_t
285 _gnutls_tls_aid_to_sign (const sign_algorithm_st * aid)
287 gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
289 if (memcmp(aid, &unknown_tls_aid, sizeof(*aid))==0)
290 return ret;
292 GNUTLS_SIGN_LOOP (if (p->aid.hash_algorithm == aid->hash_algorithm
293 && p->aid.sign_algorithm == aid->sign_algorithm)
295 ret = p->id; break;
300 return ret;
303 /* Returns NULL if a valid AID is not found
305 const sign_algorithm_st*
306 _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign)
308 const sign_algorithm_st * ret = NULL;
310 GNUTLS_SIGN_ALG_LOOP (ret = &p->aid);
312 if (ret != NULL && memcmp(ret, &unknown_tls_aid, sizeof(*ret))==0)
313 return NULL;
315 return ret;