Restored ability to decrypt PKCS #8 and #12 keys with a NULL password. Certtool now...
[gnutls.git] / lib / algorithms / sign.c
blobb422c4c5c0be3df8c812d8ee3df87675f7e96afd
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_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) \
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_list:
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)
126 int i = 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;
149 GNUTLS_SIGN_LOOP (
150 if (strcasecmp (p->name, name) == 0)
152 ret = p->id;
153 break;
157 return ret;
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)
168 ret = p->id;
169 break;
173 if (ret == 0)
175 _gnutls_debug_log ("Unknown SIGN OID: '%s'\n", oid);
176 return GNUTLS_SIGN_UNKNOWN;
178 return ret;
182 * gnutls_pk_to_sign:
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)
198 ret = p->id; break;}
201 if (ret == 0)
202 return GNUTLS_SIGN_UNKNOWN;
203 return ret;
206 const char *
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)
215 return NULL;
217 GNUTLS_SIGN_ALG_LOOP (ret = p->oid);
218 return ret;
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);
228 return ret;
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);
238 return ret;
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)
247 return ret;
249 GNUTLS_SIGN_LOOP (if (p->aid.hash_algorithm == aid->hash_algorithm
250 && p->aid.sign_algorithm == aid->sign_algorithm)
252 ret = p->id; break;
257 return ret;
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)
270 return NULL;
272 return ret;