Import Ruby/OpenSSL 2.1.0.beta2. The full commit log since commit
e72d960db262 which was imported by r60013 can be found at:

	https://github.com/ruby/openssl/compare/e72d960db262...v2.1.0.beta2

----------------------------------------------------------------
Kazuki Yamaguchi (26):
      bn: use ALLOCV() macro instead of xmalloc()
      appveyor.yml: remove 'openssl version' line
      test/test_ssl_session: skip tests for session_remove_cb
      x509ext: implement X509::Extension#==
      x509attr: implement X509::Attribute#==
      x509cert: implement X509::Certificate#==
      x509revoked: add missing X509::Revoked#to_der
      x509crl, x509revoked: implement X509::{CRL,Revoked}#==
      x509req: implement X509::Request#==
      ssl: extract rb_intern("call")
      cipher: disallow setting AAD for non-AEAD ciphers
      test/test_cipher: fix test_non_aead_cipher_set_auth_data failure
      ssl: fix conflict of options in SSLContext#set_params
      buffering: let #write accept multiple arguments
      pkey: make pkey_check_public_key() non-static
      x509cert, x509crl, x509req, ns_spki: check sanity of public key
      test/envutil: port assert_warning from Ruby trunk
      test/utils: remove a pointless .public_key call in issue_cert
      ssl: add SSLContext#add_certificate
      test/test_ssl: fix test_security_level
      Drop support for LibreSSL 2.4
      kdf: add HKDF support
      test/test_x509cert: fix flaky test
      test/test_x509crl: fix random failure
      History.md: fix a typo
      Ruby/OpenSSL 2.1.0.beta2

Mark Wright (1):
      Fix build failure against OpenSSL 1.1 built with no-deprecated Thanks rhenium for the code review and fixes.

Peter Karman (1):
      Add RSA sign_pss() and verify_pss() methods

aeris (1):
      TLS Fallback Signaling Cipher Suite Value

kazu (1):
      Use caller with length to reduce unused strings

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60907 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
rhe 2017-11-25 14:12:08 +00:00
Родитель 55953e374d
Коммит a55320b093
32 изменённых файлов: 1020 добавлений и 116 удалений

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

@ -1,18 +1,21 @@
Version 2.1.0.beta1
Version 2.1.0.beta2
===================
Notable changes
---------------
* Support for OpenSSL versions before 1.0.1 is removed.
* Support for OpenSSL versions before 1.0.1 and LibreSSL versions before 2.5
is removed.
[[GitHub #86]](https://github.com/ruby/openssl/pull/86)
* OpenSSL::BN#negative?, #+@, and #-@ are added.
* OpenSSL::SSL::SSLSocket#connect raises a more informative exception when
certificate verification fails.
[[GitHub #99]](https://github.com/ruby/openssl/pull/99)
* OpenSSL::KDF module is newly added. Support for scrypt is added.
* OpenSSL::KDF module is newly added. In addition to PBKDF2-HMAC that has moved
from OpenSSL::PKCS5, scrypt and HKDF are supported.
[[GitHub #109]](https://github.com/ruby/openssl/pull/109)
* OpenSSL.fips_mode is added. We have had the setter, but not the getter.
[[GitHub #173]](https://github.com/ruby/openssl/pull/173)
* OpenSSL.fips_mode is added. We had the setter, but not the getter.
[[GitHub #125]](https://github.com/ruby/openssl/pull/125)
* OpenSSL::OCSP::Request#signed? is added.
* OpenSSL::ASN1 handles the indefinite length form better. OpenSSL::ASN1.decode
@ -22,11 +25,31 @@ Notable changes
* OpenSSL::X509::Name#add_entry now accepts two additional keyword arguments
'loc' and 'set'.
[[GitHub #94]](https://github.com/ruby/openssl/issues/94)
* OpenSSL::SSL::SSLContext#min_version= and #max_version= are added.
* OpenSSL::SSL::SSLContext#min_version= and #max_version= are added to replace
#ssl_version= that was built on top of the deprecated OpenSSL C API. Use of
that method and the constant OpenSSL::SSL::SSLContext::METHODS is now
deprecated.
[[GitHub #142]](https://github.com/ruby/openssl/pull/142)
* OpenSSL::X509::Name#to_utf8 is added.
[[GitHub #26]](https://github.com/ruby/openssl/issues/26)
[[GitHub #143]](https://github.com/ruby/openssl/pull/143)
* OpenSSL::X509::{Extension,Attribute,Certificate,CRL,Revoked,Request} can be
compared with == operator.
[[GitHub #161]](https://github.com/ruby/openssl/pull/161)
* TLS Fallback Signaling Cipher Suite Value (SCSV) support is added.
[[GitHub #165]](https://github.com/ruby/openssl/pull/165)
* Build failure with OpenSSL 1.1 built with no-deprecated is fixed.
[[GitHub #160]](https://github.com/ruby/openssl/pull/160)
* OpenSSL::Buffering#write accepts an arbitrary number of arguments.
[[Feature #9323]](https://bugs.ruby-lang.org/issues/9323)
[[GitHub #162]](https://github.com/ruby/openssl/pull/162)
* OpenSSL::PKey::RSA#sign_pss and #verify_pss are added. They perform RSA-PSS
signature and verification.
[[GitHub #75]](https://github.com/ruby/openssl/issues/75)
[[GitHub #76]](https://github.com/ruby/openssl/pull/76)
[[GitHub #169]](https://github.com/ruby/openssl/pull/169)
* OpenSSL::SSL::SSLContext#add_certificate is added.
[[GitHub #167]](https://github.com/ruby/openssl/pull/167)
Version 2.0.6
@ -201,7 +224,7 @@ Notable changes
- 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.
OpenSSL::SSL::SSLContext#set_params.
[[GH ruby/openssl#60]](https://github.com/ruby/openssl/pull/60)
Removals

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

@ -340,9 +340,10 @@ module OpenSSL::Buffering
# converted using +.to_s+ method. Returns the number of bytes written.
def write(*s)
s = s.size == 1 ? s[0] : s.join("")
do_write(s)
s.bytesize
s.inject(0) do |written, str|
do_write(str)
written + str.bytesize
end
end
##

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

@ -41,6 +41,11 @@ module OpenSSL
end
class Extension
def ==(other)
return false unless Extension === other
to_der == other.to_der
end
def to_s # "oid = critical, value"
str = self.oid
str << " = "
@ -160,6 +165,13 @@ module OpenSSL
end
end
class Attribute
def ==(other)
return false unless Attribute === other
to_der == other.to_der
end
end
class StoreContext
def cleanup
warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE
@ -178,5 +190,26 @@ module OpenSSL
}
end
end
class CRL
def ==(other)
return false unless CRL === other
to_der == other.to_der
end
end
class Revoked
def ==(other)
return false unless Revoked === other
to_der == other.to_der
end
end
class Request
def ==(other)
return false unless Request === other
to_der == other.to_der
end
end
end
end

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

@ -1,16 +1,16 @@
# -*- encoding: utf-8 -*-
# stub: openssl 2.1.0.beta1 ruby lib
# stub: openssl 2.1.0.beta2 ruby lib
# stub: ext/openssl/extconf.rb
Gem::Specification.new do |s|
s.name = "openssl".freeze
s.version = "2.1.0.beta1"
s.version = "2.1.0.beta2"
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1".freeze) if s.respond_to? :required_rubygems_version=
s.metadata = { "msys2_mingw_dependencies" => "openssl" } if s.respond_to? :metadata=
s.require_paths = ["lib".freeze]
s.authors = ["Martin Bosslet".freeze, "SHIBATA Hiroshi".freeze, "Zachary Scott".freeze, "Kazuki Yamaguchi".freeze]
s.date = "2017-09-24"
s.date = "2017-11-25"
s.description = "It wraps the OpenSSL library.".freeze
s.email = ["ruby-core@ruby-lang.org".freeze]
s.extensions = ["ext/openssl/extconf.rb".freeze]
@ -20,7 +20,7 @@ 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.13".freeze
s.rubygems_version = "2.7.2".freeze
s.summary = "OpenSSL provides SSL, TLS and general purpose cryptography.".freeze
if s.respond_to? :specification_version then

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

@ -209,6 +209,10 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
# define X509_get0_notAfter(x) X509_get_notAfter(x)
# define X509_CRL_get0_lastUpdate(x) X509_CRL_get_lastUpdate(x)
# define X509_CRL_get0_nextUpdate(x) X509_CRL_get_nextUpdate(x)
# define X509_set1_notBefore(x, t) X509_set_notBefore(x, t)
# define X509_set1_notAfter(x, t) X509_set_notAfter(x, t)
# define X509_CRL_set1_lastUpdate(x, t) X509_CRL_set_lastUpdate(x, t)
# define X509_CRL_set1_nextUpdate(x, t) X509_CRL_set_nextUpdate(x, t)
#endif
#if !defined(HAVE_SSL_SESSION_GET_PROTOCOL_VERSION)

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

@ -1109,25 +1109,14 @@ Init_openssl(void)
/*
* Init all digests, ciphers
*/
/* CRYPTO_malloc_init(); */
/* ENGINE_load_builtin_engines(); */
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
if (!OPENSSL_init_ssl(0, NULL))
rb_raise(rb_eRuntimeError, "OPENSSL_init_ssl");
#else
OpenSSL_add_ssl_algorithms();
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
SSL_load_error_strings();
/*
* FIXME:
* On unload do:
*/
#if 0
CONF_modules_unload(1);
destroy_ui_method();
EVP_cleanup();
ENGINE_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_remove_state(0);
ERR_free_strings();
#endif
/*
@ -1149,7 +1138,11 @@ Init_openssl(void)
/*
* Version of OpenSSL the ruby OpenSSL extension is running with
*/
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
#else
rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
#endif
/*
* Version number of OpenSSL the ruby OpenSSL extension was built with

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

@ -35,6 +35,11 @@
#if !defined(OPENSSL_NO_OCSP)
# include <openssl/ocsp.h>
#endif
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/evp.h>
#include <openssl/dh.h>
/*
* Common Module

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

@ -979,20 +979,20 @@ static VALUE
ossl_bn_hash(VALUE self)
{
BIGNUM *bn;
VALUE hash;
VALUE tmp, hash;
unsigned char *buf;
int len;
GetBN(self, bn);
len = BN_num_bytes(bn);
buf = xmalloc(len);
buf = ALLOCV(tmp, len);
if (BN_bn2bin(bn, buf) != len) {
xfree(buf);
ossl_raise(eBNError, NULL);
ALLOCV_END(tmp);
ossl_raise(eBNError, "BN_bn2bin");
}
hash = ST2FIX(rb_memhash(buf, len));
xfree(buf);
ALLOCV_END(tmp);
return hash;
}

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

@ -508,7 +508,7 @@ ossl_cipher_set_iv(VALUE self, VALUE iv)
StringValue(iv);
GetCipher(self, ctx);
if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER)
if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)
iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
if (!iv_len)
iv_len = EVP_CIPHER_CTX_iv_length(ctx);
@ -535,7 +535,7 @@ ossl_cipher_is_authenticated(VALUE self)
GetCipher(self, ctx);
return (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
return (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
}
/*
@ -569,6 +569,8 @@ ossl_cipher_set_auth_data(VALUE self, VALUE data)
in_len = RSTRING_LEN(data);
GetCipher(self, ctx);
if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
ossl_raise(eCipherError, "AEAD not supported by this cipher");
if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len))
ossl_raise(eCipherError, "couldn't set additional authenticated data");
@ -606,7 +608,7 @@ ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self)
GetCipher(self, ctx);
if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
ossl_raise(eCipherError, "authentication tag not supported by this cipher");
ret = rb_str_new(NULL, tag_len);
@ -641,7 +643,7 @@ ossl_cipher_set_auth_tag(VALUE self, VALUE vtag)
tag_len = RSTRING_LENINT(vtag);
GetCipher(self, ctx);
if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
ossl_raise(eCipherError, "authentication tag not supported by this cipher");
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, tag))
@ -668,7 +670,7 @@ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen)
EVP_CIPHER_CTX *ctx;
GetCipher(self, ctx);
if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
ossl_raise(eCipherError, "AEAD not supported by this cipher");
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, NULL))
@ -695,7 +697,7 @@ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length)
EVP_CIPHER_CTX *ctx;
GetCipher(self, ctx);
if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
ossl_raise(eCipherError, "cipher does not support AEAD");
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL))
@ -786,7 +788,7 @@ ossl_cipher_iv_length(VALUE self)
int len = 0;
GetCipher(self, ctx);
if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER)
if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)
len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
if (!len)
len = EVP_CIPHER_CTX_iv_length(ctx);

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

@ -46,13 +46,25 @@ VALUE eEngineError;
/*
* Private
*/
#define OSSL_ENGINE_LOAD_IF_MATCH(x) \
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
#define OSSL_ENGINE_LOAD_IF_MATCH(engine_name, x) \
do{\
if(!strcmp(#x, RSTRING_PTR(name))){\
ENGINE_load_##x();\
if(!strcmp(#engine_name, RSTRING_PTR(name))){\
if (OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_##x, NULL))\
return Qtrue;\
else\
ossl_raise(eEngineError, "OPENSSL_init_crypto"); \
}\
}while(0)
#else
#define OSSL_ENGINE_LOAD_IF_MATCH(engine_name, x) \
do{\
if(!strcmp(#engine_name, RSTRING_PTR(name))){\
ENGINE_load_##engine_name();\
return Qtrue;\
}\
}while(0)
#endif
static void
ossl_engine_free(void *engine)
@ -94,55 +106,55 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
StringValueCStr(name);
#ifndef OPENSSL_NO_STATIC_ENGINE
#if HAVE_ENGINE_LOAD_DYNAMIC
OSSL_ENGINE_LOAD_IF_MATCH(dynamic);
OSSL_ENGINE_LOAD_IF_MATCH(dynamic, DYNAMIC);
#endif
#if HAVE_ENGINE_LOAD_4758CCA
OSSL_ENGINE_LOAD_IF_MATCH(4758cca);
OSSL_ENGINE_LOAD_IF_MATCH(4758cca, 4758CCA);
#endif
#if HAVE_ENGINE_LOAD_AEP
OSSL_ENGINE_LOAD_IF_MATCH(aep);
OSSL_ENGINE_LOAD_IF_MATCH(aep, AEP);
#endif
#if HAVE_ENGINE_LOAD_ATALLA
OSSL_ENGINE_LOAD_IF_MATCH(atalla);
OSSL_ENGINE_LOAD_IF_MATCH(atalla, ATALLA);
#endif
#if HAVE_ENGINE_LOAD_CHIL
OSSL_ENGINE_LOAD_IF_MATCH(chil);
OSSL_ENGINE_LOAD_IF_MATCH(chil, CHIL);
#endif
#if HAVE_ENGINE_LOAD_CSWIFT
OSSL_ENGINE_LOAD_IF_MATCH(cswift);
OSSL_ENGINE_LOAD_IF_MATCH(cswift, CSWIFT);
#endif
#if HAVE_ENGINE_LOAD_NURON
OSSL_ENGINE_LOAD_IF_MATCH(nuron);
OSSL_ENGINE_LOAD_IF_MATCH(nuron, NURON);
#endif
#if HAVE_ENGINE_LOAD_SUREWARE
OSSL_ENGINE_LOAD_IF_MATCH(sureware);
OSSL_ENGINE_LOAD_IF_MATCH(sureware, SUREWARE);
#endif
#if HAVE_ENGINE_LOAD_UBSEC
OSSL_ENGINE_LOAD_IF_MATCH(ubsec);
OSSL_ENGINE_LOAD_IF_MATCH(ubsec, UBSEC);
#endif
#if HAVE_ENGINE_LOAD_PADLOCK
OSSL_ENGINE_LOAD_IF_MATCH(padlock);
OSSL_ENGINE_LOAD_IF_MATCH(padlock, PADLOCK);
#endif
#if HAVE_ENGINE_LOAD_CAPI
OSSL_ENGINE_LOAD_IF_MATCH(capi);
OSSL_ENGINE_LOAD_IF_MATCH(capi, CAPI);
#endif
#if HAVE_ENGINE_LOAD_GMP
OSSL_ENGINE_LOAD_IF_MATCH(gmp);
OSSL_ENGINE_LOAD_IF_MATCH(gmp, GMP);
#endif
#if HAVE_ENGINE_LOAD_GOST
OSSL_ENGINE_LOAD_IF_MATCH(gost);
OSSL_ENGINE_LOAD_IF_MATCH(gost, GOST);
#endif
#if HAVE_ENGINE_LOAD_CRYPTODEV
OSSL_ENGINE_LOAD_IF_MATCH(cryptodev);
OSSL_ENGINE_LOAD_IF_MATCH(cryptodev, CRYPTODEV);
#endif
#if HAVE_ENGINE_LOAD_AESNI
OSSL_ENGINE_LOAD_IF_MATCH(aesni);
OSSL_ENGINE_LOAD_IF_MATCH(aesni, AESNI);
#endif
#endif
#ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO
OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto);
OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto, OPENBSD_DEV_CRYPTO);
#endif
OSSL_ENGINE_LOAD_IF_MATCH(openssl);
OSSL_ENGINE_LOAD_IF_MATCH(openssl, OPENSSL);
rb_warning("no such builtin loader for `%"PRIsVALUE"'", name);
return Qnil;
#endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
@ -160,7 +172,9 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
static VALUE
ossl_engine_s_cleanup(VALUE self)
{
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000
ENGINE_cleanup();
#endif
return Qnil;
}

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

@ -3,6 +3,9 @@
* Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors
*/
#include "ossl.h"
#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
# include <openssl/kdf.h>
#endif
static VALUE mKDF, eKDF;
@ -138,6 +141,97 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self)
}
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
/*
* call-seq:
* KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String
*
* HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as specified in
* {RFC 5869}[https://tools.ietf.org/html/rfc5869].
*
* New in OpenSSL 1.1.0.
*
* === Parameters
* _ikm_::
* The input keying material.
* _salt_::
* The salt.
* _info_::
* The context and application specific information.
* _length_::
* The output length in octets. Must be <= <tt>255 * HashLen</tt>, where
* HashLen is the length of the hash function output in octets.
* _hash_::
* The hash function.
*/
static VALUE
kdf_hkdf(int argc, VALUE *argv, VALUE self)
{
VALUE ikm, salt, info, opts, kwargs[4], str;
static ID kwargs_ids[4];
int saltlen, ikmlen, infolen;
size_t len;
const EVP_MD *md;
EVP_PKEY_CTX *pctx;
if (!kwargs_ids[0]) {
kwargs_ids[0] = rb_intern_const("salt");
kwargs_ids[1] = rb_intern_const("info");
kwargs_ids[2] = rb_intern_const("length");
kwargs_ids[3] = rb_intern_const("hash");
}
rb_scan_args(argc, argv, "1:", &ikm, &opts);
rb_get_kwargs(opts, kwargs_ids, 4, 0, kwargs);
StringValue(ikm);
ikmlen = RSTRING_LENINT(ikm);
salt = StringValue(kwargs[0]);
saltlen = RSTRING_LENINT(salt);
info = StringValue(kwargs[1]);
infolen = RSTRING_LENINT(info);
len = (size_t)NUM2LONG(kwargs[2]);
if (len > LONG_MAX)
rb_raise(rb_eArgError, "length must be non-negative");
md = ossl_evp_get_digestbyname(kwargs[3]);
str = rb_str_new(NULL, (long)len);
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
if (!pctx)
ossl_raise(eKDF, "EVP_PKEY_CTX_new_id");
if (EVP_PKEY_derive_init(pctx) <= 0) {
EVP_PKEY_CTX_free(pctx);
ossl_raise(eKDF, "EVP_PKEY_derive_init");
}
if (EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0) {
EVP_PKEY_CTX_free(pctx);
ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_md");
}
if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, (unsigned char *)RSTRING_PTR(salt),
saltlen) <= 0) {
EVP_PKEY_CTX_free(pctx);
ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_salt");
}
if (EVP_PKEY_CTX_set1_hkdf_key(pctx, (unsigned char *)RSTRING_PTR(ikm),
ikmlen) <= 0) {
EVP_PKEY_CTX_free(pctx);
ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_key");
}
if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (unsigned char *)RSTRING_PTR(info),
infolen) <= 0) {
EVP_PKEY_CTX_free(pctx);
ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_info");
}
if (EVP_PKEY_derive(pctx, (unsigned char *)RSTRING_PTR(str), &len) <= 0) {
EVP_PKEY_CTX_free(pctx);
ossl_raise(eKDF, "EVP_PKEY_derive");
}
rb_str_set_len(str, (long)len);
EVP_PKEY_CTX_free(pctx);
return str;
}
#endif
void
Init_ossl_kdf(void)
{
@ -162,6 +256,7 @@ Init_ossl_kdf(void)
* * PKCS #5 PBKDF2 (Password-Based Key Derivation Function 2) in
* combination with HMAC
* * scrypt
* * HKDF
*
* == Examples
* === Generating a 128 bit key for a Cipher (e.g. AES)
@ -218,4 +313,7 @@ Init_ossl_kdf(void)
#if defined(HAVE_EVP_PBE_SCRYPT)
rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1);
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
rb_define_module_function(mKDF, "hkdf", kdf_hkdf, -1);
#endif
}

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

@ -208,12 +208,13 @@ static VALUE
ossl_spki_set_public_key(VALUE self, VALUE key)
{
NETSCAPE_SPKI *spki;
EVP_PKEY *pkey;
GetSPKI(self, spki);
if (!NETSCAPE_SPKI_set_pubkey(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
ossl_raise(eSPKIError, NULL);
}
pkey = GetPKeyPtr(key);
ossl_pkey_check_public_key(pkey);
if (!NETSCAPE_SPKI_set_pubkey(spki, pkey))
ossl_raise(eSPKIError, "NETSCAPE_SPKI_set_pubkey");
return key;
}
@ -307,17 +308,20 @@ static VALUE
ossl_spki_verify(VALUE self, VALUE key)
{
NETSCAPE_SPKI *spki;
EVP_PKEY *pkey;
GetSPKI(self, spki);
switch (NETSCAPE_SPKI_verify(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
case 0:
pkey = GetPKeyPtr(key);
ossl_pkey_check_public_key(pkey);
switch (NETSCAPE_SPKI_verify(spki, pkey)) {
case 0:
ossl_clear_error();
return Qfalse;
case 1:
case 1:
return Qtrue;
default:
ossl_raise(eSPKIError, NULL);
default:
ossl_raise(eSPKIError, "NETSCAPE_SPKI_verify");
}
return Qnil; /* dummy */
}
/* Document-class: OpenSSL::Netscape::SPKI

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

@ -163,8 +163,8 @@ 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
ossl_pkey_check_public_key(const EVP_PKEY *pkey)
{
void *ptr;
const BIGNUM *n, *e, *pubkey;
@ -172,7 +172,8 @@ pkey_check_public_key(EVP_PKEY *pkey)
if (EVP_PKEY_missing_parameters(pkey))
ossl_raise(ePKeyError, "parameters missing");
ptr = EVP_PKEY_get0(pkey);
/* OpenSSL < 1.1.0 takes non-const pointer */
ptr = EVP_PKEY_get0((EVP_PKEY *)pkey);
switch (EVP_PKEY_base_id(pkey)) {
case EVP_PKEY_RSA:
RSA_get0_key(ptr, &n, &e, NULL);
@ -352,7 +353,7 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
int siglen, result;
GetPKey(self, pkey);
pkey_check_public_key(pkey);
ossl_pkey_check_public_key(pkey);
md = ossl_evp_get_digestbyname(digest);
StringValue(sig);
siglen = RSTRING_LENINT(sig);

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

@ -44,6 +44,7 @@ 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 *);
void ossl_pkey_check_public_key(const EVP_PKEY *);
EVP_PKEY *GetPKeyPtr(VALUE);
EVP_PKEY *DupPKeyPtr(VALUE);
EVP_PKEY *GetPrivPKeyPtr(VALUE);

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

@ -536,6 +536,196 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
return str;
}
/*
* call-seq:
* rsa.sign_pss(digest, data, salt_length:, mgf1_hash:) -> String
*
* Signs _data_ using the Probabilistic Signature Scheme (RSA-PSS) and returns
* the calculated signature.
*
* RSAError will be raised if an error occurs.
*
* See #verify_pss for the verification operation.
*
* === Parameters
* _digest_::
* A String containing the message digest algorithm name.
* _data_::
* A String. The data to be signed.
* _salt_length_::
* The length in octets of the salt. Two special values are reserved:
* +:digest+ means the digest length, and +:max+ means the maximum possible
* length for the combination of the private key and the selected message
* digest algorithm.
* _mgf1_hash_::
* The hash algorithm used in MGF1 (the currently supported mask generation
* function (MGF)).
*
* === Example
* data = "Sign me!"
* pkey = OpenSSL::PKey::RSA.new(2048)
* signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256")
* pub_key = pkey.public_key
* puts pub_key.verify_pss("SHA256", signature, data,
* salt_length: :auto, mgf1_hash: "SHA256") # => true
*/
static VALUE
ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self)
{
VALUE digest, data, options, kwargs[2], signature;
static ID kwargs_ids[2];
EVP_PKEY *pkey;
EVP_PKEY_CTX *pkey_ctx;
const EVP_MD *md, *mgf1md;
EVP_MD_CTX *md_ctx;
size_t buf_len;
int salt_len;
if (!kwargs_ids[0]) {
kwargs_ids[0] = rb_intern_const("salt_length");
kwargs_ids[1] = rb_intern_const("mgf1_hash");
}
rb_scan_args(argc, argv, "2:", &digest, &data, &options);
rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
if (kwargs[0] == ID2SYM(rb_intern("max")))
salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */
else if (kwargs[0] == ID2SYM(rb_intern("digest")))
salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
else
salt_len = NUM2INT(kwargs[0]);
mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
pkey = GetPrivPKeyPtr(self);
buf_len = EVP_PKEY_size(pkey);
md = ossl_evp_get_digestbyname(digest);
StringValue(data);
signature = rb_str_new(NULL, (long)buf_len);
md_ctx = EVP_MD_CTX_new();
if (!md_ctx)
goto err;
if (EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
goto err;
if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
goto err;
if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
goto err;
if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
goto err;
if (EVP_DigestSignUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
goto err;
if (EVP_DigestSignFinal(md_ctx, (unsigned char *)RSTRING_PTR(signature), &buf_len) != 1)
goto err;
rb_str_set_len(signature, (long)buf_len);
EVP_MD_CTX_free(md_ctx);
return signature;
err:
EVP_MD_CTX_free(md_ctx);
ossl_raise(eRSAError, NULL);
}
/*
* call-seq:
* rsa.verify_pss(digest, signature, data, salt_length:, mgf1_hash:) -> true | false
*
* Verifies _data_ using the Probabilistic Signature Scheme (RSA-PSS).
*
* The return value is +true+ if the signature is valid, +false+ otherwise.
* RSAError will be raised if an error occurs.
*
* See #sign_pss for the signing operation and an example code.
*
* === Parameters
* _digest_::
* A String containing the message digest algorithm name.
* _data_::
* A String. The data to be signed.
* _salt_length_::
* The length in octets of the salt. Two special values are reserved:
* +:digest+ means the digest length, and +:auto+ means automatically
* determining the length based on the signature.
* _mgf1_hash_::
* The hash algorithm used in MGF1.
*/
static VALUE
ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self)
{
VALUE digest, signature, data, options, kwargs[2];
static ID kwargs_ids[2];
EVP_PKEY *pkey;
EVP_PKEY_CTX *pkey_ctx;
const EVP_MD *md, *mgf1md;
EVP_MD_CTX *md_ctx;
int result, salt_len;
if (!kwargs_ids[0]) {
kwargs_ids[0] = rb_intern_const("salt_length");
kwargs_ids[1] = rb_intern_const("mgf1_hash");
}
rb_scan_args(argc, argv, "3:", &digest, &signature, &data, &options);
rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
if (kwargs[0] == ID2SYM(rb_intern("auto")))
salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */
else if (kwargs[0] == ID2SYM(rb_intern("digest")))
salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
else
salt_len = NUM2INT(kwargs[0]);
mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
GetPKey(self, pkey);
md = ossl_evp_get_digestbyname(digest);
StringValue(signature);
StringValue(data);
md_ctx = EVP_MD_CTX_new();
if (!md_ctx)
goto err;
if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
goto err;
if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
goto err;
if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
goto err;
if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
goto err;
if (EVP_DigestVerifyUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
goto err;
result = EVP_DigestVerifyFinal(md_ctx,
(unsigned char *)RSTRING_PTR(signature),
RSTRING_LEN(signature));
switch (result) {
case 0:
ossl_clear_error();
EVP_MD_CTX_free(md_ctx);
return Qfalse;
case 1:
EVP_MD_CTX_free(md_ctx);
return Qtrue;
default:
goto err;
}
err:
EVP_MD_CTX_free(md_ctx);
ossl_raise(eRSAError, NULL);
}
/*
* call-seq:
* rsa.params => hash
@ -731,6 +921,8 @@ Init_ossl_rsa(void)
rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
rb_define_method(cRSA, "sign_pss", ossl_rsa_sign_pss, -1);
rb_define_method(cRSA, "verify_pss", ossl_rsa_verify_pss, -1);
DEF_OSSL_PKEY_BN(cRSA, rsa, n);
DEF_OSSL_PKEY_BN(cRSA, rsa, e);

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

@ -32,7 +32,7 @@ VALUE cSSLSocket;
static VALUE eSSLErrorWaitReadable;
static VALUE eSSLErrorWaitWritable;
static ID ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
id_npn_protocols_encoded;
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
@ -205,7 +205,7 @@ ossl_call_client_cert_cb(VALUE obj)
if (NIL_P(cb))
return Qnil;
ary = rb_funcall(cb, rb_intern("call"), 1, obj);
ary = rb_funcallv(cb, id_call, 1, &obj);
Check_Type(ary, T_ARRAY);
GetX509CertPtr(cert = rb_ary_entry(ary, 0));
GetPrivPKeyPtr(key = rb_ary_entry(ary, 1));
@ -248,8 +248,8 @@ ossl_call_tmp_dh_callback(struct tmp_dh_callback_args *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));
dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
INT2NUM(args->keylength));
pkey = GetPKeyPtr(dh);
if (EVP_PKEY_base_id(pkey) != args->type)
return NULL;
@ -374,12 +374,12 @@ ossl_call_session_get_cb(VALUE ary)
cb = rb_funcall(ssl_obj, rb_intern("session_get_cb"), 0);
if (NIL_P(cb)) return Qnil;
return rb_funcall(cb, rb_intern("call"), 1, ary);
return rb_funcallv(cb, id_call, 1, &ary);
}
/* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */
static SSL_SESSION *
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
#else
ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
@ -420,7 +420,7 @@ ossl_call_session_new_cb(VALUE ary)
cb = rb_funcall(ssl_obj, rb_intern("session_new_cb"), 0);
if (NIL_P(cb)) return Qnil;
return rb_funcall(cb, rb_intern("call"), 1, ary);
return rb_funcallv(cb, id_call, 1, &ary);
}
/* return 1 normal. return 0 removes the session */
@ -467,7 +467,7 @@ ossl_call_session_remove_cb(VALUE ary)
cb = rb_attr_get(sslctx_obj, id_i_session_remove_cb);
if (NIL_P(cb)) return Qnil;
return rb_funcall(cb, rb_intern("call"), 1, ary);
return rb_funcallv(cb, id_call, 1, &ary);
}
static void
@ -533,7 +533,7 @@ ossl_call_servername_cb(VALUE ary)
cb = rb_attr_get(sslctx_obj, id_i_servername_cb);
if (NIL_P(cb)) return Qnil;
ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary);
ret_obj = rb_funcallv(cb, id_call, 1, &ary);
if (rb_obj_is_kind_of(ret_obj, cSSLContext)) {
SSL *ssl;
SSL_CTX *ctx2;
@ -585,7 +585,7 @@ ssl_renegotiation_cb(const SSL *ssl)
cb = rb_attr_get(sslctx_obj, id_i_renegotiation_cb);
if (NIL_P(cb)) return;
(void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
rb_funcallv(cb, id_call, 1, &ssl_obj);
}
#if !defined(OPENSSL_NO_NEXTPROTONEG) || \
@ -635,7 +635,7 @@ npn_select_cb_common_i(VALUE tmp)
in += l;
}
selected = rb_funcall(args->cb, rb_intern("call"), 1, protocols);
selected = rb_funcallv(args->cb, id_call, 1, &protocols);
StringValue(selected);
len = RSTRING_LEN(selected);
if (len < 1 || len >= 256) {
@ -1193,6 +1193,134 @@ ossl_sslctx_set_security_level(VALUE self, VALUE value)
return value;
}
#ifdef SSL_MODE_SEND_FALLBACK_SCSV
/*
* call-seq:
* ctx.enable_fallback_scsv() => nil
*
* Activate TLS_FALLBACK_SCSV for this context.
* See RFC 7507.
*/
static VALUE
ossl_sslctx_enable_fallback_scsv(VALUE self)
{
SSL_CTX *ctx;
GetSSLCTX(self, ctx);
SSL_CTX_set_mode(ctx, SSL_MODE_SEND_FALLBACK_SCSV);
return Qnil;
}
#endif
/*
* call-seq:
* ctx.add_certificate(certiticate, pkey [, extra_certs]) -> self
*
* Adds a certificate to the context. _pkey_ must be a corresponding private
* key with _certificate_.
*
* Multiple certificates with different public key type can be added by
* repeated calls of this method, and OpenSSL will choose the most appropriate
* certificate during the handshake.
*
* #cert=, #key=, and #extra_chain_cert= are old accessor methods for setting
* certificate and internally call this method.
*
* === Parameters
* _certificate_::
* A certificate. An instance of OpenSSL::X509::Certificate.
* _pkey_::
* The private key for _certificate_. An instance of OpenSSL::PKey::PKey.
* _extra_certs_::
* Optional. An array of OpenSSL::X509::Certificate. When sending a
* certificate chain, the certificates specified by this are sent following
* _certificate_, in the order in the array.
*
* === Example
* rsa_cert = OpenSSL::X509::Certificate.new(...)
* rsa_pkey = OpenSSL::PKey.read(...)
* ca_intermediate_cert = OpenSSL::X509::Certificate.new(...)
* ctx.add_certificate(rsa_cert, rsa_pkey, [ca_intermediate_cert])
*
* ecdsa_cert = ...
* ecdsa_pkey = ...
* another_ca_cert = ...
* ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
*
* === Note
* OpenSSL before the version 1.0.2 could handle only one extra chain across
* all key types. Calling this method discards the chain set previously.
*/
static VALUE
ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
{
VALUE cert, key, extra_chain_ary;
SSL_CTX *ctx;
X509 *x509;
STACK_OF(X509) *extra_chain = NULL;
EVP_PKEY *pkey, *pub_pkey;
GetSSLCTX(self, ctx);
rb_scan_args(argc, argv, "21", &cert, &key, &extra_chain_ary);
rb_check_frozen(self);
x509 = GetX509CertPtr(cert);
pkey = GetPrivPKeyPtr(key);
/*
* The reference counter is bumped, and decremented immediately.
* X509_get0_pubkey() is only available in OpenSSL >= 1.1.0.
*/
pub_pkey = X509_get_pubkey(x509);
EVP_PKEY_free(pub_pkey);
if (!pub_pkey)
rb_raise(rb_eArgError, "certificate does not contain public key");
if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
rb_raise(rb_eArgError, "public key mismatch");
if (argc >= 3)
extra_chain = ossl_x509_ary2sk(extra_chain_ary);
if (!SSL_CTX_use_certificate(ctx, x509)) {
sk_X509_pop_free(extra_chain, X509_free);
ossl_raise(eSSLError, "SSL_CTX_use_certificate");
}
if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
sk_X509_pop_free(extra_chain, X509_free);
ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
}
if (extra_chain) {
#if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
sk_X509_pop_free(extra_chain, X509_free);
ossl_raise(eSSLError, "SSL_CTX_set0_chain");
}
#else
STACK_OF(X509) *orig_extra_chain;
X509 *x509_tmp;
/* First, clear the existing chain */
SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
rb_warning("SSL_CTX_set0_chain() is not available; " \
"clearing previously set certificate chain");
SSL_CTX_clear_extra_chain_certs(ctx);
}
while ((x509_tmp = sk_X509_shift(extra_chain))) {
/* Transfers ownership */
if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
X509_free(x509_tmp);
sk_X509_pop_free(extra_chain, X509_free);
ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
}
}
sk_X509_free(extra_chain);
#endif
}
return self;
}
/*
* call-seq:
* ctx.session_add(session) -> true | false
@ -2261,6 +2389,7 @@ Init_ossl_ssl(void)
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
#endif
id_call = rb_intern("call");
ID_callback_state = rb_intern("callback_state");
ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
@ -2324,11 +2453,17 @@ Init_ossl_ssl(void)
/*
* Context certificate
*
* The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
* It is recommended to use #add_certificate instead.
*/
rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
/*
* Context private key
*
* The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
* It is recommended to use #add_certificate instead.
*/
rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
@ -2402,6 +2537,9 @@ Init_ossl_ssl(void)
/*
* An Array of extra X509 certificates to be added to the certificate
* chain.
*
* The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
* It is recommended to use #add_certificate instead.
*/
rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
@ -2561,6 +2699,10 @@ Init_ossl_ssl(void)
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
#ifdef SSL_MODE_SEND_FALLBACK_SCSV
rb_define_method(cSSLContext, "enable_fallback_scsv", ossl_sslctx_enable_fallback_scsv, 0);
#endif
rb_define_method(cSSLContext, "add_certificate", ossl_sslctx_add_certificate, -1);
rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
rb_define_alias(cSSLContext, "freeze", "setup");

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

@ -440,7 +440,7 @@ ossl_x509_set_not_before(VALUE self, VALUE time)
GetX509(self, x509);
asn1time = ossl_x509_time_adjust(NULL, time);
if (!X509_set_notBefore(x509, asn1time)) {
if (!X509_set1_notBefore(x509, asn1time)) {
ASN1_TIME_free(asn1time);
ossl_raise(eX509CertError, "X509_set_notBefore");
}
@ -479,7 +479,7 @@ ossl_x509_set_not_after(VALUE self, VALUE time)
GetX509(self, x509);
asn1time = ossl_x509_time_adjust(NULL, time);
if (!X509_set_notAfter(x509, asn1time)) {
if (!X509_set1_notAfter(x509, asn1time)) {
ASN1_TIME_free(asn1time);
ossl_raise(eX509CertError, "X509_set_notAfter");
}
@ -508,18 +508,19 @@ ossl_x509_get_public_key(VALUE self)
/*
* call-seq:
* cert.public_key = key => key
* cert.public_key = key
*/
static VALUE
ossl_x509_set_public_key(VALUE self, VALUE key)
{
X509 *x509;
EVP_PKEY *pkey;
GetX509(self, x509);
if (!X509_set_pubkey(x509, GetPKeyPtr(key))) { /* DUPs pkey */
ossl_raise(eX509CertError, NULL);
}
pkey = GetPKeyPtr(key);
ossl_pkey_check_public_key(pkey);
if (!X509_set_pubkey(x509, pkey))
ossl_raise(eX509CertError, "X509_set_pubkey");
return key;
}
@ -557,9 +558,9 @@ ossl_x509_verify(VALUE self, VALUE key)
X509 *x509;
EVP_PKEY *pkey;
pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
GetX509(self, x509);
pkey = GetPKeyPtr(key);
ossl_pkey_check_public_key(pkey);
switch (X509_verify(x509, pkey)) {
case 1:
return Qtrue;
@ -683,6 +684,26 @@ ossl_x509_inspect(VALUE self)
ossl_x509_get_not_after(self));
}
/*
* call-seq:
* cert1 == cert2 -> true | false
*
* Compares the two certificates. Note that this takes into account all fields,
* not just the issuer name and the serial number.
*/
static VALUE
ossl_x509_eq(VALUE self, VALUE other)
{
X509 *a, *b;
GetX509(self, a);
if (!rb_obj_is_kind_of(other, cX509Cert))
return Qfalse;
GetX509(other, b);
return !X509_cmp(a, b) ? Qtrue : Qfalse;
}
/*
* INIT
*/
@ -821,4 +842,5 @@ Init_ossl_x509cert(void)
rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1);
rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1);
rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0);
rb_define_method(cX509Cert, "==", ossl_x509_eq, 1);
}

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

@ -226,7 +226,7 @@ ossl_x509crl_set_last_update(VALUE self, VALUE time)
GetX509CRL(self, crl);
asn1time = ossl_x509_time_adjust(NULL, time);
if (!X509_CRL_set_lastUpdate(crl, asn1time)) {
if (!X509_CRL_set1_lastUpdate(crl, asn1time)) {
ASN1_TIME_free(asn1time);
ossl_raise(eX509CRLError, "X509_CRL_set_lastUpdate");
}
@ -257,7 +257,7 @@ ossl_x509crl_set_next_update(VALUE self, VALUE time)
GetX509CRL(self, crl);
asn1time = ossl_x509_time_adjust(NULL, time);
if (!X509_CRL_set_nextUpdate(crl, asn1time)) {
if (!X509_CRL_set1_nextUpdate(crl, asn1time)) {
ASN1_TIME_free(asn1time);
ossl_raise(eX509CRLError, "X509_CRL_set_nextUpdate");
}
@ -359,9 +359,12 @@ static VALUE
ossl_x509crl_verify(VALUE self, VALUE key)
{
X509_CRL *crl;
EVP_PKEY *pkey;
GetX509CRL(self, crl);
switch (X509_CRL_verify(crl, GetPKeyPtr(key))) {
pkey = GetPKeyPtr(key);
ossl_pkey_check_public_key(pkey);
switch (X509_CRL_verify(crl, pkey)) {
case 1:
return Qtrue;
case 0:

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

@ -293,11 +293,10 @@ ossl_x509req_set_public_key(VALUE self, VALUE key)
EVP_PKEY *pkey;
GetX509Req(self, req);
pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
if (!X509_REQ_set_pubkey(req, pkey)) {
ossl_raise(eX509ReqError, NULL);
}
pkey = GetPKeyPtr(key);
ossl_pkey_check_public_key(pkey);
if (!X509_REQ_set_pubkey(req, pkey))
ossl_raise(eX509ReqError, "X509_REQ_set_pubkey");
return key;
}
@ -328,7 +327,8 @@ ossl_x509req_verify(VALUE self, VALUE key)
EVP_PKEY *pkey;
GetX509Req(self, req);
pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
pkey = GetPKeyPtr(key);
ossl_pkey_check_public_key(pkey);
switch (X509_REQ_verify(req, pkey)) {
case 1:
return Qtrue;

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

@ -249,6 +249,26 @@ ossl_x509revoked_add_extension(VALUE self, VALUE ext)
return ext;
}
static VALUE
ossl_x509revoked_to_der(VALUE self)
{
X509_REVOKED *rev;
VALUE str;
int len;
unsigned char *p;
GetX509Rev(self, rev);
len = i2d_X509_REVOKED(rev, NULL);
if (len <= 0)
ossl_raise(eX509RevError, "i2d_X509_REVOKED");
str = rb_str_new(NULL, len);
p = (unsigned char *)RSTRING_PTR(str);
if (i2d_X509_REVOKED(rev, &p) <= 0)
ossl_raise(eX509RevError, "i2d_X509_REVOKED");
ossl_str_adjust(str, p);
return str;
}
/*
* INIT
*/
@ -276,4 +296,5 @@ Init_ossl_x509revoked(void)
rb_define_method(cX509Rev, "extensions", ossl_x509revoked_get_extensions, 0);
rb_define_method(cX509Rev, "extensions=", ossl_x509revoked_set_extensions, 1);
rb_define_method(cX509Rev, "add_extension", ossl_x509revoked_add_extension, 1);
rb_define_method(cX509Rev, "to_der", ossl_x509revoked_to_der, 0);
}

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

@ -295,6 +295,13 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
assert_equal tag1, tag2
end
def test_non_aead_cipher_set_auth_data
assert_raise(OpenSSL::Cipher::CipherError) {
cipher = OpenSSL::Cipher.new("aes-128-cfb").encrypt
cipher.auth_data = "123"
}
end
private
def new_encryptor(algo, **kwargs)

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

@ -131,6 +131,48 @@ class OpenSSL::TestKDF < OpenSSL::TestCase
assert_equal(expected, OpenSSL::KDF.scrypt(pass, salt: salt, N: n, r: r, p: p, length: dklen))
end
def test_hkdf_rfc5869_test_case_1
pend "HKDF is not implemented" unless OpenSSL::KDF.respond_to?(:hkdf) # OpenSSL >= 1.1.0
hash = "sha256"
ikm = B("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")
salt = B("000102030405060708090a0b0c")
info = B("f0f1f2f3f4f5f6f7f8f9")
l = 42
okm = B("3cb25f25faacd57a90434f64d0362f2a" \
"2d2d0a90cf1a5a4c5db02d56ecc4c5bf" \
"34007208d5b887185865")
assert_equal(okm, OpenSSL::KDF.hkdf(ikm, salt: salt, info: info, length: l, hash: hash))
end
def test_hkdf_rfc5869_test_case_3
pend "HKDF is not implemented" unless OpenSSL::KDF.respond_to?(:hkdf) # OpenSSL >= 1.1.0
hash = "sha256"
ikm = B("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")
salt = B("")
info = B("")
l = 42
okm = B("8da4e775a563c18f715f802a063c5a31" \
"b8a11f5c5ee1879ec3454e5f3c738d2d" \
"9d201395faa4b61a96c8")
assert_equal(okm, OpenSSL::KDF.hkdf(ikm, salt: salt, info: info, length: l, hash: hash))
end
def test_hkdf_rfc5869_test_case_4
pend "HKDF is not implemented" unless OpenSSL::KDF.respond_to?(:hkdf) # OpenSSL >= 1.1.0
hash = "sha1"
ikm = B("0b0b0b0b0b0b0b0b0b0b0b")
salt = B("000102030405060708090a0b0c")
info = B("f0f1f2f3f4f5f6f7f8f9")
l = 42
okm = B("085a01ea1b10f36933068b56efa5ad81" \
"a4f14b822f5b091568a9cdd4f155fda2" \
"c22e422478d305f3f896")
assert_equal(okm, OpenSSL::KDF.hkdf(ikm, salt: salt, info: info, length: l, hash: hash))
end
private
def B(ary)

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

@ -122,12 +122,12 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
assert_equal true, req.verify([@cert], store, OpenSSL::OCSP::NOINTERN)
ret = req.verify([@cert], store)
if ret || openssl?(1, 0, 2) || libressl?(2, 4, 2)
if ret || openssl?(1, 0, 2)
assert_equal true, ret
else
# RT2560; OCSP_request_verify() does not find signer cert from 'certs' when
# OCSP_NOINTERN is not specified.
# fixed by OpenSSL 1.0.1j, 1.0.2 and LibreSSL 2.4.2
# fixed by OpenSSL 1.0.1j, 1.0.2
pend "RT2560: ocsp_req_find_signer"
end
@ -262,11 +262,6 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
bres.add_status(cid2, OpenSSL::OCSP::V_CERTSTATUS_REVOKED, OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, -400, -300, nil, [])
bres.add_status(cid2, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, nil, Time.now + 100, nil, nil)
if bres.responses[2].check_validity # thisUpdate is in future; must fail
# LibreSSL bug; skip for now
pend "OCSP_check_validity() is broken"
end
single1 = bres.responses[0]
assert_equal false, single1.check_validity
assert_equal false, single1.check_validity(30)
@ -275,6 +270,8 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
assert_equal true, single2.check_validity
assert_equal true, single2.check_validity(0, 500)
assert_equal false, single2.check_validity(0, 200)
single3 = bres.responses[2]
assert_equal false, single3.check_validity
end
def test_response

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

@ -362,6 +362,15 @@ module OpenSSL::TestPairM
}
end
def test_write_multiple_arguments
ssl_pair {|s1, s2|
str1 = "foo"; str2 = "bar"
assert_equal 6, s1.write(str1, str2)
s1.close
assert_equal "foobar", s2.read
}
end
def test_partial_tls_record_read_nonblock
ssl_pair { |s1, s2|
# the beginning of a TLS record

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

@ -113,6 +113,39 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
}
end
def test_sign_verify_pss
key = Fixtures.pkey("rsa1024")
data = "Sign me!"
invalid_data = "Sign me?"
signature = key.sign_pss("SHA256", data, salt_length: 20, mgf1_hash: "SHA1")
assert_equal 128, signature.bytesize
assert_equal true,
key.verify_pss("SHA256", signature, data, salt_length: 20, mgf1_hash: "SHA1")
assert_equal true,
key.verify_pss("SHA256", signature, data, salt_length: :auto, mgf1_hash: "SHA1")
assert_equal false,
key.verify_pss("SHA256", signature, invalid_data, salt_length: 20, mgf1_hash: "SHA1")
signature = key.sign_pss("SHA256", data, salt_length: :digest, mgf1_hash: "SHA1")
assert_equal true,
key.verify_pss("SHA256", signature, data, salt_length: 32, mgf1_hash: "SHA1")
assert_equal true,
key.verify_pss("SHA256", signature, data, salt_length: :auto, mgf1_hash: "SHA1")
assert_equal false,
key.verify_pss("SHA256", signature, data, salt_length: 20, mgf1_hash: "SHA1")
signature = key.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA1")
assert_equal true,
key.verify_pss("SHA256", signature, data, salt_length: 94, mgf1_hash: "SHA1")
assert_equal true,
key.verify_pss("SHA256", signature, data, salt_length: :auto, mgf1_hash: "SHA1")
assert_raise(OpenSSL::PKey::RSAError) {
key.sign_pss("SHA256", data, salt_length: 95, mgf1_hash: "SHA1")
}
end
def test_RSAPrivateKey
rsa1024 = Fixtures.pkey("rsa1024")
asn1 = OpenSSL::ASN1::Sequence([

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

@ -54,6 +54,87 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
end
def test_add_certificate
ctx_proc = -> ctx {
# Unset values set by start_server
ctx.cert = ctx.key = ctx.extra_chain_cert = nil
ctx.add_certificate(@svr_cert, @svr_key, [@ca_cert]) # RSA
}
start_server(ctx_proc: ctx_proc) do |port|
server_connect(port) { |ssl|
assert_equal @svr_cert.subject, ssl.peer_cert.subject
assert_equal [@svr_cert.subject, @ca_cert.subject],
ssl.peer_cert_chain.map(&:subject)
}
end
end
def test_add_certificate_multiple_certs
pend "EC is not supported" unless defined?(OpenSSL::PKey::EC)
pend "TLS 1.2 is not supported" unless tls12_supported?
# SSL_CTX_set0_chain() is needed for setting multiple certificate chains
add0_chain_supported = openssl?(1, 0, 2)
if add0_chain_supported
ca2_key = Fixtures.pkey("rsa1024")
ca2_exts = [
["basicConstraints", "CA:TRUE", true],
["keyUsage", "cRLSign, keyCertSign", true],
]
ca2_dn = OpenSSL::X509::Name.parse_rfc2253("CN=CA2")
ca2_cert = issue_cert(ca2_dn, ca2_key, 123, ca2_exts, nil, nil)
else
# Use the same CA as @svr_cert
ca2_key = @ca_key; ca2_cert = @ca_cert
end
ecdsa_key = Fixtures.pkey("p256")
exts = [
["keyUsage", "digitalSignature", false],
]
ecdsa_dn = OpenSSL::X509::Name.parse_rfc2253("CN=localhost2")
ecdsa_cert = issue_cert(ecdsa_dn, ecdsa_key, 456, exts, ca2_cert, ca2_key)
if !add0_chain_supported
# Testing the warning emitted when 'extra' chain is replaced
tctx = OpenSSL::SSL::SSLContext.new
tctx.add_certificate(@svr_cert, @svr_key, [@ca_cert])
assert_warning(/set0_chain/) {
tctx.add_certificate(ecdsa_cert, ecdsa_key, [ca2_cert])
}
end
ctx_proc = -> ctx {
# Unset values set by start_server
ctx.cert = ctx.key = ctx.extra_chain_cert = nil
ctx.ecdh_curves = "P-256" unless openssl?(1, 0, 2)
ctx.add_certificate(@svr_cert, @svr_key, [@ca_cert]) # RSA
EnvUtil.suppress_warning do # !add0_chain_supported
ctx.add_certificate(ecdsa_cert, ecdsa_key, [ca2_cert])
end
}
start_server(ctx_proc: ctx_proc) do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = :TLS1_2 # TODO: We need this to force certificate type
ctx.ciphers = "aECDSA"
server_connect(port, ctx) { |ssl|
assert_equal ecdsa_cert.subject, ssl.peer_cert.subject
assert_equal [ecdsa_cert.subject, ca2_cert.subject],
ssl.peer_cert_chain.map(&:subject)
}
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = :TLS1_2
ctx.ciphers = "aRSA"
server_connect(port, ctx) { |ssl|
assert_equal @svr_cert.subject, ssl.peer_cert.subject
assert_equal [@svr_cert.subject, @ca_cert.subject],
ssl.peer_cert_chain.map(&:subject)
}
end
end
def test_sysread_and_syswrite
start_server { |port|
server_connect(port) { |ssl|
@ -1222,6 +1303,59 @@ end
end
end
def test_fallback_scsv
pend "Fallback SCSV is not supported" unless OpenSSL::SSL::SSLContext.method_defined?( :enable_fallback_scsv)
start_server do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
# Here is OK
# TLS1.2 supported and this is what we ask the first time
server_connect(port, ctx)
end
ctx_proc = proc { |ctx|
ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION
}
start_server(ctx_proc: ctx_proc) do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.enable_fallback_scsv
ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION
# Here is OK too
# TLS1.2 not supported, fallback to TLS1.1 and signaling the fallback
# Server doesn't support better, so connection OK
server_connect(port, ctx)
end
# Here is not OK
# TLS1.2 is supported, fallback to TLS1.1 (downgrade attack) and signaling the fallback
# Server support better, so refuse the connection
sock1, sock2 = socketpair
begin
ctx1 = OpenSSL::SSL::SSLContext.new
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.enable_fallback_scsv
ctx2.max_version = OpenSSL::SSL::TLS1_1_VERSION
s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2)
t = Thread.new {
assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback/) {
s2.connect
}
}
assert_raise_with_message(OpenSSL::SSL::SSLError, /inappropriate fallback/) {
s1.accept
}
assert t.join
ensure
sock1.close
sock2.close
end
end
def test_dh_callback
pend "TLS 1.2 is not supported" unless tls12_supported?
@ -1336,11 +1470,24 @@ end
return
end
assert_equal(1, ctx.security_level)
# assert_raise(OpenSSL::SSL::SSLError) { ctx.key = Fixtures.pkey("dsa512") }
# ctx.key = Fixtures.pkey("rsa1024")
# ctx.security_level = 2
# assert_raise(OpenSSL::SSL::SSLError) { ctx.key = Fixtures.pkey("rsa1024") }
pend "FIXME: SSLContext#key= currently does not raise because SSL_CTX_use_certificate() is delayed"
dsa512 = Fixtures.pkey("dsa512")
dsa512_cert = issue_cert(@svr, dsa512, 50, [], @ca_cert, @ca_key)
rsa1024 = Fixtures.pkey("rsa1024")
rsa1024_cert = issue_cert(@svr, rsa1024, 51, [], @ca_cert, @ca_key)
assert_raise(OpenSSL::SSL::SSLError) {
# 512 bit DSA key is rejected because it offers < 80 bits of security
ctx.add_certificate(dsa512_cert, dsa512)
}
assert_nothing_raised {
ctx.add_certificate(rsa1024_cert, rsa1024)
}
ctx.security_level = 2
assert_raise(OpenSSL::SSL::SSLError) {
# < 112 bits of security
ctx.add_certificate(rsa1024_cert, rsa1024)
}
end
def test_dup

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

@ -62,6 +62,23 @@ class OpenSSL::TestX509Attribute < OpenSSL::TestCase
attr = OpenSSL::X509::Attribute.new("challengePassword", val)
assert_equal(attr.to_der, attr.dup.to_der)
end
def test_eq
val1 = OpenSSL::ASN1::Set([
OpenSSL::ASN1::UTF8String("abc123")
])
attr1 = OpenSSL::X509::Attribute.new("challengePassword", val1)
attr2 = OpenSSL::X509::Attribute.new("challengePassword", val1)
ef = OpenSSL::X509::ExtensionFactory.new
val2 = OpenSSL::ASN1::Set.new([OpenSSL::ASN1::Sequence.new([
ef.create_extension("keyUsage", "keyCertSign", true)
])])
attr3 = OpenSSL::X509::Attribute.new("extReq", val2)
assert_equal false, attr1 == 12345
assert_equal true, attr1 == attr2
assert_equal false, attr1 == attr3
end
end
end

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

@ -169,6 +169,26 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
}
end
def test_eq
now = Time.now
cacert = issue_cert(@ca, @rsa1024, 1, [], nil, nil,
not_before: now, not_after: now + 3600)
cert1 = issue_cert(@ee1, @rsa2048, 2, [], cacert, @rsa1024,
not_before: now, not_after: now + 3600)
cert2 = issue_cert(@ee1, @rsa2048, 2, [], cacert, @rsa1024,
not_before: now, not_after: now + 3600)
cert3 = issue_cert(@ee1, @rsa2048, 3, [], cacert, @rsa1024,
not_before: now, not_after: now + 3600)
cert4 = issue_cert(@ee1, @rsa2048, 2, [], cacert, @rsa1024,
digest: "sha512", not_before: now, not_after: now + 3600)
assert_equal false, cert1 == 12345
assert_equal true, cert1 == cert2
assert_equal false, cert1 == cert3
assert_equal false, cert1 == cert4
assert_equal false, cert3 == cert4
end
private
def certificate_error_returns_false

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

@ -197,6 +197,58 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
assert_equal(false, crl.verify(@dsa512))
end
def test_revoked_to_der
# revokedCertificates SEQUENCE OF SEQUENCE {
# userCertificate CertificateSerialNumber,
# revocationDate Time,
# crlEntryExtensions Extensions OPTIONAL
# -- if present, version MUST be v2
# } OPTIONAL,
now = Time.utc(2000, 1, 1)
rev1 = OpenSSL::X509::Revoked.new
rev1.serial = 123
rev1.time = now
ext = OpenSSL::X509::Extension.new("CRLReason", OpenSSL::ASN1::Enumerated(1))
rev1.extensions = [ext]
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(123),
OpenSSL::ASN1::UTCTime(now),
OpenSSL::ASN1::Sequence([ext.to_der])
])
assert_equal asn1.to_der, rev1.to_der
end
def test_eq
now = Time.now
cacert = issue_cert(@ca, @rsa1024, 1, [], nil, nil)
crl1 = issue_crl([], 1, now, now + 3600, [], cacert, @rsa1024, "sha256")
rev1 = OpenSSL::X509::Revoked.new.tap { |rev|
rev.serial = 1
rev.time = now
}
crl1.add_revoked(rev1)
crl2 = OpenSSL::X509::CRL.new(crl1.to_der)
# CRL
assert_equal false, crl1 == 12345
assert_equal true, crl1 == crl2
rev2 = OpenSSL::X509::Revoked.new.tap { |rev|
rev.serial = 2
rev.time = now
}
crl2.add_revoked(rev2)
assert_equal false, crl1 == crl2
# Revoked
assert_equal false, rev1 == 12345
assert_equal true, rev1 == crl2.revoked[0]
assert_equal false, rev1 == crl2.revoked[1]
assert_equal true, rev2 == crl2.revoked[1]
end
private
def crl_error_returns_false

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

@ -75,6 +75,17 @@ class OpenSSL::TestX509Extension < OpenSSL::TestCase
assert_equal(@basic_constraints.to_der, ext.to_der)
assert_equal(ext.to_der, ext.dup.to_der)
end
def test_eq
ext1 = OpenSSL::X509::Extension.new(@basic_constraints.to_der)
ef = OpenSSL::X509::ExtensionFactory.new
ext2 = ef.create_extension("basicConstraints", "critical, CA:TRUE, pathlen:2")
ext3 = ef.create_extension("basicConstraints", "critical, CA:TRUE")
assert_equal false, ext1 == 12345
assert_equal true, ext1 == ext2
assert_equal false, ext1 == ext3
end
end
end

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

@ -141,6 +141,16 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
assert_equal(req.to_der, req.dup.to_der)
end
def test_eq
req1 = issue_csr(0, @dn, @rsa1024, "sha1")
req2 = issue_csr(0, @dn, @rsa1024, "sha1")
req3 = issue_csr(0, @dn, @rsa1024, "sha256")
assert_equal false, req1 == 12345
assert_equal true, req1 == req2
assert_equal false, req1 == req3
end
private
def request_error_returns_false

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

@ -67,7 +67,7 @@ module OpenSSL::TestUtils
cert.serial = serial
cert.subject = dn
cert.issuer = issuer.subject
cert.public_key = key.public_key
cert.public_key = key
now = Time.now
cert.not_before = not_before || now - 3600
cert.not_after = not_after || now + 3600