-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
pr-zlib is version 1.0.3, commit c1418dd1abde5c4f6bcc7073b7965eeb4c168144 | ||
openssl is from MRI 2.3.1 | ||
openssl/openssl.rb has been modified to refer to 'openssl/openssl' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# frozen_string_literal: false | ||
=begin | ||
= Info | ||
'OpenSSL for Ruby 2' project | ||
Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
All rights reserved. | ||
= Licence | ||
This program is licensed under the same licence as Ruby. | ||
(See the file 'LICENCE'.) | ||
=end | ||
|
||
require 'openssl.so' | ||
|
||
require 'openssl/bn' | ||
require 'openssl/pkey' | ||
require 'openssl/cipher' | ||
require 'openssl/config' | ||
require 'openssl/digest' | ||
require 'openssl/x509' | ||
require 'openssl/ssl' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# frozen_string_literal: false | ||
#-- | ||
# | ||
# = Ruby-space definitions that completes C-space funcs for BN | ||
# | ||
# = Info | ||
# 'OpenSSL for Ruby 2' project | ||
# Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
# All rights reserved. | ||
# | ||
# = Licence | ||
# This program is licensed under the same licence as Ruby. | ||
# (See the file 'LICENCE'.) | ||
#++ | ||
|
||
module OpenSSL | ||
class BN | ||
include Comparable | ||
|
||
def pretty_print(q) | ||
q.object_group(self) { | ||
q.text ' ' | ||
q.text to_i.to_s | ||
} | ||
end | ||
end # BN | ||
end # OpenSSL | ||
|
||
## | ||
# Add double dispatch to Integer | ||
# | ||
class Integer | ||
# Casts an Integer as an OpenSSL::BN | ||
# | ||
# See `man bn` for more info. | ||
def to_bn | ||
OpenSSL::BN::new(self) | ||
end | ||
end # Integer |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# frozen_string_literal: false | ||
#-- | ||
# = Ruby-space predefined Cipher subclasses | ||
# | ||
# = Info | ||
# 'OpenSSL for Ruby 2' project | ||
# Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
# All rights reserved. | ||
# | ||
# = Licence | ||
# This program is licensed under the same licence as Ruby. | ||
# (See the file 'LICENCE'.) | ||
#++ | ||
|
||
module OpenSSL | ||
class Cipher | ||
%w(AES CAST5 BF DES IDEA RC2 RC4 RC5).each{|name| | ||
klass = Class.new(Cipher){ | ||
define_method(:initialize){|*args| | ||
cipher_name = args.inject(name){|n, arg| "#{n}-#{arg}" } | ||
super(cipher_name) | ||
} | ||
} | ||
const_set(name, klass) | ||
} | ||
|
||
%w(128 192 256).each{|keylen| | ||
klass = Class.new(Cipher){ | ||
define_method(:initialize){|mode| | ||
mode ||= "CBC" | ||
cipher_name = "AES-#{keylen}-#{mode}" | ||
super(cipher_name) | ||
} | ||
} | ||
const_set("AES#{keylen}", klass) | ||
} | ||
|
||
# Generate, set, and return a random key. | ||
# You must call cipher.encrypt or cipher.decrypt before calling this method. | ||
def random_key | ||
str = OpenSSL::Random.random_bytes(self.key_len) | ||
self.key = str | ||
return str | ||
end | ||
|
||
# Generate, set, and return a random iv. | ||
# You must call cipher.encrypt or cipher.decrypt before calling this method. | ||
def random_iv | ||
str = OpenSSL::Random.random_bytes(self.iv_len) | ||
self.iv = str | ||
return str | ||
end | ||
|
||
# This class is only provided for backwards compatibility. Use OpenSSL::Cipher in the future. | ||
class Cipher < Cipher | ||
# add warning | ||
end | ||
end # Cipher | ||
end # OpenSSL |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# frozen_string_literal: false | ||
#-- | ||
# = Ruby-space predefined Digest subclasses | ||
# | ||
# = Info | ||
# 'OpenSSL for Ruby 2' project | ||
# Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
# All rights reserved. | ||
# | ||
# = Licence | ||
# This program is licensed under the same licence as Ruby. | ||
# (See the file 'LICENCE'.) | ||
#++ | ||
|
||
module OpenSSL | ||
class Digest | ||
|
||
alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1) | ||
if OPENSSL_VERSION_NUMBER < 0x10100000 | ||
alg += %w(DSS DSS1 SHA) | ||
end | ||
if OPENSSL_VERSION_NUMBER > 0x00908000 | ||
alg += %w(SHA224 SHA256 SHA384 SHA512) | ||
end | ||
|
||
# Return the +data+ hash computed with +name+ Digest. +name+ is either the | ||
# long name or short name of a supported digest algorithm. | ||
# | ||
# === Examples | ||
# | ||
# OpenSSL::Digest.digest("SHA256", "abc") | ||
# | ||
# which is equivalent to: | ||
# | ||
# OpenSSL::Digest::SHA256.digest("abc") | ||
|
||
def self.digest(name, data) | ||
super(data, name) | ||
end | ||
|
||
alg.each{|name| | ||
klass = Class.new(self) { | ||
define_method(:initialize, ->(data = nil) {super(name, data)}) | ||
} | ||
singleton = (class << klass; self; end) | ||
singleton.class_eval{ | ||
define_method(:digest){|data| new.digest(data) } | ||
define_method(:hexdigest){|data| new.hexdigest(data) } | ||
} | ||
const_set(name, klass) | ||
} | ||
|
||
# Deprecated. | ||
# | ||
# This class is only provided for backwards compatibility. | ||
class Digest < Digest # :nodoc: | ||
# Deprecated. | ||
# | ||
# See OpenSSL::Digest.new | ||
def initialize(*args) | ||
warn('Digest::Digest is deprecated; use Digest') | ||
super(*args) | ||
end | ||
end | ||
|
||
end # Digest | ||
|
||
# Returns a Digest subclass by +name+. | ||
# | ||
# require 'openssl' | ||
# | ||
# OpenSSL::Digest("MD5") | ||
# # => OpenSSL::Digest::MD5 | ||
# | ||
# Digest("Foo") | ||
# # => NameError: wrong constant name Foo | ||
|
||
def Digest(name) | ||
OpenSSL::Digest.const_get(name) | ||
end | ||
|
||
module_function :Digest | ||
|
||
end # OpenSSL |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# frozen_string_literal: false | ||
module OpenSSL | ||
module PKey | ||
if defined?(OpenSSL::PKey::DH) | ||
|
||
class DH | ||
DEFAULT_1024 = new <<-_end_of_pem_ | ||
-----BEGIN DH PARAMETERS----- | ||
MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ | ||
AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR | ||
T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC | ||
-----END DH PARAMETERS----- | ||
_end_of_pem_ | ||
|
||
DEFAULT_2048 = new <<-_end_of_pem_ | ||
-----BEGIN DH PARAMETERS----- | ||
MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY | ||
JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab | ||
VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6 | ||
YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 | ||
1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD | ||
7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg== | ||
-----END DH PARAMETERS----- | ||
_end_of_pem_ | ||
end | ||
|
||
DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| | ||
warn "using default DH parameters." if $VERBOSE | ||
case keylen | ||
when 1024 then OpenSSL::PKey::DH::DEFAULT_1024 | ||
when 2048 then OpenSSL::PKey::DH::DEFAULT_2048 | ||
else | ||
nil | ||
end | ||
} | ||
|
||
else | ||
DEFAULT_TMP_DH_CALLBACK = nil | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,390 @@ | ||
# frozen_string_literal: false | ||
=begin | ||
= Info | ||
'OpenSSL for Ruby 2' project | ||
Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org> | ||
All rights reserved. | ||
= Licence | ||
This program is licensed under the same licence as Ruby. | ||
(See the file 'LICENCE'.) | ||
=end | ||
|
||
require "openssl/buffering" | ||
require "io/nonblock" | ||
|
||
module OpenSSL | ||
module SSL | ||
class SSLContext | ||
DEFAULT_PARAMS = { | ||
:ssl_version => "SSLv23", | ||
:verify_mode => OpenSSL::SSL::VERIFY_PEER, | ||
:ciphers => %w{ | ||
ECDHE-ECDSA-AES128-GCM-SHA256 | ||
ECDHE-RSA-AES128-GCM-SHA256 | ||
ECDHE-ECDSA-AES256-GCM-SHA384 | ||
ECDHE-RSA-AES256-GCM-SHA384 | ||
DHE-RSA-AES128-GCM-SHA256 | ||
DHE-DSS-AES128-GCM-SHA256 | ||
DHE-RSA-AES256-GCM-SHA384 | ||
DHE-DSS-AES256-GCM-SHA384 | ||
ECDHE-ECDSA-AES128-SHA256 | ||
ECDHE-RSA-AES128-SHA256 | ||
ECDHE-ECDSA-AES128-SHA | ||
ECDHE-RSA-AES128-SHA | ||
ECDHE-ECDSA-AES256-SHA384 | ||
ECDHE-RSA-AES256-SHA384 | ||
ECDHE-ECDSA-AES256-SHA | ||
ECDHE-RSA-AES256-SHA | ||
DHE-RSA-AES128-SHA256 | ||
DHE-RSA-AES256-SHA256 | ||
DHE-RSA-AES128-SHA | ||
DHE-RSA-AES256-SHA | ||
DHE-DSS-AES128-SHA256 | ||
DHE-DSS-AES256-SHA256 | ||
DHE-DSS-AES128-SHA | ||
DHE-DSS-AES256-SHA | ||
AES128-GCM-SHA256 | ||
AES256-GCM-SHA384 | ||
AES128-SHA256 | ||
AES256-SHA256 | ||
AES128-SHA | ||
AES256-SHA | ||
ECDHE-ECDSA-RC4-SHA | ||
ECDHE-RSA-RC4-SHA | ||
RC4-SHA | ||
}.join(":"), | ||
:options => -> { | ||
opts = OpenSSL::SSL::OP_ALL | ||
opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS | ||
opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION) | ||
opts |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 | ||
opts | ||
}.call | ||
} | ||
|
||
DEFAULT_CERT_STORE = OpenSSL::X509::Store.new | ||
DEFAULT_CERT_STORE.set_default_paths | ||
DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL | ||
|
||
INIT_VARS = ["cert", "key", "client_ca", "ca_file", "ca_path", | ||
"timeout", "verify_mode", "verify_depth", "renegotiation_cb", | ||
"verify_callback", "cert_store", "extra_chain_cert", | ||
"client_cert_cb", "session_id_context", "tmp_dh_callback", | ||
"session_get_cb", "session_new_cb", "session_remove_cb", | ||
"tmp_ecdh_callback", "servername_cb", "npn_protocols", | ||
"alpn_protocols", "alpn_select_cb", | ||
"npn_select_cb"].map { |x| "@#{x}" } | ||
|
||
# A callback invoked when DH parameters are required. | ||
# | ||
# The callback is invoked with the Session for the key exchange, an | ||
# flag indicating the use of an export cipher and the keylength | ||
# required. | ||
# | ||
# The callback must return an OpenSSL::PKey::DH instance of the correct | ||
# key length. | ||
|
||
attr_accessor :tmp_dh_callback | ||
|
||
if ExtConfig::HAVE_TLSEXT_HOST_NAME | ||
# A callback invoked at connect time to distinguish between multiple | ||
# server names. | ||
# | ||
# The callback is invoked with an SSLSocket and a server name. The | ||
# callback must return an SSLContext for the server name or nil. | ||
attr_accessor :servername_cb | ||
end | ||
|
||
# call-seq: | ||
# SSLContext.new => ctx | ||
# SSLContext.new(:TLSv1) => ctx | ||
# SSLContext.new("SSLv23_client") => ctx | ||
# | ||
# You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS | ||
def initialize(version = nil) | ||
INIT_VARS.each { |v| instance_variable_set v, nil } | ||
self.options = self.options | OpenSSL::SSL::OP_ALL | ||
return unless version | ||
self.ssl_version = version | ||
end | ||
|
||
## | ||
# Sets the parameters for this SSL context to the values in +params+. | ||
# The keys in +params+ must be assignment methods on SSLContext. | ||
# | ||
# If the verify_mode is not VERIFY_NONE and ca_file, ca_path and | ||
# cert_store are not set then the system default certificate store is | ||
# used. | ||
|
||
def set_params(params={}) | ||
params = DEFAULT_PARAMS.merge(params) | ||
params.each{|name, value| self.__send__("#{name}=", value) } | ||
if self.verify_mode != OpenSSL::SSL::VERIFY_NONE | ||
unless self.ca_file or self.ca_path or self.cert_store | ||
self.cert_store = DEFAULT_CERT_STORE | ||
end | ||
end | ||
return params | ||
end | ||
end | ||
|
||
module SocketForwarder | ||
def addr | ||
to_io.addr | ||
end | ||
|
||
def peeraddr | ||
to_io.peeraddr | ||
end | ||
|
||
def setsockopt(level, optname, optval) | ||
to_io.setsockopt(level, optname, optval) | ||
end | ||
|
||
def getsockopt(level, optname) | ||
to_io.getsockopt(level, optname) | ||
end | ||
|
||
def fcntl(*args) | ||
to_io.fcntl(*args) | ||
end | ||
|
||
def closed? | ||
to_io.closed? | ||
end | ||
|
||
def do_not_reverse_lookup=(flag) | ||
to_io.do_not_reverse_lookup = flag | ||
end | ||
end | ||
|
||
def verify_certificate_identity(cert, hostname) | ||
should_verify_common_name = true | ||
cert.extensions.each{|ext| | ||
next if ext.oid != "subjectAltName" | ||
ostr = OpenSSL::ASN1.decode(ext.to_der).value.last | ||
sequence = OpenSSL::ASN1.decode(ostr.value) | ||
sequence.value.each{|san| | ||
case san.tag | ||
when 2 # dNSName in GeneralName (RFC5280) | ||
should_verify_common_name = false | ||
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 | ||
end | ||
end | ||
} | ||
} | ||
if should_verify_common_name | ||
cert.subject.to_a.each{|oid, value| | ||
if oid == "CN" | ||
return true if verify_hostname(hostname, value) | ||
end | ||
} | ||
end | ||
return false | ||
end | ||
module_function :verify_certificate_identity | ||
|
||
def verify_hostname(hostname, san) # :nodoc: | ||
# RFC 5280, IA5String is limited to the set of ASCII characters | ||
return false unless san.ascii_only? | ||
return false unless hostname.ascii_only? | ||
|
||
# See RFC 6125, section 6.4.1 | ||
# Matching is case-insensitive. | ||
san_parts = san.downcase.split(".") | ||
|
||
# TODO: this behavior should probably be more strict | ||
return san == hostname if san_parts.size < 2 | ||
|
||
# Matching is case-insensitive. | ||
host_parts = hostname.downcase.split(".") | ||
|
||
# RFC 6125, section 6.4.3, subitem 2. | ||
# If the wildcard character is the only character of the left-most | ||
# label in the presented identifier, the client SHOULD NOT compare | ||
# against anything but the left-most label of the reference | ||
# identifier (e.g., *.example.com would match foo.example.com but | ||
# not bar.foo.example.com or example.com). | ||
return false unless san_parts.size == host_parts.size | ||
|
||
# RFC 6125, section 6.4.3, subitem 1. | ||
# The client SHOULD NOT attempt to match a presented identifier in | ||
# which the wildcard character comprises a label other than the | ||
# left-most label (e.g., do not match bar.*.example.net). | ||
return false unless verify_wildcard(host_parts.shift, san_parts.shift) | ||
|
||
san_parts.join(".") == host_parts.join(".") | ||
end | ||
module_function :verify_hostname | ||
|
||
def verify_wildcard(domain_component, san_component) # :nodoc: | ||
parts = san_component.split("*", -1) | ||
|
||
return false if parts.size > 2 | ||
return san_component == domain_component if parts.size == 1 | ||
|
||
# RFC 6125, section 6.4.3, subitem 3. | ||
# The client SHOULD NOT attempt to match a presented identifier | ||
# where the wildcard character is embedded within an A-label or | ||
# U-label of an internationalized domain name. | ||
return false if domain_component.start_with?("xn--") && san_component != "*" | ||
|
||
parts[0].length + parts[1].length < domain_component.length && | ||
domain_component.start_with?(parts[0]) && | ||
domain_component.end_with?(parts[1]) | ||
end | ||
module_function :verify_wildcard | ||
|
||
class SSLSocket | ||
include Buffering | ||
include SocketForwarder | ||
|
||
if ExtConfig::HAVE_TLSEXT_HOST_NAME | ||
attr_reader :hostname | ||
end | ||
|
||
attr_reader :io, :context | ||
attr_accessor :sync_close | ||
alias :to_io :io | ||
|
||
# call-seq: | ||
# ssl.sysclose => nil | ||
# | ||
# Sends "close notify" to the peer and tries to shut down the SSL | ||
# connection gracefully. | ||
# | ||
# If sync_close is set to +true+, the underlying IO is also closed. | ||
def sysclose | ||
return if closed? | ||
stop | ||
io.close if sync_close | ||
end | ||
|
||
## | ||
# Perform hostname verification after an SSL connection is established | ||
# | ||
# This method MUST be called after calling #connect to ensure that the | ||
# hostname of a remote peer has been verified. | ||
def post_connection_check(hostname) | ||
if peer_cert.nil? | ||
msg = "Peer verification enabled, but no certificate received." | ||
if using_anon_cipher? | ||
msg += " Anonymous cipher suite #{cipher[0]} was negotiated. Anonymous suites must be disabled to use peer verification." | ||
end | ||
raise SSLError, msg | ||
end | ||
|
||
unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) | ||
raise SSLError, "hostname \"#{hostname}\" does not match the server certificate" | ||
end | ||
return true | ||
end | ||
|
||
def session | ||
SSL::Session.new(self) | ||
rescue SSL::Session::SessionError | ||
nil | ||
end | ||
|
||
private | ||
|
||
def using_anon_cipher? | ||
ctx = OpenSSL::SSL::SSLContext.new | ||
ctx.ciphers = "aNULL" | ||
ctx.ciphers.include?(cipher) | ||
end | ||
|
||
def client_cert_cb | ||
@context.client_cert_cb | ||
end | ||
|
||
def tmp_dh_callback | ||
@context.tmp_dh_callback || OpenSSL::PKey::DEFAULT_TMP_DH_CALLBACK | ||
end | ||
|
||
def tmp_ecdh_callback | ||
@context.tmp_ecdh_callback | ||
end | ||
|
||
def session_new_cb | ||
@context.session_new_cb | ||
end | ||
|
||
def session_get_cb | ||
@context.session_get_cb | ||
end | ||
end | ||
|
||
## | ||
# SSLServer represents a TCP/IP server socket with Secure Sockets Layer. | ||
class SSLServer | ||
include SocketForwarder | ||
# When true then #accept works exactly the same as TCPServer#accept | ||
attr_accessor :start_immediately | ||
|
||
# Creates a new instance of SSLServer. | ||
# * +srv+ is an instance of TCPServer. | ||
# * +ctx+ is an instance of OpenSSL::SSL::SSLContext. | ||
def initialize(svr, ctx) | ||
@svr = svr | ||
@ctx = ctx | ||
unless ctx.session_id_context | ||
# see #6137 - session id may not exceed 32 bytes | ||
prng = ::Random.new($0.hash) | ||
session_id = prng.bytes(16).unpack('H*')[0] | ||
@ctx.session_id_context = session_id | ||
end | ||
@start_immediately = true | ||
end | ||
|
||
# Returns the TCPServer passed to the SSLServer when initialized. | ||
def to_io | ||
@svr | ||
end | ||
|
||
# See TCPServer#listen for details. | ||
def listen(backlog=5) | ||
@svr.listen(backlog) | ||
end | ||
|
||
# See BasicSocket#shutdown for details. | ||
def shutdown(how=Socket::SHUT_RDWR) | ||
@svr.shutdown(how) | ||
end | ||
|
||
# Works similar to TCPServer#accept. | ||
def accept | ||
# Socket#accept returns [socket, addrinfo]. | ||
# TCPServer#accept returns a socket. | ||
# The following comma strips addrinfo. | ||
sock, = @svr.accept | ||
begin | ||
ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) | ||
ssl.sync_close = true | ||
ssl.accept if @start_immediately | ||
ssl | ||
rescue Exception => ex | ||
if ssl | ||
ssl.close | ||
else | ||
sock.close | ||
end | ||
raise ex | ||
end | ||
end | ||
|
||
# See IO#close for details. | ||
def close | ||
@svr.close | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
# frozen_string_literal: false | ||
#-- | ||
# = Ruby-space definitions that completes C-space funcs for X509 and subclasses | ||
# | ||
# = Info | ||
# 'OpenSSL for Ruby 2' project | ||
# Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
# All rights reserved. | ||
# | ||
# = Licence | ||
# This program is licensed under the same licence as Ruby. | ||
# (See the file 'LICENCE'.) | ||
#++ | ||
|
||
module OpenSSL | ||
module X509 | ||
class ExtensionFactory | ||
def create_extension(*arg) | ||
if arg.size > 1 | ||
create_ext(*arg) | ||
else | ||
send("create_ext_from_"+arg[0].class.name.downcase, arg[0]) | ||
end | ||
end | ||
|
||
def create_ext_from_array(ary) | ||
raise ExtensionError, "unexpected array form" if ary.size > 3 | ||
create_ext(ary[0], ary[1], ary[2]) | ||
end | ||
|
||
def create_ext_from_string(str) # "oid = critical, value" | ||
oid, value = str.split(/=/, 2) | ||
oid.strip! | ||
value.strip! | ||
create_ext(oid, value) | ||
end | ||
|
||
def create_ext_from_hash(hash) | ||
create_ext(hash["oid"], hash["value"], hash["critical"]) | ||
end | ||
end | ||
|
||
class Extension | ||
def to_s # "oid = critical, value" | ||
str = self.oid | ||
str << " = " | ||
str << "critical, " if self.critical? | ||
str << self.value.gsub(/\n/, ", ") | ||
end | ||
|
||
def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false} | ||
{"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?} | ||
end | ||
|
||
def to_a | ||
[ self.oid, self.value, self.critical? ] | ||
end | ||
end | ||
|
||
class Name | ||
module RFC2253DN | ||
Special = ',=+<>#;' | ||
HexChar = /[0-9a-fA-F]/ | ||
HexPair = /#{HexChar}#{HexChar}/ | ||
HexString = /#{HexPair}+/ | ||
Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/ | ||
StringChar = /[^\\"#{Special}]/ | ||
QuoteChar = /[^\\"]/ | ||
AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/ | ||
AttributeValue = / | ||
(?!["#])((?:#{StringChar}|#{Pair})*)| | ||
\#(#{HexString})| | ||
"((?:#{QuoteChar}|#{Pair})*)" | ||
/x | ||
TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/ | ||
|
||
module_function | ||
|
||
def expand_pair(str) | ||
return nil unless str | ||
return str.gsub(Pair){ | ||
pair = $& | ||
case pair.size | ||
when 2 then pair[1,1] | ||
when 3 then Integer("0x#{pair[1,2]}").chr | ||
else raise OpenSSL::X509::NameError, "invalid pair: #{str}" | ||
end | ||
} | ||
end | ||
|
||
def expand_hexstring(str) | ||
return nil unless str | ||
der = str.gsub(HexPair){$&.to_i(16).chr } | ||
a1 = OpenSSL::ASN1.decode(der) | ||
return a1.value, a1.tag | ||
end | ||
|
||
def expand_value(str1, str2, str3) | ||
value = expand_pair(str1) | ||
value, tag = expand_hexstring(str2) unless value | ||
value = expand_pair(str3) unless value | ||
return value, tag | ||
end | ||
|
||
def scan(dn) | ||
str = dn | ||
ary = [] | ||
while true | ||
if md = TypeAndValue.match(str) | ||
remain = md.post_match | ||
type = md[1] | ||
value, tag = expand_value(md[2], md[3], md[4]) rescue nil | ||
if value | ||
type_and_value = [type, value] | ||
type_and_value.push(tag) if tag | ||
ary.unshift(type_and_value) | ||
if remain.length > 2 && remain[0] == ?, | ||
str = remain[1..-1] | ||
next | ||
elsif remain.length > 2 && remain[0] == ?+ | ||
raise OpenSSL::X509::NameError, | ||
"multi-valued RDN is not supported: #{dn}" | ||
elsif remain.empty? | ||
break | ||
end | ||
end | ||
end | ||
msg_dn = dn[0, dn.length - str.length] + " =>" + str | ||
raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}" | ||
end | ||
return ary | ||
end | ||
end | ||
|
||
class << self | ||
def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE) | ||
ary = OpenSSL::X509::Name::RFC2253DN.scan(str) | ||
self.new(ary, template) | ||
end | ||
|
||
def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE) | ||
ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) } | ||
self.new(ary, template) | ||
end | ||
|
||
alias parse parse_openssl | ||
end | ||
|
||
def pretty_print(q) | ||
q.object_group(self) { | ||
q.text ' ' | ||
q.text to_s(OpenSSL::X509::Name::RFC2253) | ||
} | ||
end | ||
end | ||
|
||
class StoreContext | ||
def cleanup | ||
warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE | ||
end | ||
end | ||
|
||
class Certificate | ||
def pretty_print(q) | ||
q.object_group(self) { | ||
q.breakable | ||
q.text 'subject='; q.pp self.subject; q.text ','; q.breakable | ||
q.text 'issuer='; q.pp self.issuer; q.text ','; q.breakable | ||
q.text 'serial='; q.pp self.serial; q.text ','; q.breakable | ||
q.text 'not_before='; q.pp self.not_before; q.text ','; q.breakable | ||
q.text 'not_after='; q.pp self.not_after | ||
} | ||
end | ||
end | ||
end | ||
end |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
src: $GEM_HOME/gems/nokogiri-1.6.8/ext/nokogiri/*.c | ||
cflags: -I$GEM_HOME/gems/nokogiri-1.6.8/ext/nokogiri `xml2-config --cflags` | ||
out: lib/nokogiri/nokogiri.su |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
openssl is from MRI 2.3.1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
src: ./*.c | ||
out: ../../../../../lib/ruby/truffle/openssl/openssl.su |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# frozen_string_literal: false | ||
module OpenSSL | ||
def self.deprecated_warning_flag | ||
unless flag = (@deprecated_warning_flag ||= nil) | ||
if try_compile("", flag = "-Werror=deprecated-declarations") | ||
if with_config("broken-apple-openssl") | ||
flag = "-Wno-deprecated-declarations" | ||
end | ||
$warnflags << " #{flag}" | ||
else | ||
flag = "" | ||
end | ||
@deprecated_warning_flag = flag | ||
end | ||
flag | ||
end | ||
|
||
def self.check_func(func, header) | ||
have_func(func, header, deprecated_warning_flag) | ||
end | ||
|
||
def self.check_func_or_macro(func, header) | ||
check_func(func, header) or | ||
have_macro(func, header) && $defs.push("-DHAVE_#{func.upcase}") | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
# -*- coding: us-ascii -*- | ||
# frozen_string_literal: false | ||
=begin | ||
= Info | ||
'OpenSSL for Ruby 2' project | ||
Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
All rights reserved. | ||
= Licence | ||
This program is licensed under the same licence as Ruby. | ||
(See the file 'LICENCE'.) | ||
=end | ||
|
||
require "mkmf" | ||
require File.expand_path('../deprecation', __FILE__) | ||
|
||
dir_config("openssl") | ||
dir_config("kerberos") | ||
|
||
Logging::message "=== OpenSSL for Ruby configurator ===\n" | ||
|
||
# Add -Werror=deprecated-declarations to $warnflags if available | ||
OpenSSL.deprecated_warning_flag | ||
|
||
## | ||
# Adds -DOSSL_DEBUG for compilation and some more targets when GCC is used | ||
# To turn it on, use: --with-debug or --enable-debug | ||
# | ||
if with_config("debug") or enable_config("debug") | ||
$defs.push("-DOSSL_DEBUG") | ||
end | ||
|
||
Logging::message "=== Checking for system dependent stuff... ===\n" | ||
have_library("nsl", "t_open") | ||
have_library("socket", "socket") | ||
have_header("assert.h") | ||
|
||
Logging::message "=== Checking for required stuff... ===\n" | ||
if $mingw | ||
have_library("wsock32") | ||
have_library("gdi32") | ||
end | ||
|
||
result = pkg_config("openssl") && have_header("openssl/ssl.h") | ||
unless result | ||
result = have_header("openssl/ssl.h") | ||
result &&= %w[crypto libeay32].any? {|lib| have_library(lib, "CRYPTO_malloc")} | ||
result &&= %w[ssl ssleay32].any? {|lib| have_library(lib, "SSL_new")} | ||
unless result | ||
Logging::message "=== Checking for required stuff failed. ===\n" | ||
Logging::message "Makefile wasn't created. Fix the errors above.\n" | ||
exit 1 | ||
end | ||
end | ||
|
||
result = checking_for("OpenSSL version is 0.9.8 or later") { | ||
try_static_assert("OPENSSL_VERSION_NUMBER >= 0x00908000L", "openssl/opensslv.h") | ||
} | ||
unless result | ||
raise "OpenSSL 0.9.8 or later required." | ||
end | ||
|
||
unless OpenSSL.check_func("SSL_library_init()", "openssl/ssl.h") | ||
raise "Ignore OpenSSL broken by Apple.\nPlease use another openssl. (e.g. using `configure --with-openssl-dir=/path/to/openssl')" | ||
end | ||
|
||
Logging::message "=== Checking for OpenSSL features... ===\n" | ||
# compile options | ||
|
||
# check OPENSSL_NO_{SSL2,SSL3_METHOD} macro: on some environment, these symbols | ||
# exist even if compiled with no-ssl2 or no-ssl3-method. | ||
unless have_macro("OPENSSL_NO_SSL2", "openssl/opensslconf.h") | ||
have_func("SSLv2_method") | ||
end | ||
unless have_macro("OPENSSL_NO_SSL3_METHOD", "openssl/opensslconf.h") | ||
have_func("SSLv3_method") | ||
end | ||
have_func("TLSv1_1_method") | ||
have_func("TLSv1_2_method") | ||
have_func("RAND_egd") | ||
engines = %w{builtin_engines openbsd_dev_crypto dynamic 4758cca aep atalla chil | ||
cswift nuron sureware ubsec padlock capi gmp gost cryptodev aesni} | ||
engines.each { |name| | ||
OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h") | ||
} | ||
|
||
# added in 0.9.8X | ||
have_func("EVP_CIPHER_CTX_new") | ||
have_func("EVP_CIPHER_CTX_free") | ||
|
||
# added in 1.0.0 | ||
have_func("ASN1_TIME_adj") | ||
have_func("EVP_CIPHER_CTX_copy") | ||
have_func("EVP_PKEY_base_id") | ||
have_func("HMAC_CTX_copy") | ||
have_func("PKCS5_PBKDF2_HMAC") | ||
have_func("X509_NAME_hash_old") | ||
have_func("X509_STORE_CTX_get0_current_crl") | ||
have_func("X509_STORE_set_verify_cb") | ||
have_func("i2d_ASN1_SET_ANY") | ||
have_func("SSL_SESSION_cmp") # removed | ||
OpenSSL.check_func_or_macro("SSL_set_tlsext_host_name", "openssl/ssl.h") | ||
have_struct_member("CRYPTO_THREADID", "ptr", "openssl/crypto.h") | ||
|
||
# added in 1.0.1 | ||
have_func("SSL_CTX_set_next_proto_select_cb") | ||
have_macro("EVP_CTRL_GCM_GET_TAG", ['openssl/evp.h']) && $defs.push("-DHAVE_AUTHENTICATED_ENCRYPTION") | ||
|
||
# added in 1.0.2 | ||
have_func("EC_curve_nist2nid") | ||
have_func("X509_REVOKED_dup") | ||
have_func("X509_STORE_CTX_get0_store") | ||
have_func("SSL_CTX_set_alpn_select_cb") | ||
OpenSSL.check_func_or_macro("SSL_CTX_set1_curves_list", "openssl/ssl.h") | ||
OpenSSL.check_func_or_macro("SSL_CTX_set_ecdh_auto", "openssl/ssl.h") | ||
OpenSSL.check_func_or_macro("SSL_get_server_tmp_key", "openssl/ssl.h") | ||
have_func("SSL_is_server") | ||
|
||
# added in 1.1.0 | ||
have_func("CRYPTO_lock") || $defs.push("-DHAVE_OPENSSL_110_THREADING_API") | ||
have_struct_member("SSL", "ctx", "openssl/ssl.h") || $defs.push("-DHAVE_OPAQUE_OPENSSL") | ||
have_func("BN_GENCB_new") | ||
have_func("BN_GENCB_free") | ||
have_func("BN_GENCB_get_arg") | ||
have_func("EVP_MD_CTX_new") | ||
have_func("EVP_MD_CTX_free") | ||
have_func("HMAC_CTX_new") | ||
have_func("HMAC_CTX_free") | ||
OpenSSL.check_func("RAND_pseudo_bytes", "openssl/rand.h") # deprecated | ||
have_func("X509_STORE_get_ex_data") | ||
have_func("X509_STORE_set_ex_data") | ||
have_func("X509_CRL_get0_signature") | ||
have_func("X509_REQ_get0_signature") | ||
have_func("X509_REVOKED_get0_serialNumber") | ||
have_func("X509_REVOKED_get0_revocationDate") | ||
have_func("X509_get0_tbs_sigalg") | ||
have_func("X509_STORE_CTX_get0_untrusted") | ||
have_func("X509_STORE_CTX_get0_cert") | ||
have_func("X509_STORE_CTX_get0_chain") | ||
have_func("OCSP_SINGLERESP_get0_id") | ||
have_func("SSL_CTX_get_ciphers") | ||
have_func("X509_up_ref") | ||
have_func("X509_CRL_up_ref") | ||
have_func("X509_STORE_up_ref") | ||
have_func("SSL_SESSION_up_ref") | ||
have_func("EVP_PKEY_up_ref") | ||
OpenSSL.check_func_or_macro("SSL_CTX_set_tmp_ecdh_callback", "openssl/ssl.h") # removed | ||
OpenSSL.check_func_or_macro("SSL_CTX_set_min_proto_version", "openssl/ssl.h") | ||
have_func("SSL_CTX_get_security_level") | ||
|
||
Logging::message "=== Checking done. ===\n" | ||
|
||
create_header | ||
create_makefile("openssl") {|conf| | ||
conf << "THREAD_MODEL = #{CONFIG["THREAD_MODEL"]}\n" | ||
} | ||
Logging::message "Done.\n" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#include RUBY_EXTCONF_H | ||
|
||
#include <string.h> /* memcpy() */ | ||
#if !defined(OPENSSL_NO_ENGINE) | ||
# include <openssl/engine.h> | ||
#endif | ||
#if !defined(OPENSSL_NO_HMAC) | ||
# include <openssl/hmac.h> | ||
#endif | ||
#include <openssl/x509_vfy.h> | ||
|
||
#include "openssl_missing.h" | ||
|
||
/* added in 0.9.8X */ | ||
#if !defined(HAVE_EVP_CIPHER_CTX_NEW) | ||
EVP_CIPHER_CTX * | ||
EVP_CIPHER_CTX_new(void) | ||
{ | ||
EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)); | ||
if (!ctx) | ||
return NULL; | ||
EVP_CIPHER_CTX_init(ctx); | ||
return ctx; | ||
} | ||
#endif | ||
|
||
#if !defined(HAVE_EVP_CIPHER_CTX_FREE) | ||
void | ||
EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) | ||
{ | ||
if (ctx) { | ||
EVP_CIPHER_CTX_cleanup(ctx); | ||
OPENSSL_free(ctx); | ||
} | ||
} | ||
#endif | ||
|
||
/* added in 1.0.0 */ | ||
#if !defined(HAVE_EVP_CIPHER_CTX_COPY) | ||
/* | ||
* this function does not exist in OpenSSL yet... or ever?. | ||
* a future version may break this function. | ||
* tested on 0.9.7d. | ||
*/ | ||
int | ||
EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) | ||
{ | ||
memcpy(out, in, sizeof(EVP_CIPHER_CTX)); | ||
|
||
#if !defined(OPENSSL_NO_ENGINE) | ||
if (in->engine) ENGINE_add(out->engine); | ||
if (in->cipher_data) { | ||
out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); | ||
memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); | ||
} | ||
#endif | ||
|
||
return 1; | ||
} | ||
#endif | ||
|
||
#if !defined(OPENSSL_NO_HMAC) | ||
#if !defined(HAVE_HMAC_CTX_COPY) | ||
int | ||
HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) | ||
{ | ||
if (!out || !in) | ||
return 0; | ||
|
||
memcpy(out, in, sizeof(HMAC_CTX)); | ||
|
||
EVP_MD_CTX_copy(&out->md_ctx, &in->md_ctx); | ||
EVP_MD_CTX_copy(&out->i_ctx, &in->i_ctx); | ||
EVP_MD_CTX_copy(&out->o_ctx, &in->o_ctx); | ||
|
||
return 1; | ||
} | ||
#endif /* HAVE_HMAC_CTX_COPY */ | ||
#endif /* NO_HMAC */ | ||
|
||
/* added in 1.0.2 */ | ||
#if !defined(OPENSSL_NO_EC) | ||
#if !defined(HAVE_EC_CURVE_NIST2NID) | ||
static struct { | ||
const char *name; | ||
int nid; | ||
} nist_curves[] = { | ||
{"B-163", NID_sect163r2}, | ||
{"B-233", NID_sect233r1}, | ||
{"B-283", NID_sect283r1}, | ||
{"B-409", NID_sect409r1}, | ||
{"B-571", NID_sect571r1}, | ||
{"K-163", NID_sect163k1}, | ||
{"K-233", NID_sect233k1}, | ||
{"K-283", NID_sect283k1}, | ||
{"K-409", NID_sect409k1}, | ||
{"K-571", NID_sect571k1}, | ||
{"P-192", NID_X9_62_prime192v1}, | ||
{"P-224", NID_secp224r1}, | ||
{"P-256", NID_X9_62_prime256v1}, | ||
{"P-384", NID_secp384r1}, | ||
{"P-521", NID_secp521r1} | ||
}; | ||
|
||
int | ||
EC_curve_nist2nid(const char *name) | ||
{ | ||
size_t i; | ||
for (i = 0; i < (sizeof(nist_curves) / sizeof(nist_curves[0])); i++) { | ||
if (!strcmp(nist_curves[i].name, name)) | ||
return nist_curves[i].nid; | ||
} | ||
return NID_undef; | ||
} | ||
#endif | ||
#endif | ||
|
||
/*** added in 1.1.0 ***/ | ||
#if !defined(HAVE_HMAC_CTX_NEW) | ||
HMAC_CTX * | ||
HMAC_CTX_new(void) | ||
{ | ||
HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); | ||
if (!ctx) | ||
return NULL; | ||
HMAC_CTX_init(ctx); | ||
return ctx; | ||
} | ||
#endif | ||
|
||
#if !defined(HAVE_HMAC_CTX_FREE) | ||
void | ||
HMAC_CTX_free(HMAC_CTX *ctx) | ||
{ | ||
if (ctx) { | ||
HMAC_CTX_cleanup(ctx); | ||
OPENSSL_free(ctx); | ||
} | ||
} | ||
#endif | ||
|
||
#if !defined(HAVE_X509_CRL_GET0_SIGNATURE) | ||
void | ||
X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_CRL *crl) | ||
{ | ||
if (psig != NULL) | ||
*psig = crl->signature; | ||
if (palg != NULL) | ||
*palg = crl->sig_alg; | ||
} | ||
#endif | ||
|
||
#if !defined(HAVE_X509_REQ_GET0_SIGNATURE) | ||
void | ||
X509_REQ_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_REQ *req) | ||
{ | ||
if (psig != NULL) | ||
*psig = req->signature; | ||
if (palg != NULL) | ||
*palg = req->sig_alg; | ||
} | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_OPENSSL_MISSING_H_) | ||
#define _OSSL_OPENSSL_MISSING_H_ | ||
|
||
#include "ruby/config.h" | ||
|
||
/* added in 0.9.8X */ | ||
#if !defined(HAVE_EVP_CIPHER_CTX_NEW) | ||
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); | ||
#endif | ||
|
||
#if !defined(HAVE_EVP_CIPHER_CTX_FREE) | ||
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); | ||
#endif | ||
|
||
/* added in 1.0.0 */ | ||
#if !defined(HAVE_EVP_PKEY_BASE_ID) | ||
# define EVP_PKEY_base_id(pkey) EVP_PKEY_type((pkey)->type) | ||
#endif | ||
|
||
#if !defined(HAVE_EVP_CIPHER_CTX_COPY) | ||
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); | ||
#endif | ||
|
||
#if !defined(HAVE_HMAC_CTX_COPY) | ||
int HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); | ||
#endif | ||
|
||
#if !defined(HAVE_X509_STORE_CTX_GET0_CURRENT_CRL) | ||
# define X509_STORE_CTX_get0_current_crl(x) ((x)->current_crl) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_STORE_SET_VERIFY_CB) | ||
# define X509_STORE_set_verify_cb X509_STORE_set_verify_cb_func | ||
#endif | ||
|
||
#if !defined(HAVE_I2D_ASN1_SET_ANY) | ||
# define i2d_ASN1_SET_ANY(sk, x) i2d_ASN1_SET_OF_ASN1_TYPE((sk), (x), \ | ||
i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0) | ||
#endif | ||
|
||
/* added in 1.0.2 */ | ||
#if !defined(OPENSSL_NO_EC) | ||
#if !defined(HAVE_EC_CURVE_NIST2NID) | ||
int EC_curve_nist2nid(const char *); | ||
#endif | ||
#endif | ||
|
||
#if !defined(HAVE_X509_REVOKED_DUP) | ||
# define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((i2d_of_void *)i2d_X509_REVOKED, \ | ||
(d2i_of_void *)d2i_X509_REVOKED, (char *)(rev)) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_STORE_CTX_GET0_STORE) | ||
# define X509_STORE_CTX_get0_store(x) ((x)->ctx) | ||
#endif | ||
|
||
#if !defined(HAVE_SSL_IS_SERVER) | ||
# define SSL_is_server(s) ((s)->server) | ||
#endif | ||
|
||
/* added in 1.1.0 */ | ||
#if !defined(HAVE_BN_GENCB_NEW) | ||
# define BN_GENCB_new() ((BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB))) | ||
#endif | ||
|
||
#if !defined(HAVE_BN_GENCB_FREE) | ||
# define BN_GENCB_free(cb) OPENSSL_free(cb) | ||
#endif | ||
|
||
#if !defined(HAVE_BN_GENCB_GET_ARG) | ||
# define BN_GENCB_get_arg(cb) (cb)->arg | ||
#endif | ||
|
||
#if !defined(HAVE_EVP_MD_CTX_NEW) | ||
# define EVP_MD_CTX_new EVP_MD_CTX_create | ||
#endif | ||
|
||
#if !defined(HAVE_EVP_MD_CTX_FREE) | ||
# define EVP_MD_CTX_free EVP_MD_CTX_destroy | ||
#endif | ||
|
||
#if !defined(HAVE_HMAC_CTX_NEW) | ||
HMAC_CTX *HMAC_CTX_new(void); | ||
#endif | ||
|
||
#if !defined(HAVE_HMAC_CTX_FREE) | ||
void HMAC_CTX_free(HMAC_CTX *ctx); | ||
#endif | ||
|
||
#if !defined(HAVE_X509_STORE_GET_EX_DATA) | ||
# define X509_STORE_get_ex_data(x, idx) \ | ||
CRYPTO_get_ex_data(&(x)->ex_data, (idx)) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_STORE_SET_EX_DATA) | ||
# define X509_STORE_set_ex_data(x, idx, data) \ | ||
CRYPTO_set_ex_data(&(x)->ex_data, (idx), (data)) | ||
# define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ | ||
CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, (l), (p), \ | ||
(newf), (dupf), (freef)) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_CRL_GET0_SIGNATURE) | ||
void X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_CRL *crl); | ||
#endif | ||
|
||
#if !defined(HAVE_X509_REQ_GET0_SIGNATURE) | ||
void X509_REQ_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_REQ *req); | ||
#endif | ||
|
||
#if !defined(HAVE_X509_REVOKED_GET0_SERIALNUMBER) | ||
# define X509_REVOKED_get0_serialNumber(x) ((x)->serialNumber) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_REVOKED_GET0_REVOCATIONDATE) | ||
# define X509_REVOKED_get0_revocationDate(x) ((x)->revocationDate) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_GET0_TBS_SIGALG) | ||
# define X509_get0_tbs_sigalg(x) ((x)->cert_info->signature) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_STORE_CTX_GET0_UNTRUSTED) | ||
# define X509_STORE_CTX_get0_untrusted(x) ((x)->untrusted) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_STORE_CTX_GET0_CERT) | ||
# define X509_STORE_CTX_get0_cert(x) ((x)->cert) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_STORE_CTX_GET0_CHAIN) | ||
# define X509_STORE_CTX_get0_chain(ctx) X509_STORE_CTX_get_chain(ctx) | ||
#endif | ||
|
||
#if !defined(HAVE_OCSP_SINGLERESP_GET0_ID) | ||
# define OCSP_SINGLERESP_get0_id(s) ((s)->certId) | ||
#endif | ||
|
||
#if !defined(HAVE_SSL_CTX_GET_CIPHERS) | ||
# define SSL_CTX_get_ciphers(ctx) ((ctx)->cipher_list) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_UP_REF) | ||
# define X509_up_ref(x) \ | ||
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509) | ||
#endif | ||
|
||
#if !defined(HAVE_X509_CRL_UP_REF) | ||
# define X509_CRL_up_ref(x) \ | ||
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_CRL); | ||
#endif | ||
|
||
#if !defined(HAVE_X509_STORE_UP_REF) | ||
# define X509_STORE_up_ref(x) \ | ||
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_STORE); | ||
#endif | ||
|
||
#if !defined(HAVE_SSL_SESSION_UP_REF) | ||
# define SSL_SESSION_up_ref(x) \ | ||
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_SSL_SESSION); | ||
#endif | ||
|
||
#if !defined(HAVE_EVP_PKEY_UP_REF) | ||
# define EVP_PKEY_up_ref(x) \ | ||
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_EVP_PKEY); | ||
#endif | ||
|
||
#if !defined(HAVE_OPAQUE_OPENSSL) | ||
#define IMPL_PKEY_GETTER(_type, _name) \ | ||
static inline _type *EVP_PKEY_get0_##_type(EVP_PKEY *pkey) { \ | ||
return pkey->pkey._name; } | ||
#define IMPL_KEY_ACCESSOR2(_type, _group, a1, a2, _fail_cond) \ | ||
static inline void _type##_get0_##_group(_type *obj, const BIGNUM **a1, const BIGNUM **a2) { \ | ||
if (a1) *a1 = obj->a1; \ | ||
if (a2) *a2 = obj->a2; } \ | ||
static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2) { \ | ||
if (_fail_cond) return 0; \ | ||
BN_clear_free(obj->a1); obj->a1 = a1; \ | ||
BN_clear_free(obj->a2); obj->a2 = a2; \ | ||
return 1; } | ||
#define IMPL_KEY_ACCESSOR3(_type, _group, a1, a2, a3, _fail_cond) \ | ||
static inline void _type##_get0_##_group(_type *obj, const BIGNUM **a1, const BIGNUM **a2, const BIGNUM **a3) { \ | ||
if (a1) *a1 = obj->a1; \ | ||
if (a2) *a2 = obj->a2; \ | ||
if (a3) *a3 = obj->a3; } \ | ||
static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2, BIGNUM *a3) { \ | ||
if (_fail_cond) return 0; \ | ||
BN_clear_free(obj->a1); obj->a1 = a1; \ | ||
BN_clear_free(obj->a2); obj->a2 = a2; \ | ||
BN_clear_free(obj->a3); obj->a3 = a3; \ | ||
return 1; } | ||
|
||
#if !defined(OPENSSL_NO_RSA) | ||
IMPL_PKEY_GETTER(RSA, rsa) | ||
IMPL_KEY_ACCESSOR3(RSA, key, n, e, d, (n == obj->n || e == obj->e || (obj->d && d == obj->d))) | ||
IMPL_KEY_ACCESSOR2(RSA, factors, p, q, (p == obj->p || q == obj->q)) | ||
IMPL_KEY_ACCESSOR3(RSA, crt_params, dmp1, dmq1, iqmp, (dmp1 == obj->dmp1 || dmq1 == obj->dmq1 || iqmp == obj->iqmp)) | ||
#endif | ||
|
||
#if !defined(OPENSSL_NO_DSA) | ||
IMPL_PKEY_GETTER(DSA, dsa) | ||
IMPL_KEY_ACCESSOR2(DSA, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key))) | ||
IMPL_KEY_ACCESSOR3(DSA, pqg, p, q, g, (p == obj->p || q == obj->q || g == obj->g)) | ||
#endif | ||
|
||
#if !defined(OPENSSL_NO_DH) | ||
IMPL_PKEY_GETTER(DH, dh) | ||
IMPL_KEY_ACCESSOR2(DH, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key))) | ||
IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || obj->q && q == obj->q || g == obj->g)) | ||
static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; } | ||
#endif | ||
|
||
#if !defined(OPENSSL_NO_EC) | ||
IMPL_PKEY_GETTER(EC_KEY, ec) | ||
#endif | ||
|
||
#undef IMPL_PKEY_GETTER | ||
#undef IMPL_KEY_ACCESSOR2 | ||
#undef IMPL_KEY_ACCESSOR3 | ||
#endif /* HAVE_OPAQUE_OPENSSL */ | ||
|
||
#if defined(HAVE_AUTHENTICATED_ENCRYPTION) && !defined(EVP_CTRL_AEAD_GET_TAG) | ||
# define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG | ||
# define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG | ||
#endif | ||
|
||
#endif /* _OSSL_OPENSSL_MISSING_H_ */ |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_H_) | ||
#define _OSSL_H_ | ||
|
||
#include RUBY_EXTCONF_H | ||
|
||
#if 0 | ||
mOSSL = rb_define_module("OpenSSL"); | ||
mX509 = rb_define_module_under(mOSSL, "X509"); | ||
#endif | ||
|
||
/* | ||
* OpenSSL has defined RFILE and Ruby has defined RFILE - so undef it! | ||
*/ | ||
#if defined(RFILE) /*&& !defined(OSSL_DEBUG)*/ | ||
# undef RFILE | ||
#endif | ||
#include <ruby.h> | ||
#include <ruby/io.h> | ||
#include <ruby/thread.h> | ||
|
||
#include <openssl/opensslv.h> | ||
|
||
#ifdef HAVE_ASSERT_H | ||
# include <assert.h> | ||
#else | ||
# define assert(condition) | ||
#endif | ||
|
||
#if defined(_WIN32) && !defined(LIBRESSL_VERSION_NUMBER) | ||
# include <openssl/e_os2.h> | ||
# if !defined(OPENSSL_SYS_WIN32) | ||
# define OPENSSL_SYS_WIN32 1 | ||
# endif | ||
# include <winsock2.h> | ||
#endif | ||
#include <errno.h> | ||
#include <openssl/err.h> | ||
#include <openssl/asn1.h> | ||
#include <openssl/x509v3.h> | ||
#include <openssl/ssl.h> | ||
#include <openssl/pkcs12.h> | ||
#include <openssl/pkcs7.h> | ||
#include <openssl/hmac.h> | ||
#include <openssl/rand.h> | ||
#include <openssl/conf.h> | ||
#include <openssl/conf_api.h> | ||
#if !defined(_WIN32) | ||
# include <openssl/crypto.h> | ||
#endif | ||
#if !defined(OPENSSL_NO_ENGINE) | ||
# include <openssl/engine.h> | ||
#endif | ||
#if !defined(OPENSSL_NO_OCSP) | ||
# include <openssl/ocsp.h> | ||
#endif | ||
|
||
/* | ||
* Common Module | ||
*/ | ||
extern VALUE mOSSL; | ||
|
||
/* | ||
* Common Error Class | ||
*/ | ||
extern VALUE eOSSLError; | ||
|
||
/* | ||
* CheckTypes | ||
*/ | ||
#define OSSL_Check_Kind(obj, klass) do {\ | ||
if (!rb_obj_is_kind_of((obj), (klass))) {\ | ||
ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected kind of %"PRIsVALUE")",\ | ||
rb_obj_class(obj), (klass));\ | ||
}\ | ||
} while (0) | ||
|
||
#define OSSL_Check_Instance(obj, klass) do {\ | ||
if (!rb_obj_is_instance_of((obj), (klass))) {\ | ||
ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected instance of %"PRIsVALUE")",\ | ||
rb_obj_class(obj), (klass));\ | ||
}\ | ||
} while (0) | ||
|
||
#define OSSL_Check_Same_Class(obj1, obj2) do {\ | ||
if (!rb_obj_is_instance_of((obj1), rb_obj_class(obj2))) {\ | ||
ossl_raise(rb_eTypeError, "wrong argument type");\ | ||
}\ | ||
} while (0) | ||
|
||
/* | ||
* String to HEXString conversion | ||
*/ | ||
int string2hex(const unsigned char *, int, char **, int *); | ||
|
||
/* | ||
* Data Conversion | ||
*/ | ||
STACK_OF(X509) *ossl_x509_ary2sk0(VALUE); | ||
STACK_OF(X509) *ossl_x509_ary2sk(VALUE); | ||
STACK_OF(X509) *ossl_protect_x509_ary2sk(VALUE,int*); | ||
VALUE ossl_x509_sk2ary(STACK_OF(X509) *certs); | ||
VALUE ossl_x509crl_sk2ary(STACK_OF(X509_CRL) *crl); | ||
VALUE ossl_x509name_sk2ary(STACK_OF(X509_NAME) *names); | ||
VALUE ossl_buf2str(char *buf, int len); | ||
#define ossl_str_adjust(str, p) \ | ||
do{\ | ||
long len = RSTRING_LEN(str);\ | ||
long newlen = (long)((p) - (unsigned char*)RSTRING_PTR(str));\ | ||
assert(newlen <= len);\ | ||
rb_str_set_len((str), newlen);\ | ||
}while(0) | ||
|
||
/* | ||
* Our default PEM callback | ||
*/ | ||
/* Convert the argument to String and validate the length. Note this may raise. */ | ||
VALUE ossl_pem_passwd_value(VALUE); | ||
/* Can be casted to pem_password_cb. If a password (String) is passed as the | ||
* "arbitrary data" (typically the last parameter of PEM_{read,write}_ | ||
* functions), uses the value. If not, but a block is given, yields to it. | ||
* If not either, fallbacks to PEM_def_callback() which reads from stdin. */ | ||
int ossl_pem_passwd_cb(char *, int, int, void *); | ||
|
||
/* | ||
* Clear BIO* with this in PEM/DER fallback scenarios to avoid decoding | ||
* errors piling up in OpenSSL::Errors | ||
*/ | ||
#define OSSL_BIO_reset(bio) do { \ | ||
(void)BIO_reset((bio)); \ | ||
ossl_clear_error(); \ | ||
} while (0) | ||
|
||
/* | ||
* ERRor messages | ||
*/ | ||
#define OSSL_ErrMsg() ERR_reason_error_string(ERR_get_error()) | ||
NORETURN(void ossl_raise(VALUE, const char *, ...)); | ||
VALUE ossl_exc_new(VALUE, const char *, ...); | ||
/* Clear OpenSSL error queue. If dOSSL is set, rb_warn() them. */ | ||
void ossl_clear_error(void); | ||
|
||
/* | ||
* Verify callback | ||
*/ | ||
extern int ossl_store_ctx_ex_verify_cb_idx; | ||
extern int ossl_store_ex_verify_cb_idx; | ||
|
||
struct ossl_verify_cb_args { | ||
VALUE proc; | ||
VALUE preverify_ok; | ||
VALUE store_ctx; | ||
}; | ||
|
||
VALUE ossl_call_verify_cb_proc(struct ossl_verify_cb_args *); | ||
int ossl_verify_cb(int, X509_STORE_CTX *); | ||
|
||
/* | ||
* String to DER String | ||
*/ | ||
extern ID ossl_s_to_der; | ||
VALUE ossl_to_der(VALUE); | ||
VALUE ossl_to_der_if_possible(VALUE); | ||
|
||
/* | ||
* Debug | ||
*/ | ||
extern VALUE dOSSL; | ||
|
||
#if defined(HAVE_VA_ARGS_MACRO) | ||
#define OSSL_Debug(...) do { \ | ||
if (dOSSL == Qtrue) { \ | ||
fprintf(stderr, "OSSL_DEBUG: "); \ | ||
fprintf(stderr, __VA_ARGS__); \ | ||
fprintf(stderr, " [%s:%d]\n", __FILE__, __LINE__); \ | ||
} \ | ||
} while (0) | ||
|
||
#define OSSL_Warning(fmt, ...) do { \ | ||
OSSL_Debug((fmt), ##__VA_ARGS__); \ | ||
rb_warning((fmt), ##__VA_ARGS__); \ | ||
} while (0) | ||
|
||
#define OSSL_Warn(fmt, ...) do { \ | ||
OSSL_Debug((fmt), ##__VA_ARGS__); \ | ||
rb_warn((fmt), ##__VA_ARGS__); \ | ||
} while (0) | ||
#else | ||
void ossl_debug(const char *, ...); | ||
#define OSSL_Debug ossl_debug | ||
#define OSSL_Warning rb_warning | ||
#define OSSL_Warn rb_warn | ||
#endif | ||
|
||
/* | ||
* Include all parts | ||
*/ | ||
#include "openssl_missing.h" | ||
#include "ruby_missing.h" | ||
#include "ossl_asn1.h" | ||
#include "ossl_bio.h" | ||
#include "ossl_bn.h" | ||
#include "ossl_cipher.h" | ||
#include "ossl_config.h" | ||
#include "ossl_digest.h" | ||
#include "ossl_hmac.h" | ||
#include "ossl_ns_spki.h" | ||
#include "ossl_ocsp.h" | ||
#include "ossl_pkcs12.h" | ||
#include "ossl_pkcs7.h" | ||
#include "ossl_pkcs5.h" | ||
#include "ossl_pkey.h" | ||
#include "ossl_rand.h" | ||
#include "ossl_ssl.h" | ||
#include "ossl_version.h" | ||
#include "ossl_x509.h" | ||
#include "ossl_engine.h" | ||
|
||
void Init_openssl(void); | ||
|
||
#endif /* _OSSL_H_ */ |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* 'OpenSSL for Ruby' team members | ||
* Copyright (C) 2003 | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_ASN1_H_) | ||
#define _OSSL_ASN1_H_ | ||
|
||
/* | ||
* ASN1_DATE conversions | ||
*/ | ||
VALUE asn1time_to_time(ASN1_TIME *); | ||
#if defined(HAVE_ASN1_TIME_ADJ) | ||
/* Splits VALUE to seconds and offset days. VALUE is typically a Time or an | ||
* Integer. This is used when updating ASN1_*TIME with ASN1_TIME_adj() or | ||
* X509_time_adj_ex(). We can't use ASN1_TIME_set() and X509_time_adj() because | ||
* they have the Year 2038 issue on sizeof(time_t) == 4 environment */ | ||
void ossl_time_split(VALUE, time_t *, int *); | ||
#else | ||
time_t time_to_time_t(VALUE); | ||
#endif | ||
|
||
/* | ||
* ASN1_STRING conversions | ||
*/ | ||
VALUE asn1str_to_str(ASN1_STRING *); | ||
|
||
/* | ||
* ASN1_INTEGER conversions | ||
*/ | ||
VALUE asn1integer_to_num(ASN1_INTEGER *); | ||
ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *); | ||
|
||
/* | ||
* ASN1 module | ||
*/ | ||
extern VALUE mASN1; | ||
extern VALUE eASN1Error; | ||
|
||
extern VALUE cASN1Data; | ||
extern VALUE cASN1Primitive; | ||
extern VALUE cASN1Constructive; | ||
|
||
extern VALUE cASN1Boolean; /* BOOLEAN */ | ||
extern VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */ | ||
extern VALUE cASN1BitString; /* BIT STRING */ | ||
extern VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */ | ||
extern VALUE cASN1NumericString, cASN1PrintableString; | ||
extern VALUE cASN1T61String, cASN1VideotexString; | ||
extern VALUE cASN1IA5String, cASN1GraphicString; | ||
extern VALUE cASN1ISO64String, cASN1GeneralString; | ||
extern VALUE cASN1UniversalString, cASN1BMPString; | ||
extern VALUE cASN1Null; /* NULL */ | ||
extern VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */ | ||
extern VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */ | ||
extern VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ | ||
|
||
ASN1_TYPE *ossl_asn1_get_asn1type(VALUE); | ||
|
||
void Init_ossl_asn1(void); | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
* 'OpenSSL for Ruby' team members | ||
* Copyright (C) 2003 | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#include "ossl.h" | ||
#ifdef HAVE_UNISTD_H | ||
#include <unistd.h> | ||
#endif | ||
|
||
BIO * | ||
ossl_obj2bio(VALUE obj) | ||
{ | ||
BIO *bio; | ||
|
||
if (RB_TYPE_P(obj, T_FILE)) { | ||
rb_io_t *fptr; | ||
FILE *fp; | ||
int fd; | ||
|
||
GetOpenFile(obj, fptr); | ||
rb_io_check_readable(fptr); | ||
if ((fd = rb_cloexec_dup(FPTR_TO_FD(fptr))) < 0){ | ||
rb_sys_fail(0); | ||
} | ||
rb_update_max_fd(fd); | ||
if (!(fp = fdopen(fd, "r"))){ | ||
int e = errno; | ||
close(fd); | ||
rb_syserr_fail(e, 0); | ||
} | ||
if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){ | ||
fclose(fp); | ||
ossl_raise(eOSSLError, NULL); | ||
} | ||
} | ||
else { | ||
StringValue(obj); | ||
bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj)); | ||
if (!bio) ossl_raise(eOSSLError, NULL); | ||
} | ||
|
||
return bio; | ||
} | ||
|
||
BIO * | ||
ossl_protect_obj2bio(VALUE obj, int *status) | ||
{ | ||
BIO *ret = NULL; | ||
ret = (BIO*)rb_protect((VALUE(*)_((VALUE)))ossl_obj2bio, obj, status); | ||
return ret; | ||
} | ||
|
||
VALUE | ||
ossl_membio2str0(BIO *bio) | ||
{ | ||
VALUE ret; | ||
BUF_MEM *buf; | ||
|
||
BIO_get_mem_ptr(bio, &buf); | ||
ret = rb_str_new(buf->data, buf->length); | ||
|
||
return ret; | ||
} | ||
|
||
VALUE | ||
ossl_protect_membio2str(BIO *bio, int *status) | ||
{ | ||
return rb_protect((VALUE(*)_((VALUE)))ossl_membio2str0, (VALUE)bio, status); | ||
} | ||
|
||
VALUE | ||
ossl_membio2str(BIO *bio) | ||
{ | ||
VALUE ret; | ||
int status = 0; | ||
|
||
ret = ossl_protect_membio2str(bio, &status); | ||
BIO_free(bio); | ||
if(status) rb_jump_tag(status); | ||
|
||
return ret; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* 'OpenSSL for Ruby' team members | ||
* Copyright (C) 2003 | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_BIO_H_) | ||
#define _OSSL_BIO_H_ | ||
|
||
BIO *ossl_obj2bio(VALUE); | ||
BIO *ossl_protect_obj2bio(VALUE,int*); | ||
VALUE ossl_membio2str0(BIO*); | ||
VALUE ossl_membio2str(BIO*); | ||
VALUE ossl_protect_membio2str(BIO*,int*); | ||
|
||
#endif |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_BN_H_) | ||
#define _OSSL_BN_H_ | ||
|
||
extern VALUE cBN; | ||
extern VALUE eBNError; | ||
|
||
extern BN_CTX *ossl_bn_ctx; | ||
|
||
VALUE ossl_bn_new(const BIGNUM *); | ||
BIGNUM *GetBNPtr(VALUE); | ||
void Init_ossl_bn(void); | ||
|
||
|
||
#endif /* _OSS_BN_H_ */ |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_CIPHER_H_) | ||
#define _OSSL_CIPHER_H_ | ||
|
||
extern VALUE cCipher; | ||
extern VALUE eCipherError; | ||
|
||
const EVP_CIPHER *GetCipherPtr(VALUE); | ||
VALUE ossl_cipher_new(const EVP_CIPHER *); | ||
void Init_ossl_cipher(void); | ||
|
||
#endif /* _OSSL_CIPHER_H_ */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#include "ossl.h" | ||
|
||
|
||
/* | ||
* Classes | ||
*/ | ||
VALUE cConfig; | ||
/* Document-class: OpenSSL::ConfigError | ||
* | ||
* General error for openssl library configuration files. Including formatting, | ||
* parsing errors, etc. | ||
*/ | ||
VALUE eConfigError; | ||
|
||
/* | ||
* Public | ||
*/ | ||
|
||
/* | ||
* GetConfigPtr is a public C-level function for getting OpenSSL CONF struct | ||
* from an OpenSSL::Config(eConfig) instance. We decided to implement | ||
* OpenSSL::Config in Ruby level but we need to pass native CONF struct for | ||
* some OpenSSL features such as X509V3_EXT_*. | ||
*/ | ||
CONF * | ||
GetConfigPtr(VALUE obj) | ||
{ | ||
CONF *conf; | ||
VALUE str; | ||
BIO *bio; | ||
long eline = -1; | ||
|
||
OSSL_Check_Kind(obj, cConfig); | ||
str = rb_funcall(obj, rb_intern("to_s"), 0); | ||
bio = ossl_obj2bio(str); | ||
conf = NCONF_new(NULL); | ||
if(!conf){ | ||
BIO_free(bio); | ||
ossl_raise(eConfigError, NULL); | ||
} | ||
if(!NCONF_load_bio(conf, bio, &eline)){ | ||
BIO_free(bio); | ||
NCONF_free(conf); | ||
if (eline <= 0) ossl_raise(eConfigError, "wrong config format"); | ||
else ossl_raise(eConfigError, "error in line %d", eline); | ||
ossl_raise(eConfigError, NULL); | ||
} | ||
BIO_free(bio); | ||
|
||
return conf; | ||
} | ||
|
||
/* Document-const: DEFAULT_CONFIG_FILE | ||
* | ||
* The default system configuration file for openssl | ||
*/ | ||
|
||
/* | ||
* INIT | ||
*/ | ||
void | ||
Init_ossl_config(void) | ||
{ | ||
char *default_config_file; | ||
eConfigError = rb_define_class_under(mOSSL, "ConfigError", eOSSLError); | ||
cConfig = rb_define_class_under(mOSSL, "Config", rb_cObject); | ||
|
||
default_config_file = CONF_get1_default_config_file(); | ||
rb_define_const(cConfig, "DEFAULT_CONFIG_FILE", | ||
rb_str_new2(default_config_file)); | ||
OPENSSL_free(default_config_file); | ||
/* methods are defined by openssl/config.rb */ | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_CONFIG_H_) | ||
#define _OSSL_CONFIG_H_ | ||
|
||
extern VALUE cConfig; | ||
extern VALUE eConfigError; | ||
|
||
CONF* GetConfigPtr(VALUE obj); | ||
CONF* DupConfigPtr(VALUE obj); | ||
void Init_ossl_config(void); | ||
|
||
#endif /* _OSSL_CONFIG_H_ */ |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_DIGEST_H_) | ||
#define _OSSL_DIGEST_H_ | ||
|
||
extern VALUE cDigest; | ||
extern VALUE eDigestError; | ||
|
||
const EVP_MD *GetDigestPtr(VALUE); | ||
VALUE ossl_digest_new(const EVP_MD *); | ||
void Init_ossl_digest(void); | ||
|
||
#endif /* _OSSL_DIGEST_H_ */ |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(OSSL_ENGINE_H) | ||
#define OSSL_ENGINE_H | ||
|
||
extern VALUE cEngine; | ||
extern VALUE eEngineError; | ||
|
||
void Init_ossl_engine(void); | ||
|
||
#endif /* OSSL_ENGINE_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,382 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(OPENSSL_NO_HMAC) | ||
|
||
#include "ossl.h" | ||
|
||
#define NewHMAC(klass) \ | ||
TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0) | ||
#define GetHMAC(obj, ctx) do { \ | ||
TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \ | ||
if (!(ctx)) { \ | ||
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \ | ||
} \ | ||
} while (0) | ||
#define SafeGetHMAC(obj, ctx) do { \ | ||
OSSL_Check_Kind((obj), cHMAC); \ | ||
GetHMAC((obj), (ctx)); \ | ||
} while (0) | ||
|
||
/* | ||
* Classes | ||
*/ | ||
VALUE cHMAC; | ||
VALUE eHMACError; | ||
|
||
/* | ||
* Public | ||
*/ | ||
|
||
/* | ||
* Private | ||
*/ | ||
static void | ||
ossl_hmac_free(void *ctx) | ||
{ | ||
HMAC_CTX_free(ctx); | ||
} | ||
|
||
static const rb_data_type_t ossl_hmac_type = { | ||
"OpenSSL/HMAC", | ||
{ | ||
0, ossl_hmac_free, | ||
}, | ||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY, | ||
}; | ||
|
||
static VALUE | ||
ossl_hmac_alloc(VALUE klass) | ||
{ | ||
VALUE obj; | ||
HMAC_CTX *ctx; | ||
|
||
obj = NewHMAC(klass); | ||
ctx = HMAC_CTX_new(); | ||
if (!ctx) | ||
ossl_raise(eHMACError, NULL); | ||
RTYPEDDATA_DATA(obj) = ctx; | ||
|
||
return obj; | ||
} | ||
|
||
|
||
/* | ||
* call-seq: | ||
* HMAC.new(key, digest) -> hmac | ||
* | ||
* Returns an instance of OpenSSL::HMAC set with the key and digest | ||
* algorithm to be used. The instance represents the initial state of | ||
* the message authentication code before any data has been processed. | ||
* To process data with it, use the instance method #update with your | ||
* data as an argument. | ||
* | ||
* === Example | ||
* | ||
* key = 'key' | ||
* digest = OpenSSL::Digest.new('sha1') | ||
* instance = OpenSSL::HMAC.new(key, digest) | ||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f | ||
* instance.class | ||
* #=> OpenSSL::HMAC | ||
* | ||
* === A note about comparisons | ||
* | ||
* Two instances won't be equal when they're compared, even if they have the | ||
* same value. Use #to_s or #hexdigest to return the authentication code that | ||
* the instance represents. For example: | ||
* | ||
* other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) | ||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f | ||
* instance | ||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f | ||
* instance == other_instance | ||
* #=> false | ||
* instance.to_s == other_instance.to_s | ||
* #=> true | ||
* | ||
*/ | ||
static VALUE | ||
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) | ||
{ | ||
HMAC_CTX *ctx; | ||
|
||
StringValue(key); | ||
GetHMAC(self, ctx); | ||
HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key), | ||
GetDigestPtr(digest), NULL); | ||
|
||
return self; | ||
} | ||
|
||
static VALUE | ||
ossl_hmac_copy(VALUE self, VALUE other) | ||
{ | ||
HMAC_CTX *ctx1, *ctx2; | ||
|
||
rb_check_frozen(self); | ||
if (self == other) return self; | ||
|
||
GetHMAC(self, ctx1); | ||
SafeGetHMAC(other, ctx2); | ||
|
||
if (!HMAC_CTX_copy(ctx1, ctx2)) | ||
ossl_raise(eHMACError, "HMAC_CTX_copy"); | ||
return self; | ||
} | ||
|
||
/* | ||
* call-seq: | ||
* hmac.update(string) -> self | ||
* | ||
* Returns +self+ updated with the message to be authenticated. | ||
* Can be called repeatedly with chunks of the message. | ||
* | ||
* === Example | ||
* | ||
* first_chunk = 'The quick brown fox jumps ' | ||
* second_chunk = 'over the lazy dog' | ||
* | ||
* instance.update(first_chunk) | ||
* #=> 5b9a8038a65d571076d97fe783989e52278a492a | ||
* instance.update(second_chunk) | ||
* #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 | ||
* | ||
*/ | ||
static VALUE | ||
ossl_hmac_update(VALUE self, VALUE data) | ||
{ | ||
HMAC_CTX *ctx; | ||
|
||
StringValue(data); | ||
GetHMAC(self, ctx); | ||
HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data)); | ||
|
||
return self; | ||
} | ||
|
||
static void | ||
hmac_final(HMAC_CTX *ctx, unsigned char **buf, unsigned int *buf_len) | ||
{ | ||
HMAC_CTX *final; | ||
|
||
final = HMAC_CTX_new(); | ||
if (!final) | ||
ossl_raise(eHMACError, "HMAC_CTX_new"); | ||
|
||
if (!HMAC_CTX_copy(final, ctx)) { | ||
HMAC_CTX_free(final); | ||
ossl_raise(eHMACError, "HMAC_CTX_copy"); | ||
} | ||
|
||
if (!(*buf = OPENSSL_malloc(HMAC_size(final)))) { | ||
HMAC_CTX_free(final); | ||
OSSL_Debug("Allocating %d mem", (int)HMAC_size(final)); | ||
ossl_raise(eHMACError, "Cannot allocate memory for hmac"); | ||
} | ||
HMAC_Final(final, *buf, buf_len); | ||
HMAC_CTX_free(final); | ||
} | ||
|
||
/* | ||
* call-seq: | ||
* hmac.digest -> string | ||
* | ||
* Returns the authentication code an instance represents as a binary string. | ||
* | ||
* === Example | ||
* | ||
* instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) | ||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f | ||
* instance.digest | ||
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?" | ||
* | ||
*/ | ||
static VALUE | ||
ossl_hmac_digest(VALUE self) | ||
{ | ||
HMAC_CTX *ctx; | ||
unsigned char *buf; | ||
unsigned int buf_len; | ||
VALUE digest; | ||
|
||
GetHMAC(self, ctx); | ||
hmac_final(ctx, &buf, &buf_len); | ||
digest = ossl_buf2str((char *)buf, buf_len); | ||
|
||
return digest; | ||
} | ||
|
||
/* | ||
* call-seq: | ||
* hmac.hexdigest -> string | ||
* | ||
* Returns the authentication code an instance represents as a hex-encoded | ||
* string. | ||
* | ||
*/ | ||
static VALUE | ||
ossl_hmac_hexdigest(VALUE self) | ||
{ | ||
HMAC_CTX *ctx; | ||
unsigned char *buf; | ||
char *hexbuf; | ||
unsigned int buf_len; | ||
VALUE hexdigest; | ||
|
||
GetHMAC(self, ctx); | ||
hmac_final(ctx, &buf, &buf_len); | ||
if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * (int)buf_len) { | ||
OPENSSL_free(buf); | ||
ossl_raise(eHMACError, "Memory alloc error"); | ||
} | ||
OPENSSL_free(buf); | ||
hexdigest = ossl_buf2str(hexbuf, 2 * buf_len); | ||
|
||
return hexdigest; | ||
} | ||
|
||
/* | ||
* call-seq: | ||
* hmac.reset -> self | ||
* | ||
* Returns +self+ as it was when it was first initialized, with all processed | ||
* data cleared from it. | ||
* | ||
* === Example | ||
* | ||
* data = "The quick brown fox jumps over the lazy dog" | ||
* instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) | ||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f | ||
* | ||
* instance.update(data) | ||
* #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 | ||
* instance.reset | ||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f | ||
* | ||
*/ | ||
static VALUE | ||
ossl_hmac_reset(VALUE self) | ||
{ | ||
HMAC_CTX *ctx; | ||
|
||
GetHMAC(self, ctx); | ||
HMAC_Init_ex(ctx, NULL, 0, NULL, NULL); | ||
|
||
return self; | ||
} | ||
|
||
/* | ||
* call-seq: | ||
* HMAC.digest(digest, key, data) -> aString | ||
* | ||
* Returns the authentication code as a binary string. The +digest+ parameter | ||
* must be an instance of OpenSSL::Digest. | ||
* | ||
* === Example | ||
* | ||
* key = 'key' | ||
* data = 'The quick brown fox jumps over the lazy dog' | ||
* digest = OpenSSL::Digest.new('sha1') | ||
* | ||
* hmac = OpenSSL::HMAC.digest(digest, key, data) | ||
* #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9" | ||
* | ||
*/ | ||
static VALUE | ||
ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data) | ||
{ | ||
unsigned char *buf; | ||
unsigned int buf_len; | ||
|
||
StringValue(key); | ||
StringValue(data); | ||
buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key), | ||
(unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len); | ||
|
||
return rb_str_new((const char *)buf, buf_len); | ||
} | ||
|
||
/* | ||
* call-seq: | ||
* HMAC.hexdigest(digest, key, data) -> aString | ||
* | ||
* Returns the authentication code as a hex-encoded string. The +digest+ | ||
* parameter must be an instance of OpenSSL::Digest. | ||
* | ||
* === Example | ||
* | ||
* key = 'key' | ||
* data = 'The quick brown fox jumps over the lazy dog' | ||
* digest = OpenSSL::Digest.new('sha1') | ||
* | ||
* hmac = OpenSSL::HMAC.hexdigest(digest, key, data) | ||
* #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" | ||
* | ||
*/ | ||
static VALUE | ||
ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data) | ||
{ | ||
unsigned char *buf; | ||
char *hexbuf; | ||
unsigned int buf_len; | ||
VALUE hexdigest; | ||
|
||
StringValue(key); | ||
StringValue(data); | ||
|
||
buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key), | ||
(unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len); | ||
if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * (int)buf_len) { | ||
ossl_raise(eHMACError, "Cannot convert buf to hexbuf"); | ||
} | ||
hexdigest = ossl_buf2str(hexbuf, 2 * buf_len); | ||
|
||
return hexdigest; | ||
} | ||
|
||
/* | ||
* INIT | ||
*/ | ||
void | ||
Init_ossl_hmac(void) | ||
{ | ||
#if 0 | ||
/* :nodoc: */ | ||
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ | ||
#endif | ||
|
||
eHMACError = rb_define_class_under(mOSSL, "HMACError", eOSSLError); | ||
|
||
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject); | ||
|
||
rb_define_alloc_func(cHMAC, ossl_hmac_alloc); | ||
rb_define_singleton_method(cHMAC, "digest", ossl_hmac_s_digest, 3); | ||
rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3); | ||
|
||
rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2); | ||
rb_define_copy_func(cHMAC, ossl_hmac_copy); | ||
|
||
rb_define_method(cHMAC, "reset", ossl_hmac_reset, 0); | ||
rb_define_method(cHMAC, "update", ossl_hmac_update, 1); | ||
rb_define_alias(cHMAC, "<<", "update"); | ||
rb_define_method(cHMAC, "digest", ossl_hmac_digest, 0); | ||
rb_define_method(cHMAC, "hexdigest", ossl_hmac_hexdigest, 0); | ||
rb_define_alias(cHMAC, "inspect", "hexdigest"); | ||
rb_define_alias(cHMAC, "to_s", "hexdigest"); | ||
} | ||
|
||
#else /* NO_HMAC */ | ||
# warning >>> OpenSSL is compiled without HMAC support <<< | ||
void | ||
Init_ossl_hmac(void) | ||
{ | ||
rb_warning("HMAC is not available: OpenSSL is compiled without HMAC."); | ||
} | ||
#endif /* NO_HMAC */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_HMAC_H_) | ||
#define _OSSL_HMAC_H_ | ||
|
||
extern VALUE cHMAC; | ||
extern VALUE eHMACError; | ||
|
||
void Init_ossl_hmac(void); | ||
|
||
#endif /* _OSSL_HMAC_H_ */ |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_NS_SPKI_H_) | ||
#define _OSSL_NS_SPKI_H_ | ||
|
||
extern VALUE mNetscape; | ||
extern VALUE cSPKI; | ||
extern VALUE eSPKIError; | ||
|
||
void Init_ossl_ns_spki(void); | ||
|
||
#endif /* _OSSL_NS_SPKI_H_ */ |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* 'OpenSSL for Ruby' project | ||
* Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz> | ||
* Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org> | ||
* All rights reserved. | ||
*/ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_OCSP_H_) | ||
#define _OSSL_OCSP_H_ | ||
|
||
#if !defined(OPENSSL_NO_OCSP) | ||
extern VALUE mOCSP; | ||
extern VALUE cOPCSReq; | ||
extern VALUE cOPCSRes; | ||
extern VALUE cOPCSBasicRes; | ||
#endif | ||
|
||
void Init_ossl_ocsp(void); | ||
|
||
#endif /* _OSSL_OCSP_H_ */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#include "ossl.h" | ||
|
||
#define NewPKCS12(klass) \ | ||
TypedData_Wrap_Struct((klass), &ossl_pkcs12_type, 0) | ||
|
||
#define SetPKCS12(obj, p12) do { \ | ||
if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \ | ||
RTYPEDDATA_DATA(obj) = (p12); \ | ||
} while (0) | ||
|
||
#define GetPKCS12(obj, p12) do { \ | ||
TypedData_Get_Struct((obj), PKCS12, &ossl_pkcs12_type, (p12)); \ | ||
if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \ | ||
} while (0) | ||
|
||
#define SafeGetPKCS12(obj, p12) do { \ | ||
OSSL_Check_Kind((obj), cPKCS12); \ | ||
GetPKCS12((obj), (p12)); \ | ||
} while (0) | ||
|
||
#define ossl_pkcs12_set_key(o,v) rb_iv_set((o), "@key", (v)) | ||
#define ossl_pkcs12_set_cert(o,v) rb_iv_set((o), "@certificate", (v)) | ||
#define ossl_pkcs12_set_ca_certs(o,v) rb_iv_set((o), "@ca_certs", (v)) | ||
#define ossl_pkcs12_get_key(o) rb_iv_get((o), "@key") | ||
#define ossl_pkcs12_get_cert(o) rb_iv_get((o), "@certificate") | ||
#define ossl_pkcs12_get_ca_certs(o) rb_iv_get((o), "@ca_certs") | ||
|
||
/* | ||
* Classes | ||
*/ | ||
VALUE cPKCS12; | ||
VALUE ePKCS12Error; | ||
|
||
/* | ||
* Private | ||
*/ | ||
static void | ||
ossl_pkcs12_free(void *ptr) | ||
{ | ||
PKCS12_free(ptr); | ||
} | ||
|
||
static const rb_data_type_t ossl_pkcs12_type = { | ||
"OpenSSL/PKCS12", | ||
{ | ||
0, ossl_pkcs12_free, | ||
}, | ||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY, | ||
}; | ||
|
||
static VALUE | ||
ossl_pkcs12_s_allocate(VALUE klass) | ||
{ | ||
PKCS12 *p12; | ||
VALUE obj; | ||
|
||
obj = NewPKCS12(klass); | ||
if(!(p12 = PKCS12_new())) ossl_raise(ePKCS12Error, NULL); | ||
SetPKCS12(obj, p12); | ||
|
||
return obj; | ||
} | ||
|
||
/* | ||
* call-seq: | ||
* PKCS12.create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]]) | ||
* | ||
* === Parameters | ||
* * +pass+ - string | ||
* * +name+ - A string describing the key. | ||
* * +key+ - Any PKey. | ||
* * +cert+ - A X509::Certificate. | ||
* * * The public_key portion of the certificate must contain a valid public key. | ||
* * * The not_before and not_after fields must be filled in. | ||
* * +ca+ - An optional array of X509::Certificate's. | ||
* * +key_pbe+ - string | ||
* * +cert_pbe+ - string | ||
* * +key_iter+ - integer | ||
* * +mac_iter+ - integer | ||
* * +keytype+ - An integer representing an MSIE specific extension. | ||
* | ||
* Any optional arguments may be supplied as nil to preserve the OpenSSL defaults. | ||
* | ||
* See the OpenSSL documentation for PKCS12_create(). | ||
*/ | ||
static VALUE | ||
ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) | ||
{ | ||
VALUE pass, name, pkey, cert, ca, key_nid, cert_nid, key_iter, mac_iter, keytype; | ||
VALUE obj; | ||
char *passphrase, *friendlyname; | ||
EVP_PKEY *key; | ||
X509 *x509; | ||
STACK_OF(X509) *x509s; | ||
int nkey = 0, ncert = 0, kiter = 0, miter = 0, ktype = 0; | ||
PKCS12 *p12; | ||
|
||
rb_scan_args(argc, argv, "46", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype); | ||
passphrase = NIL_P(pass) ? NULL : StringValueCStr(pass); | ||
friendlyname = NIL_P(name) ? NULL : StringValueCStr(name); | ||
key = GetPKeyPtr(pkey); | ||
x509 = GetX509CertPtr(cert); | ||
x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca); | ||
/* TODO: make a VALUE to nid function */ | ||
if (!NIL_P(key_nid)) { | ||
if ((nkey = OBJ_txt2nid(StringValueCStr(key_nid))) == NID_undef) | ||
ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, key_nid); | ||
} | ||
if (!NIL_P(cert_nid)) { | ||
if ((ncert = OBJ_txt2nid(StringValueCStr(cert_nid))) == NID_undef) | ||
ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, cert_nid); | ||
} | ||
if (!NIL_P(key_iter)) | ||
kiter = NUM2INT(key_iter); | ||
if (!NIL_P(mac_iter)) | ||
miter = NUM2INT(mac_iter); | ||
if (!NIL_P(keytype)) | ||
ktype = NUM2INT(keytype); | ||
|
||
obj = NewPKCS12(cPKCS12); | ||
p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s, | ||
nkey, ncert, kiter, miter, ktype); | ||
sk_X509_pop_free(x509s, X509_free); | ||
if(!p12) ossl_raise(ePKCS12Error, NULL); | ||
SetPKCS12(obj, p12); | ||
|
||
ossl_pkcs12_set_key(obj, pkey); | ||
ossl_pkcs12_set_cert(obj, cert); | ||
ossl_pkcs12_set_ca_certs(obj, ca); | ||
|
||
return obj; | ||
} | ||
|
||
/* | ||
* call-seq: | ||
* PKCS12.new -> pkcs12 | ||
* PKCS12.new(str) -> pkcs12 | ||
* PKCS12.new(str, pass) -> pkcs12 | ||
* | ||
* === Parameters | ||
* * +str+ - Must be a DER encoded PKCS12 string. | ||
* * +pass+ - string | ||
*/ | ||
static VALUE | ||
ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self) | ||
{ | ||
BIO *in; | ||
VALUE arg, pass, pkey, cert, ca; | ||
char *passphrase; | ||
EVP_PKEY *key; | ||
X509 *x509; | ||
STACK_OF(X509) *x509s = NULL; | ||
int st = 0; | ||
PKCS12 *pkcs = DATA_PTR(self); | ||
|
||
if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self; | ||
passphrase = NIL_P(pass) ? NULL : StringValueCStr(pass); | ||
in = ossl_obj2bio(arg); | ||
d2i_PKCS12_bio(in, &pkcs); | ||
DATA_PTR(self) = pkcs; | ||
BIO_free(in); | ||
|
||
pkey = cert = ca = Qnil; | ||
/* OpenSSL's bug; PKCS12_parse() puts errors even if it succeeds. | ||
* Fixed in OpenSSL 1.0.0t, 1.0.1p, 1.0.2d */ | ||
ERR_set_mark(); | ||
if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s)) | ||
ossl_raise(ePKCS12Error, "PKCS12_parse"); | ||
ERR_pop_to_mark(); | ||
pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key, | ||
&st); /* NO DUP */ | ||
if(st) goto err; | ||
cert = rb_protect((VALUE(*)_((VALUE)))ossl_x509_new, (VALUE)x509, &st); | ||
if(st) goto err; | ||
if(x509s){ | ||
ca = | ||
rb_protect((VALUE(*)_((VALUE)))ossl_x509_sk2ary, (VALUE)x509s, &st); | ||
if(st) goto err; | ||
} | ||
|
||
err: | ||
X509_free(x509); | ||
sk_X509_pop_free(x509s, X509_free); | ||
ossl_pkcs12_set_key(self, pkey); | ||
ossl_pkcs12_set_cert(self, cert); | ||
ossl_pkcs12_set_ca_certs(self, ca); | ||
if(st) rb_jump_tag(st); | ||
|
||
return self; | ||
} | ||
|
||
static VALUE | ||
ossl_pkcs12_to_der(VALUE self) | ||
{ | ||
PKCS12 *p12; | ||
VALUE str; | ||
long len; | ||
unsigned char *p; | ||
|
||
GetPKCS12(self, p12); | ||
if((len = i2d_PKCS12(p12, NULL)) <= 0) | ||
ossl_raise(ePKCS12Error, NULL); | ||
str = rb_str_new(0, len); | ||
p = (unsigned char *)RSTRING_PTR(str); | ||
if(i2d_PKCS12(p12, &p) <= 0) | ||
ossl_raise(ePKCS12Error, NULL); | ||
ossl_str_adjust(str, p); | ||
|
||
return str; | ||
} | ||
|
||
void | ||
Init_ossl_pkcs12(void) | ||
{ | ||
/* | ||
* Defines a file format commonly used to store private keys with | ||
* accompanying public key certificates, protected with a password-based | ||
* symmetric key. | ||
*/ | ||
cPKCS12 = rb_define_class_under(mOSSL, "PKCS12", rb_cObject); | ||
ePKCS12Error = rb_define_class_under(cPKCS12, "PKCS12Error", eOSSLError); | ||
rb_define_singleton_method(cPKCS12, "create", ossl_pkcs12_s_create, -1); | ||
|
||
rb_define_alloc_func(cPKCS12, ossl_pkcs12_s_allocate); | ||
rb_attr(cPKCS12, rb_intern("key"), 1, 0, Qfalse); | ||
rb_attr(cPKCS12, rb_intern("certificate"), 1, 0, Qfalse); | ||
rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse); | ||
rb_define_method(cPKCS12, "initialize", ossl_pkcs12_initialize, -1); | ||
rb_define_method(cPKCS12, "to_der", ossl_pkcs12_to_der, 0); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
* This program is licensed under the same licence as Ruby. | ||
* (See the file 'LICENCE'.) | ||
*/ | ||
#if !defined(_OSSL_PKCS12_H_) | ||
#define _OSSL_PKCS12_H_ | ||
|
||
extern VALUE cPKCS12; | ||
extern VALUE ePKCS12Error; | ||
|
||
void Init_ossl_pkcs12(void); | ||
|
||
#endif /* _OSSL_PKCS12_H_ */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
/* | ||
* Copyright (C) 2007 Technorama Ltd. <oss-ruby@technorama.net> | ||
*/ | ||
#include "ossl.h" | ||
|
||
VALUE mPKCS5; | ||
VALUE ePKCS5; | ||
|
||
#ifdef HAVE_PKCS5_PBKDF2_HMAC | ||
/* | ||
* call-seq: | ||
* PKCS5.pbkdf2_hmac(pass, salt, iter, keylen, digest) => string | ||
* | ||
* === Parameters | ||
* * +pass+ - string | ||
* * +salt+ - string - should be at least 8 bytes long. | ||
* * +iter+ - integer - should be greater than 1000. 20000 is better. | ||
* * +keylen+ - integer | ||
* * +digest+ - a string or OpenSSL::Digest object. | ||
* | ||
* Available in OpenSSL 0.9.4. | ||
* | ||
* Digests other than SHA1 may not be supported by other cryptography libraries. | ||
*/ | ||
static VALUE | ||
ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest) | ||
{ | ||
VALUE str; | ||
const EVP_MD *md; | ||
int len = NUM2INT(keylen); | ||
|
||
StringValue(pass); | ||
StringValue(salt); | ||
md = GetDigestPtr(digest); | ||
|
||
str = rb_str_new(0, len); | ||
|
||
if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass), | ||
(unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), | ||
NUM2INT(iter), md, len, | ||
(unsigned char *)RSTRING_PTR(str)) != 1) | ||
ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC"); | ||
|
||
return str; | ||
} | ||
#else | ||
#define ossl_pkcs5_pbkdf2_hmac rb_f_notimplement | ||
#endif | ||
|
||
|
||
/* | ||
* call-seq: | ||
* PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string | ||
* | ||
* === Parameters | ||
* * +pass+ - string | ||
* * +salt+ - string - should be at least 8 bytes long. | ||
* * +iter+ - integer - should be greater than 1000. 20000 is better. | ||
* * +keylen+ - integer | ||
* | ||
* This method is available in almost any version of OpenSSL. | ||
* | ||
* Conforms to rfc2898. | ||
*/ | ||
static VALUE | ||
ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen) | ||
{ | ||
VALUE str; | ||
int len = NUM2INT(keylen); | ||
|
||
StringValue(pass); | ||
StringValue(salt); | ||
|
||
str = rb_str_new(0, len); | ||
|
||
if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass), | ||
(const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter), | ||
len, (unsigned char *)RSTRING_PTR(str)) != 1) | ||
ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1"); | ||
|
||
return str; | ||
} | ||
|
||
void | ||
Init_ossl_pkcs5(void) | ||
{ | ||
/* | ||
* Password-based Encryption | ||
* | ||
*/ | ||
|
||
#if 0 | ||
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ | ||
#endif | ||
|
||
/* Document-class: OpenSSL::PKCS5 | ||
* | ||
* Provides password-based encryption functionality based on PKCS#5. | ||
* Typically used for securely deriving arbitrary length symmetric keys | ||
* to be used with an OpenSSL::Cipher from passwords. Another use case | ||
* is for storing passwords: Due to the ability to tweak the effort of | ||
* computation by increasing the iteration count, computation can be | ||
* slowed down artificially in order to render possible attacks infeasible. | ||
* | ||
* PKCS5 offers support for PBKDF2 with an OpenSSL::Digest::SHA1-based | ||
* HMAC, or an arbitrary Digest if the underlying version of OpenSSL | ||
* already supports it (>= 0.9.4). | ||
* | ||
* === Parameters | ||
* ==== Password | ||
* Typically an arbitrary String that represents the password to be used | ||
* for deriving a key. | ||
* ==== Salt | ||
* Prevents attacks based on dictionaries of common passwords. It is a | ||
* public value that can be safely stored along with the password (e.g. | ||
* if PBKDF2 is used for password storage). For maximum security, a fresh, | ||
* random salt should be generated for each stored password. According | ||
* to PKCS#5, a salt should be at least 8 bytes long. | ||
* ==== Iteration Count | ||
* Allows to tweak the length that the actual computation will take. The | ||
* larger the iteration count, the longer it will take. | ||
* ==== Key Length | ||
* Specifies the length in bytes of the output that will be generated. | ||
* Typically, the key length should be larger than or equal to the output | ||
* length of the underlying digest function, otherwise an attacker could | ||
* simply try to brute-force the key. According to PKCS#5, security is | ||
* limited by the output length of the underlying digest function, i.e. | ||
* security is not improved if a key length strictly larger than the | ||
* digest output length is chosen. Therefore, when using PKCS5 for | ||
* password storage, it suffices to store values equal to the digest | ||
* output length, nothing is gained by storing larger values. | ||
* | ||
* == Examples | ||
* === Generating a 128 bit key for a Cipher (e.g. AES) | ||
* pass = "secret" | ||
* salt = OpenSSL::Random.random_bytes(16) | ||
* iter = 20000 | ||
* key_len = 16 | ||
* key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, key_len) | ||
* | ||
* === Storing Passwords | ||
* pass = "secret" | ||
* salt = OpenSSL::Random.random_bytes(16) #store this with the generated value | ||
* iter = 20000 | ||
* digest = OpenSSL::Digest::SHA256.new | ||
* len = digest.digest_length | ||
* #the final value to be stored | ||
* value = OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, iter, len, digest) | ||
* | ||
* === Important Note on Checking Passwords | ||
* When comparing passwords provided by the user with previously stored | ||
* values, a common mistake made is comparing the two values using "==". | ||
* Typically, "==" short-circuits on evaluation, and is therefore | ||
* vulnerable to timing attacks. The proper way is to use a method that | ||
* always takes the same amount of time when comparing two values, thus | ||
* not leaking any information to potential attackers. To compare two | ||
* values, the following could be used: | ||
* def eql_time_cmp(a, b) | ||
* unless a.length == b.length | ||
* return false | ||
* end | ||
* cmp = b.bytes.to_a | ||
* result = 0 | ||
* a.bytes.each_with_index {|c,i| | ||
* result |= c ^ cmp[i] | ||
* } | ||
* result == 0 | ||
* end | ||
* Please note that the premature return in case of differing lengths | ||
* typically does not leak valuable information - when using PKCS#5, the | ||
* length of the values to be compared is of fixed size. | ||
*/ | ||
|
||
mPKCS5 = rb_define_module_under(mOSSL, "PKCS5"); | ||
/* Document-class: OpenSSL::PKCS5::PKCS5Error | ||
* | ||
* Generic Exception class that is raised if an error occurs during a | ||
* computation. | ||
*/ | ||
ePKCS5 = rb_define_class_under(mPKCS5, "PKCS5Error", eOSSLError); | ||
|
||
rb_define_module_function(mPKCS5, "pbkdf2_hmac", ossl_pkcs5_pbkdf2_hmac, 5); | ||
rb_define_module_function(mPKCS5, "pbkdf2_hmac_sha1", ossl_pkcs5_pbkdf2_hmac_sha1, 4); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#if !defined(_OSSL_PKCS5_H_) | ||
#define _OSSL_PKCS5_H_ | ||
|
||
void Init_ossl_pkcs5(void); | ||
|
||
#endif /* _OSSL_PKCS5_H_ */ |