~ubuntu-branches/ubuntu/hardy/ruby1.8/hardy-updates

« back to all changes in this revision

Viewing changes to ext/openssl/lib/openssl/x509.rb

  • Committer: Bazaar Package Importer
  • Author(s): akira yamada
  • Date: 2007-03-13 22:11:58 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070313221158-h3oql37brlaf2go2
Tags: 1.8.6-1
* new upstream version, 1.8.6.
* libruby1.8 conflicts with libopenssl-ruby1.8 (< 1.8.6) (closes: #410018)
* changed packaging style to cdbs from dbs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
=begin
 
2
= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses
 
3
 
 
4
= Info
 
5
  'OpenSSL for Ruby 2' project
 
6
  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
 
7
  All rights reserved.
 
8
 
 
9
= Licence
 
10
  This program is licenced under the same licence as Ruby.
 
11
  (See the file 'LICENCE'.)
 
12
 
 
13
= Version
 
14
  $Id: x509.rb 11708 2007-02-12 23:01:19Z shyouhei $
 
15
=end
 
16
 
 
17
require "openssl"
 
18
 
 
19
module OpenSSL
 
20
  module X509
 
21
    class ExtensionFactory
 
22
      def create_extension(*arg)
 
23
        if arg.size > 1
 
24
          create_ext(*arg)
 
25
        else
 
26
          send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
 
27
        end
 
28
      end
 
29
 
 
30
      def create_ext_from_array(ary)
 
31
        raise ExtensionError, "unexpected array form" if ary.size > 3 
 
32
        create_ext(ary[0], ary[1], ary[2])
 
33
      end
 
34
 
 
35
      def create_ext_from_string(str) # "oid = critical, value"
 
36
        oid, value = str.split(/=/, 2)
 
37
        oid.strip!
 
38
        value.strip!
 
39
        create_ext(oid, value)
 
40
      end
 
41
      
 
42
      def create_ext_from_hash(hash)
 
43
        create_ext(hash["oid"], hash["value"], hash["critical"])
 
44
      end
 
45
    end
 
46
    
 
47
    class Extension
 
48
      def to_s # "oid = critical, value"
 
49
        str = self.oid
 
50
        str << " = "
 
51
        str << "critical, " if self.critical?
 
52
        str << self.value.gsub(/\n/, ", ")
 
53
      end
 
54
        
 
55
      def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
 
56
        {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
 
57
      end
 
58
 
 
59
      def to_a
 
60
        [ self.oid, self.value, self.critical? ]
 
61
      end
 
62
    end
 
63
 
 
64
    class Name
 
65
      module RFC2253DN
 
66
        Special = ',=+<>#;'
 
67
        HexChar = /[0-9a-fA-F]/
 
68
        HexPair = /#{HexChar}#{HexChar}/
 
69
        HexString = /#{HexPair}+/
 
70
        Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
 
71
        StringChar = /[^#{Special}\\"]/
 
72
        QuoteChar = /[^\\"]/
 
73
        AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
 
74
        AttributeValue = /
 
75
          (?!["#])((?:#{StringChar}|#{Pair})*)|
 
76
          \#(#{HexString})|
 
77
          "((?:#{QuoteChar}|#{Pair})*)"
 
78
        /x
 
79
        TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/
 
80
 
 
81
        module_function
 
82
 
 
83
        def expand_pair(str)
 
84
          return nil unless str
 
85
          return str.gsub(Pair){|pair|
 
86
            case pair.size
 
87
            when 2 then pair[1,1]
 
88
            when 3 then Integer("0x#{pair[1,2]}").chr
 
89
            else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
 
90
            end
 
91
          }
 
92
        end
 
93
 
 
94
        def expand_hexstring(str)
 
95
          return nil unless str
 
96
          der = str.gsub(HexPair){|hex| Integer("0x#{hex}").chr }
 
97
          a1 = OpenSSL::ASN1.decode(der)
 
98
          return a1.value, a1.tag
 
99
        end
 
100
 
 
101
        def expand_value(str1, str2, str3)
 
102
          value = expand_pair(str1)
 
103
          value, tag = expand_hexstring(str2) unless value
 
104
          value = expand_pair(str3) unless value
 
105
          return value, tag
 
106
        end
 
107
 
 
108
        def scan(dn)
 
109
          str = dn
 
110
          ary = []
 
111
          while true
 
112
            if md = TypeAndValue.match(str)
 
113
              matched = md.to_s
 
114
              remain = md.post_match
 
115
              type = md[1]
 
116
              value, tag = expand_value(md[2], md[3], md[4]) rescue nil
 
117
              if value
 
118
                type_and_value = [type, value]
 
119
                type_and_value.push(tag) if tag
 
120
                ary.unshift(type_and_value)
 
121
                if remain.length > 2 && remain[0] == ?,
 
122
                  str = remain[1..-1]
 
123
                  next
 
124
                elsif remain.length > 2 && remain[0] == ?+
 
125
                  raise OpenSSL::X509::NameError,
 
126
                    "multi-valued RDN is not supported: #{dn}"
 
127
                elsif remain.empty?
 
128
                  break
 
129
                end
 
130
              end
 
131
            end
 
132
            msg_dn = dn[0, dn.length - str.length] + " =>" + str
 
133
            raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
 
134
          end
 
135
          return ary
 
136
        end
 
137
      end
 
138
 
 
139
      class <<self
 
140
        def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
 
141
          ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
 
142
          self.new(ary, template)
 
143
        end
 
144
 
 
145
        def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
 
146
          ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
 
147
          self.new(ary, template)
 
148
        end
 
149
 
 
150
        alias parse parse_openssl
 
151
      end
 
152
    end
 
153
  end
 
154
end