コード例 #1
0
/*
  Return the last found cert.  Caller must free it.
 */
int
keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert)
{
  const unsigned char *buffer;
  size_t length;
  size_t cert_off, cert_len;
  ksba_reader_t reader = NULL;
  ksba_cert_t cert = NULL;
  int rc;

  if (!hd)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (!hd->found.blob)
    return gpg_error (GPG_ERR_NOTHING_FOUND);

  if (blob_get_type (hd->found.blob) != BLOBTYPE_X509)
    return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);

  buffer = _keybox_get_blob_image (hd->found.blob, &length);
  if (length < 40)
    return gpg_error (GPG_ERR_TOO_SHORT);
  cert_off = get32 (buffer+8);
  cert_len = get32 (buffer+12);
  if (cert_off+cert_len > length)
    return gpg_error (GPG_ERR_TOO_SHORT);

  rc = ksba_reader_new (&reader);
  if (rc)
    return rc;
  rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
  if (rc)
    {
      ksba_reader_release (reader);
      /* fixme: need to map the error codes */
      return gpg_error (GPG_ERR_GENERAL);
    }

  rc = ksba_cert_new (&cert);
  if (rc)
    {
      ksba_reader_release (reader);
      return rc;
    }

  rc = ksba_cert_read_der (cert, reader);
  if (rc)
    {
      ksba_cert_release (cert);
      ksba_reader_release (reader);
      /* fixme: need to map the error codes */
      return gpg_error (GPG_ERR_GENERAL);
    }

  *r_cert = cert;
  ksba_reader_release (reader);
  return 0;
}
コード例 #2
0
ファイル: ldap.c プロジェクト: gilbert-fernandes/gnupg
void
end_cert_fetch_ldap (cert_fetch_context_t context)
{
  if (context)
    {
      ksba_reader_t reader = context->reader;

      xfree (context->tmpbuf);
      xfree (context);
      ldap_wrapper_release_context (reader);
      ksba_reader_release (reader);
    }
}
コード例 #3
0
ファイル: misc.c プロジェクト: FMayzek/gnupg
/* Create a KSBA reader object and connect it to the estream FP.  */
gpg_error_t
create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp)
{
  gpg_error_t err;
  ksba_reader_t reader;

  *r_reader = NULL;
  err = ksba_reader_new (&reader);
  if (!err)
    err = ksba_reader_set_cb (reader, my_estream_ksba_reader_cb, fp);
  if (err)
    {
      log_error (_("error initializing reader object: %s\n"),
                 gpg_strerror (err));
      ksba_reader_release (reader);
      return err;
    }
  *r_reader = reader;
  return 0;
}
コード例 #4
0
ファイル: ber-dump.c プロジェクト: idodeclare/MacGPG2
static void
one_file (FILE *fp, const char *fname, ksba_asn_tree_t asn_tree)
{
  gpg_error_t err;
  ksba_reader_t r;
  BerDecoder d;

  (void)fname;  /* Not yet used in error messages.  */

  err = ksba_reader_new (&r);
  if (err)
    fatal ("out of core\n");
  err = ksba_reader_set_file (r, fp);
  if (err)
    fatal ("ksba_reader_set_file failed: rc=%d\n", err);

  d = _ksba_ber_decoder_new ();
  if (!d)
    fatal ("out of core\n");
  err = _ksba_ber_decoder_set_reader (d, r);
  if (err)
    fatal ("ksba_ber_decoder_set_reader failed: rc=%d\n", err);
  
  if (asn_tree)
    {
      err = _ksba_ber_decoder_set_module (d, asn_tree);
      if (err)
        fatal ("ksba_ber_decoder_set_module failed: rc=%d\n", err);
    }

  err = _ksba_ber_decoder_dump (d, stdout);
  if (err)
    print_error ("ksba_ber_decoder_dump failed: rc=%d\n", err);
  
  _ksba_ber_decoder_release (d);
  ksba_reader_release (r);
}
コード例 #5
0
ファイル: encrypt.c プロジェクト: GroovIM/transport
/* Perform an encrypt operation.  

   Encrypt the data received on DATA-FD and write it to OUT_FP.  The
   recipients are take from the certificate given in recplist; if this
   is NULL it will be encrypted for a default recipient */
int
gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
{
  int rc = 0;
  Base64Context b64writer = NULL;
  gpg_error_t err;
  ksba_writer_t writer;
  ksba_reader_t reader = NULL;
  ksba_cms_t cms = NULL;
  ksba_stop_reason_t stopreason;
  KEYDB_HANDLE kh = NULL;
  struct encrypt_cb_parm_s encparm;
  DEK dek = NULL;
  int recpno;
  FILE *data_fp = NULL;
  certlist_t cl;
  int count;

  memset (&encparm, 0, sizeof encparm);

  audit_set_type (ctrl->audit, AUDIT_TYPE_ENCRYPT);

  /* Check that the certificate list is not empty and that at least
     one certificate is not flagged as encrypt_to; i.e. is a real
     recipient. */
  for (cl = recplist; cl; cl = cl->next)
    if (!cl->is_encrypt_to)
      break;
  if (!cl)
    {
      log_error(_("no valid recipients given\n"));
      gpgsm_status (ctrl, STATUS_NO_RECP, "0");
      audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, 0);
      rc = gpg_error (GPG_ERR_NO_PUBKEY);
      goto leave;
    }

  for (count = 0, cl = recplist; cl; cl = cl->next)
    count++;
  audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, count);

  kh = keydb_new (0);
  if (!kh)
    {
      log_error (_("failed to allocated keyDB handle\n"));
      rc = gpg_error (GPG_ERR_GENERAL);
      goto leave;
    }

  data_fp = fdopen ( dup (data_fd), "rb");
  if (!data_fp)
    {
      rc = gpg_error (gpg_err_code_from_errno (errno));
      log_error ("fdopen() failed: %s\n", strerror (errno));
      goto leave;
    }

  err = ksba_reader_new (&reader);
  if (err)
      rc = err;
  if (!rc)
    rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm);
  if (rc)
      goto leave;

  encparm.fp = data_fp;

  ctrl->pem_name = "ENCRYPTED MESSAGE";
  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
  if (rc)
    {
      log_error ("can't create writer: %s\n", gpg_strerror (rc));
      goto leave;
    }

  err = ksba_cms_new (&cms);
  if (err)
    {
      rc = err;
      goto leave;
    }

  err = ksba_cms_set_reader_writer (cms, reader, writer);
  if (err)
    {
      log_debug ("ksba_cms_set_reader_writer failed: %s\n",
                 gpg_strerror (err));
      rc = err;
      goto leave;
    }

  audit_log (ctrl->audit, AUDIT_GOT_DATA);

  /* We are going to create enveloped data with uninterpreted data as
     inner content */
  err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA);
  if (!err)
    err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA);
  if (err)
    {
      log_debug ("ksba_cms_set_content_type failed: %s\n",
                 gpg_strerror (err));
      rc = err;
      goto leave;
    }

  /* Create a session key */
  dek = xtrycalloc_secure (1, sizeof *dek); 
  if (!dek)
    rc = out_of_core ();
  else
  {
    dek->algoid = opt.def_cipher_algoid;
    rc = init_dek (dek);
  }
  if (rc)
    {
      log_error ("failed to create the session key: %s\n",
                 gpg_strerror (rc));
      goto leave;
    }

  err = ksba_cms_set_content_enc_algo (cms, dek->algoid, dek->iv, dek->ivlen);
  if (err)
    {
      log_error ("ksba_cms_set_content_enc_algo failed: %s\n",
                 gpg_strerror (err));
      rc = err;
      goto leave;
    }

  encparm.dek = dek;
  /* Use a ~8k (AES) or ~4k (3DES) buffer */
  encparm.bufsize = 500 * dek->ivlen;
  encparm.buffer = xtrymalloc (encparm.bufsize);
  if (!encparm.buffer)
    {
      rc = out_of_core ();
      goto leave;
    }
  
  audit_log_s (ctrl->audit, AUDIT_SESSION_KEY, dek->algoid);

  /* Gather certificates of recipients, encrypt the session key for
     each and store them in the CMS object */
  for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
    {
      unsigned char *encval;
      
      rc = encrypt_dek (dek, cl->cert, &encval);
      if (rc)
        {
          audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, rc);
          log_error ("encryption failed for recipient no. %d: %s\n",
                     recpno, gpg_strerror (rc));
          goto leave;
        }
      
      err = ksba_cms_add_recipient (cms, cl->cert);
      if (err)
        {
          audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
          log_error ("ksba_cms_add_recipient failed: %s\n",
                     gpg_strerror (err));
          rc = err;
          xfree (encval);
          goto leave;
        }
      
      err = ksba_cms_set_enc_val (cms, recpno, encval);
      xfree (encval);
      audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
      if (err)
        {
          log_error ("ksba_cms_set_enc_val failed: %s\n",
                     gpg_strerror (err));
          rc = err;
          goto leave;
        }
    }

  /* Main control loop for encryption. */
  recpno = 0;
  do 
    {
      err = ksba_cms_build (cms, &stopreason);
      if (err)
        {
          log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err));
          rc = err;
          goto leave;
        }
    }
  while (stopreason != KSBA_SR_READY);   

  if (encparm.readerror)
    {
      log_error ("error reading input: %s\n", strerror (encparm.readerror));
      rc = gpg_error (gpg_err_code_from_errno (encparm.readerror));
      goto leave;
    }


  rc = gpgsm_finish_writer (b64writer);
  if (rc) 
    {
      log_error ("write failed: %s\n", gpg_strerror (rc));
      goto leave;
    }
  audit_log (ctrl->audit, AUDIT_ENCRYPTION_DONE);
  log_info ("encrypted data created\n");

 leave:
  ksba_cms_release (cms);
  gpgsm_destroy_writer (b64writer);
  ksba_reader_release (reader);
  keydb_release (kh); 
  xfree (dek);
  if (data_fp)
    fclose (data_fp);
  xfree (encparm.buffer);
  return rc;
}
コード例 #6
0
ファイル: certcache.c プロジェクト: 0ndorio/gnupg
/* Load certificates from the directory DIRNAME.  All certificates
   matching the pattern "*.crt" or "*.der"  are loaded.  We assume that
   certificates are DER encoded and not PEM encapsulated. The cache
   should be in a locked state when calling this function.  */
static gpg_error_t
load_certs_from_dir (const char *dirname, int are_trusted)
{
  gpg_error_t err;
  DIR *dir;
  struct dirent *ep;
  char *p;
  size_t n;
  estream_t fp;
  ksba_reader_t reader;
  ksba_cert_t cert;
  char *fname = NULL;

  dir = opendir (dirname);
  if (!dir)
    {
      if (opt.system_daemon)
        log_info (_("can't access directory '%s': %s\n"),
                  dirname, strerror (errno));
      return 0; /* We do not consider this a severe error.  */
    }

  while ( (ep=readdir (dir)) )
    {
      p = ep->d_name;
      if (*p == '.' || !*p)
        continue; /* Skip any hidden files and invalid entries.  */
      n = strlen (p);
      if ( n < 5 || (strcmp (p+n-4,".crt") && strcmp (p+n-4,".der")))
        continue; /* Not the desired "*.crt" or "*.der" pattern.  */

      xfree (fname);
      fname = make_filename (dirname, p, NULL);
      fp = es_fopen (fname, "rb");
      if (!fp)
        {
          log_error (_("can't open '%s': %s\n"),
                     fname, strerror (errno));
          continue;
        }

      err = create_estream_ksba_reader (&reader, fp);
      if (err)
        {
          es_fclose (fp);
          continue;
        }

      err = ksba_cert_new (&cert);
      if (!err)
        err = ksba_cert_read_der (cert, reader);
      ksba_reader_release (reader);
      es_fclose (fp);
      if (err)
        {
          log_error (_("can't parse certificate '%s': %s\n"),
                     fname, gpg_strerror (err));
          ksba_cert_release (cert);
          continue;
        }

      err = put_cert (cert, 1, are_trusted, NULL);
      if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
        log_info (_("certificate '%s' already cached\n"), fname);
      else if (!err)
        {
          if (are_trusted)
            log_info (_("trusted certificate '%s' loaded\n"), fname);
          else
            log_info (_("certificate '%s' loaded\n"), fname);
          if (opt.verbose)
            {
              p = get_fingerprint_hexstring_colon (cert);
              log_info (_("  SHA1 fingerprint = %s\n"), p);
              xfree (p);

              cert_log_name (_("   issuer ="), cert);
              cert_log_subject (_("  subject ="), cert);
            }
        }
      else
        log_error (_("error loading certificate '%s': %s\n"),
                     fname, gpg_strerror (err));
      ksba_cert_release (cert);
    }

  xfree (fname);
  closedir (dir);
  return 0;
}
コード例 #7
0
/* Return true if the key in BLOB matches the 20 bytes keygrip GRIP.
   We don't have the keygrips as meta data, thus we need to parse the
   certificate. Fixme: We might want to return proper error codes
   instead of failing a search for invalid certificates etc.  */
static int
blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip)
{
  int rc;
  const unsigned char *buffer;
  size_t length;
  size_t cert_off, cert_len;
  ksba_reader_t reader = NULL;
  ksba_cert_t cert = NULL;
  ksba_sexp_t p = NULL;
  gcry_sexp_t s_pkey;
  unsigned char array[20];
  unsigned char *rcp;
  size_t n;

  buffer = _keybox_get_blob_image (blob, &length);
  if (length < 40)
    return 0; /* Too short. */
  cert_off = get32 (buffer+8);
  cert_len = get32 (buffer+12);
  if (cert_off+cert_len > length)
    return 0; /* Too short.  */

  rc = ksba_reader_new (&reader);
  if (rc)
    return 0; /* Problem with ksba. */
  rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
  if (rc)
    goto failed;
  rc = ksba_cert_new (&cert);
  if (rc)
    goto failed;
  rc = ksba_cert_read_der (cert, reader);
  if (rc)
    goto failed;
  p = ksba_cert_get_public_key (cert);
  if (!p)
    goto failed;
  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
  if (!n)
    goto failed;
  rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)p, n);
  if (rc)
    {
      gcry_sexp_release (s_pkey);
      goto failed;
    }
  rcp = gcry_pk_get_keygrip (s_pkey, array);
  gcry_sexp_release (s_pkey);
  if (!rcp)
    goto failed; /* Can't calculate keygrip. */

  xfree (p);
  ksba_cert_release (cert);
  ksba_reader_release (reader);
  return !memcmp (array, grip, 20);
 failed:
  xfree (p);
  ksba_cert_release (cert);
  ksba_reader_release (reader);
  return 0;
}