x509Chain.build gagal, certutil -verify lolos

Saya memiliki sertifikat root dan daun. Daun tersebut memiliki ekstensi OID URL CRL yang menunjuk ke lokasi online yang valid. Melakukan ini:

certutil -verify .\leaf.cer

gagal dengan

KESALAHAN: Memverifikasi status pencabutan sertifikat daun dikembalikan Fungsi pencabutan tidak dapat memeriksa pencabutan karena server pencabutan sedang offline. 0x80092013 (-2146885613 CRYPT_E_REVOCATION_OFFLINE)

Jika saya melakukan ini:

certutil -verify .\leaf.cer .\root.cer

Kemudian verifikasi lolos, dan saya melihat CRL ditarik dari online di Fiddler.

Dalam kode C# saya, saya melakukan ini:

X509Chain childCertChain = new X509Chain();
childCertChain.ChainPolicy.ExtraStore.Add(rootCert);
childCertChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
childCertChain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(10);
if (!childCertChain.Build(childCert))
        {
            // The root cert is not in the windows certificate store, that is fine
            if (childCertChain.ChainStatus.Length != 1 || childCertChain.ChainStatus.First().Status != X509ChainStatusFlags.UntrustedRoot)
            {
                throw new Exception("Certificate validation error.");
            }
        }

Ini akan menjadi pengecualian saya, dan meskipun chainElements akan diisi dengan 2 sertifikat dengan benar, ChainStatus akan menampilkan:

OfflineRevocation, RevocationStatusTidak Diketahui

Saya juga tidak akan melihat permintaan web apa pun di Fiddler. Saya dapat mengunduh CRL secara terprogram dengan memberikan URL-nya sehingga ini bukan lingkungan debug saya AFAIK. Adakah ide bagaimana agar x509Chain.Build berhasil?


person serkan    schedule 08.04.2020    source sumber
comment
Berapa banyak elemen yang Anda dapatkan di chain.ChainElements?   -  person Crypt32    schedule 08.04.2020
comment
ia memiliki 2 elemen, sehingga pembangunan rantai berfungsi. Hanya bagian verifikasinya saja yang gagal.   -  person serkan    schedule 08.04.2020
comment
Maka, mungkin, root dipercaya oleh pengguna, tetapi tidak oleh mesin. Atau ada masalah pemeriksaan pencabutan.   -  person Crypt32    schedule 08.04.2020
comment
Ya, dalam kode saya di atas, saya mengizinkan untrustedRoot, tetapi saya mendapatkan dua kesalahan lainnya di ChainStatus: OfflineRevocation, RevocationStatusUnknown   -  person serkan    schedule 08.04.2020
comment
Apa yang dikatakan certutil -verify -urlfetch cert.cer. Periksa apakah semua URL baik-baik saja, atau lebih baik lagi, posting keluaran certutil.   -  person Crypt32    schedule 08.04.2020
comment
Yup dalam pertanyaan saya di atas saya menyebutkan bahwa certutil -verify .\leaf.cer gagal tetapi certutil -verify .\leaf.cer .\root.cer lolos   -  person serkan    schedule 08.04.2020
comment
Dengan saklar -urlfetch?   -  person Crypt32    schedule 08.04.2020
comment
perilaku yang sama dengan -urlfetch, jika saya meneruskan leaf dan root maka akan lulus. jika saya hanya meneruskan leaf saya melihat URL terverifikasi untuk leaf tetapi juga mencari URL root tetapi saya belum meneruskan sertifikat root sehingga gagal . Mungkin hal yang sama terjadi pada kode saya, mungkin extraStore tidak diperiksa saat memvalidasi URL?   -  person serkan    schedule 08.04.2020


Jawaban (1)


Saya telah membaca kode Anda dari PC dan mengetahui apa yang terjadi: sertifikat root Anda tidak dipercaya di sistem Anda. Windows CryptoAPI menampilkan CERT_E_UNTRUSTEDROOT ketika sertifikat root tidak dipercaya. Bersamaan dengan ini, CryptoAPI menghentikan pemeriksaan pencabutan dan memunculkan dua kesalahan tambahan: CRYPT_E_NO_REVOCATION_CHECK dan CERT_E_UNTRUSTEDROOT, karena pemeriksaan pencabutan dilewati. Selain root yang tidak tepercaya, CryptoAPI melewatkan pemeriksaan lain (seperti batasan, misalnya), tetapi tidak melaporkannya. Semuanya benar dan sesuai harapan.

Anda mencoba untuk mengizinkan root yang tidak tepercaya, tetapi melakukannya secara tidak benar, karena dengan cara ini Anda melewatkan pemeriksaan lainnya (seperti yang disebutkan dalam paragraf sebelumnya) dan logika Anda rentan.

Anda dapat mengecualikan pengecualian root yang tidak tepercaya dalam pengaturan rantai dan memaksa CryptoAPI untuk melanjutkan validasi dan mengembalikan kesuksesan jika tidak ditemukan kesalahan lain, tetapi saya sangat menyarankan untuk tidak melakukan itu, karena Anda terbuka untuk segala jenis MITM.

Anda memiliki dua opsi:

  1. membuat sertifikat root dipercaya oleh mesin (sistem lokal). Ini mungkin tidak dapat dilakukan.
  2. panggil fungsi CertCreateCertificateChainEngine secara langsung dan letakkan sertifikat root Anda di hRestrictedTrust anggota struktur CERT_CHAIN_ENGINE_CONFIG.

Jika Anda menggunakan Windows, pendekatan ke-2 adalah yang paling aman dan andal. Sampai sekarang, X509Chain .NET tidak mengimplementasikan fungsi ini. Ini memerlukan pengkodean tambahan, tetapi tidak ada banyak alternatif.

person Crypt32    schedule 08.04.2020
comment
Anda benar, menginstal sertifikat menyelesaikan kesalahan root tidak tepercaya serta kesalahan revocationUnknown. Saya akan mencoba menerapkan 2. atau mendapatkan persetujuan untuk 1. Terima kasih! - person serkan; 09.04.2020
comment
Opsi pertama membuka kerentanan keamanan. Anda telah diperingatkan. - person Crypt32; 09.04.2020