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

« back to all changes in this revision

Viewing changes to scd/iso7816.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:
16
16
 * You should have received a copy of the GNU General Public License
17
17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18
18
 *
19
 
 * $Id: iso7816.c 4912 2009-01-08 19:56:30Z wk $
 
19
 * $Id: iso7816.c 5043 2009-06-17 09:45:50Z wk $
20
20
 */
21
21
 
22
22
#include <config.h>
213
213
  *result = NULL;
214
214
  *resultlen = 0;
215
215
 
216
 
  sw = apdu_send (slot, 0x80, 0xAA, list_dirs? 1:2, 0, -1, NULL,
 
216
  sw = apdu_send (slot, 0, 0x80, 0xAA, list_dirs? 1:2, 0, -1, NULL,
217
217
                  result, resultlen);
218
218
  if (sw != SW_SUCCESS)
219
219
    {
244
244
  *result = NULL;
245
245
  *resultlen = 0;
246
246
 
247
 
  sw = apdu_send_direct (slot, apdudata, apdudatalen, handle_more,
 
247
  sw = apdu_send_direct (slot, 0, apdudata, apdudatalen, handle_more,
248
248
                         result, resultlen);
249
249
  if (!sw)
250
250
    {
420
420
   a newly allocated buffer at the address passed by RESULT.  Return
421
421
   the length of this data at the address of RESULTLEN. */
422
422
gpg_error_t
423
 
iso7816_get_data (int slot, int tag,
 
423
iso7816_get_data (int slot, int extended_mode, int tag,
424
424
                  unsigned char **result, size_t *resultlen)
425
425
{
426
426
  int sw;
 
427
  int le;
427
428
 
428
429
  if (!result || !resultlen)
429
430
    return gpg_error (GPG_ERR_INV_VALUE);
430
431
  *result = NULL;
431
432
  *resultlen = 0;
432
433
 
433
 
  sw = apdu_send (slot, 0x00, CMD_GET_DATA,
434
 
                  ((tag >> 8) & 0xff), (tag & 0xff), -1, NULL,
435
 
                  result, resultlen);
 
434
  if (extended_mode > 0 && extended_mode < 256)
 
435
    le = 65534; /* Not 65535 in case it is used as some special flag.  */
 
436
  else if (extended_mode > 0)
 
437
    le = extended_mode;
 
438
  else
 
439
    le = 256;
 
440
 
 
441
  sw = apdu_send_le (slot, extended_mode, 0x00, CMD_GET_DATA,
 
442
                     ((tag >> 8) & 0xff), (tag & 0xff), -1, NULL, le,
 
443
                     result, resultlen);
436
444
  if (sw != SW_SUCCESS)
437
445
    {
438
446
      /* Make sure that pending buffers are released. */
462
470
  return map_sw (sw);
463
471
}
464
472
 
465
 
/* Same as iso7816_put_data but uses an odd instrcution byte.  */
 
473
/* Same as iso7816_put_data but uses an odd instruction byte.  */
466
474
gpg_error_t
467
475
iso7816_put_data_odd (int slot, int extended_mode, int tag,
468
476
                      const unsigned char *data, size_t datalen)
509
517
  *result = NULL;
510
518
  *resultlen = 0;
511
519
 
512
 
  sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, (const char*)data,
 
520
  sw = apdu_send (slot, 0, 
 
521
                  0x00, CMD_PSO, 0x9E, 0x9A, datalen, (const char*)data,
513
522
                  result, resultlen);
514
523
  if (sw != SW_SUCCESS)
515
524
    {
530
539
   and the plaintext is available in a newly allocated buffer stored
531
540
   at RESULT with its length stored at RESULTLEN. */
532
541
gpg_error_t
533
 
iso7816_decipher (int slot, const unsigned char *data, size_t datalen,
 
542
iso7816_decipher (int slot, int extended_mode, 
 
543
                  const unsigned char *data, size_t datalen,
534
544
                  int padind, unsigned char **result, size_t *resultlen)
535
545
{
536
546
  int sw;
547
557
      buf = xtrymalloc (datalen + 1);
548
558
      if (!buf)
549
559
        return gpg_error (gpg_err_code_from_errno (errno));
550
 
 
 
560
      
551
561
      *buf = padind; /* Padding indicator. */
552
562
      memcpy (buf+1, data, datalen);
553
 
      sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86,
 
563
      sw = apdu_send (slot, extended_mode, 
 
564
                      0x00, CMD_PSO, 0x80, 0x86,
554
565
                      datalen+1, (char*)buf,
555
566
                      result, resultlen);
556
567
      xfree (buf);
557
568
    }
558
569
  else
559
570
    {
560
 
      sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86,
 
571
      sw = apdu_send (slot, extended_mode,
 
572
                      0x00, CMD_PSO, 0x80, 0x86,
561
573
                      datalen, (const char *)data,
562
574
                      result, resultlen);
563
575
    }
586
598
  *result = NULL;
587
599
  *resultlen = 0;
588
600
 
589
 
  sw = apdu_send (slot, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0,
 
601
  sw = apdu_send (slot, 0, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0,
590
602
                  datalen, (const char*)data,  result, resultlen);
591
603
  if (sw != SW_SUCCESS)
592
604
    {
601
613
}
602
614
 
603
615
 
 
616
/* LE is the expected return length.  This is usually 0 except if
 
617
   extended length mode is used and more than 256 byte will be
 
618
   returned.  In that case a value of -1 uses a large default
 
619
   (e.g. 4096 bytes), a value larger 256 used that value.  */
604
620
static gpg_error_t
605
 
do_generate_keypair (int slot, int readonly,
606
 
                  const unsigned char *data, size_t datalen,
607
 
                  unsigned char **result, size_t *resultlen)
 
621
do_generate_keypair (int slot, int extended_mode, int readonly,
 
622
                     const unsigned char *data, size_t datalen,
 
623
                     int le, 
 
624
                     unsigned char **result, size_t *resultlen)
608
625
{
609
626
  int sw;
610
627
 
613
630
  *result = NULL;
614
631
  *resultlen = 0;
615
632
 
616
 
  sw = apdu_send (slot, 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0,
617
 
                  datalen, (const char*)data,  result, resultlen);
 
633
  sw = apdu_send_le (slot, extended_mode,
 
634
                     0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0,
 
635
                     datalen, (const char*)data,
 
636
                     le >= 0 && le < 256? 256:le,
 
637
                     result, resultlen);
618
638
  if (sw != SW_SUCCESS)
619
639
    {
620
640
      /* Make sure that pending buffers are released. */
629
649
 
630
650
 
631
651
gpg_error_t
632
 
iso7816_generate_keypair (int slot,
 
652
iso7816_generate_keypair (int slot, int extended_mode,
633
653
                          const unsigned char *data, size_t datalen,
 
654
                          int le, 
634
655
                          unsigned char **result, size_t *resultlen)
635
656
{
636
 
  return do_generate_keypair (slot, 0, data, datalen, result, resultlen);
 
657
  return do_generate_keypair (slot, extended_mode, 0,
 
658
                              data, datalen, le, result, resultlen);
637
659
}
638
660
 
639
661
 
640
662
gpg_error_t
641
 
iso7816_read_public_key (int slot,
642
 
                          const unsigned char *data, size_t datalen,
643
 
                          unsigned char **result, size_t *resultlen)
 
663
iso7816_read_public_key (int slot, int extended_mode,
 
664
                         const unsigned char *data, size_t datalen,
 
665
                         int le, 
 
666
                         unsigned char **result, size_t *resultlen)
644
667
{
645
 
  return do_generate_keypair (slot, 1, data, datalen, result, resultlen);
 
668
  return do_generate_keypair (slot, extended_mode, 1,
 
669
                              data, datalen, le, result, resultlen);
646
670
}
647
671
 
648
672
 
661
685
    {
662
686
      result = NULL;
663
687
      n = length > 254? 254 : length;
664
 
      sw = apdu_send_le (slot, 0x00, CMD_GET_CHALLENGE, 0, 0, -1, NULL,
665
 
                         n,
 
688
      sw = apdu_send_le (slot, 0, 
 
689
                         0x00, CMD_GET_CHALLENGE, 0, 0, -1, NULL, n,
666
690
                         &result, &resultlen);
667
691
      if (sw != SW_SUCCESS)
668
692
        {
711
735
      buffer = NULL;
712
736
      bufferlen = 0;
713
737
      n = read_all? 0 : nmax;
714
 
      sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY,
 
738
      sw = apdu_send_le (slot, 0, 0x00, CMD_READ_BINARY,
715
739
                         ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,
716
740
                         n, &buffer, &bufferlen);
717
741
      if ( SW_EXACT_LENGTH_P(sw) )
718
742
        {
719
743
          n = (sw & 0x00ff);
720
 
          sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY,
 
744
          sw = apdu_send_le (slot, 0, 0x00, CMD_READ_BINARY,
721
745
                             ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,
722
746
                             n, &buffer, &bufferlen);
723
747
        }
804
828
 
805
829
  buffer = NULL;
806
830
  bufferlen = 0;
807
 
  sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD,
 
831
  sw = apdu_send_le (slot, 0, 0x00, CMD_READ_RECORD,
808
832
                     recno, 
809
833
                     short_ef? short_ef : 0x04,
810
834
                     -1, NULL,