openssl 2.1.4 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +9 -7
- data/History.md +100 -0
- data/README.md +2 -2
- data/ext/openssl/extconf.rb +24 -15
- data/ext/openssl/openssl_missing.h +36 -1
- data/ext/openssl/ossl.c +58 -25
- data/ext/openssl/ossl.h +7 -4
- data/ext/openssl/ossl_asn1.c +25 -0
- data/ext/openssl/ossl_bn.c +65 -10
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +33 -24
- data/ext/openssl/ossl_digest.c +16 -51
- data/ext/openssl/ossl_engine.c +2 -12
- data/ext/openssl/ossl_hmac.c +5 -11
- data/ext/openssl/ossl_kdf.c +3 -19
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +6 -11
- data/ext/openssl/ossl_ocsp.h +3 -3
- data/ext/openssl/ossl_pkcs7.c +3 -19
- data/ext/openssl/ossl_pkcs7.h +16 -0
- data/ext/openssl/ossl_pkey.c +180 -14
- data/ext/openssl/ossl_pkey_dsa.c +2 -2
- data/ext/openssl/ossl_pkey_ec.c +29 -0
- data/ext/openssl/ossl_pkey_rsa.c +17 -9
- data/ext/openssl/ossl_rand.c +2 -32
- data/ext/openssl/ossl_ssl.c +94 -42
- data/ext/openssl/ossl_ts.c +1524 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509cert.c +2 -2
- data/ext/openssl/ossl_x509ext.c +14 -0
- data/ext/openssl/ossl_x509name.c +7 -3
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +28 -5
- data/lib/openssl/cipher.rb +1 -1
- data/lib/openssl/config.rb +17 -8
- data/lib/openssl/digest.rb +10 -12
- data/lib/openssl/hmac.rb +13 -0
- data/lib/openssl/marshal.rb +30 -0
- data/lib/openssl/pkcs5.rb +1 -1
- data/lib/openssl/pkey.rb +18 -1
- data/lib/openssl/ssl.rb +40 -2
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +155 -1
- data/lib/openssl.rb +25 -9
- metadata +6 -3
- data/ext/openssl/deprecation.rb +0 -27
- data/ext/openssl/ossl_version.h +0 -15
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* Copyright (C) 2010 Martin Bosslet <Martin.Bosslet@googlemail.com>
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
/*
|
|
7
|
+
* This program is licenced under the same licence as Ruby.
|
|
8
|
+
* (See the file 'LICENCE'.)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#if !defined(_OSSL_TS_H_)
|
|
12
|
+
#define _OSSL_TS_H_
|
|
13
|
+
|
|
14
|
+
void Init_ossl_ts(void);
|
|
15
|
+
|
|
16
|
+
#endif
|
data/ext/openssl/ossl_x509cert.c
CHANGED
|
@@ -788,7 +788,7 @@ Init_ossl_x509cert(void)
|
|
|
788
788
|
* root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
|
|
789
789
|
* root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
|
790
790
|
* root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
|
|
791
|
-
* root_ca.sign(root_key, OpenSSL::Digest
|
|
791
|
+
* root_ca.sign(root_key, OpenSSL::Digest.new('SHA256'))
|
|
792
792
|
*
|
|
793
793
|
* The next step is to create the end-entity certificate using the root CA
|
|
794
794
|
* certificate.
|
|
@@ -807,7 +807,7 @@ Init_ossl_x509cert(void)
|
|
|
807
807
|
* ef.issuer_certificate = root_ca
|
|
808
808
|
* cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
|
|
809
809
|
* cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
|
810
|
-
* cert.sign(root_key, OpenSSL::Digest
|
|
810
|
+
* cert.sign(root_key, OpenSSL::Digest.new('SHA256'))
|
|
811
811
|
*
|
|
812
812
|
*/
|
|
813
813
|
cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
|
data/ext/openssl/ossl_x509ext.c
CHANGED
|
@@ -402,6 +402,19 @@ ossl_x509ext_get_value(VALUE obj)
|
|
|
402
402
|
return ret;
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
+
static VALUE
|
|
406
|
+
ossl_x509ext_get_value_der(VALUE obj)
|
|
407
|
+
{
|
|
408
|
+
X509_EXTENSION *ext;
|
|
409
|
+
ASN1_OCTET_STRING *value;
|
|
410
|
+
|
|
411
|
+
GetX509Ext(obj, ext);
|
|
412
|
+
if ((value = X509_EXTENSION_get_data(ext)) == NULL)
|
|
413
|
+
ossl_raise(eX509ExtError, NULL);
|
|
414
|
+
|
|
415
|
+
return rb_str_new((const char *)value->data, value->length);
|
|
416
|
+
}
|
|
417
|
+
|
|
405
418
|
static VALUE
|
|
406
419
|
ossl_x509ext_get_critical(VALUE obj)
|
|
407
420
|
{
|
|
@@ -472,6 +485,7 @@ Init_ossl_x509ext(void)
|
|
|
472
485
|
rb_define_method(cX509Ext, "critical=", ossl_x509ext_set_critical, 1);
|
|
473
486
|
rb_define_method(cX509Ext, "oid", ossl_x509ext_get_oid, 0);
|
|
474
487
|
rb_define_method(cX509Ext, "value", ossl_x509ext_get_value, 0);
|
|
488
|
+
rb_define_method(cX509Ext, "value_der", ossl_x509ext_get_value_der, 0);
|
|
475
489
|
rb_define_method(cX509Ext, "critical?", ossl_x509ext_get_critical, 0);
|
|
476
490
|
rb_define_method(cX509Ext, "to_der", ossl_x509ext_to_der, 0);
|
|
477
491
|
}
|
data/ext/openssl/ossl_x509name.c
CHANGED
|
@@ -387,17 +387,21 @@ ossl_x509name_cmp0(VALUE self, VALUE other)
|
|
|
387
387
|
|
|
388
388
|
/*
|
|
389
389
|
* call-seq:
|
|
390
|
-
* name.cmp(other) -> -1 | 0 | 1
|
|
391
|
-
* name <=> other -> -1 | 0 | 1
|
|
390
|
+
* name.cmp(other) -> -1 | 0 | 1 | nil
|
|
391
|
+
* name <=> other -> -1 | 0 | 1 | nil
|
|
392
392
|
*
|
|
393
393
|
* Compares this Name with _other_ and returns +0+ if they are the same and +-1+
|
|
394
394
|
* or ++1+ if they are greater or less than each other respectively.
|
|
395
|
+
* Returns +nil+ if they are not comparable (i.e. different types).
|
|
395
396
|
*/
|
|
396
397
|
static VALUE
|
|
397
398
|
ossl_x509name_cmp(VALUE self, VALUE other)
|
|
398
399
|
{
|
|
399
400
|
int result;
|
|
400
401
|
|
|
402
|
+
if (!rb_obj_is_kind_of(other, cX509Name))
|
|
403
|
+
return Qnil;
|
|
404
|
+
|
|
401
405
|
result = ossl_x509name_cmp0(self, other);
|
|
402
406
|
if (result < 0) return INT2FIX(-1);
|
|
403
407
|
if (result > 0) return INT2FIX(1);
|
|
@@ -494,7 +498,7 @@ ossl_x509name_to_der(VALUE self)
|
|
|
494
498
|
* You can create a Name by parsing a distinguished name String or by
|
|
495
499
|
* supplying the distinguished name as an Array.
|
|
496
500
|
*
|
|
497
|
-
* name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
|
|
501
|
+
* name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
|
|
498
502
|
*
|
|
499
503
|
* name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]
|
|
500
504
|
*/
|
data/lib/openssl/bn.rb
CHANGED
data/lib/openssl/buffering.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# coding: binary
|
|
2
|
-
# frozen_string_literal:
|
|
2
|
+
# frozen_string_literal: true
|
|
3
3
|
#--
|
|
4
4
|
#= Info
|
|
5
5
|
# 'OpenSSL for Ruby 2' project
|
|
@@ -22,6 +22,29 @@
|
|
|
22
22
|
module OpenSSL::Buffering
|
|
23
23
|
include Enumerable
|
|
24
24
|
|
|
25
|
+
# A buffer which will retain binary encoding.
|
|
26
|
+
class Buffer < String
|
|
27
|
+
BINARY = Encoding::BINARY
|
|
28
|
+
|
|
29
|
+
def initialize
|
|
30
|
+
super
|
|
31
|
+
|
|
32
|
+
force_encoding(BINARY)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def << string
|
|
36
|
+
if string.encoding == BINARY
|
|
37
|
+
super(string)
|
|
38
|
+
else
|
|
39
|
+
super(string.b)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
return self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
alias concat <<
|
|
46
|
+
end
|
|
47
|
+
|
|
25
48
|
##
|
|
26
49
|
# The "sync mode" of the SSLSocket.
|
|
27
50
|
#
|
|
@@ -40,7 +63,7 @@ module OpenSSL::Buffering
|
|
|
40
63
|
def initialize(*)
|
|
41
64
|
super
|
|
42
65
|
@eof = false
|
|
43
|
-
@rbuffer =
|
|
66
|
+
@rbuffer = Buffer.new
|
|
44
67
|
@sync = @io.sync
|
|
45
68
|
end
|
|
46
69
|
|
|
@@ -312,7 +335,7 @@ module OpenSSL::Buffering
|
|
|
312
335
|
# buffer is flushed to the underlying socket.
|
|
313
336
|
|
|
314
337
|
def do_write(s)
|
|
315
|
-
@wbuffer =
|
|
338
|
+
@wbuffer = Buffer.new unless defined? @wbuffer
|
|
316
339
|
@wbuffer << s
|
|
317
340
|
@wbuffer.force_encoding(Encoding::BINARY)
|
|
318
341
|
@sync ||= false
|
|
@@ -398,7 +421,7 @@ module OpenSSL::Buffering
|
|
|
398
421
|
# See IO#puts for full details.
|
|
399
422
|
|
|
400
423
|
def puts(*args)
|
|
401
|
-
s =
|
|
424
|
+
s = Buffer.new
|
|
402
425
|
if args.empty?
|
|
403
426
|
s << "\n"
|
|
404
427
|
end
|
|
@@ -416,7 +439,7 @@ module OpenSSL::Buffering
|
|
|
416
439
|
# See IO#print for full details.
|
|
417
440
|
|
|
418
441
|
def print(*args)
|
|
419
|
-
s =
|
|
442
|
+
s = Buffer.new
|
|
420
443
|
args.each{ |arg| s << arg.to_s }
|
|
421
444
|
do_write(s)
|
|
422
445
|
nil
|
data/lib/openssl/cipher.rb
CHANGED
data/lib/openssl/config.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal:
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
=begin
|
|
3
3
|
= Ruby-space definitions that completes C-space funcs for Config
|
|
4
4
|
|
|
@@ -37,7 +37,7 @@ module OpenSSL
|
|
|
37
37
|
def parse(string)
|
|
38
38
|
c = new()
|
|
39
39
|
parse_config(StringIO.new(string)).each do |section, hash|
|
|
40
|
-
c
|
|
40
|
+
c.set_section(section, hash)
|
|
41
41
|
end
|
|
42
42
|
c
|
|
43
43
|
end
|
|
@@ -53,9 +53,8 @@ module OpenSSL
|
|
|
53
53
|
def parse_config(io)
|
|
54
54
|
begin
|
|
55
55
|
parse_config_lines(io)
|
|
56
|
-
rescue
|
|
57
|
-
|
|
58
|
-
raise
|
|
56
|
+
rescue => error
|
|
57
|
+
raise ConfigError, "error in line #{io.lineno}: " + error.message
|
|
59
58
|
end
|
|
60
59
|
end
|
|
61
60
|
|
|
@@ -267,7 +266,7 @@ module OpenSSL
|
|
|
267
266
|
if filename
|
|
268
267
|
File.open(filename.to_s) do |file|
|
|
269
268
|
Config.parse_config(file).each do |section, hash|
|
|
270
|
-
|
|
269
|
+
set_section(section, hash)
|
|
271
270
|
end
|
|
272
271
|
end
|
|
273
272
|
end
|
|
@@ -316,6 +315,8 @@ module OpenSSL
|
|
|
316
315
|
end
|
|
317
316
|
|
|
318
317
|
##
|
|
318
|
+
# *Deprecated in v2.2.0*. This method will be removed in a future release.
|
|
319
|
+
#
|
|
319
320
|
# Set the target _key_ with a given _value_ under a specific _section_.
|
|
320
321
|
#
|
|
321
322
|
# Given the following configurating file being loaded:
|
|
@@ -370,6 +371,8 @@ module OpenSSL
|
|
|
370
371
|
end
|
|
371
372
|
|
|
372
373
|
##
|
|
374
|
+
# *Deprecated in v2.2.0*. This method will be removed in a future release.
|
|
375
|
+
#
|
|
373
376
|
# Sets a specific _section_ name with a Hash _pairs_.
|
|
374
377
|
#
|
|
375
378
|
# Given the following configuration being created:
|
|
@@ -395,9 +398,13 @@ module OpenSSL
|
|
|
395
398
|
#
|
|
396
399
|
def []=(section, pairs)
|
|
397
400
|
check_modify
|
|
398
|
-
|
|
401
|
+
set_section(section, pairs)
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def set_section(section, pairs) # :nodoc:
|
|
405
|
+
hash = @data[section] ||= {}
|
|
399
406
|
pairs.each do |key, value|
|
|
400
|
-
|
|
407
|
+
hash[key] = value
|
|
401
408
|
end
|
|
402
409
|
end
|
|
403
410
|
|
|
@@ -482,6 +489,8 @@ module OpenSSL
|
|
|
482
489
|
end
|
|
483
490
|
|
|
484
491
|
def check_modify
|
|
492
|
+
warn "#{caller(2, 1)[0]}: warning: do not modify OpenSSL::Config; this " \
|
|
493
|
+
"method is deprecated and will be removed in a future release."
|
|
485
494
|
raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
|
|
486
495
|
end
|
|
487
496
|
|
data/lib/openssl/digest.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal:
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
#--
|
|
3
3
|
# = Ruby-space predefined Digest subclasses
|
|
4
4
|
#
|
|
@@ -15,11 +15,6 @@
|
|
|
15
15
|
module OpenSSL
|
|
16
16
|
class Digest
|
|
17
17
|
|
|
18
|
-
alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)
|
|
19
|
-
if OPENSSL_VERSION_NUMBER < 0x10100000
|
|
20
|
-
alg += %w(DSS DSS1 SHA)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
18
|
# Return the hash value computed with _name_ Digest. _name_ is either the
|
|
24
19
|
# long name or short name of a supported digest algorithm.
|
|
25
20
|
#
|
|
@@ -29,23 +24,26 @@ module OpenSSL
|
|
|
29
24
|
#
|
|
30
25
|
# which is equivalent to:
|
|
31
26
|
#
|
|
32
|
-
# OpenSSL::Digest
|
|
27
|
+
# OpenSSL::Digest.digest('SHA256', "abc")
|
|
33
28
|
|
|
34
29
|
def self.digest(name, data)
|
|
35
30
|
super(data, name)
|
|
36
31
|
end
|
|
37
32
|
|
|
38
|
-
|
|
33
|
+
%w(MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512).each do |name|
|
|
39
34
|
klass = Class.new(self) {
|
|
40
35
|
define_method(:initialize, ->(data = nil) {super(name, data)})
|
|
41
36
|
}
|
|
37
|
+
|
|
42
38
|
singleton = (class << klass; self; end)
|
|
39
|
+
|
|
43
40
|
singleton.class_eval{
|
|
44
|
-
define_method(:digest){|data| new.digest(data)
|
|
45
|
-
define_method(:hexdigest){|data| new.hexdigest(data)
|
|
41
|
+
define_method(:digest) {|data| new.digest(data)}
|
|
42
|
+
define_method(:hexdigest) {|data| new.hexdigest(data)}
|
|
46
43
|
}
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
|
|
45
|
+
const_set(name.tr('-', '_'), klass)
|
|
46
|
+
end
|
|
49
47
|
|
|
50
48
|
# Deprecated.
|
|
51
49
|
#
|
data/lib/openssl/hmac.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenSSL
|
|
4
|
+
class HMAC
|
|
5
|
+
# Securely compare with another HMAC instance in constant time.
|
|
6
|
+
def ==(other)
|
|
7
|
+
return false unless HMAC === other
|
|
8
|
+
return false unless self.digest.bytesize == other.digest.bytesize
|
|
9
|
+
|
|
10
|
+
OpenSSL.fixed_length_secure_compare(self.digest, other.digest)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#--
|
|
3
|
+
# = Ruby-space definitions to add DER (de)serialization to classes
|
|
4
|
+
#
|
|
5
|
+
# = Info
|
|
6
|
+
# 'OpenSSL for Ruby 2' project
|
|
7
|
+
# Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
|
8
|
+
# All rights reserved.
|
|
9
|
+
#
|
|
10
|
+
# = Licence
|
|
11
|
+
# This program is licensed under the same licence as Ruby.
|
|
12
|
+
# (See the file 'LICENCE'.)
|
|
13
|
+
#++
|
|
14
|
+
module OpenSSL
|
|
15
|
+
module Marshal
|
|
16
|
+
def self.included(base)
|
|
17
|
+
base.extend(ClassMethods)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module ClassMethods
|
|
21
|
+
def _load(string)
|
|
22
|
+
new(string)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def _dump(_level)
|
|
27
|
+
to_der
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/openssl/pkcs5.rb
CHANGED
data/lib/openssl/pkey.rb
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
# frozen_string_literal:
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
#--
|
|
3
3
|
# Ruby/OpenSSL Project
|
|
4
4
|
# Copyright (C) 2017 Ruby/OpenSSL Project Authors
|
|
5
5
|
#++
|
|
6
6
|
|
|
7
|
+
require_relative 'marshal'
|
|
8
|
+
|
|
7
9
|
module OpenSSL::PKey
|
|
10
|
+
class DH
|
|
11
|
+
include OpenSSL::Marshal
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class DSA
|
|
15
|
+
include OpenSSL::Marshal
|
|
16
|
+
end
|
|
17
|
+
|
|
8
18
|
if defined?(EC)
|
|
19
|
+
class EC
|
|
20
|
+
include OpenSSL::Marshal
|
|
21
|
+
end
|
|
9
22
|
class EC::Point
|
|
10
23
|
# :call-seq:
|
|
11
24
|
# point.to_bn([conversion_form]) -> OpenSSL::BN
|
|
@@ -22,4 +35,8 @@ module OpenSSL::PKey
|
|
|
22
35
|
end
|
|
23
36
|
end
|
|
24
37
|
end
|
|
38
|
+
|
|
39
|
+
class RSA
|
|
40
|
+
include OpenSSL::Marshal
|
|
41
|
+
end
|
|
25
42
|
end
|
data/lib/openssl/ssl.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal:
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
=begin
|
|
3
3
|
= Info
|
|
4
4
|
'OpenSSL for Ruby 2' project
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
require "openssl/buffering"
|
|
14
14
|
require "io/nonblock"
|
|
15
15
|
require "ipaddr"
|
|
16
|
+
require "socket"
|
|
16
17
|
|
|
17
18
|
module OpenSSL
|
|
18
19
|
module SSL
|
|
@@ -231,6 +232,11 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
|
|
|
231
232
|
end
|
|
232
233
|
|
|
233
234
|
module SocketForwarder
|
|
235
|
+
# The file descriptor for the socket.
|
|
236
|
+
def fileno
|
|
237
|
+
to_io.fileno
|
|
238
|
+
end
|
|
239
|
+
|
|
234
240
|
def addr
|
|
235
241
|
to_io.addr
|
|
236
242
|
end
|
|
@@ -435,6 +441,38 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
|
|
|
435
441
|
def session_get_cb
|
|
436
442
|
@context.session_get_cb
|
|
437
443
|
end
|
|
444
|
+
|
|
445
|
+
class << self
|
|
446
|
+
|
|
447
|
+
# call-seq:
|
|
448
|
+
# open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil)
|
|
449
|
+
#
|
|
450
|
+
# Creates a new instance of SSLSocket.
|
|
451
|
+
# _remote\_host_ and _remote\_port_ are used to open TCPSocket.
|
|
452
|
+
# If _local\_host_ and _local\_port_ are specified,
|
|
453
|
+
# then those parameters are used on the local end to establish the connection.
|
|
454
|
+
# If _context_ is provided,
|
|
455
|
+
# the SSL Sockets initial params will be taken from the context.
|
|
456
|
+
#
|
|
457
|
+
# === Examples
|
|
458
|
+
#
|
|
459
|
+
# sock = OpenSSL::SSL::SSLSocket.open('localhost', 443)
|
|
460
|
+
# sock.connect # Initiates a connection to localhost:443
|
|
461
|
+
#
|
|
462
|
+
# with SSLContext:
|
|
463
|
+
#
|
|
464
|
+
# ctx = OpenSSL::SSL::SSLContext.new
|
|
465
|
+
# sock = OpenSSL::SSL::SSLSocket.open('localhost', 443, context: ctx)
|
|
466
|
+
# sock.connect # Initiates a connection to localhost:443 with SSLContext
|
|
467
|
+
def open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil)
|
|
468
|
+
sock = ::TCPSocket.open(remote_host, remote_port, local_host, local_port)
|
|
469
|
+
if context.nil?
|
|
470
|
+
return OpenSSL::SSL::SSLSocket.new(sock)
|
|
471
|
+
else
|
|
472
|
+
return OpenSSL::SSL::SSLSocket.new(sock, context)
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
end
|
|
438
476
|
end
|
|
439
477
|
|
|
440
478
|
##
|
|
@@ -465,7 +503,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
|
|
|
465
503
|
end
|
|
466
504
|
|
|
467
505
|
# See TCPServer#listen for details.
|
|
468
|
-
def listen(backlog=
|
|
506
|
+
def listen(backlog=Socket::SOMAXCONN)
|
|
469
507
|
@svr.listen(backlog)
|
|
470
508
|
end
|
|
471
509
|
|
data/lib/openssl/x509.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal:
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
#--
|
|
3
3
|
# = Ruby-space definitions that completes C-space funcs for X509 and subclasses
|
|
4
4
|
#
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# (See the file 'LICENCE'.)
|
|
13
13
|
#++
|
|
14
14
|
|
|
15
|
+
require_relative 'marshal'
|
|
16
|
+
|
|
15
17
|
module OpenSSL
|
|
16
18
|
module X509
|
|
17
19
|
class ExtensionFactory
|
|
@@ -41,6 +43,8 @@ module OpenSSL
|
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
class Extension
|
|
46
|
+
include OpenSSL::Marshal
|
|
47
|
+
|
|
44
48
|
def ==(other)
|
|
45
49
|
return false unless Extension === other
|
|
46
50
|
to_der == other.to_der
|
|
@@ -60,9 +64,146 @@ module OpenSSL
|
|
|
60
64
|
def to_a
|
|
61
65
|
[ self.oid, self.value, self.critical? ]
|
|
62
66
|
end
|
|
67
|
+
|
|
68
|
+
module Helpers
|
|
69
|
+
def find_extension(oid)
|
|
70
|
+
extensions.find { |e| e.oid == oid }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
module SubjectKeyIdentifier
|
|
75
|
+
include Helpers
|
|
76
|
+
|
|
77
|
+
# Get the subject's key identifier from the subjectKeyIdentifier
|
|
78
|
+
# exteension, as described in RFC5280 Section 4.2.1.2.
|
|
79
|
+
#
|
|
80
|
+
# Returns the binary String key identifier or nil or raises
|
|
81
|
+
# ASN1::ASN1Error.
|
|
82
|
+
def subject_key_identifier
|
|
83
|
+
ext = find_extension("subjectKeyIdentifier")
|
|
84
|
+
return nil if ext.nil?
|
|
85
|
+
|
|
86
|
+
ski_asn1 = ASN1.decode(ext.value_der)
|
|
87
|
+
if ext.critical? || ski_asn1.tag_class != :UNIVERSAL || ski_asn1.tag != ASN1::OCTET_STRING
|
|
88
|
+
raise ASN1::ASN1Error, "invalid extension"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
ski_asn1.value
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
module AuthorityKeyIdentifier
|
|
96
|
+
include Helpers
|
|
97
|
+
|
|
98
|
+
# Get the issuing certificate's key identifier from the
|
|
99
|
+
# authorityKeyIdentifier extension, as described in RFC5280
|
|
100
|
+
# Section 4.2.1.1
|
|
101
|
+
#
|
|
102
|
+
# Returns the binary String keyIdentifier or nil or raises
|
|
103
|
+
# ASN1::ASN1Error.
|
|
104
|
+
def authority_key_identifier
|
|
105
|
+
ext = find_extension("authorityKeyIdentifier")
|
|
106
|
+
return nil if ext.nil?
|
|
107
|
+
|
|
108
|
+
aki_asn1 = ASN1.decode(ext.value_der)
|
|
109
|
+
if ext.critical? || aki_asn1.tag_class != :UNIVERSAL || aki_asn1.tag != ASN1::SEQUENCE
|
|
110
|
+
raise ASN1::ASN1Error, "invalid extension"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
key_id = aki_asn1.value.find do |v|
|
|
114
|
+
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
key_id.nil? ? nil : key_id.value
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
module CRLDistributionPoints
|
|
122
|
+
include Helpers
|
|
123
|
+
|
|
124
|
+
# Get the distributionPoint fullName URI from the certificate's CRL
|
|
125
|
+
# distribution points extension, as described in RFC5280 Section
|
|
126
|
+
# 4.2.1.13
|
|
127
|
+
#
|
|
128
|
+
# Returns an array of strings or nil or raises ASN1::ASN1Error.
|
|
129
|
+
def crl_uris
|
|
130
|
+
ext = find_extension("crlDistributionPoints")
|
|
131
|
+
return nil if ext.nil?
|
|
132
|
+
|
|
133
|
+
cdp_asn1 = ASN1.decode(ext.value_der)
|
|
134
|
+
if cdp_asn1.tag_class != :UNIVERSAL || cdp_asn1.tag != ASN1::SEQUENCE
|
|
135
|
+
raise ASN1::ASN1Error, "invalid extension"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
crl_uris = cdp_asn1.map do |crl_distribution_point|
|
|
139
|
+
distribution_point = crl_distribution_point.value.find do |v|
|
|
140
|
+
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
|
|
141
|
+
end
|
|
142
|
+
full_name = distribution_point&.value&.find do |v|
|
|
143
|
+
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
|
|
144
|
+
end
|
|
145
|
+
full_name&.value&.find do |v|
|
|
146
|
+
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 6 # uniformResourceIdentifier
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
crl_uris&.map(&:value)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
module AuthorityInfoAccess
|
|
155
|
+
include Helpers
|
|
156
|
+
|
|
157
|
+
# Get the information and services for the issuer from the certificate's
|
|
158
|
+
# authority information access extension exteension, as described in RFC5280
|
|
159
|
+
# Section 4.2.2.1.
|
|
160
|
+
#
|
|
161
|
+
# Returns an array of strings or nil or raises ASN1::ASN1Error.
|
|
162
|
+
def ca_issuer_uris
|
|
163
|
+
aia_asn1 = parse_aia_asn1
|
|
164
|
+
return nil if aia_asn1.nil?
|
|
165
|
+
|
|
166
|
+
ca_issuer = aia_asn1.value.select do |authority_info_access|
|
|
167
|
+
authority_info_access.value.first.value == "caIssuers"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
ca_issuer&.map(&:value)&.map(&:last)&.map(&:value)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Get the URIs for OCSP from the certificate's authority information access
|
|
174
|
+
# extension exteension, as described in RFC5280 Section 4.2.2.1.
|
|
175
|
+
#
|
|
176
|
+
# Returns an array of strings or nil or raises ASN1::ASN1Error.
|
|
177
|
+
def ocsp_uris
|
|
178
|
+
aia_asn1 = parse_aia_asn1
|
|
179
|
+
return nil if aia_asn1.nil?
|
|
180
|
+
|
|
181
|
+
ocsp = aia_asn1.value.select do |authority_info_access|
|
|
182
|
+
authority_info_access.value.first.value == "OCSP"
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
ocsp&.map(&:value)&.map(&:last)&.map(&:value)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
private
|
|
189
|
+
|
|
190
|
+
def parse_aia_asn1
|
|
191
|
+
ext = find_extension("authorityInfoAccess")
|
|
192
|
+
return nil if ext.nil?
|
|
193
|
+
|
|
194
|
+
aia_asn1 = ASN1.decode(ext.value_der)
|
|
195
|
+
if ext.critical? || aia_asn1.tag_class != :UNIVERSAL || aia_asn1.tag != ASN1::SEQUENCE
|
|
196
|
+
raise ASN1::ASN1Error, "invalid extension"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
aia_asn1
|
|
200
|
+
end
|
|
201
|
+
end
|
|
63
202
|
end
|
|
64
203
|
|
|
65
204
|
class Name
|
|
205
|
+
include OpenSSL::Marshal
|
|
206
|
+
|
|
66
207
|
module RFC2253DN
|
|
67
208
|
Special = ',=+<>#;'
|
|
68
209
|
HexChar = /[0-9a-fA-F]/
|
|
@@ -166,6 +307,8 @@ module OpenSSL
|
|
|
166
307
|
end
|
|
167
308
|
|
|
168
309
|
class Attribute
|
|
310
|
+
include OpenSSL::Marshal
|
|
311
|
+
|
|
169
312
|
def ==(other)
|
|
170
313
|
return false unless Attribute === other
|
|
171
314
|
to_der == other.to_der
|
|
@@ -179,6 +322,12 @@ module OpenSSL
|
|
|
179
322
|
end
|
|
180
323
|
|
|
181
324
|
class Certificate
|
|
325
|
+
include OpenSSL::Marshal
|
|
326
|
+
include Extension::SubjectKeyIdentifier
|
|
327
|
+
include Extension::AuthorityKeyIdentifier
|
|
328
|
+
include Extension::CRLDistributionPoints
|
|
329
|
+
include Extension::AuthorityInfoAccess
|
|
330
|
+
|
|
182
331
|
def pretty_print(q)
|
|
183
332
|
q.object_group(self) {
|
|
184
333
|
q.breakable
|
|
@@ -192,6 +341,9 @@ module OpenSSL
|
|
|
192
341
|
end
|
|
193
342
|
|
|
194
343
|
class CRL
|
|
344
|
+
include OpenSSL::Marshal
|
|
345
|
+
include Extension::AuthorityKeyIdentifier
|
|
346
|
+
|
|
195
347
|
def ==(other)
|
|
196
348
|
return false unless CRL === other
|
|
197
349
|
to_der == other.to_der
|
|
@@ -206,6 +358,8 @@ module OpenSSL
|
|
|
206
358
|
end
|
|
207
359
|
|
|
208
360
|
class Request
|
|
361
|
+
include OpenSSL::Marshal
|
|
362
|
+
|
|
209
363
|
def ==(other)
|
|
210
364
|
return false unless Request === other
|
|
211
365
|
to_der == other.to_der
|