LCOV - code coverage report
Current view: top level - pkcs11/gkm - gkm-dsa-mechanism.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 81.0 % 63 51
Test Date: 2024-04-08 13:24:42 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /*
       2              :  * gnome-keyring
       3              :  *
       4              :  * Copyright (C) 2008 Stefan Walter
       5              :  *
       6              :  * This program is free software; you can redistribute it and/or modify
       7              :  * it under the terms of the GNU Lesser General Public License as
       8              :  * published by the Free Software Foundation; either version 2.1 of
       9              :  * the License, or (at your option) any later version.
      10              :  *
      11              :  * This program is distributed in the hope that it will be useful, but
      12              :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14              :  * Lesser General Public License for more details.
      15              :  *
      16              :  * You should have received a copy of the GNU Lesser General Public
      17              :  * License along with this program; if not, see
      18              :  * <http://www.gnu.org/licenses/>.
      19              :  */
      20              : 
      21              : #include "config.h"
      22              : 
      23              : #include "gkm-crypto.h"
      24              : #include "gkm-dsa-mechanism.h"
      25              : #include "gkm-session.h"
      26              : #include "gkm-sexp.h"
      27              : #include "gkm-sexp-key.h"
      28              : 
      29              : #include "egg/egg-libgcrypt.h"
      30              : #include "egg/egg-secure-memory.h"
      31              : 
      32              : /* ----------------------------------------------------------------------------
      33              :  * PUBLIC
      34              :  */
      35              : 
      36              : CK_RV
      37            1 : gkm_dsa_mechanism_sign (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data,
      38              :                         CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
      39              : {
      40              :         gcry_sexp_t ssig, splain;
      41              :         gcry_error_t gcry;
      42              :         gcry_mpi_t mpi;
      43              :         CK_ULONG size;
      44              :         CK_RV rv;
      45              : 
      46            1 :         g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
      47            1 :         g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
      48            1 :         g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
      49              : 
      50            1 :         if (n_data != 20)
      51            0 :                 return CKR_DATA_LEN_RANGE;
      52              : 
      53              :         /* If no output, then don't process */
      54            1 :         if (!signature) {
      55            0 :                 *n_signature = 40;
      56            0 :                 return CKR_OK;
      57            1 :         } else if (*n_signature < 40) {
      58            0 :                 *n_signature = 40;
      59            0 :                 return CKR_BUFFER_TOO_SMALL;
      60              :         }
      61              : 
      62              :         /* Prepare the input s-expression */
      63            1 :         gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
      64            1 :         g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
      65            1 :         gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
      66            1 :         gcry_mpi_release (mpi);
      67            1 :         g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
      68              : 
      69              :         /* Do the magic */
      70            1 :         gcry = gcry_pk_sign (&ssig, splain, sexp);
      71            1 :         gcry_sexp_release (splain);
      72              : 
      73              :         /* TODO: Certain codes should be returned (data too big etc... ) */
      74            1 :         if (gcry) {
      75            0 :                 g_message ("signing of the data failed: %s", gcry_strerror (gcry));
      76            0 :                 return CKR_FUNCTION_FAILED;
      77              :         }
      78              : 
      79            1 :         g_assert (*n_signature >= 40);
      80              : 
      81            1 :         size = 20;
      82            1 :         rv = gkm_crypto_sexp_to_data (ssig, 20 * 8, signature, &size, NULL, "dsa", "r", NULL);
      83            1 :         if (rv == CKR_OK) {
      84            1 :                 g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
      85            1 :                 rv = gkm_crypto_sexp_to_data (ssig, 20 * 8, signature + 20, &size, NULL, "dsa", "s", NULL);
      86            1 :                 if (rv == CKR_OK) {
      87            1 :                         g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
      88            1 :                         *n_signature = 40;
      89              :                 }
      90              :         }
      91              : 
      92            1 :         gcry_sexp_release (ssig);
      93            1 :         return rv;
      94              : }
      95              : 
      96              : CK_RV
      97            1 : gkm_dsa_mechanism_verify (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data,
      98              :                           CK_BYTE_PTR signature, CK_ULONG n_signature)
      99              : {
     100              :         gcry_sexp_t ssig, splain;
     101              :         gcry_error_t gcry;
     102              :         gcry_mpi_t mpi, mpi2;
     103              : 
     104            1 :         g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
     105            1 :         g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
     106            1 :         g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
     107              : 
     108            1 :         if (n_data != 20)
     109            0 :                 return CKR_DATA_LEN_RANGE;
     110            1 :         if (n_signature != 40)
     111            0 :                 return CKR_SIGNATURE_LEN_RANGE;
     112              : 
     113              :         /* Prepare the input s-expressions */
     114            1 :         gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
     115            1 :         g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
     116            1 :         gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
     117            1 :         gcry_mpi_release (mpi);
     118            1 :         g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
     119              : 
     120            1 :         gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, signature, 20, NULL);
     121            1 :         g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
     122            1 :         gcry = gcry_mpi_scan (&mpi2, GCRYMPI_FMT_USG, signature + 20, 20, NULL);
     123            1 :         g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
     124            1 :         gcry = gcry_sexp_build (&ssig, NULL, "(sig-val (dsa (r %m) (s %m)))", mpi, mpi2);
     125            1 :         gcry_mpi_release (mpi);
     126            1 :         gcry_mpi_release (mpi2);
     127            1 :         g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
     128              : 
     129              :         /* Do the magic */
     130            1 :         gcry = gcry_pk_verify (ssig, splain, sexp);
     131            1 :         gcry_sexp_release (splain);
     132            1 :         gcry_sexp_release (ssig);
     133              : 
     134              :         /* TODO: See if any other codes should be mapped */
     135            1 :         if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
     136            0 :                 return CKR_SIGNATURE_INVALID;
     137            1 :         } else if (gcry) {
     138            0 :                 g_message ("verifying of the data failed: %s", gcry_strerror (gcry));
     139            0 :                 return CKR_FUNCTION_FAILED;
     140              :         }
     141              : 
     142            1 :         return CKR_OK;
     143              : }
        

Generated by: LCOV version 2.0-1