LCOV - code coverage report
Current view: top level - scd - app-help.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 63 0.0 %
Date: 2016-09-12 12:29:17 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /* app-help.c - Application helper functions
       2             :  * Copyright (C) 2004, 2009 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 <errno.h>
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <string.h>
      25             : 
      26             : #include "scdaemon.h"
      27             : #include "app-common.h"
      28             : #include "iso7816.h"
      29             : #include "tlv.h"
      30             : 
      31             : 
      32             : /* Count the number of bits, assuming the A represents an unsigned big
      33             :    integer of length LEN bytes.  If A is NULL a length of 0 is
      34             :    returned. */
      35             : unsigned int
      36           0 : app_help_count_bits (const unsigned char *a, size_t len)
      37             : {
      38           0 :   unsigned int n = len * 8;
      39             :   int i;
      40             : 
      41           0 :   if (!a)
      42           0 :     return 0;
      43             : 
      44           0 :   for (; len && !*a; len--, a++, n -=8)
      45             :     ;
      46           0 :   if (len)
      47             :     {
      48           0 :       for (i=7; i && !(*a & (1<<i)); i--)
      49           0 :         n--;
      50             :     }
      51           0 :   return n;
      52             : }
      53             : 
      54             : 
      55             : /* Return the KEYGRIP for the certificate CERT as an hex encoded
      56             :    string in the user provided buffer HEXKEYGRIP which must be of at
      57             :    least 41 bytes. */
      58             : gpg_error_t
      59           0 : app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip)
      60             : {
      61             :   gpg_error_t err;
      62             :   gcry_sexp_t s_pkey;
      63             :   ksba_sexp_t p;
      64             :   size_t n;
      65             :   unsigned char array[20];
      66             : 
      67           0 :   p = ksba_cert_get_public_key (cert);
      68           0 :   if (!p)
      69           0 :     return gpg_error (GPG_ERR_BUG);
      70           0 :   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
      71           0 :   if (!n)
      72           0 :     return gpg_error (GPG_ERR_INV_SEXP);
      73           0 :   err = gcry_sexp_sscan (&s_pkey, NULL, (char*)p, n);
      74           0 :   xfree (p);
      75           0 :   if (err)
      76           0 :     return err; /* Can't parse that S-expression. */
      77           0 :   if (!gcry_pk_get_keygrip (s_pkey, array))
      78             :     {
      79           0 :       gcry_sexp_release (s_pkey);
      80           0 :       return gpg_error (GPG_ERR_GENERAL); /* Failed to calculate the keygrip.*/
      81             :     }
      82           0 :   gcry_sexp_release (s_pkey);
      83             : 
      84           0 :   bin2hex (array, 20, hexkeygrip);
      85             : 
      86           0 :   return 0;
      87             : }
      88             : 
      89             : 
      90             : 
      91             : /* Given the SLOT and the File ID FID, return the length of the
      92             :    certificate contained in that file. Returns 0 if the file does not
      93             :    exists or does not contain a certificate.  If R_CERTOFF is not
      94             :    NULL, the length the header will be stored at this address; thus to
      95             :    parse the X.509 certificate a read should start at that offset.
      96             : 
      97             :    On success the file is still selected.
      98             : */
      99             : size_t
     100           0 : app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff)
     101             : {
     102             :   gpg_error_t err;
     103             :   unsigned char *buffer;
     104             :   const unsigned char *p;
     105             :   size_t buflen, n;
     106             :   int class, tag, constructed, ndef;
     107             :   size_t resultlen, objlen, hdrlen;
     108             : 
     109           0 :   err = iso7816_select_file (slot, fid, 0, NULL, NULL);
     110           0 :   if (err)
     111             :     {
     112           0 :       log_info ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
     113           0 :       return 0;
     114             :     }
     115             : 
     116           0 :   err = iso7816_read_binary (slot, 0, 32, &buffer, &buflen);
     117           0 :   if (err)
     118             :     {
     119           0 :       log_info ("error reading certificate from FID 0x%04X: %s\n",
     120             :                  fid, gpg_strerror (err));
     121           0 :       return 0;
     122             :     }
     123             : 
     124           0 :   if (!buflen || *buffer == 0xff)
     125             :     {
     126           0 :       log_info ("no certificate contained in FID 0x%04X\n", fid);
     127           0 :       xfree (buffer);
     128           0 :       return 0;
     129             :     }
     130             : 
     131           0 :   p = buffer;
     132           0 :   n = buflen;
     133           0 :   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
     134             :                           &ndef, &objlen, &hdrlen);
     135           0 :   if (err)
     136             :     {
     137           0 :       log_info ("error parsing certificate in FID 0x%04X: %s\n",
     138             :                 fid, gpg_strerror (err));
     139           0 :       xfree (buffer);
     140           0 :       return 0;
     141             :     }
     142             : 
     143             :   /* All certificates should commence with a SEQUENCE except for the
     144             :      special ROOT CA which are enclosed in a SET. */
     145           0 :   if ( !(class == CLASS_UNIVERSAL &&  constructed
     146           0 :          && (tag == TAG_SEQUENCE || tag == TAG_SET)))
     147             :     {
     148           0 :       log_info ("data at FID 0x%04X does not look like a certificate\n", fid);
     149           0 :       return 0;
     150             :     }
     151             : 
     152           0 :   resultlen = objlen + hdrlen;
     153           0 :   if (r_certoff)
     154             :     {
     155             :       /* The callers want the offset to the actual certificate. */
     156           0 :       *r_certoff = hdrlen;
     157             : 
     158           0 :       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
     159             :                               &ndef, &objlen, &hdrlen);
     160           0 :       if (err)
     161           0 :         return 0;
     162             : 
     163           0 :       if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
     164             :         {
     165             :           /* The certificate seems to be contained in a
     166             :              userCertificate container.  Assume the following sequence
     167             :              is the certificate. */
     168           0 :           *r_certoff += hdrlen + objlen;
     169           0 :           if (*r_certoff > resultlen)
     170             :             {
     171           0 :               *r_certoff = 0;
     172           0 :               return 0; /* That should never happen. */
     173             :             }
     174             :         }
     175             :       else
     176           0 :         *r_certoff = 0;
     177             :     }
     178             : 
     179           0 :   return resultlen;
     180             : }

Generated by: LCOV version 1.11