2 // gcertview.cs: GTK# Certificate Viewer
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // (C) 2004 Novell (http://www.novell.com)
13 using System
.Reflection
;
15 using Mono
.Security
.X509
;
23 [assembly
: AssemblyTitle("Mono Certificate Viewer")]
24 [assembly
: AssemblyDescription("X.509 Certificate Viewer for GTK#")]
26 namespace Mono
.Tools
.CertView
{
28 public class GtkCertificateViewer
{
30 static private void Header ()
32 Assembly a
= Assembly
.GetExecutingAssembly ();
33 AssemblyName an
= a
.GetName ();
35 object [] att
= a
.GetCustomAttributes (typeof (AssemblyTitleAttribute
), false);
36 string title
= ((att
.Length
> 0) ? ((AssemblyTitleAttribute
) att
[0]).Title
: "Mono Certificate Viewer");
38 att
= a
.GetCustomAttributes (typeof (AssemblyCopyrightAttribute
), false);
39 string copyright
= ((att
.Length
> 0) ? ((AssemblyCopyrightAttribute
) att
[0]).Copyright
: "");
41 Console
.WriteLine ("{0} {1}", title
, an
.Version
.ToString ());
42 Console
.WriteLine ("{0}{1}", copyright
, Environment
.NewLine
);
45 public static void Main (string[] args
)
47 string filename
= ((args
.Length
> 0) ? args
[0] : null);
48 if ((filename
!= null) && (File
.Exists (filename
)))
49 new GtkCertificateViewer (filename
);
52 Console
.WriteLine ("Usage: mono gcertview.exe certificate.cer");
56 [Glade
.Widget
] Button issuerStatementButton
;
57 [Glade
.Widget
] Gtk
.Image brokenSealImage
;
58 [Glade
.Widget
] Gtk
.Image sealImage
;
59 [Glade
.Widget
] Entry issuedToEntry
;
60 [Glade
.Widget
] Entry issuedByEntry
;
61 [Glade
.Widget
] Label subjectAltNameLabel
;
62 [Glade
.Widget
] TextView certInfoTextview
;
63 [Glade
.Widget
] TextView certStatusTextview
;
64 [Glade
.Widget
] Entry notBeforeEntry
;
65 [Glade
.Widget
] Entry notAfterEntry
;
66 [Glade
.Widget
] TreeView detailsTreeview
;
67 [Glade
.Widget
] TextView detailsTextview
;
68 [Glade
.Widget
] Entry showComboEntry
;
71 private static Pixbuf
[] version
;
72 private static TreeCellDataFunc dataFunc
= null;
73 private ListStore allStore
;
74 private ListStore v1Store
;
75 private ListStore extensionsStore
;
76 private ListStore criticalStore
;
77 private ListStore propertiesStore
;
78 private ListStore emptyStore
;
81 private CertificateFormatter cf
;
83 public GtkCertificateViewer (string filename
)
87 Glade
.XML gxml
= new Glade
.XML ("certview.glade", "CertificateViewer", null);
88 gxml
.Autoconnect (this);
90 cf
= new CertificateFormatter (filename
);
93 Tooltips tt
= new Tooltips ();
94 issuedToEntry
.Text
= cf
.Issuer (false);
95 tt
.SetTip (issuedToEntry
, issuedToEntry
.Text
, issuedToEntry
.Text
);
96 issuedByEntry
.Text
= cf
.Subject (false);
97 tt
.SetTip (issuedByEntry
, issuedByEntry
.Text
, issuedByEntry
.Text
);
99 subjectAltNameLabel
.Text
= cf
.SubjectAltName (false);
100 subjectAltNameLabel
.Visible
= (subjectAltNameLabel
.Text
!= null);
102 notBeforeEntry
.Text
= cf
.Certificate
.ValidFrom
.ToString ("yyyy-MM-dd");
103 notAfterEntry
.Text
= cf
.Certificate
.ValidUntil
.ToString ("yyyy-MM-dd");
105 TextBuffer tb
= new TextBuffer (null);
106 if (cf
.Status
!= null)
107 tb
.SetText (cf
.Status
);
108 certStatusTextview
.Buffer
= tb
;
109 if (cf
.Status
!= null) {
110 certInfoTextview
.Buffer
= tb
;
111 certInfoTextview
.ModifyText (StateType
.Normal
, new Gdk
.Color (0xff, 0x00, 0x00));
114 sealImage
.Visible
= (cf
.Status
== null);
115 brokenSealImage
.Visible
= !sealImage
.Visible
;
117 Type
[] storeType
= new Type
[4] { typeof (string), typeof (string), typeof (string), typeof (int) }
;
118 allStore
= new ListStore (storeType
);
119 v1Store
= new ListStore (storeType
);
120 extensionsStore
= new ListStore (storeType
);
121 criticalStore
= new ListStore (storeType
);
122 propertiesStore
= new ListStore (storeType
);
123 emptyStore
= new ListStore (storeType
);
125 AddToStores (CertificateFormatter
.FieldNames
.Version
, cf
.Version (false), cf
.Version (true), 1);
126 AddToStores (CertificateFormatter
.FieldNames
.SerialNumber
, cf
.SerialNumber (false), cf
.SerialNumber (true), 0);
127 AddToStores (CertificateFormatter
.FieldNames
.SignatureAlgorithm
, cf
.SignatureAlgorithm (false), cf
.SignatureAlgorithm (true), 0);
128 AddToStores (CertificateFormatter
.FieldNames
.Issuer
, cf
.Issuer (false), cf
.Issuer (true), 0);
129 AddToStores (CertificateFormatter
.FieldNames
.ValidFrom
, cf
.ValidFrom (false), cf
.ValidFrom (true), 0);
130 AddToStores (CertificateFormatter
.FieldNames
.ValidUntil
, cf
.ValidUntil (false), cf
.ValidUntil (true), 0);
131 AddToStores (CertificateFormatter
.FieldNames
.Subject
, cf
.Subject (false), cf
.Subject (true), 0);
132 AddToStores (CertificateFormatter
.FieldNames
.PublicKey
, cf
.PublicKey (false), cf
.PublicKey (true), 0);
133 for (int i
=0; i
< cf
.Certificate
.Extensions
.Count
; i
++) {
134 X509Extension xe
= cf
.GetExtension (i
);
135 string name
= xe
.Name
;
139 string exts
= xe
.ToString ();
141 if (xe
.Name
== xe
.OID
) {
142 exts
= cf
.Extension (i
, false);
143 details
= cf
.Extension (i
, true);
146 details
= xe
.ToString ();
147 exts
= CertificateFormatter
.OneLine (details
);
150 AddToStores (name
, exts
, details
, icon
);
152 AddToStores (CertificateFormatter
.PropertyNames
.ThumbprintAlgorithm
, cf
.ThumbprintAlgorithm
, cf
.ThumbprintAlgorithm
, 4);
153 string ftb
= CertificateFormatter
.Array2Word (cf
.Thumbprint
);
154 AddToStores (CertificateFormatter
.PropertyNames
.Thumbprint
, ftb
, ftb
, 4);
156 // select appropriate store to show
157 OnShowComboChanged (null, null);
159 TreeViewColumn fieldColumn
= new TreeViewColumn ();
160 CellRendererPixbuf pr
= new CellRendererPixbuf ();
161 CellRenderer fieldRenderer
= new CellRendererText ();
162 fieldColumn
.PackStart (pr
, false);
163 fieldColumn
.SetCellDataFunc (pr
, CellDataFunc
, IntPtr
.Zero
, null);
164 fieldColumn
.Title
= "Field";
165 fieldColumn
.PackStart (fieldRenderer
, false);
166 fieldColumn
.AddAttribute (fieldRenderer
, "text", 0);
167 detailsTreeview
.AppendColumn (fieldColumn
);
169 TreeViewColumn valueColumn
= new TreeViewColumn ();
170 CellRenderer valueRenderer
= new CellRendererText ();
171 valueColumn
.Title
= "Value";
172 valueColumn
.PackStart (valueRenderer
, true);
173 valueColumn
.AddAttribute (valueRenderer
, "text", 1);
174 detailsTreeview
.AppendColumn (valueColumn
);
176 // detailsTreeview.ModifyText (StateType.Selected, new Gdk.Color (0x33, 0xff, 0x33));
181 static void SetCellData (TreeViewColumn col
, CellRenderer cell
, TreeModel model
, TreeIter iter
)
183 int icon
= (int) model
.GetValue (iter
, 3);
184 CellRendererPixbuf cr
= (CellRendererPixbuf
) cell
;
185 cr
.Pixbuf
= version
[icon
];
188 public static Gtk
.TreeCellDataFunc CellDataFunc
{
190 if (dataFunc
== null) {
191 dataFunc
= new TreeCellDataFunc (SetCellData
);
192 version
= new Pixbuf
[5];
193 version
[0] = new Pixbuf ("v1.bmp");
194 version
[1] = new Pixbuf ("v2.bmp");
195 version
[2] = new Pixbuf ("v3.bmp");
196 version
[3] = new Pixbuf ("v3critical.bmp");
197 version
[4] = new Pixbuf ("mono.bmp");
204 private void AddToStores (string fieldName
, string fieldValue
, string detailedValue
, int iconValue
)
206 GLib
.Value fv
= new GLib
.Value (fieldName
);
207 GLib
.Value vv
= new GLib
.Value (fieldValue
);
208 GLib
.Value dv
= new GLib
.Value (detailedValue
);
209 GLib
.Value iv
= new GLib
.Value (iconValue
);
211 case 0: // X.509 version 1 fields
212 AddToStore (v1Store
, fv
, vv
, dv
, iv
);
214 case 2: // extensions
215 AddToStore (extensionsStore
, fv
, vv
, dv
, iv
);
217 case 3: // critical extensions
218 AddToStore (extensionsStore
, fv
, vv
, dv
, iv
);
219 AddToStore (criticalStore
, fv
, vv
, dv
, iv
);
221 case 4: // properties
222 AddToStore (propertiesStore
, fv
, vv
, dv
, iv
);
225 // and we always add to allStore
226 AddToStore (allStore
, fv
, vv
, dv
, iv
);
229 private void AddToStore (ListStore store
, GLib
.Value field
, GLib
.Value
value, GLib
.Value details
, GLib
.Value icon
)
231 TreeIter iter
= store
.Append ();
232 store
.SetValue (iter
, 0, field
);
233 store
.SetValue (iter
, 1, value);
234 store
.SetValue (iter
, 2, details
);
235 store
.SetValue (iter
, 3, icon
);
238 private void OnCursorChanged (object o
, EventArgs args
)
241 TreeIter iter
= new TreeIter ();
242 TreeSelection ts
= detailsTreeview
.Selection
;
243 ts
.GetSelected (out model
, out iter
);
245 TextBuffer tb
= new TextBuffer (null);
246 tb
.SetText ((string) detailsTreeview
.Model
.GetValue (iter
, 2));
247 detailsTextview
.Buffer
= tb
;
250 private void OnShowComboChanged (object o
, EventArgs e
)
252 // FIXME: yuck - how can I get an index ?
253 switch (showComboEntry
.Text
) {
255 detailsTreeview
.Model
= allStore
;
257 case "Version 1 Fields Only":
258 detailsTreeview
.Model
= v1Store
;
260 case "Extensions Only":
261 detailsTreeview
.Model
= extensionsStore
;
263 case "Critical Extensions Only":
264 detailsTreeview
.Model
= criticalStore
;
266 case "Properties Only":
267 detailsTreeview
.Model
= propertiesStore
;
270 detailsTreeview
.Model
= emptyStore
;
275 public void OnWindowDeleteEvent (object o
, DeleteEventArgs args
)
281 public void OnOkButtonClicked (object o
, EventArgs e
)
286 public void OnIssuerStatementButtonClicked (object o
, EventArgs e
)