gea-program 0.62.0__tar.gz → 0.63.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gea_program-0.62.0 → gea_program-0.63.0}/PKG-INFO +11 -1
- {gea_program-0.62.0 → gea_program-0.63.0}/README.md +10 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/__init__.py +1 -1
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/__main__.py +43 -2
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/acceptance_tests.py +366 -1
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/casing_design.py +5 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/dossier.py +165 -4
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/dossier_verify.py +41 -7
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/IT_SECURITY.md +1 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/dossier.md +3 -1
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/helplib.py +1 -1
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/service.py +17 -0
- gea_program-0.63.0/gea/timestamp.py +568 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/web/app.html +13 -2
- {gea_program-0.62.0 → gea_program-0.63.0}/gea_program.egg-info/PKG-INFO +11 -1
- {gea_program-0.62.0 → gea_program-0.63.0}/gea_program.egg-info/SOURCES.txt +1 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/pyproject.toml +1 -1
- {gea_program-0.62.0 → gea_program-0.63.0}/LICENSE +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/alerts.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/backup.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/bench.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/blind_harness.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog_map.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/catalog_register.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/certificates.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/cli.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/client_reports.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/collision.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/config_versioning.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/conformance.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/control_room.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/correlation.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/dashboard.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/declarations.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/decline.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/deviation.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/dlis.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/dnp3.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/doctor.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/drill_string.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/earth_model.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/economics.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/ed25519.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/edr.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/elevation.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/etp.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/example_register_map.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/fat_sat.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/files.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/follower.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/forward_model.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/frac_hits.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/friction_priors.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/gamma.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/geodesy.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/geomag.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/hartip.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/alarms.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/alerts.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/backup.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/casing.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/catalog.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/charts.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/collision.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/company-sign-in.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/conformance.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/control-room.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/data-in.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/declare.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/decline.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/dlis.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/doctor.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/drift.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/economics.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/edr.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/etp.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/files.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/frac-hits.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/historian.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/https.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/hydraulics.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/instruments.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/interval.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/invoice-check.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/map.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/month-end.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/notifications.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/opseis.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/osdu.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/pad-summary.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/patches.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/plan.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/pore-pressure.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/quality.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/report-history.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/rig-time.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/seismic.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/setup.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/simulation.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/site.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/sites.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/slip.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/soak.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/sra.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/start.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/structure.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/tools.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/torque-drag.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/transients.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/vibration.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/well-report.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/help/well3d.md +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/housekeeping.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/hydraulics.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/interval.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/invoice_check.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/jobs.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/live_ports.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/loadtest.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/modbus.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/model_card.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/month_end.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/notify.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/oidc.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/oidc_mock.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/op_seismicity.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/opcua_port.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/operator_app.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/osdu.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/pad_summary.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/patches.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/pdf_report.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/penetrator.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/permits.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/piwebapi.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/pore_pressure.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/ports.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/ppdm.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/project.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/quakeml.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reconciler.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/WMM2025.COF +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/iscwsa_rev4_example.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/iscwsa_rev5_example.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/mahoning_example.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/owsg_tool_models.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/seismicity_protocols.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/report_history.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/rig_state.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/sample_record.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/sbom.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seedlink.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/segy.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_array.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_film.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_response.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_track.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/seismic_watch.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/series_cache.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/service_life.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/shapefile.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/shell.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/shut_in.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/simulation.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/site_map.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/sla_report.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/slip.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/soak.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/sra.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/store_forward.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/strata_join.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/structure.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/supervisor.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/survey_view.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/telemetry.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/tls.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/tool_library.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/torque_drag.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/transient.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/vibration.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/well3d.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/well_assembler.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/well_report.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/wellplan.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/wellpos.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/wits0.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/witsml.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/workspace.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea/xlsx_read.py +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/setup.cfg +0 -0
- {gea_program-0.62.0 → gea_program-0.63.0}/tests/test_acceptance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gea-program
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.63.0
|
|
4
4
|
Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
|
|
5
5
|
Author: Daniel T. Murphy
|
|
6
6
|
License: MPL-2.0
|
|
@@ -683,6 +683,16 @@ catalogue well is added only from an entry that carries a downhole gauge
|
|
|
683
683
|
series, with a well inside it and its gauge depth; a live seismic station
|
|
684
684
|
whose feed has written nothing yet is listed as having no recording yet.
|
|
685
685
|
|
|
686
|
+
### Trusted timestamps
|
|
687
|
+
|
|
688
|
+
A signed dossier's time is the signing machine's clock. With a public
|
|
689
|
+
time-stamping service named (RFC 3161: DigiCert, Sectigo or the site's
|
|
690
|
+
own), each dossier also carries the authority's signed word that its
|
|
691
|
+
signature existed at a given time - only the signature's SHA-256 is
|
|
692
|
+
sent - and the dossier's own checker verifies it to a root the reader's
|
|
693
|
+
computer trusts. `gea dossier --workspace C:\site --timestamp-url
|
|
694
|
+
http://timestamp.digicert.com --timestamp on`; `gea help dossier`.
|
|
695
|
+
|
|
686
696
|
### Casing design and kick tolerance
|
|
687
697
|
|
|
688
698
|
Each casing string's burst, collapse and tension ratings by API TR 5C3,
|
|
@@ -644,6 +644,16 @@ catalogue well is added only from an entry that carries a downhole gauge
|
|
|
644
644
|
series, with a well inside it and its gauge depth; a live seismic station
|
|
645
645
|
whose feed has written nothing yet is listed as having no recording yet.
|
|
646
646
|
|
|
647
|
+
### Trusted timestamps
|
|
648
|
+
|
|
649
|
+
A signed dossier's time is the signing machine's clock. With a public
|
|
650
|
+
time-stamping service named (RFC 3161: DigiCert, Sectigo or the site's
|
|
651
|
+
own), each dossier also carries the authority's signed word that its
|
|
652
|
+
signature existed at a given time - only the signature's SHA-256 is
|
|
653
|
+
sent - and the dossier's own checker verifies it to a root the reader's
|
|
654
|
+
computer trusts. `gea dossier --workspace C:\site --timestamp-url
|
|
655
|
+
http://timestamp.digicert.com --timestamp on`; `gea help dossier`.
|
|
656
|
+
|
|
647
657
|
### Casing design and kick tolerance
|
|
648
658
|
|
|
649
659
|
Each casing string's burst, collapse and tension ratings by API TR 5C3,
|
|
@@ -596,6 +596,12 @@ def main(argv=None) -> int:
|
|
|
596
596
|
p_dz.add_argument("--rotate-key", action="store_true", help="retire this site's signing key and start a new one, signed over by the old (give --reason)")
|
|
597
597
|
p_dz.add_argument("--reason", type=str, default="", help="with --rotate-key: why the key is retired")
|
|
598
598
|
p_dz.add_argument("--key-history", action="store_true", help="the site's keys, current and retired, and the rotations between them")
|
|
599
|
+
p_dz.add_argument("--timestamp-url", type=str, default=None, help="the RFC 3161 time-stamping service to use, e.g. http://timestamp.digicert.com ('none' to forget it)")
|
|
600
|
+
p_dz.add_argument("--timestamp", type=str, choices=["on", "off"], default=None, help="stamp every dossier as it is signed (on) or not (off)")
|
|
601
|
+
p_dz.add_argument("--timestamp-anchors", type=str, default=None, help="a PEM file with the service's root certificate, when this machine's store does not hold it ('none' to forget it)")
|
|
602
|
+
p_dz.add_argument("--timestamp-test", action="store_true", help="ask the service to stamp a random hash and check its reply (nothing is written)")
|
|
603
|
+
p_dz.add_argument("--stamp", type=str, default=None, help="stamp a dossier this site signed, by its id (gea dossier --list)")
|
|
604
|
+
p_dz.add_argument("--anchors", type=str, default="", help="with --verify: a PEM file of roots to trust for the timestamp, beside this machine's own")
|
|
599
605
|
p_dz.add_argument("--actor", type=str, default="cli")
|
|
600
606
|
p_dz.add_argument("--json", action="store_true")
|
|
601
607
|
|
|
@@ -2507,11 +2513,40 @@ def main(argv=None) -> int:
|
|
|
2507
2513
|
except WorkspaceError as e:
|
|
2508
2514
|
raise SystemExit(f"dossier: {e}")
|
|
2509
2515
|
if a.verify:
|
|
2510
|
-
|
|
2516
|
+
if a.anchors and ws is None:
|
|
2517
|
+
from . import dossier_verify as _DV, timestamp as _TSM
|
|
2518
|
+
with open(a.anchors, "rb") as fh_:
|
|
2519
|
+
r = _DV.check(a.verify, a.sources, _TSM.ts_system_anchors() + _TSM.ts_pem_certs(fh_.read()))
|
|
2520
|
+
else:
|
|
2521
|
+
r = _DZ.verify(a.verify, ws, a.sources)
|
|
2511
2522
|
print(_json.dumps(r, default=str) if a.json else _DZ.text(r))
|
|
2512
2523
|
return 0 if r["status"] == "VALID" else 1
|
|
2513
2524
|
if ws is None:
|
|
2514
2525
|
raise SystemExit("dossier: give --workspace (or --verify FILE)")
|
|
2526
|
+
if a.timestamp_url is not None or a.timestamp is not None or a.timestamp_anchors is not None:
|
|
2527
|
+
try:
|
|
2528
|
+
st_ = _DZ.set_timestamp(ws, a.actor, ("" if (a.timestamp_url or "").lower() == "none" else a.timestamp_url),
|
|
2529
|
+
None if a.timestamp is None else a.timestamp == "on",
|
|
2530
|
+
("" if (a.timestamp_anchors or "").lower() == "none" else a.timestamp_anchors))
|
|
2531
|
+
except ValueError as ex:
|
|
2532
|
+
raise SystemExit(f"dossier: {ex}")
|
|
2533
|
+
print(f"time-stamping service: {st_['url'] or 'none'}; every dossier stamped as it is signed: {'yes' if st_['enabled'] else 'no'}"
|
|
2534
|
+
+ (f"; extra trusted roots: {st_['anchors']}" if st_["anchors"] else ""))
|
|
2535
|
+
return 0
|
|
2536
|
+
if a.timestamp_test or a.stamp:
|
|
2537
|
+
from . import timestamp as _TSM
|
|
2538
|
+
try:
|
|
2539
|
+
if a.timestamp_test:
|
|
2540
|
+
t_ = _DZ.test_timestamp(ws)
|
|
2541
|
+
print(f"{t_['url']}: {t_['status']} - {t_['tsa']} stamped {t_['gen_time']}" + (f" (accuracy {t_['accuracy_s']:g} s)" if t_.get("accuracy_s") else ""))
|
|
2542
|
+
print(f" the chain: {t_['chain_detail']}")
|
|
2543
|
+
return 0 if t_["status"] in ("TRUSTED", "VERIFIED") else 1
|
|
2544
|
+
rec = _DZ.stamp(ws, a.actor, a.stamp)
|
|
2545
|
+
except (KeyError, ValueError, OSError) as ex:
|
|
2546
|
+
raise SystemExit(f"dossier: {ex.args[0] if ex.args else ex}")
|
|
2547
|
+
print(f"stamped {rec['dossier_id']}: {rec['status']} - {rec['tsa']} at {rec['gen_time']} (signed {rec['signed_utc']} by this machine's clock)")
|
|
2548
|
+
print(f" the chain: {rec['chain']}")
|
|
2549
|
+
return 0
|
|
2515
2550
|
if a.key:
|
|
2516
2551
|
k = _DZ.key_info(ws)
|
|
2517
2552
|
print(f"Ed25519 {k['fingerprint']} (public key {k['public_key']}, made {k['created_utc']})" if k else "no signing key yet: the first dossier makes one")
|
|
@@ -2534,8 +2569,11 @@ def main(argv=None) -> int:
|
|
|
2534
2569
|
print("no key history yet")
|
|
2535
2570
|
return 0
|
|
2536
2571
|
if a.list:
|
|
2572
|
+
st_ = _DZ.stamps(ws)
|
|
2537
2573
|
for e in reversed(_DZ.ledger(ws)):
|
|
2538
|
-
|
|
2574
|
+
t_ = st_.get(e["dossier_id"]) or {}
|
|
2575
|
+
print(f"{e['utc']} {e['dossier_id']} {e['display']:<24} {e['n_files']:>4} files {e['path']}"
|
|
2576
|
+
+ (f" [timestamp {t_['status']}" + (f" {t_['gen_time']}]" if t_.get("gen_time") else "]") if t_ else ""))
|
|
2539
2577
|
return 0
|
|
2540
2578
|
try:
|
|
2541
2579
|
e = _DZ.build(ws, a.actor, __version__, a.well, a.include_sources)
|
|
@@ -2544,6 +2582,9 @@ def main(argv=None) -> int:
|
|
|
2544
2582
|
print(f"signed {e['dossier_id']}: {e['display']}, {e['n_files']} file(s), {e['n_sources']} source record(s) {'embedded' if e['sources_embedded'] else 'by hash'}")
|
|
2545
2583
|
print(f" {os.path.join(ws.reports_dir, e['path'])}")
|
|
2546
2584
|
print(f" key fingerprint {e['fingerprint']}")
|
|
2585
|
+
t_ = e.get("timestamp")
|
|
2586
|
+
if t_:
|
|
2587
|
+
print(f" trusted timestamp: {t_['status']}" + (f" - {t_['tsa']} at {t_['gen_time']}" if t_.get("gen_time") else f" - {t_.get('reason', '')}"))
|
|
2547
2588
|
return 0
|
|
2548
2589
|
elif a.cmd == "collision":
|
|
2549
2590
|
import json as _json
|
|
@@ -13611,6 +13611,11 @@ def section_de_real_gas(tmp: str) -> None:
|
|
|
13611
13611
|
"carried": abs(k_["volume_shoe_as_bottom_bbl"] - carried) < 0.15 and "real-gas law" in k_["carried_by"] and "Boyle" in kf["carried_by"],
|
|
13612
13612
|
"z_t": k_["z_bottom"] > 0 and abs(k_["temp_bottom_f"] - CSG.temperature_f(ex["config"], 10000.0 - h_b / 2)) < 0.1,
|
|
13613
13613
|
"swabbed": all(k["swabbed"]["kick_ppg"] == k["mw_ppg"] and k["swabbed"]["volume_bbl"] > k["volume_bbl"] for k in ex["kicks"]),
|
|
13614
|
+
"open_hole": (lambda k: k.get("limited_by_open_hole") and k["governs"] == "the open hole itself" and "taller than the" in k["detail"])(
|
|
13615
|
+
CSG.analyse({**CSG.DEFAULTS, "strings": CSG.check_strings([{"what": "intermediate", "od_in": "9-5/8", "weight_lbft": 40, "grade": "N80", "top_md_ft": 0,
|
|
13616
|
+
"shoe_md_ft": 8000, "hole_in": 12.25, "mw_ppg": 9.5}]),
|
|
13617
|
+
"td_md_ft": 9000.0, "td_hole_in": 8.5, "td_mw_ppg": 10.0, "bha_od_in": 6.75, "bha_length_ft": 400.0, "dp_od_in": 5.0},
|
|
13618
|
+
lambda md: float(md), {"pp_const": 9.5, "fg_const": 14.0})["kicks"][0]),
|
|
13614
13619
|
"burst_real": abs(sv["rows"][0]["burst_net_psi"] - top_load) <= 1.0 and sv["rows"][0]["burst_limited_by_shoe"]
|
|
13615
13620
|
and "real gas" in sv["gas"] and "0.1 psi/ft" in exf["strings"][0]["gas"],
|
|
13616
13621
|
}
|
|
@@ -13618,7 +13623,8 @@ def section_de_real_gas(tmp: str) -> None:
|
|
|
13618
13623
|
ok(not failed3,
|
|
13619
13624
|
"DE3 on the worked example: the gas's gradient in the bubble at its own middle's pressure and temperature, heavier on bottom than at the shoe; "
|
|
13620
13625
|
"the bubble's heights from them; the shoe's volume carried to the bottom by p V / z T (Boyle's law with a fixed gradient); a swabbed kick "
|
|
13621
|
-
"(no underbalance) beside each, larger;
|
|
13626
|
+
"(no underbalance) beside each, larger; a shoe that would hold more gas than the open hole below it says the open hole is the limit; the burst load at "
|
|
13627
|
+
"the top the real gas's column from the fracture pressure at the shoe"
|
|
13622
13628
|
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
13623
13629
|
|
|
13624
13630
|
# -- DE4 declared --------------------------------------------------------------------------------------------------------------
|
|
@@ -13663,6 +13669,364 @@ def section_de_real_gas(tmp: str) -> None:
|
|
|
13663
13669
|
"the help" + (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
|
|
13664
13670
|
|
|
13665
13671
|
|
|
13672
|
+
# -- trusted timestamps: four time-stamp replies OpenSSL 3.0 made (a root, then RSA, ECDSA P-256, P-384 tokens over
|
|
13673
|
+
# SHA-256('hello dossier')), for section DF; made for these checks, by no real authority
|
|
13674
|
+
_TSF_CA = ('MIIDJDCCAgygAwIBAgIUGHYUXAMX2bEUAqBmXzWi3yefo28wDQYJKoZIhvcNAQELBQAwKjEVMBMGA1UEAwwMVGVzdCBSb290IENBMREwDwYDVQQKDAhHRUEg'
|
|
13675
|
+
'dGVzdDAeFw0yNjEwMjIxMDEyNTVaFw0zNjEwMTkxMDEyNTVaMCoxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTERMA8GA1UECgwIR0VBIHRlc3QwggEiMA0GCSqG'
|
|
13676
|
+
'SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAgRnGIUewLTPEkHlyaS3hrMtqJ+nR2UiQGDXVZsbTyx0jw5yT/DbX95mxfQ0wGI4hA+QQwfycNUGyQ4PHOz133wjK'
|
|
13677
|
+
'uH2PqyTxIWq10eSmk1bKN7xkrWn+M/530uPna5XcqGdd4fvYw3c2C4pns5ABjBpVS22CQ+UobLAP6XOBvdXskRDtBIuDE4kfUd7Z0BKLLVFLrFmhhimewBMW'
|
|
13678
|
+
'K5FjMFQZL2GkI3WsTQpK9IZ84yOO8mVcVlBkQoR6U3YVY7M57ISO54ph1umAUkUK2jk8OctJW/2FgAQ3c+gJ94/yRQGgI9zCWzDBCfBUWjzwz1s6Q6dSfQx7'
|
|
13679
|
+
'U7mQiYl4rOLpAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRrdCnx+4GIdaiSiwJ59XMT33qZKjANBgkqhkiG'
|
|
13680
|
+
'9w0BAQsFAAOCAQEAIWRaLc8LYGaOzxh8KPHOG6GNH7aTmBAvdPZDOyqyD7VL9psblX1Ad+yh68G4/fhcLhgy6SNHmcDG7bwa1n3qV1MnoOQm4qxsez/kujQC'
|
|
13681
|
+
'5KizMnJZjZqJY5PVgo+1/4hRvdP9WA8dv8TIw4/r4X9Q6H0ec74qCX2hZUrTeUjd1gibZ1RKgMP+kwQ0DEQOEdJU3eA5GRT/xpI6i5kFPpgb0HkkDQivYrqa'
|
|
13682
|
+
'WKkANb6GAXMnDZbjGJWSQx0KwQ64h63itQ38CcVrIEZufwIWWgo9d41eDwRtvef0+SsyGE5c+iZOj6XBJRUGbDEMRfSxnPnXz55UU3N3ZUS00RruGnypEA==')
|
|
13683
|
+
_TSF_RSA = ('MIIJrzADAgEAMIIJpgYJKoZIhvcNAQcCoIIJlzCCCZMCAQMxDzANBglghkgBZQMEAgEFADCBqwYLKoZIhvcNAQkQAQSggZsEgZgwgZUCAQEGBCoDBAEwMTAN'
|
|
13684
|
+
'BglghkgBZQMEAgEFAAQgpf3YGM3Xqxbz6uMRumW8TAcySa/vTTVJKIwpdN5IqogCAQIYDzIwMjYxMDIyMTAxMjU1WjAKAgEBgAIB9IEBZAEB/wIIM2L78IUF'
|
|
13685
|
+
'H+igKqQoMCYxETAPBgNVBAMMCFRlc3QgVFNBMREwDwYDVQQKDAhHRUEgdGVzdKCCBrAwggNbMIICQ6ADAgECAhRQBQHe0ZbZiT6oIDo1qnmSZKb54TANBgkq'
|
|
13686
|
+
'hkiG9w0BAQsFADAvMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTERMA8GA1UECgwIR0VBIHRlc3QwHhcNMjYxMDIyMTAxMjU1WhcNMzIwNDEzMTAxMjU1'
|
|
13687
|
+
'WjAmMREwDwYDVQQDDAhUZXN0IFRTQTERMA8GA1UECgwIR0VBIHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEaAjK5vfOj1M9nOacc9gT'
|
|
13688
|
+
'eQOghj1nOO6K7r01de2lphAJKC62ygn1rnYDpQFAvG9HZRtu6HngX6hj0t+ak5VNaOFi6E7o/+DXDkyAACu2rPRkvUp57OoQoqzZj5xbCHrBSq40M1s55/O9'
|
|
13689
|
+
'nGQEn7k+iumhj+hrj85s3wGyJp0eqp/zepkzxuaqEnpm9vhJhX113YxOOOIe6mZaGGK4hmQ7QhBaPuS6YaPcfgJxcNL/YMjdNFzlBcL1FM1cIM3ytQfchw+1'
|
|
13690
|
+
'+I6pxqr867ZzfUI/13wfQNkl61c0KwX+zXp8eaEvuEabgbqtpkgla+qP4F7jbXJn0Pe4BuQBKukgSv1XAgMBAAGjeDB2MAwGA1UdEwEB/wQCMAAwDgYDVR0P'
|
|
13691
|
+
'AQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMB0GA1UdDgQWBBR9pWr/h3aAurbsvhR8Oye4WYs2iDAfBgNVHSMEGDAWgBTnbKtOJfPeQuyAk/ny'
|
|
13692
|
+
'7nlUQ2X4UjANBgkqhkiG9w0BAQsFAAOCAQEABrxESQrdMoLXAPVXZETDKNqdxbPwgbaatIb/+uQ8bzz6W6Q/G39/8dYjYPmKVPW9euw66moX2QS2RPjg4boq'
|
|
13693
|
+
'1i/lrsWiBoVPPtzzRsKNv2t5q5dSvAgYAZSqFyyqXZFt+vJai8YH304ewa7q402ldLyYBHLJYTc7lqeTzXQSxUpjo3xctlaYkwOWAwYlDBVlQnoRR0Ix4hRx'
|
|
13694
|
+
'rOnbzqHqF8KFEYp9BqIZB8VpsZF7UhbCtz95a8CUD3RXh4V47LwW0y5Bb/2s8PxQcZ09Z20yDBDYGwLw+nXuhwu3x3UAQ9TtsoT4KGknDNSKLREcmw8Jczfw'
|
|
13695
|
+
'Rbu+0nofDuO4FyPsaDCCA00wggI1oAMCAQICFDrWSB8IC6uckCbmVUN+44yj+yaIMA0GCSqGSIb3DQEBCwUAMCoxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTER'
|
|
13696
|
+
'MA8GA1UECgwIR0VBIHRlc3QwHhcNMjYxMDIyMTAxMjU1WhcNMzUwMTA4MTAxMjU1WjAvMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTERMA8GA1UECgwI'
|
|
13697
|
+
'R0VBIHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrB+E7+70zmq2oxTxsOFzvPMPJ2KSsvntmm9ULxKWynAQpQDsqtl8iQGpC7Tshfkkg'
|
|
13698
|
+
'dWy6UocKCc7lFe+JJ3PYpA0dC0gpLt4gjlxOV1qroLit5jy3hdea89dLGgZYCHvgkTtOct1VKIVqfpHLbzZaedyXlzlT4wJS+qSwETebyRPoW49ilOwZt2tR'
|
|
13699
|
+
'McDOA+gmXQhwHwcvzPoBExLGqocAqupbYcZ6kuL4WX1/IofuMHjjmXxJwa5PyTmL0xIaXp8jHpbn6doLbf71McQo7Mqzy7MUjvmr/xmJvuGlWtuZjK2269d4'
|
|
13700
|
+
'OGnjv7H3942Q/DS9uPP0kC2B/72iudtNbwE3AgMBAAGjZjBkMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTnbKtOJfPe'
|
|
13701
|
+
'QuyAk/ny7nlUQ2X4UjAfBgNVHSMEGDAWgBRrdCnx+4GIdaiSiwJ59XMT33qZKjANBgkqhkiG9w0BAQsFAAOCAQEAtKynEqrAob2dE01ik6ZmKjHg2ejV2Di+'
|
|
13702
|
+
'nFSWMlUrmpFvvVu2Jiolgy/53gdisyg01j55n6fgCP8jKpcJtKznBPOWFST7dmxzBUe/ds4IMVrNtpzow/6IdwU8iiRdungQ26kJHbKaKXuUykgIv3KjsfrK'
|
|
13703
|
+
'3apBjBoj8wgg5bt42Q/s5KQpuq3aw146eCkrJfF1rXBl3ekBovzSjlWmC++Zof37qB+WSuDq87m/6KaBSr3TA0DQgX2gRv7/brhaZbPMZIWW7bWoRLFfYQaw'
|
|
13704
|
+
'yKyubuZKDS5Sl4x0dlDxdvVr8hTV+YUC8Z3DrCHySSE1qPDOKo6CY7eYXoQSuwUukJnFpDGCAhkwggIVAgEBMEcwLzEaMBgGA1UEAwwRVGVzdCBJbnRlcm1l'
|
|
13705
|
+
'ZGlhdGUxETAPBgNVBAoMCEdFQSB0ZXN0AhRQBQHe0ZbZiT6oIDo1qnmSZKb54TANBglghkgBZQMEAgEFAKCBpDAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQ'
|
|
13706
|
+
'AQQwHAYJKoZIhvcNAQkFMQ8XDTI2MTAyMjEwMTI1NVowLwYJKoZIhvcNAQkEMSIEIPSAbRnRwUsYAuiCIZ3h+E5u+EceAdcrebQdBylF1HNnMDcGCyqGSIb3'
|
|
13707
|
+
'DQEJEAIvMSgwJjAkMCIEINXcpmLFUV+aUxLz17QKKpkxQkav4w801wiJq0X0IO/eMA0GCSqGSIb3DQEBAQUABIIBAFPjwPVhgHEl6T+KMxJGgzOyU3GNeNqG'
|
|
13708
|
+
'bpS32ebB+hlJ0/r6WUD86NpulH+qMEEuX1rNx21TElRViQ0dSqy9i82vgWz4FW9Owfz/ReNroBhoPUb0im8ETD6hj73E6Ol7kxpz6k6/LLGwevNU5VwY3LtB'
|
|
13709
|
+
'UI7HHVj7DY2/7sjT6QyeFljjEgh8+eLFWUqvccFs0gDJxZG+S2E8Qy1Lmk3CqH0UqhH1XdfuYAd8wdmIbsdhpARI4vviXsA066cz/WDJxd8o04247hxuRa5h'
|
|
13710
|
+
'2JlKap5MuH8Sity0JYld2AGj1CRi9meUiRCXLcRqbf3PvN71wy9ZpsTvValRht9DQLdlVu8=')
|
|
13711
|
+
_TSF_P256 = ('MIIILTADAgEAMIIIJAYJKoZIhvcNAQcCoIIIFTCCCBECAQMxDzANBglghkgBZQMEAgEFADCBrgYLKoZIhvcNAQkQAQSggZ4EgZswgZgCAQEGBCoDBAEwMTAN'
|
|
13712
|
+
'BglghkgBZQMEAgEFAAQgpf3YGM3Xqxbz6uMRumW8TAcySa/vTTVJKIwpdN5IqogCAQMYDzIwMjYxMDIyMTAxMjU1WjAKAgEBgAIB9IEBZAEB/wIIM2L78IUF'
|
|
13713
|
+
'H+igLaQrMCkxFDASBgNVBAMMC1Rlc3QgVFNBIEVDMREwDwYDVQQKDAhHRUEgdGVzdKCCBegwggKTMIIBe6ADAgECAhRQBQHe0ZbZiT6oIDo1qnmSZKb54jAN'
|
|
13714
|
+
'BgkqhkiG9w0BAQsFADAvMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTERMA8GA1UECgwIR0VBIHRlc3QwHhcNMjYxMDIyMTAxMjU1WhcNMzIwNDEzMTAx'
|
|
13715
|
+
'MjU1WjApMRQwEgYDVQQDDAtUZXN0IFRTQSBFQzERMA8GA1UECgwIR0VBIHRlc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARYQt0GNa05PQcAimdBLWJr'
|
|
13716
|
+
'o5drbydyOi2aDyOXJmLpq+z7kEflU8S1K6WEsBE6eb4V4+q/KdrGyE+Oiss0D+dio3gwdjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUB'
|
|
13717
|
+
'Af8EDDAKBggrBgEFBQcDCDAdBgNVHQ4EFgQUs4jt9hGv65H2e00mgeUU8VuIRGgwHwYDVR0jBBgwFoAU52yrTiXz3kLsgJP58u55VENl+FIwDQYJKoZIhvcN'
|
|
13718
|
+
'AQELBQADggEBADmps17KDCyCHwSsP6Pxix78qe9G+ZdSt/qEglOXZwuyHWRRO3C9FkcUx1vdB8R+YOdlE9qlItcZMXXWjGayw5YikJTHM7bJg8rz4mDg7XfR'
|
|
13719
|
+
'sFF1xQVlVyCO68gaXXZ88PAbjQW7lMT6h8GuLcrpQJbyYfSiDpXuJdkpPD02pu5KvxLW3CZAUbxDQkZ9aAJc6Z34jCNEWyEqyQ920OTPuAgf4sllbWG2m5gy'
|
|
13720
|
+
'4FZvGrpVsFm3DmcktfGdIZ9P1OQ1g4+d2gh8SfcVtloPHXgwMq8t/TznJrKUCTzRiKLLUv9sIskMwfmHmKPtN3UzHvypT8dQwODkMNGF77EX+MjvNLEwggNN'
|
|
13721
|
+
'MIICNaADAgECAhQ61kgfCAurnJAm5lVDfuOMo/smiDANBgkqhkiG9w0BAQsFADAqMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0ExETAPBgNVBAoMCEdFQSB0ZXN0'
|
|
13722
|
+
'MB4XDTI2MTAyMjEwMTI1NVoXDTM1MDEwODEwMTI1NVowLzEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUxETAPBgNVBAoMCEdFQSB0ZXN0MIIBIjANBgkq'
|
|
13723
|
+
'hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqwfhO/u9M5qtqMU8bDhc7zzDydikrL57ZpvVC8SlspwEKUA7KrZfIkBqQu07IX5JIHVsulKHCgnO5RXviSdz2KQN'
|
|
13724
|
+
'HQtIKS7eII5cTldaq6C4reY8t4XXmvPXSxoGWAh74JE7TnLdVSiFan6Ry282Wnncl5c5U+MCUvqksBE3m8kT6FuPYpTsGbdrUTHAzgPoJl0IcB8HL8z6ARMS'
|
|
13725
|
+
'xqqHAKrqW2HGepLi+Fl9fyKH7jB445l8ScGuT8k5i9MSGl6fIx6W5+naC23+9THEKOzKs8uzFI75q/8Zib7hpVrbmYyttuvXeDhp47+x9/eNkPw0vbjz9JAt'
|
|
13726
|
+
'gf+9ornbTW8BNwIDAQABo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU52yrTiXz3kLsgJP58u55VENl+FIwHwYD'
|
|
13727
|
+
'VR0jBBgwFoAUa3Qp8fuBiHWokosCefVzE996mSowDQYJKoZIhvcNAQELBQADggEBALSspxKqwKG9nRNNYpOmZiox4Nno1dg4vpxUljJVK5qRb71btiYqJYMv'
|
|
13728
|
+
'+d4HYrMoNNY+eZ+n4Aj/IyqXCbSs5wTzlhUk+3ZscwVHv3bOCDFazbac6MP+iHcFPIokXbp4ENupCR2ymil7lMpICL9yo7H6yt2qQYwaI/MIIOW7eNkP7OSk'
|
|
13729
|
+
'Kbqt2sNeOngpKyXxda1wZd3pAaL80o5VpgvvmaH9+6gflkrg6vO5v+imgUq90wNA0IF9oEb+/264WmWzzGSFlu21qESxX2EGsMisrm7mSg0uUpeMdHZQ8Xb1'
|
|
13730
|
+
'a/IU1fmFAvGdw6wh8kkhNajwziqOgmO3mF6EErsFLpCZxaQxggFcMIIBWAIBATBHMC8xGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRlMREwDwYDVQQKDAhH'
|
|
13731
|
+
'RUEgdGVzdAIUUAUB3tGW2Yk+qCA6Nap5kmSm+eIwDQYJYIZIAWUDBAIBBQCggaQwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEP'
|
|
13732
|
+
'Fw0yNjEwMjIxMDEyNTVaMC8GCSqGSIb3DQEJBDEiBCAE5TS0HR7scBy9+RNkbVuDYeCK19GuauwAzM4y8IftLDA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCDm'
|
|
13733
|
+
'G6Gj1g2jPRj1bJc7UXIIPz6Rv/2DCLeU0atHHaV9FjAKBggqhkjOPQQDAgRIMEYCIQDYrOX3jrGqg6+DmhVBgNyEpDFGL+l+MVc76XfBs8Ip/AIhAM4HN/88'
|
|
13734
|
+
'd+nd/I+vxtLUz5GF/V/ZAc0n0W3zdqHsAa7S')
|
|
13735
|
+
_TSF_P384 = ('MIIIfzADAgEAMIIIdgYJKoZIhvcNAQcCoIIIZzCCCGMCAQMxDzANBglghkgBZQMEAgIFADCBsQYLKoZIhvcNAQkQAQSggaEEgZ4wgZsCAQEGBCoDBAEwMTAN'
|
|
13736
|
+
'BglghkgBZQMEAgEFAAQgpf3YGM3Xqxbz6uMRumW8TAcySa/vTTVJKIwpdN5IqogCAQQYDzIwMjYxMDIyMTAxMjU2WjAKAgEBgAIB9IEBZAEB/wIIM2L78IUF'
|
|
13737
|
+
'H+igMKQuMCwxFzAVBgNVBAMMDlRlc3QgVFNBIEVDMzg0MREwDwYDVQQKDAhHRUEgdGVzdKCCBggwggKzMIIBm6ADAgECAhRQBQHe0ZbZiT6oIDo1qnmSZKb5'
|
|
13738
|
+
'4zANBgkqhkiG9w0BAQsFADAvMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTERMA8GA1UECgwIR0VBIHRlc3QwHhcNMjYxMDIyMTAxMjU1WhcNMzIwNDEz'
|
|
13739
|
+
'MTAxMjU1WjAsMRcwFQYDVQQDDA5UZXN0IFRTQSBFQzM4NDERMA8GA1UECgwIR0VBIHRlc3QwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATyIqtdYgECcyF0LELj'
|
|
13740
|
+
'MX2frh4Gs0ijfkRwAs11+0F7Gn4U89nI5evfWeE2o18RfDiBPShixZY6ja/R0EVZRbyjnNRZQgesqfUsXzymYMczOUxR62ceJBgfYgYseL2cglujeDB2MAwG'
|
|
13741
|
+
'A1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMB0GA1UdDgQWBBQqloFXH2ZIof62vG5VyBK/9KLtbDAfBgNVHSME'
|
|
13742
|
+
'GDAWgBTnbKtOJfPeQuyAk/ny7nlUQ2X4UjANBgkqhkiG9w0BAQsFAAOCAQEAE+b5Cqjyup3JH6APIj33IRWaFimUM7K5tGHwXB0TpQsg6V8WUdniiXln/BiQ'
|
|
13743
|
+
'soSF9RNoyCGx2JTaHyoSJcfd0ncY+AbwVkc3Jcv9p19Pkl8gSrdsTIfuXP3l1Ft+WKJyk86ACOVPRheH/sI964hrgNz885+0m2mUFsvybGVVVyMnfot5WC33'
|
|
13744
|
+
'KvxcC/FQ3FPledyadoG+0t2566WLWXImBNJtnFrqdS6oUqP5foSh3b10GG5ToeoAiD0zcX+84YHyTMSOgu8MWYVzpoyEY7Korc73xfdPc7jprA2g3zsH4jKh'
|
|
13745
|
+
't7Y4CjS/Cb7IVSlVv5cPrPwOF8OTPAMrIABHL41k5jCCA00wggI1oAMCAQICFDrWSB8IC6uckCbmVUN+44yj+yaIMA0GCSqGSIb3DQEBCwUAMCoxFTATBgNV'
|
|
13746
|
+
'BAMMDFRlc3QgUm9vdCBDQTERMA8GA1UECgwIR0VBIHRlc3QwHhcNMjYxMDIyMTAxMjU1WhcNMzUwMTA4MTAxMjU1WjAvMRowGAYDVQQDDBFUZXN0IEludGVy'
|
|
13747
|
+
'bWVkaWF0ZTERMA8GA1UECgwIR0VBIHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrB+E7+70zmq2oxTxsOFzvPMPJ2KSsvntmm9ULxKWy'
|
|
13748
|
+
'nAQpQDsqtl8iQGpC7TshfkkgdWy6UocKCc7lFe+JJ3PYpA0dC0gpLt4gjlxOV1qroLit5jy3hdea89dLGgZYCHvgkTtOct1VKIVqfpHLbzZaedyXlzlT4wJS'
|
|
13749
|
+
'+qSwETebyRPoW49ilOwZt2tRMcDOA+gmXQhwHwcvzPoBExLGqocAqupbYcZ6kuL4WX1/IofuMHjjmXxJwa5PyTmL0xIaXp8jHpbn6doLbf71McQo7Mqzy7MU'
|
|
13750
|
+
'jvmr/xmJvuGlWtuZjK2269d4OGnjv7H3942Q/DS9uPP0kC2B/72iudtNbwE3AgMBAAGjZjBkMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEG'
|
|
13751
|
+
'MB0GA1UdDgQWBBTnbKtOJfPeQuyAk/ny7nlUQ2X4UjAfBgNVHSMEGDAWgBRrdCnx+4GIdaiSiwJ59XMT33qZKjANBgkqhkiG9w0BAQsFAAOCAQEAtKynEqrA'
|
|
13752
|
+
'ob2dE01ik6ZmKjHg2ejV2Di+nFSWMlUrmpFvvVu2Jiolgy/53gdisyg01j55n6fgCP8jKpcJtKznBPOWFST7dmxzBUe/ds4IMVrNtpzow/6IdwU8iiRdungQ'
|
|
13753
|
+
'26kJHbKaKXuUykgIv3KjsfrK3apBjBoj8wgg5bt42Q/s5KQpuq3aw146eCkrJfF1rXBl3ekBovzSjlWmC++Zof37qB+WSuDq87m/6KaBSr3TA0DQgX2gRv7/'
|
|
13754
|
+
'brhaZbPMZIWW7bWoRLFfYQawyKyubuZKDS5Sl4x0dlDxdvVr8hTV+YUC8Z3DrCHySSE1qPDOKo6CY7eYXoQSuwUukJnFpDGCAYswggGHAgEBMEcwLzEaMBgG'
|
|
13755
|
+
'A1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUxETAPBgNVBAoMCEdFQSB0ZXN0AhRQBQHe0ZbZiT6oIDo1qnmSZKb54zANBglghkgBZQMEAgIFAKCBtDAaBgkqhkiG'
|
|
13756
|
+
'9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTI2MTAyMjEwMTI1NlowNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQg2CMpQc5q4duxT+WhU1zW'
|
|
13757
|
+
'2bOVC/86InR/3U3cQYMCJGAwPwYJKoZIhvcNAQkEMTIEMAUaSVBfI+TaGuBVL7kEknIuC8+Z6IgUpbcnd2Wgj2SO5gI9nalHk8y9ophHiOvDUDAKBggqhkjO'
|
|
13758
|
+
'PQQDAwRnMGUCMFKzJVdh8wAgcksAjKzqiaDyUrGE8PouWM1EuBy86ZUiqIgcAXabuOT/cKGbz//kLgIxAMP9axYsDTCCkiJDlT7VNsTQuA+K1Df/n6Cu4/ph'
|
|
13759
|
+
'MQsKFLjuOOhqJIoQHBXQkLfeAw==')
|
|
13760
|
+
|
|
13761
|
+
|
|
13762
|
+
def _test_tsa(bits: int = 2048, eku_critical: bool = True, wrong_nonce: bool = False, break_signature: bool = False,
|
|
13763
|
+
gen_time=None, ca_valid_days: int = 3650):
|
|
13764
|
+
"""A time-stamping authority for the checks, never a real one: a root it made, a TSA certificate the root issued, and
|
|
13765
|
+
a function answering an RFC 3161 request as a service would (CMS SignedData, RSA with SHA-256, ESS v2)."""
|
|
13766
|
+
import hashlib as _h
|
|
13767
|
+
import secrets as _sec
|
|
13768
|
+
from datetime import datetime as _dt, timedelta as _td, timezone as _tz
|
|
13769
|
+
from . import timestamp as TS
|
|
13770
|
+
from . import tls as TL
|
|
13771
|
+
S, I, O, T_, N, E = TL._seq, TL._int, TL._oid, TL._tlv, TL._name, TL._ext
|
|
13772
|
+
rsa_alg = S(O('1.2.840.113549.1.1.11'), T_(0x05, b''))
|
|
13773
|
+
now = _dt.now(_tz.utc).replace(microsecond=0)
|
|
13774
|
+
|
|
13775
|
+
def spki(k):
|
|
13776
|
+
return S(S(O('1.2.840.113549.1.1.1'), T_(0x05, b'')), T_(0x03, b'\x00' + S(I(k['n']), I(k['e']))))
|
|
13777
|
+
|
|
13778
|
+
def cert(serial, subject, issuer, key, signer_key, exts, days):
|
|
13779
|
+
tbs = S(T_(0xA0, I(2)), I(serial), rsa_alg, issuer, S(TL._time(now - _td(days=1)), TL._time(now + _td(days=days))), subject, spki(key), T_(0xA3, S(*exts)))
|
|
13780
|
+
return S(tbs, rsa_alg, T_(0x03, b'\x00' + TL.sign_pkcs1_sha256(signer_key, tbs)))
|
|
13781
|
+
ca_key, tsa_key = TL.rsa_key(bits), TL.rsa_key(bits)
|
|
13782
|
+
ca_name, tsa_name = N('GEA Test Root (not a real authority)', 'GEA acceptance'), N('GEA Test TSA (not a real authority)', 'GEA acceptance')
|
|
13783
|
+
ca = cert(1001, ca_name, ca_name, ca_key, ca_key, [E('2.5.29.19', True, S(T_(0x01, b'\xff'))), E('2.5.29.15', True, T_(0x03, b'\x01\x06'))], ca_valid_days)
|
|
13784
|
+
tsa = cert(1002, tsa_name, ca_name, tsa_key, ca_key, [E('2.5.29.19', True, S()), E('2.5.29.15', True, T_(0x03, b'\x07\x80')),
|
|
13785
|
+
E('2.5.29.37', eku_critical, S(O('1.3.6.1.5.5.7.3.8')))], 1800)
|
|
13786
|
+
served = []
|
|
13787
|
+
|
|
13788
|
+
def answer(url, req, timeout=None):
|
|
13789
|
+
k = TS._ts_kids(TS._ts_one(req)[1])
|
|
13790
|
+
imp = k[1][2]
|
|
13791
|
+
nonce = next((TS._ts_int(v) for t, v, _ in k[2:] if t == 0x02), None)
|
|
13792
|
+
if wrong_nonce and nonce is not None:
|
|
13793
|
+
nonce += 1
|
|
13794
|
+
when = gen_time or _dt.now(_tz.utc)
|
|
13795
|
+
serial = _sec.randbits(62)
|
|
13796
|
+
tst = S(I(1), O('1.3.6.1.4.1.99999.1'), imp, I(serial), T_(0x18, when.strftime('%Y%m%d%H%M%SZ').encode('ascii')), S(I(1)),
|
|
13797
|
+
*([I(nonce)] if nonce is not None else []))
|
|
13798
|
+
attrs = sorted([S(O('1.2.840.113549.1.9.3'), TL._set(O('1.2.840.113549.1.9.16.1.4'))),
|
|
13799
|
+
S(O('1.2.840.113549.1.9.4'), TL._set(T_(0x04, _h.sha256(tst).digest()))),
|
|
13800
|
+
S(O('1.2.840.113549.1.9.16.2.47'), TL._set(S(S(S(T_(0x04, _h.sha256(tsa).digest()))))))])
|
|
13801
|
+
signed = TL._set(*attrs)
|
|
13802
|
+
sig = TL.sign_pkcs1_sha256(tsa_key, signed)
|
|
13803
|
+
if break_signature:
|
|
13804
|
+
sig = sig[:-1] + bytes([sig[-1] ^ 1])
|
|
13805
|
+
si = S(I(1), S(ca_name, I(1002)), S(O('2.16.840.1.101.3.4.2.1'), T_(0x05, b'')), b'\xa0' + signed[1:],
|
|
13806
|
+
S(O('1.2.840.113549.1.1.1'), T_(0x05, b'')), T_(0x04, sig))
|
|
13807
|
+
sd = S(I(3), TL._set(S(O('2.16.840.1.101.3.4.2.1'), T_(0x05, b''))), S(O('1.2.840.113549.1.9.16.1.4'), T_(0xA0, T_(0x04, tst))),
|
|
13808
|
+
T_(0xA0, tsa), TL._set(si))
|
|
13809
|
+
served.append(serial)
|
|
13810
|
+
return S(S(I(0)), S(O('1.2.840.113549.1.7.2'), T_(0xA0, sd)))
|
|
13811
|
+
return {'ca': ca, 'tsa': tsa, 'answer': answer, 'served': served}
|
|
13812
|
+
|
|
13813
|
+
|
|
13814
|
+
def section_df_trusted_timestamp(tmp: str) -> None:
|
|
13815
|
+
"""Section DF - trusted timestamps (RFC 3161) on the signed dossier: tokens an independent implementation (OpenSSL
|
|
13816
|
+
3.0) made with RSA, ECDSA P-256 and P-384 read and verified to their root, and every tampering caught; a request
|
|
13817
|
+
OpenSSL reads; a dossier stamped as it is signed through a service over HTTP, the token inside, the standalone
|
|
13818
|
+
checker reading it with and without the root trusted; a service that cannot be reached leaves the dossier signed
|
|
13819
|
+
and says so; stamping later; the settings, the command line, the API, the tab and the help."""
|
|
13820
|
+
import base64 as _b64
|
|
13821
|
+
import hashlib
|
|
13822
|
+
import http.cookiejar
|
|
13823
|
+
import http.server
|
|
13824
|
+
import subprocess as _sp
|
|
13825
|
+
import threading as _th
|
|
13826
|
+
import urllib.error
|
|
13827
|
+
import urllib.request
|
|
13828
|
+
import zipfile as _zf
|
|
13829
|
+
from datetime import datetime as _dt, timedelta as _td, timezone as _tz
|
|
13830
|
+
from . import __version__ as _ver
|
|
13831
|
+
from . import dossier as DZ
|
|
13832
|
+
from . import helplib as H
|
|
13833
|
+
from . import timestamp as TS
|
|
13834
|
+
from .service import Service, Users
|
|
13835
|
+
from .workspace import Workspace
|
|
13836
|
+
pkg = Path(__file__).parent
|
|
13837
|
+
fx = {k: _b64.b64decode(v) for k, v in (('ca', _TSF_CA), ('rsa', _TSF_RSA), ('p256', _TSF_P256), ('p384', _TSF_P384))}
|
|
13838
|
+
data_hash = hashlib.sha256(b'hello dossier').digest()
|
|
13839
|
+
|
|
13840
|
+
# -- DF1 tokens OpenSSL made ------------------------------------------------------------------------------------------------
|
|
13841
|
+
res = {k: TS.ts_verify(TS.ts_read_response(fx[k])['token'], data_hash, anchors=[fx['ca']]) for k in ('rsa', 'p256', 'p384')}
|
|
13842
|
+
tok = TS.ts_read_response(fx['rsa'])['token']
|
|
13843
|
+
other = TS.ts_verify(tok, hashlib.sha256(b'another dossier').digest(), anchors=[fx['ca']])
|
|
13844
|
+
untrusted = TS.ts_verify(tok, data_hash, anchors=[])
|
|
13845
|
+
i_t = tok.find(TS.ts_read_token(tok)['tst_der'])
|
|
13846
|
+
t_tst = TS.ts_verify(tok[:i_t + 40] + bytes([tok[i_t + 40] ^ 1]) + tok[i_t + 41:], data_hash, anchors=[fx['ca']])
|
|
13847
|
+
t_sig = TS.ts_verify(tok[:-3] + bytes([tok[-3] ^ 1]) + tok[-2:], data_hash, anchors=[fx['ca']])
|
|
13848
|
+
req, nonce = TS.ts_request(data_hash, nonce=12345)
|
|
13849
|
+
rk = TS._ts_kids(TS._ts_one(req)[1])
|
|
13850
|
+
try:
|
|
13851
|
+
TS.ts_request(b'short')
|
|
13852
|
+
short = ''
|
|
13853
|
+
except TS.TimestampError as e:
|
|
13854
|
+
short = str(e)
|
|
13855
|
+
c1 = {
|
|
13856
|
+
"openssl_tokens": all(r['status'] == 'TRUSTED' for r in res.values()) and res['rsa']['gen_time'] == '2026-10-22T10:12:55Z'
|
|
13857
|
+
and res['rsa']['tsa'] == 'Test TSA' and abs(res['rsa']['accuracy_s'] - 1.5001) < 1e-9,
|
|
13858
|
+
"algorithms": 'RSA with SHA256' in res['rsa']['checks'][3]['detail'] and 'ECDSA P-256 with SHA256' in res['p256']['checks'][3]['detail']
|
|
13859
|
+
and 'ECDSA P-384 with SHA384' in res['p384']['checks'][3]['detail'],
|
|
13860
|
+
"chain": res['rsa']['chain'] == ['Test TSA', 'Test Intermediate', 'Test Root CA'] and res['rsa']['root'] == 'Test Root CA',
|
|
13861
|
+
"other_hash": other['status'] == 'INVALID' and not other['checks'][1]['ok'],
|
|
13862
|
+
"not_trusted": untrusted['status'] == 'VERIFIED' and 'not trusted here' in untrusted['chain_detail'],
|
|
13863
|
+
"tampered": t_tst['status'] == 'INVALID' and t_sig['status'] == 'INVALID',
|
|
13864
|
+
"request": len(req) > 50 and TS._ts_int(rk[0][1]) == 1 and TS._ts_kids(rk[1][1])[1][1] == data_hash and TS._ts_int(rk[2][1]) == 12345
|
|
13865
|
+
and rk[3][1] == b'\xff' and 'a sha256 hash is 32 bytes' in short,
|
|
13866
|
+
}
|
|
13867
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
13868
|
+
ok(not failed1,
|
|
13869
|
+
"DF1 time-stamp tokens OpenSSL 3.0 made (RSA, ECDSA P-256, P-384) read and verified: the hash they cover, the signed attributes, the authority's "
|
|
13870
|
+
"signature, its signing-certificate attribute, a time-stamping certificate, the chain through the intermediate to the root; another hash, a "
|
|
13871
|
+
"changed TSTInfo or signature INVALID; the root not trusted here VERIFIED, said so; the request as RFC 3161 lays it out"
|
|
13872
|
+
+ (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
13873
|
+
|
|
13874
|
+
# -- DF2 a service made here, and what a bad one does -------------------------------------------------------------------------------
|
|
13875
|
+
good = _test_tsa()
|
|
13876
|
+
bad_nonce, soft_eku, bad_sig = _test_tsa(wrong_nonce=True), _test_tsa(eku_critical=False), _test_tsa(break_signature=True)
|
|
13877
|
+
late = _test_tsa(gen_time=_dt.now(_tz.utc) + _td(days=4000))
|
|
13878
|
+
|
|
13879
|
+
def ask(t):
|
|
13880
|
+
rq, n = TS.ts_request(data_hash)
|
|
13881
|
+
return TS.ts_verify(TS.ts_read_response(t['answer']('x', rq))['token'], data_hash, nonce=n, anchors=[t['ca']])
|
|
13882
|
+
rg, rn, re_, rs, rl = ask(good), ask(bad_nonce), ask(soft_eku), ask(bad_sig), ask(late)
|
|
13883
|
+
try: # a TimeStampResp whose status is 2 (rejection), "no"
|
|
13884
|
+
TS.ts_read_response(b'\x30\x0b\x30\x09\x02\x01\x02\x30\x04\x0c\x02no')
|
|
13885
|
+
refused_ = ''
|
|
13886
|
+
except TS.TimestampError as e:
|
|
13887
|
+
refused_ = str(e)
|
|
13888
|
+
c2 = {
|
|
13889
|
+
"good": rg['status'] == 'TRUSTED' and any(c['check'] == 'the nonce is the one sent' and c['ok'] for c in rg['checks']),
|
|
13890
|
+
"nonce": rn['status'] == 'INVALID' and any(c['check'] == 'the nonce is the one sent' and not c['ok'] for c in rn['checks']),
|
|
13891
|
+
"eku": re_['status'] == 'INVALID' and any('time stamping only' in c['detail'] for c in re_['checks'] if not c['ok']),
|
|
13892
|
+
"signature": rs['status'] == 'INVALID' and any(c['check'] == "the authority's signature verifies" and not c['ok'] for c in rs['checks']),
|
|
13893
|
+
"out_of_validity": rl['status'] == 'INVALID' and any('not valid at the time stamped' in c['detail'] for c in rl['checks']),
|
|
13894
|
+
"rejected": 'did not grant a time stamp: rejection' in refused_ and '(no)' in refused_,
|
|
13895
|
+
}
|
|
13896
|
+
failed2 = [k for k, v in c2.items() if not v]
|
|
13897
|
+
ok(not failed2,
|
|
13898
|
+
"DF2 a service made here with the program's own RSA (a root and a time-stamping certificate it issued) answers and verifies; a reply with "
|
|
13899
|
+
"another nonce, a certificate not marked for time stamping only, a broken signature, a time outside the certificate's validity are each "
|
|
13900
|
+
"INVALID, said which; a rejection is reported with the service's words" + (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
13901
|
+
|
|
13902
|
+
# -- DF3 a dossier stamped as it is signed, over HTTP ---------------------------------------------------------------------------------
|
|
13903
|
+
d = Path(tmp, "tsa"); d.mkdir()
|
|
13904
|
+
(d / "root.pem").write_text('-----BEGIN CERTIFICATE-----\n' + _b64.encodebytes(good['ca']).decode() + '-----END CERTIFICATE-----\n', encoding='ascii')
|
|
13905
|
+
|
|
13906
|
+
class TSAHandler(http.server.BaseHTTPRequestHandler):
|
|
13907
|
+
def log_message(self, *a):
|
|
13908
|
+
pass
|
|
13909
|
+
|
|
13910
|
+
def do_POST(self):
|
|
13911
|
+
n = int(self.headers.get('Content-Length') or 0)
|
|
13912
|
+
body = good['answer']('x', self.rfile.read(n))
|
|
13913
|
+
self.send_response(200); self.send_header('Content-Type', 'application/timestamp-reply'); self.send_header('Content-Length', str(len(body)))
|
|
13914
|
+
self.end_headers(); self.wfile.write(body)
|
|
13915
|
+
srv = http.server.ThreadingHTTPServer(('127.0.0.1', 0), TSAHandler)
|
|
13916
|
+
_th.Thread(target=srv.serve_forever, daemon=True).start()
|
|
13917
|
+
url = f"http://127.0.0.1:{srv.server_address[1]}/tsr"
|
|
13918
|
+
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
|
|
13919
|
+
ws.add_well_catalog("volve_f12_f14_production_excerpt", "15/9-F-12", 10000.0, actor="tester")
|
|
13920
|
+
ws.refresh_dashboard(actor="tester")
|
|
13921
|
+
|
|
13922
|
+
def refused(**kw):
|
|
13923
|
+
try:
|
|
13924
|
+
DZ.set_timestamp(ws, "tester", **kw)
|
|
13925
|
+
return ''
|
|
13926
|
+
except ValueError as e:
|
|
13927
|
+
return str(e)
|
|
13928
|
+
m_url, m_on, m_anc = refused(url='ftp://x'), refused(enabled=True), refused(anchors=str(d / 'none.pem'))
|
|
13929
|
+
st = DZ.set_timestamp(ws, "tester", url, True, str(d / "root.pem"))
|
|
13930
|
+
e1 = DZ.build(ws, "tester", _ver, None)
|
|
13931
|
+
zp = os.path.join(ws.reports_dir, e1['path'])
|
|
13932
|
+
with _zf.ZipFile(zp) as z_:
|
|
13933
|
+
names = set(z_.namelist())
|
|
13934
|
+
verifier = z_.read('verify_dossier.py')
|
|
13935
|
+
(d / "verify_dossier.py").write_bytes(verifier)
|
|
13936
|
+
v_any = _sp.run([sys.executable, str(d / "verify_dossier.py"), zp], capture_output=True, text=True, cwd=str(d))
|
|
13937
|
+
v_anc = _sp.run([sys.executable, str(d / "verify_dossier.py"), zp, "--anchors", str(d / "root.pem")], capture_output=True, text=True, cwd=str(d))
|
|
13938
|
+
v_ws = DZ.verify(zp, ws)
|
|
13939
|
+
with _zf.ZipFile(zp) as z_: # a token changed after the fact
|
|
13940
|
+
items = [(i, z_.read(i.filename)) for i in z_.infolist()]
|
|
13941
|
+
zp_bad = str(d / "bad.zip")
|
|
13942
|
+
with _zf.ZipFile(zp_bad, 'w') as z_:
|
|
13943
|
+
for i, b in items:
|
|
13944
|
+
z_.writestr(i, (b[:-5] + bytes([b[-5] ^ 1]) + b[-4:]) if i.filename == 'timestamp.tsr' else b)
|
|
13945
|
+
v_bad = _sp.run([sys.executable, str(d / "verify_dossier.py"), zp_bad, "--anchors", str(d / "root.pem")], capture_output=True, text=True, cwd=str(d))
|
|
13946
|
+
DZ.set_timestamp(ws, "tester", "http://127.0.0.1:9/tsr") # nothing listens there
|
|
13947
|
+
e2 = DZ.build(ws, "tester", _ver, None)
|
|
13948
|
+
DZ.set_timestamp(ws, "tester", url)
|
|
13949
|
+
later = DZ.stamp(ws, "tester", e2['dossier_id'])
|
|
13950
|
+
stamps = DZ.stamps(ws)
|
|
13951
|
+
pg = DZ.page(ws)
|
|
13952
|
+
audit = Path(ws.audit_path).read_text(encoding="utf-8")
|
|
13953
|
+
c3 = {
|
|
13954
|
+
"settings": "http:// or https://" in m_url and "address first" in m_on and "no file" in m_anc and st['enabled'] and st['url'] == url,
|
|
13955
|
+
"stamped": e1['timestamp']['status'] == 'TRUSTED' and 'timestamp.tsr' in names and e1['timestamp']['tsa'].startswith('GEA Test TSA'),
|
|
13956
|
+
"checker_anchor": v_anc.returncode == 0 and "VALID" in v_anc.stdout and "the trusted timestamp verifies" in v_anc.stdout
|
|
13957
|
+
and "a root this computer trusts" in v_anc.stdout and "after the signing machine's clock" in v_anc.stdout,
|
|
13958
|
+
"checker_untrusted": v_any.returncode == 0 and "does not reach a root this computer trusts" in v_any.stdout,
|
|
13959
|
+
"workspace": v_ws['status'] == 'VALID' and v_ws['timestamp']['status'] == 'TRUSTED',
|
|
13960
|
+
"tampered": v_bad.returncode == 1 and "INVALID" in v_bad.stdout and "NO the trusted timestamp verifies" in v_bad.stdout,
|
|
13961
|
+
"unreachable": e2['timestamp']['status'] == 'NOT STAMPED' and 'did not answer' in e2['timestamp']['reason'] and os.path.isfile(os.path.join(ws.reports_dir, e2['path'])),
|
|
13962
|
+
"later": later['status'] == 'TRUSTED' and stamps[e2['dossier_id']]['status'] == 'TRUSTED' and DZ.verify(os.path.join(ws.reports_dir, e2['path']), ws)['status'] == 'VALID',
|
|
13963
|
+
"page": pg['timestamp']['url'] == url and all(x['timestamp'] and x['timestamp']['status'] == 'TRUSTED' for x in pg['dossiers']),
|
|
13964
|
+
"audit": '"dossier.timestamp"' in audit and '"dossier.timestamp_settings"' in audit and 'NOT STAMPED' in audit,
|
|
13965
|
+
}
|
|
13966
|
+
failed3 = [k for k, v in c3.items() if not v]
|
|
13967
|
+
ok(not failed3,
|
|
13968
|
+
"DF3 a dossier stamped as it is signed, through a service over HTTP: the token rides in it; the standalone checker reads it - TRUSTED with the "
|
|
13969
|
+
"service's root given, its chain short of a trusted root said so without it, a changed token INVALID; a service that cannot be reached leaves "
|
|
13970
|
+
"the dossier signed and NOT STAMPED with why, and stamping it later adds the token; settings refused when wrong; audited"
|
|
13971
|
+
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
13972
|
+
|
|
13973
|
+
# -- DF4 the command line, the API, the tab, the help ------------------------------------------------------------------------------
|
|
13974
|
+
run = lambda *a: _sp.run([sys.executable, "-m", "gea", "dossier", "--workspace", wsp, *a], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
13975
|
+
r_test = run("--timestamp-test")
|
|
13976
|
+
e3 = DZ.build(ws, "tester", _ver, None)
|
|
13977
|
+
r_stamp = run("--stamp", e3['dossier_id'])
|
|
13978
|
+
r_list = run("--list")
|
|
13979
|
+
r_off = run("--timestamp", "off")
|
|
13980
|
+
r_none = run("--timestamp-url", "none")
|
|
13981
|
+
st_none = DZ.timestamp_settings(ws)
|
|
13982
|
+
DZ.set_timestamp(ws, "tester", url, True)
|
|
13983
|
+
Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator"); Users(str(Path(wsp, "users.json"))).add("adm", "admin-pass-123", "admin")
|
|
13984
|
+
svc = Service(wsp, port=0, scheduler=False).start()
|
|
13985
|
+
base_url = svc.url.rstrip("/")
|
|
13986
|
+
|
|
13987
|
+
def opener(name, pw_):
|
|
13988
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
13989
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
13990
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
13991
|
+
return o
|
|
13992
|
+
|
|
13993
|
+
def call(o, method, path, body=None):
|
|
13994
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
13995
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
13996
|
+
try:
|
|
13997
|
+
with o.open(rq, timeout=120) as rr_:
|
|
13998
|
+
return rr_.status, json.loads(rr_.read())
|
|
13999
|
+
except urllib.error.HTTPError as e:
|
|
14000
|
+
return e.code, json.loads(e.read())
|
|
14001
|
+
try:
|
|
14002
|
+
op, adm = opener("op", "op-pass-123"), opener("adm", "admin-pass-123")
|
|
14003
|
+
s_op, _ = call(op, "POST", "/api/dossier/timestamp/settings", {"url": url})
|
|
14004
|
+
s_ad, sa = call(adm, "POST", "/api/dossier/timestamp/settings", {"url": url, "enabled": True})
|
|
14005
|
+
t_ad, ta = call(adm, "POST", "/api/dossier/timestamp/test", {})
|
|
14006
|
+
sg, sgv = call(op, "POST", "/api/dossier/sign", {})
|
|
14007
|
+
gp, gpv = call(op, "GET", "/api/dossier")
|
|
14008
|
+
st_x, sx = call(op, "POST", "/api/dossier/stamp", {"dossier_id": "nope"})
|
|
14009
|
+
finally:
|
|
14010
|
+
svc.stop(); srv.shutdown()
|
|
14011
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
14012
|
+
it = H.security_text() or ""
|
|
14013
|
+
c4 = {
|
|
14014
|
+
"cli": r_test.returncode == 0 and "TRUSTED" in r_test.stdout and r_stamp.returncode == 0 and "stamped " in r_stamp.stdout
|
|
14015
|
+
and "[timestamp TRUSTED" in r_list.stdout and r_off.returncode == 0 and "stamped as it is signed: no" in r_off.stdout
|
|
14016
|
+
and r_none.returncode == 0 and st_none['url'] is None and not st_none['enabled'],
|
|
14017
|
+
"api": s_op == 403 and s_ad == 200 and sa['enabled'] and t_ad == 200 and ta['status'] == 'TRUSTED' and sg == 200 and sgv['timestamp']['status'] == 'TRUSTED'
|
|
14018
|
+
and gp == 200 and gpv['dossiers'][0]['timestamp']['status'] == 'TRUSTED' and st_x == 404,
|
|
14019
|
+
"page": all(x in page_src for x in ("/api/dossier/timestamp/settings", "/api/dossier/timestamp/test", "/api/dossier/stamp", "Trusted timestamp", "dz-stamp")),
|
|
14020
|
+
"help": not H.check("dossier") and "--timestamp-url http://timestamp.digicert.com" in (H.page("dossier") or "") and "Trusted timestamp" in it
|
|
14021
|
+
and "only the SHA-256 of a dossier's signature" in it,
|
|
14022
|
+
}
|
|
14023
|
+
failed4 = [k for k, v in c4.items() if not v]
|
|
14024
|
+
ok(not failed4,
|
|
14025
|
+
"DF4 from the command line (the service set, tested, a dossier stamped, the list showing it, turned off, forgotten), the API (the settings for "
|
|
14026
|
+
"the administrator only, the test, signing stamped), the Reports tab, the help and the IT overview naming the service and what is sent"
|
|
14027
|
+
+ (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
|
|
14028
|
+
|
|
14029
|
+
|
|
13666
14030
|
def PR_read_ok(path) -> bool:
|
|
13667
14031
|
from . import pdf_report as PR
|
|
13668
14032
|
try:
|
|
@@ -13783,6 +14147,7 @@ def main() -> int:
|
|
|
13783
14147
|
section_dc_every_tab(tmp)
|
|
13784
14148
|
section_dd_casing_design(tmp)
|
|
13785
14149
|
section_de_real_gas(tmp)
|
|
14150
|
+
section_df_trusted_timestamp(tmp)
|
|
13786
14151
|
if _FAILS:
|
|
13787
14152
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
13788
14153
|
for f in _FAILS:
|
|
@@ -620,6 +620,11 @@ def kick_tolerance(cfg: dict, i: int, tvd_of, win) -> Optional[dict]:
|
|
|
620
620
|
out.update({'volume_at_bottom_bbl': round(v_bottom, 1), 'volume_at_shoe_bbl': round(v_shoe, 1), 'volume_shoe_as_bottom_bbl': round(v_shoe_at_bottom, 1),
|
|
621
621
|
'volume_bbl': round(min(v_bottom, v_shoe_at_bottom), 1), 'carried_by': law,
|
|
622
622
|
'governs': 'the bubble at the bottom' if v_bottom <= v_shoe_at_bottom else 'the bubble at the shoe'})
|
|
623
|
+
if bot['h'] > open_h and sho['h'] > open_h:
|
|
624
|
+
out['governs'] = 'the open hole itself'
|
|
625
|
+
out['limited_by_open_hole'] = True
|
|
626
|
+
out['detail'] = (f"the shoe would hold a gas column taller than the {open_h:,.0f} ft of open hole below it: the tolerance is the open hole's "
|
|
627
|
+
"whole volume, and the shoe is not what limits it")
|
|
623
628
|
return out
|
|
624
629
|
|
|
625
630
|
|