Bug Summary

File:lib/x509/privkey.c
Location:line 1608, column 3
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

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 **/
46int
47gnutls_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 **/
67void
68gnutls_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 **/
89int
90gnutls_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 */
122ASN1_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
224error:
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 */
234ASN1_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
331error:
332 asn1_delete_structure (&pkey_asn);
333 gnutls_pk_params_release (&pkey->params);
334 return NULL((void*)0);
335
336}
337
338
339static ASN1_TYPE
340decode_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
401error:
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 **/
429int
430gnutls_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
544failover:
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 **/
578int
579gnutls_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 **/
610int
611gnutls_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
726cleanup:
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 **/
748int
749gnutls_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
817cleanup:
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 **/
840int
841gnutls_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
889cleanup:
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 **/
906int
907gnutls_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 **/
940int
941gnutls_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 **/
978gnutls_sec_param_t
979gnutls_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 **/
1007int 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 **/
1071int
1072gnutls_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 **/
1103int
1104gnutls_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
1211error:
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 **/
1238int
1239gnutls_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 **/
1322int
1323gnutls_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
1357cleanup:
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 **/
1373int
1374gnutls_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 **/
1408int
1409gnutls_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 -*/
1455static 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
1492cleanup:
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 */
1513int
1514gnutls_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 */
1564int
1565gnutls_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))
1
Taking false branch
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)
2
Taking false branch
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)
3
Taking false branch
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)
4
Taking false branch
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);
5
Null pointer passed as an argument to a 'nonnull' parameter
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 **/
1626int
1627gnutls_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