บนแพลตฟอร์ม Apple ลูกค้าไม่ตรวจสอบรายการเพิกถอนใบรับรอง (CRL) ของ CA และไม่ใช้ OCSP ตามค่าเริ่มต้น
อย่างไรก็ตามแพลตฟอร์มของ Apple สนับสนุนการเย็บเล่ม OCSP และยังมีกลไกที่เรียกการปรับปรุงการเพิกถอนซึ่งอาจนำไปสู่การโทร OCSP ได้อย่างแท้จริงดูรายละเอียดด้านล่าง
OCSP Stapling
การอธิบายครั้งแรกของการเย็บเล่ม OCSP:
การเย็บเล่มสถานะใบรับรองออนไลน์ (OCSP)ออนไลน์หรือที่รู้จักกันอย่างเป็นทางการว่าเป็นส่วนขยายคำขอสถานะใบรับรอง TLSเป็นมาตรฐานสำหรับการตรวจสอบสถานะการเพิกถอนใบรับรองดิจิทัล X.509 1ช่วยให้ผู้นำเสนอใบรับรองแบกรับต้นทุนทรัพยากรที่เกี่ยวข้องในการตอบสนองออนไลน์โพรโทคอลสถานะโพรโทคอลการรับรอง (OCSP) โดยการผนวก ("เย็บเล่ม") การตอบสนอง OCSP ประทับเวลาลงนามโดย CA เพื่อจับมือ TLS เริ่มต้น สำหรับลูกค้าที่จะติดต่อ CA โดยมีวัตถุประสงค์เพื่อปรับปรุงความปลอดภัยและประสิทธิภาพ
ดูhttps://en.wikipedia.org/wiki/OCSP_stapling
ความแตกต่างระหว่าง OCSP และ OCSP Stapling
หากไคลเอนต์เชื่อมต่อกับเซิร์ฟเวอร์ในโฟลว์ OCSP ดั้งเดิมและดึงข้อมูลใบรับรองตรวจสอบว่าใบรับรองที่ได้รับนั้นถูกเพิกถอนโดยทำการร้องขอไปยัง CA หรือไม่ นี่มีข้อเสียบางอย่างเช่นจำเป็นต้องมีการเชื่อมต่อเครือข่ายเพิ่มเติมข้อมูลไม่ได้เข้ารหัสและดังนั้นจึงแสดงถึงปัญหาความเป็นส่วนตัวของข้อมูล
ผ่านการเย็บเล่ม OCSP เซิร์ฟเวอร์ร้องขอข้อมูลการเพิกถอนที่ลงนามจาก CA และเพิ่มลงในการจับมือ TLS
นอกจากนี้ยังหมายถึงเมื่อใช้การเย็บเล่ม OCSP คุณไม่เห็นคำขอ OCSP จาก iOS ไปยังเซิร์ฟเวอร์ CA
ข้อเสียของการเย็บ OCSP
เซิร์ฟเวอร์ที่คุณกำลังเชื่อมต่อจะต้องสนับสนุนการเย็บเล่ม OCSP สิ่งนี้ไม่ได้ป้องกันเซิร์ฟเวอร์ที่เป็นอันตราย
นี่คือเหตุผลหลักที่ Apple ให้การปรับปรุงการเพิกถอน
การปรับปรุงการเพิกถอนของ Apple
นี่คือวิธีการทำงาน:
- รายการบันทึกความโปร่งใสของใบรับรองจะถูกรวบรวมโดย Apple
- ด้วยข้อมูลนี้ Apple จะรวบรวมข้อมูลเกี่ยวกับการเพิกถอนจาก CA
- ข้อมูลที่รวบรวมนี้จะถูกเปิดเผยโดยอัตโนมัติให้กับลูกค้าของ Apple ทุกเครื่องเป็นประจำ
- ตามข้อมูลนี้เมื่อแอป iOS พยายามเชื่อมต่อกับเซิร์ฟเวอร์ที่มีใบรับรองที่ถูกเพิกถอนจะทำการตรวจสอบเพิ่มเติมผ่าน OCSP
ความต้องการ
ข้อกำหนดเพียงอย่างเดียวสำหรับแอปที่ให้การสนับสนุนนี่คือการเพิ่มใบรับรองเซิร์ฟเวอร์ที่ใช้ในบันทึกความโปร่งใสของใบรับรอง โดยปกติ CA ทำเช่นนั้นแล้ว แต่คุณควรตรวจสอบว่าใบรับรองโดเมนอยู่ในบันทึกความโปร่งใสที่ใช้งานอยู่สำหรับใบรับรองสาธารณะเช่นโดยใช้ลิงก์ต่อไปนี้: https://transparencyreport.google.com/https/certificates
WWDC 2017 เซสชัน 701
มีเซสชัน WWDC ที่ยอดเยี่ยมที่มีการอธิบายหัวข้อและแรงจูงใจของ Apple ในรายละเอียด: WWDC 2017, เซสชัน 701: https://developer.apple.com/videos/play/wwdc2017/701/
ประมาณ 12:10 น. วิศวกรของ Apple จะอธิบายหัวข้อการเพิกถอนทั้งหมดอย่างละเอียด เมื่อเวลาประมาณ 15:30 น. เธออธิบายว่า OCSP ปกติจะต้องใช้ API เพิ่มเติม
ทดสอบการเย็บ OCSP บน iOS
สำหรับการทดสอบเราต้องการเซิร์ฟเวอร์ที่รองรับการเย็บเล่ม OCSP และใช้ใบรับรองที่ถูกเพิกถอน: https://revoked.grc.com
(พบเซิร์ฟเวอร์นี้ในคำตอบข้อผิดพลาดเซิร์ฟเวอร์นี้: https://serverfault.com/a/645066 )
จากนั้นเราสามารถลองเชื่อมต่อจาก iOS ด้วยโปรแกรมทดสอบขนาดเล็กที่พยายามดาวน์โหลดการตอบสนอง HTML และส่งออกไปยังคอนโซล
ตามข้อมูลจากเซสชัน WWDC ที่กล่าวถึงข้างต้นความพยายามในการเชื่อมต่อควรล้มเหลว
...
let session = URLSession(configuration: .default)
...
func onDownloadAction() {
let url = URL(string: "https://revoked.grc.com")!
self.download(from: url) { (result, error) in
if let result = result {
print("result: " + result)
} else {
print("download failed")
if let error = error {
print("error: \(error)")
}
}
}
}
func download(from url: URL, completion: @escaping(String?, Error?)->Void) {
let dataTask = self.session.dataTask(with: url) { data, response, error in
guard let data = data else {
if let error = error {
completion(nil, error)
return
}
completion(nil, NSError(domain: "DownloadFailure", code: 0, userInfo:nil))
return
}
guard let response = response as? HTTPURLResponse else {
completion(nil, NSError(domain: "ResponseFailure", code: 0, userInfo:nil))
return
}
print("http status: \(response.statusCode)")
let res = String(bytes: data, encoding: .utf8)
completion(res, nil)
}
dataTask.resume()
}
หากเราดำเนินการตามขั้นตอนข้างต้นใน iOS Simulator เราสามารถใช้ Wireshark เพื่อตรวจสอบว่าการตอบสนอง OCSP แบบประทับเวลาที่ลงนามโดย CA นั้นได้รับการเย็บเล่มไปยัง TLS handshake หรือไม่
ด้วยการnslookup revoked.grc.com
ที่เราได้รับที่อยู่ IP ของเซิร์ฟเวอร์และสามารถกรองใน Wireshark ip.addr==4.79.142.205
กับ
revoked
ในภาพหนึ่งจะเห็นว่าใบรับรองมีสถานะ
ดังนั้นการดูในคอนโซล Xcodes สามารถเห็นผลลัพธ์ต่อไปนี้:
2019-10-12 21:32:25.734382+0200 OCSPTests[6701:156558] ATS failed system trust
2019-10-12 21:32:25.734526+0200 OCSPTests[6701:156558] Connection 1: system TLS Trust evaluation failed(-9802)
2019-10-12 21:32:25.734701+0200 OCSPTests[6701:156558] Connection 1: TLS Trust encountered error 3:-9802
2019-10-12 21:32:25.734787+0200 OCSPTests[6701:156558] Connection 1: encountered error(3:-9802)
2019-10-12 21:32:25.737672+0200 OCSPTests[6701:156558] Task <12408947-689F-4537-9642-C8F95E86CA62>.<1> HTTP load failed, 0/0 bytes (error code: -1200 [3:-9802])
download failed
error: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x6000037f8510>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<cert(0x7fda78828200) s: revoked.grc.com i: DigiCert SHA2 Secure Server CA>",
"<cert(0x7fda7882b200) s: DigiCert SHA2 Secure Server CA i: DigiCert Global Root CA>"
), NSUnderlyingError=0x600000be9170 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x6000037f8510>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7fda78828200) s: revoked.grc.com i: DigiCert SHA2 Secure Server CA>",
"<cert(0x7fda7882b200) s: DigiCert SHA2 Secure Server CA i: DigiCert Global Root CA>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://revoked.grc.com/, NSErrorFailingURLStringKey=https://revoked.grc.com/, NSErrorClientCertificateStateKey=0}
iOS ยกเลิกการพยายามเชื่อมต่อกับเซิร์ฟเวอร์ด้วยข้อผิดพลาด TLS
ทดสอบ revoked.badssl.com
revoked.badssl.com ไม่รองรับการเย็บเล่ม OCSP
หากเราดูรายละเอียดใบรับรองของhttps://revoked.badssl.comเราสามารถค้นหา:
หากมีใครดาวน์โหลดไฟล์. crl (2.5MB) และออก
openssl crl -inform DER -text -in ssca-sha2-g6.crl | grep 0371B58A86F6CE9C3ECB7BF42F9208FC
จะเห็นได้ว่าใบรับรองนี้ถูกเพิกถอนผ่าน CRL
น่าสนใจไม่ว่า Safari หรือ Chrome หรือ iOS จะไม่รับรู้สถานะที่ถูกเพิกถอนนี้ Mozilla Firefox เท่านั้นที่แสดงข้อความแสดงข้อผิดพลาด ( เพิกถอนใบรับรองของเพื่อนแล้วรหัสข้อผิดพลาด: SEC_ERROR_REVOKED_CERTIFICATE )
สาเหตุอาจเป็นเพราะใบรับรองได้รับการต่ออายุเพียงไม่กี่วันที่ผ่านมาและยังไม่พบวิธีในการเพิกถอนรายการเบราว์เซอร์และระบบปฏิบัติการในท้องถิ่นทั้งหมด