2003-12-01 Sebastien Pouliot <spouliot@videotron.ca>
[mono.git] / mcs / class / Mono.Security / Mono.Security.X509 / X509Chain.cs
1 //
2 // X509Chain.cs: X.509 Certificate Path
3 //      This is a VERY simplified and minimal version (for Authenticode support)
4 //
5 // Author:
6 //      Sebastien Pouliot (spouliot@motus.com)
7 //
8 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
9 //
10
11 using System;
12
13 namespace Mono.Security.X509 {
14
15         public class X509Chain {
16
17                 private X509CertificateCollection roots;
18                 private X509CertificateCollection certs;
19                 private X509Certificate root;
20
21                 public X509Chain ()
22                 {
23                         certs = new X509CertificateCollection ();
24                 }
25
26                 public void LoadCertificate (X509Certificate x509) 
27                 {
28                         certs.Add (x509);
29                 }
30
31                 public void LoadCertificates (X509CertificateCollection coll) 
32                 {
33                         certs.AddRange (coll);
34                 }
35
36                 public X509Certificate FindByIssuerName (string issuerName) 
37                 {
38                         foreach (X509Certificate x in certs) {
39                                 if (x.IssuerName == issuerName)
40                                         return x;
41                         }
42                         return null;
43                 }
44
45                 public X509CertificateCollection GetChain (X509Certificate x509) 
46                 {
47                         X509CertificateCollection path = new X509CertificateCollection ();
48                         X509Certificate x = FindCertificateParent (x509);
49                         if (x != null) {
50                                 while (x != null) {
51                                         x509 = x;
52                                         path.Add (x509);
53                                         x = FindCertificateParent (x509);
54                                         if ((x != null) && (x.IsSelfSigned))
55                                                 x = null;
56                                 }
57                         }
58                         // find a trusted root
59                         x = FindCertificateRoot (x509);
60                         if (x == null)
61                                 return null;
62                         root = x;
63                         return path;
64                 }
65
66                 private X509CertificateCollection GetTrustAnchors () 
67                 {
68                         // TODO - Load from machine.config
69                         ITrustAnchors trust = (ITrustAnchors) new TestAnchors ();
70                         return trust.Anchors;
71                 }
72
73                 public X509CertificateCollection TrustAnchors {
74                         get { return ((roots == null) ? GetTrustAnchors () : roots); }
75                         set { roots = value; }
76                 }
77
78                 public X509Certificate Root {
79                         get { return root; }
80                 }
81
82                 public void Reset () 
83                 {
84                         // this force a reload
85                         roots = null;
86                         certs.Clear ();
87                 }
88
89                 private X509Certificate FindCertificateParent (X509Certificate child) 
90                 {
91                         foreach (X509Certificate potentialParent in certs) {
92                                 if (IsParent (child, potentialParent))
93                                         return potentialParent;
94                         }
95                         return null;
96                 }
97
98                 private X509Certificate FindCertificateRoot (X509Certificate x509) 
99                 {
100                         // if the trusted root is in the path
101                         if (TrustAnchors.Contains (x509))
102                                 return x509;
103
104                         foreach (X509Certificate root in TrustAnchors) {
105                                 if (IsParent (x509, root))
106                                         return root;
107                         }
108
109                         return null;
110                 }
111
112                 private bool IsParent (X509Certificate child, X509Certificate parent) 
113                 {
114                         if (child.IssuerName != parent.SubjectName)
115                                 return false;
116                         return (child.VerifySignature (parent.RSA));
117                 }
118         }
119 }