1 puan yazan GN⁺ 2025-10-25 | 1 yorum | WhatsApp'ta paylaş
  • Bir geliştirici, D diliyle bir ASN.1 derleyicisini (dasn1) bizzat geliştirirken yaşadığı teknik ve zihinsel yolculuğu paylaşıyor
  • Proje, x.509 sertifikaları ve TLS 1.3 uygulamasını hedefliyor ve ASN.1’in karmaşık DER kodlama işleme yapısını destekliyor
  • Yazı; ASN.1’in yapısal olarak ne kadar zor olduğunu, x.680~x.683 standartlarını uygulamanın güçlüğünü ve D dilinin metaprogramlama olanaklarının nasıl kullanıldığını ayrıntılı biçimde ele alıyor
  • D’nin static import, mixin template, typeof(), alias this gibi özelliklerinin kod üretimi ile AST/IR tasarımında nasıl faydalı olduğuna somut örneklerle değiniliyor
  • Yazı, “ASN.1 acı verici ama çok şey öğreten bir deneyim” diyerek derleyici geliştirmenin gerçek zorluklarını ve tatminini dürüstçe aktarıyor

Projenin genel görünümü ve motivasyonu

  • Yazar, Juptune adlı D tabanlı asenkron I/O çerçevesi üzerinde çalışıyor ve TLS uygulaması için ASN.1 DER kodlamasını doğrudan işlemesi gerektiğini söylüyor
    • TLS’deki x.509 sertifika yapısını ayrıştırmak için ASN.1’in karmaşık veri gösterim biçimini anlamak gerekiyor
  • Bu proje, öğrenme ve eğlence amacıyla kişisel bir meydan okuma olarak başlamış ve gerçekten de bazı sertifikaları başarıyla ayrıştırma aşamasına kadar ilerlemiş
  • ASN.1, 1990’lardan kalma eski bir standart olsa da bugün hâlâ TLS, SNMP, LDAP gibi modern sistemlerde yaygın biçimde kullanılıyor
  • Yazar, “ASN.1 dünyada çok yaygın ama çoğu geliştirici onun varlığından bile habersiz” diyor

ASN.1 nedir

  • ASN.1 (Abstract Syntax Notation One), veri yapılarını tanımlamak ve kodlamak için kullanılan bir dil; bir bakıma “Protocol Buffers’ın atası”
  • Standart, gösterim kuralları (x.680~x.683) ve kodlama kuralları (BER, CER, DER, PER, XER, JER vb.) olarak ikiye ayrılıyor
    • BER: temel TLV biçimi, sonsuz uzunluğu destekler
    • CER: BER’in kısıtlı biçimi, her zaman sonsuz uzunluk kullanır
    • DER: BER’in deterministik alt kümesi, kriptografide standart olarak kullanılır
    • PER/OER: bit düzeyinde sıkıştırılmış kodlama
    • XER/JER: XML ve JSON tabanlı kodlama
  • Kodlama türlerinin çokluğu sistemi karmaşıklaştırsa da esneklik ve genişletilebilirlik sağlıyor

ASN.1 gösteriminin karmaşıklığı

  • ASN.1’in temel standardı x.680’dir; genişletme standartları olan x.681~x.683 ise oldukça ağır ve akademik bir üslupla yazılmıştır
  • Yalnızca x.680 ile uygulama yapmak mümkün olsa da anlamsal dönüşüm kuralları ve sözdizimsel varyasyonlar çok olduğu için uygulama zorluğu yüksektir
  • x.681, Information Object Class sistemini tanımlar ve kendine özgü bir başlatma sözdizimini destekler
    • Örnek: CALLED &name [WHO IS &age YEARS OLD]
  • x.682, Table Constraint; x.683 ise şablonlu (Parameterized) tipleri tanımlar
    • Bu, D dilindeki generics’e benzer bir kavramdır; hem tipleri hem de değerleri parametre olarak alabilir

ASN.1’in ilginç özellikleri

  • Constraint sistemi: Tip tanımlarken değer aralığı veya boyut doğrudan belirtilebilir
    • Örnek: UInt8 ::= INTEGER (0..255)
    • SIZE, UNION(|), INTERSECTION(^) işleçlerini destekler
  • Sürüm yönetim sistemi: OBJECT IDENTIFIER ile modül sürümleri açık biçimde ayrıştırılabilir
    • Örnek: id-pkix1-implicit(19) vs id-mod-pkix1-implicit-02(59)
    • Böylece ad çakışması olmadan modüller net biçimde tanımlanabilir

D dilinin kod üretimi için avantajları

  • D’deki static import, ad çakışmalarını önler ve ASN.1 tip adlarını olduğu gibi korumayı mümkün kılar
  • Modül yerel arama (.Type1) özelliği, sembol aramasını açık şekilde sınırlar
  • typeof() sayesinde tipler otomatik çıkarılır; kod üretiminde elle yönetim gerekmez
  • Sondaki virgül (trailing comma) desteği kod üretimini basitleştirir
  • Derleme zamanı sabit birleştirme sayesinde @nogc işlevlerinde bile string birleştirme yapılabilir

D dili özellikleriyle yapılan uygulama örnekleri

Mixin template tabanlı AST düğümleri

  • D’nin mixin template özelliği kullanılarak ASN.1 sözdizim ağacı (AST) düğümleri tanımlanmış
    • Her düğüm tipi (List, Container, OneOf) şablon olarak yeniden kullanılıyor
    • Karmaşık kalıtım yerine derleme zamanında kod kopyalama ile yapı sadeleştiriliyor

Template tabanlı API ve derleme zamanı doğrulama

  • Container düğümü birden çok alt düğüm içeriyor ve derleme zamanında tip doğrulaması yapıyor
    • node.getNode!Asn1TagDefaultNode biçiminde güvenli erişim mümkün
  • OneOf düğümü birden fazla tipten birini tutuyor ve match işleviyle örüntü eşleme destekliyor
    • Tüm tip işleyicilerinin tanımlanması zorunlu olduğu için derleme zamanı güvenliği sağlanıyor

D’nin deneysel bellek yönetimi paketinin kullanımı

  • std.experimental.allocator kullanılarak @nogc ortamında nesne oluşturma ve serbest bırakma gerçekleştirilmiş
    • Region, StatsCollector gibi bileşenlerle özel ayırıcılar oluşturulmuş
    • Ancak bu yapı 10 yıldır hâlâ deneysel durumda

alias this özelliği

  • alias this kullanılarak sarmalayıcı struct’ların iç alan gibi davranması sağlanmış
    • Örnek: cast(Asn1ValueReferenceIr)item biçiminde daha sade cast kullanımı mümkün

version(unittest)

  • version(unittest) anahtar sözcüğüyle yalnızca test için işlevler tanımlanıyor; bunlar gerçek build’e dahil edilmiyor

Template + with() kullanarak test harness’i kurma

  • Ortak test mantığı template hâline getirilmiş ve with() deyimiyle daha kısa test kodu yazılmış
    • Harness.T() yerine T() çağrısı yapılabiliyor

Uygulama sırasında yaşanan başlıca zorluklar

Değer dizisi sözdizimi (Value Sequence Syntax)

  • {} ile başlayan çeşitli değer sözdizimleri bağlama göre belirsizlik taşıyor
    • Ayrıştırıcı yorumlarında “bu eğlenceli değil” denecek kadar karmaşık olduğu belirtiliyor
  • Sözdizimsel analiz ile anlamsal analiz ayrıldığı için işleme zorluğu daha da artmış

Belirtimin açık olmaması

  • Belirli koşullarda etiketin EXPLICIT olarak ele alınması gibi belgede açıkça yazmayan davranışlar bulunuyor
  • Modül sürümleme yöntemi de net biçimde tanımlanmış değil

Constraint’leri üç kez uygulama gereği

  1. Sözdizimi doğrulaması için
  2. Değer geçerliliği doğrulaması için
  3. Çalışma zamanı kod üretimi için
  • UNION, INTERSECTION işlenirken hata mesajlarını oluşturmak da karmaşıklaşıyor

Değişmez IR düğümleri yanılsaması

  • AST’yi IR’ye dönüştürdükten sonra artık değişiklik gerekmeyeceği düşünülmüş
    ancak AUTOMATIC TAGS gibi anlamsal dönüşümlerde veri değişikliği gerekmiş

ASN.1’in baştan sona karmaşıklığı

  • x.509 eski sözdizimini kullandığı için görece basit; ancak modern standartlarda x.681~x.683 uygulaması zorunlu
    • Bu yüzden ASN.1, akademik ve ticari alanlar dışında neredeyse hiç kullanılmıyor

ANY DEFINED BY sorunu

  • ANY DEFINED BY, başka bir alanın değerine göre tipi değişen bir yapı
    • dasn1 bunu uygulamıyor; yerine özel intrinsic Dasn1-Any kullanılıyor
    • Gerçek çözümleme sırasında bunun elle işlenmesi gerekiyor

Bilgi yüklenmesi

  • ASN.1, x.68x, x.690, Juptune gibi birden fazla projeyle aynı anda uğraşmak kod tabanı bağlamını korumayı zorlaştırmış

Derleyici geliştirmenin gerçeği

  • Binlerce düğüm ziyaretçisi, tekrar eden kodlar ve küçük farklarla ayrılan uygulamalar nedeniyle bu iş sıkıcı ve yorucu bir emek gerektiriyor
  • Buna rağmen her aşamada büyük bir tatmin ve öğrenme etkisi var
  • Yazar, “Muhtemelen kimse kullanmayacak ama gerçek bir derleyici deneyimi kazandım” diye anlatıyor
  • Yazı, “ASN.1 ile uğraşmayın, hayatınızı değiştirir” esprisiyle kapanıyor

Sonuç

  • Bir yıllık çalışmaya rağmen dasn1 hâlâ tamamlanmış değil, ancak bu süreç D dilinin potansiyelini ve ASN.1’in karmaşıklığını derinlemesine anlamayı sağlamış
  • Yazar, bir gün özgeçmişine “ASN.1 derleyicisi + TLS 1.3 uygulama deneyimi” yazmayı umarken,
    yazıyı geliştiricinin büyümesi ve sektörün gerçekleri üzerine mizahi bir geri bakışla bitiriyor

1 yorum

 
GN⁺ 2025-10-25
Hacker News görüşleri
  • Özetle ASN.1, D dili ve derleyicinin kendisi hakkında konuşmak istemiş
    Ama tutarlı bir biçim bulamayınca ilgili düşüncelerini toplayıp bir blog yazısı haline getirmiş
    Ortaya çıkan şey çok cilalı değil ama kısa geçilmesi zor bir konu olduğu için anlayış bekliyor

    • Kesişim örneği (intersection example) amaçlandığı gibi çalışmıyor gibi görünüyor
      Matematiksel olarak bakınca {0} ∪ ({2} ∩ {4,5,6,7,8}) = {0} olduğundan sonuçta yalnızca tek bir değere izin veriliyor
    • D dilinden söz açmak biraz da Walter Bright'ı çağırmak gibi
      Ben de D'yi gerçekten seviyorum ama pratikte Go ve Rust çok daha yaygın kullanılıyor
    • Ben de ASN.1 verisiyle çalıştım; özellikle sertifika ile ilgili işler çok acı vericiydi
      Yazarın çektiği sıkıntıyla derinden empati kuruyorum
    • Yazıyı gerçekten keyifle okudum
      D'yi seviyorum ama uzun zamandır elimi sürmemiştim
      Geçmişte parser ve protokol implementasyonu yaptığım için daha da ilgi çekiciydi
    • Sonuçta blog senin kendi alanın; kendi tarzınla devam etmeni isterim
  • “OMG ASN.1” gerçekten görmekten memnun olduğum bir konu
    İnternetin büyüdüğü, IETF'nin protokolleri geliştirdiği dönemi hatırlıyorum
    O zamanlar şirketler internetle ilgilenmiyordu; işi akademi ve IETF sürüklüyordu
    Ama şirketler bunun para getirdiğini fark edince Protocol Wars başladı
    ASN.1, o savaşın bir ürünü ve şirket kültürü ile akademik kültürün çatışmasının bir örneği
    Şirket tarafını “tarif kültürü”, akademiyi ise “işlev kültürü” diye düşünebilirsiniz
    Bu düşünme biçimi farkı bugün yapay zeka geliştirme kültürü için de çıkarımlar sunuyor

    • Bir zamanlar Father of the Bride filmini izlerken X.25 ağ iletişiminden söz edilmesine çok şaşırmıştım
      İşlerin internet yerine “CN=wikipedia, OU=org, C=US” gibi bir adresleme düzenine evrilebileceğini düşünmek bile ürkütücüydü
    • “OMG ASN.1”ı bir sonraki grubumun adı yapmam gerektiğini düşündüm
    • Anlatılanların bir kısmı doğru ama baş aktörü “şirketler” diye tanımlamak biraz isabetsiz
      Aslında merkezde ITU ve ISO vardı
      Sonra 90'ların sonunda bir başka “protokol savaşı” daha yaşandı ve bu kez IETF kaybetti
    • Bu savaş aynı zamanda internetin erken ticarileşme (en-shittification) süreciydi
      ISO mükemmelliği kovalamaktan yavaş kaldı, IETF ise “sonra düzeltiriz” yaklaşımıyla hızlı hareket etti
      Bunun sonucunda protokollerin taşlaşması gibi sorunlar ortaya çıktı
      Ayrıca 1990'larda C için ASN.1 implementasyonlarının berbat olması da ayrı bir problemdi
    • Şirket bakış açısı denilen şeyin özünde mainframe bakış açısı olması kritik nokta
  • Türkçede “Bu insan için yapılmış bir şey değil!” diye bir ifade var
    Bunu tasarım felsefesinin mottosu yapmak isterdim
    Ayrıca Game of Thrones'taki “Hükmü veren kişi kılıcı da kendisi sallamalıdır” sözü gibi,
    spesifikasyonu yazan kişi parser'ı da kendisi implemente etmeli
    Gerçekten çalışan bir parser ve testler de birlikte teslim edilmeden spesifikasyon onaylanmasa kalite muhtemelen çok daha yüksek olurdu

  • D dilini gerçekten seviyorum
    Yalnızca Raylib'e bağlı bir vim tarzı metin editörü yazıyorum
    D'nin güçlü yanları şunlar

    • Her yerde unit test yazılabiliyor
    • version(unittest) bloklarıyla yalnızca test amaçlı kodu yönetmek kolay
    • enum, union, assert, sözleşmeli programlama gibi dil özellikleri harika
      Belgeleri okuyunca ya da ChatGPT'ye sorunca hep zarif bir çözüm bulabildim
    • D benim için tatlı-acı bir dil
      Tasarım felsefesi açısından neredeyse kusursuz ama araçları ve ekosistemi Rust veya Go düzeyinde olsaydı çok daha başarılı olabilirdi
    • D'nin özellikleri iyi ama dil giderek gürültülü (noisy) hale geliyor
      Phobos standart kütüphanesinde çok fazla küçük can sıkıntısı vardı, sonunda bıraktım
      Yeni sürüm Phobos V3 üzerinde çalışılıyor ama insan kaynağı az olduğu için hem umutluyum hem tedirginim
  • “ASN.1'in karmaşık olduğunu söylediğim oldu mu?”
    Hem şema hem veri biçimi karmaşık ama bunun büyük kısmı göz ardı edilebilir bir karmaşıklık
    Ben ASN.1 şema gösterimini kullanmadım; onun yerine doğrudan C ile bir DER implementasyonu yazdım
    Standart kodlamalar içinde işe yarar olanın yalnızca DER olduğunu düşünüyorum
    Ayrıca DSER, SDSER ve TER gibi kendi kodlama biçimlerimi de yaptım
    ANY DEFINED BY gibi yapıları hâlâ faydalı biçimde kullanıyorum
    Verimli kodlama için OBJECT IDENTIFIER RELATIVE TO adında standart dışı bir özellik bile ekledim

  • Ben de bir ASN.1 derleyicisi yazdım
    X.681~X.683'ün yalnızca bazı özelliklerini implemente ettim ama tek bir codec çağrısıyla tüm sertifikayı özyinelemeli olarak decode edebiliyordu
    ASN.1 basit bir sözdiziminden ibaret değil, güçlü bir tür sistemi
    Hak ettiği değeri görmüyor ama gerçekten çok havalı bir teknoloji

  • Bir zamanlar Swift için bir ASN.1 derleyicisi yapmıştım
    ASN1Codable projesiydi; Heimdal'in libasn1 kütüphanesini kullanarak
    ASN.1'i JSON AST'ye dönüştürüp parse etmeyi basitleştirmiştim

    • libasn1'in README'sinde ASN.1'e karşı gizli bir nefret hissediliyor
      “Bunu JSON'a çevirelim” demek, incinmiş bir geliştiricinin çığlığı gibi geliyor 😄
  • Garip şekilde ASN.1 ile uğraşmak eğlenceli geliyor
    Bir gün Rust için kendi ASN.1 derleyicimi yazmak istiyorum
    Şu anki Rust implementasyonlarının çoğu derive makroları ya da elle zincirleme yaklaşımına dayanıyor; bu biraz hayal kırıklığı yaratıyor

  • Genel olarak bir standardı implemente ederken işin %80'ini zamanın %20'sinde tamamlarsınız ama
    ASN.1'in kalan %20'si bir ömür sürebilir

  • Bir zamanlar Netscape kod tabanındaki ASN.1 parser'ını genişletip PKCS#12 desteği eklemiştim
    RSA standardını ve ASN.1 tanımlarını gereğinden fazla iyi öğrenmiş olmaktan pişmanım ama
    blog yazarının azmine ve biraz da mazoşizmine saygı duyuyorum

    • O deneyimden gerçekten savaş hikâyesi gibi geliştirme anıları çıkmıştır