示例#1
0
void set_atomickeys(struct coin777 *coin)
{
    char *addr; struct destbuf pubkey;
    if ( (addr= get_acct_coinaddr(coin->atomicrecv,coin->name,coin->serverport,coin->userpass,"atomicrecv")) != 0 )
    {
        get_pubkey(&pubkey,coin->name,coin->serverport,coin->userpass,coin->atomicrecv);
        strcpy(coin->atomicrecvpubkey,pubkey.buf);
    }
    if ( (addr= get_acct_coinaddr(coin->atomicsend,coin->name,coin->serverport,coin->userpass,"atomicsend")) != 0 )
    {
        get_pubkey(&pubkey,coin->name,coin->serverport,coin->userpass,coin->atomicsend);
        strcpy(coin->atomicsendpubkey,pubkey.buf);
    }
}
示例#2
0
static void recv_ok(CcnetProcessor *processor, 
                    char *code, char *code_msg,
                    char *content, int clen)
{
    USE_PRIV;

    if (processor->state != INIT) {
        close_processor(processor);
        return;
    }

    /* check version */
    if (clen != 0) {
        int v = get_version(content);
        if ((priv->used_version = get_used_version(v)) == -1) {
            ccnet_processor_send_error_update(processor, SC_VERSION_MISMATCH,
                                              SS_VERSION_MISMATCH);
            close_processor(processor);
            return;
        }
    } else {
        ccnet_processor_send_error_update(processor, SC_VERSION_MISMATCH,
                                          SS_VERSION_MISMATCH);
        close_processor(processor);
        return;
    }

    if (processor->peer->net_state == PEER_DOWN)
        ccnet_peer_set_net_state (processor->peer, PEER_INDIRECT);
    
    if (processor->peer->pubkey)
        send_challenge(processor);
    else
        get_pubkey(processor);
}
示例#3
0
BUF_MEM *
CA_STEP2_get_eph_pubkey(const EAC_CTX *ctx)
{
    check_return(ctx && ctx->ca_ctx && ctx->ca_ctx->ka_ctx,
            "Invalid arguments");

    return get_pubkey(ctx->ca_ctx->ka_ctx->key, ctx->bn_ctx);
}
示例#4
0
文件: mgw.c 项目: apitests/libjl777
char *_parse_withdraw_instructions(char *destaddr,char *NXTaddr,struct mgw777 *mgw,struct NXT_assettxid *tp,struct NXT_asset *ap)
{
    char pubkey[1024],withdrawaddr[1024],*retstr = destaddr;
    int64_t amount,minwithdraw;
    cJSON *argjson = 0;
    destaddr[0] = withdrawaddr[0] = 0;
    if ( tp->redeemtxid == 0 )
    {
        printf("no redeem txid %s %s\n",mgw->coinstr,cJSON_Print(argjson));
        retstr = 0;
    }
    else
    {
        amount = tp->quantity * ap->mult;
        if ( tp->comment != 0 && (argjson= cJSON_Parse(tp->comment)) != 0 ) //(tp->comment[0] == '{' || tp->comment[0] == '[') &&
        {
            if ( _calc_withdrawaddr(withdrawaddr,mgw,tp,argjson) == 0 )
            {
                printf("(%llu) no withdraw.(%s) or autoconvert.(%s)\n",(long long)tp->redeemtxid,withdrawaddr,tp->comment);
                _complete_assettxid(tp);
                retstr = 0;
            }
        }
        if ( retstr != 0 )
        {
            minwithdraw = mgw->txfee * MIN_DEPOSIT_FACTOR;
            if ( amount <= minwithdraw )
            {
                printf("%llu: minimum withdrawal must be more than %.8f %s\n",(long long)tp->redeemtxid,dstr(minwithdraw),mgw->coinstr);
                _complete_assettxid(tp);
                retstr = 0;
            }
            else if ( withdrawaddr[0] == 0 )
            {
                printf("%llu: no withdraw address for %.8f | ",(long long)tp->redeemtxid,dstr(amount));
                _complete_assettxid(tp);
                retstr = 0;
            }
            else if ( mgw != 0 && get_pubkey(pubkey,mgw->coinstr,mgw->serverport,mgw->userpass,withdrawaddr) < 0 )
            {
                printf("%llu: invalid address.(%s) for NXT.%s %.8f validate.%d\n",(long long)tp->redeemtxid,withdrawaddr,NXTaddr,dstr(amount),get_pubkey(pubkey,mgw->coinstr,mgw->serverport,mgw->userpass,withdrawaddr));
                _complete_assettxid(tp);
                retstr = 0;
            }
        }
    }
    //printf("withdraw addr.(%s) for (%s)\n",withdrawaddr,NXTaddr);
    if ( retstr != 0 )
        strcpy(retstr,withdrawaddr);
    if ( argjson != 0 )
        free_json(argjson);
    return(retstr);
}
示例#5
0
/* This function must be called before trying to sign any file.
 * It loads string for errors, and ciphers are auto-loaded by OpenSSL now.
 * If this function fails it may be because the certificate cannot
 * be validated.
 *
 * returns: true if can initialize and validate certificates, otherwise false */
bool initialize_signature(void)
{
	int ret = -1;
	time_t mod_sec = 0;
	struct tm *alttime;
	struct stat statt;

	string_or_die(&CERTNAME, "%s/%s", cert_path, SWUPDCERT);

	ERR_load_crypto_strings();
	ERR_load_PKCS7_strings();
	EVP_add_digest(EVP_sha256());

	if (!get_pubkey()) {
		goto fail;
	}

	ret = validate_certificate();
	if (ret) {
		printf("Failed to verify certificate: %s\n", X509_verify_cert_error_string(ret));
		if (ret == X509_V_ERR_CERT_NOT_YET_VALID) {
			/* If we can retrieve an approx. good system time, report out to user */
			if (stat("/usr/lib/os-release", &statt) != -1) {
				mod_sec = statt.st_mtim.tv_sec;
				char timebuf[30];
				alttime = localtime(&mod_sec);
				strftime(timebuf, sizeof(timebuf), "%F", alttime);
				printf("System clock should be at least %s\n", timebuf);
			}
		}
		goto fail;
	}

	/* Push our trust cert(s) to the stack, which is a set of certificates
	 * in which to search for the signer's cert. */
	x509_stack = sk_X509_new_null();
	if (!x509_stack) {
		goto fail;
	}
	sk_X509_push(x509_stack, cert);

	return true;
fail:
	return false;
}
示例#6
0
文件: passphrase.c 项目: cuidi/gnupg
/*
 * Clear the cached passphrase.  If CACHEID is not NULL, it will be
 * used instead of a cache ID derived from KEYID.
 */
void
passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
{
  int rc;

  (void)algo;

  if (!cacheid)
    {
      PKT_public_key *pk;
#     if MAX_FINGERPRINT_LEN < 20
#       error agent needs a 20 byte fingerprint
#     endif
      byte fpr[MAX_FINGERPRINT_LEN];
      char hexfprbuf[2*20+1];
      size_t dummy;

      pk = xcalloc (1, sizeof *pk);
      if ( !keyid || get_pubkey( pk, keyid ) )
        {
          log_error ("key not found in passphrase_clear_cache\n");
          free_public_key (pk);
          return;
        }
      memset (fpr, 0, MAX_FINGERPRINT_LEN );
      fingerprint_from_pk ( pk, fpr, &dummy );
      bin2hex (fpr, 20, hexfprbuf);
      rc = agent_clear_passphrase (hexfprbuf);
      free_public_key ( pk );
    }
  else
    rc = agent_clear_passphrase (cacheid);

  if (rc)
    log_error (_("problem with the agent: %s\n"), gpg_strerror (rc));
}
示例#7
0
BUF_MEM *
CA_get_pubkey(const EAC_CTX *ctx,
        const unsigned char *ef_cardsecurity,
        size_t ef_cardsecurity_len)
{
    BUF_MEM *pubkey = NULL;
    EAC_CTX *signed_ctx = EAC_CTX_new();
    check(ctx && ctx->ca_ctx, "Invalid arguments");

    if (ctx->ca_ctx->flags & CA_FLAG_DISABLE_PASSIVE_AUTH)
        CA_disable_passive_authentication(signed_ctx);

    check(EAC_CTX_init_ef_cardsecurity(ef_cardsecurity, ef_cardsecurity_len,
                signed_ctx)
            && signed_ctx && signed_ctx->ca_ctx && signed_ctx->ca_ctx->ka_ctx,
            "Could not parse EF.CardSecurity");

    pubkey = get_pubkey(signed_ctx->ca_ctx->ka_ctx->key, signed_ctx->bn_ctx);

err:
    EAC_CTX_clear_free(signed_ctx);

    return pubkey;
}
示例#8
0
文件: passphrase.c 项目: cuidi/gnupg
/* Return a new DEK object using the string-to-key specifier S2K.  Use
   KEYID and PUBKEY_ALGO to prompt the user.  Returns NULL is the user
   selected to cancel the passphrase entry and if CANCELED is not
   NULL, sets it to true.

   MODE 0:  Allow cached passphrase
        1:  Ignore cached passphrase
        2:  Ditto, but create a new key
        3:  Allow cached passphrase; use the S2K salt as the cache ID
        4:  Ditto, but create a new key
*/
DEK *
passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
                       int cipher_algo, STRING2KEY *s2k, int mode,
                       const char *tryagain_text,
                       const char *custdesc, const char *custprompt,
                       int *canceled)
{
  char *pw = NULL;
  DEK *dek;
  STRING2KEY help_s2k;
  int dummy_canceled;
  char s2k_cacheidbuf[1+16+1], *s2k_cacheid = NULL;

  if (!canceled)
    canceled = &dummy_canceled;
  *canceled = 0;

  if ( !s2k )
    {
      log_assert (mode != 3 && mode != 4);
      /* This is used for the old rfc1991 mode
       * Note: This must match the code in encode.c with opt.rfc1991 set */
      s2k = &help_s2k;
      s2k->mode = 0;
      s2k->hash_algo = S2K_DIGEST_ALGO;
    }

  /* Create a new salt or what else to be filled into the s2k for a
     new key.  */
  if ((mode == 2 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
    {
      gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM);
      if ( s2k->mode == 3 )
        {
          /* We delay the encoding until it is really needed.  This is
             if we are going to dynamically calibrate it, we need to
             call out to gpg-agent and that should not be done during
             option processing in main().  */
          if (!opt.s2k_count)
            opt.s2k_count = encode_s2k_iterations (0);
          s2k->count = opt.s2k_count;
        }
    }

  /* If we do not have a passphrase available in NEXT_PW and status
     information are request, we print them now. */
  if ( !next_pw && is_status_enabled() )
    {
      char buf[50];

      if ( keyid )
        {
          emit_status_need_passphrase (keyid,
                                       keyid[2] && keyid[3]? keyid+2:NULL,
                                       pubkey_algo);
	}
      else
        {
          snprintf (buf, sizeof buf -1, "%d %d %d",
                    cipher_algo, s2k->mode, s2k->hash_algo );
          write_status_text ( STATUS_NEED_PASSPHRASE_SYM, buf );
	}
    }

  /* If we do have a keyID, we do not have a passphrase available in
     NEXT_PW, we are not running in batch mode and we do not want to
     ignore the passphrase cache (mode!=1), print a prompt with
     information on that key. */
  if ( keyid && !opt.batch && !next_pw && mode!=1 )
    {
      PKT_public_key *pk = xmalloc_clear( sizeof *pk );
      char *p;

      p = get_user_id_native(keyid);
      tty_printf ("\n");
      tty_printf (_("You need a passphrase to unlock the secret key for\n"
                    "user: \"%s\"\n"),p);
      xfree(p);

      if ( !get_pubkey( pk, keyid ) )
        {
          const char *s = openpgp_pk_algo_name ( pk->pubkey_algo );

          tty_printf (_("%u-bit %s key, ID %s, created %s"),
                      nbits_from_pk( pk ), s?s:"?", keystr(keyid),
                      strtimestamp(pk->timestamp) );
          if ( keyid[2] && keyid[3]
               && keyid[0] != keyid[2] && keyid[1] != keyid[3] )
            {
              if ( keystrlen () > 10 )
                {
                  tty_printf ("\n");
                  tty_printf (_("         (subkey on main key ID %s)"),
                              keystr(&keyid[2]) );
                }
              else
                tty_printf ( _(" (main key ID %s)"), keystr(&keyid[2]) );
            }
          tty_printf("\n");
	}

      tty_printf("\n");
      free_public_key (pk);
    }

  if ( next_pw )
    {
      /* Simply return the passphrase we already have in NEXT_PW. */
      pw = next_pw;
      next_pw = NULL;
    }
  else if ( have_static_passphrase () )
    {
      /* Return the passphrase we have stored in FD_PASSWD. */
      pw = xmalloc_secure ( strlen(fd_passwd)+1 );
      strcpy ( pw, fd_passwd );
    }
  else
    {
      if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
	{
	  memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf);
	  *s2k_cacheidbuf = 'S';
	  bin2hex (s2k->salt, 8, s2k_cacheidbuf + 1);
	  s2k_cacheid = s2k_cacheidbuf;
	}

      if (opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
        {
          char buf[32];

          snprintf (buf, sizeof (buf), "%u", 100);
          write_status_text (STATUS_INQUIRE_MAXLEN, buf);
        }

      /* Divert to the gpg-agent. */
      pw = passphrase_get (keyid, mode == 2, s2k_cacheid,
                           (mode == 2 || mode == 4)? opt.passphrase_repeat : 0,
                           tryagain_text, custdesc, custprompt, canceled);
      if (*canceled)
        {
          xfree (pw);
	  write_status( STATUS_MISSING_PASSPHRASE );
          return NULL;
        }
    }

  if ( !pw || !*pw )
    write_status( STATUS_MISSING_PASSPHRASE );

  /* Hash the passphrase and store it in a newly allocated DEK object.
     Keep a copy of the passphrase in LAST_PW for use by
     get_last_passphrase(). */
  dek = xmalloc_secure_clear ( sizeof *dek );
  dek->algo = cipher_algo;
  if ( (!pw || !*pw) && (mode == 2 || mode == 4))
    dek->keylen = 0;
  else
    {
      gpg_error_t err;

      dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo);
      if (!(dek->keylen > 0 && dek->keylen <= DIM(dek->key)))
        BUG ();
      err = gcry_kdf_derive (pw, strlen (pw),
                             s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K :
                             s2k->mode == 1? GCRY_KDF_SALTED_S2K :
                             /* */           GCRY_KDF_SIMPLE_S2K,
                             s2k->hash_algo, s2k->salt, 8,
                             S2K_DECODE_COUNT(s2k->count),
                             dek->keylen, dek->key);
      if (err)
        {
          log_error ("gcry_kdf_derive failed: %s", gpg_strerror (err));
          xfree (pw);
          xfree (dek);
	  write_status( STATUS_MISSING_PASSPHRASE );
          return NULL;
        }
    }
  if (s2k_cacheid)
    memcpy (dek->s2k_cacheid, s2k_cacheid, sizeof dek->s2k_cacheid);
  xfree(last_pw);
  last_pw = pw;
  return dek;
}
示例#9
0
文件: passphrase.c 项目: cuidi/gnupg
/*
 * Ask the GPG Agent for the passphrase.
 * Mode 0:  Allow cached passphrase
 *      1:  No cached passphrase; that is we are asking for a new passphrase
 *          FIXME: Only partially implemented
 *
 * Note that TRYAGAIN_TEXT must not be translated.  If CANCELED is not
 * NULL, the function does set it to 1 if the user canceled the
 * operation.  If CACHEID is not NULL, it will be used as the cacheID
 * for the gpg-agent; if is NULL and a key fingerprint can be
 * computed, this will be used as the cacheid.
 */
static char *
passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
                 const char *tryagain_text,
                 const char *custom_description,
                 const char *custom_prompt, int *canceled)
{
  int rc;
  char *atext = NULL;
  char *pw = NULL;
  PKT_public_key *pk = xmalloc_clear( sizeof *pk );
  byte fpr[MAX_FINGERPRINT_LEN];
  int have_fpr = 0;
  char *orig_codeset;
  char *my_prompt;
  char hexfprbuf[20*2+1];
  const char *my_cacheid;
  int check = (mode == 1);

  if (canceled)
    *canceled = 0;

#if MAX_FINGERPRINT_LEN < 20
#error agent needs a 20 byte fingerprint
#endif

  memset (fpr, 0, MAX_FINGERPRINT_LEN );
  if( keyid && get_pubkey( pk, keyid ) )
    {
      free_public_key (pk);
      pk = NULL; /* oops: no key for some reason */
    }

  orig_codeset = i18n_switchto_utf8 ();

  if (custom_description)
    atext = native_to_utf8 (custom_description);
  else if ( !mode && pk && keyid )
    {
      char *uid;
      size_t uidlen;
      const char *algo_name = openpgp_pk_algo_name ( pk->pubkey_algo );
      const char *timestr;
      char *maink;

      if ( !algo_name )
        algo_name = "?";

      if (keyid[2] && keyid[3]
          && keyid[0] != keyid[2]
          && keyid[1] != keyid[3] )
        maink = xasprintf (_(" (main key ID %s)"), keystr (&keyid[2]));
      else
        maink = xstrdup ("");

      uid = get_user_id ( keyid, &uidlen );
      timestr = strtimestamp (pk->timestamp);

      atext = xasprintf (_("Please enter the passphrase to unlock the"
                           " secret key for the OpenPGP certificate:\n"
                           "\"%.*s\"\n"
                           "%u-bit %s key, ID %s,\n"
                           "created %s%s.\n"),
                         (int)uidlen, uid,
                         nbits_from_pk (pk), algo_name, keystr(&keyid[0]),
                         timestr, maink);
      xfree (uid);
      xfree (maink);

      {
        size_t dummy;
        fingerprint_from_pk( pk, fpr, &dummy );
        have_fpr = 1;
      }

    }
  else
    atext = xstrdup ( _("Enter passphrase\n") );


  if (!mode && cacheid)
    my_cacheid = cacheid;
  else if (!mode && have_fpr)
    my_cacheid = bin2hex (fpr, 20, hexfprbuf);
  else
    my_cacheid = NULL;

  if (tryagain_text)
    tryagain_text = _(tryagain_text);

  my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL;

  rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext,
                             repeat, check, &pw);

  xfree (my_prompt);
  xfree (atext); atext = NULL;

  i18n_switchback (orig_codeset);


  if (!rc)
    ;
  else if (gpg_err_code (rc) == GPG_ERR_CANCELED
            || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
    {
      log_info (_("cancelled by user\n") );
      if (canceled)
        *canceled = 1;
    }
  else
    {
      log_error (_("problem with the agent: %s\n"), gpg_strerror (rc));
      /* Due to limitations in the API of the upper layers they
         consider an error as no passphrase entered.  This works in
         most cases but not during key creation where this should
         definitely not happen and let it continue without requiring a
         passphrase.  Given that now all the upper layers handle a
         cancel correctly, we simply set the cancel flag now for all
         errors from the agent.  */
      if (canceled)
        *canceled = 1;

      write_status_errcode ("get_passphrase", rc);
    }

  free_public_key (pk);
  if (rc)
    {
      xfree (pw);
      return NULL;
    }
  return pw;
}
示例#10
0
文件: sig-check.c 项目: CSNW/gnupg
int
signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
		  int *r_expired, int *r_revoked, PKT_public_key *pk )
{
    int rc=0;
    int pk_internal;

    if (pk)
      pk_internal = 0;
    else
      {
	pk_internal = 1;
	pk = xmalloc_clear( sizeof *pk );
      }

    if ( (rc=openpgp_md_test_algo(sig->digest_algo)) )
      ; /* We don't have this digest. */
    else if ((rc=openpgp_pk_test_algo(sig->pubkey_algo)))
      ; /* We don't have this pubkey algo. */
    else if (!gcry_md_is_enabled (digest,sig->digest_algo))
      {
	/* Sanity check that the md has a context for the hash that the
	   sig is expecting.  This can happen if a onepass sig header does
	   not match the actual sig, and also if the clearsign "Hash:"
	   header is missing or does not match the actual sig. */

        log_info(_("WARNING: signature digest conflict in message\n"));
	rc = GPG_ERR_GENERAL;
      }
    else if( get_pubkey( pk, sig->keyid ) )
	rc = GPG_ERR_NO_PUBKEY;
    else if(!pk->flags.valid && !pk->flags.primary)
      {
        /* You cannot have a good sig from an invalid subkey.  */
        rc = GPG_ERR_BAD_PUBKEY;
      }
    else
      {
        if(r_expiredate)
	  *r_expiredate = pk->expiredate;

	rc = do_check( pk, sig, digest, r_expired, r_revoked, NULL );

	/* Check the backsig.  This is a 0x19 signature from the
	   subkey on the primary key.  The idea here is that it should
	   not be possible for someone to "steal" subkeys and claim
	   them as their own.  The attacker couldn't actually use the
	   subkey, but they could try and claim ownership of any
	   signaures issued by it. */
	if(rc==0 && !pk->flags.primary && pk->flags.backsig < 2)
	  {
	    if (!pk->flags.backsig)
	      {
		log_info(_("WARNING: signing subkey %s is not"
			   " cross-certified\n"),keystr_from_pk(pk));
		log_info(_("please see %s for more information\n"),
			 "https://gnupg.org/faq/subkey-cross-certify.html");
		/* --require-cross-certification makes this warning an
                     error.  TODO: change the default to require this
                     after more keys have backsigs. */
		if(opt.flags.require_cross_cert)
		  rc = GPG_ERR_GENERAL;
	      }
	    else if(pk->flags.backsig == 1)
	      {
		log_info(_("WARNING: signing subkey %s has an invalid"
			   " cross-certification\n"),keystr_from_pk(pk));
		rc = GPG_ERR_GENERAL;
	      }
	  }
      }

    if (pk_internal || rc)
      {
	release_public_key_parts (pk);
	if (pk_internal)
	  xfree (pk);
	else
	  /* Be very sure that the caller doesn't try to use *PK.  */
	  memset (pk, 0, sizeof (*pk));
      }

    if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
	/* This signature id works best with DLP algorithms because
	 * they use a random parameter for every signature.  Instead of
	 * this sig-id we could have also used the hash of the document
	 * and the timestamp, but the drawback of this is, that it is
	 * not possible to sign more than one identical document within
	 * one second.	Some remote batch processing applications might
	 * like this feature here.
         *
         * Note that before 2.0.10, we used RIPE-MD160 for the hash
         * and accidently didn't include the timestamp and algorithm
         * information in the hash.  Given that this feature is not
         * commonly used and that a replay attacks detection should
         * not solely be based on this feature (because it does not
         * work with RSA), we take the freedom and switch to SHA-1
         * with 2.0.10 to take advantage of hardware supported SHA-1
         * implementations.  We also include the missing information
         * in the hash.  Note also the SIG_ID as computed by gpg 1.x
         * and gpg 2.x didn't matched either because 2.x used to print
         * MPIs not in PGP format.  */
	u32 a = sig->timestamp;
	int nsig = pubkey_get_nsig( sig->pubkey_algo );
	unsigned char *p, *buffer;
        size_t n, nbytes;
        int i;
        char hashbuf[20];

        nbytes = 6;
	for (i=0; i < nsig; i++ )
          {
	    if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &n, sig->data[i]))
              BUG();
            nbytes += n;
          }

        /* Make buffer large enough to be later used as output buffer.  */
        if (nbytes < 100)
          nbytes = 100;
        nbytes += 10;  /* Safety margin.  */

        /* Fill and hash buffer.  */
        buffer = p = xmalloc (nbytes);
	*p++ = sig->pubkey_algo;
	*p++ = sig->digest_algo;
	*p++ = (a >> 24) & 0xff;
	*p++ = (a >> 16) & 0xff;
	*p++ = (a >>  8) & 0xff;
	*p++ =  a & 0xff;
        nbytes -= 6;
	for (i=0; i < nsig; i++ )
          {
	    if (gcry_mpi_print (GCRYMPI_FMT_PGP, p, nbytes, &n, sig->data[i]))
              BUG();
            p += n;
            nbytes -= n;
          }
        gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, buffer, p-buffer);

	p = make_radix64_string (hashbuf, 20);
	sprintf (buffer, "%s %s %lu",
		 p, strtimestamp (sig->timestamp), (ulong)sig->timestamp);
	xfree (p);
	write_status_text (STATUS_SIG_ID, buffer);
	xfree (buffer);
    }
/****************
 * Check whether we can trust this signature.
 * Returns: Error if we shall not trust this signatures.
 */
int
check_signatures_trust( PKT_signature *sig )
{
  PKT_public_key *pk = xmalloc_clear( sizeof *pk );
  unsigned int trustlevel;
  int rc=0;

  rc = get_pubkey( pk, sig->keyid );
  if (rc) 
    { /* this should not happen */
      log_error("Ooops; the key vanished  - can't check the trust\n");
      rc = G10ERR_NO_PUBKEY;
      goto leave;
    }

  if ( opt.trust_model==TM_ALWAYS )
    {
      if( !opt.quiet )
        log_info(_("WARNING: Using untrusted key!\n"));
      if (opt.with_fingerprint)
        print_fingerprint (pk, NULL, 1);
      goto leave;
    }

  if(pk->maybe_revoked && !pk->is_revoked)
    log_info(_("WARNING: this key might be revoked (revocation key"
	       " not present)\n"));

  trustlevel = get_validity (pk, NULL);

  if ( (trustlevel & TRUST_FLAG_REVOKED) ) 
    {
      write_status( STATUS_KEYREVOKED );
      if(pk->is_revoked==2)
	log_info(_("WARNING: This key has been revoked by its"
		   " designated revoker!\n"));
      else
	log_info(_("WARNING: This key has been revoked by its owner!\n"));
      log_info(_("         This could mean that the signature is forged.\n"));
      show_revocation_reason( pk, 0 );
    }
  else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) ) 
    {
      write_status( STATUS_KEYREVOKED );
      log_info(_("WARNING: This subkey has been revoked by its owner!\n"));
      show_revocation_reason( pk, 0 );
    }
  
  if ((trustlevel & TRUST_FLAG_DISABLED))
    log_info (_("Note: This key has been disabled.\n"));

  /* If we have PKA information adjust the trustlevel. */
  if (sig->pka_info && sig->pka_info->valid)
    {
      unsigned char fpr[MAX_FINGERPRINT_LEN];
      PKT_public_key *primary_pk;
      size_t fprlen;
      int okay;


      primary_pk = xmalloc_clear (sizeof *primary_pk);
      get_pubkey (primary_pk, pk->main_keyid);
      fingerprint_from_pk (primary_pk, fpr, &fprlen);
      free_public_key (primary_pk);

      if ( fprlen == 20 && !memcmp (sig->pka_info->fpr, fpr, 20) )
        {
          okay = 1;
          write_status_text (STATUS_PKA_TRUST_GOOD, sig->pka_info->email);
          log_info (_("Note: Verified signer's address is `%s'\n"),
                    sig->pka_info->email);
        }
      else
        {
          okay = 0;
          write_status_text (STATUS_PKA_TRUST_BAD, sig->pka_info->email);
          log_info (_("Note: Signer's address `%s' "
                      "does not match DNS entry\n"), sig->pka_info->email);
        }

      switch ( (trustlevel & TRUST_MASK) ) 
        {
        case TRUST_UNKNOWN: 
        case TRUST_UNDEFINED:
        case TRUST_MARGINAL:
          if (okay && opt.verify_options&VERIFY_PKA_TRUST_INCREASE)
            {
              trustlevel = ((trustlevel & ~TRUST_MASK) | TRUST_FULLY);
              log_info (_("trustlevel adjusted to FULL"
                          " due to valid PKA info\n"));
            }
          /* (fall through) */
        case TRUST_FULLY:
          if (!okay)
            {
              trustlevel = ((trustlevel & ~TRUST_MASK) | TRUST_NEVER);
              log_info (_("trustlevel adjusted to NEVER"
                          " due to bad PKA info\n"));
            }
          break;
        }
    }

  /* Now let the user know what up with the trustlevel. */
  switch ( (trustlevel & TRUST_MASK) ) 
    {
    case TRUST_EXPIRED:
      log_info(_("Note: This key has expired!\n"));
      print_fingerprint (pk, NULL, 1);
      break;
        
    default:
      log_error ("invalid trustlevel %u returned from validation layer\n",
                 trustlevel);
      /* fall thru */
    case TRUST_UNKNOWN: 
    case TRUST_UNDEFINED:
      write_status( STATUS_TRUST_UNDEFINED );
      log_info(_("WARNING: This key is not certified with"
                 " a trusted signature!\n"));
      log_info(_("         There is no indication that the "
                 "signature belongs to the owner.\n" ));
      print_fingerprint (pk, NULL, 1);
      break;

    case TRUST_NEVER:
      /* currently we won't get that status */
      write_status( STATUS_TRUST_NEVER );
      log_info(_("WARNING: We do NOT trust this key!\n"));
      log_info(_("         The signature is probably a FORGERY.\n"));
      if (opt.with_fingerprint)
        print_fingerprint (pk, NULL, 1);
      rc = G10ERR_BAD_SIGN;
      break;

    case TRUST_MARGINAL:
      write_status( STATUS_TRUST_MARGINAL );
      log_info(_("WARNING: This key is not certified with"
                 " sufficiently trusted signatures!\n"));
      log_info(_("         It is not certain that the"
                 " signature belongs to the owner.\n" ));
      print_fingerprint (pk, NULL, 1);
      break;

    case TRUST_FULLY:
      write_status( STATUS_TRUST_FULLY );
      if (opt.with_fingerprint)
        print_fingerprint (pk, NULL, 1);
      break;

    case TRUST_ULTIMATE:
      write_status( STATUS_TRUST_ULTIMATE );
      if (opt.with_fingerprint)
        print_fingerprint (pk, NULL, 1);
      break;
    }

 leave:
  free_public_key( pk );
  return rc;
}
示例#12
0
int
signature_check2( PKT_signature *sig, MD_HANDLE digest,
		  u32 *r_expiredate, int *r_expired )
{
    PKT_public_key *pk = m_alloc_clear( sizeof *pk );
    int rc=0;

    *r_expiredate = 0;

    /* Sanity check that the md has a context for the hash that the
       sig is expecting.  This can happen if a onepass sig header does
       not match the actual sig, and also if the clearsign "Hash:"
       header is missing or does not match the actual sig. */

    if(!md_algo_present(digest,sig->digest_algo)) {
        log_info(_("WARNING: signature digest conflict in message\n"));
	rc=G10ERR_BAD_SIGN;
    }
    else if( get_pubkey( pk, sig->keyid ) )
	rc = G10ERR_NO_PUBKEY;
    else if(!pk->is_valid && !pk->is_primary)
        rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
				 invalid subkey */
    else {
	*r_expiredate = pk->expiredate;
	rc = do_check( pk, sig, digest, r_expired );
    }

    free_public_key( pk );

    if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
	/* This signature id works best with DLP algorithms because
	 * they use a random parameter for every signature.  Instead of
	 * this sig-id we could have also used the hash of the document
	 * and the timestamp, but the drawback of this is, that it is
	 * not possible to sign more than one identical document within
	 * one second.	Some remote batch processing applications might
	 * like this feature here */
	MD_HANDLE md;
	u32 a = sig->timestamp;
	int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
	byte *p, *buffer;

	md = md_open( DIGEST_ALGO_RMD160, 0);
	md_putc( digest, sig->pubkey_algo );
	md_putc( digest, sig->digest_algo );
	md_putc( digest, (a >> 24) & 0xff );
	md_putc( digest, (a >> 16) & 0xff );
	md_putc( digest, (a >>	8) & 0xff );
	md_putc( digest,  a	   & 0xff );
	for(i=0; i < nsig; i++ ) {
	    unsigned n = mpi_get_nbits( sig->data[i]);

	    md_putc( md, n>>8);
	    md_putc( md, n );
	    p = mpi_get_buffer( sig->data[i], &n, NULL );
	    md_write( md, p, n );
	    m_free(p);
	}
	md_final( md );
	p = make_radix64_string( md_read( md, 0 ), 20 );
	buffer = m_alloc( strlen(p) + 60 );
	sprintf( buffer, "%s %s %lu",
		 p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
	write_status_text( STATUS_SIG_ID, buffer );
	m_free(buffer);
	m_free(p);
	md_close(md);
    }
示例#13
0
/* return 1 if user allows given key */
static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
{
    char *line = NULL;
	const char *reason;
	int found_key = 0;
	FILE *f;
	u_long linenum = 0;
	Key *found;
	char *fp;

	/* Temporarily use the user's uid. */
	temporarily_use_uid(pw);

	debug("trying public key file %s", file);
	f = auth_openkeyfile(file, pw, options.strict_modes);

	if (!f) {
		restore_uid();
		return 0;
	}

	found_key = 0;
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);

    gs_auth_fingerprint = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
    if (gs_auth_pubkey == NULL) {
        gs_auth_pubkey = get_pubkey();
    }
    line = gs_auth_pubkey;
    while (line) {
		char *cp, *key_options = NULL;

		auth_clear_options();

		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '\n' || *cp == '#')
			break;

		if (key_read(found, &cp) != 1) {
			/* no key?  check if there are options for this key */
			int quoted = 0;
			debug2("user_key_allowed: check options: '%s'", cp);
			key_options = cp;
			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
					cp++;	/* Skip both */
				else if (*cp == '"')
					quoted = !quoted;
			}
			/* Skip remaining whitespace. */
			for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			if (key_read(found, &cp) != 1) {
				debug2("user_key_allowed: advance: '%s'", cp);
				/* still no key?  advance to next line*/
				break;
			}
		}
		if (key_equal(found, key)) {
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				break;
			if (key_is_cert_authority)
				break;
			found_key = 1;
			debug("matching key found: file %s, line %lu",
			    file, linenum);
			fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
			verbose("Found matching %s key: %s",
			    key_type(found), fp);
			xfree(fp);
			break;
		}
		break;
	}
	restore_uid();
	fclose(f);
	key_free(found);
	if (!found_key)
		debug2("key not found");
	return found_key;
}
示例#14
0
static int
get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
{
    int rc;
    MPI plain_dek  = NULL;
    byte *frame = NULL;
    unsigned n, nframe;
    u16 csum, csum2;

    rc = pubkey_decrypt(sk->pubkey_algo, &plain_dek, k->data, sk->skey );
    if( rc )
	goto leave;
    frame = mpi_get_buffer( plain_dek, &nframe, NULL );
    mpi_free( plain_dek ); plain_dek = NULL;

    /* Now get the DEK (data encryption key) from the frame
     *
     * Old versions encode the DEK in in this format (msb is left):
     *
     *	   0  1  DEK(16 bytes)	CSUM(2 bytes)  0  RND(n bytes) 2
     *
     * Later versions encode the DEK like this:
     *
     *	   0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
     *
     * (mpi_get_buffer already removed the leading zero).
     *
     * RND are non-zero randow bytes.
     * A   is the cipher algorithm
     * DEK is the encryption key (session key) with length k
     * CSUM
     */
    if( DBG_CIPHER )
	log_hexdump("DEK frame:", frame, nframe );
    n=0;
    if( n + 7 > nframe )
	{ rc = G10ERR_WRONG_SECKEY; goto leave; }
    if( frame[n] == 1 && frame[nframe-1] == 2 ) {
	log_info(_("old encoding of the DEK is not supported\n"));
	rc = G10ERR_CIPHER_ALGO;
	goto leave;
    }
    if( frame[n] != 2 )  /* somethink is wrong */
	{ rc = G10ERR_WRONG_SECKEY; goto leave; }
    for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
	;
    n++; /* and the zero byte */
    if( n + 4 > nframe )
	{ rc = G10ERR_WRONG_SECKEY; goto leave; }

    dek->keylen = nframe - (n+1) - 2;
    dek->algo = frame[n++];
    if( dek->algo ==  CIPHER_ALGO_IDEA )
	write_status(STATUS_RSA_OR_IDEA);
    rc = check_cipher_algo( dek->algo );
    if( rc ) {
	if( !opt.quiet && rc == G10ERR_CIPHER_ALGO ) {
	    log_info(_("cipher algorithm %d is unknown or disabled\n"),
							    dek->algo);
	}
	dek->algo = 0;
	goto leave;
    }
    if( (dek->keylen*8) != cipher_get_keylen( dek->algo ) ) {
	rc = G10ERR_WRONG_SECKEY;
	goto leave;
    }

    /* copy the key to DEK and compare the checksum */
    csum  = frame[nframe-2] << 8;
    csum |= frame[nframe-1];
    memcpy( dek->key, frame+n, dek->keylen );
    for( csum2=0, n=0; n < dek->keylen; n++ )
	csum2 += dek->key[n];
    if( csum != csum2 ) {
	rc = G10ERR_WRONG_SECKEY;
	goto leave;
    }
    if( DBG_CIPHER )
	log_hexdump("DEK is:", dek->key, dek->keylen );
    /* check that the algo is in the preferences and whether it has expired */
    {
	PKT_public_key *pk = m_alloc_clear( sizeof *pk );
	if( (rc = get_pubkey( pk, keyid )) )
	    log_error("public key problem: %s\n", g10_errstr(rc) );
	else if( !pk->local_id && query_trust_record(pk) )
	    log_error("can't check algorithm against preferences\n");
	else if( dek->algo != CIPHER_ALGO_3DES
	    && !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, dek->algo ) ) {
	    /* Don't print a note while we are not on verbose mode,
	     * the cipher is blowfish and the preferences have twofish
	     * listed */
	    if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH
		|| !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM,
						    CIPHER_ALGO_TWOFISH ) )
		log_info(_(
		    "NOTE: cipher algorithm %d not found in preferences\n"),
								 dek->algo );
	}


	if( !rc && pk->expiredate && pk->expiredate <= make_timestamp() ) {
	    log_info(_("NOTE: secret key %08lX expired at %s\n"),
			   (ulong)keyid[1], asctimestamp( pk->expiredate) );
	}

	/* FIXME: check wheter the key has been revoked and display
	 * the revocation reason.  Actually the user should know this himself,
	 * but the sender might not know already and therefor the user
	 * should get a notice that an revoked key has been used to decode
	 * the message.  The user can than watch out for snakes send by
	 * one of those Eves outside his paradise :-)
	 */
	free_public_key( pk );
	rc = 0;
    }


  leave:
    mpi_free(plain_dek);
    m_free(frame);
    return rc;
}
示例#15
0
int main(int argc, char **argv)
{
	gnutls_certificate_credentials ctx;
	gnutls_datum_t dat, xml, pk;
	gnutls_openpgp_name uid;
	gnutls_privkey *pkey;
	gnutls_cert *cert;
	unsigned char fpr[20], keyid[8];
	char *s, *t;
	size_t fprlen = 0;
	int rc, nbits = 0, i;

	rc = gnutls_certificate_allocate_credentials(&ctx);
	assert(rc == 0);

	s = "../doc/credentials/openpgp/cli_ring.gpg";
	rc = gnutls_certificate_set_openpgp_keyring_file(ctx, s);
	assert(rc == 0);

	s = "../doc/credentials/openpgp/pub.asc";
	t = "../doc/credentials/openpgp/sec.asc";
	rc = gnutls_certificate_set_openpgp_key_file(ctx, s, t);
	assert(rc == 0);

	dat = ctx->cert_list[0]->raw;
	assert(ctx->cert_list[0]);
	printf("Key v%d\n", gnutls_openpgp_extract_key_version(&dat));
	rc = gnutls_openpgp_extract_key_name(&dat, 1, &uid);
	assert(rc == 0);
	printf("userID    %s\n", uid.name);

	rc = gnutls_openpgp_extract_key_pk_algorithm(&dat, &nbits);
	printf("pk-algorithm %s %d bits\n", get_pkalgo(rc), nbits);

	rc = gnutls_openpgp_extract_key_creation_time(&dat);
	printf("creation time %s\n", get_pktime(rc));

	rc = gnutls_openpgp_extract_key_expiration_time(&dat);
	printf("expiration time %lu\n", rc);

	printf("key fingerprint: ");
	rc = gnutls_openpgp_fingerprint(&dat, fpr, &fprlen);
	assert(rc == 0);
	for (i = 0; i < fprlen / 2; i++)
		printf("%02X%02X ", fpr[2 * i], fpr[2 * i + 1]);
	printf("\n");

	printf("key id: ");
	rc = gnutls_openpgp_extract_key_id(&dat, keyid);
	assert(rc == 0);
	for (i = 0; i < 8; i++)
		printf("%02X", keyid[i]);
	printf("\n\n");

	printf("Check MPIs\n");
	cert = ctx->cert_list[0];
	printf("number of certs %d\n", *ctx->cert_list_length);
	assert(*ctx->cert_list_length == 1);
	printf("number of items %d\n", cert->params_size);
	for (i = 0; i < cert->params_size; i++) {
		nbits = gcry_mpi_get_nbits(cert->params[i]);
		printf("mpi %d %d bits\n", i, nbits);
	}

	printf("\nCheck key\n");
	rc = gnutls_openpgp_verify_key(NULL, &ctx->keyring, &dat, 1);
	printf("certifiacte status...%d\n", rc);

	printf("\nSeckey\n");
	pkey = ctx->pkey;
	assert(pkey);
	assert(pkey->params_size);
	nbits = gcry_mpi_get_nbits(pkey->params[0]);
	rc = pkey->pk_algorithm;
	printf("pk-algorithm %s %d bits\n", get_pkalgo(rc), nbits);
	printf("number of items %d\n", pkey->params_size);
	for (i = 0; i < pkey->params_size; i++) {
		nbits = gcry_mpi_get_nbits(pkey->params[i]);
		printf("mpi %d %d bits\n", i, nbits);
	}

	printf("\nGet public key\n");
	rc = get_pubkey(&pk, &ctx->keyring, 0xA7D93C3F);
	assert(rc == 0);

	printf("key fingerprint: ");
	gnutls_openpgp_fingerprint(&pk, fpr, &fprlen);
	for (i = 0; i < fprlen / 2; i++)
		printf("%02X%02X ", fpr[2 * i], fpr[2 * i + 1]);
	printf("\n");
	_gnutls_free_datum(&pk);

#if 0
	rc = gnutls_openpgp_key_to_xml(&dat, &xml, 1);
	printf("rc=%d\n", rc);
	assert(rc == 0);
	xml.data[xml.size] = '\0';
	printf("%s\n", xml.data);
	_gnutls_free_datum(&xml);
#endif

	_gnutls_free_datum(&dat);
	gnutls_certificate_free_credentials(ctx);

	return 0;
}
int
signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, 
		  int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
{
    PKT_public_key *pk = xmalloc_clear( sizeof *pk );
    int rc=0;

    if( (rc=check_digest_algo(sig->digest_algo)) )
      ; /* we don't have this digest */
    else if((rc=check_pubkey_algo(sig->pubkey_algo)))
      ; /* we don't have this pubkey algo */
    else if(!md_algo_present(digest,sig->digest_algo))
      {
	/* Sanity check that the md has a context for the hash that the
	   sig is expecting.  This can happen if a onepass sig header does
	   not match the actual sig, and also if the clearsign "Hash:"
	   header is missing or does not match the actual sig. */

        log_info(_("WARNING: signature digest conflict in message\n"));
	rc=G10ERR_GENERAL;
      }
    else if( get_pubkey( pk, sig->keyid ) )
	rc = G10ERR_NO_PUBKEY;
    else if(!pk->is_valid && !pk->is_primary)
        rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
				 invalid subkey */
    else
      {
        if(r_expiredate)
	  *r_expiredate = pk->expiredate;

	rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );

	/* Check the backsig.  This is a 0x19 signature from the
	   subkey on the primary key.  The idea here is that it should
	   not be possible for someone to "steal" subkeys and claim
	   them as their own.  The attacker couldn't actually use the
	   subkey, but they could try and claim ownership of any
	   signaures issued by it. */
	if(rc==0 && !pk->is_primary && pk->backsig<2)
	  {
	    if(pk->backsig==0)
	      {
		log_info(_("WARNING: signing subkey %s is not"
			   " cross-certified\n"),keystr_from_pk(pk));
		log_info(_("please see %s for more information\n"),
			 "http://www.gnupg.org/faq/subkey-cross-certify.html");
		/* --require-cross-certification makes this warning an
                     error.  TODO: change the default to require this
                     after more keys have backsigs. */
		if(opt.flags.require_cross_cert)
		  rc=G10ERR_GENERAL;
	      }
	    else if(pk->backsig==1)
	      {
		log_info(_("WARNING: signing subkey %s has an invalid"
			   " cross-certification\n"),keystr_from_pk(pk));
		rc=G10ERR_GENERAL;
	      }
	  }
      }

    free_public_key( pk );

    if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
	/* This signature id works best with DLP algorithms because
	 * they use a random parameter for every signature.  Instead of
	 * this sig-id we could have also used the hash of the document
	 * and the timestamp, but the drawback of this is, that it is
	 * not possible to sign more than one identical document within
	 * one second.	Some remote batch processing applications might
	 * like this feature here */
	MD_HANDLE md;
	u32 a = sig->timestamp;
	int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
	byte *p, *buffer;

	md = md_open( DIGEST_ALGO_RMD160, 0);
	md_putc( digest, sig->pubkey_algo );
	md_putc( digest, sig->digest_algo );
	md_putc( digest, (a >> 24) & 0xff );
	md_putc( digest, (a >> 16) & 0xff );
	md_putc( digest, (a >>	8) & 0xff );
	md_putc( digest,  a	   & 0xff );
	for(i=0; i < nsig; i++ ) {
	    unsigned n = mpi_get_nbits( sig->data[i]);

	    md_putc( md, n>>8);
	    md_putc( md, n );
	    p = mpi_get_buffer( sig->data[i], &n, NULL );
	    md_write( md, p, n );
	    xfree(p);
	}
	md_final( md );
	p = make_radix64_string( md_read( md, 0 ), 20 );
	buffer = xmalloc( strlen(p) + 60 );
	sprintf( buffer, "%s %s %lu",
		 p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
	write_status_text( STATUS_SIG_ID, buffer );
	xfree(buffer);
	xfree(p);
	md_close(md);
    }