/* * Start the next search on this handle right at the beginning */ gpg_error_t keydb_search_reset (KEYDB_HANDLE hd) { gpg_error_t rc = 0; int i; if (!hd) return gpg_error (GPG_ERR_INV_ARG); keyblock_cache_clear (); if (DBG_CLOCK) log_clock ("keydb_search_reset"); hd->current = 0; hd->found = -1; /* Now reset all resources. */ for (i=0; !rc && i < hd->used; i++) { switch (hd->active[i].type) { case KEYDB_RESOURCE_TYPE_NONE: break; case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_search_reset (hd->active[i].u.kr); break; case KEYDB_RESOURCE_TYPE_KEYBOX: rc = keybox_search_reset (hd->active[i].u.kb); break; } } return rc; }
int main(int argc, char **argv) { Args args(argc, argv, "DRIVER INFILE OUTFILE"); DebugReplay *replay = CreateDebugReplay(args); if (replay == NULL) return EXIT_FAILURE; const char *output_file = args.ExpectNext(); args.ExpectEnd(); while (!replay->Basic().time_available) if (!replay->Next()) return 0; const TCHAR *driver_name = _T("Unknown"); PathName igc_path(output_file); IGCWriter writer(igc_path, replay->Basic()); writer.WriteHeader(replay->Basic().date_time_utc, _T("Manfred Mustermann"), _T("Ventus"), _T("D-1234"), _T("MM"), _T("Foo"), driver_name); GPSClock log_clock(fixed(1)); while (replay->Next()) if (log_clock.check_advance(replay->Basic().time)) writer.LogPoint(replay->Basic()); writer.Flush(); return EXIT_SUCCESS; }
int main(int argc, char **argv) { if (argc != 3) { fprintf(stderr, "Usage: %s DRIVER FILE.IGC\n" "Where DRIVER is one of:\n", argv[0]); const TCHAR *name; for (unsigned i = 0; (name = devRegisterGetName(i)) != NULL; ++i) _ftprintf(stderr, _T("\t%s\n"), name); return 1; } PathName driver_name(argv[1]); device.Driver = devGetDriver(driver_name); if (device.Driver == NULL) { fprintf(stderr, "No such driver: %s\n", argv[1]); return 1; } NullPort port(*(Port::Handler *)NULL); device.Com = &port; device.enable_baro = true; if (!device.Open()) { fprintf(stderr, "Failed to open driver: %s\n", argv[1]); return 1; } char buffer[1024]; for (unsigned i = 0; i < 10 && fgets(buffer, sizeof(buffer), stdin) != NULL; ++i) device.LineReceived(buffer); PathName igc_path(argv[2]); IGCWriter writer(igc_path, device_blackboard.Basic()); writer.header(device_blackboard.Basic().DateTime, _T("Manfred Mustermann"), _T("Ventus"), _T("D-1234"), _T("Foo"), driver_name); GPSClock log_clock(fixed(1)); while (fgets(buffer, sizeof(buffer), stdin) != NULL) { device.LineReceived(buffer); if (log_clock.check_advance(device_blackboard.Basic().Time)) writer.LogPoint(device_blackboard.Basic()); } }
KEYDB_HANDLE keydb_new (void) { KEYDB_HANDLE hd; int i, j; if (DBG_CLOCK) log_clock ("keydb_new"); hd = xmalloc_clear (sizeof *hd); hd->found = -1; assert (used_resources <= MAX_KEYDB_RESOURCES); for (i=j=0; i < used_resources; i++) { switch (all_resources[i].type) { case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ break; case KEYDB_RESOURCE_TYPE_KEYRING: hd->active[j].type = all_resources[i].type; hd->active[j].token = all_resources[i].token; hd->active[j].u.kr = keyring_new (all_resources[i].token); if (!hd->active[j].u.kr) { xfree (hd); return NULL; /* fixme: release all previously allocated handles*/ } j++; break; case KEYDB_RESOURCE_TYPE_KEYBOX: hd->active[j].type = all_resources[i].type; hd->active[j].token = all_resources[i].token; hd->active[j].u.kb = keybox_new (all_resources[i].token, 0); if (!hd->active[j].u.kb) { xfree (hd); return NULL; /* fixme: release all previously allocated handles*/ } j++; break; } } hd->used = j; active_handles++; return hd; }
/* * Search through all keydb resources, starting at the current * position, for a keyblock which contains one of the keys described * in the DESC array. Returns GPG_ERR_NOT_FOUND if no matching * keyring was found. */ gpg_error_t keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc, size_t *descindex) { gpg_error_t rc; if (!hd) return gpg_error (GPG_ERR_INV_ARG); if (DBG_CLOCK) log_clock ("keydb_search enter"); if (DBG_CACHE) dump_search_desc ("keydb_search", desc, ndesc); if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID && keyblock_cache.state == KEYBLOCK_CACHE_FILLED && keyblock_cache.kid[0] == desc[0].u.kid[0] && keyblock_cache.kid[1] == desc[0].u.kid[1]) { if (DBG_CLOCK) log_clock ("keydb_search leave (cached)"); return 0; } rc = -1; while ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) && hd->current >= 0 && hd->current < hd->used) { switch (hd->active[hd->current].type) { case KEYDB_RESOURCE_TYPE_NONE: BUG(); /* we should never see it here */ break; case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_search (hd->active[hd->current].u.kr, desc, ndesc, descindex); break; case KEYDB_RESOURCE_TYPE_KEYBOX: rc = keybox_search (hd->active[hd->current].u.kb, desc, ndesc); break; } if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) { /* EOF -> switch to next resource */ hd->current++; } else if (!rc) hd->found = hd->current; } rc = ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) ? gpg_error (GPG_ERR_NOT_FOUND) : rc); keyblock_cache_clear (); if (!rc && ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID) { keyblock_cache.state = KEYBLOCK_CACHE_PREPARED; keyblock_cache.kid[0] = desc[0].u.kid[0]; keyblock_cache.kid[1] = desc[0].u.kid[1]; } if (DBG_CLOCK) log_clock (rc? "keydb_search leave (not found)" : "keydb_search leave (found)"); return rc; }
/* * Get the session key from a pubkey enc packet and return it in DEK, * which should have been allocated in secure memory by the caller. */ gpg_error_t get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek) { PKT_public_key *sk = NULL; int rc; if (DBG_CLOCK) log_clock ("get_session_key enter"); rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC); if (rc) goto leave; if ((k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets) { sk = xmalloc_clear (sizeof *sk); sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo. */ if (!(rc = get_seckey (ctrl, sk, k->keyid))) { /* Check compliance. */ if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION, sk->pubkey_algo, sk->pkey, nbits_from_pk (sk), NULL)) { log_info (_("key %s is not suitable for decryption" " in %s mode\n"), keystr_from_pk (sk), gnupg_compliance_option_string (opt.compliance)); rc = gpg_error (GPG_ERR_PUBKEY_ALGO); } else rc = get_it (ctrl, k, dek, sk, k->keyid); } } else if (opt.skip_hidden_recipients) rc = gpg_error (GPG_ERR_NO_SECKEY); else /* Anonymous receiver: Try all available secret keys. */ { void *enum_context = NULL; u32 keyid[2]; for (;;) { free_public_key (sk); sk = xmalloc_clear (sizeof *sk); rc = enum_secret_keys (ctrl, &enum_context, sk); if (rc) { rc = GPG_ERR_NO_SECKEY; break; } if (sk->pubkey_algo != k->pubkey_algo) continue; if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC)) continue; keyid_from_pk (sk, keyid); if (!opt.quiet) log_info (_("anonymous recipient; trying secret key %s ...\n"), keystr (keyid)); /* Check compliance. */ if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION, sk->pubkey_algo, sk->pkey, nbits_from_pk (sk), NULL)) { log_info (_("key %s is not suitable for decryption" " in %s mode\n"), keystr_from_pk (sk), gnupg_compliance_option_string (opt.compliance)); continue; } rc = get_it (ctrl, k, dek, sk, keyid); if (!rc) { if (!opt.quiet) log_info (_("okay, we are the anonymous recipient.\n")); break; } else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED) break; /* Don't try any more secret keys. */ } enum_secret_keys (ctrl, &enum_context, NULL); /* free context */ } leave: free_public_key (sk); if (DBG_CLOCK) log_clock ("get_session_key leave"); return rc; }
static gpg_error_t get_it (ctrl_t ctrl, PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) { gpg_error_t err; byte *frame = NULL; unsigned int n; size_t nframe; u16 csum, csum2; int padding; gcry_sexp_t s_data; char *desc; char *keygrip; byte fp[MAX_FINGERPRINT_LEN]; size_t fpn; if (DBG_CLOCK) log_clock ("decryption start"); /* Get the keygrip. */ err = hexkeygrip_from_pk (sk, &keygrip); if (err) goto leave; /* Convert the data to an S-expression. */ if (sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL || sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E) { if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); else err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", enc->data[0], enc->data[1]); } else if (sk->pubkey_algo == PUBKEY_ALGO_RSA || sk->pubkey_algo == PUBKEY_ALGO_RSA_E) { if (!enc->data[0]) err = gpg_error (GPG_ERR_BAD_MPI); else err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", enc->data[0]); } else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) { if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); else err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))", enc->data[1], enc->data[0]); } else err = gpg_error (GPG_ERR_BUG); if (err) goto leave; if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) { fingerprint_from_pk (sk, fp, &fpn); log_assert (fpn == 20); } /* Decrypt. */ desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1); err = agent_pkdecrypt (NULL, keygrip, desc, sk->keyid, sk->main_keyid, sk->pubkey_algo, s_data, &frame, &nframe, &padding); xfree (desc); gcry_sexp_release (s_data); if (err) goto leave; /* Now get the DEK (data encryption key) from the frame * * Old versions encode the DEK 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_CRYPTO) log_printhex (frame, nframe, "DEK frame:"); n = 0; if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) { gcry_mpi_t shared_mpi; gcry_mpi_t decoded; /* At the beginning the frame are the bytes of shared point MPI. */ err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL); if (err) { err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/, shared_mpi, sk->pkey); mpi_release (shared_mpi); if(err) goto leave; xfree (frame); err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, decoded); mpi_release (decoded); if (err) goto leave; /* Now the frame are the bytes decrypted but padded session key. */ /* Allow double padding for the benefit of DEK size concealment. Higher than this is wasteful. */ if (!nframe || frame[nframe-1] > 8*2 || nframe <= 8 || frame[nframe-1] > nframe) { err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } nframe -= frame[nframe-1]; /* Remove padding. */ log_assert (!n); /* (used just below) */ } else { if (padding) { if (n + 7 > nframe) { err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } if (frame[n] == 1 && frame[nframe - 1] == 2) { log_info (_("old encoding of the DEK is not supported\n")); err = gpg_error (GPG_ERR_CIPHER_ALGO); goto leave; } if (frame[n] != 2) /* Something went wrong. */ { err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ ; n++; /* Skip the zero byte. */ } } if (n + 4 > nframe) { err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } dek->keylen = nframe - (n + 1) - 2; dek->algo = frame[n++]; err = openpgp_cipher_test_algo (dek->algo); if (err) { if (!opt.quiet && gpg_err_code (err) == GPG_ERR_CIPHER_ALGO) { log_info (_("cipher algorithm %d%s is unknown or disabled\n"), dek->algo, dek->algo == CIPHER_ALGO_IDEA ? " (IDEA)" : ""); } dek->algo = 0; goto leave; } if (dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo)) { err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } /* Copy the key to DEK and compare the checksum. */ csum = buf16_to_u16 (frame+nframe-2); memcpy (dek->key, frame + n, dek->keylen); for (csum2 = 0, n = 0; n < dek->keylen; n++) csum2 += dek->key[n]; if (csum != csum2) { err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } if (DBG_CLOCK) log_clock ("decryption ready"); if (DBG_CRYPTO) log_printhex (dek->key, dek->keylen, "DEK is:"); /* Check that the algo is in the preferences and whether it has * expired. Also print a status line with the key's fingerprint. */ { PKT_public_key *pk = NULL; PKT_public_key *mainpk = NULL; KBNODE pkb = get_pubkeyblock (ctrl, keyid); if (!pkb) { err = -1; log_error ("oops: public key not found for preference check\n"); } else if (pkb->pkt->pkt.public_key->selfsigversion > 3 && dek->algo != CIPHER_ALGO_3DES && !opt.quiet && !is_algo_in_prefs (pkb, PREFTYPE_SYM, dek->algo)) log_info (_("WARNING: cipher algorithm %s not found in recipient" " preferences\n"), openpgp_cipher_algo_name (dek->algo)); if (!err) { kbnode_t k; int first = 1; for (k = pkb; k; k = k->next) { if (k->pkt->pkttype == PKT_PUBLIC_KEY || k->pkt->pkttype == PKT_PUBLIC_SUBKEY) { u32 aki[2]; if (first) { first = 0; mainpk = k->pkt->pkt.public_key; } keyid_from_pk (k->pkt->pkt.public_key, aki); if (aki[0] == keyid[0] && aki[1] == keyid[1]) { pk = k->pkt->pkt.public_key; break; } } } if (!pk) BUG (); if (pk->expiredate && pk->expiredate <= make_timestamp ()) { log_info (_("Note: secret key %s expired at %s\n"), keystr (keyid), asctimestamp (pk->expiredate)); } } if (pk && pk->flags.revoked) { log_info (_("Note: key has been revoked")); log_printf ("\n"); show_revocation_reason (ctrl, pk, 1); } if (is_status_enabled () && pk && mainpk) { char pkhex[MAX_FINGERPRINT_LEN*2+1]; char mainpkhex[MAX_FINGERPRINT_LEN*2+1]; hexfingerprint (pk, pkhex, sizeof pkhex); hexfingerprint (mainpk, mainpkhex, sizeof mainpkhex); /* Note that we do not want to create a trustdb just for * getting the ownertrust: If there is no trustdb there can't * be ulitmately trusted key anyway and thus the ownertrust * value is irrelevant. */ write_status_printf (STATUS_DECRYPTION_KEY, "%s %s %c", pkhex, mainpkhex, get_ownertrust_info (ctrl, mainpk, 1)); } release_kbnode (pkb); err = 0; } leave: xfree (frame); xfree (keygrip); return err; }