~ubuntu-branches/ubuntu/raring/gnupg2/raring-proposed

« back to all changes in this revision

Viewing changes to g10/call-agent.c

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2012-11-06 11:25:58 UTC
  • mfrom: (14.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20121106112558-kxptsug6ivixhx8m
Tags: 2.0.19-1ubuntu1
* Resynchronize on Debian, remaining changes:
  - Add udev rules to give gpg access to some smartcard readers;
    Debian #543217.
    . debian/gnupg2.dev: udev rules to set ACLs on SCM smartcard readers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* call-agent.c - Divert GPG operations to the agent.
2
 
 * Copyright (C) 2001, 2002, 2003, 2006, 2007, 
 
2
 * Copyright (C) 2001, 2002, 2003, 2006, 2007,
3
3
 *               2008, 2009 Free Software Foundation, Inc.
4
4
 *
5
5
 * This file is part of GnuPG.
23
23
#include <stdlib.h>
24
24
#include <string.h>
25
25
#include <errno.h>
26
 
#include <unistd.h> 
 
26
#include <unistd.h>
27
27
#include <time.h>
28
28
#include <assert.h>
29
29
#ifdef HAVE_LOCALE_H
48
48
static assuan_context_t agent_ctx = NULL;
49
49
static int did_early_card_test;
50
50
 
51
 
struct cipher_parm_s 
 
51
struct cipher_parm_s
52
52
{
53
53
  assuan_context_t ctx;
54
54
  const char *ciphertext;
69
69
  size_t keydatalen;
70
70
};
71
71
 
72
 
struct genkey_parm_s 
 
72
struct genkey_parm_s
73
73
{
74
74
  assuan_context_t ctx;
75
75
  const char *sexp;
76
76
  size_t sexplen;
77
77
};
78
78
 
 
79
struct scd_genkey_parm_s
 
80
{
 
81
  struct agent_card_genkey_s *cgk;
 
82
  char *savedbytes;     /* Malloced space to save key parameter chunks.  */
 
83
};
 
84
 
79
85
 
80
86
static gpg_error_t learn_status_cb (void *opaque, const char *line);
81
87
 
99
105
      write_status (STATUS_SC_OP_FAILURE);
100
106
      break;
101
107
    }
102
 
}  
 
108
}
103
109
 
104
110
 
105
111
 
162
168
      if (!rc && is_status_enabled () && info.serialno)
163
169
        {
164
170
          char *buf;
165
 
          
 
171
 
166
172
          buf = xasprintf ("3 %s", info.serialno);
167
173
          write_status_text (STATUS_CARDCTRL, buf);
168
174
          xfree (buf);
174
180
        did_early_card_test = 1;
175
181
    }
176
182
 
177
 
  
 
183
 
178
184
  return rc;
179
185
}
180
186
 
267
273
      memcpy (*serialno, line, n);
268
274
      (*serialno)[n] = 0;
269
275
    }
270
 
  
 
276
 
271
277
  return 0;
272
278
}
273
279
 
329
335
    {
330
336
      xfree (parm->serialno);
331
337
      parm->serialno = store_serialno (line);
332
 
      parm->is_v2 = (strlen (parm->serialno) >= 16 
 
338
      parm->is_v2 = (strlen (parm->serialno) >= 16
333
339
                     && xtoi_2 (parm->serialno+12) >= 2 );
334
340
    }
335
341
  else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen))
510
516
  /* Also try to get the key attributes.  */
511
517
  if (!rc)
512
518
    agent_scd_getattr ("KEY-ATTR", info);
513
 
  
 
519
 
514
520
  return rc;
515
521
}
516
522
 
529
535
  /* We assume that NAME does not need escaping. */
530
536
  if (12 + strlen (name) > DIM(line)-1)
531
537
    return gpg_error (GPG_ERR_TOO_LARGE);
532
 
  stpcpy (stpcpy (line, "SCD GETATTR "), name); 
 
538
  stpcpy (stpcpy (line, "SCD GETATTR "), name);
533
539
 
534
540
  rc = start_agent (1);
535
541
  if (rc)
537
543
 
538
544
  rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
539
545
                        learn_status_cb, info);
540
 
  
 
546
 
541
547
  return rc;
542
548
}
543
549
 
562
568
  /* We assume that NAME does not need escaping. */
563
569
  if (12 + strlen (name) > DIM(line)-1)
564
570
    return gpg_error (GPG_ERR_TOO_LARGE);
565
 
      
566
 
  p = stpcpy (stpcpy (line, "SCD SETATTR "), name); 
 
571
 
 
572
  p = stpcpy (stpcpy (line, "SCD SETATTR "), name);
567
573
  *p++ = ' ';
568
574
  for (; valuelen; value++, valuelen--)
569
575
    {
584
590
  rc = start_agent (1);
585
591
  if (!rc)
586
592
    {
587
 
      rc = assuan_transact (agent_ctx, line, NULL, NULL, 
 
593
      rc = assuan_transact (agent_ctx, line, NULL, NULL,
588
594
                            default_inq_cb, NULL, NULL, NULL);
589
595
    }
590
596
 
601
607
inq_writecert_parms (void *opaque, const char *line)
602
608
{
603
609
  int rc;
604
 
  struct writecert_parm_s *parm = opaque; 
 
610
  struct writecert_parm_s *parm = opaque;
605
611
 
606
612
  if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
607
613
    {
615
621
 
616
622
 
617
623
/* Send a WRITECERT command to the SCdaemon. */
618
 
int 
 
624
int
619
625
agent_scd_writecert (const char *certidstr,
620
626
                     const unsigned char *certdata, size_t certdatalen)
621
627
{
634
640
  parms.ctx = agent_ctx;
635
641
  parms.certdata = certdata;
636
642
  parms.certdatalen = certdatalen;
637
 
  
 
643
 
638
644
  rc = assuan_transact (agent_ctx, line, NULL, NULL,
639
645
                        inq_writecert_parms, &parms, NULL, NULL);
640
646
 
649
655
inq_writekey_parms (void *opaque, const char *line)
650
656
{
651
657
  int rc;
652
 
  struct writekey_parm_s *parm = opaque; 
 
658
  struct writekey_parm_s *parm = opaque;
653
659
 
654
660
  if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
655
661
    {
663
669
 
664
670
 
665
671
/* Send a WRITEKEY command to the SCdaemon. */
666
 
int 
 
672
int
667
673
agent_scd_writekey (int keyno, const char *serialno,
668
674
                    const unsigned char *keydata, size_t keydatalen)
669
675
{
684
690
  parms.ctx = agent_ctx;
685
691
  parms.keydata = keydata;
686
692
  parms.keydatalen = keydatalen;
687
 
  
 
693
 
688
694
  rc = assuan_transact (agent_ctx, line, NULL, NULL,
689
695
                        inq_writekey_parms, &parms, NULL, NULL);
690
696
 
694
700
 
695
701
 
696
702
 
 
703
static gpg_error_t
 
704
scd_genkey_cb_append_savedbytes (struct scd_genkey_parm_s *parm,
 
705
                                 const char *line)
 
706
{
 
707
  gpg_error_t err = 0;
 
708
  char *p;
 
709
 
 
710
  if (!parm->savedbytes)
 
711
    {
 
712
      parm->savedbytes = xtrystrdup (line);
 
713
      if (!parm->savedbytes)
 
714
        err = gpg_error_from_syserror ();
 
715
    }
 
716
  else
 
717
    {
 
718
      p = xtrymalloc (strlen (parm->savedbytes) + strlen (line) + 1);
 
719
      if (!p)
 
720
        err = gpg_error_from_syserror ();
 
721
      else
 
722
        {
 
723
          strcpy (stpcpy (p, parm->savedbytes), line);
 
724
          xfree (parm->savedbytes);
 
725
          parm->savedbytes = p;
 
726
        }
 
727
    }
 
728
 
 
729
  return err;
 
730
}
 
731
 
 
732
 
697
733
/* Status callback for the SCD GENKEY command. */
698
734
static gpg_error_t
699
735
scd_genkey_cb (void *opaque, const char *line)
700
736
{
701
 
  struct agent_card_genkey_s *parm = opaque;
 
737
  struct scd_genkey_parm_s *parm = opaque;
702
738
  const char *keyword = line;
703
739
  int keywordlen;
704
 
  gpg_error_t rc;
 
740
  gpg_error_t rc = 0;
705
741
 
706
742
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
707
743
    ;
710
746
 
711
747
  if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
712
748
    {
713
 
      parm->fprvalid = unhexify_fpr (line, parm->fpr);
 
749
      parm->cgk->fprvalid = unhexify_fpr (line, parm->cgk->fpr);
714
750
    }
715
751
  else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
716
752
    {
722
758
      while (spacep (line))
723
759
        line++;
724
760
 
725
 
      rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
726
 
      if (rc)
727
 
        log_error ("error parsing received key data: %s\n", gpg_strerror (rc));
728
 
      else if (*name == 'n' && spacep (name+1))
729
 
        parm->n = a;
730
 
      else if (*name == 'e' && spacep (name+1))
731
 
        parm->e = a;
 
761
      if (*name == '-' && spacep (name+1))
 
762
        rc = scd_genkey_cb_append_savedbytes (parm, line);
732
763
      else
733
764
        {
734
 
          log_info ("unknown parameter name in received key data\n");
735
 
          gcry_mpi_release (a);
 
765
          if (parm->savedbytes)
 
766
            {
 
767
              rc = scd_genkey_cb_append_savedbytes (parm, line);
 
768
              if (!rc)
 
769
                rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX,
 
770
                                    parm->savedbytes, 0, NULL);
 
771
            }
 
772
          else
 
773
            rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
 
774
          if (rc)
 
775
            log_error ("error parsing received key data: %s\n",
 
776
                       gpg_strerror (rc));
 
777
          else if (*name == 'n' && spacep (name+1))
 
778
            parm->cgk->n = a;
 
779
          else if (*name == 'e' && spacep (name+1))
 
780
            parm->cgk->e = a;
 
781
          else
 
782
            {
 
783
              log_info ("unknown parameter name in received key data\n");
 
784
              gcry_mpi_release (a);
 
785
              rc = gpg_error (GPG_ERR_INV_PARAMETER);
 
786
            }
 
787
 
 
788
          xfree (parm->savedbytes);
 
789
          parm->savedbytes = NULL;
736
790
        }
737
791
    }
738
792
  else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
739
793
    {
740
 
      parm->created_at = (u32)strtoul (line, NULL, 10);
 
794
      parm->cgk->created_at = (u32)strtoul (line, NULL, 10);
741
795
    }
742
796
  else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
743
797
    {
744
798
      write_status_text (STATUS_PROGRESS, line);
745
799
    }
746
800
 
747
 
  return 0;
 
801
  return rc;
748
802
}
749
803
 
750
804
/* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
759
813
  int rc;
760
814
  char line[ASSUAN_LINELENGTH];
761
815
  gnupg_isotime_t tbuf;
 
816
  struct scd_genkey_parm_s parms;
762
817
 
763
818
  (void)serialno;
764
819
 
 
820
  memset (&parms, 0, sizeof parms);
 
821
  parms.cgk = info;
 
822
 
765
823
  rc = start_agent (1);
766
824
  if (rc)
767
825
    return rc;
774
832
  memset (info, 0, sizeof *info);
775
833
  snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
776
834
            *tbuf? "--timestamp=":"", tbuf,
777
 
            force? "--force":"", 
 
835
            force? "--force":"",
778
836
            keyno);
779
837
  line[DIM(line)-1] = 0;
780
838
 
781
839
  memset (info, 0, sizeof *info);
782
840
  rc = assuan_transact (agent_ctx, line,
783
841
                        NULL, NULL, default_inq_cb, NULL,
784
 
                        scd_genkey_cb, info);
785
 
  
 
842
                        scd_genkey_cb, &parms);
 
843
 
 
844
  xfree (parms.savedbytes);
 
845
 
786
846
  status_sc_op_failure (rc);
787
847
  return rc;
788
848
}
800
860
  /* Send the serialno command to initialize the connection.  Without
801
861
     a given S/N we don't care about the data returned.  If the card
802
862
     has already been initialized, this is a very fast command.  We
803
 
     request the openpgp card because that is what we expect. 
 
863
     request the openpgp card because that is what we expect.
804
864
 
805
865
     Note that an opt.limit_card_insert_tries of 1 means: No tries at
806
866
     all whereas 0 means do not limit the number of tries.  Due to the
816
876
      int ask;
817
877
      char *want_sn;
818
878
      char *p;
819
 
      
 
879
 
820
880
      want_sn = xtrystrdup (serialno);
821
881
      if (!want_sn)
822
882
        return gpg_error_from_syserror ();
824
884
      if (p)
825
885
        *p = 0;
826
886
 
827
 
      do 
 
887
      do
828
888
        {
829
889
          ask = 0;
830
890
          err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
831
 
                                 NULL, NULL, NULL, NULL, 
 
891
                                 NULL, NULL, NULL, NULL,
832
892
                                 get_serialno_cb, &this_sn);
833
893
          if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
834
 
            ask = 1; 
 
894
            ask = 1;
835
895
          else if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
836
896
            ask = 2;
837
897
          else if (err)
844
904
 
845
905
          xfree (this_sn);
846
906
          this_sn = NULL;
847
 
                  
 
907
 
848
908
          if (ask)
849
909
            {
850
910
              char *formatted = NULL;
851
911
              char *ocodeset = i18n_switchto_utf8 ();
852
912
 
853
 
              if (!strncmp (want_sn, "D27600012401", 12) 
 
913
              if (!strncmp (want_sn, "D27600012401", 12)
854
914
                  && strlen (want_sn) == 32 )
855
915
                formatted = xtryasprintf ("(%.4s) %.8s",
856
916
                                          want_sn + 16, want_sn + 20);
857
 
              
 
917
 
858
918
              err = 0;
859
 
              desc = xtryasprintf 
 
919
              desc = xtryasprintf
860
920
                ("%s:\n\n"
861
921
                 "  \"%s\"",
862
922
                 ask == 1
891
951
    put_membuf (data, buffer, length);
892
952
  return 0;
893
953
}
894
 
  
 
954
 
895
955
 
896
956
/* Helper returning a command option to describe the used hash
897
957
   algorithm.  See scd/command.c:cmd_pksign.  */
1004
1064
  rc = select_openpgp (serialno);
1005
1065
  if (rc)
1006
1066
    return rc;
1007
 
  
 
1067
 
1008
1068
  sprintf (line, "SCD SETDATA ");
1009
1069
  p = line + strlen (line);
1010
1070
  for (i=0; i < indatalen ; i++, p += 2 )
1037
1097
 
1038
1098
 
1039
1099
/* Send a READCERT command to the SCdaemon. */
1040
 
int 
 
1100
int
1041
1101
agent_scd_readcert (const char *certidstr,
1042
1102
                    void **r_buf, size_t *r_buflen)
1043
1103
{
1157
1217
  int rc;
1158
1218
  char line[ASSUAN_LINELENGTH];
1159
1219
  char *arg1 = NULL;
1160
 
  char *arg2 = NULL;  
1161
 
  char *arg3 = NULL; 
 
1220
  char *arg2 = NULL;
 
1221
  char *arg3 = NULL;
1162
1222
  char *arg4 = NULL;
1163
1223
  membuf_t data;
1164
1224
 
1169
1229
    return rc;
1170
1230
 
1171
1231
  /* Check that the gpg-agent understands the repeat option.  */
1172
 
  if (assuan_transact (agent_ctx, 
 
1232
  if (assuan_transact (agent_ctx,
1173
1233
                       "GETINFO cmd_has_option GET_PASSPHRASE repeat",
1174
1234
                       NULL, NULL, NULL, NULL, NULL, NULL))
1175
1235
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
1187
1247
    if (!(arg4 = percent_plus_escape (desc_msg)))
1188
1248
      goto no_mem;
1189
1249
 
1190
 
  snprintf (line, DIM(line)-1, 
1191
 
            "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s", 
1192
 
            repeat, 
 
1250
  snprintf (line, DIM(line)-1,
 
1251
            "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
 
1252
            repeat,
1193
1253
            check? " --check --qualitybar":"",
1194
1254
            arg1? arg1:"X",
1195
1255
            arg2? arg2:"X",
1202
1262
  xfree (arg4);
1203
1263
 
1204
1264
  init_membuf_secure (&data, 64);
1205
 
  rc = assuan_transact (agent_ctx, line, 
 
1265
  rc = assuan_transact (agent_ctx, line,
1206
1266
                        membuf_data_cb, &data,
1207
1267
                        default_inq_cb, NULL, NULL, NULL);
1208
1268
 
1209
1269
  if (rc)
1210
1270
    xfree (get_membuf (&data, NULL));
1211
 
  else 
 
1271
  else
1212
1272
    {
1213
1273
      put_membuf (&data, "", 1);
1214
1274
      *r_passphrase = get_membuf (&data, NULL);
1287
1347
    return err;
1288
1348
 
1289
1349
  init_membuf (&data, 32);
1290
 
  err = assuan_transact (agent_ctx, "GETINFO s2k_count", 
 
1350
  err = assuan_transact (agent_ctx, "GETINFO s2k_count",
1291
1351
                        membuf_data_cb, &data,
1292
1352
                        NULL, NULL, NULL, NULL);
1293
1353
  if (err)
1294
1354
    xfree (get_membuf (&data, NULL));
1295
 
  else 
 
1355
  else
1296
1356
    {
1297
1357
      put_membuf (&data, "", 1);
1298
1358
      buf = get_membuf (&data, NULL);