scd:piv: Allow writecert to only write matching certs.
[gnupg.git] / scd / app-help.c
index 1cc86b1..f0f551c 100644 (file)
 #include "scdaemon.h"
 #include "app-common.h"
 #include "iso7816.h"
-#include "tlv.h"
+#include "../common/tlv.h"
 
 
-/* Count the number of bits, assuming the A represents an unsigned big
  integer of length LEN bytes.  If A is NULL a length of 0 is
  returned. */
+/* Count the number of bits, assuming that A represents an unsigned
* big integer of length LEN bytes.  If A is NULL a length of 0 is
* returned. */
 unsigned int
 app_help_count_bits (const unsigned char *a, size_t len)
 {
@@ -87,6 +87,45 @@ app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip)
 }
 
 
+gpg_error_t
+app_help_pubkey_from_cert (const void *cert, size_t certlen,
+                           unsigned char **r_pk, size_t *r_pklen)
+{
+  gpg_error_t err;
+  ksba_cert_t kc;
+  unsigned char *pk;
+  size_t pklen;
+
+  *r_pk = NULL;
+  *r_pklen = 0;
+
+  err = ksba_cert_new (&kc);
+  if (err)
+    return err;
+
+  err = ksba_cert_init_from_mem (kc, cert, certlen);
+  if (err)
+    goto leave;
+
+  pk = ksba_cert_get_public_key (kc);
+  if (!pk)
+    {
+      err = gpg_error (GPG_ERR_NO_PUBKEY);
+      goto leave;
+    }
+  pklen = gcry_sexp_canon_len (pk, 0, NULL, &err);
+
+ leave:
+  if (!err)
+    {
+      *r_pk = pk;
+      *r_pklen = pklen;
+    }
+  else
+    ksba_free (pk);
+  ksba_cert_release (kc);
+  return err;
+}
 
 /* Given the SLOT and the File ID FID, return the length of the
    certificate contained in that file. Returns 0 if the file does not
@@ -106,7 +145,7 @@ app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff)
   int class, tag, constructed, ndef;
   size_t resultlen, objlen, hdrlen;
 
-  err = iso7816_select_file (slot, fid, 0, NULL, NULL);
+  err = iso7816_select_file (slot, fid, 0);
   if (err)
     {
       log_info ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));