2017-04-12 20 views
0

私はルートCAの状態のためのチェーン内の各証明書を評価するために、このコードを使用しています:チェーンから最上位のルートCA証明書を確実に取得する方法を教えてください。

Function GetRootCaCertificates(Chain As X509Chain) As IEnumerable(Of X509Certificate2) 
    With Chain.ChainElements.Cast(Of X509ChainElement) 
    With .Select(Function(Element As X509ChainElement) Element.Certificate) 
     Return .Where(Function(Certificate As X509Certificate2) 
         With Certificate.Extensions.Cast(Of X509Extension) 
         With .Where(Function(Extension As X509Extension) TypeOf Extension Is X509BasicConstraintsExtension) 
          With .Cast(Of X509BasicConstraintsExtension) 
          Return .Where(Function(Extension As X509BasicConstraintsExtension) Extension.CertificateAuthority = True).Count > 0 
          End With 
         End With 
         End With 
        End Function).ToList 
    End With 
    End With 
End Function 

それはうまく動作しますが、現在の場合には、それは2つのStartCom証明書戻っています:

Certificate Chain

(はい、私はStartComが上場廃止 - 私がされたことをその今週後半に対処することを知っている。)

ServerCertificateValidationCallbackデリゲートがを受け取りますにはチェーンを構成する証明書の配列が含まれています。配列の要素の順序に基づいて最上位のルートCAを判断できるとは確信していません。

私はthisthisを見つけましたが、最初はMagic Strings ™に依存し、2番目はオプションのフィールドに依存しています。そして、上記のExtension.CertificateAuthorityプロパティはそれを十分に絞り込んでいません。ご覧のとおり、チェーン内の2つの証明書には、このプロパティがTrueに設定されています。

X509Certificate2の公開プロパティーには、チェーン内の発行者を確実に識別するために使用できるものは含まれていないようです。最も便利なのは、Certificate.IssuerThumbprintまたは類似のものです。

チェーンが最初に構築されたので、明らかにこの情報は利用可能です。この単純な機能がAPIで見落とされている可能性を考慮すると、苦労しています。

私はどこかでそれを紛失する必要があります。

--EDIT--

私はを除くすべての証明書我々は後にしているものを含んでいるようだX509ChainPolicy.ExtraStoreプロパティを見つけました。ここから排除の簡単な問題です:

Dim oCertificates As List(Of X509Certificate2) 
Dim oThumbprints As IEnumerable(Of String) 

oThumbprints = Chain.ChainPolicy.ExtraStore.Cast(Of X509Certificate2).Select(Function(Certificate As X509Certificate2) Certificate.Thumbprint) 
oCertificates = Chain.ChainElements.Cast(Of X509ChainElement).Select(Function(Element As X509ChainElement) Element.Certificate).ToList 
oCertificates.RemoveAll(Function(Certificate As X509Certificate2) oThumbprints.Contains(Certificate.Thumbprint)) 

これはチェーン内のトップレベルルートCAを見つける信頼できる手段ですか?

答えて

1

ChainElementsは、葉から葉の順に並んでいます。したがって、PartialChainエラーが発生しない限り、最後のChainElementの証明書です。

private static X509Certificate2 GetRootCertificate(X509Chain chain) 
{ 
    // Assumes that chain.Build was already called 

    X509ChainElement chainElement = chain.ChainElements[chain.ChainElements.Count - 1]; 

    foreach (X509ChainStatus status in chainElement.ChainElementStatus) 
    { 
     if (status.Status == X509ChainStatusFlags.PartialChain) 
     { 
      return null; 
     } 
    } 

    return chainElement.Certificate; 
} 
+0

...これは100%信頼できるソート順ですか? (私の編集を参照してください) – InteXX

+0

はい、1符号0,2記号1、等 – bartonjs

+0

それは、それです。ありがとう。 – InteXX

関連する問題