openssl ca: תאריך פקיעה לא חוקי ב-index.txt ואיך לתקן אותו
ה-CA מסרב להנפיק כי שורה אחת ב-index.txt אינה ניתנת לניתוח. העתיקו את מצב ה-CA, פענחו את הרשומה ואז תיאמו אותה עם התעודה החתומה.
ריצת הנפקה נעצרת עם entry 22: invalid expiry date, והבקשה שלפניכם תקינה לחלוטין. התלונה מגיעה ממנתח מסד הנתונים של ה-CA, לא מה-CSR ולא מלקוח ה-VPN שיציג בסופו של דבר את התעודה. ההבחנה הזו קובעת את כל מה שאחריה: רשומה פגומה, ולכן התיקון שייך למצב ה-CA ולא לבקשה או לתצורת העמית. התייחסו לרשומה הממוספרת כאל שורה ב-index.txt, והבעיה מצטמצמת לשאלת נתונים תחומה עם תשובה ניתנת לבדיקה.
קראו את השגיאה כתלונה על מסד הנתונים
כל openssl ca קריאה עוברת על מסד הנתונים הטקסטואלי שלה לפני שהיא חותמת על משהו. כל שורה מכילה אות סטטוס, חותמת זמן פקיעה, חותמת ביטול אופציונלית, מספר סידורי בהקסדצימלי, שם קובץ והנושא. כששדה אחד אינו ניתן לניתוח, הפקודה מדווחת את מספר השורה ועוצרת במקום לנחש את שאר הרשומה.
העצירה הזו מגנה ולא קפדנית. רשומה שהכלי אינו יכול לקרוא משאירה אותו בלי יכולת להחליט אם הנושא המבוקש כבר קיים, אם הוקצה מספר סידורי, או מה צריכה להכיל רשימת הביטולים הבאה. המשך מעבר לשורה פגומה היה יוצר בדיוק את חוסר העקביות השקט שמציץ חודשים אחר כך, בדרך כלל בזמן ביטול שאיש אינו יודע להסביר. קראו את ההודעה כתלונה על הנתונים, והחקירה נשארת בתוך ספריית ה-CA.
העתיקו את מצב ה-CA לפני שנוגעים במשהו
צלמו את כל ספריית ה-CA, לא רק את קובץ מסד הנתונים. האינדקס, קובץ התכונות שלו, קובצי המספר הסידורי ומספר רשימת הביטולים, המפתח הפרטי והתעודות שהונפקו כולם משתתפים בפעולות מאוחרות יותר, ותיקון שמשחזר אחד ומפספס את האחרים יוצר תקרית שנייה. השתמשו בשגרת הגיבוי של ה-CA עצמו כשהיא קיימת, והשהו את ההנפקה המתוזמנת למשך העבודה.
רשמו את גרסת ה-OpenSSL ואת קובץ התצורה שהפקודה שנכשלה טענה בפועל. התקנות שומרות לעתים קרובות יותר מספריית CA אחת, והשגיאה מקבלת משמעות רק מול מסד הנתונים שהתצורה הנבחרת מציינת.
מצאו את הרשומה ופענחו את שדה התאריך שלה
מספר השורה המדווח נספר מהרשומה הראשונה, ולכן sed -n '22p' index.txt נוחת על הרשומה הבעייתית לאחר שתאשרו שאין מעליה שורות ריקות או הערות. הדפיסו את השורה הזו עם מפרידים גלויים, כי טאבים ורווחים בסוף נפוצים ואינם נראים בחלון עורך רגיל.
שדה הפקיעה הוא חותמת זמן שרוחבה תלוי בשנה. ערכים עד 2049 נכתבים ב-UTCTime בתור YYMMDDHHMMSSZ, בעוד שערכים מאוחרים יותר עוברים ל-GeneralizedTime עם שנה בת ארבע ספרות. רשומה שמערבבת בין שתי הצורות, או שנושאת שנה בת שתי ספרות במקום שבו המנתח מצפה כעת לארבע, נכשלת בדיוק בנקודה הזו. כך גם שדה קטוע שהותיר כתיבה שנקטעה.
השוו את הרשומה לתעודה שהיא מפנה אליה ולא לקובץ של CA אחר. התעודה החתומה היא הסמכות לגבי מה שהתוקף אמור לומר, והיא כבר קיימת כאובייקט שניתן לניתוח.
תקנו את הרשומה לפי התעודה החתומה
קראו את התאריכים האמיתיים עם openssl x509 -in issued.pem -noout -dates -serial -subject. המירו את notAfter לרוחב החותמת שהבילד שלכם כותב לאותה שנה, ואשרו שהמספר הסידורי תואם לרשומה שאתם עומדים לערוך לפני שתשנו תו אחד.
ערכו רק את השדה השבור, שמרו על אות הסטטוס ועל המספר הסידורי, והניחו לשאר השורה. אם לא ניתן ליישב את הרשומה עם שום תעודה חתומה, התייחסו אליה כרשומה תועה והוציאו אותה דרך נתיב הביטול של ה-CA במקום למחוק את השורה ביד.
אל תתקנו על ידי קיצוץ תאריך כדי שיתאים לניחוש לגבי השנה. חיתוך של שני תווים אינו נייד בין בילדים, והוא משנה בשקט את התוקף שמסד הנתונים מדווח לבדיקות נושא כפול ורשימת ביטולים עתידיות. כשהערך המקורי אינו ניתן לשחזור, הנפיקו מחדש תחת מספר סידורי חדש ורשמו מדוע נזנח הישן. שרשרת הביקורת היא חלק מהתיקון, לא ניירת מסביבו.
אמתו הנפקה ויצירת רשימת ביטולים לפני שאתם הולכים
הריצו הנפקה אחת עם אותה תצורה ואשרו שהיא מסתיימת בלי תלונה על מספר שורה. לאחר מכן צרו רשימת ביטולים עם openssl ca -gencrl -config openssl.cnf ובדקו שהיא ניתנת לניתוח, כי רשומה פגומה מציצה לעתים קרובות דווקא שם ולא בזמן החתימה.
בדקו את התעודה החדשה עם openssl x509 -noout -dates -serial והשוו אותה לשורה שה-CA זה עתה כתב. אשרו שאות הסטטוס ותאריך הפקיעה תואמים לתעודה, ואשרו ש-openssl verify -CAfile ca.pem issued.pem חוזרת בלי שגיאה. לאחר מכן שחזרו את ההנפקה המתוזמנת וצפו בריצה הראשונה, כי שורה פגומה שנייה תודיע על עצמה מיד.