aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cunnie <brian.cunnie@gmail.com>2018-01-29 20:08:49 -0800
committerBrian Cunnie <brian.cunnie@gmail.com>2018-02-06 06:37:50 -0800
commit9322a104d16b02c7a79f9ab589859c9d63fabf52 (patch)
treeea63f2d604f0e23b7990ef4e55d82bff04113548
parentf707996f80ab5e63fd584d576b9a39f091b22dca (diff)
downloadruby-openssl-9322a104d16b02c7a79f9ab589859c9d63fabf52.tar.gz
Correctly verify abbreviated IPv6 SANs
IPv6 SAN-verification accommodates ["zero-compression"](https://tools.ietf.org/html/rfc5952#section-2.2). It also accommodates non-compressed addresses. Previously the verification of IPv6 addresses would fail unless the address syntax matched a specific format (no zero-compression, no leading zeroes). As an example, the IPv6 loopback address, if represented as `::1`, would not verify. Nor would it verify if represented as `0000:0000:0000:0000:0000:0000:0000:0001`; however, both representations are valid, RFC-compliant representations. The library would only accept a very specific representation (i.e. `0:0:0:0:0:0:0:1`). This commit addresses that shortcoming, and ensures that any valid IPv6 representation will correctly verify.
-rw-r--r--lib/openssl/ssl.rb11
-rw-r--r--openssl.gemspec1
-rw-r--r--test/test_ssl.rb6
3 files changed, 12 insertions, 6 deletions
diff --git a/lib/openssl/ssl.rb b/lib/openssl/ssl.rb
index 6a6f2b94..355eb2eb 100644
--- a/lib/openssl/ssl.rb
+++ b/lib/openssl/ssl.rb
@@ -12,6 +12,7 @@
require "openssl/buffering"
require "io/nonblock"
+require "ipaddr"
module OpenSSL
module SSL
@@ -272,11 +273,11 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
return true if verify_hostname(hostname, san.value)
when 7 # iPAddress in GeneralName (RFC5280)
should_verify_common_name = false
- # follows GENERAL_NAME_print() in x509v3/v3_alt.c
- if san.value.size == 4
- return true if san.value.unpack('C*').join('.') == hostname
- elsif san.value.size == 16
- return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
+ if san.value.size == 4 || san.value.size == 16
+ begin
+ return true if san.value == IPAddr.new(hostname).hton
+ rescue IPAddr::InvalidAddressError
+ end
end
end
}
diff --git a/openssl.gemspec b/openssl.gemspec
index 40525c4a..4896eac3 100644
--- a/openssl.gemspec
+++ b/openssl.gemspec
@@ -17,6 +17,7 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = ">= 2.3.0"
+ spec.add_runtime_dependency "ipaddr"
spec.add_development_dependency "rake"
spec.add_development_dependency "rake-compiler"
spec.add_development_dependency "test-unit", "~> 3.0"
diff --git a/test/test_ssl.rb b/test/test_ssl.rb
index 3b063d2e..186de27d 100644
--- a/test/test_ssl.rb
+++ b/test/test_ssl.rb
@@ -516,8 +516,12 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
assert_equal(true, OpenSSL::SSL.verify_certificate_identity(cert, "www.example.com\0.evil.com"))
assert_equal(false, OpenSSL::SSL.verify_certificate_identity(cert, '192.168.7.255'))
assert_equal(true, OpenSSL::SSL.verify_certificate_identity(cert, '192.168.7.1'))
- assert_equal(false, OpenSSL::SSL.verify_certificate_identity(cert, '13::17'))
+ assert_equal(true, OpenSSL::SSL.verify_certificate_identity(cert, '13::17'))
+ assert_equal(false, OpenSSL::SSL.verify_certificate_identity(cert, '13::18'))
assert_equal(true, OpenSSL::SSL.verify_certificate_identity(cert, '13:0:0:0:0:0:0:17'))
+ assert_equal(false, OpenSSL::SSL.verify_certificate_identity(cert, '44:0:0:0:0:0:0:17'))
+ assert_equal(true, OpenSSL::SSL.verify_certificate_identity(cert, '0013:0000:0000:0000:0000:0000:0000:0017'))
+ assert_equal(false, OpenSSL::SSL.verify_certificate_identity(cert, '1313:0000:0000:0000:0000:0000:0000:0017'))
end
end