File: | lib/x509/privkey.c |
Location: | line 1608, column 3 |
Description: | Null pointer passed as an argument to a 'nonnull' parameter |
1 | /* | ||
2 | * Copyright (C) 2003-2005, 2007-2012 Free Software Foundation, Inc. | ||
3 | * | ||
4 | * Author: Nikos Mavrogiannopoulos | ||
5 | * | ||
6 | * This file is part of GnuTLS. | ||
7 | * | ||
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. | ||
12 | * | ||
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. | ||
17 | * | ||
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/> | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <gnutls_int.h> | ||
24 | #include <gnutls_datumgnutls_datum_t.h> | ||
25 | #include <gnutls_global.h> | ||
26 | #include <gnutls_errors.h> | ||
27 | #include <gnutls_rsa_export.h> | ||
28 | #include <gnutls_sig.h> | ||
29 | #include <common.h> | ||
30 | #include <gnutls_x509.h> | ||
31 | #include <x509_b64.h> | ||
32 | #include <x509_int.h> | ||
33 | #include <gnutls_pk.h> | ||
34 | #include <gnutls_mpi.h> | ||
35 | #include <gnutls_ecc.h> | ||
36 | |||
37 | /** | ||
38 | * gnutls_x509_privkey_init: | ||
39 | * @key: The structure to be initialized | ||
40 | * | ||
41 | * This function will initialize an private key structure. | ||
42 | * | ||
43 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
44 | * negative error value. | ||
45 | **/ | ||
46 | int | ||
47 | gnutls_x509_privkey_init (gnutls_x509_privkey_t * key) | ||
48 | { | ||
49 | *key = gnutls_calloc (1, sizeof (gnutls_x509_privkey_int)); | ||
50 | |||
51 | if (*key) | ||
52 | { | ||
53 | (*key)->key = ASN1_TYPE_EMPTY((void*)0); | ||
54 | (*key)->pk_algorithm = GNUTLS_PK_UNKNOWN; | ||
55 | return 0; /* success */ | ||
56 | } | ||
57 | |||
58 | return GNUTLS_E_MEMORY_ERROR-25; | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * gnutls_x509_privkey_deinit: | ||
63 | * @key: The structure to be deinitialized | ||
64 | * | ||
65 | * This function will deinitialize a private key structure. | ||
66 | **/ | ||
67 | void | ||
68 | gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key) | ||
69 | { | ||
70 | if (!key) | ||
71 | return; | ||
72 | |||
73 | gnutls_pk_params_release(&key->params); | ||
74 | asn1_delete_structure (&key->key); | ||
75 | gnutls_free (key); | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * gnutls_x509_privkey_cpy: | ||
80 | * @dst: The destination key, which should be initialized. | ||
81 | * @src: The source key | ||
82 | * | ||
83 | * This function will copy a private key from source to destination | ||
84 | * key. Destination has to be initialized. | ||
85 | * | ||
86 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
87 | * negative error value. | ||
88 | **/ | ||
89 | int | ||
90 | gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst, gnutls_x509_privkey_t src) | ||
91 | { | ||
92 | int i, ret; | ||
93 | |||
94 | if (!src || !dst) | ||
95 | return GNUTLS_E_INVALID_REQUEST-50; | ||
96 | |||
97 | for (i = 0; i < src->params.params_nr; i++) | ||
98 | { | ||
99 | dst->params.params[i] = _gnutls_mpi_copy (src->params.params[i])_gnutls_mpi_ops.bigint_set(((void*)0),src->params.params[i ]); | ||
100 | if (dst->params.params[i] == NULL((void*)0)) | ||
101 | return GNUTLS_E_MEMORY_ERROR-25; | ||
102 | } | ||
103 | |||
104 | dst->params.params_nr = src->params.params_nr; | ||
105 | dst->params.flags = src->params.flags; | ||
106 | |||
107 | dst->pk_algorithm = src->pk_algorithm; | ||
108 | |||
109 | ret = _gnutls_asn1_encode_privkey (dst->pk_algorithm, &dst->key, &dst->params); | ||
110 | if (ret < 0) | ||
111 | { | ||
112 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",112); } while(0);; | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | /* Converts an RSA PKCS#1 key to | ||
120 | * an internal structure (gnutls_private_key) | ||
121 | */ | ||
122 | ASN1_TYPE | ||
123 | _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, | ||
124 | gnutls_x509_privkey_t pkey) | ||
125 | { | ||
126 | int result; | ||
127 | ASN1_TYPE pkey_asn; | ||
128 | |||
129 | gnutls_pk_params_init(&pkey->params); | ||
130 | |||
131 | if ((result = | ||
132 | asn1_create_element (_gnutls_get_gnutls_asn ()((ASN1_TYPE) _gnutls_gnutls_asn), | ||
133 | "GNUTLS.RSAPrivateKey", | ||
134 | &pkey_asn)) != ASN1_SUCCESS0) | ||
135 | { | ||
136 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",136); } while(0);; | ||
137 | return NULL((void*)0); | ||
138 | } | ||
139 | |||
140 | result = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL((void*)0)); | ||
141 | if (result != ASN1_SUCCESS0) | ||
142 | { | ||
143 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",143); } while(0);; | ||
144 | goto error; | ||
145 | } | ||
146 | |||
147 | if ((result = _gnutls_x509_read_int (pkey_asn, "modulus", | ||
148 | &pkey->params.params[0])) < 0) | ||
149 | { | ||
150 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",150); } while(0);; | ||
151 | goto error; | ||
152 | } | ||
153 | pkey->params.params_nr++; | ||
154 | |||
155 | if ((result = | ||
156 | _gnutls_x509_read_int (pkey_asn, "publicExponent", | ||
157 | &pkey->params.params[1])) < 0) | ||
158 | { | ||
159 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",159); } while(0);; | ||
160 | goto error; | ||
161 | } | ||
162 | pkey->params.params_nr++; | ||
163 | |||
164 | if ((result = | ||
165 | _gnutls_x509_read_int (pkey_asn, "privateExponent", | ||
166 | &pkey->params.params[2])) < 0) | ||
167 | { | ||
168 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",168); } while(0);; | ||
169 | goto error; | ||
170 | } | ||
171 | pkey->params.params_nr++; | ||
172 | |||
173 | if ((result = _gnutls_x509_read_int (pkey_asn, "prime1", | ||
174 | &pkey->params.params[3])) < 0) | ||
175 | { | ||
176 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",176); } while(0);; | ||
177 | goto error; | ||
178 | } | ||
179 | pkey->params.params_nr++; | ||
180 | |||
181 | if ((result = _gnutls_x509_read_int (pkey_asn, "prime2", | ||
182 | &pkey->params.params[4])) < 0) | ||
183 | { | ||
184 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",184); } while(0);; | ||
185 | goto error; | ||
186 | } | ||
187 | pkey->params.params_nr++; | ||
188 | |||
189 | if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient", | ||
190 | &pkey->params.params[5])) < 0) | ||
191 | { | ||
192 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",192); } while(0);; | ||
193 | goto error; | ||
194 | } | ||
195 | pkey->params.params_nr++; | ||
196 | |||
197 | if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1", | ||
198 | &pkey->params.params[6])) < 0) | ||
199 | { | ||
200 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",200); } while(0);; | ||
201 | goto error; | ||
202 | } | ||
203 | pkey->params.params_nr++; | ||
204 | |||
205 | if ((result = _gnutls_x509_read_int (pkey_asn, "exponent2", | ||
206 | &pkey->params.params[7])) < 0) | ||
207 | { | ||
208 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",208); } while(0);; | ||
209 | goto error; | ||
210 | } | ||
211 | pkey->params.params_nr++; | ||
212 | |||
213 | result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params); | ||
214 | if (result < 0) | ||
215 | { | ||
216 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",216); } while(0);; | ||
217 | goto error; | ||
218 | } | ||
219 | |||
220 | pkey->params.params_nr = RSA_PRIVATE_PARAMS8; | ||
221 | |||
222 | return pkey_asn; | ||
223 | |||
224 | error: | ||
225 | asn1_delete_structure (&pkey_asn); | ||
226 | gnutls_pk_params_release (&pkey->params); | ||
227 | return NULL((void*)0); | ||
228 | |||
229 | } | ||
230 | |||
231 | /* Converts an ECC key to | ||
232 | * an internal structure (gnutls_private_key) | ||
233 | */ | ||
234 | ASN1_TYPE | ||
235 | _gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key, | ||
236 | gnutls_x509_privkey_t pkey) | ||
237 | { | ||
238 | int ret; | ||
239 | ASN1_TYPE pkey_asn; | ||
240 | unsigned int version; | ||
241 | char oid[MAX_OID_SIZE128]; | ||
242 | int oid_size; | ||
243 | gnutls_datumgnutls_datum_t out; | ||
244 | |||
245 | gnutls_pk_params_init(&pkey->params); | ||
246 | |||
247 | if ((ret = | ||
248 | asn1_create_element (_gnutls_get_gnutls_asn ()((ASN1_TYPE) _gnutls_gnutls_asn), | ||
249 | "GNUTLS.ECPrivateKey", | ||
250 | &pkey_asn)) != ASN1_SUCCESS0) | ||
251 | { | ||
252 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",252); } while(0);; | ||
253 | return NULL((void*)0); | ||
254 | } | ||
255 | |||
256 | ret = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL((void*)0)); | ||
257 | if (ret != ASN1_SUCCESS0) | ||
258 | { | ||
259 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",259); } while(0);; | ||
260 | goto error; | ||
261 | } | ||
262 | |||
263 | ret = _gnutls_x509_read_uint (pkey_asn, "Version", &version); | ||
264 | if (ret < 0) | ||
265 | { | ||
266 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",266); } while(0);; | ||
267 | goto error; | ||
268 | } | ||
269 | |||
270 | if (version != 1) | ||
271 | { | ||
272 | _gnutls_debug_log("ECC private key version %u is not supported\n", version)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ECC private key version %u is not supported\n", version ); } while(0); | ||
273 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",273); } while(0);; | ||
274 | goto error; | ||
275 | } | ||
276 | |||
277 | /* read the curve */ | ||
278 | oid_size = sizeof(oid); | ||
279 | ret = asn1_read_value(pkey_asn, "parameters.namedCurve", oid, &oid_size); | ||
280 | if (ret != ASN1_SUCCESS0) | ||
281 | { | ||
282 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",282); } while(0);; | ||
283 | goto error; | ||
284 | } | ||
285 | |||
286 | pkey->params.flags = _gnutls_oid_to_ecc_curve(oid); | ||
287 | if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID) | ||
288 | { | ||
289 | _gnutls_debug_log("Curve %s is not supported\n", oid)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Curve %s is not supported\n", oid); } while(0); | ||
290 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",290); } while(0);; | ||
291 | goto error; | ||
292 | } | ||
293 | |||
294 | ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params); | ||
295 | if (ret < 0) | ||
296 | { | ||
297 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",297); } while(0);; | ||
298 | goto error; | ||
299 | } | ||
300 | |||
301 | /* read the public key */ | ||
302 | ret = _gnutls_x509_read_value(pkey_asn, "publicKey", &out, 2); | ||
303 | if (ret < 0) | ||
304 | { | ||
305 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",305); } while(0);; | ||
306 | goto error; | ||
307 | } | ||
308 | |||
309 | ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[ECC_X6], | ||
310 | &pkey->params.params[ECC_Y7]); | ||
311 | |||
312 | _gnutls_free_datum(&out)_gnutls_free_datum_m(&out, gnutls_free); | ||
313 | if (ret < 0) | ||
314 | { | ||
315 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",315); } while(0);; | ||
316 | goto error; | ||
317 | } | ||
318 | pkey->params.params_nr += 2; | ||
319 | |||
320 | /* read the private key */ | ||
321 | ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[ECC_K8]); | ||
322 | if (ret < 0) | ||
323 | { | ||
324 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",324); } while(0);; | ||
325 | goto error; | ||
326 | } | ||
327 | pkey->params.params_nr ++; | ||
328 | |||
329 | return pkey_asn; | ||
330 | |||
331 | error: | ||
332 | asn1_delete_structure (&pkey_asn); | ||
333 | gnutls_pk_params_release (&pkey->params); | ||
334 | return NULL((void*)0); | ||
335 | |||
336 | } | ||
337 | |||
338 | |||
339 | static ASN1_TYPE | ||
340 | decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) | ||
341 | { | ||
342 | int result; | ||
343 | ASN1_TYPE dsa_asn; | ||
344 | |||
345 | if ((result = | ||
346 | asn1_create_element (_gnutls_get_gnutls_asn ()((ASN1_TYPE) _gnutls_gnutls_asn), | ||
347 | "GNUTLS.DSAPrivateKey", | ||
348 | &dsa_asn)) != ASN1_SUCCESS0) | ||
349 | { | ||
350 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",350); } while(0);; | ||
351 | return NULL((void*)0); | ||
352 | } | ||
353 | |||
354 | pkey->params.params_nr = 0; | ||
355 | |||
356 | result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL((void*)0)); | ||
357 | if (result != ASN1_SUCCESS0) | ||
358 | { | ||
359 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",359); } while(0);; | ||
360 | goto error; | ||
361 | } | ||
362 | |||
363 | if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params.params[0])) < 0) | ||
364 | { | ||
365 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",365); } while(0);; | ||
366 | goto error; | ||
367 | } | ||
368 | pkey->params.params_nr++; | ||
369 | |||
370 | if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params.params[1])) < 0) | ||
371 | { | ||
372 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",372); } while(0);; | ||
373 | goto error; | ||
374 | } | ||
375 | pkey->params.params_nr++; | ||
376 | |||
377 | if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params.params[2])) < 0) | ||
378 | { | ||
379 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",379); } while(0);; | ||
380 | goto error; | ||
381 | } | ||
382 | pkey->params.params_nr++; | ||
383 | |||
384 | if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params.params[3])) < 0) | ||
385 | { | ||
386 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",386); } while(0);; | ||
387 | goto error; | ||
388 | } | ||
389 | pkey->params.params_nr++; | ||
390 | |||
391 | if ((result = _gnutls_x509_read_int (dsa_asn, "priv", | ||
392 | &pkey->params.params[4])) < 0) | ||
393 | { | ||
394 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",394); } while(0);; | ||
395 | goto error; | ||
396 | } | ||
397 | pkey->params.params_nr++; | ||
398 | |||
399 | return dsa_asn; | ||
400 | |||
401 | error: | ||
402 | asn1_delete_structure (&dsa_asn); | ||
403 | gnutls_pk_params_release(&pkey->params); | ||
404 | return NULL((void*)0); | ||
405 | |||
406 | } | ||
407 | |||
408 | |||
409 | #define PEM_KEY_DSA"DSA PRIVATE KEY" "DSA PRIVATE KEY" | ||
410 | #define PEM_KEY_RSA"RSA PRIVATE KEY" "RSA PRIVATE KEY" | ||
411 | #define PEM_KEY_ECC"EC PRIVATE KEY" "EC PRIVATE KEY" | ||
412 | |||
413 | /** | ||
414 | * gnutls_x509_privkey_import: | ||
415 | * @key: The structure to store the parsed key | ||
416 | * @data: The DER or PEM encoded certificate. | ||
417 | * @format: One of DER or PEM | ||
418 | * | ||
419 | * This function will convert the given DER or PEM encoded key to the | ||
420 | * native #gnutls_x509_privkey_t format. The output will be stored in | ||
421 | * @key . | ||
422 | * | ||
423 | * If the key is PEM encoded it should have a header of "RSA PRIVATE | ||
424 | * KEY", or "DSA PRIVATE KEY". | ||
425 | * | ||
426 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
427 | * negative error value. | ||
428 | **/ | ||
429 | int | ||
430 | gnutls_x509_privkey_import (gnutls_x509_privkey_t key, | ||
431 | const gnutls_datum_t * data, | ||
432 | gnutls_x509_crt_fmt_t format) | ||
433 | { | ||
434 | int result = 0, need_free = 0; | ||
435 | gnutls_datum_t _data; | ||
436 | |||
437 | if (key == NULL((void*)0)) | ||
438 | { | ||
439 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",439); } while(0);; | ||
440 | return GNUTLS_E_INVALID_REQUEST-50; | ||
441 | } | ||
442 | |||
443 | _data.data = data->data; | ||
444 | _data.size = data->size; | ||
445 | |||
446 | key->pk_algorithm = GNUTLS_PK_UNKNOWN; | ||
447 | |||
448 | /* If the Certificate is in PEM format then decode it | ||
449 | */ | ||
450 | if (format == GNUTLS_X509_FMT_PEM) | ||
451 | { | ||
452 | opaque *out; | ||
453 | |||
454 | /* Try the first header */ | ||
455 | result = | ||
456 | _gnutls_fbase64_decode (PEM_KEY_RSA"RSA PRIVATE KEY", data->data, data->size, &out); | ||
457 | |||
458 | if (result >= 0) | ||
459 | key->pk_algorithm = GNUTLS_PK_RSA; | ||
460 | |||
461 | if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR-207) | ||
462 | { | ||
463 | /* try for the second header */ | ||
464 | result = | ||
465 | _gnutls_fbase64_decode (PEM_KEY_DSA"DSA PRIVATE KEY", data->data, data->size, | ||
466 | &out); | ||
467 | |||
468 | if (result >= 0) | ||
469 | key->pk_algorithm = GNUTLS_PK_DSA; | ||
470 | |||
471 | if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR-207) | ||
472 | { | ||
473 | /* try for the second header */ | ||
474 | result = | ||
475 | _gnutls_fbase64_decode (PEM_KEY_ECC"EC PRIVATE KEY", data->data, data->size, | ||
476 | &out); | ||
477 | if (result >= 0) | ||
478 | key->pk_algorithm = GNUTLS_PK_EC; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | if (result < 0) | ||
483 | { | ||
484 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",484); } while(0);; | ||
485 | goto failover; | ||
486 | } | ||
487 | |||
488 | _data.data = out; | ||
489 | _data.size = result; | ||
490 | |||
491 | need_free = 1; | ||
492 | } | ||
493 | |||
494 | if (key->pk_algorithm == GNUTLS_PK_RSA) | ||
495 | { | ||
496 | key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key); | ||
497 | if (key->key == NULL((void*)0)) | ||
498 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",498); } while(0);; | ||
499 | } | ||
500 | else if (key->pk_algorithm == GNUTLS_PK_DSA) | ||
501 | { | ||
502 | key->key = decode_dsa_key (&_data, key); | ||
503 | if (key->key == NULL((void*)0)) | ||
504 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",504); } while(0);; | ||
505 | } | ||
506 | else if (key->pk_algorithm == GNUTLS_PK_EC) | ||
507 | { | ||
508 | key->key = _gnutls_privkey_decode_ecc_key (&_data, key); | ||
509 | if (key->key == NULL((void*)0)) | ||
510 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",510); } while(0);; | ||
511 | } | ||
512 | else | ||
513 | { | ||
514 | /* Try decoding with both, and accept the one that | ||
515 | * succeeds. | ||
516 | */ | ||
517 | key->pk_algorithm = GNUTLS_PK_RSA; | ||
518 | key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key); | ||
519 | |||
520 | if (key->key == NULL((void*)0)) | ||
521 | { | ||
522 | key->pk_algorithm = GNUTLS_PK_DSA; | ||
523 | key->key = decode_dsa_key (&_data, key); | ||
524 | if (key->key == NULL((void*)0)) | ||
525 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",525); } while(0);; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | if (key->key == NULL((void*)0)) | ||
530 | { | ||
531 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",531); } while(0);; | ||
532 | result = GNUTLS_E_ASN1_DER_ERROR-69; | ||
533 | goto failover; | ||
534 | } | ||
535 | |||
536 | if (need_free) | ||
537 | _gnutls_free_datum (&_data)_gnutls_free_datum_m(&_data, gnutls_free); | ||
538 | |||
539 | /* The key has now been decoded. | ||
540 | */ | ||
541 | |||
542 | return 0; | ||
543 | |||
544 | failover: | ||
545 | /* Try PKCS #8 */ | ||
546 | #ifdef ENABLE_PKI1 | ||
547 | if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR-207) | ||
548 | { | ||
549 | _gnutls_debug_log ("Falling back to PKCS #8 key decoding\n")do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Falling back to PKCS #8 key decoding\n"); } while(0); | ||
550 | result = gnutls_x509_privkey_import_pkcs8 (key, data, format, | ||
551 | NULL((void*)0), GNUTLS_PKCS_PLAIN); | ||
552 | } | ||
553 | #endif | ||
554 | |||
555 | if (need_free) | ||
556 | _gnutls_free_datum (&_data)_gnutls_free_datum_m(&_data, gnutls_free); | ||
557 | |||
558 | return result; | ||
559 | } | ||
560 | |||
561 | /** | ||
562 | * gnutls_x509_privkey_import_rsa_raw: | ||
563 | * @key: The structure to store the parsed key | ||
564 | * @m: holds the modulus | ||
565 | * @e: holds the public exponent | ||
566 | * @d: holds the private exponent | ||
567 | * @p: holds the first prime (p) | ||
568 | * @q: holds the second prime (q) | ||
569 | * @u: holds the coefficient | ||
570 | * | ||
571 | * This function will convert the given RSA raw parameters to the | ||
572 | * native #gnutls_x509_privkey_t format. The output will be stored in | ||
573 | * @key. | ||
574 | * | ||
575 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
576 | * negative error value. | ||
577 | **/ | ||
578 | int | ||
579 | gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key, | ||
580 | const gnutls_datum_t * m, | ||
581 | const gnutls_datum_t * e, | ||
582 | const gnutls_datum_t * d, | ||
583 | const gnutls_datum_t * p, | ||
584 | const gnutls_datum_t * q, | ||
585 | const gnutls_datum_t * u) | ||
586 | { | ||
587 | return gnutls_x509_privkey_import_rsa_raw2 (key, m, e, d, p, q, u, NULL((void*)0), | ||
588 | NULL((void*)0)); | ||
589 | } | ||
590 | |||
591 | /** | ||
592 | * gnutls_x509_privkey_import_rsa_raw2: | ||
593 | * @key: The structure to store the parsed key | ||
594 | * @m: holds the modulus | ||
595 | * @e: holds the public exponent | ||
596 | * @d: holds the private exponent | ||
597 | * @p: holds the first prime (p) | ||
598 | * @q: holds the second prime (q) | ||
599 | * @u: holds the coefficient | ||
600 | * @e1: holds e1 = d mod (p-1) | ||
601 | * @e2: holds e2 = d mod (q-1) | ||
602 | * | ||
603 | * This function will convert the given RSA raw parameters to the | ||
604 | * native #gnutls_x509_privkey_t format. The output will be stored in | ||
605 | * @key. | ||
606 | * | ||
607 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
608 | * negative error value. | ||
609 | **/ | ||
610 | int | ||
611 | gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key, | ||
612 | const gnutls_datum_t * m, | ||
613 | const gnutls_datum_t * e, | ||
614 | const gnutls_datum_t * d, | ||
615 | const gnutls_datum_t * p, | ||
616 | const gnutls_datum_t * q, | ||
617 | const gnutls_datum_t * u, | ||
618 | const gnutls_datum_t * e1, | ||
619 | const gnutls_datum_t * e2) | ||
620 | { | ||
621 | int ret; | ||
622 | size_t siz = 0; | ||
623 | |||
624 | if (key == NULL((void*)0)) | ||
625 | { | ||
626 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",626); } while(0);; | ||
627 | return GNUTLS_E_INVALID_REQUEST-50; | ||
628 | } | ||
629 | |||
630 | gnutls_pk_params_init(&key->params); | ||
631 | |||
632 | siz = m->size; | ||
633 | if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz)) | ||
634 | { | ||
635 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",635); } while(0);; | ||
636 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
637 | goto cleanup; | ||
638 | } | ||
639 | key->params.params_nr++; | ||
640 | |||
641 | siz = e->size; | ||
642 | if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz)) | ||
643 | { | ||
644 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",644); } while(0);; | ||
645 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
646 | goto cleanup; | ||
647 | } | ||
648 | key->params.params_nr++; | ||
649 | |||
650 | siz = d->size; | ||
651 | if (_gnutls_mpi_scan_nz (&key->params.params[2], d->data, siz)) | ||
652 | { | ||
653 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",653); } while(0);; | ||
654 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
655 | goto cleanup; | ||
656 | } | ||
657 | key->params.params_nr++; | ||
658 | |||
659 | siz = p->size; | ||
660 | if (_gnutls_mpi_scan_nz (&key->params.params[3], p->data, siz)) | ||
661 | { | ||
662 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",662); } while(0);; | ||
663 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
664 | goto cleanup; | ||
665 | } | ||
666 | key->params.params_nr++; | ||
667 | |||
668 | siz = q->size; | ||
669 | if (_gnutls_mpi_scan_nz (&key->params.params[4], q->data, siz)) | ||
670 | { | ||
671 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",671); } while(0);; | ||
672 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
673 | goto cleanup; | ||
674 | } | ||
675 | key->params.params_nr++; | ||
676 | |||
677 | siz = u->size; | ||
678 | if (_gnutls_mpi_scan_nz (&key->params.params[5], u->data, siz)) | ||
679 | { | ||
680 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",680); } while(0);; | ||
681 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
682 | goto cleanup; | ||
683 | } | ||
684 | key->params.params_nr++; | ||
685 | |||
686 | if (e1 && e2) | ||
687 | { | ||
688 | siz = e1->size; | ||
689 | if (_gnutls_mpi_scan_nz (&key->params.params[6], e1->data, siz)) | ||
690 | { | ||
691 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",691); } while(0);; | ||
692 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
693 | goto cleanup; | ||
694 | } | ||
695 | key->params.params_nr++; | ||
696 | |||
697 | siz = e2->size; | ||
698 | if (_gnutls_mpi_scan_nz (&key->params.params[7], e2->data, siz)) | ||
699 | { | ||
700 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",700); } while(0);; | ||
701 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
702 | goto cleanup; | ||
703 | } | ||
704 | key->params.params_nr++; | ||
705 | } | ||
706 | |||
707 | ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params); | ||
708 | if (ret < 0) | ||
709 | { | ||
710 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",710); } while(0);; | ||
711 | goto cleanup; | ||
712 | } | ||
713 | |||
714 | ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA, &key->key, &key->params); | ||
715 | if (ret < 0) | ||
716 | { | ||
717 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",717); } while(0);; | ||
718 | goto cleanup; | ||
719 | } | ||
720 | |||
721 | key->params.params_nr = RSA_PRIVATE_PARAMS8; | ||
722 | key->pk_algorithm = GNUTLS_PK_RSA; | ||
723 | |||
724 | return 0; | ||
725 | |||
726 | cleanup: | ||
727 | gnutls_pk_params_release(&key->params); | ||
728 | return ret; | ||
729 | |||
730 | } | ||
731 | |||
732 | /** | ||
733 | * gnutls_x509_privkey_import_dsa_raw: | ||
734 | * @key: The structure to store the parsed key | ||
735 | * @p: holds the p | ||
736 | * @q: holds the q | ||
737 | * @g: holds the g | ||
738 | * @y: holds the y | ||
739 | * @x: holds the x | ||
740 | * | ||
741 | * This function will convert the given DSA raw parameters to the | ||
742 | * native #gnutls_x509_privkey_t format. The output will be stored | ||
743 | * in @key. | ||
744 | * | ||
745 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
746 | * negative error value. | ||
747 | **/ | ||
748 | int | ||
749 | gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key, | ||
750 | const gnutls_datum_t * p, | ||
751 | const gnutls_datum_t * q, | ||
752 | const gnutls_datum_t * g, | ||
753 | const gnutls_datum_t * y, | ||
754 | const gnutls_datum_t * x) | ||
755 | { | ||
756 | int ret; | ||
757 | size_t siz = 0; | ||
758 | |||
759 | if (key == NULL((void*)0)) | ||
760 | { | ||
761 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",761); } while(0);; | ||
762 | return GNUTLS_E_INVALID_REQUEST-50; | ||
763 | } | ||
764 | |||
765 | siz = p->size; | ||
766 | if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz)) | ||
767 | { | ||
768 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",768); } while(0);; | ||
769 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
770 | goto cleanup; | ||
771 | } | ||
772 | |||
773 | siz = q->size; | ||
774 | if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz)) | ||
775 | { | ||
776 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",776); } while(0);; | ||
777 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
778 | goto cleanup; | ||
779 | } | ||
780 | |||
781 | siz = g->size; | ||
782 | if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz)) | ||
783 | { | ||
784 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",784); } while(0);; | ||
785 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
786 | goto cleanup; | ||
787 | } | ||
788 | |||
789 | siz = y->size; | ||
790 | if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz)) | ||
791 | { | ||
792 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",792); } while(0);; | ||
793 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
794 | goto cleanup; | ||
795 | } | ||
796 | |||
797 | siz = x->size; | ||
798 | if (_gnutls_mpi_scan_nz (&key->params.params[4], x->data, siz)) | ||
799 | { | ||
800 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",800); } while(0);; | ||
801 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
802 | goto cleanup; | ||
803 | } | ||
804 | |||
805 | ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA, &key->key, &key->params); | ||
806 | if (ret < 0) | ||
807 | { | ||
808 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",808); } while(0);; | ||
809 | goto cleanup; | ||
810 | } | ||
811 | |||
812 | key->params.params_nr = DSA_PRIVATE_PARAMS5; | ||
813 | key->pk_algorithm = GNUTLS_PK_DSA; | ||
814 | |||
815 | return 0; | ||
816 | |||
817 | cleanup: | ||
818 | gnutls_pk_params_release(&key->params); | ||
819 | return ret; | ||
820 | |||
821 | } | ||
822 | |||
823 | /** | ||
824 | * gnutls_x509_privkey_import_ecc_raw: | ||
825 | * @key: The structure to store the parsed key | ||
826 | * @curve: holds the curve | ||
827 | * @x: holds the x | ||
828 | * @y: holds the y | ||
829 | * @k: holds the k | ||
830 | * | ||
831 | * This function will convert the given elliptic curve parameters to the | ||
832 | * native #gnutls_x509_privkey_t format. The output will be stored | ||
833 | * in @key. | ||
834 | * | ||
835 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
836 | * negative error value. | ||
837 | * | ||
838 | * Since: 3.0.0 | ||
839 | **/ | ||
840 | int | ||
841 | gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key, | ||
842 | gnutls_ecc_curve_t curve, | ||
843 | const gnutls_datum_t * x, | ||
844 | const gnutls_datum_t * y, | ||
845 | const gnutls_datum_t * k) | ||
846 | { | ||
847 | int ret; | ||
848 | |||
849 | if (key == NULL((void*)0)) | ||
850 | { | ||
851 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",851); } while(0);; | ||
852 | return GNUTLS_E_INVALID_REQUEST-50; | ||
853 | } | ||
854 | |||
855 | key->params.flags = curve; | ||
856 | |||
857 | ret = _gnutls_ecc_curve_fill_params(curve, &key->params); | ||
858 | if (ret < 0) | ||
859 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "privkey.c", 859); | ||
860 | |||
861 | if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X6], x->data, x->size)) | ||
862 | { | ||
863 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",863); } while(0);; | ||
864 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
865 | goto cleanup; | ||
866 | } | ||
867 | key->params.params_nr++; | ||
868 | |||
869 | if (_gnutls_mpi_scan_nz (&key->params.params[ECC_Y7], y->data, y->size)) | ||
870 | { | ||
871 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",871); } while(0);; | ||
872 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
873 | goto cleanup; | ||
874 | } | ||
875 | key->params.params_nr++; | ||
876 | |||
877 | if (_gnutls_mpi_scan_nz (&key->params.params[ECC_K8], k->data, k->size)) | ||
878 | { | ||
879 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",879); } while(0);; | ||
880 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; | ||
881 | goto cleanup; | ||
882 | } | ||
883 | key->params.params_nr++; | ||
884 | |||
885 | key->pk_algorithm = GNUTLS_PK_EC; | ||
886 | |||
887 | return 0; | ||
888 | |||
889 | cleanup: | ||
890 | gnutls_pk_params_release(&key->params); | ||
891 | return ret; | ||
892 | |||
893 | } | ||
894 | |||
895 | |||
896 | /** | ||
897 | * gnutls_x509_privkey_get_pk_algorithm: | ||
898 | * @key: should contain a #gnutls_x509_privkey_t structure | ||
899 | * | ||
900 | * This function will return the public key algorithm of a private | ||
901 | * key. | ||
902 | * | ||
903 | * Returns: a member of the #gnutls_pk_algorithm_t enumeration on | ||
904 | * success, or a negative error code on error. | ||
905 | **/ | ||
906 | int | ||
907 | gnutls_x509_privkey_get_pk_algorithm (gnutls_x509_privkey_t key) | ||
908 | { | ||
909 | if (key == NULL((void*)0)) | ||
910 | { | ||
911 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",911); } while(0);; | ||
912 | return GNUTLS_E_INVALID_REQUEST-50; | ||
913 | } | ||
914 | |||
915 | return key->pk_algorithm; | ||
916 | } | ||
917 | |||
918 | /** | ||
919 | * gnutls_x509_privkey_export: | ||
920 | * @key: Holds the key | ||
921 | * @format: the format of output params. One of PEM or DER. | ||
922 | * @output_data: will contain a private key PEM or DER encoded | ||
923 | * @output_data_size: holds the size of output_data (and will be | ||
924 | * replaced by the actual size of parameters) | ||
925 | * | ||
926 | * This function will export the private key to a PKCS1 structure for | ||
927 | * RSA keys, or an integer sequence for DSA keys. The DSA keys are in | ||
928 | * the same format with the parameters used by openssl. | ||
929 | * | ||
930 | * If the buffer provided is not long enough to hold the output, then | ||
931 | * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER | ||
932 | * will be returned. | ||
933 | * | ||
934 | * If the structure is PEM encoded, it will have a header | ||
935 | * of "BEGIN RSA PRIVATE KEY". | ||
936 | * | ||
937 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
938 | * negative error value. | ||
939 | **/ | ||
940 | int | ||
941 | gnutls_x509_privkey_export (gnutls_x509_privkey_t key, | ||
942 | gnutls_x509_crt_fmt_t format, void *output_data, | ||
943 | size_t * output_data_size) | ||
944 | { | ||
945 | const char *msg; | ||
946 | |||
947 | if (key == NULL((void*)0)) | ||
948 | { | ||
949 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",949); } while(0);; | ||
950 | return GNUTLS_E_INVALID_REQUEST-50; | ||
951 | } | ||
952 | |||
953 | if (key->pk_algorithm == GNUTLS_PK_RSA) | ||
954 | msg = PEM_KEY_RSA"RSA PRIVATE KEY"; | ||
955 | else if (key->pk_algorithm == GNUTLS_PK_DSA) | ||
956 | msg = PEM_KEY_DSA"DSA PRIVATE KEY"; | ||
957 | else if (key->pk_algorithm == GNUTLS_PK_EC) | ||
958 | msg = PEM_KEY_ECC"EC PRIVATE KEY"; | ||
959 | else | ||
960 | msg = "UNKNOWN"; | ||
961 | |||
962 | return _gnutls_x509_export_int (key->key, format, msg, | ||
963 | output_data, output_data_size); | ||
964 | } | ||
965 | |||
966 | /** | ||
967 | * gnutls_x509_privkey_sec_param: | ||
968 | * @key: a key structure | ||
969 | * | ||
970 | * This function will return the security parameter appropriate with | ||
971 | * this private key. | ||
972 | * | ||
973 | * Returns: On success, a valid security parameter is returned otherwise | ||
974 | * %GNUTLS_SEC_PARAM_UNKNOWN is returned. | ||
975 | * | ||
976 | * Since: 2.12.0 | ||
977 | **/ | ||
978 | gnutls_sec_param_t | ||
979 | gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key) | ||
980 | { | ||
981 | int bits; | ||
982 | |||
983 | bits = pubkey_to_bits(key->pk_algorithm, &key->params); | ||
984 | if (bits <= 0) | ||
985 | return GNUTLS_SEC_PARAM_UNKNOWN; | ||
986 | |||
987 | return gnutls_pk_bits_to_sec_param(key->pk_algorithm, bits); | ||
988 | } | ||
989 | |||
990 | /** | ||
991 | * gnutls_x509_privkey_export_ecc_raw: | ||
992 | * @key: a structure that holds the rsa parameters | ||
993 | * @curve: will hold the curve | ||
994 | * @x: will hold the x coordinate | ||
995 | * @y: will hold the y coordinate | ||
996 | * @k: will hold the private key | ||
997 | * | ||
998 | * This function will export the ECC private key's parameters found | ||
999 | * in the given structure. The new parameters will be allocated using | ||
1000 | * gnutls_malloc() and will be stored in the appropriate datum. | ||
1001 | * | ||
1002 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1003 | * negative error value. | ||
1004 | * | ||
1005 | * Since: 3.0.0 | ||
1006 | **/ | ||
1007 | int gnutls_x509_privkey_export_ecc_raw (gnutls_x509_privkey_t key, | ||
1008 | gnutls_ecc_curve_t *curve, | ||
1009 | gnutls_datum_t * x, gnutls_datum_t * y, | ||
1010 | gnutls_datum_t* k) | ||
1011 | { | ||
1012 | int ret; | ||
1013 | |||
1014 | if (key == NULL((void*)0)) | ||
1015 | { | ||
1016 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1016); } while(0);; | ||
1017 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1018 | } | ||
1019 | |||
1020 | *curve = key->params.flags; | ||
1021 | |||
1022 | /* X */ | ||
1023 | ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_X6], x); | ||
1024 | if (ret < 0) | ||
1025 | { | ||
1026 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1026); } while(0);; | ||
1027 | return ret; | ||
1028 | } | ||
1029 | |||
1030 | /* Y */ | ||
1031 | ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_Y7], y); | ||
1032 | if (ret < 0) | ||
1033 | { | ||
1034 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1034); } while(0);; | ||
1035 | _gnutls_free_datum (x)_gnutls_free_datum_m(x, gnutls_free); | ||
1036 | return ret; | ||
1037 | } | ||
1038 | |||
1039 | |||
1040 | /* K */ | ||
1041 | ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_K8], k); | ||
1042 | if (ret < 0) | ||
1043 | { | ||
1044 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1044); } while(0);; | ||
1045 | _gnutls_free_datum (x)_gnutls_free_datum_m(x, gnutls_free); | ||
1046 | _gnutls_free_datum (y)_gnutls_free_datum_m(y, gnutls_free); | ||
1047 | return ret; | ||
1048 | } | ||
1049 | |||
1050 | return 0; | ||
1051 | |||
1052 | } | ||
1053 | |||
1054 | /** | ||
1055 | * gnutls_x509_privkey_export_rsa_raw: | ||
1056 | * @key: a structure that holds the rsa parameters | ||
1057 | * @m: will hold the modulus | ||
1058 | * @e: will hold the public exponent | ||
1059 | * @d: will hold the private exponent | ||
1060 | * @p: will hold the first prime (p) | ||
1061 | * @q: will hold the second prime (q) | ||
1062 | * @u: will hold the coefficient | ||
1063 | * | ||
1064 | * This function will export the RSA private key's parameters found | ||
1065 | * in the given structure. The new parameters will be allocated using | ||
1066 | * gnutls_malloc() and will be stored in the appropriate datum. | ||
1067 | * | ||
1068 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1069 | * negative error value. | ||
1070 | **/ | ||
1071 | int | ||
1072 | gnutls_x509_privkey_export_rsa_raw (gnutls_x509_privkey_t key, | ||
1073 | gnutls_datum_t * m, gnutls_datum_t * e, | ||
1074 | gnutls_datum_t * d, gnutls_datum_t * p, | ||
1075 | gnutls_datum_t * q, gnutls_datum_t * u) | ||
1076 | { | ||
1077 | |||
1078 | return gnutls_x509_privkey_export_rsa_raw2 (key, m, e, d, p, q, u, NULL((void*)0), | ||
1079 | NULL((void*)0)); | ||
1080 | } | ||
1081 | |||
1082 | /** | ||
1083 | * gnutls_x509_privkey_export_rsa_raw2: | ||
1084 | * @key: a structure that holds the rsa parameters | ||
1085 | * @m: will hold the modulus | ||
1086 | * @e: will hold the public exponent | ||
1087 | * @d: will hold the private exponent | ||
1088 | * @p: will hold the first prime (p) | ||
1089 | * @q: will hold the second prime (q) | ||
1090 | * @u: will hold the coefficient | ||
1091 | * @e1: will hold e1 = d mod (p-1) | ||
1092 | * @e2: will hold e2 = d mod (q-1) | ||
1093 | * | ||
1094 | * This function will export the RSA private key's parameters found | ||
1095 | * in the given structure. The new parameters will be allocated using | ||
1096 | * gnutls_malloc() and will be stored in the appropriate datum. | ||
1097 | * | ||
1098 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1099 | * negative error value. | ||
1100 | * | ||
1101 | * Since: 2.12.0 | ||
1102 | **/ | ||
1103 | int | ||
1104 | gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key, | ||
1105 | gnutls_datum_t * m, gnutls_datum_t * e, | ||
1106 | gnutls_datum_t * d, gnutls_datum_t * p, | ||
1107 | gnutls_datum_t * q, gnutls_datum_t * u, | ||
1108 | gnutls_datum_t * e1, gnutls_datum_t * e2) | ||
1109 | { | ||
1110 | int ret; | ||
1111 | gnutls_pk_params_st pk_params; | ||
1112 | |||
1113 | gnutls_pk_params_init(&pk_params); | ||
1114 | |||
1115 | if (key == NULL((void*)0)) | ||
1116 | { | ||
1117 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1117); } while(0);; | ||
1118 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1119 | } | ||
1120 | |||
1121 | m->data = e->data = d->data = p->data = q->data = u->data = NULL((void*)0); | ||
1122 | m->size = e->size = d->size = p->size = q->size = u->size = 0; | ||
1123 | |||
1124 | ret = _gnutls_pk_params_copy (&pk_params, &key->params); | ||
1125 | if (ret < 0) | ||
1126 | { | ||
1127 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1127); } while(0);; | ||
1128 | return ret; | ||
1129 | } | ||
1130 | |||
1131 | ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params); | ||
1132 | if (ret < 0) | ||
1133 | { | ||
1134 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1134); } while(0);; | ||
1135 | goto error; | ||
1136 | } | ||
1137 | |||
1138 | ret = _gnutls_mpi_dprint_lz (pk_params.params[0], m); | ||
1139 | if (ret < 0) | ||
1140 | { | ||
1141 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1141); } while(0);; | ||
1142 | goto error; | ||
1143 | } | ||
1144 | |||
1145 | /* E */ | ||
1146 | ret = _gnutls_mpi_dprint_lz (pk_params.params[1], e); | ||
1147 | if (ret < 0) | ||
1148 | { | ||
1149 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1149); } while(0);; | ||
1150 | goto error; | ||
1151 | } | ||
1152 | |||
1153 | /* D */ | ||
1154 | ret = _gnutls_mpi_dprint_lz (pk_params.params[2], d); | ||
1155 | if (ret < 0) | ||
1156 | { | ||
1157 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1157); } while(0);; | ||
1158 | goto error; | ||
1159 | } | ||
1160 | |||
1161 | /* P */ | ||
1162 | ret = _gnutls_mpi_dprint_lz (pk_params.params[3], p); | ||
1163 | if (ret < 0) | ||
1164 | { | ||
1165 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1165); } while(0);; | ||
1166 | goto error; | ||
1167 | } | ||
1168 | |||
1169 | /* Q */ | ||
1170 | ret = _gnutls_mpi_dprint_lz (pk_params.params[4], q); | ||
1171 | if (ret < 0) | ||
1172 | { | ||
1173 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1173); } while(0);; | ||
1174 | goto error; | ||
1175 | } | ||
1176 | |||
1177 | /* U */ | ||
1178 | ret = _gnutls_mpi_dprint_lz (key->params.params[5], u); | ||
1179 | if (ret < 0) | ||
1180 | { | ||
1181 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1181); } while(0);; | ||
1182 | goto error; | ||
1183 | } | ||
1184 | |||
1185 | /* E1 */ | ||
1186 | if (e1) | ||
1187 | { | ||
1188 | ret = _gnutls_mpi_dprint_lz (key->params.params[6], e1); | ||
1189 | if (ret < 0) | ||
1190 | { | ||
1191 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1191); } while(0);; | ||
1192 | goto error; | ||
1193 | } | ||
1194 | } | ||
1195 | |||
1196 | /* E2 */ | ||
1197 | if (e2) | ||
1198 | { | ||
1199 | ret = _gnutls_mpi_dprint_lz (key->params.params[7], e2); | ||
1200 | if (ret < 0) | ||
1201 | { | ||
1202 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1202); } while(0);; | ||
1203 | goto error; | ||
1204 | } | ||
1205 | } | ||
1206 | |||
1207 | gnutls_pk_params_release (&pk_params); | ||
1208 | |||
1209 | return 0; | ||
1210 | |||
1211 | error: | ||
1212 | _gnutls_free_datum (m)_gnutls_free_datum_m(m, gnutls_free); | ||
1213 | _gnutls_free_datum (d)_gnutls_free_datum_m(d, gnutls_free); | ||
1214 | _gnutls_free_datum (e)_gnutls_free_datum_m(e, gnutls_free); | ||
1215 | _gnutls_free_datum (p)_gnutls_free_datum_m(p, gnutls_free); | ||
1216 | _gnutls_free_datum (q)_gnutls_free_datum_m(q, gnutls_free); | ||
1217 | gnutls_pk_params_release (&pk_params); | ||
1218 | |||
1219 | return ret; | ||
1220 | } | ||
1221 | |||
1222 | /** | ||
1223 | * gnutls_x509_privkey_export_dsa_raw: | ||
1224 | * @key: a structure that holds the DSA parameters | ||
1225 | * @p: will hold the p | ||
1226 | * @q: will hold the q | ||
1227 | * @g: will hold the g | ||
1228 | * @y: will hold the y | ||
1229 | * @x: will hold the x | ||
1230 | * | ||
1231 | * This function will export the DSA private key's parameters found | ||
1232 | * in the given structure. The new parameters will be allocated using | ||
1233 | * gnutls_malloc() and will be stored in the appropriate datum. | ||
1234 | * | ||
1235 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1236 | * negative error value. | ||
1237 | **/ | ||
1238 | int | ||
1239 | gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, | ||
1240 | gnutls_datum_t * p, gnutls_datum_t * q, | ||
1241 | gnutls_datum_t * g, gnutls_datum_t * y, | ||
1242 | gnutls_datum_t * x) | ||
1243 | { | ||
1244 | int ret; | ||
1245 | |||
1246 | if (key == NULL((void*)0)) | ||
1247 | { | ||
1248 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1248); } while(0);; | ||
1249 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1250 | } | ||
1251 | |||
1252 | /* P */ | ||
1253 | ret = _gnutls_mpi_dprint_lz (key->params.params[0], p); | ||
1254 | if (ret < 0) | ||
1255 | { | ||
1256 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1256); } while(0);; | ||
1257 | return ret; | ||
1258 | } | ||
1259 | |||
1260 | /* Q */ | ||
1261 | ret = _gnutls_mpi_dprint_lz (key->params.params[1], q); | ||
1262 | if (ret < 0) | ||
1263 | { | ||
1264 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1264); } while(0);; | ||
1265 | _gnutls_free_datum (p)_gnutls_free_datum_m(p, gnutls_free); | ||
1266 | return ret; | ||
1267 | } | ||
1268 | |||
1269 | |||
1270 | /* G */ | ||
1271 | ret = _gnutls_mpi_dprint_lz (key->params.params[2], g); | ||
1272 | if (ret < 0) | ||
1273 | { | ||
1274 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1274); } while(0);; | ||
1275 | _gnutls_free_datum (p)_gnutls_free_datum_m(p, gnutls_free); | ||
1276 | _gnutls_free_datum (q)_gnutls_free_datum_m(q, gnutls_free); | ||
1277 | return ret; | ||
1278 | } | ||
1279 | |||
1280 | |||
1281 | /* Y */ | ||
1282 | ret = _gnutls_mpi_dprint_lz (key->params.params[3], y); | ||
1283 | if (ret < 0) | ||
1284 | { | ||
1285 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1285); } while(0);; | ||
1286 | _gnutls_free_datum (p)_gnutls_free_datum_m(p, gnutls_free); | ||
1287 | _gnutls_free_datum (g)_gnutls_free_datum_m(g, gnutls_free); | ||
1288 | _gnutls_free_datum (q)_gnutls_free_datum_m(q, gnutls_free); | ||
1289 | return ret; | ||
1290 | } | ||
1291 | |||
1292 | /* X */ | ||
1293 | ret = _gnutls_mpi_dprint_lz (key->params.params[4], x); | ||
1294 | if (ret < 0) | ||
1295 | { | ||
1296 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1296); } while(0);; | ||
1297 | _gnutls_free_datum (y)_gnutls_free_datum_m(y, gnutls_free); | ||
1298 | _gnutls_free_datum (p)_gnutls_free_datum_m(p, gnutls_free); | ||
1299 | _gnutls_free_datum (g)_gnutls_free_datum_m(g, gnutls_free); | ||
1300 | _gnutls_free_datum (q)_gnutls_free_datum_m(q, gnutls_free); | ||
1301 | return ret; | ||
1302 | } | ||
1303 | |||
1304 | return 0; | ||
1305 | } | ||
1306 | |||
1307 | /** | ||
1308 | * gnutls_x509_privkey_generate: | ||
1309 | * @key: should contain a #gnutls_x509_privkey_t structure | ||
1310 | * @algo: is one of the algorithms in #gnutls_pk_algorithm_t. | ||
1311 | * @bits: the size of the modulus | ||
1312 | * @flags: unused for now. Must be 0. | ||
1313 | * | ||
1314 | * This function will generate a random private key. Note that this | ||
1315 | * function must be called on an empty private key. | ||
1316 | * | ||
1317 | * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits(). | ||
1318 | * | ||
1319 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1320 | * negative error value. | ||
1321 | **/ | ||
1322 | int | ||
1323 | gnutls_x509_privkey_generate (gnutls_x509_privkey_t key, | ||
1324 | gnutls_pk_algorithm_t algo, unsigned int bits, | ||
1325 | unsigned int flags) | ||
1326 | { | ||
1327 | int ret; | ||
1328 | |||
1329 | if (key == NULL((void*)0)) | ||
1330 | { | ||
1331 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1331); } while(0);; | ||
1332 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1333 | } | ||
1334 | |||
1335 | gnutls_pk_params_init(&key->params); | ||
1336 | |||
1337 | if (algo == GNUTLS_PK_EC) | ||
1338 | bits = _gnutls_ecc_bits_to_curve(bits); | ||
1339 | |||
1340 | ret = _gnutls_pk_generate (algo, bits, &key->params)_gnutls_pk_ops.generate( algo, bits, &key->params); | ||
1341 | if (ret < 0) | ||
1342 | { | ||
1343 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1343); } while(0);; | ||
1344 | return ret; | ||
1345 | } | ||
1346 | |||
1347 | ret = _gnutls_asn1_encode_privkey (algo, &key->key, &key->params); | ||
1348 | if (ret < 0) | ||
1349 | { | ||
1350 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1350); } while(0);; | ||
1351 | goto cleanup; | ||
1352 | } | ||
1353 | key->pk_algorithm = algo; | ||
1354 | |||
1355 | return 0; | ||
1356 | |||
1357 | cleanup: | ||
1358 | key->pk_algorithm = GNUTLS_PK_UNKNOWN; | ||
1359 | gnutls_pk_params_release(&key->params); | ||
1360 | |||
1361 | return ret; | ||
1362 | } | ||
1363 | |||
1364 | /** | ||
1365 | * gnutls_x509_privkey_verify_params: | ||
1366 | * @key: should contain a #gnutls_x509_privkey_t structure | ||
1367 | * | ||
1368 | * This function will verify the private key parameters. | ||
1369 | * | ||
1370 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1371 | * negative error value. | ||
1372 | **/ | ||
1373 | int | ||
1374 | gnutls_x509_privkey_verify_params (gnutls_x509_privkey_t key) | ||
1375 | { | ||
1376 | int ret; | ||
1377 | |||
1378 | ret = _gnutls_pk_verify_params (key->pk_algorithm, &key->params)_gnutls_pk_ops.verify_params( key->pk_algorithm, &key-> params); | ||
1379 | if (ret < 0) | ||
1380 | { | ||
1381 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1381); } while(0);; | ||
1382 | return ret; | ||
1383 | } | ||
1384 | |||
1385 | return 0; | ||
1386 | } | ||
1387 | |||
1388 | /** | ||
1389 | * gnutls_x509_privkey_get_key_id: | ||
1390 | * @key: Holds the key | ||
1391 | * @flags: should be 0 for now | ||
1392 | * @output_data: will contain the key ID | ||
1393 | * @output_data_size: holds the size of output_data (and will be | ||
1394 | * replaced by the actual size of parameters) | ||
1395 | * | ||
1396 | * This function will return a unique ID the depends on the public key | ||
1397 | * parameters. This ID can be used in checking whether a certificate | ||
1398 | * corresponds to the given key. | ||
1399 | * | ||
1400 | * If the buffer provided is not long enough to hold the output, then | ||
1401 | * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will | ||
1402 | * be returned. The output will normally be a SHA-1 hash output, | ||
1403 | * which is 20 bytes. | ||
1404 | * | ||
1405 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1406 | * negative error value. | ||
1407 | **/ | ||
1408 | int | ||
1409 | gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key, | ||
1410 | unsigned int flags, | ||
1411 | unsigned char *output_data, | ||
1412 | size_t * output_data_size) | ||
1413 | { | ||
1414 | int ret; | ||
1415 | |||
1416 | if (key == NULL((void*)0)) | ||
1417 | { | ||
1418 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1418); } while(0);; | ||
1419 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1420 | } | ||
1421 | |||
1422 | ret = _gnutls_get_key_id(key->pk_algorithm, &key->params, output_data, output_data_size); | ||
1423 | if (ret < 0) | ||
1424 | { | ||
1425 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1425); } while(0);; | ||
1426 | } | ||
1427 | |||
1428 | return ret; | ||
1429 | } | ||
1430 | |||
1431 | |||
1432 | #ifdef ENABLE_PKI1 | ||
1433 | /*- | ||
1434 | * _gnutls_x509_privkey_sign_hash2: | ||
1435 | * @signer: Holds the signer's key | ||
1436 | * @hash_algo: The hash algorithm used | ||
1437 | * @hash_data: holds the data to be signed | ||
1438 | * @signature: will contain newly allocated signature | ||
1439 | * @flags: (0) for now | ||
1440 | * | ||
1441 | * This function will sign the given hashed data using a signature algorithm | ||
1442 | * supported by the private key. Signature algorithms are always used | ||
1443 | * together with a hash functions. Different hash functions may be | ||
1444 | * used for the RSA algorithm, but only SHA-1,SHA-224 and SHA-256 | ||
1445 | * for the DSA keys, depending on their bit size. | ||
1446 | * | ||
1447 | * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine | ||
1448 | * the hash algorithm. | ||
1449 | * | ||
1450 | * The RSA algorithm is used in PKCS #1 v1.5 mode. | ||
1451 | * | ||
1452 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1453 | * negative error value. | ||
1454 | -*/ | ||
1455 | static int | ||
1456 | _gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer, | ||
1457 | gnutls_digest_algorithm_t hash_algo, | ||
1458 | unsigned int flags, | ||
1459 | const gnutls_datum_t * hash_data, | ||
1460 | gnutls_datum_t * signature) | ||
1461 | { | ||
1462 | int ret; | ||
1463 | gnutls_datum_t digest; | ||
1464 | |||
1465 | digest.data = gnutls_malloc (hash_data->size); | ||
1466 | if (digest.data == NULL((void*)0)) | ||
1467 | { | ||
1468 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1468); } while(0);; | ||
1469 | return GNUTLS_E_MEMORY_ERROR-25; | ||
1470 | } | ||
1471 | digest.size = hash_data->size; | ||
1472 | memcpy (digest.data, hash_data->data, digest.size); | ||
1473 | |||
1474 | ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest); | ||
1475 | if (ret < 0) | ||
1476 | { | ||
1477 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1477); } while(0);; | ||
1478 | goto cleanup; | ||
1479 | } | ||
1480 | |||
1481 | ret = _gnutls_soft_sign (signer->pk_algorithm, &signer->params, | ||
1482 | &digest, signature); | ||
1483 | |||
1484 | if (ret < 0) | ||
1485 | { | ||
1486 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1486); } while(0);; | ||
1487 | goto cleanup; | ||
1488 | } | ||
1489 | |||
1490 | ret = 0; | ||
1491 | |||
1492 | cleanup: | ||
1493 | _gnutls_free_datum (&digest)_gnutls_free_datum_m(&digest, gnutls_free); | ||
1494 | return ret; | ||
1495 | } | ||
1496 | |||
1497 | /** | ||
1498 | * gnutls_x509_privkey_sign_hash: | ||
1499 | * @key: Holds the key | ||
1500 | * @hash: holds the data to be signed | ||
1501 | * @signature: will contain newly allocated signature | ||
1502 | * | ||
1503 | * This function will sign the given hash using the private key. Do not | ||
1504 | * use this function directly unless you know what it is. Typical signing | ||
1505 | * requires the data to be hashed and stored in special formats | ||
1506 | * (e.g. BER Digest-Info for RSA). | ||
1507 | * | ||
1508 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1509 | * negative error value. | ||
1510 | * | ||
1511 | * Deprecated in: 2.12.0 | ||
1512 | */ | ||
1513 | int | ||
1514 | gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key, | ||
1515 | const gnutls_datum_t * hash, | ||
1516 | gnutls_datum_t * signature) | ||
1517 | { | ||
1518 | int result; | ||
1519 | |||
1520 | if (key == NULL((void*)0)) | ||
1521 | { | ||
1522 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1522); } while(0);; | ||
1523 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1524 | } | ||
1525 | |||
1526 | result = _gnutls_soft_sign (key->pk_algorithm, &key->params, | ||
1527 | hash, signature); | ||
1528 | if (result < 0) | ||
1529 | { | ||
1530 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1530); } while(0);; | ||
1531 | return result; | ||
1532 | } | ||
1533 | |||
1534 | return 0; | ||
1535 | } | ||
1536 | |||
1537 | /** | ||
1538 | * gnutls_x509_privkey_sign_data: | ||
1539 | * @key: Holds the key | ||
1540 | * @digest: should be MD5 or SHA1 | ||
1541 | * @flags: should be 0 for now | ||
1542 | * @data: holds the data to be signed | ||
1543 | * @signature: will contain the signature | ||
1544 | * @signature_size: holds the size of signature (and will be replaced | ||
1545 | * by the new size) | ||
1546 | * | ||
1547 | * This function will sign the given data using a signature algorithm | ||
1548 | * supported by the private key. Signature algorithms are always used | ||
1549 | * together with a hash functions. Different hash functions may be | ||
1550 | * used for the RSA algorithm, but only SHA-1 for the DSA keys. | ||
1551 | * | ||
1552 | * If the buffer provided is not long enough to hold the output, then | ||
1553 | * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will | ||
1554 | * be returned. | ||
1555 | * | ||
1556 | * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine | ||
1557 | * the hash algorithm. | ||
1558 | * | ||
1559 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1560 | * negative error value. | ||
1561 | * | ||
1562 | * Deprecated: Use gnutls_privkey_sign_data(). | ||
1563 | */ | ||
1564 | int | ||
1565 | gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key, | ||
1566 | gnutls_digest_algorithm_t digest, | ||
1567 | unsigned int flags, | ||
1568 | const gnutls_datum_t * data, | ||
1569 | void *signature, size_t * signature_size) | ||
1570 | { | ||
1571 | int result; | ||
1572 | gnutls_datum_t sig = { NULL((void*)0), 0 }; | ||
1573 | gnutls_datum_t hash; | ||
1574 | |||
1575 | if (key == NULL((void*)0)) | ||
| |||
1576 | { | ||
1577 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1577); } while(0);; | ||
1578 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1579 | } | ||
1580 | |||
1581 | result = | ||
1582 | pk_hash_data (key->pk_algorithm, digest, &key->params, data, &hash); | ||
1583 | if (result < 0) | ||
| |||
1584 | { | ||
1585 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1585); } while(0);; | ||
1586 | return result; | ||
1587 | } | ||
1588 | |||
1589 | result = | ||
1590 | _gnutls_x509_privkey_sign_hash2 (key, digest, flags, &hash, signature); | ||
1591 | |||
1592 | _gnutls_free_datum(&hash)_gnutls_free_datum_m(&hash, gnutls_free); | ||
1593 | |||
1594 | if (result < 0) | ||
| |||
1595 | { | ||
1596 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1596); } while(0);; | ||
1597 | return result; | ||
1598 | } | ||
1599 | |||
1600 | if (*signature_size < sig.size) | ||
| |||
1601 | { | ||
1602 | *signature_size = sig.size; | ||
1603 | _gnutls_free_datum (&sig)_gnutls_free_datum_m(&sig, gnutls_free); | ||
1604 | return GNUTLS_E_SHORT_MEMORY_BUFFER-51; | ||
1605 | } | ||
1606 | |||
1607 | *signature_size = sig.size; | ||
1608 | memcpy (signature, sig.data, sig.size); | ||
| |||
1609 | |||
1610 | _gnutls_free_datum (&sig)_gnutls_free_datum_m(&sig, gnutls_free); | ||
1611 | |||
1612 | return 0; | ||
1613 | } | ||
1614 | |||
1615 | |||
1616 | /** | ||
1617 | * gnutls_x509_privkey_fix: | ||
1618 | * @key: Holds the key | ||
1619 | * | ||
1620 | * This function will recalculate the secondary parameters in a key. | ||
1621 | * In RSA keys, this can be the coefficient and exponent1,2. | ||
1622 | * | ||
1623 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a | ||
1624 | * negative error value. | ||
1625 | **/ | ||
1626 | int | ||
1627 | gnutls_x509_privkey_fix (gnutls_x509_privkey_t key) | ||
1628 | { | ||
1629 | int ret; | ||
1630 | |||
1631 | if (key == NULL((void*)0)) | ||
1632 | { | ||
1633 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1633); } while(0);; | ||
1634 | return GNUTLS_E_INVALID_REQUEST-50; | ||
1635 | } | ||
1636 | |||
1637 | asn1_delete_structure (&key->key); | ||
1638 | |||
1639 | ret = _gnutls_asn1_encode_privkey (key->pk_algorithm, &key->key, &key->params); | ||
1640 | if (ret < 0) | ||
1641 | { | ||
1642 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "privkey.c",1642); } while(0);; | ||
1643 | return ret; | ||
1644 | } | ||
1645 | |||
1646 | return 0; | ||
1647 | } | ||
1648 | |||
1649 | #endif |