LCOV - code coverage report
Current view: top level - sm - import.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 83 435 19.1 %
Date: 2016-09-12 12:29:17 Functions: 5 11 45.5 %

          Line data    Source code
       1             : /* import.c - Import certificates
       2             :  * Copyright (C) 2001, 2003, 2004, 2009, 2010 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : #include <stdio.h>
      22             : #include <stdlib.h>
      23             : #include <string.h>
      24             : #include <errno.h>
      25             : #include <time.h>
      26             : #include <assert.h>
      27             : #include <unistd.h>
      28             : 
      29             : #include "gpgsm.h"
      30             : #include <gcrypt.h>
      31             : #include <ksba.h>
      32             : 
      33             : #include "keydb.h"
      34             : #include "exechelp.h"
      35             : #include "i18n.h"
      36             : #include "sysutils.h"
      37             : #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
      38             : #include "../common/membuf.h"
      39             : #include "minip12.h"
      40             : 
      41             : /* The arbitrary limit of one PKCS#12 object.  */
      42             : #define MAX_P12OBJ_SIZE 128 /*kb*/
      43             : 
      44             : 
      45             : struct stats_s {
      46             :   unsigned long count;
      47             :   unsigned long imported;
      48             :   unsigned long unchanged;
      49             :   unsigned long not_imported;
      50             :   unsigned long secret_read;
      51             :   unsigned long secret_imported;
      52             :   unsigned long secret_dups;
      53             :  };
      54             : 
      55             : 
      56             : struct rsa_secret_key_s
      57             : {
      58             :   gcry_mpi_t n;     /* public modulus */
      59             :   gcry_mpi_t e;     /* public exponent */
      60             :   gcry_mpi_t d;     /* exponent */
      61             :   gcry_mpi_t p;     /* prime  p. */
      62             :   gcry_mpi_t q;     /* prime  q. */
      63             :   gcry_mpi_t u;     /* inverse of p mod q. */
      64             : };
      65             : 
      66             : 
      67             : static gpg_error_t parse_p12 (ctrl_t ctrl, ksba_reader_t reader,
      68             :                               struct stats_s *stats);
      69             : 
      70             : 
      71             : 
      72             : static void
      73           3 : print_imported_status (ctrl_t ctrl, ksba_cert_t cert, int new_cert)
      74             : {
      75             :   char *fpr;
      76             : 
      77           3 :   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
      78           3 :   if (new_cert)
      79           3 :     gpgsm_status2 (ctrl, STATUS_IMPORTED, fpr, "[X.509]", NULL);
      80             : 
      81           3 :   gpgsm_status2 (ctrl, STATUS_IMPORT_OK,
      82             :                  new_cert? "1":"0",  fpr, NULL);
      83             : 
      84           3 :   xfree (fpr);
      85           3 : }
      86             : 
      87             : 
      88             : /* Print an IMPORT_PROBLEM status.  REASON is one of:
      89             :    0 := "No specific reason given".
      90             :    1 := "Invalid Certificate".
      91             :    2 := "Issuer Certificate missing".
      92             :    3 := "Certificate Chain too long".
      93             :    4 := "Error storing certificate".
      94             : */
      95             : static void
      96           0 : print_import_problem (ctrl_t ctrl, ksba_cert_t cert, int reason)
      97             : {
      98           0 :   char *fpr = NULL;
      99             :   char buf[25];
     100             :   int i;
     101             : 
     102           0 :   sprintf (buf, "%d", reason);
     103           0 :   if (cert)
     104             :     {
     105           0 :       fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
     106             :       /* detetect an error (all high) value */
     107           0 :       for (i=0; fpr[i] == 'F'; i++)
     108             :         ;
     109           0 :       if (!fpr[i])
     110             :         {
     111           0 :           xfree (fpr);
     112           0 :           fpr = NULL;
     113             :         }
     114             :     }
     115           0 :   gpgsm_status2 (ctrl, STATUS_IMPORT_PROBLEM, buf, fpr, NULL);
     116           0 :   xfree (fpr);
     117           0 : }
     118             : 
     119             : 
     120             : void
     121           3 : print_imported_summary (ctrl_t ctrl, struct stats_s *stats)
     122             : {
     123             :   char buf[14*25];
     124             : 
     125           3 :   if (!opt.quiet)
     126             :     {
     127           3 :       log_info (_("total number processed: %lu\n"), stats->count);
     128           3 :       if (stats->imported)
     129             :         {
     130           3 :           log_info (_("              imported: %lu"), stats->imported );
     131           3 :           log_printf ("\n");
     132             :         }
     133           3 :       if (stats->unchanged)
     134           0 :         log_info (_("             unchanged: %lu\n"), stats->unchanged);
     135           3 :       if (stats->secret_read)
     136           0 :         log_info (_("      secret keys read: %lu\n"), stats->secret_read );
     137           3 :       if (stats->secret_imported)
     138           0 :         log_info (_("  secret keys imported: %lu\n"), stats->secret_imported );
     139           3 :       if (stats->secret_dups)
     140           0 :         log_info (_(" secret keys unchanged: %lu\n"), stats->secret_dups );
     141           3 :       if (stats->not_imported)
     142           0 :         log_info (_("          not imported: %lu\n"), stats->not_imported);
     143             :     }
     144             : 
     145           3 :   sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
     146             :           stats->count,
     147             :           0l /*stats->no_user_id*/,
     148             :           stats->imported,
     149             :           0l /*stats->imported_rsa*/,
     150             :           stats->unchanged,
     151             :           0l /*stats->n_uids*/,
     152             :           0l /*stats->n_subk*/,
     153             :           0l /*stats->n_sigs*/,
     154             :           0l /*stats->n_revoc*/,
     155             :           stats->secret_read,
     156             :           stats->secret_imported,
     157             :           stats->secret_dups,
     158             :           0l /*stats->skipped_new_keys*/,
     159             :           stats->not_imported
     160             :           );
     161           3 :   gpgsm_status (ctrl, STATUS_IMPORT_RES, buf);
     162           3 : }
     163             : 
     164             : 
     165             : 
     166             : static void
     167           3 : check_and_store (ctrl_t ctrl, struct stats_s *stats,
     168             :                  ksba_cert_t cert, int depth)
     169             : {
     170             :   int rc;
     171             : 
     172           3 :   if (stats)
     173           3 :     stats->count++;
     174           3 :   if ( depth >= 50 )
     175             :     {
     176           0 :       log_error (_("certificate chain too long\n"));
     177           0 :       if (stats)
     178           0 :         stats->not_imported++;
     179           0 :       print_import_problem (ctrl, cert, 3);
     180           3 :       return;
     181             :     }
     182             : 
     183             :   /* Some basic checks, but don't care about missing certificates;
     184             :      this is so that we are able to import entire certificate chains
     185             :      w/o requiring a special order (i.e. root-CA first).  This used
     186             :      to be different but because gpgsm_verify even imports
     187             :      certificates without any checks, it doesn't matter much and the
     188             :      code gets much cleaner.  A housekeeping function to remove
     189             :      certificates w/o an anchor would be nice, though.
     190             : 
     191             :      Optionally we do a full validation in addition to the basic test.
     192             :   */
     193           3 :   rc = gpgsm_basic_cert_check (ctrl, cert);
     194           3 :   if (!rc && ctrl->with_validation)
     195           0 :     rc = gpgsm_validate_chain (ctrl, cert, "", NULL, 0, NULL, 0, NULL);
     196           3 :   if (!rc || (!ctrl->with_validation
     197           0 :               && (gpg_err_code (rc) == GPG_ERR_MISSING_CERT
     198           0 :                   || gpg_err_code (rc) == GPG_ERR_MISSING_ISSUER_CERT)))
     199           3 :     {
     200             :       int existed;
     201             : 
     202           3 :       if (!keydb_store_cert (cert, 0, &existed))
     203             :         {
     204           3 :           ksba_cert_t next = NULL;
     205             : 
     206           3 :           if (!existed)
     207             :             {
     208           3 :               print_imported_status (ctrl, cert, 1);
     209           3 :               if (stats)
     210           3 :                 stats->imported++;
     211             :             }
     212             :           else
     213             :             {
     214           0 :               print_imported_status (ctrl, cert, 0);
     215           0 :               if (stats)
     216           0 :                 stats->unchanged++;
     217             :             }
     218             : 
     219           3 :           if (opt.verbose > 1 && existed)
     220             :             {
     221           0 :               if (depth)
     222           0 :                 log_info ("issuer certificate already in DB\n");
     223             :               else
     224           0 :                 log_info ("certificate already in DB\n");
     225             :             }
     226           3 :           else if (opt.verbose && !existed)
     227             :             {
     228           0 :               if (depth)
     229           0 :                 log_info ("issuer certificate imported\n");
     230             :               else
     231           0 :                 log_info ("certificate imported\n");
     232             :             }
     233             : 
     234             :           /* Now lets walk up the chain and import all certificates up
     235             :              the chain.  This is required in case we already stored
     236             :              parent certificates in the ephemeral keybox.  Do not
     237             :              update the statistics, though. */
     238           3 :           if (!gpgsm_walk_cert_chain (ctrl, cert, &next))
     239             :             {
     240           0 :               check_and_store (ctrl, NULL, next, depth+1);
     241           0 :               ksba_cert_release (next);
     242             :             }
     243             :         }
     244             :       else
     245             :         {
     246           0 :           log_error (_("error storing certificate\n"));
     247           0 :           if (stats)
     248           0 :             stats->not_imported++;
     249           0 :           print_import_problem (ctrl, cert, 4);
     250             :         }
     251             :     }
     252             :   else
     253             :     {
     254           0 :       log_error (_("basic certificate checks failed - not imported\n"));
     255           0 :       if (stats)
     256           0 :         stats->not_imported++;
     257             :       /* We keep the test for GPG_ERR_MISSING_CERT only in case
     258             :          GPG_ERR_MISSING_CERT has been used instead of the newer
     259             :          GPG_ERR_MISSING_ISSUER_CERT.  */
     260           0 :       print_import_problem
     261             :         (ctrl, cert,
     262           0 :          gpg_err_code (rc) == GPG_ERR_MISSING_ISSUER_CERT? 2 :
     263           0 :          gpg_err_code (rc) == GPG_ERR_MISSING_CERT? 2 :
     264           0 :          gpg_err_code (rc) == GPG_ERR_BAD_CERT?     1 : 0);
     265             :     }
     266             : }
     267             : 
     268             : 
     269             : 
     270             : 
     271             : static int
     272           3 : import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
     273             : {
     274             :   int rc;
     275           3 :   Base64Context b64reader = NULL;
     276             :   ksba_reader_t reader;
     277           3 :   ksba_cert_t cert = NULL;
     278           3 :   ksba_cms_t cms = NULL;
     279           3 :   estream_t fp = NULL;
     280             :   ksba_content_type_t ct;
     281           3 :   int any = 0;
     282             : 
     283           3 :   fp = es_fdopen_nc (in_fd, "rb");
     284           3 :   if (!fp)
     285             :     {
     286           0 :       rc = gpg_error_from_syserror ();
     287           0 :       log_error ("fdopen() failed: %s\n", strerror (errno));
     288           0 :       goto leave;
     289             :     }
     290             : 
     291           3 :   rc = gpgsm_create_reader (&b64reader, ctrl, fp, 1, &reader);
     292           3 :   if (rc)
     293             :     {
     294           0 :       log_error ("can't create reader: %s\n", gpg_strerror (rc));
     295           0 :       goto leave;
     296             :     }
     297             : 
     298             : 
     299             :   /* We need to loop here to handle multiple PEM objects in one
     300             :      file. */
     301             :   do
     302             :     {
     303           6 :       ksba_cms_release (cms); cms = NULL;
     304           6 :       ksba_cert_release (cert); cert = NULL;
     305             : 
     306           6 :       ct = ksba_cms_identify (reader);
     307           6 :       if (ct == KSBA_CT_SIGNED_DATA)
     308             :         { /* This is probably a signed-only message - import the certs */
     309             :           ksba_stop_reason_t stopreason;
     310             :           int i;
     311             : 
     312           0 :           rc = ksba_cms_new (&cms);
     313           0 :           if (rc)
     314           0 :             goto leave;
     315             : 
     316           0 :           rc = ksba_cms_set_reader_writer (cms, reader, NULL);
     317           0 :           if (rc)
     318             :             {
     319           0 :               log_error ("ksba_cms_set_reader_writer failed: %s\n",
     320             :                          gpg_strerror (rc));
     321           0 :               goto leave;
     322             :             }
     323             : 
     324             :           do
     325             :             {
     326           0 :               rc = ksba_cms_parse (cms, &stopreason);
     327           0 :               if (rc)
     328             :                 {
     329           0 :                   log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
     330           0 :                   goto leave;
     331             :                 }
     332             : 
     333           0 :               if (stopreason == KSBA_SR_BEGIN_DATA)
     334           0 :                 log_info ("not a certs-only message\n");
     335             :             }
     336           0 :           while (stopreason != KSBA_SR_READY);
     337             : 
     338           0 :           for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
     339             :             {
     340           0 :               check_and_store (ctrl, stats, cert, 0);
     341           0 :               ksba_cert_release (cert);
     342           0 :               cert = NULL;
     343             :             }
     344           0 :           if (!i)
     345           0 :             log_error ("no certificate found\n");
     346             :           else
     347           0 :             any = 1;
     348             :         }
     349           6 :       else if (ct == KSBA_CT_PKCS12)
     350             :         {
     351             :           /* This seems to be a pkcs12 message. */
     352           0 :           rc = parse_p12 (ctrl, reader, stats);
     353           0 :           if (!rc)
     354           0 :             any = 1;
     355             :         }
     356           6 :       else if (ct == KSBA_CT_NONE)
     357             :         { /* Failed to identify this message - assume a certificate */
     358             : 
     359           6 :           rc = ksba_cert_new (&cert);
     360           6 :           if (rc)
     361           0 :             goto leave;
     362             : 
     363           6 :           rc = ksba_cert_read_der (cert, reader);
     364           6 :           if (rc)
     365           3 :             goto leave;
     366             : 
     367           3 :           check_and_store (ctrl, stats, cert, 0);
     368           3 :           any = 1;
     369             :         }
     370             :       else
     371             :         {
     372           0 :           log_error ("can't extract certificates from input\n");
     373           0 :           rc = gpg_error (GPG_ERR_NO_DATA);
     374             :         }
     375             : 
     376           3 :       ksba_reader_clear (reader, NULL, NULL);
     377             :     }
     378           3 :   while (!gpgsm_reader_eof_seen (b64reader));
     379             : 
     380             :  leave:
     381           3 :   if (any && gpg_err_code (rc) == GPG_ERR_EOF)
     382           3 :     rc = 0;
     383           3 :   ksba_cms_release (cms);
     384           3 :   ksba_cert_release (cert);
     385           3 :   gpgsm_destroy_reader (b64reader);
     386           3 :   es_fclose (fp);
     387           3 :   return rc;
     388             : }
     389             : 
     390             : 
     391             : 
     392             : /* Re-import certifciates.  IN_FD is a list of linefeed delimited
     393             :    fingerprints t re-import.  The actual re-import is done by clearing
     394             :    the ephemeral flag.  */
     395             : static int
     396           0 : reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
     397             : {
     398           0 :   gpg_error_t err = 0;
     399           0 :   estream_t fp = NULL;
     400             :   char line[100];  /* Sufficient for a fingerprint.  */
     401             :   KEYDB_HANDLE kh;
     402             :   KEYDB_SEARCH_DESC desc;
     403           0 :   ksba_cert_t cert = NULL;
     404             :   unsigned int flags;
     405             : 
     406           0 :   kh = keydb_new (0);
     407           0 :   if (!kh)
     408             :     {
     409           0 :       err = gpg_error (GPG_ERR_ENOMEM);;
     410           0 :       log_error (_("failed to allocate keyDB handle\n"));
     411           0 :       goto leave;
     412             :     }
     413           0 :   keydb_set_ephemeral (kh, 1);
     414             : 
     415           0 :   fp = es_fdopen_nc (in_fd, "r");
     416           0 :   if (!fp)
     417             :     {
     418           0 :       err = gpg_error_from_syserror ();
     419           0 :       log_error ("es_fdopen(%d) failed: %s\n", in_fd, gpg_strerror (err));
     420           0 :       goto leave;
     421             :     }
     422             : 
     423           0 :   while (es_fgets (line, DIM(line)-1, fp) )
     424             :     {
     425           0 :       if (*line && line[strlen(line)-1] != '\n')
     426             :         {
     427           0 :           err = gpg_error (GPG_ERR_LINE_TOO_LONG);
     428           0 :           goto leave;
     429             :         }
     430           0 :       trim_spaces (line);
     431           0 :       if (!*line)
     432           0 :         continue;
     433             : 
     434           0 :       stats->count++;
     435             : 
     436           0 :       err = classify_user_id (line, &desc, 0);
     437           0 :       if (err)
     438             :         {
     439           0 :           print_import_problem (ctrl, NULL, 0);
     440           0 :           stats->not_imported++;
     441           0 :           continue;
     442             :         }
     443             : 
     444           0 :       keydb_search_reset (kh);
     445           0 :       err = keydb_search (kh, &desc, 1);
     446           0 :       if (err)
     447             :         {
     448           0 :           print_import_problem (ctrl, NULL, 0);
     449           0 :           stats->not_imported++;
     450           0 :           continue;
     451             :         }
     452             : 
     453           0 :       ksba_cert_release (cert);
     454           0 :       cert = NULL;
     455           0 :       err = keydb_get_cert (kh, &cert);
     456           0 :       if (err)
     457             :         {
     458           0 :           log_error ("keydb_get_cert() failed: %s\n", gpg_strerror (err));
     459           0 :           print_import_problem (ctrl, NULL, 1);
     460           0 :           stats->not_imported++;
     461           0 :           continue;
     462             :         }
     463             : 
     464           0 :       err = keydb_get_flags (kh, KEYBOX_FLAG_BLOB, 0, &flags);
     465           0 :       if (err)
     466             :         {
     467           0 :           log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
     468           0 :           print_imported_status (ctrl, cert, 0);
     469           0 :           stats->not_imported++;
     470           0 :           continue;
     471             :         }
     472           0 :       if ( !(flags & KEYBOX_FLAG_BLOB_EPHEMERAL) )
     473             :         {
     474           0 :           print_imported_status (ctrl, cert, 0);
     475           0 :           stats->unchanged++;
     476           0 :           continue;
     477             :         }
     478             : 
     479           0 :       err = keydb_set_cert_flags (cert, 1, KEYBOX_FLAG_BLOB, 0,
     480             :                                   KEYBOX_FLAG_BLOB_EPHEMERAL, 0);
     481           0 :       if (err)
     482             :         {
     483           0 :           log_error ("clearing ephemeral flag failed: %s\n",
     484             :                      gpg_strerror (err));
     485           0 :           print_import_problem (ctrl, cert, 0);
     486           0 :           stats->not_imported++;
     487           0 :           continue;
     488             :         }
     489             : 
     490           0 :       print_imported_status (ctrl, cert, 1);
     491           0 :       stats->imported++;
     492             :     }
     493           0 :   err = 0;
     494           0 :   if (es_ferror (fp))
     495             :     {
     496           0 :       err = gpg_error_from_syserror ();
     497           0 :       log_error ("error reading fd %d: %s\n", in_fd, gpg_strerror (err));
     498           0 :       goto leave;
     499             :     }
     500             : 
     501             :  leave:
     502           0 :   ksba_cert_release (cert);
     503           0 :   keydb_release (kh);
     504           0 :   es_fclose (fp);
     505           0 :   return err;
     506             : }
     507             : 
     508             : 
     509             : 
     510             : int
     511           0 : gpgsm_import (ctrl_t ctrl, int in_fd, int reimport_mode)
     512             : {
     513             :   int rc;
     514             :   struct stats_s stats;
     515             : 
     516           0 :   memset (&stats, 0, sizeof stats);
     517           0 :   if (reimport_mode)
     518           0 :     rc = reimport_one (ctrl, &stats, in_fd);
     519             :   else
     520           0 :     rc = import_one (ctrl, &stats, in_fd);
     521           0 :   print_imported_summary (ctrl, &stats);
     522             :   /* If we never printed an error message do it now so that a command
     523             :      line invocation will return with an error (log_error keeps a
     524             :      global errorcount) */
     525           0 :   if (rc && !log_get_errorcount (0))
     526           0 :     log_error (_("error importing certificate: %s\n"), gpg_strerror (rc));
     527           0 :   return rc;
     528             : }
     529             : 
     530             : 
     531             : int
     532           3 : gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files,
     533             :                     int (*of)(const char *fname))
     534             : {
     535           3 :   int rc = 0;
     536             :   struct stats_s stats;
     537             : 
     538           3 :   memset (&stats, 0, sizeof stats);
     539             : 
     540           3 :   if (!nfiles)
     541           0 :     rc = import_one (ctrl, &stats, 0);
     542             :   else
     543             :     {
     544           6 :       for (; nfiles && !rc ; nfiles--, files++)
     545             :         {
     546           3 :           int fd = of (*files);
     547           3 :           rc = import_one (ctrl, &stats, fd);
     548           3 :           close (fd);
     549           3 :           if (rc == -1)
     550           0 :             rc = 0;
     551             :         }
     552             :     }
     553           3 :   print_imported_summary (ctrl, &stats);
     554             :   /* If we never printed an error message do it now so that a command
     555             :      line invocation will return with an error (log_error keeps a
     556             :      global errorcount) */
     557           3 :   if (rc && !log_get_errorcount (0))
     558           0 :     log_error (_("error importing certificate: %s\n"), gpg_strerror (rc));
     559           3 :   return rc;
     560             : }
     561             : 
     562             : 
     563             : /* Check that the RSA secret key SKEY is valid.  Swap parameters to
     564             :    the libgcrypt standard.  */
     565             : static gpg_error_t
     566           0 : rsa_key_check (struct rsa_secret_key_s *skey)
     567             : {
     568           0 :   int err = 0;
     569           0 :   gcry_mpi_t t = gcry_mpi_snew (0);
     570           0 :   gcry_mpi_t t1 = gcry_mpi_snew (0);
     571           0 :   gcry_mpi_t t2 = gcry_mpi_snew (0);
     572           0 :   gcry_mpi_t phi = gcry_mpi_snew (0);
     573             : 
     574             :   /* Check that n == p * q.  */
     575           0 :   gcry_mpi_mul (t, skey->p, skey->q);
     576           0 :   if (gcry_mpi_cmp( t, skey->n) )
     577             :     {
     578           0 :       log_error ("RSA oops: n != p * q\n");
     579           0 :       err++;
     580             :     }
     581             : 
     582             :   /* Check that p is less than q.  */
     583           0 :   if (gcry_mpi_cmp (skey->p, skey->q) > 0)
     584             :     {
     585             :       gcry_mpi_t tmp;
     586             : 
     587           0 :       log_info ("swapping secret primes\n");
     588           0 :       tmp = gcry_mpi_copy (skey->p);
     589           0 :       gcry_mpi_set (skey->p, skey->q);
     590           0 :       gcry_mpi_set (skey->q, tmp);
     591           0 :       gcry_mpi_release (tmp);
     592             :       /* Recompute u.  */
     593           0 :       gcry_mpi_invm (skey->u, skey->p, skey->q);
     594             :     }
     595             : 
     596             :   /* Check that e divides neither p-1 nor q-1.  */
     597           0 :   gcry_mpi_sub_ui (t, skey->p, 1 );
     598           0 :   gcry_mpi_div (NULL, t, t, skey->e, 0);
     599           0 :   if (!gcry_mpi_cmp_ui( t, 0) )
     600             :     {
     601           0 :       log_error ("RSA oops: e divides p-1\n");
     602           0 :       err++;
     603             :     }
     604           0 :   gcry_mpi_sub_ui (t, skey->q, 1);
     605           0 :   gcry_mpi_div (NULL, t, t, skey->e, 0);
     606           0 :   if (!gcry_mpi_cmp_ui( t, 0))
     607             :     {
     608           0 :       log_info ("RSA oops: e divides q-1\n" );
     609           0 :       err++;
     610             :     }
     611             : 
     612             :   /* Check that d is correct.  */
     613           0 :   gcry_mpi_sub_ui (t1, skey->p, 1);
     614           0 :   gcry_mpi_sub_ui (t2, skey->q, 1);
     615           0 :   gcry_mpi_mul (phi, t1, t2);
     616           0 :   gcry_mpi_invm (t, skey->e, phi);
     617           0 :   if (gcry_mpi_cmp (t, skey->d))
     618             :     {
     619             :       /* No: try universal exponent. */
     620           0 :       gcry_mpi_gcd (t, t1, t2);
     621           0 :       gcry_mpi_div (t, NULL, phi, t, 0);
     622           0 :       gcry_mpi_invm (t, skey->e, t);
     623           0 :       if (gcry_mpi_cmp (t, skey->d))
     624             :         {
     625           0 :           log_error ("RSA oops: bad secret exponent\n");
     626           0 :           err++;
     627             :         }
     628             :     }
     629             : 
     630             :   /* Check for correctness of u.  */
     631           0 :   gcry_mpi_invm (t, skey->p, skey->q);
     632           0 :   if (gcry_mpi_cmp (t, skey->u))
     633             :     {
     634           0 :       log_info ("RSA oops: bad u parameter\n");
     635           0 :       err++;
     636             :     }
     637             : 
     638           0 :   if (err)
     639           0 :     log_info ("RSA secret key check failed\n");
     640             : 
     641           0 :   gcry_mpi_release (t);
     642           0 :   gcry_mpi_release (t1);
     643           0 :   gcry_mpi_release (t2);
     644           0 :   gcry_mpi_release (phi);
     645             : 
     646           0 :   return err? gpg_error (GPG_ERR_BAD_SECKEY):0;
     647             : }
     648             : 
     649             : 
     650             : /* Object passed to store_cert_cb.  */
     651             : struct store_cert_parm_s
     652             : {
     653             :   gpg_error_t err;        /* First error seen.  */
     654             :   struct stats_s *stats;  /* The stats object.  */
     655             :   ctrl_t ctrl;            /* The control object.  */
     656             : };
     657             : 
     658             : /* Helper to store the DER encoded certificate CERTDATA of length
     659             :    CERTDATALEN.  */
     660             : static void
     661           0 : store_cert_cb (void *opaque,
     662             :                const unsigned char *certdata, size_t certdatalen)
     663             : {
     664           0 :   struct store_cert_parm_s *parm = opaque;
     665             :   gpg_error_t err;
     666             :   ksba_cert_t cert;
     667             : 
     668           0 :   err = ksba_cert_new (&cert);
     669           0 :   if (err)
     670             :     {
     671           0 :       if (!parm->err)
     672           0 :         parm->err = err;
     673           0 :       return;
     674             :     }
     675             : 
     676           0 :   err = ksba_cert_init_from_mem (cert, certdata, certdatalen);
     677           0 :   if (err)
     678             :     {
     679           0 :       log_error ("failed to parse a certificate: %s\n", gpg_strerror (err));
     680           0 :       if (!parm->err)
     681           0 :         parm->err = err;
     682             :     }
     683             :   else
     684           0 :     check_and_store (parm->ctrl, parm->stats, cert, 0);
     685           0 :   ksba_cert_release (cert);
     686             : }
     687             : 
     688             : 
     689             : /* Assume that the reader is at a pkcs#12 message and try to import
     690             :    certificates from that stupid format.  We will transfer secret
     691             :    keys to the agent.  */
     692             : static gpg_error_t
     693           0 : parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
     694             : {
     695           0 :   gpg_error_t err = 0;
     696             :   char buffer[1024];
     697             :   size_t ntotal, nread;
     698             :   membuf_t p12mbuf;
     699           0 :   char *p12buffer = NULL;
     700             :   size_t p12buflen;
     701             :   size_t p12bufoff;
     702           0 :   gcry_mpi_t *kparms = NULL;
     703             :   struct rsa_secret_key_s sk;
     704           0 :   char *passphrase = NULL;
     705           0 :   unsigned char *key = NULL;
     706             :   size_t keylen;
     707           0 :   void *kek = NULL;
     708             :   size_t keklen;
     709           0 :   unsigned char *wrappedkey = NULL;
     710             :   size_t wrappedkeylen;
     711           0 :   gcry_cipher_hd_t cipherhd = NULL;
     712           0 :   gcry_sexp_t s_key = NULL;
     713             :   unsigned char grip[20];
     714           0 :   int bad_pass = 0;
     715             :   int i;
     716             :   struct store_cert_parm_s store_cert_parm;
     717             : 
     718           0 :   memset (&store_cert_parm, 0, sizeof store_cert_parm);
     719           0 :   store_cert_parm.ctrl = ctrl;
     720           0 :   store_cert_parm.stats = stats;
     721             : 
     722           0 :   init_membuf (&p12mbuf, 4096);
     723           0 :   ntotal = 0;
     724           0 :   while (!(err = ksba_reader_read (reader, buffer, sizeof buffer, &nread)))
     725             :     {
     726           0 :       if (ntotal >= MAX_P12OBJ_SIZE*1024)
     727             :         {
     728             :           /* Arbitrary limit to avoid DoS attacks. */
     729           0 :           err = gpg_error (GPG_ERR_TOO_LARGE);
     730           0 :           log_error ("pkcs#12 object is larger than %dk\n", MAX_P12OBJ_SIZE);
     731           0 :           break;
     732             :         }
     733           0 :       put_membuf (&p12mbuf, buffer, nread);
     734           0 :       ntotal += nread;
     735             :     }
     736           0 :   if (gpg_err_code (err) == GPG_ERR_EOF)
     737           0 :     err = 0;
     738           0 :   if (!err)
     739             :     {
     740           0 :       p12buffer = get_membuf (&p12mbuf, &p12buflen);
     741           0 :       if (!p12buffer)
     742           0 :         err = gpg_error_from_syserror ();
     743             :     }
     744           0 :   if (err)
     745             :     {
     746           0 :       log_error (_("error reading input: %s\n"), gpg_strerror (err));
     747           0 :       goto leave;
     748             :     }
     749             : 
     750             :   /* GnuPG 2.0.4 accidentally created binary P12 files with the string
     751             :      "The passphrase is %s encoded.\n\n" prepended to the ASN.1 data.
     752             :      We fix that here.  */
     753           0 :   if (p12buflen > 29 && !memcmp (p12buffer, "The passphrase is ", 18))
     754             :     {
     755           0 :       for (p12bufoff=18;
     756           0 :            p12bufoff < p12buflen && p12buffer[p12bufoff] != '\n';
     757           0 :            p12bufoff++)
     758             :         ;
     759           0 :       p12bufoff++;
     760           0 :       if (p12bufoff < p12buflen && p12buffer[p12bufoff] == '\n')
     761           0 :         p12bufoff++;
     762             :     }
     763             :   else
     764           0 :     p12bufoff = 0;
     765             : 
     766             : 
     767           0 :   err = gpgsm_agent_ask_passphrase
     768             :     (ctrl,
     769             :      i18n_utf8 ("Please enter the passphrase to unprotect the PKCS#12 object."),
     770             :      0, &passphrase);
     771           0 :   if (err)
     772           0 :     goto leave;
     773             : 
     774           0 :   kparms = p12_parse (p12buffer + p12bufoff, p12buflen - p12bufoff,
     775             :                       passphrase, store_cert_cb, &store_cert_parm, &bad_pass);
     776             : 
     777           0 :   xfree (passphrase);
     778           0 :   passphrase = NULL;
     779             : 
     780           0 :   if (!kparms)
     781             :     {
     782           0 :       log_error ("error parsing or decrypting the PKCS#12 file\n");
     783           0 :       err = gpg_error (GPG_ERR_INV_OBJ);
     784           0 :       goto leave;
     785             :     }
     786             : 
     787             : /*    print_mpi ("   n", kparms[0]); */
     788             : /*    print_mpi ("   e", kparms[1]); */
     789             : /*    print_mpi ("   d", kparms[2]); */
     790             : /*    print_mpi ("   p", kparms[3]); */
     791             : /*    print_mpi ("   q", kparms[4]); */
     792             : /*    print_mpi ("dmp1", kparms[5]); */
     793             : /*    print_mpi ("dmq1", kparms[6]); */
     794             : /*    print_mpi ("   u", kparms[7]); */
     795             : 
     796           0 :   sk.n = kparms[0];
     797           0 :   sk.e = kparms[1];
     798           0 :   sk.d = kparms[2];
     799           0 :   sk.q = kparms[3];
     800           0 :   sk.p = kparms[4];
     801           0 :   sk.u = kparms[7];
     802           0 :   err = rsa_key_check (&sk);
     803           0 :   if (err)
     804           0 :     goto leave;
     805             : /*    print_mpi ("   n", sk.n); */
     806             : /*    print_mpi ("   e", sk.e); */
     807             : /*    print_mpi ("   d", sk.d); */
     808             : /*    print_mpi ("   p", sk.p); */
     809             : /*    print_mpi ("   q", sk.q); */
     810             : /*    print_mpi ("   u", sk.u); */
     811             : 
     812             :   /* Create an S-expresion from the parameters. */
     813           0 :   err = gcry_sexp_build (&s_key, NULL,
     814             :                          "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
     815             :                          sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL);
     816           0 :   for (i=0; i < 8; i++)
     817           0 :     gcry_mpi_release (kparms[i]);
     818           0 :   gcry_free (kparms);
     819           0 :   kparms = NULL;
     820           0 :   if (err)
     821             :     {
     822           0 :       log_error ("failed to create S-expression from key: %s\n",
     823             :                  gpg_strerror (err));
     824           0 :       goto leave;
     825             :     }
     826             : 
     827             :   /* Compute the keygrip. */
     828           0 :   if (!gcry_pk_get_keygrip (s_key, grip))
     829             :     {
     830           0 :       err = gpg_error (GPG_ERR_GENERAL);
     831           0 :       log_error ("can't calculate keygrip\n");
     832           0 :       goto leave;
     833             :     }
     834           0 :   log_printhex ("keygrip=", grip, 20);
     835             : 
     836             :   /* Convert to canonical encoding using a function which pads it to a
     837             :      multiple of 64 bits.  We need this padding for AESWRAP.  */
     838           0 :   err = make_canon_sexp_pad (s_key, 1, &key, &keylen);
     839           0 :   if (err)
     840             :     {
     841           0 :       log_error ("error creating canonical S-expression\n");
     842           0 :       goto leave;
     843             :     }
     844           0 :   gcry_sexp_release (s_key);
     845           0 :   s_key = NULL;
     846             : 
     847             :   /* Get the current KEK.  */
     848           0 :   err = gpgsm_agent_keywrap_key (ctrl, 0, &kek, &keklen);
     849           0 :   if (err)
     850             :     {
     851           0 :       log_error ("error getting the KEK: %s\n", gpg_strerror (err));
     852           0 :       goto leave;
     853             :     }
     854             : 
     855             :   /* Wrap the key.  */
     856           0 :   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
     857             :                           GCRY_CIPHER_MODE_AESWRAP, 0);
     858           0 :   if (err)
     859           0 :     goto leave;
     860           0 :   err = gcry_cipher_setkey (cipherhd, kek, keklen);
     861           0 :   if (err)
     862           0 :     goto leave;
     863           0 :   xfree (kek);
     864           0 :   kek = NULL;
     865             : 
     866           0 :   wrappedkeylen = keylen + 8;
     867           0 :   wrappedkey = xtrymalloc (wrappedkeylen);
     868           0 :   if (!wrappedkey)
     869             :     {
     870           0 :       err = gpg_error_from_syserror ();
     871           0 :       goto leave;
     872             :     }
     873             : 
     874           0 :   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
     875           0 :   if (err)
     876           0 :     goto leave;
     877           0 :   xfree (key);
     878           0 :   key = NULL;
     879           0 :   gcry_cipher_close (cipherhd);
     880           0 :   cipherhd = NULL;
     881             : 
     882             :   /* Send the wrapped key to the agent.  */
     883           0 :   err = gpgsm_agent_import_key (ctrl, wrappedkey, wrappedkeylen);
     884           0 :   if (!err)
     885             :     {
     886           0 :       stats->count++;
     887           0 :       stats->secret_read++;
     888           0 :       stats->secret_imported++;
     889             :     }
     890           0 :   else if ( gpg_err_code (err) == GPG_ERR_EEXIST )
     891             :     {
     892           0 :       err = 0;
     893           0 :       stats->count++;
     894           0 :       stats->secret_read++;
     895           0 :       stats->secret_dups++;
     896             :     }
     897             : 
     898             :   /* If we did not get an error from storing the secret key we return
     899             :      a possible error from parsing the certificates.  We do this after
     900             :      storing the secret keys so that a bad certificate does not
     901             :      inhibit our chance to store the secret key.  */
     902           0 :   if (!err && store_cert_parm.err)
     903           0 :     err = store_cert_parm.err;
     904             : 
     905             :  leave:
     906           0 :   if (kparms)
     907             :     {
     908           0 :       for (i=0; i < 8; i++)
     909           0 :         gcry_mpi_release (kparms[i]);
     910           0 :       gcry_free (kparms);
     911           0 :       kparms = NULL;
     912             :     }
     913           0 :   xfree (key);
     914           0 :   gcry_sexp_release (s_key);
     915           0 :   xfree (passphrase);
     916           0 :   gcry_cipher_close (cipherhd);
     917           0 :   xfree (wrappedkey);
     918           0 :   xfree (kek);
     919           0 :   xfree (get_membuf (&p12mbuf, NULL));
     920           0 :   xfree (p12buffer);
     921             : 
     922           0 :   if (bad_pass)
     923             :     {
     924             :       /* We only write a plain error code and not direct
     925             :          BAD_PASSPHRASE because the pkcs12 parser might issue this
     926             :          message multiple times, BAD_PASSPHRASE in general requires a
     927             :          keyID and parts of the import might actually succeed so that
     928             :          IMPORT_PROBLEM is also not appropriate. */
     929           0 :       gpgsm_status_with_err_code (ctrl, STATUS_ERROR,
     930             :                                   "import.parsep12", GPG_ERR_BAD_PASSPHRASE);
     931             :     }
     932             : 
     933           0 :   return err;
     934             : }

Generated by: LCOV version 1.11