@@ -118,4 +118,269 @@ def test_hash_old
118118 assert_equal 3294068023 , name . hash_old
119119 end
120120
121+ def setup
122+ super
123+ @obj_type_tmpl = Hash . new ( OpenSSL ::ASN1 ::PRINTABLESTRING )
124+ @obj_type_tmpl . update ( OpenSSL ::X509 ::Name ::OBJECT_TYPE_TEMPLATE )
125+ end
126+
127+ def test_s_new
128+ dn = [ [ "C" , "JP" ] , [ "O" , "example" ] , [ "CN" , "www.example.jp" ] ]
129+ name = OpenSSL ::X509 ::Name . new ( dn )
130+ ary = name . to_a
131+ assert_equal ( "/C=JP/O=example/CN=www.example.jp" , name . to_s )
132+ assert_equal ( "C" , ary [ 0 ] [ 0 ] )
133+ assert_equal ( "O" , ary [ 1 ] [ 0 ] )
134+ assert_equal ( "CN" , ary [ 2 ] [ 0 ] )
135+ assert_equal ( "JP" , ary [ 0 ] [ 1 ] )
136+ assert_equal ( "example" , ary [ 1 ] [ 1 ] )
137+ assert_equal ( "www.example.jp" , ary [ 2 ] [ 1 ] )
138+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 0 ] [ 2 ] )
139+ assert_equal ( OpenSSL ::ASN1 ::UTF8STRING , ary [ 1 ] [ 2 ] )
140+ assert_equal ( OpenSSL ::ASN1 ::UTF8STRING , ary [ 2 ] [ 2 ] )
141+
142+ dn = [
143+ [ "countryName" , "JP" ] ,
144+ [ "organizationName" , "example" ] ,
145+ [ "commonName" , "www.example.jp" ]
146+ ]
147+ name = OpenSSL ::X509 ::Name . new ( dn )
148+ ary = name . to_a
149+ assert_equal ( "/C=JP/O=example/CN=www.example.jp" , name . to_s )
150+ assert_equal ( "C" , ary [ 0 ] [ 0 ] )
151+ assert_equal ( "O" , ary [ 1 ] [ 0 ] )
152+ assert_equal ( "CN" , ary [ 2 ] [ 0 ] )
153+ assert_equal ( "JP" , ary [ 0 ] [ 1 ] )
154+ assert_equal ( "example" , ary [ 1 ] [ 1 ] )
155+ assert_equal ( "www.example.jp" , ary [ 2 ] [ 1 ] )
156+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 0 ] [ 2 ] )
157+ assert_equal ( OpenSSL ::ASN1 ::UTF8STRING , ary [ 1 ] [ 2 ] )
158+ assert_equal ( OpenSSL ::ASN1 ::UTF8STRING , ary [ 2 ] [ 2 ] )
159+
160+ name = OpenSSL ::X509 ::Name . new ( dn , @obj_type_tmpl )
161+ ary = name . to_a
162+ assert_equal ( "/C=JP/O=example/CN=www.example.jp" , name . to_s )
163+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 0 ] [ 2 ] )
164+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 1 ] [ 2 ] )
165+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 2 ] [ 2 ] )
166+
167+ dn = [
168+ [ "countryName" , "JP" , OpenSSL ::ASN1 ::PRINTABLESTRING ] ,
169+ [ "organizationName" , "example" , OpenSSL ::ASN1 ::PRINTABLESTRING ] ,
170+ [ "commonName" , "www.example.jp" , OpenSSL ::ASN1 ::PRINTABLESTRING ]
171+ ]
172+ name = OpenSSL ::X509 ::Name . new ( dn )
173+ ary = name . to_a
174+ assert_equal ( "/C=JP/O=example/CN=www.example.jp" , name . to_s )
175+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 0 ] [ 2 ] )
176+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 1 ] [ 2 ] )
177+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 2 ] [ 2 ] )
178+
179+ dn = [
180+ [ "DC" , "org" ] ,
181+ [ "DC" , "ruby-lang" ] ,
182+ [ "CN" , "GOTOU Yuuzou" ] ,
183+ [ "emailAddress" , "gotoyuzo@ruby-lang.org" ] ,
184+ [ "serialNumber" , "123" ] ,
185+ ]
186+ name = OpenSSL ::X509 ::Name . new ( dn )
187+ ary = name . to_a
188+ assert_equal ( "/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123" , name . to_s )
189+ assert_equal ( "DC" , ary [ 0 ] [ 0 ] )
190+ assert_equal ( "DC" , ary [ 1 ] [ 0 ] )
191+ assert_equal ( "CN" , ary [ 2 ] [ 0 ] )
192+ assert_equal ( "emailAddress" , ary [ 3 ] [ 0 ] )
193+ assert_equal ( "serialNumber" , ary [ 4 ] [ 0 ] )
194+ assert_equal ( "org" , ary [ 0 ] [ 1 ] )
195+ assert_equal ( "ruby-lang" , ary [ 1 ] [ 1 ] )
196+ assert_equal ( "GOTOU Yuuzou" , ary [ 2 ] [ 1 ] )
197+ assert_equal ( "gotoyuzo@ruby-lang.org" , ary [ 3 ] [ 1 ] )
198+ assert_equal ( "123" , ary [ 4 ] [ 1 ] )
199+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 0 ] [ 2 ] )
200+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 1 ] [ 2 ] )
201+ assert_equal ( OpenSSL ::ASN1 ::UTF8STRING , ary [ 2 ] [ 2 ] )
202+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 3 ] [ 2 ] )
203+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 4 ] [ 2 ] )
204+
205+ name_from_der = OpenSSL ::X509 ::Name . new ( name . to_der )
206+ assert_equal ( name_from_der . to_s , name . to_s )
207+ assert_equal ( name_from_der . to_a , name . to_a )
208+ assert_equal ( name_from_der . to_der , name . to_der )
209+ end
210+
211+ def test_unrecognized_oid_parse_encode_equality
212+ dn = [ [ "1.2.3.4.5.6.7.8.9.7.5.3.2" , "Unknown OID1" ] ,
213+ [ "1.1.2.3.5.8.13.21.35" , "Unknown OID2" ] ,
214+ [ "C" , "US" ] ,
215+ [ "postalCode" , "60602" ] ,
216+ [ "ST" , "Illinois" ] ,
217+ [ "L" , "Chicago" ] ,
218+ #["street", "123 Fake St"],
219+ [ "O" , "Some Company LLC" ] ,
220+ [ "CN" , "mydomain.com" ] ]
221+
222+ name1 = OpenSSL ::X509 ::Name . new ( dn )
223+ name2 = OpenSSL ::X509 ::Name . parse ( name1 . to_s )
224+ assert_equal ( name1 . to_s , name2 . to_s )
225+ assert_equal ( name1 . to_a , name2 . to_a )
226+ end
227+
228+ def test_s_parse
229+ dn = "/DC=org/DC=ruby-lang/CN=www.ruby-lang.org/1.2.3.4.5.6=A=BCD"
230+ name = OpenSSL ::X509 ::Name . parse ( dn )
231+ assert_equal ( dn , name . to_s )
232+ ary = name . to_a
233+ assert_equal [
234+ [ "DC" , "org" , OpenSSL ::ASN1 ::IA5STRING ] ,
235+ [ "DC" , "ruby-lang" , OpenSSL ::ASN1 ::IA5STRING ] ,
236+ [ "CN" , "www.ruby-lang.org" , OpenSSL ::ASN1 ::UTF8STRING ] ,
237+ [ "1.2.3.4.5.6" , "A=BCD" , OpenSSL ::ASN1 ::UTF8STRING ] ,
238+ ] , ary
239+
240+ dn2 = "DC=org, DC=ruby-lang, CN=www.ruby-lang.org, 1.2.3.4.5.6=A=BCD"
241+ name = OpenSSL ::X509 ::Name . parse ( dn2 )
242+ assert_equal ( dn , name . to_s )
243+ assert_equal ary , name . to_a
244+
245+ name = OpenSSL ::X509 ::Name . parse ( dn2 , @obj_type_tmpl )
246+ ary = name . to_a
247+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 0 ] [ 2 ] )
248+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 1 ] [ 2 ] )
249+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 2 ] [ 2 ] )
250+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 3 ] [ 2 ] )
251+ end
252+
253+ def test_s_parse_rfc2253
254+ scanner = OpenSSL ::X509 ::Name ::RFC2253DN . method ( :scan )
255+
256+ assert_equal ( [ [ "C" , "JP" ] ] , scanner . call ( "C=JP" ) )
257+ assert_equal ( [
258+ [ "DC" , "org" ] ,
259+ [ "DC" , "ruby-lang" ] ,
260+ [ "CN" , "GOTOU Yuuzou" ] ,
261+ [ "emailAddress" , "gotoyuzo@ruby-lang.org" ] ,
262+ ] ,
263+ scanner . call (
264+ "emailAddress=gotoyuzo@ruby-lang.org,CN=GOTOU Yuuzou," +
265+ "DC=ruby-lang,DC=org" )
266+ )
267+
268+ dn = "CN=www.ruby-lang.org,DC=ruby-lang,DC=org"
269+ name = OpenSSL ::X509 ::Name . parse_rfc2253 ( dn )
270+ assert_equal ( dn , name . to_s ( OpenSSL ::X509 ::Name ::RFC2253 ) )
271+ ary = name . to_a
272+ assert_equal ( "DC" , ary [ 0 ] [ 0 ] )
273+ assert_equal ( "DC" , ary [ 1 ] [ 0 ] )
274+ assert_equal ( "CN" , ary [ 2 ] [ 0 ] )
275+ assert_equal ( "org" , ary [ 0 ] [ 1 ] )
276+ assert_equal ( "ruby-lang" , ary [ 1 ] [ 1 ] )
277+ assert_equal ( "www.ruby-lang.org" , ary [ 2 ] [ 1 ] )
278+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 0 ] [ 2 ] )
279+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 1 ] [ 2 ] )
280+ assert_equal ( OpenSSL ::ASN1 ::UTF8STRING , ary [ 2 ] [ 2 ] )
281+ end
282+
283+ def test_add_entry
284+ dn = [
285+ [ "DC" , "org" ] ,
286+ [ "DC" , "ruby-lang" ] ,
287+ [ "CN" , "GOTOU Yuuzou" ] ,
288+ [ "emailAddress" , "gotoyuzo@ruby-lang.org" ] ,
289+ [ "serialNumber" , "123" ] ,
290+ ]
291+ name = OpenSSL ::X509 ::Name . new
292+ dn . each { |attr | name . add_entry ( *attr ) }
293+ ary = name . to_a
294+ assert_equal ( "/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123" , name . to_s )
295+ assert_equal ( "DC" , ary [ 0 ] [ 0 ] )
296+ assert_equal ( "DC" , ary [ 1 ] [ 0 ] )
297+ assert_equal ( "CN" , ary [ 2 ] [ 0 ] )
298+ assert_equal ( "emailAddress" , ary [ 3 ] [ 0 ] )
299+ assert_equal ( "serialNumber" , ary [ 4 ] [ 0 ] )
300+ assert_equal ( "org" , ary [ 0 ] [ 1 ] )
301+ assert_equal ( "ruby-lang" , ary [ 1 ] [ 1 ] )
302+ assert_equal ( "GOTOU Yuuzou" , ary [ 2 ] [ 1 ] )
303+ assert_equal ( "gotoyuzo@ruby-lang.org" , ary [ 3 ] [ 1 ] )
304+ assert_equal ( "123" , ary [ 4 ] [ 1 ] )
305+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 0 ] [ 2 ] )
306+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 1 ] [ 2 ] )
307+ assert_equal ( OpenSSL ::ASN1 ::UTF8STRING , ary [ 2 ] [ 2 ] )
308+ assert_equal ( OpenSSL ::ASN1 ::IA5STRING , ary [ 3 ] [ 2 ] )
309+ assert_equal ( OpenSSL ::ASN1 ::PRINTABLESTRING , ary [ 4 ] [ 2 ] )
310+ end
311+
312+ def test_add_entry_street
313+ # openssl/crypto/objects/obj_mac.h 1.83
314+ dn = [
315+ [ "DC" , "org" ] ,
316+ [ "DC" , "ruby-lang" ] ,
317+ [ "CN" , "GOTOU Yuuzou" ] ,
318+ [ "emailAddress" , "gotoyuzo@ruby-lang.org" ] ,
319+ [ "serialNumber" , "123" ] ,
320+ [ "street" , "Namiki" ] ,
321+ ]
322+ name = OpenSSL ::X509 ::Name . new
323+ dn . each { |attr | name . add_entry ( *attr ) }
324+ ary = name . to_a
325+ assert_equal ( "/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123/street=Namiki" , name . to_s )
326+ assert_equal ( "Namiki" , ary [ 5 ] [ 1 ] )
327+ end
328+
329+ ###
330+
331+ def test_integration
332+ key = OpenSSL ::PKey ::RSA . new ( 4096 )
333+
334+ subject = "/C=FR/ST=IDF/L=PARIS/O=Company/CN=myhost.example"
335+
336+ cert = OpenSSL ::X509 ::Certificate . new
337+
338+ fields = [ ]
339+ OpenSSL ::X509 ::Name . parse ( subject ) . to_a . each do |field |
340+ fields << [ field [ 0 ] , field [ 1 ] , OpenSSL ::ASN1 ::PRINTABLESTRING ]
341+ end
342+
343+ subject_x509 = OpenSSL ::X509 ::Name . new ( fields )
344+
345+ assert_equal '#<OpenSSL::X509::Name CN=myhost.example,O=Company,L=PARIS,ST=IDF,C=FR>' , subject_x509 . inspect
346+
347+ cert . subject = cert . issuer = subject_x509
348+
349+ cert . not_before = Time . now
350+ cert . not_after = Time . now + 365 *24 *60 *60
351+ cert . public_key = key . public_key
352+ cert . serial = 0x0
353+ cert . version = 2
354+
355+ ef = OpenSSL ::X509 ::ExtensionFactory . new
356+ ef . subject_certificate = ef . issuer_certificate = cert
357+
358+ cert . add_extension ef . create_extension ( 'basicConstraints' , 'CA:FALSE' , true )
359+ cert . add_extension ef . create_extension ( 'keyUsage' , 'keyEncipherment,dataEncipherment,digitalSignature' )
360+ cert . add_extension ef . create_extension ( 'subjectKeyIdentifier' , 'hash' )
361+ cert . add_extension ef . create_extension ( 'authorityKeyIdentifier' , 'keyid:always,issuer:always' )
362+
363+ cert . sign key , OpenSSL ::Digest ::SHA256 . new
364+
365+ asn1 = OpenSSL ::ASN1 . decode ( cert . to_der )
366+
367+ print_asn_strings ( asn1 )
368+ end
369+
370+ private
371+
372+ def print_asn_strings ( obj , depth = 0 )
373+ if obj . respond_to? :each
374+ obj . each do |item |
375+ print_asn_strings ( item , depth + 1 )
376+ end
377+ else
378+ # printf("%-40s %s\n", obj.value, obj.class)
379+ assert_equal OpenSSL ::ASN1 ::PrintableString , obj . class if (
380+ obj . class . to_s . match ( /String/ ) && obj . class != OpenSSL ::ASN1 ::BitString
381+ )
382+ end
383+ nil
384+ end
385+
121386end
0 commit comments