LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - privkey.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 443 628 70.5 %
Date: 2020-10-30 04:50:48 Functions: 35 42 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * GnuTLS PKCS#11 support
       3             :  * Copyright (C) 2010-2014 Free Software Foundation, Inc.
       4             :  * Copyright (C) 2012-2015 Nikos Mavrogiannopoulos
       5             :  * Copyright (C) 2016-2017 Red Hat, Inc.
       6             :  * 
       7             :  * Author: Nikos Mavrogiannopoulos
       8             :  *
       9             :  * The GnuTLS is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public License
      11             :  * as published by the Free Software Foundation; either version 2.1 of
      12             :  * the License, or (at your option) any later version.
      13             :  *
      14             :  * This library is distributed in the hope that it will be useful, but
      15             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public License
      20             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      21             :  */
      22             : 
      23             : #include "gnutls_int.h"
      24             : #include <gnutls/pkcs11.h>
      25             : #include <stdio.h>
      26             : #include <string.h>
      27             : #include "errors.h"
      28             : #include <datum.h>
      29             : #include <pkcs11_int.h>
      30             : #include <gnutls/abstract.h>
      31             : #include <pk.h>
      32             : #include <x509_int.h>
      33             : #include <tls-sig.h>
      34             : #include <algorithms.h>
      35             : #include <fips.h>
      36             : #include <system-keys.h>
      37             : #include "urls.h"
      38             : #include "pkcs11_int.h"
      39             : #include <abstract_int.h>
      40             : 
      41             : static int
      42             : privkey_sign_prehashed(gnutls_privkey_t signer,
      43             :                        const gnutls_sign_entry_st *se,
      44             :                        const gnutls_datum_t * hash_data,
      45             :                        gnutls_datum_t * signature,
      46             :                        gnutls_x509_spki_st * params);
      47             : 
      48             : /**
      49             :  * gnutls_privkey_get_type:
      50             :  * @key: should contain a #gnutls_privkey_t type
      51             :  *
      52             :  * This function will return the type of the private key. This is
      53             :  * actually the type of the subsystem used to set this private key.
      54             :  *
      55             :  * Returns: a member of the #gnutls_privkey_type_t enumeration on
      56             :  *   success, or a negative error code on error.
      57             :  *
      58             :  * Since: 2.12.0
      59             :  **/
      60           0 : gnutls_privkey_type_t gnutls_privkey_get_type(gnutls_privkey_t key)
      61             : {
      62           0 :         return key->type;
      63             : }
      64             : 
      65             : /**
      66             :  * gnutls_privkey_get_seed:
      67             :  * @key: should contain a #gnutls_privkey_t type
      68             :  * @digest: if non-NULL it will contain the digest algorithm used for key generation (if applicable)
      69             :  * @seed: where seed will be copied to
      70             :  * @seed_size: originally holds the size of @seed, will be updated with actual size
      71             :  *
      72             :  * This function will return the seed that was used to generate the
      73             :  * given private key. That function will succeed only if the key was generated
      74             :  * as a provable key.
      75             :  *
      76             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
      77             :  *   negative error value.
      78             :  *
      79             :  * Since: 3.5.0
      80             :  **/
      81           0 : int gnutls_privkey_get_seed(gnutls_privkey_t key, gnutls_digest_algorithm_t *digest, void *seed, size_t *seed_size)
      82             : {
      83           0 :         if (key->type != GNUTLS_PRIVKEY_X509)
      84           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
      85           0 :         return gnutls_x509_privkey_get_seed(key->key.x509, digest, seed, seed_size);
      86             : }
      87             : 
      88             : /**
      89             :  * gnutls_privkey_verify_seed:
      90             :  * @key: should contain a #gnutls_privkey_t type
      91             :  * @digest: it contains the digest algorithm used for key generation (if applicable)
      92             :  * @seed: the seed of the key to be checked with
      93             :  * @seed_size: holds the size of @seed
      94             :  *
      95             :  * This function will verify that the given private key was generated from
      96             :  * the provided seed.
      97             :  *
      98             :  * Returns: In case of a verification failure %GNUTLS_E_PRIVKEY_VERIFICATION_ERROR
      99             :  * is returned, and zero or positive code on success.
     100             :  *
     101             :  * Since: 3.5.0
     102             :  **/
     103          13 : int gnutls_privkey_verify_seed(gnutls_privkey_t key, gnutls_digest_algorithm_t digest, const void *seed, size_t seed_size)
     104             : {
     105          13 :         if (key->type != GNUTLS_PRIVKEY_X509)
     106           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     107          13 :         return gnutls_x509_privkey_verify_seed(key->key.x509, digest, seed, seed_size);
     108             : }
     109             : 
     110             : /**
     111             :  * gnutls_privkey_get_pk_algorithm:
     112             :  * @key: should contain a #gnutls_privkey_t type
     113             :  * @bits: If set will return the number of bits of the parameters (may be NULL)
     114             :  *
     115             :  * This function will return the public key algorithm of a private
     116             :  * key and if possible will return a number of bits that indicates
     117             :  * the security parameter of the key.
     118             :  *
     119             :  * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
     120             :  *   success, or a negative error code on error.
     121             :  *
     122             :  * Since: 2.12.0
     123             :  **/
     124       30965 : int gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key, unsigned int *bits)
     125             : {
     126       30965 :         switch (key->type) {
     127             : #ifdef ENABLE_PKCS11
     128         320 :         case GNUTLS_PRIVKEY_PKCS11:
     129         320 :                 return gnutls_pkcs11_privkey_get_pk_algorithm(key->key.pkcs11,
     130             :                                                               bits);
     131             : #endif
     132       30544 :         case GNUTLS_PRIVKEY_X509:
     133       30544 :                 if (bits) {
     134       17718 :                         *bits = pubkey_to_bits(&key->key.x509->params);
     135             :                 }
     136             : 
     137       30544 :                 return gnutls_x509_privkey_get_pk_algorithm(key->key.x509);
     138         101 :         case GNUTLS_PRIVKEY_EXT:
     139         101 :                 if (bits)
     140          74 :                         *bits = key->key.ext.bits;
     141             : 
     142         101 :                 return key->pk_algorithm;
     143           0 :         default:
     144           0 :                 gnutls_assert();
     145             :                 return GNUTLS_E_INVALID_REQUEST;
     146             :         }
     147             : 
     148             : }
     149             : 
     150             : static int
     151        1404 : privkey_to_pubkey(gnutls_pk_algorithm_t pk,
     152             :                   const gnutls_pk_params_st * priv, gnutls_pk_params_st * pub)
     153             : {
     154        1404 :         int ret;
     155             : 
     156        1404 :         pub->algo = priv->algo;
     157        1404 :         pub->pkflags = priv->pkflags;
     158        1404 :         pub->curve = priv->curve;
     159        1404 :         pub->gost_params = priv->gost_params;
     160        1404 :         pub->qbits = priv->qbits;
     161        1404 :         memcpy(&pub->spki, &priv->spki, sizeof(gnutls_x509_spki_st));
     162             : 
     163        1404 :         switch (pk) {
     164         424 :         case GNUTLS_PK_RSA_PSS:
     165             :         case GNUTLS_PK_RSA:
     166         424 :                 pub->params[0] = _gnutls_mpi_copy(priv->params[0]);
     167         424 :                 pub->params[1] = _gnutls_mpi_copy(priv->params[1]);
     168             : 
     169         424 :                 pub->params_nr = RSA_PUBLIC_PARAMS;
     170             : 
     171         424 :                 if (pub->params[0] == NULL || pub->params[1] == NULL) {
     172           0 :                         gnutls_assert();
     173           0 :                         ret = GNUTLS_E_MEMORY_ERROR;
     174           0 :                         goto cleanup;
     175             :                 }
     176             : 
     177             :                 break;
     178          13 :         case GNUTLS_PK_DSA:
     179          13 :                 pub->params[0] = _gnutls_mpi_copy(priv->params[0]);
     180          13 :                 pub->params[1] = _gnutls_mpi_copy(priv->params[1]);
     181          13 :                 pub->params[2] = _gnutls_mpi_copy(priv->params[2]);
     182          13 :                 pub->params[3] = _gnutls_mpi_copy(priv->params[3]);
     183             : 
     184          13 :                 pub->params_nr = DSA_PUBLIC_PARAMS;
     185             : 
     186          13 :                 if (pub->params[0] == NULL || pub->params[1] == NULL ||
     187          13 :                     pub->params[2] == NULL || pub->params[3] == NULL) {
     188           0 :                         gnutls_assert();
     189           0 :                         ret = GNUTLS_E_MEMORY_ERROR;
     190           0 :                         goto cleanup;
     191             :                 }
     192             : 
     193             :                 break;
     194         429 :         case GNUTLS_PK_ECDSA:
     195         429 :                 pub->params[ECC_X] = _gnutls_mpi_copy(priv->params[ECC_X]);
     196         429 :                 pub->params[ECC_Y] = _gnutls_mpi_copy(priv->params[ECC_Y]);
     197             : 
     198         429 :                 pub->params_nr = ECC_PUBLIC_PARAMS;
     199             : 
     200         429 :                 if (pub->params[ECC_X] == NULL || pub->params[ECC_Y] == NULL) {
     201           0 :                         gnutls_assert();
     202           0 :                         ret = GNUTLS_E_MEMORY_ERROR;
     203           0 :                         goto cleanup;
     204             :                 }
     205             : 
     206             :                 break;
     207          15 :         case GNUTLS_PK_EDDSA_ED25519:
     208             :         case GNUTLS_PK_EDDSA_ED448:
     209          15 :                 ret = _gnutls_set_datum(&pub->raw_pub, priv->raw_pub.data, priv->raw_pub.size);
     210          15 :                 if (ret < 0)
     211           0 :                         return gnutls_assert_val(ret);
     212             : 
     213             :                 break;
     214         523 :         case GNUTLS_PK_GOST_01:
     215             :         case GNUTLS_PK_GOST_12_256:
     216             :         case GNUTLS_PK_GOST_12_512:
     217         523 :                 pub->params[GOST_X] = _gnutls_mpi_copy(priv->params[GOST_X]);
     218         523 :                 pub->params[GOST_Y] = _gnutls_mpi_copy(priv->params[GOST_Y]);
     219             : 
     220         523 :                 pub->params_nr = GOST_PUBLIC_PARAMS;
     221             : 
     222         523 :                 if (pub->params[GOST_X] == NULL || pub->params[GOST_Y] == NULL) {
     223           0 :                         gnutls_assert();
     224           0 :                         ret = GNUTLS_E_MEMORY_ERROR;
     225           0 :                         goto cleanup;
     226             :                 }
     227             : 
     228             :                 break;
     229           0 :         default:
     230           0 :                 gnutls_assert();
     231             :                 return GNUTLS_E_INVALID_REQUEST;
     232             :         }
     233             : 
     234             :         return 0;
     235           0 :  cleanup:
     236           0 :         gnutls_pk_params_release(pub);
     237           0 :         return ret;
     238             : }
     239             : 
     240             : /* Returns the public key of the private key (if possible)
     241             :  */
     242             : int
     243        1427 : _gnutls_privkey_get_mpis(gnutls_privkey_t key, gnutls_pk_params_st * params)
     244             : {
     245        1427 :         int ret;
     246             : 
     247        1427 :         switch (key->type) {
     248        1398 :         case GNUTLS_PRIVKEY_X509:
     249        1398 :                 ret = _gnutls_pk_params_copy(params, &key->key.x509->params);
     250        1398 :                 break;
     251             : #ifdef ENABLE_PKCS11
     252          26 :         case GNUTLS_PRIVKEY_PKCS11: {
     253          26 :                 gnutls_pubkey_t pubkey;
     254             : 
     255          26 :                 ret = _pkcs11_privkey_get_pubkey(key->key.pkcs11, &pubkey, 0);
     256          26 :                 if (ret < 0)
     257           1 :                         return gnutls_assert_val(ret);
     258             : 
     259          25 :                 ret = _gnutls_pubkey_get_mpis(pubkey, params);
     260          25 :                 gnutls_pubkey_deinit(pubkey);
     261             : 
     262          25 :                 break;
     263             :                 }
     264             : #endif
     265           3 :         default:
     266           3 :                 gnutls_assert();
     267             :                 return GNUTLS_E_INVALID_REQUEST;
     268             :         }
     269             : 
     270             :         return ret;
     271             : }
     272             : 
     273             : int
     274        1407 : _gnutls_privkey_get_public_mpis(gnutls_privkey_t key,
     275             :                                 gnutls_pk_params_st * params)
     276             : {
     277        1407 :         int ret;
     278        1407 :         gnutls_pk_params_st tmp1;
     279             : 
     280        1407 :         gnutls_pk_params_init(&tmp1);
     281             : 
     282        1407 :         ret = _gnutls_privkey_get_mpis(key, &tmp1);
     283        1407 :         if (ret < 0)
     284           3 :                 return gnutls_assert_val(ret);
     285             : 
     286        1404 :         ret = privkey_to_pubkey(key->pk_algorithm, &tmp1, params);
     287             : 
     288        1404 :         gnutls_pk_params_release(&tmp1);
     289             : 
     290        1404 :         if (ret < 0)
     291           0 :                 gnutls_assert();
     292             : 
     293             :         return ret;
     294             : }
     295             : 
     296             : /* This function retrieves default sign parameters from KEY. */
     297             : int
     298       16635 : _gnutls_privkey_get_spki_params(gnutls_privkey_t key,
     299             :                                 gnutls_x509_spki_st * params)
     300             : {
     301       16635 :         switch (key->type) {
     302             : #ifdef ENABLE_PKCS11
     303             :         case GNUTLS_PRIVKEY_PKCS11:
     304             :                 break;
     305             : #endif
     306             :         case GNUTLS_PRIVKEY_EXT:
     307             :                 break;
     308       16315 :         case GNUTLS_PRIVKEY_X509:
     309       16315 :                 _gnutls_x509_privkey_get_spki_params(key->key.x509, params);
     310       16315 :                 return 0;
     311           0 :         default:
     312           0 :                 gnutls_assert();
     313             :                 return GNUTLS_E_INVALID_REQUEST;
     314             :         }
     315             : 
     316         320 :         memset(params, 0, sizeof(gnutls_x509_spki_st));
     317             : 
     318         320 :         return 0;
     319             : }
     320             : 
     321             : /* This function fills in PARAMS with the necessary parameters to sign
     322             :  * with PK and DIG. PARAMS must be initialized with
     323             :  * _gnutls_privkey_get_spki_params in advance.
     324             :  *
     325             :  * After calling this function the params structure will
     326             :  * be initialized even if the original SubjectPublicKeyInfo was empty.
     327             :  */
     328             : int
     329       16635 : _gnutls_privkey_update_spki_params(gnutls_privkey_t key,
     330             :                                  gnutls_pk_algorithm_t pk,
     331             :                                  gnutls_digest_algorithm_t dig,
     332             :                                  unsigned flags,
     333             :                                  gnutls_x509_spki_st *params)
     334             : {
     335       16635 :         unsigned salt_size = 0;
     336       16635 :         unsigned bits = 0;
     337       16635 :         gnutls_pk_algorithm_t key_pk;
     338             : 
     339       16635 :         if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS) {
     340          10 :                 if (!GNUTLS_PK_IS_RSA(pk))
     341           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     342             :                 pk = GNUTLS_PK_RSA_PSS;
     343             :         }
     344             : 
     345       16635 :         key_pk = gnutls_privkey_get_pk_algorithm(key, &bits);
     346       16635 :         if ((key_pk != pk) &&
     347         961 :               !(key_pk == GNUTLS_PK_RSA && pk == GNUTLS_PK_RSA_PSS)) {
     348           2 :                 gnutls_assert();
     349           2 :                 return GNUTLS_E_CONSTRAINT_ERROR;
     350             :         }
     351             : 
     352       16633 :         if (pk == GNUTLS_PK_RSA_PSS) {
     353        4261 :                 const mac_entry_st *me;
     354        4261 :                 int ret;
     355             : 
     356        4261 :                 me = hash_to_entry(dig);
     357        4261 :                 if (unlikely(me == NULL))
     358           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     359             : 
     360        4261 :                 if (params->pk == GNUTLS_PK_RSA)
     361             :                         salt_size = 0;
     362        4261 :                 else if (params->pk == GNUTLS_PK_RSA_PSS) {
     363          43 :                         if (params->rsa_pss_dig != GNUTLS_DIG_UNKNOWN && dig != params->rsa_pss_dig) {
     364           4 :                                 return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
     365             :                         }
     366             : 
     367          39 :                         salt_size = params->salt_size;
     368             :                 }
     369             : 
     370        4257 :                 if (flags & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE)
     371           0 :                         params->salt_size = 0;
     372             :                 else {
     373        4257 :                         ret = _gnutls_find_rsa_pss_salt_size(bits, me, salt_size);
     374        4257 :                         if (ret < 0)
     375           1 :                                 return gnutls_assert_val(ret);
     376        4256 :                         params->salt_size = ret;
     377             :                 }
     378        4256 :                 params->rsa_pss_dig = dig;
     379             :         }
     380             : 
     381       16628 :         params->pk = pk;
     382             : 
     383       16628 :         return 0;
     384             : }
     385             : 
     386             : /**
     387             :  * gnutls_privkey_init:
     388             :  * @key: A pointer to the type to be initialized
     389             :  *
     390             :  * This function will initialize a private key object. The object can
     391             :  * be used to generate, import, and perform cryptographic operations
     392             :  * on the associated private key.
     393             :  *
     394             :  * Note that when the underlying private key is a PKCS#11 key (i.e.,
     395             :  * when imported with a PKCS#11 URI), the limitations of gnutls_pkcs11_privkey_init()
     396             :  * apply to this object as well. In versions of GnuTLS later than 3.5.11 the object
     397             :  * is protected using locks and a single %gnutls_privkey_t can be re-used
     398             :  * by many threads. However, for performance it is recommended to utilize
     399             :  * one object per key per thread.
     400             :  *
     401             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     402             :  *   negative error value.
     403             :  *
     404             :  * Since: 2.12.0
     405             :  **/
     406       13052 : int gnutls_privkey_init(gnutls_privkey_t * key)
     407             : {
     408       13052 :         FAIL_IF_LIB_ERROR;
     409             : 
     410       13052 :         *key = gnutls_calloc(1, sizeof(struct gnutls_privkey_st));
     411       13052 :         if (*key == NULL) {
     412           0 :                 gnutls_assert();
     413           0 :                 return GNUTLS_E_MEMORY_ERROR;
     414             :         }
     415             : 
     416             :         return 0;
     417             : }
     418             : 
     419             : /**
     420             :  * gnutls_privkey_deinit:
     421             :  * @key: The key to be deinitialized
     422             :  *
     423             :  * This function will deinitialize a private key structure.
     424             :  *
     425             :  * Since: 2.12.0
     426             :  **/
     427       12568 : void gnutls_privkey_deinit(gnutls_privkey_t key)
     428             : {
     429       12568 :         if (key == NULL)
     430             :                 return;
     431             : 
     432       12562 :         if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
     433       12562 :             || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY)
     434       12475 :                 switch (key->type) {
     435             : #ifdef ENABLE_PKCS11
     436          58 :                 case GNUTLS_PRIVKEY_PKCS11:
     437          58 :                         gnutls_pkcs11_privkey_deinit(key->key.pkcs11);
     438          58 :                         break;
     439             : #endif
     440       12379 :                 case GNUTLS_PRIVKEY_X509:
     441       12379 :                         gnutls_x509_privkey_deinit(key->key.x509);
     442       12379 :                         break;
     443          38 :                 case GNUTLS_PRIVKEY_EXT:
     444          38 :                         if (key->key.ext.deinit_func != NULL)
     445          38 :                                 key->key.ext.deinit_func(key,
     446             :                                                          key->key.ext.userdata);
     447             :                         break;
     448             :                 default:
     449             :                         break;
     450             :                 }
     451       12562 :         gnutls_free(key);
     452             : }
     453             : 
     454             : /* Will erase all private key information, except PIN */
     455           3 : void _gnutls_privkey_cleanup(gnutls_privkey_t key)
     456             : {
     457           3 :         memset(&key->key, 0, sizeof(key->key));
     458           3 :         key->type = 0;
     459           3 :         key->pk_algorithm = 0;
     460           3 :         key->flags = 0;
     461           3 : }
     462             : 
     463             : /* will fail if the private key contains an actual key.
     464             :  */
     465       11848 : static int check_if_clean(gnutls_privkey_t key)
     466             : {
     467       11848 :         if (key->type != 0)
     468           0 :                 return GNUTLS_E_INVALID_REQUEST;
     469             : 
     470             :         return 0;
     471             : }
     472             : 
     473             : #ifdef ENABLE_PKCS11
     474             : 
     475             : /**
     476             :  * gnutls_privkey_import_pkcs11:
     477             :  * @pkey: The private key
     478             :  * @key: The private key to be imported
     479             :  * @flags: Flags for the import
     480             :  *
     481             :  * This function will import the given private key to the abstract
     482             :  * #gnutls_privkey_t type.
     483             :  *
     484             :  * The #gnutls_pkcs11_privkey_t object must not be deallocated
     485             :  * during the lifetime of this structure.
     486             :  *
     487             :  * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
     488             :  * and %GNUTLS_PRIVKEY_IMPORT_COPY.
     489             :  *
     490             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     491             :  *   negative error value.
     492             :  *
     493             :  * Since: 2.12.0
     494             :  **/
     495             : int
     496          69 : gnutls_privkey_import_pkcs11(gnutls_privkey_t pkey,
     497             :                              gnutls_pkcs11_privkey_t key, unsigned int flags)
     498             : {
     499          69 :         int ret;
     500             : 
     501          69 :         ret = check_if_clean(pkey);
     502          69 :         if (ret < 0) {
     503           0 :                 gnutls_assert();
     504           0 :                 return ret;
     505             :         }
     506             : 
     507          69 :         if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
     508           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     509             : 
     510          69 :         pkey->key.pkcs11 = key;
     511          69 :         pkey->type = GNUTLS_PRIVKEY_PKCS11;
     512          69 :         pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm(key, NULL);
     513          69 :         pkey->flags = flags;
     514             : 
     515          69 :         if (pkey->pin.data)
     516           1 :                 gnutls_pkcs11_privkey_set_pin_function(key, pkey->pin.cb,
     517             :                                                        pkey->pin.data);
     518             : 
     519             :         return 0;
     520             : }
     521             : 
     522             : #if 0
     523             : /**
     524             :  * gnutls_privkey_import_pkcs11_url:
     525             :  * @key: A key of type #gnutls_pubkey_t
     526             :  * @url: A PKCS 11 url
     527             :  *
     528             :  * This function will import a PKCS 11 private key to a #gnutls_private_key_t
     529             :  * type.
     530             :  *
     531             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     532             :  *   negative error value.
     533             :  *
     534             :  * Since: 3.1.0
     535             :  **/
     536             : 
     537             : int gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key, const char *url)
     538             : {
     539             :         int x;
     540             : }
     541             : #endif
     542             : 
     543             : static
     544          71 : int _gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key, const char *url, unsigned flags)
     545             : {
     546          71 :         gnutls_pkcs11_privkey_t pkey;
     547          71 :         int ret;
     548             : 
     549          71 :         ret = gnutls_pkcs11_privkey_init(&pkey);
     550          71 :         if (ret < 0) {
     551           0 :                 gnutls_assert();
     552           0 :                 return ret;
     553             :         }
     554             : 
     555          71 :         if (key->pin.cb)
     556          12 :                 gnutls_pkcs11_privkey_set_pin_function(pkey, key->pin.cb,
     557             :                                                        key->pin.data);
     558             : 
     559          71 :         ret = gnutls_pkcs11_privkey_import_url(pkey, url, flags);
     560          71 :         if (ret < 0) {
     561           2 :                 gnutls_assert();
     562           2 :                 goto cleanup;
     563             :         }
     564             : 
     565          69 :         ret =
     566          69 :             gnutls_privkey_import_pkcs11(key, pkey,
     567             :                                          GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
     568          69 :         if (ret < 0) {
     569           0 :                 gnutls_assert();
     570           0 :                 goto cleanup;
     571             :         }
     572             : 
     573             :         return 0;
     574             : 
     575           2 :  cleanup:
     576           2 :         gnutls_pkcs11_privkey_deinit(pkey);
     577             : 
     578           2 :         return ret;
     579             : }
     580             : 
     581             : /**
     582             :  * gnutls_privkey_export_pkcs11:
     583             :  * @pkey: The private key
     584             :  * @key: Location for the key to be exported.
     585             :  *
     586             :  * Converts the given abstract private key to a #gnutls_pkcs11_privkey_t
     587             :  * type. The key must be of type %GNUTLS_PRIVKEY_PKCS11. The key
     588             :  * returned in @key must be deinitialized with
     589             :  * gnutls_pkcs11_privkey_deinit().
     590             :  *
     591             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     592             :  *   negative error value.
     593             :  *
     594             :  * Since: 3.4.0
     595             :  */
     596             : int
     597           0 : gnutls_privkey_export_pkcs11(gnutls_privkey_t pkey,
     598             :                              gnutls_pkcs11_privkey_t *key)
     599             : {
     600           0 :         int ret;
     601             : 
     602           0 :         if (pkey->type != GNUTLS_PRIVKEY_PKCS11) {
     603           0 :                 gnutls_assert();
     604           0 :                 return GNUTLS_E_INVALID_REQUEST;
     605             :         }
     606             : 
     607           0 :         ret = gnutls_pkcs11_privkey_init(key);
     608           0 :         if (ret < 0)
     609           0 :                 return gnutls_assert_val(ret);
     610             : 
     611           0 :         ret = gnutls_pkcs11_privkey_cpy(*key, pkey->key.pkcs11);
     612           0 :         if (ret < 0) {
     613           0 :                 gnutls_pkcs11_privkey_deinit(*key);
     614           0 :                 *key = NULL;
     615             : 
     616           0 :                 return gnutls_assert_val(ret);
     617             :         }
     618             : 
     619             :         return 0;
     620             : }
     621             : #endif                          /* ENABLE_PKCS11 */
     622             : 
     623             : /**
     624             :  * gnutls_privkey_import_ext:
     625             :  * @pkey: The private key
     626             :  * @pk: The public key algorithm
     627             :  * @userdata: private data to be provided to the callbacks
     628             :  * @sign_func: callback for signature operations
     629             :  * @decrypt_func: callback for decryption operations
     630             :  * @flags: Flags for the import
     631             :  *
     632             :  * This function will associate the given callbacks with the
     633             :  * #gnutls_privkey_t type. At least one of the two callbacks
     634             :  * must be non-null.
     635             :  *
     636             :  * Note that the signing function is supposed to "raw" sign data, i.e.,
     637             :  * without any hashing or preprocessing. In case of RSA the DigestInfo
     638             :  * will be provided, and the signing function is expected to do the PKCS #1
     639             :  * 1.5 padding and the exponentiation.
     640             :  *
     641             :  * See also gnutls_privkey_import_ext3().
     642             :  *
     643             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     644             :  *   negative error value.
     645             :  *
     646             :  * Since: 3.0
     647             :  **/
     648             : int
     649           0 : gnutls_privkey_import_ext(gnutls_privkey_t pkey,
     650             :                           gnutls_pk_algorithm_t pk,
     651             :                           void *userdata,
     652             :                           gnutls_privkey_sign_func sign_func,
     653             :                           gnutls_privkey_decrypt_func decrypt_func,
     654             :                           unsigned int flags)
     655             : {
     656           0 :         return gnutls_privkey_import_ext2(pkey, pk, userdata, sign_func,
     657             :                                           decrypt_func, NULL, flags);
     658             : }
     659             : 
     660             : #define PK_IS_OK_FOR_EXT2(pk) \
     661             :         ((pk == GNUTLS_PK_RSA) || (pk == GNUTLS_PK_ECDSA) || (pk == GNUTLS_PK_DSA))
     662             : 
     663             : /**
     664             :  * gnutls_privkey_import_ext2:
     665             :  * @pkey: The private key
     666             :  * @pk: The public key algorithm
     667             :  * @userdata: private data to be provided to the callbacks
     668             :  * @sign_fn: callback for signature operations
     669             :  * @decrypt_fn: callback for decryption operations
     670             :  * @deinit_fn: a deinitialization function
     671             :  * @flags: Flags for the import
     672             :  *
     673             :  * This function will associate the given callbacks with the
     674             :  * #gnutls_privkey_t type. At least one of the two callbacks
     675             :  * must be non-null. If a deinitialization function is provided
     676             :  * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
     677             :  *
     678             :  * Note that the signing function is supposed to "raw" sign data, i.e.,
     679             :  * without any hashing or preprocessing. In case of RSA the DigestInfo
     680             :  * will be provided, and the signing function is expected to do the PKCS #1
     681             :  * 1.5 padding and the exponentiation.
     682             :  *
     683             :  * See also gnutls_privkey_import_ext3().
     684             :  *
     685             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     686             :  *   negative error value.
     687             :  *
     688             :  * Since: 3.1
     689             :  **/
     690             : int
     691          17 : gnutls_privkey_import_ext2(gnutls_privkey_t pkey,
     692             :                            gnutls_pk_algorithm_t pk,
     693             :                            void *userdata,
     694             :                            gnutls_privkey_sign_func sign_fn,
     695             :                            gnutls_privkey_decrypt_func decrypt_fn,
     696             :                            gnutls_privkey_deinit_func deinit_fn,
     697             :                            unsigned int flags)
     698             : {
     699          17 :         int ret;
     700             : 
     701          17 :         ret = check_if_clean(pkey);
     702          17 :         if (ret < 0) {
     703           0 :                 gnutls_assert();
     704           0 :                 return ret;
     705             :         }
     706             : 
     707          17 :         if (!PK_IS_OK_FOR_EXT2(pk))
     708           3 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     709             : 
     710          14 :         if (sign_fn == NULL && decrypt_fn == NULL)
     711           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     712             : 
     713          14 :         pkey->key.ext.sign_func = sign_fn;
     714          14 :         pkey->key.ext.decrypt_func = decrypt_fn;
     715          14 :         pkey->key.ext.deinit_func = deinit_fn;
     716          14 :         pkey->key.ext.userdata = userdata;
     717          14 :         pkey->type = GNUTLS_PRIVKEY_EXT;
     718          14 :         pkey->pk_algorithm = pk;
     719          14 :         pkey->flags = flags;
     720             : 
     721             :         /* Ensure gnutls_privkey_deinit() calls the deinit_func */
     722          14 :         if (deinit_fn)
     723          14 :                 pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
     724             : 
     725             :         return 0;
     726             : }
     727             : 
     728             : /**
     729             :  * gnutls_privkey_import_ext3:
     730             :  * @pkey: The private key
     731             :  * @userdata: private data to be provided to the callbacks
     732             :  * @sign_fn: callback for signature operations
     733             :  * @decrypt_fn: callback for decryption operations
     734             :  * @deinit_fn: a deinitialization function
     735             :  * @info_fn: returns info about the public key algorithm (should not be %NULL)
     736             :  * @flags: Flags for the import
     737             :  *
     738             :  * This function will associate the given callbacks with the
     739             :  * #gnutls_privkey_t type. At least one of the two callbacks
     740             :  * must be non-null. If a deinitialization function is provided
     741             :  * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
     742             :  *
     743             :  * Note that the signing function is supposed to "raw" sign data, i.e.,
     744             :  * without any hashing or preprocessing. In case of RSA the DigestInfo
     745             :  * will be provided, and the signing function is expected to do the PKCS #1
     746             :  * 1.5 padding and the exponentiation.
     747             :  *
     748             :  * The @info_fn must provide information on the algorithms supported by
     749             :  * this private key, and should support the flags %GNUTLS_PRIVKEY_INFO_PK_ALGO and
     750             :  * %GNUTLS_PRIVKEY_INFO_SIGN_ALGO. It must return -1 on unknown flags.
     751             :  *
     752             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     753             :  *   negative error value.
     754             :  *
     755             :  * Since: 3.4.0
     756             :  **/
     757             : int
     758           0 : gnutls_privkey_import_ext3(gnutls_privkey_t pkey,
     759             :                            void *userdata,
     760             :                            gnutls_privkey_sign_func sign_fn,
     761             :                            gnutls_privkey_decrypt_func decrypt_fn,
     762             :                            gnutls_privkey_deinit_func deinit_fn,
     763             :                            gnutls_privkey_info_func info_fn,
     764             :                            unsigned int flags)
     765             : {
     766           0 :         int ret;
     767             : 
     768           0 :         ret = check_if_clean(pkey);
     769           0 :         if (ret < 0) {
     770           0 :                 gnutls_assert();
     771           0 :                 return ret;
     772             :         }
     773             : 
     774           0 :         if (sign_fn == NULL && decrypt_fn == NULL)
     775           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     776             : 
     777           0 :         if (info_fn == NULL)
     778           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     779             : 
     780           0 :         pkey->key.ext.sign_func = sign_fn;
     781           0 :         pkey->key.ext.decrypt_func = decrypt_fn;
     782           0 :         pkey->key.ext.deinit_func = deinit_fn;
     783           0 :         pkey->key.ext.info_func = info_fn;
     784           0 :         pkey->key.ext.userdata = userdata;
     785           0 :         pkey->type = GNUTLS_PRIVKEY_EXT;
     786           0 :         pkey->flags = flags;
     787             : 
     788           0 :         pkey->pk_algorithm = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata);
     789             : 
     790           0 :         if (!PK_IS_OK_FOR_EXT2(pkey->pk_algorithm))
     791           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     792             : 
     793             :         /* Ensure gnutls_privkey_deinit() calls the deinit_func */
     794           0 :         if (deinit_fn)
     795           0 :                 pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
     796             : 
     797             :         return 0;
     798             : }
     799             : 
     800             : /**
     801             :  * gnutls_privkey_import_ext4:
     802             :  * @pkey: The private key
     803             :  * @userdata: private data to be provided to the callbacks
     804             :  * @sign_data_fn: callback for signature operations (may be %NULL)
     805             :  * @sign_hash_fn: callback for signature operations (may be %NULL)
     806             :  * @decrypt_fn: callback for decryption operations (may be %NULL)
     807             :  * @deinit_fn: a deinitialization function
     808             :  * @info_fn: returns info about the public key algorithm (should not be %NULL)
     809             :  * @flags: Flags for the import
     810             :  *
     811             :  * This function will associate the given callbacks with the
     812             :  * #gnutls_privkey_t type. At least one of the callbacks
     813             :  * must be non-null. If a deinitialization function is provided
     814             :  * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
     815             :  *
     816             :  * Note that in contrast with the signing function of
     817             :  * gnutls_privkey_import_ext3(), the signing functions provided to this
     818             :  * function take explicitly the signature algorithm as parameter and
     819             :  * different functions are provided to sign the data and hashes.
     820             :  *
     821             :  * The @sign_hash_fn is to be called to sign pre-hashed data. The input
     822             :  * to the callback is the output of the hash (such as SHA256) corresponding
     823             :  * to the signature algorithm. For RSA PKCS#1 signatures, the signature
     824             :  * algorithm can be set to %GNUTLS_SIGN_RSA_RAW, and in that case the data
     825             :  * should be handled as if they were an RSA PKCS#1 DigestInfo structure.
     826             :  *
     827             :  * The @sign_data_fn is to be called to sign data. The input data will be
     828             :  * he data to be signed (and hashed), with the provided signature
     829             :  * algorithm. This function is to be used for signature algorithms like
     830             :  * Ed25519 which cannot take pre-hashed data as input.
     831             :  *
     832             :  * When both @sign_data_fn and @sign_hash_fn functions are provided they
     833             :  * must be able to operate on all the supported signature algorithms,
     834             :  * unless prohibited by the type of the algorithm (e.g., as with Ed25519).
     835             :  *
     836             :  * The @info_fn must provide information on the signature algorithms supported by
     837             :  * this private key, and should support the flags %GNUTLS_PRIVKEY_INFO_PK_ALGO,
     838             :  * %GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO and %GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS.
     839             :  * It must return -1 on unknown flags.
     840             :  *
     841             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     842             :  *   negative error value.
     843             :  *
     844             :  * Since: 3.6.0
     845             :  **/
     846             : int
     847          24 : gnutls_privkey_import_ext4(gnutls_privkey_t pkey,
     848             :                            void *userdata,
     849             :                            gnutls_privkey_sign_data_func sign_data_fn,
     850             :                            gnutls_privkey_sign_hash_func sign_hash_fn,
     851             :                            gnutls_privkey_decrypt_func decrypt_fn,
     852             :                            gnutls_privkey_deinit_func deinit_fn,
     853             :                            gnutls_privkey_info_func info_fn,
     854             :                            unsigned int flags)
     855             : {
     856          24 :         int ret;
     857             : 
     858          24 :         ret = check_if_clean(pkey);
     859          24 :         if (ret < 0) {
     860           0 :                 gnutls_assert();
     861           0 :                 return ret;
     862             :         }
     863             : 
     864          24 :         if (sign_data_fn == NULL && sign_hash_fn == NULL && decrypt_fn == NULL)
     865           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     866             : 
     867          24 :         if (info_fn == NULL)
     868           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     869             : 
     870          24 :         pkey->key.ext.sign_data_func = sign_data_fn;
     871          24 :         pkey->key.ext.sign_hash_func = sign_hash_fn;
     872          24 :         pkey->key.ext.decrypt_func = decrypt_fn;
     873          24 :         pkey->key.ext.deinit_func = deinit_fn;
     874          24 :         pkey->key.ext.info_func = info_fn;
     875          24 :         pkey->key.ext.userdata = userdata;
     876          24 :         pkey->type = GNUTLS_PRIVKEY_EXT;
     877          24 :         pkey->flags = flags;
     878             : 
     879          24 :         pkey->pk_algorithm = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata);
     880             : 
     881          24 :         ret = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS, pkey->key.ext.userdata);
     882          24 :         if (ret >= 0)
     883          24 :                 pkey->key.ext.bits = ret;
     884             : 
     885             :         /* Ensure gnutls_privkey_deinit() calls the deinit_func */
     886          24 :         if (deinit_fn)
     887          24 :                 pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
     888             : 
     889             :         return 0;
     890             : }
     891             : 
     892             : /**
     893             :  * gnutls_privkey_import_x509:
     894             :  * @pkey: The private key
     895             :  * @key: The private key to be imported
     896             :  * @flags: Flags for the import
     897             :  *
     898             :  * This function will import the given private key to the abstract
     899             :  * #gnutls_privkey_t type.
     900             :  *
     901             :  * The #gnutls_x509_privkey_t object must not be deallocated
     902             :  * during the lifetime of this structure.
     903             :  *
     904             :  * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
     905             :  * and %GNUTLS_PRIVKEY_IMPORT_COPY.
     906             :  *
     907             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     908             :  *   negative error value.
     909             :  *
     910             :  * Since: 2.12.0
     911             :  **/
     912             : int
     913       11738 : gnutls_privkey_import_x509(gnutls_privkey_t pkey,
     914             :                            gnutls_x509_privkey_t key, unsigned int flags)
     915             : {
     916       11738 :         int ret;
     917             : 
     918       11738 :         ret = check_if_clean(pkey);
     919       11738 :         if (ret < 0) {
     920           0 :                 gnutls_assert();
     921           0 :                 return ret;
     922             :         }
     923             : 
     924       11738 :         if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) {
     925          33 :                 ret = gnutls_x509_privkey_init(&pkey->key.x509);
     926          33 :                 if (ret < 0)
     927           0 :                         return gnutls_assert_val(ret);
     928             : 
     929          33 :                 ret = gnutls_x509_privkey_cpy(pkey->key.x509, key);
     930          33 :                 if (ret < 0) {
     931           0 :                         gnutls_x509_privkey_deinit(pkey->key.x509);
     932           0 :                         return gnutls_assert_val(ret);
     933             :                 }
     934             :         } else
     935       11705 :                 pkey->key.x509 = key;
     936             : 
     937       11738 :         pkey->type = GNUTLS_PRIVKEY_X509;
     938       11738 :         pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm(key);
     939       11738 :         pkey->flags = flags;
     940             : 
     941       11738 :         return 0;
     942             : }
     943             : 
     944             : /**
     945             :  * gnutls_privkey_export_x509:
     946             :  * @pkey: The private key
     947             :  * @key: Location for the key to be exported.
     948             :  *
     949             :  * Converts the given abstract private key to a #gnutls_x509_privkey_t
     950             :  * type. The abstract key must be of type %GNUTLS_PRIVKEY_X509. The input
     951             :  * @key must not be initialized. The key returned in @key should be deinitialized
     952             :  * using gnutls_x509_privkey_deinit().
     953             :  *
     954             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     955             :  *   negative error value.
     956             :  *
     957             :  * Since: 3.4.0
     958             :  */
     959             : int
     960           7 : gnutls_privkey_export_x509(gnutls_privkey_t pkey,
     961             :                            gnutls_x509_privkey_t *key)
     962             : {
     963           7 :         int ret;
     964             : 
     965           7 :         if (pkey->type != GNUTLS_PRIVKEY_X509) {
     966           0 :                 gnutls_assert();
     967           0 :                 return GNUTLS_E_INVALID_REQUEST;
     968             :         }
     969             : 
     970           7 :         ret = gnutls_x509_privkey_init(key);
     971           7 :         if (ret < 0)
     972           0 :                 return gnutls_assert_val(ret);
     973             : 
     974           7 :         ret = gnutls_x509_privkey_cpy(*key, pkey->key.x509);
     975           7 :         if (ret < 0) {
     976           0 :                 gnutls_x509_privkey_deinit(*key);
     977           0 :                 *key = NULL;
     978             : 
     979           0 :                 return gnutls_assert_val(ret);
     980             :         }
     981             : 
     982             :         return 0;
     983             : }
     984             : 
     985             : /**
     986             :  * gnutls_privkey_generate:
     987             :  * @pkey: An initialized private key
     988             :  * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
     989             :  * @bits: the size of the parameters to generate
     990             :  * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
     991             :  *
     992             :  * This function will generate a random private key. Note that this
     993             :  * function must be called on an initialized private key.
     994             :  *
     995             :  * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
     996             :  * instructs the key generation process to use algorithms like Shawe-Taylor
     997             :  * (from FIPS PUB186-4) which generate provable parameters out of a seed
     998             :  * for RSA and DSA keys. See gnutls_privkey_generate2() for more
     999             :  * information.
    1000             :  *
    1001             :  * Note that when generating an elliptic curve key, the curve
    1002             :  * can be substituted in the place of the bits parameter using the
    1003             :  * GNUTLS_CURVE_TO_BITS() macro. The input to the macro is any curve from
    1004             :  * %gnutls_ecc_curve_t.
    1005             :  *
    1006             :  * For DSA keys, if the subgroup size needs to be specified check
    1007             :  * the GNUTLS_SUBGROUP_TO_BITS() macro.
    1008             :  *
    1009             :  * It is recommended to do not set the number of @bits directly, use gnutls_sec_param_to_pk_bits() instead .
    1010             :  *
    1011             :  * See also gnutls_privkey_generate2().
    1012             :  *
    1013             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1014             :  *   negative error value.
    1015             :  *
    1016             :  * Since: 3.3.0
    1017             :  **/
    1018             : int
    1019        1201 : gnutls_privkey_generate(gnutls_privkey_t pkey,
    1020             :                         gnutls_pk_algorithm_t algo, unsigned int bits,
    1021             :                         unsigned int flags)
    1022             : {
    1023        1201 :         return gnutls_privkey_generate2(pkey, algo, bits, flags, NULL, 0);
    1024             : }
    1025             : 
    1026             : /**
    1027             :  * gnutls_privkey_generate2:
    1028             :  * @pkey: The private key
    1029             :  * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
    1030             :  * @bits: the size of the modulus
    1031             :  * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
    1032             :  * @data: Allow specifying %gnutls_keygen_data_st types such as the seed to be used.
    1033             :  * @data_size: The number of @data available.
    1034             :  *
    1035             :  * This function will generate a random private key. Note that this
    1036             :  * function must be called on an initialized private key.
    1037             :  *
    1038             :  * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
    1039             :  * instructs the key generation process to use algorithms like Shawe-Taylor
    1040             :  * (from FIPS PUB186-4) which generate provable parameters out of a seed
    1041             :  * for RSA and DSA keys. On DSA keys the PQG parameters are generated using the
    1042             :  * seed, while on RSA the two primes. To specify an explicit seed
    1043             :  * (by default a random seed is used), use the @data with a %GNUTLS_KEYGEN_SEED
    1044             :  * type.
    1045             :  *
    1046             :  * Note that when generating an elliptic curve key, the curve
    1047             :  * can be substituted in the place of the bits parameter using the
    1048             :  * GNUTLS_CURVE_TO_BITS() macro.
    1049             :  *
    1050             :  * To export the generated keys in memory or in files it is recommended to use the
    1051             :  * PKCS#8 form as it can handle all key types, and can store additional parameters
    1052             :  * such as the seed, in case of provable RSA or DSA keys.
    1053             :  * Generated keys can be exported in memory using gnutls_privkey_export_x509(),
    1054             :  * and then with gnutls_x509_privkey_export2_pkcs8().
    1055             :  *
    1056             :  * If key generation is part of your application, avoid setting the number
    1057             :  * of bits directly, and instead use gnutls_sec_param_to_pk_bits().
    1058             :  * That way the generated keys will adapt to the security levels
    1059             :  * of the underlying GnuTLS library.
    1060             :  *
    1061             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1062             :  *   negative error value.
    1063             :  *
    1064             :  * Since: 3.5.0
    1065             :  **/
    1066             : int
    1067        1201 : gnutls_privkey_generate2(gnutls_privkey_t pkey,
    1068             :                          gnutls_pk_algorithm_t algo, unsigned int bits,
    1069             :                          unsigned int flags, const gnutls_keygen_data_st *data, unsigned data_size)
    1070             : {
    1071        1201 :         int ret;
    1072             : 
    1073        1201 :         ret = gnutls_x509_privkey_init(&pkey->key.x509);
    1074        1201 :         if (ret < 0)
    1075           0 :                 return gnutls_assert_val(ret);
    1076             : 
    1077        1201 :         ret = gnutls_x509_privkey_generate2(pkey->key.x509, algo, bits, flags, data, data_size);
    1078        1201 :         if (ret < 0) {
    1079           0 :                 gnutls_x509_privkey_deinit(pkey->key.x509);
    1080           0 :                 pkey->key.x509 = NULL;
    1081           0 :                 return gnutls_assert_val(ret);
    1082             :         }
    1083             : 
    1084        1201 :         pkey->type = GNUTLS_PRIVKEY_X509;
    1085        1201 :         pkey->pk_algorithm = algo;
    1086        1201 :         pkey->flags = flags | GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
    1087             : 
    1088        1201 :         return 0;
    1089             : }
    1090             : 
    1091             : /**
    1092             :  * gnutls_privkey_sign_data:
    1093             :  * @signer: Holds the key
    1094             :  * @hash: should be a digest algorithm
    1095             :  * @flags: Zero or one of %gnutls_privkey_flags_t
    1096             :  * @data: holds the data to be signed
    1097             :  * @signature: will contain the signature allocated with gnutls_malloc()
    1098             :  *
    1099             :  * This function will sign the given data using a signature algorithm
    1100             :  * supported by the private key. Signature algorithms are always used
    1101             :  * together with a hash functions.  Different hash functions may be
    1102             :  * used for the RSA algorithm, but only the SHA family for the DSA keys.
    1103             :  *
    1104             :  * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
    1105             :  * the hash algorithm.
    1106             :  *
    1107             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1108             :  * negative error value.
    1109             :  *
    1110             :  * Since: 2.12.0
    1111             :  **/
    1112             : int
    1113         237 : gnutls_privkey_sign_data(gnutls_privkey_t signer,
    1114             :                          gnutls_digest_algorithm_t hash,
    1115             :                          unsigned int flags,
    1116             :                          const gnutls_datum_t * data,
    1117             :                          gnutls_datum_t * signature)
    1118             : {
    1119         237 :         int ret;
    1120         237 :         gnutls_x509_spki_st params;
    1121             : 
    1122         237 :         if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
    1123           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1124             : 
    1125         237 :         ret = _gnutls_privkey_get_spki_params(signer, &params);
    1126         237 :         if (ret < 0) {
    1127           0 :                 gnutls_assert();
    1128           0 :                 return ret;
    1129             :         }
    1130             : 
    1131         237 :         ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm,
    1132             :                                                  hash, flags, &params);
    1133         237 :         if (ret < 0) {
    1134           0 :                 gnutls_assert();
    1135           0 :                 return ret;
    1136             :         }
    1137             : 
    1138         237 :         FIX_SIGN_PARAMS(params, flags, hash);
    1139             : 
    1140         237 :         return privkey_sign_and_hash_data(signer, _gnutls_pk_to_sign_entry(params.pk, hash), data, signature, &params);
    1141             : }
    1142             : 
    1143             : /**
    1144             :  * gnutls_privkey_sign_data2:
    1145             :  * @signer: Holds the key
    1146             :  * @algo: The signature algorithm used
    1147             :  * @flags: Zero or one of %gnutls_privkey_flags_t
    1148             :  * @data: holds the data to be signed
    1149             :  * @signature: will contain the signature allocated with gnutls_malloc()
    1150             :  *
    1151             :  * This function will sign the given data using the specified signature
    1152             :  * algorithm. This function is an enhancement of gnutls_privkey_sign_data(),
    1153             :  * as it allows utilizing a alternative signature algorithm where possible
    1154             :  * (e.g, use an RSA key with RSA-PSS).
    1155             :  *
    1156             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1157             :  * negative error value.
    1158             :  *
    1159             :  * Since: 3.6.0
    1160             :  **/
    1161             : int
    1162       17341 : gnutls_privkey_sign_data2(gnutls_privkey_t signer,
    1163             :                           gnutls_sign_algorithm_t algo,
    1164             :                           unsigned int flags,
    1165             :                           const gnutls_datum_t * data,
    1166             :                           gnutls_datum_t * signature)
    1167             : {
    1168       17341 :         int ret;
    1169       17341 :         gnutls_x509_spki_st params;
    1170       17341 :         const gnutls_sign_entry_st *se;
    1171             : 
    1172       17341 :         if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
    1173           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1174             : 
    1175       17341 :         se = _gnutls_sign_to_entry(algo);
    1176       17341 :         if (se == NULL)
    1177        4071 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1178             : 
    1179       13270 :         ret = _gnutls_privkey_get_spki_params(signer, &params);
    1180       13270 :         if (ret < 0) {
    1181           0 :                 gnutls_assert();
    1182           0 :                 return ret;
    1183             :         }
    1184             : 
    1185       13270 :         ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash,
    1186             :                                                  flags, &params);
    1187       13270 :         if (ret < 0) {
    1188           7 :                 gnutls_assert();
    1189           7 :                 return ret;
    1190             :         }
    1191             : 
    1192       13263 :         FIX_SIGN_PARAMS(params, flags, se->hash);
    1193             : 
    1194       13263 :         return privkey_sign_and_hash_data(signer, se, data, signature, &params);
    1195             : }
    1196             : 
    1197             : /**
    1198             :  * gnutls_privkey_sign_hash2:
    1199             :  * @signer: Holds the signer's key
    1200             :  * @algo: The signature algorithm used
    1201             :  * @flags: Zero or one of %gnutls_privkey_flags_t
    1202             :  * @hash_data: holds the data to be signed
    1203             :  * @signature: will contain newly allocated signature
    1204             :  *
    1205             :  * This function will sign the given hashed data using the specified signature
    1206             :  * algorithm. This function is an enhancement of gnutls_privkey_sign_hash(),
    1207             :  * as it allows utilizing a alternative signature algorithm where possible
    1208             :  * (e.g, use an RSA key with RSA-PSS).
    1209             :  *
    1210             :  * The flags may be %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA.
    1211             :  * In that case this function will ignore @hash_algo and perform a raw PKCS1 signature.
    1212             :  * Note that this flag is supported since 3.6.9.
    1213             :  *
    1214             :  * Note also that, not all algorithm support signing already hashed data. When
    1215             :  * signing with Ed25519, gnutls_privkey_sign_data2() should be used instead.
    1216             :  *
    1217             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1218             :  *   negative error value.
    1219             :  *
    1220             :  * Since: 3.6.0
    1221             :  **/
    1222             : int
    1223          30 : gnutls_privkey_sign_hash2(gnutls_privkey_t signer,
    1224             :                           gnutls_sign_algorithm_t algo,
    1225             :                           unsigned int flags,
    1226             :                           const gnutls_datum_t * hash_data,
    1227             :                           gnutls_datum_t * signature)
    1228             : {
    1229          30 :         int ret;
    1230          30 :         gnutls_x509_spki_st params;
    1231          30 :         const gnutls_sign_entry_st *se;
    1232             : 
    1233          30 :         if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA) {
    1234             :                 /* the corresponding signature algorithm is SIGN_RSA_RAW,
    1235             :                  * irrespective of hash algorithm. */
    1236           1 :                 se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
    1237             :         } else {
    1238          29 :                 se = _gnutls_sign_to_entry(algo);
    1239          29 :                 if (unlikely(se == NULL))
    1240           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1241             : 
    1242             :         }
    1243             : 
    1244          30 :         ret = _gnutls_privkey_get_spki_params(signer, &params);
    1245          30 :         if (ret < 0) {
    1246           0 :                 gnutls_assert();
    1247           0 :                 return ret;
    1248             :         }
    1249             : 
    1250          30 :         ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash,
    1251             :                                                  flags, &params);
    1252          30 :         if (ret < 0) {
    1253           0 :                 gnutls_assert();
    1254           0 :                 return ret;
    1255             :         }
    1256             : 
    1257          30 :         FIX_SIGN_PARAMS(params, flags, se->hash);
    1258             : 
    1259          30 :         return privkey_sign_prehashed(signer, se, hash_data, signature, &params);
    1260             : }
    1261             : 
    1262             : int
    1263       13621 : privkey_sign_and_hash_data(gnutls_privkey_t signer,
    1264             :                            const gnutls_sign_entry_st *se,
    1265             :                            const gnutls_datum_t * data,
    1266             :                            gnutls_datum_t * signature,
    1267             :                            gnutls_x509_spki_st * params)
    1268             : {
    1269       13621 :         int ret;
    1270       13621 :         gnutls_datum_t digest;
    1271       13621 :         const mac_entry_st *me;
    1272             : 
    1273       13621 :         if (unlikely(se == NULL))
    1274           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1275             : 
    1276       13621 :         if (_gnutls_pk_is_not_prehashed(se->pk)) {
    1277          55 :                 return privkey_sign_raw_data(signer, se, data, signature, params);
    1278             :         }
    1279             : 
    1280       13566 :         me = hash_to_entry(se->hash);
    1281       13566 :         if (me == NULL)
    1282           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1283             : 
    1284       13566 :         ret = pk_hash_data(se->pk, me, NULL, data, &digest);
    1285       13566 :         if (ret < 0) {
    1286           0 :                 gnutls_assert();
    1287           0 :                 return ret;
    1288             :         }
    1289             : 
    1290       13566 :         ret = pk_prepare_hash(se->pk, me, &digest);
    1291       13566 :         if (ret < 0) {
    1292           0 :                 gnutls_assert();
    1293           0 :                 goto cleanup;
    1294             :         }
    1295             : 
    1296       13566 :         ret = privkey_sign_raw_data(signer, se, &digest, signature, params);
    1297       13566 :         _gnutls_free_datum(&digest);
    1298             : 
    1299       13566 :         if (ret < 0) {
    1300           2 :                 gnutls_assert();
    1301           2 :                 return ret;
    1302             :         }
    1303             : 
    1304             :         return 0;
    1305             : 
    1306           0 :  cleanup:
    1307           0 :         _gnutls_free_datum(&digest);
    1308           0 :         return ret;
    1309             : }
    1310             : 
    1311             : 
    1312             : /**
    1313             :  * gnutls_privkey_sign_hash:
    1314             :  * @signer: Holds the signer's key
    1315             :  * @hash_algo: The hash algorithm used
    1316             :  * @flags: Zero or one of %gnutls_privkey_flags_t
    1317             :  * @hash_data: holds the data to be signed
    1318             :  * @signature: will contain newly allocated signature
    1319             :  *
    1320             :  * This function will sign the given hashed data using a signature algorithm
    1321             :  * supported by the private key. Signature algorithms are always used
    1322             :  * together with a hash functions.  Different hash functions may be
    1323             :  * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
    1324             :  *
    1325             :  * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
    1326             :  * the hash algorithm.
    1327             :  *
    1328             :  * The flags may be %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA or %GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS.
    1329             :  * In the former case this function will ignore @hash_algo and perform a raw PKCS1 signature,
    1330             :  * and in the latter an RSA-PSS signature will be generated.
    1331             :  *
    1332             :  * Note that, not all algorithm support signing already hashed data. When
    1333             :  * signing with Ed25519, gnutls_privkey_sign_data() should be used.
    1334             :  *
    1335             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1336             :  *   negative error value.
    1337             :  *
    1338             :  * Since: 2.12.0
    1339             :  **/
    1340             : int
    1341        2976 : gnutls_privkey_sign_hash(gnutls_privkey_t signer,
    1342             :                          gnutls_digest_algorithm_t hash_algo,
    1343             :                          unsigned int flags,
    1344             :                          const gnutls_datum_t * hash_data,
    1345             :                          gnutls_datum_t * signature)
    1346             : {
    1347        2976 :         int ret;
    1348        2976 :         gnutls_x509_spki_st params;
    1349        2976 :         const gnutls_sign_entry_st *se;
    1350             : 
    1351        2976 :         ret = _gnutls_privkey_get_spki_params(signer, &params);
    1352        2976 :         if (ret < 0) {
    1353           0 :                 gnutls_assert();
    1354           0 :                 return ret;
    1355             :         }
    1356             : 
    1357        2976 :         ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm,
    1358             :                                                hash_algo, flags, &params);
    1359        2976 :         if (ret < 0) {
    1360           0 :                 gnutls_assert();
    1361           0 :                 return ret;
    1362             :         }
    1363             : 
    1364             :         /* legacy callers of this API could use a hash algorithm of 0 (unknown)
    1365             :          * to indicate raw hashing. As we now always want to know the signing
    1366             :          * algorithm involved, we try discovering the hash algorithm. */
    1367        2976 :         if (hash_algo == 0 && (params.pk == GNUTLS_PK_DSA || params.pk == GNUTLS_PK_ECDSA)) {
    1368          10 :                 hash_algo = _gnutls_hash_size_to_sha_hash(hash_data->size);
    1369             :         }
    1370             : 
    1371        2976 :         if (params.pk == GNUTLS_PK_RSA && (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)) {
    1372             :                 /* the corresponding signature algorithm is SIGN_RSA_RAW,
    1373             :                  * irrespective of hash algorithm. */
    1374        1641 :                 se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
    1375             :         } else {
    1376        1335 :                 se = _gnutls_pk_to_sign_entry(params.pk, hash_algo);
    1377             :         }
    1378             : 
    1379        2976 :         if (unlikely(se == NULL))
    1380           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1381             : 
    1382        2976 :         FIX_SIGN_PARAMS(params, flags, hash_algo);
    1383             : 
    1384        2976 :         return privkey_sign_prehashed(signer, se,
    1385             :                                       hash_data, signature, &params);
    1386             : }
    1387             : 
    1388             : static int
    1389        3006 : privkey_sign_prehashed(gnutls_privkey_t signer,
    1390             :                        const gnutls_sign_entry_st *se,
    1391             :                        const gnutls_datum_t * hash_data,
    1392             :                        gnutls_datum_t * signature,
    1393             :                        gnutls_x509_spki_st * params)
    1394             : {
    1395        3006 :         int ret;
    1396        3006 :         gnutls_datum_t digest;
    1397             : 
    1398        3006 :         if (unlikely(se == NULL))
    1399           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1400             : 
    1401        3006 :         if (se->id == GNUTLS_SIGN_RSA_RAW) {
    1402        1642 :                 return privkey_sign_raw_data(signer,
    1403             :                                              se,
    1404             :                                              hash_data, signature,
    1405             :                                              params);
    1406             :         }
    1407             : 
    1408        1364 :         if (_gnutls_pk_is_not_prehashed(signer->pk_algorithm)) {
    1409           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1410             :         }
    1411             : 
    1412        1364 :         digest.data = gnutls_malloc(hash_data->size);
    1413        1364 :         if (digest.data == NULL) {
    1414           0 :                 gnutls_assert();
    1415           0 :                 return GNUTLS_E_MEMORY_ERROR;
    1416             :         }
    1417        1364 :         digest.size = hash_data->size;
    1418        1364 :         memcpy(digest.data, hash_data->data, digest.size);
    1419             : 
    1420        1364 :         ret = pk_prepare_hash(se->pk, hash_to_entry(se->hash), &digest);
    1421        1364 :         if (ret < 0) {
    1422           0 :                 gnutls_assert();
    1423           0 :                 goto cleanup;
    1424             :         }
    1425             : 
    1426        1364 :         ret = privkey_sign_raw_data(signer,
    1427             :                                     se,
    1428             :                                     &digest, signature,
    1429             :                                     params);
    1430        1364 :         if (ret < 0) {
    1431           2 :                 gnutls_assert();
    1432           2 :                 goto cleanup;
    1433             :         }
    1434             : 
    1435             :         ret = 0;
    1436             : 
    1437        1364 :  cleanup:
    1438        1364 :         _gnutls_free_datum(&digest);
    1439        1364 :         return ret;
    1440             : }
    1441             : 
    1442             : /*-
    1443             :  * privkey_sign_raw_data:
    1444             :  * @key: Holds the key
    1445             :  * @data: holds the data to be signed
    1446             :  * @signature: will contain the signature allocated with gnutls_malloc()
    1447             :  * @params: holds the signing parameters
    1448             :  *
    1449             :  * This function will sign the given data using a signature algorithm
    1450             :  * supported by the private key. Note that this is a low-level function
    1451             :  * and does not apply any preprocessing or hash on the signed data. 
    1452             :  * For example on an RSA key the input @data should be of the DigestInfo
    1453             :  * PKCS #1 1.5 format, on RSA-PSS, DSA or ECDSA the input should be a hash output
    1454             :  * and on Ed25519 the raw data to be signed.
    1455             :  *
    1456             :  * Note this function is equivalent to using the %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA
    1457             :  * flag with gnutls_privkey_sign_hash().
    1458             :  *
    1459             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1460             :  * negative error value.
    1461             :  *
    1462             :  * Since: 3.1.10
    1463             :  -*/
    1464             : int
    1465       16628 : privkey_sign_raw_data(gnutls_privkey_t key,
    1466             :                       const gnutls_sign_entry_st *se,
    1467             :                       const gnutls_datum_t * data,
    1468             :                       gnutls_datum_t * signature,
    1469             :                       gnutls_x509_spki_st * params)
    1470             : {
    1471       16628 :         if (unlikely(se == NULL))
    1472           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1473             : 
    1474       16628 :         switch (key->type) {
    1475             : #ifdef ENABLE_PKCS11
    1476         249 :         case GNUTLS_PRIVKEY_PKCS11:
    1477         249 :                 return _gnutls_pkcs11_privkey_sign(key->key.pkcs11, se,
    1478             :                                                    data, signature,
    1479             :                                                    params);
    1480             : #endif
    1481       16309 :         case GNUTLS_PRIVKEY_X509:
    1482       16309 :                 return _gnutls_pk_sign(se->pk, signature, data,
    1483             :                                        &key->key.x509->params, params);
    1484          70 :         case GNUTLS_PRIVKEY_EXT:
    1485          70 :                 if (unlikely(key->key.ext.sign_data_func == NULL &&
    1486             :                         key->key.ext.sign_hash_func == NULL &&
    1487             :                         key->key.ext.sign_func == NULL))
    1488           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1489             : 
    1490          70 :                 if (_gnutls_pk_is_not_prehashed(se->pk)) {
    1491           3 :                         if (!key->key.ext.sign_data_func)
    1492           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1493             : 
    1494           3 :                         return key->key.ext.sign_data_func(key, se->id,
    1495             :                                                            key->key.ext.userdata,
    1496             :                                                            0,
    1497             :                                                            data, signature);
    1498          67 :                 } else if (key->key.ext.sign_hash_func) {
    1499          39 :                         if (se->pk == GNUTLS_PK_RSA) {
    1500          15 :                                 se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
    1501          15 :                                 assert(se != NULL);
    1502             :                         }
    1503             : 
    1504             :                         /* se may not be set here if we are doing legacy RSA */
    1505          39 :                         return key->key.ext.sign_hash_func(key, se->id,
    1506             :                                                            key->key.ext.userdata,
    1507             :                                                            0,
    1508             :                                                            data, signature);
    1509             :                 } else {
    1510          28 :                         if (!PK_IS_OK_FOR_EXT2(se->pk))
    1511           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1512             : 
    1513          28 :                         return key->key.ext.sign_func(key, key->key.ext.userdata,
    1514             :                                                       data, signature);
    1515             :                 }
    1516           0 :         default:
    1517           0 :                 gnutls_assert();
    1518             :                 return GNUTLS_E_INVALID_REQUEST;
    1519             :         }
    1520             : }
    1521             : 
    1522             : /**
    1523             :  * gnutls_privkey_decrypt_data:
    1524             :  * @key: Holds the key
    1525             :  * @flags: zero for now
    1526             :  * @ciphertext: holds the data to be decrypted
    1527             :  * @plaintext: will contain the decrypted data, allocated with gnutls_malloc()
    1528             :  *
    1529             :  * This function will decrypt the given data using the algorithm
    1530             :  * supported by the private key.
    1531             :  *
    1532             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1533             :  * negative error value.
    1534             :  *
    1535             :  * Since: 2.12.0
    1536             :  **/
    1537             : int
    1538          29 : gnutls_privkey_decrypt_data(gnutls_privkey_t key,
    1539             :                             unsigned int flags,
    1540             :                             const gnutls_datum_t * ciphertext,
    1541             :                             gnutls_datum_t * plaintext)
    1542             : {
    1543          29 :         switch (key->type) {
    1544          29 :         case GNUTLS_PRIVKEY_X509:
    1545          29 :                 return _gnutls_pk_decrypt(key->pk_algorithm, plaintext,
    1546             :                                           ciphertext, &key->key.x509->params);
    1547             : #ifdef ENABLE_PKCS11
    1548           0 :         case GNUTLS_PRIVKEY_PKCS11:
    1549           0 :                 return _gnutls_pkcs11_privkey_decrypt_data(key->key.pkcs11,
    1550             :                                                            flags,
    1551             :                                                            ciphertext,
    1552             :                                                            plaintext);
    1553             : #endif
    1554           0 :         case GNUTLS_PRIVKEY_EXT:
    1555           0 :                 if (key->key.ext.decrypt_func == NULL)
    1556           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1557             : 
    1558           0 :                 return key->key.ext.decrypt_func(key,
    1559             :                                                  key->key.ext.userdata,
    1560             :                                                  ciphertext, plaintext);
    1561           0 :         default:
    1562           0 :                 gnutls_assert();
    1563             :                 return GNUTLS_E_INVALID_REQUEST;
    1564             :         }
    1565             : }
    1566             : 
    1567             : /**
    1568             :  * gnutls_privkey_decrypt_data2:
    1569             :  * @key: Holds the key
    1570             :  * @flags: zero for now
    1571             :  * @ciphertext: holds the data to be decrypted
    1572             :  * @plaintext: a preallocated buffer that will be filled with the plaintext
    1573             :  * @plaintext_size: in/out size of the plaintext
    1574             :  *
    1575             :  * This function will decrypt the given data using the algorithm
    1576             :  * supported by the private key. Unlike with gnutls_privkey_decrypt_data()
    1577             :  * this function operates in constant time and constant memory access.
    1578             :  *
    1579             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1580             :  * negative error value.
    1581             :  *
    1582             :  * Since: 3.6.5
    1583             :  **/
    1584             : 
    1585             : int
    1586        1859 : gnutls_privkey_decrypt_data2(gnutls_privkey_t key,
    1587             :                              unsigned int flags,
    1588             :                              const gnutls_datum_t * ciphertext,
    1589             :                              unsigned char * plaintext,
    1590             :                              size_t plaintext_size)
    1591             : {
    1592             :         /* Note: except for the backwards compatibility function, no
    1593             :          * conditional code should be called after the decryption
    1594             :          * function call, to avoid creating oracle attacks based
    1595             :          * on cache/timing side channels */
    1596             : 
    1597             :         /* backwards compatibility */
    1598        1859 :         if (key->type == GNUTLS_PRIVKEY_EXT &&
    1599           2 :             key->key.ext.decrypt_func2 == NULL &&
    1600           2 :             key->key.ext.decrypt_func != NULL) {
    1601           2 :                 gnutls_datum_t plain;
    1602           2 :                 int ret;
    1603           2 :                 ret = key->key.ext.decrypt_func(key,
    1604             :                                                 key->key.ext.userdata,
    1605             :                                                 ciphertext,
    1606             :                                                 &plain);
    1607           2 :                 if (plain.size != plaintext_size) {
    1608           0 :                         ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1609             :                 } else {
    1610           2 :                         memcpy(plaintext, plain.data, plain.size);
    1611             :                 }
    1612           2 :                 gnutls_free(plain.data);
    1613           2 :                 return ret;
    1614             :         }
    1615             : 
    1616        1857 :         switch (key->type) {
    1617        1855 :         case GNUTLS_PRIVKEY_X509:
    1618        1855 :                 return _gnutls_pk_decrypt2(key->pk_algorithm, ciphertext,
    1619             :                                            plaintext, plaintext_size,
    1620             :                                            &key->key.x509->params);
    1621             : #ifdef ENABLE_PKCS11
    1622           2 :         case GNUTLS_PRIVKEY_PKCS11:
    1623           2 :                 return _gnutls_pkcs11_privkey_decrypt_data2(key->key.pkcs11,
    1624             :                                                             flags,
    1625             :                                                             ciphertext,
    1626             :                                                             plaintext,
    1627             :                                                             plaintext_size);
    1628             : #endif
    1629           0 :         case GNUTLS_PRIVKEY_EXT:
    1630           0 :                 if (key->key.ext.decrypt_func2 == NULL)
    1631           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1632             : 
    1633           0 :                 return key->key.ext.decrypt_func2(key,
    1634             :                                                   key->key.ext.userdata,
    1635             :                                                   ciphertext, plaintext,
    1636             :                                                   plaintext_size);
    1637           0 :         default:
    1638           0 :                 gnutls_assert();
    1639             :                 return GNUTLS_E_INVALID_REQUEST;
    1640             :         }
    1641             : }
    1642             : 
    1643             : /**
    1644             :  * gnutls_privkey_import_x509_raw:
    1645             :  * @pkey: The private key
    1646             :  * @data: The private key data to be imported
    1647             :  * @format: The format of the private key
    1648             :  * @password: A password (optional)
    1649             :  * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
    1650             :  *
    1651             :  * This function will import the given private key to the abstract
    1652             :  * #gnutls_privkey_t type. 
    1653             :  *
    1654             :  * The supported formats are basic unencrypted key, PKCS8, PKCS12, 
    1655             :  * and the openssl format.
    1656             :  *
    1657             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1658             :  *   negative error value.
    1659             :  *
    1660             :  * Since: 3.1.0
    1661             :  **/
    1662       11602 : int gnutls_privkey_import_x509_raw(gnutls_privkey_t pkey,
    1663             :                                    const gnutls_datum_t * data,
    1664             :                                    gnutls_x509_crt_fmt_t format,
    1665             :                                    const char *password, unsigned int flags)
    1666             : {
    1667       11602 :         gnutls_x509_privkey_t xpriv;
    1668       11602 :         int ret;
    1669             : 
    1670       11602 :         ret = gnutls_x509_privkey_init(&xpriv);
    1671       11602 :         if (ret < 0)
    1672           0 :                 return gnutls_assert_val(ret);
    1673             : 
    1674       11602 :         if (pkey->pin.cb) {
    1675          85 :                 gnutls_x509_privkey_set_pin_function(xpriv, pkey->pin.cb,
    1676             :                                                      pkey->pin.data);
    1677             :         }
    1678             : 
    1679       11602 :         ret = gnutls_x509_privkey_import2(xpriv, data, format, password, flags);
    1680       11602 :         if (ret < 0) {
    1681           1 :                 gnutls_assert();
    1682           1 :                 goto cleanup;
    1683             :         }
    1684             : 
    1685       11601 :         ret =
    1686       11601 :             gnutls_privkey_import_x509(pkey, xpriv,
    1687             :                                        GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
    1688       11601 :         if (ret < 0) {
    1689           0 :                 gnutls_assert();
    1690           0 :                 goto cleanup;
    1691             :         }
    1692             : 
    1693             :         return 0;
    1694             : 
    1695           1 :  cleanup:
    1696           1 :         gnutls_x509_privkey_deinit(xpriv);
    1697             : 
    1698           1 :         return ret;
    1699             : }
    1700             : 
    1701             : /**
    1702             :  * gnutls_privkey_import_url:
    1703             :  * @key: A key of type #gnutls_privkey_t
    1704             :  * @url: A PKCS 11 url
    1705             :  * @flags: should be zero
    1706             :  *
    1707             :  * This function will import a PKCS11 or TPM URL as a
    1708             :  * private key. The supported URL types can be checked
    1709             :  * using gnutls_url_is_supported().
    1710             :  *
    1711             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1712             :  *   negative error value.
    1713             :  *
    1714             :  * Since: 3.1.0
    1715             :  **/
    1716             : int
    1717          76 : gnutls_privkey_import_url(gnutls_privkey_t key, const char *url,
    1718             :                           unsigned int flags)
    1719             : {
    1720          76 :         unsigned i;
    1721          76 :         int ret;
    1722             : 
    1723          76 :         for (i=0;i<_gnutls_custom_urls_size;i++) {
    1724           0 :                 if (strncmp(url, _gnutls_custom_urls[i].name, _gnutls_custom_urls[i].name_size) == 0) {
    1725           0 :                         if (_gnutls_custom_urls[i].import_key) {
    1726           0 :                                 ret = _gnutls_custom_urls[i].import_key(key, url, flags);
    1727           0 :                                 goto cleanup;
    1728             :                         }
    1729             :                         break;
    1730             :                 }
    1731             :         }
    1732             : 
    1733          76 :         if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
    1734             : #ifdef ENABLE_PKCS11
    1735          71 :                 ret = _gnutls_privkey_import_pkcs11_url(key, url, flags);
    1736             : #else
    1737             :                 ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
    1738             : #endif
    1739          71 :                 goto cleanup;
    1740             :         }
    1741             : 
    1742           5 :         if (strncmp(url, TPMKEY_URL, TPMKEY_URL_SIZE) == 0) {
    1743             : #ifdef HAVE_TROUSERS
    1744           5 :                 ret = gnutls_privkey_import_tpm_url(key, url, NULL, NULL, 0);
    1745             : #else
    1746             :                 ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
    1747             : #endif
    1748           5 :                 goto cleanup;
    1749             :         }
    1750             : 
    1751           0 :         if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
    1752           0 :                 ret = _gnutls_privkey_import_system_url(key, url);
    1753           0 :                 goto cleanup;
    1754             :         }
    1755             : 
    1756           0 :         ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    1757          76 :  cleanup:
    1758          76 :         return ret;
    1759             : }
    1760             : 
    1761             : /**
    1762             :  * gnutls_privkey_set_pin_function:
    1763             :  * @key: A key of type #gnutls_privkey_t
    1764             :  * @fn: the callback
    1765             :  * @userdata: data associated with the callback
    1766             :  *
    1767             :  * This function will set a callback function to be used when
    1768             :  * required to access the object. This function overrides any other
    1769             :  * global PIN functions.
    1770             :  *
    1771             :  * Note that this function must be called right after initialization
    1772             :  * to have effect.
    1773             :  *
    1774             :  * Since: 3.1.0
    1775             :  *
    1776             :  **/
    1777          97 : void gnutls_privkey_set_pin_function(gnutls_privkey_t key,
    1778             :                                      gnutls_pin_callback_t fn, void *userdata)
    1779             : {
    1780          97 :         key->pin.cb = fn;
    1781          97 :         key->pin.data = userdata;
    1782          97 : }
    1783             : 
    1784             : /**
    1785             :  * gnutls_privkey_set_flags:
    1786             :  * @key: A key of type #gnutls_privkey_t
    1787             :  * @flags: flags from the %gnutls_privkey_flags
    1788             :  *
    1789             :  * This function will set flags for the specified private key, after
    1790             :  * it is generated. Currently this is useful for the %GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT
    1791             :  * to allow exporting a "provable" private key in backwards compatible way.
    1792             :  *
    1793             :  * Since: 3.5.0
    1794             :  *
    1795             :  **/
    1796           0 : void gnutls_privkey_set_flags(gnutls_privkey_t key,
    1797             :                               unsigned int flags)
    1798             : {
    1799           0 :         key->flags |= flags;
    1800           0 :         if (key->type == GNUTLS_PRIVKEY_X509)
    1801           0 :                 gnutls_x509_privkey_set_flags(key->key.x509, flags);
    1802           0 : }
    1803             : 
    1804             : /**
    1805             :  * gnutls_privkey_status:
    1806             :  * @key: Holds the key
    1807             :  *
    1808             :  * Checks the status of the private key token. This function
    1809             :  * is an actual wrapper over gnutls_pkcs11_privkey_status(), and
    1810             :  * if the private key is a PKCS #11 token it will check whether
    1811             :  * it is inserted or not.
    1812             :  *
    1813             :  * Returns: this function will return non-zero if the token 
    1814             :  * holding the private key is still available (inserted), and zero otherwise.
    1815             :  * 
    1816             :  * Since: 3.1.10
    1817             :  *
    1818             :  **/
    1819           0 : int gnutls_privkey_status(gnutls_privkey_t key)
    1820             : {
    1821           0 :         switch (key->type) {
    1822             : #ifdef ENABLE_PKCS11
    1823           0 :         case GNUTLS_PRIVKEY_PKCS11:
    1824           0 :                 return gnutls_pkcs11_privkey_status(key->key.pkcs11);
    1825             : #endif
    1826             :         default:
    1827             :                 return 1;
    1828             :         }
    1829             : }
    1830             : 
    1831             : /**
    1832             :  * gnutls_privkey_verify_params:
    1833             :  * @key: should contain a #gnutls_privkey_t type
    1834             :  *
    1835             :  * This function will verify the private key parameters.
    1836             :  *
    1837             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1838             :  *   negative error value.
    1839             :  *
    1840             :  * Since: 3.3.0
    1841             :  **/
    1842           3 : int gnutls_privkey_verify_params(gnutls_privkey_t key)
    1843             : {
    1844           3 :         gnutls_pk_params_st params;
    1845           3 :         int ret;
    1846             : 
    1847           3 :         gnutls_pk_params_init(&params);
    1848             : 
    1849           3 :         ret = _gnutls_privkey_get_mpis(key, &params);
    1850           3 :         if (ret < 0)
    1851           0 :                 return gnutls_assert_val(ret);
    1852             : 
    1853           3 :         ret = _gnutls_pk_verify_priv_params(key->pk_algorithm, &params);
    1854             : 
    1855           3 :         gnutls_pk_params_release(&params);
    1856             : 
    1857           3 :         if (ret < 0) {
    1858           1 :                 gnutls_assert();
    1859           1 :                 return ret;
    1860             :         }
    1861             : 
    1862             :         return 0;
    1863             : }
    1864             : 
    1865             : /**
    1866             :  * gnutls_privkey_get_spki:
    1867             :  * @privkey: a public key of type #gnutls_privkey_t
    1868             :  * @spki: a SubjectPublicKeyInfo structure of type #gnutls_privkey_spki_t
    1869             :  * @flags: must be zero
    1870             :  *
    1871             :  * This function will return the public key information if available.
    1872             :  * The provided @spki must be initialized.
    1873             :  *
    1874             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1875             :  *   negative error value.
    1876             :  *
    1877             :  * Since: 3.6.0
    1878             :  **/
    1879             : int
    1880          13 : gnutls_privkey_get_spki(gnutls_privkey_t privkey, gnutls_x509_spki_t spki, unsigned int flags)
    1881             : {
    1882          13 :         gnutls_x509_spki_t p = &privkey->key.x509->params.spki;
    1883             : 
    1884          13 :         if (privkey == NULL || privkey->type != GNUTLS_PRIVKEY_X509) {
    1885           0 :                 gnutls_assert();
    1886           0 :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    1887             :         }
    1888             : 
    1889          13 :         if (p->pk == GNUTLS_PK_UNKNOWN)
    1890           0 :                 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
    1891             : 
    1892          13 :         memcpy(spki, p, sizeof(gnutls_x509_spki_st));
    1893             : 
    1894          13 :         return 0;
    1895             : }
    1896             : 
    1897             : /**
    1898             :  * gnutls_privkey_set_spki:
    1899             :  * @privkey: a public key of type #gnutls_privkey_t
    1900             :  * @spki: a SubjectPublicKeyInfo structure of type #gnutls_privkey_spki_t
    1901             :  * @flags: must be zero
    1902             :  *
    1903             :  * This function will set the public key information.
    1904             :  * The provided @spki must be initialized.
    1905             :  *
    1906             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
    1907             :  *   negative error value.
    1908             :  *
    1909             :  * Since: 3.6.0
    1910             :  **/
    1911             : int
    1912           1 : gnutls_privkey_set_spki(gnutls_privkey_t privkey, const gnutls_x509_spki_t spki, unsigned int flags)
    1913             : {
    1914           1 :         if (privkey == NULL || privkey->type != GNUTLS_PRIVKEY_X509) {
    1915           0 :                 gnutls_assert();
    1916           0 :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    1917             :         }
    1918             : 
    1919           1 :         return gnutls_x509_privkey_set_spki(privkey->key.x509, spki, flags);
    1920             : }
    1921             : 
    1922             : /* Checks whether the public key given is compatible with the
    1923             :  * signature algorithm used. The session is only used for audit logging, and
    1924             :  * it may be null.
    1925             :  */
    1926       87402 : unsigned _gnutls_privkey_compatible_with_sig(gnutls_privkey_t privkey,
    1927             :                                              gnutls_sign_algorithm_t sign)
    1928             : {
    1929       87402 :         const gnutls_sign_entry_st *se;
    1930             : 
    1931       87402 :         se = _gnutls_sign_to_entry(sign);
    1932       87402 :         if (unlikely(se == NULL))
    1933           0 :                 return gnutls_assert_val(0);
    1934             : 
    1935             :         /* Prevent RSA-PSS private keys from negotiating an RSA signature,
    1936             :          * and RSA keys which cannot do RSA-PSS (e.g., smart card) from
    1937             :          * negotiating RSA-PSS sig.
    1938             :          */
    1939             : 
    1940       87402 :         if (se->pk != privkey->pk_algorithm) { /* if the PK algorithm of the signature differs to the one on the pubkey */
    1941       65317 :                 if (!sign_supports_priv_pk_algorithm(se, privkey->pk_algorithm)) {
    1942       57862 :                         _gnutls_handshake_log("cannot use privkey of %s with %s\n",
    1943             :                                               gnutls_pk_get_name(privkey->pk_algorithm), se->name);
    1944       57862 :                         return 0;
    1945             :                 }
    1946             :         }
    1947             : 
    1948       29540 :         if (privkey->type == GNUTLS_PRIVKEY_EXT) {
    1949         430 :                 if (privkey->key.ext.info_func) {
    1950         330 :                         int ret;
    1951             : 
    1952         660 :                         ret = privkey->key.ext.info_func(privkey,
    1953         330 :                                                      GNUTLS_SIGN_ALGO_TO_FLAGS(sign)|GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO,
    1954             :                                                      privkey->key.ext.userdata);
    1955         330 :                         if (ret != -1)
    1956         330 :                                 return ret;
    1957             : 
    1958             :                         /* use the old flag */
    1959           0 :                         ret = privkey->key.ext.info_func(privkey, GNUTLS_PRIVKEY_INFO_SIGN_ALGO,
    1960             :                                                      privkey->key.ext.userdata);
    1961           0 :                         if (ret == (int)sign)
    1962             :                                 return 1;
    1963             :                 }
    1964             : 
    1965             :                 /* This key type is very limited on what it can handle */
    1966         100 :                 if (!PK_IS_OK_FOR_EXT2(se->pk))
    1967          57 :                         return gnutls_assert_val(0);
    1968             :         }
    1969             : #ifdef ENABLE_PKCS11
    1970       29110 :         else if (privkey->type == GNUTLS_PRIVKEY_PKCS11) {
    1971         191 :                 if (privkey->pk_algorithm == GNUTLS_PK_RSA && se->pk == GNUTLS_PK_RSA_PSS) {
    1972          89 :                         if (!privkey->key.pkcs11->rsa_pss_ok)
    1973          23 :                                 return 0;
    1974             :                 }
    1975             :         }
    1976             : #endif
    1977             : 
    1978             :         return 1;
    1979             : }

Generated by: LCOV version 1.14