الخلاصة

  • تحظر RFC 6487 وجود authorityCertIssuer وauthorityCertSerialNumber داخل Authority Key Identifier في شهادات موارد RPKI، بينما تعرفهما RFC 5280 كعضوين اختياريين في صيغة X.509 العامة.
  • ربط التحديث 994a598 في Barry حقل authorityCertIssuer بمحلل GeneralNames لا يقبل إلا مصفوفة. وفي اليوم التالي استبدل Rapport في b1a59a السلسلة القديمة بمصفوفة تحوي rfc822Name واحداً، وصحح رسالة FORT المنتظرة.
  • يشغّل البرنامج Barry ثم المدقّق المختار، ويفحص السجل، وأخيراً يقارن VRP بمجموعة فارغة. يثبت المصدر ترتيب النية، لكنه لا يقدم سجل تنفيذ عاماً أو شهادة مولدة ومفككة أو نتيجة مرتبطة بإصدار.
  • يسرد Rapport أربعة مدقّقات قابلة للاختيار، إلا أن فحص الرسالة التي تسمي الحقل لا يعمل في هذه الحالة إلا مع fort2. أما الفراغ في المخرجات فيثبت أثراً ولا يحدد سببه دائماً.

على الاختبار السلبي أن يثبت ما صنعه

القاعدة محددة. تربط إضافة Authority Key Identifier الشهادة بالمفتاح العام للجهة المصدرة. تفرض RFC 6487 وجودها في شهادات الموارد باستثناء الشهادة ذاتية التوقيع، وتجعلها غير حرجة، وتمنع الحقلين authorityCertIssuer وauthorityCertSerialNumber. أما RFC 5280 العامة فتدرج الحقلين كعضوين اختياريين وتطلب حضورهما معاً إن استُخدما. بذلك يضيّق ملف RPKI مساحة تسمح بها البنية الأساسية لـX.509.

يبدو اختبار هذه القاعدة بسيطاً: أنشئ شهادة سلطة تصديق تحوي العضو الممنوع، وضع ROA تحتها، ثم تحقق من أن المدقّق لا يصدّر حمولة أصل مسار. لكن كلمة «أنشئ» هي نقطة التحكم الأولى. إذا عجز مولّد المستودع عن قراءة الوصف، أو أسقط الحقل، أو توقف قبل كتابة الشهادة، فلن يرى المدقّق الحالة المقصودة. قد تظهر النتيجة المتوقعة — صفر VRP — من دون أن يكون سلوك المدقّق قد اختُبر أصلاً.

لهذا صُمم Barry. قدمته LACNIC في 2025 أداةً تنشئ مستودعات RPKI صحيحة أو متعمدة الخطأ من وصف مفتاح-قيمة. ثم يمرر Rapport المستودع إلى relying party ويفحص مخرجاته. تتيح البنية تكرار حالات حدودية معقدة، لكنها تجعل المولّد نفسه جزءاً من الدليل.

لماذا لا تكفي سلسلة نصية لـGeneralNames

في 1 سبتمبر 2026 أضاف تحديث Barry 994a598321336baf1767f0fbfb460ed96c29fe4f دعم authorityCertIssuer. يربط ext.c الحقل بالنوع الداخلي ft_gnames. وفي field.c يشترط parse_gnames أن تكون القيمة مجموعة أو مصفوفة، ويعد عناصرها، ويخصص GeneralName من ASN.1 لكل عنصر، ثم يحلل كل عنصر ككائن. إذا لم تكن القيمة مصفوفة ينتقل التنفيذ إلى مسار خطأ يطلب الأقواس المربعة.

يشرح اختبار Barry الوظيفي الجديد العقد عملياً. فالمصفوفة تجمع rfc822Name وعنوان IP وregisteredID. ليست هذه وصفة لشهادة موارد متوافقة؛ إنها برهان على الأشكال التي يستطيع المولّد ترميزها داخل GeneralNames.

كانت نسخة Rapport السابقة تستخدم authorityCertIssuer = "CN=Fake Issuer"، أي سلسلة مفردة لا مصفوفة. المقارنة مع المحلل الحالي تسمح باستنتاج محدود: شكل البيانات القديم لا يطابق عقد parse_gnames الحالي. لا تسمح بالجزم بأن تشغيلًا تاريخياً بعينه فشل، ولا بأن نسخة أقدم من Barry تصرفت بالطريقة نفسها. لا تتضمن المصادر سجلاً لذلك التشغيل أو بصمة للملف التنفيذي.

في 2 سبتمبر صحح Rapport الحالة في التحديث b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c. أصبحت القيمة مصفوفة من عنصر واحد نوعه rfc822Name، وقيمته نص عنوان توضيحي. ليس مطلوباً أن يبدو العنوان اسماً واقعياً لجهة إصدار؛ فملف RPKI يحظر العضو كله. المهم أن المخالفة صارت مكتوبة بصيغة يستطيع Barry معالجتها.

كان فحص السجل يشير إلى عضو مختلف

قبل التصحيح، بحث run.sh في سجل FORT عن رسالة تتعلق بـauthorityCertSerialNumber، بينما حاولت الحالة إدخال authorityCertIssuer. بعد b1a59a صارت الرسالة المتوقعة تسمي issuer. يصلح ذلك وصلة ثانية في البرهان: حتى لو صُنعت المخالفة الصحيحة، فإن نسبة الرفض إلى حقل آخر تشوه النتيجة.

يكشف ترتيب السكربت مراحل الدليل. يأتي run_barry أولاً، ثم run_rp، ثم check_logfile، وأخيراً check_vrps. في تشغيل قابل للتدقيق ينبغي أن تترك كل مرحلة وصلاً مستقلاً: نسخة Barry وبصمة الملف التنفيذي وحالة الخروج؛ hash للشهادة وفكاً لإضافة AKI؛ اسم المدقّق وإصداره وإعداده ومرساة الثقة؛ إشارة الرفض؛ ثم بصمات مجموعتي VRP المتوقعة والفعلية.

لا تعرض الواجهة العامة التي جُمّدت لهذه القراءة هذه الحزمة. يسجل GitHub صفراً من check runs للتحديث، ولا يظهر في مستودع Rapport tag أو release. لا يثبت هذا أن المطورين لم يختبروا محلياً أو في نظام خاص. إنه يحدد ما لا يستطيع قارئ خارجي ادعاءه: لا يجوز تحويل تصحيح في المصدر إلى نتيجة منفذة وقابلة لإعادة الإنتاج ومربوطة بإصدار من دون أثر إضافي.

الفراغ نتيجة لا تشخيص

ينشئ check_vrps الملف المتوقع من المعاملات التي يتلقاها. تستدعيه هذه الحالة بلا معاملات، فيكون المتوقع فارغاً. بعد ذلك يحول خرج CSV إلى صيغة مشتركة ويرتبه ويقارنه بالملف الفارغ. نجاح المقارنة يثبت أن المدقّق لم يخرج أي VRP في ذلك المسار.

هذه النتيجة ضرورية لأن المستودع يضع ROA تحت شهادة CA المشوهة. لكن طرقاً كثيرة تنتهي إلى الفراغ نفسه: رفض صحيح للـAKI، فشل في جلب المستودع، عيب آخر في السلسلة، مرساة ثقة غير صحيحة، أو توقف Barry قبل تقديم الكائن. لا يختار الملف الفارغ سبباً من هذه الأسباب من دون إثبات البناء وسجل التنفيذ.

توجد لدى FORT إشارة إضافية. يستدعي السكربت check_logfile fort2، ولا يفحص helper السجل إلا عندما تطابق قيمة RP الاسم الأول؛ وإلا فإنه يرجع مباشرة. لذلك فإن الرسالة الدقيقة التي تسمي authorityCertIssuer خاصة بفرع FORT 2 في هذا الاختبار.

مع ذلك يسرد README المثبت عند التحديث أربعة محددات: fort2 وroutinator وrpki-client وrpki-prover، ويستهدف كل تشغيل واحداً منها. أربعة adapters لا تعني أربعة أدلة متماثلة في كل حالة. تستطيع الفروع الأخرى مقارنة مخرجات VRP بالفراغ، لكن المصدر لا يبين assertion خاصاً بكل مدقّق يسمي الحقل المحظور.

بدلاً من مربع أخضر واحد، ثلاث خانات

على مصفوفة المطابقة المفيدة أن تفصل الإنشاء عن القرار عن المخرجات. في خانة الإنشاء توضع نسخة Barry وبصمته وhash الحالة وحالة الانتهاء والشهادة وفك AKI. وفي خانة القرار يوضع المدقّق وإصداره وإعداده وTAL وكود رفض أو تشخيص مستقر. وفي خانة المخرجات توضع بصمات المتوقع والفعلي. بعد ذلك فقط يمكن تلخيص الصف بلون.

ليست كل المشاريع ملتزمة بنص سجل ثابت. ولا ينبغي لسويتة محمولة أن تفرض جملة واحدة على الجميع. قد يكفي كود منظم، أو فئة خطأ خاصة بالمنتج، أو عبارة محدودة مثل «لم تُقبل حمولة». تأتي قابلية المقارنة من دقة ما تدعيه كل خانة، لا من تشابه الواجهات ظاهرياً.

هناك أيضاً ثلاثة أوضاع نضج مختلفة: اختبار موجود في المصدر، اختبار منفذ ضد build معروف، ونتيجة منشورة ضمن إصدار محدد. الأول يسمح بمراجعة التصميم؛ الثاني يضيف البيئة والآثار؛ الثالث يربط النتيجة ببرنامج يمكن للمشغل تنزيله. دمجها في «نجح» يجعل فرعاً متحركاً يبدو ضمانة ثابتة.

الشهادة المفكوكة هي الجسر الناقص

أصغر أثر إضافي يزيل أكبر قدر من الغموض هو الشهادة التي أنشأها Barry مع فك مستقل لإضافة AKI. يبين fixture ما أراد كاتب الاختبار إدخاله، ويبين parser شكل البيانات الذي يقبله البرنامج، لكن ملف DER وحده يبين البايتات التي أمكن أن تصل إلى المدقّق. إذا حُفظ hash الشهادة ونسخة أداة الفك والحقول المرئية معاً، تصبح النية مرتبطة بكائن ملموس.

يفصل هذا الأثر كذلك بين «اكتسب Barry قدرة جديدة» و«استخدم Rapport تلك القدرة في تشغيل بعينه». يضيف 994a598 ربط الحقل ومحلل GeneralNames واختباراً وظيفياً، وتتفق مصفوفة b1a59a مع هذا العقد. ومع ذلك، لا يثبت المصدر وحده أي binary اختاره runner، ولا أن إعداداً لم يغير المسار، ولا أن الشهادة نفسها وُضعت في المستودع المقدم. اتساق المصدر شرط، لكنه ليس هوية تشغيلية كاملة.

لا يلزم أن يكون الوصل ضخماً. يكفي manifest صغير قابل للقراءة آلياً يضم hash ملف الوصف، وتحديث Barry وبصمة binary، وقائمة الكائنات الناتجة، وإصدار المدقّق، ووقت البداية والنهاية، وحالات الخروج، وفئة التشخيص، وبصمات VRP المتوقعة والفعلية. ربطه بمهمة CI أو release يجعله أكثر ثباتاً من صورة شاشة لسجل قد تتغير صياغته.

وينبغي أن يسجل الوصل مسار النقل أيضاً. قد يقدم Rapport المستودع عبر rsync أو RRDP وفق إعداد التشغيل. الفشل في جلب المستودع ورفض شهادة جرى جلبها فعلاً يمكن أن ينتهيا إلى المجموعة الفارغة نفسها، لكنهما لا يختبران الخاصية نفسها. ذكر البروتوكول وحالة الطلبات واكتمال دورة التحقق يفصل خطأ التوفر عن خطأ الإنشاء وعن قرار التشفير.

هذا الفصل يفيد مقارنة المنتجات من دون فرض واجهة موحدة. يمكن لكل مدقّق الاحتفاظ بلغته التشخيصية، بينما تتفق المصفوفة على نقاط قابلة للمقارنة: هل وصل الكائن، هل اكتملت الدورة، هل قُبلت الحمولة، وما الحد الأقصى الذي يثبته الدليل. بذلك يصبح الاختلاف في التفاصيل معلومة، لا فراغاً يملؤه التقرير بتخمين.

وعند إعادة الاختبار بعد ترقية أي مكوّن، يكشف اختلاف البصمات ما إذا كانت المقارنة ما تزال بين المدخلات نفسها. فإذا تغيرت الشهادة، ينبغي تسجيل النتيجة كسيناريو جديد لا كاستمرار صامت للسطر القديم.

يتيح هذا التقسيم استخدام كل دليل في القرار المناسب. وجود الاختبار في المصدر يبين نطاق التغطية المقصود؛ تشغيله على النسخة المرشحة يدعم قرار الترقية؛ والنتيجة المربوطة بإصدار تدعم المراجعة اللاحقة. لا ينبغي لأي طبقة أن تنتحل وظيفة الطبقتين الأخريين.

وصفت LACNIC في ديسمبر 2025 Barry وRapport بأنهما في مرحلة مبكرة، وركزت آنذاك على FORT. أما README اللاحق فيسمي أربعة مدقّقات. القراءتان تسجلان تطوراً زمنياً. لا يصح استخدام المقال القديم لنفي القدرة الحالية، ولا استخدام القائمة الحالية لاختلاق نتائج تاريخية متساوية.

الخلاصة الأقوى اليوم متواضعة عمداً. اكتسب Barry آلية ترميز authorityCertIssuer. وعدّل Rapport شكل الحالة واسم تشخيص FORT ليتوافقا مع الحقل المقصود. صار تعريف الاختبار أكثر سلامة. لكن الأدلة العامة لا تشهد بأنه نجح على FORT أو على المدقّقات الثلاثة الأخرى.

المصادر

  1. مدونة LACNIC، “Open-Source Projects at LACNIC”: https://blog.lacnic.net/en/open-source-projects-lacnic/
  2. تحديث Barry 994a598: https://github.com/LACNIC/barry/commit/994a598321336baf1767f0fbfb460ed96c29fe4f
  3. محلل Barry وربط الحقل: https://github.com/LACNIC/barry/blob/994a598321336baf1767f0fbfb460ed96c29fe4f/src/field.c و https://github.com/LACNIC/barry/blob/994a598321336baf1767f0fbfb460ed96c29fe4f/src/ext.c
  4. حالة GeneralNames الوظيفية: https://github.com/LACNIC/barry/blob/994a598321336baf1767f0fbfb460ed96c29fe4f/test/functional/tests/gnames.rd
  5. تحديث Rapport المصحح b1a59a: https://github.com/LACNIC/rapport/commit/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c
  6. الحالة والـrunner بعد التصحيح: https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/rd و https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/run.sh
  7. أدوات الفحص وREADME: https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/tools/checks.sh و https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/README.md
  8. RFC 6487: https://www.rfc-editor.org/rfc/rfc6487.html
  9. RFC 5280: https://www.rfc-editor.org/rfc/rfc5280.html
  10. الحالة والـrunner قبل التصحيح في التحديث 69da5fe: https://github.com/LACNIC/rapport/blob/69da5fe98cf09594fc009f4151a84368c08489ba/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/rd و https://github.com/LACNIC/rapport/blob/69da5fe98cf09594fc009f4151a84368c08489ba/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/run.sh
  11. الملفات التي غيّرها تحديث التصحيح b1a59a: https://github.com/LACNIC/rapport/commit/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/checks
  12. سجل مسار الحالة على main: https://github.com/LACNIC/rapport/commits/main/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/rd
  13. علامات Rapport وإصداراته: https://github.com/LACNIC/rapport/tags و https://github.com/LACNIC/rapport/releases