#include "fiko/cekirdek/lisans_uzak.hpp" #include #include "fiko/cekirdek/kripto.hpp" #include "fiko/cekirdek/lisans_dosya.hpp" // lisansKanonikGovde (aynı kanonikleştirme) namespace fiko { namespace { // Satır sonu karakteri (kaçışsız: char(10)). constexpr char NL = static_cast(10); } // namespace const char* uzakPolitikaDurumMetni(UzakPolitikaDurum d) { switch (d) { case UzakPolitikaDurum::Gecerli: return "geçerli"; case UzakPolitikaDurum::Bicim: return "politika biçimi bozuk"; case UzakPolitikaDurum::ImzaGecersiz: return "politika imzası geçersiz (kurcalanmış)"; } return "bilinmeyen"; } UzakPolitikaDurum uzakPolitikaCoz(std::string_view metin, std::string_view acikAnahtarHex, UzakPolitika& out, std::string& hata) { out = UzakPolitika{}; // İmza doğrulaması KANONİK gövde üzerinde; alan okuma HAM satırlardan — çünkü // lisansKanonikGovde "imza=" satırını GÖVDEDEN DIŞLAR (lisansCoz ile aynı desen). const std::string kanonik = lisansKanonikGovde(metin); std::string imzaB64; bool surumVar = false, zamanVar = false; std::size_t i = 0; while (i <= metin.size()) { std::size_t son = metin.find(NL, i); if (son == std::string_view::npos) son = metin.size(); std::string satir(metin.substr(i, son - i)); i = son + 1; // Kırp (CR / çevre boşlukları) + yorum ve boş satır at. while (!satir.empty() && (satir.back() == ' ' || satir.back() == '\t' || satir.back() == NL)) satir.pop_back(); std::size_t a = 0; while (a < satir.size() && (satir[a] == ' ' || satir[a] == '\t')) ++a; satir.erase(0, a); if (satir.empty() || satir[0] == '#') { if (son == metin.size()) break; continue; } const std::size_t esit = satir.find('='); if (esit == std::string::npos) continue; // bozuk satır → yok say (lisansCoz'dan farklı: // politika esnek; imza yine korur) const std::string anahtar = satir.substr(0, esit); const std::string deger = satir.substr(esit + 1); if (anahtar == "surum") { out.surum = std::strtoull(deger.c_str(), nullptr, 10); surumVar = true; } else if (anahtar == "zaman") { out.zaman = std::strtoll(deger.c_str(), nullptr, 10); zamanVar = true; } else if (anahtar == "mod") { out.mod = (deger == "izin") ? UzakMod::IzinListesi : UzakMod::EngelliListesi; } else if (anahtar == "engelle") { if (!deger.empty()) out.engelliler.push_back(deger); } else if (anahtar == "izin") { if (!deger.empty()) out.izinliler.push_back(deger); } else if (anahtar == "mesaj") { out.mesaj = deger; } else if (anahtar == "imza") { imzaB64 = deger; } // Bilinmeyen anahtarlar yok sayılır → gelecekteki sürümler geriye uyumlu. if (son == metin.size()) break; } if (!surumVar || !zamanVar) { hata = "zorunlu alan eksik (surum/zaman)"; return UzakPolitikaDurum::Bicim; } if (imzaB64.empty()) { hata = "imza satırı yok"; return UzakPolitikaDurum::Bicim; } if (acikAnahtarHex.empty()) { hata = "açık anahtar boş"; return UzakPolitikaDurum::ImzaGecersiz; } if (!kripto::imzaDogrula(kanonik, imzaB64, acikAnahtarHex)) { hata = "ECDSA doğrulaması başarısız"; return UzakPolitikaDurum::ImzaGecersiz; } return UzakPolitikaDurum::Gecerli; } const char* uzakKararMetni(UzakKarar k) { switch (k) { case UzakKarar::Izinli: return "izinli"; case UzakKarar::Engelli: return "engelli"; case UzakKarar::Belirsiz: return "belirsiz (bilgi yok)"; } return "bilinmeyen"; } UzakKarar uzakPolitikaKarar(const UzakPolitika* p, const std::string& seri) { if (!p || seri.empty()) return UzakKarar::Belirsiz; const auto iceriyor = [](const std::vector& liste, const std::string& s) { return std::find(liste.begin(), liste.end(), s) != liste.end(); }; if (p->mod == UzakMod::EngelliListesi) return iceriyor(p->engelliler, seri) ? UzakKarar::Engelli : UzakKarar::Izinli; return iceriyor(p->izinliler, seri) ? UzakKarar::Izinli : UzakKarar::Engelli; } } // namespace fiko