~ubuntu-branches/ubuntu/oneiric/gnupg2/oneiric-updates

« back to all changes in this revision

Viewing changes to g10/call-agent.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2009-08-04 12:27:49 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20090804122749-q0j52zp6xmzvyall
Tags: 2.0.12-0ubuntu1
* New upstream release.
* Add 01-scd-pw2.patch, 03-opgp-writekey.patch, and 06-opgp-sign3072.patch
  from https://bugs.g10code.com/gnupg/issue1094 to make OpenPGP 2.0
  smartcards work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
116
116
static char *
117
117
unescape_status_string (const unsigned char *s)
118
118
{
119
 
  char *buffer, *d;
120
 
 
121
 
  buffer = d = xtrymalloc (strlen (s)+1);
122
 
  if (!buffer)
123
 
    return NULL;
124
 
  while (*s)
125
 
    {
126
 
      if (*s == '%' && s[1] && s[2])
127
 
        { 
128
 
          s++;
129
 
          *d = xtoi_2 (s);
130
 
          if (!*d)
131
 
            *d = '\xff';
132
 
          d++;
133
 
          s += 2;
134
 
        }
135
 
      else if (*s == '+')
136
 
        {
137
 
          *d++ = ' ';
138
 
          s++;
139
 
        }
140
 
      else
141
 
        *d++ = *s++;
142
 
    }
143
 
  *d = 0; 
144
 
  return buffer;
145
 
}
146
 
 
147
 
/* Copy the text ATEXT into the buffer P and do plus '+' and percent
148
 
   escaping.  Note that the provided buffer needs to be 3 times the
149
 
   size of ATEXT plus 1.  Returns a pointer to the leading Nul in P. */
150
 
static char *
151
 
my_percent_plus_escape (char *p, const char *atext)
152
 
{
153
 
  const unsigned char *s;
154
 
 
155
 
  for (s=atext; *s; s++)
156
 
    {
157
 
      if (*s < ' ' || *s == '+' || *s == '%')
158
 
        {
159
 
          snprintf (p, 4, "%%%02X", *s);
160
 
          p += 3;
161
 
        }
162
 
      else if (*s == ' ')
163
 
        *p++ = '+';
164
 
      else
165
 
        *p++ = *s;
166
 
    }
167
 
  *p = 0;
168
 
  return p;
169
 
}
 
119
  return percent_plus_unescape (s, 0xff);
 
120
}
 
121
 
170
122
 
171
123
/* Take a 20 byte hexencoded string and put it into the the provided
172
124
   20 byte buffer FPR in binary format. */
373
325
      else if (no == 3)
374
326
        parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
375
327
    }
376
 
  
 
328
  else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
 
329
    {
 
330
      int keyno, algo, nbits;
 
331
 
 
332
      sscanf (line, "%d %d %d", &keyno, &algo, &nbits);
 
333
      keyno--;
 
334
      if (keyno >= 0 && keyno < DIM (parm->key_attr))
 
335
        {
 
336
          parm->key_attr[keyno].algo = algo;
 
337
          parm->key_attr[keyno].nbits = nbits;
 
338
        }
 
339
    }
 
340
 
377
341
  return 0;
378
342
}
379
343
 
391
355
  rc = assuan_transact (agent_ctx, "LEARN --send",
392
356
                        dummy_data_cb, NULL, default_inq_cb, NULL,
393
357
                        learn_status_cb, info);
 
358
  /* Also try to get the key attributes.  */
 
359
  if (!rc)
 
360
    agent_scd_getattr ("KEY-ATTR", info);
394
361
  
395
362
  return rc;
396
363
}
521
488
}
522
489
 
523
490
 
524
 
 
525
491
 
526
492
/* Handle a KEYDATA inquiry.  Note, we only send the data,
527
493
   assuan_transact takes care of flushing and writing the end */
572
538
}
573
539
 
574
540
 
575
 
 
576
541
 
577
542
/* Status callback for the SCD GENKEY command. */
578
543
static int
583
548
  int keywordlen;
584
549
  gpg_error_t rc;
585
550
 
586
 
  log_debug ("got status line `%s'\n", line);
587
551
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
588
552
    ;
589
553
  while (spacep (line))
701
665
  /* Send the serialno command to initialize the connection. We don't
702
666
     care about the data returned.  If the card has already been
703
667
     initialized, this is a very fast command.  We request the openpgp
704
 
     card because that is waht we expect. */
 
668
     card because that is what we expect. */
705
669
  rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
706
670
                        NULL, NULL, NULL, NULL, NULL, NULL);
707
671
  if (rc)
766
730
  /* Send the serialno command to initialize the connection. We don't
767
731
     care about the data returned.  If the card has already been
768
732
     initialized, this is a very fast command.  We request the openpgp
769
 
     card because that is waht we expect. */
 
733
     card because that is what we expect. */
770
734
  rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
771
735
                        NULL, NULL, NULL, NULL, NULL, NULL);
772
736
  if (rc)
799
763
}
800
764
 
801
765
 
 
766
 
 
767
/* Send a READCERT command to the SCdaemon. */
 
768
int 
 
769
agent_scd_readcert (const char *certidstr,
 
770
                    void **r_buf, size_t *r_buflen)
 
771
{
 
772
  int rc;
 
773
  char line[ASSUAN_LINELENGTH];
 
774
  membuf_t data;
 
775
  size_t len;
 
776
 
 
777
  *r_buf = NULL;
 
778
  rc = start_agent ();
 
779
  if (rc)
 
780
    return rc;
 
781
 
 
782
  init_membuf (&data, 2048);
 
783
 
 
784
  snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
 
785
  line[DIM(line)-1] = 0;
 
786
  rc = assuan_transact (agent_ctx, line,
 
787
                        membuf_data_cb, &data,
 
788
                        default_inq_cb, NULL, NULL, NULL);
 
789
  if (rc)
 
790
    {
 
791
      xfree (get_membuf (&data, &len));
 
792
      return rc;
 
793
    }
 
794
  *r_buf = get_membuf (&data, r_buflen);
 
795
  if (!*r_buf)
 
796
    return gpg_error (GPG_ERR_ENOMEM);
 
797
 
 
798
  return 0;
 
799
}
 
800
 
 
801
 
 
802
 
802
803
/* Change the PIN of an OpenPGP card or reset the retry counter.
803
804
   CHVNO 1: Change the PIN
804
805
         2: For v1 cards: Same as 1.
874
875
                      const char *err_msg,
875
876
                      const char *prompt,
876
877
                      const char *desc_msg,
 
878
                      int repeat,
 
879
                      int check,
877
880
                      char **r_passphrase)
878
881
{
879
882
  int rc;
880
 
  char *line, *p;
881
 
  char cmd[] = "GET_PASSPHRASE --data -- ";
 
883
  char line[ASSUAN_LINELENGTH];
 
884
  char *arg1 = NULL;
 
885
  char *arg2 = NULL;  
 
886
  char *arg3 = NULL; 
 
887
  char *arg4 = NULL;
882
888
  membuf_t data;
883
889
 
884
890
  *r_passphrase = NULL;
887
893
  if (rc)
888
894
    return rc;
889
895
 
890
 
  /* We allocate 3 times the needed space for the texts so that
891
 
     there is enough space for escaping. */
892
 
  line = xtrymalloc ( strlen (cmd) + 1
893
 
                      + (cache_id? 3*strlen (cache_id): 1) + 1
894
 
                      + (err_msg?  3*strlen (err_msg): 1) + 1
895
 
                      + (prompt?   3*strlen (prompt): 1) + 1
896
 
                      + (desc_msg? 3*strlen (desc_msg): 1) + 1
897
 
                      + 1);
898
 
  if (!line)
899
 
    return gpg_error_from_syserror ();
 
896
  /* Check that the gpg-agent understands the repeat option.  */
 
897
  if (assuan_transact (agent_ctx, 
 
898
                       "GETINFO cmd_has_option GET_PASSPHRASE repeat",
 
899
                       NULL, NULL, NULL, NULL, NULL, NULL))
 
900
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
900
901
 
901
 
  p = stpcpy (line, cmd);
902
902
  if (cache_id && *cache_id)
903
 
    p = my_percent_plus_escape (p, cache_id);
904
 
  else
905
 
    *p++ = 'X';
906
 
  *p++ = ' ';
907
 
 
 
903
    if (!(arg1 = percent_plus_escape (cache_id)))
 
904
      goto no_mem;
908
905
  if (err_msg && *err_msg)
909
 
    p = my_percent_plus_escape (p, err_msg);
910
 
  else
911
 
    *p++ = 'X';
912
 
  *p++ = ' ';
913
 
 
 
906
    if (!(arg2 = percent_plus_escape (err_msg)))
 
907
      goto no_mem;
914
908
  if (prompt && *prompt)
915
 
    p = my_percent_plus_escape (p, prompt);
916
 
  else
917
 
    *p++ = 'X'; 
918
 
  *p++ = ' ';
919
 
 
 
909
    if (!(arg3 = percent_plus_escape (prompt)))
 
910
      goto no_mem;
920
911
  if (desc_msg && *desc_msg)
921
 
    p = my_percent_plus_escape (p, desc_msg);
922
 
  else
923
 
    *p++ = 'X';
924
 
  *p = 0;
 
912
    if (!(arg4 = percent_plus_escape (desc_msg)))
 
913
      goto no_mem;
 
914
 
 
915
  snprintf (line, DIM(line)-1, 
 
916
            "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s", 
 
917
            repeat, 
 
918
            check? " --check --qualitybar":"",
 
919
            arg1? arg1:"X",
 
920
            arg2? arg2:"X",
 
921
            arg3? arg3:"X",
 
922
            arg4? arg4:"X");
 
923
  line[DIM(line)-1] = 0;
 
924
  xfree (arg1);
 
925
  xfree (arg2);
 
926
  xfree (arg3);
 
927
  xfree (arg4);
925
928
 
926
929
  init_membuf_secure (&data, 64);
927
930
  rc = assuan_transact (agent_ctx, line, 
937
940
      if (!*r_passphrase)
938
941
        rc = gpg_error_from_syserror ();
939
942
    }
940
 
  xfree (line);
 
943
  return rc;
 
944
 no_mem:
 
945
  rc = gpg_error_from_syserror ();
 
946
  xfree (arg1);
 
947
  xfree (arg2);
 
948
  xfree (arg3);
 
949
  xfree (arg4);
941
950
  return rc;
942
951
}
943
952