LCOV - code coverage report
Current view: top level - pkcs11/gkm - gkm-sexp-key.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 62.3 % 146 91
Test Date: 2024-04-08 13:24:42 Functions: 83.3 % 18 15

            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 "pkcs11/pkcs11.h"
      24              : 
      25              : #include "gkm-attributes.h"
      26              : #define DEBUG_FLAG GKM_DEBUG_OBJECT
      27              : #include "gkm-debug.h"
      28              : #include "gkm-dsa-mechanism.h"
      29              : #include "gkm-ecdsa-mechanism.h"
      30              : #include "gkm-rsa-mechanism.h"
      31              : #include "gkm-sexp-key.h"
      32              : #include "gkm-data-der.h"
      33              : #include "gkm-util.h"
      34              : 
      35              : enum {
      36              :         PROP_0,
      37              :         PROP_BASE_SEXP,
      38              :         PROP_ALGORITHM
      39              : };
      40              : 
      41              : struct _GkmSexpKeyPrivate {
      42              :         GkmSexp *base_sexp;
      43              : };
      44              : 
      45          364 : G_DEFINE_TYPE_WITH_PRIVATE (GkmSexpKey, gkm_sexp_key, GKM_TYPE_OBJECT);
      46              : 
      47              : /* -----------------------------------------------------------------------------
      48              :  * INTERNAL
      49              :  */
      50              : 
      51              : /* -----------------------------------------------------------------------------
      52              :  * KEY
      53              :  */
      54              : 
      55              : static CK_RV
      56           64 : gkm_sexp_key_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE* attr)
      57              : {
      58           64 :         GkmSexpKey *self = GKM_SEXP_KEY (base);
      59              : 
      60           64 :         switch (attr->type) {
      61            3 :         case CKA_KEY_TYPE:
      62              :                 {
      63            3 :                         switch (gkm_sexp_key_get_algorithm (self)) {
      64            1 :                         case GCRY_PK_RSA:
      65            1 :                                 return gkm_attribute_set_ulong (attr, CKK_RSA);
      66            1 :                         case GCRY_PK_DSA:
      67            1 :                                 return gkm_attribute_set_ulong (attr, CKK_DSA);
      68            1 :                         case GCRY_PK_ECC:
      69            1 :                                 return gkm_attribute_set_ulong (attr, CKK_ECDSA);
      70            0 :                         default:
      71            0 :                                 g_return_val_if_reached (CKR_GENERAL_ERROR);
      72              :                         };
      73              :                 }
      74              :                 break;
      75              : 
      76           58 :         case CKA_ID:
      77              :                 {
      78              :                         guchar hash[20];
      79           58 :                         g_return_val_if_fail (self->pv->base_sexp, CKR_GENERAL_ERROR);
      80           58 :                         if (!gcry_pk_get_keygrip (gkm_sexp_get (self->pv->base_sexp), hash))
      81            0 :                                 g_return_val_if_reached (CKR_GENERAL_ERROR);
      82           58 :                         return gkm_attribute_set_data (attr, hash, sizeof (hash));
      83              :                 }
      84              :                 break;
      85              : 
      86            0 :         case CKA_START_DATE:
      87              :         case CKA_END_DATE:
      88            0 :                 return gkm_attribute_set_data (attr, "", 0);
      89              : 
      90            0 :         case CKA_DERIVE:
      91            0 :                 return gkm_attribute_set_bool (attr, FALSE);
      92              : 
      93            0 :         case CKA_LOCAL:
      94            0 :                 return gkm_attribute_set_bool (attr, FALSE);
      95              : 
      96            0 :         case CKA_KEY_GEN_MECHANISM:
      97            0 :                 return gkm_attribute_set_ulong (attr, CK_UNAVAILABLE_INFORMATION);
      98              : 
      99            0 :         case CKA_ALLOWED_MECHANISMS:
     100            0 :                 switch (gkm_sexp_key_get_algorithm (self)) {
     101            0 :                 case GCRY_PK_RSA:
     102            0 :                         return gkm_attribute_set_data (attr, (CK_VOID_PTR)GKM_RSA_MECHANISMS,
     103              :                                                        sizeof (GKM_RSA_MECHANISMS));
     104            0 :                 case GCRY_PK_DSA:
     105            0 :                         return gkm_attribute_set_data (attr, (CK_VOID_PTR)GKM_DSA_MECHANISMS,
     106              :                                                        sizeof (GKM_DSA_MECHANISMS));
     107            0 :                 case GCRY_PK_ECC:
     108            0 :                         return gkm_attribute_set_data (attr, (CK_VOID_PTR)GKM_ECDSA_MECHANISMS,
     109              :                                                        sizeof (GKM_ECDSA_MECHANISMS));
     110            0 :                 default:
     111            0 :                         g_return_val_if_reached (CKR_GENERAL_ERROR);
     112              :                 };
     113              : 
     114              :         /* Lookup the certificate subject */
     115            2 :         case CKA_SUBJECT:
     116              :                 /* TODO: When we have certificates, implement this */
     117            2 :                 return gkm_attribute_set_data (attr, "", 0);
     118              :         };
     119              : 
     120            1 :         return GKM_OBJECT_CLASS (gkm_sexp_key_parent_class)->get_attribute (base, session, attr);
     121              : }
     122              : 
     123              : static void
     124           60 : gkm_sexp_key_init (GkmSexpKey *self)
     125              : {
     126           60 :         self->pv = gkm_sexp_key_get_instance_private (self);
     127           60 : }
     128              : 
     129              : static void
     130           60 : gkm_sexp_key_finalize (GObject *obj)
     131              : {
     132           60 :         GkmSexpKey *self = GKM_SEXP_KEY (obj);
     133              : 
     134           60 :         if (self->pv->base_sexp)
     135           60 :                 gkm_sexp_unref (self->pv->base_sexp);
     136           60 :         self->pv->base_sexp = NULL;
     137              : 
     138           60 :         G_OBJECT_CLASS (gkm_sexp_key_parent_class)->finalize (obj);
     139           60 : }
     140              : 
     141              : static void
     142            4 : gkm_sexp_key_set_property (GObject *obj, guint prop_id, const GValue *value,
     143              :                       GParamSpec *pspec)
     144              : {
     145            4 :         GkmSexpKey *self = GKM_SEXP_KEY (obj);
     146              : 
     147            4 :         switch (prop_id) {
     148            4 :         case PROP_BASE_SEXP:
     149            4 :                 gkm_sexp_key_set_base (self, g_value_get_boxed (value));
     150            4 :                 break;
     151            0 :         default:
     152            0 :                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
     153            0 :                 break;
     154              :         }
     155            4 : }
     156              : 
     157              : static void
     158            0 : gkm_sexp_key_get_property (GObject *obj, guint prop_id, GValue *value,
     159              :                       GParamSpec *pspec)
     160              : {
     161            0 :         GkmSexpKey *self = GKM_SEXP_KEY (obj);
     162              : 
     163            0 :         switch (prop_id) {
     164            0 :         case PROP_BASE_SEXP:
     165            0 :                 g_value_set_boxed (value, gkm_sexp_key_get_base (self));
     166            0 :                 break;
     167            0 :         case PROP_ALGORITHM:
     168            0 :                 g_value_set_int (value, gkm_sexp_key_get_algorithm (self));
     169            0 :                 break;
     170            0 :         default:
     171            0 :                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
     172            0 :                 break;
     173              :         }
     174            0 : }
     175              : 
     176              : static void
     177            9 : gkm_sexp_key_class_init (GkmSexpKeyClass *klass)
     178              : {
     179            9 :         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     180            9 :         GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);
     181              : 
     182            9 :         gobject_class->finalize = gkm_sexp_key_finalize;
     183            9 :         gobject_class->set_property = gkm_sexp_key_set_property;
     184            9 :         gobject_class->get_property = gkm_sexp_key_get_property;
     185              : 
     186            9 :         gkm_class->get_attribute = gkm_sexp_key_real_get_attribute;
     187              : 
     188            9 :         g_object_class_install_property (gobject_class, PROP_BASE_SEXP,
     189              :                    g_param_spec_boxed ("base-sexp", "Base S-Exp", "Base Key S-Expression",
     190              :                                        GKM_BOXED_SEXP, G_PARAM_READWRITE));
     191              : 
     192            9 :         g_object_class_install_property (gobject_class, PROP_ALGORITHM,
     193              :                    g_param_spec_int ("algorithm", "Algorithm", "GCrypt Algorithm",
     194              :                                      0, G_MAXINT, 0, G_PARAM_READABLE));
     195            9 : }
     196              : 
     197              : /* -----------------------------------------------------------------------------
     198              :  * PUBLIC
     199              :  */
     200              : 
     201              : GkmSexp*
     202            0 : gkm_sexp_key_get_base (GkmSexpKey *self)
     203              : {
     204            0 :         g_return_val_if_fail (GKM_IS_SEXP_KEY (self), NULL);
     205            0 :         return self->pv->base_sexp;
     206              : }
     207              : 
     208              : void
     209           60 : gkm_sexp_key_set_base (GkmSexpKey *self, GkmSexp *sexp)
     210              : {
     211           60 :         g_return_if_fail (GKM_IS_SEXP_KEY (self));
     212           60 :         if (sexp)
     213           60 :                 gkm_sexp_ref (sexp);
     214           60 :         if (self->pv->base_sexp)
     215            0 :                 gkm_sexp_unref (self->pv->base_sexp);
     216           60 :         self->pv->base_sexp = sexp;
     217           60 :         g_object_notify (G_OBJECT (self), "base-sexp");
     218           60 :         g_object_notify (G_OBJECT (self), "algorithm");
     219              : }
     220              : 
     221              : int
     222            4 : gkm_sexp_key_get_algorithm (GkmSexpKey *self)
     223              : {
     224              :         int algorithm;
     225            4 :         g_return_val_if_fail (self->pv->base_sexp, 0);
     226            4 :         if (!gkm_sexp_parse_key (gkm_sexp_get (self->pv->base_sexp), &algorithm, NULL, NULL))
     227            0 :                 g_return_val_if_reached (0);
     228            4 :         return algorithm;
     229              : }
     230              : 
     231              : static CK_RV
     232            6 : gkm_sexp_key_set_part_encode (GkmSexpKey *self, int algo, const char *part,
     233              :                               CK_ATTRIBUTE_PTR attr, int der_encode)
     234              : {
     235              :         gcry_sexp_t numbers;
     236              :         gcry_mpi_t mpi;
     237              :         int algorithm;
     238              :         CK_RV rv;
     239              : 
     240            6 :         g_return_val_if_fail (GKM_IS_SEXP_KEY (self), CKR_GENERAL_ERROR);
     241            6 :         g_return_val_if_fail (self->pv->base_sexp, CKR_GENERAL_ERROR);
     242              : 
     243            6 :         if (!gkm_sexp_parse_key (gkm_sexp_get (self->pv->base_sexp),
     244              :                                  &algorithm, NULL, &numbers))
     245            0 :                 g_return_val_if_reached (CKR_GENERAL_ERROR);
     246              : 
     247            6 :         if (algorithm != algo) {
     248            0 :                 gcry_sexp_release (numbers);
     249            0 :                 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: attribute %s not valid for key algorithm: %s",
     250              :                            gkm_log_attr_type (attr->type), gcry_pk_algo_name (algo));
     251            0 :                 return CKR_ATTRIBUTE_TYPE_INVALID;
     252              :         }
     253              : 
     254            6 :         if (!gkm_sexp_extract_mpi (numbers, &mpi, part, NULL))
     255            0 :                 g_return_val_if_reached (CKR_GENERAL_ERROR);
     256              : 
     257            6 :         if (der_encode) {
     258              :                 /* convert mpi to DER encoded OCTET string */
     259              :                 GBytes *data;
     260              : 
     261            1 :                 rv = gkm_data_der_encode_ecdsa_q (mpi, &data);
     262            1 :                 g_return_val_if_fail (rv, CKR_GENERAL_ERROR);
     263              : 
     264            1 :                 rv = gkm_attribute_set_bytes (attr, data);
     265            1 :                 g_bytes_unref (data);
     266              :         } else {
     267            5 :                 rv = gkm_attribute_set_mpi (attr, mpi);
     268              :         }
     269              : 
     270            6 :         gcry_sexp_release (numbers);
     271            6 :         gcry_mpi_release (mpi);
     272              : 
     273            6 :         return rv;
     274              : }
     275              : 
     276              : CK_RV
     277            5 : gkm_sexp_key_set_part (GkmSexpKey *self, int algo, const char *part, CK_ATTRIBUTE_PTR attr)
     278              : {
     279            5 :         return gkm_sexp_key_set_part_encode (self, algo, part, attr, 0);
     280              : }
     281              : 
     282              : CK_RV
     283            1 : gkm_sexp_key_set_ec_q (GkmSexpKey *self, int algo, CK_ATTRIBUTE_PTR attr)
     284              : {
     285            1 :         return gkm_sexp_key_set_part_encode (self, algo, "q", attr, 1);
     286              : }
     287              : 
     288              : CK_RV
     289            1 : gkm_sexp_key_set_ec_params (GkmSexpKey *self, int algo, CK_ATTRIBUTE_PTR attr)
     290              : {
     291              :         CK_RV rv;
     292              :         gchar *curve_name;
     293              :         GBytes *data;
     294              :         int algorithm;
     295              :         gcry_sexp_t numbers;
     296              : 
     297            1 :         g_return_val_if_fail (GKM_IS_SEXP_KEY (self), CKR_GENERAL_ERROR);
     298            1 :         g_return_val_if_fail (self->pv->base_sexp, CKR_GENERAL_ERROR);
     299              : 
     300            1 :         if (!gkm_sexp_parse_key (gkm_sexp_get (self->pv->base_sexp),
     301              :                                  &algorithm, NULL, &numbers))
     302            0 :                 g_return_val_if_reached (CKR_GENERAL_ERROR);
     303              : 
     304            1 :         if (algorithm != algo) {
     305            0 :                 gcry_sexp_release (numbers);
     306            0 :                 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: attribute %s not valid for key algorithm: %s",
     307              :                            gkm_log_attr_type (attr->type), gcry_pk_algo_name (algo));
     308            0 :                 return CKR_ATTRIBUTE_TYPE_INVALID;
     309              :         }
     310              : 
     311            1 :         rv = gkm_sexp_extract_string (numbers, &curve_name, "curve", NULL);
     312            1 :         g_return_val_if_fail (rv, CKR_GENERAL_ERROR);
     313              : 
     314            1 :         data = gkm_data_der_curve_to_ec_params (curve_name);
     315            1 :         g_return_val_if_fail (data != NULL, CKR_GENERAL_ERROR);
     316              : 
     317            1 :         rv = gkm_attribute_set_bytes (attr, data);
     318            1 :         g_bytes_unref (data);
     319            1 :         gcry_sexp_release (numbers);
     320            1 :         g_free (curve_name);
     321              : 
     322            1 :         return rv;
     323              : }
     324              : 
     325              : GkmSexp*
     326            0 : gkm_sexp_key_acquire_crypto_sexp (GkmSexpKey *self, GkmSession *session)
     327              : {
     328            0 :         g_return_val_if_fail (GKM_IS_SEXP_KEY (self), NULL);
     329            0 :         g_return_val_if_fail (GKM_SEXP_KEY_GET_CLASS (self)->acquire_crypto_sexp, NULL);
     330            0 :         return GKM_SEXP_KEY_GET_CLASS (self)->acquire_crypto_sexp (self, session);
     331              : }
        

Generated by: LCOV version 2.0-1