LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - pubkey.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 664 976 68.0 %
Date: 2020-10-30 04:50:48 Functions: 49 52 94.2 %
Legend: Lines: hit not hit

          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(&params, &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             :                                  &params, 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(&params, &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, &params);
    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             :                                                 &params, 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             : }

Generated by: LCOV version 1.14