Line data Source code
1 : /*
2 : * GnuTLS public key support
3 : * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4 : * Copyright (C) 2017 Red Hat, Inc.
5 : *
6 : * Author: Nikos Mavrogiannopoulos
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 2.1 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 <https://www.gnu.org/licenses/>
20 : */
21 :
22 : #include "gnutls_int.h"
23 : #include <gnutls/pkcs11.h>
24 : #include <stdio.h>
25 : #include <string.h>
26 : #include "errors.h"
27 : #include <datum.h>
28 : #include <pkcs11_int.h>
29 : #include <gnutls/abstract.h>
30 : #include <tls-sig.h>
31 : #include <pk.h>
32 : #include <x509_int.h>
33 : #include <num.h>
34 : #include <x509/common.h>
35 : #include <x509_b64.h>
36 : #include <abstract_int.h>
37 : #include <fips.h>
38 : #include "urls.h"
39 : #include <ecc.h>
40 :
41 : static int
42 : pubkey_verify_hashed_data(const gnutls_sign_entry_st *se,
43 : const mac_entry_st *me,
44 : const gnutls_datum_t * hash,
45 : const gnutls_datum_t * signature,
46 : gnutls_pk_params_st * params,
47 : gnutls_x509_spki_st * sign_params,
48 : unsigned flags);
49 :
50 : static
51 : int pubkey_supports_sig(gnutls_pubkey_t pubkey,
52 : const gnutls_sign_entry_st *se);
53 :
54 37081 : unsigned pubkey_to_bits(const gnutls_pk_params_st * params)
55 : {
56 37081 : switch (params->algo) {
57 27872 : case GNUTLS_PK_RSA:
58 : case GNUTLS_PK_RSA_PSS:
59 27872 : return _gnutls_mpi_get_nbits(params->params[RSA_MODULUS]);
60 264 : case GNUTLS_PK_DSA:
61 264 : return _gnutls_mpi_get_nbits(params->params[DSA_P]);
62 8945 : case GNUTLS_PK_ECDSA:
63 : case GNUTLS_PK_EDDSA_ED25519:
64 : case GNUTLS_PK_EDDSA_ED448:
65 : case GNUTLS_PK_GOST_01:
66 : case GNUTLS_PK_GOST_12_256:
67 : case GNUTLS_PK_GOST_12_512:
68 8945 : return gnutls_ecc_curve_get_size(params->curve) * 8;
69 : default:
70 : return 0;
71 : }
72 : }
73 :
74 : /**
75 : * gnutls_pubkey_get_pk_algorithm:
76 : * @key: should contain a #gnutls_pubkey_t type
77 : * @bits: If set will return the number of bits of the parameters (may be NULL)
78 : *
79 : * This function will return the public key algorithm of a public
80 : * key and if possible will return a number of bits that indicates
81 : * the security parameter of the key.
82 : *
83 : * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
84 : * success, or a negative error code on error.
85 : *
86 : * Since: 2.12.0
87 : **/
88 27378 : int gnutls_pubkey_get_pk_algorithm(gnutls_pubkey_t key, unsigned int *bits)
89 : {
90 27378 : if (bits)
91 733 : *bits = key->bits;
92 :
93 27378 : return key->params.algo;
94 : }
95 :
96 : /**
97 : * gnutls_pubkey_get_key_usage:
98 : * @key: should contain a #gnutls_pubkey_t type
99 : * @usage: If set will return the number of bits of the parameters (may be NULL)
100 : *
101 : * This function will return the key usage of the public key.
102 : *
103 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
104 : * negative error value.
105 : *
106 : * Since: 2.12.0
107 : **/
108 5845 : int gnutls_pubkey_get_key_usage(gnutls_pubkey_t key, unsigned int *usage)
109 : {
110 5845 : if (usage)
111 5845 : *usage = key->key_usage;
112 :
113 5845 : return 0;
114 : }
115 :
116 : /**
117 : * gnutls_pubkey_init:
118 : * @key: A pointer to the type to be initialized
119 : *
120 : * This function will initialize a public key.
121 : *
122 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
123 : * negative error value.
124 : *
125 : * Since: 2.12.0
126 : **/
127 20094 : int gnutls_pubkey_init(gnutls_pubkey_t * key)
128 : {
129 20094 : FAIL_IF_LIB_ERROR;
130 :
131 20094 : *key = gnutls_calloc(1, sizeof(struct gnutls_pubkey_st));
132 20094 : if (*key == NULL) {
133 0 : gnutls_assert();
134 0 : return GNUTLS_E_MEMORY_ERROR;
135 : }
136 :
137 : return 0;
138 : }
139 :
140 : /**
141 : * gnutls_pubkey_deinit:
142 : * @key: The key to be deinitialized
143 : *
144 : * This function will deinitialize a public key structure.
145 : *
146 : * Since: 2.12.0
147 : **/
148 19567 : void gnutls_pubkey_deinit(gnutls_pubkey_t key)
149 : {
150 19567 : if (!key)
151 : return;
152 19567 : gnutls_pk_params_release(&key->params);
153 19567 : gnutls_free(key);
154 : }
155 :
156 : /**
157 : * gnutls_pubkey_import_x509:
158 : * @key: The public key
159 : * @crt: The certificate to be imported
160 : * @flags: should be zero
161 : *
162 : * This function will import the given public key to the abstract
163 : * #gnutls_pubkey_t type.
164 : *
165 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
166 : * negative error value.
167 : *
168 : * Since: 2.12.0
169 : **/
170 : int
171 18406 : gnutls_pubkey_import_x509(gnutls_pubkey_t key, gnutls_x509_crt_t crt,
172 : unsigned int flags)
173 : {
174 18406 : int ret;
175 :
176 18406 : gnutls_pk_params_release(&key->params);
177 : /* params initialized in _gnutls_x509_crt_get_mpis */
178 :
179 18406 : ret = gnutls_x509_crt_get_pk_algorithm(crt, &key->bits);
180 18406 : if (ret < 0)
181 130 : return gnutls_assert_val(ret);
182 :
183 18276 : key->params.algo = ret;
184 :
185 18276 : ret = gnutls_x509_crt_get_key_usage(crt, &key->key_usage, NULL);
186 18276 : if (ret < 0)
187 1385 : key->key_usage = 0;
188 :
189 18276 : ret = _gnutls_x509_crt_get_mpis(crt, &key->params);
190 18276 : if (ret < 0) {
191 3 : gnutls_assert();
192 3 : return ret;
193 : }
194 :
195 : return 0;
196 : }
197 :
198 : /**
199 : * gnutls_pubkey_import_x509_crq:
200 : * @key: The public key
201 : * @crq: The certificate to be imported
202 : * @flags: should be zero
203 : *
204 : * This function will import the given public key to the abstract
205 : * #gnutls_pubkey_t type.
206 : *
207 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
208 : * negative error value.
209 : *
210 : * Since: 3.1.5
211 : **/
212 : int
213 19 : gnutls_pubkey_import_x509_crq(gnutls_pubkey_t key, gnutls_x509_crq_t crq,
214 : unsigned int flags)
215 : {
216 19 : int ret;
217 :
218 19 : gnutls_pk_params_release(&key->params);
219 : /* params initialized in _gnutls_x509_crq_get_mpis */
220 :
221 19 : key->params.algo = gnutls_x509_crq_get_pk_algorithm(crq, &key->bits);
222 :
223 19 : ret = gnutls_x509_crq_get_key_usage(crq, &key->key_usage, NULL);
224 19 : if (ret < 0)
225 4 : key->key_usage = 0;
226 :
227 19 : ret = _gnutls_x509_crq_get_mpis(crq, &key->params);
228 19 : if (ret < 0) {
229 0 : gnutls_assert();
230 0 : return ret;
231 : }
232 :
233 : return 0;
234 : }
235 :
236 : /**
237 : * gnutls_pubkey_import_privkey:
238 : * @key: The public key
239 : * @pkey: The private key
240 : * @usage: GNUTLS_KEY_* key usage flags.
241 : * @flags: should be zero
242 : *
243 : * Imports the public key from a private. This function will import
244 : * the given public key to the abstract #gnutls_pubkey_t type.
245 : *
246 : * Note that in certain keys this operation may not be possible, e.g.,
247 : * in other than RSA PKCS#11 keys.
248 : *
249 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
250 : * negative error value.
251 : *
252 : * Since: 2.12.0
253 : **/
254 : int
255 1407 : gnutls_pubkey_import_privkey(gnutls_pubkey_t key, gnutls_privkey_t pkey,
256 : unsigned int usage, unsigned int flags)
257 : {
258 1407 : gnutls_pk_params_release(&key->params);
259 1407 : gnutls_pk_params_init(&key->params);
260 :
261 1407 : key->key_usage = usage;
262 1407 : key->params.algo = gnutls_privkey_get_pk_algorithm(pkey, &key->bits);
263 :
264 1407 : return _gnutls_privkey_get_public_mpis(pkey, &key->params);
265 : }
266 :
267 : /**
268 : * gnutls_pubkey_get_preferred_hash_algorithm:
269 : * @key: Holds the certificate
270 : * @hash: The result of the call with the hash algorithm used for signature
271 : * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL.
272 : *
273 : * This function will read the certificate and return the appropriate digest
274 : * algorithm to use for signing with this certificate. Some certificates (i.e.
275 : * DSA might not be able to sign without the preferred algorithm).
276 : *
277 : * To get the signature algorithm instead of just the hash use gnutls_pk_to_sign()
278 : * with the algorithm of the certificate/key and the provided @hash.
279 : *
280 : * Returns: the 0 if the hash algorithm is found. A negative error code is
281 : * returned on error.
282 : *
283 : * Since: 2.12.0
284 : **/
285 : int
286 153 : gnutls_pubkey_get_preferred_hash_algorithm(gnutls_pubkey_t key,
287 : gnutls_digest_algorithm_t *
288 : hash, unsigned int *mand)
289 : {
290 153 : int ret;
291 153 : const mac_entry_st *me;
292 :
293 153 : if (key == NULL) {
294 0 : gnutls_assert();
295 0 : return GNUTLS_E_INVALID_REQUEST;
296 : }
297 :
298 153 : if (mand)
299 113 : *mand = 0;
300 :
301 153 : switch (key->params.algo) {
302 7 : case GNUTLS_PK_DSA:
303 7 : if (mand)
304 3 : *mand = 1;
305 21 : FALLTHROUGH;
306 : case GNUTLS_PK_ECDSA:
307 :
308 21 : me = _gnutls_dsa_q_to_hash(&key->params, NULL);
309 21 : if (hash)
310 21 : *hash = (gnutls_digest_algorithm_t)me->id;
311 :
312 : ret = 0;
313 : break;
314 7 : case GNUTLS_PK_EDDSA_ED25519:
315 7 : if (hash)
316 7 : *hash = GNUTLS_DIG_SHA512;
317 :
318 : ret = 0;
319 : break;
320 4 : case GNUTLS_PK_EDDSA_ED448:
321 4 : if (hash)
322 4 : *hash = GNUTLS_DIG_SHAKE_256;
323 :
324 : ret = 0;
325 : break;
326 17 : case GNUTLS_PK_GOST_01:
327 : case GNUTLS_PK_GOST_12_256:
328 : case GNUTLS_PK_GOST_12_512:
329 17 : if (hash)
330 17 : *hash = _gnutls_gost_digest(key->params.algo);
331 17 : if (mand)
332 5 : *mand = 1;
333 :
334 : ret = 0;
335 : break;
336 20 : case GNUTLS_PK_RSA_PSS:
337 20 : if (mand && key->params.spki.rsa_pss_dig)
338 15 : *mand = 1;
339 :
340 20 : if (hash) {
341 20 : if (key->params.spki.rsa_pss_dig) {
342 15 : *hash = key->params.spki.rsa_pss_dig;
343 : } else {
344 5 : *hash = _gnutls_pk_bits_to_sha_hash(pubkey_to_bits(&key->params));
345 : }
346 : }
347 : ret = 0;
348 : break;
349 84 : case GNUTLS_PK_RSA:
350 84 : if (hash)
351 84 : *hash = _gnutls_pk_bits_to_sha_hash(pubkey_to_bits(&key->params));
352 : ret = 0;
353 : break;
354 :
355 0 : default:
356 0 : gnutls_assert();
357 : ret = GNUTLS_E_INTERNAL_ERROR;
358 : }
359 :
360 : return ret;
361 : }
362 :
363 : #ifdef ENABLE_PKCS11
364 :
365 : /* The EC_PARAMS attribute can contain either printable string with curve name
366 : * or OID defined in RFC 8410 */
367 : static int
368 3 : gnutls_pubkey_parse_ecc_eddsa_params(const gnutls_datum_t *parameters,
369 : gnutls_ecc_curve_t *outcurve)
370 : {
371 3 : gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
372 3 : ASN1_TYPE asn1 = ASN1_TYPE_EMPTY;
373 3 : unsigned int etype = ASN1_ETYPE_INVALID;
374 3 : char str[MAX_OID_SIZE];
375 3 : int str_size;
376 3 : int ret;
377 :
378 3 : ret = asn1_create_element(_gnutls_get_gnutls_asn(),
379 : "GNUTLS.pkcs-11-ec-Parameters", &asn1);
380 3 : if (ret != ASN1_SUCCESS) {
381 0 : gnutls_assert();
382 0 : return _gnutls_asn2err(ret);
383 : }
384 :
385 3 : ret = asn1_der_decoding(&asn1, parameters->data, parameters->size,
386 : NULL);
387 3 : if (ret != ASN1_SUCCESS) {
388 0 : gnutls_assert();
389 0 : ret = _gnutls_asn2err(ret);
390 0 : goto cleanup;
391 : }
392 :
393 : /* Read the type of choice.
394 : */
395 3 : str_size = sizeof(str) - 1;
396 3 : ret = asn1_read_value(asn1, "", str, &str_size);
397 3 : if (ret != ASN1_SUCCESS) {
398 0 : gnutls_assert();
399 0 : ret = _gnutls_asn2err(ret);
400 0 : goto cleanup;
401 : }
402 3 : str[str_size] = 0;
403 :
404 : /* Convert the choice to enum type */
405 3 : if (strcmp(str, "oId") == 0) {
406 : etype = ASN1_ETYPE_OBJECT_ID;
407 0 : } else if (strcmp(str, "curveName") == 0) {
408 0 : etype = ASN1_ETYPE_PRINTABLE_STRING;
409 : }
410 :
411 3 : str_size = sizeof(str) - 1;
412 0 : switch (etype) {
413 : case ASN1_ETYPE_OBJECT_ID:
414 3 : ret = asn1_read_value(asn1, "oId", str, &str_size);
415 3 : if (ret != ASN1_SUCCESS) {
416 0 : gnutls_assert();
417 0 : ret = _gnutls_asn2err(ret);
418 0 : break;
419 : }
420 :
421 3 : curve = gnutls_oid_to_ecc_curve(str);
422 3 : if (curve != GNUTLS_ECC_CURVE_ED25519 &&
423 3 : curve != GNUTLS_ECC_CURVE_ED448) {
424 0 : _gnutls_debug_log("Curve %s is not supported for EdDSA\n", str);
425 0 : gnutls_assert();
426 : curve = GNUTLS_ECC_CURVE_INVALID;
427 : ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
428 : break;
429 : }
430 :
431 : ret = GNUTLS_E_SUCCESS;
432 : break;
433 :
434 : case ASN1_ETYPE_PRINTABLE_STRING:
435 0 : ret = asn1_read_value(asn1, "curveName", str, &str_size);
436 0 : if (ret != ASN1_SUCCESS) {
437 0 : gnutls_assert();
438 0 : ret = _gnutls_asn2err(ret);
439 0 : break;
440 : }
441 :
442 0 : if (str_size == strlen("edwards25519") &&
443 0 : strncmp(str, "edwards25519", str_size) == 0) {
444 : curve = GNUTLS_ECC_CURVE_ED25519;
445 : ret = GNUTLS_E_SUCCESS;
446 : break;
447 0 : } else if (str_size == strlen("edwards448") &&
448 0 : strncmp(str, "edwards448", str_size) == 0) {
449 : curve = GNUTLS_ECC_CURVE_ED448;
450 : ret = GNUTLS_E_SUCCESS;
451 : break;
452 : }
453 : /* FALLTHROUGH */
454 :
455 : default:
456 : /* Neither of CHOICEs found. Fail */
457 0 : gnutls_assert();
458 : ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
459 : curve = GNUTLS_ECC_CURVE_INVALID;
460 : break;
461 : }
462 :
463 :
464 3 : cleanup:
465 3 : asn1_delete_structure(&asn1);
466 3 : *outcurve = curve;
467 3 : return ret;
468 : }
469 :
470 :
471 : static int
472 3 : gnutls_pubkey_import_ecc_eddsa(gnutls_pubkey_t key,
473 : const gnutls_datum_t * parameters,
474 : const gnutls_datum_t * ecpoint)
475 : {
476 3 : int ret;
477 :
478 3 : gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
479 3 : gnutls_datum_t raw_point = {NULL, 0};
480 :
481 3 : ret = gnutls_pubkey_parse_ecc_eddsa_params(parameters, &curve);
482 3 : if (ret < 0) {
483 0 : return gnutls_assert_val(ret);
484 : }
485 :
486 6 : ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING,
487 3 : ecpoint->data, ecpoint->size,
488 : &raw_point, 0);
489 3 : if (ret < 0) {
490 0 : gnutls_assert();
491 0 : gnutls_free(raw_point.data);
492 0 : return ret;
493 : }
494 3 : ret = gnutls_pubkey_import_ecc_raw(key, curve, &raw_point, NULL);
495 :
496 3 : gnutls_free(raw_point.data);
497 3 : return ret;
498 : }
499 :
500 : /**
501 : * gnutls_pubkey_import_pkcs11:
502 : * @key: The public key
503 : * @obj: The parameters to be imported
504 : * @flags: should be zero
505 : *
506 : * Imports a public key from a pkcs11 key. This function will import
507 : * the given public key to the abstract #gnutls_pubkey_t type.
508 : *
509 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
510 : * negative error value.
511 : *
512 : * Since: 2.12.0
513 : **/
514 : int
515 96 : gnutls_pubkey_import_pkcs11(gnutls_pubkey_t key,
516 : gnutls_pkcs11_obj_t obj, unsigned int flags)
517 : {
518 96 : int ret, type;
519 :
520 96 : type = gnutls_pkcs11_obj_get_type(obj);
521 96 : if (type != GNUTLS_PKCS11_OBJ_PUBKEY
522 96 : && type != GNUTLS_PKCS11_OBJ_X509_CRT) {
523 0 : gnutls_assert();
524 0 : return GNUTLS_E_INVALID_REQUEST;
525 : }
526 :
527 96 : if (type == GNUTLS_PKCS11_OBJ_X509_CRT) {
528 0 : gnutls_x509_crt_t xcrt;
529 :
530 0 : ret = gnutls_x509_crt_init(&xcrt);
531 0 : if (ret < 0) {
532 0 : gnutls_assert()
533 0 : return ret;
534 : }
535 :
536 0 : ret = gnutls_x509_crt_import_pkcs11(xcrt, obj);
537 0 : if (ret < 0) {
538 0 : gnutls_assert();
539 0 : goto cleanup_crt;
540 : }
541 :
542 0 : ret = gnutls_pubkey_import_x509(key, xcrt, 0);
543 0 : if (ret < 0) {
544 0 : gnutls_assert();
545 0 : goto cleanup_crt;
546 : }
547 :
548 0 : ret = gnutls_x509_crt_get_key_usage(xcrt, &key->key_usage, NULL);
549 0 : if (ret < 0)
550 0 : key->key_usage = 0;
551 :
552 : ret = 0;
553 0 : cleanup_crt:
554 0 : gnutls_x509_crt_deinit(xcrt);
555 0 : return ret;
556 : }
557 :
558 96 : key->key_usage = obj->key_usage;
559 :
560 96 : switch (obj->pk_algorithm) {
561 58 : case GNUTLS_PK_RSA:
562 : case GNUTLS_PK_RSA_PSS:
563 58 : ret = gnutls_pubkey_import_rsa_raw(key, &obj->pubkey[0],
564 58 : &obj->pubkey[1]);
565 58 : break;
566 8 : case GNUTLS_PK_DSA:
567 8 : ret = gnutls_pubkey_import_dsa_raw(key, &obj->pubkey[0],
568 8 : &obj->pubkey[1],
569 8 : &obj->pubkey[2],
570 8 : &obj->pubkey[3]);
571 8 : break;
572 27 : case GNUTLS_PK_EC:
573 27 : ret = gnutls_pubkey_import_ecc_x962(key, &obj->pubkey[0],
574 27 : &obj->pubkey[1]);
575 27 : break;
576 3 : case GNUTLS_PK_EDDSA_ED25519:
577 3 : ret = gnutls_pubkey_import_ecc_eddsa(key, &obj->pubkey[0],
578 3 : &obj->pubkey[1]);
579 3 : break;
580 0 : default:
581 0 : gnutls_assert();
582 : return GNUTLS_E_UNIMPLEMENTED_FEATURE;
583 : }
584 :
585 96 : if (ret < 0) {
586 0 : gnutls_assert();
587 0 : return ret;
588 : }
589 :
590 : return 0;
591 : }
592 :
593 : #endif /* ENABLE_PKCS11 */
594 :
595 : /**
596 : * gnutls_pubkey_export:
597 : * @key: Holds the certificate
598 : * @format: the format of output params. One of PEM or DER.
599 : * @output_data: will contain a certificate PEM or DER encoded
600 : * @output_data_size: holds the size of output_data (and will be
601 : * replaced by the actual size of parameters)
602 : *
603 : * This function will export the public key to DER or PEM format.
604 : * The contents of the exported data is the SubjectPublicKeyInfo
605 : * X.509 structure.
606 : *
607 : * If the buffer provided is not long enough to hold the output, then
608 : * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
609 : * be returned.
610 : *
611 : * If the structure is PEM encoded, it will have a header
612 : * of "BEGIN CERTIFICATE".
613 : *
614 : * Returns: In case of failure a negative error code will be
615 : * returned, and 0 on success.
616 : *
617 : * Since: 2.12.0
618 : **/
619 : int
620 18 : gnutls_pubkey_export(gnutls_pubkey_t key,
621 : gnutls_x509_crt_fmt_t format, void *output_data,
622 : size_t * output_data_size)
623 : {
624 18 : int result;
625 18 : ASN1_TYPE spk = ASN1_TYPE_EMPTY;
626 :
627 18 : if (key == NULL) {
628 0 : gnutls_assert();
629 0 : return GNUTLS_E_INVALID_REQUEST;
630 : }
631 :
632 18 : if ((result = asn1_create_element
633 : (_gnutls_get_pkix(), "PKIX1.SubjectPublicKeyInfo", &spk))
634 : != ASN1_SUCCESS) {
635 0 : gnutls_assert();
636 0 : return _gnutls_asn2err(result);
637 : }
638 :
639 18 : result =
640 36 : _gnutls_x509_encode_and_copy_PKI_params(spk, "",
641 18 : &key->params);
642 18 : if (result < 0) {
643 0 : gnutls_assert();
644 0 : goto cleanup;
645 : }
646 :
647 18 : result = _gnutls_x509_export_int_named(spk, "",
648 : format, PEM_PK,
649 : output_data,
650 : output_data_size);
651 18 : if (result < 0) {
652 0 : gnutls_assert();
653 0 : goto cleanup;
654 : }
655 :
656 : result = 0;
657 :
658 18 : cleanup:
659 18 : asn1_delete_structure(&spk);
660 :
661 18 : return result;
662 : }
663 :
664 : /**
665 : * gnutls_pubkey_export2:
666 : * @key: Holds the certificate
667 : * @format: the format of output params. One of PEM or DER.
668 : * @out: will contain a certificate PEM or DER encoded
669 : *
670 : * This function will export the public key to DER or PEM format.
671 : * The contents of the exported data is the SubjectPublicKeyInfo
672 : * X.509 structure.
673 : *
674 : * The output buffer will be allocated using gnutls_malloc().
675 : *
676 : * If the structure is PEM encoded, it will have a header
677 : * of "BEGIN CERTIFICATE".
678 : *
679 : * Returns: In case of failure a negative error code will be
680 : * returned, and 0 on success.
681 : *
682 : * Since: 3.1.3
683 : **/
684 : int
685 90 : gnutls_pubkey_export2(gnutls_pubkey_t key,
686 : gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
687 : {
688 90 : int result;
689 90 : ASN1_TYPE spk = ASN1_TYPE_EMPTY;
690 :
691 90 : if (key == NULL) {
692 0 : gnutls_assert();
693 0 : return GNUTLS_E_INVALID_REQUEST;
694 : }
695 :
696 90 : if ((result = asn1_create_element
697 : (_gnutls_get_pkix(), "PKIX1.SubjectPublicKeyInfo", &spk))
698 : != ASN1_SUCCESS) {
699 0 : gnutls_assert();
700 0 : return _gnutls_asn2err(result);
701 : }
702 :
703 90 : result =
704 180 : _gnutls_x509_encode_and_copy_PKI_params(spk, "",
705 90 : &key->params);
706 90 : if (result < 0) {
707 0 : gnutls_assert();
708 0 : goto cleanup;
709 : }
710 :
711 90 : result = _gnutls_x509_export_int_named2(spk, "",
712 : format, PEM_PK,
713 : out);
714 90 : if (result < 0) {
715 0 : gnutls_assert();
716 0 : goto cleanup;
717 : }
718 :
719 : result = 0;
720 :
721 90 : cleanup:
722 90 : asn1_delete_structure(&spk);
723 :
724 90 : return result;
725 : }
726 :
727 : /**
728 : * gnutls_pubkey_get_key_id:
729 : * @key: Holds the public key
730 : * @flags: should be one of the flags from %gnutls_keyid_flags_t
731 : * @output_data: will contain the key ID
732 : * @output_data_size: holds the size of output_data (and will be
733 : * replaced by the actual size of parameters)
734 : *
735 : * This function will return a unique ID that depends on the public
736 : * key parameters. This ID can be used in checking whether a
737 : * certificate corresponds to the given public key.
738 : *
739 : * If the buffer provided is not long enough to hold the output, then
740 : * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
741 : * be returned. The output will normally be a SHA-1 hash output,
742 : * which is 20 bytes.
743 : *
744 : * Returns: In case of failure a negative error code will be
745 : * returned, and 0 on success.
746 : *
747 : * Since: 2.12.0
748 : **/
749 : int
750 24 : gnutls_pubkey_get_key_id(gnutls_pubkey_t key, unsigned int flags,
751 : unsigned char *output_data,
752 : size_t * output_data_size)
753 : {
754 24 : int ret = 0;
755 :
756 24 : if (key == NULL) {
757 0 : gnutls_assert();
758 0 : return GNUTLS_E_INVALID_REQUEST;
759 : }
760 :
761 24 : ret =
762 24 : _gnutls_get_key_id(&key->params,
763 : output_data, output_data_size, flags);
764 24 : if (ret < 0) {
765 0 : gnutls_assert();
766 0 : return ret;
767 : }
768 :
769 : return 0;
770 : }
771 :
772 : /**
773 : * gnutls_pubkey_export_rsa_raw2:
774 : * @key: Holds the certificate
775 : * @m: will hold the modulus (may be %NULL)
776 : * @e: will hold the public exponent (may be %NULL)
777 : * @flags: flags from %gnutls_abstract_export_flags_t
778 : *
779 : * This function will export the RSA public key's parameters found in
780 : * the given structure. The new parameters will be allocated using
781 : * gnutls_malloc() and will be stored in the appropriate datum.
782 : *
783 : * This function allows for %NULL parameters since 3.4.1.
784 : *
785 : * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
786 : *
787 : * Since: 3.6.0
788 : **/
789 : int
790 659 : gnutls_pubkey_export_rsa_raw2(gnutls_pubkey_t key,
791 : gnutls_datum_t * m, gnutls_datum_t * e,
792 : unsigned flags)
793 : {
794 659 : int ret;
795 659 : mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
796 :
797 659 : if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
798 3 : dprint = _gnutls_mpi_dprint;
799 :
800 659 : if (key == NULL) {
801 0 : gnutls_assert();
802 0 : return GNUTLS_E_INVALID_REQUEST;
803 : }
804 :
805 659 : if (!GNUTLS_PK_IS_RSA(key->params.algo)) {
806 0 : gnutls_assert();
807 0 : return GNUTLS_E_INVALID_REQUEST;
808 : }
809 :
810 659 : if (m) {
811 659 : ret = dprint(key->params.params[0], m);
812 659 : if (ret < 0) {
813 0 : gnutls_assert();
814 0 : return ret;
815 : }
816 : }
817 :
818 659 : if (e) {
819 659 : ret = dprint(key->params.params[1], e);
820 659 : if (ret < 0) {
821 0 : gnutls_assert();
822 0 : _gnutls_free_datum(m);
823 0 : return ret;
824 : }
825 : }
826 :
827 : return 0;
828 : }
829 :
830 : /**
831 : * gnutls_pubkey_export_rsa_raw:
832 : * @key: Holds the certificate
833 : * @m: will hold the modulus (may be %NULL)
834 : * @e: will hold the public exponent (may be %NULL)
835 : *
836 : * This function will export the RSA public key's parameters found in
837 : * the given structure. The new parameters will be allocated using
838 : * gnutls_malloc() and will be stored in the appropriate datum.
839 : *
840 : * This function allows for %NULL parameters since 3.4.1.
841 : *
842 : * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
843 : *
844 : * Since: 3.3.0
845 : **/
846 : int
847 654 : gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key,
848 : gnutls_datum_t * m, gnutls_datum_t * e)
849 : {
850 654 : return gnutls_pubkey_export_rsa_raw2(key, m, e, 0);
851 : }
852 :
853 :
854 : /**
855 : * gnutls_pubkey_export_dsa_raw:
856 : * @key: Holds the public key
857 : * @p: will hold the p (may be %NULL)
858 : * @q: will hold the q (may be %NULL)
859 : * @g: will hold the g (may be %NULL)
860 : * @y: will hold the y (may be %NULL)
861 : *
862 : * This function will export the DSA public key's parameters found in
863 : * the given certificate. The new parameters will be allocated using
864 : * gnutls_malloc() and will be stored in the appropriate datum.
865 : *
866 : * This function allows for %NULL parameters since 3.4.1.
867 : *
868 : * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
869 : *
870 : * Since: 3.3.0
871 : **/
872 : int
873 5 : gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key,
874 : gnutls_datum_t * p, gnutls_datum_t * q,
875 : gnutls_datum_t * g, gnutls_datum_t * y)
876 : {
877 5 : return gnutls_pubkey_export_dsa_raw2(key, p, q, g, y, 0);
878 : }
879 :
880 : /**
881 : * gnutls_pubkey_export_dsa_raw2:
882 : * @key: Holds the public key
883 : * @p: will hold the p (may be %NULL)
884 : * @q: will hold the q (may be %NULL)
885 : * @g: will hold the g (may be %NULL)
886 : * @y: will hold the y (may be %NULL)
887 : * @flags: flags from %gnutls_abstract_export_flags_t
888 : *
889 : * This function will export the DSA public key's parameters found in
890 : * the given certificate. The new parameters will be allocated using
891 : * gnutls_malloc() and will be stored in the appropriate datum.
892 : *
893 : * This function allows for %NULL parameters since 3.4.1.
894 : *
895 : * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
896 : *
897 : * Since: 3.6.0
898 : **/
899 : int
900 9 : gnutls_pubkey_export_dsa_raw2(gnutls_pubkey_t key,
901 : gnutls_datum_t * p, gnutls_datum_t * q,
902 : gnutls_datum_t * g, gnutls_datum_t * y,
903 : unsigned flags)
904 : {
905 9 : int ret;
906 9 : mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
907 :
908 9 : if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
909 2 : dprint = _gnutls_mpi_dprint;
910 :
911 9 : if (key == NULL) {
912 0 : gnutls_assert();
913 0 : return GNUTLS_E_INVALID_REQUEST;
914 : }
915 :
916 9 : if (key->params.algo != GNUTLS_PK_DSA) {
917 0 : gnutls_assert();
918 0 : return GNUTLS_E_INVALID_REQUEST;
919 : }
920 :
921 : /* P */
922 9 : if (p) {
923 9 : ret = dprint(key->params.params[0], p);
924 9 : if (ret < 0) {
925 0 : gnutls_assert();
926 0 : return ret;
927 : }
928 : }
929 :
930 : /* Q */
931 9 : if (q) {
932 9 : ret = dprint(key->params.params[1], q);
933 9 : if (ret < 0) {
934 0 : gnutls_assert();
935 0 : _gnutls_free_datum(p);
936 0 : return ret;
937 : }
938 : }
939 :
940 : /* G */
941 9 : if (g) {
942 9 : ret = dprint(key->params.params[2], g);
943 9 : if (ret < 0) {
944 0 : gnutls_assert();
945 0 : _gnutls_free_datum(p);
946 0 : _gnutls_free_datum(q);
947 0 : return ret;
948 : }
949 : }
950 :
951 : /* Y */
952 9 : if (y) {
953 9 : ret = dprint(key->params.params[3], y);
954 9 : if (ret < 0) {
955 0 : gnutls_assert();
956 0 : _gnutls_free_datum(p);
957 0 : _gnutls_free_datum(g);
958 0 : _gnutls_free_datum(q);
959 0 : return ret;
960 : }
961 : }
962 :
963 : return 0;
964 : }
965 :
966 : /**
967 : * gnutls_pubkey_export_ecc_raw:
968 : * @key: Holds the public key
969 : * @curve: will hold the curve (may be %NULL)
970 : * @x: will hold x-coordinate (may be %NULL)
971 : * @y: will hold y-coordinate (may be %NULL)
972 : *
973 : * This function will export the ECC public key's parameters found in
974 : * the given key. The new parameters will be allocated using
975 : * gnutls_malloc() and will be stored in the appropriate datum.
976 : *
977 : * In EdDSA curves the @y parameter will be %NULL and the other parameters
978 : * will be in the native format for the curve.
979 : *
980 : * This function allows for %NULL parameters since 3.4.1.
981 : *
982 : * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
983 : *
984 : * Since: 3.0
985 : **/
986 : int
987 131 : gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key,
988 : gnutls_ecc_curve_t * curve,
989 : gnutls_datum_t * x, gnutls_datum_t * y)
990 : {
991 131 : return gnutls_pubkey_export_ecc_raw2(key, curve, x, y, 0);
992 : }
993 :
994 : /**
995 : * gnutls_pubkey_export_ecc_raw2:
996 : * @key: Holds the public key
997 : * @curve: will hold the curve (may be %NULL)
998 : * @x: will hold x-coordinate (may be %NULL)
999 : * @y: will hold y-coordinate (may be %NULL)
1000 : * @flags: flags from %gnutls_abstract_export_flags_t
1001 : *
1002 : * This function will export the ECC public key's parameters found in
1003 : * the given key. The new parameters will be allocated using
1004 : * gnutls_malloc() and will be stored in the appropriate datum.
1005 : *
1006 : * In EdDSA curves the @y parameter will be %NULL and the other parameters
1007 : * will be in the native format for the curve.
1008 : *
1009 : * This function allows for %NULL parameters since 3.4.1.
1010 : *
1011 : * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1012 : *
1013 : * Since: 3.6.0
1014 : **/
1015 : int
1016 135 : gnutls_pubkey_export_ecc_raw2(gnutls_pubkey_t key,
1017 : gnutls_ecc_curve_t * curve,
1018 : gnutls_datum_t * x, gnutls_datum_t * y,
1019 : unsigned int flags)
1020 : {
1021 135 : int ret;
1022 135 : mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
1023 :
1024 135 : if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
1025 2 : dprint = _gnutls_mpi_dprint;
1026 :
1027 135 : if (key == NULL) {
1028 0 : gnutls_assert();
1029 0 : return GNUTLS_E_INVALID_REQUEST;
1030 : }
1031 :
1032 135 : if (!IS_EC(key->params.algo)) {
1033 0 : gnutls_assert();
1034 0 : return GNUTLS_E_INVALID_REQUEST;
1035 : }
1036 :
1037 135 : if (curve)
1038 135 : *curve = key->params.curve;
1039 :
1040 135 : if (key->params.algo == GNUTLS_PK_EDDSA_ED25519 ||
1041 : key->params.algo == GNUTLS_PK_EDDSA_ED448) {
1042 12 : if (x) {
1043 7 : ret = _gnutls_set_datum(x, key->params.raw_pub.data, key->params.raw_pub.size);
1044 7 : if (ret < 0)
1045 0 : return gnutls_assert_val(ret);
1046 : }
1047 12 : if (y) {
1048 5 : y->data = NULL;
1049 5 : y->size = 0;
1050 : }
1051 12 : return 0;
1052 : }
1053 :
1054 : /* ECDSA */
1055 :
1056 : /* X */
1057 123 : if (x) {
1058 40 : ret = dprint(key->params.params[ECC_X], x);
1059 40 : if (ret < 0) {
1060 0 : gnutls_assert();
1061 0 : return ret;
1062 : }
1063 : }
1064 :
1065 : /* Y */
1066 123 : if (y) {
1067 40 : ret = dprint(key->params.params[ECC_Y], y);
1068 40 : if (ret < 0) {
1069 0 : gnutls_assert();
1070 0 : _gnutls_free_datum(x);
1071 0 : return ret;
1072 : }
1073 : }
1074 :
1075 : return 0;
1076 : }
1077 :
1078 : /**
1079 : * gnutls_pubkey_export_ecc_x962:
1080 : * @key: Holds the public key
1081 : * @parameters: DER encoding of an ANSI X9.62 parameters
1082 : * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1083 : *
1084 : * This function will export the ECC public key's parameters found in
1085 : * the given certificate. The new parameters will be allocated using
1086 : * gnutls_malloc() and will be stored in the appropriate datum.
1087 : *
1088 : * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1089 : *
1090 : * Since: 3.3.0
1091 : **/
1092 3 : int gnutls_pubkey_export_ecc_x962(gnutls_pubkey_t key,
1093 : gnutls_datum_t * parameters,
1094 : gnutls_datum_t * ecpoint)
1095 : {
1096 3 : int ret;
1097 3 : gnutls_datum_t raw_point = {NULL,0};
1098 :
1099 3 : if (key == NULL || key->params.algo != GNUTLS_PK_EC)
1100 1 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1101 :
1102 2 : ret = _gnutls_x509_write_ecc_pubkey(&key->params, &raw_point);
1103 2 : if (ret < 0)
1104 0 : return gnutls_assert_val(ret);
1105 :
1106 4 : ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
1107 2 : raw_point.data, raw_point.size, ecpoint);
1108 2 : if (ret < 0) {
1109 0 : gnutls_assert();
1110 0 : goto cleanup;
1111 : }
1112 :
1113 2 : ret = _gnutls_x509_write_ecc_params(key->params.curve, parameters);
1114 2 : if (ret < 0) {
1115 0 : _gnutls_free_datum(ecpoint);
1116 0 : gnutls_assert();
1117 0 : goto cleanup;
1118 : }
1119 :
1120 : ret = 0;
1121 2 : cleanup:
1122 2 : gnutls_free(raw_point.data);
1123 2 : return ret;
1124 : }
1125 :
1126 : /**
1127 : * gnutls_pubkey_export_gost_raw2:
1128 : * @key: Holds the public key
1129 : * @curve: will hold the curve (may be %NULL)
1130 : * @digest: will hold the curve (may be %NULL)
1131 : * @paramset: will hold the parameters id (may be %NULL)
1132 : * @x: will hold the x-coordinate (may be %NULL)
1133 : * @y: will hold the y-coordinate (may be %NULL)
1134 : * @flags: flags from %gnutls_abstract_export_flags_t
1135 : *
1136 : * This function will export the GOST public key's parameters found in
1137 : * the given key. The new parameters will be allocated using
1138 : * gnutls_malloc() and will be stored in the appropriate datum.
1139 : *
1140 : * Note: parameters will be stored with least significant byte first. On
1141 : * version 3.6.3 this was incorrectly returned in big-endian format.
1142 : *
1143 : * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1144 : *
1145 : * Since: 3.6.3
1146 : **/
1147 : int
1148 50 : gnutls_pubkey_export_gost_raw2(gnutls_pubkey_t key,
1149 : gnutls_ecc_curve_t * curve,
1150 : gnutls_digest_algorithm_t * digest,
1151 : gnutls_gost_paramset_t * paramset,
1152 : gnutls_datum_t * x, gnutls_datum_t * y,
1153 : unsigned int flags)
1154 : {
1155 50 : int ret;
1156 :
1157 50 : mpi_dprint_func dprint = _gnutls_mpi_dprint_le;
1158 :
1159 50 : if (key == NULL) {
1160 0 : gnutls_assert();
1161 0 : return GNUTLS_E_INVALID_REQUEST;
1162 : }
1163 :
1164 50 : if (key->params.algo != GNUTLS_PK_GOST_01 &&
1165 50 : key->params.algo != GNUTLS_PK_GOST_12_256 &&
1166 : key->params.algo != GNUTLS_PK_GOST_12_512) {
1167 0 : gnutls_assert();
1168 0 : return GNUTLS_E_INVALID_REQUEST;
1169 : }
1170 :
1171 50 : if (curve)
1172 50 : *curve = key->params.curve;
1173 :
1174 50 : if (digest)
1175 26 : *digest = _gnutls_gost_digest(key->params.algo);
1176 :
1177 50 : if (paramset)
1178 26 : *paramset = key->params.gost_params;
1179 :
1180 : /* X */
1181 50 : if (x) {
1182 26 : ret = dprint(key->params.params[GOST_X], x);
1183 26 : if (ret < 0) {
1184 0 : gnutls_assert();
1185 0 : return ret;
1186 : }
1187 : }
1188 :
1189 : /* Y */
1190 50 : if (y) {
1191 26 : ret = dprint(key->params.params[GOST_Y], y);
1192 26 : if (ret < 0) {
1193 0 : gnutls_assert();
1194 0 : _gnutls_free_datum(x);
1195 0 : return ret;
1196 : }
1197 : }
1198 :
1199 : return 0;
1200 : }
1201 :
1202 : /**
1203 : * gnutls_pubkey_import:
1204 : * @key: The public key.
1205 : * @data: The DER or PEM encoded certificate.
1206 : * @format: One of DER or PEM
1207 : *
1208 : * This function will import the provided public key in
1209 : * a SubjectPublicKeyInfo X.509 structure to a native
1210 : * %gnutls_pubkey_t type. The output will be stored
1211 : * in @key. If the public key is PEM encoded it should have a header
1212 : * of "PUBLIC KEY".
1213 : *
1214 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1215 : * negative error value.
1216 : *
1217 : * Since: 2.12.0
1218 : **/
1219 : int
1220 139 : gnutls_pubkey_import(gnutls_pubkey_t key,
1221 : const gnutls_datum_t * data,
1222 : gnutls_x509_crt_fmt_t format)
1223 : {
1224 139 : int result = 0, need_free = 0;
1225 139 : gnutls_datum_t _data;
1226 139 : ASN1_TYPE spk;
1227 :
1228 139 : if (key == NULL) {
1229 0 : gnutls_assert();
1230 0 : return GNUTLS_E_INVALID_REQUEST;
1231 : }
1232 :
1233 139 : _data.data = data->data;
1234 139 : _data.size = data->size;
1235 :
1236 : /* If the Certificate is in PEM format then decode it
1237 : */
1238 139 : if (format == GNUTLS_X509_FMT_PEM) {
1239 : /* Try the first header */
1240 69 : result =
1241 138 : _gnutls_fbase64_decode(PEM_PK, data->data,
1242 69 : data->size, &_data);
1243 :
1244 69 : if (result < 0) {
1245 1 : gnutls_assert();
1246 1 : return result;
1247 : }
1248 :
1249 : need_free = 1;
1250 : }
1251 :
1252 138 : if ((result = asn1_create_element
1253 : (_gnutls_get_pkix(), "PKIX1.SubjectPublicKeyInfo", &spk))
1254 : != ASN1_SUCCESS) {
1255 0 : gnutls_assert();
1256 0 : result = _gnutls_asn2err(result);
1257 0 : goto cleanup;
1258 : }
1259 :
1260 138 : result = _asn1_strict_der_decode(&spk, _data.data, _data.size, NULL);
1261 138 : if (result != ASN1_SUCCESS) {
1262 0 : gnutls_assert();
1263 0 : result = _gnutls_asn2err(result);
1264 0 : goto cleanup;
1265 : }
1266 :
1267 138 : result = _gnutls_get_asn_mpis(spk, "", &key->params);
1268 138 : if (result < 0) {
1269 0 : gnutls_assert();
1270 0 : goto cleanup;
1271 : }
1272 :
1273 138 : key->bits = pubkey_to_bits(&key->params);
1274 138 : result = 0;
1275 :
1276 138 : cleanup:
1277 138 : asn1_delete_structure(&spk);
1278 :
1279 138 : if (need_free)
1280 68 : _gnutls_free_datum(&_data);
1281 : return result;
1282 : }
1283 :
1284 : /**
1285 : * gnutls_x509_crt_set_pubkey:
1286 : * @crt: should contain a #gnutls_x509_crt_t type
1287 : * @key: holds a public key
1288 : *
1289 : * This function will set the public parameters from the given public
1290 : * key to the certificate. The @key can be deallocated after that.
1291 : *
1292 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1293 : * negative error value.
1294 : *
1295 : * Since: 2.12.0
1296 : **/
1297 87 : int gnutls_x509_crt_set_pubkey(gnutls_x509_crt_t crt, gnutls_pubkey_t key)
1298 : {
1299 87 : int result;
1300 :
1301 87 : if (crt == NULL) {
1302 0 : gnutls_assert();
1303 0 : return GNUTLS_E_INVALID_REQUEST;
1304 : }
1305 :
1306 174 : result = _gnutls_x509_encode_and_copy_PKI_params(crt->cert,
1307 : "tbsCertificate.subjectPublicKeyInfo",
1308 87 : &key->params);
1309 :
1310 87 : if (result < 0) {
1311 0 : gnutls_assert();
1312 0 : return result;
1313 : }
1314 :
1315 87 : if (key->key_usage)
1316 0 : gnutls_x509_crt_set_key_usage(crt, key->key_usage);
1317 :
1318 : return 0;
1319 : }
1320 :
1321 : /**
1322 : * gnutls_x509_crq_set_pubkey:
1323 : * @crq: should contain a #gnutls_x509_crq_t type
1324 : * @key: holds a public key
1325 : *
1326 : * This function will set the public parameters from the given public
1327 : * key to the request. The @key can be deallocated after that.
1328 : *
1329 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1330 : * negative error value.
1331 : *
1332 : * Since: 2.12.0
1333 : **/
1334 6 : int gnutls_x509_crq_set_pubkey(gnutls_x509_crq_t crq, gnutls_pubkey_t key)
1335 : {
1336 6 : int result;
1337 :
1338 6 : if (crq == NULL) {
1339 0 : gnutls_assert();
1340 0 : return GNUTLS_E_INVALID_REQUEST;
1341 : }
1342 :
1343 12 : result = _gnutls_x509_encode_and_copy_PKI_params
1344 : (crq->crq,
1345 : "certificationRequestInfo.subjectPKInfo",
1346 6 : &key->params);
1347 :
1348 6 : if (result < 0) {
1349 0 : gnutls_assert();
1350 0 : return result;
1351 : }
1352 :
1353 6 : if (key->key_usage)
1354 0 : gnutls_x509_crq_set_key_usage(crq, key->key_usage);
1355 :
1356 : return 0;
1357 : }
1358 :
1359 : /**
1360 : * gnutls_pubkey_set_key_usage:
1361 : * @key: a certificate of type #gnutls_x509_crt_t
1362 : * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
1363 : *
1364 : * This function will set the key usage flags of the public key. This
1365 : * is only useful if the key is to be exported to a certificate or
1366 : * certificate request.
1367 : *
1368 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1369 : * negative error value.
1370 : *
1371 : * Since: 2.12.0
1372 : **/
1373 0 : int gnutls_pubkey_set_key_usage(gnutls_pubkey_t key, unsigned int usage)
1374 : {
1375 0 : key->key_usage = usage;
1376 :
1377 0 : return 0;
1378 : }
1379 :
1380 : #ifdef ENABLE_PKCS11
1381 :
1382 : #if 0
1383 : /**
1384 : * gnutls_pubkey_import_pkcs11_url:
1385 : * @key: A key of type #gnutls_pubkey_t
1386 : * @url: A PKCS 11 url
1387 : * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1388 : *
1389 : * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
1390 : * structure.
1391 : *
1392 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1393 : * negative error value.
1394 : *
1395 : * Since: 2.12.0
1396 : **/
1397 : int
1398 : gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url,
1399 : unsigned int flags)
1400 : {
1401 : int x;
1402 : }
1403 : #endif
1404 :
1405 : static int
1406 23 : _gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url,
1407 : unsigned int flags)
1408 : {
1409 23 : gnutls_pkcs11_obj_t pcrt;
1410 23 : int ret;
1411 :
1412 23 : ret = gnutls_pkcs11_obj_init(&pcrt);
1413 23 : if (ret < 0) {
1414 0 : gnutls_assert();
1415 0 : return ret;
1416 : }
1417 :
1418 23 : if (key->pin.cb)
1419 0 : gnutls_pkcs11_obj_set_pin_function(pcrt, key->pin.cb,
1420 : key->pin.data);
1421 :
1422 23 : ret = gnutls_pkcs11_obj_import_url(pcrt, url, flags|GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PUBKEY);
1423 23 : if (ret < 0) {
1424 5 : gnutls_assert();
1425 5 : goto cleanup;
1426 : }
1427 :
1428 18 : ret = gnutls_pubkey_import_pkcs11(key, pcrt, flags);
1429 18 : if (ret < 0) {
1430 0 : gnutls_assert();
1431 0 : goto cleanup;
1432 : }
1433 :
1434 : ret = 0;
1435 23 : cleanup:
1436 :
1437 23 : gnutls_pkcs11_obj_deinit(pcrt);
1438 :
1439 23 : return ret;
1440 : }
1441 :
1442 : #endif /* ENABLE_PKCS11 */
1443 :
1444 : /**
1445 : * gnutls_pubkey_import_url:
1446 : * @key: A key of type #gnutls_pubkey_t
1447 : * @url: A PKCS 11 url
1448 : * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1449 : *
1450 : * This function will import a public key from the provided URL.
1451 : *
1452 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1453 : * negative error value.
1454 : *
1455 : * Since: 3.1.0
1456 : **/
1457 : int
1458 23 : gnutls_pubkey_import_url(gnutls_pubkey_t key, const char *url,
1459 : unsigned int flags)
1460 : {
1461 23 : unsigned i;
1462 :
1463 23 : for (i=0;i<_gnutls_custom_urls_size;i++) {
1464 0 : if (strncmp(url, _gnutls_custom_urls[i].name, _gnutls_custom_urls[i].name_size) == 0) {
1465 0 : if (_gnutls_custom_urls[i].import_pubkey)
1466 0 : return _gnutls_custom_urls[i].import_pubkey(key, url, flags);
1467 : }
1468 : }
1469 :
1470 23 : if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0)
1471 : #ifdef ENABLE_PKCS11
1472 23 : return _gnutls_pubkey_import_pkcs11_url(key, url, flags);
1473 : #else
1474 : return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1475 : #endif
1476 :
1477 0 : if (strncmp(url, TPMKEY_URL, TPMKEY_URL_SIZE) == 0)
1478 : #ifdef HAVE_TROUSERS
1479 0 : return gnutls_pubkey_import_tpm_url(key, url, NULL, 0);
1480 : #else
1481 : return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1482 : #endif
1483 :
1484 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1485 : }
1486 :
1487 : /**
1488 : * gnutls_pubkey_import_rsa_raw:
1489 : * @key: The key
1490 : * @m: holds the modulus
1491 : * @e: holds the public exponent
1492 : *
1493 : * This function will replace the parameters in the given structure.
1494 : * The new parameters should be stored in the appropriate
1495 : * gnutls_datum.
1496 : *
1497 : * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
1498 : *
1499 : * Since: 2.12.0
1500 : **/
1501 : int
1502 67 : gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key,
1503 : const gnutls_datum_t * m,
1504 : const gnutls_datum_t * e)
1505 : {
1506 67 : if (key == NULL) {
1507 0 : gnutls_assert();
1508 0 : return GNUTLS_E_INVALID_REQUEST;
1509 : }
1510 :
1511 67 : gnutls_pk_params_release(&key->params);
1512 67 : gnutls_pk_params_init(&key->params);
1513 :
1514 67 : if (_gnutls_mpi_init_scan_nz(&key->params.params[0], m->data, m->size)) {
1515 0 : gnutls_assert();
1516 0 : return GNUTLS_E_MPI_SCAN_FAILED;
1517 : }
1518 :
1519 67 : if (_gnutls_mpi_init_scan_nz(&key->params.params[1], e->data, e->size)) {
1520 0 : gnutls_assert();
1521 0 : _gnutls_mpi_release(&key->params.params[0]);
1522 0 : return GNUTLS_E_MPI_SCAN_FAILED;
1523 : }
1524 :
1525 67 : key->params.params_nr = RSA_PUBLIC_PARAMS;
1526 67 : key->params.algo = GNUTLS_PK_RSA;
1527 67 : key->bits = pubkey_to_bits(&key->params);
1528 :
1529 67 : return 0;
1530 : }
1531 :
1532 : /**
1533 : * gnutls_pubkey_import_ecc_raw:
1534 : * @key: The structure to store the parsed key
1535 : * @curve: holds the curve
1536 : * @x: holds the x-coordinate
1537 : * @y: holds the y-coordinate
1538 : *
1539 : * This function will convert the given elliptic curve parameters to a
1540 : * #gnutls_pubkey_t. The output will be stored in @key.
1541 : *
1542 : * In EdDSA curves the @y parameter should be %NULL and the @x parameter must
1543 : * be the value in the native format for the curve.
1544 : *
1545 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1546 : * negative error value.
1547 : *
1548 : * Since: 3.0
1549 : **/
1550 : int
1551 7 : gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key,
1552 : gnutls_ecc_curve_t curve,
1553 : const gnutls_datum_t * x,
1554 : const gnutls_datum_t * y)
1555 : {
1556 7 : int ret;
1557 :
1558 7 : if (key == NULL || x == NULL) {
1559 0 : gnutls_assert();
1560 0 : return GNUTLS_E_INVALID_REQUEST;
1561 : }
1562 :
1563 7 : gnutls_pk_params_release(&key->params);
1564 7 : gnutls_pk_params_init(&key->params);
1565 :
1566 7 : if (curve_is_eddsa(curve)) {
1567 6 : unsigned size = gnutls_ecc_curve_get_size(curve);
1568 6 : if (x->size != size) {
1569 1 : ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1570 1 : goto cleanup;
1571 : }
1572 :
1573 5 : ret = _gnutls_set_datum(&key->params.raw_pub, x->data, x->size);
1574 5 : if (ret < 0) {
1575 0 : gnutls_assert();
1576 0 : goto cleanup;
1577 : }
1578 :
1579 5 : switch (curve) {
1580 5 : case GNUTLS_ECC_CURVE_ED25519:
1581 5 : key->params.algo = GNUTLS_PK_EDDSA_ED25519;
1582 5 : break;
1583 0 : case GNUTLS_ECC_CURVE_ED448:
1584 0 : key->params.algo = GNUTLS_PK_EDDSA_ED448;
1585 0 : break;
1586 : default:
1587 : break;
1588 : }
1589 5 : key->params.curve = curve;
1590 5 : key->bits = pubkey_to_bits(&key->params);
1591 :
1592 5 : return 0;
1593 : }
1594 :
1595 : /* ECDSA */
1596 1 : if (y == NULL) {
1597 0 : gnutls_assert();
1598 0 : return GNUTLS_E_INVALID_REQUEST;
1599 : }
1600 :
1601 1 : key->params.curve = curve;
1602 :
1603 1 : if (_gnutls_mpi_init_scan_nz
1604 1 : (&key->params.params[ECC_X], x->data, x->size)) {
1605 0 : gnutls_assert();
1606 0 : ret = GNUTLS_E_MPI_SCAN_FAILED;
1607 0 : goto cleanup;
1608 : }
1609 1 : key->params.params_nr++;
1610 :
1611 1 : if (_gnutls_mpi_init_scan_nz
1612 1 : (&key->params.params[ECC_Y], y->data, y->size)) {
1613 0 : gnutls_assert();
1614 0 : ret = GNUTLS_E_MPI_SCAN_FAILED;
1615 0 : goto cleanup;
1616 : }
1617 1 : key->params.params_nr++;
1618 1 : key->params.algo = GNUTLS_PK_ECDSA;
1619 1 : key->bits = pubkey_to_bits(&key->params);
1620 :
1621 1 : return 0;
1622 :
1623 1 : cleanup:
1624 1 : gnutls_pk_params_release(&key->params);
1625 1 : return ret;
1626 : }
1627 :
1628 : /**
1629 : * gnutls_pubkey_import_ecc_x962:
1630 : * @key: The structure to store the parsed key
1631 : * @parameters: DER encoding of an ANSI X9.62 parameters
1632 : * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1633 : *
1634 : * This function will convert the given elliptic curve parameters to a
1635 : * #gnutls_pubkey_t. The output will be stored in @key.
1636 : *
1637 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1638 : * negative error value.
1639 : *
1640 : * Since: 3.0
1641 : **/
1642 : int
1643 28 : gnutls_pubkey_import_ecc_x962(gnutls_pubkey_t key,
1644 : const gnutls_datum_t * parameters,
1645 : const gnutls_datum_t * ecpoint)
1646 : {
1647 28 : int ret;
1648 28 : gnutls_datum_t raw_point = {NULL,0};
1649 :
1650 28 : if (key == NULL) {
1651 0 : gnutls_assert();
1652 0 : return GNUTLS_E_INVALID_REQUEST;
1653 : }
1654 :
1655 28 : gnutls_pk_params_release(&key->params);
1656 28 : gnutls_pk_params_init(&key->params);
1657 :
1658 28 : key->params.params_nr = 0;
1659 :
1660 28 : ret =
1661 56 : _gnutls_x509_read_ecc_params(parameters->data,
1662 28 : parameters->size, &key->params.curve);
1663 28 : if (ret < 0) {
1664 0 : gnutls_assert();
1665 0 : goto cleanup;
1666 : }
1667 :
1668 56 : ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING,
1669 28 : ecpoint->data, ecpoint->size, &raw_point, 0);
1670 28 : if (ret < 0) {
1671 0 : gnutls_assert();
1672 0 : goto cleanup;
1673 : }
1674 :
1675 28 : ret = _gnutls_ecc_ansi_x962_import(raw_point.data, raw_point.size,
1676 : &key->params.params[ECC_X],
1677 : &key->params.params[ECC_Y]);
1678 28 : if (ret < 0) {
1679 0 : gnutls_assert();
1680 0 : goto cleanup;
1681 : }
1682 28 : key->params.params_nr += 2;
1683 28 : key->params.algo = GNUTLS_PK_EC;
1684 :
1685 28 : gnutls_free(raw_point.data);
1686 28 : return 0;
1687 :
1688 0 : cleanup:
1689 0 : gnutls_pk_params_release(&key->params);
1690 0 : gnutls_free(raw_point.data);
1691 0 : return ret;
1692 : }
1693 :
1694 : /**
1695 : * gnutls_pubkey_import_gost_raw:
1696 : * @key: The structure to store the parsed key
1697 : * @curve: holds the curve
1698 : * @digest: holds the digest
1699 : * @paramset: holds the parameters id
1700 : * @x: holds the x-coordinate
1701 : * @y: holds the y-coordinate
1702 : *
1703 : * This function will convert the given GOST public key's parameters to a
1704 : * #gnutls_pubkey_t. The output will be stored in @key. @digest should be
1705 : * one of GNUTLS_DIG_GOSR_94, GNUTLS_DIG_STREEBOG_256 or
1706 : * GNUTLS_DIG_STREEBOG_512. If @paramset is set to GNUTLS_GOST_PARAMSET_UNKNOWN
1707 : * default one will be selected depending on @digest.
1708 : *
1709 : * Note: parameters should be stored with least significant byte first. On
1710 : * version 3.6.3 big-endian format was used incorrectly.
1711 : *
1712 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1713 : * negative error value.
1714 : *
1715 : * Since: 3.6.3
1716 : **/
1717 : int
1718 0 : gnutls_pubkey_import_gost_raw(gnutls_pubkey_t key,
1719 : gnutls_ecc_curve_t curve,
1720 : gnutls_digest_algorithm_t digest,
1721 : gnutls_gost_paramset_t paramset,
1722 : const gnutls_datum_t * x,
1723 : const gnutls_datum_t * y)
1724 : {
1725 0 : int ret;
1726 0 : gnutls_pk_algorithm_t pk_algo;
1727 :
1728 0 : if (key == NULL) {
1729 0 : gnutls_assert();
1730 0 : return GNUTLS_E_INVALID_REQUEST;
1731 : }
1732 :
1733 0 : pk_algo = _gnutls_digest_gost(digest);
1734 0 : if (pk_algo == GNUTLS_PK_UNKNOWN)
1735 : return GNUTLS_E_ILLEGAL_PARAMETER;
1736 :
1737 0 : if (paramset == GNUTLS_GOST_PARAMSET_UNKNOWN)
1738 0 : paramset = _gnutls_gost_paramset_default(pk_algo);
1739 :
1740 0 : gnutls_pk_params_release(&key->params);
1741 0 : gnutls_pk_params_init(&key->params);
1742 :
1743 0 : key->params.curve = curve;
1744 0 : key->params.gost_params = paramset;
1745 :
1746 0 : if (_gnutls_mpi_init_scan_le
1747 0 : (&key->params.params[GOST_X], x->data, x->size)) {
1748 0 : gnutls_assert();
1749 0 : ret = GNUTLS_E_MPI_SCAN_FAILED;
1750 0 : goto cleanup;
1751 : }
1752 0 : key->params.params_nr++;
1753 :
1754 0 : if (_gnutls_mpi_init_scan_le
1755 0 : (&key->params.params[GOST_Y], y->data, y->size)) {
1756 0 : gnutls_assert();
1757 0 : ret = GNUTLS_E_MPI_SCAN_FAILED;
1758 0 : goto cleanup;
1759 : }
1760 0 : key->params.params_nr++;
1761 0 : key->params.algo = pk_algo;
1762 :
1763 0 : return 0;
1764 :
1765 0 : cleanup:
1766 0 : gnutls_pk_params_release(&key->params);
1767 0 : return ret;
1768 : }
1769 :
1770 : /**
1771 : * gnutls_pubkey_import_dsa_raw:
1772 : * @key: The structure to store the parsed key
1773 : * @p: holds the p
1774 : * @q: holds the q
1775 : * @g: holds the g
1776 : * @y: holds the y
1777 : *
1778 : * This function will convert the given DSA raw parameters to the
1779 : * native #gnutls_pubkey_t format. The output will be stored
1780 : * in @key.
1781 : *
1782 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1783 : * negative error value.
1784 : *
1785 : * Since: 2.12.0
1786 : **/
1787 : int
1788 9 : gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key,
1789 : const gnutls_datum_t * p,
1790 : const gnutls_datum_t * q,
1791 : const gnutls_datum_t * g,
1792 : const gnutls_datum_t * y)
1793 : {
1794 9 : size_t siz = 0;
1795 :
1796 9 : if (key == NULL) {
1797 0 : gnutls_assert();
1798 0 : return GNUTLS_E_INVALID_REQUEST;
1799 : }
1800 :
1801 9 : gnutls_pk_params_release(&key->params);
1802 9 : gnutls_pk_params_init(&key->params);
1803 :
1804 9 : siz = p->size;
1805 9 : if (_gnutls_mpi_init_scan_nz(&key->params.params[0], p->data, siz)) {
1806 0 : gnutls_assert();
1807 0 : return GNUTLS_E_MPI_SCAN_FAILED;
1808 : }
1809 :
1810 9 : siz = q->size;
1811 9 : if (_gnutls_mpi_init_scan_nz(&key->params.params[1], q->data, siz)) {
1812 0 : gnutls_assert();
1813 0 : _gnutls_mpi_release(&key->params.params[0]);
1814 0 : return GNUTLS_E_MPI_SCAN_FAILED;
1815 : }
1816 :
1817 9 : siz = g->size;
1818 9 : if (_gnutls_mpi_init_scan_nz(&key->params.params[2], g->data, siz)) {
1819 0 : gnutls_assert();
1820 0 : _gnutls_mpi_release(&key->params.params[1]);
1821 0 : _gnutls_mpi_release(&key->params.params[0]);
1822 0 : return GNUTLS_E_MPI_SCAN_FAILED;
1823 : }
1824 :
1825 9 : siz = y->size;
1826 9 : if (_gnutls_mpi_init_scan_nz(&key->params.params[3], y->data, siz)) {
1827 0 : gnutls_assert();
1828 0 : _gnutls_mpi_release(&key->params.params[2]);
1829 0 : _gnutls_mpi_release(&key->params.params[1]);
1830 0 : _gnutls_mpi_release(&key->params.params[0]);
1831 0 : return GNUTLS_E_MPI_SCAN_FAILED;
1832 : }
1833 :
1834 9 : key->params.params_nr = DSA_PUBLIC_PARAMS;
1835 9 : key->params.algo = GNUTLS_PK_DSA;
1836 9 : key->bits = pubkey_to_bits(&key->params);
1837 :
1838 9 : return 0;
1839 :
1840 : }
1841 :
1842 : /* Updates the gnutls_x509_spki_st parameters based on the signature
1843 : * information, and reports any incompatibilities between the existing
1844 : * parameters (if any) with the signature algorithm */
1845 : static
1846 15550 : int fixup_spki_params(const gnutls_pk_params_st *key_params, const gnutls_sign_entry_st *se,
1847 : const mac_entry_st *me, gnutls_x509_spki_st *params)
1848 : {
1849 15550 : unsigned bits;
1850 :
1851 15550 : if (se->pk != key_params->algo) {
1852 612 : if (!sign_supports_priv_pk_algorithm(se, key_params->algo)) {
1853 6 : _gnutls_debug_log("have key: %s/%d, with sign %s/%d\n",
1854 : gnutls_pk_get_name(key_params->algo), key_params->algo,
1855 : se->name, se->id);
1856 6 : return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
1857 : }
1858 : }
1859 :
1860 15544 : if (params->pk == GNUTLS_PK_RSA_PSS) {
1861 1360 : int ret;
1862 1360 : if (!GNUTLS_PK_IS_RSA(key_params->algo))
1863 0 : return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
1864 :
1865 : /* The requested sign algorithm is RSA-PSS, while the
1866 : * pubkey doesn't include parameter information. Fill
1867 : * it with the same way as gnutls_privkey_sign*. */
1868 1360 : if (key_params->algo == GNUTLS_PK_RSA || params->rsa_pss_dig == 0) {
1869 1198 : bits = pubkey_to_bits(key_params);
1870 1198 : params->rsa_pss_dig = se->hash;
1871 1198 : ret = _gnutls_find_rsa_pss_salt_size(bits, me, 0);
1872 1198 : if (ret < 0)
1873 0 : return gnutls_assert_val(ret);
1874 :
1875 1198 : params->salt_size = ret;
1876 : }
1877 :
1878 1360 : if (params->rsa_pss_dig != se->hash)
1879 0 : return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
1880 : }
1881 :
1882 : return 0;
1883 : }
1884 :
1885 : /**
1886 : * gnutls_pubkey_verify_data2:
1887 : * @pubkey: Holds the public key
1888 : * @algo: The signature algorithm used
1889 : * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
1890 : * @data: holds the signed data
1891 : * @signature: contains the signature
1892 : *
1893 : * This function will verify the given signed data, using the
1894 : * parameters from the certificate.
1895 : *
1896 : * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1897 : * is returned, and zero or positive code on success. For known to be insecure
1898 : * signatures this function will return %GNUTLS_E_INSUFFICIENT_SECURITY unless
1899 : * the flag %GNUTLS_VERIFY_ALLOW_BROKEN is specified.
1900 : *
1901 : * Since: 3.0
1902 : **/
1903 : int
1904 9453 : gnutls_pubkey_verify_data2(gnutls_pubkey_t pubkey,
1905 : gnutls_sign_algorithm_t algo,
1906 : unsigned int flags,
1907 : const gnutls_datum_t * data,
1908 : const gnutls_datum_t * signature)
1909 : {
1910 9453 : int ret;
1911 9453 : const mac_entry_st *me;
1912 9453 : gnutls_x509_spki_st params;
1913 9453 : const gnutls_sign_entry_st *se;
1914 :
1915 9453 : if (pubkey == NULL) {
1916 0 : gnutls_assert();
1917 0 : return GNUTLS_E_INVALID_REQUEST;
1918 : }
1919 :
1920 9453 : if (flags & GNUTLS_VERIFY_USE_TLS1_RSA)
1921 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1922 :
1923 9453 : memcpy(¶ms, &pubkey->params.spki, sizeof(gnutls_x509_spki_st));
1924 :
1925 9453 : se = _gnutls_sign_to_entry(algo);
1926 9453 : if (se == NULL)
1927 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1928 :
1929 9453 : ret = pubkey_supports_sig(pubkey, se);
1930 9453 : if (ret < 0)
1931 0 : return gnutls_assert_val(ret);
1932 :
1933 9453 : params.pk = se->pk;
1934 :
1935 9453 : me = hash_to_entry(se->hash);
1936 9453 : if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk))
1937 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1938 :
1939 9453 : ret = pubkey_verify_data(se, me, data, signature, &pubkey->params,
1940 : ¶ms, flags);
1941 9453 : if (ret < 0) {
1942 297 : gnutls_assert();
1943 297 : return ret;
1944 : }
1945 :
1946 : return 0;
1947 : }
1948 :
1949 : /**
1950 : * gnutls_pubkey_verify_hash2:
1951 : * @key: Holds the public key
1952 : * @algo: The signature algorithm used
1953 : * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
1954 : * @hash: holds the hash digest to be verified
1955 : * @signature: contains the signature
1956 : *
1957 : * This function will verify the given signed digest, using the
1958 : * parameters from the public key. Note that unlike gnutls_privkey_sign_hash(),
1959 : * this function accepts a signature algorithm instead of a digest algorithm.
1960 : * You can use gnutls_pk_to_sign() to get the appropriate value.
1961 : *
1962 : * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1963 : * is returned, and zero or positive code on success. For known to be insecure
1964 : * signatures this function will return %GNUTLS_E_INSUFFICIENT_SECURITY unless
1965 : * the flag %GNUTLS_VERIFY_ALLOW_BROKEN is specified.
1966 : *
1967 : * Since: 3.0
1968 : **/
1969 : int
1970 5289 : gnutls_pubkey_verify_hash2(gnutls_pubkey_t key,
1971 : gnutls_sign_algorithm_t algo,
1972 : unsigned int flags,
1973 : const gnutls_datum_t * hash,
1974 : const gnutls_datum_t * signature)
1975 : {
1976 5289 : const mac_entry_st *me;
1977 5289 : gnutls_x509_spki_st params;
1978 5289 : const gnutls_sign_entry_st *se;
1979 5289 : int ret;
1980 :
1981 5289 : if (key == NULL) {
1982 0 : gnutls_assert();
1983 0 : return GNUTLS_E_INVALID_REQUEST;
1984 : }
1985 :
1986 5289 : if (_gnutls_pk_is_not_prehashed(key->params.algo)) {
1987 1 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1988 : }
1989 :
1990 5288 : memcpy(¶ms, &key->params.spki, sizeof(gnutls_x509_spki_st));
1991 :
1992 5288 : if (flags & GNUTLS_VERIFY_USE_TLS1_RSA) {
1993 340 : if (!GNUTLS_PK_IS_RSA(key->params.algo))
1994 0 : return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
1995 340 : params.pk = GNUTLS_PK_RSA;
1996 : /* we do not check for insecure algorithms with this flag */
1997 340 : return _gnutls_pk_verify(params.pk, hash, signature,
1998 : &key->params, ¶ms);
1999 : } else {
2000 4948 : se = _gnutls_sign_to_entry(algo);
2001 4948 : if (se == NULL)
2002 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2003 :
2004 4948 : ret = pubkey_supports_sig(key, se);
2005 4948 : if (ret < 0)
2006 0 : return gnutls_assert_val(ret);
2007 :
2008 4948 : params.pk = se->pk;
2009 :
2010 4948 : me = hash_to_entry(se->hash);
2011 4948 : if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk))
2012 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2013 :
2014 4948 : ret = pubkey_verify_hashed_data(se, me, hash, signature,
2015 : &key->params,
2016 : ¶ms, flags);
2017 4948 : if (ret < 0) {
2018 2422 : gnutls_assert();
2019 2422 : return ret;
2020 : }
2021 : }
2022 :
2023 : return 0;
2024 : }
2025 :
2026 : /**
2027 : * gnutls_pubkey_encrypt_data:
2028 : * @key: Holds the public key
2029 : * @flags: should be 0 for now
2030 : * @plaintext: The data to be encrypted
2031 : * @ciphertext: contains the encrypted data
2032 : *
2033 : * This function will encrypt the given data, using the public
2034 : * key. On success the @ciphertext will be allocated using gnutls_malloc().
2035 : *
2036 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2037 : * negative error value.
2038 : *
2039 : * Since: 3.0
2040 : **/
2041 : int
2042 5 : gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int flags,
2043 : const gnutls_datum_t * plaintext,
2044 : gnutls_datum_t * ciphertext)
2045 : {
2046 5 : if (key == NULL) {
2047 0 : gnutls_assert();
2048 0 : return GNUTLS_E_INVALID_REQUEST;
2049 : }
2050 :
2051 5 : return _gnutls_pk_encrypt(key->params.algo, ciphertext,
2052 : plaintext, &key->params);
2053 : }
2054 :
2055 : static
2056 25925 : int pubkey_supports_sig(gnutls_pubkey_t pubkey,
2057 : const gnutls_sign_entry_st *se)
2058 : {
2059 25925 : if (pubkey->params.algo == GNUTLS_PK_ECDSA && se->curve) {
2060 373 : gnutls_ecc_curve_t curve = pubkey->params.curve;
2061 :
2062 373 : if (curve != se->curve) {
2063 59 : _gnutls_handshake_log("have key: ECDSA with %s/%d, with sign %s/%d\n",
2064 : gnutls_ecc_curve_get_name(curve), (int)curve,
2065 : se->name, se->id);
2066 70 : return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
2067 : }
2068 : }
2069 :
2070 25866 : if (se->pk != pubkey->params.algo) { /* if the PK algorithm of the signature differs to the one on the pubkey */
2071 2494 : if (!sign_supports_priv_pk_algorithm(se, pubkey->params.algo)) {
2072 3 : _gnutls_handshake_log("have key: %s/%d, with sign %s/%d\n",
2073 : gnutls_pk_get_name(pubkey->params.algo), pubkey->params.algo,
2074 : se->name, se->id);
2075 3 : return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
2076 : }
2077 : }
2078 :
2079 : return 0;
2080 : }
2081 :
2082 : /* Checks whether the public key given is compatible with the
2083 : * signature algorithm used. The session is only used for audit logging, and
2084 : * it may be null.
2085 : */
2086 11582 : int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session,
2087 : gnutls_pubkey_t pubkey,
2088 : const version_entry_st * ver,
2089 : gnutls_sign_algorithm_t sign)
2090 : {
2091 11582 : unsigned int hash_size = 0;
2092 11582 : unsigned int sig_hash_size;
2093 11582 : const mac_entry_st *me;
2094 11582 : const gnutls_sign_entry_st *se;
2095 11582 : int ret;
2096 :
2097 11582 : se = _gnutls_sign_to_entry(sign);
2098 11582 : if (se != NULL) {
2099 11524 : ret = pubkey_supports_sig(pubkey, se);
2100 11524 : if (ret < 0)
2101 73 : return gnutls_assert_val(ret);
2102 58 : } else if (_gnutls_version_has_selectable_sighash(ver)) {
2103 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2104 : }
2105 :
2106 11520 : if (pubkey->params.algo == GNUTLS_PK_DSA) {
2107 28 : me = _gnutls_dsa_q_to_hash(&pubkey->params, &hash_size);
2108 :
2109 : /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
2110 28 : if (!_gnutls_version_has_selectable_sighash(ver)) {
2111 3 : if (me->id != GNUTLS_MAC_SHA1)
2112 2 : return
2113 2 : gnutls_assert_val
2114 : (GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
2115 25 : } else if (se != NULL) {
2116 25 : me = hash_to_entry(se->hash);
2117 :
2118 25 : sig_hash_size = _gnutls_hash_get_algo_len(me);
2119 25 : if (sig_hash_size < hash_size)
2120 6 : _gnutls_audit_log(session,
2121 : "The hash size used in signature (%u) is less than the expected (%u)\n",
2122 : sig_hash_size,
2123 : hash_size);
2124 : }
2125 :
2126 11492 : } else if (pubkey->params.algo == GNUTLS_PK_ECDSA) {
2127 464 : if (_gnutls_version_has_selectable_sighash(ver)
2128 458 : && se != NULL) {
2129 458 : _gnutls_dsa_q_to_hash(&pubkey->params, &hash_size);
2130 :
2131 458 : me = hash_to_entry(se->hash);
2132 :
2133 458 : sig_hash_size = _gnutls_hash_get_algo_len(me);
2134 :
2135 458 : if (sig_hash_size < hash_size)
2136 22 : _gnutls_audit_log(session,
2137 : "The hash size used in signature (%u) is less than the expected (%u)\n",
2138 : sig_hash_size,
2139 : hash_size);
2140 : }
2141 :
2142 11028 : } else if (pubkey->params.algo == GNUTLS_PK_GOST_01 ||
2143 11028 : pubkey->params.algo == GNUTLS_PK_GOST_12_256 ||
2144 : pubkey->params.algo == GNUTLS_PK_GOST_12_512) {
2145 38 : if (_gnutls_version_has_selectable_sighash(ver)
2146 38 : && se != NULL) {
2147 38 : if (_gnutls_gost_digest(pubkey->params.algo) != se->hash) {
2148 0 : _gnutls_audit_log(session,
2149 : "The hash algo used in signature (%u) is not expected (%u)\n",
2150 0 : se->hash, _gnutls_gost_digest(pubkey->params.algo));
2151 0 : return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2152 : }
2153 : }
2154 :
2155 10990 : } else if (pubkey->params.algo == GNUTLS_PK_RSA_PSS) {
2156 6426 : if (!_gnutls_version_has_selectable_sighash(ver))
2157 : /* this should not have happened */
2158 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
2159 :
2160 : /* RSA PSS public keys are restricted to a single digest, i.e., signature */
2161 :
2162 6426 : if (pubkey->params.spki.rsa_pss_dig && pubkey->params.spki.rsa_pss_dig != se->hash) {
2163 9 : return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2164 : }
2165 : }
2166 :
2167 : return 0;
2168 : }
2169 :
2170 : /* Returns the public key.
2171 : */
2172 : int
2173 251 : _gnutls_pubkey_get_mpis(gnutls_pubkey_t key, gnutls_pk_params_st * params)
2174 : {
2175 251 : return _gnutls_pk_params_copy(params, &key->params);
2176 : }
2177 :
2178 : /* if hash==MD5 then we do RSA-MD5
2179 : * if hash==SHA then we do RSA-SHA
2180 : * params[0] is modulus
2181 : * params[1] is public key
2182 : */
2183 : static int
2184 8415 : _pkcs1_rsa_verify_sig(gnutls_pk_algorithm_t pk,
2185 : const mac_entry_st * me,
2186 : const gnutls_datum_t * text,
2187 : const gnutls_datum_t * prehash,
2188 : const gnutls_datum_t * signature,
2189 : gnutls_pk_params_st * params,
2190 : gnutls_x509_spki_st * sign_params)
2191 : {
2192 8415 : int ret;
2193 8415 : uint8_t md[MAX_HASH_SIZE], *cmp;
2194 8415 : unsigned int digest_size;
2195 8415 : gnutls_datum_t d, di;
2196 :
2197 8415 : if (unlikely(me == NULL))
2198 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2199 :
2200 8415 : digest_size = _gnutls_hash_get_algo_len(me);
2201 8415 : if (prehash) {
2202 1226 : if (prehash->data == NULL || prehash->size != digest_size)
2203 400 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2204 :
2205 : cmp = prehash->data;
2206 : } else {
2207 7189 : if (!text) {
2208 0 : gnutls_assert();
2209 0 : return GNUTLS_E_INVALID_REQUEST;
2210 : }
2211 :
2212 14378 : ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)me->id,
2213 7189 : text->data, text->size, md);
2214 7189 : if (ret < 0) {
2215 0 : gnutls_assert();
2216 0 : return ret;
2217 : }
2218 :
2219 : cmp = md;
2220 : }
2221 :
2222 8015 : d.data = cmp;
2223 8015 : d.size = digest_size;
2224 :
2225 8015 : if (pk == GNUTLS_PK_RSA) {
2226 : /* decrypted is a BER encoded data of type DigestInfo
2227 : */
2228 6855 : ret = encode_ber_digest_info(me, &d, &di);
2229 6855 : if (ret < 0)
2230 0 : return gnutls_assert_val(ret);
2231 :
2232 6855 : ret = _gnutls_pk_verify(pk, &di, signature, params,
2233 : sign_params);
2234 6855 : _gnutls_free_datum(&di);
2235 : } else {
2236 1160 : ret = _gnutls_pk_verify(pk, &d, signature, params,
2237 : sign_params);
2238 : }
2239 :
2240 : return ret;
2241 : }
2242 :
2243 : /* Hashes input data and verifies a signature.
2244 : */
2245 : static int
2246 3722 : dsa_verify_hashed_data(gnutls_pk_algorithm_t pk,
2247 : const mac_entry_st * algo,
2248 : const gnutls_datum_t * hash,
2249 : const gnutls_datum_t * signature,
2250 : gnutls_pk_params_st * params,
2251 : gnutls_x509_spki_st * sign_params)
2252 : {
2253 3722 : gnutls_datum_t digest;
2254 3722 : unsigned int hash_len;
2255 :
2256 3722 : if (algo == NULL)
2257 0 : algo = _gnutls_dsa_q_to_hash(params, &hash_len);
2258 : else
2259 3722 : hash_len = _gnutls_hash_get_algo_len(algo);
2260 :
2261 : /* SHA1 or better allowed */
2262 3722 : if (!hash->data || hash->size < hash_len) {
2263 1600 : gnutls_assert();
2264 1600 : _gnutls_debug_log
2265 : ("Hash size (%d) does not correspond to hash %s(%d) or better.\n",
2266 : (int) hash->size, _gnutls_mac_get_name(algo),
2267 : hash_len);
2268 :
2269 1600 : if (hash->size != 20) /* SHA1 is allowed */
2270 0 : return
2271 0 : gnutls_assert_val
2272 : (GNUTLS_E_PK_SIG_VERIFY_FAILED);
2273 : }
2274 :
2275 3722 : digest.data = hash->data;
2276 3722 : digest.size = hash->size;
2277 :
2278 3722 : return _gnutls_pk_verify(pk, &digest, signature, params, sign_params);
2279 : }
2280 :
2281 : static int
2282 3323 : dsa_verify_data(gnutls_pk_algorithm_t pk,
2283 : const mac_entry_st * algo,
2284 : const gnutls_datum_t * data,
2285 : const gnutls_datum_t * signature,
2286 : gnutls_pk_params_st * params,
2287 : gnutls_x509_spki_st * sign_params)
2288 : {
2289 3323 : int ret;
2290 3323 : uint8_t _digest[MAX_HASH_SIZE];
2291 3323 : gnutls_datum_t digest;
2292 :
2293 3323 : if (algo == NULL)
2294 0 : algo = _gnutls_dsa_q_to_hash(params, NULL);
2295 :
2296 6646 : ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)algo->id,
2297 3323 : data->data, data->size, _digest);
2298 3323 : if (ret < 0)
2299 0 : return gnutls_assert_val(ret);
2300 :
2301 3323 : digest.data = _digest;
2302 3323 : digest.size = _gnutls_hash_get_algo_len(algo);
2303 :
2304 3323 : return _gnutls_pk_verify(pk, &digest, signature, params, sign_params);
2305 : }
2306 :
2307 : /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
2308 : * not verified, or 1 otherwise.
2309 : */
2310 : static int
2311 4948 : pubkey_verify_hashed_data(const gnutls_sign_entry_st *se,
2312 : const mac_entry_st *me,
2313 : const gnutls_datum_t * hash,
2314 : const gnutls_datum_t * signature,
2315 : gnutls_pk_params_st * params,
2316 : gnutls_x509_spki_st * sign_params,
2317 : unsigned flags)
2318 : {
2319 4948 : int ret;
2320 :
2321 4948 : if (unlikely(me==NULL))
2322 0 : return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
2323 :
2324 4948 : ret = fixup_spki_params(params, se, me, sign_params);
2325 4948 : if (ret < 0)
2326 0 : return gnutls_assert_val(ret);
2327 :
2328 4948 : switch (se->pk) {
2329 1226 : case GNUTLS_PK_RSA:
2330 : case GNUTLS_PK_RSA_PSS:
2331 :
2332 1226 : if (_pkcs1_rsa_verify_sig
2333 : (se->pk, me, NULL, hash, signature, params, sign_params) != 0)
2334 : {
2335 608 : gnutls_assert();
2336 608 : return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2337 : }
2338 :
2339 : break;
2340 :
2341 3722 : case GNUTLS_PK_ECDSA:
2342 : case GNUTLS_PK_GOST_01:
2343 : case GNUTLS_PK_GOST_12_256:
2344 : case GNUTLS_PK_GOST_12_512:
2345 : case GNUTLS_PK_DSA:
2346 3722 : if (dsa_verify_hashed_data
2347 : (se->pk, me, hash, signature, params, sign_params) != 0) {
2348 1814 : gnutls_assert();
2349 1814 : return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2350 : }
2351 :
2352 : break;
2353 0 : default:
2354 0 : gnutls_assert();
2355 : return GNUTLS_E_INVALID_REQUEST;
2356 :
2357 : }
2358 :
2359 2526 : if (_gnutls_sign_is_secure2(se, 0) == 0 && _gnutls_is_broken_sig_allowed(se, flags) == 0) {
2360 0 : return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
2361 : }
2362 :
2363 : return 1;
2364 : }
2365 :
2366 : /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
2367 : * not verified, or 1 otherwise.
2368 : */
2369 : int
2370 10602 : pubkey_verify_data(const gnutls_sign_entry_st *se,
2371 : const mac_entry_st *me,
2372 : const gnutls_datum_t * data,
2373 : const gnutls_datum_t * signature,
2374 : gnutls_pk_params_st * params,
2375 : gnutls_x509_spki_st * sign_params,
2376 : unsigned flags)
2377 : {
2378 10602 : int ret;
2379 :
2380 10602 : if (unlikely(me == NULL))
2381 0 : return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
2382 :
2383 10602 : ret = fixup_spki_params(params, se, me, sign_params);
2384 10602 : if (ret < 0)
2385 6 : return gnutls_assert_val(ret);
2386 :
2387 10596 : switch (se->pk) {
2388 7189 : case GNUTLS_PK_RSA:
2389 : case GNUTLS_PK_RSA_PSS:
2390 7189 : if (_pkcs1_rsa_verify_sig
2391 : (se->pk, me, data, NULL, signature, params, sign_params) != 0) {
2392 263 : gnutls_assert();
2393 263 : return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2394 : }
2395 :
2396 : break;
2397 :
2398 84 : case GNUTLS_PK_EDDSA_ED25519:
2399 : case GNUTLS_PK_EDDSA_ED448:
2400 84 : if (_gnutls_pk_verify(se->pk, data, signature, params, sign_params) != 0) {
2401 4 : gnutls_assert();
2402 4 : return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2403 : }
2404 :
2405 : break;
2406 :
2407 3323 : case GNUTLS_PK_EC:
2408 : case GNUTLS_PK_DSA:
2409 : case GNUTLS_PK_GOST_01:
2410 : case GNUTLS_PK_GOST_12_256:
2411 : case GNUTLS_PK_GOST_12_512:
2412 3323 : if (dsa_verify_data
2413 : (se->pk, me, data, signature, params, sign_params) != 0) {
2414 44 : gnutls_assert();
2415 44 : return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2416 : }
2417 :
2418 : break;
2419 0 : default:
2420 0 : gnutls_assert();
2421 : return GNUTLS_E_INVALID_REQUEST;
2422 :
2423 : }
2424 :
2425 10285 : if (_gnutls_sign_is_secure2(se,0) == 0 && _gnutls_is_broken_sig_allowed(se, flags) == 0) {
2426 19 : return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
2427 : }
2428 :
2429 : return 1;
2430 : }
2431 :
2432 9029 : const mac_entry_st *_gnutls_dsa_q_to_hash(const gnutls_pk_params_st *
2433 : params, unsigned int *hash_len)
2434 : {
2435 9029 : int bits = 0;
2436 9029 : int ret;
2437 :
2438 9029 : if (params->algo == GNUTLS_PK_DSA)
2439 192 : bits = _gnutls_mpi_get_nbits(params->params[1]);
2440 8837 : else if (params->algo == GNUTLS_PK_EC)
2441 8837 : bits = gnutls_ecc_curve_get_size(params->curve) * 8;
2442 :
2443 9029 : if (bits <= 160) {
2444 150 : if (hash_len)
2445 148 : *hash_len = 20;
2446 : ret = GNUTLS_DIG_SHA1;
2447 8879 : } else if (bits <= 192) {
2448 0 : if (hash_len)
2449 0 : *hash_len = 24;
2450 : ret = GNUTLS_DIG_SHA256;
2451 8879 : } else if (bits <= 224) {
2452 9 : if (hash_len)
2453 8 : *hash_len = 28;
2454 : ret = GNUTLS_DIG_SHA256;
2455 8870 : } else if (bits <= 256) {
2456 7629 : if (hash_len)
2457 7611 : *hash_len = 32;
2458 : ret = GNUTLS_DIG_SHA256;
2459 1241 : } else if (bits <= 384) {
2460 653 : if (hash_len)
2461 653 : *hash_len = 48;
2462 : ret = GNUTLS_DIG_SHA384;
2463 : } else {
2464 588 : if (hash_len)
2465 588 : *hash_len = 64;
2466 : ret = GNUTLS_DIG_SHA512;
2467 : }
2468 :
2469 9029 : return mac_to_entry(ret);
2470 : }
2471 :
2472 : /**
2473 : * gnutls_pubkey_set_pin_function:
2474 : * @key: A key of type #gnutls_pubkey_t
2475 : * @fn: the callback
2476 : * @userdata: data associated with the callback
2477 : *
2478 : * This function will set a callback function to be used when
2479 : * required to access the object. This function overrides any other
2480 : * global PIN functions.
2481 : *
2482 : * Note that this function must be called right after initialization
2483 : * to have effect.
2484 : *
2485 : * Since: 3.1.0
2486 : *
2487 : **/
2488 27 : void gnutls_pubkey_set_pin_function(gnutls_pubkey_t key,
2489 : gnutls_pin_callback_t fn,
2490 : void *userdata)
2491 : {
2492 27 : key->pin.cb = fn;
2493 27 : key->pin.data = userdata;
2494 27 : }
2495 :
2496 : /**
2497 : * gnutls_pubkey_import_x509_raw:
2498 : * @pkey: The public key
2499 : * @data: The public key data to be imported
2500 : * @format: The format of the public key
2501 : * @flags: should be zero
2502 : *
2503 : * This function will import the given public key to the abstract
2504 : * #gnutls_pubkey_t type.
2505 : *
2506 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2507 : * negative error value.
2508 : *
2509 : * Since: 3.1.3
2510 : **/
2511 17 : int gnutls_pubkey_import_x509_raw(gnutls_pubkey_t pkey,
2512 : const gnutls_datum_t * data,
2513 : gnutls_x509_crt_fmt_t format,
2514 : unsigned int flags)
2515 : {
2516 17 : gnutls_x509_crt_t xpriv;
2517 17 : int ret;
2518 :
2519 17 : ret = gnutls_x509_crt_init(&xpriv);
2520 17 : if (ret < 0)
2521 0 : return gnutls_assert_val(ret);
2522 :
2523 17 : ret = gnutls_x509_crt_import(xpriv, data, format);
2524 17 : if (ret < 0) {
2525 0 : gnutls_assert();
2526 0 : goto cleanup;
2527 : }
2528 :
2529 17 : ret = gnutls_pubkey_import_x509(pkey, xpriv, flags);
2530 17 : if (ret < 0) {
2531 0 : gnutls_assert();
2532 0 : goto cleanup;
2533 : }
2534 :
2535 : ret = 0;
2536 :
2537 17 : cleanup:
2538 17 : gnutls_x509_crt_deinit(xpriv);
2539 :
2540 17 : return ret;
2541 : }
2542 :
2543 : /**
2544 : * gnutls_pubkey_verify_params:
2545 : * @key: should contain a #gnutls_pubkey_t type
2546 : *
2547 : * This function will verify the public key parameters.
2548 : *
2549 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2550 : * negative error value.
2551 : *
2552 : * Since: 3.3.0
2553 : **/
2554 1 : int gnutls_pubkey_verify_params(gnutls_pubkey_t key)
2555 : {
2556 1 : int ret;
2557 :
2558 1 : ret = _gnutls_pk_verify_pub_params(key->params.algo, &key->params);
2559 1 : if (ret < 0) {
2560 0 : gnutls_assert();
2561 0 : return ret;
2562 : }
2563 :
2564 : return 0;
2565 : }
2566 :
2567 : /**
2568 : * gnutls_pubkey_get_spki:
2569 : * @pubkey: a public key of type #gnutls_pubkey_t
2570 : * @spki: a SubjectPublicKeyInfo structure of type #gnutls_pubkey_spki_t
2571 : * @flags: must be zero
2572 : *
2573 : * This function will return the public key information if available.
2574 : * The provided @spki must be initialized.
2575 : *
2576 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2577 : * negative error value.
2578 : *
2579 : * Since: 3.6.0
2580 : **/
2581 : int
2582 1 : gnutls_pubkey_get_spki(gnutls_pubkey_t pubkey, gnutls_x509_spki_t spki, unsigned int flags)
2583 : {
2584 1 : gnutls_x509_spki_t p = &pubkey->params.spki;
2585 :
2586 1 : if (pubkey == NULL) {
2587 0 : gnutls_assert();
2588 0 : return GNUTLS_E_INVALID_REQUEST;
2589 : }
2590 :
2591 1 : if (p->pk == GNUTLS_PK_UNKNOWN)
2592 0 : return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2593 :
2594 1 : memcpy(spki, p, sizeof(gnutls_x509_spki_st));
2595 :
2596 1 : return 0;
2597 : }
2598 :
2599 : /**
2600 : * gnutls_pubkey_set_spki:
2601 : * @pubkey: a public key of type #gnutls_pubkey_t
2602 : * @spki: a SubjectPublicKeyInfo structure of type #gnutls_pubkey_spki_t
2603 : * @flags: must be zero
2604 : *
2605 : * This function will set the public key information.
2606 : * The provided @spki must be initialized.
2607 : *
2608 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2609 : * negative error value.
2610 : *
2611 : * Since: 3.6.0
2612 : **/
2613 : int
2614 0 : gnutls_pubkey_set_spki(gnutls_pubkey_t pubkey, const gnutls_x509_spki_t spki, unsigned int flags)
2615 : {
2616 0 : if (pubkey == NULL) {
2617 0 : gnutls_assert();
2618 0 : return GNUTLS_E_INVALID_REQUEST;
2619 : }
2620 :
2621 0 : if (!_gnutls_pk_are_compat(pubkey->params.algo, spki->pk))
2622 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2623 :
2624 0 : memcpy(&pubkey->params.spki, spki, sizeof(gnutls_x509_spki_st));
2625 :
2626 0 : pubkey->params.algo = spki->pk;
2627 :
2628 0 : return 0;
2629 : }
|