diff options
Diffstat (limited to 'ruby_1_9_3/ext/openssl')
64 files changed, 0 insertions, 21367 deletions
diff --git a/ruby_1_9_3/ext/openssl/extconf.rb b/ruby_1_9_3/ext/openssl/extconf.rb deleted file mode 100644 index 2206fcab5b..0000000000 --- a/ruby_1_9_3/ext/openssl/extconf.rb +++ /dev/null @@ -1,139 +0,0 @@ -=begin -= $RCSfile$ -- Generator for Makefile - -= Info - 'OpenSSL for Ruby 2' project - Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> - All rights reserved. - -= Licence - This program is licenced under the same licence as Ruby. - (See the file 'LICENCE'.) - -= Version - $Id$ -=end - -require "mkmf" - -dir_config("openssl") -dir_config("kerberos") - -message "=== OpenSSL for Ruby configurator ===\n" - -## -# Adds -Wall -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") unless $defs.include? "-DOSSL_DEBUG" - - if CONFIG['GCC'] == 'yes' - $CPPFLAGS += " -Wall" unless $CPPFLAGS.split.include? "-Wall" - end -end - -message "=== Checking for system dependent stuff... ===\n" -have_library("nsl", "t_open") -have_library("socket", "socket") -have_header("assert.h") - -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, "OpenSSL_add_all_digests")} - result &&= %w[ssl ssleay32].any? {|lib| have_library(lib, "SSL_library_init")} - unless result - message "=== Checking for required stuff failed. ===\n" - message "Makefile wasn't created. Fix the errors above.\n" - exit 1 - end -end - -unless have_header("openssl/conf_api.h") - raise "OpenSSL 0.9.6 or later required." -end - -%w"rb_str_set_len rb_block_call".each {|func| have_func(func, "ruby.h")} - -message "=== Checking for OpenSSL features... ===\n" -have_func("ERR_peek_last_error") -have_func("ASN1_put_eoc") -have_func("BN_mod_add") -have_func("BN_mod_sqr") -have_func("BN_mod_sub") -have_func("BN_pseudo_rand_range") -have_func("BN_rand_range") -have_func("CONF_get1_default_config_file") -have_func("EVP_CIPHER_CTX_copy") -have_func("EVP_CIPHER_CTX_set_padding") -have_func("EVP_CipherFinal_ex") -have_func("EVP_CipherInit_ex") -have_func("EVP_DigestFinal_ex") -have_func("EVP_DigestInit_ex") -have_func("EVP_MD_CTX_cleanup") -have_func("EVP_MD_CTX_create") -have_func("EVP_MD_CTX_destroy") -have_func("EVP_MD_CTX_init") -have_func("HMAC_CTX_cleanup") -have_func("HMAC_CTX_copy") -have_func("HMAC_CTX_init") -have_func("PEM_def_callback") -have_func("PKCS5_PBKDF2_HMAC") -have_func("PKCS5_PBKDF2_HMAC_SHA1") -have_func("X509V3_set_nconf") -have_func("X509V3_EXT_nconf_nid") -have_func("X509_CRL_add0_revoked") -have_func("X509_CRL_set_issuer_name") -have_func("X509_CRL_set_version") -have_func("X509_CRL_sort") -have_func("X509_NAME_hash_old") -have_func("X509_STORE_get_ex_data") -have_func("X509_STORE_set_ex_data") -have_func("OBJ_NAME_do_all_sorted") -have_func("SSL_SESSION_get_id") -have_func("SSL_SESSION_cmp") -have_func("OPENSSL_cleanse") -have_func("SSLv2_method") -have_func("SSLv2_server_method") -have_func("SSLv2_client_method") -unless have_func("SSL_set_tlsext_host_name", ['openssl/ssl.h']) - have_macro("SSL_set_tlsext_host_name", ['openssl/ssl.h']) && $defs.push("-DHAVE_SSL_SET_TLSEXT_HOST_NAME") -end -if have_header("openssl/engine.h") - have_func("ENGINE_add") - have_func("ENGINE_load_builtin_engines") - have_func("ENGINE_load_openbsd_dev_crypto") - have_func("ENGINE_get_digest") - have_func("ENGINE_get_cipher") - have_func("ENGINE_cleanup") - have_func("ENGINE_load_4758cca") - have_func("ENGINE_load_aep") - have_func("ENGINE_load_atalla") - have_func("ENGINE_load_chil") - have_func("ENGINE_load_cswift") - have_func("ENGINE_load_nuron") - have_func("ENGINE_load_sureware") - have_func("ENGINE_load_ubsec") -end -if checking_for('OpenSSL version is 0.9.7 or later') { - try_static_assert('OPENSSL_VERSION_NUMBER >= 0x00907000L', 'openssl/opensslv.h') - } - have_header("openssl/ocsp.h") -end -have_struct_member("EVP_CIPHER_CTX", "flags", "openssl/evp.h") -have_struct_member("EVP_CIPHER_CTX", "engine", "openssl/evp.h") -have_struct_member("X509_ATTRIBUTE", "single", "openssl/x509.h") - -message "=== Checking done. ===\n" - -create_header -create_makefile("openssl") -message "Done.\n" diff --git a/ruby_1_9_3/ext/openssl/lib/openssl.rb b/ruby_1_9_3/ext/openssl/lib/openssl.rb deleted file mode 100644 index 3cff8d9c10..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl.rb +++ /dev/null @@ -1,25 +0,0 @@ -=begin -= $RCSfile$ -- Loader for all OpenSSL C-space and Ruby-space definitions - -= Info - 'OpenSSL for Ruby 2' project - Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> - All rights reserved. - -= Licence - This program is licenced under the same licence as Ruby. - (See the file 'LICENCE'.) - -= Version - $Id$ -=end - -require 'openssl.so' - -require 'openssl/bn' -require 'openssl/cipher' -require 'openssl/config' -require 'openssl/digest' -require 'openssl/ssl-internal' -require 'openssl/x509-internal' - diff --git a/ruby_1_9_3/ext/openssl/lib/openssl/bn.rb b/ruby_1_9_3/ext/openssl/lib/openssl/bn.rb deleted file mode 100644 index b2fca163f1..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl/bn.rb +++ /dev/null @@ -1,35 +0,0 @@ -#-- -# -# $RCSfile$ -# -# = 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 licenced under the same licence as Ruby. -# (See the file 'LICENCE'.) -# -# = Version -# $Id$ -# -#++ - -module OpenSSL - class BN - include Comparable - end # BN -end # OpenSSL - -## -# Add double dispatch to Integer -# -class Integer - def to_bn - OpenSSL::BN::new(self.to_s(16), 16) - end -end # Integer - diff --git a/ruby_1_9_3/ext/openssl/lib/openssl/buffering.rb b/ruby_1_9_3/ext/openssl/lib/openssl/buffering.rb deleted file mode 100644 index 51bc968e3a..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl/buffering.rb +++ /dev/null @@ -1,449 +0,0 @@ -=begin -= $RCSfile$ -- Buffering mix-in module. - -= Info - 'OpenSSL for Ruby 2' project - Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org> - All rights reserved. - -= Licence - This program is licenced under the same licence as Ruby. - (See the file 'LICENCE'.) - -= Version - $Id$ -=end - -## -# OpenSSL IO buffering mix-in module. -# -# This module allows an OpenSSL::SSL::SSLSocket to behave like an IO. - -module OpenSSL::Buffering - include Enumerable - - ## - # The "sync mode" of the SSLSocket. - # - # See IO#sync for full details. - - attr_accessor :sync - - ## - # Default size to read from or write to the SSLSocket for buffer operations. - - BLOCK_SIZE = 1024*16 - - def initialize(*args) - @eof = false - @rbuffer = "" - @sync = @io.sync - end - - # - # for reading. - # - private - - ## - # Fills the buffer from the underlying SSLSocket - - def fill_rbuff - begin - @rbuffer << self.sysread(BLOCK_SIZE) - rescue Errno::EAGAIN - retry - rescue EOFError - @eof = true - end - end - - ## - # Consumes +size+ bytes from the buffer - - def consume_rbuff(size=nil) - if @rbuffer.empty? - nil - else - size = @rbuffer.size unless size - ret = @rbuffer[0, size] - @rbuffer[0, size] = "" - ret - end - end - - public - - ## - # Reads +size+ bytes from the stream. If +buf+ is provided it must - # reference a string which will receive the data. - # - # See IO#read for full details. - - def read(size=nil, buf=nil) - if size == 0 - if buf - buf.clear - return buf - else - return "" - end - end - until @eof - break if size && size <= @rbuffer.size - fill_rbuff - end - ret = consume_rbuff(size) || "" - if buf - buf.replace(ret) - ret = buf - end - (size && ret.empty?) ? nil : ret - end - - ## - # Reads at most +maxlen+ bytes from the stream. If +buf+ is provided it - # must reference a string which will receive the data. - # - # See IO#readpartial for full details. - - def readpartial(maxlen, buf=nil) - if maxlen == 0 - if buf - buf.clear - return buf - else - return "" - end - end - if @rbuffer.empty? - begin - return sysread(maxlen, buf) - rescue Errno::EAGAIN - retry - end - end - ret = consume_rbuff(maxlen) - if buf - buf.replace(ret) - ret = buf - end - raise EOFError if ret.empty? - ret - end - - ## - # Reads at most +maxlen+ bytes in the non-blocking manner. - # - # When no data can be read without blocking it raises - # OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable. - # - # IO::WaitReadable means SSL needs to read internally so read_nonblock - # should be called again when the underlying IO is readable. - # - # IO::WaitWritable means SSL needs to write internally so read_nonblock - # should be called again after the underlying IO is writable. - # - # OpenSSL::Buffering#read_nonblock needs two rescue clause as follows: - # - # # emulates blocking read (readpartial). - # begin - # result = ssl.read_nonblock(maxlen) - # rescue IO::WaitReadable - # IO.select([io]) - # retry - # rescue IO::WaitWritable - # IO.select(nil, [io]) - # retry - # end - # - # Note that one reason that read_nonblock writes to the underlying IO is - # when the peer requests a new TLS/SSL handshake. See openssl the FAQ for - # more details. http://www.openssl.org/support/faq.html - - def read_nonblock(maxlen, buf=nil) - if maxlen == 0 - if buf - buf.clear - return buf - else - return "" - end - end - if @rbuffer.empty? - return sysread_nonblock(maxlen, buf) - end - ret = consume_rbuff(maxlen) - if buf - buf.replace(ret) - ret = buf - end - raise EOFError if ret.empty? - ret - end - - ## - # Reads the next "line+ from the stream. Lines are separated by +eol+. If - # +limit+ is provided the result will not be longer than the given number of - # bytes. - # - # +eol+ may be a String or Regexp. - # - # Unlike IO#gets the line read will not be assigned to +$_+. - # - # Unlike IO#gets the separator must be provided if a limit is provided. - - def gets(eol=$/, limit=nil) - idx = @rbuffer.index(eol) - until @eof - break if idx - fill_rbuff - idx = @rbuffer.index(eol) - end - if eol.is_a?(Regexp) - size = idx ? idx+$&.size : nil - else - size = idx ? idx+eol.size : nil - end - if limit and limit >= 0 - size = [size, limit].min - end - consume_rbuff(size) - end - - ## - # Executes the block for every line in the stream where lines are separated - # by +eol+. - # - # See also #gets - - def each(eol=$/) - while line = self.gets(eol) - yield line - end - end - alias each_line each - - ## - # Reads lines from the stream which are separated by +eol+. - # - # See also #gets - - def readlines(eol=$/) - ary = [] - while line = self.gets(eol) - ary << line - end - ary - end - - ## - # Reads a line from the stream which is separated by +eol+. - # - # Raises EOFError if at end of file. - - def readline(eol=$/) - raise EOFError if eof? - gets(eol) - end - - ## - # Reads one character from the stream. Returns nil if called at end of - # file. - - def getc - read(1) - end - - ## - # Calls the given block once for each byte in the stream. - - def each_byte # :yields: byte - while c = getc - yield(c.ord) - end - end - - ## - # Reads a one-character string from the stream. Raises an EOFError at end - # of file. - - def readchar - raise EOFError if eof? - getc - end - - ## - # Pushes character +c+ back onto the stream such that a subsequent buffered - # character read will return it. - # - # Unlike IO#getc multiple bytes may be pushed back onto the stream. - # - # Has no effect on unbuffered reads (such as #sysread). - - def ungetc(c) - @rbuffer[0,0] = c.chr - end - - ## - # Returns true if the stream is at file which means there is no more data to - # be read. - - def eof? - fill_rbuff if !@eof && @rbuffer.empty? - @eof && @rbuffer.empty? - end - alias eof eof? - - # - # for writing. - # - private - - ## - # Writes +s+ to the buffer. When the buffer is full or #sync is true the - # buffer is flushed to the underlying socket. - - def do_write(s) - @wbuffer = "" unless defined? @wbuffer - @wbuffer << s - @wbuffer.force_encoding(Encoding::BINARY) - @sync ||= false - if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/) - remain = idx ? idx + $/.size : @wbuffer.length - nwritten = 0 - while remain > 0 - str = @wbuffer[nwritten,remain] - begin - nwrote = syswrite(str) - rescue Errno::EAGAIN - retry - end - remain -= nwrote - nwritten += nwrote - end - @wbuffer[0,nwritten] = "" - end - end - - public - - ## - # Writes +s+ to the stream. If the argument is not a string it will be - # converted using String#to_s. Returns the number of bytes written. - - def write(s) - do_write(s) - s.bytesize - end - - ## - # Writes +str+ in the non-blocking manner. - # - # If there is buffered data, it is flushed first. This may block. - # - # write_nonblock returns number of bytes written to the SSL connection. - # - # When no data can be written without blocking it raises - # OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable. - # - # IO::WaitReadable means SSL needs to read internally so write_nonblock - # should be called again after the underlying IO is readable. - # - # IO::WaitWritable means SSL needs to write internally so write_nonblock - # should be called again after underlying IO is writable. - # - # So OpenSSL::Buffering#write_nonblock needs two rescue clause as follows. - # - # # emulates blocking write. - # begin - # result = ssl.write_nonblock(str) - # rescue IO::WaitReadable - # IO.select([io]) - # retry - # rescue IO::WaitWritable - # IO.select(nil, [io]) - # retry - # end - # - # Note that one reason that write_nonblock reads from the underlying IO - # is when the peer requests a new TLS/SSL handshake. See the openssl FAQ - # for more details. http://www.openssl.org/support/faq.html - - def write_nonblock(s) - flush - syswrite_nonblock(s) - end - - ## - # Writes +s+ to the stream. +s+ will be converted to a String using - # String#to_s. - - def << (s) - do_write(s) - self - end - - ## - # Writes +args+ to the stream along with a record separator. - # - # See IO#puts for full details. - - def puts(*args) - s = "" - if args.empty? - s << "\n" - end - args.each{|arg| - s << arg.to_s - if $/ && /\n\z/ !~ s - s << "\n" - end - } - do_write(s) - nil - end - - ## - # Writes +args+ to the stream. - # - # See IO#print for full details. - - def print(*args) - s = "" - args.each{ |arg| s << arg.to_s } - do_write(s) - nil - end - - ## - # Formats and writes to the stream converting parameters under control of - # the format string. - # - # See Kernel#sprintf for format string details. - - def printf(s, *args) - do_write(s % args) - nil - end - - ## - # Flushes buffered data to the SSLSocket. - - def flush - osync = @sync - @sync = true - do_write "" - return self - ensure - @sync = osync - end - - ## - # Closes the SSLSocket and flushes any unwritten data. - - def close - flush rescue nil - sysclose - end -end diff --git a/ruby_1_9_3/ext/openssl/lib/openssl/cipher.rb b/ruby_1_9_3/ext/openssl/lib/openssl/cipher.rb deleted file mode 100644 index eb146fb552..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl/cipher.rb +++ /dev/null @@ -1,65 +0,0 @@ -#-- -# -# $RCSfile$ -# -# = 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 licenced under the same licence as Ruby. -# (See the file 'LICENCE'.) -# -# = Version -# $Id$ -# -#++ - -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 diff --git a/ruby_1_9_3/ext/openssl/lib/openssl/config.rb b/ruby_1_9_3/ext/openssl/lib/openssl/config.rb deleted file mode 100644 index 24a54c91ec..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl/config.rb +++ /dev/null @@ -1,313 +0,0 @@ -=begin -= Ruby-space definitions that completes C-space funcs for Config - -= Info - Copyright (C) 2010 Hiroshi Nakamura <nahi@ruby-lang.org> - -= Licence - This program is licenced under the same licence as Ruby. - (See the file 'LICENCE'.) - -=end - -require 'stringio' - -module OpenSSL - class Config - include Enumerable - - class << self - def parse(str) - c = new() - parse_config(StringIO.new(str)).each do |section, hash| - c[section] = hash - end - c - end - - alias load new - - def parse_config(io) - begin - parse_config_lines(io) - rescue ConfigError => e - e.message.replace("error in line #{io.lineno}: " + e.message) - raise - end - end - - def get_key_string(data, section, key) # :nodoc: - if v = data[section] && data[section][key] - return v - elsif section == 'ENV' - if v = ENV[key] - return v - end - end - if v = data['default'] && data['default'][key] - return v - end - end - - private - - def parse_config_lines(io) - section = 'default' - data = {section => {}} - while definition = get_definition(io) - definition = clear_comments(definition) - next if definition.empty? - if definition[0] == ?[ - if /\[([^\]]*)\]/ =~ definition - section = $1.strip - data[section] ||= {} - else - raise ConfigError, "missing close square bracket" - end - else - if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition - if $2 - section = $1 - key = $2 - else - key = $1 - end - value = unescape_value(data, section, $3) - (data[section] ||= {})[key] = value.strip - else - raise ConfigError, "missing equal sign" - end - end - end - data - end - - # escape with backslash - QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/ - # escape with backslash and doubled dq - QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/ - # escaped char map - ESCAPE_MAP = { - "r" => "\r", - "n" => "\n", - "b" => "\b", - "t" => "\t", - } - - def unescape_value(data, section, value) - scanned = [] - while m = value.match(/['"\\$]/) - scanned << m.pre_match - c = m[0] - value = m.post_match - case c - when "'" - if m = value.match(QUOTE_REGEXP_SQ) - scanned << m[1].gsub(/\\(.)/, '\\1') - value = m.post_match - else - break - end - when '"' - if m = value.match(QUOTE_REGEXP_DQ) - scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1') - value = m.post_match - else - break - end - when "\\" - c = value.slice!(0, 1) - scanned << (ESCAPE_MAP[c] || c) - when "$" - ref, value = extract_reference(value) - refsec = section - if ref.index('::') - refsec, ref = ref.split('::', 2) - end - if v = get_key_string(data, refsec, ref) - scanned << v - else - raise ConfigError, "variable has no value" - end - else - raise 'must not reaced' - end - end - scanned << value - scanned.join - end - - def extract_reference(value) - rest = '' - if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/) - value = m[1] || m[2] - rest = m.post_match - elsif [?(, ?{].include?(value[0]) - raise ConfigError, "no close brace" - end - if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/) - return m[0], m.post_match + rest - else - raise - end - end - - def clear_comments(line) - # FCOMMENT - if m = line.match(/\A([\t\n\f ]*);.*\z/) - return m[1] - end - # COMMENT - scanned = [] - while m = line.match(/[#'"\\]/) - scanned << m.pre_match - c = m[0] - line = m.post_match - case c - when '#' - line = nil - break - when "'", '"' - regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ - scanned << c - if m = line.match(regexp) - scanned << m[0] - line = m.post_match - else - scanned << line - line = nil - break - end - when "\\" - scanned << c - scanned << line.slice!(0, 1) - else - raise 'must not reaced' - end - end - scanned << line - scanned.join - end - - def get_definition(io) - if line = get_line(io) - while /[^\\]\\\z/ =~ line - if extra = get_line(io) - line += extra - else - break - end - end - return line.strip - end - end - - def get_line(io) - if line = io.gets - line.gsub(/[\r\n]*/, '') - end - end - end - - def initialize(filename = nil) - @data = {} - if filename - File.open(filename.to_s) do |file| - Config.parse_config(file).each do |section, hash| - self[section] = hash - end - end - end - end - - def get_value(section, key) - if section.nil? - raise TypeError.new('nil not allowed') - end - section = 'default' if section.empty? - get_key_string(section, key) - end - - def value(arg1, arg2 = nil) - warn('Config#value is deprecated; use Config#get_value') - if arg2.nil? - section, key = 'default', arg1 - else - section, key = arg1, arg2 - end - section ||= 'default' - section = 'default' if section.empty? - get_key_string(section, key) - end - - def add_value(section, key, value) - check_modify - (@data[section] ||= {})[key] = value - end - - def [](section) - @data[section] || {} - end - - def section(name) - warn('Config#section is deprecated; use Config#[]') - @data[name] || {} - end - - def []=(section, pairs) - check_modify - @data[section] ||= {} - pairs.each do |key, value| - self.add_value(section, key, value) - end - end - - def sections - @data.keys - end - - def to_s - ary = [] - @data.keys.sort.each do |section| - ary << "[ #{section} ]\n" - @data[section].keys.each do |key| - ary << "#{key}=#{@data[section][key]}\n" - end - ary << "\n" - end - ary.join - end - - def each - @data.each do |section, hash| - hash.each do |key, value| - yield [section, key, value] - end - end - end - - def inspect - "#<#{self.class.name} sections=#{sections.inspect}>" - end - - protected - - def data - @data - end - - private - - def initialize_copy(other) - @data = other.data.dup - end - - def check_modify - raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen? - end - - def get_key_string(section, key) - Config.get_key_string(@data, section, key) - end - end -end diff --git a/ruby_1_9_3/ext/openssl/lib/openssl/digest.rb b/ruby_1_9_3/ext/openssl/lib/openssl/digest.rb deleted file mode 100644 index b47007165c..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl/digest.rb +++ /dev/null @@ -1,72 +0,0 @@ -#-- -# -# $RCSfile$ -# -# = 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 licenced under the same licence as Ruby. -# (See the file 'LICENCE'.) -# -# = Version -# $Id$ -# -#++ - -module OpenSSL - class Digest - - alg = %w(DSS DSS1 MD2 MD4 MD5 MDC2 RIPEMD160 SHA SHA1) - 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(Digest){ - define_method(:initialize){|*data| - if data.length > 1 - raise ArgumentError, - "wrong number of arguments (#{data.length} for 1)" - end - super(name, data.first) - } - } - singleton = (class << klass; self; end) - singleton.class_eval{ - define_method(:digest){|data| Digest.digest(name, data) } - define_method(:hexdigest){|data| Digest.hexdigest(name, data) } - } - const_set(name, klass) - } - - # This class is only provided for backwards compatibility. Use OpenSSL::Digest in the future. - class Digest < Digest - def initialize(*args) - # add warning - super(*args) - end - end - - end # Digest -end # OpenSSL - diff --git a/ruby_1_9_3/ext/openssl/lib/openssl/ssl-internal.rb b/ruby_1_9_3/ext/openssl/lib/openssl/ssl-internal.rb deleted file mode 100644 index c70b5b8f6b..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl/ssl-internal.rb +++ /dev/null @@ -1,177 +0,0 @@ -=begin -= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL - -= Info - 'OpenSSL for Ruby 2' project - Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org> - All rights reserved. - -= Licence - This program is licenced under the same licence as Ruby. - (See the file 'LICENCE'.) - -= Version - $Id$ -=end - -require "openssl/buffering" -require "fcntl" - -module OpenSSL - module SSL - class SSLContext - DEFAULT_PARAMS = { - :ssl_version => "SSLv23", - :verify_mode => OpenSSL::SSL::VERIFY_PEER, - :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW", - :options => OpenSSL::SSL::OP_ALL, - } - - DEFAULT_CERT_STORE = OpenSSL::X509::Store.new - DEFAULT_CERT_STORE.set_default_paths - if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL) - DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL - end - - 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 - - module Nonblock - def initialize(*args) - flag = File::NONBLOCK - flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL) - @io.fcntl(Fcntl::F_SETFL, flag) - super - end - end - - def verify_certificate_identity(cert, hostname) - should_verify_common_name = true - cert.extensions.each{|ext| - next if ext.oid != "subjectAltName" - ext.value.split(/,\s+/).each{|general_name| - if /\ADNS:(.*)/ =~ general_name - should_verify_common_name = false - reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+") - return true if /\A#{reg}\z/i =~ hostname - elsif /\AIP Address:(.*)/ =~ general_name - should_verify_common_name = false - return true if $1 == hostname - end - } - } - if should_verify_common_name - cert.subject.to_a.each{|oid, value| - if oid == "CN" - reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") - return true if /\A#{reg}\z/i =~ hostname - end - } - end - return false - end - module_function :verify_certificate_identity - - class SSLSocket - include Buffering - include SocketForwarder - include Nonblock - - def post_connection_check(hostname) - unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) - raise SSLError, "hostname does not match the server certificate" - end - return true - end - - def session - SSL::Session.new(self) - rescue SSL::Session::SessionError - nil - end - end - - class SSLServer - include SocketForwarder - attr_accessor :start_immediately - - def initialize(svr, ctx) - @svr = svr - @ctx = ctx - unless ctx.session_id_context - session_id = OpenSSL::Digest::MD5.hexdigest($0) - @ctx.session_id_context = session_id - end - @start_immediately = true - end - - def to_io - @svr - end - - def listen(backlog=5) - @svr.listen(backlog) - end - - def shutdown(how=Socket::SHUT_RDWR) - @svr.shutdown(how) - end - - def accept - sock = @svr.accept - begin - ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) - ssl.sync_close = true - ssl.accept if @start_immediately - ssl - rescue SSLError => ex - sock.close - raise ex - end - end - - def close - @svr.close - end - end - end -end diff --git a/ruby_1_9_3/ext/openssl/lib/openssl/ssl.rb b/ruby_1_9_3/ext/openssl/lib/openssl/ssl.rb deleted file mode 100644 index 15f42d6091..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl/ssl.rb +++ /dev/null @@ -1,2 +0,0 @@ -warn 'deprecated openssl/ssl use: require "openssl" instead of "openssl/ssl"' -require 'openssl' diff --git a/ruby_1_9_3/ext/openssl/lib/openssl/x509-internal.rb b/ruby_1_9_3/ext/openssl/lib/openssl/x509-internal.rb deleted file mode 100644 index 47e3a6f876..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl/x509-internal.rb +++ /dev/null @@ -1,158 +0,0 @@ -=begin -= $RCSfile$ -- 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 licenced under the same licence as Ruby. - (See the file 'LICENCE'.) - -= Version - $Id$ -=end - -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 - end - - class StoreContext - def cleanup - warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE - end - end - end -end diff --git a/ruby_1_9_3/ext/openssl/lib/openssl/x509.rb b/ruby_1_9_3/ext/openssl/lib/openssl/x509.rb deleted file mode 100644 index f1777cdf06..0000000000 --- a/ruby_1_9_3/ext/openssl/lib/openssl/x509.rb +++ /dev/null @@ -1,2 +0,0 @@ -warn 'deprecated openssl/x509 use: require "openssl" instead of "openssl/x509"' -require 'openssl' diff --git a/ruby_1_9_3/ext/openssl/openssl_missing.c b/ruby_1_9_3/ext/openssl/openssl_missing.c deleted file mode 100644 index f88dd403be..0000000000 --- a/ruby_1_9_3/ext/openssl/openssl_missing.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include RUBY_EXTCONF_H - -#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ST_ENGINE) -# include <openssl/engine.h> -#endif -#include <openssl/x509_vfy.h> - -#if !defined(OPENSSL_NO_HMAC) -#include <string.h> /* memcpy() */ -#include <openssl/hmac.h> - -#include "openssl_missing.h" - -#if !defined(HAVE_HMAC_CTX_COPY) -void -HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) -{ - if (!out || !in) return; - 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); -} -#endif /* HAVE_HMAC_CTX_COPY */ -#endif /* NO_HMAC */ - -#if !defined(HAVE_X509_STORE_SET_EX_DATA) -int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data) -{ - return CRYPTO_set_ex_data(&str->ex_data, idx, data); -} -#endif - -#if !defined(HAVE_X509_STORE_GET_EX_DATA) -void *X509_STORE_get_ex_data(X509_STORE *str, int idx) -{ - return CRYPTO_get_ex_data(&str->ex_data, idx); -} -#endif - -#if !defined(HAVE_EVP_MD_CTX_CREATE) -EVP_MD_CTX * -EVP_MD_CTX_create(void) -{ - EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)); - if (!ctx) return NULL; - - memset(ctx, 0, sizeof(EVP_MD_CTX)); - - return ctx; -} -#endif - -#if !defined(HAVE_EVP_MD_CTX_CLEANUP) -int -EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) -{ - /* FIXME!!! */ - memset(ctx, 0, sizeof(EVP_MD_CTX)); - - return 1; -} -#endif - -#if !defined(HAVE_EVP_MD_CTX_DESTROY) -void -EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) -{ - EVP_MD_CTX_cleanup(ctx); - OPENSSL_free(ctx); -} -#endif - -#if !defined(HAVE_EVP_MD_CTX_INIT) -void -EVP_MD_CTX_init(EVP_MD_CTX *ctx) -{ - memset(ctx, 0, sizeof(EVP_MD_CTX)); -} -#endif - -#if !defined(HAVE_HMAC_CTX_INIT) -void -HMAC_CTX_init(HMAC_CTX *ctx) -{ - EVP_MD_CTX_init(&ctx->i_ctx); - EVP_MD_CTX_init(&ctx->o_ctx); - EVP_MD_CTX_init(&ctx->md_ctx); -} -#endif - -#if !defined(HAVE_HMAC_CTX_CLEANUP) -void -HMAC_CTX_cleanup(HMAC_CTX *ctx) -{ - EVP_MD_CTX_cleanup(&ctx->i_ctx); - EVP_MD_CTX_cleanup(&ctx->o_ctx); - EVP_MD_CTX_cleanup(&ctx->md_ctx); - memset(ctx, 0, sizeof(HMAC_CTX)); -} -#endif - -#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, EVP_CIPHER_CTX *in) -{ - memcpy(out, in, sizeof(EVP_CIPHER_CTX)); - -#if defined(HAVE_ENGINE_ADD) && defined(HAVE_ST_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(HAVE_X509_CRL_SET_VERSION) -int -X509_CRL_set_version(X509_CRL *x, long version) -{ - if (x == NULL || x->crl == NULL) return 0; - if (x->crl->version == NULL) { - x->crl->version = M_ASN1_INTEGER_new(); - if (x->crl->version == NULL) return 0; - } - return ASN1_INTEGER_set(x->crl->version, version); -} -#endif - -#if !defined(HAVE_X509_CRL_SET_ISSUER_NAME) -int -X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) -{ - if (x == NULL || x->crl == NULL) return 0; - return X509_NAME_set(&x->crl->issuer, name); -} -#endif - -#if !defined(HAVE_X509_CRL_SORT) -int -X509_CRL_sort(X509_CRL *c) -{ - int i; - X509_REVOKED *r; - /* sort the data so it will be written in serial - * number order */ - sk_X509_REVOKED_sort(c->crl->revoked); - for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++) { - r=sk_X509_REVOKED_value(c->crl->revoked, i); - r->sequence=i; - } - return 1; -} -#endif - -#if !defined(HAVE_X509_CRL_ADD0_REVOKED) -static int -OSSL_X509_REVOKED_cmp(const X509_REVOKED * const *a, const X509_REVOKED * const *b) -{ - return(ASN1_STRING_cmp( - (ASN1_STRING *)(*a)->serialNumber, - (ASN1_STRING *)(*b)->serialNumber)); -} - -int -X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) -{ - X509_CRL_INFO *inf; - - inf = crl->crl; - if (!inf->revoked) - inf->revoked = sk_X509_REVOKED_new(OSSL_X509_REVOKED_cmp); - if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) - return 0; - return 1; -} -#endif - -#if !defined(HAVE_BN_MOD_SQR) -int -BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) -{ - if (!BN_sqr(r, (BIGNUM*)a, ctx)) return 0; - return BN_mod(r, r, m, ctx); -} -#endif - -#if !defined(HAVE_BN_MOD_ADD) || !defined(HAVE_BN_MOD_SUB) -int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) -{ - if (!BN_mod(r,m,d,ctx)) return 0; - if (!r->neg) return 1; - return (d->neg ? BN_sub : BN_add)(r, r, d); -} -#endif - -#if !defined(HAVE_BN_MOD_ADD) -int -BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) -{ - if (!BN_add(r, a, b)) return 0; - return BN_nnmod(r, r, m, ctx); -} -#endif - -#if !defined(HAVE_BN_MOD_SUB) -int -BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) -{ - if (!BN_sub(r, a, b)) return 0; - return BN_nnmod(r, r, m, ctx); -} -#endif - -#if !defined(HAVE_BN_RAND_RANGE) || !defined(HAVE_BN_PSEUDO_RAND_RANGE) -static int -bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range) -{ - int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand; - int n; - - if (range->neg || BN_is_zero(range)) return 0; - - n = BN_num_bits(range); - - if (n == 1) { - if (!BN_zero(r)) return 0; - } else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { - do { - if (!bn_rand(r, n + 1, -1, 0)) return 0; - if (BN_cmp(r ,range) >= 0) { - if (!BN_sub(r, r, range)) return 0; - if (BN_cmp(r, range) >= 0) - if (!BN_sub(r, r, range)) return 0; - } - } while (BN_cmp(r, range) >= 0); - } else { - do { - if (!bn_rand(r, n, -1, 0)) return 0; - } while (BN_cmp(r, range) >= 0); - } - - return 1; -} -#endif - -#if !defined(HAVE_BN_RAND_RANGE) -int -BN_rand_range(BIGNUM *r, BIGNUM *range) -{ - return bn_rand_range(0, r, range); -} -#endif - -#if !defined(HAVE_BN_PSEUDO_RAND_RANGE) -int -BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range) -{ - return bn_rand_range(1, r, range); -} -#endif - -#if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE) -#define OPENSSL_CONF "openssl.cnf" -char * -CONF_get1_default_config_file(void) -{ - char *file; - int len; - - file = getenv("OPENSSL_CONF"); - if (file) return BUF_strdup(file); - len = strlen(X509_get_default_cert_area()); -#ifndef OPENSSL_SYS_VMS - len++; -#endif - len += strlen(OPENSSL_CONF); - file = OPENSSL_malloc(len + 1); - if (!file) return NULL; - strcpy(file,X509_get_default_cert_area()); -#ifndef OPENSSL_SYS_VMS - strcat(file,"/"); -#endif - strcat(file,OPENSSL_CONF); - - return file; -} -#endif - -#if !defined(HAVE_PEM_DEF_CALLBACK) -#define OSSL_PASS_MIN_LENGTH 4 -int -PEM_def_callback(char *buf, int num, int w, void *key) -{ - int i,j; - const char *prompt; - - if (key) { - i = strlen(key); - i = (i > num) ? num : i; - memcpy(buf, key, i); - return i; - } - - prompt = EVP_get_pw_prompt(); - if (prompt == NULL) prompt = "Enter PEM pass phrase:"; - for (;;) { - i = EVP_read_pw_string(buf, num, prompt, w); - if (i != 0) { - memset(buf, 0, (unsigned int)num); - return(-1); - } - j = strlen(buf); - if (j < OSSL_PASS_MIN_LENGTH) { - fprintf(stderr, - "phrase is too short, needs to be at least %d chars\n", - OSSL_PASS_MIN_LENGTH); - } - else break; - } - return j; -} -#endif - -#if !defined(HAVE_ASN1_PUT_EOC) -int -ASN1_put_eoc(unsigned char **pp) -{ - unsigned char *p = *pp; - *p++ = 0; - *p++ = 0; - *pp = p; - return 2; -} -#endif - diff --git a/ruby_1_9_3/ext/openssl/openssl_missing.h b/ruby_1_9_3/ext/openssl/openssl_missing.h deleted file mode 100644 index 3635f88b73..0000000000 --- a/ruby_1_9_3/ext/openssl/openssl_missing.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_OPENSSL_MISSING_H_) -#define _OSSL_OPENSSL_MISSING_H_ - -#if defined(__cplusplus) -extern "C" { -#endif - -#ifndef TYPEDEF_D2I_OF -typedef char *d2i_of_void(); -#endif -#ifndef TYPEDEF_I2D_OF -typedef int i2d_of_void(); -#endif - -/* - * These functions are not included in headers of OPENSSL <= 0.9.6b - */ - -#if !defined(PEM_read_bio_DSAPublicKey) -# define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \ - (d2i_of_void *)d2i_DSAPublicKey,PEM_STRING_DSA_PUBLIC,(bp),(void **)(x),(cb),(u)) -#endif - -#if !defined(PEM_write_bio_DSAPublicKey) -# define PEM_write_bio_DSAPublicKey(bp,x) \ - PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPublicKey,\ - PEM_STRING_DSA_PUBLIC,\ - (bp),(char *)(x), NULL, NULL, 0, NULL, NULL) -#endif - -#if !defined(DSAPrivateKey_dup) -# define DSAPrivateKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, \ - (d2i_of_void *)d2i_DSAPrivateKey,(char *)(dsa)) -#endif - -#if !defined(DSAPublicKey_dup) -# define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPublicKey, \ - (d2i_of_void *)d2i_DSAPublicKey,(char *)(dsa)) -#endif - -#if !defined(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(PKCS7_SIGNER_INFO_dup) -# define PKCS7_SIGNER_INFO_dup(si) (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO, \ - (d2i_of_void *)d2i_PKCS7_SIGNER_INFO, (char *)(si)) -#endif - -#if !defined(PKCS7_RECIP_INFO_dup) -# define PKCS7_RECIP_INFO_dup(ri) (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, \ - (d2i_of_void *)d2i_PKCS7_RECIP_INFO, (char *)(ri)) -#endif - -#if !defined(HAVE_HMAC_CTX_INIT) -void HMAC_CTX_init(HMAC_CTX *ctx); -#endif - -#if !defined(HAVE_HMAC_CTX_COPY) -void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); -#endif - -#if !defined(HAVE_HMAC_CTX_CLEANUP) -void HMAC_CTX_cleanup(HMAC_CTX *ctx); -#endif - -#if !defined(HAVE_EVP_MD_CTX_CREATE) -EVP_MD_CTX *EVP_MD_CTX_create(void); -#endif - -#if !defined(HAVE_EVP_MD_CTX_INIT) -void EVP_MD_CTX_init(EVP_MD_CTX *ctx); -#endif - -#if !defined(HAVE_EVP_MD_CTX_CLEANUP) -int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); -#endif - -#if !defined(HAVE_EVP_MD_CTX_DESTROY) -void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); -#endif - -#if !defined(HAVE_EVP_CIPHER_CTX_COPY) -int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in); -#endif - -#if !defined(HAVE_EVP_DIGESTINIT_EX) -# define EVP_DigestInit_ex(ctx, md, engine) EVP_DigestInit((ctx), (md)) -#endif -#if !defined(HAVE_EVP_DIGESTFINAL_EX) -# define EVP_DigestFinal_ex(ctx, buf, len) EVP_DigestFinal((ctx), (buf), (len)) -#endif - -#if !defined(HAVE_EVP_CIPHERINIT_EX) -# define EVP_CipherInit_ex(ctx, type, impl, key, iv, enc) EVP_CipherInit((ctx), (type), (key), (iv), (enc)) -#endif -#if !defined(HAVE_EVP_CIPHERFINAL_EX) -# define EVP_CipherFinal_ex(ctx, outm, outl) EVP_CipherFinal((ctx), (outm), (outl)) -#endif - -#if !defined(EVP_CIPHER_name) -# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) -#endif - -#if !defined(EVP_MD_name) -# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e)) -#endif - -#if !defined(HAVE_EVP_HMAC_INIT_EX) -# define HMAC_Init_ex(ctx, key, len, digest, engine) HMAC_Init((ctx), (key), (len), (digest)) -#endif - -#if !defined(PKCS7_is_detached) -# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) -#endif - -#if !defined(PKCS7_type_is_encrypted) -# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) -#endif - -#if !defined(HAVE_OPENSSL_CLEANSE) -#define OPENSSL_cleanse(p, l) memset((p), 0, (l)) -#endif - -#if !defined(HAVE_X509_STORE_GET_EX_DATA) -void *X509_STORE_get_ex_data(X509_STORE *str, int idx); -#endif - -#if !defined(HAVE_X509_STORE_SET_EX_DATA) -int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data); -#endif - -#if !defined(HAVE_X509_CRL_SET_VERSION) -int X509_CRL_set_version(X509_CRL *x, long version); -#endif - -#if !defined(HAVE_X509_CRL_SET_ISSUER_NAME) -int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); -#endif - -#if !defined(HAVE_X509_CRL_SORT) -int X509_CRL_sort(X509_CRL *c); -#endif - -#if !defined(HAVE_X509_CRL_ADD0_REVOKED) -int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); -#endif - -#if !defined(HAVE_BN_MOD_SQR) -int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); -#endif - -#if !defined(HAVE_BN_MOD_ADD) -int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); -#endif - -#if !defined(HAVE_BN_MOD_SUB) -int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); -#endif - -#if !defined(HAVE_BN_RAND_RANGE) -int BN_rand_range(BIGNUM *r, BIGNUM *range); -#endif - -#if !defined(HAVE_BN_PSEUDO_RAND_RANGE) -int BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range); -#endif - -#if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE) -char *CONF_get1_default_config_file(void); -#endif - -#if !defined(HAVE_PEM_DEF_CALLBACK) -int PEM_def_callback(char *buf, int num, int w, void *key); -#endif - -#if !defined(HAVE_ASN1_PUT_EOC) -int ASN1_put_eoc(unsigned char **pp); -#endif - -#if defined(__cplusplus) -} -#endif - - -#endif /* _OSSL_OPENSSL_MISSING_H_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl.c b/ruby_1_9_3/ext/openssl/ossl.c deleted file mode 100644 index f3410b64e8..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl.c +++ /dev/null @@ -1,901 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" -#include <stdarg.h> /* for ossl_raise */ - -/* - * String to HEXString conversion - */ -int -string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len) -{ - static const char hex[]="0123456789abcdef"; - int i, len = 2 * buf_len; - - if (buf_len < 0 || len < buf_len) { /* PARANOIA? */ - return -1; - } - if (!hexbuf) { /* if no buf, return calculated len */ - if (hexbuf_len) { - *hexbuf_len = len; - } - return len; - } - if (!(*hexbuf = OPENSSL_malloc(len + 1))) { - return -1; - } - for (i = 0; i < buf_len; i++) { - (*hexbuf)[2 * i] = hex[((unsigned char)buf[i]) >> 4]; - (*hexbuf)[2 * i + 1] = hex[buf[i] & 0x0f]; - } - (*hexbuf)[2 * i] = '\0'; - - if (hexbuf_len) { - *hexbuf_len = len; - } - return len; -} - -/* - * Data Conversion - */ -#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \ -STACK_OF(type) * \ -ossl_##name##_ary2sk0(VALUE ary) \ -{ \ - STACK_OF(type) *sk; \ - VALUE val; \ - type *x; \ - int i; \ - \ - Check_Type(ary, T_ARRAY); \ - sk = sk_##type##_new_null(); \ - if (!sk) ossl_raise(eOSSLError, NULL); \ - \ - for (i = 0; i < RARRAY_LEN(ary); i++) { \ - val = rb_ary_entry(ary, i); \ - if (!rb_obj_is_kind_of(val, expected_class)) { \ - sk_##type##_pop_free(sk, type##_free); \ - ossl_raise(eOSSLError, "object in array not" \ - " of class ##type##"); \ - } \ - x = dup(val); /* NEED TO DUP */ \ - sk_##type##_push(sk, x); \ - } \ - return sk; \ -} \ - \ -STACK_OF(type) * \ -ossl_protect_##name##_ary2sk(VALUE ary, int *status) \ -{ \ - return (STACK_OF(type)*)rb_protect( \ - (VALUE(*)_((VALUE)))ossl_##name##_ary2sk0, \ - ary, \ - status); \ -} \ - \ -STACK_OF(type) * \ -ossl_##name##_ary2sk(VALUE ary) \ -{ \ - STACK_OF(type) *sk; \ - int status = 0; \ - \ - sk = ossl_protect_##name##_ary2sk(ary, &status); \ - if (status) rb_jump_tag(status); \ - \ - return sk; \ -} -OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr) - -#define OSSL_IMPL_SK2ARY(name, type) \ -VALUE \ -ossl_##name##_sk2ary(STACK_OF(type) *sk) \ -{ \ - type *t; \ - int i, num; \ - VALUE ary; \ - \ - if (!sk) { \ - OSSL_Debug("empty sk!"); \ - return Qnil; \ - } \ - num = sk_##type##_num(sk); \ - if (num < 0) { \ - OSSL_Debug("items in sk < -1???"); \ - return rb_ary_new(); \ - } \ - ary = rb_ary_new2(num); \ - \ - for (i=0; i<num; i++) { \ - t = sk_##type##_value(sk, i); \ - rb_ary_push(ary, ossl_##name##_new(t)); \ - } \ - return ary; \ -} -OSSL_IMPL_SK2ARY(x509, X509) -OSSL_IMPL_SK2ARY(x509crl, X509_CRL) -OSSL_IMPL_SK2ARY(x509name, X509_NAME) - -static VALUE -ossl_str_new(int size) -{ - return rb_str_new(0, size); -} - -VALUE -ossl_buf2str(char *buf, int len) -{ - VALUE str; - int status = 0; - - str = rb_protect((VALUE(*)_((VALUE)))ossl_str_new, len, &status); - if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len); - OPENSSL_free(buf); - if(status) rb_jump_tag(status); - - return str; -} - -/* - * our default PEM callback - */ -static VALUE -ossl_pem_passwd_cb0(VALUE flag) -{ - VALUE pass; - - pass = rb_yield(flag); - SafeStringValue(pass); - - return pass; -} - -int -ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd) -{ - int len, status = 0; - VALUE rflag, pass; - - if (pwd || !rb_block_given_p()) - return PEM_def_callback(buf, max_len, flag, pwd); - - while (1) { - /* - * when the flag is nonzero, this passphrase - * will be used to perform encryption; otherwise it will - * be used to perform decryption. - */ - rflag = flag ? Qtrue : Qfalse; - pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status); - if (status) return -1; /* exception was raised. */ - len = RSTRING_LENINT(pass); - if (len < 4) { /* 4 is OpenSSL hardcoded limit */ - rb_warning("password must be longer than 4 bytes"); - continue; - } - if (len > max_len) { - rb_warning("password must be shorter then %d bytes", max_len-1); - continue; - } - memcpy(buf, RSTRING_PTR(pass), len); - break; - } - return len; -} - -/* - * Verify callback - */ -int ossl_verify_cb_idx; - -VALUE -ossl_call_verify_cb_proc(struct ossl_verify_cb_args *args) -{ - return rb_funcall(args->proc, rb_intern("call"), 2, - args->preverify_ok, args->store_ctx); -} - -int -ossl_verify_cb(int ok, X509_STORE_CTX *ctx) -{ - VALUE proc, rctx, ret; - struct ossl_verify_cb_args args; - int state = 0; - - proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_verify_cb_idx); - if ((void*)proc == 0) - proc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_verify_cb_idx); - if ((void*)proc == 0) - return ok; - if (!NIL_P(proc)) { - rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, - (VALUE)ctx, &state); - ret = Qfalse; - if (!state) { - args.proc = proc; - args.preverify_ok = ok ? Qtrue : Qfalse; - args.store_ctx = rctx; - ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state); - ossl_x509stctx_clear_ptr(rctx); - if (state) { - rb_warn("exception in verify_callback is ignored"); - } - } - if (ret == Qtrue) { - X509_STORE_CTX_set_error(ctx, X509_V_OK); - ok = 1; - } - else{ - if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) { - X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); - } - ok = 0; - } - } - - return ok; -} - -/* - * main module - */ -VALUE mOSSL; - -/* - * OpenSSLError < StandardError - */ -VALUE eOSSLError; - -/* - * Convert to DER string - */ -ID ossl_s_to_der; - -VALUE -ossl_to_der(VALUE obj) -{ - VALUE tmp; - - tmp = rb_funcall(obj, ossl_s_to_der, 0); - StringValue(tmp); - - return tmp; -} - -VALUE -ossl_to_der_if_possible(VALUE obj) -{ - if(rb_respond_to(obj, ossl_s_to_der)) - return ossl_to_der(obj); - return obj; -} - -/* - * Errors - */ -static VALUE -ossl_make_error(VALUE exc, const char *fmt, va_list args) -{ - char buf[BUFSIZ]; - const char *msg; - long e; - int len = 0; - -#ifdef HAVE_ERR_PEEK_LAST_ERROR - e = ERR_peek_last_error(); -#else - e = ERR_peek_error(); -#endif - if (fmt) { - len = vsnprintf(buf, BUFSIZ, fmt, args); - } - if (len < BUFSIZ && e) { - if (dOSSL == Qtrue) /* FULL INFO */ - msg = ERR_error_string(e, NULL); - else - msg = ERR_reason_error_string(e); - len += snprintf(buf+len, BUFSIZ-len, "%s%s", (len ? ": " : ""), msg); - } - if (dOSSL == Qtrue){ /* show all errors on the stack */ - while ((e = ERR_get_error()) != 0){ - rb_warn("error on stack: %s", ERR_error_string(e, NULL)); - } - } - ERR_clear_error(); - - if(len > BUFSIZ) len = rb_long2int(strlen(buf)); - return rb_exc_new(exc, buf, len); -} - -void -ossl_raise(VALUE exc, const char *fmt, ...) -{ - va_list args; - VALUE err; - va_start(args, fmt); - err = ossl_make_error(exc, fmt, args); - va_end(args); - rb_exc_raise(err); -} - -VALUE -ossl_exc_new(VALUE exc, const char *fmt, ...) -{ - va_list args; - VALUE err; - va_start(args, fmt); - err = ossl_make_error(exc, fmt, args); - va_end(args); - return err; -} - -/* - * call-seq: - * OpenSSL.errors -> [String...] - * - * See any remaining errors held in queue. - * - * Any errors you see here are probably due to a bug in ruby's OpenSSL implementation. - */ -VALUE -ossl_get_errors() -{ - VALUE ary; - long e; - - ary = rb_ary_new(); - while ((e = ERR_get_error()) != 0){ - rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL))); - } - - return ary; -} - -/* - * Debug - */ -VALUE dOSSL; - -#if !defined(HAVE_VA_ARGS_MACRO) -void -ossl_debug(const char *fmt, ...) -{ - va_list args; - - if (dOSSL == Qtrue) { - fprintf(stderr, "OSSL_DEBUG: "); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - fprintf(stderr, " [CONTEXT N/A]\n"); - } -} -#endif - -/* - * call-seq: - * OpenSSL.debug -> true | false - */ -static VALUE -ossl_debug_get(VALUE self) -{ - return dOSSL; -} - -/* - * call-seq: - * OpenSSL.debug = boolean -> boolean - * - * Turns on or off CRYPTO_MEM_CHECK. - * Also shows some debugging message on stderr. - */ -static VALUE -ossl_debug_set(VALUE self, VALUE val) -{ - VALUE old = dOSSL; - dOSSL = val; - - if (old != dOSSL) { - if (dOSSL == Qtrue) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); - fprintf(stderr, "OSSL_DEBUG: IS NOW ON!\n"); - } else if (old == Qtrue) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF); - fprintf(stderr, "OSSL_DEBUG: IS NOW OFF!\n"); - } - } - return val; -} - -/* - * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the - * OpenSSL[http://www.openssl.org/] library. - * - * = Examples - * - * All examples assume you have loaded OpenSSL with: - * - * require 'openssl' - * - * These examples build atop each other. For example the key created in the - * next is used in throughout these examples. - * - * == Keys - * - * === Creating a Key - * - * This example creates a 2048 bit RSA keypair and writes it to the current - * directory. - * - * key = OpenSSL::PKey::RSA.new 2048 - * - * open 'private_key.pem', 'w' do |io| io.write key.to_pem end - * open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end - * - * === Exporting a Key - * - * Keys saved to disk without encryption are not secure as anyone who gets - * ahold of the key may use it unless it is encrypted. In order to securely - * export a key you may export it with a pass phrase. - * - * cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC' - * pass_phrase = 'my secure pass phrase goes here' - * - * key_secure = key.export cipher, pass_phrase - * - * open 'private.secure.pem', 'w' do |io| - * io.write key_secure - * end - * - * OpenSSL::Cipher.ciphers returns a list of available ciphers. - * - * === Loading a Key - * - * A key can also be loaded from a file. - * - * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem' - * key2.public? # => true - * - * or - * - * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem' - * key3.private? # => false - * - * === Loading an Encrypted Key - * - * OpenSSL will prompt you for your pass phrase when loading an encrypted key. - * If you will not be able to type in the pass phrase you may provide it when - * loading the key: - * - * key4_pem = File.read 'private.secure.pem' - * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase - * - * == RSA Encryption - * - * RSA provides ecryption and decryption using the public and private keys. - * You can use a variety of padding methods depending upon the intended use of - * encrypted data. - * - * === Encryption - * - * Documents encrypted with the public key can only be decrypted with the - * private key. - * - * public_encrypted = key.public_encrypt 'top secret document' - * - * Documents encrypted with the private key can only be decrypted with the - * public key. - * - * private_encrypted = key.private_encrypt 'public release document' - * - * === Decryption - * - * Use the opposite key type do decrypt the document - * - * top_secret = key.public_decrypt public_encrypted - * - * public_release = key.private_decrypt private_encrypted - * - * == PKCS #5 Password-based Encryption - * - * PKCS #5 is a password-based encryption standard documented at - * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or - * passphrase to be used to create a secure encryption key. - * - * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption - * key. - * - * pass_phrase = 'my secure pass phrase goes here' - * salt = '8 octets' - * - * === Encryption - * - * First set up the cipher for encryption - * - * encrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC' - * encrypter.encrypt - * encrypter.pkcs5_keyivgen pass_phrase, salt - * - * Then pass the data you want to encrypt through - * - * encrypted = encrypter.update 'top secret document' - * encrypted << encrypter.final - * - * === Decryption - * - * Use a new Cipher instance set up for decryption - * - * decrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC' - * decrypter.decrypt - * decrypter.pkcs5_keyivgen pass_phrase, salt - * - * Then pass the data you want to decrypt through - * - * plain = decrypter.update encrypted - * plain << decrypter.final - * - * == X509 Certificates - * - * === Creating a Certificate - * - * This example creates a self-signed certificate using an RSA key and a SHA1 - * signature. - * - * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example' - * - * cert = OpenSSL::X509::Certificate.new - * cert.version = 2 - * cert.serial = 0 - * cert.not_before = Time.now - * cert.not_after = Time.now + 3600 - * - * cert.public_key = key.public_key - * cert.subject = name - * - * === Certificate Extensions - * - * You can add extensions to the certificate with - * OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate. - * - * extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert - * - * extension_factory.create_extension 'basicConstraints', 'CA:FALSE' - * extension_factory.create_extension 'keyUsage', - * 'keyEncipherment,dataEncipherment,digitalSignature' - * extension_factory.create_extension 'subjectKeyIdentifier', 'hash' - * - * === Signing a Certificate - * - * To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign - * with a digest algorithm. This creates a self-signed cert because we're using - * the same name and key to sign the certificate as was used to create the - * certificate. - * - * cert.issuer = name - * cert.sign key, OpenSSL::Digest::SHA1.new - * - * open 'certificate.pem', 'w' do |io| io.write cert.to_pem end - * - * === Loading a Certificate - * - * Like a key, a cert can also be loaded from a file. - * - * cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem' - * - * === Verifying a Certificate - * - * Certificate#verify will return true when a certificate was signed with the - * given public key. - * - * raise 'certificate can not be verified' unless cert2.verify key - * - * == Certificate Authority - * - * A certificate authority (CA) is a trusted third party that allows you to - * verify the ownership of unknown certificates. The CA issues key signatures - * that indicate it trusts the user of that key. A user encountering the key - * can verify the signature by using the CA's public key. - * - * === CA Key - * - * CA keys are valuable, so we encrypt and save it to disk and make sure it is - * not readable by other users. - * - * ca_key = OpenSSL::PKey::RSA.new 2048 - * - * cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC' - * - * open 'ca_key.pem', 'w', 0400 do |io| - * io.write key.export(cipher, pass_phrase) - * end - * - * === CA Certificate - * - * A CA certificate is created the same way we created a certificate above, but - * with different extensions. - * - * ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example' - * - * ca_cert = OpenSSL::X509::Certificate.new - * ca_cert.serial = 0 - * ca_cert.version = 2 - * ca_cert.not_before = Time.now - * ca_cert.not_after = Time.now + 86400 - * - * ca_cert.public_key = ca_key.public_key - * ca_cert.subject = ca_name - * ca_cert.issuer = ca_name - * - * extension_factory = OpenSSL::X509::ExtensionFactory.new - * extension_factory.subject_certificate = ca_cert - * extension_factory.issuer_certificate = ca_cert - * - * extension_factory.create_extension 'subjectKeyIdentifier', 'hash' - * - * This extension indicates the CA's key may be used as a CA. - * - * extension_factory.create_extension 'basicConstraints', 'CA:TRUE', true - * - * This extension indicates the CA's key may be used to verify signatures on - * both certificates and certificate revocations. - * - * extension_factory.create_extension 'keyUsage', 'cRLSign,keyCertSign', true - * - * Root CA certificates are self-signed. - * - * ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new - * - * The CA certificate is saved to disk so it may be distributed to all the - * users of the keys this CA will sign. - * - * open 'ca_cert.pem', 'w' do |io| - * io.write ca_cert.to_pem - * end - * - * === Certificate Signing Request - * - * The CA signs keys through a Certificate Signing Request (CSR). The CSR - * contains the information necessary to identify the key. - * - * csr = OpenSSL::X509::Request.new - * csr.version = 0 - * csr.subject = name - * csr.public_key = key.public_key - * csr.sign key, OpenSSL::Digest::SHA1.new - * - * A CSR is saved to disk and sent to the CA for signing. - * - * open 'csr.pem', 'w' do |io| - * io.write csr.to_pem - * end - * - * === Creating a Certificate from a CSR - * - * Upon receiving a CSR the CA will verify it before signing it. A minimal - * verification would be to check the CSR's signature. - * - * csr = OpenSSL::X509::Request.new File.read 'csr.pem' - * - * raise 'CSR can not be verified' unless csr.verify csr.public_key - * - * After verification a certificate is created, marked for various usages, - * signed with the CA key and returned to the requester. - * - * csr_cert = OpenSSL::X509::Certificate.new - * csr_cert.serial = 0 - * csr_cert.version = 2 - * csr_cert.not_before = Time.now - * csr_cert.not_after = Time.now + 600 - * - * csr_cert.subject = csr.subject - * csr_cert.public_key = csr.public_key - * csr_cert.issuer = ca_cert.subject - * - * extension_factory = OpenSSL::X509::ExtensionFactory.new - * extension_factory.subject_certificate = csr_cert - * extension_factory.issuer_certificate = ca_cert - * - * extension_factory.create_extension 'basicConstraints', 'CA:FALSE' - * extension_factory.create_extension 'keyUsage', - * 'keyEncipherment,dataEncipherment,digitalSignature' - * extension_factory.create_extension 'subjectKeyIdentifier', 'hash' - * - * csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new - * - * open 'csr_cert.pem', 'w' do |io| - * io.write csr_cert.to_pem - * end - * - * == SSL and TLS Connections - * - * Using our created key and certificate we can create an SSL or TLS connection. - * An SSLContext is used to set up an SSL session. - * - * context = OpenSSL::SSL::SSLContext.new - * - * === SSL Server - * - * An SSL server requires the certificate and private key to communicate - * securely with its clients: - * - * context.cert = cert - * context.key = key - * - * Then create an SSLServer with a TCP server socket and the context. Use the - * SSLServer like an ordinary TCP server. - * - * require 'socket' - * - * tcp_server = TCPServer.new 5000 - * ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context - * - * loop do - * ssl_connection = ssl_server.accept - * - * data = connection.gets - * - * response = "I got #{data.dump}" - * puts response - * - * connection.puts "I got #{data.dump}" - * connection.close - * end - * - * === SSL client - * - * An SSL client is created with a TCP socket and the context. - * SSLSocket#connect must be called to initiate the SSL handshake and start - * encryption. A key and certificate are not required for the client socket. - * - * require 'socket' - * - * tcp_client = TCPSocket.new 'localhost', 5000 - * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context - * ssl_client.connect - * - * ssl_client.puts "hello server!" - * puts ssl_client.gets - * - * === Peer Verification - * - * An unverified SSL connection does not provide much security. For enhanced - * security the client or server can verify the certificate of its peer. - * - * The client can be modified to verify the server's certificate against the - * certificate authority's certificate: - * - * context.ca_file = 'ca_cert.pem' - * context.verify_mode = OpenSSL::SSL::VERIFY_PEER - * - * require 'socket' - * - * tcp_client = TCPSocket.new 'localhost', 5000 - * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context - * ssl_client.connect - * - * ssl_client.puts "hello server!" - * puts ssl_client.gets - * - * If the server certificate is invalid or <tt>context.ca_file</tt> is not set - * when verifying peers an OpenSSL::SSL::SSLError will be raised. - * - */ -void -Init_openssl() -{ - /* - * Init timezone info - */ -#if 0 - tzset(); -#endif - - /* - * Init all digests, ciphers - */ - /* CRYPTO_malloc_init(); */ - /* ENGINE_load_builtin_engines(); */ - OpenSSL_add_ssl_algorithms(); - OpenSSL_add_all_algorithms(); - ERR_load_crypto_strings(); - SSL_load_error_strings(); - - /* - * FIXME: - * On unload do: - */ -#if 0 - CONF_modules_unload(1); - destroy_ui_method(); - EVP_cleanup(); - ENGINE_cleanup(); - CRYPTO_cleanup_all_ex_data(); - ERR_remove_state(0); - ERR_free_strings(); -#endif - - /* - * Init main module - */ - mOSSL = rb_define_module("OpenSSL"); - - /* - * OpenSSL ruby extension version - */ - rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION)); - - /* - * Version of OpenSSL the ruby OpenSSL extension was built with - */ - rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT)); - /* - * Version number of OpenSSL the ruby OpenSSL extension was built with - * (base 16) - */ - rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER)); - - /* - * Generic error, - * common for all classes under OpenSSL module - */ - eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError); - - /* - * Verify callback Proc index for ext-data - */ - if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_verify_cb_idx", 0, 0, 0)) < 0) - ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index"); - - /* - * Init debug core - */ - dOSSL = Qfalse; - rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0); - rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1); - rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0); - - /* - * Get ID of to_der - */ - ossl_s_to_der = rb_intern("to_der"); - - /* - * Init components - */ - Init_ossl_bn(); - Init_ossl_cipher(); - Init_ossl_config(); - Init_ossl_digest(); - Init_ossl_hmac(); - Init_ossl_ns_spki(); - Init_ossl_pkcs12(); - Init_ossl_pkcs7(); - Init_ossl_pkcs5(); - Init_ossl_pkey(); - Init_ossl_rand(); - Init_ossl_ssl(); - Init_ossl_x509(); - Init_ossl_ocsp(); - Init_ossl_engine(); - Init_ossl_asn1(); -} - -#if defined(OSSL_DEBUG) -/* - * Check if all symbols are OK with 'make LDSHARED=gcc all' - */ -int -main(int argc, char *argv[]) -{ - return 0; -} -#endif /* OSSL_DEBUG */ - diff --git a/ruby_1_9_3/ext/openssl/ossl.h b/ruby_1_9_3/ext/openssl/ossl.h deleted file mode 100644 index 97095f7d6f..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_H_) -#define _OSSL_H_ - -#include RUBY_EXTCONF_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#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> - -/* - * Check the OpenSSL version - * The only supported are: - * OpenSSL >= 0.9.7 - */ -#include <openssl/opensslv.h> - -#ifdef HAVE_ASSERT_H -# include <assert.h> -#else -# define assert(condition) -#endif - -#if defined(_WIN32) -# include <openssl/e_os2.h> -# define OSSL_NO_CONF_API 1 -# 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_mac.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> -#undef X509_NAME -#undef PKCS7_SIGNER_INFO -#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ST_ENGINE) -# define OSSL_ENGINE_ENABLED -# include <openssl/engine.h> -#endif -#if defined(HAVE_OPENSSL_OCSP_H) -# define OSSL_OCSP_ENABLED -# 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 (%s)! (Expected kind of %s)",\ - rb_obj_classname(obj), rb_class2name(klass));\ - }\ -} while (0) - -#define OSSL_Check_Instance(obj, klass) do {\ - if (!rb_obj_is_instance_of((obj), (klass))) {\ - ossl_raise(rb_eTypeError, "wrong argument (%s)! (Expected instance of %s)",\ - rb_obj_classname(obj), rb_class2name(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) - -/* - * Compatibility - */ -#if OPENSSL_VERSION_NUMBER >= 0x10000000L -#define STACK _STACK -#endif - -/* - * 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{\ - int len = RSTRING_LENINT(str);\ - int newlen = rb_long2int((p) - (unsigned char*)RSTRING_PTR(str));\ - assert(newlen <= len);\ - rb_str_set_len((str), newlen);\ -}while(0) - -/* - * our default PEM callback - */ -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) (void)BIO_reset((bio)); \ - ERR_clear_error(); - -/* - * 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 *, ...); - -/* - * Verify callback - */ -extern int ossl_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); - -#if defined(__cplusplus) -} -#endif - -#endif /* _OSSL_H_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_asn1.c b/ruby_1_9_3/ext/openssl/ossl_asn1.c deleted file mode 100644 index 210ae5ca8b..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_asn1.c +++ /dev/null @@ -1,1947 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' team members - * Copyright (C) 2003 - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#if defined(HAVE_SYS_TIME_H) -# include <sys/time.h> -#elif !defined(NT) && !defined(_WIN32) -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -#endif - -static VALUE join_der(VALUE enumerable); -static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset, - int depth, int yield, long *num_read); -static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self); -static VALUE ossl_asn1eoc_initialize(VALUE self); - -/* - * DATE conversion - */ -VALUE -asn1time_to_time(ASN1_TIME *time) -{ - struct tm tm; - VALUE argv[6]; - - if (!time || !time->data) return Qnil; - memset(&tm, 0, sizeof(struct tm)); - - switch (time->type) { - case V_ASN1_UTCTIME: - if (sscanf((const char *)time->data, "%2d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - ossl_raise(rb_eTypeError, "bad UTCTIME format"); - } - if (tm.tm_year < 69) { - tm.tm_year += 2000; - } else { - tm.tm_year += 1900; - } - break; - case V_ASN1_GENERALIZEDTIME: - if (sscanf((const char *)time->data, "%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format" ); - } - break; - default: - rb_warning("unknown time format"); - return Qnil; - } - argv[0] = INT2NUM(tm.tm_year); - argv[1] = INT2NUM(tm.tm_mon); - argv[2] = INT2NUM(tm.tm_mday); - argv[3] = INT2NUM(tm.tm_hour); - argv[4] = INT2NUM(tm.tm_min); - argv[5] = INT2NUM(tm.tm_sec); - - return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv); -} - -/* - * This function is not exported in Ruby's *.h - */ -extern struct timeval rb_time_timeval(VALUE); - -time_t -time_to_time_t(VALUE time) -{ - return (time_t)NUM2LONG(rb_Integer(time)); -} - -/* - * STRING conversion - */ -VALUE -asn1str_to_str(ASN1_STRING *str) -{ - return rb_str_new((const char *)str->data, str->length); -} - -/* - * ASN1_INTEGER conversions - * TODO: Make a decision what's the right way to do this. - */ -#define DO_IT_VIA_RUBY 0 -VALUE -asn1integer_to_num(ASN1_INTEGER *ai) -{ - BIGNUM *bn; -#if DO_IT_VIA_RUBY - char *txt; -#endif - VALUE num; - - if (!ai) { - ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); - } - if (!(bn = ASN1_INTEGER_to_BN(ai, NULL))) { - ossl_raise(eOSSLError, NULL); - } -#if DO_IT_VIA_RUBY - if (!(txt = BN_bn2dec(bn))) { - BN_free(bn); - ossl_raise(eOSSLError, NULL); - } - num = rb_cstr_to_inum(txt, 10, Qtrue); - OPENSSL_free(txt); -#else - num = ossl_bn_new(bn); -#endif - BN_free(bn); - - return num; -} - -#if DO_IT_VIA_RUBY -ASN1_INTEGER * -num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) -{ - BIGNUM *bn = NULL; - - if (RTEST(rb_obj_is_kind_of(obj, cBN))) { - bn = GetBNPtr(obj); - } else { - obj = rb_String(obj); - if (!BN_dec2bn(&bn, StringValuePtr(obj))) { - ossl_raise(eOSSLError, NULL); - } - } - if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) { - BN_free(bn); - ossl_raise(eOSSLError, NULL); - } - BN_free(bn); - return ai; -} -#else -ASN1_INTEGER * -num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) -{ - BIGNUM *bn; - - if (NIL_P(obj)) - ossl_raise(rb_eTypeError, "Can't convert nil into Integer"); - - bn = GetBNPtr(obj); - - if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) - ossl_raise(eOSSLError, NULL); - - return ai; -} -#endif - -/********/ -/* - * ASN1 module - */ -#define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE) -#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG) -#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING) -#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS) -#define ossl_asn1_get_infinite_length(o) rb_attr_get((o),sivINFINITE_LENGTH) - -#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v)) -#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v)) -#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v)) -#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v)) -#define ossl_asn1_set_infinite_length(o,v) rb_ivar_set((o),sivINFINITE_LENGTH,(v)) - -VALUE mASN1; -VALUE eASN1Error; - -VALUE cASN1Data; -VALUE cASN1Primitive; -VALUE cASN1Constructive; - -VALUE cASN1EndOfContent; -VALUE cASN1Boolean; /* BOOLEAN */ -VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */ -VALUE cASN1BitString; /* BIT STRING */ -VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */ -VALUE cASN1NumericString, cASN1PrintableString; -VALUE cASN1T61String, cASN1VideotexString; -VALUE cASN1IA5String, cASN1GraphicString; -VALUE cASN1ISO64String, cASN1GeneralString; -VALUE cASN1UniversalString, cASN1BMPString; -VALUE cASN1Null; /* NULL */ -VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */ -VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */ -VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ - -static ID sIMPLICIT, sEXPLICIT; -static ID sUNIVERSAL, sAPPLICATION, sCONTEXT_SPECIFIC, sPRIVATE; -static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINFINITE_LENGTH, sivUNUSED_BITS; - -/* - * We need to implement these for backward compatibility - * reasons, behavior of ASN1_put_object and ASN1_object_size - * for infinite length values is different in OpenSSL <= 0.9.7 - */ -#if OPENSSL_VERSION_NUMBER < 0x00908000L -#define ossl_asn1_object_size(cons, len, tag) (cons) == 2 ? (len) + ASN1_object_size((cons), 0, (tag)) : ASN1_object_size((cons), (len), (tag)) -#define ossl_asn1_put_object(pp, cons, len, tag, xc) (cons) == 2 ? ASN1_put_object((pp), (cons), 0, (tag), (xc)) : ASN1_put_object((pp), (cons), (len), (tag), (xc)) -#else -#define ossl_asn1_object_size(cons, len, tag) ASN1_object_size((cons), (len), (tag)) -#define ossl_asn1_put_object(pp, cons, len, tag, xc) ASN1_put_object((pp), (cons), (len), (tag), (xc)) -#endif - -/* - * Ruby to ASN1 converters - */ -static ASN1_BOOLEAN -obj_to_asn1bool(VALUE obj) -{ - if (NIL_P(obj)) - ossl_raise(rb_eTypeError, "Can't convert nil into Boolean"); - -#if OPENSSL_VERSION_NUMBER < 0x00907000L - return RTEST(obj) ? 0xff : 0x100; -#else - return RTEST(obj) ? 0xff : 0x0; -#endif -} - -static ASN1_INTEGER* -obj_to_asn1int(VALUE obj) -{ - return num_to_asn1integer(obj, NULL); -} - -static ASN1_BIT_STRING* -obj_to_asn1bstr(VALUE obj, long unused_bits) -{ - ASN1_BIT_STRING *bstr; - - if(unused_bits < 0) unused_bits = 0; - StringValue(obj); - if(!(bstr = ASN1_BIT_STRING_new())) - ossl_raise(eASN1Error, NULL); - ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj)); - bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */ - bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07); - - return bstr; -} - -static ASN1_STRING* -obj_to_asn1str(VALUE obj) -{ - ASN1_STRING *str; - - StringValue(obj); - if(!(str = ASN1_STRING_new())) - ossl_raise(eASN1Error, NULL); - ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj)); - - return str; -} - -static ASN1_NULL* -obj_to_asn1null(VALUE obj) -{ - ASN1_NULL *null; - - if(!NIL_P(obj)) - ossl_raise(eASN1Error, "nil expected"); - if(!(null = ASN1_NULL_new())) - ossl_raise(eASN1Error, NULL); - - return null; -} - -static ASN1_OBJECT* -obj_to_asn1obj(VALUE obj) -{ - ASN1_OBJECT *a1obj; - - StringValue(obj); - a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 0); - if(!a1obj) a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 1); - if(!a1obj) ossl_raise(eASN1Error, "invalid OBJECT ID"); - - return a1obj; -} - -static ASN1_UTCTIME* -obj_to_asn1utime(VALUE time) -{ - time_t sec; - ASN1_UTCTIME *t; - - sec = time_to_time_t(time); - if(!(t = ASN1_UTCTIME_set(NULL, sec))) - ossl_raise(eASN1Error, NULL); - - return t; -} - -static ASN1_GENERALIZEDTIME* -obj_to_asn1gtime(VALUE time) -{ - time_t sec; - ASN1_GENERALIZEDTIME *t; - - sec = time_to_time_t(time); - if(!(t =ASN1_GENERALIZEDTIME_set(NULL, sec))) - ossl_raise(eASN1Error, NULL); - - return t; -} - -static ASN1_STRING* -obj_to_asn1derstr(VALUE obj) -{ - ASN1_STRING *a1str; - VALUE str; - - str = ossl_to_der(obj); - if(!(a1str = ASN1_STRING_new())) - ossl_raise(eASN1Error, NULL); - ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str)); - - return a1str; -} - -/* - * DER to Ruby converters - */ -static VALUE -decode_bool(unsigned char* der, int length) -{ - int val; - const unsigned char *p; - - p = der; - if((val = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0) - ossl_raise(eASN1Error, NULL); - - return val ? Qtrue : Qfalse; -} - -static VALUE -decode_int(unsigned char* der, int length) -{ - ASN1_INTEGER *ai; - const unsigned char *p; - VALUE ret; - int status = 0; - - p = der; - if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num, - (VALUE)ai, &status); - ASN1_INTEGER_free(ai); - if(status) rb_jump_tag(status); - - return ret; -} - -static VALUE -decode_bstr(unsigned char* der, int length, long *unused_bits) -{ - ASN1_BIT_STRING *bstr; - const unsigned char *p; - long len; - VALUE ret; - - p = der; - if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - len = bstr->length; - *unused_bits = 0; - if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT) - *unused_bits = bstr->flags & 0x07; - ret = rb_str_new((const char *)bstr->data, len); - ASN1_BIT_STRING_free(bstr); - - return ret; -} - -static VALUE -decode_enum(unsigned char* der, int length) -{ - ASN1_ENUMERATED *ai; - const unsigned char *p; - VALUE ret; - int status = 0; - - p = der; - if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num, - (VALUE)ai, &status); - ASN1_ENUMERATED_free(ai); - if(status) rb_jump_tag(status); - - return ret; -} - -static VALUE -decode_null(unsigned char* der, int length) -{ - ASN1_NULL *null; - const unsigned char *p; - - p = der; - if(!(null = d2i_ASN1_NULL(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - ASN1_NULL_free(null); - - return Qnil; -} - -static VALUE -decode_obj(unsigned char* der, int length) -{ - ASN1_OBJECT *obj; - const unsigned char *p; - VALUE ret; - int nid; - BIO *bio; - - p = der; - if(!(obj = d2i_ASN1_OBJECT(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - if((nid = OBJ_obj2nid(obj)) != NID_undef){ - ASN1_OBJECT_free(obj); - ret = rb_str_new2(OBJ_nid2sn(nid)); - } - else{ - if(!(bio = BIO_new(BIO_s_mem()))){ - ASN1_OBJECT_free(obj); - ossl_raise(eASN1Error, NULL); - } - i2a_ASN1_OBJECT(bio, obj); - ASN1_OBJECT_free(obj); - ret = ossl_membio2str(bio); - } - - return ret; -} - -static VALUE -decode_time(unsigned char* der, int length) -{ - ASN1_TIME *time; - const unsigned char *p; - VALUE ret; - int status = 0; - - p = der; - if(!(time = d2i_ASN1_TIME(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - ret = rb_protect((VALUE(*)_((VALUE)))asn1time_to_time, - (VALUE)time, &status); - ASN1_TIME_free(time); - if(status) rb_jump_tag(status); - - return ret; -} - -static VALUE -decode_eoc(unsigned char *der, int length) -{ - if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00)) - ossl_raise(eASN1Error, NULL); - - return rb_str_new("", 0); -} - -/********/ - -typedef struct { - const char *name; - VALUE *klass; -} ossl_asn1_info_t; - -static ossl_asn1_info_t ossl_asn1_info[] = { - { "EOC", &cASN1EndOfContent, }, /* 0 */ - { "BOOLEAN", &cASN1Boolean, }, /* 1 */ - { "INTEGER", &cASN1Integer, }, /* 2 */ - { "BIT_STRING", &cASN1BitString, }, /* 3 */ - { "OCTET_STRING", &cASN1OctetString, }, /* 4 */ - { "NULL", &cASN1Null, }, /* 5 */ - { "OBJECT", &cASN1ObjectId, }, /* 6 */ - { "OBJECT_DESCRIPTOR", NULL, }, /* 7 */ - { "EXTERNAL", NULL, }, /* 8 */ - { "REAL", NULL, }, /* 9 */ - { "ENUMERATED", &cASN1Enumerated, }, /* 10 */ - { "EMBEDDED_PDV", NULL, }, /* 11 */ - { "UTF8STRING", &cASN1UTF8String, }, /* 12 */ - { "RELATIVE_OID", NULL, }, /* 13 */ - { "[UNIVERSAL 14]", NULL, }, /* 14 */ - { "[UNIVERSAL 15]", NULL, }, /* 15 */ - { "SEQUENCE", &cASN1Sequence, }, /* 16 */ - { "SET", &cASN1Set, }, /* 17 */ - { "NUMERICSTRING", &cASN1NumericString, }, /* 18 */ - { "PRINTABLESTRING", &cASN1PrintableString, }, /* 19 */ - { "T61STRING", &cASN1T61String, }, /* 20 */ - { "VIDEOTEXSTRING", &cASN1VideotexString, }, /* 21 */ - { "IA5STRING", &cASN1IA5String, }, /* 22 */ - { "UTCTIME", &cASN1UTCTime, }, /* 23 */ - { "GENERALIZEDTIME", &cASN1GeneralizedTime, }, /* 24 */ - { "GRAPHICSTRING", &cASN1GraphicString, }, /* 25 */ - { "ISO64STRING", &cASN1ISO64String, }, /* 26 */ - { "GENERALSTRING", &cASN1GeneralString, }, /* 27 */ - { "UNIVERSALSTRING", &cASN1UniversalString, }, /* 28 */ - { "CHARACTER_STRING", NULL, }, /* 29 */ - { "BMPSTRING", &cASN1BMPString, }, /* 30 */ -}; - -int ossl_asn1_info_size = (sizeof(ossl_asn1_info)/sizeof(ossl_asn1_info[0])); - -static VALUE class_tag_map; - -static int ossl_asn1_default_tag(VALUE obj); - -ASN1_TYPE* -ossl_asn1_get_asn1type(VALUE obj) -{ - ASN1_TYPE *ret; - VALUE value, rflag; - void *ptr; - void (*free_func)(); - int tag, flag; - - tag = ossl_asn1_default_tag(obj); - value = ossl_asn1_get_value(obj); - switch(tag){ - case V_ASN1_BOOLEAN: - ptr = (void*)(VALUE)obj_to_asn1bool(value); - free_func = NULL; - break; - case V_ASN1_INTEGER: /* FALLTHROUGH */ - case V_ASN1_ENUMERATED: - ptr = obj_to_asn1int(value); - free_func = ASN1_INTEGER_free; - break; - case V_ASN1_BIT_STRING: - rflag = rb_attr_get(obj, sivUNUSED_BITS); - flag = NIL_P(rflag) ? -1 : NUM2INT(rflag); - ptr = obj_to_asn1bstr(value, flag); - free_func = ASN1_BIT_STRING_free; - break; - case V_ASN1_NULL: - ptr = obj_to_asn1null(value); - free_func = ASN1_NULL_free; - break; - case V_ASN1_OCTET_STRING: /* FALLTHROUGH */ - case V_ASN1_UTF8STRING: /* FALLTHROUGH */ - case V_ASN1_NUMERICSTRING: /* FALLTHROUGH */ - case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */ - case V_ASN1_T61STRING: /* FALLTHROUGH */ - case V_ASN1_VIDEOTEXSTRING: /* FALLTHROUGH */ - case V_ASN1_IA5STRING: /* FALLTHROUGH */ - case V_ASN1_GRAPHICSTRING: /* FALLTHROUGH */ - case V_ASN1_ISO64STRING: /* FALLTHROUGH */ - case V_ASN1_GENERALSTRING: /* FALLTHROUGH */ - case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */ - case V_ASN1_BMPSTRING: - ptr = obj_to_asn1str(value); - free_func = ASN1_STRING_free; - break; - case V_ASN1_OBJECT: - ptr = obj_to_asn1obj(value); - free_func = ASN1_OBJECT_free; - break; - case V_ASN1_UTCTIME: - ptr = obj_to_asn1utime(value); - free_func = ASN1_TIME_free; - break; - case V_ASN1_GENERALIZEDTIME: - ptr = obj_to_asn1gtime(value); - free_func = ASN1_TIME_free; - break; - case V_ASN1_SET: /* FALLTHROUGH */ - case V_ASN1_SEQUENCE: - ptr = obj_to_asn1derstr(obj); - free_func = ASN1_STRING_free; - break; - default: - ossl_raise(eASN1Error, "unsupported ASN.1 type"); - } - if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){ - if(free_func) free_func(ptr); - ossl_raise(eASN1Error, "ASN1_TYPE alloc failure"); - } - memset(ret, 0, sizeof(ASN1_TYPE)); - ASN1_TYPE_set(ret, tag, ptr); - - return ret; -} - -static int -ossl_asn1_default_tag(VALUE obj) -{ - VALUE tmp_class, tag; - - tmp_class = CLASS_OF(obj); - while (tmp_class) { - tag = rb_hash_lookup(class_tag_map, tmp_class); - if (tag != Qnil) { - return NUM2INT(tag); - } - tmp_class = rb_class_superclass(tmp_class); - } - ossl_raise(eASN1Error, "universal tag for %s not found", - rb_class2name(CLASS_OF(obj))); - - return -1; /* dummy */ -} - -static int -ossl_asn1_tag(VALUE obj) -{ - VALUE tag; - - tag = ossl_asn1_get_tag(obj); - if(NIL_P(tag)) - ossl_raise(eASN1Error, "tag number not specified"); - - return NUM2INT(tag); -} - -static int -ossl_asn1_is_explicit(VALUE obj) -{ - VALUE s; - int ret = -1; - - s = ossl_asn1_get_tagging(obj); - if(NIL_P(s)) return 0; - else if(SYMBOL_P(s)){ - if (SYM2ID(s) == sIMPLICIT) - ret = 0; - else if (SYM2ID(s) == sEXPLICIT) - ret = 1; - } - if(ret < 0){ - ossl_raise(eASN1Error, "invalid tag default"); - } - - return ret; -} - -static int -ossl_asn1_tag_class(VALUE obj) -{ - VALUE s; - int ret = -1; - - s = ossl_asn1_get_tag_class(obj); - if(NIL_P(s)) ret = V_ASN1_UNIVERSAL; - else if(SYMBOL_P(s)){ - if (SYM2ID(s) == sUNIVERSAL) - ret = V_ASN1_UNIVERSAL; - else if (SYM2ID(s) == sAPPLICATION) - ret = V_ASN1_APPLICATION; - else if (SYM2ID(s) == sCONTEXT_SPECIFIC) - ret = V_ASN1_CONTEXT_SPECIFIC; - else if (SYM2ID(s) == sPRIVATE) - ret = V_ASN1_PRIVATE; - } - if(ret < 0){ - ossl_raise(eASN1Error, "invalid tag class"); - } - - return ret; -} - -static VALUE -ossl_asn1_class2sym(int tc) -{ - if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - return ID2SYM(sPRIVATE); - else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - return ID2SYM(sCONTEXT_SPECIFIC); - else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - return ID2SYM(sAPPLICATION); - else - return ID2SYM(sUNIVERSAL); -} - -/* - * call-seq: - * OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) => ASN1Data - * - * +value+: Please have a look at Constructive and Primitive to see how Ruby - * types are mapped to ASN.1 types and vice versa. - * - * +tag+: A +Number+ indicating the tag number. - * - * +tag_class+: A +Symbol+ indicating the tag class. Please cf. ASN1 for - * possible values. - * - * == Example - * asn1_int = OpenSSL::ASN1Data.new(42, 2, :UNIVERSAL) # => Same as OpenSSL::ASN1::Integer.new(42) - * tagged_int = OpenSSL::ASN1Data.new(42, 0, :CONTEXT_SPECIFIC) # implicitly 0-tagged INTEGER - */ -static VALUE -ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class) -{ - if(!SYMBOL_P(tag_class)) - ossl_raise(eASN1Error, "invalid tag class"); - if((SYM2ID(tag_class) == sUNIVERSAL) && NUM2INT(tag) > 31) - ossl_raise(eASN1Error, "tag number for Universal too large"); - ossl_asn1_set_tag(self, tag); - ossl_asn1_set_value(self, value); - ossl_asn1_set_tag_class(self, tag_class); - ossl_asn1_set_infinite_length(self, Qfalse); - - return self; -} - -static VALUE -join_der_i(VALUE i, VALUE str) -{ - i = ossl_to_der_if_possible(i); - StringValue(i); - rb_str_append(str, i); - return Qnil; -} - -static VALUE -join_der(VALUE enumerable) -{ - VALUE str = rb_str_new(0, 0); - rb_block_call(enumerable, rb_intern("each"), 0, 0, join_der_i, str); - return str; -} - -/* - * call-seq: - * asn1.to_der => DER-encoded String - * - * Encodes this ASN1Data into a DER-encoded String value. The result is - * DER-encoded except for the possibility of infinite length encodings. - * Infinite length encodings are not allowed in strict DER, so strictly - * speaking the result of such an encoding would be a BER-encoding. - */ -static VALUE -ossl_asn1data_to_der(VALUE self) -{ - VALUE value, der, inf_length; - int tag, tag_class, is_cons = 0; - long length; - unsigned char *p; - - value = ossl_asn1_get_value(self); - if(rb_obj_is_kind_of(value, rb_cArray)){ - is_cons = 1; - value = join_der(value); - } - StringValue(value); - - tag = ossl_asn1_tag(self); - tag_class = ossl_asn1_tag_class(self); - inf_length = ossl_asn1_get_infinite_length(self); - if (inf_length == Qtrue) { - is_cons = 2; - } - if((length = ossl_asn1_object_size(is_cons, RSTRING_LENINT(value), tag)) <= 0) - ossl_raise(eASN1Error, NULL); - der = rb_str_new(0, length); - p = (unsigned char *)RSTRING_PTR(der); - ossl_asn1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class); - memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value)); - p += RSTRING_LEN(value); - ossl_str_adjust(der, p); - - return der; -} - -static VALUE -int_ossl_asn1_decode0_prim(unsigned char **pp, long length, int hlen, int tag, - VALUE tc, long *num_read) -{ - VALUE value, asn1data; - unsigned char *p; - long flag = 0; - - p = *pp; - - if(tc == sUNIVERSAL && tag < ossl_asn1_info_size) { - switch(tag){ - case V_ASN1_EOC: - value = decode_eoc(p, hlen+length); - break; - case V_ASN1_BOOLEAN: - value = decode_bool(p, hlen+length); - break; - case V_ASN1_INTEGER: - value = decode_int(p, hlen+length); - break; - case V_ASN1_BIT_STRING: - value = decode_bstr(p, hlen+length, &flag); - break; - case V_ASN1_NULL: - value = decode_null(p, hlen+length); - break; - case V_ASN1_ENUMERATED: - value = decode_enum(p, hlen+length); - break; - case V_ASN1_OBJECT: - value = decode_obj(p, hlen+length); - break; - case V_ASN1_UTCTIME: /* FALLTHROUGH */ - case V_ASN1_GENERALIZEDTIME: - value = decode_time(p, hlen+length); - break; - default: - /* use original value */ - p += hlen; - value = rb_str_new((const char *)p, length); - break; - } - } - else { - p += hlen; - value = rb_str_new((const char *)p, length); - } - - *pp += hlen + length; - *num_read = hlen + length; - - if (tc == sUNIVERSAL && tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) { - VALUE klass = *ossl_asn1_info[tag].klass; - VALUE args[4]; - args[0] = value; - args[1] = INT2NUM(tag); - args[2] = Qnil; - args[3] = ID2SYM(tc); - asn1data = rb_obj_alloc(klass); - ossl_asn1_initialize(4, args, asn1data); - if(tag == V_ASN1_BIT_STRING){ - rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag)); - } - } - else { - asn1data = rb_obj_alloc(cASN1Data); - ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), ID2SYM(tc)); - } - - return asn1data; -} - -static VALUE -int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, - long *offset, int depth, int yield, int j, - int tag, VALUE tc, long *num_read) -{ - VALUE value, asn1data, ary; - int infinite; - long off = *offset; - - infinite = (j == 0x21); - ary = rb_ary_new(); - - while (length > 0 || infinite) { - long inner_read = 0; - value = ossl_asn1_decode0(pp, max_len, &off, depth + 1, yield, &inner_read); - *num_read += inner_read; - max_len -= inner_read; - rb_ary_push(ary, value); - if (length > 0) - length -= inner_read; - - if (infinite && - NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC && - SYM2ID(ossl_asn1_get_tag_class(value)) == sUNIVERSAL) { - break; - } - } - - if (tc == sUNIVERSAL) { - VALUE args[4]; - int not_sequence_or_set; - - not_sequence_or_set = tag != V_ASN1_SEQUENCE && tag != V_ASN1_SET; - - if (not_sequence_or_set) { - if (infinite) { - asn1data = rb_obj_alloc(cASN1Constructive); - } - else { - ossl_raise(eASN1Error, "invalid non-infinite tag"); - return Qnil; - } - } - else { - VALUE klass = *ossl_asn1_info[tag].klass; - asn1data = rb_obj_alloc(klass); - } - args[0] = ary; - args[1] = INT2NUM(tag); - args[2] = Qnil; - args[3] = ID2SYM(tc); - ossl_asn1_initialize(4, args, asn1data); - } - else { - asn1data = rb_obj_alloc(cASN1Data); - ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), ID2SYM(tc)); - } - - if (infinite) - ossl_asn1_set_infinite_length(asn1data, Qtrue); - else - ossl_asn1_set_infinite_length(asn1data, Qfalse); - - *offset = off; - return asn1data; -} - -static VALUE -ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth, - int yield, long *num_read) -{ - unsigned char *start, *p; - const unsigned char *p0; - long len = 0, inner_read = 0, off = *offset; - int hlen, tag, tc, j; - VALUE asn1data, tag_class; - - p = *pp; - start = p; - p0 = p; - j = ASN1_get_object(&p0, &len, &tag, &tc, length); - p = (unsigned char *)p0; - if(j & 0x80) ossl_raise(eASN1Error, NULL); - if(len > length) ossl_raise(eASN1Error, "value is too short"); - if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - tag_class = sPRIVATE; - else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - tag_class = sCONTEXT_SPECIFIC; - else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - tag_class = sAPPLICATION; - else - tag_class = sUNIVERSAL; - - hlen = p - start; - - if(yield) { - VALUE arg = rb_ary_new(); - rb_ary_push(arg, LONG2NUM(depth)); - rb_ary_push(arg, LONG2NUM(*offset)); - rb_ary_push(arg, LONG2NUM(hlen)); - rb_ary_push(arg, LONG2NUM(len)); - rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse); - rb_ary_push(arg, ossl_asn1_class2sym(tc)); - rb_ary_push(arg, INT2NUM(tag)); - rb_yield(arg); - } - - if(j & V_ASN1_CONSTRUCTED) { - *pp += hlen; - off += hlen; - asn1data = int_ossl_asn1_decode0_cons(pp, length, len, &off, depth, yield, j, tag, tag_class, &inner_read); - inner_read += hlen; - } - else { - if ((j & 0x01) && (len == 0)) ossl_raise(eASN1Error, "Infinite length for primitive value"); - asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read); - off += hlen + len; - } - if (num_read) - *num_read = inner_read; - if (len != 0 && inner_read != hlen + len) { - ossl_raise(eASN1Error, - "Type mismatch. Bytes read: %ld Bytes available: %ld", - inner_read, hlen + len); - } - - *offset = off; - return asn1data; -} - -static void -int_ossl_decode_sanity_check(long len, long read, long offset) -{ - if (len != 0 && (read != len || offset != len)) { - ossl_raise(eASN1Error, - "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld", - read, len, offset); - } -} - -/* - * call-seq: - * OpenSSL::ASN1.traverse(asn1) -> nil - * - * If a block is given, it prints out each of the elements encountered. - * Block parameters are (in that order): - * * depth: The recursion depth, plus one with each constructed value being encountered (Number) - * * offset: Current byte offset (Number) - * * header length: Combined length in bytes of the Tag and Length headers. (Number) - * * length: The overall remaining length of the entire data (Number) - * * constructed: Whether this value is constructed or not (Boolean) - * * tag_class: Current tag class (Symbol) - * * tag: The current tag (Number) - * - * == Example - * der = File.binread('asn1data.der') - * OpenSSL::ASN1.traverse(der) do | depth, offset, header_len, length, constructed, tag_class, tag| - * puts "Depth: #{depth} Offset: #{offset} Length: #{length}" - * puts "Header length: #{header_len} Tag: #{tag} Tag class: #{tag_class} Constructed: #{constructed}" - * end - */ -static VALUE -ossl_asn1_traverse(VALUE self, VALUE obj) -{ - unsigned char *p; - volatile VALUE tmp; - long len, read = 0, offset = 0; - - obj = ossl_to_der_if_possible(obj); - tmp = rb_str_new4(StringValue(obj)); - p = (unsigned char *)RSTRING_PTR(tmp); - len = RSTRING_LEN(tmp); - ossl_asn1_decode0(&p, len, &offset, 0, 1, &read); - int_ossl_decode_sanity_check(len, read, offset); - return Qnil; -} - -/* - * call-seq: - * OpenSSL::ASN1.decode(der) -> ASN1Data - * - * Decodes a BER- or DER-encoded value and creates an ASN1Data instance. +der+ - * may be a +String+ or any object that features a +#to_der+ method transforming - * it into a BER-/DER-encoded +String+. - * - * == Example - * der = File.binread('asn1data') - * asn1 = OpenSSL::ASN1.decode(der) - */ -static VALUE -ossl_asn1_decode(VALUE self, VALUE obj) -{ - VALUE ret; - unsigned char *p; - volatile VALUE tmp; - long len, read = 0, offset = 0; - - obj = ossl_to_der_if_possible(obj); - tmp = rb_str_new4(StringValue(obj)); - p = (unsigned char *)RSTRING_PTR(tmp); - len = RSTRING_LEN(tmp); - ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read); - int_ossl_decode_sanity_check(len, read, offset); - return ret; -} - -/* - * call-seq: - * OpenSSL::ASN1.decode_all(der) -> Array of ASN1Data - * - * Similar to +decode+ with the difference that +decode+ expects one - * distinct value represented in +der+. +decode_all+ on the contrary - * decodes a sequence of sequential BER/DER values lined up in +der+ - * and returns them as an array. - * - * == Example - * ders = File.binread('asn1data_seq') - * asn1_ary = OpenSSL::ASN1.decode_all(ders) - */ -static VALUE -ossl_asn1_decode_all(VALUE self, VALUE obj) -{ - VALUE ary, val; - unsigned char *p; - long len, tmp_len = 0, read = 0, offset = 0; - volatile VALUE tmp; - - obj = ossl_to_der_if_possible(obj); - tmp = rb_str_new4(StringValue(obj)); - p = (unsigned char *)RSTRING_PTR(tmp); - len = RSTRING_LEN(tmp); - tmp_len = len; - ary = rb_ary_new(); - while (tmp_len > 0) { - long tmp_read = 0; - val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read); - rb_ary_push(ary, val); - read += tmp_read; - tmp_len -= tmp_read; - } - int_ossl_decode_sanity_check(len, read, offset); - return ary; -} - -/* - * call-seq: - * OpenSSL::ASN1::Primitive.new( value [, tag, tagging, tag_class ]) => Primitive - * - * +value+: is mandatory. - * - * +tag+: optional, may be specified for tagged values. If no +tag+ is - * specified, the UNIVERSAL tag corresponding to the Primitive sub-class - * is used by default. - * - * +tagging+: may be used as an encoding hint to encode a value either - * explicitly or implicitly, see ASN1 for possible values. - * - * +tag_class+: if +tag+ and +tagging+ are +nil+ then this is set to - * +:UNIVERSAL+ by default. If either +tag+ or +tagging+ are set then - * +:CONTEXT_SPECIFIC+ is used as the default. For possible values please - * cf. ASN1. - * - * == Example - * int = OpenSSL::ASN1::Integer.new(42) - * zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :IMPLICIT) - * private_explicit_zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :EXPLICIT, :PRIVATE) - */ -static VALUE -ossl_asn1_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE value, tag, tagging, tag_class; - - rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class); - if(argc > 1){ - if(NIL_P(tag)) - ossl_raise(eASN1Error, "must specify tag number"); - if(!NIL_P(tagging) && !SYMBOL_P(tagging)) - ossl_raise(eASN1Error, "invalid tagging method"); - if(NIL_P(tag_class)) { - if (NIL_P(tagging)) - tag_class = ID2SYM(sUNIVERSAL); - else - tag_class = ID2SYM(sCONTEXT_SPECIFIC); - } - if(!SYMBOL_P(tag_class)) - ossl_raise(eASN1Error, "invalid tag class"); - if(SYM2ID(tagging) == sIMPLICIT && NUM2INT(tag) > 31) - ossl_raise(eASN1Error, "tag number for Universal too large"); - } - else{ - tag = INT2NUM(ossl_asn1_default_tag(self)); - tagging = Qnil; - tag_class = ID2SYM(sUNIVERSAL); - } - ossl_asn1_set_tag(self, tag); - ossl_asn1_set_value(self, value); - ossl_asn1_set_tagging(self, tagging); - ossl_asn1_set_tag_class(self, tag_class); - ossl_asn1_set_infinite_length(self, Qfalse); - - return self; -} - -static VALUE -ossl_asn1eoc_initialize(VALUE self) { - VALUE tag, tagging, tag_class, value; - tag = INT2NUM(ossl_asn1_default_tag(self)); - tagging = Qnil; - tag_class = ID2SYM(sUNIVERSAL); - value = rb_str_new("", 0); - ossl_asn1_set_tag(self, tag); - ossl_asn1_set_value(self, value); - ossl_asn1_set_tagging(self, tagging); - ossl_asn1_set_tag_class(self, tag_class); - ossl_asn1_set_infinite_length(self, Qfalse); - return self; -} - -static int -ossl_i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp) -{ -#if OPENSSL_VERSION_NUMBER < 0x00907000L - if(!a) return 0; - if(a->type == V_ASN1_BOOLEAN) - return i2d_ASN1_BOOLEAN(a->value.boolean, pp); -#endif - return i2d_ASN1_TYPE(a, pp); -} - -static void -ossl_ASN1_TYPE_free(ASN1_TYPE *a) -{ -#if OPENSSL_VERSION_NUMBER < 0x00907000L - if(!a) return; - if(a->type == V_ASN1_BOOLEAN){ - OPENSSL_free(a); - return; - } -#endif - ASN1_TYPE_free(a); -} - -/* - * call-seq: - * asn1.to_der => DER-encoded String - * - * See ASN1Data#to_der for details. * - */ -static VALUE -ossl_asn1prim_to_der(VALUE self) -{ - ASN1_TYPE *asn1; - int tn, tc, explicit; - long len, reallen; - unsigned char *buf, *p; - VALUE str; - - tn = NUM2INT(ossl_asn1_get_tag(self)); - tc = ossl_asn1_tag_class(self); - explicit = ossl_asn1_is_explicit(self); - asn1 = ossl_asn1_get_asn1type(self); - - len = ossl_asn1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn); - if(!(buf = OPENSSL_malloc(len))){ - ossl_ASN1_TYPE_free(asn1); - ossl_raise(eASN1Error, "cannot alloc buffer"); - } - p = buf; - if (tc == V_ASN1_UNIVERSAL) { - ossl_i2d_ASN1_TYPE(asn1, &p); - } else if (explicit) { - ossl_asn1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc); - ossl_i2d_ASN1_TYPE(asn1, &p); - } else { - ossl_i2d_ASN1_TYPE(asn1, &p); - *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED); - } - ossl_ASN1_TYPE_free(asn1); - reallen = p - buf; - assert(reallen <= len); - str = ossl_buf2str((char *)buf, rb_long2int(reallen)); /* buf will be free in ossl_buf2str */ - - return str; -} - -/* - * call-seq: - * asn1.to_der => DER-encoded String - * - * See ASN1Data#to_der for details. - */ -static VALUE -ossl_asn1cons_to_der(VALUE self) -{ - int tag, tn, tc, explicit, constructed = 1; - int found_prim = 0, seq_len; - long length; - unsigned char *p; - VALUE value, str, inf_length; - - tn = NUM2INT(ossl_asn1_get_tag(self)); - tc = ossl_asn1_tag_class(self); - inf_length = ossl_asn1_get_infinite_length(self); - if (inf_length == Qtrue) { - VALUE ary, example; - constructed = 2; - if (CLASS_OF(self) == cASN1Sequence || - CLASS_OF(self) == cASN1Set) { - tag = ossl_asn1_default_tag(self); - } - else { /* must be a constructive encoding of a primitive value */ - ary = ossl_asn1_get_value(self); - if (!rb_obj_is_kind_of(ary, rb_cArray)) - ossl_raise(eASN1Error, "Constructive value must be an Array"); - /* Recursively descend until a primitive value is found. - The overall value of the entire constructed encoding - is of the type of the first primitive encoding to be - found. */ - while (!found_prim){ - example = rb_ary_entry(ary, 0); - if (rb_obj_is_kind_of(example, cASN1Primitive)){ - found_prim = 1; - } - else { - /* example is another ASN1Constructive */ - if (!rb_obj_is_kind_of(example, cASN1Constructive)){ - ossl_raise(eASN1Error, "invalid constructed encoding"); - return Qnil; /* dummy */ - } - ary = ossl_asn1_get_value(example); - } - } - tag = ossl_asn1_default_tag(example); - } - } - else { - if (CLASS_OF(self) == cASN1Constructive) - ossl_raise(eASN1Error, "Constructive shall only be used with infinite length"); - tag = ossl_asn1_default_tag(self); - } - explicit = ossl_asn1_is_explicit(self); - value = join_der(ossl_asn1_get_value(self)); - - seq_len = ossl_asn1_object_size(constructed, RSTRING_LENINT(value), tag); - length = ossl_asn1_object_size(constructed, seq_len, tn); - str = rb_str_new(0, length); - p = (unsigned char *)RSTRING_PTR(str); - if(tc == V_ASN1_UNIVERSAL) - ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc); - else{ - if(explicit){ - ossl_asn1_put_object(&p, constructed, seq_len, tn, tc); - ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tag, V_ASN1_UNIVERSAL); - } - else{ - ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc); - } - } - memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value)); - p += RSTRING_LEN(value); - - /* In this case we need an additional EOC (one for the explicit part and - * one for the Constructive itself. The EOC for the Constructive is - * supplied by the user, but that for the "explicit wrapper" must be - * added here. - */ - if (explicit && inf_length == Qtrue) { - ASN1_put_eoc(&p); - } - ossl_str_adjust(str, p); - - return str; -} - -/* - * call-seq: - * asn1_ary.each { |asn1| block } => asn1_ary - * - * Calls <i>block</i> once for each element in +self+, passing that element - * as parameter +asn1+. If no block is given, an enumerator is returned - * instead. - * - * == Example - * asn1_ary.each do |asn1| - * puts asn1 - * end - */ -static VALUE -ossl_asn1cons_each(VALUE self) -{ - rb_ary_each(ossl_asn1_get_value(self)); - return self; -} - -static VALUE -ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln) -{ - StringValue(oid); - StringValue(sn); - StringValue(ln); - - if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln))) - ossl_raise(eASN1Error, NULL); - - return Qtrue; -} - -static VALUE -ossl_asn1obj_get_sn(VALUE self) -{ - VALUE val, ret = Qnil; - int nid; - - val = ossl_asn1_get_value(self); - if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); - - return ret; -} - -static VALUE -ossl_asn1obj_get_ln(VALUE self) -{ - VALUE val, ret = Qnil; - int nid; - - val = ossl_asn1_get_value(self); - if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef) - ret = rb_str_new2(OBJ_nid2ln(nid)); - - return ret; -} - -static VALUE -ossl_asn1obj_get_oid(VALUE self) -{ - VALUE val; - ASN1_OBJECT *a1obj; - char buf[128]; - - val = ossl_asn1_get_value(self); - a1obj = obj_to_asn1obj(val); - OBJ_obj2txt(buf, sizeof(buf), a1obj, 1); - ASN1_OBJECT_free(a1obj); - - return rb_str_new2(buf); -} - -#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \ -static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\ -{ return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); } - -OSSL_ASN1_IMPL_FACTORY_METHOD(Boolean) -OSSL_ASN1_IMPL_FACTORY_METHOD(Integer) -OSSL_ASN1_IMPL_FACTORY_METHOD(Enumerated) -OSSL_ASN1_IMPL_FACTORY_METHOD(BitString) -OSSL_ASN1_IMPL_FACTORY_METHOD(OctetString) -OSSL_ASN1_IMPL_FACTORY_METHOD(UTF8String) -OSSL_ASN1_IMPL_FACTORY_METHOD(NumericString) -OSSL_ASN1_IMPL_FACTORY_METHOD(PrintableString) -OSSL_ASN1_IMPL_FACTORY_METHOD(T61String) -OSSL_ASN1_IMPL_FACTORY_METHOD(VideotexString) -OSSL_ASN1_IMPL_FACTORY_METHOD(IA5String) -OSSL_ASN1_IMPL_FACTORY_METHOD(GraphicString) -OSSL_ASN1_IMPL_FACTORY_METHOD(ISO64String) -OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralString) -OSSL_ASN1_IMPL_FACTORY_METHOD(UniversalString) -OSSL_ASN1_IMPL_FACTORY_METHOD(BMPString) -OSSL_ASN1_IMPL_FACTORY_METHOD(Null) -OSSL_ASN1_IMPL_FACTORY_METHOD(ObjectId) -OSSL_ASN1_IMPL_FACTORY_METHOD(UTCTime) -OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralizedTime) -OSSL_ASN1_IMPL_FACTORY_METHOD(Sequence) -OSSL_ASN1_IMPL_FACTORY_METHOD(Set) -OSSL_ASN1_IMPL_FACTORY_METHOD(EndOfContent) - -void -Init_ossl_asn1() -{ - VALUE ary; - int i; - -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ -#endif - - sUNIVERSAL = rb_intern("UNIVERSAL"); - sCONTEXT_SPECIFIC = rb_intern("CONTEXT_SPECIFIC"); - sAPPLICATION = rb_intern("APPLICATION"); - sPRIVATE = rb_intern("PRIVATE"); - sEXPLICIT = rb_intern("EXPLICIT"); - sIMPLICIT = rb_intern("IMPLICIT"); - - sivVALUE = rb_intern("@value"); - sivTAG = rb_intern("@tag"); - sivTAGGING = rb_intern("@tagging"); - sivTAG_CLASS = rb_intern("@tag_class"); - sivINFINITE_LENGTH = rb_intern("@infinite_length"); - sivUNUSED_BITS = rb_intern("@unused_bits"); - - /* - * Document-module: OpenSSL::ASN1 - * - * Abstract Syntax Notation One (or ASN.1) is a notation syntax to - * describe data structures and is defined in ITU-T X.680. ASN.1 itself - * does not mandate any encoding or parsing rules, but usually ASN.1 data - * structures are encoded using the Distinguished Encoding Rules (DER) or - * less often the Basic Encoding Rules (BER) described in ITU-T X.690. DER - * and BER encodings are binary Tag-Length-Value (TLV) encodings that are - * quite concise compared to other popular data description formats such - * as XML, JSON etc. - * ASN.1 data structures are very common in cryptographic applications, - * e.g. X.509 public key certificates or certificate revocation lists - * (CRLs) are all defined in ASN.1 and DER-encoded. ASN.1, DER and BER are - * the building blocks of applied cryptography. - * The ASN1 module provides the necessary classes that allow generation - * of ASN.1 data structures and the methods to encode them using a DER - * encoding. The decode method allows parsing arbitrary BER-/DER-encoded - * data to a Ruby object that can then be modified and re-encoded at will. - * - * == ASN.1 class hierarchy - * - * The base class representing ASN.1 structures is ASN1Data. ASN1Data offers - * attributes to read and set the +tag+, the +tag_class+ and finally the - * +value+ of a particular ASN.1 item. Upon parsing, any tagged values - * (implicit or explicit) will be represented by ASN1Data instances because - * their "real type" can only be determined using out-of-band information - * from the ASN.1 type declaration. Since this information is normally - * known when encoding a type, all sub-classes of ASN1Data offer an - * additional attribute +tagging+ that allows to encode a value implicitly - * (+:IMPLICIT+) or explicitly (+:EXPLICIT+). - * - * === Constructive - * - * Constructive is, as its name implies, the base class for all - * constructed encodings, i.e. those that consist of several values, - * opposed to "primitive" encodings with just one single value. - * Primitive values that are encoded with "infinite length" are typically - * constructed (their values come in multiple chunks) and are therefore - * represented by instances of Constructive. The value of an Constructive - * is always an Array. - * - * ==== ASN1::Set and ASN1::Sequence - * - * The most common constructive encodings are SETs and SEQUENCEs, which is - * why there are two sub-classes of Constructive representing each of - * them. - * - * === Primitive - * - * This is the super class of all primitive values. Primitive - * itself is not used when parsing ASN.1 data, all values are either - * instances of a corresponding sub-class of Primitive or they are - * instances of ASN1Data if the value was tagged implicitly or explicitly. - * Please cf. Primitive documentation for details on sub-classes and - * their respective mappings of ASN.1 data types to Ruby objects. - * - * == Possible values for +tagging+ - * - * When constructing an ASN1Data object the ASN.1 type definition may - * require certain elements to be either implicitly or explicitly tagged. - * This can be achieved by setting the +tagging+ attribute manually for - * sub-classes of ASN1Data. Use the symbol +:IMPLICIT+ for implicit - * tagging and +:EXPLICIT+ if the element requires explicit tagging. - * - * == Possible values for +tag_class+ - * - * It is possible to create arbitrary ASN1Data objects that also support - * a PRIVATE or APPLICATION tag class. Possible values for the +tag_class+ - * attribute are: - * * +:UNIVERSAL+ (the default for untagged values) - * * +:CONTEXT_SPECIFIC+ (the default for tagged values) - * * +:APPLICATION+ - * * +:PRIVATE+ - * - * == Tag constants - * - * There is a constant defined for each universal tag: - * * OpenSSL::ASN1::EOC (0) - * * OpenSSL::ASN1::BOOLEAN (1) - * * OpenSSL::ASN1::INTEGER (2) - * * OpenSSL::ASN1::BIT_STRING (3) - * * OpenSSL::ASN1::OCTET_STRING (4) - * * OpenSSL::ASN1::NULL (5) - * * OpenSSL::ASN1::OBJECT (6) - * * OpenSSL::ASN1::ENUMERATED (10) - * * OpenSSL::ASN1::UTF8STRING (12) - * * OpenSSL::ASN1::SEQUENCE (16) - * * OpenSSL::ASN1::SET (17) - * * OpenSSL::ASN1::NUMERICSTRING (18) - * * OpenSSL::ASN1::PRINTABLESTRING (19) - * * OpenSSL::ASN1::T61STRING (20) - * * OpenSSL::ASN1::VIDEOTEXSTRING (21) - * * OpenSSL::ASN1::IA5STRING (22) - * * OpenSSL::ASN1::UTCTIME (23) - * * OpenSSL::ASN1::GENERALIZEDTIME (24) - * * OpenSSL::ASN1::GRAPHICSTRING (25) - * * OpenSSL::ASN1::ISO64STRING (26) - * * OpenSSL::ASN1::GENERALSTRING (27) - * * OpenSSL::ASN1::UNIVERSALSTRING (28) - * * OpenSSL::ASN1::BMPSTRING (30) - * - * == UNIVERSAL_TAG_NAME constant - * - * An Array that stores the name of a given tag number. These names are - * the same as the name of the tag constant that is additionally defined, - * e.g. UNIVERSAL_TAG_NAME[2] = "INTEGER" and OpenSSL::ASN1::INTEGER = 2. - * - * == Example usage - * - * === Decoding and viewing a DER-encoded file - * require 'openssl' - * require 'pp' - * der = File.binread('data.der') - * asn1 = OpenSSL::ASN1.decode(der) - * pp der - * - * === Creating an ASN.1 structure and DER-encoding it - * require 'openssl' - * version = OpenSSL::ASN1::Integer.new(1) - * # Explicitly 0-tagged implies context-specific tag class - * serial = OpenSSL::ASN1::Integer.new(12345, 0, :EXPLICIT, :CONTEXT_SPECIFIC) - * name = OpenSSL::ASN1::PrintableString.new('Data 1') - * sequence = OpenSSL::ASN1::Sequence.new( [ version, serial, name ] ) - * der = sequence.to_der - */ - mASN1 = rb_define_module_under(mOSSL, "ASN1"); - - /* Document-class: OpenSSL::ASN1::ASN1Error - * - * Generic error class for all errors raised in ASN1 and any of the - * classes defined in it. - */ - eASN1Error = rb_define_class_under(mASN1, "ASN1Error", eOSSLError); - rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1); - rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1); - rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1); - ary = rb_ary_new(); - - /* - * Array storing tag names at the tag's index. - */ - rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary); - for(i = 0; i < ossl_asn1_info_size; i++){ - if(ossl_asn1_info[i].name[0] == '[') continue; - rb_define_const(mASN1, ossl_asn1_info[i].name, INT2NUM(i)); - rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name)); - } - - /* Document-class: OpenSSL::ASN1::ASN1Data - * - * The top-level class representing any ASN.1 object. When parsed by - * ASN1.decode, tagged values are always represented by an instance - * of ASN1Data. - * - * == The role of ASN1Data for parsing tagged values - * - * When encoding an ASN.1 type it is inherently clear what original - * type (e.g. INTEGER, OCTET STRING etc.) this value has, regardless - * of its tagging. - * But opposed to the time an ASN.1 type is to be encoded, when parsing - * them it is not possible to deduce the "real type" of tagged - * values. This is why tagged values are generally parsed into ASN1Data - * instances, but with a different outcome for implicit and explicit - * tagging. - * - * === Example of a parsed implicitly tagged value - * - * An implicitly 1-tagged INTEGER value will be parsed as an - * ASN1Data with - * * +tag+ equal to 1 - * * +tag_class+ equal to +:CONTEXT_SPECIFIC+ - * * +value+ equal to a +String+ that carries the raw encoding - * of the INTEGER. - * This implies that a subsequent decoding step is required to - * completely decode implicitly tagged values. - * - * === Example of a parsed explicitly tagged value - * - * An explicitly 1-tagged INTEGER value will be parsed as an - * ASN1Data with - * * +tag+ equal to 1 - * * +tag_class+ equal to +:CONTEXT_SPECIFIC+ - * * +value+ equal to an +Array+ with one single element, an - * instance of OpenSSL::ASN1::Integer, i.e. the inner element - * is the non-tagged primitive value, and the tagging is represented - * in the outer ASN1Data - * - * == Example - Decoding an implicitly tagged INTEGER - * int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) # implicit 0-tagged - * seq = OpenSSL::ASN1::Sequence.new( [int] ) - * der = seq.to_der - * asn1 = OpenSSL::ASN1.decode(der) - * # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0 - * # @infinite_length=false, - * # @tag=16, - * # @tag_class=:UNIVERSAL, - * # @tagging=nil, - * # @value= - * # [#<OpenSSL::ASN1::ASN1Data:0x87326f4 - * # @infinite_length=false, - * # @tag=0, - * # @tag_class=:CONTEXT_SPECIFIC, - * # @value="\x01">]> - * raw_int = asn1.value[0] - * # manually rewrite tag and tag class to make it an UNIVERSAL value - * raw_int.tag = OpenSSL::ASN1::INTEGER - * raw_int.tag_class = :UNIVERSAL - * int2 = OpenSSL::ASN1.decode(raw_int) - * puts int2.value # => 1 - * - * == Example - Decoding an explicitly tagged INTEGER - * int = OpenSSL::ASN1::Integer.new(1, 0, :EXPLICIT) # explicit 0-tagged - * seq = OpenSSL::ASN1::Sequence.new( [int] ) - * der = seq.to_der - * asn1 = OpenSSL::ASN1.decode(der) - * # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0 - * # @infinite_length=false, - * # @tag=16, - * # @tag_class=:UNIVERSAL, - * # @tagging=nil, - * # @value= - * # [#<OpenSSL::ASN1::ASN1Data:0x87326f4 - * # @infinite_length=false, - * # @tag=0, - * # @tag_class=:CONTEXT_SPECIFIC, - * # @value= - * # [#<OpenSSL::ASN1::Integer:0x85bf308 - * # @infinite_length=false, - * # @tag=2, - * # @tag_class=:UNIVERSAL - * # @tagging=nil, - * # @value=1>]>]> - * int2 = asn1.value[0].value[0] - * puts int2.value # => 1 - */ - cASN1Data = rb_define_class_under(mASN1, "ASN1Data", rb_cObject); - /* - * Carries the value of a ASN.1 type. - * Please confer Constructive and Primitive for the mappings between - * ASN.1 data types and Ruby classes. - */ - rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0); - /* - * A +Number+ representing the tag number of this ASN1Data. Never +nil+. - */ - rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0); - /* - * A +Symbol+ representing the tag class of this ASN1Data. Never +nil+. - * See ASN1Data for possible values. - */ - rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0); - /* - * Never +nil+. A +Boolean+ indicating whether the encoding was infinite - * length (in the case of parsing) or whether an infinite length encoding - * shall be used (in the encoding case). - * In DER, every value has a finite length associated with it. But in - * scenarios where large amounts of data need to be transferred it - * might be desirable to have some kind of streaming support available. - * For example, huge OCTET STRINGs are preferably sent in smaller-sized - * chunks, each at a time. - * This is possible in BER by setting the length bytes of an encoding - * to zero and by this indicating that the following value will be - * sent in chunks. Infinite length encodings are always constructed. - * The end of such a stream of chunks is indicated by sending a EOC - * (End of Content) tag. SETs and SEQUENCEs may use an infinite length - * encoding, but also primitive types such as e.g. OCTET STRINGS or - * BIT STRINGS may leverage this functionality (cf. ITU-T X.690). - */ - rb_attr(cASN1Data, rb_intern("infinite_length"), 1, 1, 0); - rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3); - rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0); - - /* Document-class: OpenSSL::ASN1::Primitive - * - * The parent class for all primitive encodings. Attributes are the same as - * for ASN1Data, with the addition of +tagging+. - * Primitive values can never be infinite length encodings, thus it is not - * possible to set the +infinite_length+ attribute for Primitive and its - * sub-classes. - * - * == Primitive sub-classes and their mapping to Ruby classes - * * OpenSSL::ASN1::EndOfContent <=> +value+ is always +nil+ - * * OpenSSL::ASN1::Boolean <=> +value+ is a +Boolean+ - * * OpenSSL::ASN1::Integer <=> +value+ is a +Number+ - * * OpenSSL::ASN1::BitString <=> +value+ is a +String+ - * * OpenSSL::ASN1::OctetString <=> +value+ is a +String+ - * * OpenSSL::ASN1::Null <=> +value+ is always +nil+ - * * OpenSSL::ASN1::Object <=> +value+ is a +String+ - * * OpenSSL::ASN1::Enumerated <=> +value+ is a +Number+ - * * OpenSSL::ASN1::UTF8String <=> +value+ is a +String+ - * * OpenSSL::ASN1::NumericString <=> +value+ is a +String+ - * * OpenSSL::ASN1::PrintableString <=> +value+ is a +String+ - * * OpenSSL::ASN1::T61String <=> +value+ is a +String+ - * * OpenSSL::ASN1::VideotexString <=> +value+ is a +String+ - * * OpenSSL::ASN1::IA5String <=> +value+ is a +String+ - * * OpenSSL::ASN1::UTCTime <=> +value+ is a +Time+ - * * OpenSSL::ASN1::GeneralizedTime <=> +value+ is a +Time+ - * * OpenSSL::ASN1::GraphicString <=> +value+ is a +String+ - * * OpenSSL::ASN1::ISO64String <=> +value+ is a +String+ - * * OpenSSL::ASN1::GeneralString <=> +value+ is a +String+ - * * OpenSSL::ASN1::UniversalString <=> +value+ is a +String+ - * * OpenSSL::ASN1::BMPString <=> +value+ is a +String+ - * - * == OpenSSL::ASN1::BitString - * - * === Additional attributes - * +unused_bits+: if the underlying BIT STRING's - * length is a multiple of 8 then +unused_bits+ is 0. Otherwise - * +unused_bits+ indicates the number of bits that are to be ignored in - * the final octet of the +BitString+'s +value+. - * - * == OpenSSL::ASN1::ObjectId - * - * === Additional attributes - * * +sn+: the short name as defined in <openssl/objects.h>. - * * +ln+: the long name as defined in <openssl/objects.h>. - * * +oid+: the object identifier as a +String+, e.g. "1.2.3.4.5" - * * +short_name+: alias for +sn+. - * * +long_name+: alias for +ln+. - * - * == Examples - * With the Exception of OpenSSL::ASN1::EndOfContent, each Primitive class - * constructor takes at least one parameter, the +value+. - * - * === Creating EndOfContent - * eoc = OpenSSL::ASN1::EndOfContent.new - * - * === Creating any other Primitive - * prim = <class>.new(value) # <class> being one of the sub-classes except EndOfContent - * prim_zero_tagged_implicit = <class>.new(value, 0, :IMPLICIT) - * prim_zero_tagged_explicit = <class>.new(value, 0, :EXPLICIT) - */ - cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data); - /* - * May be used as a hint for encoding a value either implicitly or - * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+. - * +tagging+ is not set when a ASN.1 structure is parsed using - * OpenSSL::ASN1.decode. - */ - rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue); - rb_undef_method(cASN1Primitive, "infinite_length="); - rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1); - rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0); - - /* Document-class: OpenSSL::ASN1::Constructive - * - * The parent class for all constructed encodings. The +value+ attribute - * of a Constructive is always an +Array+. Attributes are the same as - * for ASN1Data, with the addition of +tagging+. - * - * == SET and SEQUENCE - * - * Most constructed encodings come in the form of a SET or a SEQUENCE. - * These encodings are represented by one of the two sub-classes of - * Constructive: - * * OpenSSL::ASN1::Set - * * OpenSSL::ASN1::Sequence - * Please note that tagged sequences and sets are still parsed as - * instances of ASN1Data. Find further details on tagged values - * there. - * - * === Example - constructing a SEQUENCE - * int = OpenSSL::ASN1::Integer.new(1) - * str = OpenSSL::ASN1::PrintableString.new('abc') - * sequence = OpenSSL::ASN1::Sequence.new( [ int, str ] ) - * - * === Example - constructing a SET - * int = OpenSSL::ASN1::Integer.new(1) - * str = OpenSSL::ASN1::PrintableString.new('abc') - * set = OpenSSL::ASN1::Set.new( [ int, str ] ) - * - * == Infinite length primitive values - * - * The only case where Constructive is used directly is for infinite - * length encodings of primitive values. These encodings are always - * constructed, with the contents of the +value+ +Array+ being either - * UNIVERSAL non-infinite length partial encodings of the actual value - * or again constructive encodings with infinite length (i.e. infinite - * length primitive encodings may be constructed recursively with another - * infinite length value within an already infinite length value). Each - * partial encoding must be of the same UNIVERSAL type as the overall - * encoding. The value of the overall encoding consists of the - * concatenation of each partial encoding taken in sequence. The +value+ - * array of the outer infinite length value must end with a - * OpenSSL::ASN1::EndOfContent instance. - * - * Please note that it is not possible to encode Constructive without - * the +infinite_length+ attribute being set to +true+, use - * OpenSSL::ASN1::Sequence or OpenSSL::ASN1::Set in these cases instead. - * - * === Example - Infinite length OCTET STRING - * partial1 = OpenSSL::ASN1::OctetString.new("\x01") - * partial2 = OpenSSL::ASN1::OctetString.new("\x02") - * inf_octets = OpenSSL::ASN1::Constructive.new( [ partial1, - * partial2, - * OpenSSL::ASN1::EndOfContent.new ], - * OpenSSL::ASN1::OCTET_STRING, - * nil, - * :UNIVERSAL ) - * # The real value of inf_octets is "\x01\x02", i.e. the concatenation - * # of partial1 and partial2 - * inf_octets.infinite_length = true - * der = inf_octets.to_der - * asn1 = OpenSSL::ASN1.decode(der) - * puts asn1.infinite_length # => true - */ - cASN1Constructive = rb_define_class_under(mASN1,"Constructive", cASN1Data); - rb_include_module(cASN1Constructive, rb_mEnumerable); - /* - * May be used as a hint for encoding a value either implicitly or - * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+. - * +tagging+ is not set when a ASN.1 structure is parsed using - * OpenSSL::ASN1.decode. - */ - rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue); - rb_define_method(cASN1Constructive, "initialize", ossl_asn1_initialize, -1); - rb_define_method(cASN1Constructive, "to_der", ossl_asn1cons_to_der, 0); - rb_define_method(cASN1Constructive, "each", ossl_asn1cons_each, 0); - -#define OSSL_ASN1_DEFINE_CLASS(name, super) \ -do{\ - cASN1##name = rb_define_class_under(mASN1, #name, cASN1##super);\ - rb_define_module_function(mASN1, #name, ossl_asn1_##name, -1);\ -}while(0) - - OSSL_ASN1_DEFINE_CLASS(Boolean, Primitive); - OSSL_ASN1_DEFINE_CLASS(Integer, Primitive); - OSSL_ASN1_DEFINE_CLASS(Enumerated, Primitive); - OSSL_ASN1_DEFINE_CLASS(BitString, Primitive); - OSSL_ASN1_DEFINE_CLASS(OctetString, Primitive); - OSSL_ASN1_DEFINE_CLASS(UTF8String, Primitive); - OSSL_ASN1_DEFINE_CLASS(NumericString, Primitive); - OSSL_ASN1_DEFINE_CLASS(PrintableString, Primitive); - OSSL_ASN1_DEFINE_CLASS(T61String, Primitive); - OSSL_ASN1_DEFINE_CLASS(VideotexString, Primitive); - OSSL_ASN1_DEFINE_CLASS(IA5String, Primitive); - OSSL_ASN1_DEFINE_CLASS(GraphicString, Primitive); - OSSL_ASN1_DEFINE_CLASS(ISO64String, Primitive); - OSSL_ASN1_DEFINE_CLASS(GeneralString, Primitive); - OSSL_ASN1_DEFINE_CLASS(UniversalString, Primitive); - OSSL_ASN1_DEFINE_CLASS(BMPString, Primitive); - OSSL_ASN1_DEFINE_CLASS(Null, Primitive); - OSSL_ASN1_DEFINE_CLASS(ObjectId, Primitive); - OSSL_ASN1_DEFINE_CLASS(UTCTime, Primitive); - OSSL_ASN1_DEFINE_CLASS(GeneralizedTime, Primitive); - - OSSL_ASN1_DEFINE_CLASS(Sequence, Constructive); - OSSL_ASN1_DEFINE_CLASS(Set, Constructive); - - OSSL_ASN1_DEFINE_CLASS(EndOfContent, Data); - - rb_define_singleton_method(cASN1ObjectId, "register", ossl_asn1obj_s_register, 3); - rb_define_method(cASN1ObjectId, "sn", ossl_asn1obj_get_sn, 0); - rb_define_method(cASN1ObjectId, "ln", ossl_asn1obj_get_ln, 0); - rb_define_method(cASN1ObjectId, "oid", ossl_asn1obj_get_oid, 0); - rb_define_alias(cASN1ObjectId, "short_name", "sn"); - rb_define_alias(cASN1ObjectId, "long_name", "ln"); - rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0); - - rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0); - - class_tag_map = rb_hash_new(); - rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC)); - rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN)); - rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER)); - rb_hash_aset(class_tag_map, cASN1BitString, INT2NUM(V_ASN1_BIT_STRING)); - rb_hash_aset(class_tag_map, cASN1OctetString, INT2NUM(V_ASN1_OCTET_STRING)); - rb_hash_aset(class_tag_map, cASN1Null, INT2NUM(V_ASN1_NULL)); - rb_hash_aset(class_tag_map, cASN1ObjectId, INT2NUM(V_ASN1_OBJECT)); - rb_hash_aset(class_tag_map, cASN1Enumerated, INT2NUM(V_ASN1_ENUMERATED)); - rb_hash_aset(class_tag_map, cASN1UTF8String, INT2NUM(V_ASN1_UTF8STRING)); - rb_hash_aset(class_tag_map, cASN1Sequence, INT2NUM(V_ASN1_SEQUENCE)); - rb_hash_aset(class_tag_map, cASN1Set, INT2NUM(V_ASN1_SET)); - rb_hash_aset(class_tag_map, cASN1NumericString, INT2NUM(V_ASN1_NUMERICSTRING)); - rb_hash_aset(class_tag_map, cASN1PrintableString, INT2NUM(V_ASN1_PRINTABLESTRING)); - rb_hash_aset(class_tag_map, cASN1T61String, INT2NUM(V_ASN1_T61STRING)); - rb_hash_aset(class_tag_map, cASN1VideotexString, INT2NUM(V_ASN1_VIDEOTEXSTRING)); - rb_hash_aset(class_tag_map, cASN1IA5String, INT2NUM(V_ASN1_IA5STRING)); - rb_hash_aset(class_tag_map, cASN1UTCTime, INT2NUM(V_ASN1_UTCTIME)); - rb_hash_aset(class_tag_map, cASN1GeneralizedTime, INT2NUM(V_ASN1_GENERALIZEDTIME)); - rb_hash_aset(class_tag_map, cASN1GraphicString, INT2NUM(V_ASN1_GRAPHICSTRING)); - rb_hash_aset(class_tag_map, cASN1ISO64String, INT2NUM(V_ASN1_ISO64STRING)); - rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING)); - rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING)); - rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING)); - rb_global_variable(&class_tag_map); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_asn1.h b/ruby_1_9_3/ext/openssl/ossl_asn1.h deleted file mode 100644 index 718f43f068..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_asn1.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' team members - * Copyright (C) 2003 - * All rights reserved. - */ -/* - * This program is licenced 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 *); -time_t time_to_time_t(VALUE); - -/* - * 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 diff --git a/ruby_1_9_3/ext/openssl/ossl_bio.c b/ruby_1_9_3/ext/openssl/ossl_bio.c deleted file mode 100644 index ed7c0a71a5..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_bio.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' team members - * Copyright (C) 2003 - * All rights reserved. - */ -/* - * This program is licenced 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 (TYPE(obj) == T_FILE) { - rb_io_t *fptr; - FILE *fp; - int fd; - - GetOpenFile(obj, fptr); - rb_io_check_readable(fptr); - if ((fd = dup(FPTR_TO_FD(fptr))) < 0){ - rb_sys_fail(0); - } - rb_update_max_fd(fd); - if (!(fp = fdopen(fd, "r"))){ - close(fd); - rb_sys_fail(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; -} diff --git a/ruby_1_9_3/ext/openssl/ossl_bio.h b/ruby_1_9_3/ext/openssl/ossl_bio.h deleted file mode 100644 index 2d8f675c5b..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_bio.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' team members - * Copyright (C) 2003 - * All rights reserved. - */ -/* - * This program is licenced 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 - diff --git a/ruby_1_9_3/ext/openssl/ossl_bn.c b/ruby_1_9_3/ext/openssl/ossl_bn.c deleted file mode 100644 index 5d690af52d..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_bn.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Technorama team <oss-ruby@technorama.net> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -/* modified by Michal Rokos <m.rokos@sh.cvut.cz> */ -#include "ossl.h" - -#define WrapBN(klass, obj, bn) do { \ - if (!(bn)) { \ - ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, BN_clear_free, (bn)); \ -} while (0) - -#define GetBN(obj, bn) do { \ - Data_Get_Struct((obj), BIGNUM, (bn)); \ - if (!(bn)) { \ - ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ - } \ -} while (0) - -#define SafeGetBN(obj, bn) do { \ - OSSL_Check_Kind((obj), cBN); \ - GetBN((obj), (bn)); \ -} while (0) - -/* - * Classes - */ -VALUE cBN; -VALUE eBNError; - -/* - * Public - */ -VALUE -ossl_bn_new(const BIGNUM *bn) -{ - BIGNUM *newbn; - VALUE obj; - - newbn = bn ? BN_dup(bn) : BN_new(); - if (!newbn) { - ossl_raise(eBNError, NULL); - } - WrapBN(cBN, obj, newbn); - - return obj; -} - -BIGNUM * -GetBNPtr(VALUE obj) -{ - BIGNUM *bn = NULL; - - if (RTEST(rb_obj_is_kind_of(obj, cBN))) { - GetBN(obj, bn); - } else switch (TYPE(obj)) { - case T_FIXNUM: - case T_BIGNUM: - obj = rb_String(obj); - if (!BN_dec2bn(&bn, StringValuePtr(obj))) { - ossl_raise(eBNError, NULL); - } - WrapBN(cBN, obj, bn); /* Handle potencial mem leaks */ - break; - case T_NIL: - break; - default: - ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN"); - } - return bn; -} - -/* - * Private - */ -/* - * BN_CTX - is used in more difficult math. ops - * (Why just 1? Because Ruby itself isn't thread safe, - * we don't need to care about threads) - */ -BN_CTX *ossl_bn_ctx; - -static VALUE -ossl_bn_alloc(VALUE klass) -{ - BIGNUM *bn; - VALUE obj; - - if (!(bn = BN_new())) { - ossl_raise(eBNError, NULL); - } - WrapBN(klass, obj, bn); - - return obj; -} - -/* - * call-seq: - * BN.new => aBN - * BN.new(bn) => aBN - * BN.new(string) => aBN - * BN.new(string, 0 | 2 | 10 | 16) => aBN - */ -static VALUE -ossl_bn_initialize(int argc, VALUE *argv, VALUE self) -{ - BIGNUM *bn; - VALUE str, bs; - int base = 10; - - if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) { - base = NUM2INT(bs); - } - StringValue(str); - GetBN(self, bn); - if (RTEST(rb_obj_is_kind_of(str, cBN))) { - BIGNUM *other; - - GetBN(str, other); /* Safe - we checked kind_of? above */ - if (!BN_copy(bn, other)) { - ossl_raise(eBNError, NULL); - } - return self; - } - - switch (base) { - case 0: - if (!BN_mpi2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) { - ossl_raise(eBNError, NULL); - } - break; - case 2: - if (!BN_bin2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) { - ossl_raise(eBNError, NULL); - } - break; - case 10: - if (!BN_dec2bn(&bn, RSTRING_PTR(str))) { - ossl_raise(eBNError, NULL); - } - break; - case 16: - if (!BN_hex2bn(&bn, RSTRING_PTR(str))) { - ossl_raise(eBNError, NULL); - } - break; - default: - ossl_raise(rb_eArgError, "invalid radix %d", base); - } - return self; -} - -/* - * call-seq: - * bn.to_s => string - * bn.to_s(base) => string - * - * === Parameters - * * +base+ - integer - * * * Valid values: - * * * * 0 - MPI - * * * * 2 - binary - * * * * 10 - the default - * * * * 16 - hex - */ -static VALUE -ossl_bn_to_s(int argc, VALUE *argv, VALUE self) -{ - BIGNUM *bn; - VALUE str, bs; - int base = 10, len; - char *buf; - - if (rb_scan_args(argc, argv, "01", &bs) == 1) { - base = NUM2INT(bs); - } - GetBN(self, bn); - switch (base) { - case 0: - len = BN_bn2mpi(bn, NULL); - str = rb_str_new(0, len); - if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len) - ossl_raise(eBNError, NULL); - break; - case 2: - len = BN_num_bytes(bn); - str = rb_str_new(0, len); - if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len) - ossl_raise(eBNError, NULL); - break; - case 10: - if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL); - str = ossl_buf2str(buf, rb_long2int(strlen(buf))); - break; - case 16: - if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL); - str = ossl_buf2str(buf, rb_long2int(strlen(buf))); - break; - default: - ossl_raise(rb_eArgError, "invalid radix %d", base); - } - - return str; -} - -/* - * call-seq: - * bn.to_i => integer - */ -static VALUE -ossl_bn_to_i(VALUE self) -{ - BIGNUM *bn; - char *txt; - VALUE num; - - GetBN(self, bn); - - if (!(txt = BN_bn2dec(bn))) { - ossl_raise(eBNError, NULL); - } - num = rb_cstr_to_inum(txt, 10, Qtrue); - OPENSSL_free(txt); - - return num; -} - -static VALUE -ossl_bn_to_bn(VALUE self) -{ - return self; -} - -static VALUE -ossl_bn_coerce(VALUE self, VALUE other) -{ - switch(TYPE(other)) { - case T_STRING: - self = ossl_bn_to_s(0, NULL, self); - break; - case T_FIXNUM: - case T_BIGNUM: - self = ossl_bn_to_i(self); - break; - default: - if (!RTEST(rb_obj_is_kind_of(other, cBN))) { - ossl_raise(rb_eTypeError, "Don't know how to coerce"); - } - } - return rb_assoc_new(other, self); -} - -#define BIGNUM_BOOL1(func) \ - /* \ - * call-seq: \ - * bn.##func -> true | false \ - * \ - */ \ - static VALUE \ - ossl_bn_##func(VALUE self) \ - { \ - BIGNUM *bn; \ - GetBN(self, bn); \ - if (BN_##func(bn)) { \ - return Qtrue; \ - } \ - return Qfalse; \ - } -BIGNUM_BOOL1(is_zero) -BIGNUM_BOOL1(is_one) -BIGNUM_BOOL1(is_odd) - -#define BIGNUM_1c(func) \ - /* \ - * call-seq: \ - * bn.##func -> aBN \ - * \ - */ \ - static VALUE \ - ossl_bn_##func(VALUE self) \ - { \ - BIGNUM *bn, *result; \ - VALUE obj; \ - GetBN(self, bn); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn, ossl_bn_ctx)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - WrapBN(CLASS_OF(self), obj, result); \ - return obj; \ - } -BIGNUM_1c(sqr) - -#define BIGNUM_2(func) \ - /* \ - * call-seq: \ - * bn.##func(bn2) -> aBN \ - * \ - */ \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ - VALUE obj; \ - GetBN(self, bn1); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn1, bn2)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - WrapBN(CLASS_OF(self), obj, result); \ - return obj; \ - } -BIGNUM_2(add) -BIGNUM_2(sub) - -#define BIGNUM_2c(func) \ - /* \ - * call-seq: \ - * bn.##func(bn2) -> aBN \ - * \ - */ \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ - VALUE obj; \ - GetBN(self, bn1); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - WrapBN(CLASS_OF(self), obj, result); \ - return obj; \ - } -BIGNUM_2c(mul) -BIGNUM_2c(mod) -BIGNUM_2c(exp) -BIGNUM_2c(gcd) -BIGNUM_2c(mod_sqr) -BIGNUM_2c(mod_inverse) - -/* - * call-seq: - * bn1 / bn2 => [result, remainder] - */ -static VALUE -ossl_bn_div(VALUE self, VALUE other) -{ - BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2; - VALUE obj1, obj2; - - GetBN(self, bn1); - - if (!(r1 = BN_new())) { - ossl_raise(eBNError, NULL); - } - if (!(r2 = BN_new())) { - BN_free(r1); - ossl_raise(eBNError, NULL); - } - if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) { - BN_free(r1); - BN_free(r2); - ossl_raise(eBNError, NULL); - } - WrapBN(CLASS_OF(self), obj1, r1); - WrapBN(CLASS_OF(self), obj2, r2); - - return rb_ary_new3(2, obj1, obj2); -} - -#define BIGNUM_3c(func) \ - /* \ - * call-seq: \ - * bn.##func(bn1, bn2) -> aBN \ - * \ - */ \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other1); \ - BIGNUM *bn3 = GetBNPtr(other2), *result; \ - VALUE obj; \ - GetBN(self, bn1); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - WrapBN(CLASS_OF(self), obj, result); \ - return obj; \ - } -BIGNUM_3c(mod_add) -BIGNUM_3c(mod_sub) -BIGNUM_3c(mod_mul) -BIGNUM_3c(mod_exp) - -#define BIGNUM_BIT(func) \ - /* \ - * call-seq: \ - * bn.##func(bit) -> self \ - * \ - */ \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE bit) \ - { \ - BIGNUM *bn; \ - GetBN(self, bn); \ - if (!BN_##func(bn, NUM2INT(bit))) { \ - ossl_raise(eBNError, NULL); \ - } \ - return self; \ - } -BIGNUM_BIT(set_bit) -BIGNUM_BIT(clear_bit) -BIGNUM_BIT(mask_bits) - -/* - * call-seq: - * bn.bit_set?(bit) => true | false - */ -static VALUE -ossl_bn_is_bit_set(VALUE self, VALUE bit) -{ - int b; - BIGNUM *bn; - - b = NUM2INT(bit); - GetBN(self, bn); - if (BN_is_bit_set(bn, b)) { - return Qtrue; - } - return Qfalse; -} - -#define BIGNUM_SHIFT(func) \ - /* \ - * call-seq: \ - * bn.##func(bits) -> aBN \ - * \ - */ \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE bits) \ - { \ - BIGNUM *bn, *result; \ - int b; \ - VALUE obj; \ - b = NUM2INT(bits); \ - GetBN(self, bn); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn, b)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - WrapBN(CLASS_OF(self), obj, result); \ - return obj; \ - } -BIGNUM_SHIFT(lshift) -BIGNUM_SHIFT(rshift) - -#define BIGNUM_SELF_SHIFT(func) \ - /* \ - * call-seq: \ - * bn.##func!(bits) -> self \ - * \ - */ \ - static VALUE \ - ossl_bn_self_##func(VALUE self, VALUE bits) \ - { \ - BIGNUM *bn; \ - int b; \ - b = NUM2INT(bits); \ - GetBN(self, bn); \ - if (!BN_##func(bn, bn, b)) \ - ossl_raise(eBNError, NULL); \ - return self; \ - } -BIGNUM_SELF_SHIFT(lshift) -BIGNUM_SELF_SHIFT(rshift) - -#define BIGNUM_RAND(func) \ - /* \ - * call-seq: \ - * BN.##func(bits [, fill [, odd]]) -> aBN \ - * \ - */ \ - static VALUE \ - ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \ - { \ - BIGNUM *result; \ - int bottom = 0, top = 0, b; \ - VALUE bits, fill, odd, obj; \ - \ - switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \ - case 3: \ - bottom = (odd == Qtrue) ? 1 : 0; \ - /* FALLTHROUGH */ \ - case 2: \ - top = NUM2INT(fill); \ - } \ - b = NUM2INT(bits); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, b, top, bottom)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - WrapBN(klass, obj, result); \ - return obj; \ - } -BIGNUM_RAND(rand) -BIGNUM_RAND(pseudo_rand) - -#define BIGNUM_RAND_RANGE(func) \ - /* \ - * call-seq: \ - * BN.##func(range) -> aBN \ - * \ - */ \ - static VALUE \ - ossl_bn_s_##func##_range(VALUE klass, VALUE range) \ - { \ - BIGNUM *bn = GetBNPtr(range), *result; \ - VALUE obj; \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func##_range(result, bn)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - WrapBN(klass, obj, result); \ - return obj; \ - } -BIGNUM_RAND_RANGE(rand) -BIGNUM_RAND_RANGE(pseudo_rand) - -/* - * call-seq: - * BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn - * - * === Parameters - * * +bits+ - integer - * * +safe+ - boolean - * * +add+ - BN - * * +rem+ - BN - */ -static VALUE -ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass) -{ - BIGNUM *add = NULL, *rem = NULL, *result; - int safe = 1, num; - VALUE vnum, vsafe, vadd, vrem, obj; - - rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem); - - num = NUM2INT(vnum); - - if (vsafe == Qfalse) { - safe = 0; - } - if (!NIL_P(vadd)) { - add = GetBNPtr(vadd); - rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem); - } - if (!(result = BN_new())) { - ossl_raise(eBNError, NULL); - } - if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) { - BN_free(result); - ossl_raise(eBNError, NULL); - } - WrapBN(klass, obj, result); - - return obj; -} - -#define BIGNUM_NUM(func) \ - /* \ - * call-seq: \ - * bn.##func -> integer \ - * \ - */ \ - static VALUE \ - ossl_bn_##func(VALUE self) \ - { \ - BIGNUM *bn; \ - GetBN(self, bn); \ - return INT2FIX(BN_##func(bn)); \ - } -BIGNUM_NUM(num_bytes) -BIGNUM_NUM(num_bits) - -static VALUE -ossl_bn_copy(VALUE self, VALUE other) -{ - BIGNUM *bn1, *bn2; - - rb_check_frozen(self); - - if (self == other) return self; - - GetBN(self, bn1); - bn2 = GetBNPtr(other); - - if (!BN_copy(bn1, bn2)) { - ossl_raise(eBNError, NULL); - } - return self; -} - -#define BIGNUM_CMP(func) \ - /* \ - * call-seq: \ - * bn.##func(bn2) -> integer \ - * \ - */ \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other); \ - GetBN(self, bn1); \ - return INT2FIX(BN_##func(bn1, bn2)); \ - } -BIGNUM_CMP(cmp) -BIGNUM_CMP(ucmp) - -static VALUE -ossl_bn_eql(VALUE self, VALUE other) -{ - if (ossl_bn_cmp(self, other) == INT2FIX(0)) { - return Qtrue; - } - return Qfalse; -} - -/* - * call-seq: - * bn.prime? => true | false - * bn.prime?(checks) => true | false - * - * === Parameters - * * +checks+ - integer - */ -static VALUE -ossl_bn_is_prime(int argc, VALUE *argv, VALUE self) -{ - BIGNUM *bn; - VALUE vchecks; - int checks = BN_prime_checks; - - if (rb_scan_args(argc, argv, "01", &vchecks) == 1) { - checks = NUM2INT(vchecks); - } - GetBN(self, bn); - switch (BN_is_prime(bn, checks, NULL, ossl_bn_ctx, NULL)) { - case 1: - return Qtrue; - case 0: - return Qfalse; - default: - ossl_raise(eBNError, NULL); - } - /* not reachable */ - return Qnil; -} - -/* - * call-seq: - * bn.prime_fasttest? => true | false - * bn.prime_fasttest?(checks) => true | false - * bn.prime_fasttest?(checks, trial_div) => true | false - * - * === Parameters - * * +checks+ - integer - * * +trial_div+ - boolean - */ -static VALUE -ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self) -{ - BIGNUM *bn; - VALUE vchecks, vtrivdiv; - int checks = BN_prime_checks, do_trial_division = 1; - - rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv); - - if (!NIL_P(vchecks)) { - checks = NUM2INT(vchecks); - } - GetBN(self, bn); - /* handle true/false */ - if (vtrivdiv == Qfalse) { - do_trial_division = 0; - } - switch (BN_is_prime_fasttest(bn, checks, NULL, ossl_bn_ctx, NULL, do_trial_division)) { - case 1: - return Qtrue; - case 0: - return Qfalse; - default: - ossl_raise(eBNError, NULL); - } - /* not reachable */ - return Qnil; -} - -/* - * INIT - * (NOTE: ordering of methods is the same as in 'man bn') - */ -void -Init_ossl_bn() -{ -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ -#endif - - if (!(ossl_bn_ctx = BN_CTX_new())) { - ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX"); - } - - eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError); - - cBN = rb_define_class_under(mOSSL, "BN", rb_cObject); - - rb_define_alloc_func(cBN, ossl_bn_alloc); - rb_define_method(cBN, "initialize", ossl_bn_initialize, -1); - - rb_define_copy_func(cBN, ossl_bn_copy); - rb_define_method(cBN, "copy", ossl_bn_copy, 1); - - /* swap (=coerce?) */ - - rb_define_method(cBN, "num_bytes", ossl_bn_num_bytes, 0); - rb_define_method(cBN, "num_bits", ossl_bn_num_bits, 0); - /* num_bits_word */ - - rb_define_method(cBN, "+", ossl_bn_add, 1); - rb_define_method(cBN, "-", ossl_bn_sub, 1); - rb_define_method(cBN, "*", ossl_bn_mul, 1); - rb_define_method(cBN, "sqr", ossl_bn_sqr, 0); - rb_define_method(cBN, "/", ossl_bn_div, 1); - rb_define_method(cBN, "%", ossl_bn_mod, 1); - /* nnmod */ - - rb_define_method(cBN, "mod_add", ossl_bn_mod_add, 2); - rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2); - rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2); - rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1); - rb_define_method(cBN, "**", ossl_bn_exp, 1); - rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2); - rb_define_method(cBN, "gcd", ossl_bn_gcd, 1); - - /* add_word - * sub_word - * mul_word - * div_word - * mod_word */ - - rb_define_method(cBN, "cmp", ossl_bn_cmp, 1); - rb_define_alias(cBN, "<=>", "cmp"); - rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1); - rb_define_method(cBN, "eql?", ossl_bn_eql, 1); - rb_define_alias(cBN, "==", "eql?"); - rb_define_alias(cBN, "===", "eql?"); - rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0); - rb_define_method(cBN, "one?", ossl_bn_is_one, 0); - /* is_word */ - rb_define_method(cBN, "odd?", ossl_bn_is_odd, 0); - - /* zero - * one - * value_one - DON'T IMPL. - * set_word - * get_word */ - - rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1); - rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1); - rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1); - rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1); - - rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1); - rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1); - - rb_define_method(cBN, "set_bit!", ossl_bn_set_bit, 1); - rb_define_method(cBN, "clear_bit!", ossl_bn_clear_bit, 1); - rb_define_method(cBN, "bit_set?", ossl_bn_is_bit_set, 1); - rb_define_method(cBN, "mask_bits!", ossl_bn_mask_bits, 1); - rb_define_method(cBN, "<<", ossl_bn_lshift, 1); - rb_define_method(cBN, ">>", ossl_bn_rshift, 1); - rb_define_method(cBN, "lshift!", ossl_bn_self_lshift, 1); - rb_define_method(cBN, "rshift!", ossl_bn_self_rshift, 1); - /* lshift1 - DON'T IMPL. */ - /* rshift1 - DON'T IMPL. */ - - /* - * bn2bin - * bin2bn - * bn2hex - * bn2dec - * hex2bn - * dec2bn - all these are implemented in ossl_bn_initialize, and ossl_bn_to_s - * print - NOT IMPL. - * print_fp - NOT IMPL. - * bn2mpi - * mpi2bn - */ - rb_define_method(cBN, "to_s", ossl_bn_to_s, -1); - rb_define_method(cBN, "to_i", ossl_bn_to_i, 0); - rb_define_alias(cBN, "to_int", "to_i"); - rb_define_method(cBN, "to_bn", ossl_bn_to_bn, 0); - rb_define_method(cBN, "coerce", ossl_bn_coerce, 1); - - /* - * TODO: - * But how to: from_bin, from_mpi? PACK? - * to_bin - * to_mpi - */ - - rb_define_method(cBN, "mod_inverse", ossl_bn_mod_inverse, 1); - - /* RECiProcal - * MONTgomery */ - - /* - * TODO: - * Where to belong these? - */ - rb_define_method(cBN, "prime_fasttest?", ossl_bn_is_prime_fasttest, -1); -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_bn.h b/ruby_1_9_3/ext/openssl/ossl_bn.h deleted file mode 100644 index d6c396227b..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_bn.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced 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_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_cipher.c b/ruby_1_9_3/ext/openssl/ossl_cipher.c deleted file mode 100644 index 26851515cd..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_cipher.c +++ /dev/null @@ -1,754 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapCipher(obj, klass, ctx) \ - (obj) = Data_Wrap_Struct((klass), 0, ossl_cipher_free, (ctx)) -#define MakeCipher(obj, klass, ctx) \ - (obj) = Data_Make_Struct((klass), EVP_CIPHER_CTX, 0, ossl_cipher_free, (ctx)) -#define AllocCipher(obj, ctx) \ - memset(DATA_PTR(obj) = (ctx) = ALLOC(EVP_CIPHER_CTX), 0, sizeof(EVP_CIPHER_CTX)) -#define GetCipherInit(obj, ctx) do { \ - Data_Get_Struct((obj), EVP_CIPHER_CTX, (ctx)); \ -} while (0) -#define GetCipher(obj, ctx) do { \ - GetCipherInit((obj), (ctx)); \ - if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "Cipher not inititalized!"); \ - } \ -} while (0) -#define SafeGetCipher(obj, ctx) do { \ - OSSL_Check_Kind((obj), cCipher); \ - GetCipher((obj), (ctx)); \ -} while (0) - -/* - * Classes - */ -VALUE cCipher; -VALUE eCipherError; - -static VALUE ossl_cipher_alloc(VALUE klass); - -/* - * PUBLIC - */ -const EVP_CIPHER * -GetCipherPtr(VALUE obj) -{ - EVP_CIPHER_CTX *ctx; - - SafeGetCipher(obj, ctx); - - return EVP_CIPHER_CTX_cipher(ctx); -} - -VALUE -ossl_cipher_new(const EVP_CIPHER *cipher) -{ - VALUE ret; - EVP_CIPHER_CTX *ctx; - - ret = ossl_cipher_alloc(cCipher); - AllocCipher(ret, ctx); - EVP_CIPHER_CTX_init(ctx); - if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); - - return ret; -} - -/* - * PRIVATE - */ -static void -ossl_cipher_free(EVP_CIPHER_CTX *ctx) -{ - if (ctx) { - EVP_CIPHER_CTX_cleanup(ctx); - ruby_xfree(ctx); - } -} - -static VALUE -ossl_cipher_alloc(VALUE klass) -{ - VALUE obj; - - WrapCipher(obj, klass, 0); - - return obj; -} - -/* - * call-seq: - * Cipher.new(string) -> cipher - * - * The string must contain a valid cipher name like "AES-128-CBC" or "3DES". - * - * A list of cipher names is available by calling OpenSSL::Cipher.ciphers. - */ -static VALUE -ossl_cipher_initialize(VALUE self, VALUE str) -{ - EVP_CIPHER_CTX *ctx; - const EVP_CIPHER *cipher; - char *name; - unsigned char key[EVP_MAX_KEY_LENGTH]; - - name = StringValuePtr(str); - GetCipherInit(self, ctx); - if (ctx) { - ossl_raise(rb_eRuntimeError, "Cipher already inititalized!"); - } - AllocCipher(self, ctx); - EVP_CIPHER_CTX_init(ctx); - if (!(cipher = EVP_get_cipherbyname(name))) { - ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%s)", name); - } - /* - * The EVP which has EVP_CIPH_RAND_KEY flag (such as DES3) allows - * uninitialized key, but other EVPs (such as AES) does not allow it. - * Calling EVP_CipherUpdate() without initializing key causes SEGV so we - * set the data filled with "\0" as the key by default. - */ - memset(key, 0, EVP_MAX_KEY_LENGTH); - if (EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); - - return self; -} - -static VALUE -ossl_cipher_copy(VALUE self, VALUE other) -{ - EVP_CIPHER_CTX *ctx1, *ctx2; - - rb_check_frozen(self); - if (self == other) return self; - - GetCipherInit(self, ctx1); - if (!ctx1) { - AllocCipher(self, ctx1); - } - SafeGetCipher(other, ctx2); - if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1) - ossl_raise(eCipherError, NULL); - - return self; -} - -#ifdef HAVE_OBJ_NAME_DO_ALL_SORTED -static void* -add_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary) -{ - rb_ary_push(ary, rb_str_new2(name->name)); - return NULL; -} -#endif - -#ifdef HAVE_OBJ_NAME_DO_ALL_SORTED -/* - * call-seq: - * Cipher.ciphers -> array[string...] - * - * Returns the names of all available ciphers in an array. - */ -static VALUE -ossl_s_ciphers(VALUE self) -{ - VALUE ary; - - ary = rb_ary_new(); - OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, - (void(*)(const OBJ_NAME*,void*))add_cipher_name_to_ary, - (void*)ary); - - return ary; -} -#else -#define ossl_s_ciphers rb_f_notimplement -#endif - -/* - * call-seq: - * cipher.reset -> self - * - * Fully resets the internal state of the Cipher. By using this, the same - * Cipher instance may be used several times for en- or decryption tasks. - * - * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1). - */ -static VALUE -ossl_cipher_reset(VALUE self) -{ - EVP_CIPHER_CTX *ctx; - - GetCipher(self, ctx); - if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); - - return self; -} - -static VALUE -ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) -{ - EVP_CIPHER_CTX *ctx; - unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL; - VALUE pass, init_v; - - if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){ - /* - * oops. this code mistakes salt for IV. - * We deprecated the arguments for this method, but we decided - * keeping this behaviour for backward compatibility. - */ - const char *cname = rb_class2name(rb_obj_class(self)); - rb_warn("arguments for %s#encrypt and %s#decrypt were deprecated; " - "use %s#pkcs5_keyivgen to derive key and IV", - cname, cname, cname); - StringValue(pass); - GetCipher(self, ctx); - if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv)); - else{ - StringValue(init_v); - if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) { - memset(iv, 0, EVP_MAX_IV_LENGTH); - memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v)); - } - else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv)); - } - EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, - (unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL); - p_key = key; - p_iv = iv; - } - else { - GetCipher(self, ctx); - } - if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) { - ossl_raise(eCipherError, NULL); - } - - return self; -} - -/* - * call-seq: - * cipher.encrypt -> self - * - * Initializes the Cipher for encryption. - * - * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the - * following methods: - * * [key=, iv=, random_key, random_iv, pkcs5_keyivgen] - * - * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1). - */ -static VALUE -ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self) -{ - return ossl_cipher_init(argc, argv, self, 1); -} - -/* - * call-seq: - * cipher.decrypt -> self - * - * Initializes the Cipher for decryption. - * - * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the - * following methods: - * * [key=, iv=, random_key, random_iv, pkcs5_keyivgen] - * - * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0). - */ -static VALUE -ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self) -{ - return ossl_cipher_init(argc, argv, self, 0); -} - -/* - * call-seq: - * cipher.pkcs5_keyivgen(pass [, salt [, iterations [, digest]]] ) -> nil - * - * Generates and sets the key/IV based on a password. - * - * WARNING: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40, - * or DES with MD5 or SHA1. Using anything else (like AES) will generate the - * key/iv using an OpenSSL specific method. This method is deprecated and - * should no longer be used. Use a PKCS5 v2 key generation method from - * OpenSSL::PKCS5 instead. - * - * === Parameters - * +salt+ must be an 8 byte string if provided. - * +iterations+ is a integer with a default of 2048. - * +digest+ is a Digest object that defaults to 'MD5' - * - * A minimum of 1000 iterations is recommended. - * - */ -static VALUE -ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self) -{ - EVP_CIPHER_CTX *ctx; - const EVP_MD *digest; - VALUE vpass, vsalt, viter, vdigest; - unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL; - int iter; - - rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest); - StringValue(vpass); - if(!NIL_P(vsalt)){ - StringValue(vsalt); - if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN) - ossl_raise(eCipherError, "salt must be an 8-octet string"); - salt = (unsigned char *)RSTRING_PTR(vsalt); - } - iter = NIL_P(viter) ? 2048 : NUM2INT(viter); - digest = NIL_P(vdigest) ? EVP_md5() : GetDigestPtr(vdigest); - GetCipher(self, ctx); - EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt, - (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv); - if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1) - ossl_raise(eCipherError, NULL); - OPENSSL_cleanse(key, sizeof key); - OPENSSL_cleanse(iv, sizeof iv); - - return Qnil; -} - - -/* - * call-seq: - * cipher.update(data [, buffer]) -> string or buffer - * - * Encrypts data in a streaming fashion. Hand consecutive blocks of data - * to the +update+ method in order to encrypt it. Returns the encrypted - * data chunk. When done, the output of Cipher#final should be additionally - * added to the result. - * - * === Parameters - * +data+ is a nonempty string. - * +buffer+ is an optional string to store the result. - */ -static VALUE -ossl_cipher_update(int argc, VALUE *argv, VALUE self) -{ - EVP_CIPHER_CTX *ctx; - unsigned char *in; - int in_len, out_len; - VALUE data, str; - - rb_scan_args(argc, argv, "11", &data, &str); - - StringValue(data); - in = (unsigned char *)RSTRING_PTR(data); - if ((in_len = RSTRING_LENINT(data)) == 0) - ossl_raise(rb_eArgError, "data must not be empty"); - GetCipher(self, ctx); - out_len = in_len+EVP_CIPHER_CTX_block_size(ctx); - - if (NIL_P(str)) { - str = rb_str_new(0, out_len); - } else { - StringValue(str); - rb_str_resize(str, out_len); - } - - if (!EVP_CipherUpdate(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len)) - ossl_raise(eCipherError, NULL); - assert(out_len < RSTRING_LEN(str)); - rb_str_set_len(str, out_len); - - return str; -} - -/* - * call-seq: - * cipher.final -> string - * - * Returns the remaining data held in the cipher object. Further calls to - * Cipher#update or Cipher#final will return garbage. - * - * See EVP_CipherFinal_ex for further information. - */ -static VALUE -ossl_cipher_final(VALUE self) -{ - EVP_CIPHER_CTX *ctx; - int out_len; - VALUE str; - - GetCipher(self, ctx); - str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx)); - if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len)) - ossl_raise(eCipherError, NULL); - assert(out_len <= RSTRING_LEN(str)); - rb_str_set_len(str, out_len); - - return str; -} - -/* - * call-seq: - * cipher.name -> string - * - * Returns the name of the cipher which may differ slightly from the original - * name provided. - */ -static VALUE -ossl_cipher_name(VALUE self) -{ - EVP_CIPHER_CTX *ctx; - - GetCipher(self, ctx); - - return rb_str_new2(EVP_CIPHER_name(EVP_CIPHER_CTX_cipher(ctx))); -} - -/* - * call-seq: - * cipher.key = string -> string - * - * Sets the cipher key. To generate a key, you should either use a secure - * random byte string or, if the key is to be derived from a password, you - * should rely on PBKDF2 functionality provided by OpenSSL::PKCS5. To - * generate a secure random-based key, Cipher#random_key may be used. - * - * Only call this method after calling Cipher#encrypt or Cipher#decrypt. - */ -static VALUE -ossl_cipher_set_key(VALUE self, VALUE key) -{ - EVP_CIPHER_CTX *ctx; - - StringValue(key); - GetCipher(self, ctx); - - if (RSTRING_LEN(key) < EVP_CIPHER_CTX_key_length(ctx)) - ossl_raise(eCipherError, "key length too short"); - - if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1) - ossl_raise(eCipherError, NULL); - - return key; -} - -/* - * call-seq: - * cipher.iv = string -> string - * - * Sets the cipher IV. Please note that since you should never be using ECB - * mode, an IV is always explicitly required and should be set prior to - * encryption. The IV itself can be safely transmitted in public, but it - * should be unpredictable to prevent certain kinds of attacks. You may use - * Cipher#random_iv to create a secure random IV. - * - * Only call this method after calling Cipher#encrypt or Cipher#decrypt. - * - * If not explicitly set, the OpenSSL default of an all-zeroes ("\\0") IV is - * used. - */ -static VALUE -ossl_cipher_set_iv(VALUE self, VALUE iv) -{ - EVP_CIPHER_CTX *ctx; - - StringValue(iv); - GetCipher(self, ctx); - - if (RSTRING_LEN(iv) < EVP_CIPHER_CTX_iv_length(ctx)) - ossl_raise(eCipherError, "iv length too short"); - - if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, (unsigned char *)RSTRING_PTR(iv), -1) != 1) - ossl_raise(eCipherError, NULL); - - return iv; -} - - -/* - * call-seq: - * cipher.key_len = integer -> integer - * - * Sets the key length of the cipher. If the cipher is a fixed length cipher - * then attempting to set the key length to any value other than the fixed - * value is an error. - * - * Under normal circumstances you do not need to call this method (and probably shouldn't). - * - * See EVP_CIPHER_CTX_set_key_length for further information. - */ -static VALUE -ossl_cipher_set_key_length(VALUE self, VALUE key_length) -{ - int len = NUM2INT(key_length); - EVP_CIPHER_CTX *ctx; - - GetCipher(self, ctx); - if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1) - ossl_raise(eCipherError, NULL); - - return key_length; -} - -#if defined(HAVE_EVP_CIPHER_CTX_SET_PADDING) -/* - * call-seq: - * cipher.padding = integer -> integer - * - * Enables or disables padding. By default encryption operations are padded using standard block padding and the - * padding is checked and removed when decrypting. If the pad parameter is zero then no padding is performed, the - * total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur. - * - * See EVP_CIPHER_CTX_set_padding for further information. - */ -static VALUE -ossl_cipher_set_padding(VALUE self, VALUE padding) -{ - EVP_CIPHER_CTX *ctx; - int pad = NUM2INT(padding); - - GetCipher(self, ctx); - if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1) - ossl_raise(eCipherError, NULL); - return padding; -} -#else -#define ossl_cipher_set_padding rb_f_notimplement -#endif - -#define CIPHER_0ARG_INT(func) \ - static VALUE \ - ossl_cipher_##func(VALUE self) \ - { \ - EVP_CIPHER_CTX *ctx; \ - GetCipher(self, ctx); \ - return INT2NUM(EVP_CIPHER_##func(EVP_CIPHER_CTX_cipher(ctx))); \ - } - -/* - * call-seq: - * cipher.key_len -> integer - * - * Returns the key length in bytes of the Cipher. - */ -CIPHER_0ARG_INT(key_length) -/* - * call-seq: - * cipher.iv_len -> integer - * - * Returns the expected length in bytes for an IV for this Cipher. - */ -CIPHER_0ARG_INT(iv_length) -/* - * call-seq: - * cipher.block_size -> integer - * - * Returns the size in bytes of the blocks on which this Cipher operates on. - */ -CIPHER_0ARG_INT(block_size) - -/* - * INIT - */ -void -Init_ossl_cipher(void) -{ -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ -#endif - - /* Document-class: OpenSSL::Cipher - * - * Provides symmetric algorithms for encryption and decryption. The - * algorithms that are available depend on the particular version - * of OpenSSL that is installed. - * - * === Listing all supported algorithms - * - * A list of supported algorithms can be obtained by - * - * puts OpenSSL::Cipher.ciphers - * - * === Instantiating a Cipher - * - * There are several ways to create a Cipher instance. Generally, a - * Cipher algorithm is categorized by its name, the key length in bits - * and the cipher mode to be used. The most generic way to create a - * Cipher is the following - * - * cipher = OpenSSL::Cipher.new('<name>-<key length>-<mode>') - * - * That is, a string consisting of the hyphenated concatenation of the - * individual components name, key length and mode. Either all uppercase - * or all lowercase strings may be used, for example: - * - * cipher = OpenSSL::Cipher.new('AES-128-CBC') - * - * For each algorithm supported, there is a class defined under the - * Cipher class that goes by the name of the cipher, e.g. to obtain an - * instance of AES, you could also use - * - * # these are equivalent - * cipher = OpenSSL::Cipher::AES.new(128, :CBC) - * cipher = OpenSSL::Cipher::AES.new(128, 'CBC') - * cipher = OpenSSL::Cipher::AES.new('128-CBC') - * - * Finally, due to its wide-spread use, there are also extra classes - * defined for the different key sizes of AES - * - * cipher = OpenSSL::Cipher::AES128.new(:CBC) - * cipher = OpenSSL::Cipher::AES192.new(:CBC) - * cipher = OpenSSL::Cipher::AES256.new(:CBC) - * - * === Choosing either encryption or decryption mode - * - * Encryption and decryption are often very similar operations for - * symmetric algorithms, this is reflected by not having to choose - * different classes for either operation, both can be done using the - * same class. Still, after obtaining a Cipher instance, we need to - * tell the instance what it is that we intend to do with it, so we - * need to call either - * - * cipher.encrypt - * - * or - * - * cipher.decrypt - * - * on the Cipher instance. This should be the first call after creating - * the instance, otherwise configuration that has already been set could - * get lost in the process. - * - * === Choosing a key - * - * Symmetric encryption requires a key that is the same for the encrypting - * and for the decrypting party and after initial key establishment should - * be kept as private information. There are a lot of ways to create - * insecure keys, the most notable is to simply take a password as the key - * without processing the password further. A simple and secure way to - * create a key for a particular Cipher is - * - * cipher = OpenSSL::AES256.new(:CFB) - * cipher.encrypt - * key = cipher.random_key # also sets the generated key on the Cipher - * - * If you absolutely need to use passwords as encryption keys, you - * should use Password-Based Key Derivation Function 2 (PBKDF2) by - * generating the key with the help of the functionality provided by - * OpenSSL::PKCS5.pbkdf2_hmac_sha1 or OpenSSL::PKCS5.pbkdf2_hmac. - * - * Although there is Cipher#pkcs5_keyivgen, its use is deprecated and - * it should only be used in legacy applications because it does not use - * the newer PKCS#5 v2 algorithms. - * - * === Choosing an IV - * - * The cipher modes CBC, CFB, OFB and CTR all need an "initialization - * vector", or short, IV. ECB mode is the only mode that does not require - * an IV, but there is almost no legitimate use case for this mode - * because of the fact that it does not sufficiently hide plaintext - * patterns. Therefore - * - * <b>You should never use ECB mode unless you are absolutely sure that - * you absolutely need it</b> - * - * Because of this, you will end up with a mode that explicitly requires - * an IV in any case. Note that for backwards compatibility reasons, - * setting an IV is not explicitly mandated by the Cipher API. If not - * set, OpenSSL itself defaults to an all-zeroes IV ("\\0", not the - * character). Although the IV can be seen as public information, i.e. - * it may be transmitted in public once generated, it should still stay - * unpredictable to prevent certain kinds of attacks. Therefore, ideally - * - * <b>Always create a secure random IV for every encryption of your - * Cipher</b> - * - * A new, random IV should be created for every encryption of data. Think - * of the IV as a nonce (number used once) - it's public but random and - * unpredictable. A secure random IV can be created as follows - * - * cipher = ... - * cipher.encrypt - * key = cipher.random_key - * iv = cipher.random_iv # also sets the generated IV on the Cipher - * - * Although the key is generally a random value, too, it is a bad choice - * as an IV. There are elaborate ways how an attacker can take advantage - * of such an IV. As a general rule of thumb, exposing the key directly - * or indirectly should be avoided at all cost and exceptions only be - * made with good reason. - * - * === Calling Cipher#final - * - * ECB (which should not be used) and CBC are both block-based modes. - * This means that unlike for the other streaming-based modes, they - * operate on fixed-size blocks of data, and therefore they require a - * "finalization" step to produce or correctly decrypt the last block of - * data by appropriately handling some form of padding. Therefore it is - * essential to add the output of OpenSSL::Cipher#final to your - * encryption/decryption buffer or you will end up with decryption errors - * or truncated data. - * - * Although this is not really necessary for streaming-mode ciphers, it is - * still recommended to apply the same pattern of adding the output of - * Cipher#final there as well - it also enables you to switch between - * modes more easily in the future. - * - * === Encrypting and decrypting some data - * - * data = "Very, very confidential data" - * - * cipher = OpenSSL::Cipher::AES.new(128, :CBC) - * cipher.encrypt - * key = cipher.random_key - * iv = cipher.random_iv - * - * encrypted = cipher.update(data) + cipher.final - * ... - * decipher = OpenSSL::Cipher::AES.new(128, :CBC) - * decipher.decrypt - * decipher.key = key - * decipher.iv = iv - * - * plain = decipher.update(encrypted) + decipher.final - * - * puts data == plain #=> true - * - */ - cCipher = rb_define_class_under(mOSSL, "Cipher", rb_cObject); - eCipherError = rb_define_class_under(cCipher, "CipherError", eOSSLError); - - rb_define_alloc_func(cCipher, ossl_cipher_alloc); - rb_define_copy_func(cCipher, ossl_cipher_copy); - rb_define_module_function(cCipher, "ciphers", ossl_s_ciphers, 0); - rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1); - rb_define_method(cCipher, "reset", ossl_cipher_reset, 0); - rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1); - rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1); - rb_define_method(cCipher, "pkcs5_keyivgen", ossl_cipher_pkcs5_keyivgen, -1); - rb_define_method(cCipher, "update", ossl_cipher_update, -1); - rb_define_method(cCipher, "final", ossl_cipher_final, 0); - rb_define_method(cCipher, "name", ossl_cipher_name, 0); - rb_define_method(cCipher, "key=", ossl_cipher_set_key, 1); - rb_define_method(cCipher, "key_len=", ossl_cipher_set_key_length, 1); - rb_define_method(cCipher, "key_len", ossl_cipher_key_length, 0); - rb_define_method(cCipher, "iv=", ossl_cipher_set_iv, 1); - rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0); - rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0); - rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1); -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_cipher.h b/ruby_1_9_3/ext/openssl/ossl_cipher.h deleted file mode 100644 index bed4fa853b..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_cipher.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced 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_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_config.c b/ruby_1_9_3/ext/openssl/ossl_config.c deleted file mode 100644 index e700833076..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_config.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - - -/* - * Classes - */ -VALUE cConfig; -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; -} - - -/* - * INIT - */ -void -Init_ossl_config() -{ - 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 */ -} diff --git a/ruby_1_9_3/ext/openssl/ossl_config.h b/ruby_1_9_3/ext/openssl/ossl_config.h deleted file mode 100644 index cb226b27e5..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_config.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced 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_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_digest.c b/ruby_1_9_3/ext/openssl/ossl_digest.c deleted file mode 100644 index fdf13e98e5..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_digest.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define GetDigest(obj, ctx) do { \ - Data_Get_Struct((obj), EVP_MD_CTX, (ctx)); \ - if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \ - } \ -} while (0) -#define SafeGetDigest(obj, ctx) do { \ - OSSL_Check_Kind((obj), cDigest); \ - GetDigest((obj), (ctx)); \ -} while (0) - -/* - * Classes - */ -VALUE cDigest; -VALUE eDigestError; - -static VALUE ossl_digest_alloc(VALUE klass); - -/* - * Public - */ -const EVP_MD * -GetDigestPtr(VALUE obj) -{ - const EVP_MD *md; - ASN1_OBJECT *oid = NULL; - - if (TYPE(obj) == T_STRING) { - const char *name = StringValueCStr(obj); - - md = EVP_get_digestbyname(name); - if (!md) { - oid = OBJ_txt2obj(name, 0); - md = EVP_get_digestbyobj(oid); - ASN1_OBJECT_free(oid); - } - if(!md) - ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%s).", name); - } else { - EVP_MD_CTX *ctx; - - SafeGetDigest(obj, ctx); - - md = EVP_MD_CTX_md(ctx); - } - - return md; -} - -VALUE -ossl_digest_new(const EVP_MD *md) -{ - VALUE ret; - EVP_MD_CTX *ctx; - - ret = ossl_digest_alloc(cDigest); - GetDigest(ret, ctx); - if (EVP_DigestInit_ex(ctx, md, NULL) != 1) { - ossl_raise(eDigestError, "Digest initialization failed."); - } - - return ret; -} - -/* - * Private - */ -static VALUE -ossl_digest_alloc(VALUE klass) -{ - EVP_MD_CTX *ctx; - VALUE obj; - - ctx = EVP_MD_CTX_create(); - if (ctx == NULL) - ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_create() failed"); - obj = Data_Wrap_Struct(klass, 0, EVP_MD_CTX_destroy, ctx); - - return obj; -} - -VALUE ossl_digest_update(VALUE, VALUE); - -/* - * call-seq: - * Digest.new(string [, data]) -> Digest - * - * Creates a Digest instance based on +string+, which is either the ln - * (long name) or sn (short name) of a supported digest algorithm. - * If +data+ (a +String+) is given, it is used as the initial input to the - * Digest instance, i.e. - * digest = OpenSSL::Digest.new('sha256', 'digestdata') - * is equal to - * digest = OpenSSL::Digest.new('sha256') - * digest.update('digestdata') - * - * === Example - * digest = OpenSSL::Digest.new('sha1') - * - * - */ -static VALUE -ossl_digest_initialize(int argc, VALUE *argv, VALUE self) -{ - EVP_MD_CTX *ctx; - const EVP_MD *md; - VALUE type, data; - - rb_scan_args(argc, argv, "11", &type, &data); - md = GetDigestPtr(type); - if (!NIL_P(data)) StringValue(data); - - GetDigest(self, ctx); - if (EVP_DigestInit_ex(ctx, md, NULL) != 1) { - ossl_raise(eDigestError, "Digest initialization failed."); - } - - if (!NIL_P(data)) return ossl_digest_update(self, data); - return self; -} - -static VALUE -ossl_digest_copy(VALUE self, VALUE other) -{ - EVP_MD_CTX *ctx1, *ctx2; - - rb_check_frozen(self); - if (self == other) return self; - - GetDigest(self, ctx1); - SafeGetDigest(other, ctx2); - - if (!EVP_MD_CTX_copy(ctx1, ctx2)) { - ossl_raise(eDigestError, NULL); - } - return self; -} - -/* - * call-seq: - * digest.reset -> self - * - * Resets the Digest in the sense that any Digest#update that has been - * performed is abandoned and the Digest is set to its initial state again. - * - */ -static VALUE -ossl_digest_reset(VALUE self) -{ - EVP_MD_CTX *ctx; - - GetDigest(self, ctx); - if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) { - ossl_raise(eDigestError, "Digest initialization failed."); - } - - return self; -} - -/* - * call-seq: - * digest.update(string) -> aString - * - * Not every message digest can be computed in one single pass. If a message - * digest is to be computed from several subsequent sources, then each may - * be passed individually to the Digest instance. - * - * === Example - * digest = OpenSSL::Digest::SHA256.new - * digest.update('First input') - * digest << 'Second input' # equivalent to digest.update('Second input') - * result = digest.digest - * - */ -VALUE -ossl_digest_update(VALUE self, VALUE data) -{ - EVP_MD_CTX *ctx; - - StringValue(data); - GetDigest(self, ctx); - EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)); - - return self; -} - -/* - * call-seq: - * digest.finish -> aString - * - */ -static VALUE -ossl_digest_finish(int argc, VALUE *argv, VALUE self) -{ - EVP_MD_CTX *ctx; - VALUE str; - - rb_scan_args(argc, argv, "01", &str); - - GetDigest(self, ctx); - - if (NIL_P(str)) { - str = rb_str_new(NULL, EVP_MD_CTX_size(ctx)); - } else { - StringValue(str); - rb_str_resize(str, EVP_MD_CTX_size(ctx)); - } - - EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL); - - return str; -} - -/* - * call-seq: - * digest.name -> string - * - * Returns the sn of this Digest instance. - * - * === Example - * digest = OpenSSL::Digest::SHA512.new - * puts digest.name # => SHA512 - * - */ -static VALUE -ossl_digest_name(VALUE self) -{ - EVP_MD_CTX *ctx; - - GetDigest(self, ctx); - - return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx))); -} - -/* - * call-seq: - * digest.digest_length -> integer - * - * Returns the output size of the digest, i.e. the length in bytes of the - * final message digest result. - * - * === Example - * digest = OpenSSL::Digest::SHA1.new - * puts digest.digest_length # => 20 - * - */ -static VALUE -ossl_digest_size(VALUE self) -{ - EVP_MD_CTX *ctx; - - GetDigest(self, ctx); - - return INT2NUM(EVP_MD_CTX_size(ctx)); -} - -/* - * call-seq: - * digest.block_length -> integer - * - * Returns the block length of the digest algorithm, i.e. the length in bytes - * of an individual block. Most modern algorithms partition a message to be - * digested into a sequence of fix-sized blocks that are processed - * consecutively. - * - * === Example - * digest = OpenSSL::Digest::SHA1.new - * puts digest.block_length # => 64 - */ -static VALUE -ossl_digest_block_length(VALUE self) -{ - EVP_MD_CTX *ctx; - - GetDigest(self, ctx); - - return INT2NUM(EVP_MD_CTX_block_size(ctx)); -} - -/* - * INIT - */ -void -Init_ossl_digest() -{ - rb_require("digest"); - -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ -#endif - - /* Document-class: OpenSSL::Digest - * - * OpenSSL::Digest allows you to compute message digests (sometimes - * interchangeably called "hashes") of arbitrary data that are - * cryptographically secure, i.e. a Digest implements a secure one-way - * function. - * - * One-way functions offer some useful properties. E.g. given two - * distinct inputs the probability that both yield the same output - * is highly unlikely. Combined with the fact that every message digest - * algorithm has a fixed-length output of just a few bytes, digests are - * often used to create unique identifiers for arbitrary data. A common - * example is the creation of a unique id for binary documents that are - * stored in a database. - * - * Another useful characteristic of one-way functions (and thus the name) - * is that given a digest there is no indication about the original - * data that produced it, i.e. the only way to identify the original input - * is to "brute-force" through every possible combination of inputs. - * - * These characteristics make one-way functions also ideal companions - * for public key signature algorithms: instead of signing an entire - * document, first a hash of the document is produced with a considerably - * faster message digest algorithm and only the few bytes of its output - * need to be signed using the slower public key algorithm. To validate - * the integrity of a signed document, it suffices to re-compute the hash - * and verify that it is equal to that in the signature. - * - * Among the supported message digest algorithms are: - * * SHA, SHA1, SHA224, SHA256, SHA384 and SHA512 - * * MD2, MD4, MDC2 and MD5 - * * RIPEMD160 - * * DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is - * equal to SHA and DSS1 is equal to SHA1) - * - * For each of these algorithms, there is a sub-class of Digest that - * can be instantiated as simply as e.g. - * - * digest = OpenSSL::Digest::SHA1.new - * - * === Mapping between Digest class and sn/ln - * - * The sn (short names) and ln (long names) are defined in - * <openssl/object.h> and <openssl/obj_mac.h>. They are textual - * representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest - * algorithm has an OBJECT IDENTIFIER associated to it and those again - * have short/long names assigned to them. - * E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its - * sn is "SHA1" and its ln is "sha1". - * ==== MD2 - * * sn: MD2 - * * ln: md2 - * ==== MD4 - * * sn: MD4 - * * ln: md4 - * ==== MD5 - * * sn: MD5 - * * ln: md5 - * ==== SHA - * * sn: SHA - * * ln: SHA - * ==== SHA-1 - * * sn: SHA1 - * * ln: sha1 - * ==== SHA-224 - * * sn: SHA224 - * * ln: sha224 - * ==== SHA-256 - * * sn: SHA256 - * * ln: sha256 - * ==== SHA-384 - * * sn: SHA384 - * * ln: sha384 - * ==== SHA-512 - * * sn: SHA512 - * * ln: sha512 - * - * "Breaking" a message digest algorithm means defying its one-way - * function characteristics, i.e. producing a collision or finding a way - * to get to the original data by means that are more efficient than - * brute-forcing etc. Most of the supported digest algorithms can be - * considered broken in this sense, even the very popular MD5 and SHA1 - * algorithms. Should security be your highest concern, then you should - * probably rely on SHA224, SHA256, SHA384 or SHA512. - * - * === Hashing a file - * - * data = File.read('document') - * sha256 = OpenSSL::Digest::SHA256.new - * digest = sha256.digest(data) - * - * === Hashing several pieces of data at once - * - * data1 = File.read('file1') - * data2 = File.read('file2') - * data3 = File.read('file3') - * sha256 = OpenSSL::Digest::SHA256.new - * sha256 << data1 - * sha256 << data2 - * sha256 << data3 - * digest = sha256.digest - * - * === Reuse a Digest instance - * - * data1 = File.read('file1') - * sha256 = OpenSSL::Digest::SHA256.new - * digest1 = sha256.digest(data1) - * - * data2 = File.read('file2') - * sha256.reset - * digest2 = sha256.digest(data2) - * - */ - cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class")); - /* Document-class: OpenSSL::Digest::DigestError - * - * Generic Exception class that is raised if an error occurs during a - * Digest operation. - */ - eDigestError = rb_define_class_under(cDigest, "DigestError", eOSSLError); - - rb_define_alloc_func(cDigest, ossl_digest_alloc); - - rb_define_method(cDigest, "initialize", ossl_digest_initialize, -1); - rb_define_copy_func(cDigest, ossl_digest_copy); - rb_define_method(cDigest, "reset", ossl_digest_reset, 0); - rb_define_method(cDigest, "update", ossl_digest_update, 1); - rb_define_alias(cDigest, "<<", "update"); - rb_define_private_method(cDigest, "finish", ossl_digest_finish, -1); - rb_define_method(cDigest, "digest_length", ossl_digest_size, 0); - rb_define_method(cDigest, "block_length", ossl_digest_block_length, 0); - - rb_define_method(cDigest, "name", ossl_digest_name, 0); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_digest.h b/ruby_1_9_3/ext/openssl/ossl_digest.h deleted file mode 100644 index 8cc5b1bc56..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_digest.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced 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_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_engine.c b/ruby_1_9_3/ext/openssl/ossl_engine.c deleted file mode 100644 index a7d1e315fd..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_engine.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#if defined(OSSL_ENGINE_ENABLED) - -#define WrapEngine(klass, obj, engine) do { \ - if (!(engine)) { \ - ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, ENGINE_free, (engine)); \ -} while(0) -#define GetEngine(obj, engine) do { \ - Data_Get_Struct((obj), ENGINE, (engine)); \ - if (!(engine)) { \ - ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \ - } \ -} while (0) -#define SafeGetEngine(obj, engine) do { \ - OSSL_Check_Kind((obj), cEngine); \ - GetPKCS7((obj), (engine)); \ -} while (0) - -/* - * Classes - */ -VALUE cEngine; -VALUE eEngineError; - -/* - * Private - */ -#define OSSL_ENGINE_LOAD_IF_MATCH(x) \ -do{\ - if(!strcmp(#x, RSTRING_PTR(name))){\ - ENGINE_load_##x();\ - return Qtrue;\ - }\ -}while(0) - -static VALUE -ossl_engine_s_load(int argc, VALUE *argv, VALUE klass) -{ -#if !defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES) - return Qnil; -#else - VALUE name; - - rb_scan_args(argc, argv, "01", &name); - if(NIL_P(name)){ - ENGINE_load_builtin_engines(); - return Qtrue; - } - StringValue(name); -#ifndef OPENSSL_NO_STATIC_ENGINE -#if HAVE_ENGINE_LOAD_DYNAMIC - OSSL_ENGINE_LOAD_IF_MATCH(dynamic); -#endif -#if HAVE_ENGINE_LOAD_CSWIFT - OSSL_ENGINE_LOAD_IF_MATCH(cswift); -#endif -#if HAVE_ENGINE_LOAD_CHIL - OSSL_ENGINE_LOAD_IF_MATCH(chil); -#endif -#if HAVE_ENGINE_LOAD_ATALLA - OSSL_ENGINE_LOAD_IF_MATCH(atalla); -#endif -#if HAVE_ENGINE_LOAD_NURON - OSSL_ENGINE_LOAD_IF_MATCH(nuron); -#endif -#if HAVE_ENGINE_LOAD_UBSEC - OSSL_ENGINE_LOAD_IF_MATCH(ubsec); -#endif -#if HAVE_ENGINE_LOAD_AEP - OSSL_ENGINE_LOAD_IF_MATCH(aep); -#endif -#if HAVE_ENGINE_LOAD_SUREWARE - OSSL_ENGINE_LOAD_IF_MATCH(sureware); -#endif -#if HAVE_ENGINE_LOAD_4758CCA - OSSL_ENGINE_LOAD_IF_MATCH(4758cca); -#endif -#endif -#ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO - OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto); -#endif - OSSL_ENGINE_LOAD_IF_MATCH(openssl); - rb_warning("no such builtin loader for `%s'", RSTRING_PTR(name)); - return Qnil; -#endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */ -} - -static VALUE -ossl_engine_s_cleanup(VALUE self) -{ -#if defined(HAVE_ENGINE_CLEANUP) - ENGINE_cleanup(); -#endif - return Qnil; -} - -static VALUE -ossl_engine_s_engines(VALUE klass) -{ - ENGINE *e; - VALUE ary, obj; - - ary = rb_ary_new(); - for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)){ - /* Need a ref count of two here because of ENGINE_free being - * called internally by OpenSSL when moving to the next ENGINE - * and by us when releasing the ENGINE reference */ - ENGINE_up_ref(e); - WrapEngine(klass, obj, e); - rb_ary_push(ary, obj); - } - - return ary; -} - -static VALUE -ossl_engine_s_by_id(VALUE klass, VALUE id) -{ - ENGINE *e; - VALUE obj; - - StringValue(id); - ossl_engine_s_load(1, &id, klass); - if(!(e = ENGINE_by_id(RSTRING_PTR(id)))) - ossl_raise(eEngineError, NULL); - WrapEngine(klass, obj, e); - if(rb_block_given_p()) rb_yield(obj); - if(!ENGINE_init(e)) - ossl_raise(eEngineError, NULL); - ENGINE_ctrl(e, ENGINE_CTRL_SET_PASSWORD_CALLBACK, - 0, NULL, (void(*)(void))ossl_pem_passwd_cb); - ERR_clear_error(); - - return obj; -} - -static VALUE -ossl_engine_s_alloc(VALUE klass) -{ - ENGINE *e; - VALUE obj; - - if (!(e = ENGINE_new())) { - ossl_raise(eEngineError, NULL); - } - WrapEngine(klass, obj, e); - - return obj; -} - -static VALUE -ossl_engine_get_id(VALUE self) -{ - ENGINE *e; - GetEngine(self, e); - return rb_str_new2(ENGINE_get_id(e)); -} - -static VALUE -ossl_engine_get_name(VALUE self) -{ - ENGINE *e; - GetEngine(self, e); - return rb_str_new2(ENGINE_get_name(e)); -} - -static VALUE -ossl_engine_finish(VALUE self) -{ - ENGINE *e; - - GetEngine(self, e); - if(!ENGINE_finish(e)) ossl_raise(eEngineError, NULL); - - return Qnil; -} - -#if defined(HAVE_ENGINE_GET_CIPHER) -static VALUE -ossl_engine_get_cipher(VALUE self, VALUE name) -{ - ENGINE *e; - const EVP_CIPHER *ciph, *tmp; - char *s; - int nid; - - s = StringValuePtr(name); - tmp = EVP_get_cipherbyname(s); - if(!tmp) ossl_raise(eEngineError, "no such cipher `%s'", s); - nid = EVP_CIPHER_nid(tmp); - GetEngine(self, e); - ciph = ENGINE_get_cipher(e, nid); - if(!ciph) ossl_raise(eEngineError, NULL); - - return ossl_cipher_new(ciph); -} -#else -#define ossl_engine_get_cipher rb_f_notimplement -#endif - -#if defined(HAVE_ENGINE_GET_DIGEST) -static VALUE -ossl_engine_get_digest(VALUE self, VALUE name) -{ - ENGINE *e; - const EVP_MD *md, *tmp; - char *s; - int nid; - - s = StringValuePtr(name); - tmp = EVP_get_digestbyname(s); - if(!tmp) ossl_raise(eEngineError, "no such digest `%s'", s); - nid = EVP_MD_nid(tmp); - GetEngine(self, e); - md = ENGINE_get_digest(e, nid); - if(!md) ossl_raise(eEngineError, NULL); - - return ossl_digest_new(md); -} -#else -#define ossl_engine_get_digest rb_f_notimplement -#endif - -static VALUE -ossl_engine_load_privkey(int argc, VALUE *argv, VALUE self) -{ - ENGINE *e; - EVP_PKEY *pkey; - VALUE id, data, obj; - char *sid, *sdata; - - rb_scan_args(argc, argv, "02", &id, &data); - sid = NIL_P(id) ? NULL : StringValuePtr(id); - sdata = NIL_P(data) ? NULL : StringValuePtr(data); - GetEngine(self, e); -#if OPENSSL_VERSION_NUMBER < 0x00907000L - pkey = ENGINE_load_private_key(e, sid, sdata); -#else - pkey = ENGINE_load_private_key(e, sid, NULL, sdata); -#endif - if (!pkey) ossl_raise(eEngineError, NULL); - obj = ossl_pkey_new(pkey); - OSSL_PKEY_SET_PRIVATE(obj); - - return obj; -} - -static VALUE -ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self) -{ - ENGINE *e; - EVP_PKEY *pkey; - VALUE id, data; - char *sid, *sdata; - - rb_scan_args(argc, argv, "02", &id, &data); - sid = NIL_P(id) ? NULL : StringValuePtr(id); - sdata = NIL_P(data) ? NULL : StringValuePtr(data); - GetEngine(self, e); -#if OPENSSL_VERSION_NUMBER < 0x00907000L - pkey = ENGINE_load_public_key(e, sid, sdata); -#else - pkey = ENGINE_load_public_key(e, sid, NULL, sdata); -#endif - if (!pkey) ossl_raise(eEngineError, NULL); - - return ossl_pkey_new(pkey); -} - -static VALUE -ossl_engine_set_default(VALUE self, VALUE flag) -{ - ENGINE *e; - int f = NUM2INT(flag); - - GetEngine(self, e); - ENGINE_set_default(e, f); - - return Qtrue; -} - -static VALUE -ossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self) -{ - ENGINE *e; - VALUE cmd, val; - int ret; - - GetEngine(self, e); - rb_scan_args(argc, argv, "11", &cmd, &val); - StringValue(cmd); - if (!NIL_P(val)) StringValue(val); - ret = ENGINE_ctrl_cmd_string(e, RSTRING_PTR(cmd), - NIL_P(val) ? NULL : RSTRING_PTR(val), 0); - if (!ret) ossl_raise(eEngineError, NULL); - - return self; -} - -static VALUE -ossl_engine_cmd_flag_to_name(int flag) -{ - switch(flag){ - case ENGINE_CMD_FLAG_NUMERIC: return rb_str_new2("NUMERIC"); - case ENGINE_CMD_FLAG_STRING: return rb_str_new2("STRING"); - case ENGINE_CMD_FLAG_NO_INPUT: return rb_str_new2("NO_INPUT"); - case ENGINE_CMD_FLAG_INTERNAL: return rb_str_new2("INTERNAL"); - default: return rb_str_new2("UNKNOWN"); - } -} - -static VALUE -ossl_engine_get_cmds(VALUE self) -{ - ENGINE *e; - const ENGINE_CMD_DEFN *defn, *p; - VALUE ary, tmp; - - GetEngine(self, e); - ary = rb_ary_new(); - if ((defn = ENGINE_get_cmd_defns(e)) != NULL){ - for (p = defn; p->cmd_num > 0; p++){ - tmp = rb_ary_new(); - rb_ary_push(tmp, rb_str_new2(p->cmd_name)); - rb_ary_push(tmp, rb_str_new2(p->cmd_desc)); - rb_ary_push(tmp, ossl_engine_cmd_flag_to_name(p->cmd_flags)); - rb_ary_push(ary, tmp); - } - } - - return ary; -} - -static VALUE -ossl_engine_inspect(VALUE self) -{ - VALUE str; - const char *cname = rb_class2name(rb_obj_class(self)); - - str = rb_str_new2("#<"); - rb_str_cat2(str, cname); - rb_str_cat2(str, " id=\""); - rb_str_append(str, ossl_engine_get_id(self)); - rb_str_cat2(str, "\" name=\""); - rb_str_append(str, ossl_engine_get_name(self)); - rb_str_cat2(str, "\">"); - - return str; -} - -#define DefEngineConst(x) rb_define_const(cEngine, #x, INT2NUM(ENGINE_##x)) - -void -Init_ossl_engine() -{ - cEngine = rb_define_class_under(mOSSL, "Engine", rb_cObject); - eEngineError = rb_define_class_under(cEngine, "EngineError", eOSSLError); - - rb_define_alloc_func(cEngine, ossl_engine_s_alloc); - rb_define_singleton_method(cEngine, "load", ossl_engine_s_load, -1); - rb_define_singleton_method(cEngine, "cleanup", ossl_engine_s_cleanup, 0); - rb_define_singleton_method(cEngine, "engines", ossl_engine_s_engines, 0); - rb_define_singleton_method(cEngine, "by_id", ossl_engine_s_by_id, 1); - rb_undef_method(CLASS_OF(cEngine), "new"); - - rb_define_method(cEngine, "id", ossl_engine_get_id, 0); - rb_define_method(cEngine, "name", ossl_engine_get_name, 0); - rb_define_method(cEngine, "finish", ossl_engine_finish, 0); - rb_define_method(cEngine, "cipher", ossl_engine_get_cipher, 1); - rb_define_method(cEngine, "digest", ossl_engine_get_digest, 1); - rb_define_method(cEngine, "load_private_key", ossl_engine_load_privkey, -1); - rb_define_method(cEngine, "load_public_key", ossl_engine_load_pubkey, -1); - rb_define_method(cEngine, "set_default", ossl_engine_set_default, 1); - rb_define_method(cEngine, "ctrl_cmd", ossl_engine_ctrl_cmd, -1); - rb_define_method(cEngine, "cmds", ossl_engine_get_cmds, 0); - rb_define_method(cEngine, "inspect", ossl_engine_inspect, 0); - - DefEngineConst(METHOD_RSA); - DefEngineConst(METHOD_DSA); - DefEngineConst(METHOD_DH); - DefEngineConst(METHOD_RAND); -#ifdef ENGINE_METHOD_BN_MOD_EXP - DefEngineConst(METHOD_BN_MOD_EXP); -#endif -#ifdef ENGINE_METHOD_BN_MOD_EXP_CRT - DefEngineConst(METHOD_BN_MOD_EXP_CRT); -#endif -#ifdef ENGINE_METHOD_CIPHERS - DefEngineConst(METHOD_CIPHERS); -#endif -#ifdef ENGINE_METHOD_DIGESTS - DefEngineConst(METHOD_DIGESTS); -#endif - DefEngineConst(METHOD_ALL); - DefEngineConst(METHOD_NONE); -} -#else -void -Init_ossl_engine() -{ -} -#endif diff --git a/ruby_1_9_3/ext/openssl/ossl_engine.h b/ruby_1_9_3/ext/openssl/ossl_engine.h deleted file mode 100644 index ea2f256912..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_engine.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * $Id$ - * '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 licenced 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 */ diff --git a/ruby_1_9_3/ext/openssl/ossl_hmac.c b/ruby_1_9_3/ext/openssl/ossl_hmac.c deleted file mode 100644 index 5220c9e73d..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_hmac.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(OPENSSL_NO_HMAC) - -#include "ossl.h" - -#define MakeHMAC(obj, klass, ctx) \ - (obj) = Data_Make_Struct((klass), HMAC_CTX, 0, ossl_hmac_free, (ctx)) -#define GetHMAC(obj, ctx) do { \ - Data_Get_Struct((obj), HMAC_CTX, (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(HMAC_CTX *ctx) -{ - HMAC_CTX_cleanup(ctx); - ruby_xfree(ctx); -} - -static VALUE -ossl_hmac_alloc(VALUE klass) -{ - HMAC_CTX *ctx; - VALUE obj; - - MakeHMAC(obj, klass, ctx); - HMAC_CTX_init(ctx); - - return obj; -} - - -/* - * call-seq: - * HMAC.new(key, digest) -> hmac - * - */ -static VALUE -ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) -{ - HMAC_CTX *ctx; - - StringValue(key); - GetHMAC(self, ctx); - HMAC_Init(ctx, RSTRING_PTR(key), RSTRING_LENINT(key), - GetDigestPtr(digest)); - - 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); - - HMAC_CTX_copy(ctx1, ctx2); - return self; -} - -/* - * call-seq: - * hmac.update(string) -> self - * - */ -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; - - HMAC_CTX_copy(&final, ctx); - if (!(*buf = OPENSSL_malloc(HMAC_size(&final)))) { - HMAC_CTX_cleanup(&final); - OSSL_Debug("Allocating %d mem", HMAC_size(&final)); - ossl_raise(eHMACError, "Cannot allocate memory for hmac"); - } - HMAC_Final(&final, *buf, buf_len); - HMAC_CTX_cleanup(&final); -} - -/* - * call-seq: - * hmac.digest -> aString - * - */ -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 -> aString - * - */ -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 - * - */ -static VALUE -ossl_hmac_reset(VALUE self) -{ - HMAC_CTX *ctx; - - GetHMAC(self, ctx); - HMAC_Init(ctx, NULL, 0, NULL); - - return self; -} - -/* - * call-seq: - * HMAC.digest(digest, key, data) -> aString - * - */ -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.digest(digest, key, data) -> aString - * - */ -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() -{ -#if 0 - 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() -{ - rb_warning("HMAC will NOT be avaible: OpenSSL is compiled without HMAC."); -} -#endif /* NO_HMAC */ diff --git a/ruby_1_9_3/ext/openssl/ossl_hmac.h b/ruby_1_9_3/ext/openssl/ossl_hmac.h deleted file mode 100644 index 1a2978b39a..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_hmac.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced 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_ */ diff --git a/ruby_1_9_3/ext/openssl/ossl_ns_spki.c b/ruby_1_9_3/ext/openssl/ossl_ns_spki.c deleted file mode 100644 index bf828cbb83..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_ns_spki.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapSPKI(klass, obj, spki) do { \ - if (!(spki)) { \ - ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, NETSCAPE_SPKI_free, (spki)); \ -} while (0) -#define GetSPKI(obj, spki) do { \ - Data_Get_Struct((obj), NETSCAPE_SPKI, (spki)); \ - if (!(spki)) { \ - ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ - } \ -} while (0) - -/* - * Classes - */ -VALUE mNetscape; -VALUE cSPKI; -VALUE eSPKIError; - -/* - * Public functions - */ - -/* - * Private functions - */ -static VALUE -ossl_spki_alloc(VALUE klass) -{ - NETSCAPE_SPKI *spki; - VALUE obj; - - if (!(spki = NETSCAPE_SPKI_new())) { - ossl_raise(eSPKIError, NULL); - } - WrapSPKI(klass, obj, spki); - - return obj; -} - -static VALUE -ossl_spki_initialize(int argc, VALUE *argv, VALUE self) -{ - NETSCAPE_SPKI *spki; - VALUE buffer; - const unsigned char *p; - - if (rb_scan_args(argc, argv, "01", &buffer) == 0) { - return self; - } - StringValue(buffer); - if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), -1))) { - p = (unsigned char *)RSTRING_PTR(buffer); - if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) { - ossl_raise(eSPKIError, NULL); - } - } - NETSCAPE_SPKI_free(DATA_PTR(self)); - DATA_PTR(self) = spki; - ERR_clear_error(); - - return self; -} - -static VALUE -ossl_spki_to_der(VALUE self) -{ - NETSCAPE_SPKI *spki; - VALUE str; - long len; - unsigned char *p; - - GetSPKI(self, spki); - if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0) - ossl_raise(eX509CertError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if (i2d_NETSCAPE_SPKI(spki, &p) <= 0) - ossl_raise(eX509CertError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -static VALUE -ossl_spki_to_pem(VALUE self) -{ - NETSCAPE_SPKI *spki; - char *data; - VALUE str; - - GetSPKI(self, spki); - if (!(data = NETSCAPE_SPKI_b64_encode(spki))) { - ossl_raise(eSPKIError, NULL); - } - str = ossl_buf2str(data, rb_long2int(strlen(data))); - - return str; -} - -static VALUE -ossl_spki_print(VALUE self) -{ - NETSCAPE_SPKI *spki; - BIO *out; - BUF_MEM *buf; - VALUE str; - - GetSPKI(self, spki); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eSPKIError, NULL); - } - if (!NETSCAPE_SPKI_print(out, spki)) { - BIO_free(out); - ossl_raise(eSPKIError, NULL); - } - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - - return str; -} - -static VALUE -ossl_spki_get_public_key(VALUE self) -{ - NETSCAPE_SPKI *spki; - EVP_PKEY *pkey; - - GetSPKI(self, spki); - if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */ - ossl_raise(eSPKIError, NULL); - } - - return ossl_pkey_new(pkey); /* NO DUP - OK */ -} - -static VALUE -ossl_spki_set_public_key(VALUE self, VALUE key) -{ - NETSCAPE_SPKI *spki; - - GetSPKI(self, spki); - if (!NETSCAPE_SPKI_set_pubkey(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */ - ossl_raise(eSPKIError, NULL); - } - - return key; -} - -static VALUE -ossl_spki_get_challenge(VALUE self) -{ - NETSCAPE_SPKI *spki; - - GetSPKI(self, spki); - if (spki->spkac->challenge->length <= 0) { - OSSL_Debug("Challenge.length <= 0?"); - return rb_str_new(0, 0); - } - - return rb_str_new((const char *)spki->spkac->challenge->data, - spki->spkac->challenge->length); -} - -static VALUE -ossl_spki_set_challenge(VALUE self, VALUE str) -{ - NETSCAPE_SPKI *spki; - - StringValue(str); - GetSPKI(self, spki); - if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str), - RSTRING_LENINT(str))) { - ossl_raise(eSPKIError, NULL); - } - - return str; -} - -static VALUE -ossl_spki_sign(VALUE self, VALUE key, VALUE digest) -{ - NETSCAPE_SPKI *spki; - EVP_PKEY *pkey; - const EVP_MD *md; - - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = GetDigestPtr(digest); - GetSPKI(self, spki); - if (!NETSCAPE_SPKI_sign(spki, pkey, md)) { - ossl_raise(eSPKIError, NULL); - } - - return self; -} - -/* - * Checks that cert signature is made with PRIVversion of this PUBLIC 'key' - */ -static VALUE -ossl_spki_verify(VALUE self, VALUE key) -{ - NETSCAPE_SPKI *spki; - - GetSPKI(self, spki); - switch (NETSCAPE_SPKI_verify(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */ - case 0: - return Qfalse; - case 1: - return Qtrue; - default: - ossl_raise(eSPKIError, NULL); - } - return Qnil; /* dummy */ -} - -/* - * NETSCAPE_SPKI init - */ -void -Init_ossl_ns_spki() -{ - mNetscape = rb_define_module_under(mOSSL, "Netscape"); - - eSPKIError = rb_define_class_under(mNetscape, "SPKIError", eOSSLError); - - cSPKI = rb_define_class_under(mNetscape, "SPKI", rb_cObject); - - rb_define_alloc_func(cSPKI, ossl_spki_alloc); - rb_define_method(cSPKI, "initialize", ossl_spki_initialize, -1); - - rb_define_method(cSPKI, "to_der", ossl_spki_to_der, 0); - rb_define_method(cSPKI, "to_pem", ossl_spki_to_pem, 0); - rb_define_alias(cSPKI, "to_s", "to_pem"); - rb_define_method(cSPKI, "to_text", ossl_spki_print, 0); - rb_define_method(cSPKI, "public_key", ossl_spki_get_public_key, 0); - rb_define_method(cSPKI, "public_key=", ossl_spki_set_public_key, 1); - rb_define_method(cSPKI, "sign", ossl_spki_sign, 2); - rb_define_method(cSPKI, "verify", ossl_spki_verify, 1); - rb_define_method(cSPKI, "challenge", ossl_spki_get_challenge, 0); - rb_define_method(cSPKI, "challenge=", ossl_spki_set_challenge, 1); -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_ns_spki.h b/ruby_1_9_3/ext/openssl/ossl_ns_spki.h deleted file mode 100644 index 9977035a9c..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_ns_spki.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced 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_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_ocsp.c b/ruby_1_9_3/ext/openssl/ossl_ocsp.c deleted file mode 100644 index e82c2d859a..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_ocsp.c +++ /dev/null @@ -1,786 +0,0 @@ -/* - * $Id$ - * '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 licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#if defined(OSSL_OCSP_ENABLED) - -#define WrapOCSPReq(klass, obj, req) do { \ - if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \ - (obj) = Data_Wrap_Struct((klass), 0, OCSP_REQUEST_free, (req)); \ -} while (0) -#define GetOCSPReq(obj, req) do { \ - Data_Get_Struct((obj), OCSP_REQUEST, (req)); \ - if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \ -} while (0) -#define SafeGetOCSPReq(obj, req) do { \ - OSSL_Check_Kind((obj), cOCSPReq); \ - GetOCSPReq((obj), (req)); \ -} while (0) - -#define WrapOCSPRes(klass, obj, res) do { \ - if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ - (obj) = Data_Wrap_Struct((klass), 0, OCSP_RESPONSE_free, (res)); \ -} while (0) -#define GetOCSPRes(obj, res) do { \ - Data_Get_Struct((obj), OCSP_RESPONSE, (res)); \ - if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ -} while (0) -#define SafeGetOCSPRes(obj, res) do { \ - OSSL_Check_Kind((obj), cOCSPRes); \ - GetOCSPRes((obj), (res)); \ -} while (0) - -#define WrapOCSPBasicRes(klass, obj, res) do { \ - if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ - (obj) = Data_Wrap_Struct((klass), 0, OCSP_BASICRESP_free, (res)); \ -} while (0) -#define GetOCSPBasicRes(obj, res) do { \ - Data_Get_Struct((obj), OCSP_BASICRESP, (res)); \ - if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ -} while (0) -#define SafeGetOCSPBasicRes(obj, res) do { \ - OSSL_Check_Kind((obj), cOCSPBasicRes); \ - GetOCSPBasicRes((obj), (res)); \ -} while (0) - -#define WrapOCSPCertId(klass, obj, cid) do { \ - if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ - (obj) = Data_Wrap_Struct((klass), 0, OCSP_CERTID_free, (cid)); \ -} while (0) -#define GetOCSPCertId(obj, cid) do { \ - Data_Get_Struct((obj), OCSP_CERTID, (cid)); \ - if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ -} while (0) -#define SafeGetOCSPCertId(obj, cid) do { \ - OSSL_Check_Kind((obj), cOCSPCertId); \ - GetOCSPCertId((obj), (cid)); \ -} while (0) - -VALUE mOCSP; -VALUE eOCSPError; -VALUE cOCSPReq; -VALUE cOCSPRes; -VALUE cOCSPBasicRes; -VALUE cOCSPCertId; - -/* - * Public - */ -static VALUE -ossl_ocspcertid_new(OCSP_CERTID *cid) -{ - VALUE obj; - WrapOCSPCertId(cOCSPCertId, obj, cid); - return obj; -} - -/* - * OCSP::Resquest - */ -static VALUE -ossl_ocspreq_alloc(VALUE klass) -{ - OCSP_REQUEST *req; - VALUE obj; - - if (!(req = OCSP_REQUEST_new())) - ossl_raise(eOCSPError, NULL); - WrapOCSPReq(klass, obj, req); - - return obj; -} - -static VALUE -ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE arg; - const unsigned char *p; - - rb_scan_args(argc, argv, "01", &arg); - if(!NIL_P(arg)){ - OCSP_REQUEST *req = DATA_PTR(self), *x; - arg = ossl_to_der_if_possible(arg); - StringValue(arg); - p = (unsigned char*)RSTRING_PTR(arg); - x = d2i_OCSP_REQUEST(&req, &p, RSTRING_LEN(arg)); - DATA_PTR(self) = req; - if(!x){ - ossl_raise(eOCSPError, "cannot load DER encoded request"); - } - } - - return self; -} - -static VALUE -ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self) -{ - OCSP_REQUEST *req; - VALUE val; - int ret; - - rb_scan_args(argc, argv, "01", &val); - if(NIL_P(val)) { - GetOCSPReq(self, req); - ret = OCSP_request_add1_nonce(req, NULL, -1); - } - else{ - StringValue(val); - GetOCSPReq(self, req); - ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); - } - if(!ret) ossl_raise(eOCSPError, NULL); - - return self; -} - -/* Check nonce validity in a request and response. - * Return value reflects result: - * 1: nonces present and equal. - * 2: nonces both absent. - * 3: nonce present in response only. - * 0: nonces both present and not equal. - * -1: nonce in request only. - * - * For most responders clients can check return > 0. - * If responder doesn't handle nonces return != 0 may be - * necessary. return == 0 is always an error. - */ -static VALUE -ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp) -{ - OCSP_REQUEST *req; - OCSP_BASICRESP *bs; - int res; - - GetOCSPReq(self, req); - SafeGetOCSPBasicRes(basic_resp, bs); - res = OCSP_check_nonce(req, bs); - - return INT2NUM(res); -} - -static VALUE -ossl_ocspreq_add_certid(VALUE self, VALUE certid) -{ - OCSP_REQUEST *req; - OCSP_CERTID *id; - - GetOCSPReq(self, req); - GetOCSPCertId(certid, id); - if(!OCSP_request_add0_id(req, OCSP_CERTID_dup(id))) - ossl_raise(eOCSPError, NULL); - - return self; -} - -static VALUE -ossl_ocspreq_get_certid(VALUE self) -{ - OCSP_REQUEST *req; - OCSP_ONEREQ *one; - OCSP_CERTID *id; - VALUE ary, tmp; - int i, count; - - GetOCSPReq(self, req); - count = OCSP_request_onereq_count(req); - ary = (count > 0) ? rb_ary_new() : Qnil; - for(i = 0; i < count; i++){ - one = OCSP_request_onereq_get0(req, i); - if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one)))) - ossl_raise(eOCSPError, NULL); - WrapOCSPCertId(cOCSPCertId, tmp, id); - rb_ary_push(ary, tmp); - } - - return ary; -} - -static VALUE -ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self) -{ - VALUE signer_cert, signer_key, certs, flags; - OCSP_REQUEST *req; - X509 *signer; - EVP_PKEY *key; - STACK_OF(X509) *x509s; - unsigned long flg; - int ret; - - rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags); - signer = GetX509CertPtr(signer_cert); - key = GetPrivPKeyPtr(signer_key); - flg = NIL_P(flags) ? 0 : NUM2INT(flags); - if(NIL_P(certs)){ - x509s = sk_X509_new_null(); - flags |= OCSP_NOCERTS; - } - else x509s = ossl_x509_ary2sk(certs); - GetOCSPReq(self, req); - ret = OCSP_request_sign(req, signer, key, EVP_sha1(), x509s, flg); - sk_X509_pop_free(x509s, X509_free); - if(!ret) ossl_raise(eOCSPError, NULL); - - return self; -} - -static VALUE -ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self) -{ - VALUE certs, store, flags; - OCSP_REQUEST *req; - STACK_OF(X509) *x509s; - X509_STORE *x509st; - int flg, result; - - rb_scan_args(argc, argv, "21", &certs, &store, &flags); - x509st = GetX509StorePtr(store); - flg = NIL_P(flags) ? 0 : NUM2INT(flags); - x509s = ossl_x509_ary2sk(certs); - GetOCSPReq(self, req); - result = OCSP_request_verify(req, x509s, x509st, flg); - sk_X509_pop_free(x509s, X509_free); - if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL)); - - return result ? Qtrue : Qfalse; -} - -static VALUE -ossl_ocspreq_to_der(VALUE self) -{ - OCSP_REQUEST *req; - VALUE str; - unsigned char *p; - long len; - - GetOCSPReq(self, req); - if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_OCSP_REQUEST(req, &p) <= 0) - ossl_raise(eOCSPError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -/* - * OCSP::Response - */ -static VALUE -ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp) -{ - OCSP_BASICRESP *bs; - OCSP_RESPONSE *res; - VALUE obj; - int st = NUM2INT(status); - - if(NIL_P(basic_resp)) bs = NULL; - else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */ - if(!(res = OCSP_response_create(st, bs))) - ossl_raise(eOCSPError, NULL); - WrapOCSPRes(klass, obj, res); - - return obj; -} - -static VALUE -ossl_ocspres_alloc(VALUE klass) -{ - OCSP_RESPONSE *res; - VALUE obj; - - if(!(res = OCSP_RESPONSE_new())) - ossl_raise(eOCSPError, NULL); - WrapOCSPRes(klass, obj, res); - - return obj; -} - -static VALUE -ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE arg; - const unsigned char *p; - - rb_scan_args(argc, argv, "01", &arg); - if(!NIL_P(arg)){ - OCSP_RESPONSE *res = DATA_PTR(self), *x; - arg = ossl_to_der_if_possible(arg); - StringValue(arg); - p = (unsigned char *)RSTRING_PTR(arg); - x = d2i_OCSP_RESPONSE(&res, &p, RSTRING_LEN(arg)); - DATA_PTR(self) = res; - if(!x){ - ossl_raise(eOCSPError, "cannot load DER encoded response"); - } - } - - return self; -} - -static VALUE -ossl_ocspres_status(VALUE self) -{ - OCSP_RESPONSE *res; - int st; - - GetOCSPRes(self, res); - st = OCSP_response_status(res); - - return INT2NUM(st); -} - -static VALUE -ossl_ocspres_status_string(VALUE self) -{ - OCSP_RESPONSE *res; - int st; - - GetOCSPRes(self, res); - st = OCSP_response_status(res); - - return rb_str_new2(OCSP_response_status_str(st)); -} - -static VALUE -ossl_ocspres_get_basic(VALUE self) -{ - OCSP_RESPONSE *res; - OCSP_BASICRESP *bs; - VALUE ret; - - GetOCSPRes(self, res); - if(!(bs = OCSP_response_get1_basic(res))) - return Qnil; - WrapOCSPBasicRes(cOCSPBasicRes, ret, bs); - - return ret; -} - -static VALUE -ossl_ocspres_to_der(VALUE self) -{ - OCSP_RESPONSE *res; - VALUE str; - long len; - unsigned char *p; - - GetOCSPRes(self, res); - if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_OCSP_RESPONSE(res, &p) <= 0) - ossl_raise(eOCSPError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -/* - * OCSP::BasicResponse - */ -static VALUE -ossl_ocspbres_alloc(VALUE klass) -{ - OCSP_BASICRESP *bs; - VALUE obj; - - if(!(bs = OCSP_BASICRESP_new())) - ossl_raise(eOCSPError, NULL); - WrapOCSPBasicRes(klass, obj, bs); - - return obj; -} - -static VALUE -ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self) -{ - return self; -} - -static VALUE -ossl_ocspbres_copy_nonce(VALUE self, VALUE request) -{ - OCSP_BASICRESP *bs; - OCSP_REQUEST *req; - int ret; - - GetOCSPBasicRes(self, bs); - SafeGetOCSPReq(request, req); - ret = OCSP_copy_nonce(bs, req); - - return INT2NUM(ret); -} - -static VALUE -ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self) -{ - OCSP_BASICRESP *bs; - VALUE val; - int ret; - - rb_scan_args(argc, argv, "01", &val); - if(NIL_P(val)) { - GetOCSPBasicRes(self, bs); - ret = OCSP_basic_add1_nonce(bs, NULL, -1); - } - else{ - StringValue(val); - GetOCSPBasicRes(self, bs); - ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); - } - if(!ret) ossl_raise(eOCSPError, NULL); - - return self; -} - -static VALUE -ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, - VALUE reason, VALUE revtime, - VALUE thisupd, VALUE nextupd, VALUE ext) -{ - OCSP_BASICRESP *bs; - OCSP_SINGLERESP *single; - OCSP_CERTID *id; - int st, rsn; - ASN1_TIME *ths, *nxt, *rev; - int error, i, rstatus = 0; - VALUE tmp; - - st = NUM2INT(status); - rsn = NIL_P(status) ? 0 : NUM2INT(reason); - if(!NIL_P(ext)){ - /* All ary's members should be X509Extension */ - Check_Type(ext, T_ARRAY); - for (i = 0; i < RARRAY_LEN(ext); i++) - OSSL_Check_Kind(RARRAY_PTR(ext)[i], cX509Ext); - } - - error = 0; - ths = nxt = rev = NULL; - if(!NIL_P(revtime)){ - tmp = rb_protect(rb_Integer, revtime, &rstatus); - if(rstatus) goto err; - rev = X509_gmtime_adj(NULL, NUM2INT(tmp)); - } - tmp = rb_protect(rb_Integer, thisupd, &rstatus); - if(rstatus) goto err; - ths = X509_gmtime_adj(NULL, NUM2INT(tmp)); - tmp = rb_protect(rb_Integer, nextupd, &rstatus); - if(rstatus) goto err; - nxt = X509_gmtime_adj(NULL, NUM2INT(tmp)); - - GetOCSPBasicRes(self, bs); - SafeGetOCSPCertId(cid, id); - if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){ - error = 1; - goto err; - } - - if(!NIL_P(ext)){ - X509_EXTENSION *x509ext; - sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free); - single->singleExtensions = NULL; - for(i = 0; i < RARRAY_LEN(ext); i++){ - x509ext = DupX509ExtPtr(RARRAY_PTR(ext)[i]); - if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){ - X509_EXTENSION_free(x509ext); - error = 1; - goto err; - } - X509_EXTENSION_free(x509ext); - } - } - - err: - ASN1_TIME_free(ths); - ASN1_TIME_free(nxt); - ASN1_TIME_free(rev); - if(error) ossl_raise(eOCSPError, NULL); - if(rstatus) rb_jump_tag(rstatus); - - return self; -} - -static VALUE -ossl_ocspbres_get_status(VALUE self) -{ - OCSP_BASICRESP *bs; - OCSP_SINGLERESP *single; - OCSP_CERTID *cid; - ASN1_TIME *revtime, *thisupd, *nextupd; - int status, reason; - X509_EXTENSION *x509ext; - VALUE ret, ary, ext; - int count, ext_count, i, j; - - GetOCSPBasicRes(self, bs); - ret = rb_ary_new(); - count = OCSP_resp_count(bs); - for(i = 0; i < count; i++){ - single = OCSP_resp_get0(bs, i); - if(!single) continue; - - revtime = thisupd = nextupd = NULL; - status = OCSP_single_get0_status(single, &reason, &revtime, - &thisupd, &nextupd); - if(status < 0) continue; - if(!(cid = OCSP_CERTID_dup(single->certId))) - ossl_raise(eOCSPError, NULL); - ary = rb_ary_new(); - rb_ary_push(ary, ossl_ocspcertid_new(cid)); - rb_ary_push(ary, INT2NUM(status)); - rb_ary_push(ary, INT2NUM(reason)); - rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil); - rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil); - rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil); - ext = rb_ary_new(); - ext_count = OCSP_SINGLERESP_get_ext_count(single); - for(j = 0; j < ext_count; j++){ - x509ext = OCSP_SINGLERESP_get_ext(single, j); - rb_ary_push(ext, ossl_x509ext_new(x509ext)); - } - rb_ary_push(ary, ext); - rb_ary_push(ret, ary); - } - - return ret; -} - -static VALUE -ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self) -{ - VALUE signer_cert, signer_key, certs, flags; - OCSP_BASICRESP *bs; - X509 *signer; - EVP_PKEY *key; - STACK_OF(X509) *x509s; - unsigned long flg; - int ret; - - rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags); - signer = GetX509CertPtr(signer_cert); - key = GetPrivPKeyPtr(signer_key); - flg = NIL_P(flags) ? 0 : NUM2INT(flags); - if(NIL_P(certs)){ - x509s = sk_X509_new_null(); - flg |= OCSP_NOCERTS; - } - else{ - x509s = ossl_x509_ary2sk(certs); - } - GetOCSPBasicRes(self, bs); - ret = OCSP_basic_sign(bs, signer, key, EVP_sha1(), x509s, flg); - sk_X509_pop_free(x509s, X509_free); - if(!ret) ossl_raise(eOCSPError, NULL); - - return self; -} - -static VALUE -ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self) -{ - VALUE certs, store, flags, result; - OCSP_BASICRESP *bs; - STACK_OF(X509) *x509s; - X509_STORE *x509st; - int flg; - - rb_scan_args(argc, argv, "21", &certs, &store, &flags); - x509st = GetX509StorePtr(store); - flg = NIL_P(flags) ? 0 : NUM2INT(flags); - x509s = ossl_x509_ary2sk(certs); - GetOCSPBasicRes(self, bs); - result = OCSP_basic_verify(bs, x509s, x509st, flg) > 0 ? Qtrue : Qfalse; - sk_X509_pop_free(x509s, X509_free); - if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL)); - - return result; -} - -/* - * OCSP::CertificateId - */ -static VALUE -ossl_ocspcid_alloc(VALUE klass) -{ - OCSP_CERTID *id; - VALUE obj; - - if(!(id = OCSP_CERTID_new())) - ossl_raise(eOCSPError, NULL); - WrapOCSPCertId(klass, obj, id); - - return obj; -} - -static VALUE -ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self) -{ - OCSP_CERTID *id, *newid; - X509 *x509s, *x509i; - VALUE subject, issuer, digest; - const EVP_MD *md; - - if (rb_scan_args(argc, argv, "21", &subject, &issuer, &digest) == 0) { - return self; - } - - x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */ - x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */ - - if (!NIL_P(digest)) { - md = GetDigestPtr(digest); - newid = OCSP_cert_to_id(md, x509s, x509i); - } else { - newid = OCSP_cert_to_id(NULL, x509s, x509i); - } - if(!newid) - ossl_raise(eOCSPError, NULL); - GetOCSPCertId(self, id); - OCSP_CERTID_free(id); - RDATA(self)->data = newid; - - return self; -} - -static VALUE -ossl_ocspcid_cmp(VALUE self, VALUE other) -{ - OCSP_CERTID *id, *id2; - int result; - - GetOCSPCertId(self, id); - SafeGetOCSPCertId(other, id2); - result = OCSP_id_cmp(id, id2); - - return (result == 0) ? Qtrue : Qfalse; -} - -static VALUE -ossl_ocspcid_cmp_issuer(VALUE self, VALUE other) -{ - OCSP_CERTID *id, *id2; - int result; - - GetOCSPCertId(self, id); - SafeGetOCSPCertId(other, id2); - result = OCSP_id_issuer_cmp(id, id2); - - return (result == 0) ? Qtrue : Qfalse; -} - -static VALUE -ossl_ocspcid_get_serial(VALUE self) -{ - OCSP_CERTID *id; - - GetOCSPCertId(self, id); - - return asn1integer_to_num(id->serialNumber); -} - -void -Init_ossl_ocsp() -{ - mOCSP = rb_define_module_under(mOSSL, "OCSP"); - - eOCSPError = rb_define_class_under(mOCSP, "OCSPError", eOSSLError); - - cOCSPReq = rb_define_class_under(mOCSP, "Request", rb_cObject); - rb_define_alloc_func(cOCSPReq, ossl_ocspreq_alloc); - rb_define_method(cOCSPReq, "initialize", ossl_ocspreq_initialize, -1); - rb_define_method(cOCSPReq, "add_nonce", ossl_ocspreq_add_nonce, -1); - rb_define_method(cOCSPReq, "check_nonce", ossl_ocspreq_check_nonce, 1); - rb_define_method(cOCSPReq, "add_certid", ossl_ocspreq_add_certid, 1); - rb_define_method(cOCSPReq, "certid", ossl_ocspreq_get_certid, 0); - rb_define_method(cOCSPReq, "sign", ossl_ocspreq_sign, -1); - rb_define_method(cOCSPReq, "verify", ossl_ocspreq_verify, -1); - rb_define_method(cOCSPReq, "to_der", ossl_ocspreq_to_der, 0); - - cOCSPRes = rb_define_class_under(mOCSP, "Response", rb_cObject); - rb_define_singleton_method(cOCSPRes, "create", ossl_ocspres_s_create, 2); - rb_define_alloc_func(cOCSPRes, ossl_ocspres_alloc); - rb_define_method(cOCSPRes, "initialize", ossl_ocspres_initialize, -1); - rb_define_method(cOCSPRes, "status", ossl_ocspres_status, 0); - rb_define_method(cOCSPRes, "status_string", ossl_ocspres_status_string, 0); - rb_define_method(cOCSPRes, "basic", ossl_ocspres_get_basic, 0); - rb_define_method(cOCSPRes, "to_der", ossl_ocspres_to_der, 0); - - cOCSPBasicRes = rb_define_class_under(mOCSP, "BasicResponse", rb_cObject); - rb_define_alloc_func(cOCSPBasicRes, ossl_ocspbres_alloc); - rb_define_method(cOCSPBasicRes, "initialize", ossl_ocspbres_initialize, -1); - rb_define_method(cOCSPBasicRes, "copy_nonce", ossl_ocspbres_copy_nonce, 1); - rb_define_method(cOCSPBasicRes, "add_nonce", ossl_ocspbres_add_nonce, -1); - rb_define_method(cOCSPBasicRes, "add_status", ossl_ocspbres_add_status, 7); - rb_define_method(cOCSPBasicRes, "status", ossl_ocspbres_get_status, 0); - rb_define_method(cOCSPBasicRes, "sign", ossl_ocspbres_sign, -1); - rb_define_method(cOCSPBasicRes, "verify", ossl_ocspbres_verify, -1); - - cOCSPCertId = rb_define_class_under(mOCSP, "CertificateId", rb_cObject); - rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc); - rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize, -1); - rb_define_method(cOCSPCertId, "cmp", ossl_ocspcid_cmp, 1); - rb_define_method(cOCSPCertId, "cmp_issuer", ossl_ocspcid_cmp_issuer, 1); - rb_define_method(cOCSPCertId, "serial", ossl_ocspcid_get_serial, 0); - -#define DefOCSPConst(x) rb_define_const(mOCSP, #x, INT2NUM(OCSP_##x)) - - DefOCSPConst(RESPONSE_STATUS_SUCCESSFUL); - DefOCSPConst(RESPONSE_STATUS_MALFORMEDREQUEST); - DefOCSPConst(RESPONSE_STATUS_INTERNALERROR); - DefOCSPConst(RESPONSE_STATUS_TRYLATER); - DefOCSPConst(RESPONSE_STATUS_SIGREQUIRED); - DefOCSPConst(RESPONSE_STATUS_UNAUTHORIZED); - - DefOCSPConst(REVOKED_STATUS_NOSTATUS); - DefOCSPConst(REVOKED_STATUS_UNSPECIFIED); - DefOCSPConst(REVOKED_STATUS_KEYCOMPROMISE); - DefOCSPConst(REVOKED_STATUS_CACOMPROMISE); - DefOCSPConst(REVOKED_STATUS_AFFILIATIONCHANGED); - DefOCSPConst(REVOKED_STATUS_SUPERSEDED); - DefOCSPConst(REVOKED_STATUS_CESSATIONOFOPERATION); - DefOCSPConst(REVOKED_STATUS_CERTIFICATEHOLD); - DefOCSPConst(REVOKED_STATUS_REMOVEFROMCRL); - - DefOCSPConst(NOCERTS); - DefOCSPConst(NOINTERN); - DefOCSPConst(NOSIGS); - DefOCSPConst(NOCHAIN); - DefOCSPConst(NOVERIFY); - DefOCSPConst(NOEXPLICIT); - DefOCSPConst(NOCASIGN); - DefOCSPConst(NODELEGATED); - DefOCSPConst(NOCHECKS); - DefOCSPConst(TRUSTOTHER); - DefOCSPConst(RESPID_KEY); - DefOCSPConst(NOTIME); - -#define DefOCSPVConst(x) rb_define_const(mOCSP, "V_" #x, INT2NUM(V_OCSP_##x)) - - DefOCSPVConst(CERTSTATUS_GOOD); - DefOCSPVConst(CERTSTATUS_REVOKED); - DefOCSPVConst(CERTSTATUS_UNKNOWN); - DefOCSPVConst(RESPID_NAME); - DefOCSPVConst(RESPID_KEY); -} - -#else /* ! OSSL_OCSP_ENABLED */ -void -Init_ossl_ocsp() -{ -} -#endif diff --git a/ruby_1_9_3/ext/openssl/ossl_ocsp.h b/ruby_1_9_3/ext/openssl/ossl_ocsp.h deleted file mode 100644 index 65b4f2e23f..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_ocsp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * $Id$ - * '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 licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_OCSP_H_) -#define _OSSL_OCSP_H_ - -#if defined(OSSL_OCSP_ENABLED) -extern VALUE mOCSP; -extern VALUE cOPCSReq; -extern VALUE cOPCSRes; -extern VALUE cOPCSBasicRes; -#endif - -void Init_ossl_ocsp(void); - -#endif /* _OSSL_OCSP_H_ */ diff --git a/ruby_1_9_3/ext/openssl/ossl_pkcs12.c b/ruby_1_9_3/ext/openssl/ossl_pkcs12.c deleted file mode 100644 index 8a5f816082..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkcs12.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - * $Id$ - */ -#include "ossl.h" - -#define WrapPKCS12(klass, obj, p12) do { \ - if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \ - (obj) = Data_Wrap_Struct((klass), 0, PKCS12_free, (p12)); \ -} while (0) - -#define GetPKCS12(obj, p12) do { \ - Data_Get_Struct((obj), PKCS12, (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 VALUE -ossl_pkcs12_s_allocate(VALUE klass) -{ - PKCS12 *p12; - VALUE obj; - - if(!(p12 = PKCS12_new())) ossl_raise(ePKCS12Error, NULL); - WrapPKCS12(klass, 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 : StringValuePtr(pass); - friendlyname = NIL_P(name) ? NULL : StringValuePtr(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(StringValuePtr(key_nid))) == NID_undef) - ossl_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(key_nid)); - } - if (!NIL_P(cert_nid)) { - if ((ncert = OBJ_txt2nid(StringValuePtr(cert_nid))) == NID_undef) - ossl_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(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); - - 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); - WrapPKCS12(cPKCS12, 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 : StringValuePtr(pass); - in = ossl_obj2bio(arg); - d2i_PKCS12_bio(in, &pkcs); - DATA_PTR(self) = pkcs; - BIO_free(in); - - pkey = cert = ca = Qnil; - if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s)) - ossl_raise(ePKCS12Error, "PKCS12_parse"); - 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() -{ - /* - * 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); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_pkcs12.h b/ruby_1_9_3/ext/openssl/ossl_pkcs12.h deleted file mode 100644 index 24d25d00bb..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkcs12.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - * $Id$ - */ -#if !defined(_OSSL_PKCS12_H_) -#define _OSSL_PKCS12_H_ - -extern VALUE cPKCS12; -extern VALUE ePKCS12Error; - -void Init_ossl_pkcs12(void); - -#endif /* _OSSL_PKCS12_H_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_pkcs5.c b/ruby_1_9_3/ext/openssl/ossl_pkcs5.c deleted file mode 100644 index d3eaf2d073..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkcs5.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * $Id$ - * 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 - * * +iter+ - integer - should be greater than 1000. 2000 is better. - * * +keylen+ - integer - * * +digest+ - a string or OpenSSL::Digest object. - * - * Available in OpenSSL 0.9.9?. - * - * 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_LEN(pass), - (unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(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 - - -#ifdef HAVE_PKCS5_PBKDF2_HMAC_SHA1 -/* - * call-seq: - * PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string - * - * === Parameters - * * +pass+ - string - * * +salt+ - string - * * +iter+ - integer - should be greater than 1000. 2000 is better. - * * +keylen+ - integer - * - * This method is available almost any version 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; -} -#else -#define ossl_pkcs5_pbkdf2_hmac_sha1 rb_f_notimplement -#endif - -void -Init_ossl_pkcs5() -{ - /* - * Password-based Encryption - * - */ - mPKCS5 = rb_define_module_under(mOSSL, "PKCS5"); - 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); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_pkcs5.h b/ruby_1_9_3/ext/openssl/ossl_pkcs5.h deleted file mode 100644 index a3b132bc50..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkcs5.h +++ /dev/null @@ -1,6 +0,0 @@ -#if !defined(_OSSL_PKCS5_H_) -#define _OSSL_PKCS5_H_ - -void Init_ossl_pkcs5(void); - -#endif /* _OSSL_PKCS5_H_ */ diff --git a/ruby_1_9_3/ext/openssl/ossl_pkcs7.c b/ruby_1_9_3/ext/openssl/ossl_pkcs7.c deleted file mode 100644 index b710280c9c..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkcs7.c +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapPKCS7(klass, obj, pkcs7) do { \ - if (!(pkcs7)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, PKCS7_free, (pkcs7)); \ -} while (0) -#define GetPKCS7(obj, pkcs7) do { \ - Data_Get_Struct((obj), PKCS7, (pkcs7)); \ - if (!(pkcs7)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ - } \ -} while (0) -#define SafeGetPKCS7(obj, pkcs7) do { \ - OSSL_Check_Kind((obj), cPKCS7); \ - GetPKCS7((obj), (pkcs7)); \ -} while (0) - -#define WrapPKCS7si(klass, obj, p7si) do { \ - if (!(p7si)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, PKCS7_SIGNER_INFO_free, (p7si)); \ -} while (0) -#define GetPKCS7si(obj, p7si) do { \ - Data_Get_Struct((obj), PKCS7_SIGNER_INFO, (p7si)); \ - if (!(p7si)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ - } \ -} while (0) -#define SafeGetPKCS7si(obj, p7si) do { \ - OSSL_Check_Kind((obj), cPKCS7Signer); \ - GetPKCS7si((obj), (p7si)); \ -} while (0) - -#define WrapPKCS7ri(klass, obj, p7ri) do { \ - if (!(p7ri)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, PKCS7_RECIP_INFO_free, (p7ri)); \ -} while (0) -#define GetPKCS7ri(obj, p7ri) do { \ - Data_Get_Struct((obj), PKCS7_RECIP_INFO, (p7ri)); \ - if (!(p7ri)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ - } \ -} while (0) -#define SafeGetPKCS7ri(obj, p7ri) do { \ - OSSL_Check_Kind((obj), cPKCS7Recipient); \ - GetPKCS7ri((obj), (p7ri)); \ -} while (0) - -#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0])) - -#define ossl_pkcs7_set_data(o,v) rb_iv_set((o), "@data", (v)) -#define ossl_pkcs7_get_data(o) rb_iv_get((o), "@data") -#define ossl_pkcs7_set_err_string(o,v) rb_iv_set((o), "@error_string", (v)) -#define ossl_pkcs7_get_err_string(o) rb_iv_get((o), "@error_string") - -/* - * Classes - */ -VALUE cPKCS7; -VALUE cPKCS7Signer; -VALUE cPKCS7Recipient; -VALUE ePKCS7Error; - -/* - * Public - * (MADE PRIVATE UNTIL SOMEBODY WILL NEED THEM) - */ -static VALUE -ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si) -{ - PKCS7_SIGNER_INFO *pkcs7; - VALUE obj; - - pkcs7 = p7si ? PKCS7_SIGNER_INFO_dup(p7si) : PKCS7_SIGNER_INFO_new(); - if (!pkcs7) ossl_raise(ePKCS7Error, NULL); - WrapPKCS7si(cPKCS7Signer, obj, pkcs7); - - return obj; -} - -static PKCS7_SIGNER_INFO * -DupPKCS7SignerPtr(VALUE obj) -{ - PKCS7_SIGNER_INFO *p7si, *pkcs7; - - SafeGetPKCS7si(obj, p7si); - if (!(pkcs7 = PKCS7_SIGNER_INFO_dup(p7si))) { - ossl_raise(ePKCS7Error, NULL); - } - - return pkcs7; -} - -static VALUE -ossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri) -{ - PKCS7_RECIP_INFO *pkcs7; - VALUE obj; - - pkcs7 = p7ri ? PKCS7_RECIP_INFO_dup(p7ri) : PKCS7_RECIP_INFO_new(); - if (!pkcs7) ossl_raise(ePKCS7Error, NULL); - WrapPKCS7ri(cPKCS7Recipient, obj, pkcs7); - - return obj; -} - -static PKCS7_RECIP_INFO * -DupPKCS7RecipientPtr(VALUE obj) -{ - PKCS7_RECIP_INFO *p7ri, *pkcs7; - - SafeGetPKCS7ri(obj, p7ri); - if (!(pkcs7 = PKCS7_RECIP_INFO_dup(p7ri))) { - ossl_raise(ePKCS7Error, NULL); - } - - return pkcs7; -} - -/* - * call-seq: - * PKCS7.read_smime(string) => pkcs7 - */ -static VALUE -ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg) -{ - BIO *in, *out; - PKCS7 *pkcs7; - VALUE ret, data; - - in = ossl_obj2bio(arg); - out = NULL; - pkcs7 = SMIME_read_PKCS7(in, &out); - BIO_free(in); - if(!pkcs7) ossl_raise(ePKCS7Error, NULL); - data = out ? ossl_membio2str(out) : Qnil; - WrapPKCS7(cPKCS7, ret, pkcs7); - ossl_pkcs7_set_data(ret, data); - ossl_pkcs7_set_err_string(ret, Qnil); - - return ret; -} - -/* - * call-seq: - * PKCS7.write_smime(pkcs7 [, data [, flags]]) => string - */ -static VALUE -ossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass) -{ - VALUE pkcs7, data, flags; - BIO *out, *in; - PKCS7 *p7; - VALUE str; - int flg; - - rb_scan_args(argc, argv, "12", &pkcs7, &data, &flags); - flg = NIL_P(flags) ? 0 : NUM2INT(flags); - if(NIL_P(data)) data = ossl_pkcs7_get_data(pkcs7); - SafeGetPKCS7(pkcs7, p7); - if(!NIL_P(data) && PKCS7_is_detached(p7)) - flg |= PKCS7_DETACHED; - in = NIL_P(data) ? NULL : ossl_obj2bio(data); - if(!(out = BIO_new(BIO_s_mem()))){ - BIO_free(in); - ossl_raise(ePKCS7Error, NULL); - } - if(!SMIME_write_PKCS7(out, p7, in, flg)){ - BIO_free(out); - BIO_free(in); - ossl_raise(ePKCS7Error, NULL); - } - BIO_free(in); - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * PKCS7.sign(cert, key, data, [, certs [, flags]]) => pkcs7 - */ -static VALUE -ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass) -{ - VALUE cert, key, data, certs, flags; - X509 *x509; - EVP_PKEY *pkey; - BIO *in; - STACK_OF(X509) *x509s; - int flg, status = 0; - PKCS7 *pkcs7; - VALUE ret; - - rb_scan_args(argc, argv, "32", &cert, &key, &data, &certs, &flags); - x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - flg = NIL_P(flags) ? 0 : NUM2INT(flags); - in = ossl_obj2bio(data); - if(NIL_P(certs)) x509s = NULL; - else{ - x509s = ossl_protect_x509_ary2sk(certs, &status); - if(status){ - BIO_free(in); - rb_jump_tag(status); - } - } - if(!(pkcs7 = PKCS7_sign(x509, pkey, x509s, in, flg))){ - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - ossl_raise(ePKCS7Error, NULL); - } - WrapPKCS7(cPKCS7, ret, pkcs7); - ossl_pkcs7_set_data(ret, data); - ossl_pkcs7_set_err_string(ret, Qnil); - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - - return ret; -} - -/* - * call-seq: - * PKCS7.encrypt(certs, data, [, cipher [, flags]]) => pkcs7 - */ -static VALUE -ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass) -{ - VALUE certs, data, cipher, flags; - STACK_OF(X509) *x509s; - BIO *in; - const EVP_CIPHER *ciph; - int flg, status = 0; - VALUE ret; - PKCS7 *p7; - - rb_scan_args(argc, argv, "22", &certs, &data, &cipher, &flags); - if(NIL_P(cipher)){ -#if !defined(OPENSSL_NO_RC2) - ciph = EVP_rc2_40_cbc(); -#elif !defined(OPENSSL_NO_DES) - ciph = EVP_des_ede3_cbc(); -#elif !defined(OPENSSL_NO_RC2) - ciph = EVP_rc2_40_cbc(); -#elif !defined(OPENSSL_NO_AES) - ciph = EVP_EVP_aes_128_cbc(); -#else - ossl_raise(ePKCS7Error, "Must specify cipher"); -#endif - - } - else ciph = GetCipherPtr(cipher); /* NO NEED TO DUP */ - flg = NIL_P(flags) ? 0 : NUM2INT(flags); - in = ossl_obj2bio(data); - x509s = ossl_protect_x509_ary2sk(certs, &status); - if(status){ - BIO_free(in); - rb_jump_tag(status); - } - if(!(p7 = PKCS7_encrypt(x509s, in, (EVP_CIPHER*)ciph, flg))){ - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - ossl_raise(ePKCS7Error, NULL); - } - BIO_free(in); - WrapPKCS7(cPKCS7, ret, p7); - ossl_pkcs7_set_data(ret, data); - sk_X509_pop_free(x509s, X509_free); - - return ret; -} - -static VALUE -ossl_pkcs7_alloc(VALUE klass) -{ - PKCS7 *pkcs7; - VALUE obj; - - if (!(pkcs7 = PKCS7_new())) { - ossl_raise(ePKCS7Error, NULL); - } - WrapPKCS7(klass, obj, pkcs7); - - return obj; -} - -/* - * call-seq: - * PKCS7.new => pkcs7 - * PKCS7.new(string) => pkcs7 - * - * Many methods in this class aren't documented. - */ -static VALUE -ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) -{ - PKCS7 *p7, *pkcs = DATA_PTR(self); - BIO *in; - VALUE arg; - - if(rb_scan_args(argc, argv, "01", &arg) == 0) - return self; - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL); - if (!p7) { - OSSL_BIO_reset(in); - p7 = d2i_PKCS7_bio(in, &pkcs); - if (!p7) { - BIO_free(in); - PKCS7_free(pkcs); - DATA_PTR(self) = NULL; - ossl_raise(rb_eArgError, "Could not parse the PKCS7"); - } - } - DATA_PTR(self) = pkcs; - BIO_free(in); - ossl_pkcs7_set_data(self, Qnil); - ossl_pkcs7_set_err_string(self, Qnil); - - return self; -} - -static VALUE -ossl_pkcs7_copy(VALUE self, VALUE other) -{ - PKCS7 *a, *b, *pkcs7; - - rb_check_frozen(self); - if (self == other) return self; - - GetPKCS7(self, a); - SafeGetPKCS7(other, b); - - pkcs7 = PKCS7_dup(b); - if (!pkcs7) { - ossl_raise(ePKCS7Error, NULL); - } - DATA_PTR(self) = pkcs7; - PKCS7_free(a); - - return self; -} - -static int -ossl_pkcs7_sym2typeid(VALUE sym) -{ - int i, ret = Qnil; - const char *s; - - static struct { - const char *name; - int nid; - } p7_type_tab[] = { - { "signed", NID_pkcs7_signed }, - { "data", NID_pkcs7_data }, - { "signedAndEnveloped", NID_pkcs7_signedAndEnveloped }, - { "enveloped", NID_pkcs7_enveloped }, - { "encrypted", NID_pkcs7_encrypted }, - { "digest", NID_pkcs7_digest }, - { NULL, 0 }, - }; - - if(TYPE(sym) == T_SYMBOL) s = rb_id2name(SYM2ID(sym)); - else s = StringValuePtr(sym); - for(i = 0; i < numberof(p7_type_tab); i++){ - if(p7_type_tab[i].name == NULL) - ossl_raise(ePKCS7Error, "unknown type \"%s\"", s); - if(strcmp(p7_type_tab[i].name, s) == 0){ - ret = p7_type_tab[i].nid; - break; - } - } - - return ret; -} - -/* - * call-seq: - * pkcs7.type = type => type - */ -static VALUE -ossl_pkcs7_set_type(VALUE self, VALUE type) -{ - PKCS7 *p7; - - GetPKCS7(self, p7); - if(!PKCS7_set_type(p7, ossl_pkcs7_sym2typeid(type))) - ossl_raise(ePKCS7Error, NULL); - - return type; -} - -/* - * call-seq: - * pkcs7.type => string or nil - */ -static VALUE -ossl_pkcs7_get_type(VALUE self) -{ - PKCS7 *p7; - - GetPKCS7(self, p7); - if(PKCS7_type_is_signed(p7)) - return ID2SYM(rb_intern("signed")); - if(PKCS7_type_is_encrypted(p7)) - return ID2SYM(rb_intern("encrypted")); - if(PKCS7_type_is_enveloped(p7)) - return ID2SYM(rb_intern("enveloped")); - if(PKCS7_type_is_signedAndEnveloped(p7)) - return ID2SYM(rb_intern("signedAndEnveloped")); - if(PKCS7_type_is_data(p7)) - return ID2SYM(rb_intern("data")); - return Qnil; -} - -static VALUE -ossl_pkcs7_set_detached(VALUE self, VALUE flag) -{ - PKCS7 *p7; - - GetPKCS7(self, p7); - if(flag != Qtrue && flag != Qfalse) - ossl_raise(ePKCS7Error, "must specify a boolean"); - if(!PKCS7_set_detached(p7, flag == Qtrue ? 1 : 0)) - ossl_raise(ePKCS7Error, NULL); - - return flag; -} - -static VALUE -ossl_pkcs7_get_detached(VALUE self) -{ - PKCS7 *p7; - GetPKCS7(self, p7); - return PKCS7_get_detached(p7) ? Qtrue : Qfalse; -} - -static VALUE -ossl_pkcs7_detached_p(VALUE self) -{ - PKCS7 *p7; - GetPKCS7(self, p7); - return PKCS7_is_detached(p7) ? Qtrue : Qfalse; -} - -static VALUE -ossl_pkcs7_set_cipher(VALUE self, VALUE cipher) -{ - PKCS7 *pkcs7; - - GetPKCS7(self, pkcs7); - if (!PKCS7_set_cipher(pkcs7, GetCipherPtr(cipher))) { - ossl_raise(ePKCS7Error, NULL); - } - - return cipher; -} - -static VALUE -ossl_pkcs7_add_signer(VALUE self, VALUE signer) -{ - PKCS7 *pkcs7; - PKCS7_SIGNER_INFO *p7si; - - p7si = DupPKCS7SignerPtr(signer); /* NEED TO DUP */ - GetPKCS7(self, pkcs7); - if (!PKCS7_add_signer(pkcs7, p7si)) { - PKCS7_SIGNER_INFO_free(p7si); - ossl_raise(ePKCS7Error, "Could not add signer."); - } - if (PKCS7_type_is_signed(pkcs7)){ - PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, - V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)); - } - - return self; -} - -static VALUE -ossl_pkcs7_get_signer(VALUE self) -{ - PKCS7 *pkcs7; - STACK_OF(PKCS7_SIGNER_INFO) *sk; - PKCS7_SIGNER_INFO *si; - int num, i; - VALUE ary; - - GetPKCS7(self, pkcs7); - if (!(sk = PKCS7_get_signer_info(pkcs7))) { - OSSL_Debug("OpenSSL::PKCS7#get_signer_info == NULL!"); - return rb_ary_new(); - } - if ((num = sk_PKCS7_SIGNER_INFO_num(sk)) < 0) { - ossl_raise(ePKCS7Error, "Negative number of signers!"); - } - ary = rb_ary_new2(num); - for (i=0; i<num; i++) { - si = sk_PKCS7_SIGNER_INFO_value(sk, i); - rb_ary_push(ary, ossl_pkcs7si_new(si)); - } - - return ary; -} - -static VALUE -ossl_pkcs7_add_recipient(VALUE self, VALUE recip) -{ - PKCS7 *pkcs7; - PKCS7_RECIP_INFO *ri; - - ri = DupPKCS7RecipientPtr(recip); /* NEED TO DUP */ - GetPKCS7(self, pkcs7); - if (!PKCS7_add_recipient_info(pkcs7, ri)) { - PKCS7_RECIP_INFO_free(ri); - ossl_raise(ePKCS7Error, "Could not add recipient."); - } - - return self; -} - -static VALUE -ossl_pkcs7_get_recipient(VALUE self) -{ - PKCS7 *pkcs7; - STACK_OF(PKCS7_RECIP_INFO) *sk; - PKCS7_RECIP_INFO *si; - int num, i; - VALUE ary; - - GetPKCS7(self, pkcs7); - if (PKCS7_type_is_enveloped(pkcs7)) - sk = pkcs7->d.enveloped->recipientinfo; - else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) - sk = pkcs7->d.signed_and_enveloped->recipientinfo; - else sk = NULL; - if (!sk) return rb_ary_new(); - if ((num = sk_PKCS7_RECIP_INFO_num(sk)) < 0) { - ossl_raise(ePKCS7Error, "Negative number of recipient!"); - } - ary = rb_ary_new2(num); - for (i=0; i<num; i++) { - si = sk_PKCS7_RECIP_INFO_value(sk, i); - rb_ary_push(ary, ossl_pkcs7ri_new(si)); - } - - return ary; -} - -static VALUE -ossl_pkcs7_add_certificate(VALUE self, VALUE cert) -{ - PKCS7 *pkcs7; - X509 *x509; - - GetPKCS7(self, pkcs7); - x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ - if (!PKCS7_add_certificate(pkcs7, x509)){ - ossl_raise(ePKCS7Error, NULL); - } - - return self; -} - -static STACK_OF(X509) * -pkcs7_get_certs(VALUE self) -{ - PKCS7 *pkcs7; - STACK_OF(X509) *certs; - int i; - - GetPKCS7(self, pkcs7); - i = OBJ_obj2nid(pkcs7->type); - switch(i){ - case NID_pkcs7_signed: - certs = pkcs7->d.sign->cert; - break; - case NID_pkcs7_signedAndEnveloped: - certs = pkcs7->d.signed_and_enveloped->cert; - break; - default: - certs = NULL; - } - - return certs; -} - -static STACK_OF(X509_CRL) * -pkcs7_get_crls(VALUE self) -{ - PKCS7 *pkcs7; - STACK_OF(X509_CRL) *crls; - int i; - - GetPKCS7(self, pkcs7); - i = OBJ_obj2nid(pkcs7->type); - switch(i){ - case NID_pkcs7_signed: - crls = pkcs7->d.sign->crl; - break; - case NID_pkcs7_signedAndEnveloped: - crls = pkcs7->d.signed_and_enveloped->crl; - break; - default: - crls = NULL; - } - - return crls; -} - -static VALUE -ossl_pkcs7_set_certs_i(VALUE i, VALUE arg) -{ - return ossl_pkcs7_add_certificate(arg, i); -} - -static VALUE -ossl_pkcs7_set_certificates(VALUE self, VALUE ary) -{ - STACK_OF(X509) *certs; - X509 *cert; - - certs = pkcs7_get_certs(self); - while((cert = sk_X509_pop(certs))) X509_free(cert); - rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_certs_i, self); - - return ary; -} - -static VALUE -ossl_pkcs7_get_certificates(VALUE self) -{ - return ossl_x509_sk2ary(pkcs7_get_certs(self)); -} - -static VALUE -ossl_pkcs7_add_crl(VALUE self, VALUE crl) -{ - PKCS7 *pkcs7; - X509_CRL *x509crl; - - GetPKCS7(self, pkcs7); /* NO DUP needed! */ - x509crl = GetX509CRLPtr(crl); - if (!PKCS7_add_crl(pkcs7, x509crl)) { - ossl_raise(ePKCS7Error, NULL); - } - - return self; -} - -static VALUE -ossl_pkcs7_set_crls_i(VALUE i, VALUE arg) -{ - return ossl_pkcs7_add_crl(arg, i); -} - -static VALUE -ossl_pkcs7_set_crls(VALUE self, VALUE ary) -{ - STACK_OF(X509_CRL) *crls; - X509_CRL *crl; - - crls = pkcs7_get_crls(self); - while((crl = sk_X509_CRL_pop(crls))) X509_CRL_free(crl); - rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_crls_i, self); - - return ary; -} - -static VALUE -ossl_pkcs7_get_crls(VALUE self) -{ - return ossl_x509crl_sk2ary(pkcs7_get_crls(self)); -} - -static VALUE -ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self) -{ - VALUE certs, store, indata, flags; - STACK_OF(X509) *x509s; - X509_STORE *x509st; - int flg, ok, status = 0; - BIO *in, *out; - PKCS7 *p7; - VALUE data; - const char *msg; - - rb_scan_args(argc, argv, "22", &certs, &store, &indata, &flags); - flg = NIL_P(flags) ? 0 : NUM2INT(flags); - if(NIL_P(indata)) indata = ossl_pkcs7_get_data(self); - in = NIL_P(indata) ? NULL : ossl_obj2bio(indata); - if(NIL_P(certs)) x509s = NULL; - else{ - x509s = ossl_protect_x509_ary2sk(certs, &status); - if(status){ - BIO_free(in); - rb_jump_tag(status); - } - } - x509st = GetX509StorePtr(store); - GetPKCS7(self, p7); - if(!(out = BIO_new(BIO_s_mem()))){ - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - ossl_raise(ePKCS7Error, NULL); - } - ok = PKCS7_verify(p7, x509s, x509st, in, out, flg); - BIO_free(in); - if (ok < 0) ossl_raise(ePKCS7Error, NULL); - msg = ERR_reason_error_string(ERR_get_error()); - ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil); - ERR_clear_error(); - data = ossl_membio2str(out); - ossl_pkcs7_set_data(self, data); - sk_X509_pop_free(x509s, X509_free); - - return (ok == 1) ? Qtrue : Qfalse; -} - -static VALUE -ossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self) -{ - VALUE pkey, cert, flags; - EVP_PKEY *key; - X509 *x509; - int flg; - PKCS7 *p7; - BIO *out; - VALUE str; - - rb_scan_args(argc, argv, "21", &pkey, &cert, &flags); - key = GetPrivPKeyPtr(pkey); /* NO NEED TO DUP */ - x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ - flg = NIL_P(flags) ? 0 : NUM2INT(flags); - GetPKCS7(self, p7); - if(!(out = BIO_new(BIO_s_mem()))) - ossl_raise(ePKCS7Error, NULL); - if(!PKCS7_decrypt(p7, key, x509, out, flg)){ - BIO_free(out); - ossl_raise(ePKCS7Error, NULL); - } - str = ossl_membio2str(out); /* out will be free */ - - return str; -} - -static VALUE -ossl_pkcs7_add_data(VALUE self, VALUE data) -{ - PKCS7 *pkcs7; - BIO *out, *in; - char buf[4096]; - int len; - - in = ossl_obj2bio(data); - GetPKCS7(self, pkcs7); - if(PKCS7_type_is_signed(pkcs7)){ - if(!PKCS7_content_new(pkcs7, NID_pkcs7_data)) - ossl_raise(ePKCS7Error, NULL); - } - if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err; - for(;;){ - if((len = BIO_read(in, buf, sizeof(buf))) <= 0) - break; - if(BIO_write(out, buf, len) != len) - goto err; - } - if(!PKCS7_dataFinal(pkcs7, out)) goto err; - ossl_pkcs7_set_data(self, Qnil); - - err: - BIO_free(out); - BIO_free(in); - if(ERR_peek_error()){ - ossl_raise(ePKCS7Error, NULL); - } - - return data; -} - -static VALUE -ossl_pkcs7_to_der(VALUE self) -{ - PKCS7 *pkcs7; - VALUE str; - long len; - unsigned char *p; - - GetPKCS7(self, pkcs7); - if((len = i2d_PKCS7(pkcs7, NULL)) <= 0) - ossl_raise(ePKCS7Error, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_PKCS7(pkcs7, &p) <= 0) - ossl_raise(ePKCS7Error, NULL); - ossl_str_adjust(str, p); - - return str; -} - -static VALUE -ossl_pkcs7_to_pem(VALUE self) -{ - PKCS7 *pkcs7; - BIO *out; - VALUE str; - - GetPKCS7(self, pkcs7); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(ePKCS7Error, NULL); - } - if (!PEM_write_bio_PKCS7(out, pkcs7)) { - BIO_free(out); - ossl_raise(ePKCS7Error, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * SIGNER INFO - */ -static VALUE -ossl_pkcs7si_alloc(VALUE klass) -{ - PKCS7_SIGNER_INFO *p7si; - VALUE obj; - - if (!(p7si = PKCS7_SIGNER_INFO_new())) { - ossl_raise(ePKCS7Error, NULL); - } - WrapPKCS7si(klass, obj, p7si); - - return obj; -} - -static VALUE -ossl_pkcs7si_initialize(VALUE self, VALUE cert, VALUE key, VALUE digest) -{ - PKCS7_SIGNER_INFO *p7si; - EVP_PKEY *pkey; - X509 *x509; - const EVP_MD *md; - - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ - md = GetDigestPtr(digest); - GetPKCS7si(self, p7si); - if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, (EVP_MD*)md))) { - ossl_raise(ePKCS7Error, NULL); - } - - return self; -} - -static VALUE -ossl_pkcs7si_get_issuer(VALUE self) -{ - PKCS7_SIGNER_INFO *p7si; - - GetPKCS7si(self, p7si); - - return ossl_x509name_new(p7si->issuer_and_serial->issuer); -} - -static VALUE -ossl_pkcs7si_get_serial(VALUE self) -{ - PKCS7_SIGNER_INFO *p7si; - - GetPKCS7si(self, p7si); - - return asn1integer_to_num(p7si->issuer_and_serial->serial); -} - -static VALUE -ossl_pkcs7si_get_signed_time(VALUE self) -{ - PKCS7_SIGNER_INFO *p7si; - ASN1_TYPE *asn1obj; - - GetPKCS7si(self, p7si); - - if (!(asn1obj = PKCS7_get_signed_attribute(p7si, NID_pkcs9_signingTime))) { - ossl_raise(ePKCS7Error, NULL); - } - if (asn1obj->type == V_ASN1_UTCTIME) { - return asn1time_to_time(asn1obj->value.utctime); - } - /* - * OR - * ossl_raise(ePKCS7Error, "..."); - * ? - */ - - return Qnil; -} - -/* - * RECIPIENT INFO - */ -static VALUE -ossl_pkcs7ri_alloc(VALUE klass) -{ - PKCS7_RECIP_INFO *p7ri; - VALUE obj; - - if (!(p7ri = PKCS7_RECIP_INFO_new())) { - ossl_raise(ePKCS7Error, NULL); - } - WrapPKCS7ri(klass, obj, p7ri); - - return obj; -} - -static VALUE -ossl_pkcs7ri_initialize(VALUE self, VALUE cert) -{ - PKCS7_RECIP_INFO *p7ri; - X509 *x509; - - x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ - GetPKCS7ri(self, p7ri); - if (!PKCS7_RECIP_INFO_set(p7ri, x509)) { - ossl_raise(ePKCS7Error, NULL); - } - - return self; -} - -static VALUE -ossl_pkcs7ri_get_issuer(VALUE self) -{ - PKCS7_RECIP_INFO *p7ri; - - GetPKCS7ri(self, p7ri); - - return ossl_x509name_new(p7ri->issuer_and_serial->issuer); -} - -static VALUE -ossl_pkcs7ri_get_serial(VALUE self) -{ - PKCS7_RECIP_INFO *p7ri; - - GetPKCS7ri(self, p7ri); - - return asn1integer_to_num(p7ri->issuer_and_serial->serial); -} - -static VALUE -ossl_pkcs7ri_get_enc_key(VALUE self) -{ - PKCS7_RECIP_INFO *p7ri; - - GetPKCS7ri(self, p7ri); - - return asn1str_to_str(p7ri->enc_key); -} - -/* - * INIT - */ -void -Init_ossl_pkcs7() -{ - cPKCS7 = rb_define_class_under(mOSSL, "PKCS7", rb_cObject); - ePKCS7Error = rb_define_class_under(cPKCS7, "PKCS7Error", eOSSLError); - rb_define_singleton_method(cPKCS7, "read_smime", ossl_pkcs7_s_read_smime, 1); - rb_define_singleton_method(cPKCS7, "write_smime", ossl_pkcs7_s_write_smime, -1); - rb_define_singleton_method(cPKCS7, "sign", ossl_pkcs7_s_sign, -1); - rb_define_singleton_method(cPKCS7, "encrypt", ossl_pkcs7_s_encrypt, -1); - rb_attr(cPKCS7, rb_intern("data"), 1, 0, Qfalse); - rb_attr(cPKCS7, rb_intern("error_string"), 1, 1, Qfalse); - rb_define_alloc_func(cPKCS7, ossl_pkcs7_alloc); - rb_define_copy_func(cPKCS7, ossl_pkcs7_copy); - rb_define_method(cPKCS7, "initialize", ossl_pkcs7_initialize, -1); - rb_define_method(cPKCS7, "type=", ossl_pkcs7_set_type, 1); - rb_define_method(cPKCS7, "type", ossl_pkcs7_get_type, 0); - rb_define_method(cPKCS7, "detached=", ossl_pkcs7_set_detached, 1); - rb_define_method(cPKCS7, "detached", ossl_pkcs7_get_detached, 0); - rb_define_method(cPKCS7, "detached?", ossl_pkcs7_detached_p, 0); - rb_define_method(cPKCS7, "cipher=", ossl_pkcs7_set_cipher, 1); - rb_define_method(cPKCS7, "add_signer", ossl_pkcs7_add_signer, 1); - rb_define_method(cPKCS7, "signers", ossl_pkcs7_get_signer, 0); - rb_define_method(cPKCS7, "add_recipient", ossl_pkcs7_add_recipient, 1); - rb_define_method(cPKCS7, "recipients", ossl_pkcs7_get_recipient, 0); - rb_define_method(cPKCS7, "add_certificate", ossl_pkcs7_add_certificate, 1); - rb_define_method(cPKCS7, "certificates=", ossl_pkcs7_set_certificates, 1); - rb_define_method(cPKCS7, "certificates", ossl_pkcs7_get_certificates, 0); - rb_define_method(cPKCS7, "add_crl", ossl_pkcs7_add_crl, 1); - rb_define_method(cPKCS7, "crls=", ossl_pkcs7_set_crls, 1); - rb_define_method(cPKCS7, "crls", ossl_pkcs7_get_crls, 0); - rb_define_method(cPKCS7, "add_data", ossl_pkcs7_add_data, 1); - rb_define_alias(cPKCS7, "data=", "add_data"); - rb_define_method(cPKCS7, "verify", ossl_pkcs7_verify, -1); - rb_define_method(cPKCS7, "decrypt", ossl_pkcs7_decrypt, -1); - rb_define_method(cPKCS7, "to_pem", ossl_pkcs7_to_pem, 0); - rb_define_alias(cPKCS7, "to_s", "to_pem"); - rb_define_method(cPKCS7, "to_der", ossl_pkcs7_to_der, 0); - - cPKCS7Signer = rb_define_class_under(cPKCS7, "SignerInfo", rb_cObject); - rb_define_const(cPKCS7, "Signer", cPKCS7Signer); - rb_define_alloc_func(cPKCS7Signer, ossl_pkcs7si_alloc); - rb_define_method(cPKCS7Signer, "initialize", ossl_pkcs7si_initialize,3); - rb_define_method(cPKCS7Signer, "issuer", ossl_pkcs7si_get_issuer, 0); - rb_define_alias(cPKCS7Signer, "name", "issuer"); - rb_define_method(cPKCS7Signer, "serial", ossl_pkcs7si_get_serial,0); - rb_define_method(cPKCS7Signer,"signed_time",ossl_pkcs7si_get_signed_time,0); - - cPKCS7Recipient = rb_define_class_under(cPKCS7,"RecipientInfo",rb_cObject); - rb_define_alloc_func(cPKCS7Recipient, ossl_pkcs7ri_alloc); - rb_define_method(cPKCS7Recipient, "initialize", ossl_pkcs7ri_initialize,1); - rb_define_method(cPKCS7Recipient, "issuer", ossl_pkcs7ri_get_issuer,0); - rb_define_method(cPKCS7Recipient, "serial", ossl_pkcs7ri_get_serial,0); - rb_define_method(cPKCS7Recipient, "enc_key", ossl_pkcs7ri_get_enc_key,0); - -#define DefPKCS7Const(x) rb_define_const(cPKCS7, #x, INT2NUM(PKCS7_##x)) - - DefPKCS7Const(TEXT); - DefPKCS7Const(NOCERTS); - DefPKCS7Const(NOSIGS); - DefPKCS7Const(NOCHAIN); - DefPKCS7Const(NOINTERN); - DefPKCS7Const(NOVERIFY); - DefPKCS7Const(DETACHED); - DefPKCS7Const(BINARY); - DefPKCS7Const(NOATTR); - DefPKCS7Const(NOSMIMECAP); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_pkcs7.h b/ruby_1_9_3/ext/openssl/ossl_pkcs7.h deleted file mode 100644 index 371c421103..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkcs7.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_PKCS7_H_) -#define _OSSL_PKCS7_H_ - -extern VALUE cPKCS7; -extern VALUE cPKCS7Signer; -extern VALUE cPKCS7Recipient; -extern VALUE ePKCS7Error; - -void Init_ossl_pkcs7(void); - -#endif /* _OSSL_PKCS7_H_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_pkey.c b/ruby_1_9_3/ext/openssl/ossl_pkey.c deleted file mode 100644 index f785e66c00..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkey.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -/* - * Classes - */ -VALUE mPKey; -VALUE cPKey; -VALUE ePKeyError; -ID id_private_q; - -/* - * callback for generating keys - */ -void -ossl_generate_cb(int p, int n, void *arg) -{ - VALUE ary; - - ary = rb_ary_new2(2); - rb_ary_store(ary, 0, INT2NUM(p)); - rb_ary_store(ary, 1, INT2NUM(n)); - - rb_yield(ary); -} - -/* - * Public - */ -VALUE -ossl_pkey_new(EVP_PKEY *pkey) -{ - if (!pkey) { - ossl_raise(ePKeyError, "Cannot make new key from NULL."); - } - switch (EVP_PKEY_type(pkey->type)) { -#if !defined(OPENSSL_NO_RSA) - case EVP_PKEY_RSA: - return ossl_rsa_new(pkey); -#endif -#if !defined(OPENSSL_NO_DSA) - case EVP_PKEY_DSA: - return ossl_dsa_new(pkey); -#endif -#if !defined(OPENSSL_NO_DH) - case EVP_PKEY_DH: - return ossl_dh_new(pkey); -#endif -#if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL) - case EVP_PKEY_EC: - return ossl_ec_new(pkey); -#endif - default: - ossl_raise(ePKeyError, "unsupported key type"); - } - return Qnil; /* not reached */ -} - -VALUE -ossl_pkey_new_from_file(VALUE filename) -{ - FILE *fp; - EVP_PKEY *pkey; - - SafeStringValue(filename); - if (!(fp = fopen(RSTRING_PTR(filename), "r"))) { - ossl_raise(ePKeyError, "%s", strerror(errno)); - } - - pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL); - fclose(fp); - if (!pkey) { - ossl_raise(ePKeyError, NULL); - } - - return ossl_pkey_new(pkey); -} - -/* - * call-seq: - * OpenSSL::PKey.read(string [, pwd ] ) -> PKey - * OpenSSL::PKey.read(file [, pwd ]) -> PKey - * - * === Parameters - * * +string+ is a DER- or PEM-encoded string containing an arbitrary private - * or public key. - * * +file+ is an instance of +File+ containing a DER- or PEM-encoded - * arbitrary private or public key. - * * +pwd+ is an optional password in case +string+ or +file+ is an encrypted - * PEM resource. - */ -static VALUE -ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - BIO *bio; - VALUE data, pass; - char *passwd = NULL; - - rb_scan_args(argc, argv, "11", &data, &pass); - - bio = ossl_obj2bio(data); - if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) { - OSSL_BIO_reset(bio); - if (!NIL_P(pass)) { - passwd = StringValuePtr(pass); - } - if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) { - OSSL_BIO_reset(bio); - if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) { - OSSL_BIO_reset(bio); - if (!NIL_P(pass)) { - passwd = StringValuePtr(pass); - } - pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd); - } - } - } - - BIO_free(bio); - if (!pkey) - ossl_raise(rb_eArgError, "Could not parse PKey"); - return ossl_pkey_new(pkey); -} - -EVP_PKEY * -GetPKeyPtr(VALUE obj) -{ - EVP_PKEY *pkey; - - SafeGetPKey(obj, pkey); - - return pkey; -} - -EVP_PKEY * -GetPrivPKeyPtr(VALUE obj) -{ - EVP_PKEY *pkey; - - if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) { - ossl_raise(rb_eArgError, "Private key is needed."); - } - SafeGetPKey(obj, pkey); - - return pkey; -} - -EVP_PKEY * -DupPKeyPtr(VALUE obj) -{ - EVP_PKEY *pkey; - - SafeGetPKey(obj, pkey); - CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - - return pkey; -} - -EVP_PKEY * -DupPrivPKeyPtr(VALUE obj) -{ - EVP_PKEY *pkey; - - if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) { - ossl_raise(rb_eArgError, "Private key is needed."); - } - SafeGetPKey(obj, pkey); - CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - - return pkey; -} - -/* - * Private - */ -static VALUE -ossl_pkey_alloc(VALUE klass) -{ - EVP_PKEY *pkey; - VALUE obj; - - if (!(pkey = EVP_PKEY_new())) { - ossl_raise(ePKeyError, NULL); - } - WrapPKey(klass, obj, pkey); - - return obj; -} - -/* - * call-seq: - * PKeyClass.new -> self - * - * Because PKey is an abstract class, actually calling this method explicitly - * will raise a +NotImplementedError+. - */ -static VALUE -ossl_pkey_initialize(VALUE self) -{ - if (rb_obj_is_instance_of(self, cPKey)) { - ossl_raise(rb_eNotImpError, "OpenSSL::PKey::PKey is an abstract class."); - } - return self; -} - -/* - * call-seq: - * pkey.sign(digest, data) -> String - * - * To sign the +String+ +data+, +digest+, an instance of OpenSSL::Digest, must - * be provided. The return value is again a +String+ containing the signature. - * A PKeyError is raised should errors occur. - * Any previous state of the +Digest+ instance is irrelevant to the signature - * outcome, the digest instance is reset to its initial state during the - * operation. - * - * == Example - * data = 'Sign me!' - * digest = OpenSSL::Digest::SHA256.new - * pkey = OpenSSL::PKey::RSA.new(2048) - * signature = pkey.sign(digest, data) - */ -static VALUE -ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) -{ - EVP_PKEY *pkey; - EVP_MD_CTX ctx; - unsigned int buf_len; - VALUE str; - - if (rb_funcall(self, id_private_q, 0, NULL) != Qtrue) { - ossl_raise(rb_eArgError, "Private key is needed."); - } - GetPKey(self, pkey); - EVP_SignInit(&ctx, GetDigestPtr(digest)); - StringValue(data); - EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data)); - str = rb_str_new(0, EVP_PKEY_size(pkey)+16); - if (!EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey)) - ossl_raise(ePKeyError, NULL); - assert((long)buf_len <= RSTRING_LEN(str)); - rb_str_set_len(str, buf_len); - - return str; -} - -/* - * call-seq: - * pkey.verify(digest, signature, data) -> String - * - * To verify the +String+ +signature+, +digest+, an instance of - * OpenSSL::Digest, must be provided to re-compute the message digest of the - * original +data+, also a +String+. The return value is +true+ if the - * signature is valid, +false+ otherwise. A PKeyError is raised should errors - * occur. - * Any previous state of the +Digest+ instance is irrelevant to the validation - * outcome, the digest instance is reset to its initial state during the - * operation. - * - * == Example - * data = 'Sign me!' - * digest = OpenSSL::Digest::SHA256.new - * pkey = OpenSSL::PKey::RSA.new(2048) - * signature = pkey.sign(digest, data) - * pub_key = pkey.public_key - * puts pub_key.verify(digest, signature, data) # => true - */ -static VALUE -ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) -{ - EVP_PKEY *pkey; - EVP_MD_CTX ctx; - - GetPKey(self, pkey); - EVP_VerifyInit(&ctx, GetDigestPtr(digest)); - StringValue(sig); - StringValue(data); - EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data)); - switch (EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey)) { - case 0: - return Qfalse; - case 1: - return Qtrue; - default: - ossl_raise(ePKeyError, NULL); - } - return Qnil; /* dummy */ -} - -/* - * INIT - */ -void -Init_ossl_pkey() -{ -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ -#endif - - /* Document-module: OpenSSL::PKey - * - * == Asymmetric Public Key Algorithms - * - * Asymmetric public key algorithms solve the problem of establishing and - * sharing secret keys to en-/decrypt messages. The key in such an - * algorithm consists of two parts: a public key that may be distributed - * to others and a private key that needs to remain secret. - * - * Messages encrypted with a public key can only be encrypted by - * recipients that are in possession of the associated private key. - * Since public key algorithms are considerably slower than symmetric - * key algorithms (cf. OpenSSL::Cipher) they are often used to establish - * a symmetric key shared between two parties that are in possession of - * each other's public key. - * - * Asymmetric algorithms offer a lot of nice features that are used in a - * lot of different areas. A very common application is the creation and - * validation of digital signatures. To sign a document, the signatory - * generally uses a message digest algorithm (cf. OpenSSL::Digest) to - * compute a digest of the document that is then encrypted (i.e. signed) - * using the private key. Anyone in possession of the public key may then - * verify the signature by computing the message digest of the original - * document on their own, decrypting the signature using the signatory's - * public key and comparing the result to the message digest they - * previously computed. The signature is valid if and only if the - * decrypted signature is equal to this message digest. - * - * The PKey module offers support for three popular public/private key - * algorithms: - * * RSA (OpenSSL::PKey::RSA) - * * DSA (OpenSSL::PKey::DSA) - * * Elliptic Curve Cryptography (OpenSSL::PKey::EC) - * Each of these implementations is in fact a sub-class of the abstract - * PKey class which offers the interface for supporting digital signatures - * in the form of PKey#sign and PKey#verify. - * - * == Diffie-Hellman Key Exchange - * - * Finally PKey also features OpenSSL::PKey::DH, an implementation of - * the Diffie-Hellman key exchange protocol based on discrete logarithms - * in finite fields, the same basis that DSA is built on. - * The Diffie-Hellman protocol can be used to exchange (symmetric) keys - * over insecure channels without needing any prior joint knowledge - * between the participating parties. As the security of DH demands - * relatively long "public keys" (i.e. the part that is overtly - * transmitted between participants) DH tends to be quite slow. If - * security or speed is your primary concern, OpenSSL::PKey::EC offers - * another implementation of the Diffie-Hellman protocol. - * - */ - mPKey = rb_define_module_under(mOSSL, "PKey"); - - /* Document-class: OpenSSL::PKey::PKeyError - * - *Raised when errors occur during PKey#sign or PKey#verify. - */ - ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); - - /* Document-class: OpenSSL::PKey::PKey - * - * An abstract class that bundles signature creation (PKey#sign) and - * validation (PKey#verify) that is common to all implementations except - * OpenSSL::PKey::DH - * * OpenSSL::PKey::RSA - * * OpenSSL::PKey::DSA - * * OpenSSL::PKey::EC - */ - cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); - - rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1); - - rb_define_alloc_func(cPKey, ossl_pkey_alloc); - rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); - - rb_define_method(cPKey, "sign", ossl_pkey_sign, 2); - rb_define_method(cPKey, "verify", ossl_pkey_verify, 3); - - id_private_q = rb_intern("private?"); - - /* - * INIT rsa, dsa, dh, ec - */ - Init_ossl_rsa(); - Init_ossl_dsa(); - Init_ossl_dh(); - Init_ossl_ec(); -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_pkey.h b/ruby_1_9_3/ext/openssl/ossl_pkey.h deleted file mode 100644 index 5e3329d326..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkey.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_PKEY_H_) -#define _OSSL_PKEY_H_ - -extern VALUE mPKey; -extern VALUE cPKey; -extern VALUE ePKeyError; -extern ID id_private_q; - -#define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), "private", Qtrue) -#define OSSL_PKEY_SET_PUBLIC(obj) rb_iv_set((obj), "private", Qfalse) -#define OSSL_PKEY_IS_PRIVATE(obj) (rb_iv_get((obj), "private") == Qtrue) - -#define WrapPKey(klass, obj, pkey) do { \ - if (!(pkey)) { \ - rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, EVP_PKEY_free, (pkey)); \ - OSSL_PKEY_SET_PUBLIC(obj); \ -} while (0) -#define GetPKey(obj, pkey) do {\ - Data_Get_Struct((obj), EVP_PKEY, (pkey));\ - if (!(pkey)) { \ - rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!");\ - } \ -} while (0) -#define SafeGetPKey(obj, pkey) do { \ - OSSL_Check_Kind((obj), cPKey); \ - GetPKey((obj), (pkey)); \ -} while (0) - -void ossl_generate_cb(int, int, void *); - -VALUE ossl_pkey_new(EVP_PKEY *); -VALUE ossl_pkey_new_from_file(VALUE); -EVP_PKEY *GetPKeyPtr(VALUE); -EVP_PKEY *DupPKeyPtr(VALUE); -EVP_PKEY *GetPrivPKeyPtr(VALUE); -EVP_PKEY *DupPrivPKeyPtr(VALUE); -void Init_ossl_pkey(void); - -/* - * RSA - */ -extern VALUE cRSA; -extern VALUE eRSAError; - -VALUE ossl_rsa_new(EVP_PKEY *); -void Init_ossl_rsa(void); - -/* - * DSA - */ -extern VALUE cDSA; -extern VALUE eDSAError; - -VALUE ossl_dsa_new(EVP_PKEY *); -void Init_ossl_dsa(void); - -/* - * DH - */ -extern VALUE cDH; -extern VALUE eDHError; -extern DH *OSSL_DEFAULT_DH_512; -extern DH *OSSL_DEFAULT_DH_1024; - -VALUE ossl_dh_new(EVP_PKEY *); -void Init_ossl_dh(void); - -/* - * EC - */ -extern VALUE cEC; -extern VALUE eECError; -extern VALUE cEC_GROUP; -extern VALUE eEC_GROUP; -extern VALUE cEC_POINT; -extern VALUE eEC_POINT; -VALUE ossl_ec_new(EVP_PKEY *); -void Init_ossl_ec(void); - - -#define OSSL_PKEY_BN(keytype, name) \ -/* \ - * call-seq: \ - * key.##name -> aBN \ - */ \ -static VALUE ossl_##keytype##_get_##name(VALUE self) \ -{ \ - EVP_PKEY *pkey; \ - BIGNUM *bn; \ - \ - GetPKey(self, pkey); \ - bn = pkey->pkey.keytype->name; \ - if (bn == NULL) \ - return Qnil; \ - return ossl_bn_new(bn); \ -} \ -/* \ - * call-seq: \ - * key.##name = bn -> bn \ - */ \ -static VALUE ossl_##keytype##_set_##name(VALUE self, VALUE bignum) \ -{ \ - EVP_PKEY *pkey; \ - BIGNUM *bn; \ - \ - GetPKey(self, pkey); \ - if (NIL_P(bignum)) { \ - BN_clear_free(pkey->pkey.keytype->name); \ - pkey->pkey.keytype->name = NULL; \ - return Qnil; \ - } \ - \ - bn = GetBNPtr(bignum); \ - if (pkey->pkey.keytype->name == NULL) \ - pkey->pkey.keytype->name = BN_new(); \ - if (pkey->pkey.keytype->name == NULL) \ - ossl_raise(eBNError, NULL); \ - if (BN_copy(pkey->pkey.keytype->name, bn) == NULL) \ - ossl_raise(eBNError, NULL); \ - return bignum; \ -} - -#define DEF_OSSL_PKEY_BN(class, keytype, name) \ -do { \ - rb_define_method((class), #name, ossl_##keytype##_get_##name, 0); \ - rb_define_method((class), #name "=", ossl_##keytype##_set_##name, 1);\ -} while (0) - -#endif /* _OSSL_PKEY_H_ */ diff --git a/ruby_1_9_3/ext/openssl/ossl_pkey_dh.c b/ruby_1_9_3/ext/openssl/ossl_pkey_dh.c deleted file mode 100644 index 748d9c82fd..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkey_dh.c +++ /dev/null @@ -1,618 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(OPENSSL_NO_DH) - -#include "ossl.h" - -#define GetPKeyDH(obj, pkey) do { \ - GetPKey((obj), (pkey)); \ - if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_DH) { /* PARANOIA? */ \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \ - } \ -} while (0) - -#define DH_HAS_PRIVATE(dh) ((dh)->priv_key) - -#ifdef OSSL_ENGINE_ENABLED -# define DH_PRIVATE(dh) (DH_HAS_PRIVATE(dh) || (dh)->engine) -#else -# define DH_PRIVATE(dh) DH_HAS_PRIVATE(dh) -#endif - - -/* - * Classes - */ -VALUE cDH; -VALUE eDHError; - -/* - * Public - */ -static VALUE -dh_instance(VALUE klass, DH *dh) -{ - EVP_PKEY *pkey; - VALUE obj; - - if (!dh) { - return Qfalse; - } - if (!(pkey = EVP_PKEY_new())) { - return Qfalse; - } - if (!EVP_PKEY_assign_DH(pkey, dh)) { - EVP_PKEY_free(pkey); - return Qfalse; - } - WrapPKey(klass, obj, pkey); - - return obj; -} - -VALUE -ossl_dh_new(EVP_PKEY *pkey) -{ - VALUE obj; - - if (!pkey) { - obj = dh_instance(cDH, DH_new()); - } else { - if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) { - ossl_raise(rb_eTypeError, "Not a DH key!"); - } - WrapPKey(cDH, obj, pkey); - } - if (obj == Qfalse) { - ossl_raise(eDHError, NULL); - } - - return obj; -} - -/* - * Private - */ -static DH * -dh_generate(int size, int gen) -{ - DH *dh; - - dh = DH_generate_parameters(size, gen, - rb_block_given_p() ? ossl_generate_cb : NULL, - NULL); - if (!dh) return 0; - - if (!DH_generate_key(dh)) { - DH_free(dh); - return 0; - } - - return dh; -} - -/* - * call-seq: - * DH.generate(size [, generator]) -> dh - * - * Creates a new DH instance from scratch by generating the private and public - * components alike. - * - * === Parameters - * * +size+ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. - * * +generator+ is a small number > 1, typically 2 or 5. - * - */ -static VALUE -ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass) -{ - DH *dh ; - int g = 2; - VALUE size, gen, obj; - - if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) { - g = NUM2INT(gen); - } - dh = dh_generate(NUM2INT(size), g); - obj = dh_instance(klass, dh); - if (obj == Qfalse) { - DH_free(dh); - ossl_raise(eDHError, NULL); - } - - return obj; -} - -/* - * call-seq: - * DH.new([size [, generator] | string]) -> dh - * - * Either generates a DH instance from scratch or by reading already existing - * DH parameters from +string+. Note that when reading a DH instance from - * data that was encoded from a DH instance by using DH#to_pem or DH#to_der - * the result will *not* contain a public/private key pair yet. This needs to - * be generated using DH#generate_key! first. - * - * === Parameters - * * +size+ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. - * * +generator+ is a small number > 1, typically 2 or 5. - * * +string+ contains the DER or PEM encoded key. - * - * === Examples - * DH.new # -> dh - * DH.new(1024) # -> dh - * DH.new(1024, 5) # -> dh - * #Reading DH parameters - * dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet - * dh.generate_key! # -> dh with public and private key - */ -static VALUE -ossl_dh_initialize(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - DH *dh; - int g = 2; - BIO *in; - VALUE arg, gen; - - GetPKey(self, pkey); - if(rb_scan_args(argc, argv, "02", &arg, &gen) == 0) { - dh = DH_new(); - } - else if (FIXNUM_P(arg)) { - if (!NIL_P(gen)) { - g = NUM2INT(gen); - } - if (!(dh = dh_generate(FIX2INT(arg), g))) { - ossl_raise(eDHError, NULL); - } - } - else { - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); - if (!dh){ - OSSL_BIO_reset(in); - dh = d2i_DHparams_bio(in, NULL); - } - BIO_free(in); - if (!dh) { - ossl_raise(eDHError, NULL); - } - } - if (!EVP_PKEY_assign_DH(pkey, dh)) { - DH_free(dh); - ossl_raise(eDHError, NULL); - } - return self; -} - -/* - * call-seq: - * dh.public? -> true | false - * - * Indicates whether this DH instance has a public key associated with it or - * not. The public key may be retrieved with DH#pub_key. - */ -static VALUE -ossl_dh_is_public(VALUE self) -{ - EVP_PKEY *pkey; - - GetPKeyDH(self, pkey); - - return (pkey->pkey.dh->pub_key) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * dh.private? -> true | false - * - * Indicates whether this DH instance has a private key associated with it or - * not. The private key may be retrieved with DH#priv_key. - */ -static VALUE -ossl_dh_is_private(VALUE self) -{ - EVP_PKEY *pkey; - - GetPKeyDH(self, pkey); - - return (DH_PRIVATE(pkey->pkey.dh)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * dh.to_pem -> aString - * - * Encodes this DH to its PEM encoding. Note that any existing per-session - * public/private keys will *not* get encoded, just the Diffie-Hellman - * parameters will be encoded. - */ -static VALUE -ossl_dh_export(VALUE self) -{ - EVP_PKEY *pkey; - BIO *out; - VALUE str; - - GetPKeyDH(self, pkey); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eDHError, NULL); - } - if (!PEM_write_bio_DHparams(out, pkey->pkey.dh)) { - BIO_free(out); - ossl_raise(eDHError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * dh.to_der -> aString - * - * Encodes this DH to its DER encoding. Note that any existing per-session - * public/private keys will *not* get encoded, just the Diffie-Hellman - * parameters will be encoded. - - */ -static VALUE -ossl_dh_to_der(VALUE self) -{ - EVP_PKEY *pkey; - unsigned char *p; - long len; - VALUE str; - - GetPKeyDH(self, pkey); - if((len = i2d_DHparams(pkey->pkey.dh, NULL)) <= 0) - ossl_raise(eDHError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_DHparams(pkey->pkey.dh, &p) < 0) - ossl_raise(eDHError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -/* - * call-seq: - * dh.params -> hash - * - * Stores all parameters of key to the hash - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dh_get_params(VALUE self) -{ - EVP_PKEY *pkey; - VALUE hash; - - GetPKeyDH(self, pkey); - - hash = rb_hash_new(); - - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dh->p)); - rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dh->g)); - rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dh->pub_key)); - rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dh->priv_key)); - - return hash; -} - -/* - * call-seq: - * dh.to_text -> aString - * - * Prints all parameters of key to buffer - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dh_to_text(VALUE self) -{ - EVP_PKEY *pkey; - BIO *out; - VALUE str; - - GetPKeyDH(self, pkey); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eDHError, NULL); - } - if (!DHparams_print(out, pkey->pkey.dh)) { - BIO_free(out); - ossl_raise(eDHError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * dh.public_key -> aDH - * - * Returns a new DH instance that carries just the public information, i.e. - * the prime +p+ and the generator +g+, but no public/private key yet. Such - * a pair may be generated using DH#generate_key!. The "public key" needed - * for a key exchange with DH#compute_key is considered as per-session - * information and may be retrieved with DH#pub_key once a key pair has - * been generated. - * If the current instance already contains private information (and thus a - * valid public/private key pair), this information will no longer be present - * in the new instance generated by DH#public_key. This feature is helpful for - * publishing the Diffie-Hellman parameters without leaking any of the private - * per-session information. - * - * === Example - * dh = OpenSSL::PKey::DH.new(2048) # has public and private key set - * public_key = dh.public_key # contains only prime and generator - * parameters = public_key.to_der # it's safe to publish this - */ -static VALUE -ossl_dh_to_public_key(VALUE self) -{ - EVP_PKEY *pkey; - DH *dh; - VALUE obj; - - GetPKeyDH(self, pkey); - dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */ - obj = dh_instance(CLASS_OF(self), dh); - if (obj == Qfalse) { - DH_free(dh); - ossl_raise(eDHError, NULL); - } - - return obj; -} - -/* - * call-seq: - * dh.check_params -> true | false - * - * Validates the Diffie-Hellman parameters associated with this instance. - * It checks whether a safe prime and a suitable generator are used. If this - * is not the case, +false+ is returned. - */ -static VALUE -ossl_dh_check_params(VALUE self) -{ - DH *dh; - EVP_PKEY *pkey; - int codes; - - GetPKeyDH(self, pkey); - dh = pkey->pkey.dh; - - if (!DH_check(dh, &codes)) { - return Qfalse; - } - - return codes == 0 ? Qtrue : Qfalse; -} - -/* - * call-seq: - * dh.generate_key! -> self - * - * Generates a private and public key unless a private key already exists. - * If this DH instance was generated from public DH parameters (e.g. by - * encoding the result of DH#public_key), then this method needs to be - * called first in order to generate the per-session keys before performing - * the actual key exchange. - * - * === Example - * dh = OpenSSL::PKey::DH.new(2048) - * public_key = dh.public_key #contains no private/public key yet - * public_key.generate_key! - * puts public_key.private? # => true - */ -static VALUE -ossl_dh_generate_key(VALUE self) -{ - DH *dh; - EVP_PKEY *pkey; - - GetPKeyDH(self, pkey); - dh = pkey->pkey.dh; - - if (!DH_generate_key(dh)) - ossl_raise(eDHError, "Failed to generate key"); - return self; -} - -/* - * call-seq: - * dh.compute_key(pub_bn) -> aString - * - * Returns a String containing a shared secret computed from the other party's public value. - * See DH_compute_key() for further information. - * - * === Parameters - * * +pub_bn+ is a OpenSSL::BN, *not* the DH instance returned by - * DH#public_key as that contains the DH parameters only. - */ -static VALUE -ossl_dh_compute_key(VALUE self, VALUE pub) -{ - DH *dh; - EVP_PKEY *pkey; - BIGNUM *pub_key; - VALUE str; - int len; - - GetPKeyDH(self, pkey); - dh = pkey->pkey.dh; - pub_key = GetBNPtr(pub); - len = DH_size(dh); - str = rb_str_new(0, len); - if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) { - ossl_raise(eDHError, NULL); - } - rb_str_set_len(str, len); - - return str; -} - -OSSL_PKEY_BN(dh, p) -OSSL_PKEY_BN(dh, g) -OSSL_PKEY_BN(dh, pub_key) -OSSL_PKEY_BN(dh, priv_key) - -/* - * -----BEGIN DH PARAMETERS----- - * MEYCQQD0zXHljRg/mJ9PYLACLv58Cd8VxBxxY7oEuCeURMiTqEhMym16rhhKgZG2 - * zk2O9uUIBIxSj+NKMURHGaFKyIvLAgEC - * -----END DH PARAMETERS----- - */ -static unsigned char DEFAULT_DH_512_PRIM[] = { - 0xf4, 0xcd, 0x71, 0xe5, 0x8d, 0x18, 0x3f, 0x98, - 0x9f, 0x4f, 0x60, 0xb0, 0x02, 0x2e, 0xfe, 0x7c, - 0x09, 0xdf, 0x15, 0xc4, 0x1c, 0x71, 0x63, 0xba, - 0x04, 0xb8, 0x27, 0x94, 0x44, 0xc8, 0x93, 0xa8, - 0x48, 0x4c, 0xca, 0x6d, 0x7a, 0xae, 0x18, 0x4a, - 0x81, 0x91, 0xb6, 0xce, 0x4d, 0x8e, 0xf6, 0xe5, - 0x08, 0x04, 0x8c, 0x52, 0x8f, 0xe3, 0x4a, 0x31, - 0x44, 0x47, 0x19, 0xa1, 0x4a, 0xc8, 0x8b, 0xcb, -}; -static unsigned char DEFAULT_DH_512_GEN[] = { 0x02 }; -DH *OSSL_DEFAULT_DH_512 = NULL; - -/* - * -----BEGIN DH PARAMETERS----- - * MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ - * AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR - * T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC - * -----END DH PARAMETERS----- - */ -static unsigned char DEFAULT_DH_1024_PRIM[] = { - 0x9d, 0x25, 0x39, 0x5c, 0xb4, 0x54, 0x8a, 0xff, - 0x25, 0xe6, 0xd6, 0x9f, 0x4c, 0xc3, 0xc1, 0x8d, - 0xa1, 0xfa, 0xba, 0x88, 0x4c, 0x53, 0xa9, 0x74, - 0xda, 0xfa, 0xba, 0x0b, 0x20, 0xbe, 0x40, 0xd7, - 0xba, 0xe7, 0x1d, 0x70, 0x28, 0x61, 0x60, 0x4c, - 0x49, 0x01, 0x5f, 0xd9, 0x0f, 0x60, 0x16, 0x3d, - 0xba, 0xd3, 0xa9, 0x5e, 0xfa, 0x98, 0x64, 0x60, - 0x26, 0x0e, 0x04, 0x75, 0xd8, 0x13, 0xd7, 0x31, - 0xb4, 0x8e, 0xad, 0xeb, 0x9c, 0x57, 0x4c, 0x8f, - 0x65, 0xf3, 0x90, 0x16, 0x31, 0xdc, 0x15, 0x6f, - 0x7d, 0x1d, 0x00, 0xae, 0x76, 0xf2, 0xd1, 0x11, - 0xd1, 0x4f, 0x88, 0x7b, 0x29, 0x9f, 0xf6, 0xce, - 0x68, 0xef, 0x57, 0xe7, 0x85, 0xf2, 0x40, 0x54, - 0x1c, 0x12, 0x40, 0xa2, 0x35, 0x25, 0xcf, 0x12, - 0xa3, 0xe1, 0x07, 0x8e, 0xdb, 0x1d, 0xb4, 0x14, - 0xff, 0x57, 0xe7, 0x19, 0x8d, 0x51, 0x77, 0x83 -}; -static unsigned char DEFAULT_DH_1024_GEN[] = { 0x02 }; -DH *OSSL_DEFAULT_DH_1024 = NULL; - -static DH* -ossl_create_dh(unsigned char *p, size_t plen, unsigned char *g, size_t glen) -{ - DH *dh; - - if ((dh = DH_new()) == NULL) ossl_raise(eDHError, NULL); - dh->p = BN_bin2bn(p, rb_long2int(plen), NULL); - dh->g = BN_bin2bn(g, rb_long2int(glen), NULL); - if (dh->p == NULL || dh->g == NULL){ - DH_free(dh); - ossl_raise(eDHError, NULL); - } - - return dh; -} - -/* - * INIT - */ -void -Init_ossl_dh() -{ -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */ - mPKey = rb_define_module_under(mOSSL, "PKey"); -#endif - - /* Document-class: OpenSSL::PKey::DHError - * - * Generic exception that is raised if an operation on a DH PKey - * fails unexpectedly or in case an instantiation of an instance of DH - * fails due to non-conformant input data. - */ - eDHError = rb_define_class_under(mPKey, "DHError", ePKeyError); - /* Document-class: OpenSSL::PKey::DH - * - * An implementation of the Diffie-Hellman key exchange protocol based on - * discrete logarithms in finite fields, the same basis that DSA is built - * on. - * - * === Accessor methods for the Diffie-Hellman parameters - * * DH#p - * The prime (an OpenSSL::BN) of the Diffie-Hellman parameters. - * * DH#g - * The generator (an OpenSSL::BN) g of the Diffie-Hellman parameters. - * * DH#pub_key - * The per-session public key (an OpenSSL::BN) matching the private key. - * This needs to be passed to DH#compute_key. - * * DH#priv_key - * The per-session private key, an OpenSSL::BN. - * - * === Example of a key exchange - * dh1 = OpenSSL::PKey::DH.new(2048) - * params = dh1.public_key.to_der #you may send this publicly to the participating party - * dh2 = OpenSSL::PKey::DH.new(der) - * dh2.generate_key! #generate the per-session key pair - * symm_key1 = dh1.compute_key(dh2.pub_key) - * symm_key2 = dh2.compute_key(dh1.pub_key) - * - * puts symm_key1 == symm_key2 # => true - */ - cDH = rb_define_class_under(mPKey, "DH", cPKey); - rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1); - rb_define_method(cDH, "initialize", ossl_dh_initialize, -1); - rb_define_method(cDH, "public?", ossl_dh_is_public, 0); - rb_define_method(cDH, "private?", ossl_dh_is_private, 0); - rb_define_method(cDH, "to_text", ossl_dh_to_text, 0); - rb_define_method(cDH, "export", ossl_dh_export, 0); - rb_define_alias(cDH, "to_pem", "export"); - rb_define_alias(cDH, "to_s", "export"); - rb_define_method(cDH, "to_der", ossl_dh_to_der, 0); - rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0); - rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0); - rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0); - rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1); - - DEF_OSSL_PKEY_BN(cDH, dh, p); - DEF_OSSL_PKEY_BN(cDH, dh, g); - DEF_OSSL_PKEY_BN(cDH, dh, pub_key); - DEF_OSSL_PKEY_BN(cDH, dh, priv_key); - rb_define_method(cDH, "params", ossl_dh_get_params, 0); - - OSSL_DEFAULT_DH_512 = ossl_create_dh( - DEFAULT_DH_512_PRIM, sizeof(DEFAULT_DH_512_PRIM), - DEFAULT_DH_512_GEN, sizeof(DEFAULT_DH_512_GEN)); - OSSL_DEFAULT_DH_1024 = ossl_create_dh( - DEFAULT_DH_1024_PRIM, sizeof(DEFAULT_DH_1024_PRIM), - DEFAULT_DH_1024_GEN, sizeof(DEFAULT_DH_1024_GEN)); -} - -#else /* defined NO_DH */ -void -Init_ossl_dh() -{ -} -#endif /* NO_DH */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_pkey_dsa.c b/ruby_1_9_3/ext/openssl/ossl_pkey_dsa.c deleted file mode 100644 index 6b10e8fdf8..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkey_dsa.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(OPENSSL_NO_DSA) - -#include "ossl.h" - -#define GetPKeyDSA(obj, pkey) do { \ - GetPKey((obj), (pkey)); \ - if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_DSA) { /* PARANOIA? */ \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A DSA!"); \ - } \ -} while (0) - -#define DSA_HAS_PRIVATE(dsa) ((dsa)->priv_key) -#define DSA_PRIVATE(obj,dsa) (DSA_HAS_PRIVATE(dsa)||OSSL_PKEY_IS_PRIVATE(obj)) - -/* - * Classes - */ -VALUE cDSA; -VALUE eDSAError; - -/* - * Public - */ -static VALUE -dsa_instance(VALUE klass, DSA *dsa) -{ - EVP_PKEY *pkey; - VALUE obj; - - if (!dsa) { - return Qfalse; - } - if (!(pkey = EVP_PKEY_new())) { - return Qfalse; - } - if (!EVP_PKEY_assign_DSA(pkey, dsa)) { - EVP_PKEY_free(pkey); - return Qfalse; - } - WrapPKey(klass, obj, pkey); - - return obj; -} - -VALUE -ossl_dsa_new(EVP_PKEY *pkey) -{ - VALUE obj; - - if (!pkey) { - obj = dsa_instance(cDSA, DSA_new()); - } else { - if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DSA) { - ossl_raise(rb_eTypeError, "Not a DSA key!"); - } - WrapPKey(cDSA, obj, pkey); - } - if (obj == Qfalse) { - ossl_raise(eDSAError, NULL); - } - - return obj; -} - -/* - * Private - */ -static DSA * -dsa_generate(int size) -{ - DSA *dsa; - unsigned char seed[20]; - int seed_len = 20, counter; - unsigned long h; - - if (!RAND_bytes(seed, seed_len)) { - return 0; - } - dsa = DSA_generate_parameters(size, seed, seed_len, &counter, &h, - rb_block_given_p() ? ossl_generate_cb : NULL, - NULL); - if(!dsa) return 0; - - if (!DSA_generate_key(dsa)) { - DSA_free(dsa); - return 0; - } - - return dsa; -} - -/* - * call-seq: - * DSA.generate(size) -> dsa - * - * Creates a new DSA instance by generating a private/public key pair - * from scratch. - * - * === Parameters - * * +size+ is an integer representing the desired key size. - * - */ -static VALUE -ossl_dsa_s_generate(VALUE klass, VALUE size) -{ - DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */ - VALUE obj = dsa_instance(klass, dsa); - - if (obj == Qfalse) { - DSA_free(dsa); - ossl_raise(eDSAError, NULL); - } - - return obj; -} - -/* - * call-seq: - * DSA.new([size | string [, pass]) -> dsa - * - * Creates a new DSA instance by reading an existing key from +string+. - * - * === Parameters - * * +size+ is an integer representing the desired key size. - * * +string+ contains a DER or PEM encoded key. - * * +pass+ is a string that contains an optional password. - * - * === Examples - * DSA.new -> dsa - * DSA.new(1024) -> dsa - * DSA.new(File.read('dsa.pem')) -> dsa - * DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa - * - */ -static VALUE -ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - DSA *dsa; - BIO *in; - char *passwd = NULL; - VALUE arg, pass; - - GetPKey(self, pkey); - if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) { - dsa = DSA_new(); - } - else if (FIXNUM_P(arg)) { - if (!(dsa = dsa_generate(FIX2INT(arg)))) { - ossl_raise(eDSAError, NULL); - } - } - else { - if (!NIL_P(pass)) passwd = StringValuePtr(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); - if (!dsa) { - OSSL_BIO_reset(in); - dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL); - } - if (!dsa) { - OSSL_BIO_reset(in); - dsa = d2i_DSAPrivateKey_bio(in, NULL); - } - if (!dsa) { - OSSL_BIO_reset(in); - dsa = d2i_DSA_PUBKEY_bio(in, NULL); - } - if (!dsa) { - OSSL_BIO_reset(in); - dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL); - } - BIO_free(in); - if (!dsa) { - ERR_clear_error(); - ossl_raise(eDSAError, "Neither PUB key nor PRIV key:"); - } - } - if (!EVP_PKEY_assign_DSA(pkey, dsa)) { - DSA_free(dsa); - ossl_raise(eDSAError, NULL); - } - - return self; -} - -/* - * call-seq: - * dsa.public? -> true | false - * - * Indicates whether this DSA instance has a public key associated with it or - * not. The public key may be retrieved with DSA#public_key. - */ -static VALUE -ossl_dsa_is_public(VALUE self) -{ - EVP_PKEY *pkey; - - GetPKeyDSA(self, pkey); - - return (pkey->pkey.dsa->pub_key) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * dsa.private? -> true | false - * - * Indicates whether this DSA instance has a private key associated with it or - * not. The private key may be retrieved with DSA#private_key. - */ -static VALUE -ossl_dsa_is_private(VALUE self) -{ - EVP_PKEY *pkey; - - GetPKeyDSA(self, pkey); - - return (DSA_PRIVATE(self, pkey->pkey.dsa)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * dsa.to_pem([cipher, password]) -> aString - * - * Encodes this DSA to its PEM encoding. - * - * === Parameters - * * +cipher+ is an OpenSSL::Cipher. - * * +password+ is a string containing your password. - * - * === Examples - * DSA.to_pem -> aString - * DSA.to_pem(cipher, 'mypassword') -> aString - * - */ -static VALUE -ossl_dsa_export(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - BIO *out; - const EVP_CIPHER *ciph = NULL; - char *passwd = NULL; - VALUE cipher, pass, str; - - GetPKeyDSA(self, pkey); - rb_scan_args(argc, argv, "02", &cipher, &pass); - if (!NIL_P(cipher)) { - ciph = GetCipherPtr(cipher); - if (!NIL_P(pass)) { - passwd = StringValuePtr(pass); - } - } - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eDSAError, NULL); - } - if (DSA_HAS_PRIVATE(pkey->pkey.dsa)) { - if (!PEM_write_bio_DSAPrivateKey(out, pkey->pkey.dsa, ciph, - NULL, 0, ossl_pem_passwd_cb, passwd)){ - BIO_free(out); - ossl_raise(eDSAError, NULL); - } - } else { - if (!PEM_write_bio_DSA_PUBKEY(out, pkey->pkey.dsa)) { - BIO_free(out); - ossl_raise(eDSAError, NULL); - } - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * dsa.to_der -> aString - * - * Encodes this DSA to its DER encoding. - * - */ -static VALUE -ossl_dsa_to_der(VALUE self) -{ - EVP_PKEY *pkey; - int (*i2d_func)_((DSA*, unsigned char**)); - unsigned char *p; - long len; - VALUE str; - - GetPKeyDSA(self, pkey); - if(DSA_HAS_PRIVATE(pkey->pkey.dsa)) - i2d_func = (int(*)_((DSA*,unsigned char**)))i2d_DSAPrivateKey; - else - i2d_func = i2d_DSA_PUBKEY; - if((len = i2d_func(pkey->pkey.dsa, NULL)) <= 0) - ossl_raise(eDSAError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_func(pkey->pkey.dsa, &p) < 0) - ossl_raise(eDSAError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -/* - * call-seq: - * dsa.params -> hash - * - * Stores all parameters of key to the hash - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dsa_get_params(VALUE self) -{ - EVP_PKEY *pkey; - VALUE hash; - - GetPKeyDSA(self, pkey); - - hash = rb_hash_new(); - - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dsa->p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.dsa->q)); - rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dsa->g)); - rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dsa->pub_key)); - rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dsa->priv_key)); - - return hash; -} - -/* - * call-seq: - * dsa.to_text -> aString - * - * Prints all parameters of key to buffer - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dsa_to_text(VALUE self) -{ - EVP_PKEY *pkey; - BIO *out; - VALUE str; - - GetPKeyDSA(self, pkey); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eDSAError, NULL); - } - if (!DSA_print(out, pkey->pkey.dsa, 0)) { /* offset = 0 */ - BIO_free(out); - ossl_raise(eDSAError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * dsa.public_key -> aDSA - * - * Returns a new DSA instance that carries just the public key information. - * If the current instance has also private key information, this will no - * longer be present in the new instance. This feature is helpful for - * publishing the public key information without leaking any of the private - * information. - * - * === Example - * dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information - * pub_key = dsa.public_key # has only the public part available - * pub_key_der = pub_key.to_der # it's safe to publish this - * - * - */ -static VALUE -ossl_dsa_to_public_key(VALUE self) -{ - EVP_PKEY *pkey; - DSA *dsa; - VALUE obj; - - GetPKeyDSA(self, pkey); - /* err check performed by dsa_instance */ - dsa = DSAPublicKey_dup(pkey->pkey.dsa); - obj = dsa_instance(CLASS_OF(self), dsa); - if (obj == Qfalse) { - DSA_free(dsa); - ossl_raise(eDSAError, NULL); - } - return obj; -} - -#define ossl_dsa_buf_size(pkey) (DSA_size((pkey)->pkey.dsa)+16) - -/* - * call-seq: - * dsa.syssign(string) -> aString - * - * Computes and returns the DSA signature of +string+, where +string+ is - * expected to be an already-computed message digest of the original input - * data. The signature is issued using the private key of this DSA instance. - * - * === Parameters - * * +string+ is a message digest of the original input data to be signed - * - * === Example - * dsa = OpenSSL::PKey::DSA.new(2048) - * doc = "Sign me" - * digest = OpenSSL::Digest::SHA1.digest(doc) - * sig = dsa.syssign(digest) - * - * - */ -static VALUE -ossl_dsa_sign(VALUE self, VALUE data) -{ - EVP_PKEY *pkey; - unsigned int buf_len; - VALUE str; - - GetPKeyDSA(self, pkey); - StringValue(data); - if (!DSA_PRIVATE(self, pkey->pkey.dsa)) { - ossl_raise(eDSAError, "Private DSA key needed!"); - } - str = rb_str_new(0, ossl_dsa_buf_size(pkey)); - if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data), - (unsigned char *)RSTRING_PTR(str), - &buf_len, pkey->pkey.dsa)) { /* type is ignored (0) */ - ossl_raise(eDSAError, NULL); - } - rb_str_set_len(str, buf_len); - - return str; -} - -/* - * call-seq: - * dsa.sysverify(digest, sig) -> true | false - * - * Verifies whether the signature is valid given the message digest input. It - * does so by validating +sig+ using the public key of this DSA instance. - * - * === Parameters - * * +digest+ is a message digest of the original input data to be signed - * * +sig+ is a DSA signature value - * - * === Example - * dsa = OpenSSL::PKey::DSA.new(2048) - * doc = "Sign me" - * digest = OpenSSL::Digest::SHA1.digest(doc) - * sig = dsa.syssign(digest) - * puts dsa.sysverify(digest, sig) # => true - * - */ -static VALUE -ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig) -{ - EVP_PKEY *pkey; - int ret; - - GetPKeyDSA(self, pkey); - StringValue(digest); - StringValue(sig); - /* type is ignored (0) */ - ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest), - (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey->pkey.dsa); - if (ret < 0) { - ossl_raise(eDSAError, NULL); - } - else if (ret == 1) { - return Qtrue; - } - - return Qfalse; -} - -OSSL_PKEY_BN(dsa, p) -OSSL_PKEY_BN(dsa, q) -OSSL_PKEY_BN(dsa, g) -OSSL_PKEY_BN(dsa, pub_key) -OSSL_PKEY_BN(dsa, priv_key) - -/* - * INIT - */ -void -Init_ossl_dsa() -{ -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */ - mPKey = rb_define_module_under(mOSSL, "PKey"); -#endif - - /* Document-class: OpenSSL::PKey::DSAError - * - * Generic exception that is raised if an operation on a DSA PKey - * fails unexpectedly or in case an instantiation of an instance of DSA - * fails due to non-conformant input data. - */ - eDSAError = rb_define_class_under(mPKey, "DSAError", ePKeyError); - - /* Document-class: OpenSSL::PKey::DSA - * - * DSA, the Digital Signature Algorithm, is specified in NIST's - * FIPS 186-3. It is an asymmetric public key algorithm that may be used - * similar to e.g. RSA. - * Please note that for OpenSSL versions prior to 1.0.0 the digest - * algorithms OpenSSL::Digest::DSS (equivalent to SHA) or - * OpenSSL::Digest::DSS1 (equivalent to SHA-1) must be used for issuing - * signatures with a DSA key using OpenSSL::PKey#sign. - * Starting with OpenSSL 1.0.0, digest algorithms are no longer restricted, - * any Digest may be used for signing. - */ - cDSA = rb_define_class_under(mPKey, "DSA", cPKey); - - rb_define_singleton_method(cDSA, "generate", ossl_dsa_s_generate, 1); - rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1); - - rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0); - rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0); - rb_define_method(cDSA, "to_text", ossl_dsa_to_text, 0); - rb_define_method(cDSA, "export", ossl_dsa_export, -1); - rb_define_alias(cDSA, "to_pem", "export"); - rb_define_alias(cDSA, "to_s", "export"); - rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0); - rb_define_method(cDSA, "public_key", ossl_dsa_to_public_key, 0); - rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1); - rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2); - - DEF_OSSL_PKEY_BN(cDSA, dsa, p); - DEF_OSSL_PKEY_BN(cDSA, dsa, q); - DEF_OSSL_PKEY_BN(cDSA, dsa, g); - DEF_OSSL_PKEY_BN(cDSA, dsa, pub_key); - DEF_OSSL_PKEY_BN(cDSA, dsa, priv_key); - - rb_define_method(cDSA, "params", ossl_dsa_get_params, 0); -} - -#else /* defined NO_DSA */ -void -Init_ossl_dsa() -{ -} -#endif /* NO_DSA */ diff --git a/ruby_1_9_3/ext/openssl/ossl_pkey_ec.c b/ruby_1_9_3/ext/openssl/ossl_pkey_ec.c deleted file mode 100644 index 9f1050f62d..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkey_ec.c +++ /dev/null @@ -1,1594 +0,0 @@ -/* - * Copyright (C) 2006-2007 Technorama Ltd. <oss-ruby@technorama.net> - */ - -#include "ossl.h" - -#if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL) - -typedef struct { - EC_GROUP *group; - int dont_free; -} ossl_ec_group; - -typedef struct { - EC_POINT *point; - int dont_free; -} ossl_ec_point; - - -#define EXPORT_PEM 0 -#define EXPORT_DER 1 - - -#define GetPKeyEC(obj, pkey) do { \ - GetPKey((obj), (pkey)); \ - if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_EC) { \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \ - } \ -} while (0) - -#define SafeGet_ec_group(obj, group) do { \ - OSSL_Check_Kind((obj), cEC_GROUP); \ - Data_Get_Struct((obj), ossl_ec_group, (group)); \ -} while(0) - -#define Get_EC_KEY(obj, key) do { \ - EVP_PKEY *pkey; \ - GetPKeyEC((obj), pkey); \ - (key) = pkey->pkey.ec; \ -} while(0) - -#define Require_EC_KEY(obj, key) do { \ - Get_EC_KEY((obj), (key)); \ - if ((key) == NULL) \ - ossl_raise(eECError, "EC_KEY is not initialized"); \ -} while(0) - -#define SafeRequire_EC_KEY(obj, key) do { \ - OSSL_Check_Kind((obj), cEC); \ - Require_EC_KEY((obj), (key)); \ -} while (0) - -#define Get_EC_GROUP(obj, g) do { \ - ossl_ec_group *ec_group; \ - Data_Get_Struct((obj), ossl_ec_group, ec_group); \ - if (ec_group == NULL) \ - ossl_raise(eEC_GROUP, "missing ossl_ec_group structure"); \ - (g) = ec_group->group; \ -} while(0) - -#define Require_EC_GROUP(obj, group) do { \ - Get_EC_GROUP((obj), (group)); \ - if ((group) == NULL) \ - ossl_raise(eEC_GROUP, "EC_GROUP is not initialized"); \ -} while(0) - -#define SafeRequire_EC_GROUP(obj, group) do { \ - OSSL_Check_Kind((obj), cEC_GROUP); \ - Require_EC_GROUP((obj), (group)); \ -} while(0) - -#define Get_EC_POINT(obj, p) do { \ - ossl_ec_point *ec_point; \ - Data_Get_Struct((obj), ossl_ec_point, ec_point); \ - if (ec_point == NULL) \ - ossl_raise(eEC_POINT, "missing ossl_ec_point structure"); \ - (p) = ec_point->point; \ -} while(0) - -#define Require_EC_POINT(obj, point) do { \ - Get_EC_POINT((obj), (point)); \ - if ((point) == NULL) \ - ossl_raise(eEC_POINT, "EC_POINT is not initialized"); \ -} while(0) - -#define SafeRequire_EC_POINT(obj, point) do { \ - OSSL_Check_Kind((obj), cEC_POINT); \ - Require_EC_POINT((obj), (point)); \ -} while(0) - -VALUE cEC; -VALUE eECError; -VALUE cEC_GROUP; -VALUE eEC_GROUP; -VALUE cEC_POINT; -VALUE eEC_POINT; - -static ID s_GFp; -static ID s_GFp_simple; -static ID s_GFp_mont; -static ID s_GFp_nist; -static ID s_GF2m; -static ID s_GF2m_simple; - -static ID ID_uncompressed; -static ID ID_compressed; -static ID ID_hybrid; - -static VALUE ec_instance(VALUE klass, EC_KEY *ec) -{ - EVP_PKEY *pkey; - VALUE obj; - - if (!ec) { - return Qfalse; - } - if (!(pkey = EVP_PKEY_new())) { - return Qfalse; - } - if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { - EVP_PKEY_free(pkey); - return Qfalse; - } - WrapPKey(klass, obj, pkey); - - return obj; -} - -VALUE ossl_ec_new(EVP_PKEY *pkey) -{ - VALUE obj; - - if (!pkey) { - obj = ec_instance(cEC, EC_KEY_new()); - } else { - if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) { - ossl_raise(rb_eTypeError, "Not a EC key!"); - } - WrapPKey(cEC, obj, pkey); - } - if (obj == Qfalse) { - ossl_raise(eECError, NULL); - } - - return obj; -} - - -/* call-seq: - * OpenSSL::PKey::EC.new() - * OpenSSL::PKey::EC.new(ec_key) - * OpenSSL::PKey::EC.new(ec_group) - * OpenSSL::PKey::EC.new("secp112r1") - * OpenSSL::PKey::EC.new(pem_string) - * OpenSSL::PKey::EC.new(pem_string [, pwd]) - * OpenSSL::PKey::EC.new(der_string) - * - * See the OpenSSL documentation for: - * EC_KEY_* - */ -static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - EC_KEY *ec = NULL; - VALUE arg, pass; - VALUE group = Qnil; - char *passwd = NULL; - - GetPKey(self, pkey); - if (pkey->pkey.ec) - ossl_raise(eECError, "EC_KEY already initialized"); - - rb_scan_args(argc, argv, "02", &arg, &pass); - - if (NIL_P(arg)) { - ec = EC_KEY_new(); - } else { - if (rb_obj_is_kind_of(arg, cEC)) { - EC_KEY *other_ec = NULL; - - SafeRequire_EC_KEY(arg, other_ec); - ec = EC_KEY_dup(other_ec); - } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { - ec = EC_KEY_new(); - group = arg; - } else { - BIO *in = ossl_obj2bio(arg); - - if (!NIL_P(pass)) { - passwd = StringValuePtr(pass); - } - ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); - if (!ec) { - OSSL_BIO_reset(in); - ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd); - } - if (!ec) { - OSSL_BIO_reset(in); - ec = d2i_ECPrivateKey_bio(in, NULL); - } - if (!ec) { - OSSL_BIO_reset(in); - ec = d2i_EC_PUBKEY_bio(in, NULL); - } - - BIO_free(in); - - if (ec == NULL) { - const char *name = StringValueCStr(arg); - int nid = OBJ_sn2nid(name); - - (void)ERR_get_error(); - if (nid == NID_undef) - ossl_raise(eECError, "unknown curve name (%s)\n", name); - - if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL) - ossl_raise(eECError, "unable to create curve (%s)\n", name); - - EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); - EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); - } - } - } - - if (ec == NULL) - ossl_raise(eECError, NULL); - - if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { - EC_KEY_free(ec); - ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); - } - - rb_iv_set(self, "@group", Qnil); - - if (!NIL_P(group)) - rb_funcall(self, rb_intern("group="), 1, arg); - - return self; -} - -/* - * call-seq: - * key.group => group - * - * Returns a constant <code>OpenSSL::EC::Group</code> that is tied to the key. - * Modifying the returned group can make the key invalid. - */ -static VALUE ossl_ec_key_get_group(VALUE self) -{ - VALUE group_v; - EC_KEY *ec; - ossl_ec_group *ec_group; - EC_GROUP *group; - - Require_EC_KEY(self, ec); - - group_v = rb_iv_get(self, "@group"); - if (!NIL_P(group_v)) - return group_v; - - if ((group = (EC_GROUP *)EC_KEY_get0_group(ec)) != NULL) { - group_v = rb_obj_alloc(cEC_GROUP); - SafeGet_ec_group(group_v, ec_group); - ec_group->group = group; - ec_group->dont_free = 1; - rb_iv_set(group_v, "@key", self); - rb_iv_set(self, "@group", group_v); - return group_v; - } - - return Qnil; -} - -/* - * call-seq: - * key.group = group => group - * - * Returns the same object passed, not the group object associated with the key. - * If you wish to access the group object tied to the key call key.group after setting - * the group. - * - * Setting the group will immediately destroy any previously assigned group object. - * The group is internally copied by OpenSSL. Modifying the original group after - * assignment will not effect the internal key structure. - * (your changes may be lost). BE CAREFUL. - * - * EC_KEY_set_group calls EC_GROUP_free(key->group) then EC_GROUP_dup(), not EC_GROUP_copy. - * This documentation is accurate for OpenSSL 0.9.8b. - */ -static VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v) -{ - VALUE old_group_v; - EC_KEY *ec; - EC_GROUP *group; - - Require_EC_KEY(self, ec); - SafeRequire_EC_GROUP(group_v, group); - - old_group_v = rb_iv_get(self, "@group"); - if (!NIL_P(old_group_v)) { - ossl_ec_group *old_ec_group; - SafeGet_ec_group(old_group_v, old_ec_group); - - old_ec_group->group = NULL; - old_ec_group->dont_free = 0; - rb_iv_set(old_group_v, "@key", Qnil); - } - - rb_iv_set(self, "@group", Qnil); - - if (EC_KEY_set_group(ec, group) != 1) - ossl_raise(eECError, "EC_KEY_set_group"); - - return group_v; -} - -/* - * call-seq: - * key.private_key => OpenSSL::BN - * - * See the OpenSSL documentation for EC_KEY_get0_private_key() - */ -static VALUE ossl_ec_key_get_private_key(VALUE self) -{ - EC_KEY *ec; - const BIGNUM *bn; - - Require_EC_KEY(self, ec); - - if ((bn = EC_KEY_get0_private_key(ec)) == NULL) - return Qnil; - - return ossl_bn_new(bn); -} - -/* - * call-seq: - * key.private_key = openssl_bn - * - * See the OpenSSL documentation for EC_KEY_set_private_key() - */ -static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) -{ - EC_KEY *ec; - BIGNUM *bn = NULL; - - Require_EC_KEY(self, ec); - if (!NIL_P(private_key)) - bn = GetBNPtr(private_key); - - switch (EC_KEY_set_private_key(ec, bn)) { - case 1: - break; - case 0: - if (bn == NULL) - break; - default: - ossl_raise(eECError, "EC_KEY_set_private_key"); - } - - return private_key; -} - - -static VALUE ossl_ec_point_dup(const EC_POINT *point, VALUE group_v) -{ - VALUE obj; - const EC_GROUP *group; - ossl_ec_point *new_point; - - obj = rb_obj_alloc(cEC_POINT); - Data_Get_Struct(obj, ossl_ec_point, new_point); - - SafeRequire_EC_GROUP(group_v, group); - - new_point->point = EC_POINT_dup(point, group); - if (new_point->point == NULL) - ossl_raise(eEC_POINT, "EC_POINT_dup"); - rb_iv_set(obj, "@group", group_v); - - return obj; -} - -/* - * call-seq: - * key.public_key => OpenSSL::PKey::EC::Point - * - * See the OpenSSL documentation for EC_KEY_get0_public_key() - */ -static VALUE ossl_ec_key_get_public_key(VALUE self) -{ - EC_KEY *ec; - const EC_POINT *point; - VALUE group; - - Require_EC_KEY(self, ec); - - if ((point = EC_KEY_get0_public_key(ec)) == NULL) - return Qnil; - - group = rb_funcall(self, rb_intern("group"), 0); - if (NIL_P(group)) - ossl_raise(eECError, "EC_KEY_get0_get0_group (has public_key but no group???"); - - return ossl_ec_point_dup(point, group); -} - -/* - * call-seq: - * key.public_key = ec_point - * - * See the OpenSSL documentation for EC_KEY_set_public_key() - */ -static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) -{ - EC_KEY *ec; - EC_POINT *point = NULL; - - Require_EC_KEY(self, ec); - if (!NIL_P(public_key)) - SafeRequire_EC_POINT(public_key, point); - - switch (EC_KEY_set_public_key(ec, point)) { - case 1: - break; - case 0: - if (point == NULL) - break; - default: - ossl_raise(eECError, "EC_KEY_set_public_key"); - } - - return public_key; -} - -/* - * call-seq: - * key.public_key? => true or false - * - * Both public_key? and private_key? may return false at the same time unlike other PKey classes. - */ -static VALUE ossl_ec_key_is_public_key(VALUE self) -{ - EC_KEY *ec; - - Require_EC_KEY(self, ec); - - return (EC_KEY_get0_public_key(ec) ? Qtrue : Qfalse); -} - -/* - * call-seq: - * key.private_key? => true or false - * - * Both public_key? and private_key? may return false at the same time unlike other PKey classes. - */ -static VALUE ossl_ec_key_is_private_key(VALUE self) -{ - EC_KEY *ec; - - Require_EC_KEY(self, ec); - - return (EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse); -} - -static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format) -{ - EC_KEY *ec; - BIO *out; - int i = -1; - int private = 0; - char *password = NULL; - VALUE str; - - Require_EC_KEY(self, ec); - - if (EC_KEY_get0_public_key(ec) == NULL) - ossl_raise(eECError, "can't export - no public key set"); - - if (EC_KEY_check_key(ec) != 1) - ossl_raise(eECError, "can't export - EC_KEY_check_key failed"); - - if (EC_KEY_get0_private_key(ec)) - private = 1; - - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eECError, "BIO_new(BIO_s_mem())"); - - switch(format) { - case EXPORT_PEM: - if (private) { - const EVP_CIPHER *cipher; - if (!NIL_P(ciph)) { - cipher = GetCipherPtr(ciph); - if (!NIL_P(pass)) { - password = StringValuePtr(pass); - } - } - else { - cipher = NULL; - } - i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password); - } else { - i = PEM_write_bio_EC_PUBKEY(out, ec); - } - - break; - case EXPORT_DER: - if (private) { - i = i2d_ECPrivateKey_bio(out, ec); - } else { - i = i2d_EC_PUBKEY_bio(out, ec); - } - - break; - default: - BIO_free(out); - ossl_raise(rb_eRuntimeError, "unknown format (internal error)"); - } - - if (i != 1) { - BIO_free(out); - ossl_raise(eECError, "outlen=%d", i); - } - - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * key.to_pem => String - * key.to_pem(cipher, pass_phrase) => String - * - * Outputs the EC key in PEM encoding. If +cipher+ and +pass_phrase+ are - * given they will be used to encrypt the key. +cipher+ must be an - * OpenSSL::Cipher::Cipher instance. Note that encryption will only be - * effective for a private key, public keys will always be encoded in plain - * text. - * - */ -static VALUE ossl_ec_key_to_pem(int argc, VALUE *argv, VALUE self) -{ - VALUE cipher, passwd; - rb_scan_args(argc, argv, "02", &cipher, &passwd); - return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM); -} - -/* - * call-seq: - * key.to_der => String - * - * See the OpenSSL documentation for i2d_ECPrivateKey_bio() - */ -static VALUE ossl_ec_key_to_der(VALUE self) -{ - return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER); -} - -/* - * call-seq: - * key.to_text => String - * - * See the OpenSSL documentation for EC_KEY_print() - */ -static VALUE ossl_ec_key_to_text(VALUE self) -{ - EC_KEY *ec; - BIO *out; - VALUE str; - - Require_EC_KEY(self, ec); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eECError, "BIO_new(BIO_s_mem())"); - } - if (!EC_KEY_print(out, ec, 0)) { - BIO_free(out); - ossl_raise(eECError, "EC_KEY_print"); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * key.generate_key => self - * - * See the OpenSSL documentation for EC_KEY_generate_key() - */ -static VALUE ossl_ec_key_generate_key(VALUE self) -{ - EC_KEY *ec; - - Require_EC_KEY(self, ec); - - if (EC_KEY_generate_key(ec) != 1) - ossl_raise(eECError, "EC_KEY_generate_key"); - - return self; -} - -/* - * call-seq: - * key.check_key => true - * - * Raises an exception if the key is invalid. - * - * See the OpenSSL documentation for EC_KEY_check_key() - */ -static VALUE ossl_ec_key_check_key(VALUE self) -{ - EC_KEY *ec; - - Require_EC_KEY(self, ec); - - if (EC_KEY_check_key(ec) != 1) - ossl_raise(eECError, "EC_KEY_check_key"); - - return Qtrue; -} - -/* - * call-seq: - * key.dh_compute_key(pubkey) => String - * - * See the OpenSSL documentation for ECDH_compute_key() - */ -static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey) -{ - EC_KEY *ec; - EC_POINT *point; - int buf_len; - VALUE str; - - Require_EC_KEY(self, ec); - SafeRequire_EC_POINT(pubkey, point); - -/* BUG: need a way to figure out the maximum string size */ - buf_len = 1024; - str = rb_str_new(0, buf_len); -/* BUG: take KDF as a block */ - buf_len = ECDH_compute_key(RSTRING_PTR(str), buf_len, point, ec, NULL); - if (buf_len < 0) - ossl_raise(eECError, "ECDH_compute_key"); - - rb_str_resize(str, buf_len); - - return str; -} - -/* sign_setup */ - -/* - * call-seq: - * key.dsa_sign_asn1(data) => String - * - * See the OpenSSL documentation for ECDSA_sign() - */ -static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data) -{ - EC_KEY *ec; - unsigned int buf_len; - VALUE str; - - Require_EC_KEY(self, ec); - StringValue(data); - - if (EC_KEY_get0_private_key(ec) == NULL) - ossl_raise(eECError, "Private EC key needed!"); - - str = rb_str_new(0, ECDSA_size(ec) + 16); - if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1) - ossl_raise(eECError, "ECDSA_sign"); - - rb_str_resize(str, buf_len); - - return str; -} - -/* - * call-seq: - * key.dsa_verify_asn1(data, sig) => true or false - * - * See the OpenSSL documentation for ECDSA_verify() - */ -static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig) -{ - EC_KEY *ec; - - Require_EC_KEY(self, ec); - StringValue(data); - StringValue(sig); - - switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) { - case 1: return Qtrue; - case 0: return Qfalse; - default: break; - } - - ossl_raise(eECError, "ECDSA_verify"); -} - -static void ossl_ec_group_free(ossl_ec_group *ec_group) -{ - if (!ec_group->dont_free && ec_group->group) - EC_GROUP_clear_free(ec_group->group); - ruby_xfree(ec_group); -} - -static VALUE ossl_ec_group_alloc(VALUE klass) -{ - ossl_ec_group *ec_group; - VALUE obj; - - obj = Data_Make_Struct(klass, ossl_ec_group, 0, ossl_ec_group_free, ec_group); - - return obj; -} - -/* call-seq: - * OpenSSL::PKey::EC::Group.new("secp112r1") - * OpenSSL::PKey::EC::Group.new(ec_group) - * OpenSSL::PKey::EC::Group.new(pem_string) - * OpenSSL::PKey::EC::Group.new(der_string) - * OpenSSL::PKey::EC::Group.new(pem_file) - * OpenSSL::PKey::EC::Group.new(der_file) - * OpenSSL::PKey::EC::Group.new(:GFp_simple) - * OpenSSL::PKey::EC::Group.new(:GFp_mult) - * OpenSSL::PKey::EC::Group.new(:GFp_nist) - * OpenSSL::PKey::EC::Group.new(:GF2m_simple) - * OpenSSL::PKey::EC::Group.new(:GFp, bignum_p, bignum_a, bignum_b) - * OpenSSL::PKey::EC::Group.new(:GF2m, bignum_p, bignum_a, bignum_b) - * - * See the OpenSSL documentation for EC_GROUP_* - */ -static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE arg1, arg2, arg3, arg4; - ossl_ec_group *ec_group; - EC_GROUP *group = NULL; - - Data_Get_Struct(self, ossl_ec_group, ec_group); - if (ec_group->group != NULL) - ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized"); - - switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) { - case 1: - if (SYMBOL_P(arg1)) { - const EC_METHOD *method = NULL; - ID id = SYM2ID(arg1); - - if (id == s_GFp_simple) { - method = EC_GFp_simple_method(); - } else if (id == s_GFp_mont) { - method = EC_GFp_mont_method(); - } else if (id == s_GFp_nist) { - method = EC_GFp_nist_method(); - } else if (id == s_GF2m_simple) { - method = EC_GF2m_simple_method(); - } - - if (method) { - if ((group = EC_GROUP_new(method)) == NULL) - ossl_raise(eEC_GROUP, "EC_GROUP_new"); - } else { - ossl_raise(rb_eArgError, "unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple"); - } - } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) { - const EC_GROUP *arg1_group; - - SafeRequire_EC_GROUP(arg1, arg1_group); - if ((group = EC_GROUP_dup(arg1_group)) == NULL) - ossl_raise(eEC_GROUP, "EC_GROUP_dup"); - } else { - BIO *in = ossl_obj2bio(arg1); - - group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); - if (!group) { - OSSL_BIO_reset(in); - group = d2i_ECPKParameters_bio(in, NULL); - } - - BIO_free(in); - - if (!group) { - const char *name = StringValueCStr(arg1); - int nid = OBJ_sn2nid(name); - - (void)ERR_get_error(); - if (nid == NID_undef) - ossl_raise(eEC_GROUP, "unknown curve name (%s)", name); - - group = EC_GROUP_new_by_curve_name(nid); - if (group == NULL) - ossl_raise(eEC_GROUP, "unable to create curve (%s)", name); - - EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); - EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED); - } - } - - break; - case 4: - if (SYMBOL_P(arg1)) { - ID id = SYM2ID(arg1); - EC_GROUP *(*new_curve)(const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL; - const BIGNUM *p = GetBNPtr(arg2); - const BIGNUM *a = GetBNPtr(arg3); - const BIGNUM *b = GetBNPtr(arg4); - - if (id == s_GFp) { - new_curve = EC_GROUP_new_curve_GFp; - } else if (id == s_GF2m) { - new_curve = EC_GROUP_new_curve_GF2m; - } else { - ossl_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m"); - } - - if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL) - ossl_raise(eEC_GROUP, "EC_GROUP_new_by_GF*"); - } else { - ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m"); - } - - break; - default: - ossl_raise(rb_eArgError, "wrong number of arguments"); - } - - if (group == NULL) - ossl_raise(eEC_GROUP, ""); - - ec_group->group = group; - - return self; -} - -/* call-seq: - * group1 == group2 => true | false - * - */ -static VALUE ossl_ec_group_eql(VALUE a, VALUE b) -{ - EC_GROUP *group1 = NULL, *group2 = NULL; - - Require_EC_GROUP(a, group1); - SafeRequire_EC_GROUP(b, group2); - - if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1) - return Qfalse; - - return Qtrue; -} - -/* call-seq: - * group.generator => ec_point - * - * See the OpenSSL documentation for EC_GROUP_get0_generator() - */ -static VALUE ossl_ec_group_get_generator(VALUE self) -{ - VALUE point_obj; - EC_GROUP *group = NULL; - - Require_EC_GROUP(self, group); - - point_obj = ossl_ec_point_dup(EC_GROUP_get0_generator(group), self); - - return point_obj; -} - -/* call-seq: - * group.set_generator(generator, order, cofactor) => self - * - * See the OpenSSL documentation for EC_GROUP_set_generator() - */ -static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE order, VALUE cofactor) -{ - EC_GROUP *group = NULL; - const EC_POINT *point; - const BIGNUM *o, *co; - - Require_EC_GROUP(self, group); - SafeRequire_EC_POINT(generator, point); - o = GetBNPtr(order); - co = GetBNPtr(cofactor); - - if (EC_GROUP_set_generator(group, point, o, co) != 1) - ossl_raise(eEC_GROUP, "EC_GROUP_set_generator"); - - return self; -} - -/* call-seq: - * group.get_order => order_bn - * - * See the OpenSSL documentation for EC_GROUP_get_order() - */ -static VALUE ossl_ec_group_get_order(VALUE self) -{ - VALUE bn_obj; - BIGNUM *bn; - EC_GROUP *group = NULL; - - Require_EC_GROUP(self, group); - - bn_obj = ossl_bn_new(NULL); - bn = GetBNPtr(bn_obj); - - if (EC_GROUP_get_order(group, bn, ossl_bn_ctx) != 1) - ossl_raise(eEC_GROUP, "EC_GROUP_get_order"); - - return bn_obj; -} - -/* call-seq: - * group.get_cofactor => cofactor_bn - * - * See the OpenSSL documentation for EC_GROUP_get_cofactor() - */ -static VALUE ossl_ec_group_get_cofactor(VALUE self) -{ - VALUE bn_obj; - BIGNUM *bn; - EC_GROUP *group = NULL; - - Require_EC_GROUP(self, group); - - bn_obj = ossl_bn_new(NULL); - bn = GetBNPtr(bn_obj); - - if (EC_GROUP_get_cofactor(group, bn, ossl_bn_ctx) != 1) - ossl_raise(eEC_GROUP, "EC_GROUP_get_cofactor"); - - return bn_obj; -} - -/* call-seq: - * group.curve_name => String - * - * See the OpenSSL documentation for EC_GROUP_get_curve_name() - */ -static VALUE ossl_ec_group_get_curve_name(VALUE self) -{ - EC_GROUP *group = NULL; - int nid; - - Get_EC_GROUP(self, group); - if (group == NULL) - return Qnil; - - nid = EC_GROUP_get_curve_name(group); - -/* BUG: an nid or asn1 object should be returned, maybe. */ - return rb_str_new2(OBJ_nid2sn(nid)); -} - -/* call-seq: - * EC.builtin_curves => [[name, comment], ...] - * - * See the OpenSSL documentation for EC_builtin_curves() - */ -static VALUE ossl_s_builtin_curves(VALUE self) -{ - EC_builtin_curve *curves = NULL; - int n; - int crv_len = rb_long2int(EC_get_builtin_curves(NULL, 0)); - VALUE ary, ret; - - curves = ALLOCA_N(EC_builtin_curve, crv_len); - if (curves == NULL) - return Qnil; - if (!EC_get_builtin_curves(curves, crv_len)) - ossl_raise(rb_eRuntimeError, "EC_get_builtin_curves"); - - ret = rb_ary_new2(crv_len); - - for (n = 0; n < crv_len; n++) { - const char *sname = OBJ_nid2sn(curves[n].nid); - const char *comment = curves[n].comment; - - ary = rb_ary_new2(2); - rb_ary_push(ary, rb_str_new2(sname)); - rb_ary_push(ary, comment ? rb_str_new2(comment) : Qnil); - rb_ary_push(ret, ary); - } - - return ret; -} - -/* call-seq: - * group.asn1_flag => Fixnum - * - * See the OpenSSL documentation for EC_GROUP_get_asn1_flag() - */ -static VALUE ossl_ec_group_get_asn1_flag(VALUE self) -{ - EC_GROUP *group = NULL; - int flag; - - Require_EC_GROUP(self, group); - - flag = EC_GROUP_get_asn1_flag(group); - - return INT2FIX(flag); -} - -/* call-seq: - * group.asn1_flag = Fixnum => Fixnum - * - * See the OpenSSL documentation for EC_GROUP_set_asn1_flag() - */ -static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v) -{ - EC_GROUP *group = NULL; - - Require_EC_GROUP(self, group); - - EC_GROUP_set_asn1_flag(group, NUM2INT(flag_v)); - - return flag_v; -} - -/* call-seq: - * group.point_conversion_form => :uncompressed | :compressed | :hybrid - * - * See the OpenSSL documentation for EC_GROUP_get_point_conversion_form() - */ -static VALUE ossl_ec_group_get_point_conversion_form(VALUE self) -{ - EC_GROUP *group = NULL; - point_conversion_form_t form; - VALUE ret; - - Require_EC_GROUP(self, group); - - form = EC_GROUP_get_point_conversion_form(group); - - switch (form) { - case POINT_CONVERSION_UNCOMPRESSED: ret = ID_uncompressed; break; - case POINT_CONVERSION_COMPRESSED: ret = ID_compressed; break; - case POINT_CONVERSION_HYBRID: ret = ID_hybrid; break; - default: ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, this module should be updated", form); - } - - return ID2SYM(ret); -} - -/* call-seq: - * group.point_conversion_form = form => form - * - * See the OpenSSL documentation for EC_GROUP_set_point_conversion_form() - */ -static VALUE ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v) -{ - EC_GROUP *group = NULL; - point_conversion_form_t form; - ID form_id = SYM2ID(form_v); - - Require_EC_GROUP(self, group); - - if (form_id == ID_uncompressed) { - form = POINT_CONVERSION_UNCOMPRESSED; - } else if (form_id == ID_compressed) { - form = POINT_CONVERSION_COMPRESSED; - } else if (form_id == ID_hybrid) { - form = POINT_CONVERSION_HYBRID; - } else { - ossl_raise(rb_eArgError, "form must be :compressed, :uncompressed, or :hybrid"); - } - - EC_GROUP_set_point_conversion_form(group, form); - - return form_v; -} - -/* call-seq: - * group.seed => String or nil - * - * See the OpenSSL documentation for EC_GROUP_get0_seed() - */ -static VALUE ossl_ec_group_get_seed(VALUE self) -{ - EC_GROUP *group = NULL; - size_t seed_len; - - Require_EC_GROUP(self, group); - - seed_len = EC_GROUP_get_seed_len(group); - - if (seed_len == 0) - return Qnil; - - return rb_str_new((const char *)EC_GROUP_get0_seed(group), seed_len); -} - -/* call-seq: - * group.seed = seed => seed - * - * See the OpenSSL documentation for EC_GROUP_set_seed() - */ -static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed) -{ - EC_GROUP *group = NULL; - - Require_EC_GROUP(self, group); - StringValue(seed); - - if (EC_GROUP_set_seed(group, (unsigned char *)RSTRING_PTR(seed), RSTRING_LEN(seed)) != (size_t)RSTRING_LEN(seed)) - ossl_raise(eEC_GROUP, "EC_GROUP_set_seed"); - - return seed; -} - -/* get/set curve GFp, GF2m */ - -/* call-seq: - * group.degree => Fixnum - * - * See the OpenSSL documentation for EC_GROUP_get_degree() - */ -static VALUE ossl_ec_group_get_degree(VALUE self) -{ - EC_GROUP *group = NULL; - - Require_EC_GROUP(self, group); - - return INT2NUM(EC_GROUP_get_degree(group)); -} - -static VALUE ossl_ec_group_to_string(VALUE self, int format) -{ - EC_GROUP *group; - BIO *out; - int i = -1; - VALUE str; - - Get_EC_GROUP(self, group); - - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())"); - - switch(format) { - case EXPORT_PEM: - i = PEM_write_bio_ECPKParameters(out, group); - break; - case EXPORT_DER: - i = i2d_ECPKParameters_bio(out, group); - break; - default: - BIO_free(out); - ossl_raise(rb_eRuntimeError, "unknown format (internal error)"); - } - - if (i != 1) { - BIO_free(out); - ossl_raise(eECError, NULL); - } - - str = ossl_membio2str(out); - - return str; -} - -/* call-seq: - * group.to_pem => String - * - * See the OpenSSL documentation for PEM_write_bio_ECPKParameters() - */ -static VALUE ossl_ec_group_to_pem(VALUE self) -{ - return ossl_ec_group_to_string(self, EXPORT_PEM); -} - -/* call-seq: - * group.to_der => String - * - * See the OpenSSL documentation for i2d_ECPKParameters_bio() - */ -static VALUE ossl_ec_group_to_der(VALUE self) -{ - return ossl_ec_group_to_string(self, EXPORT_DER); -} - -/* call-seq: - * group.to_text => String - * - * See the OpenSSL documentation for ECPKParameters_print() - */ -static VALUE ossl_ec_group_to_text(VALUE self) -{ - EC_GROUP *group; - BIO *out; - VALUE str; - - Require_EC_GROUP(self, group); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())"); - } - if (!ECPKParameters_print(out, group, 0)) { - BIO_free(out); - ossl_raise(eEC_GROUP, NULL); - } - str = ossl_membio2str(out); - - return str; -} - - -static void ossl_ec_point_free(ossl_ec_point *ec_point) -{ - if (!ec_point->dont_free && ec_point->point) - EC_POINT_clear_free(ec_point->point); - ruby_xfree(ec_point); -} - -static VALUE ossl_ec_point_alloc(VALUE klass) -{ - ossl_ec_point *ec_point; - VALUE obj; - - obj = Data_Make_Struct(klass, ossl_ec_point, 0, ossl_ec_point_free, ec_point); - - return obj; -} - -/* - * call-seq: - * OpenSSL::PKey::EC::Point.new(point) - * OpenSSL::PKey::EC::Point.new(group) - * OpenSSL::PKey::EC::Point.new(group, bn) - * - * See the OpenSSL documentation for EC_POINT_* - */ -static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) -{ - ossl_ec_point *ec_point; - EC_POINT *point = NULL; - VALUE arg1, arg2; - VALUE group_v = Qnil; - const EC_GROUP *group = NULL; - - Data_Get_Struct(self, ossl_ec_point, ec_point); - if (ec_point->point) - ossl_raise(eEC_POINT, "EC_POINT already initialized"); - - switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) { - case 1: - if (rb_obj_is_kind_of(arg1, cEC_POINT)) { - const EC_POINT *arg_point; - - group_v = rb_iv_get(arg1, "@group"); - SafeRequire_EC_GROUP(group_v, group); - SafeRequire_EC_POINT(arg1, arg_point); - - point = EC_POINT_dup(arg_point, group); - } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) { - group_v = arg1; - SafeRequire_EC_GROUP(group_v, group); - - point = EC_POINT_new(group); - } else { - ossl_raise(eEC_POINT, "wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group"); - } - - break; - case 2: - if (!rb_obj_is_kind_of(arg1, cEC_GROUP)) - ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group"); - group_v = arg1; - SafeRequire_EC_GROUP(group_v, group); - - if (rb_obj_is_kind_of(arg2, cBN)) { - const BIGNUM *bn = GetBNPtr(arg2); - - point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx); - } else { - BIO *in = ossl_obj2bio(arg1); - -/* BUG: finish me */ - - BIO_free(in); - - if (point == NULL) { - ossl_raise(eEC_POINT, "unknown type for 2nd arg"); - } - } - break; - default: - ossl_raise(rb_eArgError, "wrong number of arguments"); - } - - if (point == NULL) - ossl_raise(eEC_POINT, NULL); - - if (NIL_P(group_v)) - ossl_raise(rb_eRuntimeError, "missing group (internal error)"); - - ec_point->point = point; - - rb_iv_set(self, "@group", group_v); - - return self; -} - -/* - * call-seq: - * point1 == point2 => true | false - * - */ -static VALUE ossl_ec_point_eql(VALUE a, VALUE b) -{ - EC_POINT *point1, *point2; - VALUE group_v1 = rb_iv_get(a, "@group"); - VALUE group_v2 = rb_iv_get(b, "@group"); - const EC_GROUP *group; - - if (ossl_ec_group_eql(group_v1, group_v2) == Qfalse) - return Qfalse; - - Require_EC_POINT(a, point1); - SafeRequire_EC_POINT(b, point2); - SafeRequire_EC_GROUP(group_v1, group); - - if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1) - return Qfalse; - - return Qtrue; -} - -/* - * call-seq: - * point.infinity? => true | false - * - */ -static VALUE ossl_ec_point_is_at_infinity(VALUE self) -{ - EC_POINT *point; - VALUE group_v = rb_iv_get(self, "@group"); - const EC_GROUP *group; - - Require_EC_POINT(self, point); - SafeRequire_EC_GROUP(group_v, group); - - switch (EC_POINT_is_at_infinity(group, point)) { - case 1: return Qtrue; - case 0: return Qfalse; - default: ossl_raise(cEC_POINT, "EC_POINT_is_at_infinity"); - } -} - -/* - * call-seq: - * point.on_curve? => true | false - * - */ -static VALUE ossl_ec_point_is_on_curve(VALUE self) -{ - EC_POINT *point; - VALUE group_v = rb_iv_get(self, "@group"); - const EC_GROUP *group; - - Require_EC_POINT(self, point); - SafeRequire_EC_GROUP(group_v, group); - - switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) { - case 1: return Qtrue; - case 0: return Qfalse; - default: ossl_raise(cEC_POINT, "EC_POINT_is_on_curve"); - } -} - -/* - * call-seq: - * point.make_affine! => self - * - */ -static VALUE ossl_ec_point_make_affine(VALUE self) -{ - EC_POINT *point; - VALUE group_v = rb_iv_get(self, "@group"); - const EC_GROUP *group; - - Require_EC_POINT(self, point); - SafeRequire_EC_GROUP(group_v, group); - - if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1) - ossl_raise(cEC_POINT, "EC_POINT_make_affine"); - - return self; -} - -/* - * call-seq: - * point.invert! => self - * - */ -static VALUE ossl_ec_point_invert(VALUE self) -{ - EC_POINT *point; - VALUE group_v = rb_iv_get(self, "@group"); - const EC_GROUP *group; - - Require_EC_POINT(self, point); - SafeRequire_EC_GROUP(group_v, group); - - if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1) - ossl_raise(cEC_POINT, "EC_POINT_invert"); - - return self; -} - -/* - * call-seq: - * point.set_to_infinity! => self - * - */ -static VALUE ossl_ec_point_set_to_infinity(VALUE self) -{ - EC_POINT *point; - VALUE group_v = rb_iv_get(self, "@group"); - const EC_GROUP *group; - - Require_EC_POINT(self, point); - SafeRequire_EC_GROUP(group_v, group); - - if (EC_POINT_set_to_infinity(group, point) != 1) - ossl_raise(cEC_POINT, "EC_POINT_set_to_infinity"); - - return self; -} - -/* - * call-seq: - * point.to_bn => OpenSSL::BN - * - * See the OpenSSL documentation for EC_POINT_point2bn() - */ -static VALUE ossl_ec_point_to_bn(VALUE self) -{ - EC_POINT *point; - VALUE bn_obj; - VALUE group_v = rb_iv_get(self, "@group"); - const EC_GROUP *group; - point_conversion_form_t form; - BIGNUM *bn; - - Require_EC_POINT(self, point); - SafeRequire_EC_GROUP(group_v, group); - - form = EC_GROUP_get_point_conversion_form(group); - - bn_obj = rb_obj_alloc(cBN); - bn = GetBNPtr(bn_obj); - - if (EC_POINT_point2bn(group, point, form, bn, ossl_bn_ctx) == NULL) - ossl_raise(eEC_POINT, "EC_POINT_point2bn"); - - return bn_obj; -} - -static void no_copy(VALUE klass) -{ - rb_undef_method(klass, "copy"); - rb_undef_method(klass, "clone"); - rb_undef_method(klass, "dup"); - rb_undef_method(klass, "initialize_copy"); -} - -void Init_ossl_ec() -{ -#ifdef DONT_NEED_RDOC_WORKAROUND - mOSSL = rb_define_module("OpenSSL"); - mPKey = rb_define_module_under(mOSSL, "PKey"); -#endif - - eECError = rb_define_class_under(mPKey, "ECError", ePKeyError); - - cEC = rb_define_class_under(mPKey, "EC", cPKey); - cEC_GROUP = rb_define_class_under(cEC, "Group", rb_cObject); - cEC_POINT = rb_define_class_under(cEC, "Point", rb_cObject); - eEC_GROUP = rb_define_class_under(cEC_GROUP, "Error", eOSSLError); - eEC_POINT = rb_define_class_under(cEC_POINT, "Error", eOSSLError); - - s_GFp = rb_intern("GFp"); - s_GF2m = rb_intern("GF2m"); - s_GFp_simple = rb_intern("GFp_simple"); - s_GFp_mont = rb_intern("GFp_mont"); - s_GFp_nist = rb_intern("GFp_nist"); - s_GF2m_simple = rb_intern("GF2m_simple"); - - ID_uncompressed = rb_intern("uncompressed"); - ID_compressed = rb_intern("compressed"); - ID_hybrid = rb_intern("hybrid"); - -#ifdef OPENSSL_EC_NAMED_CURVE - rb_define_const(cEC, "NAMED_CURVE", ULONG2NUM(OPENSSL_EC_NAMED_CURVE)); -#endif - - rb_define_singleton_method(cEC, "builtin_curves", ossl_s_builtin_curves, 0); - - rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1); -/* copy/dup/cmp */ - - rb_define_method(cEC, "group", ossl_ec_key_get_group, 0); - rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1); - rb_define_method(cEC, "private_key", ossl_ec_key_get_private_key, 0); - rb_define_method(cEC, "private_key=", ossl_ec_key_set_private_key, 1); - rb_define_method(cEC, "public_key", ossl_ec_key_get_public_key, 0); - rb_define_method(cEC, "public_key=", ossl_ec_key_set_public_key, 1); - rb_define_method(cEC, "private_key?", ossl_ec_key_is_private_key, 0); - rb_define_method(cEC, "public_key?", ossl_ec_key_is_public_key, 0); -/* rb_define_method(cEC, "", ossl_ec_key_get_, 0); - rb_define_method(cEC, "=", ossl_ec_key_set_ 1); - set/get enc_flags - set/get _conv_from - set/get asn1_flag (can use ruby to call self.group.asn1_flag) - set/get precompute_mult -*/ - rb_define_method(cEC, "generate_key", ossl_ec_key_generate_key, 0); - rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0); - - rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1); - rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1); - rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2); -/* do_sign/do_verify */ - - rb_define_method(cEC, "to_pem", ossl_ec_key_to_pem, -1); - rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0); - rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0); - - - rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc); - rb_define_method(cEC_GROUP, "initialize", ossl_ec_group_initialize, -1); - rb_define_method(cEC_GROUP, "eql?", ossl_ec_group_eql, 1); - rb_define_alias(cEC_GROUP, "==", "eql?"); -/* copy/dup/cmp */ - - rb_define_method(cEC_GROUP, "generator", ossl_ec_group_get_generator, 0); - rb_define_method(cEC_GROUP, "set_generator", ossl_ec_group_set_generator, 3); - rb_define_method(cEC_GROUP, "order", ossl_ec_group_get_order, 0); - rb_define_method(cEC_GROUP, "cofactor", ossl_ec_group_get_cofactor, 0); - - rb_define_method(cEC_GROUP, "curve_name", ossl_ec_group_get_curve_name, 0); -/* rb_define_method(cEC_GROUP, "curve_name=", ossl_ec_group_set_curve_name, 1); */ - - rb_define_method(cEC_GROUP, "asn1_flag", ossl_ec_group_get_asn1_flag, 0); - rb_define_method(cEC_GROUP, "asn1_flag=", ossl_ec_group_set_asn1_flag, 1); - - rb_define_method(cEC_GROUP, "point_conversion_form", ossl_ec_group_get_point_conversion_form, 0); - rb_define_method(cEC_GROUP, "point_conversion_form=", ossl_ec_group_set_point_conversion_form, 1); - - rb_define_method(cEC_GROUP, "seed", ossl_ec_group_get_seed, 0); - rb_define_method(cEC_GROUP, "seed=", ossl_ec_group_set_seed, 1); - -/* get/set GFp, GF2m */ - - rb_define_method(cEC_GROUP, "degree", ossl_ec_group_get_degree, 0); - -/* check* */ - - - rb_define_method(cEC_GROUP, "to_pem", ossl_ec_group_to_pem, 0); - rb_define_method(cEC_GROUP, "to_der", ossl_ec_group_to_der, 0); - rb_define_method(cEC_GROUP, "to_text", ossl_ec_group_to_text, 0); - - - rb_define_alloc_func(cEC_POINT, ossl_ec_point_alloc); - rb_define_method(cEC_POINT, "initialize", ossl_ec_point_initialize, -1); - rb_attr(cEC_POINT, rb_intern("group"), 1, 0, 0); - rb_define_method(cEC_POINT, "eql?", ossl_ec_point_eql, 1); - rb_define_alias(cEC_POINT, "==", "eql?"); - - rb_define_method(cEC_POINT, "infinity?", ossl_ec_point_is_at_infinity, 0); - rb_define_method(cEC_POINT, "on_curve?", ossl_ec_point_is_on_curve, 0); - rb_define_method(cEC_POINT, "make_affine!", ossl_ec_point_make_affine, 0); - rb_define_method(cEC_POINT, "invert!", ossl_ec_point_invert, 0); - rb_define_method(cEC_POINT, "set_to_infinity!", ossl_ec_point_set_to_infinity, 0); -/* all the other methods */ - - rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn, 0); - - no_copy(cEC); - no_copy(cEC_GROUP); - no_copy(cEC_POINT); -} - -#else /* defined NO_EC */ -void Init_ossl_ec() -{ -} -#endif /* NO_EC */ diff --git a/ruby_1_9_3/ext/openssl/ossl_pkey_rsa.c b/ruby_1_9_3/ext/openssl/ossl_pkey_rsa.c deleted file mode 100644 index eba693b057..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_pkey_rsa.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(OPENSSL_NO_RSA) - -#include "ossl.h" - -#define GetPKeyRSA(obj, pkey) do { \ - GetPKey((obj), (pkey)); \ - if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_RSA) { /* PARANOIA? */ \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \ - } \ -} while (0) - -#define RSA_HAS_PRIVATE(rsa) ((rsa)->p && (rsa)->q) -#define RSA_PRIVATE(obj,rsa) (RSA_HAS_PRIVATE(rsa)||OSSL_PKEY_IS_PRIVATE(obj)) - -/* - * Classes - */ -VALUE cRSA; -VALUE eRSAError; - -/* - * Public - */ -static VALUE -rsa_instance(VALUE klass, RSA *rsa) -{ - EVP_PKEY *pkey; - VALUE obj; - - if (!rsa) { - return Qfalse; - } - if (!(pkey = EVP_PKEY_new())) { - return Qfalse; - } - if (!EVP_PKEY_assign_RSA(pkey, rsa)) { - EVP_PKEY_free(pkey); - return Qfalse; - } - WrapPKey(klass, obj, pkey); - - return obj; -} - -VALUE -ossl_rsa_new(EVP_PKEY *pkey) -{ - VALUE obj; - - if (!pkey) { - obj = rsa_instance(cRSA, RSA_new()); - } - else { - if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) { - ossl_raise(rb_eTypeError, "Not a RSA key!"); - } - WrapPKey(cRSA, obj, pkey); - } - if (obj == Qfalse) { - ossl_raise(eRSAError, NULL); - } - - return obj; -} - -/* - * Private - */ -static RSA * -rsa_generate(int size, int exp) -{ - return RSA_generate_key(size, exp, - rb_block_given_p() ? ossl_generate_cb : NULL, - NULL); -} - -/* - * call-seq: - * RSA.generate(size) => RSA instance - * RSA.generate(size, exponent) => RSA instance - * - * Generates an RSA keypair. +size+ is an integer representing the desired key - * size. Keys smaller than 1024 should be considered insecure. +exponent+ is - * an odd number normally 3, 17, or 65537. - */ -static VALUE -ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass) -{ -/* why does this method exist? why can't initialize take an optional exponent? */ - RSA *rsa; - VALUE size, exp; - VALUE obj; - - rb_scan_args(argc, argv, "11", &size, &exp); - - rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2INT(exp)); /* err handled by rsa_instance */ - obj = rsa_instance(klass, rsa); - - if (obj == Qfalse) { - RSA_free(rsa); - ossl_raise(eRSAError, NULL); - } - - return obj; -} - -/* - * call-seq: - * RSA.new(key_size) => RSA instance - * RSA.new(encoded_key) => RSA instance - * RSA.new(encoded_key, pass_phrase) => RSA instance - * - * Generates or loads an RSA keypair. If an integer +key_size+ is given it - * represents the desired key size. Keys less than 1024 bits should be - * considered insecure. - * - * A key can instead be loaded from an +encoded_key+ which must be PEM or DER - * encoded. A +pass_phrase+ can be used to decrypt the key. If none is given - * OpenSSL will prompt for the pass phrase. - * - * = Examples - * - * OpenSSL::PKey::RSA.new 2048 - * OpenSSL::PKey::RSA.new File.read 'rsa.pem' - * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase' - */ -static VALUE -ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - RSA *rsa; - BIO *in; - char *passwd = NULL; - VALUE arg, pass; - - GetPKey(self, pkey); - if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) { - rsa = RSA_new(); - } - else if (FIXNUM_P(arg)) { - rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass)); - if (!rsa) ossl_raise(eRSAError, NULL); - } - else { - if (!NIL_P(pass)) passwd = StringValuePtr(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); - if (!rsa) { - OSSL_BIO_reset(in); - rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = d2i_RSA_PUBKEY_bio(in, NULL); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = d2i_RSAPublicKey_bio(in, NULL); - } - BIO_free(in); - if (!rsa) { - ossl_raise(eRSAError, "Neither PUB key nor PRIV key:"); - } - } - if (!EVP_PKEY_assign_RSA(pkey, rsa)) { - RSA_free(rsa); - ossl_raise(eRSAError, NULL); - } - - return self; -} - -/* - * call-seq: - * rsa.public? => true - * - * The return value is always true since every private key is also a public - * key. - */ -static VALUE -ossl_rsa_is_public(VALUE self) -{ - EVP_PKEY *pkey; - - GetPKeyRSA(self, pkey); - /* - * This method should check for n and e. BUG. - */ - return Qtrue; -} - -/* - * call-seq: - * rsa.private? => true | false - * - * Does this keypair contain a private key? - */ -static VALUE -ossl_rsa_is_private(VALUE self) -{ - EVP_PKEY *pkey; - - GetPKeyRSA(self, pkey); - - return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * rsa.to_pem => PEM-format String - * rsa.to_pem(cipher, pass_phrase) => PEM-format String - * - * Outputs this keypair in PEM encoding. If +cipher+ and +pass_phrase+ are - * given they will be used to encrypt the key. +cipher+ must be an - * OpenSSL::Cipher::Cipher instance. - */ -static VALUE -ossl_rsa_export(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - BIO *out; - const EVP_CIPHER *ciph = NULL; - char *passwd = NULL; - VALUE cipher, pass, str; - - GetPKeyRSA(self, pkey); - - rb_scan_args(argc, argv, "02", &cipher, &pass); - - if (!NIL_P(cipher)) { - ciph = GetCipherPtr(cipher); - if (!NIL_P(pass)) { - passwd = StringValuePtr(pass); - } - } - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eRSAError, NULL); - } - if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) { - if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph, - NULL, 0, ossl_pem_passwd_cb, passwd)) { - BIO_free(out); - ossl_raise(eRSAError, NULL); - } - } else { - if (!PEM_write_bio_RSA_PUBKEY(out, pkey->pkey.rsa)) { - BIO_free(out); - ossl_raise(eRSAError, NULL); - } - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * rsa.to_der => DER-format String - * - * Outputs this keypair in DER encoding. - */ -static VALUE -ossl_rsa_to_der(VALUE self) -{ - EVP_PKEY *pkey; - int (*i2d_func)_((const RSA*, unsigned char**)); - unsigned char *p; - long len; - VALUE str; - - GetPKeyRSA(self, pkey); - if(RSA_HAS_PRIVATE(pkey->pkey.rsa)) - i2d_func = i2d_RSAPrivateKey; - else - i2d_func = (int (*)(const RSA*, unsigned char**))i2d_RSA_PUBKEY; - if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0) - ossl_raise(eRSAError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_func(pkey->pkey.rsa, &p) < 0) - ossl_raise(eRSAError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -#define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16) - -/* - * call-seq: - * rsa.public_encrypt(string) => String - * rsa.public_encrypt(string, padding) => String - * - * Encrypt +string+ with the public key. +padding+ defaults to PKCS1_PADDING. - * The encrypted string output can be decrypted using #private_decrypt. - */ -static VALUE -ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - int buf_len, pad; - VALUE str, buffer, padding; - - GetPKeyRSA(self, pkey); - rb_scan_args(argc, argv, "11", &buffer, &padding); - pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); - StringValue(buffer); - str = rb_str_new(0, ossl_rsa_buf_size(pkey)); - buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), - (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa, - pad); - if (buf_len < 0) ossl_raise(eRSAError, NULL); - rb_str_set_len(str, buf_len); - - return str; -} - -/* - * call-seq: - * rsa.public_decrypt(string) => String - * rsa.public_decrypt(string, padding) => String - * - * Decrypt +string+, which has been encrypted with the private key, with the - * public key. +padding+ defaults to PKCS1_PADDING. - */ -static VALUE -ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - int buf_len, pad; - VALUE str, buffer, padding; - - GetPKeyRSA(self, pkey); - rb_scan_args(argc, argv, "11", &buffer, &padding); - pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); - StringValue(buffer); - str = rb_str_new(0, ossl_rsa_buf_size(pkey)); - buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), - (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa, - pad); - if (buf_len < 0) ossl_raise(eRSAError, NULL); - rb_str_set_len(str, buf_len); - - return str; -} - -/* - * call-seq: - * rsa.private_encrypt(string) => String - * rsa.private_encrypt(string, padding) => String - * - * Encrypt +string+ with the private key. +padding+ defaults to PKCS1_PADDING. - * The encrypted string output can be decrypted using #public_decrypt. - */ -static VALUE -ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - int buf_len, pad; - VALUE str, buffer, padding; - - GetPKeyRSA(self, pkey); - if (!RSA_PRIVATE(self, pkey->pkey.rsa)) { - ossl_raise(eRSAError, "private key needed."); - } - rb_scan_args(argc, argv, "11", &buffer, &padding); - pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); - StringValue(buffer); - str = rb_str_new(0, ossl_rsa_buf_size(pkey)); - buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), - (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa, - pad); - if (buf_len < 0) ossl_raise(eRSAError, NULL); - rb_str_set_len(str, buf_len); - - return str; -} - -/* - * call-seq: - * rsa.private_decrypt(string) => String - * rsa.private_decrypt(string, padding) => String - * - * Decrypt +string+, which has been encrypted with the public key, with the - * private key. +padding+ defaults to PKCS1_PADDING. - */ -static VALUE -ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self) -{ - EVP_PKEY *pkey; - int buf_len, pad; - VALUE str, buffer, padding; - - GetPKeyRSA(self, pkey); - if (!RSA_PRIVATE(self, pkey->pkey.rsa)) { - ossl_raise(eRSAError, "private key needed."); - } - rb_scan_args(argc, argv, "11", &buffer, &padding); - pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); - StringValue(buffer); - str = rb_str_new(0, ossl_rsa_buf_size(pkey)); - buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), - (unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa, - pad); - if (buf_len < 0) ossl_raise(eRSAError, NULL); - rb_str_set_len(str, buf_len); - - return str; -} - -/* - * call-seq: - * rsa.params => hash - * - * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!! - * - * Stores all parameters of key to the hash. The hash has keys 'n', 'e', 'd', - * 'p', 'q', 'dmp1', 'dmq1', 'iqmp'. - * - * Don't use :-)) (It's up to you) - */ -static VALUE -ossl_rsa_get_params(VALUE self) -{ - EVP_PKEY *pkey; - VALUE hash; - - GetPKeyRSA(self, pkey); - - hash = rb_hash_new(); - - rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n)); - rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e)); - rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d)); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q)); - rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1)); - rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1)); - rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp)); - - return hash; -} - -/* - * call-seq: - * rsa.to_text => String - * - * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!! - * - * Dumps all parameters of a keypair to a String - * - * Don't use :-)) (It's up to you) - */ -static VALUE -ossl_rsa_to_text(VALUE self) -{ - EVP_PKEY *pkey; - BIO *out; - VALUE str; - - GetPKeyRSA(self, pkey); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eRSAError, NULL); - } - if (!RSA_print(out, pkey->pkey.rsa, 0)) { /* offset = 0 */ - BIO_free(out); - ossl_raise(eRSAError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * rsa.public_key -> RSA - * - * Makes new RSA instance containing the public key from the private key. - */ -static VALUE -ossl_rsa_to_public_key(VALUE self) -{ - EVP_PKEY *pkey; - RSA *rsa; - VALUE obj; - - GetPKeyRSA(self, pkey); - /* err check performed by rsa_instance */ - rsa = RSAPublicKey_dup(pkey->pkey.rsa); - obj = rsa_instance(CLASS_OF(self), rsa); - if (obj == Qfalse) { - RSA_free(rsa); - ossl_raise(eRSAError, NULL); - } - return obj; -} - -/* - * TODO: Test me - -static VALUE -ossl_rsa_blinding_on(VALUE self) -{ - EVP_PKEY *pkey; - - GetPKeyRSA(self, pkey); - - if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) { - ossl_raise(eRSAError, NULL); - } - return self; -} - -static VALUE -ossl_rsa_blinding_off(VALUE self) -{ - EVP_PKEY *pkey; - - GetPKeyRSA(self, pkey); - RSA_blinding_off(pkey->pkey.rsa); - - return self; -} - */ - -OSSL_PKEY_BN(rsa, n) -OSSL_PKEY_BN(rsa, e) -OSSL_PKEY_BN(rsa, d) -OSSL_PKEY_BN(rsa, p) -OSSL_PKEY_BN(rsa, q) -OSSL_PKEY_BN(rsa, dmp1) -OSSL_PKEY_BN(rsa, dmq1) -OSSL_PKEY_BN(rsa, iqmp) - -/* - * INIT - */ -#define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x)) - -void -Init_ossl_rsa() -{ -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */ - mPKey = rb_define_module_under(mOSSL, "PKey"); -#endif - - /* Document-class: OpenSSL::PKey::RSAError - * - * Generic exception that is raised if an operation on an RSA PKey - * fails unexpectedly or in case an instantiation of an instance of RSA - * fails due to non-conformant input data. - */ - eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError); - - /* Document-class: OpenSSL::PKey::RSA - * - * RSA is an asymmetric public key algorithm that has been formalized in - * RFC 3447. It is in widespread use in public key infrastuctures (PKI) - * where certificates (cf. OpenSSL::X509::Certificate) often are issued - * on the basis of a public/private RSA key pair. RSA is used in a wide - * field of applications such as secure (symmetric) key exchange, e.g. - * when establishing a secure TLS/SSL connection. It is also used in - * various digital signature schemes. - */ - cRSA = rb_define_class_under(mPKey, "RSA", cPKey); - - rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1); - rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1); - - rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0); - rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0); - rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0); - rb_define_method(cRSA, "export", ossl_rsa_export, -1); - rb_define_alias(cRSA, "to_pem", "export"); - rb_define_alias(cRSA, "to_s", "export"); - rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0); - rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0); - rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1); - rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1); - rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1); - rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1); - - DEF_OSSL_PKEY_BN(cRSA, rsa, n); - DEF_OSSL_PKEY_BN(cRSA, rsa, e); - DEF_OSSL_PKEY_BN(cRSA, rsa, d); - DEF_OSSL_PKEY_BN(cRSA, rsa, p); - DEF_OSSL_PKEY_BN(cRSA, rsa, q); - DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1); - DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1); - DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp); - - rb_define_method(cRSA, "params", ossl_rsa_get_params, 0); - - DefRSAConst(PKCS1_PADDING); - DefRSAConst(SSLV23_PADDING); - DefRSAConst(NO_PADDING); - DefRSAConst(PKCS1_OAEP_PADDING); - -/* - * TODO: Test it - rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0); - rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0); - */ -} - -#else /* defined NO_RSA */ -void -Init_ossl_rsa() -{ -} -#endif /* NO_RSA */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_rand.c b/ruby_1_9_3/ext/openssl/ossl_rand.c deleted file mode 100644 index 270a4b7437..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_rand.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -/* - * Classes - */ -VALUE mRandom; -VALUE eRandomError; - -/* - * Struct - */ - -/* - * Public - */ - -/* - * Private - */ - -/* - * call-seq: - * seed(str) -> str - * - */ -static VALUE -ossl_rand_seed(VALUE self, VALUE str) -{ - StringValue(str); - RAND_seed(RSTRING_PTR(str), RSTRING_LENINT(str)); - - return str; -} - -/* - * call-seq: - * add(str, entropy) -> self - * - */ -static VALUE -ossl_rand_add(VALUE self, VALUE str, VALUE entropy) -{ - StringValue(str); - RAND_add(RSTRING_PTR(str), RSTRING_LENINT(str), NUM2DBL(entropy)); - - return self; -} - -/* - * call-seq: - * load_random_file(filename) -> true - * - */ -static VALUE -ossl_rand_load_file(VALUE self, VALUE filename) -{ - SafeStringValue(filename); - - if(!RAND_load_file(RSTRING_PTR(filename), -1)) { - ossl_raise(eRandomError, NULL); - } - return Qtrue; -} - -/* - * call-seq: - * write_random_file(filename) -> true - * - */ -static VALUE -ossl_rand_write_file(VALUE self, VALUE filename) -{ - SafeStringValue(filename); - if (RAND_write_file(RSTRING_PTR(filename)) == -1) { - ossl_raise(eRandomError, NULL); - } - return Qtrue; -} - -/* - * call-seq: - * random_bytes(length) -> aString - * - */ -static VALUE -ossl_rand_bytes(VALUE self, VALUE len) -{ - VALUE str; - int n = NUM2INT(len); - - str = rb_str_new(0, n); - if (!RAND_bytes((unsigned char *)RSTRING_PTR(str), n)) { - ossl_raise(eRandomError, NULL); - } - - return str; -} - -/* - * call-seq: - * pseudo_bytes(length) -> aString - * - */ -static VALUE -ossl_rand_pseudo_bytes(VALUE self, VALUE len) -{ - VALUE str; - int n = NUM2INT(len); - - str = rb_str_new(0, n); - if (!RAND_pseudo_bytes((unsigned char *)RSTRING_PTR(str), n)) { - ossl_raise(eRandomError, NULL); - } - - return str; -} - -/* - * call-seq: - * egd(filename) -> true - * - */ -static VALUE -ossl_rand_egd(VALUE self, VALUE filename) -{ - SafeStringValue(filename); - - if(!RAND_egd(RSTRING_PTR(filename))) { - ossl_raise(eRandomError, NULL); - } - return Qtrue; -} - -/* - * call-seq: - * egd_bytes(filename, length) -> true - * - */ -static VALUE -ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len) -{ - int n = NUM2INT(len); - - SafeStringValue(filename); - - if (!RAND_egd_bytes(RSTRING_PTR(filename), n)) { - ossl_raise(eRandomError, NULL); - } - return Qtrue; -} - -/* - * call-seq: - * status? => true | false - * - * Return true if the PRNG has been seeded with enough data, false otherwise. - */ -static VALUE -ossl_rand_status(VALUE self) -{ - return RAND_status() ? Qtrue : Qfalse; -} - -#define DEFMETH(class, name, func, argc) \ - rb_define_method((class), (name), (func), (argc)); \ - rb_define_singleton_method((class), (name), (func), (argc)); - -/* - * INIT - */ -void -Init_ossl_rand() -{ -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ -#endif - - mRandom = rb_define_module_under(mOSSL, "Random"); - - eRandomError = rb_define_class_under(mRandom, "RandomError", eOSSLError); - - DEFMETH(mRandom, "seed", ossl_rand_seed, 1); - DEFMETH(mRandom, "random_add", ossl_rand_add, 2); - DEFMETH(mRandom, "load_random_file", ossl_rand_load_file, 1); - DEFMETH(mRandom, "write_random_file", ossl_rand_write_file, 1); - DEFMETH(mRandom, "random_bytes", ossl_rand_bytes, 1); - DEFMETH(mRandom, "pseudo_bytes", ossl_rand_pseudo_bytes, 1); - DEFMETH(mRandom, "egd", ossl_rand_egd, 1); - DEFMETH(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2); - DEFMETH(mRandom, "status?", ossl_rand_status, 0) -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_rand.h b/ruby_1_9_3/ext/openssl/ossl_rand.h deleted file mode 100644 index ce2ae0d129..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_rand.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_RAND_H_) -#define _OSSL_RAND_H_ - -extern VALUE mRandom; -extern VALUE eRandomError; - -void Init_ossl_rand(void); - -#endif /* _OSSL_RAND_H_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_ssl.c b/ruby_1_9_3/ext/openssl/ossl_ssl.c deleted file mode 100644 index e437e7ecd6..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_ssl.c +++ /dev/null @@ -1,2019 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2000-2002 GOTOU Yuuzou <gotoyuzo@notwork.org> - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * Copyright (C) 2001-2007 Technorama Ltd. <oss-ruby@technorama.net> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#if defined(HAVE_UNISTD_H) -# include <unistd.h> /* for read(), and write() */ -#endif - -#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0])) - -#ifdef _WIN32 -# define TO_SOCKET(s) _get_osfhandle(s) -#else -# define TO_SOCKET(s) (s) -#endif - -VALUE mSSL; -VALUE eSSLError; -VALUE cSSLContext; -VALUE cSSLSocket; - -#define ossl_sslctx_set_cert(o,v) rb_iv_set((o),"@cert",(v)) -#define ossl_sslctx_set_key(o,v) rb_iv_set((o),"@key",(v)) -#define ossl_sslctx_set_client_ca(o,v) rb_iv_set((o),"@client_ca",(v)) -#define ossl_sslctx_set_ca_file(o,v) rb_iv_set((o),"@ca_file",(v)) -#define ossl_sslctx_set_ca_path(o,v) rb_iv_set((o),"@ca_path",(v)) -#define ossl_sslctx_set_timeout(o,v) rb_iv_set((o),"@timeout",(v)) -#define ossl_sslctx_set_verify_mode(o,v) rb_iv_set((o),"@verify_mode",(v)) -#define ossl_sslctx_set_verify_dep(o,v) rb_iv_set((o),"@verify_depth",(v)) -#define ossl_sslctx_set_verify_cb(o,v) rb_iv_set((o),"@verify_callback",(v)) -#define ossl_sslctx_set_options(o,v) rb_iv_set((o),"@options",(v)) -#define ossl_sslctx_set_cert_store(o,v) rb_iv_set((o),"@cert_store",(v)) -#define ossl_sslctx_set_extra_cert(o,v) rb_iv_set((o),"@extra_chain_cert",(v)) -#define ossl_sslctx_set_client_cert_cb(o,v) rb_iv_set((o),"@client_cert_cb",(v)) -#define ossl_sslctx_set_tmp_dh_cb(o,v) rb_iv_set((o),"@tmp_dh_callback",(v)) -#define ossl_sslctx_set_sess_id_ctx(o, v) rb_iv_get((o),"@session_id_context"(v)) - -#define ossl_sslctx_get_cert(o) rb_iv_get((o),"@cert") -#define ossl_sslctx_get_key(o) rb_iv_get((o),"@key") -#define ossl_sslctx_get_client_ca(o) rb_iv_get((o),"@client_ca") -#define ossl_sslctx_get_ca_file(o) rb_iv_get((o),"@ca_file") -#define ossl_sslctx_get_ca_path(o) rb_iv_get((o),"@ca_path") -#define ossl_sslctx_get_timeout(o) rb_iv_get((o),"@timeout") -#define ossl_sslctx_get_verify_mode(o) rb_iv_get((o),"@verify_mode") -#define ossl_sslctx_get_verify_dep(o) rb_iv_get((o),"@verify_depth") -#define ossl_sslctx_get_verify_cb(o) rb_iv_get((o),"@verify_callback") -#define ossl_sslctx_get_options(o) rb_iv_get((o),"@options") -#define ossl_sslctx_get_cert_store(o) rb_iv_get((o),"@cert_store") -#define ossl_sslctx_get_extra_cert(o) rb_iv_get((o),"@extra_chain_cert") -#define ossl_sslctx_get_client_cert_cb(o) rb_iv_get((o),"@client_cert_cb") -#define ossl_sslctx_get_tmp_dh_cb(o) rb_iv_get((o),"@tmp_dh_callback") -#define ossl_sslctx_get_sess_id_ctx(o) rb_iv_get((o),"@session_id_context") - -static const char *ossl_sslctx_attrs[] = { - "cert", "key", "client_ca", "ca_file", "ca_path", - "timeout", "verify_mode", "verify_depth", - "verify_callback", "options", "cert_store", "extra_chain_cert", - "client_cert_cb", "tmp_dh_callback", "session_id_context", - "session_get_cb", "session_new_cb", "session_remove_cb", -#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME - "servername_cb", -#endif -}; - -#define ossl_ssl_get_io(o) rb_iv_get((o),"@io") -#define ossl_ssl_get_ctx(o) rb_iv_get((o),"@context") -#define ossl_ssl_get_sync_close(o) rb_iv_get((o),"@sync_close") -#define ossl_ssl_get_x509(o) rb_iv_get((o),"@x509") -#define ossl_ssl_get_key(o) rb_iv_get((o),"@key") -#define ossl_ssl_get_tmp_dh(o) rb_iv_get((o),"@tmp_dh") - -#define ossl_ssl_set_io(o,v) rb_iv_set((o),"@io",(v)) -#define ossl_ssl_set_ctx(o,v) rb_iv_set((o),"@context",(v)) -#define ossl_ssl_set_sync_close(o,v) rb_iv_set((o),"@sync_close",(v)) -#define ossl_ssl_set_x509(o,v) rb_iv_set((o),"@x509",(v)) -#define ossl_ssl_set_key(o,v) rb_iv_set((o),"@key",(v)) -#define ossl_ssl_set_tmp_dh(o,v) rb_iv_set((o),"@tmp_dh",(v)) - -static const char *ossl_ssl_attr_readers[] = { "io", "context", }; -static const char *ossl_ssl_attrs[] = { -#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME - "hostname", -#endif - "sync_close", -}; - -ID ID_callback_state; - -/* - * SSLContext class - */ -struct { - const char *name; - SSL_METHOD *(*func)(void); -} ossl_ssl_method_tab[] = { -#define OSSL_SSL_METHOD_ENTRY(name) { #name, (SSL_METHOD *(*)(void))name##_method } - OSSL_SSL_METHOD_ENTRY(TLSv1), - OSSL_SSL_METHOD_ENTRY(TLSv1_server), - OSSL_SSL_METHOD_ENTRY(TLSv1_client), -#if defined(HAVE_SSLV2_METHOD) && defined(HAVE_SSLV2_SERVER_METHOD) && \ - defined(HAVE_SSLV2_CLIENT_METHOD) - OSSL_SSL_METHOD_ENTRY(SSLv2), - OSSL_SSL_METHOD_ENTRY(SSLv2_server), - OSSL_SSL_METHOD_ENTRY(SSLv2_client), -#endif - OSSL_SSL_METHOD_ENTRY(SSLv3), - OSSL_SSL_METHOD_ENTRY(SSLv3_server), - OSSL_SSL_METHOD_ENTRY(SSLv3_client), - OSSL_SSL_METHOD_ENTRY(SSLv23), - OSSL_SSL_METHOD_ENTRY(SSLv23_server), - OSSL_SSL_METHOD_ENTRY(SSLv23_client), -#undef OSSL_SSL_METHOD_ENTRY -}; - -int ossl_ssl_ex_vcb_idx; -int ossl_ssl_ex_store_p; -int ossl_ssl_ex_ptr_idx; -int ossl_ssl_ex_client_cert_cb_idx; -int ossl_ssl_ex_tmp_dh_callback_idx; - -static void -ossl_sslctx_free(SSL_CTX *ctx) -{ - if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1) - ctx->cert_store = NULL; - SSL_CTX_free(ctx); -} - -static VALUE -ossl_sslctx_s_alloc(VALUE klass) -{ - SSL_CTX *ctx; - long mode = SSL_MODE_ENABLE_PARTIAL_WRITE; - -#ifdef SSL_MODE_RELEASE_BUFFERS - mode |= SSL_MODE_RELEASE_BUFFERS; -#endif - - ctx = SSL_CTX_new(SSLv23_method()); - if (!ctx) { - ossl_raise(eSSLError, "SSL_CTX_new:"); - } - SSL_CTX_set_mode(ctx, mode); - return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx); -} - -/* - * call-seq: - * ctx.ssl_version = :TLSv1 - * ctx.ssl_version = "SSLv23_client" - * - * You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS - */ -static VALUE -ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method) -{ - SSL_METHOD *method = NULL; - const char *s; - int i; - - SSL_CTX *ctx; - if(TYPE(ssl_method) == T_SYMBOL) - s = rb_id2name(SYM2ID(ssl_method)); - else - s = StringValuePtr(ssl_method); - for (i = 0; i < numberof(ossl_ssl_method_tab); i++) { - if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) { - method = ossl_ssl_method_tab[i].func(); - break; - } - } - if (!method) { - ossl_raise(rb_eArgError, "unknown SSL method `%s'.", s); - } - Data_Get_Struct(self, SSL_CTX, ctx); - if (SSL_CTX_set_ssl_version(ctx, method) != 1) { - ossl_raise(eSSLError, "SSL_CTX_set_ssl_version:"); - } - - return ssl_method; -} - -/* - * 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 - */ -static VALUE -ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE ssl_method; - int i; - - for(i = 0; i < numberof(ossl_sslctx_attrs); i++){ - char buf[32]; - snprintf(buf, sizeof(buf), "@%s", ossl_sslctx_attrs[i]); - rb_iv_set(self, buf, Qnil); - } - if (rb_scan_args(argc, argv, "01", &ssl_method) == 0){ - return self; - } - ossl_sslctx_set_ssl_version(self, ssl_method); - - return self; -} - -static VALUE -ossl_call_client_cert_cb(VALUE obj) -{ - VALUE cb, ary, cert, key; - SSL *ssl; - - Data_Get_Struct(obj, SSL, ssl); - cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx); - if (NIL_P(cb)) return Qfalse; - ary = rb_funcall(cb, rb_intern("call"), 1, obj); - Check_Type(ary, T_ARRAY); - GetX509CertPtr(cert = rb_ary_entry(ary, 0)); - GetPKeyPtr(key = rb_ary_entry(ary, 1)); - ossl_ssl_set_x509(obj, cert); - ossl_ssl_set_key(obj, key); - - return Qtrue; -} - -static int -ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey) -{ - VALUE obj, success; - - obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - success = rb_protect((VALUE(*)_((VALUE)))ossl_call_client_cert_cb, - obj, NULL); - if (!RTEST(success)) return 0; - *x509 = DupX509CertPtr(ossl_ssl_get_x509(obj)); - *pkey = DupPKeyPtr(ossl_ssl_get_key(obj)); - - return 1; -} - -#if !defined(OPENSSL_NO_DH) -static VALUE -ossl_call_tmp_dh_callback(VALUE *args) -{ - SSL *ssl; - VALUE cb, dh; - EVP_PKEY *pkey; - - Data_Get_Struct(args[0], SSL, ssl); - cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx); - if (NIL_P(cb)) return Qfalse; - dh = rb_funcall(cb, rb_intern("call"), 3, args[0], args[1], args[2]); - pkey = GetPKeyPtr(dh); - if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) return Qfalse; - ossl_ssl_set_tmp_dh(args[0], dh); - - return Qtrue; -} - -static DH* -ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength) -{ - VALUE args[3], success; - - args[0] = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - args[1] = INT2FIX(is_export); - args[2] = INT2FIX(keylength); - success = rb_protect((VALUE(*)_((VALUE)))ossl_call_tmp_dh_callback, - (VALUE)args, NULL); - if (!RTEST(success)) return NULL; - - return GetPKeyPtr(ossl_ssl_get_tmp_dh(args[0]))->pkey.dh; -} - -static DH* -ossl_default_tmp_dh_callback(SSL *ssl, int is_export, int keylength) -{ - rb_warning("using default DH parameters."); - - switch(keylength){ - case 512: - return OSSL_DEFAULT_DH_512; - case 1024: - return OSSL_DEFAULT_DH_1024; - } - return NULL; -} -#endif /* OPENSSL_NO_DH */ - -static int -ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) -{ - VALUE cb; - SSL *ssl; - - ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); - cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx); - X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx, (void*)cb); - return ossl_verify_cb(preverify_ok, ctx); -} - -static VALUE -ossl_call_session_get_cb(VALUE ary) -{ - VALUE ssl_obj, sslctx_obj, cb; - - Check_Type(ary, T_ARRAY); - ssl_obj = rb_ary_entry(ary, 0); - - sslctx_obj = rb_iv_get(ssl_obj, "@context"); - if (NIL_P(sslctx_obj)) return Qnil; - cb = rb_iv_get(sslctx_obj, "@session_get_cb"); - if (NIL_P(cb)) return Qnil; - - return rb_funcall(cb, rb_intern("call"), 1, ary); -} - -/* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */ -static SSL_SESSION * -ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy) -{ - VALUE ary, ssl_obj, ret_obj; - SSL_SESSION *sess; - void *ptr; - int state = 0; - - OSSL_Debug("SSL SESSION get callback entered"); - if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) - return NULL; - ssl_obj = (VALUE)ptr; - ary = rb_ary_new2(2); - rb_ary_push(ary, ssl_obj); - rb_ary_push(ary, rb_str_new((const char *)buf, len)); - - ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_get_cb, ary, &state); - if (state) { - rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); - return NULL; - } - if (!rb_obj_is_instance_of(ret_obj, cSSLSession)) - return NULL; - - SafeGetSSLSession(ret_obj, sess); - *copy = 1; - - return sess; -} - -static VALUE -ossl_call_session_new_cb(VALUE ary) -{ - VALUE ssl_obj, sslctx_obj, cb; - - Check_Type(ary, T_ARRAY); - ssl_obj = rb_ary_entry(ary, 0); - - sslctx_obj = rb_iv_get(ssl_obj, "@context"); - if (NIL_P(sslctx_obj)) return Qnil; - cb = rb_iv_get(sslctx_obj, "@session_new_cb"); - if (NIL_P(cb)) return Qnil; - - return rb_funcall(cb, rb_intern("call"), 1, ary); -} - -/* return 1 normal. return 0 removes the session */ -static int -ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess) -{ - VALUE ary, ssl_obj, sess_obj, ret_obj; - void *ptr; - int state = 0; - - OSSL_Debug("SSL SESSION new callback entered"); - - if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) - return 1; - ssl_obj = (VALUE)ptr; - sess_obj = rb_obj_alloc(cSSLSession); - CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); - DATA_PTR(sess_obj) = sess; - - ary = rb_ary_new2(2); - rb_ary_push(ary, ssl_obj); - rb_ary_push(ary, sess_obj); - - ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state); - if (state) { - rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); - } - - /* - * return 0 which means to OpenSSL that the the session is still - * valid (since we created Ruby Session object) and was not freed by us - * with SSL_SESSION_free(). Call SSLContext#remove_session(sess) in - * session_get_cb block if you don't want OpenSSL to cache the session - * internally. - */ - return 0; -} - -static VALUE -ossl_call_session_remove_cb(VALUE ary) -{ - VALUE sslctx_obj, cb; - - Check_Type(ary, T_ARRAY); - sslctx_obj = rb_ary_entry(ary, 0); - - cb = rb_iv_get(sslctx_obj, "@session_remove_cb"); - if (NIL_P(cb)) return Qnil; - - return rb_funcall(cb, rb_intern("call"), 1, ary); -} - -static void -ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) -{ - VALUE ary, sslctx_obj, sess_obj, ret_obj; - void *ptr; - int state = 0; - - OSSL_Debug("SSL SESSION remove callback entered"); - - if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL) - return; - sslctx_obj = (VALUE)ptr; - sess_obj = rb_obj_alloc(cSSLSession); - CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); - DATA_PTR(sess_obj) = sess; - - ary = rb_ary_new2(2); - rb_ary_push(ary, sslctx_obj); - rb_ary_push(ary, sess_obj); - - ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_remove_cb, ary, &state); - if (state) { -/* - the SSL_CTX is frozen, nowhere to save state. - there is no common accessor method to check it either. - rb_ivar_set(sslctx_obj, ID_callback_state, INT2NUM(state)); -*/ - } -} - -static VALUE -ossl_sslctx_add_extra_chain_cert_i(VALUE i, VALUE arg) -{ - X509 *x509; - SSL_CTX *ctx; - - Data_Get_Struct(arg, SSL_CTX, ctx); - x509 = DupX509CertPtr(i); - if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){ - ossl_raise(eSSLError, NULL); - } - - return i; -} - -static VALUE ossl_sslctx_setup(VALUE self); - -#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME -static VALUE -ossl_call_servername_cb(VALUE ary) -{ - VALUE ssl_obj, sslctx_obj, cb, ret_obj; - - Check_Type(ary, T_ARRAY); - ssl_obj = rb_ary_entry(ary, 0); - - sslctx_obj = rb_iv_get(ssl_obj, "@context"); - if (NIL_P(sslctx_obj)) return Qnil; - cb = rb_iv_get(sslctx_obj, "@servername_cb"); - if (NIL_P(cb)) return Qnil; - - ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary); - if (rb_obj_is_kind_of(ret_obj, cSSLContext)) { - SSL *ssl; - SSL_CTX *ctx2; - - ossl_sslctx_setup(ret_obj); - Data_Get_Struct(ssl_obj, SSL, ssl); - Data_Get_Struct(ret_obj, SSL_CTX, ctx2); - SSL_set_SSL_CTX(ssl, ctx2); - } else if (!NIL_P(ret_obj)) { - ossl_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil"); - } - - return ret_obj; -} - -static int -ssl_servername_cb(SSL *ssl, int *ad, void *arg) -{ - VALUE ary, ssl_obj, ret_obj; - void *ptr; - int state = 0; - const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); - - if (!servername) - return SSL_TLSEXT_ERR_OK; - - if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) - return SSL_TLSEXT_ERR_ALERT_FATAL; - ssl_obj = (VALUE)ptr; - ary = rb_ary_new2(2); - rb_ary_push(ary, ssl_obj); - rb_ary_push(ary, rb_str_new2(servername)); - - ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_servername_cb, ary, &state); - if (state) { - rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); - return SSL_TLSEXT_ERR_ALERT_FATAL; - } - - return SSL_TLSEXT_ERR_OK; -} -#endif - -/* - * call-seq: - * ctx.setup => Qtrue # first time - * ctx.setup => nil # thereafter - * - * This method is called automatically when a new SSLSocket is created. - * Normally you do not need to call this method (unless you are writing an - * extension in C). - */ -static VALUE -ossl_sslctx_setup(VALUE self) -{ - SSL_CTX *ctx; - X509 *cert = NULL, *client_ca = NULL; - X509_STORE *store; - EVP_PKEY *key = NULL; - char *ca_path = NULL, *ca_file = NULL; - int i, verify_mode; - VALUE val; - - if(OBJ_FROZEN(self)) return Qnil; - Data_Get_Struct(self, SSL_CTX, ctx); - -#if !defined(OPENSSL_NO_DH) - if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){ - SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); - } - else{ - SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback); - } -#endif - SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self); - - val = ossl_sslctx_get_cert_store(self); - if(!NIL_P(val)){ - /* - * WORKAROUND: - * X509_STORE can count references, but - * X509_STORE_free() doesn't care it. - * So we won't increment it but mark it by ex_data. - */ - store = GetX509StorePtr(val); /* NO NEED TO DUP */ - SSL_CTX_set_cert_store(ctx, store); - SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1); - } - - val = ossl_sslctx_get_extra_cert(self); - if(!NIL_P(val)){ - rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self); - } - - /* private key may be bundled in certificate file. */ - val = ossl_sslctx_get_cert(self); - cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */ - val = ossl_sslctx_get_key(self); - key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */ - if (cert && key) { - if (!SSL_CTX_use_certificate(ctx, cert)) { - /* Adds a ref => Safe to FREE */ - ossl_raise(eSSLError, "SSL_CTX_use_certificate:"); - } - if (!SSL_CTX_use_PrivateKey(ctx, key)) { - /* Adds a ref => Safe to FREE */ - ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey:"); - } - if (!SSL_CTX_check_private_key(ctx)) { - ossl_raise(eSSLError, "SSL_CTX_check_private_key:"); - } - } - - val = ossl_sslctx_get_client_ca(self); - if(!NIL_P(val)){ - if(TYPE(val) == T_ARRAY){ - for(i = 0; i < RARRAY_LEN(val); i++){ - client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]); - if (!SSL_CTX_add_client_CA(ctx, client_ca)){ - /* Copies X509_NAME => FREE it. */ - ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); - } - } - } - else{ - client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ - if (!SSL_CTX_add_client_CA(ctx, client_ca)){ - /* Copies X509_NAME => FREE it. */ - ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); - } - } - } - - val = ossl_sslctx_get_ca_file(self); - ca_file = NIL_P(val) ? NULL : StringValuePtr(val); - val = ossl_sslctx_get_ca_path(self); - ca_path = NIL_P(val) ? NULL : StringValuePtr(val); - if(ca_file || ca_path){ - if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) - rb_warning("can't set verify locations"); - } - - val = ossl_sslctx_get_verify_mode(self); - verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val); - SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback); - if (RTEST(ossl_sslctx_get_client_cert_cb(self))) - SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); - - val = ossl_sslctx_get_timeout(self); - if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val)); - - val = ossl_sslctx_get_verify_dep(self); - if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val)); - - val = ossl_sslctx_get_options(self); - if(!NIL_P(val)) { - SSL_CTX_set_options(ctx, NUM2LONG(val)); - } - else { - SSL_CTX_set_options(ctx, SSL_OP_ALL); - } - rb_obj_freeze(self); - - val = ossl_sslctx_get_sess_id_ctx(self); - if (!NIL_P(val)){ - StringValue(val); - if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val), - RSTRING_LENINT(val))){ - ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:"); - } - } - - if (RTEST(rb_iv_get(self, "@session_get_cb"))) { - SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); - OSSL_Debug("SSL SESSION get callback added"); - } - if (RTEST(rb_iv_get(self, "@session_new_cb"))) { - SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); - OSSL_Debug("SSL SESSION new callback added"); - } - if (RTEST(rb_iv_get(self, "@session_remove_cb"))) { - SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); - OSSL_Debug("SSL SESSION remove callback added"); - } - -#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME - val = rb_iv_get(self, "@servername_cb"); - if (!NIL_P(val)) { - SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); - OSSL_Debug("SSL TLSEXT servername callback added"); - } -#endif - - return Qtrue; -} - -static VALUE -ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher) -{ - VALUE ary; - int bits, alg_bits; - - ary = rb_ary_new2(4); - rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_name(cipher))); - rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_version(cipher))); - bits = SSL_CIPHER_get_bits(cipher, &alg_bits); - rb_ary_push(ary, INT2FIX(bits)); - rb_ary_push(ary, INT2FIX(alg_bits)); - - return ary; -} - -/* - * call-seq: - * ctx.ciphers => [[name, version, bits, alg_bits], ...] - * - * The list of ciphers configured for this context. - */ -static VALUE -ossl_sslctx_get_ciphers(VALUE self) -{ - SSL_CTX *ctx; - STACK_OF(SSL_CIPHER) *ciphers; - SSL_CIPHER *cipher; - VALUE ary; - int i, num; - - Data_Get_Struct(self, SSL_CTX, ctx); - if(!ctx){ - rb_warning("SSL_CTX is not initialized."); - return Qnil; - } - ciphers = ctx->cipher_list; - - if (!ciphers) - return rb_ary_new(); - - num = sk_SSL_CIPHER_num(ciphers); - ary = rb_ary_new2(num); - for(i = 0; i < num; i++){ - cipher = sk_SSL_CIPHER_value(ciphers, i); - rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher)); - } - return ary; -} - -/* - * call-seq: - * ctx.ciphers = "cipher1:cipher2:..." - * ctx.ciphers = [name, ...] - * ctx.ciphers = [[name, version, bits, alg_bits], ...] - * - * Sets the list of available ciphers for this context. Note in a server - * context some ciphers require the appropriate certificates. For example, an - * RSA cipher can only be chosen when an RSA certificate is available. - * - * See also OpenSSL::Cipher and OpenSSL::Cipher::ciphers - */ -static VALUE -ossl_sslctx_set_ciphers(VALUE self, VALUE v) -{ - SSL_CTX *ctx; - VALUE str, elem; - int i; - - rb_check_frozen(self); - if (NIL_P(v)) - return v; - else if (TYPE(v) == T_ARRAY) { - str = rb_str_new(0, 0); - for (i = 0; i < RARRAY_LEN(v); i++) { - elem = rb_ary_entry(v, i); - if (TYPE(elem) == T_ARRAY) elem = rb_ary_entry(elem, 0); - elem = rb_String(elem); - rb_str_append(str, elem); - if (i < RARRAY_LEN(v)-1) rb_str_cat2(str, ":"); - } - } else { - str = v; - StringValue(str); - } - - Data_Get_Struct(self, SSL_CTX, ctx); - if(!ctx){ - ossl_raise(eSSLError, "SSL_CTX is not initialized."); - return Qnil; - } - if (!SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(str))) { - ossl_raise(eSSLError, "SSL_CTX_set_cipher_list:"); - } - - return v; -} - - -/* - * call-seq: - * ctx.session_add(session) -> true | false - * - * Adds +session+ to the session cache - */ -static VALUE -ossl_sslctx_session_add(VALUE self, VALUE arg) -{ - SSL_CTX *ctx; - SSL_SESSION *sess; - - Data_Get_Struct(self, SSL_CTX, ctx); - SafeGetSSLSession(arg, sess); - - return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse; -} - -/* - * call-seq: - * ctx.session_remove(session) -> true | false - * - * Removes +session+ from the session cache - */ -static VALUE -ossl_sslctx_session_remove(VALUE self, VALUE arg) -{ - SSL_CTX *ctx; - SSL_SESSION *sess; - - Data_Get_Struct(self, SSL_CTX, ctx); - SafeGetSSLSession(arg, sess); - - return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse; -} - -/* - * call-seq: - * ctx.session_cache_mode -> Integer - * - * The current session cache mode. - */ -static VALUE -ossl_sslctx_get_session_cache_mode(VALUE self) -{ - SSL_CTX *ctx; - - Data_Get_Struct(self, SSL_CTX, ctx); - - return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx)); -} - -/* - * call-seq: - * ctx.session_cache_mode=(integer) -> Integer - * - * Sets the SSL session cache mode. Bitwise-or together the desired - * SESSION_CACHE_* constants to set. See SSL_CTX_set_session_cache_mode(3) for - * details. - */ -static VALUE -ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg) -{ - SSL_CTX *ctx; - - Data_Get_Struct(self, SSL_CTX, ctx); - - SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg)); - - return arg; -} - -/* - * call-seq: - * ctx.session_cache_size -> Integer - * - * Returns the current session cache size. Zero is used to represent an - * unlimited cache size. - */ -static VALUE -ossl_sslctx_get_session_cache_size(VALUE self) -{ - SSL_CTX *ctx; - - Data_Get_Struct(self, SSL_CTX, ctx); - - return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx)); -} - -/* - * call-seq: - * ctx.session_cache_size=(integer) -> Integer - * - * Sets the session cache size. Returns the previously valid session cache - * size. Zero is used to represent an unlimited session cache size. - */ -static VALUE -ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg) -{ - SSL_CTX *ctx; - - Data_Get_Struct(self, SSL_CTX, ctx); - - SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg)); - - return arg; -} - -/* - * call-seq: - * ctx.session_cache_stats -> Hash - * - * Returns a Hash containing the following keys: - * - * :accept:: Number of started SSL/TLS handshakes in server mode - * :accept_good:: Number of established SSL/TLS sessions in server mode - * :accept_renegotiate:: Number of start renegotiations in server mode - * :cache_full:: Number of sessions that were removed due to cache overflow - * :cache_hits:: Number of successfully reused connections - * :cache_misses:: Number of sessions proposed by clients that were not found - * in the cache - * :cache_num:: Number of sessions in the internal session cache - * :cb_hits:: Number of sessions retrieved from the external cache in server - * mode - * :connect:: Number of started SSL/TLS handshakes in client mode - * :connect_good:: Number of established SSL/TLS sessions in client mode - * :connect_renegotiate:: Number of start renegotiations in client mode - * :timeouts:: Number of sessions proposed by clients that were found in the - * cache but had expired due to timeouts - */ -static VALUE -ossl_sslctx_get_session_cache_stats(VALUE self) -{ - SSL_CTX *ctx; - VALUE hash; - - Data_Get_Struct(self, SSL_CTX, ctx); - - hash = rb_hash_new(); - rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("connect")), LONG2NUM(SSL_CTX_sess_connect(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("connect_good")), LONG2NUM(SSL_CTX_sess_connect_good(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("connect_renegotiate")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("accept")), LONG2NUM(SSL_CTX_sess_accept(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("accept_good")), LONG2NUM(SSL_CTX_sess_accept_good(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("accept_renegotiate")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("cache_hits")), LONG2NUM(SSL_CTX_sess_hits(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("cb_hits")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("cache_misses")), LONG2NUM(SSL_CTX_sess_misses(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("cache_full")), LONG2NUM(SSL_CTX_sess_cache_full(ctx))); - rb_hash_aset(hash, ID2SYM(rb_intern("timeouts")), LONG2NUM(SSL_CTX_sess_timeouts(ctx))); - - return hash; -} - - -/* - * call-seq: - * ctx.flush_sessions(time | nil) -> self - * - * Removes sessions in the internal cache that have expired at +time+. - */ -static VALUE -ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self) -{ - VALUE arg1; - SSL_CTX *ctx; - time_t tm = 0; - - rb_scan_args(argc, argv, "01", &arg1); - - Data_Get_Struct(self, SSL_CTX, ctx); - - if (NIL_P(arg1)) { - tm = time(0); - } else if (rb_obj_is_instance_of(arg1, rb_cTime)) { - tm = NUM2LONG(rb_funcall(arg1, rb_intern("to_i"), 0)); - } else { - ossl_raise(rb_eArgError, "arg must be Time or nil"); - } - - SSL_CTX_flush_sessions(ctx, (long)tm); - - return self; -} - -/* - * SSLSocket class - */ -static void -ossl_ssl_shutdown(SSL *ssl) -{ - int i, rc; - - if (ssl) { - /* 4 is from SSL_smart_shutdown() of mod_ssl.c (v2.2.19) */ - /* It says max 2x pending + 2x data = 4 */ - for (i = 0; i < 4; ++i) { - /* - * Ignore the case SSL_shutdown returns -1. Empty handshake_func - * must not happen. - */ - if (rc = SSL_shutdown(ssl)) - break; - } - ERR_clear_error(); - SSL_clear(ssl); - } -} - -static void -ossl_ssl_free(SSL *ssl) -{ - SSL_free(ssl); -} - -static VALUE -ossl_ssl_s_alloc(VALUE klass) -{ - return Data_Wrap_Struct(klass, 0, ossl_ssl_free, NULL); -} - -/* - * call-seq: - * SSLSocket.new(io) => aSSLSocket - * SSLSocket.new(io, ctx) => aSSLSocket - * - * Creates a new SSL socket from +io+ which must be a real ruby object (not an - * IO-like object that responds to read/write. - * - * If +ctx+ is provided the SSL Sockets initial params will be taken from - * the context. - * - * The OpenSSL::Buffering module provides additional IO methods. - * - * This method will freeze the SSLContext if one is provided; - * however, session management is still allowed in the frozen SSLContext. - */ -static VALUE -ossl_ssl_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE io, ctx; - - if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) { - ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); - } - OSSL_Check_Kind(ctx, cSSLContext); - Check_Type(io, T_FILE); - ossl_ssl_set_io(self, io); - ossl_ssl_set_ctx(self, ctx); - ossl_ssl_set_sync_close(self, Qfalse); - ossl_sslctx_setup(ctx); - - rb_iv_set(self, "@hostname", Qnil); - - rb_call_super(0, 0); - - return self; -} - -static VALUE -ossl_ssl_setup(VALUE self) -{ - VALUE io, v_ctx, cb; - SSL_CTX *ctx; - SSL *ssl; - rb_io_t *fptr; - - Data_Get_Struct(self, SSL, ssl); - if(!ssl){ -#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME - VALUE hostname = rb_iv_get(self, "@hostname"); -#endif - - v_ctx = ossl_ssl_get_ctx(self); - Data_Get_Struct(v_ctx, SSL_CTX, ctx); - - ssl = SSL_new(ctx); - if (!ssl) { - ossl_raise(eSSLError, "SSL_new:"); - } - DATA_PTR(self) = ssl; - -#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME - if (!NIL_P(hostname)) { - if (SSL_set_tlsext_host_name(ssl, StringValuePtr(hostname)) != 1) - ossl_raise(eSSLError, "SSL_set_tlsext_host_name:"); - } -#endif - io = ossl_ssl_get_io(self); - GetOpenFile(io, fptr); - rb_io_check_readable(fptr); - rb_io_check_writable(fptr); - SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr))); - SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void*)self); - cb = ossl_sslctx_get_verify_cb(v_ctx); - SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void*)cb); - cb = ossl_sslctx_get_client_cert_cb(v_ctx); - SSL_set_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx, (void*)cb); - cb = ossl_sslctx_get_tmp_dh_cb(v_ctx); - SSL_set_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx, (void*)cb); - } - - return Qtrue; -} - -#ifdef _WIN32 -#define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret))) -#else -#define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret)) -#endif - -static void -write_would_block(int nonblock) -{ - if (nonblock) { - VALUE exc = ossl_exc_new(eSSLError, "write would block"); - rb_extend_object(exc, rb_mWaitWritable); - rb_exc_raise(exc); - } -} - -static void -read_would_block(int nonblock) -{ - if (nonblock) { - VALUE exc = ossl_exc_new(eSSLError, "read would block"); - rb_extend_object(exc, rb_mWaitReadable); - rb_exc_raise(exc); - } -} - -static VALUE -ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, int nonblock) -{ - SSL *ssl; - rb_io_t *fptr; - int ret, ret2; - VALUE cb_state; - - rb_ivar_set(self, ID_callback_state, Qnil); - - Data_Get_Struct(self, SSL, ssl); - GetOpenFile(ossl_ssl_get_io(self), fptr); - for(;;){ - ret = func(ssl); - - cb_state = rb_ivar_get(self, ID_callback_state); - if (!NIL_P(cb_state)) - rb_jump_tag(NUM2INT(cb_state)); - - if (ret > 0) - break; - - switch((ret2 = ssl_get_error(ssl, ret))){ - case SSL_ERROR_WANT_WRITE: - write_would_block(nonblock); - rb_io_wait_writable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_WANT_READ: - read_would_block(nonblock); - rb_io_wait_readable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_SYSCALL: - if (errno) rb_sys_fail(funcname); - ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); - default: - ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); - } - } - - return self; -} - -/* - * call-seq: - * ssl.connect => self - * - * Initiates an SSL/TLS handshake with a server. The handshake may be started - * after unencrypted data has been sent over the socket. - */ -static VALUE -ossl_ssl_connect(VALUE self) -{ - ossl_ssl_setup(self); - return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0); -} - -/* - * call-seq: - * ssl.connect_nonblock => self - * - * Initiates the SSL/TLS handshake as a client in non-blocking manner. - * - * # emulates blocking connect - * begin - * ssl.connect_nonblock - * rescue IO::WaitReadable - * IO.select([s2]) - * retry - * rescue IO::WaitWritable - * IO.select(nil, [s2]) - * retry - * end - * - */ -static VALUE -ossl_ssl_connect_nonblock(VALUE self) -{ - ossl_ssl_setup(self); - return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1); -} - -/* - * call-seq: - * ssl.accept => self - * - * Waits for a SSL/TLS client to initiate a handshake. The handshake may be - * started after unencrypted data has been sent over the socket. - */ -static VALUE -ossl_ssl_accept(VALUE self) -{ - ossl_ssl_setup(self); - return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0); -} - -/* - * call-seq: - * ssl.accept_nonblock => self - * - * Initiates the SSL/TLS handshake as a server in non-blocking manner. - * - * # emulates blocking accept - * begin - * ssl.accept_nonblock - * rescue IO::WaitReadable - * IO.select([s2]) - * retry - * rescue IO::WaitWritable - * IO.select(nil, [s2]) - * retry - * end - * - */ -static VALUE -ossl_ssl_accept_nonblock(VALUE self) -{ - ossl_ssl_setup(self); - return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1); -} - -static VALUE -ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) -{ - SSL *ssl; - int ilen, nread = 0; - VALUE len, str; - rb_io_t *fptr; - - rb_scan_args(argc, argv, "11", &len, &str); - ilen = NUM2INT(len); - if(NIL_P(str)) str = rb_str_new(0, ilen); - else{ - StringValue(str); - rb_str_modify(str); - rb_str_resize(str, ilen); - } - if(ilen == 0) return str; - - Data_Get_Struct(self, SSL, ssl); - GetOpenFile(ossl_ssl_get_io(self), fptr); - if (ssl) { - if(!nonblock && SSL_pending(ssl) <= 0) - rb_thread_wait_fd(FPTR_TO_FD(fptr)); - for (;;){ - nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str)); - switch(ssl_get_error(ssl, nread)){ - case SSL_ERROR_NONE: - goto end; - case SSL_ERROR_ZERO_RETURN: - rb_eof_error(); - case SSL_ERROR_WANT_WRITE: - write_would_block(nonblock); - rb_io_wait_writable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_WANT_READ: - read_would_block(nonblock); - rb_io_wait_readable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_SYSCALL: - if(ERR_peek_error() == 0 && nread == 0) rb_eof_error(); - rb_sys_fail(0); - default: - ossl_raise(eSSLError, "SSL_read:"); - } - } - } - else { - ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); - rb_warning("SSL session is not started yet."); - return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str); - } - - end: - rb_str_set_len(str, nread); - OBJ_TAINT(str); - - return str; -} - - -/* - * call-seq: - * ssl.sysread(length) => string - * ssl.sysread(length, buffer) => buffer - * - * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+ - * is provided the data will be written into it. - */ -static VALUE -ossl_ssl_read(int argc, VALUE *argv, VALUE self) -{ - return ossl_ssl_read_internal(argc, argv, self, 0); -} - -/* - * call-seq: - * ssl.sysread_nonblock(length) => string - * ssl.sysread_nonblock(length, buffer) => buffer - * - * A non-blocking version of #sysread. Raises an SSLError if reading would - * block. - * - * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+ - * is provided the data will be written into it. - */ -static VALUE -ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self) -{ - return ossl_ssl_read_internal(argc, argv, self, 1); -} - -static VALUE -ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock) -{ - SSL *ssl; - int nwrite = 0; - rb_io_t *fptr; - - StringValue(str); - Data_Get_Struct(self, SSL, ssl); - GetOpenFile(ossl_ssl_get_io(self), fptr); - - if (ssl) { - for (;;){ - nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str)); - switch(ssl_get_error(ssl, nwrite)){ - case SSL_ERROR_NONE: - goto end; - case SSL_ERROR_WANT_WRITE: - write_would_block(nonblock); - rb_io_wait_writable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_WANT_READ: - read_would_block(nonblock); - rb_io_wait_readable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_SYSCALL: - if (errno) rb_sys_fail(0); - default: - ossl_raise(eSSLError, "SSL_write:"); - } - } - } - else { - ID id_syswrite = rb_intern("syswrite"); - rb_warning("SSL session is not started yet."); - return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str); - } - - end: - return INT2NUM(nwrite); -} - -/* - * call-seq: - * ssl.syswrite(string) => Integer - * - * Writes +string+ to the SSL connection. - */ -static VALUE -ossl_ssl_write(VALUE self, VALUE str) -{ - return ossl_ssl_write_internal(self, str, 0); -} - -/* - * call-seq: - * ssl.syswrite_nonblock(string) => Integer - * - * Writes +string+ to the SSL connection in a non-blocking manner. Raises an - * SSLError if writing would block. - */ -static VALUE -ossl_ssl_write_nonblock(VALUE self, VALUE str) -{ - return ossl_ssl_write_internal(self, str, 1); -} - -/* - * call-seq: - * ssl.sysclose => nil - * - * Shuts down the SSL connection and prepares it for another connection. - */ -static VALUE -ossl_ssl_close(VALUE self) -{ - SSL *ssl; - - Data_Get_Struct(self, SSL, ssl); - if (ssl) { - VALUE io = ossl_ssl_get_io(self); - if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) { - ossl_ssl_shutdown(ssl); - SSL_free(ssl); - DATA_PTR(self) = NULL; - if (RTEST(ossl_ssl_get_sync_close(self))) - rb_funcall(io, rb_intern("close"), 0); - } - } - - return Qnil; -} - -/* - * call-seq: - * ssl.cert => cert or nil - * - * The X509 certificate for this socket endpoint. - */ -static VALUE -ossl_ssl_get_cert(VALUE self) -{ - SSL *ssl; - X509 *cert = NULL; - - Data_Get_Struct(self, SSL, ssl); - if (!ssl) { - rb_warning("SSL session is not started yet."); - return Qnil; - } - - /* - * Is this OpenSSL bug? Should add a ref? - * TODO: Ask for. - */ - cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */ - - if (!cert) { - return Qnil; - } - return ossl_x509_new(cert); -} - -/* - * call-seq: - * ssl.peer_cert => cert or nil - * - * The X509 certificate for this socket's peer. - */ -static VALUE -ossl_ssl_get_peer_cert(VALUE self) -{ - SSL *ssl; - X509 *cert = NULL; - VALUE obj; - - Data_Get_Struct(self, SSL, ssl); - - if (!ssl){ - rb_warning("SSL session is not started yet."); - return Qnil; - } - - cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */ - - if (!cert) { - return Qnil; - } - obj = ossl_x509_new(cert); - X509_free(cert); - - return obj; -} - -/* - * call-seq: - * ssl.peer_cert_chain => [cert, ...] or nil - * - * The X509 certificate chain for this socket's peer. - */ -static VALUE -ossl_ssl_get_peer_cert_chain(VALUE self) -{ - SSL *ssl; - STACK_OF(X509) *chain; - X509 *cert; - VALUE ary; - int i, num; - - Data_Get_Struct(self, SSL, ssl); - if(!ssl){ - rb_warning("SSL session is not started yet."); - return Qnil; - } - chain = SSL_get_peer_cert_chain(ssl); - if(!chain) return Qnil; - num = sk_X509_num(chain); - ary = rb_ary_new2(num); - for (i = 0; i < num; i++){ - cert = sk_X509_value(chain, i); - rb_ary_push(ary, ossl_x509_new(cert)); - } - - return ary; -} - -/* - * call-seq: - * ssl.cipher => [name, version, bits, alg_bits] - * - * The cipher being used for the current connection - */ -static VALUE -ossl_ssl_get_cipher(VALUE self) -{ - SSL *ssl; - SSL_CIPHER *cipher; - - Data_Get_Struct(self, SSL, ssl); - if (!ssl) { - rb_warning("SSL session is not started yet."); - return Qnil; - } - cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl); - - return ossl_ssl_cipher_to_ary(cipher); -} - -/* - * call-seq: - * ssl.state => string - * - * A description of the current connection state. - */ -static VALUE -ossl_ssl_get_state(VALUE self) -{ - SSL *ssl; - VALUE ret; - - Data_Get_Struct(self, SSL, ssl); - if (!ssl) { - rb_warning("SSL session is not started yet."); - return Qnil; - } - ret = rb_str_new2(SSL_state_string(ssl)); - if (ruby_verbose) { - rb_str_cat2(ret, ": "); - rb_str_cat2(ret, SSL_state_string_long(ssl)); - } - return ret; -} - -/* - * call-seq: - * ssl.pending => Integer - * - * The number of bytes that are immediately available for reading - */ -static VALUE -ossl_ssl_pending(VALUE self) -{ - SSL *ssl; - - Data_Get_Struct(self, SSL, ssl); - if (!ssl) { - rb_warning("SSL session is not started yet."); - return Qnil; - } - - return INT2NUM(SSL_pending(ssl)); -} - -/* - * call-seq: - * ssl.session_reused? -> true | false - * - * Returns true if a reused session was negotiated during the handshake. - */ -static VALUE -ossl_ssl_session_reused(VALUE self) -{ - SSL *ssl; - - Data_Get_Struct(self, SSL, ssl); - if (!ssl) { - rb_warning("SSL session is not started yet."); - return Qnil; - } - - switch(SSL_session_reused(ssl)) { - case 1: return Qtrue; - case 0: return Qfalse; - default: ossl_raise(eSSLError, "SSL_session_reused"); - } -} - -/* - * call-seq: - * ssl.session = session -> session - * - * Sets the Session to be used when the connection is established. - */ -static VALUE -ossl_ssl_set_session(VALUE self, VALUE arg1) -{ - SSL *ssl; - SSL_SESSION *sess; - -/* why is ossl_ssl_setup delayed? */ - ossl_ssl_setup(self); - - Data_Get_Struct(self, SSL, ssl); - if (!ssl) { - rb_warning("SSL session is not started yet."); - return Qnil; - } - - SafeGetSSLSession(arg1, sess); - - if (SSL_set_session(ssl, sess) != 1) - ossl_raise(eSSLError, "SSL_set_session"); - - return arg1; -} - -/* - * call-seq: - * ssl.verify_result => Integer - * - * Returns the result of the peer certificates verification. See verify(1) - * for error values and descriptions. - * - * If no peer certificate was presented X509_V_OK is returned. - */ -static VALUE -ossl_ssl_get_verify_result(VALUE self) -{ - SSL *ssl; - - Data_Get_Struct(self, SSL, ssl); - if (!ssl) { - rb_warning("SSL session is not started yet."); - return Qnil; - } - - return INT2FIX(SSL_get_verify_result(ssl)); -} - -/* - * call-seq: - * ssl.client_ca => [x509name, ...] - * - * Returns the list of client CAs. Please note that in contrast to - * SSLContext#client_ca= no array of X509::Certificate is returned but - * X509::Name instances of the CA's subject distinguished name. - * - * In server mode, returns the list set by SSLContext#client_ca=. - * In client mode, returns the list of client CAs sent from the server. - */ -static VALUE -ossl_ssl_get_client_ca_list(VALUE self) -{ - SSL *ssl; - STACK_OF(X509_NAME) *ca; - - Data_Get_Struct(self, SSL, ssl); - if (!ssl) { - rb_warning("SSL session is not started yet."); - return Qnil; - } - - ca = SSL_get_client_CA_list(ssl); - return ossl_x509name_sk2ary(ca); -} - -void -Init_ossl_ssl() -{ - int i; - VALUE ary; - -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ -#endif - - ID_callback_state = rb_intern("@callback_state"); - - ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0); - ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0); - ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0); - ossl_ssl_ex_client_cert_cb_idx = - SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_client_cert_cb_idx",0,0,0); - ossl_ssl_ex_tmp_dh_callback_idx = - SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0); - - mSSL = rb_define_module_under(mOSSL, "SSL"); - eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError); - - Init_ossl_ssl_session(); - - /* Document-class: OpenSSL::SSL::SSLContext - * - * An SSLContext is used to set various options regarding certificates, - * algorithms, verification, session caching, etc. The SSLContext is - * used to create an SSLSocket. - * - * All attributes must be set before creating an SSLSocket as the - * SSLContext will be frozen afterward. - * - * The following attributes are available but don't show up in rdoc: - * * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout, - * * verify_mode, verify_depth client_cert_cb, tmp_dh_callback, - * * session_id_context, session_add_cb, session_new_cb, session_remove_cb - */ - cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject); - rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc); - - /* - * Context certificate - */ - rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse); - - /* - * Context private key - */ - rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse); - - /* - * A certificate or Array of certificates that will be sent to the client. - */ - rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse); - - /* - * The path to a file containing a PEM-format CA certificate - */ - rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse); - - /* - * The path to a directory containing CA certificates in PEM format. - * - * Files are looked up by subject's X509 name's hash value. - */ - rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse); - - /* - * Maximum session lifetime. - */ - rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse); - - /* - * Session verification mode. - * - * Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE, - * VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL - */ - rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse); - - /* - * Number of CA certificates to walk when verifying a certificate chain. - */ - rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse); - - /* - * A callback for additional certificate verification. The callback is - * invoked for each certificate in the chain. - * - * The callback is invoked with two values. +preverify_ok+ indicates - * indicates if the verification was passed (true) or not (false). - * +store_context+ is an OpenSSL::X509::StoreContext containing the - * context used for certificate verification. - * - * If the callback returns false verification is stopped. - */ - rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse); - - /* - * Sets various OpenSSL options. - */ - rb_attr(cSSLContext, rb_intern("options"), 1, 1, Qfalse); - - /* - * An OpenSSL::X509::Store used for certificate verification - */ - rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse); - - /* - * An Array of extra X509 certificates to be added to the certificate - * chain. - */ - rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse); - - /* - * A callback invoked when a client certificate is requested by a server - * and no certificate has been set. - * - * The callback is invoked with a Session and must return an Array - * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any - * other value is returned the handshake is suspended. - */ - rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse); - - /* - * 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. - */ - rb_attr(cSSLContext, rb_intern("tmp_dh_callback"), 1, 1, Qfalse); - - /* - * Sets the context in which a session can be reused. This allows - * sessions for multiple applications to be distinguished, for exapmle, by - * name. - */ - rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse); - - /* - * A callback invoked on a server when a session is proposed by the client - * but the session could not be found in the server's internal cache. - * - * The callback is invoked with the SSLSocket and session id. The - * callback may return a Session from an external cache. - */ - rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse); - - /* - * A callback invoked when a new session was negotiatied. - * - * The callback is invoked with an SSLSocket. If false is returned the - * session will be removed from the internal cache. - */ - rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse); - - /* - * A callback invoked when a session is removed from the internal cache. - * - * The callback is invoked with an SSLContext and a Session. - */ - rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse); - -#ifdef HAVE_SSL_SET_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. - */ - rb_attr(cSSLContext, rb_intern("servername_cb"), 1, 1, Qfalse); -#endif - - rb_define_alias(cSSLContext, "ssl_timeout", "timeout"); - rb_define_alias(cSSLContext, "ssl_timeout=", "timeout="); - rb_define_method(cSSLContext, "initialize", ossl_sslctx_initialize, -1); - rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1); - rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0); - rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1); - - rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0); - - - /* - * No session caching for client or server - */ - rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2FIX(SSL_SESS_CACHE_OFF)); - - /* - * Client sessions are added to the session cache - */ - rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */ - - /* - * Server sessions are added to the session cache - */ - rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2FIX(SSL_SESS_CACHE_SERVER)); - - /* - * Both client and server sessions are added to the session cache - */ - rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2FIX(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */ - - /* - * Normally the sesison cache is checked for expired sessions every 255 - * connections. Since this may lead to a delay that cannot be controlled, - * the automatic flushing may be disabled and #flush_sessions can be - * called explicitly. - */ - rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2FIX(SSL_SESS_CACHE_NO_AUTO_CLEAR)); - - /* - * Always perform external lookups of sessions even if they are in the - * internal cache. - * - * This flag has no effect on clients - */ - rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)); - - /* - * Never automatically store sessions in the internal store. - */ - rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_STORE)); - - /* - * Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and - * SESSION_CACHE_NO_INTERNAL_STORE. - */ - rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL)); - - rb_define_method(cSSLContext, "session_add", ossl_sslctx_session_add, 1); - rb_define_method(cSSLContext, "session_remove", ossl_sslctx_session_remove, 1); - rb_define_method(cSSLContext, "session_cache_mode", ossl_sslctx_get_session_cache_mode, 0); - rb_define_method(cSSLContext, "session_cache_mode=", ossl_sslctx_set_session_cache_mode, 1); - rb_define_method(cSSLContext, "session_cache_size", ossl_sslctx_get_session_cache_size, 0); - rb_define_method(cSSLContext, "session_cache_size=", ossl_sslctx_set_session_cache_size, 1); - rb_define_method(cSSLContext, "session_cache_stats", ossl_sslctx_get_session_cache_stats, 0); - rb_define_method(cSSLContext, "flush_sessions", ossl_sslctx_flush_sessions, -1); - - ary = rb_ary_new2(numberof(ossl_ssl_method_tab)); - for (i = 0; i < numberof(ossl_ssl_method_tab); i++) { - rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name))); - } - rb_obj_freeze(ary); - /* The list of available SSL/TLS methods */ - rb_define_const(cSSLContext, "METHODS", ary); - - /* - * Document-class: OpenSSL::SSL::SSLSocket - * - * The following attributes are available but don't show up in rdoc. - * * io, context, sync_close - * - */ - cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject); - rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc); - for(i = 0; i < numberof(ossl_ssl_attr_readers); i++) - rb_attr(cSSLSocket, rb_intern(ossl_ssl_attr_readers[i]), 1, 0, Qfalse); - for(i = 0; i < numberof(ossl_ssl_attrs); i++) - rb_attr(cSSLSocket, rb_intern(ossl_ssl_attrs[i]), 1, 1, Qfalse); - rb_define_alias(cSSLSocket, "to_io", "io"); - rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1); - rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0); - rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, 0); - rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0); - rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, 0); - rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1); - rb_define_private_method(cSSLSocket, "sysread_nonblock", ossl_ssl_read_nonblock, -1); - rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1); - rb_define_private_method(cSSLSocket, "syswrite_nonblock", ossl_ssl_write_nonblock, 1); - rb_define_method(cSSLSocket, "sysclose", ossl_ssl_close, 0); - rb_define_method(cSSLSocket, "cert", ossl_ssl_get_cert, 0); - rb_define_method(cSSLSocket, "peer_cert", ossl_ssl_get_peer_cert, 0); - rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0); - rb_define_method(cSSLSocket, "cipher", ossl_ssl_get_cipher, 0); - rb_define_method(cSSLSocket, "state", ossl_ssl_get_state, 0); - rb_define_method(cSSLSocket, "pending", ossl_ssl_pending, 0); - rb_define_method(cSSLSocket, "session_reused?", ossl_ssl_session_reused, 0); - rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1); - rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0); - rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0); - -#define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2NUM(SSL_##x)) - - ossl_ssl_def_const(VERIFY_NONE); - ossl_ssl_def_const(VERIFY_PEER); - ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT); - ossl_ssl_def_const(VERIFY_CLIENT_ONCE); - /* Introduce constants included in OP_ALL. These constants are mostly for - * unset some bits in OP_ALL such as: - * ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS - */ - ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG); - ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG); - ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG); - ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG); - ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER); - ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING); - ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG); - ossl_ssl_def_const(OP_TLS_D5_BUG); - ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG); - ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS); - ossl_ssl_def_const(OP_ALL); -#if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION) - ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); -#endif -#if defined(SSL_OP_SINGLE_ECDH_USE) - ossl_ssl_def_const(OP_SINGLE_ECDH_USE); -#endif - ossl_ssl_def_const(OP_SINGLE_DH_USE); - ossl_ssl_def_const(OP_EPHEMERAL_RSA); -#if defined(SSL_OP_CIPHER_SERVER_PREFERENCE) - ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE); -#endif - ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG); - ossl_ssl_def_const(OP_NO_SSLv2); - ossl_ssl_def_const(OP_NO_SSLv3); - ossl_ssl_def_const(OP_NO_TLSv1); -#if defined(SSL_OP_NO_TICKET) - ossl_ssl_def_const(OP_NO_TICKET); -#endif -#if defined(SSL_OP_NO_COMPRESSION) - ossl_ssl_def_const(OP_NO_COMPRESSION); -#endif - ossl_ssl_def_const(OP_PKCS1_CHECK_1); - ossl_ssl_def_const(OP_PKCS1_CHECK_2); - ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG); - ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_ssl.h b/ruby_1_9_3/ext/openssl/ossl_ssl.h deleted file mode 100644 index 034762fc46..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_ssl.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_SSL_H_) -#define _OSSL_SSL_H_ - -#define GetSSLSession(obj, sess) do { \ - Data_Get_Struct((obj), SSL_SESSION, (sess)); \ - if (!(sess)) { \ - ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \ - } \ -} while (0) - -#define SafeGetSSLSession(obj, sess) do { \ - OSSL_Check_Kind((obj), cSSLSession); \ - GetSSLSession((obj), (sess)); \ -} while (0) - -extern VALUE mSSL; -extern VALUE eSSLError; -extern VALUE cSSLSocket; -extern VALUE cSSLContext; -extern VALUE cSSLSession; - -void Init_ossl_ssl(void); -void Init_ossl_ssl_session(void); - -#endif /* _OSSL_SSL_H_ */ - diff --git a/ruby_1_9_3/ext/openssl/ossl_ssl_session.c b/ruby_1_9_3/ext/openssl/ossl_ssl_session.c deleted file mode 100644 index a7437caf37..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_ssl_session.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (C) 2004-2007 Technorama Ltd. <oss-ruby@technorama.net> - */ - -#include "ossl.h" - -#define GetSSLSession(obj, sess) do { \ - Data_Get_Struct((obj), SSL_SESSION, (sess)); \ - if (!(sess)) { \ - ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \ - } \ -} while (0) - -#define SafeGetSSLSession(obj, sess) do { \ - OSSL_Check_Kind((obj), cSSLSession); \ - GetSSLSession((obj), (sess)); \ -} while (0) - - -VALUE cSSLSession; -static VALUE eSSLSession; - -static VALUE ossl_ssl_session_alloc(VALUE klass) -{ - return Data_Wrap_Struct(klass, 0, SSL_SESSION_free, NULL); -} - -/* - * call-seq: - * Session.new(SSLSocket | string) => session - * - * === Parameters - * +SSLSocket+ is an OpenSSL::SSL::SSLSocket - * +string+ must be a DER or PEM encoded Session. -*/ -static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1) -{ - SSL_SESSION *ctx = NULL; - - if (RDATA(self)->data) - ossl_raise(eSSLSession, "SSL Session already initialized"); - - if (rb_obj_is_instance_of(arg1, cSSLSocket)) { - SSL *ssl; - - Data_Get_Struct(arg1, SSL, ssl); - - if (!ssl || (ctx = SSL_get1_session(ssl)) == NULL) - ossl_raise(eSSLSession, "no session available"); - } else { - BIO *in = ossl_obj2bio(arg1); - - ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL); - - if (!ctx) { - OSSL_BIO_reset(in); - ctx = d2i_SSL_SESSION_bio(in, NULL); - } - - BIO_free(in); - - if (!ctx) - ossl_raise(rb_eArgError, "unknown type"); - } - - /* should not happen */ - if (ctx == NULL) - ossl_raise(eSSLSession, "ctx not set - internal error"); - - RDATA(self)->data = ctx; - - return self; -} - -#if HAVE_SSL_SESSION_CMP == 0 -int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b) -{ - if (a->ssl_version != b->ssl_version || - a->session_id_length != b->session_id_length) - return 1; - return memcmp(a->session_id,b-> session_id, a->session_id_length); -} -#endif - -/* - * call-seq: - * session1 == session2 -> boolean - * -*/ -static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2) -{ - SSL_SESSION *ctx1, *ctx2; - - GetSSLSession(val1, ctx1); - SafeGetSSLSession(val2, ctx2); - - switch (SSL_SESSION_cmp(ctx1, ctx2)) { - case 0: return Qtrue; - default: return Qfalse; - } -} - -/* - * call-seq: - * session.time -> Time - * - * Gets start time of the session. - * -*/ -static VALUE ossl_ssl_session_get_time(VALUE self) -{ - SSL_SESSION *ctx; - time_t t; - - GetSSLSession(self, ctx); - - t = SSL_SESSION_get_time(ctx); - - if (t == 0) - return Qnil; - - return rb_funcall(rb_cTime, rb_intern("at"), 1, TIMET2NUM(t)); -} - -/* - * call-seq: - * session.timeout -> integer - * - * Gets how long until the session expires in seconds. - * -*/ -static VALUE ossl_ssl_session_get_timeout(VALUE self) -{ - SSL_SESSION *ctx; - time_t t; - - GetSSLSession(self, ctx); - - t = SSL_SESSION_get_timeout(ctx); - - return TIMET2NUM(t); -} - -/* - * call-seq: - * session.time=(Time) -> Time - * session.time=(integer) -> Time - * - * Sets start time of the session. Time resolution is in seconds. - * -*/ -static VALUE ossl_ssl_session_set_time(VALUE self, VALUE time_v) -{ - SSL_SESSION *ctx; - long t; - - GetSSLSession(self, ctx); - if (rb_obj_is_instance_of(time_v, rb_cTime)) { - time_v = rb_funcall(time_v, rb_intern("to_i"), 0); - } - t = NUM2LONG(time_v); - SSL_SESSION_set_time(ctx, t); - return ossl_ssl_session_get_time(self); -} - -/* - * call-seq: - * session.timeout=(integer) -> integer - * - * Sets how long until the session expires in seconds. - * -*/ -static VALUE ossl_ssl_session_set_timeout(VALUE self, VALUE time_v) -{ - SSL_SESSION *ctx; - long t; - - GetSSLSession(self, ctx); - t = NUM2LONG(time_v); - SSL_SESSION_set_timeout(ctx, t); - return ossl_ssl_session_get_timeout(self); -} - -#ifdef HAVE_SSL_SESSION_GET_ID -/* - * call-seq: - * session.id -> aString - * - * Returns the Session ID. -*/ -static VALUE ossl_ssl_session_get_id(VALUE self) -{ - SSL_SESSION *ctx; - const unsigned char *p = NULL; - unsigned int i = 0; - - GetSSLSession(self, ctx); - - p = SSL_SESSION_get_id(ctx, &i); - - return rb_str_new((const char *) p, i); -} -#endif - -/* - * call-seq: - * session.to_der -> aString - * - * Returns an ASN1 encoded String that contains the Session object. -*/ -static VALUE ossl_ssl_session_to_der(VALUE self) -{ - SSL_SESSION *ctx; - unsigned char *p; - int len; - VALUE str; - - GetSSLSession(self, ctx); - len = i2d_SSL_SESSION(ctx, NULL); - if (len <= 0) { - ossl_raise(eSSLSession, "i2d_SSL_SESSION"); - } - - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - i2d_SSL_SESSION(ctx, &p); - ossl_str_adjust(str, p); - return str; -} - -/* - * call-seq: - * session.to_pem -> String - * - * Returns a PEM encoded String that contains the Session object. -*/ -static VALUE ossl_ssl_session_to_pem(VALUE self) -{ - SSL_SESSION *ctx; - BIO *out; - BUF_MEM *buf; - VALUE str; - int i; - - GetSSLSession(self, ctx); - - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eSSLSession, "BIO_s_mem()"); - } - - if (!(i=PEM_write_bio_SSL_SESSION(out, ctx))) { - BIO_free(out); - ossl_raise(eSSLSession, "SSL_SESSION_print()"); - } - - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - - return str; -} - - -/* - * call-seq: - * session.to_text -> String - * - * Shows everything in the Session object. -*/ -static VALUE ossl_ssl_session_to_text(VALUE self) -{ - SSL_SESSION *ctx; - BIO *out; - BUF_MEM *buf; - VALUE str; - - GetSSLSession(self, ctx); - - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eSSLSession, "BIO_s_mem()"); - } - - if (!SSL_SESSION_print(out, ctx)) { - BIO_free(out); - ossl_raise(eSSLSession, "SSL_SESSION_print()"); - } - - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - - return str; -} - - -void Init_ossl_ssl_session(void) -{ -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ - mSSL = rb_define_module_under(mOSSL, "SSL"); -#endif - cSSLSession = rb_define_class_under(mSSL, "Session", rb_cObject); - eSSLSession = rb_define_class_under(cSSLSession, "SessionError", eOSSLError); - - rb_define_alloc_func(cSSLSession, ossl_ssl_session_alloc); - rb_define_method(cSSLSession, "initialize", ossl_ssl_session_initialize, 1); - - rb_define_method(cSSLSession, "==", ossl_ssl_session_eq, 1); - - rb_define_method(cSSLSession, "time", ossl_ssl_session_get_time, 0); - rb_define_method(cSSLSession, "time=", ossl_ssl_session_set_time, 1); - rb_define_method(cSSLSession, "timeout", ossl_ssl_session_get_timeout, 0); - rb_define_method(cSSLSession, "timeout=", ossl_ssl_session_set_timeout, 1); - -#ifdef HAVE_SSL_SESSION_GET_ID - rb_define_method(cSSLSession, "id", ossl_ssl_session_get_id, 0); -#else - rb_undef_method(cSSLSession, "id"); -#endif - rb_define_method(cSSLSession, "to_der", ossl_ssl_session_to_der, 0); - rb_define_method(cSSLSession, "to_pem", ossl_ssl_session_to_pem, 0); - rb_define_method(cSSLSession, "to_text", ossl_ssl_session_to_text, 0); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_version.h b/ruby_1_9_3/ext/openssl/ossl_version.h deleted file mode 100644 index 193ceab089..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_version.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_VERSION_H_) -#define _OSSL_VERSION_H_ - -#define OSSL_VERSION "1.1.0" - -#endif /* _OSSL_VERSION_H_ */ diff --git a/ruby_1_9_3/ext/openssl/ossl_x509.c b/ruby_1_9_3/ext/openssl/ossl_x509.c deleted file mode 100644 index fd1d9b6c7e..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -VALUE mX509; - -#define DefX509Const(x) rb_define_const(mX509, #x,INT2FIX(X509_##x)) -#define DefX509Default(x,i) \ - rb_define_const(mX509, "DEFAULT_" #x, rb_str_new2(X509_get_default_##i())) - -void -Init_ossl_x509() -{ - mX509 = rb_define_module_under(mOSSL, "X509"); - - Init_ossl_x509attr(); - Init_ossl_x509cert(); - Init_ossl_x509crl(); - Init_ossl_x509ext(); - Init_ossl_x509name(); - Init_ossl_x509req(); - Init_ossl_x509revoked(); - Init_ossl_x509store(); - - DefX509Const(V_OK); - DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT); - DefX509Const(V_ERR_UNABLE_TO_GET_CRL); - DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE); - DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE); - DefX509Const(V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY); - DefX509Const(V_ERR_CERT_SIGNATURE_FAILURE); - DefX509Const(V_ERR_CRL_SIGNATURE_FAILURE); - DefX509Const(V_ERR_CERT_NOT_YET_VALID); - DefX509Const(V_ERR_CERT_HAS_EXPIRED); - DefX509Const(V_ERR_CRL_NOT_YET_VALID); - DefX509Const(V_ERR_CRL_HAS_EXPIRED); - DefX509Const(V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD); - DefX509Const(V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD); - DefX509Const(V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD); - DefX509Const(V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); - DefX509Const(V_ERR_OUT_OF_MEM); - DefX509Const(V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT); - DefX509Const(V_ERR_SELF_SIGNED_CERT_IN_CHAIN); - DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); - DefX509Const(V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); - DefX509Const(V_ERR_CERT_CHAIN_TOO_LONG); - DefX509Const(V_ERR_CERT_REVOKED); - DefX509Const(V_ERR_INVALID_CA); - DefX509Const(V_ERR_PATH_LENGTH_EXCEEDED); - DefX509Const(V_ERR_INVALID_PURPOSE); - DefX509Const(V_ERR_CERT_UNTRUSTED); - DefX509Const(V_ERR_CERT_REJECTED); - DefX509Const(V_ERR_SUBJECT_ISSUER_MISMATCH); - DefX509Const(V_ERR_AKID_SKID_MISMATCH); - DefX509Const(V_ERR_AKID_ISSUER_SERIAL_MISMATCH); - DefX509Const(V_ERR_KEYUSAGE_NO_CERTSIGN); - DefX509Const(V_ERR_APPLICATION_VERIFICATION); - -#if defined(X509_V_FLAG_CRL_CHECK) - DefX509Const(V_FLAG_CRL_CHECK); -#endif -#if defined(X509_V_FLAG_CRL_CHECK_ALL) - DefX509Const(V_FLAG_CRL_CHECK_ALL); -#endif - - DefX509Const(PURPOSE_SSL_CLIENT); - DefX509Const(PURPOSE_SSL_SERVER); - DefX509Const(PURPOSE_NS_SSL_SERVER); - DefX509Const(PURPOSE_SMIME_SIGN); - DefX509Const(PURPOSE_SMIME_ENCRYPT); - DefX509Const(PURPOSE_CRL_SIGN); - DefX509Const(PURPOSE_ANY); -#if defined(X509_PURPOSE_OCSP_HELPER) - DefX509Const(PURPOSE_OCSP_HELPER); -#endif - - DefX509Const(TRUST_COMPAT); - DefX509Const(TRUST_SSL_CLIENT); - DefX509Const(TRUST_SSL_SERVER); - DefX509Const(TRUST_EMAIL); - DefX509Const(TRUST_OBJECT_SIGN); -#if defined(X509_TRUST_OCSP_SIGN) - DefX509Const(TRUST_OCSP_SIGN); -#endif -#if defined(X509_TRUST_OCSP_REQUEST) - DefX509Const(TRUST_OCSP_REQUEST); -#endif - - DefX509Default(CERT_AREA, cert_area); - DefX509Default(CERT_DIR, cert_dir); - DefX509Default(CERT_FILE, cert_file); - DefX509Default(CERT_DIR_ENV, cert_dir_env); - DefX509Default(CERT_FILE_ENV, cert_file_env); - DefX509Default(PRIVATE_DIR, private_dir); -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_x509.h b/ruby_1_9_3/ext/openssl/ossl_x509.h deleted file mode 100644 index 1a43569073..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_X509_H_) -#define _OSSL_X509_H_ - -/* - * X509 main module - */ -extern VALUE mX509; - -void Init_ossl_x509(void); - -/* - * X509Attr - */ -extern VALUE cX509Attr; -extern VALUE eX509AttrError; - -VALUE ossl_x509attr_new(X509_ATTRIBUTE *); -X509_ATTRIBUTE *DupX509AttrPtr(VALUE); -void Init_ossl_x509attr(void); - -/* - * X509Cert - */ -extern VALUE cX509Cert; -extern VALUE eX509CertError; - -VALUE ossl_x509_new(X509 *); -VALUE ossl_x509_new_from_file(VALUE); -X509 *GetX509CertPtr(VALUE); -X509 *DupX509CertPtr(VALUE); -void Init_ossl_x509cert(void); - -/* - * X509CRL - */ -extern VALUE cX509CRL; -extern VALUE eX509CRLError; - -VALUE ossl_x509crl_new(X509_CRL *); -X509_CRL *GetX509CRLPtr(VALUE); -X509_CRL *DupX509CRLPtr(VALUE); -void Init_ossl_x509crl(void); - -/* - * X509Extension - */ -extern VALUE cX509Ext; -extern VALUE cX509ExtFactory; -extern VALUE eX509ExtError; - -VALUE ossl_x509ext_new(X509_EXTENSION *); -X509_EXTENSION *GetX509ExtPtr(VALUE); -X509_EXTENSION *DupX509ExtPtr(VALUE); -void Init_ossl_x509ext(void); - -/* - * X509Name - */ -extern VALUE cX509Name; -extern VALUE eX509NameError; - -VALUE ossl_x509name_new(X509_NAME *); -X509_NAME *GetX509NamePtr(VALUE); -void Init_ossl_x509name(void); - -/* - * X509Request - */ -extern VALUE cX509Req; -extern VALUE eX509ReqError; - -VALUE ossl_x509req_new(X509_REQ *); -X509_REQ *GetX509ReqPtr(VALUE); -X509_REQ *DupX509ReqPtr(VALUE); -void Init_ossl_x509req(void); - -/* - * X509Revoked - */ -extern VALUE cX509Rev; -extern VALUE eX509RevError; - -VALUE ossl_x509revoked_new(X509_REVOKED *); -X509_REVOKED *DupX509RevokedPtr(VALUE); -void Init_ossl_x509revoked(void); - -/* - * X509Store and X509StoreContext - */ -extern VALUE cX509Store; -extern VALUE cX509StoreContext; -extern VALUE eX509StoreError; - -VALUE ossl_x509store_new(X509_STORE *); -X509_STORE *GetX509StorePtr(VALUE); -X509_STORE *DupX509StorePtr(VALUE); - -VALUE ossl_x509stctx_new(X509_STORE_CTX *); -VALUE ossl_x509stctx_clear_ptr(VALUE); -X509_STORE_CTX *GetX509StCtxtPtr(VALUE); - -void Init_ossl_x509store(void); - -#endif /* _OSSL_X509_H_ */ diff --git a/ruby_1_9_3/ext/openssl/ossl_x509attr.c b/ruby_1_9_3/ext/openssl/ossl_x509attr.c deleted file mode 100644 index 1f36ca8b12..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509attr.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapX509Attr(klass, obj, attr) do { \ - if (!(attr)) { \ - ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_ATTRIBUTE_free, (attr)); \ -} while (0) -#define GetX509Attr(obj, attr) do { \ - Data_Get_Struct((obj), X509_ATTRIBUTE, (attr)); \ - if (!(attr)) { \ - ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ - } \ -} while (0) -#define SafeGetX509Attr(obj, attr) do { \ - OSSL_Check_Kind((obj), cX509Attr); \ - GetX509Attr((obj), (attr)); \ -} while (0) - -/* - * Classes - */ -VALUE cX509Attr; -VALUE eX509AttrError; - -/* - * Public - */ -VALUE -ossl_x509attr_new(X509_ATTRIBUTE *attr) -{ - X509_ATTRIBUTE *new; - VALUE obj; - - if (!attr) { - new = X509_ATTRIBUTE_new(); - } else { - new = X509_ATTRIBUTE_dup(attr); - } - if (!new) { - ossl_raise(eX509AttrError, NULL); - } - WrapX509Attr(cX509Attr, obj, new); - - return obj; -} - -X509_ATTRIBUTE * -DupX509AttrPtr(VALUE obj) -{ - X509_ATTRIBUTE *attr, *new; - - SafeGetX509Attr(obj, attr); - if (!(new = X509_ATTRIBUTE_dup(attr))) { - ossl_raise(eX509AttrError, NULL); - } - - return new; -} - -/* - * Private - */ -static VALUE -ossl_x509attr_alloc(VALUE klass) -{ - X509_ATTRIBUTE *attr; - VALUE obj; - - if (!(attr = X509_ATTRIBUTE_new())) - ossl_raise(eX509AttrError, NULL); - WrapX509Attr(klass, obj, attr); - - return obj; -} - -/* - * call-seq: - * Attribute.new(oid [, value]) => attr - */ -static VALUE -ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE oid, value; - X509_ATTRIBUTE *attr, *x; - const unsigned char *p; - - GetX509Attr(self, attr); - if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){ - oid = ossl_to_der_if_possible(oid); - StringValue(oid); - p = (unsigned char *)RSTRING_PTR(oid); - x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid)); - DATA_PTR(self) = attr; - if(!x){ - ossl_raise(eX509AttrError, NULL); - } - return self; - } - rb_funcall(self, rb_intern("oid="), 1, oid); - rb_funcall(self, rb_intern("value="), 1, value); - - return self; -} - -/* - * call-seq: - * attr.oid = string => string - */ -static VALUE -ossl_x509attr_set_oid(VALUE self, VALUE oid) -{ - X509_ATTRIBUTE *attr; - ASN1_OBJECT *obj; - char *s; - - s = StringValuePtr(oid); - obj = OBJ_txt2obj(s, 0); - if(!obj) obj = OBJ_txt2obj(s, 1); - if(!obj) ossl_raise(eX509AttrError, NULL); - GetX509Attr(self, attr); - X509_ATTRIBUTE_set1_object(attr, obj); - - return oid; -} - -/* - * call-seq: - * attr.oid => string - */ -static VALUE -ossl_x509attr_get_oid(VALUE self) -{ - X509_ATTRIBUTE *attr; - ASN1_OBJECT *oid; - BIO *out; - VALUE ret; - int nid; - - GetX509Attr(self, attr); - oid = X509_ATTRIBUTE_get0_object(attr); - if ((nid = OBJ_obj2nid(oid)) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); - else{ - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509AttrError, NULL); - i2a_ASN1_OBJECT(out, oid); - ret = ossl_membio2str(out); - } - - return ret; -} - -#if defined(HAVE_ST_X509_ATTRIBUTE_SINGLE) || defined(HAVE_ST_SINGLE) -# define OSSL_X509ATTR_IS_SINGLE(attr) ((attr)->single) -# define OSSL_X509ATTR_SET_SINGLE(attr) ((attr)->single = 1) -#else -# define OSSL_X509ATTR_IS_SINGLE(attr) (!(attr)->set) -# define OSSL_X509ATTR_SET_SINGLE(attr) ((attr)->set = 0) -#endif - -/* - * call-seq: - * attr.value = asn1 => asn1 - */ -static VALUE -ossl_x509attr_set_value(VALUE self, VALUE value) -{ - X509_ATTRIBUTE *attr; - ASN1_TYPE *a1type; - - if(!(a1type = ossl_asn1_get_asn1type(value))) - ossl_raise(eASN1Error, "could not get ASN1_TYPE"); - if(ASN1_TYPE_get(a1type) == V_ASN1_SEQUENCE){ - ASN1_TYPE_free(a1type); - ossl_raise(eASN1Error, "couldn't set SEQUENCE for attribute value."); - } - GetX509Attr(self, attr); - if(attr->value.set){ - if(OSSL_X509ATTR_IS_SINGLE(attr)) ASN1_TYPE_free(attr->value.single); - else sk_ASN1_TYPE_free(attr->value.set); - } - OSSL_X509ATTR_SET_SINGLE(attr); - attr->value.single = a1type; - - return value; -} - -/* - * call-seq: - * attr.value => asn1 - */ -static VALUE -ossl_x509attr_get_value(VALUE self) -{ - X509_ATTRIBUTE *attr; - VALUE str, asn1; - long length; - unsigned char *p; - - GetX509Attr(self, attr); - if(attr->value.ptr == NULL) return Qnil; - if(OSSL_X509ATTR_IS_SINGLE(attr)){ - length = i2d_ASN1_TYPE(attr->value.single, NULL); - str = rb_str_new(0, length); - p = (unsigned char *)RSTRING_PTR(str); - i2d_ASN1_TYPE(attr->value.single, &p); - ossl_str_adjust(str, p); - } - else{ - length = i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, - (unsigned char **) NULL, i2d_ASN1_TYPE, - V_ASN1_SET, V_ASN1_UNIVERSAL, 0); - str = rb_str_new(0, length); - p = (unsigned char *)RSTRING_PTR(str); - i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p, - i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0); - ossl_str_adjust(str, p); - } - asn1 = rb_funcall(mASN1, rb_intern("decode"), 1, str); - - return asn1; -} - -/* - * call-seq: - * attr.to_der => string - */ -static VALUE -ossl_x509attr_to_der(VALUE self) -{ - X509_ATTRIBUTE *attr; - VALUE str; - int len; - unsigned char *p; - - GetX509Attr(self, attr); - if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0) - ossl_raise(eX509AttrError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_X509_ATTRIBUTE(attr, &p) <= 0) - ossl_raise(eX509AttrError, NULL); - rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str)); - - return str; -} - -/* - * X509_ATTRIBUTE init - */ -void -Init_ossl_x509attr() -{ - eX509AttrError = rb_define_class_under(mX509, "AttributeError", eOSSLError); - - cX509Attr = rb_define_class_under(mX509, "Attribute", rb_cObject); - rb_define_alloc_func(cX509Attr, ossl_x509attr_alloc); - rb_define_method(cX509Attr, "initialize", ossl_x509attr_initialize, -1); - rb_define_method(cX509Attr, "oid=", ossl_x509attr_set_oid, 1); - rb_define_method(cX509Attr, "oid", ossl_x509attr_get_oid, 0); - rb_define_method(cX509Attr, "value=", ossl_x509attr_set_value, 1); - rb_define_method(cX509Attr, "value", ossl_x509attr_get_value, 0); - rb_define_method(cX509Attr, "to_der", ossl_x509attr_to_der, 0); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_x509cert.c b/ruby_1_9_3/ext/openssl/ossl_x509cert.c deleted file mode 100644 index f5b2f4ff4a..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509cert.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapX509(klass, obj, x509) do { \ - if (!(x509)) { \ - ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_free, (x509)); \ -} while (0) -#define GetX509(obj, x509) do { \ - Data_Get_Struct((obj), X509, (x509)); \ - if (!(x509)) { \ - ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ - } \ -} while (0) -#define SafeGetX509(obj, x509) do { \ - OSSL_Check_Kind((obj), cX509Cert); \ - GetX509((obj), (x509)); \ -} while (0) - -/* - * Classes - */ -VALUE cX509Cert; -VALUE eX509CertError; - -/* - * Public - */ -VALUE -ossl_x509_new(X509 *x509) -{ - X509 *new; - VALUE obj; - - if (!x509) { - new = X509_new(); - } else { - new = X509_dup(x509); - } - if (!new) { - ossl_raise(eX509CertError, NULL); - } - WrapX509(cX509Cert, obj, new); - - return obj; -} - -VALUE -ossl_x509_new_from_file(VALUE filename) -{ - X509 *x509; - FILE *fp; - VALUE obj; - - SafeStringValue(filename); - if (!(fp = fopen(RSTRING_PTR(filename), "r"))) { - ossl_raise(eX509CertError, "%s", strerror(errno)); - } - x509 = PEM_read_X509(fp, NULL, NULL, NULL); - /* - * prepare for DER... -#if !defined(OPENSSL_NO_FP_API) - if (!x509) { - (void)ERR_get_error(); - rewind(fp); - - x509 = d2i_X509_fp(fp, NULL); - } -#endif - */ - fclose(fp); - if (!x509) { - ossl_raise(eX509CertError, NULL); - } - WrapX509(cX509Cert, obj, x509); - - return obj; -} - -X509 * -GetX509CertPtr(VALUE obj) -{ - X509 *x509; - - SafeGetX509(obj, x509); - - return x509; -} - -X509 * -DupX509CertPtr(VALUE obj) -{ - X509 *x509; - - SafeGetX509(obj, x509); - - CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); - - return x509; -} - -/* - * Private - */ -static VALUE -ossl_x509_alloc(VALUE klass) -{ - X509 *x509; - VALUE obj; - - x509 = X509_new(); - if (!x509) ossl_raise(eX509CertError, NULL); - - WrapX509(klass, obj, x509); - - return obj; -} - -/* - * call-seq: - * Certificate.new => cert - * Certificate.new(string) => cert - */ -static VALUE -ossl_x509_initialize(int argc, VALUE *argv, VALUE self) -{ - BIO *in; - X509 *x509, *x = DATA_PTR(self); - VALUE arg; - - if (rb_scan_args(argc, argv, "01", &arg) == 0) { - /* create just empty X509Cert */ - return self; - } - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - x509 = PEM_read_bio_X509(in, &x, NULL, NULL); - DATA_PTR(self) = x; - if (!x509) { - OSSL_BIO_reset(in); - x509 = d2i_X509_bio(in, &x); - DATA_PTR(self) = x; - } - BIO_free(in); - if (!x509) ossl_raise(eX509CertError, NULL); - - return self; -} - -static VALUE -ossl_x509_copy(VALUE self, VALUE other) -{ - X509 *a, *b, *x509; - - rb_check_frozen(self); - if (self == other) return self; - - GetX509(self, a); - SafeGetX509(other, b); - - x509 = X509_dup(b); - if (!x509) ossl_raise(eX509CertError, NULL); - - DATA_PTR(self) = x509; - X509_free(a); - - return self; -} - -/* - * call-seq: - * cert.to_der => string - */ -static VALUE -ossl_x509_to_der(VALUE self) -{ - X509 *x509; - VALUE str; - long len; - unsigned char *p; - - GetX509(self, x509); - if ((len = i2d_X509(x509, NULL)) <= 0) - ossl_raise(eX509CertError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if (i2d_X509(x509, &p) <= 0) - ossl_raise(eX509CertError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -/* - * call-seq: - * cert.to_pem => string - */ -static VALUE -ossl_x509_to_pem(VALUE self) -{ - X509 *x509; - BIO *out; - VALUE str; - - GetX509(self, x509); - out = BIO_new(BIO_s_mem()); - if (!out) ossl_raise(eX509CertError, NULL); - - if (!PEM_write_bio_X509(out, x509)) { - BIO_free(out); - ossl_raise(eX509CertError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * cert.to_text => string - */ -static VALUE -ossl_x509_to_text(VALUE self) -{ - X509 *x509; - BIO *out; - VALUE str; - - GetX509(self, x509); - - out = BIO_new(BIO_s_mem()); - if (!out) ossl_raise(eX509CertError, NULL); - - if (!X509_print(out, x509)) { - BIO_free(out); - ossl_raise(eX509CertError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -#if 0 -/* - * Makes from X509 X509_REQuest - */ -static VALUE -ossl_x509_to_req(VALUE self) -{ - X509 *x509; - X509_REQ *req; - VALUE obj; - - GetX509(self, x509); - if (!(req = X509_to_X509_REQ(x509, NULL, EVP_md5()))) { - ossl_raise(eX509CertError, NULL); - } - obj = ossl_x509req_new(req); - X509_REQ_free(req); - - return obj; -} -#endif - -/* - * call-seq: - * cert.version => integer - */ -static VALUE -ossl_x509_get_version(VALUE self) -{ - X509 *x509; - - GetX509(self, x509); - - return LONG2NUM(X509_get_version(x509)); -} - -/* - * call-seq: - * cert.version = integer => integer - */ -static VALUE -ossl_x509_set_version(VALUE self, VALUE version) -{ - X509 *x509; - long ver; - - if ((ver = NUM2LONG(version)) < 0) { - ossl_raise(eX509CertError, "version must be >= 0!"); - } - GetX509(self, x509); - if (!X509_set_version(x509, ver)) { - ossl_raise(eX509CertError, NULL); - } - - return version; -} - -/* - * call-seq: - * cert.serial => integer - */ -static VALUE -ossl_x509_get_serial(VALUE self) -{ - X509 *x509; - - GetX509(self, x509); - - return asn1integer_to_num(X509_get_serialNumber(x509)); -} - -/* - * call-seq: - * cert.serial = integer => integer - */ -static VALUE -ossl_x509_set_serial(VALUE self, VALUE num) -{ - X509 *x509; - - GetX509(self, x509); - - x509->cert_info->serialNumber = - num_to_asn1integer(num, X509_get_serialNumber(x509)); - - return num; -} - -/* - * call-seq: - * cert.signature_algorithm => string - */ -static VALUE -ossl_x509_get_signature_algorithm(VALUE self) -{ - X509 *x509; - BIO *out; - VALUE str; - - GetX509(self, x509); - out = BIO_new(BIO_s_mem()); - if (!out) ossl_raise(eX509CertError, NULL); - - if (!i2a_ASN1_OBJECT(out, x509->cert_info->signature->algorithm)) { - BIO_free(out); - ossl_raise(eX509CertError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * cert.subject => name - */ -static VALUE -ossl_x509_get_subject(VALUE self) -{ - X509 *x509; - X509_NAME *name; - - GetX509(self, x509); - if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */ - ossl_raise(eX509CertError, NULL); - } - - return ossl_x509name_new(name); -} - -/* - * call-seq: - * cert.subject = name => name - */ -static VALUE -ossl_x509_set_subject(VALUE self, VALUE subject) -{ - X509 *x509; - - GetX509(self, x509); - if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */ - ossl_raise(eX509CertError, NULL); - } - - return subject; -} - -/* - * call-seq: - * cert.issuer => name - */ -static VALUE -ossl_x509_get_issuer(VALUE self) -{ - X509 *x509; - X509_NAME *name; - - GetX509(self, x509); - if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */ - ossl_raise(eX509CertError, NULL); - } - - return ossl_x509name_new(name); -} - -/* - * call-seq: - * cert.issuer = name => name - */ -static VALUE -ossl_x509_set_issuer(VALUE self, VALUE issuer) -{ - X509 *x509; - - GetX509(self, x509); - if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */ - ossl_raise(eX509CertError, NULL); - } - - return issuer; -} - -/* - * call-seq: - * cert.not_before => time - */ -static VALUE -ossl_x509_get_not_before(VALUE self) -{ - X509 *x509; - ASN1_UTCTIME *asn1time; - - GetX509(self, x509); - if (!(asn1time = X509_get_notBefore(x509))) { /* NO DUP - don't free! */ - ossl_raise(eX509CertError, NULL); - } - - return asn1time_to_time(asn1time); -} - -/* - * call-seq: - * cert.not_before = time => time - */ -static VALUE -ossl_x509_set_not_before(VALUE self, VALUE time) -{ - X509 *x509; - time_t sec; - - sec = time_to_time_t(time); - GetX509(self, x509); - if (!X509_time_adj(X509_get_notBefore(x509), 0, &sec)) { - ossl_raise(eX509CertError, NULL); - } - - return time; -} - -/* - * call-seq: - * cert.not_after => time - */ -static VALUE -ossl_x509_get_not_after(VALUE self) -{ - X509 *x509; - ASN1_TIME *asn1time; - - GetX509(self, x509); - if (!(asn1time = X509_get_notAfter(x509))) { /* NO DUP - don't free! */ - ossl_raise(eX509CertError, NULL); - } - - return asn1time_to_time(asn1time); -} - -/* - * call-seq: - * cert.not_after = time => time - */ -static VALUE -ossl_x509_set_not_after(VALUE self, VALUE time) -{ - X509 *x509; - time_t sec; - - sec = time_to_time_t(time); - GetX509(self, x509); - if (!X509_time_adj(X509_get_notAfter(x509), 0, &sec)) { - ossl_raise(eX509CertError, NULL); - } - - return time; -} - -/* - * call-seq: - * cert.public_key => key - */ -static VALUE -ossl_x509_get_public_key(VALUE self) -{ - X509 *x509; - EVP_PKEY *pkey; - - GetX509(self, x509); - if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */ - ossl_raise(eX509CertError, NULL); - } - - return ossl_pkey_new(pkey); /* NO DUP - OK */ -} - -/* - * call-seq: - * cert.public_key = key => key - */ -static VALUE -ossl_x509_set_public_key(VALUE self, VALUE key) -{ - X509 *x509; - - GetX509(self, x509); - if (!X509_set_pubkey(x509, GetPKeyPtr(key))) { /* DUPs pkey */ - ossl_raise(eX509CertError, NULL); - } - - return key; -} - -/* - * call-seq: - * cert.sign(key, digest) => self - */ -static VALUE -ossl_x509_sign(VALUE self, VALUE key, VALUE digest) -{ - X509 *x509; - EVP_PKEY *pkey; - const EVP_MD *md; - - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = GetDigestPtr(digest); - GetX509(self, x509); - if (!X509_sign(x509, pkey, md)) { - ossl_raise(eX509CertError, NULL); - } - - return self; -} - -/* - * call-seq: - * cert.verify(key) => true | false - * - * Checks that cert signature is made with PRIVversion of this PUBLIC 'key' - */ -static VALUE -ossl_x509_verify(VALUE self, VALUE key) -{ - X509 *x509; - EVP_PKEY *pkey; - int i; - - pkey = GetPKeyPtr(key); /* NO NEED TO DUP */ - GetX509(self, x509); - if ((i = X509_verify(x509, pkey)) < 0) { - ossl_raise(eX509CertError, NULL); - } - if (i > 0) { - return Qtrue; - } - - return Qfalse; -} - -/* - * call-seq: - * cert.check_private_key(key) - * - * Checks if 'key' is PRIV key for this cert - */ -static VALUE -ossl_x509_check_private_key(VALUE self, VALUE key) -{ - X509 *x509; - EVP_PKEY *pkey; - - /* not needed private key, but should be */ - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - GetX509(self, x509); - if (!X509_check_private_key(x509, pkey)) { - OSSL_Warning("Check private key:%s", OSSL_ErrMsg()); - return Qfalse; - } - - return Qtrue; -} - -/* - * call-seq: - * cert.extensions => [extension...] - */ -static VALUE -ossl_x509_get_extensions(VALUE self) -{ - X509 *x509; - int count, i; - X509_EXTENSION *ext; - VALUE ary; - - GetX509(self, x509); - count = X509_get_ext_count(x509); - if (count < 0) { - return rb_ary_new(); - } - ary = rb_ary_new2(count); - for (i=0; i<count; i++) { - ext = X509_get_ext(x509, i); /* NO DUP - don't free! */ - rb_ary_push(ary, ossl_x509ext_new(ext)); - } - - return ary; -} - -/* - * call-seq: - * cert.extensions = [ext...] => [ext...] - */ -static VALUE -ossl_x509_set_extensions(VALUE self, VALUE ary) -{ - X509 *x509; - X509_EXTENSION *ext; - int i; - - Check_Type(ary, T_ARRAY); - /* All ary's members should be X509Extension */ - for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext); - } - GetX509(self, x509); - sk_X509_EXTENSION_pop_free(x509->cert_info->extensions, X509_EXTENSION_free); - x509->cert_info->extensions = NULL; - for (i=0; i<RARRAY_LEN(ary); i++) { - ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]); - - if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */ - X509_EXTENSION_free(ext); - ossl_raise(eX509CertError, NULL); - } - X509_EXTENSION_free(ext); - } - - return ary; -} - -/* - * call-seq: - * cert.add_extension(extension) => extension - */ -static VALUE -ossl_x509_add_extension(VALUE self, VALUE extension) -{ - X509 *x509; - X509_EXTENSION *ext; - - GetX509(self, x509); - ext = DupX509ExtPtr(extension); - if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */ - X509_EXTENSION_free(ext); - ossl_raise(eX509CertError, NULL); - } - X509_EXTENSION_free(ext); - - return extension; -} - -static VALUE -ossl_x509_inspect(VALUE self) -{ - VALUE str; - const char *cname = rb_class2name(rb_obj_class(self)); - - str = rb_str_new2("#<"); - rb_str_cat2(str, cname); - rb_str_cat2(str, " "); - - rb_str_cat2(str, "subject="); - rb_str_append(str, rb_inspect(ossl_x509_get_subject(self))); - rb_str_cat2(str, ", "); - - rb_str_cat2(str, "issuer="); - rb_str_append(str, rb_inspect(ossl_x509_get_issuer(self))); - rb_str_cat2(str, ", "); - - rb_str_cat2(str, "serial="); - rb_str_append(str, rb_inspect(ossl_x509_get_serial(self))); - rb_str_cat2(str, ", "); - - rb_str_cat2(str, "not_before="); - rb_str_append(str, rb_inspect(ossl_x509_get_not_before(self))); - rb_str_cat2(str, ", "); - - rb_str_cat2(str, "not_after="); - rb_str_append(str, rb_inspect(ossl_x509_get_not_after(self))); - - str = rb_str_cat2(str, ">"); - - return str; -} - -/* - * INIT - */ -void -Init_ossl_x509cert() -{ - -#if 0 - mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - - eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError); - - /* Document-class: OpenSSL::X509::Certificate - * - * Implementation of an X.509 certificate as specified in RFC 5280. - * Provides access to a certificate's attributes and allows certificates - * to be read from a string, but also supports the creation of new - * certificates from scratch. - * - * === Reading a certificate from a file - * - * Certificate is capable of handling DER-encoded certificates and - * certificates encoded in OpenSSL's PEM format. - * - * raw = File.read "cert.cer" # DER- or PEM-encoded - * certificate = OpenSSL::X509::Certificate.new raw - * - * === Saving a certificate to a file - * - * A certificate may be encoded in DER format - * - * cert = ... - * File.open("cert.cer", "wb") { |f| f.print cert.to_der } - * - * or in PEM format - * - * cert = ... - * File.open("cert.pem", "wb") { |f| f.print cert.to_pem } - * - * X.509 certificates are associated with a private/public key pair, - * typically a RSA, DSA or ECC key (see also OpenSSL::PKey::RSA, - * OpenSSL::PKey::DSA and OpenSSL::PKey::EC), the public key itself is - * stored within the certificate and can be accessed in form of an - * OpenSSL::PKey. Certificates are typically used to be able to associate - * some form of identity with a key pair, for example web servers serving - * pages over HTTPs use certificates to authenticate themselves to the user. - * - * The public key infrastructure (PKI) model relies on trusted certificate - * authorities ("root CAs") that issue these certificates, so that end - * users need to base their trust just on a selected few authorities - * that themselves again vouch for subordinate CAs issuing their - * certificates to end users. - * - * The OpenSSL::X509 module provides the tools to set up an independent - * PKI, similar to scenarios where the 'openssl' command line tool is - * used for issuing certificates in a private PKI. - * - * === Creating a root CA certificate and an end-entity certificate - * - * First, we need to create a "self-signed" root certificate. To do so, - * we need to generate a key first. Please note that the choice of "1" - * as a serial number is considered a security flaw for real certificates. - * Secure choices are integers in the two-digit byte range and ideally - * not sequential but secure random numbers, steps omitted here to keep - * the example concise. - * - * root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key - * root_ca = OpenSSL::X509::Certificate.new - * root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate - * root_ca.serial = 1 - * root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA" - * root_ca.issuer = root_ca.subject # root CA's are "self-signed" - * root_ca.public_key = root_key.public_key - * root_ca.not_before = Time.now - * root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity - * ef = OpenSSL::X509::ExtensionFactory.new - * ef.subject_certificate = root_ca - * ef.issuer_certificate = root_ca - * root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true)) - * root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true)) - * root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) - * root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false)) - * root_ca.sign(root_key, OpenSSL::Digest::SHA256.new) - * - * The next step is to create the end-entity certificate using the root CA - * certificate. - * - * key = OpenSSL::PKey::RSA.new 2048 - * cert = OpenSSL::X509::Certificate.new - * cert.version = 2 - * cert.serial = 2 - * cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate" - * cert.issuer = root_ca.subject # root CA is the issuer - * cert.public_key = key.public_key - * cert.not_before = Time.now - * cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity - * ef = OpenSSL::X509::ExtensionFactory.new - * ef.subject_certificate = cert - * ef.issuer_certificate = root_ca - * cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true)) - * cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) - * cert.sign(root_key, OpenSSL::Digest::SHA256.new) - * - */ - - eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError); - - cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject); - - rb_define_alloc_func(cX509Cert, ossl_x509_alloc); - rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1); - rb_define_copy_func(cX509Cert, ossl_x509_copy); - - rb_define_method(cX509Cert, "to_der", ossl_x509_to_der, 0); - rb_define_method(cX509Cert, "to_pem", ossl_x509_to_pem, 0); - rb_define_alias(cX509Cert, "to_s", "to_pem"); - rb_define_method(cX509Cert, "to_text", ossl_x509_to_text, 0); - rb_define_method(cX509Cert, "version", ossl_x509_get_version, 0); - rb_define_method(cX509Cert, "version=", ossl_x509_set_version, 1); - rb_define_method(cX509Cert, "signature_algorithm", ossl_x509_get_signature_algorithm, 0); - rb_define_method(cX509Cert, "serial", ossl_x509_get_serial, 0); - rb_define_method(cX509Cert, "serial=", ossl_x509_set_serial, 1); - rb_define_method(cX509Cert, "subject", ossl_x509_get_subject, 0); - rb_define_method(cX509Cert, "subject=", ossl_x509_set_subject, 1); - rb_define_method(cX509Cert, "issuer", ossl_x509_get_issuer, 0); - rb_define_method(cX509Cert, "issuer=", ossl_x509_set_issuer, 1); - rb_define_method(cX509Cert, "not_before", ossl_x509_get_not_before, 0); - rb_define_method(cX509Cert, "not_before=", ossl_x509_set_not_before, 1); - rb_define_method(cX509Cert, "not_after", ossl_x509_get_not_after, 0); - rb_define_method(cX509Cert, "not_after=", ossl_x509_set_not_after, 1); - rb_define_method(cX509Cert, "public_key", ossl_x509_get_public_key, 0); - rb_define_method(cX509Cert, "public_key=", ossl_x509_set_public_key, 1); - rb_define_method(cX509Cert, "sign", ossl_x509_sign, 2); - rb_define_method(cX509Cert, "verify", ossl_x509_verify, 1); - rb_define_method(cX509Cert, "check_private_key", ossl_x509_check_private_key, 1); - rb_define_method(cX509Cert, "extensions", ossl_x509_get_extensions, 0); - rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1); - rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1); - rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0); -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_x509crl.c b/ruby_1_9_3/ext/openssl/ossl_x509crl.c deleted file mode 100644 index dec13c8cae..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509crl.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapX509CRL(klass, obj, crl) do { \ - if (!(crl)) { \ - ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_CRL_free, (crl)); \ -} while (0) -#define GetX509CRL(obj, crl) do { \ - Data_Get_Struct((obj), X509_CRL, (crl)); \ - if (!(crl)) { \ - ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ - } \ -} while (0) -#define SafeGetX509CRL(obj, crl) do { \ - OSSL_Check_Kind((obj), cX509CRL); \ - GetX509CRL((obj), (crl)); \ -} while (0) - -/* - * Classes - */ -VALUE cX509CRL; -VALUE eX509CRLError; - -/* - * PUBLIC - */ -X509_CRL * -GetX509CRLPtr(VALUE obj) -{ - X509_CRL *crl; - - SafeGetX509CRL(obj, crl); - - return crl; -} - -X509_CRL * -DupX509CRLPtr(VALUE obj) -{ - X509_CRL *crl; - - SafeGetX509CRL(obj, crl); - CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); - - return crl; -} - -VALUE -ossl_x509crl_new(X509_CRL *crl) -{ - X509_CRL *tmp; - VALUE obj; - - tmp = crl ? X509_CRL_dup(crl) : X509_CRL_new(); - if(!tmp) ossl_raise(eX509CRLError, NULL); - WrapX509CRL(cX509CRL, obj, tmp); - - return obj; -} - -/* - * PRIVATE - */ -static VALUE -ossl_x509crl_alloc(VALUE klass) -{ - X509_CRL *crl; - VALUE obj; - - if (!(crl = X509_CRL_new())) { - ossl_raise(eX509CRLError, NULL); - } - WrapX509CRL(klass, obj, crl); - - return obj; -} - -static VALUE -ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self) -{ - BIO *in; - X509_CRL *crl, *x = DATA_PTR(self); - VALUE arg; - - if (rb_scan_args(argc, argv, "01", &arg) == 0) { - return self; - } - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - crl = PEM_read_bio_X509_CRL(in, &x, NULL, NULL); - DATA_PTR(self) = x; - if (!crl) { - OSSL_BIO_reset(in); - crl = d2i_X509_CRL_bio(in, &x); - DATA_PTR(self) = x; - } - BIO_free(in); - if (!crl) ossl_raise(eX509CRLError, NULL); - - return self; -} - -static VALUE -ossl_x509crl_copy(VALUE self, VALUE other) -{ - X509_CRL *a, *b, *crl; - - rb_check_frozen(self); - if (self == other) return self; - GetX509CRL(self, a); - SafeGetX509CRL(other, b); - if (!(crl = X509_CRL_dup(b))) { - ossl_raise(eX509CRLError, NULL); - } - X509_CRL_free(a); - DATA_PTR(self) = crl; - - return self; -} - -static VALUE -ossl_x509crl_get_version(VALUE self) -{ - X509_CRL *crl; - long ver; - - GetX509CRL(self, crl); - ver = X509_CRL_get_version(crl); - - return LONG2NUM(ver); -} - -static VALUE -ossl_x509crl_set_version(VALUE self, VALUE version) -{ - X509_CRL *crl; - long ver; - - if ((ver = NUM2LONG(version)) < 0) { - ossl_raise(eX509CRLError, "version must be >= 0!"); - } - GetX509CRL(self, crl); - if (!X509_CRL_set_version(crl, ver)) { - ossl_raise(eX509CRLError, NULL); - } - - return version; -} - -static VALUE -ossl_x509crl_get_signature_algorithm(VALUE self) -{ - X509_CRL *crl; - BIO *out; - BUF_MEM *buf; - VALUE str; - - GetX509CRL(self, crl); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); - } - if (!i2a_ASN1_OBJECT(out, crl->sig_alg->algorithm)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); - } - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - return str; -} - -static VALUE -ossl_x509crl_get_issuer(VALUE self) -{ - X509_CRL *crl; - - GetX509CRL(self, crl); - - return ossl_x509name_new(X509_CRL_get_issuer(crl)); /* NO DUP - don't free */ -} - -static VALUE -ossl_x509crl_set_issuer(VALUE self, VALUE issuer) -{ - X509_CRL *crl; - - GetX509CRL(self, crl); - - if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */ - ossl_raise(eX509CRLError, NULL); - } - return issuer; -} - -static VALUE -ossl_x509crl_get_last_update(VALUE self) -{ - X509_CRL *crl; - - GetX509CRL(self, crl); - - return asn1time_to_time(X509_CRL_get_lastUpdate(crl)); -} - -static VALUE -ossl_x509crl_set_last_update(VALUE self, VALUE time) -{ - X509_CRL *crl; - time_t sec; - - sec = time_to_time_t(time); - GetX509CRL(self, crl); - if (!X509_time_adj(crl->crl->lastUpdate, 0, &sec)) { - ossl_raise(eX509CRLError, NULL); - } - - return time; -} - -static VALUE -ossl_x509crl_get_next_update(VALUE self) -{ - X509_CRL *crl; - - GetX509CRL(self, crl); - - return asn1time_to_time(X509_CRL_get_nextUpdate(crl)); -} - -static VALUE -ossl_x509crl_set_next_update(VALUE self, VALUE time) -{ - X509_CRL *crl; - time_t sec; - - sec = time_to_time_t(time); - GetX509CRL(self, crl); - /* This must be some thinko in OpenSSL */ - if (!(crl->crl->nextUpdate = X509_time_adj(crl->crl->nextUpdate, 0, &sec))){ - ossl_raise(eX509CRLError, NULL); - } - - return time; -} - -static VALUE -ossl_x509crl_get_revoked(VALUE self) -{ - X509_CRL *crl; - int i, num; - X509_REVOKED *rev; - VALUE ary, revoked; - - GetX509CRL(self, crl); - num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); - if (num < 0) { - OSSL_Debug("num < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(num); - for(i=0; i<num; i++) { - /* NO DUP - don't free! */ - rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); - revoked = ossl_x509revoked_new(rev); - rb_ary_push(ary, revoked); - } - - return ary; -} - -static VALUE -ossl_x509crl_set_revoked(VALUE self, VALUE ary) -{ - X509_CRL *crl; - X509_REVOKED *rev; - int i; - - Check_Type(ary, T_ARRAY); - /* All ary members should be X509 Revoked */ - for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Rev); - } - GetX509CRL(self, crl); - sk_X509_REVOKED_pop_free(crl->crl->revoked, X509_REVOKED_free); - crl->crl->revoked = NULL; - for (i=0; i<RARRAY_LEN(ary); i++) { - rev = DupX509RevokedPtr(RARRAY_PTR(ary)[i]); - if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */ - ossl_raise(eX509CRLError, NULL); - } - } - X509_CRL_sort(crl); - - return ary; -} - -static VALUE -ossl_x509crl_add_revoked(VALUE self, VALUE revoked) -{ - X509_CRL *crl; - X509_REVOKED *rev; - - GetX509CRL(self, crl); - rev = DupX509RevokedPtr(revoked); - if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */ - ossl_raise(eX509CRLError, NULL); - } - X509_CRL_sort(crl); - - return revoked; -} - -static VALUE -ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest) -{ - X509_CRL *crl; - EVP_PKEY *pkey; - const EVP_MD *md; - - GetX509CRL(self, crl); - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = GetDigestPtr(digest); - if (!X509_CRL_sign(crl, pkey, md)) { - ossl_raise(eX509CRLError, NULL); - } - - return self; -} - -static VALUE -ossl_x509crl_verify(VALUE self, VALUE key) -{ - X509_CRL *crl; - int ret; - - GetX509CRL(self, crl); - if ((ret = X509_CRL_verify(crl, GetPKeyPtr(key))) < 0) { - ossl_raise(eX509CRLError, NULL); - } - if (ret == 1) { - return Qtrue; - } - - return Qfalse; -} - -static VALUE -ossl_x509crl_to_der(VALUE self) -{ - X509_CRL *crl; - BIO *out; - BUF_MEM *buf; - VALUE str; - - GetX509CRL(self, crl); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); - } - if (!i2d_X509_CRL_bio(out, crl)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); - } - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - - return str; -} - -static VALUE -ossl_x509crl_to_pem(VALUE self) -{ - X509_CRL *crl; - BIO *out; - BUF_MEM *buf; - VALUE str; - - GetX509CRL(self, crl); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); - } - if (!PEM_write_bio_X509_CRL(out, crl)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); - } - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - - return str; -} - -static VALUE -ossl_x509crl_to_text(VALUE self) -{ - X509_CRL *crl; - BIO *out; - BUF_MEM *buf; - VALUE str; - - GetX509CRL(self, crl); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); - } - if (!X509_CRL_print(out, crl)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); - } - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - - return str; -} - -/* - * Gets X509v3 extensions as array of X509Ext objects - */ -static VALUE -ossl_x509crl_get_extensions(VALUE self) -{ - X509_CRL *crl; - int count, i; - X509_EXTENSION *ext; - VALUE ary; - - GetX509CRL(self, crl); - count = X509_CRL_get_ext_count(crl); - if (count < 0) { - OSSL_Debug("count < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(count); - for (i=0; i<count; i++) { - ext = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */ - rb_ary_push(ary, ossl_x509ext_new(ext)); - } - - return ary; -} - -/* - * Sets X509_EXTENSIONs - */ -static VALUE -ossl_x509crl_set_extensions(VALUE self, VALUE ary) -{ - X509_CRL *crl; - X509_EXTENSION *ext; - int i; - - Check_Type(ary, T_ARRAY); - /* All ary members should be X509 Extensions */ - for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext); - } - GetX509CRL(self, crl); - sk_X509_EXTENSION_pop_free(crl->crl->extensions, X509_EXTENSION_free); - crl->crl->extensions = NULL; - for (i=0; i<RARRAY_LEN(ary); i++) { - ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]); - if(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */ - X509_EXTENSION_free(ext); - ossl_raise(eX509CRLError, NULL); - } - X509_EXTENSION_free(ext); - } - - return ary; -} - -static VALUE -ossl_x509crl_add_extension(VALUE self, VALUE extension) -{ - X509_CRL *crl; - X509_EXTENSION *ext; - - GetX509CRL(self, crl); - ext = DupX509ExtPtr(extension); - if (!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */ - X509_EXTENSION_free(ext); - ossl_raise(eX509CRLError, NULL); - } - X509_EXTENSION_free(ext); - - return extension; -} - -/* - * INIT - */ -void -Init_ossl_x509crl() -{ - eX509CRLError = rb_define_class_under(mX509, "CRLError", eOSSLError); - - cX509CRL = rb_define_class_under(mX509, "CRL", rb_cObject); - - rb_define_alloc_func(cX509CRL, ossl_x509crl_alloc); - rb_define_method(cX509CRL, "initialize", ossl_x509crl_initialize, -1); - rb_define_copy_func(cX509CRL, ossl_x509crl_copy); - - rb_define_method(cX509CRL, "version", ossl_x509crl_get_version, 0); - rb_define_method(cX509CRL, "version=", ossl_x509crl_set_version, 1); - rb_define_method(cX509CRL, "signature_algorithm", ossl_x509crl_get_signature_algorithm, 0); - rb_define_method(cX509CRL, "issuer", ossl_x509crl_get_issuer, 0); - rb_define_method(cX509CRL, "issuer=", ossl_x509crl_set_issuer, 1); - rb_define_method(cX509CRL, "last_update", ossl_x509crl_get_last_update, 0); - rb_define_method(cX509CRL, "last_update=", ossl_x509crl_set_last_update, 1); - rb_define_method(cX509CRL, "next_update", ossl_x509crl_get_next_update, 0); - rb_define_method(cX509CRL, "next_update=", ossl_x509crl_set_next_update, 1); - rb_define_method(cX509CRL, "revoked", ossl_x509crl_get_revoked, 0); - rb_define_method(cX509CRL, "revoked=", ossl_x509crl_set_revoked, 1); - rb_define_method(cX509CRL, "add_revoked", ossl_x509crl_add_revoked, 1); - rb_define_method(cX509CRL, "sign", ossl_x509crl_sign, 2); - rb_define_method(cX509CRL, "verify", ossl_x509crl_verify, 1); - rb_define_method(cX509CRL, "to_der", ossl_x509crl_to_der, 0); - rb_define_method(cX509CRL, "to_pem", ossl_x509crl_to_pem, 0); - rb_define_alias(cX509CRL, "to_s", "to_pem"); - rb_define_method(cX509CRL, "to_text", ossl_x509crl_to_text, 0); - rb_define_method(cX509CRL, "extensions", ossl_x509crl_get_extensions, 0); - rb_define_method(cX509CRL, "extensions=", ossl_x509crl_set_extensions, 1); - rb_define_method(cX509CRL, "add_extension", ossl_x509crl_add_extension, 1); -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_x509ext.c b/ruby_1_9_3/ext/openssl/ossl_x509ext.c deleted file mode 100644 index bd2e1dd2fa..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509ext.c +++ /dev/null @@ -1,471 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapX509Ext(klass, obj, ext) do { \ - if (!(ext)) { \ - ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_EXTENSION_free, (ext)); \ -} while (0) -#define GetX509Ext(obj, ext) do { \ - Data_Get_Struct((obj), X509_EXTENSION, (ext)); \ - if (!(ext)) { \ - ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ - } \ -} while (0) -#define SafeGetX509Ext(obj, ext) do { \ - OSSL_Check_Kind((obj), cX509Ext); \ - GetX509Ext((obj), (ext)); \ -} while (0) -#define MakeX509ExtFactory(klass, obj, ctx) do { \ - if (!((ctx) = OPENSSL_malloc(sizeof(X509V3_CTX)))) \ - ossl_raise(rb_eRuntimeError, "CTX wasn't allocated!"); \ - X509V3_set_ctx((ctx), NULL, NULL, NULL, NULL, 0); \ - (obj) = Data_Wrap_Struct((klass), 0, ossl_x509extfactory_free, (ctx)); \ -} while (0) -#define GetX509ExtFactory(obj, ctx) do { \ - Data_Get_Struct((obj), X509V3_CTX, (ctx)); \ - if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "CTX wasn't initialized!"); \ - } \ -} while (0) - -/* - * Classes - */ -VALUE cX509Ext; -VALUE cX509ExtFactory; -VALUE eX509ExtError; - -/* - * Public - */ -VALUE -ossl_x509ext_new(X509_EXTENSION *ext) -{ - X509_EXTENSION *new; - VALUE obj; - - if (!ext) { - new = X509_EXTENSION_new(); - } else { - new = X509_EXTENSION_dup(ext); - } - if (!new) { - ossl_raise(eX509ExtError, NULL); - } - WrapX509Ext(cX509Ext, obj, new); - - return obj; -} - -X509_EXTENSION * -GetX509ExtPtr(VALUE obj) -{ - X509_EXTENSION *ext; - - SafeGetX509Ext(obj, ext); - - return ext; -} - -X509_EXTENSION * -DupX509ExtPtr(VALUE obj) -{ - X509_EXTENSION *ext, *new; - - SafeGetX509Ext(obj, ext); - if (!(new = X509_EXTENSION_dup(ext))) { - ossl_raise(eX509ExtError, NULL); - } - - return new; -} - -/* - * Private - */ -/* - * Ext factory - */ -static void -ossl_x509extfactory_free(X509V3_CTX *ctx) -{ - OPENSSL_free(ctx); -} - -static VALUE -ossl_x509extfactory_alloc(VALUE klass) -{ - X509V3_CTX *ctx; - VALUE obj; - - MakeX509ExtFactory(klass, obj, ctx); - rb_iv_set(obj, "@config", Qnil); - - return obj; -} - -static VALUE -ossl_x509extfactory_set_issuer_cert(VALUE self, VALUE cert) -{ - X509V3_CTX *ctx; - - GetX509ExtFactory(self, ctx); - rb_iv_set(self, "@issuer_certificate", cert); - ctx->issuer_cert = GetX509CertPtr(cert); /* NO DUP NEEDED */ - - return cert; -} - -static VALUE -ossl_x509extfactory_set_subject_cert(VALUE self, VALUE cert) -{ - X509V3_CTX *ctx; - - GetX509ExtFactory(self, ctx); - rb_iv_set(self, "@subject_certificate", cert); - ctx->subject_cert = GetX509CertPtr(cert); /* NO DUP NEEDED */ - - return cert; -} - -static VALUE -ossl_x509extfactory_set_subject_req(VALUE self, VALUE req) -{ - X509V3_CTX *ctx; - - GetX509ExtFactory(self, ctx); - rb_iv_set(self, "@subject_request", req); - ctx->subject_req = GetX509ReqPtr(req); /* NO DUP NEEDED */ - - return req; -} - -static VALUE -ossl_x509extfactory_set_crl(VALUE self, VALUE crl) -{ - X509V3_CTX *ctx; - - GetX509ExtFactory(self, ctx); - rb_iv_set(self, "@crl", crl); - ctx->crl = GetX509CRLPtr(crl); /* NO DUP NEEDED */ - - return crl; -} - -#ifdef HAVE_X509V3_SET_NCONF -static VALUE -ossl_x509extfactory_set_config(VALUE self, VALUE config) -{ - X509V3_CTX *ctx; - CONF *conf; - - GetX509ExtFactory(self, ctx); - rb_iv_set(self, "@config", config); - conf = GetConfigPtr(config); /* NO DUP NEEDED */ - X509V3_set_nconf(ctx, conf); - - return config; -} -#else -#define ossl_x509extfactory_set_config rb_f_notimplement -#endif - -static VALUE -ossl_x509extfactory_initialize(int argc, VALUE *argv, VALUE self) -{ - /*X509V3_CTX *ctx;*/ - VALUE issuer_cert, subject_cert, subject_req, crl; - - /*GetX509ExtFactory(self, ctx);*/ - - rb_scan_args(argc, argv, "04", - &issuer_cert, &subject_cert, &subject_req, &crl); - if (!NIL_P(issuer_cert)) - ossl_x509extfactory_set_issuer_cert(self, issuer_cert); - if (!NIL_P(subject_cert)) - ossl_x509extfactory_set_subject_cert(self, subject_cert); - if (!NIL_P(subject_req)) - ossl_x509extfactory_set_subject_req(self, subject_req); - if (!NIL_P(crl)) - ossl_x509extfactory_set_crl(self, crl); - - return self; -} - -/* - * Array to X509_EXTENSION - * Structure: - * ["ln", "value", bool_critical] or - * ["sn", "value", bool_critical] or - * ["ln", "critical,value"] or the same for sn - * ["ln", "value"] => not critical - */ -static VALUE -ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) -{ - X509V3_CTX *ctx; - X509_EXTENSION *ext; - VALUE oid, value, critical, valstr, obj; - int nid; -#ifdef HAVE_X509V3_EXT_NCONF_NID - VALUE rconf; - CONF *conf; -#else - static LHASH *empty_lhash; -#endif - - rb_scan_args(argc, argv, "21", &oid, &value, &critical); - StringValue(oid); - StringValue(value); - if(NIL_P(critical)) critical = Qfalse; - - nid = OBJ_ln2nid(RSTRING_PTR(oid)); - if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid)); - if(!nid) ossl_raise(eX509ExtError, "unknown OID `%s'", RSTRING_PTR(oid)); - valstr = rb_str_new2(RTEST(critical) ? "critical," : ""); - rb_str_append(valstr, value); - GetX509ExtFactory(self, ctx); -#ifdef HAVE_X509V3_EXT_NCONF_NID - rconf = rb_iv_get(self, "@config"); - conf = NIL_P(rconf) ? NULL : GetConfigPtr(rconf); - ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr)); -#else - if (!empty_lhash) empty_lhash = lh_new(NULL, NULL); - ext = X509V3_EXT_conf_nid(empty_lhash, ctx, nid, RSTRING_PTR(valstr)); -#endif - if (!ext){ - ossl_raise(eX509ExtError, "%s = %s", - RSTRING_PTR(oid), RSTRING_PTR(value)); - } - WrapX509Ext(cX509Ext, obj, ext); - - return obj; -} - -/* - * Ext - */ -static VALUE -ossl_x509ext_alloc(VALUE klass) -{ - X509_EXTENSION *ext; - VALUE obj; - - if(!(ext = X509_EXTENSION_new())){ - ossl_raise(eX509ExtError, NULL); - } - WrapX509Ext(klass, obj, ext); - - return obj; -} - -/* - * call-seq: - * OpenSSL::X509::Extension.new asn1 - * OpenSSL::X509::Extension.new name, value - * OpenSSL::X509::Extension.new name, value, critical - * - * Creates an X509 extension. - * - * The extension may be created from +asn1+ data or from an extension +name+ - * and +value+. The +name+ may be either an OID or an extension name. If - * +critical+ is true the extension is marked critical. - */ -static VALUE -ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE oid, value, critical; - const unsigned char *p; - X509_EXTENSION *ext, *x; - - GetX509Ext(self, ext); - if(rb_scan_args(argc, argv, "12", &oid, &value, &critical) == 1){ - oid = ossl_to_der_if_possible(oid); - StringValue(oid); - p = (unsigned char *)RSTRING_PTR(oid); - x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid)); - DATA_PTR(self) = ext; - if(!x) - ossl_raise(eX509ExtError, NULL); - return self; - } - rb_funcall(self, rb_intern("oid="), 1, oid); - rb_funcall(self, rb_intern("value="), 1, value); - if(argc > 2) rb_funcall(self, rb_intern("critical="), 1, critical); - - return self; -} - -static VALUE -ossl_x509ext_set_oid(VALUE self, VALUE oid) -{ - X509_EXTENSION *ext; - ASN1_OBJECT *obj; - char *s; - - s = StringValuePtr(oid); - obj = OBJ_txt2obj(s, 0); - if(!obj) obj = OBJ_txt2obj(s, 1); - if(!obj) ossl_raise(eX509ExtError, NULL); - GetX509Ext(self, ext); - X509_EXTENSION_set_object(ext, obj); - - return oid; -} - -static VALUE -ossl_x509ext_set_value(VALUE self, VALUE data) -{ - X509_EXTENSION *ext; - ASN1_OCTET_STRING *asn1s; - char *s; - - data = ossl_to_der_if_possible(data); - StringValue(data); - if(!(s = OPENSSL_malloc(RSTRING_LEN(data)))) - ossl_raise(eX509ExtError, "malloc error"); - memcpy(s, RSTRING_PTR(data), RSTRING_LEN(data)); - if(!(asn1s = ASN1_OCTET_STRING_new())){ - OPENSSL_free(s); - ossl_raise(eX509ExtError, NULL); - } - if(!M_ASN1_OCTET_STRING_set(asn1s, s, RSTRING_LENINT(data))){ - OPENSSL_free(s); - ASN1_OCTET_STRING_free(asn1s); - ossl_raise(eX509ExtError, NULL); - } - OPENSSL_free(s); - GetX509Ext(self, ext); - X509_EXTENSION_set_data(ext, asn1s); - - return data; -} - -static VALUE -ossl_x509ext_set_critical(VALUE self, VALUE flag) -{ - X509_EXTENSION *ext; - - GetX509Ext(self, ext); - X509_EXTENSION_set_critical(ext, RTEST(flag) ? 1 : 0); - - return flag; -} - -static VALUE -ossl_x509ext_get_oid(VALUE obj) -{ - X509_EXTENSION *ext; - ASN1_OBJECT *extobj; - BIO *out; - VALUE ret; - int nid; - - GetX509Ext(obj, ext); - extobj = X509_EXTENSION_get_object(ext); - if ((nid = OBJ_obj2nid(extobj)) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); - else{ - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509ExtError, NULL); - i2a_ASN1_OBJECT(out, extobj); - ret = ossl_membio2str(out); - } - - return ret; -} - -static VALUE -ossl_x509ext_get_value(VALUE obj) -{ - X509_EXTENSION *ext; - BIO *out; - VALUE ret; - - GetX509Ext(obj, ext); - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509ExtError, NULL); - if (!X509V3_EXT_print(out, ext, 0, 0)) - M_ASN1_OCTET_STRING_print(out, ext->value); - ret = ossl_membio2str(out); - - return ret; -} - -static VALUE -ossl_x509ext_get_critical(VALUE obj) -{ - X509_EXTENSION *ext; - - GetX509Ext(obj, ext); - return X509_EXTENSION_get_critical(ext) ? Qtrue : Qfalse; -} - -static VALUE -ossl_x509ext_to_der(VALUE obj) -{ - X509_EXTENSION *ext; - unsigned char *p; - long len; - VALUE str; - - GetX509Ext(obj, ext); - if((len = i2d_X509_EXTENSION(ext, NULL)) <= 0) - ossl_raise(eX509ExtError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_X509_EXTENSION(ext, &p) < 0) - ossl_raise(eX509ExtError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -/* - * INIT - */ -void -Init_ossl_x509ext() -{ - eX509ExtError = rb_define_class_under(mX509, "ExtensionError", eOSSLError); - - cX509ExtFactory = rb_define_class_under(mX509, "ExtensionFactory", rb_cObject); - - rb_define_alloc_func(cX509ExtFactory, ossl_x509extfactory_alloc); - rb_define_method(cX509ExtFactory, "initialize", ossl_x509extfactory_initialize, -1); - - rb_attr(cX509ExtFactory, rb_intern("issuer_certificate"), 1, 0, Qfalse); - rb_attr(cX509ExtFactory, rb_intern("subject_certificate"), 1, 0, Qfalse); - rb_attr(cX509ExtFactory, rb_intern("subject_request"), 1, 0, Qfalse); - rb_attr(cX509ExtFactory, rb_intern("crl"), 1, 0, Qfalse); - rb_attr(cX509ExtFactory, rb_intern("config"), 1, 0, Qfalse); - - rb_define_method(cX509ExtFactory, "issuer_certificate=", ossl_x509extfactory_set_issuer_cert, 1); - rb_define_method(cX509ExtFactory, "subject_certificate=", ossl_x509extfactory_set_subject_cert, 1); - rb_define_method(cX509ExtFactory, "subject_request=", ossl_x509extfactory_set_subject_req, 1); - rb_define_method(cX509ExtFactory, "crl=", ossl_x509extfactory_set_crl, 1); - rb_define_method(cX509ExtFactory, "config=", ossl_x509extfactory_set_config, 1); - rb_define_method(cX509ExtFactory, "create_ext", ossl_x509extfactory_create_ext, -1); - - cX509Ext = rb_define_class_under(mX509, "Extension", rb_cObject); - rb_define_alloc_func(cX509Ext, ossl_x509ext_alloc); - rb_define_method(cX509Ext, "initialize", ossl_x509ext_initialize, -1); - rb_define_method(cX509Ext, "oid=", ossl_x509ext_set_oid, 1); - rb_define_method(cX509Ext, "value=", ossl_x509ext_set_value, 1); - rb_define_method(cX509Ext, "critical=", ossl_x509ext_set_critical, 1); - rb_define_method(cX509Ext, "oid", ossl_x509ext_get_oid, 0); - rb_define_method(cX509Ext, "value", ossl_x509ext_get_value, 0); - rb_define_method(cX509Ext, "critical?", ossl_x509ext_get_critical, 0); - rb_define_method(cX509Ext, "to_der", ossl_x509ext_to_der, 0); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_x509name.c b/ruby_1_9_3/ext/openssl/ossl_x509name.c deleted file mode 100644 index a8f288f4a5..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509name.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapX509Name(klass, obj, name) do { \ - if (!(name)) { \ - ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_NAME_free, (name)); \ -} while (0) -#define GetX509Name(obj, name) do { \ - Data_Get_Struct((obj), X509_NAME, (name)); \ - if (!(name)) { \ - ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ - } \ -} while (0) -#define SafeGetX509Name(obj, name) do { \ - OSSL_Check_Kind((obj), cX509Name); \ - GetX509Name((obj), (name)); \ -} while (0) - -#define OBJECT_TYPE_TEMPLATE \ - rb_const_get(cX509Name, rb_intern("OBJECT_TYPE_TEMPLATE")) -#define DEFAULT_OBJECT_TYPE \ - rb_const_get(cX509Name, rb_intern("DEFAULT_OBJECT_TYPE")) - -/* - * Classes - */ -VALUE cX509Name; -VALUE eX509NameError; - -/* - * Public - */ -VALUE -ossl_x509name_new(X509_NAME *name) -{ - X509_NAME *new; - VALUE obj; - - if (!name) { - new = X509_NAME_new(); - } else { - new = X509_NAME_dup(name); - } - if (!new) { - ossl_raise(eX509NameError, NULL); - } - WrapX509Name(cX509Name, obj, new); - - return obj; -} - -X509_NAME * -GetX509NamePtr(VALUE obj) -{ - X509_NAME *name; - - SafeGetX509Name(obj, name); - - return name; -} - -/* - * Private - */ -static VALUE -ossl_x509name_alloc(VALUE klass) -{ - X509_NAME *name; - VALUE obj; - - if (!(name = X509_NAME_new())) { - ossl_raise(eX509NameError, NULL); - } - WrapX509Name(klass, obj, name); - - return obj; -} - -static ID id_aref; -static VALUE ossl_x509name_add_entry(int, VALUE*, VALUE); -#define rb_aref(obj, key) rb_funcall((obj), id_aref, 1, (key)) - -static VALUE -ossl_x509name_init_i(VALUE i, VALUE args) -{ - VALUE self = rb_ary_entry(args, 0); - VALUE template = rb_ary_entry(args, 1); - VALUE entry[3]; - - Check_Type(i, T_ARRAY); - entry[0] = rb_ary_entry(i, 0); - entry[1] = rb_ary_entry(i, 1); - entry[2] = rb_ary_entry(i, 2); - if(NIL_P(entry[2])) entry[2] = rb_aref(template, entry[0]); - if(NIL_P(entry[2])) entry[2] = DEFAULT_OBJECT_TYPE; - ossl_x509name_add_entry(3, entry, self); - - return Qnil; -} - -/* - * call-seq: - * X509::Name.new => name - * X509::Name.new(string) => name - * X509::Name.new(dn) => name - * X509::Name.new(dn, template) => name - */ -static VALUE -ossl_x509name_initialize(int argc, VALUE *argv, VALUE self) -{ - X509_NAME *name; - VALUE arg, template; - - GetX509Name(self, name); - if (rb_scan_args(argc, argv, "02", &arg, &template) == 0) { - return self; - } - else { - VALUE tmp = rb_check_array_type(arg); - if (!NIL_P(tmp)) { - VALUE args; - if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE; - args = rb_ary_new3(2, self, template); - rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args); - } - else{ - const unsigned char *p; - VALUE str = ossl_to_der_if_possible(arg); - X509_NAME *x; - StringValue(str); - p = (unsigned char *)RSTRING_PTR(str); - x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str)); - DATA_PTR(self) = name; - if(!x){ - ossl_raise(eX509NameError, NULL); - } - } - } - - return self; -} - -/* - * call-seq: - * name.add_entry(oid, value [, type]) => self - */ -static -VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self) -{ - X509_NAME *name; - VALUE oid, value, type; - - rb_scan_args(argc, argv, "21", &oid, &value, &type); - StringValue(oid); - StringValue(value); - if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid); - GetX509Name(self, name); - if (!X509_NAME_add_entry_by_txt(name, RSTRING_PTR(oid), NUM2INT(type), - (const unsigned char *)RSTRING_PTR(value), RSTRING_LENINT(value), -1, 0)) { - ossl_raise(eX509NameError, NULL); - } - - return self; -} - -static VALUE -ossl_x509name_to_s_old(VALUE self) -{ - X509_NAME *name; - char *buf; - VALUE str; - - GetX509Name(self, name); - buf = X509_NAME_oneline(name, NULL, 0); - str = rb_str_new2(buf); - OPENSSL_free(buf); - - return str; -} - -/* - * call-seq: - * name.to_s => string - * name.to_s(integer) => string - */ -static VALUE -ossl_x509name_to_s(int argc, VALUE *argv, VALUE self) -{ - X509_NAME *name; - VALUE flag, str; - BIO *out; - unsigned long iflag; - - rb_scan_args(argc, argv, "01", &flag); - if (NIL_P(flag)) - return ossl_x509name_to_s_old(self); - else iflag = NUM2ULONG(flag); - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509NameError, NULL); - GetX509Name(self, name); - if (!X509_NAME_print_ex(out, name, 0, iflag)){ - BIO_free(out); - ossl_raise(eX509NameError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * name.to_a => [[name, data, type], ...] - */ -static VALUE -ossl_x509name_to_a(VALUE self) -{ - X509_NAME *name; - X509_NAME_ENTRY *entry; - int i,entries,nid; - char long_name[512]; - const char *short_name; - VALUE ary, vname, ret; - - GetX509Name(self, name); - entries = X509_NAME_entry_count(name); - if (entries < 0) { - OSSL_Debug("name entries < 0!"); - return rb_ary_new(); - } - ret = rb_ary_new2(entries); - for (i=0; i<entries; i++) { - if (!(entry = X509_NAME_get_entry(name, i))) { - ossl_raise(eX509NameError, NULL); - } - if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name), entry->object)) { - ossl_raise(eX509NameError, NULL); - } - nid = OBJ_ln2nid(long_name); - if (nid == NID_undef) { - vname = rb_str_new2((const char *) &long_name); - } else { - short_name = OBJ_nid2sn(nid); - vname = rb_str_new2(short_name); /*do not free*/ - } - ary = rb_ary_new3(3, - vname, - rb_str_new((const char *)entry->value->data, entry->value->length), - INT2FIX(entry->value->type)); - rb_ary_push(ret, ary); - } - return ret; -} - -static int -ossl_x509name_cmp0(VALUE self, VALUE other) -{ - X509_NAME *name1, *name2; - - GetX509Name(self, name1); - SafeGetX509Name(other, name2); - - return X509_NAME_cmp(name1, name2); -} - -/* - * call-seq: - * name.cmp other => integer - * name.<=> other => integer - * - * Compares this Name with +other+ and returns 0 if they are the same and -1 or - * +1 if they are greater or less than each other respectively. - */ -static VALUE -ossl_x509name_cmp(VALUE self, VALUE other) -{ - int result; - - result = ossl_x509name_cmp0(self, other); - if (result < 0) return INT2FIX(-1); - if (result > 1) return INT2FIX(1); - - return INT2FIX(0); -} - -static VALUE -ossl_x509name_eql(VALUE self, VALUE other) -{ - int result; - - if(CLASS_OF(other) != cX509Name) return Qfalse; - result = ossl_x509name_cmp0(self, other); - - return (result == 0) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * name.hash => integer - * - * The hash value returned is suitable for use as a certificate's filename in - * a CA path. - */ -static VALUE -ossl_x509name_hash(VALUE self) -{ - X509_NAME *name; - unsigned long hash; - - GetX509Name(self, name); - - hash = X509_NAME_hash(name); - - return ULONG2NUM(hash); -} - -#ifdef HAVE_X509_NAME_HASH_OLD -/* - * call-seq: - * name.hash_old => integer - * - * hash_old returns MD5 based hash used in OpenSSL 0.9.X. - */ -static VALUE -ossl_x509name_hash_old(VALUE self) -{ - X509_NAME *name; - unsigned long hash; - - GetX509Name(self, name); - - hash = X509_NAME_hash_old(name); - - return ULONG2NUM(hash); -} -#endif - -/* - * call-seq: - * name.to_der => string - */ -static VALUE -ossl_x509name_to_der(VALUE self) -{ - X509_NAME *name; - VALUE str; - long len; - unsigned char *p; - - GetX509Name(self, name); - if((len = i2d_X509_NAME(name, NULL)) <= 0) - ossl_raise(eX509NameError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_X509_NAME(name, &p) <= 0) - ossl_raise(eX509NameError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -/* - * INIT - */ -void -Init_ossl_x509name() -{ - VALUE utf8str, ptrstr, ia5str, hash; - - id_aref = rb_intern("[]"); - eX509NameError = rb_define_class_under(mX509, "NameError", eOSSLError); - cX509Name = rb_define_class_under(mX509, "Name", rb_cObject); - - rb_include_module(cX509Name, rb_mComparable); - - rb_define_alloc_func(cX509Name, ossl_x509name_alloc); - rb_define_method(cX509Name, "initialize", ossl_x509name_initialize, -1); - rb_define_method(cX509Name, "add_entry", ossl_x509name_add_entry, -1); - rb_define_method(cX509Name, "to_s", ossl_x509name_to_s, -1); - rb_define_method(cX509Name, "to_a", ossl_x509name_to_a, 0); - rb_define_method(cX509Name, "cmp", ossl_x509name_cmp, 1); - rb_define_alias(cX509Name, "<=>", "cmp"); - rb_define_method(cX509Name, "eql?", ossl_x509name_eql, 1); - rb_define_method(cX509Name, "hash", ossl_x509name_hash, 0); -#ifdef HAVE_X509_NAME_HASH_OLD - rb_define_method(cX509Name, "hash_old", ossl_x509name_hash_old, 0); -#endif - rb_define_method(cX509Name, "to_der", ossl_x509name_to_der, 0); - - utf8str = INT2NUM(V_ASN1_UTF8STRING); - ptrstr = INT2NUM(V_ASN1_PRINTABLESTRING); - ia5str = INT2NUM(V_ASN1_IA5STRING); - rb_define_const(cX509Name, "DEFAULT_OBJECT_TYPE", utf8str); - hash = rb_hash_new(); - RHASH(hash)->ifnone = utf8str; - rb_hash_aset(hash, rb_str_new2("C"), ptrstr); - rb_hash_aset(hash, rb_str_new2("countryName"), ptrstr); - rb_hash_aset(hash, rb_str_new2("serialNumber"), ptrstr); - rb_hash_aset(hash, rb_str_new2("dnQualifier"), ptrstr); - rb_hash_aset(hash, rb_str_new2("DC"), ia5str); - rb_hash_aset(hash, rb_str_new2("domainComponent"), ia5str); - rb_hash_aset(hash, rb_str_new2("emailAddress"), ia5str); - rb_define_const(cX509Name, "OBJECT_TYPE_TEMPLATE", hash); - - rb_define_const(cX509Name, "COMPAT", ULONG2NUM(XN_FLAG_COMPAT)); - rb_define_const(cX509Name, "RFC2253", ULONG2NUM(XN_FLAG_RFC2253)); - rb_define_const(cX509Name, "ONELINE", ULONG2NUM(XN_FLAG_ONELINE)); - rb_define_const(cX509Name, "MULTILINE", ULONG2NUM(XN_FLAG_MULTILINE)); -} diff --git a/ruby_1_9_3/ext/openssl/ossl_x509req.c b/ruby_1_9_3/ext/openssl/ossl_x509req.c deleted file mode 100644 index 5927f76d44..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509req.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapX509Req(klass, obj, req) do { \ - if (!(req)) { \ - ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_REQ_free, (req)); \ -} while (0) -#define GetX509Req(obj, req) do { \ - Data_Get_Struct((obj), X509_REQ, (req)); \ - if (!(req)) { \ - ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ - } \ -} while (0) -#define SafeGetX509Req(obj, req) do { \ - OSSL_Check_Kind((obj), cX509Req); \ - GetX509Req((obj), (req)); \ -} while (0) - -/* - * Classes - */ -VALUE cX509Req; -VALUE eX509ReqError; - -/* - * Public functions - */ -VALUE -ossl_x509req_new(X509_REQ *req) -{ - X509_REQ *new; - VALUE obj; - - if (!req) { - new = X509_REQ_new(); - } else { - new = X509_REQ_dup(req); - } - if (!new) { - ossl_raise(eX509ReqError, NULL); - } - WrapX509Req(cX509Req, obj, new); - - return obj; -} - -X509_REQ * -GetX509ReqPtr(VALUE obj) -{ - X509_REQ *req; - - SafeGetX509Req(obj, req); - - return req; -} - -X509_REQ * -DupX509ReqPtr(VALUE obj) -{ - X509_REQ *req, *new; - - SafeGetX509Req(obj, req); - if (!(new = X509_REQ_dup(req))) { - ossl_raise(eX509ReqError, NULL); - } - - return new; -} - -/* - * Private functions - */ -static VALUE -ossl_x509req_alloc(VALUE klass) -{ - X509_REQ *req; - VALUE obj; - - if (!(req = X509_REQ_new())) { - ossl_raise(eX509ReqError, NULL); - } - WrapX509Req(klass, obj, req); - - return obj; -} - -static VALUE -ossl_x509req_initialize(int argc, VALUE *argv, VALUE self) -{ - BIO *in; - X509_REQ *req, *x = DATA_PTR(self); - VALUE arg; - - if (rb_scan_args(argc, argv, "01", &arg) == 0) { - return self; - } - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(arg); - req = PEM_read_bio_X509_REQ(in, &x, NULL, NULL); - DATA_PTR(self) = x; - if (!req) { - OSSL_BIO_reset(in); - req = d2i_X509_REQ_bio(in, &x); - DATA_PTR(self) = x; - } - BIO_free(in); - if (!req) ossl_raise(eX509ReqError, NULL); - - return self; -} - -static VALUE -ossl_x509req_copy(VALUE self, VALUE other) -{ - X509_REQ *a, *b, *req; - - rb_check_frozen(self); - if (self == other) return self; - GetX509Req(self, a); - SafeGetX509Req(other, b); - if (!(req = X509_REQ_dup(b))) { - ossl_raise(eX509ReqError, NULL); - } - X509_REQ_free(a); - DATA_PTR(self) = req; - - return self; -} - -static VALUE -ossl_x509req_to_pem(VALUE self) -{ - X509_REQ *req; - BIO *out; - BUF_MEM *buf; - VALUE str; - - GetX509Req(self, req); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509ReqError, NULL); - } - if (!PEM_write_bio_X509_REQ(out, req)) { - BIO_free(out); - ossl_raise(eX509ReqError, NULL); - } - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - - return str; -} - -static VALUE -ossl_x509req_to_der(VALUE self) -{ - X509_REQ *req; - VALUE str; - long len; - unsigned char *p; - - GetX509Req(self, req); - if ((len = i2d_X509_REQ(req, NULL)) <= 0) - ossl_raise(eX509ReqError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if (i2d_X509_REQ(req, &p) <= 0) - ossl_raise(eX509ReqError, NULL); - ossl_str_adjust(str, p); - - return str; -} - -static VALUE -ossl_x509req_to_text(VALUE self) -{ - X509_REQ *req; - BIO *out; - BUF_MEM *buf; - VALUE str; - - GetX509Req(self, req); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509ReqError, NULL); - } - if (!X509_REQ_print(out, req)) { - BIO_free(out); - ossl_raise(eX509ReqError, NULL); - } - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - - return str; -} - -#if 0 -/* - * Makes X509 from X509_REQuest - */ -static VALUE -ossl_x509req_to_x509(VALUE self, VALUE days, VALUE key) -{ - X509_REQ *req; - X509 *x509; - - GetX509Req(self, req); - ... - if (!(x509 = X509_REQ_to_X509(req, d, pkey))) { - ossl_raise(eX509ReqError, NULL); - } - - return ossl_x509_new(x509); -} -#endif - -static VALUE -ossl_x509req_get_version(VALUE self) -{ - X509_REQ *req; - long version; - - GetX509Req(self, req); - version = X509_REQ_get_version(req); - - return LONG2FIX(version); -} - -static VALUE -ossl_x509req_set_version(VALUE self, VALUE version) -{ - X509_REQ *req; - long ver; - - if ((ver = FIX2LONG(version)) < 0) { - ossl_raise(eX509ReqError, "version must be >= 0!"); - } - GetX509Req(self, req); - if (!X509_REQ_set_version(req, ver)) { - ossl_raise(eX509ReqError, NULL); - } - - return version; -} - -static VALUE -ossl_x509req_get_subject(VALUE self) -{ - X509_REQ *req; - X509_NAME *name; - - GetX509Req(self, req); - if (!(name = X509_REQ_get_subject_name(req))) { /* NO DUP - don't free */ - ossl_raise(eX509ReqError, NULL); - } - - return ossl_x509name_new(name); -} - -static VALUE -ossl_x509req_set_subject(VALUE self, VALUE subject) -{ - X509_REQ *req; - - GetX509Req(self, req); - /* DUPs name */ - if (!X509_REQ_set_subject_name(req, GetX509NamePtr(subject))) { - ossl_raise(eX509ReqError, NULL); - } - - return subject; -} - -static VALUE -ossl_x509req_get_signature_algorithm(VALUE self) -{ - X509_REQ *req; - BIO *out; - BUF_MEM *buf; - VALUE str; - - GetX509Req(self, req); - - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509ReqError, NULL); - } - if (!i2a_ASN1_OBJECT(out, req->sig_alg->algorithm)) { - BIO_free(out); - ossl_raise(eX509ReqError, NULL); - } - BIO_get_mem_ptr(out, &buf); - str = rb_str_new(buf->data, buf->length); - BIO_free(out); - return str; -} - -static VALUE -ossl_x509req_get_public_key(VALUE self) -{ - X509_REQ *req; - EVP_PKEY *pkey; - - GetX509Req(self, req); - if (!(pkey = X509_REQ_get_pubkey(req))) { /* adds reference */ - ossl_raise(eX509ReqError, NULL); - } - - return ossl_pkey_new(pkey); /* NO DUP - OK */ -} - -static VALUE -ossl_x509req_set_public_key(VALUE self, VALUE key) -{ - X509_REQ *req; - EVP_PKEY *pkey; - - GetX509Req(self, req); - pkey = GetPKeyPtr(key); /* NO NEED TO DUP */ - if (!X509_REQ_set_pubkey(req, pkey)) { - ossl_raise(eX509ReqError, NULL); - } - - return key; -} - -static VALUE -ossl_x509req_sign(VALUE self, VALUE key, VALUE digest) -{ - X509_REQ *req; - EVP_PKEY *pkey; - const EVP_MD *md; - - GetX509Req(self, req); - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = GetDigestPtr(digest); - if (!X509_REQ_sign(req, pkey, md)) { - ossl_raise(eX509ReqError, NULL); - } - - return self; -} - -/* - * Checks that cert signature is made with PRIVversion of this PUBLIC 'key' - */ -static VALUE -ossl_x509req_verify(VALUE self, VALUE key) -{ - X509_REQ *req; - EVP_PKEY *pkey; - int i; - - GetX509Req(self, req); - pkey = GetPKeyPtr(key); /* NO NEED TO DUP */ - if ((i = X509_REQ_verify(req, pkey)) < 0) { - ossl_raise(eX509ReqError, NULL); - } - if (i > 0) { - return Qtrue; - } - - return Qfalse; -} - -static VALUE -ossl_x509req_get_attributes(VALUE self) -{ - X509_REQ *req; - int count, i; - X509_ATTRIBUTE *attr; - VALUE ary; - - GetX509Req(self, req); - - count = X509_REQ_get_attr_count(req); - if (count < 0) { - OSSL_Debug("count < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(count); - for (i=0; i<count; i++) { - attr = X509_REQ_get_attr(req, i); - rb_ary_push(ary, ossl_x509attr_new(attr)); - } - - return ary; -} - -static VALUE -ossl_x509req_set_attributes(VALUE self, VALUE ary) -{ - X509_REQ *req; - X509_ATTRIBUTE *attr; - int i; - VALUE item; - - Check_Type(ary, T_ARRAY); - for (i=0;i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Attr); - } - GetX509Req(self, req); - sk_X509_ATTRIBUTE_pop_free(req->req_info->attributes, X509_ATTRIBUTE_free); - req->req_info->attributes = NULL; - for (i=0;i<RARRAY_LEN(ary); i++) { - item = RARRAY_PTR(ary)[i]; - attr = DupX509AttrPtr(item); - if (!X509_REQ_add1_attr(req, attr)) { - ossl_raise(eX509ReqError, NULL); - } - } - return ary; -} - -static VALUE -ossl_x509req_add_attribute(VALUE self, VALUE attr) -{ - X509_REQ *req; - - GetX509Req(self, req); - if (!X509_REQ_add1_attr(req, DupX509AttrPtr(attr))) { - ossl_raise(eX509ReqError, NULL); - } - - return attr; -} - -/* - * X509_REQUEST init - */ -void -Init_ossl_x509req() -{ - eX509ReqError = rb_define_class_under(mX509, "RequestError", eOSSLError); - - cX509Req = rb_define_class_under(mX509, "Request", rb_cObject); - - rb_define_alloc_func(cX509Req, ossl_x509req_alloc); - rb_define_method(cX509Req, "initialize", ossl_x509req_initialize, -1); - rb_define_copy_func(cX509Req, ossl_x509req_copy); - - rb_define_method(cX509Req, "to_pem", ossl_x509req_to_pem, 0); - rb_define_method(cX509Req, "to_der", ossl_x509req_to_der, 0); - rb_define_alias(cX509Req, "to_s", "to_pem"); - rb_define_method(cX509Req, "to_text", ossl_x509req_to_text, 0); - rb_define_method(cX509Req, "version", ossl_x509req_get_version, 0); - rb_define_method(cX509Req, "version=", ossl_x509req_set_version, 1); - rb_define_method(cX509Req, "subject", ossl_x509req_get_subject, 0); - rb_define_method(cX509Req, "subject=", ossl_x509req_set_subject, 1); - rb_define_method(cX509Req, "signature_algorithm", ossl_x509req_get_signature_algorithm, 0); - rb_define_method(cX509Req, "public_key", ossl_x509req_get_public_key, 0); - rb_define_method(cX509Req, "public_key=", ossl_x509req_set_public_key, 1); - rb_define_method(cX509Req, "sign", ossl_x509req_sign, 2); - rb_define_method(cX509Req, "verify", ossl_x509req_verify, 1); - rb_define_method(cX509Req, "attributes", ossl_x509req_get_attributes, 0); - rb_define_method(cX509Req, "attributes=", ossl_x509req_set_attributes, 1); - rb_define_method(cX509Req, "add_attribute", ossl_x509req_add_attribute, 1); -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_x509revoked.c b/ruby_1_9_3/ext/openssl/ossl_x509revoked.c deleted file mode 100644 index 320abaa7ae..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509revoked.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapX509Rev(klass, obj, rev) do { \ - if (!(rev)) { \ - ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_REVOKED_free, (rev)); \ -} while (0) -#define GetX509Rev(obj, rev) do { \ - Data_Get_Struct((obj), X509_REVOKED, (rev)); \ - if (!(rev)) { \ - ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ - } \ -} while (0) -#define SafeGetX509Rev(obj, rev) do { \ - OSSL_Check_Kind((obj), cX509Rev); \ - GetX509Rev((obj), (rev)); \ -} while (0) - -/* - * Classes - */ -VALUE cX509Rev; -VALUE eX509RevError; - -/* - * PUBLIC - */ -VALUE -ossl_x509revoked_new(X509_REVOKED *rev) -{ - X509_REVOKED *new; - VALUE obj; - - if (!rev) { - new = X509_REVOKED_new(); - } else { - new = X509_REVOKED_dup(rev); - } - if (!new) { - ossl_raise(eX509RevError, NULL); - } - WrapX509Rev(cX509Rev, obj, new); - - return obj; -} - -X509_REVOKED * -DupX509RevokedPtr(VALUE obj) -{ - X509_REVOKED *rev, *new; - - SafeGetX509Rev(obj, rev); - if (!(new = X509_REVOKED_dup(rev))) { - ossl_raise(eX509RevError, NULL); - } - - return new; -} - -/* - * PRIVATE - */ -static VALUE -ossl_x509revoked_alloc(VALUE klass) -{ - X509_REVOKED *rev; - VALUE obj; - - if (!(rev = X509_REVOKED_new())) { - ossl_raise(eX509RevError, NULL); - } - WrapX509Rev(klass, obj, rev); - - return obj; -} - -static VALUE -ossl_x509revoked_initialize(int argc, VALUE *argv, VALUE self) -{ - /* EMPTY */ - return self; -} - -static VALUE -ossl_x509revoked_get_serial(VALUE self) -{ - X509_REVOKED *rev; - - GetX509Rev(self, rev); - - return asn1integer_to_num(rev->serialNumber); -} - -static VALUE -ossl_x509revoked_set_serial(VALUE self, VALUE num) -{ - X509_REVOKED *rev; - - GetX509Rev(self, rev); - rev->serialNumber = num_to_asn1integer(num, rev->serialNumber); - - return num; -} - -static VALUE -ossl_x509revoked_get_time(VALUE self) -{ - X509_REVOKED *rev; - - GetX509Rev(self, rev); - - return asn1time_to_time(rev->revocationDate); -} - -static VALUE -ossl_x509revoked_set_time(VALUE self, VALUE time) -{ - X509_REVOKED *rev; - time_t sec; - - sec = time_to_time_t(time); - GetX509Rev(self, rev); - if (!X509_time_adj(rev->revocationDate, 0, &sec)) { - ossl_raise(eX509RevError, NULL); - } - - return time; -} -/* - * Gets X509v3 extensions as array of X509Ext objects - */ -static VALUE -ossl_x509revoked_get_extensions(VALUE self) -{ - X509_REVOKED *rev; - int count, i; - X509_EXTENSION *ext; - VALUE ary; - - GetX509Rev(self, rev); - count = X509_REVOKED_get_ext_count(rev); - if (count < 0) { - OSSL_Debug("count < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(count); - for (i=0; i<count; i++) { - ext = X509_REVOKED_get_ext(rev, i); - rb_ary_push(ary, ossl_x509ext_new(ext)); - } - - return ary; -} - -/* - * Sets X509_EXTENSIONs - */ -static VALUE -ossl_x509revoked_set_extensions(VALUE self, VALUE ary) -{ - X509_REVOKED *rev; - X509_EXTENSION *ext; - int i; - VALUE item; - - Check_Type(ary, T_ARRAY); - for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext); - } - GetX509Rev(self, rev); - sk_X509_EXTENSION_pop_free(rev->extensions, X509_EXTENSION_free); - rev->extensions = NULL; - for (i=0; i<RARRAY_LEN(ary); i++) { - item = RARRAY_PTR(ary)[i]; - ext = DupX509ExtPtr(item); - if(!X509_REVOKED_add_ext(rev, ext, -1)) { - ossl_raise(eX509RevError, NULL); - } - } - - return ary; -} - -static VALUE -ossl_x509revoked_add_extension(VALUE self, VALUE ext) -{ - X509_REVOKED *rev; - - GetX509Rev(self, rev); - if(!X509_REVOKED_add_ext(rev, DupX509ExtPtr(ext), -1)) { - ossl_raise(eX509RevError, NULL); - } - - return ext; -} - -/* - * INIT - */ -void -Init_ossl_x509revoked() -{ - eX509RevError = rb_define_class_under(mX509, "RevokedError", eOSSLError); - - cX509Rev = rb_define_class_under(mX509, "Revoked", rb_cObject); - - rb_define_alloc_func(cX509Rev, ossl_x509revoked_alloc); - rb_define_method(cX509Rev, "initialize", ossl_x509revoked_initialize, -1); - - rb_define_method(cX509Rev, "serial", ossl_x509revoked_get_serial, 0); - rb_define_method(cX509Rev, "serial=", ossl_x509revoked_set_serial, 1); - rb_define_method(cX509Rev, "time", ossl_x509revoked_get_time, 0); - rb_define_method(cX509Rev, "time=", ossl_x509revoked_set_time, 1); - rb_define_method(cX509Rev, "extensions", ossl_x509revoked_get_extensions, 0); - rb_define_method(cX509Rev, "extensions=", ossl_x509revoked_set_extensions, 1); - rb_define_method(cX509Rev, "add_extension", ossl_x509revoked_add_extension, 1); -} - diff --git a/ruby_1_9_3/ext/openssl/ossl_x509store.c b/ruby_1_9_3/ext/openssl/ossl_x509store.c deleted file mode 100644 index 5d341c5192..0000000000 --- a/ruby_1_9_3/ext/openssl/ossl_x509store.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include "ossl.h" - -#define WrapX509Store(klass, obj, st) do { \ - if (!(st)) { \ - ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_STORE_free, (st)); \ -} while (0) -#define GetX509Store(obj, st) do { \ - Data_Get_Struct((obj), X509_STORE, (st)); \ - if (!(st)) { \ - ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ - } \ -} while (0) -#define SafeGetX509Store(obj, st) do { \ - OSSL_Check_Kind((obj), cX509Store); \ - GetX509Store((obj), (st)); \ -} while (0) - -#define WrapX509StCtx(klass, obj, ctx) do { \ - if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "STORE_CTX wasn't initialized!"); \ - } \ - (obj) = Data_Wrap_Struct((klass), 0, ossl_x509stctx_free, (ctx)); \ -} while (0) -#define GetX509StCtx(obj, ctx) do { \ - Data_Get_Struct((obj), X509_STORE_CTX, (ctx)); \ - if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "STORE_CTX is out of scope!"); \ - } \ -} while (0) -#define SafeGetX509StCtx(obj, storep) do { \ - OSSL_Check_Kind((obj), cX509StoreContext); \ - GetX509Store((obj), (ctx)); \ -} while (0) - -/* - * Classes - */ -VALUE cX509Store; -VALUE cX509StoreContext; -VALUE eX509StoreError; - -/* - * Public functions - */ -VALUE -ossl_x509store_new(X509_STORE *store) -{ - VALUE obj; - - WrapX509Store(cX509Store, obj, store); - - return obj; -} - -X509_STORE * -GetX509StorePtr(VALUE obj) -{ - X509_STORE *store; - - SafeGetX509Store(obj, store); - - return store; -} - -X509_STORE * -DupX509StorePtr(VALUE obj) -{ - X509_STORE *store; - - SafeGetX509Store(obj, store); - CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); - - return store; -} - -/* - * Private functions - */ -static VALUE -ossl_x509store_alloc(VALUE klass) -{ - X509_STORE *store; - VALUE obj; - - if((store = X509_STORE_new()) == NULL){ - ossl_raise(eX509StoreError, NULL); - } - WrapX509Store(klass, obj, store); - - return obj; -} - -/* - * General callback for OpenSSL verify - */ -static VALUE -ossl_x509store_set_vfy_cb(VALUE self, VALUE cb) -{ - X509_STORE *store; - - GetX509Store(self, store); - X509_STORE_set_ex_data(store, ossl_verify_cb_idx, (void*)cb); - rb_iv_set(self, "@verify_callback", cb); - - return cb; -} - - -/* - * call-seq: - * X509::Store.new => store - * - */ -static VALUE -ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) -{ - X509_STORE *store; - -/* BUG: This method takes any number of arguments but appears to ignore them. */ - GetX509Store(self, store); - store->ex_data.sk = NULL; - X509_STORE_set_verify_cb_func(store, ossl_verify_cb); - ossl_x509store_set_vfy_cb(self, Qnil); - -#if (OPENSSL_VERSION_NUMBER < 0x00907000L) - rb_iv_set(self, "@flags", INT2NUM(0)); - rb_iv_set(self, "@purpose", INT2NUM(0)); - rb_iv_set(self, "@trust", INT2NUM(0)); -#endif - - /* last verification status */ - rb_iv_set(self, "@error", Qnil); - rb_iv_set(self, "@error_string", Qnil); - rb_iv_set(self, "@chain", Qnil); - rb_iv_set(self, "@time", Qnil); - - return self; -} - -static VALUE -ossl_x509store_set_flags(VALUE self, VALUE flags) -{ -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - X509_STORE *store; - long f = NUM2LONG(flags); - - GetX509Store(self, store); - X509_STORE_set_flags(store, f); -#else - rb_iv_set(self, "@flags", flags); -#endif - - return flags; -} - -static VALUE -ossl_x509store_set_purpose(VALUE self, VALUE purpose) -{ -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - X509_STORE *store; - int p = NUM2INT(purpose); - - GetX509Store(self, store); - X509_STORE_set_purpose(store, p); -#else - rb_iv_set(self, "@purpose", purpose); -#endif - - return purpose; -} - -static VALUE -ossl_x509store_set_trust(VALUE self, VALUE trust) -{ -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - X509_STORE *store; - int t = NUM2INT(trust); - - GetX509Store(self, store); - X509_STORE_set_trust(store, t); -#else - rb_iv_set(self, "@trust", trust); -#endif - - return trust; -} - -static VALUE -ossl_x509store_set_time(VALUE self, VALUE time) -{ - rb_iv_set(self, "@time", time); - return time; -} - -static VALUE -ossl_x509store_add_file(VALUE self, VALUE file) -{ - X509_STORE *store; - X509_LOOKUP *lookup; - char *path = NULL; - - if(file != Qnil){ - SafeStringValue(file); - path = RSTRING_PTR(file); - } - GetX509Store(self, store); - lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); - if(lookup == NULL) ossl_raise(eX509StoreError, NULL); - if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){ - ossl_raise(eX509StoreError, NULL); - } - - return self; -} - -static VALUE -ossl_x509store_add_path(VALUE self, VALUE dir) -{ - X509_STORE *store; - X509_LOOKUP *lookup; - char *path = NULL; - - if(dir != Qnil){ - SafeStringValue(dir); - path = RSTRING_PTR(dir); - } - GetX509Store(self, store); - lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); - if(lookup == NULL) ossl_raise(eX509StoreError, NULL); - if(X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1){ - ossl_raise(eX509StoreError, NULL); - } - - return self; -} - -static VALUE -ossl_x509store_set_default_paths(VALUE self) -{ - X509_STORE *store; - - GetX509Store(self, store); - if (X509_STORE_set_default_paths(store) != 1){ - ossl_raise(eX509StoreError, NULL); - } - - return Qnil; -} - -static VALUE -ossl_x509store_add_cert(VALUE self, VALUE arg) -{ - X509_STORE *store; - X509 *cert; - - cert = GetX509CertPtr(arg); /* NO NEED TO DUP */ - GetX509Store(self, store); - if (X509_STORE_add_cert(store, cert) != 1){ - ossl_raise(eX509StoreError, NULL); - } - - return self; -} - -static VALUE -ossl_x509store_add_crl(VALUE self, VALUE arg) -{ - X509_STORE *store; - X509_CRL *crl; - - crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */ - GetX509Store(self, store); - if (X509_STORE_add_crl(store, crl) != 1){ - ossl_raise(eX509StoreError, NULL); - } - - return self; -} - -static VALUE ossl_x509stctx_get_err(VALUE); -static VALUE ossl_x509stctx_get_err_string(VALUE); -static VALUE ossl_x509stctx_get_chain(VALUE); - -static VALUE -ossl_x509store_verify(int argc, VALUE *argv, VALUE self) -{ - VALUE cert, chain; - VALUE ctx, proc, result; - - rb_scan_args(argc, argv, "11", &cert, &chain); - ctx = rb_funcall(cX509StoreContext, rb_intern("new"), 3, self, cert, chain); - proc = rb_block_given_p() ? rb_block_proc() : - rb_iv_get(self, "@verify_callback"); - rb_iv_set(ctx, "@verify_callback", proc); - result = rb_funcall(ctx, rb_intern("verify"), 0); - - rb_iv_set(self, "@error", ossl_x509stctx_get_err(ctx)); - rb_iv_set(self, "@error_string", ossl_x509stctx_get_err_string(ctx)); - rb_iv_set(self, "@chain", ossl_x509stctx_get_chain(ctx)); - - return result; -} - -/* - * Public Functions - */ -static void ossl_x509stctx_free(X509_STORE_CTX*); - -VALUE -ossl_x509stctx_new(X509_STORE_CTX *ctx) -{ - VALUE obj; - - WrapX509StCtx(cX509StoreContext, obj, ctx); - - return obj; -} - -VALUE -ossl_x509stctx_clear_ptr(VALUE obj) -{ - OSSL_Check_Kind(obj, cX509StoreContext); - RDATA(obj)->data = NULL; - - return obj; -} - -/* - * Private functions - */ -static void -ossl_x509stctx_free(X509_STORE_CTX *ctx) -{ - if(ctx->untrusted) - sk_X509_pop_free(ctx->untrusted, X509_free); - if(ctx->cert) - X509_free(ctx->cert); - X509_STORE_CTX_free(ctx); -} - -static VALUE -ossl_x509stctx_alloc(VALUE klass) -{ - X509_STORE_CTX *ctx; - VALUE obj; - - if((ctx = X509_STORE_CTX_new()) == NULL){ - ossl_raise(eX509StoreError, NULL); - } - WrapX509StCtx(klass, obj, ctx); - - return obj; -} - -static VALUE ossl_x509stctx_set_flags(VALUE, VALUE); -static VALUE ossl_x509stctx_set_purpose(VALUE, VALUE); -static VALUE ossl_x509stctx_set_trust(VALUE, VALUE); -static VALUE ossl_x509stctx_set_time(VALUE, VALUE); - -static VALUE -ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE store, cert, chain, t; - X509_STORE_CTX *ctx; - X509_STORE *x509st; - X509 *x509 = NULL; - STACK_OF(X509) *x509s = NULL; - - rb_scan_args(argc, argv, "12", &store, &cert, &chain); - GetX509StCtx(self, ctx); - SafeGetX509Store(store, x509st); - if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */ - if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain); -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){ - sk_X509_pop_free(x509s, X509_free); - ossl_raise(eX509StoreError, NULL); - } -#else - X509_STORE_CTX_init(ctx, x509st, x509, x509s); - ossl_x509stctx_set_flags(self, rb_iv_get(store, "@flags")); - ossl_x509stctx_set_purpose(self, rb_iv_get(store, "@purpose")); - ossl_x509stctx_set_trust(self, rb_iv_get(store, "@trust")); -#endif - if (!NIL_P(t = rb_iv_get(store, "@time"))) - ossl_x509stctx_set_time(self, t); - rb_iv_set(self, "@verify_callback", rb_iv_get(store, "@verify_callback")); - rb_iv_set(self, "@cert", cert); - - return self; -} - -static VALUE -ossl_x509stctx_verify(VALUE self) -{ - X509_STORE_CTX *ctx; - int result; - - GetX509StCtx(self, ctx); - X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx, - (void*)rb_iv_get(self, "@verify_callback")); - result = X509_verify_cert(ctx); - - return result ? Qtrue : Qfalse; -} - -static VALUE -ossl_x509stctx_get_chain(VALUE self) -{ - X509_STORE_CTX *ctx; - STACK_OF(X509) *chain; - X509 *x509; - int i, num; - VALUE ary; - - GetX509StCtx(self, ctx); - if((chain = X509_STORE_CTX_get_chain(ctx)) == NULL){ - return Qnil; - } - if((num = sk_X509_num(chain)) < 0){ - OSSL_Debug("certs in chain < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(num); - for(i = 0; i < num; i++) { - x509 = sk_X509_value(chain, i); - rb_ary_push(ary, ossl_x509_new(x509)); - } - - return ary; -} - -static VALUE -ossl_x509stctx_get_err(VALUE self) -{ - X509_STORE_CTX *ctx; - - GetX509StCtx(self, ctx); - - return INT2FIX(X509_STORE_CTX_get_error(ctx)); -} - -static VALUE -ossl_x509stctx_set_error(VALUE self, VALUE err) -{ - X509_STORE_CTX *ctx; - - GetX509StCtx(self, ctx); - X509_STORE_CTX_set_error(ctx, NUM2INT(err)); - - return err; -} - -static VALUE -ossl_x509stctx_get_err_string(VALUE self) -{ - X509_STORE_CTX *ctx; - long err; - - GetX509StCtx(self, ctx); - err = X509_STORE_CTX_get_error(ctx); - - return rb_str_new2(X509_verify_cert_error_string(err)); -} - -static VALUE -ossl_x509stctx_get_err_depth(VALUE self) -{ - X509_STORE_CTX *ctx; - - GetX509StCtx(self, ctx); - - return INT2FIX(X509_STORE_CTX_get_error_depth(ctx)); -} - -static VALUE -ossl_x509stctx_get_curr_cert(VALUE self) -{ - X509_STORE_CTX *ctx; - - GetX509StCtx(self, ctx); - - return ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx)); -} - -static VALUE -ossl_x509stctx_get_curr_crl(VALUE self) -{ -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) - X509_STORE_CTX *ctx; - - GetX509StCtx(self, ctx); - if(!ctx->current_crl) return Qnil; - - return ossl_x509crl_new(ctx->current_crl); -#else - return Qnil; -#endif -} - -static VALUE -ossl_x509stctx_set_flags(VALUE self, VALUE flags) -{ - X509_STORE_CTX *store; - long f = NUM2LONG(flags); - - GetX509StCtx(self, store); - X509_STORE_CTX_set_flags(store, f); - - return flags; -} - -static VALUE -ossl_x509stctx_set_purpose(VALUE self, VALUE purpose) -{ - X509_STORE_CTX *store; - int p = NUM2INT(purpose); - - GetX509StCtx(self, store); - X509_STORE_CTX_set_purpose(store, p); - - return purpose; -} - -static VALUE -ossl_x509stctx_set_trust(VALUE self, VALUE trust) -{ - X509_STORE_CTX *store; - int t = NUM2INT(trust); - - GetX509StCtx(self, store); - X509_STORE_CTX_set_trust(store, t); - - return trust; -} - -/* - * call-seq: - * storectx.time = time => time - */ -static VALUE -ossl_x509stctx_set_time(VALUE self, VALUE time) -{ - X509_STORE_CTX *store; - long t; - - t = NUM2LONG(rb_Integer(time)); - GetX509StCtx(self, store); - X509_STORE_CTX_set_time(store, 0, t); - - return time; -} - -/* - * INIT - */ -void -Init_ossl_x509store() -{ - VALUE x509stctx; - - eX509StoreError = rb_define_class_under(mX509, "StoreError", eOSSLError); - - cX509Store = rb_define_class_under(mX509, "Store", rb_cObject); - rb_attr(cX509Store, rb_intern("verify_callback"), 1, 0, Qfalse); - rb_attr(cX509Store, rb_intern("error"), 1, 0, Qfalse); - rb_attr(cX509Store, rb_intern("error_string"), 1, 0, Qfalse); - rb_attr(cX509Store, rb_intern("chain"), 1, 0, Qfalse); - rb_define_alloc_func(cX509Store, ossl_x509store_alloc); - rb_define_method(cX509Store, "initialize", ossl_x509store_initialize, -1); - rb_define_method(cX509Store, "verify_callback=", ossl_x509store_set_vfy_cb, 1); - rb_define_method(cX509Store, "flags=", ossl_x509store_set_flags, 1); - rb_define_method(cX509Store, "purpose=", ossl_x509store_set_purpose, 1); - rb_define_method(cX509Store, "trust=", ossl_x509store_set_trust, 1); - rb_define_method(cX509Store, "time=", ossl_x509store_set_time, 1); - rb_define_method(cX509Store, "add_path", ossl_x509store_add_path, 1); - rb_define_method(cX509Store, "add_file", ossl_x509store_add_file, 1); - rb_define_method(cX509Store, "set_default_paths", ossl_x509store_set_default_paths, 0); - rb_define_method(cX509Store, "add_cert", ossl_x509store_add_cert, 1); - rb_define_method(cX509Store, "add_crl", ossl_x509store_add_crl, 1); - rb_define_method(cX509Store, "verify", ossl_x509store_verify, -1); - - cX509StoreContext = rb_define_class_under(mX509,"StoreContext",rb_cObject); - x509stctx = cX509StoreContext; - rb_define_alloc_func(cX509StoreContext, ossl_x509stctx_alloc); - rb_define_method(x509stctx,"initialize", ossl_x509stctx_initialize, -1); - rb_define_method(x509stctx,"verify", ossl_x509stctx_verify, 0); - rb_define_method(x509stctx,"chain", ossl_x509stctx_get_chain,0); - rb_define_method(x509stctx,"error", ossl_x509stctx_get_err, 0); - rb_define_method(x509stctx,"error=", ossl_x509stctx_set_error, 1); - rb_define_method(x509stctx,"error_string",ossl_x509stctx_get_err_string,0); - rb_define_method(x509stctx,"error_depth", ossl_x509stctx_get_err_depth, 0); - rb_define_method(x509stctx,"current_cert",ossl_x509stctx_get_curr_cert, 0); - rb_define_method(x509stctx,"current_crl", ossl_x509stctx_get_curr_crl, 0); - rb_define_method(x509stctx,"flags=", ossl_x509stctx_set_flags, 1); - rb_define_method(x509stctx,"purpose=", ossl_x509stctx_set_purpose, 1); - rb_define_method(x509stctx,"trust=", ossl_x509stctx_set_trust, 1); - rb_define_method(x509stctx,"time=", ossl_x509stctx_set_time, 1); - -} diff --git a/ruby_1_9_3/ext/openssl/ruby_missing.h b/ruby_1_9_3/ext/openssl/ruby_missing.h deleted file mode 100644 index 1c5d05baca..0000000000 --- a/ruby_1_9_3/ext/openssl/ruby_missing.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * $Id$ - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2003 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_RUBY_MISSING_H_) -#define _OSSL_RUBY_MISSING_H_ - -#define rb_define_copy_func(klass, func) \ - rb_define_method((klass), "initialize_copy", (func), 1) - - -#ifndef GetReadFile -#define FPTR_TO_FD(fptr) ((fptr)->fd) -#else -#define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr))) -#endif - -#ifndef HAVE_RB_IO_T -#define rb_io_t OpenFile -#endif - -#ifndef HAVE_RB_STR_SET_LEN -/* these methods should probably be backported to 1.8 */ -#define rb_str_set_len(str, length) do { \ - RSTRING(str)->ptr[(length)] = 0; \ - RSTRING(str)->len = (length); \ -} while(0) -#endif /* ! HAVE_RB_STR_SET_LEN */ - -#ifndef HAVE_RB_BLOCK_CALL -/* the openssl module doesn't use arg[3-4] and arg2 is always rb_each */ -#define rb_block_call(arg1, arg2, arg3, arg4, arg5, arg6) rb_iterate(rb_each, (arg1), (arg5), (arg6)) -#endif /* ! HAVE_RB_BLOCK_CALL */ - -#endif /* _OSSL_RUBY_MISSING_H_ */ |