@@ -359,6 +359,156 @@ def test_verify_certificate_identity
359
359
end
360
360
end
361
361
362
+ def test_verify_hostname
363
+ assert_equal ( true , OpenSSL ::SSL . verify_hostname ( "www.example.com" , "*.example.com" ) )
364
+ assert_equal ( false , OpenSSL ::SSL . verify_hostname ( "www.subdomain.example.com" , "*.example.com" ) )
365
+ end
366
+
367
+ def test_verify_wildcard
368
+ assert_equal ( false , OpenSSL ::SSL . verify_wildcard ( "foo" , "x*" ) )
369
+ assert_equal ( true , OpenSSL ::SSL . verify_wildcard ( "foo" , "foo" ) )
370
+ assert_equal ( true , OpenSSL ::SSL . verify_wildcard ( "foo" , "f*" ) )
371
+ assert_equal ( true , OpenSSL ::SSL . verify_wildcard ( "foo" , "*" ) )
372
+ assert_equal ( false , OpenSSL ::SSL . verify_wildcard ( "abc*bcd" , "abcd" ) )
373
+ assert_equal ( false , OpenSSL ::SSL . verify_wildcard ( "xn--qdk4b9b" , "x*" ) )
374
+ assert_equal ( false , OpenSSL ::SSL . verify_wildcard ( "xn--qdk4b9b" , "*--qdk4b9b" ) )
375
+ assert_equal ( true , OpenSSL ::SSL . verify_wildcard ( "xn--qdk4b9b" , "xn--qdk4b9b" ) )
376
+ end
377
+
378
+ # Comments in this test is excerpted from http://tools.ietf.org/html/rfc6125#page-27
379
+ def test_post_connection_check_wildcard_san
380
+ # case-insensitive ASCII comparison
381
+ # RFC 6125, section 6.4.1
382
+ #
383
+ # "..matching of the reference identifier against the presented identifier
384
+ # is performed by comparing the set of domain name labels using a
385
+ # case-insensitive ASCII comparison, as clarified by [DNS-CASE] (e.g.,
386
+ # "WWW.Example.Com" would be lower-cased to "www.example.com" for
387
+ # comparison purposes)
388
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
389
+ create_cert_with_san ( 'DNS:*.example.com' ) , 'www.example.com' ) )
390
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
391
+ create_cert_with_san ( 'DNS:*.Example.COM' ) , 'www.example.com' ) )
392
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
393
+ create_cert_with_san ( 'DNS:*.example.com' ) , 'WWW.Example.COM' ) )
394
+ # 1. The client SHOULD NOT attempt to match a presented identifier in
395
+ # which the wildcard character comprises a label other than the
396
+ # left-most label (e.g., do not match bar.*.example.net).
397
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
398
+ create_cert_with_san ( 'DNS:www.*.com' ) , 'www.example.com' ) )
399
+ # 2. If the wildcard character is the only character of the left-most
400
+ # label in the presented identifier, the client SHOULD NOT compare
401
+ # against anything but the left-most label of the reference
402
+ # identifier (e.g., *.example.com would match foo.example.com but
403
+ # not bar.foo.example.com or example.com).
404
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
405
+ create_cert_with_san ( 'DNS:*.example.com' ) , 'foo.example.com' ) )
406
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
407
+ create_cert_with_san ( 'DNS:*.example.com' ) , 'bar.foo.example.com' ) )
408
+ # 3. The client MAY match a presented identifier in which the wildcard
409
+ # character is not the only character of the label (e.g.,
410
+ # baz*.example.net and *baz.example.net and b*z.example.net would
411
+ # be taken to match baz1.example.net and foobaz.example.net and
412
+ # buzz.example.net, respectively). ...
413
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
414
+ create_cert_with_san ( 'DNS:baz*.example.com' ) , 'baz1.example.com' ) )
415
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
416
+ create_cert_with_san ( 'DNS:*baz.example.com' ) , 'foobaz.example.com' ) )
417
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
418
+ create_cert_with_san ( 'DNS:b*z.example.com' ) , 'buzz.example.com' ) )
419
+ # Section 6.4.3 of RFC6125 states that client should NOT match identifier
420
+ # where wildcard is other than left-most label.
421
+ #
422
+ # Also implicitly mentions the wildcard character only in singular form,
423
+ # and discourages matching against more than one wildcard.
424
+ #
425
+ # See RFC 6125, section 7.2, subitem 2.
426
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
427
+ create_cert_with_san ( 'DNS:*b*.example.com' ) , 'abc.example.com' ) )
428
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
429
+ create_cert_with_san ( 'DNS:*b*.example.com' ) , 'ab.example.com' ) )
430
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
431
+ create_cert_with_san ( 'DNS:*b*.example.com' ) , 'bc.example.com' ) )
432
+ # ... However, the client SHOULD NOT
433
+ # attempt to match a presented identifier where the wildcard
434
+ # character is embedded within an A-label or U-label [IDNA-DEFS] of
435
+ # an internationalized domain name [IDNA-PROTO].
436
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
437
+ create_cert_with_san ( 'DNS:xn*.example.com' ) , 'xn1ca.example.com' ) )
438
+ # part of A-label
439
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
440
+ create_cert_with_san ( 'DNS:xn--*.example.com' ) , 'xn--1ca.example.com' ) )
441
+ # part of U-label
442
+ # dNSName in RFC5280 is an IA5String so U-label should NOT be allowed
443
+ # regardless of wildcard.
444
+ #
445
+ # See Section 7.2 of RFC 5280:
446
+ # IA5String is limited to the set of ASCII characters.
447
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
448
+ create_cert_with_san ( 'DNS:á*.example.com' ) , 'á1.example.com' ) )
449
+ end
450
+
451
+ def test_post_connection_check_wildcard_cn
452
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
453
+ create_cert_with_name ( '*.example.com' ) , 'www.example.com' ) )
454
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
455
+ create_cert_with_name ( '*.Example.COM' ) , 'www.example.com' ) )
456
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
457
+ create_cert_with_name ( '*.example.com' ) , 'WWW.Example.COM' ) )
458
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
459
+ create_cert_with_name ( 'www.*.com' ) , 'www.example.com' ) )
460
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
461
+ create_cert_with_name ( '*.example.com' ) , 'foo.example.com' ) )
462
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
463
+ create_cert_with_name ( '*.example.com' ) , 'bar.foo.example.com' ) )
464
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
465
+ create_cert_with_name ( 'baz*.example.com' ) , 'baz1.example.com' ) )
466
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
467
+ create_cert_with_name ( '*baz.example.com' ) , 'foobaz.example.com' ) )
468
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
469
+ create_cert_with_name ( 'b*z.example.com' ) , 'buzz.example.com' ) )
470
+ # Section 6.4.3 of RFC6125 states that client should NOT match identifier
471
+ # where wildcard is other than left-most label.
472
+ #
473
+ # Also implicitly mentions the wildcard character only in singular form,
474
+ # and discourages matching against more than one wildcard.
475
+ #
476
+ # See RFC 6125, section 7.2, subitem 2.
477
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
478
+ create_cert_with_name ( '*b*.example.com' ) , 'abc.example.com' ) )
479
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
480
+ create_cert_with_name ( '*b*.example.com' ) , 'ab.example.com' ) )
481
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
482
+ create_cert_with_name ( '*b*.example.com' ) , 'bc.example.com' ) )
483
+ assert_equal ( true , OpenSSL ::SSL . verify_certificate_identity (
484
+ create_cert_with_name ( 'xn*.example.com' ) , 'xn1ca.example.com' ) )
485
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
486
+ create_cert_with_name ( 'xn--*.example.com' ) , 'xn--1ca.example.com' ) )
487
+ # part of U-label
488
+ # Subject in RFC5280 states case-insensitive ASCII comparison.
489
+ #
490
+ # See Section 7.2 of RFC 5280:
491
+ # IA5String is limited to the set of ASCII characters.
492
+ assert_equal ( false , OpenSSL ::SSL . verify_certificate_identity (
493
+ create_cert_with_name ( 'á*.example.com' ) , 'á1.example.com' ) )
494
+ end
495
+
496
+ def create_cert_with_san ( san )
497
+ ef = OpenSSL ::X509 ::ExtensionFactory . new
498
+ cert = OpenSSL ::X509 ::Certificate . new
499
+ cert . subject = OpenSSL ::X509 ::Name . parse ( "/DC=some/DC=site/CN=Some Site" )
500
+ ext = ef . create_ext ( 'subjectAltName' , san )
501
+ cert . add_extension ( ext )
502
+ cert
503
+ end
504
+
505
+ def create_cert_with_name ( name )
506
+ cert = OpenSSL ::X509 ::Certificate . new
507
+ cert . subject = OpenSSL ::X509 ::Name . new ( [ [ 'DC' , 'some' ] , [ 'DC' , 'site' ] , [ 'CN' , name ] ] )
508
+ cert
509
+ end
510
+
511
+
362
512
# Create NULL byte SAN certificate
363
513
def create_null_byte_SAN_certificate ( critical = false )
364
514
ef = OpenSSL ::X509 ::ExtensionFactory . new
0 commit comments