LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - key_encode.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 335 547 61.2 %
Date: 2020-10-30 04:50:48 Functions: 16 16 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2011-2012 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2013-2017 Red Hat
       4             :  *
       5             :  * Author: Nikos Mavrogiannopoulos
       6             :  *
       7             :  * This file is part of GnuTLS.
       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             : 
      24             : #include "gnutls_int.h"
      25             : #include "errors.h"
      26             : #include <global.h>
      27             : #include <libtasn1.h>
      28             : #include <datum.h>
      29             : #include "common.h"
      30             : #include "x509_int.h"
      31             : #include <num.h>
      32             : #include <pk.h>
      33             : #include <mpi.h>
      34             : #include <ecc.h>
      35             : 
      36             : static int _gnutls_x509_write_rsa_pubkey(const gnutls_pk_params_st * params,
      37             :                                          gnutls_datum_t * der);
      38             : static int _gnutls_x509_write_dsa_params(const gnutls_pk_params_st * params,
      39             :                                          gnutls_datum_t * der);
      40             : static int _gnutls_x509_write_dsa_pubkey(const gnutls_pk_params_st * params,
      41             :                                          gnutls_datum_t * der);
      42             : static int _gnutls_x509_write_gost_params(const gnutls_pk_params_st * params,
      43             :                                          gnutls_datum_t * der);
      44             : static int _gnutls_x509_write_gost_pubkey(const gnutls_pk_params_st * params,
      45             :                                          gnutls_datum_t * der);
      46             : 
      47             : /*
      48             :  * some x509 certificate functions that relate to MPI parameter
      49             :  * setting. This writes the BIT STRING subjectPublicKey.
      50             :  * Needs 2 parameters (m,e).
      51             :  *
      52             :  * Allocates the space used to store the DER data.
      53             :  */
      54             : static int
      55        3729 : _gnutls_x509_write_rsa_pubkey(const gnutls_pk_params_st * params,
      56             :                               gnutls_datum_t * der)
      57             : {
      58        3729 :         int result;
      59        3729 :         ASN1_TYPE spk = ASN1_TYPE_EMPTY;
      60             : 
      61        3729 :         der->data = NULL;
      62        3729 :         der->size = 0;
      63             : 
      64        3729 :         if (params->params_nr < RSA_PUBLIC_PARAMS) {
      65           0 :                 gnutls_assert();
      66           0 :                 result = GNUTLS_E_INVALID_REQUEST;
      67           0 :                 goto cleanup;
      68             :         }
      69             : 
      70        3729 :         if ((result = asn1_create_element
      71             :              (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk))
      72             :             != ASN1_SUCCESS) {
      73           0 :                 gnutls_assert();
      74           0 :                 return _gnutls_asn2err(result);
      75             :         }
      76             : 
      77        3729 :         result =
      78        3729 :             _gnutls_x509_write_int(spk, "modulus", params->params[0], 1);
      79        3729 :         if (result < 0) {
      80           0 :                 gnutls_assert();
      81           0 :                 goto cleanup;
      82             :         }
      83             : 
      84        3729 :         result =
      85        3729 :             _gnutls_x509_write_int(spk, "publicExponent",
      86             :                                    params->params[1], 1);
      87        3729 :         if (result < 0) {
      88           0 :                 gnutls_assert();
      89           0 :                 goto cleanup;
      90             :         }
      91             : 
      92        3729 :         result = _gnutls_x509_der_encode(spk, "", der, 0);
      93        3729 :         if (result < 0) {
      94           0 :                 gnutls_assert();
      95           0 :                 goto cleanup;
      96             :         }
      97             : 
      98             :         result = 0;
      99             : 
     100        3729 :       cleanup:
     101        3729 :         asn1_delete_structure(&spk);
     102             : 
     103        3729 :         return result;
     104             : }
     105             : 
     106             : /*
     107             :  * some x509 certificate functions that relate to MPI parameter
     108             :  * setting. This writes an ECPoint.
     109             :  *
     110             :  * Allocates the space used to store the DER data.
     111             :  */
     112             : int
     113         429 : _gnutls_x509_write_ecc_pubkey(const gnutls_pk_params_st * params,
     114             :                               gnutls_datum_t * der)
     115             : {
     116         429 :         int result;
     117             : 
     118         429 :         der->data = NULL;
     119         429 :         der->size = 0;
     120             : 
     121         429 :         if (params->params_nr < ECC_PUBLIC_PARAMS)
     122           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     123             : 
     124         429 :         result =
     125         429 :             _gnutls_ecc_ansi_x962_export(params->curve,
     126             :                                          params->params[ECC_X],
     127             :                                          params->params[ECC_Y], /*&out */
     128             :                                          der);
     129         429 :         if (result < 0)
     130           1 :                 return gnutls_assert_val(result);
     131             : 
     132             :         return 0;
     133             : }
     134             : 
     135             : /*
     136             :  * some x509 certificate functions that relate to MPI parameter
     137             :  * setting. This writes a raw public key.
     138             :  *
     139             :  * Allocates the space used to store the data.
     140             :  */
     141             : int
     142          38 : _gnutls_x509_write_eddsa_pubkey(const gnutls_pk_params_st * params,
     143             :                               gnutls_datum_t * raw)
     144             : {
     145          38 :         int ret;
     146             : 
     147          38 :         raw->data = NULL;
     148          38 :         raw->size = 0;
     149             : 
     150          38 :         if (params->raw_pub.size == 0)
     151           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     152             : 
     153          38 :         if (params->curve != GNUTLS_ECC_CURVE_ED25519 &&
     154             :             params->curve != GNUTLS_ECC_CURVE_ED448)
     155           0 :                 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
     156             : 
     157          38 :         ret = _gnutls_set_datum(raw, params->raw_pub.data, params->raw_pub.size);
     158          38 :         if (ret < 0)
     159           0 :                 return gnutls_assert_val(ret);
     160             : 
     161             :         return 0;
     162             : }
     163             : 
     164             : int
     165         160 : _gnutls_x509_write_gost_pubkey(const gnutls_pk_params_st * params,
     166             :                               gnutls_datum_t * der)
     167             : {
     168         160 :         bigint_t x, y;
     169         160 :         int numlen;
     170         160 :         int byte_size, ret;
     171         160 :         size_t size;
     172         160 :         int pos;
     173             : 
     174         160 :         der->data = NULL;
     175         160 :         der->size = 0;
     176             : 
     177         160 :         if (params->params_nr < GOST_PUBLIC_PARAMS)
     178           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     179             : 
     180         160 :         x = params->params[GOST_X];
     181         160 :         y = params->params[GOST_Y];
     182         160 :         numlen = gnutls_ecc_curve_get_size(params->curve);
     183             : 
     184         160 :         if (numlen == 0)
     185           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     186             : 
     187         160 :         der->size = 1 + ASN1_MAX_LENGTH_SIZE + 2 * numlen;
     188             : 
     189         160 :         der->data = gnutls_malloc(der->size);
     190         160 :         if (der->data == NULL)
     191           0 :                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     192             : 
     193         160 :         memset(der->data, 0, der->size);
     194             : 
     195         160 :         der->data[0] = ASN1_TAG_OCTET_STRING;
     196         160 :         asn1_length_der(2 * numlen, &der->data[1], &pos);
     197         160 :         pos += 1;
     198             : 
     199             :         /* pad and store x */
     200         160 :         byte_size = (_gnutls_mpi_get_nbits(x) + 7) / 8;
     201         160 :         if (numlen < byte_size) {
     202           0 :                 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     203           0 :                 goto cleanup;
     204             :         }
     205             : 
     206         160 :         size = numlen;
     207         160 :         ret = _gnutls_mpi_print_le(x, &der->data[pos], &size);
     208         160 :         if (ret < 0) {
     209           0 :                 gnutls_assert();
     210           0 :                 goto cleanup;
     211             :         }
     212             : 
     213             :         /* pad and store y */
     214         160 :         byte_size = (_gnutls_mpi_get_nbits(y) + 7) / 8;
     215         160 :         if (numlen < byte_size) {
     216           0 :                 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     217           0 :                 goto cleanup;
     218             :         }
     219             : 
     220         160 :         size = numlen;
     221         160 :         ret = _gnutls_mpi_print_le(y, &der->data[pos + numlen], &size);
     222         160 :         if (ret < 0) {
     223           0 :                 gnutls_assert();
     224           0 :                 goto cleanup;
     225             :         }
     226             : 
     227         160 :         der->size = pos + 2 * numlen;
     228             : 
     229         160 :         return 0;
     230             : 
     231           0 :  cleanup:
     232           0 :         _gnutls_free_datum(der);
     233             :         return ret;
     234             : }
     235             : 
     236             : int
     237        4536 : _gnutls_x509_write_pubkey_params(const gnutls_pk_params_st * params,
     238             :                                  gnutls_datum_t * der)
     239             : {
     240        4536 :         switch (params->algo) {
     241         128 :         case GNUTLS_PK_DSA:
     242         128 :                 return _gnutls_x509_write_dsa_params(params, der);
     243        3510 :         case GNUTLS_PK_RSA:
     244        3510 :                 der->data = gnutls_malloc(ASN1_NULL_SIZE);
     245        3510 :                 if (der->data == NULL)
     246           0 :                         return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     247             : 
     248        3510 :                 memcpy(der->data, ASN1_NULL, ASN1_NULL_SIZE);
     249        3510 :                 der->size = ASN1_NULL_SIZE;
     250        3510 :                 return 0;
     251         246 :         case GNUTLS_PK_RSA_PSS:
     252         246 :                 return _gnutls_x509_write_rsa_pss_params(&params->spki, der);
     253         437 :         case GNUTLS_PK_ECDSA:
     254         437 :                 return _gnutls_x509_write_ecc_params(params->curve, der);
     255          43 :         case GNUTLS_PK_EDDSA_ED25519:
     256             :         case GNUTLS_PK_EDDSA_ED448:
     257          43 :                 der->data = NULL;
     258          43 :                 der->size = 0;
     259             : 
     260          43 :                 return 0;
     261         172 :         case GNUTLS_PK_GOST_01:
     262             :         case GNUTLS_PK_GOST_12_256:
     263             :         case GNUTLS_PK_GOST_12_512:
     264         172 :                 return _gnutls_x509_write_gost_params(params, der);
     265             :         default:
     266           0 :                 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
     267             :         }
     268             : }
     269             : 
     270             : int
     271        4476 : _gnutls_x509_write_pubkey(const gnutls_pk_params_st * params,
     272             :                           gnutls_datum_t * der)
     273             : {
     274        4476 :         switch (params->algo) {
     275         122 :         case GNUTLS_PK_DSA:
     276         122 :                 return _gnutls_x509_write_dsa_pubkey(params, der);
     277        3729 :         case GNUTLS_PK_RSA:
     278             :         case GNUTLS_PK_RSA_PSS:
     279        3729 :                 return _gnutls_x509_write_rsa_pubkey(params, der);
     280         427 :         case GNUTLS_PK_ECDSA:
     281         427 :                 return _gnutls_x509_write_ecc_pubkey(params, der);
     282          38 :         case GNUTLS_PK_EDDSA_ED25519:
     283             :         case GNUTLS_PK_EDDSA_ED448:
     284          38 :                 return _gnutls_x509_write_eddsa_pubkey(params, der);
     285         160 :         case GNUTLS_PK_GOST_01:
     286             :         case GNUTLS_PK_GOST_12_256:
     287             :         case GNUTLS_PK_GOST_12_512:
     288         160 :                 return _gnutls_x509_write_gost_pubkey(params, der);
     289             :         default:
     290           0 :                 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
     291             :         }
     292             : }
     293             : 
     294             : /*
     295             :  * This function writes the parameters for DSS keys.
     296             :  * Needs 3 parameters (p,q,g).
     297             :  *
     298             :  * Allocates the space used to store the DER data.
     299             :  */
     300             : static int
     301         128 : _gnutls_x509_write_dsa_params(const gnutls_pk_params_st * params,
     302             :                               gnutls_datum_t * der)
     303             : {
     304         128 :         int result;
     305         128 :         ASN1_TYPE spk = ASN1_TYPE_EMPTY;
     306             : 
     307         128 :         der->data = NULL;
     308         128 :         der->size = 0;
     309             : 
     310         128 :         if (params->params_nr < DSA_PUBLIC_PARAMS - 1) {
     311           0 :                 gnutls_assert();
     312           0 :                 result = GNUTLS_E_INVALID_REQUEST;
     313           0 :                 goto cleanup;
     314             :         }
     315             : 
     316         128 :         if ((result = asn1_create_element
     317             :              (_gnutls_get_gnutls_asn(), "GNUTLS.DSAParameters", &spk))
     318             :             != ASN1_SUCCESS) {
     319           0 :                 gnutls_assert();
     320           0 :                 return _gnutls_asn2err(result);
     321             :         }
     322             : 
     323         128 :         result = _gnutls_x509_write_int(spk, "p", params->params[0], 1);
     324         128 :         if (result < 0) {
     325           0 :                 gnutls_assert();
     326           0 :                 goto cleanup;
     327             :         }
     328             : 
     329         128 :         result = _gnutls_x509_write_int(spk, "q", params->params[1], 1);
     330         128 :         if (result < 0) {
     331           0 :                 gnutls_assert();
     332           0 :                 goto cleanup;
     333             :         }
     334             : 
     335         128 :         result = _gnutls_x509_write_int(spk, "g", params->params[2], 1);
     336         128 :         if (result < 0) {
     337           0 :                 gnutls_assert();
     338           0 :                 goto cleanup;
     339             :         }
     340             : 
     341         128 :         result = _gnutls_x509_der_encode(spk, "", der, 0);
     342         128 :         if (result < 0) {
     343           0 :                 gnutls_assert();
     344           0 :                 goto cleanup;
     345             :         }
     346             : 
     347             :         result = 0;
     348             : 
     349         128 :       cleanup:
     350         128 :         asn1_delete_structure(&spk);
     351         128 :         return result;
     352             : }
     353             : 
     354             : /*
     355             :  * This function writes the parameters for ECC keys.
     356             :  * That is the ECParameters struct.
     357             :  *
     358             :  * Allocates the space used to store the DER data.
     359             :  */
     360             : int
     361         452 : _gnutls_x509_write_ecc_params(const gnutls_ecc_curve_t curve,
     362             :                               gnutls_datum_t * der)
     363             : {
     364         452 :         int result;
     365         452 :         ASN1_TYPE spk = ASN1_TYPE_EMPTY;
     366         452 :         const char *oid;
     367             : 
     368         452 :         der->data = NULL;
     369         452 :         der->size = 0;
     370             : 
     371         452 :         oid = gnutls_ecc_curve_get_oid(curve);
     372         452 :         if (oid == NULL)
     373           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     374             : 
     375             : 
     376         452 :         if ((result = asn1_create_element
     377             :              (_gnutls_get_gnutls_asn(), "GNUTLS.ECParameters", &spk))
     378             :             != ASN1_SUCCESS) {
     379           0 :                 gnutls_assert();
     380           0 :                 return _gnutls_asn2err(result);
     381             :         }
     382             : 
     383         904 :         if ((result =
     384         452 :              asn1_write_value(spk, "", "namedCurve", 1)) != ASN1_SUCCESS) {
     385           0 :                 gnutls_assert();
     386           0 :                 result = _gnutls_asn2err(result);
     387           0 :                 goto cleanup;
     388             :         }
     389             : 
     390         904 :         if ((result =
     391         452 :              asn1_write_value(spk, "namedCurve", oid,
     392             :                               1)) != ASN1_SUCCESS) {
     393           0 :                 gnutls_assert();
     394           0 :                 result = _gnutls_asn2err(result);
     395           0 :                 goto cleanup;
     396             :         }
     397             : 
     398         452 :         result = _gnutls_x509_der_encode(spk, "", der, 0);
     399         452 :         if (result < 0) {
     400           0 :                 gnutls_assert();
     401           0 :                 goto cleanup;
     402             :         }
     403             : 
     404             :         result = 0;
     405             : 
     406         452 :       cleanup:
     407         452 :         asn1_delete_structure(&spk);
     408         452 :         return result;
     409             : }
     410             : 
     411             : int
     412         302 : _gnutls_x509_write_rsa_pss_params(const gnutls_x509_spki_st *params,
     413             :                                   gnutls_datum_t *der)
     414             : {
     415         302 :         int result;
     416         302 :         ASN1_TYPE spk = ASN1_TYPE_EMPTY;
     417         302 :         ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
     418         302 :         const char *oid;
     419         302 :         gnutls_datum_t tmp = { NULL, 0 };
     420             : 
     421         302 :         der->data = NULL;
     422         302 :         der->size = 0;
     423             : 
     424         302 :         if (params->pk != GNUTLS_PK_RSA_PSS)
     425             :                 return 0;
     426             : 
     427             :         /* refuse to write parameters we cannot read */
     428         211 :         if (gnutls_pk_to_sign(GNUTLS_PK_RSA_PSS, params->rsa_pss_dig) == GNUTLS_SIGN_UNKNOWN)
     429           6 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     430             : 
     431         205 :         if ((result = asn1_create_element
     432             :              (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPSSParameters", &spk))
     433             :             != ASN1_SUCCESS) {
     434           0 :                 gnutls_assert();
     435           0 :                 result = _gnutls_asn2err(result);
     436           0 :                 goto cleanup;
     437             :         }
     438             : 
     439         205 :         oid = gnutls_digest_get_oid(params->rsa_pss_dig);
     440             : 
     441         205 :         if ((result = asn1_write_value(spk, "hashAlgorithm.algorithm", oid, 1))
     442             :             != ASN1_SUCCESS) {
     443           0 :                 gnutls_assert();
     444           0 :                 result = _gnutls_asn2err(result);
     445           0 :                 goto cleanup;
     446             :         }
     447             : 
     448         205 :         if ((result = asn1_write_value(spk, "hashAlgorithm.parameters", NULL, 0))
     449             :             != ASN1_SUCCESS) {
     450           0 :                 gnutls_assert();
     451           0 :                 result = _gnutls_asn2err(result);
     452           0 :                 goto cleanup;
     453             :         }
     454             : 
     455         410 :         if ((result =
     456         205 :              asn1_write_value(spk, "maskGenAlgorithm.algorithm",
     457             :                               PKIX1_RSA_PSS_MGF1_OID, 1))
     458             :             != ASN1_SUCCESS) {
     459           0 :                 gnutls_assert();
     460           0 :                 result = _gnutls_asn2err(result);
     461           0 :                 goto cleanup;
     462             :         }
     463             : 
     464         205 :         if ((result = asn1_create_element
     465             :              (_gnutls_get_pkix(), "PKIX1.AlgorithmIdentifier", &c2))
     466             :             != ASN1_SUCCESS) {
     467           0 :                 gnutls_assert();
     468           0 :                 result = _gnutls_asn2err(result);
     469           0 :                 goto cleanup;
     470             :         }
     471             : 
     472         205 :         if ((result = asn1_write_value(c2, "algorithm", oid, 1))
     473             :             != ASN1_SUCCESS) {
     474           0 :                 gnutls_assert();
     475           0 :                 result = _gnutls_asn2err(result);
     476           0 :                 goto cleanup;
     477             :         }
     478             : 
     479         205 :         if ((result = asn1_write_value(c2, "parameters", NULL, 0))
     480             :             != ASN1_SUCCESS) {
     481           0 :                 gnutls_assert();
     482           0 :                 result = _gnutls_asn2err(result);
     483           0 :                 goto cleanup;
     484             :         }
     485             : 
     486         205 :         result = _gnutls_x509_der_encode(c2, "", &tmp, 0);
     487         205 :         if (result < 0) {
     488           0 :                 gnutls_assert();
     489           0 :                 goto cleanup;
     490             :         }
     491             : 
     492         410 :         if ((result =
     493         205 :              asn1_write_value(spk, "maskGenAlgorithm.parameters",
     494         205 :                               tmp.data, tmp.size))
     495             :             != ASN1_SUCCESS) {
     496           0 :                 gnutls_assert();
     497           0 :                 result = _gnutls_asn2err(result);
     498           0 :                 goto cleanup;
     499             :         }
     500             : 
     501         205 :         result = _gnutls_x509_write_uint32(spk, "saltLength",
     502             :                                            params->salt_size);
     503         205 :         if (result < 0) {
     504           0 :                 gnutls_assert();
     505           0 :                 goto cleanup;
     506             :         }
     507             : 
     508         205 :         result = _gnutls_x509_write_uint32(spk, "trailerField", 1);
     509         205 :         if (result < 0) {
     510           0 :                 gnutls_assert();
     511           0 :                 goto cleanup;
     512             :         }
     513             : 
     514         205 :         result = _gnutls_x509_der_encode(spk, "", der, 0);
     515         205 :         if (result < 0) {
     516           0 :                 gnutls_assert();
     517           0 :                 goto cleanup;
     518             :         }
     519             : 
     520             :         result = 0;
     521             : 
     522         205 :       cleanup:
     523         205 :         _gnutls_free_datum(&tmp);
     524         205 :         asn1_delete_structure(&c2);
     525         205 :         asn1_delete_structure(&spk);
     526         205 :         return result;
     527             : }
     528             : 
     529             : static int
     530         172 : _gnutls_x509_write_gost_params(const gnutls_pk_params_st * params,
     531             :                               gnutls_datum_t * der)
     532             : {
     533         172 :         int result;
     534         172 :         ASN1_TYPE spk = ASN1_TYPE_EMPTY;
     535         172 :         const char *oid;
     536             : 
     537         172 :         der->data = NULL;
     538         172 :         der->size = 0;
     539             : 
     540         172 :         oid = gnutls_ecc_curve_get_oid(params->curve);
     541         172 :         if (oid == NULL)
     542           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     543             : 
     544             : 
     545         172 :         if ((result = asn1_create_element
     546             :              (_gnutls_get_gnutls_asn(),
     547         172 :               params->algo == GNUTLS_PK_GOST_01 ?
     548             :               "GNUTLS.GOSTParametersOld" :
     549             :               "GNUTLS.GOSTParameters", &spk))
     550             :             != ASN1_SUCCESS) {
     551           0 :                 gnutls_assert();
     552           0 :                 return _gnutls_asn2err(result);
     553             :         }
     554             : 
     555         344 :         if ((result =
     556         172 :              asn1_write_value(spk, "publicKeyParamSet", oid,
     557             :                               1)) != ASN1_SUCCESS) {
     558           0 :                 gnutls_assert();
     559           0 :                 result = _gnutls_asn2err(result);
     560           0 :                 goto cleanup;
     561             :         }
     562             : 
     563             :         /* For compatibility per R 1323565.1.023—2018 provide digest OID only
     564             :          * for GOST-2001 keys or GOST-2012 keys with CryptoPro curves. Do not
     565             :          * set this optional parameter for TC26 curves */
     566         172 :         if (params->algo == GNUTLS_PK_GOST_01)
     567             :                 oid = HASH_OID_GOST_R_3411_94_CRYPTOPRO_PARAMS;
     568          89 :         else if (params->algo == GNUTLS_PK_GOST_12_256 &&
     569          40 :                  (params->curve == GNUTLS_ECC_CURVE_GOST256CPA ||
     570             :                   params->curve == GNUTLS_ECC_CURVE_GOST256CPB ||
     571             :                   params->curve == GNUTLS_ECC_CURVE_GOST256CPC ||
     572          40 :                   params->curve == GNUTLS_ECC_CURVE_GOST256CPXA ||
     573             :                   params->curve == GNUTLS_ECC_CURVE_GOST256CPXB))
     574             :                 oid = HASH_OID_STREEBOG_256;
     575          49 :         else if (params->algo == GNUTLS_PK_GOST_12_512 &&
     576          49 :                  (params->curve == GNUTLS_ECC_CURVE_GOST512A ||
     577             :                   params->curve == GNUTLS_ECC_CURVE_GOST512B))
     578             :                 oid = HASH_OID_STREEBOG_512;
     579             :         else
     580           0 :                 oid = NULL;
     581             : 
     582         172 :         if ((result = asn1_write_value(spk, "digestParamSet", oid, oid ? 1 : 0)) != ASN1_SUCCESS) {
     583           0 :                 gnutls_assert();
     584           0 :                 result = _gnutls_asn2err(result);
     585           0 :                 goto cleanup;
     586             :         }
     587             : 
     588         172 :         oid = gnutls_gost_paramset_get_oid(params->gost_params);
     589         172 :         if (oid == NULL) {
     590           0 :                 gnutls_assert();
     591           0 :                 result = GNUTLS_E_INVALID_REQUEST;
     592           0 :                 goto cleanup;
     593             :         }
     594             : 
     595         172 :         if (params->algo == GNUTLS_PK_GOST_01) {
     596          83 :                 if (params->gost_params == _gnutls_gost_paramset_default(params->algo))
     597          83 :                         oid = NULL;
     598             : 
     599         166 :                 if ((result =
     600          83 :                      asn1_write_value(spk, "encryptionParamSet", oid,
     601             :                                       oid ? 1 : 0)) != ASN1_SUCCESS) {
     602           0 :                         gnutls_assert();
     603           0 :                         result = _gnutls_asn2err(result);
     604           0 :                         goto cleanup;
     605             :                 }
     606             :         }
     607             : 
     608         172 :         result = _gnutls_x509_der_encode(spk, "", der, 0);
     609         172 :         if (result < 0) {
     610           0 :                 gnutls_assert();
     611           0 :                 goto cleanup;
     612             :         }
     613             : 
     614             :         result = 0;
     615             : 
     616         172 :       cleanup:
     617         172 :         asn1_delete_structure(&spk);
     618         172 :         return result;
     619             : }
     620             : 
     621             : /*
     622             :  * This function writes the public parameters for DSS keys.
     623             :  * Needs 1 parameter (y).
     624             :  *
     625             :  * Allocates the space used to store the DER data.
     626             :  */
     627             : static int
     628         122 : _gnutls_x509_write_dsa_pubkey(const gnutls_pk_params_st * params,
     629             :                               gnutls_datum_t * der)
     630             : {
     631         122 :         int result;
     632         122 :         ASN1_TYPE spk = ASN1_TYPE_EMPTY;
     633             : 
     634         122 :         der->data = NULL;
     635         122 :         der->size = 0;
     636             : 
     637         122 :         if (params->params_nr < DSA_PUBLIC_PARAMS) {
     638           0 :                 gnutls_assert();
     639           0 :                 result = GNUTLS_E_INVALID_REQUEST;
     640           0 :                 goto cleanup;
     641             :         }
     642             : 
     643         122 :         if ((result = asn1_create_element
     644             :              (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &spk))
     645             :             != ASN1_SUCCESS) {
     646           0 :                 gnutls_assert();
     647           0 :                 return _gnutls_asn2err(result);
     648             :         }
     649             : 
     650         122 :         result = _gnutls_x509_write_int(spk, "", params->params[3], 1);
     651         122 :         if (result < 0) {
     652           0 :                 gnutls_assert();
     653           0 :                 goto cleanup;
     654             :         }
     655             : 
     656         122 :         result = _gnutls_x509_der_encode(spk, "", der, 0);
     657         122 :         if (result < 0) {
     658           0 :                 gnutls_assert();
     659           0 :                 goto cleanup;
     660             :         }
     661             : 
     662             :         result = 0;
     663             : 
     664         122 :       cleanup:
     665         122 :         asn1_delete_structure(&spk);
     666         122 :         return result;
     667             : }
     668             : 
     669             : /* Encodes the RSA parameters into an ASN.1 RSA private key structure.
     670             :  */
     671             : static int
     672         357 : _gnutls_asn1_encode_rsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
     673             : {
     674         357 :         int result, ret;
     675         357 :         uint8_t null = '\0';
     676         357 :         gnutls_pk_params_st pk_params;
     677             : 
     678             :         /* we do copy the parameters into a new structure to run _gnutls_pk_fixup,
     679             :          * i.e., regenerate some parameters in case they were broken */
     680         357 :         gnutls_pk_params_init(&pk_params);
     681             : 
     682         357 :         ret = _gnutls_pk_params_copy(&pk_params, params);
     683         357 :         if (ret < 0) {
     684           0 :                 gnutls_assert();
     685           0 :                 return ret;
     686             :         }
     687             : 
     688         357 :         ret =
     689         714 :             _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
     690         357 :         if (ret < 0) {
     691           0 :                 gnutls_assert();
     692           0 :                 goto cleanup;
     693             :         }
     694             : 
     695             :         /* Ok. Now we have the data. Create the asn1 structures
     696             :          */
     697             : 
     698             :         /* first make sure that no previously allocated data are leaked */
     699         357 :         if (*c2 != ASN1_TYPE_EMPTY) {
     700           0 :                 asn1_delete_structure(c2);
     701           0 :                 *c2 = ASN1_TYPE_EMPTY;
     702             :         }
     703             : 
     704         357 :         if ((result = asn1_create_element
     705             :              (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", c2))
     706             :             != ASN1_SUCCESS) {
     707           0 :                 gnutls_assert();
     708           0 :                 ret = _gnutls_asn2err(result);
     709           0 :                 goto cleanup;
     710             :         }
     711             : 
     712             :         /* Write PRIME
     713             :          */
     714         357 :         ret =
     715         357 :             _gnutls_x509_write_int(*c2, "modulus",
     716             :                                    params->params[RSA_MODULUS], 1);
     717         357 :         if (ret < 0) {
     718           0 :                 gnutls_assert();
     719           0 :                 goto cleanup;
     720             :         }
     721             : 
     722         357 :         ret =
     723         357 :             _gnutls_x509_write_int(*c2, "publicExponent",
     724             :                                    params->params[RSA_PUB], 1);
     725         357 :         if (ret < 0) {
     726           0 :                 gnutls_assert();
     727           0 :                 goto cleanup;
     728             :         }
     729             : 
     730         357 :         ret =
     731         357 :             _gnutls_x509_write_key_int(*c2, "privateExponent",
     732             :                                    params->params[RSA_PRIV], 1);
     733         357 :         if (ret < 0) {
     734           0 :                 gnutls_assert();
     735           0 :                 goto cleanup;
     736             :         }
     737             : 
     738         357 :         ret =
     739         357 :             _gnutls_x509_write_key_int(*c2, "prime1",
     740             :                                    params->params[RSA_PRIME1], 1);
     741         357 :         if (ret < 0) {
     742           0 :                 gnutls_assert();
     743           0 :                 goto cleanup;
     744             :         }
     745             : 
     746         357 :         ret =
     747         357 :             _gnutls_x509_write_key_int(*c2, "prime2",
     748             :                                    params->params[RSA_PRIME2], 1);
     749         357 :         if (ret < 0) {
     750           0 :                 gnutls_assert();
     751           0 :                 goto cleanup;
     752             :         }
     753             : 
     754         357 :         ret =
     755         357 :             _gnutls_x509_write_key_int(*c2, "coefficient",
     756             :                                    params->params[RSA_COEF], 1);
     757         357 :         if (ret < 0) {
     758           0 :                 gnutls_assert();
     759           0 :                 goto cleanup;
     760             :         }
     761             : 
     762         357 :         ret =
     763         357 :             _gnutls_x509_write_key_int(*c2, "exponent1",
     764             :                                    params->params[RSA_E1], 1);
     765         357 :         if (ret < 0) {
     766           0 :                 gnutls_assert();
     767           0 :                 goto cleanup;
     768             :         }
     769             : 
     770         357 :         ret =
     771         357 :             _gnutls_x509_write_key_int(*c2, "exponent2",
     772             :                                    params->params[RSA_E2], 1);
     773         357 :         if (ret < 0) {
     774           0 :                 gnutls_assert();
     775           0 :                 goto cleanup;
     776             :         }
     777             : 
     778         357 :         if ((result = asn1_write_value(*c2, "otherPrimeInfos",
     779             :                                        NULL, 0)) != ASN1_SUCCESS) {
     780           0 :                 gnutls_assert();
     781           0 :                 ret = _gnutls_asn2err(result);
     782           0 :                 goto cleanup;
     783             :         }
     784             : 
     785         714 :         if ((result =
     786         357 :              asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) {
     787           0 :                 gnutls_assert();
     788           0 :                 ret = _gnutls_asn2err(result);
     789           0 :                 goto cleanup;
     790             :         }
     791             : 
     792             :         ret = 0;
     793             : 
     794           0 :       cleanup:
     795           0 :         if (ret < 0)
     796           0 :                 asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
     797             : 
     798         357 :         gnutls_pk_params_clear(&pk_params);
     799         357 :         gnutls_pk_params_release(&pk_params);
     800         357 :         return ret;
     801             : }
     802             : 
     803             : /* Encodes the ECC parameters into an ASN.1 ECPrivateKey structure.
     804             :  */
     805             : static int
     806         442 : _gnutls_asn1_encode_ecc(ASN1_TYPE * c2, gnutls_pk_params_st * params)
     807             : {
     808         442 :         int ret;
     809         442 :         uint8_t one = '\x01';
     810         442 :         gnutls_datum_t pubkey = { NULL, 0 };
     811         442 :         const char *oid;
     812             : 
     813         442 :         oid = gnutls_ecc_curve_get_oid(params->curve);
     814         442 :         if (oid == NULL)
     815           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     816             : 
     817             :         /* first make sure that no previously allocated data are leaked */
     818         442 :         if (*c2 != ASN1_TYPE_EMPTY) {
     819           0 :                 asn1_delete_structure(c2);
     820           0 :                 *c2 = ASN1_TYPE_EMPTY;
     821             :         }
     822             : 
     823         442 :         if ((ret = asn1_create_element
     824             :              (_gnutls_get_gnutls_asn(), "GNUTLS.ECPrivateKey", c2))
     825             :             != ASN1_SUCCESS) {
     826           0 :                 gnutls_assert();
     827           0 :                 ret = _gnutls_asn2err(ret);
     828           0 :                 goto cleanup;
     829             :         }
     830             : 
     831         884 :         if ((ret =
     832         442 :              asn1_write_value(*c2, "Version", &one, 1)) != ASN1_SUCCESS) {
     833           0 :                 gnutls_assert();
     834           0 :                 ret = _gnutls_asn2err(ret);
     835           0 :                 goto cleanup;
     836             :         }
     837             : 
     838         442 :         if (curve_is_eddsa(params->curve)) {
     839          11 :                 if (params->raw_pub.size == 0 || params->raw_priv.size == 0)
     840           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     841          11 :                 ret =
     842          11 :                     asn1_write_value(*c2, "privateKey", params->raw_priv.data, params->raw_priv.size);
     843          11 :                 if (ret != ASN1_SUCCESS) {
     844           0 :                         gnutls_assert();
     845           0 :                         ret = _gnutls_asn2err(ret);
     846           0 :                         goto cleanup;
     847             :                 }
     848             : 
     849          11 :                 ret =
     850          11 :                     asn1_write_value(*c2, "publicKey", params->raw_pub.data, params->raw_pub.size*8);
     851          11 :                 if (ret != ASN1_SUCCESS) {
     852           0 :                         gnutls_assert();
     853           0 :                         ret = _gnutls_asn2err(ret);
     854           0 :                         goto cleanup;
     855             :                 }
     856             :         } else {
     857         431 :                 if (params->params_nr != ECC_PRIVATE_PARAMS)
     858           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     859             : 
     860         431 :                 ret =
     861         431 :                     _gnutls_ecc_ansi_x962_export(params->curve,
     862             :                                                  params->params[ECC_X],
     863             :                                                  params->params[ECC_Y], &pubkey);
     864         431 :                 if (ret < 0)
     865           0 :                         return gnutls_assert_val(ret);
     866             : 
     867         431 :                 ret =
     868         431 :                     _gnutls_x509_write_key_int(*c2, "privateKey",
     869             :                                            params->params[ECC_K], 1);
     870         431 :                 if (ret < 0) {
     871           0 :                         gnutls_assert();
     872           0 :                         goto cleanup;
     873             :                 }
     874             : 
     875         862 :                 if ((ret =
     876         431 :                      asn1_write_value(*c2, "publicKey", pubkey.data,
     877         431 :                                       pubkey.size * 8)) != ASN1_SUCCESS) {
     878           0 :                         gnutls_assert();
     879           0 :                         ret = _gnutls_asn2err(ret);
     880           0 :                         goto cleanup;
     881             :                 }
     882             :         }
     883             : 
     884             :         /* write our choice */
     885         884 :         if ((ret =
     886         442 :              asn1_write_value(*c2, "parameters", "namedCurve",
     887             :                               1)) != ASN1_SUCCESS) {
     888           0 :                 gnutls_assert();
     889           0 :                 ret = _gnutls_asn2err(ret);
     890           0 :                 goto cleanup;
     891             :         }
     892             : 
     893         884 :         if ((ret =
     894         442 :              asn1_write_value(*c2, "parameters.namedCurve", oid,
     895             :                               1)) != ASN1_SUCCESS) {
     896           0 :                 gnutls_assert();
     897           0 :                 ret = _gnutls_asn2err(ret);
     898           0 :                 goto cleanup;
     899             :         }
     900             : 
     901         442 :         _gnutls_free_datum(&pubkey);
     902         442 :         return 0;
     903             : 
     904           0 : cleanup:
     905           0 :         asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
     906           0 :         _gnutls_free_datum(&pubkey);
     907             : 
     908           0 :         return ret;
     909             : }
     910             : 
     911             : static int
     912         518 : _gnutls_asn1_encode_gost(ASN1_TYPE * c2, gnutls_pk_params_st * params)
     913             : {
     914         518 :         int ret;
     915         518 :         const char *oid;
     916             : 
     917         518 :         oid = gnutls_pk_get_oid(params->algo);
     918             : 
     919         518 :         if (params->params_nr != GOST_PRIVATE_PARAMS || oid == NULL)
     920           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     921             : 
     922             :         /* first make sure that no previously allocated data are leaked */
     923         518 :         if (*c2 != ASN1_TYPE_EMPTY) {
     924           0 :                 asn1_delete_structure(c2);
     925           0 :                 *c2 = ASN1_TYPE_EMPTY;
     926             :         }
     927             : 
     928         518 :         if ((ret = asn1_create_element
     929             :              (_gnutls_get_gnutls_asn(), "GNUTLS.GOSTPrivateKey", c2))
     930             :             != ASN1_SUCCESS) {
     931           0 :                 gnutls_assert();
     932           0 :                 ret = _gnutls_asn2err(ret);
     933           0 :                 goto cleanup;
     934             :         }
     935             : 
     936         518 :         ret =
     937         518 :             _gnutls_x509_write_key_int_le(*c2, "", params->params[GOST_K]);
     938         518 :         if (ret < 0) {
     939           0 :                 gnutls_assert();
     940           0 :                 goto cleanup;
     941             :         }
     942             : 
     943             : 
     944             :         return 0;
     945             : 
     946           0 : cleanup:
     947           0 :         asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
     948             : 
     949           0 :         return ret;
     950             : }
     951             : 
     952             : /* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
     953             :  */
     954             : static int
     955          35 : _gnutls_asn1_encode_dsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
     956             : {
     957          35 :         int result, ret;
     958          35 :         const uint8_t null = '\0';
     959             : 
     960             :         /* first make sure that no previously allocated data are leaked */
     961          35 :         if (*c2 != ASN1_TYPE_EMPTY) {
     962           0 :                 asn1_delete_structure(c2);
     963           0 :                 *c2 = ASN1_TYPE_EMPTY;
     964             :         }
     965             : 
     966          35 :         if ((result = asn1_create_element
     967             :              (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPrivateKey", c2))
     968             :             != ASN1_SUCCESS) {
     969           0 :                 gnutls_assert();
     970           0 :                 return _gnutls_asn2err(result);
     971             :         }
     972             : 
     973             :         /* Write PRIME
     974             :          */
     975          35 :         ret =
     976          35 :             _gnutls_x509_write_int(*c2, "p",
     977             :                                    params->params[DSA_P], 1);
     978          35 :         if (ret < 0) {
     979           0 :                 gnutls_assert();
     980           0 :                 goto cleanup;
     981             :         }
     982             : 
     983          35 :         ret =
     984          35 :             _gnutls_x509_write_int(*c2, "q",
     985             :                                    params->params[DSA_Q], 1);
     986          35 :         if (ret < 0) {
     987           0 :                 gnutls_assert();
     988           0 :                 goto cleanup;
     989             :         }
     990             : 
     991          35 :         ret =
     992          35 :             _gnutls_x509_write_int(*c2, "g",
     993             :                                    params->params[DSA_G], 1);
     994          35 :         if (ret < 0) {
     995           0 :                 gnutls_assert();
     996           0 :                 goto cleanup;
     997             :         }
     998             : 
     999          35 :         ret =
    1000          35 :             _gnutls_x509_write_int(*c2, "Y",
    1001             :                                    params->params[DSA_Y], 1);
    1002          35 :         if (ret < 0) {
    1003           0 :                 gnutls_assert();
    1004           0 :                 goto cleanup;
    1005             :         }
    1006             : 
    1007          35 :         ret =
    1008          35 :             _gnutls_x509_write_key_int(*c2, "priv",
    1009             :                                    params->params[DSA_X], 1);
    1010          35 :         if (ret < 0) {
    1011           0 :                 gnutls_assert();
    1012           0 :                 goto cleanup;
    1013             :         }
    1014             : 
    1015          70 :         if ((result =
    1016          35 :              asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) {
    1017           0 :                 gnutls_assert();
    1018           0 :                 ret = _gnutls_asn2err(result);
    1019           0 :                 goto cleanup;
    1020             :         }
    1021             : 
    1022             :         return 0;
    1023             : 
    1024           0 : cleanup:
    1025           0 :         asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
    1026             : 
    1027           0 :         return ret;
    1028             : }
    1029             : 
    1030        1352 : int _gnutls_asn1_encode_privkey(ASN1_TYPE * c2,
    1031             :                                 gnutls_pk_params_st * params)
    1032             : {
    1033        1352 :         switch (params->algo) {
    1034         357 :         case GNUTLS_PK_RSA:
    1035             :         case GNUTLS_PK_RSA_PSS:
    1036         357 :                 return _gnutls_asn1_encode_rsa(c2, params);
    1037          35 :         case GNUTLS_PK_DSA:
    1038          35 :                 return _gnutls_asn1_encode_dsa(c2, params);
    1039         442 :         case GNUTLS_PK_ECDSA:
    1040             :         case GNUTLS_PK_EDDSA_ED25519:
    1041             :         case GNUTLS_PK_EDDSA_ED448:
    1042         442 :                 return _gnutls_asn1_encode_ecc(c2, params);
    1043         518 :         case GNUTLS_PK_GOST_01:
    1044             :         case GNUTLS_PK_GOST_12_256:
    1045             :         case GNUTLS_PK_GOST_12_512:
    1046         518 :                 return _gnutls_asn1_encode_gost(c2, params);
    1047             :         default:
    1048             :                 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
    1049             :         }
    1050             : }

Generated by: LCOV version 1.14