~ubuntu-branches/ubuntu/trusty/ruby1.9/trusty

« back to all changes in this revision

Viewing changes to sample/openssl/cert_store_view.rb

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2008-01-24 11:42:29 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20080124114229-jw2f87rdxlq6gp11
Tags: 1.9.0.0-2ubuntu1
* Merge from debian unstable, remaining changes:
  - Robustify check for target_os, fixing build failure on lpia.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env ruby
2
 
 
3
 
require 'fox'
4
 
require 'openssl'
5
 
require 'time'
6
 
require 'certstore'
7
 
require 'getopts'
8
 
 
9
 
include Fox
10
 
 
11
 
module CertDumpSupport
12
 
  def cert_label(cert)
13
 
    subject_alt_name =
14
 
      cert.extensions.find { |ext| ext.oid == 'subjectAltName' }
15
 
    if subject_alt_name
16
 
      subject_alt_name.value.split(/\s*,\s/).each do |alt_name_pair|
17
 
        alt_tag, alt_name = alt_name_pair.split(/:/)
18
 
        return alt_name
19
 
      end
20
 
    end
21
 
    name_label(cert.subject)
22
 
  end
23
 
 
24
 
  def name_label(name)
25
 
    ary = name.to_a
26
 
    if (cn = ary.find { |rdn| rdn[0] == 'CN' })
27
 
      return cn[1]
28
 
    end
29
 
    if ary.last[0] == 'OU'
30
 
      return ary.last[1]
31
 
    end
32
 
    name.to_s
33
 
  end
34
 
 
35
 
  def name_text(name)
36
 
    name.to_a.collect { |tag, value|
37
 
      "#{tag} = #{value}"
38
 
    }.reverse.join("\n")
39
 
  end
40
 
 
41
 
  def bn_label(bn)
42
 
    ("0" << sprintf("%X", bn)).scan(/../).join(" ")
43
 
  end
44
 
end
45
 
 
46
 
class CertDump
47
 
  include CertDumpSupport
48
 
 
49
 
  def initialize(cert)
50
 
    @cert = cert
51
 
  end
52
 
 
53
 
  def get_dump(tag)
54
 
    case tag
55
 
    when 'Version'
56
 
      version
57
 
    when 'Serial'
58
 
      serial
59
 
    when 'Signature Algorithm'
60
 
      signature_algorithm
61
 
    when 'Issuer'
62
 
      issuer
63
 
    when 'Validity'
64
 
      validity
65
 
    when 'Not before'
66
 
      not_before
67
 
    when 'Not after'
68
 
      not_after
69
 
    when 'Subject'
70
 
      subject
71
 
    when 'Public key'
72
 
      public_key
73
 
    else
74
 
      ext(tag)
75
 
    end
76
 
  end
77
 
 
78
 
  def get_dump_line(tag)
79
 
    case tag
80
 
    when 'Version'
81
 
      version_line
82
 
    when 'Serial'
83
 
      serial_line
84
 
    when 'Signature Algorithm'
85
 
      signature_algorithm_line
86
 
    when 'Subject'
87
 
      subject_line
88
 
    when 'Issuer'
89
 
      issuer_line
90
 
    when 'Validity'
91
 
      validity_line
92
 
    when 'Not before'
93
 
      not_before_line
94
 
    when 'Not after'
95
 
      not_after_line
96
 
    when 'Public key'
97
 
      public_key_line
98
 
    else
99
 
      ext_line(tag)
100
 
    end
101
 
  end
102
 
 
103
 
private
104
 
 
105
 
  def version
106
 
    "Version: #{@cert.version + 1}"
107
 
  end
108
 
 
109
 
  def version_line
110
 
    version
111
 
  end
112
 
 
113
 
  def serial
114
 
    bn_label(@cert.serial)
115
 
  end
116
 
 
117
 
  def serial_line
118
 
    serial
119
 
  end
120
 
 
121
 
  def signature_algorithm
122
 
    @cert.signature_algorithm
123
 
  end
124
 
 
125
 
  def signature_algorithm_line
126
 
    signature_algorithm
127
 
  end
128
 
 
129
 
  def subject
130
 
    name_text(@cert.subject)
131
 
  end
132
 
 
133
 
  def subject_line
134
 
    @cert.subject.to_s
135
 
  end
136
 
 
137
 
  def issuer
138
 
    name_text(@cert.issuer)
139
 
  end
140
 
 
141
 
  def issuer_line
142
 
    @cert.issuer.to_s
143
 
  end
144
 
 
145
 
  def validity
146
 
    <<EOS
147
 
Not before: #{not_before}
148
 
Not after: #{not_after}
149
 
EOS
150
 
  end
151
 
 
152
 
  def validity_line
153
 
    "from #{@cert.not_before.iso8601} to #{@cert.not_after.iso8601}"
154
 
  end
155
 
 
156
 
  def not_before
157
 
    @cert.not_before.to_s
158
 
  end
159
 
 
160
 
  def not_before_line
161
 
    not_before
162
 
  end
163
 
 
164
 
  def not_after
165
 
    @cert.not_after.to_s
166
 
  end
167
 
 
168
 
  def not_after_line
169
 
    not_after
170
 
  end
171
 
 
172
 
  def public_key
173
 
    @cert.public_key.to_text
174
 
  end
175
 
 
176
 
  def public_key_line
177
 
    "#{@cert.public_key.class} -- " << public_key.scan(/\A[^\n]*/)[0] << '...'
178
 
  end
179
 
 
180
 
  def ext(tag)
181
 
    @cert.extensions.each do |ext|
182
 
      if ext.oid == tag
183
 
        return ext_detail(tag, ext.value)
184
 
      end
185
 
    end
186
 
    "(unknown)"
187
 
  end
188
 
 
189
 
  def ext_line(tag)
190
 
    ext(tag).tr("\r\n", '')
191
 
  end
192
 
 
193
 
  def ext_detail(tag, value)
194
 
    value
195
 
  end
196
 
end
197
 
 
198
 
class CrlDump
199
 
  include CertDumpSupport
200
 
 
201
 
  def initialize(crl)
202
 
    @crl = crl
203
 
  end
204
 
 
205
 
  def get_dump(tag)
206
 
    case tag
207
 
    when 'Version'
208
 
      version
209
 
    when 'Signature Algorithm'
210
 
      signature_algorithm
211
 
    when 'Issuer'
212
 
      issuer
213
 
    when 'Last update'
214
 
      last_update
215
 
    when 'Next update'
216
 
      next_update
217
 
    else
218
 
      ext(tag)
219
 
    end
220
 
  end
221
 
 
222
 
  def get_dump_line(tag)
223
 
    case tag
224
 
    when 'Version'
225
 
      version_line
226
 
    when 'Signature Algorithm'
227
 
      signature_algorithm_line
228
 
    when 'Issuer'
229
 
      issuer_line
230
 
    when 'Last update'
231
 
      last_update_line
232
 
    when 'Next update'
233
 
      next_update_line
234
 
    else
235
 
      ext_line(tag)
236
 
    end
237
 
  end
238
 
 
239
 
private
240
 
 
241
 
  def version
242
 
    "Version: #{@crl.version + 1}"
243
 
  end
244
 
 
245
 
  def version_line
246
 
    version
247
 
  end
248
 
 
249
 
  def signature_algorithm
250
 
    @crl.signature_algorithm
251
 
  end
252
 
 
253
 
  def signature_algorithm_line
254
 
    signature_algorithm
255
 
  end
256
 
 
257
 
  def issuer
258
 
    name_text(@crl.issuer)
259
 
  end
260
 
 
261
 
  def issuer_line
262
 
    @crl.issuer.to_s
263
 
  end
264
 
 
265
 
  def last_update
266
 
    @crl.last_update.to_s
267
 
  end
268
 
 
269
 
  def last_update_line
270
 
    last_update
271
 
  end
272
 
 
273
 
  def next_update
274
 
    @crl.next_update.to_s
275
 
  end
276
 
 
277
 
  def next_update_line
278
 
    next_update
279
 
  end
280
 
 
281
 
  def ext(tag)
282
 
    @crl.extensions.each do |ext|
283
 
      if ext.oid == tag
284
 
        return ext_detail(tag, ext.value)
285
 
      end
286
 
    end
287
 
    "(unknown)"
288
 
  end
289
 
 
290
 
  def ext_line(tag)
291
 
    ext(tag).tr("\r\n", '')
292
 
  end
293
 
 
294
 
  def ext_detail(tag, value)
295
 
    value
296
 
  end
297
 
end
298
 
 
299
 
class RevokedDump
300
 
  include CertDumpSupport
301
 
 
302
 
  def initialize(revoked)
303
 
    @revoked = revoked
304
 
  end
305
 
 
306
 
  def get_dump(tag)
307
 
    case tag
308
 
    when 'Serial'
309
 
      serial
310
 
    when 'Time'
311
 
      time
312
 
    else
313
 
      ext(tag)
314
 
    end
315
 
  end
316
 
 
317
 
  def get_dump_line(tag)
318
 
    case tag
319
 
    when 'Serial'
320
 
      serial_line
321
 
    when 'Time'
322
 
      time_line
323
 
    else
324
 
      ext_line(tag)
325
 
    end
326
 
  end
327
 
 
328
 
private
329
 
 
330
 
  def serial
331
 
    bn_label(@revoked.serial)
332
 
  end
333
 
 
334
 
  def serial_line
335
 
    serial
336
 
  end
337
 
 
338
 
  def time
339
 
    @revoked.time.to_s
340
 
  end
341
 
 
342
 
  def time_line
343
 
    time
344
 
  end
345
 
 
346
 
  def ext(tag)
347
 
    @revoked.extensions.each do |ext|
348
 
      if ext.oid == tag
349
 
        return ext_detail(tag, ext.value)
350
 
      end
351
 
    end
352
 
    "(unknown)"
353
 
  end
354
 
 
355
 
  def ext_line(tag)
356
 
    ext(tag).tr("\r\n", '')
357
 
  end
358
 
 
359
 
  def ext_detail(tag, value)
360
 
    value
361
 
  end
362
 
end
363
 
 
364
 
class RequestDump
365
 
  include CertDumpSupport
366
 
 
367
 
  def initialize(req)
368
 
    @req = req
369
 
  end
370
 
 
371
 
  def get_dump(tag)
372
 
    case tag
373
 
    when 'Version'
374
 
      version
375
 
    when 'Signature Algorithm'
376
 
      signature_algorithm
377
 
    when 'Subject'
378
 
      subject
379
 
    when 'Public key'
380
 
      public_key
381
 
    else
382
 
      attributes(tag)
383
 
    end
384
 
  end
385
 
 
386
 
  def get_dump_line(tag)
387
 
    case tag
388
 
    when 'Version'
389
 
      version_line
390
 
    when 'Signature Algorithm'
391
 
      signature_algorithm_line
392
 
    when 'Subject'
393
 
      subject_line
394
 
    when 'Public key'
395
 
      public_key_line
396
 
    else
397
 
      attributes_line(tag)
398
 
    end
399
 
  end
400
 
 
401
 
private
402
 
 
403
 
  def version
404
 
    "Version: #{@req.version + 1}"
405
 
  end
406
 
 
407
 
  def version_line
408
 
    version
409
 
  end
410
 
 
411
 
  def signature_algorithm
412
 
    @req.signature_algorithm
413
 
  end
414
 
 
415
 
  def signature_algorithm_line
416
 
    signature_algorithm
417
 
  end
418
 
 
419
 
  def subject
420
 
    name_text(@req.subject)
421
 
  end
422
 
 
423
 
  def subject_line
424
 
    @req.subject.to_s
425
 
  end
426
 
 
427
 
  def public_key
428
 
    @req.public_key.to_text
429
 
  end
430
 
 
431
 
  def public_key_line
432
 
    "#{@req.public_key.class} -- " << public_key.scan(/\A[^\n]*/)[0] << '...'
433
 
  end
434
 
 
435
 
  def attributes(tag)
436
 
    "(unknown)"
437
 
  end
438
 
 
439
 
  def attributes_line(tag)
440
 
    attributes(tag).tr("\r\n", '')
441
 
  end
442
 
end
443
 
 
444
 
class CertStoreView < FXMainWindow
445
 
  class CertTree
446
 
    include CertDumpSupport
447
 
 
448
 
    def initialize(observer, tree)
449
 
      @observer = observer
450
 
      @tree = tree
451
 
      @tree.connect(SEL_COMMAND) do |sender, sel, item|
452
 
        if item.data
453
 
          @observer.getApp().beginWaitCursor do
454
 
            @observer.show_item(item.data)
455
 
          end
456
 
        else
457
 
          @observer.show_item(nil)
458
 
        end
459
 
      end
460
 
    end
461
 
 
462
 
    def show(cert_store)
463
 
      @tree.clearItems
464
 
      @self_signed_ca_node = add_item_last(nil, "Trusted root CA")
465
 
      @other_ca_node = add_item_last(nil, "Intermediate CA")
466
 
      @ee_node = add_item_last(nil, "Personal")
467
 
      @crl_node = add_item_last(nil, "CRL")
468
 
      @request_node = add_item_last(nil, "Request")
469
 
      @verify_path_node = add_item_last(nil, "Certification path")
470
 
      show_certs(cert_store)
471
 
    end
472
 
 
473
 
    def show_certs(cert_store)
474
 
      remove_items(@self_signed_ca_node)
475
 
      remove_items(@other_ca_node)
476
 
      remove_items(@ee_node)
477
 
      remove_items(@crl_node)
478
 
      remove_items(@request_node)
479
 
      import_certs(cert_store)
480
 
    end
481
 
 
482
 
    def show_request(req)
483
 
      node = add_item_last(@request_node, name_label(req.subject), req)
484
 
      @tree.selectItem(node)
485
 
      @observer.show_item(req)
486
 
    end
487
 
 
488
 
    def show_verify_path(verify_path)
489
 
      add_verify_path(verify_path)
490
 
    end
491
 
 
492
 
  private
493
 
 
494
 
    def open_node(node)
495
 
      node.expanded = node.opened = true
496
 
    end
497
 
 
498
 
    def close_node(node)
499
 
      node.expanded = node.opened = false
500
 
    end
501
 
 
502
 
    def import_certs(cert_store)
503
 
      cert_store.self_signed_ca.each do |cert|
504
 
        add_item_last(@self_signed_ca_node, cert_label(cert), cert)
505
 
      end
506
 
      cert_store.other_ca.each do |cert|
507
 
        add_item_last(@other_ca_node, cert_label(cert), cert)
508
 
      end
509
 
      cert_store.ee.each do |cert|
510
 
        add_item_last(@ee_node, cert_label(cert), cert)
511
 
      end
512
 
      cert_store.crl.each do |crl|
513
 
        node = add_item_last(@crl_node, name_label(crl.issuer), crl)
514
 
        close_node(node)
515
 
        crl.revoked.each do |revoked|
516
 
          add_item_last(node, bn_label(revoked.serial), revoked)
517
 
        end
518
 
      end
519
 
      cert_store.request.each do |req|
520
 
        add_item_last(@requestnode, name_label(req.subject), req)
521
 
      end
522
 
    end
523
 
 
524
 
    def add_verify_path(verify_path)
525
 
      node = @verify_path_node
526
 
      last_cert = nil
527
 
      verify_path.reverse_each do |ok, cert, crl_check, error_string|
528
 
        warn = []
529
 
        if @observer.cert_store.is_ca?(cert)
530
 
          warn << 'NO ARL' unless crl_check
531
 
        else
532
 
          warn << 'NO CRL' unless crl_check
533
 
        end
534
 
        warn_str = '(' << warn.join(", ") << ')'
535
 
        warn_mark = warn.empty? ? '' : '!'
536
 
        label = if ok
537
 
            "OK#{warn_mark}..." + cert_label(cert)
538
 
          else
539
 
            "NG(#{error_string})..." + cert_label(cert)
540
 
          end
541
 
        label << warn_str unless warn.empty?
542
 
        node = add_item_last(node, label, cert)
543
 
        node.expanded = true
544
 
        last_cert = cert
545
 
      end
546
 
      if last_cert
547
 
        @tree.selectItem(node)
548
 
        @observer.show_item(last_cert)
549
 
      end
550
 
    end
551
 
 
552
 
    def add_item_last(parent, label, obj = nil)
553
 
      node = @tree.addItemLast(parent, FXTreeItem.new(label))
554
 
      node.data = obj if obj
555
 
      open_node(node)
556
 
      node
557
 
    end
558
 
 
559
 
    def remove_items(node)
560
 
      while node.getNumChildren > 0
561
 
        @tree.removeItem(node.getFirst)
562
 
      end
563
 
    end
564
 
  end
565
 
 
566
 
  class CertInfo
567
 
    def initialize(observer, table)
568
 
      @observer = observer
569
 
      @table = table
570
 
      @table.leadingRows = 0
571
 
      @table.leadingCols = 0
572
 
      @table.trailingRows = 0
573
 
      @table.trailingCols = 0
574
 
      @table.showVertGrid(false)
575
 
      @table.showHorzGrid(false)
576
 
      @table.setTableSize(1, 2)
577
 
      @table.setColumnWidth(0, 125)
578
 
      @table.setColumnWidth(1, 350)
579
 
    end
580
 
 
581
 
    def show(item)
582
 
      @observer.show_detail(nil, nil)
583
 
      if item.nil?
584
 
        set_column_size(1)
585
 
        return
586
 
      end
587
 
      case item
588
 
      when OpenSSL::X509::Certificate
589
 
        show_cert(item)
590
 
      when OpenSSL::X509::CRL
591
 
        show_crl(item)
592
 
      when OpenSSL::X509::Revoked
593
 
        show_revoked(item)
594
 
      when OpenSSL::X509::Request
595
 
        show_request(item)
596
 
      else
597
 
        raise NotImplementedError.new("Unknown item type #{item.class}.")
598
 
      end
599
 
    end
600
 
 
601
 
  private
602
 
 
603
 
    def show_cert(cert)
604
 
      wrap = CertDump.new(cert)
605
 
      items = []
606
 
      items << ['Version', wrap.get_dump_line('Version')]
607
 
      items << ['Signature Algorithm', wrap.get_dump_line('Signature Algorithm')]
608
 
      items << ['Issuer', wrap.get_dump_line('Issuer')]
609
 
      items << ['Serial', wrap.get_dump_line('Serial')]
610
 
      #items << ['Not before', wrap.get_dump_line('Not before')]
611
 
      #items << ['Not after', wrap.get_dump_line('Not after')]
612
 
      items << ['Subject', wrap.get_dump_line('Subject')]
613
 
      items << ['Public key', wrap.get_dump_line('Public key')]
614
 
      items << ['Validity', wrap.get_dump_line('Validity')]
615
 
      (cert.extensions.sort { |a, b| a.oid <=> b.oid }).each do |ext|
616
 
        items << [ext.oid, wrap.get_dump_line(ext.oid)]
617
 
      end
618
 
      show_items(cert, items)
619
 
    end
620
 
 
621
 
    def show_crl(crl)
622
 
      wrap = CrlDump.new(crl)
623
 
      items = []
624
 
      items << ['Version', wrap.get_dump_line('Version')]
625
 
      items << ['Signature Algorithm', wrap.get_dump_line('Signature Algorithm')]
626
 
      items << ['Issuer', wrap.get_dump_line('Issuer')]
627
 
      items << ['Last update', wrap.get_dump_line('Last update')]
628
 
      items << ['Next update', wrap.get_dump_line('Next update')]
629
 
      crl.extensions.each do |ext|
630
 
        items << [ext.oid, wrap.get_dump_line(ext.oid)]
631
 
      end
632
 
      show_items(crl, items)
633
 
    end
634
 
 
635
 
    def show_revoked(revoked)
636
 
      wrap = RevokedDump.new(revoked)
637
 
      items = []
638
 
      items << ['Serial', wrap.get_dump_line('Serial')]
639
 
      items << ['Time', wrap.get_dump_line('Time')]
640
 
      revoked.extensions.each do |ext|
641
 
        items << [ext.oid, wrap.get_dump_line(ext.oid)]
642
 
      end
643
 
      show_items(revoked, items)
644
 
    end
645
 
 
646
 
    def show_request(req)
647
 
      wrap = RequestDump.new(req)
648
 
      items = []
649
 
      items << ['Version', wrap.get_dump_line('Version')]
650
 
      items << ['Signature Algorithm', wrap.get_dump_line('Signature Algorithm')]
651
 
      items << ['Subject', wrap.get_dump_line('Subject')]
652
 
      items << ['Public key', wrap.get_dump_line('Public key')]
653
 
      req.attributes.each do |attr|
654
 
        items << [attr.attr, wrap.get_dump_line(attr.oid)]
655
 
      end
656
 
      show_items(req, items)
657
 
    end
658
 
 
659
 
    def show_items(obj, items)
660
 
      set_column_size(items.size)
661
 
      items.each_with_index do |ele, idx|
662
 
        tag, value = ele
663
 
        @table.setItemText(idx, 0, tag)
664
 
        @table.getItem(idx, 0).data = tag
665
 
        @table.setItemText(idx, 1, value.to_s)
666
 
        @table.getItem(idx, 1).data = tag
667
 
      end
668
 
      @table.connect(SEL_COMMAND) do |sender, sel, loc|
669
 
        item = @table.getItem(loc.row, loc.col)
670
 
        @observer.show_detail(obj, item.data)
671
 
      end
672
 
      justify_table
673
 
    end
674
 
 
675
 
    def set_column_size(size)
676
 
      col0_width = @table.getColumnWidth(0)
677
 
      col1_width = @table.getColumnWidth(1)
678
 
      @table.setTableSize(size, 2)
679
 
      @table.setColumnWidth(0, col0_width)
680
 
      @table.setColumnWidth(1, col1_width)
681
 
    end
682
 
 
683
 
    def justify_table
684
 
      for col in 0..@table.numCols-1
685
 
        for row in 0..@table.numRows-1
686
 
          @table.getItem(row, col).justify = FXTableItem::LEFT
687
 
        end
688
 
      end
689
 
    end
690
 
  end
691
 
 
692
 
  class CertDetail
693
 
    def initialize(observer, detail)
694
 
      @observer = observer
695
 
      @detail = detail
696
 
    end
697
 
 
698
 
    def show(item, tag)
699
 
      if item.nil?
700
 
        @detail.text = ''
701
 
        return
702
 
      end
703
 
      case item
704
 
      when OpenSSL::X509::Certificate
705
 
        show_cert(item, tag)
706
 
      when OpenSSL::X509::CRL
707
 
        show_crl(item, tag)
708
 
      when OpenSSL::X509::Revoked
709
 
        show_revoked(item, tag)
710
 
      when OpenSSL::X509::Request
711
 
        show_request(item, tag)
712
 
      else
713
 
        raise NotImplementedError.new("Unknown item type #{item.class}.")
714
 
      end
715
 
    end
716
 
 
717
 
  private
718
 
 
719
 
    def show_cert(cert, tag)
720
 
      wrap = CertDump.new(cert)
721
 
      @detail.text = wrap.get_dump(tag)
722
 
    end
723
 
 
724
 
    def show_crl(crl, tag)
725
 
      wrap = CrlDump.new(crl)
726
 
      @detail.text = wrap.get_dump(tag)
727
 
    end
728
 
 
729
 
    def show_revoked(revoked, tag)
730
 
      wrap = RevokedDump.new(revoked)
731
 
      @detail.text = wrap.get_dump(tag)
732
 
    end
733
 
 
734
 
    def show_request(request, tag)
735
 
      wrap = RequestDump.new(request)
736
 
      @detail.text = wrap.get_dump(tag)
737
 
    end
738
 
  end
739
 
 
740
 
  attr_reader :cert_store
741
 
 
742
 
  def initialize(app, cert_store)
743
 
    @cert_store = cert_store
744
 
    @verify_filter = 0
745
 
    @verify_filename = nil
746
 
    full_width = 800
747
 
    full_height = 500
748
 
    horz_pos = 300
749
 
 
750
 
    super(app, "Certificate store", nil, nil, DECOR_ALL, 0, 0, full_width,
751
 
      full_height)
752
 
 
753
 
    FXTooltip.new(self.getApp())
754
 
 
755
 
    menubar = FXMenubar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
756
 
    file_menu = FXMenuPane.new(self)
757
 
    FXMenuTitle.new(menubar, "&File", nil, file_menu)
758
 
    file_open_menu = FXMenuPane.new(self)
759
 
    FXMenuCommand.new(file_open_menu, "&Directory\tCtl-O").connect(SEL_COMMAND,
760
 
      method(:on_cmd_file_open_dir))
761
 
    FXMenuCascade.new(file_menu, "&Open\tCtl-O", nil, file_open_menu)
762
 
    FXMenuCommand.new(file_menu, "&Quit\tCtl-Q", nil, getApp(), FXApp::ID_QUIT)
763
 
 
764
 
    tool_menu = FXMenuPane.new(self)
765
 
    FXMenuTitle.new(menubar, "&Tool", nil, tool_menu)
766
 
    FXMenuCommand.new(tool_menu, "&Verify\tCtl-N").connect(SEL_COMMAND,
767
 
      method(:on_cmd_tool_verify))
768
 
    FXMenuCommand.new(tool_menu, "&Show Request\tCtl-R").connect(SEL_COMMAND,
769
 
      method(:on_cmd_tool_request))
770
 
 
771
 
    base_frame = FXHorizontalFrame.new(self, LAYOUT_FILL_X | LAYOUT_FILL_Y)
772
 
    splitter_horz = FXSplitter.new(base_frame, LAYOUT_SIDE_TOP | LAYOUT_FILL_X |
773
 
    LAYOUT_FILL_Y | SPLITTER_TRACKING | SPLITTER_HORIZONTAL)
774
 
 
775
 
    # Cert tree
776
 
    cert_tree_frame = FXHorizontalFrame.new(splitter_horz, LAYOUT_FILL_X |
777
 
      LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK)
778
 
    cert_tree_frame.setWidth(horz_pos)
779
 
    cert_tree = FXTreeList.new(cert_tree_frame, 0, nil, 0,
780
 
      TREELIST_BROWSESELECT | TREELIST_SHOWS_LINES | TREELIST_SHOWS_BOXES |
781
 
      TREELIST_ROOT_BOXES | LAYOUT_FILL_X | LAYOUT_FILL_Y)
782
 
    @cert_tree = CertTree.new(self, cert_tree)
783
 
 
784
 
    # Cert info
785
 
    splitter_vert = FXSplitter.new(splitter_horz, LAYOUT_SIDE_TOP |
786
 
      LAYOUT_FILL_X | LAYOUT_FILL_Y | SPLITTER_TRACKING | SPLITTER_VERTICAL |
787
 
      SPLITTER_REVERSED)
788
 
    cert_list_base = FXVerticalFrame.new(splitter_vert, LAYOUT_FILL_X |
789
 
      LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0)
790
 
    cert_list_frame = FXHorizontalFrame.new(cert_list_base, FRAME_SUNKEN |
791
 
      FRAME_THICK | LAYOUT_FILL_X | LAYOUT_FILL_Y)
792
 
    cert_info = FXTable.new(cert_list_frame, 2, 10, nil, 0, FRAME_SUNKEN |
793
 
      TABLE_COL_SIZABLE | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 2, 2, 2, 2)
794
 
    @cert_info = CertInfo.new(self, cert_info)
795
 
 
796
 
    cert_detail_base = FXVerticalFrame.new(splitter_vert, LAYOUT_FILL_X |
797
 
      LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0)
798
 
    cert_detail_frame = FXHorizontalFrame.new(cert_detail_base, FRAME_SUNKEN |
799
 
      FRAME_THICK | LAYOUT_FILL_X | LAYOUT_FILL_Y)
800
 
    cert_detail = FXText.new(cert_detail_frame, nil, 0, TEXT_READONLY |
801
 
      LAYOUT_FILL_X | LAYOUT_FILL_Y)
802
 
    @cert_detail = CertDetail.new(self, cert_detail)
803
 
 
804
 
    show_init
805
 
  end
806
 
 
807
 
  def create
808
 
    super
809
 
    show(PLACEMENT_SCREEN)
810
 
  end
811
 
 
812
 
  def show_init
813
 
    @cert_tree.show(@cert_store)
814
 
    show_item(nil)
815
 
  end
816
 
 
817
 
  def show_certs
818
 
    @cert_tree.show_certs(@cert_store)
819
 
  end
820
 
 
821
 
  def show_request(req)
822
 
    @cert_tree.show_request(req)
823
 
  end
824
 
 
825
 
  def show_verify_path(verify_path)
826
 
    @cert_tree.show_verify_path(verify_path)
827
 
  end
828
 
 
829
 
  def show_item(item)
830
 
    @cert_info.show(item) if @cert_info
831
 
  end
832
 
 
833
 
  def show_detail(item, tag)
834
 
    @cert_detail.show(item, tag) if @cert_detail
835
 
  end
836
 
 
837
 
  def verify(certfile)
838
 
    path = verify_certfile(certfile)
839
 
    show_certs  # CRL could be change.
840
 
    show_verify_path(path)
841
 
  end
842
 
 
843
 
private
844
 
 
845
 
  def on_cmd_file_open_dir(sender, sel, ptr)
846
 
    dir = FXFileDialog.getOpenDirectory(self, "Open certificate directory", ".")
847
 
    unless dir.empty?
848
 
      begin
849
 
        @cert_store = CertStore.new(dir)
850
 
      rescue
851
 
        show_error($!)
852
 
      end
853
 
      show_init
854
 
    end
855
 
    1
856
 
  end
857
 
 
858
 
  def on_cmd_tool_verify(sender, sel, ptr)
859
 
    dialog = FXFileDialog.new(self, "Verify certificate")
860
 
    dialog.filename = ''
861
 
    dialog.patternList = ["All Files (*)", "PEM formatted certificate (*.pem)"]
862
 
    dialog.currentPattern = @verify_filter
863
 
    if dialog.execute != 0
864
 
      @verify_filename = dialog.filename
865
 
      verify(@verify_filename)
866
 
    end
867
 
    @verify_filter = dialog.currentPattern
868
 
    1
869
 
  end
870
 
 
871
 
  def on_cmd_tool_request(sender, sel, ptr)
872
 
    dialog = FXFileDialog.new(self, "Show request")
873
 
    dialog.filename = ''
874
 
    dialog.patternList = ["All Files (*)", "PEM formatted certificate (*.pem)"]
875
 
    if dialog.execute != 0
876
 
      req = @cert_store.generate_cert(dialog.filename)
877
 
      show_request(req)
878
 
    end
879
 
    1
880
 
  end
881
 
 
882
 
  def verify_certfile(filename)
883
 
    begin
884
 
      cert = @cert_store.generate_cert(filename)
885
 
      result = @cert_store.verify(cert)
886
 
      @cert_store.scan_certs
887
 
      result
888
 
    rescue
889
 
      show_error($!)
890
 
      []
891
 
    end
892
 
  end
893
 
 
894
 
  def show_error(e)
895
 
    msg = e.inspect + "\n" + e.backtrace.join("\n")
896
 
    FXMessageBox.error(self, MBOX_OK, "Error", msg)
897
 
  end
898
 
end
899
 
 
900
 
getopts nil, "cert:"
901
 
 
902
 
certs_dir = ARGV.shift or raise "#{$0} cert_dir"
903
 
certfile = $OPT_cert
904
 
app = FXApp.new("CertStore", "FoxTest")
905
 
cert_store = CertStore.new(certs_dir)
906
 
w = CertStoreView.new(app, cert_store)
907
 
app.create
908
 
if certfile
909
 
  w.verify(certfile)
910
 
end
911
 
app.run