Import Ruby/OpenSSL 2.0.0. The full commit history since 2.0.0 beta.2
(imported at r56098) can be found at:

  https://github.com/ruby/openssl/compare/v2.0.0.beta.2...v2.0.0

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56946 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
rhe 2016-11-30 14:41:46 +00:00
Родитель 0a5abaf745
Коммит aab0d67a1f
49 изменённых файлов: 1230 добавлений и 1286 удалений

7
NEWS
Просмотреть файл

@ -217,9 +217,10 @@ with all sufficient information, see the ChangeLog file or Redmine
* OpenSSL
* OpenSSL is extracted as a gem and the upstream has been migrated to
https://github.com/ruby/openssl. OpenSSL still remains as a default gem.
Refer to its History.md for the full release note. [Feature #9612]
* Includes Ruby/OpenSSL 2.0. OpenSSL has been extracted as a Gem and is
maintained at a separate repository now: https://github.com/ruby/openssl.
It still remains as a 'default gem'. [Feature #9612]
Refer to ext/openssl/History.md for the full release note.
* optparse

137
ext/openssl/History.md Normal file
Просмотреть файл

@ -0,0 +1,137 @@
Version 2.0.0
=============
This is the first release of openssl gem, formerly a standard library of Ruby,
ext/openssl. This is the successor of the version included in Ruby 2.3.
Compatibility notes
-------------------
* Support for OpenSSL version 0.9.6 and 0.9.7 is completely removed. openssl gem
still works with OpenSSL 0.9.8, but users are strongly encouraged to upgrade
to at least 1.0.1, as OpenSSL < 1.0.1 will not receive any security fixes from
the OpenSSL development team.
Supported platforms
-------------------
* OpenSSL 1.0.0, 1.0.1, 1.0.2, 1.1.0
* OpenSSL < 0.9.8 is no longer supported.
* LibreSSL 2.3, 2.4, 2.5
* Ruby 2.3, 2.4
Notable changes
---------------
* Add support for OpenSSL 1.1.0. [[Feature #12324]](https://bugs.ruby-lang.org/issues/12324)
* Add support for LibreSSL
* OpenSSL::Cipher
- OpenSSL::Cipher#key= and #iv= reject too long inputs. They used to truncate
silently. [[Bug #12561]](https://bugs.ruby-lang.org/issues/12561)
- OpenSSL::Cipher#iv_len= is added. It allows changing IV (nonce) length if
using AEAD ciphers.
[[Bug #8667]](https://bugs.ruby-lang.org/issues/8667),
[[Bug #10420]](https://bugs.ruby-lang.org/issues/10420),
[[GH ruby/ruby#569]](https://github.com/ruby/ruby/pull/569),
[[GH ruby/openssl#58]](https://github.com/ruby/openssl/pull/58)
- OpenSSL::Cipher#auth_tag_len= is added. This sets the authentication tag
length to be generated by an AEAD cipher.
* OpenSSL::OCSP
- Accessor methods are added to OpenSSL::OCSP::CertificateId.
[[Feature #7181]](https://bugs.ruby-lang.org/issues/7181)
- OpenSSL::OCSP::Request and BasicResponse can be signed with non-SHA-1 hash
algorithm. [[Feature #11552]](https://bugs.ruby-lang.org/issues/11552)
- OpenSSL::OCSP::CertificateId and BasicResponse can be encoded into DER.
- A new class OpenSSL::OCSP::SingleResponse is added for convenience.
- OpenSSL::OCSP::BasicResponse#add_status accepts absolute times. They used to
accept only relative seconds from the current time.
* OpenSSL::PKey
- OpenSSL::PKey::EC follows the general PKey interface.
[[Bug #6567]](https://bugs.ruby-lang.org/issues/6567)
- OpenSSL::PKey.read raises OpenSSL::PKey::PKeyError instead of ArgumentError
for consistency with OpenSSL::PKey::{DH,DSA,RSA,EC}#new.
[[Bug #11774]](https://bugs.ruby-lang.org/issues/11774),
[[GH ruby/openssl#55]](https://github.com/ruby/openssl/pull/55)
- OpenSSL::PKey::EC::Group retrieved by OpenSSL::PKey::EC#group is no longer
linked with the EC key. Modifications to the EC::Group have no effect on the
key. [[GH ruby/openssl#71]](https://github.com/ruby/openssl/pull/71)
- OpenSSL::PKey::EC::Point#to_bn allows specifying the point conversion form
by the optional argument.
* OpenSSL::SSL
- OpenSSL::SSL::SSLSocket#tmp_key is added. A client can call it after the
connection is established to retrieve the ephemeral key.
[[GH ruby/ruby#1318]](https://github.com/ruby/ruby/pull/1318)
- The automatic ephemeral ECDH curve selection is enabled by default when
built with OpenSSL >= 1.0.2 or LibreSSL.
- OpenSSL::SSL::SSLContext#security_level= is added. You can set the "security
level" of the SSL context. This is effective only when built with OpenSSL
1.1.0.
- A new option 'verify_hostname' is added to OpenSSL::SSL::SSLContext. When it
is enabled, and the SNI hostname is also set, the hostname verification on
the server certificate is automatically performed. It is now enabled by
OpenSSL::SSL::Context#set_params.
[[GH ruby/openssl#60]](https://github.com/ruby/openssl/pull/60)
Removals
--------
* OpenSSL::Engine
- OpenSSL::Engine.cleanup does nothing when built with OpenSSL 1.1.0.
* OpenSSL::SSL
- OpenSSL::PKey::DH::DEFAULT_512 is removed. Hence servers no longer use
512-bit DH group by default. It is considered too weak nowadays.
[[Bug #11968]](https://bugs.ruby-lang.org/issues/11968),
[[GH ruby/ruby#1196]](https://github.com/ruby/ruby/pull/1196)
- RC4 cipher suites are removed from OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.
RC4 is now considered to be weak.
[[GH ruby/openssl#50]](https://github.com/ruby/openssl/pull/50)
Deprecations
------------
* OpenSSL::PKey
- OpenSSL::PKey::RSA#n=, #e=, #d=, #p=, #q=, #dmp1=, #dmq1=, #iqmp=,
OpenSSL::PKey::DSA#p=, #q=, #g=, #priv_key=, #pub_key=,
OpenSSL::PKey::DH#p=, #g=, #priv_key= and #pub_key= are deprecated. They are
disabled when built with OpenSSL 1.1.0, due to its API change. Instead,
OpenSSL::PKey::RSA#set_key, #set_factors, #set_crt_params,
OpenSSL::PKey::DSA#set_pqg, #set_key, OpenSSL::PKey::DH#set_pqg and #set_key
are added.
* OpenSSL::Random
- OpenSSL::Random.pseudo_bytes is deprecated, and not defined when built with
OpenSSL 1.1.0. Use OpenSSL::Random.random_bytes instead.
* OpenSSL::SSL
- OpenSSL::SSL::SSLContext#tmp_ecdh_callback is deprecated, as the underlying
API SSL_CTX_set_tmp_ecdh_callback() is removed in OpenSSL 1.1.0. It was
first added in Ruby 2.3.0. To specify the curve to be used in ephemeral
ECDH, use OpenSSL::SSL::SSLContext#ecdh_curves=. The automatic curve
selection is also now enabled by default when built with a capable OpenSSL.

Просмотреть файл

@ -33,14 +33,8 @@ end
Logging::message "=== Checking for system dependent stuff... ===\n"
have_library("nsl", "t_open")
have_library("socket", "socket")
have_header("assert.h")
Logging::message "=== Checking for required stuff... ===\n"
if $mingw
have_library("wsock32")
have_library("gdi32")
end
result = pkg_config("openssl") && have_header("openssl/ssl.h")
unless result
result = have_header("openssl/ssl.h")

Просмотреть файл

@ -163,6 +163,10 @@ module OpenSSL::Buffering
# 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
#
# By specifying `exception: false`, the options hash allows you to indicate
# that read_nonblock should not raise an IO::Wait*able exception, but
# return the symbol :wait_writable or :wait_readable instead.
def read_nonblock(maxlen, buf=nil, exception: true)
if maxlen == 0
@ -371,6 +375,10 @@ module OpenSSL::Buffering
# 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
#
# By specifying `exception: false`, the options hash allows you to indicate
# that write_nonblock should not raise an IO::Wait*able exception, but
# return the symbol :wait_writable or :wait_readable instead.
def write_nonblock(s, exception: true)
flush

Просмотреть файл

@ -16,8 +16,7 @@ require "io/nonblock"
module OpenSSL
module SSL
class SSLContext
# :nodoc:
DEFAULT_PARAMS = {
DEFAULT_PARAMS = { # :nodoc:
:ssl_version => "SSLv23",
:verify_mode => OpenSSL::SSL::VERIFY_PEER,
:verify_hostname => true,
@ -68,8 +67,7 @@ module OpenSSL
)
end
# :nodoc:
DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
DEFAULT_CERT_STORE = OpenSSL::X509::Store.new # :nodoc:
DEFAULT_CERT_STORE.set_default_paths
DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
@ -84,14 +82,12 @@ module OpenSSL
attr_accessor :tmp_dh_callback
if ExtConfig::HAVE_TLSEXT_HOST_NAME
# A callback invoked at connect time to distinguish between multiple
# server names.
#
# The callback is invoked with an SSLSocket and a server name. The
# callback must return an SSLContext for the server name or nil.
attr_accessor :servername_cb
end
# A callback invoked at connect time to distinguish between multiple
# server names.
#
# The callback is invoked with an SSLSocket and a server name. The
# callback must return an SSLContext for the server name or nil.
attr_accessor :servername_cb if ExtConfig::HAVE_TLSEXT_HOST_NAME
# call-seq:
# SSLContext.new => ctx

Просмотреть файл

@ -1,15 +1,15 @@
# -*- encoding: utf-8 -*-
# stub: openssl 2.0.0.beta.2 ruby lib
# stub: openssl 2.0.0 ruby lib
# stub: ext/openssl/extconf.rb
Gem::Specification.new do |s|
s.name = "openssl".freeze
s.version = "2.0.0.beta.2"
s.version = "2.0.0"
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1".freeze) if s.respond_to? :required_rubygems_version=
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
s.authors = ["Martin Bosslet".freeze, "SHIBATA Hiroshi".freeze, "Zachary Scott".freeze, "Kazuki Yamaguchi".freeze]
s.date = "2016-09-08"
s.date = "2016-11-30"
s.description = "It wraps the OpenSSL library.".freeze
s.email = ["ruby-core@ruby-lang.org".freeze]
s.extensions = ["ext/openssl/extconf.rb".freeze]
@ -19,27 +19,27 @@ Gem::Specification.new do |s|
s.licenses = ["Ruby".freeze]
s.rdoc_options = ["--main".freeze, "README.md".freeze]
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0".freeze)
s.rubygems_version = "2.6.6".freeze
s.rubygems_version = "2.6.8".freeze
s.summary = "OpenSSL provides SSL, TLS and general purpose cryptography.".freeze
if s.respond_to? :specification_version then
s.specification_version = 4
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_development_dependency(%q<rake>.freeze, ["~> 10.3"])
s.add_development_dependency(%q<rake-compiler>.freeze, ["~> 0.9"])
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
s.add_development_dependency(%q<rake-compiler>.freeze, [">= 0"])
s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.0"])
s.add_development_dependency(%q<rdoc>.freeze, ["~> 4.2"])
s.add_development_dependency(%q<rdoc>.freeze, [">= 0"])
else
s.add_dependency(%q<rake>.freeze, ["~> 10.3"])
s.add_dependency(%q<rake-compiler>.freeze, ["~> 0.9"])
s.add_dependency(%q<rake>.freeze, [">= 0"])
s.add_dependency(%q<rake-compiler>.freeze, [">= 0"])
s.add_dependency(%q<test-unit>.freeze, ["~> 3.0"])
s.add_dependency(%q<rdoc>.freeze, ["~> 4.2"])
s.add_dependency(%q<rdoc>.freeze, [">= 0"])
end
else
s.add_dependency(%q<rake>.freeze, ["~> 10.3"])
s.add_dependency(%q<rake-compiler>.freeze, ["~> 0.9"])
s.add_dependency(%q<rake>.freeze, [">= 0"])
s.add_dependency(%q<rake-compiler>.freeze, [">= 0"])
s.add_dependency(%q<test-unit>.freeze, ["~> 3.0"])
s.add_dependency(%q<rdoc>.freeze, ["~> 4.2"])
s.add_dependency(%q<rdoc>.freeze, [">= 0"])
end
end

Просмотреть файл

@ -149,7 +149,7 @@ ossl_pem_passwd_value(VALUE pass)
/* PEM_BUFSIZE is currently used as the second argument of pem_password_cb,
* that is +max_len+ of ossl_pem_passwd_cb() */
if (RSTRING_LEN(pass) > PEM_BUFSIZE)
ossl_raise(eOSSLError, "password must be shorter than %d bytes", PEM_BUFSIZE);
ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE);
return pass;
}
@ -168,7 +168,8 @@ ossl_pem_passwd_cb0(VALUE flag)
int
ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
{
int len, status;
long len;
int status;
VALUE rflag, pass = (VALUE)pwd_;
if (RTEST(pass)) {
@ -176,7 +177,7 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
* work because it does not allow NUL characters and truncates to 1024
* bytes silently if the input is over 1024 bytes */
if (RB_TYPE_P(pass, T_STRING)) {
len = RSTRING_LENINT(pass);
len = RSTRING_LEN(pass);
if (len >= OSSL_MIN_PWD_LEN && len <= max_len) {
memcpy(buf, RSTRING_PTR(pass), len);
return len;
@ -203,78 +204,19 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
rb_set_errinfo(Qnil);
return -1;
}
len = RSTRING_LENINT(pass);
len = RSTRING_LEN(pass);
if (len < OSSL_MIN_PWD_LEN) {
rb_warning("password must be at least %d bytes", OSSL_MIN_PWD_LEN);
continue;
}
if (len > max_len) {
rb_warning("password must be shorter than %d bytes", max_len);
rb_warning("password must not be longer than %d bytes", max_len);
continue;
}
memcpy(buf, RSTRING_PTR(pass), len);
break;
}
return len;
}
/*
* Verify callback
*/
int ossl_store_ctx_ex_verify_cb_idx;
int ossl_store_ex_verify_cb_idx;
struct ossl_verify_cb_args {
VALUE proc;
VALUE preverify_ok;
VALUE store_ctx;
};
static 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_call(VALUE proc, int ok, X509_STORE_CTX *ctx)
{
VALUE rctx, ret;
struct ossl_verify_cb_args args;
int state;
if (NIL_P(proc))
return ok;
ret = Qfalse;
rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, (VALUE)ctx, &state);
if (state) {
rb_set_errinfo(Qnil);
rb_warn("StoreContext initialization failure");
}
else {
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);
if (state) {
rb_set_errinfo(Qnil);
rb_warn("exception in verify_callback is ignored");
}
ossl_x509stctx_clear_ptr(rctx);
}
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;
return (int)len;
}
/*
@ -355,27 +297,32 @@ ossl_raise(VALUE exc, const char *fmt, ...)
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;
}
void
ossl_clear_error(void)
{
if (dOSSL == Qtrue) {
long e;
while ((e = ERR_get_error())) {
rb_warn("error on stack: %s", ERR_error_string(e, NULL));
unsigned long e;
const char *file, *data, *errstr;
int line, flags;
while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
errstr = ERR_error_string(e, NULL);
if (!errstr)
errstr = "(null)";
if (flags & ERR_TXT_STRING) {
if (!data)
data = "(null)";
rb_warn("error on stack: %s (%s)", errstr, data);
}
else {
rb_warn("error on stack: %s", errstr);
}
}
}
ERR_clear_error();
else {
ERR_clear_error();
}
}
/*
@ -1151,14 +1098,6 @@ Init_openssl(void)
rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);
/*
* Verify callback Proc index for ext-data
*/
if ((ossl_store_ctx_ex_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_store_ctx_ex_verify_cb_idx", 0, 0, 0)) < 0)
ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
if ((ossl_store_ex_verify_cb_idx = X509_STORE_get_ex_new_index(0, (void *)"ossl_store_ex_verify_cb_idx", 0, 0, 0)) < 0)
ossl_raise(eOSSLError, "X509_STORE_get_ex_new_index");
/*
* Get ID of to_der
*/

Просмотреть файл

@ -12,37 +12,12 @@
#include RUBY_EXTCONF_H
#if 0
mOSSL = rb_define_module("OpenSSL");
mX509 = rb_define_module_under(mOSSL, "X509");
#endif
/*
* OpenSSL has defined RFILE and Ruby has defined RFILE - so undef it!
*/
#if defined(RFILE) /*&& !defined(OSSL_DEBUG)*/
# undef RFILE
#endif
#include <assert.h>
#include <errno.h>
#include <ruby.h>
#include <ruby/io.h>
#include <ruby/thread.h>
#include <openssl/opensslv.h>
#ifdef HAVE_ASSERT_H
# include <assert.h>
#else
# define assert(condition)
#endif
#if defined(_WIN32) && !defined(LIBRESSL_VERSION_NUMBER)
# include <openssl/e_os2.h>
# if !defined(OPENSSL_SYS_WIN32)
# define OPENSSL_SYS_WIN32 1
# endif
# include <winsock2.h>
#endif
#include <errno.h>
#include <openssl/err.h>
#include <openssl/asn1.h>
#include <openssl/x509v3.h>
@ -53,9 +28,7 @@
#include <openssl/rand.h>
#include <openssl/conf.h>
#include <openssl/conf_api.h>
#if !defined(_WIN32)
# include <openssl/crypto.h>
#endif
#include <openssl/crypto.h>
#if !defined(OPENSSL_NO_ENGINE)
# include <openssl/engine.h>
#endif
@ -144,18 +117,9 @@ int ossl_pem_passwd_cb(char *, int, int, void *);
*/
#define OSSL_ErrMsg() ERR_reason_error_string(ERR_get_error())
NORETURN(void ossl_raise(VALUE, const char *, ...));
VALUE ossl_exc_new(VALUE, const char *, ...);
/* Clear OpenSSL error queue. If dOSSL is set, rb_warn() them. */
void ossl_clear_error(void);
/*
* Verify callback
*/
extern int ossl_store_ctx_ex_verify_cb_idx;
extern int ossl_store_ex_verify_cb_idx;
int ossl_verify_cb_call(VALUE, int, X509_STORE_CTX *);
/*
* String to DER String
*/

Просмотреть файл

@ -9,15 +9,6 @@
*/
#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);
@ -110,16 +101,11 @@ asn1str_to_str(const ASN1_STRING *str)
/*
* 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(const ASN1_INTEGER *ai)
{
BIGNUM *bn;
#if DO_IT_VIA_RUBY
char *txt;
#endif
VALUE num;
if (!ai) {
@ -133,43 +119,12 @@ asn1integer_to_num(const ASN1_INTEGER *ai)
if (!bn)
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, StringValueCStr(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)
{
@ -185,7 +140,6 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
return ai;
}
#endif
/********/
/*
@ -225,9 +179,10 @@ VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */
VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */
VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
static ID sIMPLICIT, sEXPLICIT;
static ID sUNIVERSAL, sAPPLICATION, sCONTEXT_SPECIFIC, sPRIVATE;
static VALUE sym_IMPLICIT, sym_EXPLICIT;
static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINFINITE_LENGTH, sivUNUSED_BITS;
static ID id_each;
/*
* Ruby to ASN1 converters
@ -364,13 +319,12 @@ decode_bool(unsigned char* der, long length)
{
const unsigned char *p = der;
assert(length == 3);
if (*p++ != 1)
ossl_raise(eASN1Error, "not a boolean");
if (*p++ != 1)
ossl_raise(eASN1Error, "length is not 1");
if (length != 3)
ossl_raise(eASN1Error, "invalid length for BOOLEAN");
if (p[0] != 1 || p[1] != 1)
ossl_raise(eASN1Error, "invalid BOOLEAN");
return *p ? Qtrue : Qfalse;
return p[2] ? Qtrue : Qfalse;
}
static VALUE
@ -632,17 +586,14 @@ ossl_asn1_default_tag(VALUE obj)
VALUE tmp_class, tag;
tmp_class = CLASS_OF(obj);
while (tmp_class) {
while (!NIL_P(tmp_class)) {
tag = rb_hash_lookup(class_tag_map, tmp_class);
if (tag != Qnil) {
return NUM2INT(tag);
}
tmp_class = rb_class_superclass(tmp_class);
if (tag != Qnil)
return NUM2INT(tag);
tmp_class = rb_class_superclass(tmp_class);
}
ossl_raise(eASN1Error, "universal tag for %"PRIsVALUE" not found",
rb_obj_class(obj));
return -1; /* dummy */
}
static int
@ -661,59 +612,45 @@ 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){
if (NIL_P(s) || s == sym_IMPLICIT)
return 0;
else if (s == sym_EXPLICIT)
return 1;
else
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){
if (NIL_P(s) || s == sym_UNIVERSAL)
return V_ASN1_UNIVERSAL;
else if (s == sym_APPLICATION)
return V_ASN1_APPLICATION;
else if (s == sym_CONTEXT_SPECIFIC)
return V_ASN1_CONTEXT_SPECIFIC;
else if (s == sym_PRIVATE)
return V_ASN1_PRIVATE;
else
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);
return sym_PRIVATE;
else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
return ID2SYM(sCONTEXT_SPECIFIC);
return sym_CONTEXT_SPECIFIC;
else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
return ID2SYM(sAPPLICATION);
return sym_APPLICATION;
else
return ID2SYM(sUNIVERSAL);
return sym_UNIVERSAL;
}
/*
@ -737,7 +674,7 @@ 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)
if (tag_class == sym_UNIVERSAL && NUM2INT(tag) > 31)
ossl_raise(eASN1Error, "tag number for Universal too large");
ossl_asn1_set_tag(self, tag);
ossl_asn1_set_value(self, value);
@ -760,7 +697,7 @@ 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);
rb_block_call(enumerable, id_each, 0, 0, join_der_i, str);
return str;
}
@ -816,7 +753,7 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
p = *pp;
if(tc == sUNIVERSAL && tag < ossl_asn1_info_size) {
if(tc == sym_UNIVERSAL && tag < ossl_asn1_info_size) {
switch(tag){
case V_ASN1_EOC:
value = decode_eoc(p, hlen+length);
@ -858,13 +795,14 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
*pp += hlen + length;
*num_read = hlen + length;
if (tc == sUNIVERSAL && tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
if (tc == sym_UNIVERSAL &&
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);
args[3] = tc;
asn1data = rb_obj_alloc(klass);
ossl_asn1_initialize(4, args, asn1data);
if(tag == V_ASN1_BIT_STRING){
@ -873,7 +811,7 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
}
else {
asn1data = rb_obj_alloc(cASN1Data);
ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), ID2SYM(tc));
ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), tc);
}
return asn1data;
@ -886,28 +824,27 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
{
VALUE value, asn1data, ary;
int infinite;
long off = *offset;
long available_len, off = *offset;
infinite = (j == 0x21);
ary = rb_ary_new();
while (length > 0 || infinite) {
available_len = infinite ? max_len : length;
while (available_len > 0) {
long inner_read = 0;
value = ossl_asn1_decode0(pp, max_len, &off, depth + 1, yield, &inner_read);
value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read);
*num_read += inner_read;
max_len -= inner_read;
available_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) {
ossl_asn1_get_tag_class(value) == sym_UNIVERSAL) {
break;
}
}
if (tc == sUNIVERSAL) {
if (tc == sym_UNIVERSAL) {
VALUE args[4];
int not_sequence_or_set;
@ -929,12 +866,12 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
args[0] = ary;
args[1] = INT2NUM(tag);
args[2] = Qnil;
args[3] = ID2SYM(tc);
args[3] = tc;
ossl_asn1_initialize(4, args, asn1data);
}
else {
asn1data = rb_obj_alloc(cASN1Data);
ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), ID2SYM(tc));
ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc);
}
if (infinite)
@ -964,13 +901,13 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
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;
tag_class = sym_PRIVATE;
else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
tag_class = sCONTEXT_SPECIFIC;
tag_class = sym_CONTEXT_SPECIFIC;
else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
tag_class = sAPPLICATION;
tag_class = sym_APPLICATION;
else
tag_class = sUNIVERSAL;
tag_class = sym_UNIVERSAL;
hlen = p - start;
@ -989,7 +926,7 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
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);
asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read);
inner_read += hlen;
}
else {
@ -1162,19 +1099,19 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
ossl_raise(eASN1Error, "invalid tagging method");
if(NIL_P(tag_class)) {
if (NIL_P(tagging))
tag_class = ID2SYM(sUNIVERSAL);
tag_class = sym_UNIVERSAL;
else
tag_class = ID2SYM(sCONTEXT_SPECIFIC);
tag_class = sym_CONTEXT_SPECIFIC;
}
if(!SYMBOL_P(tag_class))
ossl_raise(eASN1Error, "invalid tag class");
if(!NIL_P(tagging) && SYM2ID(tagging) == sIMPLICIT && NUM2INT(tag) > 31)
if (tagging == sym_IMPLICIT && 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);
tag_class = sym_UNIVERSAL;
}
ossl_asn1_set_tag(self, tag);
ossl_asn1_set_value(self, value);
@ -1190,7 +1127,7 @@ ossl_asn1eoc_initialize(VALUE self) {
VALUE tag, tagging, tag_class, value;
tag = INT2NUM(ossl_asn1_default_tag(self));
tagging = Qnil;
tag_class = ID2SYM(sUNIVERSAL);
tag_class = sym_UNIVERSAL;
value = rb_str_new("", 0);
ossl_asn1_set_tag(self, tag);
ossl_asn1_set_value(self, value);
@ -1264,8 +1201,8 @@ ossl_asn1cons_to_der(VALUE self)
if (inf_length == Qtrue) {
VALUE ary, example;
constructed = 2;
if (CLASS_OF(self) == cASN1Sequence ||
CLASS_OF(self) == cASN1Set) {
if (rb_obj_class(self) == cASN1Sequence ||
rb_obj_class(self) == cASN1Set) {
tag = ossl_asn1_default_tag(self);
}
else { /* must be a constructive encoding of a primitive value */
@ -1294,7 +1231,7 @@ ossl_asn1cons_to_der(VALUE self)
}
}
else {
if (CLASS_OF(self) == cASN1Constructive)
if (rb_obj_class(self) == cASN1Constructive)
ossl_raise(eASN1Error, "Constructive shall only be used with infinite length");
tag = ossl_asn1_default_tag(self);
}
@ -1348,7 +1285,8 @@ ossl_asn1cons_to_der(VALUE self)
static VALUE
ossl_asn1cons_each(VALUE self)
{
rb_ary_each(ossl_asn1_get_value(self));
rb_funcall(ossl_asn1_get_value(self), id_each, 0);
return self;
}
@ -1476,12 +1414,12 @@ Init_ossl_asn1(void)
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
#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");
sym_UNIVERSAL = ID2SYM(rb_intern_const("UNIVERSAL"));
sym_CONTEXT_SPECIFIC = ID2SYM(rb_intern_const("CONTEXT_SPECIFIC"));
sym_APPLICATION = ID2SYM(rb_intern_const("APPLICATION"));
sym_PRIVATE = ID2SYM(rb_intern_const("PRIVATE"));
sym_EXPLICIT = ID2SYM(rb_intern_const("EXPLICIT"));
sym_IMPLICIT = ID2SYM(rb_intern_const("IMPLICIT"));
sivVALUE = rb_intern("@value");
sivTAG = rb_intern("@tag");
@ -1989,4 +1927,6 @@ do{\
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);
id_each = rb_intern_const("each");
}

Просмотреть файл

@ -8,9 +8,6 @@
* (See the file 'LICENCE'.)
*/
#include "ossl.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
BIO *
ossl_obj2bio(VALUE obj)

Просмотреть файл

@ -380,7 +380,7 @@ BIGNUM_BOOL1(is_odd)
BIGNUM *bn, *result; \
VALUE obj; \
GetBN(self, bn); \
obj = NewBN(CLASS_OF(self)); \
obj = NewBN(rb_obj_class(self)); \
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
@ -406,7 +406,7 @@ BIGNUM_1c(sqr)
BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
VALUE obj; \
GetBN(self, bn1); \
obj = NewBN(CLASS_OF(self)); \
obj = NewBN(rb_obj_class(self)); \
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
@ -439,7 +439,7 @@ BIGNUM_2(sub)
BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
VALUE obj; \
GetBN(self, bn1); \
obj = NewBN(CLASS_OF(self)); \
obj = NewBN(rb_obj_class(self)); \
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
@ -504,12 +504,13 @@ static VALUE
ossl_bn_div(VALUE self, VALUE other)
{
BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
VALUE obj1, obj2;
VALUE klass, obj1, obj2;
GetBN(self, bn1);
obj1 = NewBN(CLASS_OF(self));
obj2 = NewBN(CLASS_OF(self));
klass = rb_obj_class(self);
obj1 = NewBN(klass);
obj2 = NewBN(klass);
if (!(r1 = BN_new())) {
ossl_raise(eBNError, NULL);
}
@ -536,7 +537,7 @@ ossl_bn_div(VALUE self, VALUE other)
BIGNUM *bn3 = GetBNPtr(other2), *result; \
VALUE obj; \
GetBN(self, bn1); \
obj = NewBN(CLASS_OF(self)); \
obj = NewBN(rb_obj_class(self)); \
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \
@ -639,7 +640,7 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit)
VALUE obj; \
b = NUM2INT(bits); \
GetBN(self, bn); \
obj = NewBN(CLASS_OF(self)); \
obj = NewBN(rb_obj_class(self)); \
if (!(result = BN_new())) { \
ossl_raise(eBNError, NULL); \
} \

Просмотреть файл

@ -36,7 +36,7 @@
*/
VALUE cCipher;
VALUE eCipherError;
static ID id_auth_tag_len;
static ID id_auth_tag_len, id_key_set;
static VALUE ossl_cipher_alloc(VALUE klass);
static void ossl_cipher_free(void *ptr);
@ -118,7 +118,6 @@ ossl_cipher_initialize(VALUE self, VALUE str)
EVP_CIPHER_CTX *ctx;
const EVP_CIPHER *cipher;
char *name;
unsigned char dummy_key[EVP_MAX_KEY_LENGTH] = { 0 };
name = StringValueCStr(str);
GetCipherInit(self, ctx);
@ -129,16 +128,7 @@ ossl_cipher_initialize(VALUE self, VALUE str)
if (!(cipher = EVP_get_cipherbyname(name))) {
ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%"PRIsVALUE")", str);
}
/*
* EVP_CipherInit_ex() allows to specify NULL to key and IV, however some
* ciphers don't handle well (OpenSSL's bug). [Bug #2768]
*
* 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.
*/
if (EVP_CipherInit_ex(ctx, cipher, NULL, dummy_key, NULL, -1) != 1)
if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
ossl_raise(eCipherError, NULL);
return self;
@ -251,6 +241,9 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
ossl_raise(eCipherError, NULL);
}
if (p_key)
rb_ivar_set(self, id_key_set, Qtrue);
return self;
}
@ -337,6 +330,8 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
OPENSSL_cleanse(key, sizeof key);
OPENSSL_cleanse(iv, sizeof iv);
rb_ivar_set(self, id_key_set, Qtrue);
return Qnil;
}
@ -387,6 +382,9 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
rb_scan_args(argc, argv, "11", &data, &str);
if (!RTEST(rb_attr_get(self, id_key_set)))
ossl_raise(eCipherError, "key not set");
StringValue(data);
in = (unsigned char *)RSTRING_PTR(data);
if ((in_len = RSTRING_LEN(data)) == 0)
@ -488,6 +486,8 @@ ossl_cipher_set_key(VALUE self, VALUE key)
if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1)
ossl_raise(eCipherError, NULL);
rb_ivar_set(self, id_key_set, Qtrue);
return key;
}
@ -502,9 +502,6 @@ ossl_cipher_set_key(VALUE self, VALUE key)
* 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)
@ -530,6 +527,27 @@ ossl_cipher_set_iv(VALUE self, VALUE iv)
return iv;
}
/*
* call-seq:
* cipher.authenticated? -> true | false
*
* Indicated whether this Cipher instance uses an Authenticated Encryption
* mode.
*/
static VALUE
ossl_cipher_is_authenticated(VALUE self)
{
EVP_CIPHER_CTX *ctx;
GetCipher(self, ctx);
#if defined(HAVE_AUTHENTICATED_ENCRYPTION)
return (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
#else
return Qfalse;
#endif
}
#ifdef HAVE_AUTHENTICATED_ENCRYPTION
/*
* call-seq:
@ -675,23 +693,6 @@ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen)
return vlen;
}
/*
* call-seq:
* cipher.authenticated? -> boolean
*
* Indicated whether this Cipher instance uses an Authenticated Encryption
* mode.
*/
static VALUE
ossl_cipher_is_authenticated(VALUE self)
{
EVP_CIPHER_CTX *ctx;
GetCipher(self, ctx);
return (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
}
/*
* call-seq:
* cipher.iv_len = integer -> integer
@ -726,7 +727,6 @@ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length)
#define ossl_cipher_get_auth_tag rb_f_notimplement
#define ossl_cipher_set_auth_tag rb_f_notimplement
#define ossl_cipher_set_auth_tag_len rb_f_notimplement
#define ossl_cipher_is_authenticated rb_f_notimplement
#define ossl_cipher_set_iv_length rb_f_notimplement
#endif
@ -939,12 +939,10 @@ Init_ossl_cipher(void)
* 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
* an IV in any case. 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>
@ -1082,4 +1080,5 @@ Init_ossl_cipher(void)
rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
id_auth_tag_len = rb_intern_const("auth_tag_len");
id_key_set = rb_intern_const("key_set");
}

Просмотреть файл

@ -80,10 +80,13 @@ ossl_digest_new(const EVP_MD *md)
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.");
}
ctx = EVP_MD_CTX_new();
if (!ctx)
ossl_raise(eDigestError, "EVP_MD_CTX_new");
RTYPEDDATA_DATA(ret) = ctx;
if (!EVP_DigestInit_ex(ctx, md, NULL))
ossl_raise(eDigestError, "Digest initialization failed");
return ret;
}
@ -94,13 +97,7 @@ ossl_digest_new(const EVP_MD *md)
static VALUE
ossl_digest_alloc(VALUE klass)
{
VALUE obj = TypedData_Wrap_Struct(klass, &ossl_digest_type, 0);
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
if (ctx == NULL)
ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_create() failed");
RTYPEDDATA_DATA(obj) = ctx;
return obj;
return TypedData_Wrap_Struct(klass, &ossl_digest_type, 0);
}
VALUE ossl_digest_update(VALUE, VALUE);
@ -133,11 +130,16 @@ ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
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.");
TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx);
if (!ctx) {
RTYPEDDATA_DATA(self) = ctx = EVP_MD_CTX_new();
if (!ctx)
ossl_raise(eDigestError, "EVP_MD_CTX_new");
}
if (!EVP_DigestInit_ex(ctx, md, NULL))
ossl_raise(eDigestError, "Digest initialization failed");
if (!NIL_P(data)) return ossl_digest_update(self, data);
return self;
}
@ -150,7 +152,12 @@ ossl_digest_copy(VALUE self, VALUE other)
rb_check_frozen(self);
if (self == other) return self;
GetDigest(self, ctx1);
TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx1);
if (!ctx1) {
RTYPEDDATA_DATA(self) = ctx1 = EVP_MD_CTX_new();
if (!ctx1)
ossl_raise(eDigestError, "EVP_MD_CTX_new");
}
SafeGetDigest(other, ctx2);
if (!EVP_MD_CTX_copy(ctx1, ctx2)) {

Просмотреть файл

@ -227,21 +227,6 @@ ossl_engine_s_by_id(VALUE klass, VALUE id)
return obj;
}
static VALUE
ossl_engine_s_alloc(VALUE klass)
{
ENGINE *e;
VALUE obj;
obj = NewEngine(klass);
if (!(e = ENGINE_new())) {
ossl_raise(eEngineError, NULL);
}
SetEngine(obj, e);
return obj;
}
/* Document-method: OpenSSL::Engine#id
*
* Get the id for this engine
@ -537,13 +522,11 @@ Init_ossl_engine(void)
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_undef_alloc_func(cEngine);
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_undef_method(cEngine, "initialize_copy");
rb_define_method(cEngine, "id", ossl_engine_get_id, 0);
rb_define_method(cEngine, "name", ossl_engine_get_name, 0);

Просмотреть файл

@ -159,8 +159,6 @@ 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()))) {
@ -170,11 +168,8 @@ ossl_spki_print(VALUE self)
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;
return ossl_membio2str(out);
}
/*

Просмотреть файл

@ -795,7 +795,7 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
BIO_free(in);
sk_X509_pop_free(x509s, X509_free);
if (ok < 0) ossl_raise(ePKCS7Error, "PKCS7_verify");
msg = ERR_reason_error_string(ERR_get_error());
msg = ERR_reason_error_string(ERR_peek_error());
ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil);
ossl_clear_error();
data = ossl_membio2str(out);

Просмотреть файл

@ -70,12 +70,12 @@ const rb_data_type_t ossl_evp_pkey_type = {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
VALUE
ossl_pkey_new(EVP_PKEY *pkey)
static VALUE
pkey_new0(EVP_PKEY *pkey)
{
if (!pkey) {
ossl_raise(ePKeyError, "Cannot make new key from NULL.");
}
if (!pkey)
ossl_raise(ePKeyError, "cannot make new key from NULL");
switch (EVP_PKEY_base_id(pkey)) {
#if !defined(OPENSSL_NO_RSA)
case EVP_PKEY_RSA:
@ -96,29 +96,21 @@ ossl_pkey_new(EVP_PKEY *pkey)
default:
ossl_raise(ePKeyError, "unsupported key type");
}
UNREACHABLE;
}
VALUE
ossl_pkey_new_from_file(VALUE filename)
ossl_pkey_new(EVP_PKEY *pkey)
{
FILE *fp;
EVP_PKEY *pkey;
VALUE obj;
int status;
rb_check_safe_obj(filename);
if (!(fp = fopen(StringValueCStr(filename), "r"))) {
ossl_raise(ePKeyError, "%s", strerror(errno));
}
rb_fd_fix_cloexec(fileno(fp));
pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL);
fclose(fp);
if (!pkey) {
ossl_raise(ePKeyError, NULL);
obj = rb_protect((VALUE (*)(VALUE))pkey_new0, (VALUE)pkey, &status);
if (status) {
EVP_PKEY_free(pkey);
rb_jump_tag(status);
}
return ossl_pkey_new(pkey);
return obj;
}
/*
@ -166,6 +158,45 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
return ossl_pkey_new(pkey);
}
static void
pkey_check_public_key(EVP_PKEY *pkey)
{
void *ptr;
const BIGNUM *n, *e, *pubkey;
if (EVP_PKEY_missing_parameters(pkey))
ossl_raise(ePKeyError, "parameters missing");
ptr = EVP_PKEY_get0(pkey);
switch (EVP_PKEY_base_id(pkey)) {
case EVP_PKEY_RSA:
RSA_get0_key(ptr, &n, &e, NULL);
if (n && e)
return;
break;
case EVP_PKEY_DSA:
DSA_get0_key(ptr, &pubkey, NULL);
if (pubkey)
return;
break;
case EVP_PKEY_DH:
DH_get0_key(ptr, &pubkey, NULL);
if (pubkey)
return;
break;
#if !defined(OPENSSL_NO_EC)
case EVP_PKEY_EC:
if (EC_KEY_get0_public_key(ptr))
return;
break;
#endif
default:
/* unsupported type; assuming ok */
return;
}
ossl_raise(ePKeyError, "public key missing");
}
EVP_PKEY *
GetPKeyPtr(VALUE obj)
{
@ -264,18 +295,23 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
pkey = GetPrivPKeyPtr(self);
md = GetDigestPtr(digest);
StringValue(data);
str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
str = rb_str_new(0, EVP_PKEY_size(pkey));
ctx = EVP_MD_CTX_new();
if (!ctx)
ossl_raise(ePKeyError, "EVP_MD_CTX_new");
EVP_SignInit(ctx, md);
EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));
if (!EVP_SignInit_ex(ctx, md, NULL)) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_SignInit_ex");
}
if (!EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_SignUpdate");
}
result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
EVP_MD_CTX_free(ctx);
if (!result)
ossl_raise(ePKeyError, NULL);
assert((long)buf_len <= RSTRING_LEN(str));
ossl_raise(ePKeyError, "EVP_SignFinal");
rb_str_set_len(str, buf_len);
return str;
@ -308,19 +344,27 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
EVP_PKEY *pkey;
const EVP_MD *md;
EVP_MD_CTX *ctx;
int result;
int siglen, result;
GetPKey(self, pkey);
pkey_check_public_key(pkey);
md = GetDigestPtr(digest);
StringValue(sig);
siglen = RSTRING_LENINT(sig);
StringValue(data);
ctx = EVP_MD_CTX_new();
if (!ctx)
ossl_raise(ePKeyError, "EVP_MD_CTX_new");
EVP_VerifyInit(ctx, md);
EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));
result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey);
if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_VerifyInit_ex");
}
if (!EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_VerifyUpdate");
}
result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), siglen, pkey);
EVP_MD_CTX_free(ctx);
switch (result) {
case 0:
@ -329,9 +373,8 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
case 1:
return Qtrue;
default:
ossl_raise(ePKeyError, NULL);
ossl_raise(ePKeyError, "EVP_VerifyFinal");
}
return Qnil; /* dummy */
}
/*

Просмотреть файл

@ -48,7 +48,6 @@ int ossl_generate_cb_2(int p, int n, BN_GENCB *cb);
void ossl_generate_cb_stop(void *ptr);
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);

Просмотреть файл

@ -460,7 +460,7 @@ ossl_dh_to_public_key(VALUE self)
GetDH(self, orig_dh);
dh = DHparams_dup(orig_dh); /* err check perfomed by dh_instance */
obj = dh_instance(CLASS_OF(self), dh);
obj = dh_instance(rb_obj_class(self), dh);
if (obj == Qfalse) {
DH_free(dh);
ossl_raise(eDHError, NULL);

Просмотреть файл

@ -491,7 +491,7 @@ ossl_dsa_to_public_key(VALUE self)
(i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa))
dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey));
#undef DSAPublicKey_dup
obj = dsa_instance(CLASS_OF(self), dsa);
obj = dsa_instance(rb_obj_class(self), dsa);
if (obj == Qfalse) {
DSA_free(dsa);
ossl_raise(eDSAError, NULL);
@ -499,8 +499,6 @@ ossl_dsa_to_public_key(VALUE self)
return obj;
}
#define ossl_dsa_buf_size(dsa) (DSA_size(dsa) + 16)
/*
* call-seq:
* dsa.syssign(string) -> aString
@ -535,7 +533,7 @@ ossl_dsa_sign(VALUE self, VALUE data)
if (!DSA_PRIVATE(self, dsa))
ossl_raise(eDSAError, "Private DSA key needed!");
StringValue(data);
str = rb_str_new(0, ossl_dsa_buf_size(dsa));
str = rb_str_new(0, DSA_size(dsa));
if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
(unsigned char *)RSTRING_PTR(str),
&buf_len, dsa)) { /* type is ignored (0) */

Просмотреть файл

@ -643,11 +643,10 @@ static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE 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);
str = rb_str_new(0, ECDSA_size(ec));
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);
ossl_raise(eECError, "ECDSA_sign");
rb_str_set_len(str, buf_len);
return str;
}
@ -1106,6 +1105,22 @@ static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
return ID2SYM(ret);
}
static point_conversion_form_t
parse_point_conversion_form_symbol(VALUE sym)
{
ID id = SYM2ID(sym);
if (id == ID_uncompressed)
return POINT_CONVERSION_UNCOMPRESSED;
else if (id == ID_compressed)
return POINT_CONVERSION_COMPRESSED;
else if (id == ID_hybrid)
return POINT_CONVERSION_HYBRID;
else
ossl_raise(rb_eArgError, "unsupported point conversion form %+"PRIsVALUE
" (expected :compressed, :uncompressed, or :hybrid)", sym);
}
/*
* call-seq:
* group.point_conversion_form = form
@ -1125,23 +1140,14 @@ static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
*
* 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)
static VALUE
ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)
{
EC_GROUP *group = NULL;
EC_GROUP *group;
point_conversion_form_t form;
ID form_id = SYM2ID(form_v);
GetECGroup(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");
}
form = parse_point_conversion_form_symbol(form_v);
EC_GROUP_set_point_conversion_form(group, form);
@ -1549,22 +1555,30 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self)
/*
* call-seq:
* point.to_bn => OpenSSL::BN
* point.to_bn(conversion_form = nil) => OpenSSL::BN
*
* See the OpenSSL documentation for EC_POINT_point2bn()
* Convert the EC point into an octet string and store in an OpenSSL::BN. If
* +conversion_form+ is given, the point data is converted using the specified
* form. If not given, the default form set in the EC::Group object is used.
*
* See also EC::Point#point_conversion_form=.
*/
static VALUE ossl_ec_point_to_bn(VALUE self)
static VALUE
ossl_ec_point_to_bn(int argc, VALUE *argv, VALUE self)
{
EC_POINT *point;
VALUE bn_obj;
VALUE form_obj, bn_obj;
const EC_GROUP *group;
point_conversion_form_t form;
BIGNUM *bn;
GetECPoint(self, point);
GetECPointGroup(self, group);
form = EC_GROUP_get_point_conversion_form(group);
rb_scan_args(argc, argv, "01", &form_obj);
if (NIL_P(form_obj))
form = EC_GROUP_get_point_conversion_form(group);
else
form = parse_point_conversion_form_symbol(form_obj);
bn_obj = rb_obj_alloc(cBN);
bn = GetBNPtr(bn_obj);
@ -1793,7 +1807,7 @@ void Init_ossl_ec(void)
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);
rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn, -1);
rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
id_i_group = rb_intern("@group");

Просмотреть файл

@ -404,8 +404,6 @@ ossl_rsa_to_der(VALUE self)
return str;
}
#define ossl_rsa_buf_size(rsa) (RSA_size(rsa)+16)
/*
* call-seq:
* rsa.public_encrypt(string) => String
@ -429,7 +427,7 @@ ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
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(rsa));
str = rb_str_new(0, RSA_size(rsa));
buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
@ -461,7 +459,7 @@ ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
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(rsa));
str = rb_str_new(0, RSA_size(rsa));
buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
@ -495,7 +493,7 @@ ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
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(rsa));
str = rb_str_new(0, RSA_size(rsa));
buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
@ -529,7 +527,7 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
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(rsa));
str = rb_str_new(0, RSA_size(rsa));
buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
@ -620,7 +618,7 @@ ossl_rsa_to_public_key(VALUE self)
GetPKeyRSA(self, pkey);
/* err check performed by rsa_instance */
rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey));
obj = rsa_instance(CLASS_OF(self), rsa);
obj = rsa_instance(rb_obj_class(self), rsa);
if (obj == Qfalse) {
RSA_free(rsa);
ossl_raise(eRSAError, NULL);

Просмотреть файл

@ -11,10 +11,6 @@
*/
#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
@ -36,7 +32,7 @@ VALUE cSSLSocket;
static VALUE eSSLErrorWaitReadable;
static VALUE eSSLErrorWaitWritable;
static ID ID_callback_state;
static ID ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback;
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
@ -223,69 +219,90 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
return 1;
}
#if !defined(OPENSSL_NO_DH)
static VALUE
ossl_call_tmp_dh_callback(VALUE args)
#if !defined(OPENSSL_NO_DH) || \
!defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
struct tmp_dh_callback_args {
VALUE ssl_obj;
ID id;
int type;
int is_export;
int keylength;
};
static EVP_PKEY *
ossl_call_tmp_dh_callback(struct tmp_dh_callback_args *args)
{
VALUE cb, dh;
EVP_PKEY *pkey;
cb = rb_funcall(rb_ary_entry(args, 0), rb_intern("tmp_dh_callback"), 0);
if (NIL_P(cb)) return Qfalse;
dh = rb_apply(cb, rb_intern("call"), args);
cb = rb_funcall(args->ssl_obj, args->id, 0);
if (NIL_P(cb))
return NULL;
dh = rb_funcall(cb, rb_intern("call"), 3,
args->ssl_obj, INT2NUM(args->is_export), INT2NUM(args->keylength));
pkey = GetPKeyPtr(dh);
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) return Qfalse;
if (EVP_PKEY_base_id(pkey) != args->type)
return NULL;
return dh;
return pkey;
}
#endif
static DH*
#if !defined(OPENSSL_NO_DH)
static DH *
ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
{
VALUE args, dh, rb_ssl;
VALUE rb_ssl;
EVP_PKEY *pkey;
struct tmp_dh_callback_args args;
int state;
rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
args.ssl_obj = rb_ssl;
args.id = id_tmp_dh_callback;
args.is_export = is_export;
args.keylength = keylength;
args.type = EVP_PKEY_DH;
args = rb_ary_new_from_args(3, rb_ssl, INT2NUM(is_export), INT2NUM(keylength));
pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
(VALUE)&args, &state);
if (state) {
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
return NULL;
}
if (!pkey)
return NULL;
dh = rb_protect(ossl_call_tmp_dh_callback, args, NULL);
if (!RTEST(dh)) return NULL;
return EVP_PKEY_get0_DH(GetPKeyPtr(dh));
return EVP_PKEY_get0_DH(pkey);
}
#endif /* OPENSSL_NO_DH */
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
static VALUE
ossl_call_tmp_ecdh_callback(VALUE args)
{
VALUE cb, ecdh;
EVP_PKEY *pkey;
cb = rb_funcall(rb_ary_entry(args, 0), rb_intern("tmp_ecdh_callback"), 0);
if (NIL_P(cb)) return Qfalse;
ecdh = rb_apply(cb, rb_intern("call"), args);
pkey = GetPKeyPtr(ecdh);
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) return Qfalse;
return ecdh;
}
static EC_KEY*
static EC_KEY *
ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
{
VALUE args, ecdh, rb_ssl;
VALUE rb_ssl;
EVP_PKEY *pkey;
struct tmp_dh_callback_args args;
int state;
rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
args.ssl_obj = rb_ssl;
args.id = id_tmp_ecdh_callback;
args.is_export = is_export;
args.keylength = keylength;
args.type = EVP_PKEY_EC;
args = rb_ary_new_from_args(3, rb_ssl, INT2NUM(is_export), INT2NUM(keylength));
pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
(VALUE)&args, &state);
if (state) {
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
return NULL;
}
if (!pkey)
return NULL;
ecdh = rb_protect(ossl_call_tmp_ecdh_callback, args, NULL);
if (!RTEST(ecdh)) return NULL;
return EVP_PKEY_get0_EC_KEY(GetPKeyPtr(ecdh));
return EVP_PKEY_get0_EC_KEY(pkey);
}
#endif
@ -1376,24 +1393,6 @@ ssl_started(SSL *ssl)
return SSL_get_fd(ssl) >= 0;
}
static void
ossl_ssl_shutdown(SSL *ssl)
{
int i;
/* 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 (SSL_shutdown(ssl) != 0)
break;
}
ossl_clear_error();
}
static void
ossl_ssl_free(void *ssl)
{
@ -1496,19 +1495,15 @@ ossl_ssl_setup(VALUE self)
static void
write_would_block(int nonblock)
{
if (nonblock) {
VALUE exc = ossl_exc_new(eSSLErrorWaitWritable, "write would block");
rb_exc_raise(exc);
}
if (nonblock)
ossl_raise(eSSLErrorWaitWritable, "write would block");
}
static void
read_would_block(int nonblock)
{
if (nonblock) {
VALUE exc = ossl_exc_new(eSSLErrorWaitReadable, "read would block");
rb_exc_raise(exc);
}
if (nonblock)
ossl_raise(eSSLErrorWaitReadable, "read would block");
}
static int
@ -1714,11 +1709,21 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
rb_io_wait_readable(FPTR_TO_FD(fptr));
continue;
case SSL_ERROR_SYSCALL:
if(ERR_peek_error() == 0 && nread == 0) {
if (no_exception_p(opts)) { return Qnil; }
rb_eof_error();
if (!ERR_peek_error()) {
if (errno)
rb_sys_fail(0);
else {
/*
* The underlying BIO returned 0. This is actually a
* protocol error. But unfortunately, not all
* implementations cleanly shutdown the TLS connection
* but just shutdown/close the TCP connection. So report
* EOF for now...
*/
if (no_exception_p(opts)) { return Qnil; }
rb_eof_error();
}
}
rb_sys_fail(0);
default:
ossl_raise(eSSLError, "SSL_read");
}
@ -1871,11 +1876,24 @@ static VALUE
ossl_ssl_stop(VALUE self)
{
SSL *ssl;
int ret;
GetSSL(self, ssl);
if (!ssl_started(ssl))
return Qnil;
ret = SSL_shutdown(ssl);
if (ret == 1) /* Have already received close_notify */
return Qnil;
if (ret == 0) /* Sent close_notify, but we don't wait for reply */
return Qnil;
ossl_ssl_shutdown(ssl);
/*
* XXX: Something happened. Possibly it failed because the underlying socket
* is not writable/readable, since it is in non-blocking mode. We should do
* some proper error handling using SSL_get_error() and maybe retry, but we
* can't block here. Give up for now.
*/
ossl_clear_error();
return Qnil;
}
@ -2525,6 +2543,7 @@ Init_ossl_ssl(void)
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
rb_define_alias(cSSLContext, "freeze", "setup");
/*
* No session caching for client or server
@ -2691,6 +2710,9 @@ Init_ossl_ssl(void)
sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
id_tmp_dh_callback = rb_intern("tmp_dh_callback");
id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
#define DefIVarID(name) do \
id_i_##name = rb_intern("@"#name); while (0)

Просмотреть файл

@ -108,11 +108,7 @@ int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
if (a_len != b_len)
return 1;
#if defined(_WIN32)
return memcmp(a_sid, b_sid, a_len);
#else
return CRYPTO_memcmp(a_sid, b_sid, a_len);
#endif
}
#endif
@ -141,19 +137,18 @@ static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2)
*
* Returns the time at which the session was established.
*/
static VALUE ossl_ssl_session_get_time(VALUE self)
static VALUE
ossl_ssl_session_get_time(VALUE self)
{
SSL_SESSION *ctx;
time_t t;
SSL_SESSION *ctx;
long t;
GetSSLSession(self, ctx);
GetSSLSession(self, ctx);
t = SSL_SESSION_get_time(ctx);
if (t == 0)
return Qnil;
t = SSL_SESSION_get_time(ctx);
if (t == 0)
return Qnil;
return rb_funcall(rb_cTime, rb_intern("at"), 1, TIMET2NUM(t));
return rb_funcall(rb_cTime, rb_intern("at"), 1, LONG2NUM(t));
}
/*
@ -164,16 +159,16 @@ static VALUE ossl_ssl_session_get_time(VALUE self)
* established time.
*
*/
static VALUE ossl_ssl_session_get_timeout(VALUE self)
static VALUE
ossl_ssl_session_get_timeout(VALUE self)
{
SSL_SESSION *ctx;
time_t t;
SSL_SESSION *ctx;
long t;
GetSSLSession(self, ctx);
GetSSLSession(self, ctx);
t = SSL_SESSION_get_timeout(ctx);
t = SSL_SESSION_get_timeout(ctx);
return TIMET2NUM(t);
return LONG2NUM(t);
}
/*
@ -270,9 +265,6 @@ static VALUE ossl_ssl_session_to_pem(VALUE self)
{
SSL_SESSION *ctx;
BIO *out;
BUF_MEM *buf;
VALUE str;
int i;
GetSSLSession(self, ctx);
@ -280,16 +272,13 @@ static VALUE ossl_ssl_session_to_pem(VALUE self)
ossl_raise(eSSLSession, "BIO_s_mem()");
}
if (!(i=PEM_write_bio_SSL_SESSION(out, ctx))) {
if (!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;
return ossl_membio2str(out);
}
@ -303,8 +292,6 @@ static VALUE ossl_ssl_session_to_text(VALUE self)
{
SSL_SESSION *ctx;
BIO *out;
BUF_MEM *buf;
VALUE str;
GetSSLSession(self, ctx);
@ -317,11 +304,7 @@ static VALUE ossl_ssl_session_to_text(VALUE self)
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;
return ossl_membio2str(out);
}

Просмотреть файл

@ -110,10 +110,13 @@ 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);
/*
* Calls the verify callback Proc (the first parameter) with given pre-verify
* result and the X509_STORE_CTX.
*/
int ossl_verify_cb_call(VALUE, int, X509_STORE_CTX *);
#endif /* _OSSL_X509_H_ */

Просмотреть файл

@ -624,7 +624,7 @@ ossl_x509_check_private_key(VALUE self, VALUE key)
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());
ossl_clear_error();
return Qfalse;
}

Просмотреть файл

@ -182,8 +182,6 @@ ossl_x509crl_get_signature_algorithm(VALUE self)
X509_CRL *crl;
const X509_ALGOR *alg;
BIO *out;
BUF_MEM *buf;
VALUE str;
GetX509CRL(self, crl);
if (!(out = BIO_new(BIO_s_mem()))) {
@ -194,10 +192,8 @@ ossl_x509crl_get_signature_algorithm(VALUE self)
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;
return ossl_membio2str(out);
}
static VALUE
@ -388,8 +384,6 @@ 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()))) {
@ -399,11 +393,8 @@ ossl_x509crl_to_der(VALUE self)
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;
return ossl_membio2str(out);
}
static VALUE
@ -411,8 +402,6 @@ 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()))) {
@ -422,11 +411,8 @@ ossl_x509crl_to_pem(VALUE self)
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;
return ossl_membio2str(out);
}
static VALUE
@ -434,8 +420,6 @@ 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()))) {
@ -445,11 +429,8 @@ ossl_x509crl_to_text(VALUE self)
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;
return ossl_membio2str(out);
}
/*

Просмотреть файл

@ -372,12 +372,10 @@ ossl_x509name_cmp(VALUE self, VALUE other)
static VALUE
ossl_x509name_eql(VALUE self, VALUE other)
{
int result;
if (!rb_obj_is_kind_of(other, cX509Name))
return Qfalse;
if(CLASS_OF(other) != cX509Name) return Qfalse;
result = ossl_x509name_cmp0(self, other);
return (result == 0) ? Qtrue : Qfalse;
return ossl_x509name_cmp0(self, other) ? Qtrue : Qfalse;
}
/*

Просмотреть файл

@ -160,8 +160,6 @@ 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()))) {
@ -171,11 +169,8 @@ ossl_x509req_to_pem(VALUE self)
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;
return ossl_membio2str(out);
}
static VALUE
@ -203,8 +198,6 @@ 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()))) {
@ -214,11 +207,8 @@ ossl_x509req_to_text(VALUE self)
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;
return ossl_membio2str(out);
}
#if 0
@ -304,8 +294,6 @@ ossl_x509req_get_signature_algorithm(VALUE self)
X509_REQ *req;
const X509_ALGOR *alg;
BIO *out;
BUF_MEM *buf;
VALUE str;
GetX509Req(self, req);
@ -317,10 +305,8 @@ ossl_x509req_get_signature_algorithm(VALUE self)
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;
return ossl_membio2str(out);
}
static VALUE

Просмотреть файл

@ -47,6 +47,65 @@
GetX509Store((obj), (ctx)); \
} while (0)
/*
* Verify callback stuff
*/
static int stctx_ex_verify_cb_idx, store_ex_verify_cb_idx;
static VALUE ossl_x509stctx_new(X509_STORE_CTX *);
struct ossl_verify_cb_args {
VALUE proc;
VALUE preverify_ok;
VALUE store_ctx;
};
static VALUE
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_call(VALUE proc, int ok, X509_STORE_CTX *ctx)
{
VALUE rctx, ret;
struct ossl_verify_cb_args args;
int state;
if (NIL_P(proc))
return ok;
ret = Qfalse;
rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, (VALUE)ctx, &state);
if (state) {
rb_set_errinfo(Qnil);
rb_warn("StoreContext initialization failure");
}
else {
args.proc = proc;
args.preverify_ok = ok ? Qtrue : Qfalse;
args.store_ctx = rctx;
ret = rb_protect((VALUE(*)(VALUE))call_verify_cb_proc, (VALUE)&args, &state);
if (state) {
rb_set_errinfo(Qnil);
rb_warn("exception in verify_callback is ignored");
}
RTYPEDDATA_DATA(rctx) = NULL;
}
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;
}
/*
* Classes
*/
@ -111,9 +170,10 @@ x509store_verify_cb(int ok, X509_STORE_CTX *ctx)
{
VALUE proc;
proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_store_ctx_ex_verify_cb_idx);
proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx);
if (!proc)
proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx), ossl_store_ex_verify_cb_idx);
proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx),
store_ex_verify_cb_idx);
if (!proc)
return ok;
@ -144,7 +204,7 @@ ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
X509_STORE *store;
GetX509Store(self, store);
X509_STORE_set_ex_data(store, ossl_store_ex_verify_cb_idx, (void *)cb);
X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb);
rb_iv_set(self, "@verify_callback", cb);
return cb;
@ -432,27 +492,6 @@ static const rb_data_type_t ossl_x509stctx_type = {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
VALUE
ossl_x509stctx_new(X509_STORE_CTX *ctx)
{
VALUE obj;
obj = NewX509StCtx(cX509StoreContext);
SetX509StCtx(obj, ctx);
return obj;
}
VALUE
ossl_x509stctx_clear_ptr(VALUE obj)
{
OSSL_Check_Kind(obj, cX509StoreContext);
RDATA(obj)->data = NULL;
return obj;
}
/*
* Private functions
*/
@ -482,6 +521,17 @@ ossl_x509stctx_alloc(VALUE klass)
return obj;
}
static VALUE
ossl_x509stctx_new(X509_STORE_CTX *ctx)
{
VALUE obj;
obj = NewX509StCtx(cX509StoreContext);
SetX509StCtx(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);
@ -527,7 +577,7 @@ ossl_x509stctx_verify(VALUE self)
X509_STORE_CTX *ctx;
GetX509StCtx(self, ctx);
X509_STORE_CTX_set_ex_data(ctx, ossl_store_ctx_ex_verify_cb_idx,
X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx,
(void *)rb_iv_get(self, "@verify_callback"));
switch (X509_verify_cert(ctx)) {
@ -747,6 +797,14 @@ Init_ossl_x509store(void)
mX509 = rb_define_module_under(mOSSL, "X509");
#endif
/* Register ext_data slot for verify callback Proc */
stctx_ex_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"stctx_ex_verify_cb_idx", 0, 0, 0);
if (stctx_ex_verify_cb_idx < 0)
ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
store_ex_verify_cb_idx = X509_STORE_get_ex_new_index(0, (void *)"store_ex_verify_cb_idx", 0, 0, 0);
if (store_ex_verify_cb_idx < 0)
ossl_raise(eOSSLError, "X509_STORE_get_ex_new_index");
eX509StoreError = rb_define_class_under(mX509, "StoreError", eOSSLError);
/* Document-class: OpenSSL::X509::Store

Просмотреть файл

@ -13,16 +13,7 @@
#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 RB_INTEGER_TYPE_P
/* for Ruby 2.3 compatibility */

Просмотреть файл

@ -14,7 +14,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
]
dgst = OpenSSL::Digest::SHA1.new
cert = OpenSSL::TestUtils.issue_cert(
subj, key, s, now, now+3600, exts, nil, nil, dgst)
subj, key, s, exts, nil, nil, digest: dgst, not_before: now, not_after: now+3600)
asn1 = OpenSSL::ASN1.decode(cert)
@ -243,14 +243,9 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
end
def test_primitive_cannot_set_infinite_length
begin
prim = OpenSSL::ASN1::Integer.new(50)
assert_equal(false, prim.infinite_length)
prim.infinite_length = true
flunk('Could set infinite length on primitive value')
rescue NoMethodError
#ok
end
prim = OpenSSL::ASN1::Integer.new(50)
assert_equal false, prim.infinite_length
assert_not_respond_to prim, :infinite_length=
end
def test_decode_all
@ -289,12 +284,8 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
def test_create_inf_length_primitive
expected = %w{ 24 80 04 01 61 00 00 }
raw = [expected.join('')].pack('H*')
val = OpenSSL::ASN1::OctetString.new('a')
cons = OpenSSL::ASN1::Constructive.new([val,
OpenSSL::ASN1::EndOfContent.new],
OpenSSL::ASN1::OCTET_STRING,
nil,
:UNIVERSAL)
content = [OpenSSL::ASN1::OctetString.new("a"), OpenSSL::ASN1::EndOfContent.new]
cons = OpenSSL::ASN1::Constructive.new(content, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
cons.infinite_length = true
assert_equal(nil, cons.tagging)
assert_equal(raw, cons.to_der)
@ -306,10 +297,7 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
def test_cons_without_inf_length_forbidden
assert_raise(OpenSSL::ASN1::ASN1Error) do
val = OpenSSL::ASN1::OctetString.new('a')
cons = OpenSSL::ASN1::Constructive.new([val],
OpenSSL::ASN1::OCTET_STRING,
nil,
:UNIVERSAL)
cons = OpenSSL::ASN1::Constructive.new([val], OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
cons.to_der
end
end
@ -317,10 +305,7 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
def test_cons_without_array_forbidden
assert_raise(OpenSSL::ASN1::ASN1Error) do
val = OpenSSL::ASN1::OctetString.new('a')
cons = OpenSSL::ASN1::Constructive.new(val,
OpenSSL::ASN1::OCTET_STRING,
nil,
:UNIVERSAL)
cons = OpenSSL::ASN1::Constructive.new(val, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
cons.infinite_length = true
cons.to_der
end
@ -352,218 +337,158 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
end
def test_seq_infinite_length
begin
content = [ OpenSSL::ASN1::Null.new(nil),
OpenSSL::ASN1::EndOfContent.new ]
cons = OpenSSL::ASN1::Sequence.new(content)
cons.infinite_length = true
expected = %w{ 30 80 05 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
content = [ OpenSSL::ASN1::Null.new(nil),
OpenSSL::ASN1::EndOfContent.new ]
cons = OpenSSL::ASN1::Sequence.new(content)
cons.infinite_length = true
expected = %w{ 30 80 05 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_set_infinite_length
begin
content = [ OpenSSL::ASN1::Null.new(nil),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Set.new(content)
cons.infinite_length = true
expected = %w{ 31 80 05 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
content = [ OpenSSL::ASN1::Null.new(nil),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Set.new(content)
cons.infinite_length = true
expected = %w{ 31 80 05 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_octet_string_infinite_length
begin
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(
octets,
OpenSSL::ASN1::OCTET_STRING,
nil,
:UNIVERSAL)
cons.infinite_length = true
expected = %w{ 24 80 04 03 61 61 61 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(octets, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
cons.infinite_length = true
expected = %w{ 24 80 04 03 61 61 61 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_prim_explicit_tagging
begin
oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
expected = %w{ A0 03 04 01 61 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, oct_str.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
expected = %w{ A0 03 04 01 61 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, oct_str.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_prim_explicit_tagging_tag_class
begin
oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
oct_str2 = OpenSSL::ASN1::OctetString.new(
"a",
0,
:EXPLICIT,
:CONTEXT_SPECIFIC)
assert_equal(oct_str.to_der, oct_str2.to_der)
end
oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
oct_str2 = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT, :CONTEXT_SPECIFIC)
assert_equal(oct_str.to_der, oct_str2.to_der)
end
def test_prim_implicit_tagging
begin
int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
expected = %w{ 80 01 01 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, int.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
expected = %w{ 80 01 01 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, int.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_prim_implicit_tagging_tag_class
begin
int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
int2 = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT, :CONTEXT_SPECIFIC);
assert_equal(int.to_der, int2.to_der)
end
int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
int2 = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT, :CONTEXT_SPECIFIC);
assert_equal(int.to_der, int2.to_der)
end
def test_cons_explicit_tagging
begin
content = [ OpenSSL::ASN1::PrintableString.new('abc') ]
seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT)
expected = %w{ A2 07 30 05 13 03 61 62 63 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, seq.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
content = [ OpenSSL::ASN1::PrintableString.new('abc') ]
seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT)
expected = %w{ A2 07 30 05 13 03 61 62 63 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, seq.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_cons_explicit_tagging_inf_length
begin
content = [ OpenSSL::ASN1::PrintableString.new('abc') ,
OpenSSL::ASN1::EndOfContent.new() ]
seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT)
seq.infinite_length = true
expected = %w{ A2 80 30 80 13 03 61 62 63 00 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, seq.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
content = [ OpenSSL::ASN1::PrintableString.new('abc') ,
OpenSSL::ASN1::EndOfContent.new() ]
seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT)
seq.infinite_length = true
expected = %w{ A2 80 30 80 13 03 61 62 63 00 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, seq.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_cons_implicit_tagging
begin
content = [ OpenSSL::ASN1::Null.new(nil) ]
seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT)
expected = %w{ A1 02 05 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, seq.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
content = [ OpenSSL::ASN1::Null.new(nil) ]
seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT)
expected = %w{ A1 02 05 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, seq.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_cons_implicit_tagging_inf_length
begin
content = [ OpenSSL::ASN1::Null.new(nil),
OpenSSL::ASN1::EndOfContent.new() ]
seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT)
seq.infinite_length = true
expected = %w{ A1 80 05 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, seq.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
content = [ OpenSSL::ASN1::Null.new(nil),
OpenSSL::ASN1::EndOfContent.new() ]
seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT)
seq.infinite_length = true
expected = %w{ A1 80 05 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, seq.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_octet_string_infinite_length_explicit_tagging
begin
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(
octets,
1,
:EXPLICIT)
cons.infinite_length = true
expected = %w{ A1 80 24 80 04 03 61 61 61 00 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(octets, 1, :EXPLICIT)
cons.infinite_length = true
expected = %w{ A1 80 24 80 04 03 61 61 61 00 00 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_octet_string_infinite_length_implicit_tagging
begin
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(
octets,
0,
:IMPLICIT)
cons.infinite_length = true
expected = %w{ A0 80 04 03 61 61 61 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(octets, 0, :IMPLICIT)
cons.infinite_length = true
expected = %w{ A0 80 04 03 61 61 61 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_recursive_octet_string_infinite_length
begin
octets_sub1 = [ OpenSSL::ASN1::OctetString.new("\x01"),
OpenSSL::ASN1::EndOfContent.new() ]
octets_sub2 = [ OpenSSL::ASN1::OctetString.new("\x02"),
OpenSSL::ASN1::EndOfContent.new() ]
container1 = OpenSSL::ASN1::Constructive.new(
octets_sub1,
OpenSSL::ASN1::OCTET_STRING,
nil,
:UNIVERSAL)
container1.infinite_length = true
container2 = OpenSSL::ASN1::Constructive.new(
octets_sub2,
OpenSSL::ASN1::OCTET_STRING,
nil,
:UNIVERSAL)
container2.infinite_length = true
octets3 = OpenSSL::ASN1::OctetString.new("\x03")
octets_sub1 = [ OpenSSL::ASN1::OctetString.new("\x01"),
OpenSSL::ASN1::EndOfContent.new() ]
octets_sub2 = [ OpenSSL::ASN1::OctetString.new("\x02"),
OpenSSL::ASN1::EndOfContent.new() ]
container1 = OpenSSL::ASN1::Constructive.new(octets_sub1, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
container1.infinite_length = true
container2 = OpenSSL::ASN1::Constructive.new(octets_sub2, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
container2.infinite_length = true
octets3 = OpenSSL::ASN1::OctetString.new("\x03")
octets = [ container1, container2, octets3,
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(
octets,
OpenSSL::ASN1::OCTET_STRING,
nil,
:UNIVERSAL)
cons.infinite_length = true
expected = %w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
octets = [ container1, container2, octets3,
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(octets, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
cons.infinite_length = true
expected = %w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_bit_string_infinite_length
begin
content = [ OpenSSL::ASN1::BitString.new("\x01"),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(
content,
OpenSSL::ASN1::BIT_STRING,
nil,
:UNIVERSAL)
cons.infinite_length = true
expected = %w{ 23 80 03 02 00 01 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
content = [ OpenSSL::ASN1::BitString.new("\x01"),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(content, OpenSSL::ASN1::BIT_STRING, nil, :UNIVERSAL)
cons.infinite_length = true
expected = %w{ 23 80 03 02 00 01 00 00 }
raw = [expected.join('')].pack('H*')
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
def test_primitive_inf_length
@ -610,6 +535,29 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
assert_equal(false, asn1.value[3].infinite_length)
end
def test_decode_constructed_overread
test = %w{ 31 06 31 02 30 02 05 00 }
# ^ <- invalid
raw = [test.join].pack("H*")
ret = []
assert_raise(OpenSSL::ASN1::ASN1Error) {
OpenSSL::ASN1.traverse(raw) { |x| ret << x }
}
assert_equal 2, ret.size
assert_equal 17, ret[0][6]
assert_equal 17, ret[1][6]
test = %w{ 31 80 30 03 00 00 }
# ^ <- invalid
raw = [test.join].pack("H*")
ret = []
assert_raise(OpenSSL::ASN1::ASN1Error) {
OpenSSL::ASN1.traverse(raw) { |x| ret << x }
}
assert_equal 1, ret.size
assert_equal 17, ret[0][6]
end
private
def assert_universal(tag, asn1)
@ -621,4 +569,3 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
end
end if defined?(OpenSSL::TestUtils)

Просмотреть файл

@ -4,110 +4,131 @@ require_relative 'utils'
if defined?(OpenSSL::TestUtils)
class OpenSSL::TestCipher < OpenSSL::TestCase
@ciphers = OpenSSL::Cipher.ciphers
class << self
module Helper
def has_cipher?(name)
@ciphers ||= OpenSSL::Cipher.ciphers
@ciphers.include?(name)
end
end
include Helper
extend Helper
def has_ciphers?(list)
list.all? { |name| has_cipher?(name) }
end
def test_encrypt_decrypt
# NIST SP 800-38A F.2.1
key = ["2b7e151628aed2a6abf7158809cf4f3c"].pack("H*")
iv = ["000102030405060708090a0b0c0d0e0f"].pack("H*")
pt = ["6bc1bee22e409f96e93d7e117393172a" \
"ae2d8a571e03ac9c9eb76fac45af8e51"].pack("H*")
ct = ["7649abac8119b246cee98e9b12e9197d" \
"5086cb9b507219ee95db113a917678b2"].pack("H*")
cipher = new_encryptor("aes-128-cbc", key: key, iv: iv, padding: 0)
assert_equal ct, cipher.update(pt) << cipher.final
cipher = new_decryptor("aes-128-cbc", key: key, iv: iv, padding: 0)
assert_equal pt, cipher.update(ct) << cipher.final
end
def setup
@c1 = OpenSSL::Cipher.new("DES-EDE3-CBC")
@c2 = OpenSSL::Cipher::DES.new(:EDE3, "CBC")
@key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
@iv = "\0\0\0\0\0\0\0\0"
@hexkey = "0000000000000000000000000000000000000000000000"
@hexiv = "0000000000000000"
@data = "DATA"
end
def test_pkcs5_keyivgen
pass = "\x00" * 8
salt = "\x01" * 8
num = 2048
pt = "data to be encrypted"
cipher = OpenSSL::Cipher.new("DES-EDE3-CBC").encrypt
cipher.pkcs5_keyivgen(pass, salt, num, "MD5")
s1 = cipher.update(pt) << cipher.final
def teardown
super
@c1 = @c2 = nil
end
d1 = num.times.inject(pass + salt) {|out, _| OpenSSL::Digest::MD5.digest(out) }
d2 = num.times.inject(d1 + pass + salt) {|out, _| OpenSSL::Digest::MD5.digest(out) }
key = (d1 + d2)[0, 24]
iv = (d1 + d2)[24, 8]
cipher = new_encryptor("DES-EDE3-CBC", key: key, iv: iv)
s2 = cipher.update(pt) << cipher.final
def test_crypt
@c1.encrypt.pkcs5_keyivgen(@key, @iv)
@c2.encrypt.pkcs5_keyivgen(@key, @iv)
s1 = @c1.update(@data) + @c1.final
s2 = @c2.update(@data) + @c2.final
assert_equal(s1, s2, "encrypt")
@c1.decrypt.pkcs5_keyivgen(@key, @iv)
@c2.decrypt.pkcs5_keyivgen(@key, @iv)
assert_equal(@data, @c1.update(s1)+@c1.final, "decrypt")
assert_equal(@data, @c2.update(s2)+@c2.final, "decrypt")
assert_equal s1, s2
end
def test_info
assert_equal("DES-EDE3-CBC", @c1.name, "name")
assert_equal("DES-EDE3-CBC", @c2.name, "name")
assert_kind_of(Integer, @c1.key_len, "key_len")
assert_kind_of(Integer, @c1.iv_len, "iv_len")
cipher = OpenSSL::Cipher.new("DES-EDE3-CBC").encrypt
assert_equal "DES-EDE3-CBC", cipher.name
assert_equal 24, cipher.key_len
assert_equal 8, cipher.iv_len
end
def test_dup
assert_equal(@c1.name, @c1.dup.name, "dup")
assert_equal(@c1.name, @c1.clone.name, "clone")
@c1.encrypt
@c1.key = @key
@c1.iv = @iv
tmpc = @c1.dup
s1 = @c1.update(@data) + @c1.final
s2 = tmpc.update(@data) + tmpc.final
cipher = OpenSSL::Cipher.new("aes-128-cbc").encrypt
assert_equal cipher.name, cipher.dup.name
cipher.encrypt
cipher.random_key
cipher.random_iv
tmpc = cipher.dup
s1 = cipher.update("data") + cipher.final
s2 = tmpc.update("data") + tmpc.final
assert_equal(s1, s2, "encrypt dup")
end
def test_reset
@c1.encrypt
@c1.key = @key
@c1.iv = @iv
s1 = @c1.update(@data) + @c1.final
@c1.reset
s2 = @c1.update(@data) + @c1.final
cipher = OpenSSL::Cipher.new("aes-128-cbc").encrypt
cipher.encrypt
cipher.random_key
cipher.random_iv
s1 = cipher.update("data") + cipher.final
cipher.reset
s2 = cipher.update("data") + cipher.final
assert_equal(s1, s2, "encrypt reset")
end
def test_key_iv_set
# default value for DES-EDE3-CBC
assert_equal(24, @c1.key_len)
assert_equal(8, @c1.iv_len)
assert_raise(ArgumentError) { @c1.key = "\x01" * 23 }
@c1.key = "\x01" * 24
assert_raise(ArgumentError) { @c1.key = "\x01" * 25 }
assert_raise(ArgumentError) { @c1.iv = "\x01" * 7 }
@c1.iv = "\x01" * 8
assert_raise(ArgumentError) { @c1.iv = "\x01" * 9 }
cipher = OpenSSL::Cipher.new("DES-EDE3-CBC").encrypt
assert_raise(ArgumentError) { cipher.key = "\x01" * 23 }
assert_nothing_raised { cipher.key = "\x01" * 24 }
assert_raise(ArgumentError) { cipher.key = "\x01" * 25 }
assert_raise(ArgumentError) { cipher.iv = "\x01" * 7 }
assert_nothing_raised { cipher.iv = "\x01" * 8 }
assert_raise(ArgumentError) { cipher.iv = "\x01" * 9 }
end
def test_random_key_iv
data = "data"
s1, s2 = 2.times.map do
cipher = OpenSSL::Cipher.new("aes-128-cbc").encrypt
cipher.random_key
cipher.iv = "\x01" * 16
cipher.update(data) << cipher.final
end
assert_not_equal s1, s2
s1, s2 = 2.times.map do
cipher = OpenSSL::Cipher.new("aes-128-cbc").encrypt
cipher.key = "\x01" * 16
cipher.random_iv
cipher.update(data) << cipher.final
end
assert_not_equal s1, s2
end
def test_empty_data
@c1.encrypt
assert_raise(ArgumentError){ @c1.update("") }
cipher = OpenSSL::Cipher.new("DES-EDE3-CBC").encrypt
cipher.random_key
assert_raise(ArgumentError) { cipher.update("") }
end
def test_initialize
assert_raise(RuntimeError) {@c1.__send__(:initialize, "DES-EDE3-CBC")}
assert_raise(RuntimeError) {OpenSSL::Cipher.allocate.final}
cipher = OpenSSL::Cipher.new("DES-EDE3-CBC")
assert_raise(RuntimeError) { cipher.__send__(:initialize, "DES-EDE3-CBC") }
assert_raise(RuntimeError) { OpenSSL::Cipher.allocate.final }
end
def test_ctr_if_exists
begin
cipher = OpenSSL::Cipher.new('aes-128-ctr')
cipher.encrypt
cipher.pkcs5_keyivgen('password')
c = cipher.update('hello,world') + cipher.final
cipher.decrypt
cipher.pkcs5_keyivgen('password')
assert_equal('hello,world', cipher.update(c) + cipher.final)
end
# NIST SP 800-38A F.5.1
key = ["2b7e151628aed2a6abf7158809cf4f3c"].pack("H*")
iv = ["f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"].pack("H*")
pt = ["6bc1bee22e409f96e93d7e117393172a" \
"ae2d8a571e03ac9c9eb76fac45af8e51"].pack("H*")
ct = ["874d6191b620e3261bef6864990db6ce" \
"9806f66b7970fdff8617187bb9fffdff"].pack("H*")
cipher = new_encryptor("aes-128-ctr", key: key, iv: iv, padding: 0)
assert_equal ct, cipher.update(pt) << cipher.final
cipher = new_decryptor("aes-128-ctr", key: key, iv: iv, padding: 0)
assert_equal pt, cipher.update(ct) << cipher.final
end if has_cipher?('aes-128-ctr')
def test_ciphers
@ -136,202 +157,159 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
}
end
def test_AES_crush
500.times do
assert_nothing_raised("[Bug #2768]") do
# it caused OpenSSL SEGV by uninitialized key
OpenSSL::Cipher::AES128.new("ECB").update "." * 17
end
def test_update_raise_if_key_not_set
assert_raise(OpenSSL::Cipher::CipherError) do
# it caused OpenSSL SEGV by uninitialized key [Bug #2768]
OpenSSL::Cipher::AES128.new("ECB").update "." * 17
end
end
if has_ciphers?(['aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm'])
def test_authenticated
def test_authenticated
if has_cipher?('aes-128-gcm')
cipher = OpenSSL::Cipher.new('aes-128-gcm')
assert_predicate(cipher, :authenticated?)
cipher = OpenSSL::Cipher.new('aes-128-cbc')
assert_not_predicate(cipher, :authenticated?)
end
def test_aes_gcm
['aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm'].each do |algo|
pt = "You should all use Authenticated Encryption!"
cipher, key, iv = new_encryptor(algo)
cipher.auth_data = "aad"
ct = cipher.update(pt) + cipher.final
tag = cipher.auth_tag
assert_equal(16, tag.size)
decipher = new_decryptor(algo, key, iv)
decipher.auth_tag = tag
decipher.auth_data = "aad"
assert_equal(pt, decipher.update(ct) + decipher.final)
end
end
def test_aes_gcm_short_tag
['aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm'].each do |algo|
pt = "You should all use Authenticated Encryption!"
cipher, key, iv = new_encryptor(algo)
cipher.auth_data = "aad"
ct = cipher.update(pt) + cipher.final
tag = cipher.auth_tag(8)
assert_equal(8, tag.size)
decipher = new_decryptor(algo, key, iv)
decipher.auth_tag = tag
decipher.auth_data = "aad"
assert_equal(pt, decipher.update(ct) + decipher.final)
end
end
def test_aes_gcm_wrong_tag
pt = "You should all use Authenticated Encryption!"
cipher, key, iv = new_encryptor('aes-128-gcm')
cipher.auth_data = "aad"
ct = cipher.update(pt) + cipher.final
tag = cipher.auth_tag
decipher = new_decryptor('aes-128-gcm', key, iv)
tag.setbyte(-1, (tag.getbyte(-1) + 1) & 0xff)
decipher.auth_tag = tag
decipher.auth_data = "aad"
assert_raise OpenSSL::Cipher::CipherError do
decipher.update(ct) + decipher.final
end
end
def test_aes_gcm_wrong_auth_data
pt = "You should all use Authenticated Encryption!"
cipher, key, iv = new_encryptor('aes-128-gcm')
cipher.auth_data = "aad"
ct = cipher.update(pt) + cipher.final
tag = cipher.auth_tag
decipher = new_decryptor('aes-128-gcm', key, iv)
decipher.auth_tag = tag
decipher.auth_data = "daa"
assert_raise OpenSSL::Cipher::CipherError do
decipher.update(ct) + decipher.final
end
end
def test_aes_gcm_wrong_ciphertext
pt = "You should all use Authenticated Encryption!"
cipher, key, iv = new_encryptor('aes-128-gcm')
cipher.auth_data = "aad"
ct = cipher.update(pt) + cipher.final
tag = cipher.auth_tag
decipher = new_decryptor('aes-128-gcm', key, iv)
decipher.auth_tag = tag
decipher.auth_data = "aad"
assert_raise OpenSSL::Cipher::CipherError do
decipher.update(ct[0..-2] << ct[-1].succ) + decipher.final
end
end
def test_aes_gcm_variable_iv_len
pt = "You should all use Authenticated Encryption!"
cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
cipher.key = "x" * 16
assert_equal(12, cipher.iv_len)
cipher.iv = "a" * 12
ct1 = cipher.update(pt) << cipher.final
tag1 = cipher.auth_tag
cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
cipher.key = "x" * 16
cipher.iv_len = 10
assert_equal(10, cipher.iv_len)
cipher.iv = "a" * 10
ct2 = cipher.update(pt) << cipher.final
tag2 = cipher.auth_tag
assert_not_equal ct1, ct2
assert_not_equal tag1, tag2
decipher = OpenSSL::Cipher.new("aes-128-gcm").decrypt
decipher.auth_tag = tag1
decipher.key = "x" * 16
decipher.iv_len = 12
decipher.iv = "a" * 12
assert_equal(pt, decipher.update(ct1) << decipher.final)
decipher.reset
decipher.auth_tag = tag2
assert_raise(OpenSSL::Cipher::CipherError) {
decipher.update(ct2) << decipher.final
}
decipher.reset
decipher.auth_tag = tag2
decipher.iv_len = 10
decipher.iv = "a" * 10
assert_equal(pt, decipher.update(ct2) << decipher.final)
end
cipher = OpenSSL::Cipher.new('aes-128-cbc')
assert_not_predicate(cipher, :authenticated?)
end
def test_aes_gcm
# GCM spec Appendix B Test Case 4
key = ["feffe9928665731c6d6a8f9467308308"].pack("H*")
iv = ["cafebabefacedbaddecaf888"].pack("H*")
aad = ["feedfacedeadbeeffeedfacedeadbeef" \
"abaddad2"].pack("H*")
pt = ["d9313225f88406e5a55909c5aff5269a" \
"86a7a9531534f7da2e4c303d8a318a72" \
"1c3c0c95956809532fcf0e2449a6b525" \
"b16aedf5aa0de657ba637b39"].pack("H*")
ct = ["42831ec2217774244b7221b784d0d49c" \
"e3aa212f2c02a4e035c17e2329aca12e" \
"21d514b25466931c7d8f6a5aac84aa05" \
"1ba30b396a0aac973d58e091"].pack("H*")
tag = ["5bc94fbc3221a5db94fae95ae7121a47"].pack("H*")
cipher = new_encryptor("aes-128-gcm", key: key, iv: iv, auth_data: aad)
assert_equal ct, cipher.update(pt) << cipher.final
assert_equal tag, cipher.auth_tag
cipher = new_decryptor("aes-128-gcm", key: key, iv: iv, auth_data: aad, auth_tag: tag)
assert_equal pt, cipher.update(ct) << cipher.final
# truncated tag is accepted
cipher = new_encryptor("aes-128-gcm", key: key, iv: iv, auth_data: aad)
assert_equal ct, cipher.update(pt) << cipher.final
assert_equal tag[0, 8], cipher.auth_tag(8)
cipher = new_decryptor("aes-128-gcm", key: key, iv: iv, auth_data: aad, auth_tag: tag[0, 8])
assert_equal pt, cipher.update(ct) << cipher.final
# wrong tag is rejected
tag2 = tag.dup
tag2.setbyte(-1, (tag2.getbyte(-1) + 1) & 0xff)
cipher = new_decryptor("aes-128-gcm", key: key, iv: iv, auth_data: aad, auth_tag: tag2)
cipher.update(ct)
assert_raise(OpenSSL::Cipher::CipherError) { cipher.final }
# wrong aad is rejected
aad2 = aad[0..-2] << aad[-1].succ
cipher = new_decryptor("aes-128-gcm", key: key, iv: iv, auth_data: aad2, auth_tag: tag)
cipher.update(ct)
assert_raise(OpenSSL::Cipher::CipherError) { cipher.final }
# wrong ciphertext is rejected
ct2 = ct[0..-2] << ct[-1].succ
cipher = new_decryptor("aes-128-gcm", key: key, iv: iv, auth_data: aad, auth_tag: tag)
cipher.update(ct2)
assert_raise(OpenSSL::Cipher::CipherError) { cipher.final }
end if has_cipher?("aes-128-gcm")
def test_aes_gcm_variable_iv_len
# GCM spec Appendix B Test Case 5
key = ["feffe9928665731c6d6a8f9467308308"].pack("H*")
iv = ["cafebabefacedbad"].pack("H*")
aad = ["feedfacedeadbeeffeedfacedeadbeef" \
"abaddad2"].pack("H*")
pt = ["d9313225f88406e5a55909c5aff5269a" \
"86a7a9531534f7da2e4c303d8a318a72" \
"1c3c0c95956809532fcf0e2449a6b525" \
"b16aedf5aa0de657ba637b39"].pack("H*")
ct = ["61353b4c2806934a777ff51fa22a4755" \
"699b2a714fcdc6f83766e5f97b6c7423" \
"73806900e49f24b22b097544d4896b42" \
"4989b5e1ebac0f07c23f4598"].pack("H*")
tag = ["3612d2e79e3b0785561be14aaca2fccb"].pack("H*")
cipher = new_encryptor("aes-128-gcm", key: key, iv_len: 8, iv: iv, auth_data: aad)
assert_equal ct, cipher.update(pt) << cipher.final
assert_equal tag, cipher.auth_tag
cipher = new_decryptor("aes-128-gcm", key: key, iv_len: 8, iv: iv, auth_data: aad, auth_tag: tag)
assert_equal pt, cipher.update(ct) << cipher.final
end if has_cipher?("aes-128-gcm")
def test_aes_ocb_tag_len
pt = "You should all use Authenticated Encryption!"
cipher = OpenSSL::Cipher.new("aes-128-ocb").encrypt
cipher.auth_tag_len = 14
cipher.iv_len = 8
key = cipher.random_key
iv = cipher.random_iv
cipher.auth_data = "aad"
ct = cipher.update(pt) + cipher.final
tag = cipher.auth_tag
assert_equal(14, tag.size)
# RFC 7253 Appendix A; the second sample
key = ["000102030405060708090A0B0C0D0E0F"].pack("H*")
iv = ["BBAA99887766554433221101"].pack("H*")
aad = ["0001020304050607"].pack("H*")
pt = ["0001020304050607"].pack("H*")
ct = ["6820B3657B6F615A"].pack("H*")
tag = ["5725BDA0D3B4EB3A257C9AF1F8F03009"].pack("H*")
decipher = OpenSSL::Cipher.new("aes-128-ocb").decrypt
decipher.auth_tag_len = 14
decipher.auth_tag = tag
decipher.iv_len = 8
decipher.key = key
decipher.iv = iv
decipher.auth_data = "aad"
assert_equal(pt, decipher.update(ct) + decipher.final)
cipher = new_encryptor("aes-128-ocb", key: key, iv: iv, auth_data: aad)
assert_equal ct, cipher.update(pt) << cipher.final
assert_equal tag, cipher.auth_tag
cipher = new_decryptor("aes-128-ocb", key: key, iv: iv, auth_data: aad, auth_tag: tag)
assert_equal pt, cipher.update(ct) << cipher.final
# RFC 7253 Appendix A; with 96 bits tag length
key = ["0F0E0D0C0B0A09080706050403020100"].pack("H*")
iv = ["BBAA9988776655443322110D"].pack("H*")
aad = ["000102030405060708090A0B0C0D0E0F1011121314151617" \
"18191A1B1C1D1E1F2021222324252627"].pack("H*")
pt = ["000102030405060708090A0B0C0D0E0F1011121314151617" \
"18191A1B1C1D1E1F2021222324252627"].pack("H*")
ct = ["1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1" \
"A0124B0A55BAE884ED93481529C76B6A"].pack("H*")
tag = ["D0C515F4D1CDD4FDAC4F02AA"].pack("H*")
cipher = new_encryptor("aes-128-ocb", auth_tag_len: 12, key: key, iv: iv, auth_data: aad)
assert_equal ct, cipher.update(pt) << cipher.final
assert_equal tag, cipher.auth_tag
cipher = new_decryptor("aes-128-ocb", auth_tag_len: 12, key: key, iv: iv, auth_data: aad, auth_tag: tag)
assert_equal pt, cipher.update(ct) << cipher.final
decipher = OpenSSL::Cipher.new("aes-128-ocb").decrypt
decipher.auth_tag_len = 9
decipher.auth_tag = tag[0, 9]
decipher.iv_len = 8
decipher.key = key
decipher.iv = iv
decipher.auth_data = "aad"
assert_raise(OpenSSL::Cipher::CipherError) {
decipher.update(ct) + decipher.final
}
end if has_cipher?("aes-128-ocb")
def test_aes_gcm_key_iv_order_issue
pt = "[ruby/openssl#49]"
cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
cipher.key = "x" * 16
cipher.iv = "a" * 12
ct1 = cipher.update(pt) << cipher.final
tag1 = cipher.auth_tag
cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
cipher.iv = "a" * 12
cipher.key = "x" * 16
ct2 = cipher.update(pt) << cipher.final
tag2 = cipher.auth_tag
assert_equal ct1, ct2
assert_equal tag1, tag2
end if has_cipher?("aes-128-gcm")
private
def new_encryptor(algo)
cipher = OpenSSL::Cipher.new(algo)
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv
[cipher, key, iv]
def new_encryptor(algo, **kwargs)
OpenSSL::Cipher.new(algo).tap do |cipher|
cipher.encrypt
kwargs.each {|k, v| cipher.send(:"#{k}=", v) }
end
end
def new_decryptor(algo, key, iv)
def new_decryptor(algo, **kwargs)
OpenSSL::Cipher.new(algo).tap do |cipher|
cipher.decrypt
cipher.key = key
cipher.iv = iv
kwargs.each {|k, v| cipher.send(:"#{k}=", v) }
end
end

Просмотреть файл

@ -7,27 +7,21 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
def setup
@d1 = OpenSSL::Digest.new("MD5")
@d2 = OpenSSL::Digest::MD5.new
@md = Digest::MD5.new
@data = "DATA"
end
def teardown
super
@d1 = @d2 = @md = nil
end
def test_digest
assert_equal(@md.digest, @d1.digest)
assert_equal(@md.hexdigest, @d1.hexdigest)
@d1 << @data
@d2 << @data
@md << @data
assert_equal(@md.digest, @d1.digest)
assert_equal(@md.hexdigest, @d1.hexdigest)
assert_equal(@d1.digest, @d2.digest)
assert_equal(@d1.hexdigest, @d2.hexdigest)
assert_equal(@md.digest, OpenSSL::Digest::MD5.digest(@data))
assert_equal(@md.hexdigest, OpenSSL::Digest::MD5.hexdigest(@data))
null_hex = "d41d8cd98f00b204e9800998ecf8427e"
null_bin = [null_hex].pack("H*")
data = "DATA"
hex = "e44f9e348e41cb272efa87387728571b"
bin = [hex].pack("H*")
assert_equal(null_bin, @d1.digest)
assert_equal(null_hex, @d1.hexdigest)
@d1 << data
assert_equal(bin, @d1.digest)
assert_equal(hex, @d1.hexdigest)
assert_equal(bin, OpenSSL::Digest::MD5.digest(data))
assert_equal(hex, OpenSSL::Digest::MD5.hexdigest(data))
end
def test_eql
@ -43,17 +37,17 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
end
def test_dup
@d1.update(@data)
@d1.update("DATA")
assert_equal(@d1.name, @d1.dup.name, "dup")
assert_equal(@d1.name, @d1.clone.name, "clone")
assert_equal(@d1.digest, @d1.clone.digest, "clone .digest")
end
def test_reset
@d1.update(@data)
@d1.update("DATA")
dig1 = @d1.digest
@d1.reset
@d1.update(@data)
@d1.update("DATA")
dig2 = @d1.digest
assert_equal(dig1, dig2, "reset")
end

Просмотреть файл

@ -72,13 +72,6 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
end;
end
def test_dup
with_openssl <<-'end;'
engine = get_engine
assert_raise(NoMethodError) { engine.dup }
end;
end
private
# this is required because OpenSSL::Engine methods change global state

Просмотреть файл

@ -1,33 +1,26 @@
# coding: UTF-8
# frozen_string_literal: false
require_relative 'utils'
class OpenSSL::TestHMAC < OpenSSL::TestCase
def setup
@digest = OpenSSL::Digest::MD5
@key = "KEY"
@data = "DATA"
@h1 = OpenSSL::HMAC.new(@key, @digest.new)
@h2 = OpenSSL::HMAC.new(@key, "MD5")
end
def test_hmac
@h1.update(@data)
@h2.update(@data)
assert_equal(@h1.digest, @h2.digest)
# RFC 2202 2. Test Cases for HMAC-MD5
hmac = OpenSSL::HMAC.new(["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*"), "MD5")
hmac.update("Hi There")
assert_equal ["9294727a3638bb1c13f48ef8158bfc9d"].pack("H*"), hmac.digest
assert_equal "9294727a3638bb1c13f48ef8158bfc9d", hmac.hexdigest
assert_equal(OpenSSL::HMAC.digest(@digest.new, @key, @data), @h1.digest, "digest")
assert_equal(OpenSSL::HMAC.hexdigest(@digest.new, @key, @data), @h1.hexdigest, "hexdigest")
assert_equal(OpenSSL::HMAC.digest("MD5", @key, @data), @h2.digest, "digest")
assert_equal(OpenSSL::HMAC.hexdigest("MD5", @key, @data), @h2.hexdigest, "hexdigest")
# RFC 4231 4.2. Test Case 1
hmac = OpenSSL::HMAC.new(["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*"), "SHA224")
hmac.update("Hi There")
assert_equal ["896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22"].pack("H*"), hmac.digest
assert_equal "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22", hmac.hexdigest
end
def test_dup
@h1.update(@data)
h = @h1.dup
assert_equal(@h1.digest, h.digest, "dup digest")
h1 = OpenSSL::HMAC.new("KEY", "MD5")
h1.update("DATA")
h = h1.dup
assert_equal(h1.digest, h.digest, "dup digest")
end
def test_binary_update
@ -38,9 +31,10 @@ class OpenSSL::TestHMAC < OpenSSL::TestCase
end
def test_reset_keep_key
first = @h1.update("test").hexdigest
@h2.reset
second = @h2.update("test").hexdigest
h1 = OpenSSL::HMAC.new("KEY", "MD5")
first = h1.update("test").hexdigest
h1.reset
second = h1.update("test").hexdigest
assert_equal first, second
end
end if defined?(OpenSSL::TestUtils)

Просмотреть файл

@ -5,9 +5,6 @@ if defined?(OpenSSL::TestUtils)
class OpenSSL::TestOCSP < OpenSSL::TestCase
def setup
now = Time.at(Time.now.to_i) # suppress usec
dgst = OpenSSL::Digest::SHA1.new
# @ca_cert
# |
# @cert
@ -21,7 +18,7 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
["keyUsage", "cRLSign,keyCertSign", true],
]
@ca_cert = OpenSSL::TestUtils.issue_cert(
ca_subj, @ca_key, 1, now, now+3600, ca_exts, nil, nil, dgst)
ca_subj, @ca_key, 1, ca_exts, nil, nil)
cert_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA2")
@cert_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
@ -30,14 +27,14 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
["keyUsage", "cRLSign,keyCertSign", true],
]
@cert = OpenSSL::TestUtils.issue_cert(
cert_subj, @cert_key, 5, now, now+3600, cert_exts, @ca_cert, @ca_key, dgst)
cert_subj, @cert_key, 5, cert_exts, @ca_cert, @ca_key)
cert2_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCert")
@cert2_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
cert2_exts = [
]
@cert2 = OpenSSL::TestUtils.issue_cert(
cert2_subj, @cert2_key, 10, now, now+3600, cert2_exts, @cert, @cert_key, dgst)
cert2_subj, @cert2_key, 10, cert2_exts, @cert, @cert_key)
ocsp_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCAOCSP")
@ocsp_key = OpenSSL::TestUtils::TEST_KEY_RSA2048
@ -45,7 +42,7 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
["extendedKeyUsage", "OCSPSigning", true],
]
@ocsp_cert = OpenSSL::TestUtils.issue_cert(
ocsp_subj, @ocsp_key, 100, now, now+3600, ocsp_exts, @cert, @cert_key, "SHA256")
ocsp_subj, @ocsp_key, 100, ocsp_exts, @cert, @cert_key)
end
def test_new_certificate_id

Просмотреть файл

@ -259,18 +259,12 @@ module OpenSSL::TestPairM
def test_write_nonblock_no_exceptions
ssl_pair {|s1, s2|
n = 0
begin
n += write_nonblock_no_ex s1, "a" * 100000
n += write_nonblock_no_ex s1, "b" * 100000
n += write_nonblock_no_ex s1, "c" * 100000
n += write_nonblock_no_ex s1, "d" * 100000
n += write_nonblock_no_ex s1, "e" * 100000
n += write_nonblock_no_ex s1, "f" * 100000
rescue OpenSSL::SSL::SSLError => e
# on some platforms (maybe depend on OpenSSL version), writing to
# SSLSocket after SSL_ERROR_WANT_WRITE causes this error.
raise e if n == 0
end
n += write_nonblock_no_ex s1, "a" * 100000
n += write_nonblock_no_ex s1, "b" * 100000
n += write_nonblock_no_ex s1, "c" * 100000
n += write_nonblock_no_ex s1, "d" * 100000
n += write_nonblock_no_ex s1, "e" * 100000
n += write_nonblock_no_ex s1, "f" * 100000
s1.close
assert_equal(n, s2.read.length)
}

Просмотреть файл

@ -9,17 +9,13 @@ module OpenSSL
def setup
ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
now = Time.now
ca_exts = [
["basicConstraints","CA:TRUE",true],
["keyUsage","keyCertSign, cRLSign",true],
["subjectKeyIdentifier","hash",false],
["authorityKeyIdentifier","keyid:always",false],
]
@cacert = issue_cert(ca, TEST_KEY_RSA2048, 1, now, now+3600, ca_exts,
nil, nil, OpenSSL::Digest::SHA1.new)
@cacert = issue_cert(ca, TEST_KEY_RSA2048, 1, ca_exts, nil, nil)
inter_ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Intermediate CA")
inter_ca_key = OpenSSL::PKey.read <<-_EOS_
@ -39,17 +35,14 @@ FJx7d3f29gkzynCLJDkCQGQZlEZJC4vWmWJGRKJ24P6MyQn3VsPfErSKOg4lvyM3
Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
-----END RSA PRIVATE KEY-----
_EOS_
@inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, now, now+3600, ca_exts,
@cacert, TEST_KEY_RSA2048, OpenSSL::Digest::SHA1.new)
@inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, TEST_KEY_RSA2048)
exts = [
["keyUsage","digitalSignature",true],
["subjectKeyIdentifier","hash",false],
]
ee = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Ruby PKCS12 Test Certificate")
@mycert = issue_cert(ee, TEST_KEY_RSA1024, 3, now, now+3600, exts,
@inter_cacert, inter_ca_key, OpenSSL::Digest::SHA1.new)
@mycert = issue_cert(ee, TEST_KEY_RSA1024, 3, exts, @inter_cacert, inter_ca_key)
end
def test_create

Просмотреть файл

@ -11,24 +11,20 @@ class OpenSSL::TestPKCS7 < OpenSSL::TestCase
ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
now = Time.now
ca_exts = [
["basicConstraints","CA:TRUE",true],
["keyUsage","keyCertSign, cRLSign",true],
["subjectKeyIdentifier","hash",false],
["authorityKeyIdentifier","keyid:always",false],
]
@ca_cert = issue_cert(ca, @rsa2048, 1, now, now+3600, ca_exts,
nil, nil, OpenSSL::Digest::SHA1.new)
@ca_cert = issue_cert(ca, @rsa2048, 1, ca_exts, nil, nil)
ee_exts = [
["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true],
["authorityKeyIdentifier","keyid:always",false],
["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
]
@ee1_cert = issue_cert(ee1, @rsa1024, 2, now, now+1800, ee_exts,
@ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
@ee2_cert = issue_cert(ee2, @rsa1024, 3, now, now+1800, ee_exts,
@ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
@ee1_cert = issue_cert(ee1, @rsa1024, 2, ee_exts, @ca_cert, @rsa2048)
@ee2_cert = issue_cert(ee2, @rsa1024, 3, ee_exts, @ca_cert, @rsa2048)
end
def issue_cert(*args)

Просмотреть файл

@ -36,6 +36,26 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
end
end
def test_sign_verify
data = "Sign me!"
if defined?(OpenSSL::Digest::DSS1)
signature = DSA512.sign(OpenSSL::Digest::DSS1.new, data)
assert_equal true, DSA512.verify(OpenSSL::Digest::DSS1.new, signature, data)
end
return if OpenSSL::OPENSSL_VERSION_NUMBER <= 0x010000000
signature = DSA512.sign("SHA1", data)
assert_equal true, DSA512.verify("SHA1", signature, data)
signature0 = (<<~'end;').unpack("m")[0]
MCwCFH5h40plgU5Fh0Z4wvEEpz0eE9SnAhRPbkRB8ggsN/vsSEYMXvJwjGg/
6g==
end;
assert_equal true, DSA512.verify("SHA256", signature0, data)
signature1 = signature0.succ
assert_equal false, DSA512.verify("SHA256", signature1, data)
end
def test_sys_sign_verify
key = OpenSSL::TestUtils::TEST_KEY_DSA256
data = 'Sign me!'

Просмотреть файл

@ -73,6 +73,20 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
assert_raise(OpenSSL::PKey::ECError) { key2.check_key }
end
def test_sign_verify
data = "Sign me!"
signature = P256.sign("SHA1", data)
assert_equal true, P256.verify("SHA1", signature, data)
signature0 = (<<~'end;').unpack("m")[0]
MEQCIEOTY/hD7eI8a0qlzxkIt8LLZ8uwiaSfVbjX2dPAvN11AiAQdCYx56Fq
QdBp1B4sxJoA8jvODMMklMyBKVmudboA6A==
end;
assert_equal true, P256.verify("SHA256", signature0, data)
signature1 = signature0.succ
assert_equal false, P256.verify("SHA256", signature1, data)
end
def test_dsa_sign_verify
data1 = "foo"
data2 = "bar"
@ -244,6 +258,10 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
raise
end
assert_equal 0x040603.to_bn, point.to_bn(:uncompressed)
assert_equal 0x0306.to_bn, point.to_bn(:compressed)
assert_equal 0x070603.to_bn, point.to_bn(:hybrid)
assert_equal 0x040603.to_bn, point.to_bn
assert_equal true, point.on_curve?
point.invert! # 8.5

Просмотреть файл

@ -70,6 +70,21 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
end
end
def test_sign_verify
data = "Sign me!"
signature = RSA1024.sign("SHA1", data)
assert_equal true, RSA1024.verify("SHA1", signature, data)
signature0 = (<<~'end;').unpack("m")[0]
oLCgbprPvfhM4pjFQiDTFeWI9Sk+Og7Nh9TmIZ/xSxf2CGXQrptlwo7NQ28+
WA6YQo8jPH4hSuyWIM4Gz4qRYiYRkl5TDMUYob94zm8Si1HxEiS9354tzvqS
zS8MLW2BtNPuTubMxTItHGTnOzo9sUg0LAHVFt8kHG2NfKAw/gQ=
end;
assert_equal true, RSA1024.verify("SHA256", signature0, data)
signature1 = signature0.succ
assert_equal false, RSA1024.verify("SHA256", signature1, data)
end
def test_digest_state_irrelevant_sign
key = RSA1024
digest1 = OpenSSL::Digest::SHA1.new
@ -93,6 +108,13 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
assert(key.verify(digest2, sig, data))
end
def test_verify_empty_rsa
rsa = OpenSSL::PKey::RSA.new
assert_raise(OpenSSL::PKey::PKeyError, "[Bug #12783]") {
rsa.verify("SHA1", "a", "b")
}
end
def test_RSAPrivateKey
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(0),

Просмотреть файл

@ -394,14 +394,12 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
}
now = Time.now
exts = [
["keyUsage","keyEncipherment,digitalSignature",true],
["subjectAltName","DNS:localhost.localdomain",false],
["subjectAltName","IP:127.0.0.1",false],
]
@svr_cert = issue_cert(@svr, @svr_key, 4, now, now+1800, exts,
@ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
@svr_cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key)
start_server { |server, port|
server_connect(port) { |ssl|
assert(ssl.post_connection_check("localhost.localdomain"))
@ -417,13 +415,11 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
}
now = Time.now
exts = [
["keyUsage","keyEncipherment,digitalSignature",true],
["subjectAltName","DNS:*.localdomain",false],
]
@svr_cert = issue_cert(@svr, @svr_key, 5, now, now+1800, exts,
@ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
@svr_cert = issue_cert(@svr, @svr_key, 5, exts, @ca_cert, @ca_key)
start_server { |server, port|
server_connect(port) { |ssl|
assert(ssl.post_connection_check("localhost.localdomain"))
@ -656,7 +652,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
ssl.hostname = "foo.example.com"
ssl.connect
assert_match /^ADH-/, ssl.cipher[0], "the context returned by servername_cb is used"
assert_match (/^ADH-/), ssl.cipher[0], "the context returned by servername_cb is used"
assert_predicate ctx3, :frozen?
ensure
sock.close
@ -667,7 +663,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
ssl.hostname = "bar.example.com"
ssl.connect
assert_not_match /^A(EC)?DH-/, ssl.cipher[0], "the original context is used"
assert_not_match (/^A(EC)?DH-/), ssl.cipher[0], "the original context is used"
ensure
sock.close
end
@ -711,14 +707,12 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
def test_verify_hostname_on_connect
ctx_proc = proc { |ctx|
now = Time.now
exts = [
["keyUsage", "keyEncipherment,digitalSignature", true],
["subjectAltName", "DNS:a.example.com,DNS:*.b.example.com," \
"DNS:c*.example.com,DNS:d.*.example.com"],
]
ctx.cert = issue_cert(@svr, @svr_key, 4, now, now+1800, exts,
@ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
ctx.cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key)
ctx.key = @svr_key
}
@ -1252,6 +1246,18 @@ end
sock2.close
end
def test_freeze_calls_setup
bug = "[ruby/openssl#85]"
start_server(ignore_listener_error: true) { |server, port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
ctx.freeze
assert_raise(OpenSSL::SSL::SSLError, bug) {
server_connect(port, ctx)
}
}
end
private
def start_server_version(version, ctx_proc = nil,

Просмотреть файл

@ -11,7 +11,6 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
@dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
@ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
@ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
@ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
end
def issue_cert(*args)
@ -20,8 +19,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
def test_serial
[1, 2**32, 2**100].each{|s|
cert = issue_cert(@ca, @rsa2048, s, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, s, [], nil, nil)
assert_equal(s, cert.serial)
cert = OpenSSL::X509::Certificate.new(cert.to_der)
assert_equal(s, cert.serial)
@ -41,8 +39,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
[
[@rsa1024, sha1], [@rsa2048, sha1], [@dsa256, dsa_digest], [@dsa512, dsa_digest]
].each{|pk, digest|
cert = issue_cert(@ca, pk, 1, Time.now, Time.now+3600, exts,
nil, nil, digest)
cert = issue_cert(@ca, pk, 1, exts, nil, nil, digest: digest)
assert_equal(cert.extensions.sort_by(&:to_s)[2].value,
OpenSSL::TestUtils.get_subject_key_id(cert))
cert = OpenSSL::X509::Certificate.new(cert.to_der)
@ -52,27 +49,27 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
end
def test_validity
now = Time.now until now && now.usec != 0
cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
assert_not_equal(now, cert.not_before)
assert_not_equal(now+3600, cert.not_after)
now = Time.at(Time.now.to_i + 0.9)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil,
not_before: now, not_after: now+3600)
assert_equal(Time.at(now.to_i), cert.not_before)
assert_equal(Time.at(now.to_i+3600), cert.not_after)
now = Time.at(now.to_i)
cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil,
not_before: now, not_after: now+3600)
assert_equal(now.getutc, cert.not_before)
assert_equal((now+3600).getutc, cert.not_after)
now = Time.at(0)
cert = issue_cert(@ca, @rsa2048, 1, now, now, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil,
not_before: now, not_after: now)
assert_equal(now.getutc, cert.not_before)
assert_equal(now.getutc, cert.not_after)
now = Time.at(0x7fffffff)
cert = issue_cert(@ca, @rsa2048, 1, now, now, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil,
not_before: now, not_after: now)
assert_equal(now.getutc, cert.not_before)
assert_equal(now.getutc, cert.not_after)
end
@ -84,8 +81,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
["subjectKeyIdentifier","hash",false],
["authorityKeyIdentifier","keyid:always",false],
]
ca_cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, ca_exts,
nil, nil, OpenSSL::Digest::SHA1.new)
ca_cert = issue_cert(@ca, @rsa2048, 1, ca_exts, nil, nil)
ca_cert.extensions.each_with_index{|ext, i|
assert_equal(ca_exts[i].first, ext.oid)
assert_equal(ca_exts[i].last, ext.critical?)
@ -98,34 +94,16 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
["subjectAltName","email:ee1@ruby-lang.org",false],
]
ee1_cert = issue_cert(@ee1, @rsa1024, 2, Time.now, Time.now+1800, ee1_exts,
ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
ee1_cert = issue_cert(@ee1, @rsa1024, 2, ee1_exts, ca_cert, @rsa2048)
assert_equal(ca_cert.subject.to_der, ee1_cert.issuer.to_der)
ee1_cert.extensions.each_with_index{|ext, i|
assert_equal(ee1_exts[i].first, ext.oid)
assert_equal(ee1_exts[i].last, ext.critical?)
}
ee2_exts = [
["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true],
["subjectKeyIdentifier","hash",false],
["authorityKeyIdentifier","issuer:always",false],
["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
["subjectAltName","email:ee2@ruby-lang.org",false],
]
ee2_cert = issue_cert(@ee2, @rsa1024, 3, Time.now, Time.now+1800, ee2_exts,
ca_cert, @rsa2048, OpenSSL::Digest::MD5.new)
assert_equal(ca_cert.subject.to_der, ee2_cert.issuer.to_der)
ee2_cert.extensions.each_with_index{|ext, i|
assert_equal(ee2_exts[i].first, ext.oid)
assert_equal(ee2_exts[i].last, ext.critical?)
}
end
def test_sign_and_verify_rsa_sha1
cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil, digest: "sha1")
assert_equal(false, cert.verify(@rsa1024))
assert_equal(true, cert.verify(@rsa2048))
assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })
@ -135,8 +113,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
end
def test_sign_and_verify_rsa_md5
cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::MD5.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil, digest: "md5")
assert_equal(false, cert.verify(@rsa1024))
assert_equal(true, cert.verify(@rsa2048))
@ -148,8 +125,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
end
def test_sign_and_verify_dsa
cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::TestUtils::DSA_SIGNATURE_DIGEST.new)
cert = issue_cert(@ca, @dsa512, 1, [], nil, nil)
assert_equal(false, certificate_error_returns_false { cert.verify(@rsa1024) })
assert_equal(false, certificate_error_returns_false { cert.verify(@rsa2048) })
assert_equal(false, cert.verify(@dsa256))
@ -159,8 +135,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
end
def test_sign_and_verify_rsa_dss1
cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::DSS1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil, digest: OpenSSL::Digest::DSS1.new)
assert_equal(false, cert.verify(@rsa1024))
assert_equal(true, cert.verify(@rsa2048))
assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })
@ -172,27 +147,19 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
def test_sign_and_verify_dsa_md5
assert_raise(OpenSSL::X509::CertificateError){
issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::MD5.new)
issue_cert(@ca, @dsa512, 1, [], nil, nil, digest: "md5")
}
end
def test_dsig_algorithm_mismatch
assert_raise(OpenSSL::X509::CertificateError) do
issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::DSS1.new)
issue_cert(@ca, @rsa2048, 1, [], nil, nil, digest: OpenSSL::Digest::DSS1.new)
end if OpenSSL::OPENSSL_VERSION_NUMBER < 0x10001000 # [ruby-core:42949]
assert_raise(OpenSSL::X509::CertificateError) do
issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::MD5.new)
end
end
def test_dsa_with_sha2
begin
cert = issue_cert(@ca, @dsa256, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::SHA256.new)
cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha256")
assert_equal("dsa_with_SHA256", cert.signature_algorithm)
rescue OpenSSL::X509::CertificateError
# dsa_with_sha2 not supported. skip following test.
@ -201,14 +168,12 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
# TODO: need more tests for dsa + sha2
# SHA1 is allowed from OpenSSL 1.0.0 (0.9.8 requires DSS1)
cert = issue_cert(@ca, @dsa256, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha1")
assert_equal("dsaWithSHA1", cert.signature_algorithm)
end if defined?(OpenSSL::Digest::SHA256)
def test_check_private_key
cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
assert_equal(true, cert.check_private_key(@rsa2048))
end

Просмотреть файл

@ -25,8 +25,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
def test_basic
now = Time.at(Time.now.to_i)
cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
crl = issue_crl([], 1, now, now+1600, [],
cert, @rsa2048, OpenSSL::Digest::SHA1.new)
assert_equal(1, crl.version)
@ -63,8 +62,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
[4, now, 4],
[5, now, 5],
]
cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [],
cert, @rsa2048, OpenSSL::Digest::SHA1.new)
revoked = crl.revoked
@ -131,8 +129,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
["issuerAltName", "issuer:copy", false],
]
cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, cert_exts,
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, cert_exts, nil, nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, crl_exts,
cert, @rsa2048, OpenSSL::Digest::SHA1.new)
exts = crl.extensions
@ -168,8 +165,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
end
def test_crlnumber
cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, [],
cert, @rsa2048, OpenSSL::Digest::SHA1.new)
assert_match(1.to_s, crl.extensions[0].value)
@ -187,8 +183,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
end
def test_sign_and_verify
cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, [],
cert, @rsa2048, OpenSSL::Digest::SHA1.new)
assert_equal(false, crl.verify(@rsa1024))
@ -198,8 +193,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
crl.version = 0
assert_equal(false, crl.verify(@rsa2048))
cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
nil, nil, OpenSSL::TestUtils::DSA_SIGNATURE_DIGEST.new)
cert = issue_cert(@ca, @dsa512, 1, [], nil, nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, [],
cert, @dsa512, OpenSSL::TestUtils::DSA_SIGNATURE_DIGEST.new)
assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) })

Просмотреть файл

@ -345,13 +345,13 @@ class OpenSSL::TestX509Name < OpenSSL::TestCase
def test_hash
dn = "/DC=org/DC=ruby-lang/CN=www.ruby-lang.org"
name = OpenSSL::X509::Name.parse(dn)
d = Digest::MD5.digest(name.to_der)
d = OpenSSL::Digest::MD5.digest(name.to_der)
expected = (d[0].ord & 0xff) | (d[1].ord & 0xff) << 8 | (d[2].ord & 0xff) << 16 | (d[3].ord & 0xff) << 24
assert_equal(expected, name_hash(name))
#
dn = "/DC=org/DC=ruby-lang/CN=baz.ruby-lang.org"
name = OpenSSL::X509::Name.parse(dn)
d = Digest::MD5.digest(name.to_der)
d = OpenSSL::Digest::MD5.digest(name.to_der)
expected = (d[0].ord & 0xff) | (d[1].ord & 0xff) << 8 | (d[2].ord & 0xff) << 16 | (d[3].ord & 0xff) << 24
assert_equal(expected, name_hash(name))
end

Просмотреть файл

@ -34,7 +34,9 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase
end
def test_verify
now = Time.at(Time.now.to_i)
# OpenSSL uses time(2) while Time.now uses clock_gettime(CLOCK_REALTIME),
# and there may be difference.
now = Time.now - 3
ca_exts = [
["basicConstraints","CA:TRUE",true],
["keyUsage","cRLSign,keyCertSign",true],
@ -42,18 +44,15 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase
ee_exts = [
["keyUsage","keyEncipherment,digitalSignature",true],
]
ca1_cert = issue_cert(@ca1, @rsa2048, 1, now, now+3600, ca_exts,
nil, nil, OpenSSL::Digest::SHA1.new)
ca2_cert = issue_cert(@ca2, @rsa1024, 2, now, now+1800, ca_exts,
ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
ee1_cert = issue_cert(@ee1, @dsa256, 10, now, now+1800, ee_exts,
ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
ee2_cert = issue_cert(@ee2, @dsa512, 20, now, now+1800, ee_exts,
ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
ee3_cert = issue_cert(@ee2, @dsa512, 30, now-100, now-1, ee_exts,
ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
ee4_cert = issue_cert(@ee2, @dsa512, 40, now+1000, now+2000, ee_exts,
ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
ca1_cert = issue_cert(@ca1, @rsa2048, 1, ca_exts, nil, nil)
ca2_cert = issue_cert(@ca2, @rsa1024, 2, ca_exts, ca1_cert, @rsa2048,
not_after: now+1800)
ee1_cert = issue_cert(@ee1, @dsa256, 10, ee_exts, ca2_cert, @rsa1024)
ee2_cert = issue_cert(@ee2, @dsa512, 20, ee_exts, ca2_cert, @rsa1024)
ee3_cert = issue_cert(@ee2, @dsa512, 30, ee_exts, ca2_cert, @rsa1024,
not_before: now-100, not_after: now-1)
ee4_cert = issue_cert(@ee2, @dsa512, 40, ee_exts, ca2_cert, @rsa1024,
not_before: now+1000, not_after: now+2000,)
revoke_info = []
crl1 = issue_crl(revoke_info, 1, now, now+1800, [],
@ -195,8 +194,7 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase
def test_set_errors
now = Time.now
ca1_cert = issue_cert(@ca1, @rsa2048, 1, now, now+3600, [],
nil, nil, OpenSSL::Digest::SHA1.new)
ca1_cert = issue_cert(@ca1, @rsa2048, 1, [], nil, nil)
store = OpenSSL::X509::Store.new
store.add_cert(ca1_cert)
assert_raise(OpenSSL::X509::StoreError){

Просмотреть файл

@ -10,7 +10,6 @@ rescue LoadError
end
require "test/unit"
require "digest/md5"
require 'tempfile'
require "rbconfig"
require "socket"
@ -131,8 +130,8 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
module_function
def issue_cert(dn, key, serial, not_before, not_after, extensions,
issuer, issuer_key, digest)
def issue_cert(dn, key, serial, extensions, issuer, issuer_key,
not_before: nil, not_after: nil, digest: nil)
cert = OpenSSL::X509::Certificate.new
issuer = cert unless issuer
issuer_key = key unless issuer_key
@ -141,14 +140,16 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
cert.subject = dn
cert.issuer = issuer.subject
cert.public_key = key.public_key
cert.not_before = not_before
cert.not_after = not_after
now = Time.now
cert.not_before = not_before || now - 3600
cert.not_after = not_after || now + 3600
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = cert
ef.issuer_certificate = issuer
extensions.each{|oid, value, critical|
cert.add_extension(ef.create_extension(oid, value, critical))
}
digest ||= OpenSSL::PKey::DSA === issuer_key ? DSA_SIGNATURE_DIGEST.new : "sha256"
cert.sign(issuer_key, digest)
cert
end
@ -217,7 +218,6 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
@ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
@svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
@cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
now = Time.at(Time.now.to_i)
ca_exts = [
["basicConstraints","CA:TRUE",true],
["keyUsage","cRLSign,keyCertSign",true],
@ -225,9 +225,9 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
ee_exts = [
["keyUsage","keyEncipherment,digitalSignature",true],
]
@ca_cert = issue_cert(@ca, @ca_key, 1, now, now+3600, ca_exts, nil, nil, OpenSSL::Digest::SHA1.new)
@svr_cert = issue_cert(@svr, @svr_key, 2, now, now+1800, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
@cli_cert = issue_cert(@cli, @cli_key, 3, now, now+1800, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
@ca_cert = issue_cert(@ca, @ca_key, 1, ca_exts, nil, nil)
@svr_cert = issue_cert(@svr, @svr_key, 2, ee_exts, @ca_cert, @ca_key)
@cli_cert = issue_cert(@cli, @cli_key, 3, ee_exts, @ca_cert, @ca_key)
@server = nil
end