openssl: adapt to OpenSSL 1.1.0 opaque structs

* ext/openssl/extconf.rb: Check existence of accessor functions that
  don't exist in OpenSSL 0.9.8. OpenSSL 1.1.0 made most of its
  structures opaque and requires use of these accessor functions.
  [ruby-core:75225] [Feature #12324]

* ext/openssl/openssl_missing.[ch]: Implement them if missing.

* ext/openssl/ossl*.c: Use these accessor functions.

* test/openssl/test_hmac.rb: Add missing test for HMAC#reset.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55287 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
rhe 2016-06-05 15:35:12 +00:00
parent 5df1a31c06
commit 0a523ab20d
23 changed files with 458 additions and 172 deletions

View File

@ -1,3 +1,16 @@
Mon Jun 6 00:34:16 2016 Kazuki Yamaguchi <k@rhe.jp>
* ext/openssl/extconf.rb: Check existence of accessor functions that
don't exist in OpenSSL 0.9.8. OpenSSL 1.1.0 made most of its
structures opaque and requires use of these accessor functions.
[ruby-core:75225] [Feature #12324]
* ext/openssl/openssl_missing.[ch]: Implement them if missing.
* ext/openssl/ossl*.c: Use these accessor functions.
* test/openssl/test_hmac.rb: Add missing test for HMAC#reset.
Mon Jun 6 00:00:13 2016 Kazuki Yamaguchi <k@rhe.jp> Mon Jun 6 00:00:13 2016 Kazuki Yamaguchi <k@rhe.jp>
* ext/openssl/openssl_missing.[ch]: Implement EVP_PKEY_get0_*() and * ext/openssl/openssl_missing.[ch]: Implement EVP_PKEY_get0_*() and

View File

@ -84,6 +84,10 @@ engines.each { |name|
OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h") OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h")
} }
# added in 0.9.8X
have_func("EVP_CIPHER_CTX_new")
have_func("EVP_CIPHER_CTX_free")
# added in 1.0.0 # added in 1.0.0
have_func("ASN1_TIME_adj") have_func("ASN1_TIME_adj")
have_func("EVP_CIPHER_CTX_copy") have_func("EVP_CIPHER_CTX_copy")
@ -91,6 +95,9 @@ have_func("EVP_PKEY_base_id")
have_func("HMAC_CTX_copy") have_func("HMAC_CTX_copy")
have_func("PKCS5_PBKDF2_HMAC") have_func("PKCS5_PBKDF2_HMAC")
have_func("X509_NAME_hash_old") have_func("X509_NAME_hash_old")
have_func("X509_STORE_CTX_get0_current_crl")
have_func("X509_STORE_set_verify_cb")
have_func("i2d_ASN1_SET_ANY")
have_func("SSL_SESSION_cmp") # removed have_func("SSL_SESSION_cmp") # removed
OpenSSL.check_func_or_macro("SSL_set_tlsext_host_name", "openssl/ssl.h") OpenSSL.check_func_or_macro("SSL_set_tlsext_host_name", "openssl/ssl.h")
have_struct_member("CRYPTO_THREADID", "ptr", "openssl/crypto.h") have_struct_member("CRYPTO_THREADID", "ptr", "openssl/crypto.h")
@ -102,6 +109,7 @@ have_macro("EVP_CTRL_GCM_GET_TAG", ['openssl/evp.h']) && $defs.push("-DHAVE_AUTH
# added in 1.0.2 # added in 1.0.2
have_func("EC_curve_nist2nid") have_func("EC_curve_nist2nid")
have_func("X509_REVOKED_dup") have_func("X509_REVOKED_dup")
have_func("X509_STORE_CTX_get0_store")
have_func("SSL_CTX_set_alpn_select_cb") have_func("SSL_CTX_set_alpn_select_cb")
OpenSSL.check_func_or_macro("SSL_CTX_set1_curves_list", "openssl/ssl.h") OpenSSL.check_func_or_macro("SSL_CTX_set1_curves_list", "openssl/ssl.h")
OpenSSL.check_func_or_macro("SSL_CTX_set_ecdh_auto", "openssl/ssl.h") OpenSSL.check_func_or_macro("SSL_CTX_set_ecdh_auto", "openssl/ssl.h")
@ -109,9 +117,27 @@ OpenSSL.check_func_or_macro("SSL_get_server_tmp_key", "openssl/ssl.h")
# added in 1.1.0 # added in 1.1.0
have_func("CRYPTO_lock") || $defs.push("-DHAVE_OPENSSL_110_THREADING_API") have_func("CRYPTO_lock") || $defs.push("-DHAVE_OPENSSL_110_THREADING_API")
have_struct_member("SSL", "ctx", "openssl/ssl.h") || $defs.push("-DHAVE_OPAQUE_OPENSSL")
have_func("BN_GENCB_new")
have_func("BN_GENCB_free")
have_func("BN_GENCB_get_arg")
have_func("EVP_MD_CTX_new")
have_func("EVP_MD_CTX_free")
have_func("HMAC_CTX_new")
have_func("HMAC_CTX_free")
OpenSSL.check_func("RAND_pseudo_bytes", "openssl/rand.h") # deprecated OpenSSL.check_func("RAND_pseudo_bytes", "openssl/rand.h") # deprecated
have_func("X509_STORE_get_ex_data") have_func("X509_STORE_get_ex_data")
have_func("X509_STORE_set_ex_data") have_func("X509_STORE_set_ex_data")
have_func("X509_CRL_get0_signature")
have_func("X509_REQ_get0_signature")
have_func("X509_REVOKED_get0_serialNumber")
have_func("X509_REVOKED_get0_revocationDate")
have_func("X509_get0_tbs_sigalg")
have_func("X509_STORE_CTX_get0_untrusted")
have_func("X509_STORE_CTX_get0_cert")
have_func("X509_STORE_CTX_get0_chain")
have_func("OCSP_SINGLERESP_get0_id")
have_func("SSL_CTX_get_ciphers")
have_func("X509_up_ref") have_func("X509_up_ref")
have_func("X509_CRL_up_ref") have_func("X509_CRL_up_ref")
have_func("X509_STORE_up_ref") have_func("X509_STORE_up_ref")

View File

@ -20,6 +20,30 @@
#include "openssl_missing.h" #include "openssl_missing.h"
/* added in 0.9.8X */
#if !defined(HAVE_EVP_CIPHER_CTX_NEW)
EVP_CIPHER_CTX *
EVP_CIPHER_CTX_new(void)
{
EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
if (!ctx)
return NULL;
EVP_CIPHER_CTX_init(ctx);
return ctx;
}
#endif
#if !defined(HAVE_EVP_CIPHER_CTX_FREE)
void
EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
{
if (ctx) {
EVP_CIPHER_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}
}
#endif
/* added in 1.0.0 */ /* added in 1.0.0 */
#if !defined(HAVE_EVP_CIPHER_CTX_COPY) #if !defined(HAVE_EVP_CIPHER_CTX_COPY)
/* /*
@ -46,15 +70,19 @@ EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
#if !defined(OPENSSL_NO_HMAC) #if !defined(OPENSSL_NO_HMAC)
#if !defined(HAVE_HMAC_CTX_COPY) #if !defined(HAVE_HMAC_CTX_COPY)
void int
HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in)
{ {
if (!out || !in) return; if (!out || !in)
return 0;
memcpy(out, in, sizeof(HMAC_CTX)); memcpy(out, in, sizeof(HMAC_CTX));
EVP_MD_CTX_copy(&out->md_ctx, &in->md_ctx); EVP_MD_CTX_copy(&out->md_ctx, &in->md_ctx);
EVP_MD_CTX_copy(&out->i_ctx, &in->i_ctx); EVP_MD_CTX_copy(&out->i_ctx, &in->i_ctx);
EVP_MD_CTX_copy(&out->o_ctx, &in->o_ctx); EVP_MD_CTX_copy(&out->o_ctx, &in->o_ctx);
return 1;
} }
#endif /* HAVE_HMAC_CTX_COPY */ #endif /* HAVE_HMAC_CTX_COPY */
#endif /* NO_HMAC */ #endif /* NO_HMAC */
@ -95,3 +123,49 @@ EC_curve_nist2nid(const char *name)
} }
#endif #endif
#endif #endif
/*** added in 1.1.0 ***/
#if !defined(HAVE_HMAC_CTX_NEW)
HMAC_CTX *
HMAC_CTX_new(void)
{
HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX));
if (!ctx)
return NULL;
HMAC_CTX_init(ctx);
return ctx;
}
#endif
#if !defined(HAVE_HMAC_CTX_FREE)
void
HMAC_CTX_free(HMAC_CTX *ctx)
{
if (ctx) {
HMAC_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}
}
#endif
#if !defined(HAVE_X509_CRL_GET0_SIGNATURE)
void
X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_CRL *crl)
{
if (psig != NULL)
*psig = crl->signature;
if (palg != NULL)
*palg = crl->sig_alg;
}
#endif
#if !defined(HAVE_X509_REQ_GET0_SIGNATURE)
void
X509_REQ_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_REQ *req)
{
if (psig != NULL)
*psig = req->signature;
if (palg != NULL)
*palg = req->sig_alg;
}
#endif

View File

@ -10,6 +10,15 @@
#if !defined(_OSSL_OPENSSL_MISSING_H_) #if !defined(_OSSL_OPENSSL_MISSING_H_)
#define _OSSL_OPENSSL_MISSING_H_ #define _OSSL_OPENSSL_MISSING_H_
/* added in 0.9.8X */
#if !defined(HAVE_EVP_CIPHER_CTX_NEW)
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
#endif
#if !defined(HAVE_EVP_CIPHER_CTX_FREE)
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx);
#endif
/* added in 1.0.0 */ /* added in 1.0.0 */
#if !defined(HAVE_EVP_PKEY_BASE_ID) #if !defined(HAVE_EVP_PKEY_BASE_ID)
# define EVP_PKEY_base_id(pkey) EVP_PKEY_type((pkey)->type) # define EVP_PKEY_base_id(pkey) EVP_PKEY_type((pkey)->type)
@ -20,7 +29,20 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
#endif #endif
#if !defined(HAVE_HMAC_CTX_COPY) #if !defined(HAVE_HMAC_CTX_COPY)
void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); int HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in);
#endif
#if !defined(HAVE_X509_STORE_CTX_GET0_CURRENT_CRL)
# define X509_STORE_CTX_get0_current_crl(x) ((x)->current_crl)
#endif
#if !defined(HAVE_X509_STORE_SET_VERIFY_CB)
# define X509_STORE_set_verify_cb X509_STORE_set_verify_cb_func
#endif
#if !defined(HAVE_I2D_ASN1_SET_ANY)
# define i2d_ASN1_SET_ANY(sk, x) i2d_ASN1_SET_OF_ASN1_TYPE((sk), (x), \
i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0)
#endif #endif
/* added in 1.0.2 */ /* added in 1.0.2 */
@ -35,7 +57,39 @@ int EC_curve_nist2nid(const char *);
(d2i_of_void *)d2i_X509_REVOKED, (char *)(rev)) (d2i_of_void *)d2i_X509_REVOKED, (char *)(rev))
#endif #endif
#if !defined(HAVE_X509_STORE_CTX_GET0_STORE)
# define X509_STORE_CTX_get0_store(x) ((x)->ctx)
#endif
/* added in 1.1.0 */ /* added in 1.1.0 */
#if !defined(HAVE_BN_GENCB_NEW)
# define BN_GENCB_new() ((BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB)))
#endif
#if !defined(HAVE_BN_GENCB_FREE)
# define BN_GENCB_free(cb) OPENSSL_free(cb)
#endif
#if !defined(HAVE_BN_GENCB_GET_ARG)
# define BN_GENCB_get_arg(cb) (cb)->arg
#endif
#if !defined(HAVE_EVP_MD_CTX_NEW)
# define EVP_MD_CTX_new EVP_MD_CTX_create
#endif
#if !defined(HAVE_EVP_MD_CTX_FREE)
# define EVP_MD_CTX_free EVP_MD_CTX_destroy
#endif
#if !defined(HAVE_HMAC_CTX_NEW)
HMAC_CTX *HMAC_CTX_new(void);
#endif
#if !defined(HAVE_HMAC_CTX_FREE)
void HMAC_CTX_free(HMAC_CTX *ctx);
#endif
#if !defined(HAVE_X509_STORE_GET_EX_DATA) #if !defined(HAVE_X509_STORE_GET_EX_DATA)
# define X509_STORE_get_ex_data(x, idx) \ # define X509_STORE_get_ex_data(x, idx) \
CRYPTO_get_ex_data(&(x)->ex_data, (idx)) CRYPTO_get_ex_data(&(x)->ex_data, (idx))
@ -49,6 +103,46 @@ int EC_curve_nist2nid(const char *);
(newf), (dupf), (freef)) (newf), (dupf), (freef))
#endif #endif
#if !defined(HAVE_X509_CRL_GET0_SIGNATURE)
void X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_CRL *crl);
#endif
#if !defined(HAVE_X509_REQ_GET0_SIGNATURE)
void X509_REQ_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_REQ *req);
#endif
#if !defined(HAVE_X509_REVOKED_GET0_SERIALNUMBER)
# define X509_REVOKED_get0_serialNumber(x) ((x)->serialNumber)
#endif
#if !defined(HAVE_X509_REVOKED_GET0_REVOCATIONDATE)
# define X509_REVOKED_get0_revocationDate(x) ((x)->revocationDate)
#endif
#if !defined(HAVE_X509_GET0_TBS_SIGALG)
# define X509_get0_tbs_sigalg(x) ((x)->cert_info->signature)
#endif
#if !defined(HAVE_X509_STORE_CTX_GET0_UNTRUSTED)
# define X509_STORE_CTX_get0_untrusted(x) ((x)->untrusted)
#endif
#if !defined(HAVE_X509_STORE_CTX_GET0_CERT)
# define X509_STORE_CTX_get0_cert(x) ((x)->cert)
#endif
#if !defined(HAVE_X509_STORE_CTX_GET0_CHAIN)
# define X509_STORE_CTX_get0_chain(ctx) X509_STORE_CTX_get_chain(ctx)
#endif
#if !defined(HAVE_OCSP_SINGLERESP_GET0_ID)
# define OCSP_SINGLERESP_get0_id(s) ((s)->certId)
#endif
#if !defined(HAVE_SSL_CTX_GET_CIPHERS)
# define SSL_CTX_get_ciphers(ctx) ((ctx)->cipher_list)
#endif
#if !defined(HAVE_X509_UP_REF) #if !defined(HAVE_X509_UP_REF)
# define X509_up_ref(x) \ # define X509_up_ref(x) \
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509) CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509)

View File

@ -258,7 +258,7 @@ ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
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, ossl_store_ctx_ex_verify_cb_idx);
if (!proc) if (!proc)
proc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_store_ex_verify_cb_idx); proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx), ossl_store_ex_verify_cb_idx);
if (!proc) if (!proc)
return ok; return ok;
if (!NIL_P(proc)) { if (!NIL_P(proc)) {

View File

@ -37,17 +37,12 @@ ossl_bn_free(void *ptr)
BN_clear_free(ptr); BN_clear_free(ptr);
} }
static size_t
ossl_bn_size(const void *ptr)
{
return sizeof(BIGNUM);
}
static const rb_data_type_t ossl_bn_type = { static const rb_data_type_t ossl_bn_type = {
"OpenSSL/BN", "OpenSSL/BN",
{0, ossl_bn_free, ossl_bn_size,}, {
0, 0, 0, ossl_bn_free,
RUBY_TYPED_FREE_IMMEDIATELY, },
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
}; };
/* /*

View File

@ -11,10 +11,12 @@
#define NewCipher(klass) \ #define NewCipher(klass) \
TypedData_Wrap_Struct((klass), &ossl_cipher_type, 0) TypedData_Wrap_Struct((klass), &ossl_cipher_type, 0)
#define MakeCipher(obj, klass, ctx) \ #define AllocCipher(obj, ctx) do { \
(obj) = TypedData_Make_Struct((klass), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)) (ctx) = EVP_CIPHER_CTX_new(); \
#define AllocCipher(obj, ctx) \ if (!(ctx)) \
(DATA_PTR(obj) = (ctx) = ZALLOC(EVP_CIPHER_CTX)) ossl_raise(rb_eRuntimeError, NULL); \
RTYPEDDATA_DATA(obj) = (ctx); \
} while (0)
#define GetCipherInit(obj, ctx) do { \ #define GetCipherInit(obj, ctx) do { \
TypedData_Get_Struct((obj), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)); \ TypedData_Get_Struct((obj), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)); \
} while (0) } while (0)
@ -37,13 +39,13 @@ VALUE eCipherError;
static VALUE ossl_cipher_alloc(VALUE klass); static VALUE ossl_cipher_alloc(VALUE klass);
static void ossl_cipher_free(void *ptr); static void ossl_cipher_free(void *ptr);
static size_t ossl_cipher_memsize(const void *ptr);
static const rb_data_type_t ossl_cipher_type = { static const rb_data_type_t ossl_cipher_type = {
"OpenSSL/Cipher", "OpenSSL/Cipher",
{0, ossl_cipher_free, ossl_cipher_memsize,}, {
0, 0, 0, ossl_cipher_free,
RUBY_TYPED_FREE_IMMEDIATELY, },
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
}; };
/* /*
@ -67,7 +69,6 @@ ossl_cipher_new(const EVP_CIPHER *cipher)
ret = ossl_cipher_alloc(cCipher); ret = ossl_cipher_alloc(cCipher);
AllocCipher(ret, ctx); AllocCipher(ret, ctx);
EVP_CIPHER_CTX_init(ctx);
if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
ossl_raise(eCipherError, NULL); ossl_raise(eCipherError, NULL);
@ -87,13 +88,6 @@ ossl_cipher_free(void *ptr)
} }
} }
static size_t
ossl_cipher_memsize(const void *ptr)
{
const EVP_CIPHER_CTX *ctx = ptr;
return sizeof(*ctx);
}
static VALUE static VALUE
ossl_cipher_alloc(VALUE klass) ossl_cipher_alloc(VALUE klass)
{ {
@ -114,7 +108,7 @@ ossl_cipher_initialize(VALUE self, VALUE str)
EVP_CIPHER_CTX *ctx; EVP_CIPHER_CTX *ctx;
const EVP_CIPHER *cipher; const EVP_CIPHER *cipher;
char *name; char *name;
unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char dummy_key[EVP_MAX_KEY_LENGTH] = { 0 };
name = StringValueCStr(str); name = StringValueCStr(str);
GetCipherInit(self, ctx); GetCipherInit(self, ctx);
@ -122,18 +116,19 @@ ossl_cipher_initialize(VALUE self, VALUE str)
ossl_raise(rb_eRuntimeError, "Cipher already inititalized!"); ossl_raise(rb_eRuntimeError, "Cipher already inititalized!");
} }
AllocCipher(self, ctx); AllocCipher(self, ctx);
EVP_CIPHER_CTX_init(ctx);
if (!(cipher = EVP_get_cipherbyname(name))) { if (!(cipher = EVP_get_cipherbyname(name))) {
ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%"PRIsVALUE")", str); 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 * 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. * uninitialized key, but other EVPs (such as AES) does not allow it.
* Calling EVP_CipherUpdate() without initializing key causes SEGV so we * Calling EVP_CipherUpdate() without initializing key causes SEGV so we
* set the data filled with "\0" as the key by default. * set the data filled with "\0" as the key by default.
*/ */
memset(key, 0, EVP_MAX_KEY_LENGTH); if (EVP_CipherInit_ex(ctx, cipher, NULL, dummy_key, NULL, -1) != 1)
if (EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, -1) != 1)
ossl_raise(eCipherError, NULL); ossl_raise(eCipherError, NULL);
return self; return self;

View File

@ -11,8 +11,8 @@
#include "ossl.h" #include "ossl.h"
#define MakeHMAC(obj, klass, ctx) \ #define NewHMAC(klass) \
(obj) = TypedData_Make_Struct((klass), HMAC_CTX, &ossl_hmac_type, (ctx)) TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0)
#define GetHMAC(obj, ctx) do { \ #define GetHMAC(obj, ctx) do { \
TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \ TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \
if (!(ctx)) { \ if (!(ctx)) { \
@ -40,8 +40,7 @@ VALUE eHMACError;
static void static void
ossl_hmac_free(void *ctx) ossl_hmac_free(void *ctx)
{ {
HMAC_CTX_cleanup(ctx); HMAC_CTX_free(ctx);
ruby_xfree(ctx);
} }
static const rb_data_type_t ossl_hmac_type = { static const rb_data_type_t ossl_hmac_type = {
@ -55,11 +54,14 @@ static const rb_data_type_t ossl_hmac_type = {
static VALUE static VALUE
ossl_hmac_alloc(VALUE klass) ossl_hmac_alloc(VALUE klass)
{ {
HMAC_CTX *ctx;
VALUE obj; VALUE obj;
HMAC_CTX *ctx;
MakeHMAC(obj, klass, ctx); obj = NewHMAC(klass);
HMAC_CTX_init(ctx); ctx = HMAC_CTX_new();
if (!ctx)
ossl_raise(eHMACError, NULL);
RTYPEDDATA_DATA(obj) = ctx;
return obj; return obj;
} }
@ -107,8 +109,8 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
StringValue(key); StringValue(key);
GetHMAC(self, ctx); GetHMAC(self, ctx);
HMAC_Init(ctx, RSTRING_PTR(key), RSTRING_LENINT(key), HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
GetDigestPtr(digest)); GetDigestPtr(digest), NULL);
return self; return self;
} }
@ -124,7 +126,8 @@ ossl_hmac_copy(VALUE self, VALUE other)
GetHMAC(self, ctx1); GetHMAC(self, ctx1);
SafeGetHMAC(other, ctx2); SafeGetHMAC(other, ctx2);
HMAC_CTX_copy(ctx1, ctx2); if (!HMAC_CTX_copy(ctx1, ctx2))
ossl_raise(eHMACError, "HMAC_CTX_copy");
return self; return self;
} }
@ -161,16 +164,24 @@ ossl_hmac_update(VALUE self, VALUE data)
static void static void
hmac_final(HMAC_CTX *ctx, unsigned char **buf, unsigned int *buf_len) hmac_final(HMAC_CTX *ctx, unsigned char **buf, unsigned int *buf_len)
{ {
HMAC_CTX final; HMAC_CTX *final;
HMAC_CTX_copy(&final, ctx); final = HMAC_CTX_new();
if (!(*buf = OPENSSL_malloc(HMAC_size(&final)))) { if (!final)
HMAC_CTX_cleanup(&final); ossl_raise(eHMACError, "HMAC_CTX_new");
OSSL_Debug("Allocating %d mem", HMAC_size(&final));
if (!HMAC_CTX_copy(final, ctx)) {
HMAC_CTX_free(final);
ossl_raise(eHMACError, "HMAC_CTX_copy");
}
if (!(*buf = OPENSSL_malloc(HMAC_size(final)))) {
HMAC_CTX_free(final);
OSSL_Debug("Allocating %d mem", (int)HMAC_size(final));
ossl_raise(eHMACError, "Cannot allocate memory for hmac"); ossl_raise(eHMACError, "Cannot allocate memory for hmac");
} }
HMAC_Final(&final, *buf, buf_len); HMAC_Final(final, *buf, buf_len);
HMAC_CTX_cleanup(&final); HMAC_CTX_free(final);
} }
/* /*
@ -256,7 +267,7 @@ ossl_hmac_reset(VALUE self)
HMAC_CTX *ctx; HMAC_CTX *ctx;
GetHMAC(self, ctx); GetHMAC(self, ctx);
HMAC_Init(ctx, NULL, 0, NULL); HMAC_Init_ex(ctx, NULL, 0, NULL, NULL);
return self; return self;
} }

View File

@ -708,8 +708,8 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
if(!NIL_P(ext)){ if(!NIL_P(ext)){
X509_EXTENSION *x509ext; X509_EXTENSION *x509ext;
sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free); while ((x509ext = OCSP_SINGLERESP_delete_ext(single, 0)))
single->singleExtensions = NULL; X509_EXTENSION_free(x509ext);
for(i = 0; i < RARRAY_LEN(ext); i++){ for(i = 0; i < RARRAY_LEN(ext); i++){
x509ext = DupX509ExtPtr(RARRAY_AREF(ext, i)); x509ext = DupX509ExtPtr(RARRAY_AREF(ext, i));
if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){ if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
@ -764,7 +764,7 @@ ossl_ocspbres_get_status(VALUE self)
status = OCSP_single_get0_status(single, &reason, &revtime, status = OCSP_single_get0_status(single, &reason, &revtime,
&thisupd, &nextupd); &thisupd, &nextupd);
if(status < 0) continue; if(status < 0) continue;
if(!(cid = OCSP_CERTID_dup(single->certId))) if(!(cid = OCSP_CERTID_dup(OCSP_SINGLERESP_get0_id(single))))
ossl_raise(eOCSPError, NULL); ossl_raise(eOCSPError, NULL);
ary = rb_ary_new(); ary = rb_ary_new();
rb_ary_push(ary, ossl_ocspcertid_new(cid)); rb_ary_push(ary, ossl_ocspcertid_new(cid));
@ -963,10 +963,12 @@ static VALUE
ossl_ocspcid_get_serial(VALUE self) ossl_ocspcid_get_serial(VALUE self)
{ {
OCSP_CERTID *id; OCSP_CERTID *id;
ASN1_INTEGER *serial;
GetOCSPCertId(self, id); GetOCSPCertId(self, id);
OCSP_id_get0_info(NULL, NULL, NULL, &serial, id);
return asn1integer_to_num(id->serialNumber); return asn1integer_to_num(serial);
} }
void void

View File

@ -27,7 +27,7 @@ ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
struct ossl_generate_cb_arg *arg; struct ossl_generate_cb_arg *arg;
int state; int state;
arg = (struct ossl_generate_cb_arg *)cb->arg; arg = (struct ossl_generate_cb_arg *)BN_GENCB_get_arg(cb);
if (arg->yield) { if (arg->yield) {
ary = rb_ary_new2(2); ary = rb_ary_new2(2);
rb_ary_store(ary, 0, INT2NUM(p)); rb_ary_store(ary, 0, INT2NUM(p));
@ -265,21 +265,26 @@ static VALUE
ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
{ {
EVP_PKEY *pkey; EVP_PKEY *pkey;
EVP_MD_CTX ctx; const EVP_MD *md;
EVP_MD_CTX *ctx;
unsigned int buf_len; unsigned int buf_len;
VALUE str; VALUE str;
int result; int result;
if (rb_funcallv(self, id_private_q, 0, NULL) != Qtrue) { if (rb_funcallv(self, id_private_q, 0, NULL) != Qtrue)
ossl_raise(rb_eArgError, "Private key is needed."); ossl_raise(rb_eArgError, "Private key is needed.");
}
GetPKey(self, pkey); GetPKey(self, pkey);
EVP_SignInit(&ctx, GetDigestPtr(digest)); md = GetDigestPtr(digest);
StringValue(data); StringValue(data);
EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
str = rb_str_new(0, EVP_PKEY_size(pkey)+16); str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
result = EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
EVP_MD_CTX_cleanup(&ctx); 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));
result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
EVP_MD_CTX_free(ctx);
if (!result) if (!result)
ossl_raise(ePKeyError, NULL); ossl_raise(ePKeyError, NULL);
assert((long)buf_len <= RSTRING_LEN(str)); assert((long)buf_len <= RSTRING_LEN(str));
@ -313,16 +318,22 @@ static VALUE
ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
{ {
EVP_PKEY *pkey; EVP_PKEY *pkey;
EVP_MD_CTX ctx; const EVP_MD *md;
EVP_MD_CTX *ctx;
int result; int result;
GetPKey(self, pkey); GetPKey(self, pkey);
md = GetDigestPtr(digest);
StringValue(sig); StringValue(sig);
StringValue(data); StringValue(data);
EVP_VerifyInit(&ctx, GetDigestPtr(digest));
EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data)); ctx = EVP_MD_CTX_new();
result = EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey); if (!ctx)
EVP_MD_CTX_cleanup(&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);
EVP_MD_CTX_free(ctx);
switch (result) { switch (result) {
case 0: case 0:
return Qfalse; return Qfalse;

View File

@ -97,21 +97,24 @@ dh_blocking_gen(void *arg)
static DH * static DH *
dh_generate(int size, int gen) dh_generate(int size, int gen)
{ {
BN_GENCB cb; struct ossl_generate_cb_arg cb_arg = { 0 };
struct ossl_generate_cb_arg cb_arg;
struct dh_blocking_gen_arg gen_arg; struct dh_blocking_gen_arg gen_arg;
DH *dh = DH_new(); DH *dh = DH_new();
BN_GENCB *cb = BN_GENCB_new();
if (!dh) return 0; if (!dh || !cb) {
DH_free(dh);
BN_GENCB_free(cb);
return NULL;
}
memset(&cb_arg, 0, sizeof(struct ossl_generate_cb_arg));
if (rb_block_given_p()) if (rb_block_given_p())
cb_arg.yield = 1; cb_arg.yield = 1;
BN_GENCB_set(&cb, ossl_generate_cb_2, &cb_arg); BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
gen_arg.dh = dh; gen_arg.dh = dh;
gen_arg.size = size; gen_arg.size = size;
gen_arg.gen = gen; gen_arg.gen = gen;
gen_arg.cb = &cb; gen_arg.cb = cb;
if (cb_arg.yield == 1) { if (cb_arg.yield == 1) {
/* we cannot release GVL when callback proc is supplied */ /* we cannot release GVL when callback proc is supplied */
dh_blocking_gen(&gen_arg); dh_blocking_gen(&gen_arg);
@ -120,6 +123,7 @@ dh_generate(int size, int gen)
rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
} }
BN_GENCB_free(cb);
if (!gen_arg.result) { if (!gen_arg.result) {
DH_free(dh); DH_free(dh);
if (cb_arg.state) { if (cb_arg.state) {
@ -127,12 +131,12 @@ dh_generate(int size, int gen)
ossl_clear_error(); ossl_clear_error();
rb_jump_tag(cb_arg.state); rb_jump_tag(cb_arg.state);
} }
return 0; return NULL;
} }
if (!DH_generate_key(dh)) { if (!DH_generate_key(dh)) {
DH_free(dh); DH_free(dh);
return 0; return NULL;
} }
return dh; return dh;

View File

@ -114,31 +114,33 @@ dsa_blocking_gen(void *arg)
static DSA * static DSA *
dsa_generate(int size) dsa_generate(int size)
{ {
BN_GENCB cb; struct ossl_generate_cb_arg cb_arg = { 0 };
struct ossl_generate_cb_arg cb_arg;
struct dsa_blocking_gen_arg gen_arg; struct dsa_blocking_gen_arg gen_arg;
DSA *dsa = DSA_new(); DSA *dsa = DSA_new();
BN_GENCB *cb = BN_GENCB_new();
unsigned char seed[20]; unsigned char seed[20];
int seed_len = 20, counter; int seed_len = 20, counter;
unsigned long h; unsigned long h;
if (!dsa) return 0; if (RAND_bytes(seed, seed_len) <= 0)
if (RAND_bytes(seed, seed_len) <= 0) { return NULL;
if (!dsa || !cb) {
DSA_free(dsa); DSA_free(dsa);
return 0; BN_GENCB_free(cb);
return NULL;
} }
memset(&cb_arg, 0, sizeof(struct ossl_generate_cb_arg));
if (rb_block_given_p()) if (rb_block_given_p())
cb_arg.yield = 1; cb_arg.yield = 1;
BN_GENCB_set(&cb, ossl_generate_cb_2, &cb_arg); BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
gen_arg.dsa = dsa; gen_arg.dsa = dsa;
gen_arg.size = size; gen_arg.size = size;
gen_arg.seed = seed; gen_arg.seed = seed;
gen_arg.seed_len = seed_len; gen_arg.seed_len = seed_len;
gen_arg.counter = &counter; gen_arg.counter = &counter;
gen_arg.h = &h; gen_arg.h = &h;
gen_arg.cb = &cb; gen_arg.cb = cb;
if (cb_arg.yield == 1) { if (cb_arg.yield == 1) {
/* we cannot release GVL when callback proc is supplied */ /* we cannot release GVL when callback proc is supplied */
dsa_blocking_gen(&gen_arg); dsa_blocking_gen(&gen_arg);
@ -146,6 +148,8 @@ dsa_generate(int size)
/* there's a chance to unblock */ /* there's a chance to unblock */
rb_thread_call_without_gvl(dsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); rb_thread_call_without_gvl(dsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
} }
BN_GENCB_free(cb);
if (!gen_arg.result) { if (!gen_arg.result) {
DSA_free(dsa); DSA_free(dsa);
if (cb_arg.state) { if (cb_arg.state) {
@ -156,12 +160,12 @@ dsa_generate(int size)
ossl_clear_error(); ossl_clear_error();
rb_jump_tag(cb_arg.state); rb_jump_tag(cb_arg.state);
} }
return 0; return NULL;
} }
if (!DSA_generate_key(dsa)) { if (!DSA_generate_key(dsa)) {
DSA_free(dsa); DSA_free(dsa);
return 0; return NULL;
} }
return dsa; return dsa;

View File

@ -114,35 +114,36 @@ static RSA *
rsa_generate(int size, unsigned long exp) rsa_generate(int size, unsigned long exp)
{ {
int i; int i;
BN_GENCB cb; struct ossl_generate_cb_arg cb_arg = { 0 };
struct ossl_generate_cb_arg cb_arg;
struct rsa_blocking_gen_arg gen_arg; struct rsa_blocking_gen_arg gen_arg;
RSA *rsa = RSA_new(); RSA *rsa = RSA_new();
BIGNUM *e = BN_new(); BIGNUM *e = BN_new();
BN_GENCB *cb = BN_GENCB_new();
if (!rsa || !e) { if (!rsa || !e || !cb) {
if (e) BN_free(e); RSA_free(rsa);
if (rsa) RSA_free(rsa); BN_free(e);
return 0; BN_GENCB_free(cb);
return NULL;
} }
for (i = 0; i < (int)sizeof(exp) * 8; ++i) { for (i = 0; i < (int)sizeof(exp) * 8; ++i) {
if (exp & (1UL << i)) { if (exp & (1UL << i)) {
if (BN_set_bit(e, i) == 0) { if (BN_set_bit(e, i) == 0) {
BN_free(e); BN_free(e);
RSA_free(rsa); RSA_free(rsa);
return 0; BN_GENCB_free(cb);
return NULL;
} }
} }
} }
memset(&cb_arg, 0, sizeof(struct ossl_generate_cb_arg));
if (rb_block_given_p()) if (rb_block_given_p())
cb_arg.yield = 1; cb_arg.yield = 1;
BN_GENCB_set(&cb, ossl_generate_cb_2, &cb_arg); BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
gen_arg.rsa = rsa; gen_arg.rsa = rsa;
gen_arg.e = e; gen_arg.e = e;
gen_arg.size = size; gen_arg.size = size;
gen_arg.cb = &cb; gen_arg.cb = cb;
if (cb_arg.yield == 1) { if (cb_arg.yield == 1) {
/* we cannot release GVL when callback proc is supplied */ /* we cannot release GVL when callback proc is supplied */
rsa_blocking_gen(&gen_arg); rsa_blocking_gen(&gen_arg);
@ -150,18 +151,19 @@ rsa_generate(int size, unsigned long exp)
/* there's a chance to unblock */ /* there's a chance to unblock */
rb_thread_call_without_gvl(rsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); rb_thread_call_without_gvl(rsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
} }
BN_GENCB_free(cb);
BN_free(e);
if (!gen_arg.result) { if (!gen_arg.result) {
BN_free(e);
RSA_free(rsa); RSA_free(rsa);
if (cb_arg.state) { if (cb_arg.state) {
/* must clear OpenSSL error stack */ /* must clear OpenSSL error stack */
ossl_clear_error(); ossl_clear_error();
rb_jump_tag(cb_arg.state); rb_jump_tag(cb_arg.state);
} }
return 0; return NULL;
} }
BN_free(e);
return rsa; return rsa;
} }

View File

@ -922,7 +922,7 @@ ossl_sslctx_get_ciphers(VALUE self)
rb_warning("SSL_CTX is not initialized."); rb_warning("SSL_CTX is not initialized.");
return Qnil; return Qnil;
} }
ciphers = ctx->cipher_list; ciphers = SSL_CTX_get_ciphers(ctx);
if (!ciphers) if (!ciphers)
return rb_ary_new(); return rb_ary_new();

View File

@ -76,13 +76,22 @@ static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
#if HAVE_SSL_SESSION_CMP == 0 #if HAVE_SSL_SESSION_CMP == 0
int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b) int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
{ {
if (a->ssl_version != b->ssl_version || unsigned int a_len;
a->session_id_length != b->session_id_length) const unsigned char *a_sid = SSL_SESSION_get_id(a, &a_len);
unsigned int b_len;
const unsigned char *b_sid = SSL_SESSION_get_id(b, &b_len);
#if !defined(HAVE_OPAQUE_OPENSSL) /* missing SSL_SESSION_get_ssl_version() ? */
if (a->ssl_version != b->ssl_version)
return 1; return 1;
#endif
if (a_len != b_len)
return 1;
#if defined(_WIN32) #if defined(_WIN32)
return memcmp(a->session_id, b->session_id, a->session_id_length); return memcmp(a_sid, b_sid, a_len);
#else #else
return CRYPTO_memcmp(a->session_id, b->session_id, a->session_id_length); return CRYPTO_memcmp(a_sid, b_sid, a_len);
#endif #endif
} }
#endif #endif

View File

@ -186,22 +186,37 @@ static VALUE
ossl_x509attr_set_value(VALUE self, VALUE value) ossl_x509attr_set_value(VALUE self, VALUE value)
{ {
X509_ATTRIBUTE *attr; X509_ATTRIBUTE *attr;
ASN1_TYPE *a1type; VALUE asn1_value;
int i, asn1_tag;
OSSL_Check_Kind(value, cASN1Data); OSSL_Check_Kind(value, cASN1Data);
if(!(a1type = ossl_asn1_get_asn1type(value))) asn1_tag = NUM2INT(rb_attr_get(value, rb_intern("@tag")));
ossl_raise(eASN1Error, "could not get ASN1_TYPE"); asn1_value = rb_attr_get(value, rb_intern("@value"));
if(ASN1_TYPE_get(a1type) == V_ASN1_SEQUENCE){ if (asn1_tag != V_ASN1_SET)
ASN1_TYPE_free(a1type); ossl_raise(eASN1Error, "argument must be ASN1::Set");
ossl_raise(eASN1Error, "couldn't set SEQUENCE for attribute value."); if (!RB_TYPE_P(asn1_value, T_ARRAY))
} ossl_raise(eASN1Error, "ASN1::Set has non-array value");
GetX509Attr(self, attr); GetX509Attr(self, attr);
if(attr->value.set){ if (X509_ATTRIBUTE_count(attr)) { /* populated, reset first */
if(attr->single) ASN1_TYPE_free(attr->value.single); ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr);
else sk_ASN1_TYPE_free(attr->value.set); X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1);
if (!new_attr)
ossl_raise(eX509AttrError, NULL);
SetX509Attr(self, new_attr);
X509_ATTRIBUTE_free(attr);
attr = new_attr;
}
for (i = 0; i < RARRAY_LEN(asn1_value); i++) {
ASN1_TYPE *a1type = ossl_asn1_get_asn1type(RARRAY_AREF(asn1_value, i));
if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type),
a1type->value.ptr, -1)) {
ASN1_TYPE_free(a1type);
ossl_raise(eX509AttrError, NULL);
}
ASN1_TYPE_free(a1type);
} }
attr->single = 1;
attr->value.single = a1type;
return value; return value;
} }
@ -214,32 +229,34 @@ static VALUE
ossl_x509attr_get_value(VALUE self) ossl_x509attr_get_value(VALUE self)
{ {
X509_ATTRIBUTE *attr; X509_ATTRIBUTE *attr;
VALUE str, asn1; STACK_OF(ASN1_TYPE) *sk;
long length; VALUE str;
int i, count, len;
unsigned char *p; unsigned char *p;
GetX509Attr(self, attr); GetX509Attr(self, attr);
if(attr->value.ptr == NULL) return Qnil; /* there is no X509_ATTRIBUTE_get0_set() :( */
if(attr->single){ if (!(sk = sk_ASN1_TYPE_new_null()))
length = i2d_ASN1_TYPE(attr->value.single, NULL); ossl_raise(eX509AttrError, "sk_new");
str = rb_str_new(0, length);
p = (unsigned char *)RSTRING_PTR(str);
i2d_ASN1_TYPE(attr->value.single, &p);
ossl_str_adjust(str, p);
}
else{
length = i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set,
(unsigned char **) NULL, i2d_ASN1_TYPE,
V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
str = rb_str_new(0, length);
p = (unsigned char *)RSTRING_PTR(str);
i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p,
i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
ossl_str_adjust(str, p);
}
asn1 = rb_funcall(mASN1, rb_intern("decode"), 1, str);
return asn1; count = X509_ATTRIBUTE_count(attr);
for (i = 0; i < count; i++)
sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i));
if ((len = i2d_ASN1_SET_ANY(sk, NULL)) <= 0) {
sk_ASN1_TYPE_free(sk);
ossl_raise(eX509AttrError, NULL);
}
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if (i2d_ASN1_SET_ANY(sk, &p) <= 0) {
sk_ASN1_TYPE_free(sk);
ossl_raise(eX509AttrError, NULL);
}
ossl_str_adjust(str, p);
sk_ASN1_TYPE_free(sk);
return rb_funcall(mASN1, rb_intern("decode"), 1, str);
} }
/* /*

View File

@ -349,9 +349,7 @@ ossl_x509_set_serial(VALUE self, VALUE num)
X509 *x509; X509 *x509;
GetX509(self, x509); GetX509(self, x509);
X509_set_serialNumber(x509, num_to_asn1integer(num, X509_get_serialNumber(x509)));
x509->cert_info->serialNumber =
num_to_asn1integer(num, X509_get_serialNumber(x509));
return num; return num;
} }
@ -371,7 +369,7 @@ ossl_x509_get_signature_algorithm(VALUE self)
out = BIO_new(BIO_s_mem()); out = BIO_new(BIO_s_mem());
if (!out) ossl_raise(eX509CertError, NULL); if (!out) ossl_raise(eX509CertError, NULL);
if (!i2a_ASN1_OBJECT(out, x509->cert_info->signature->algorithm)) { if (!i2a_ASN1_OBJECT(out, X509_get0_tbs_sigalg(x509)->algorithm)) {
BIO_free(out); BIO_free(out);
ossl_raise(eX509CertError, NULL); ossl_raise(eX509CertError, NULL);
} }
@ -666,8 +664,8 @@ ossl_x509_set_extensions(VALUE self, VALUE ary)
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
} }
GetX509(self, x509); GetX509(self, x509);
sk_X509_EXTENSION_pop_free(x509->cert_info->extensions, X509_EXTENSION_free); while ((ext = X509_delete_ext(x509, 0)))
x509->cert_info->extensions = NULL; X509_EXTENSION_free(ext);
for (i=0; i<RARRAY_LEN(ary); i++) { for (i=0; i<RARRAY_LEN(ary); i++) {
ext = DupX509ExtPtr(RARRAY_AREF(ary, i)); ext = DupX509ExtPtr(RARRAY_AREF(ary, i));

View File

@ -180,6 +180,7 @@ static VALUE
ossl_x509crl_get_signature_algorithm(VALUE self) ossl_x509crl_get_signature_algorithm(VALUE self)
{ {
X509_CRL *crl; X509_CRL *crl;
X509_ALGOR *alg;
BIO *out; BIO *out;
BUF_MEM *buf; BUF_MEM *buf;
VALUE str; VALUE str;
@ -188,7 +189,8 @@ ossl_x509crl_get_signature_algorithm(VALUE self)
if (!(out = BIO_new(BIO_s_mem()))) { if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eX509CRLError, NULL); ossl_raise(eX509CRLError, NULL);
} }
if (!i2a_ASN1_OBJECT(out, crl->sig_alg->algorithm)) { X509_CRL_get0_signature(NULL, &alg, crl);
if (!i2a_ASN1_OBJECT(out, alg->algorithm)) {
BIO_free(out); BIO_free(out);
ossl_raise(eX509CRLError, NULL); ossl_raise(eX509CRLError, NULL);
} }
@ -237,7 +239,7 @@ ossl_x509crl_set_last_update(VALUE self, VALUE time)
X509_CRL *crl; X509_CRL *crl;
GetX509CRL(self, crl); GetX509CRL(self, crl);
if (!ossl_x509_time_adjust(crl->crl->lastUpdate, time)) if (!ossl_x509_time_adjust(X509_CRL_get_lastUpdate(crl), time))
ossl_raise(eX509CRLError, NULL); ossl_raise(eX509CRLError, NULL);
return time; return time;
@ -257,11 +259,21 @@ static VALUE
ossl_x509crl_set_next_update(VALUE self, VALUE time) ossl_x509crl_set_next_update(VALUE self, VALUE time)
{ {
X509_CRL *crl; X509_CRL *crl;
ASN1_TIME *orig, *new;
GetX509CRL(self, crl); GetX509CRL(self, crl);
/* crl->crl->nextUpdate may be NULL at this time */ /* orig may be NULL at this time; in this case a new ASN1_TIME is created */
if (!(crl->crl->nextUpdate = ossl_x509_time_adjust(crl->crl->nextUpdate, time))) orig = X509_CRL_get_nextUpdate(crl);
new = ossl_x509_time_adjust(orig, time);
if (!X509_CRL_set_nextUpdate(crl, new)) {
if (!orig)
ASN1_TIME_free(new);
ossl_raise(eX509CRLError, NULL); ossl_raise(eX509CRLError, NULL);
}
/* X509_CRL_set_nextUpdate() dups when orig != new */
if (!orig)
ASN1_TIME_free(new);
return time; return time;
} }
@ -304,8 +316,7 @@ ossl_x509crl_set_revoked(VALUE self, VALUE ary)
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Rev); OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Rev);
} }
GetX509CRL(self, crl); GetX509CRL(self, crl);
sk_X509_REVOKED_pop_free(crl->crl->revoked, X509_REVOKED_free); sk_X509_REVOKED_pop_free(X509_CRL_get_REVOKED(crl), X509_REVOKED_free);
crl->crl->revoked = NULL;
for (i=0; i<RARRAY_LEN(ary); i++) { for (i=0; i<RARRAY_LEN(ary); i++) {
rev = DupX509RevokedPtr(RARRAY_AREF(ary, i)); rev = DupX509RevokedPtr(RARRAY_AREF(ary, i));
if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */ if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
@ -478,8 +489,8 @@ ossl_x509crl_set_extensions(VALUE self, VALUE ary)
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
} }
GetX509CRL(self, crl); GetX509CRL(self, crl);
sk_X509_EXTENSION_pop_free(crl->crl->extensions, X509_EXTENSION_free); while ((ext = X509_CRL_delete_ext(crl, 0)))
crl->crl->extensions = NULL; X509_EXTENSION_free(ext);
for (i=0; i<RARRAY_LEN(ary); i++) { for (i=0; i<RARRAY_LEN(ary); i++) {
ext = DupX509ExtPtr(RARRAY_AREF(ary, i)); ext = DupX509ExtPtr(RARRAY_AREF(ary, i));
if(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */ if(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */

View File

@ -282,6 +282,7 @@ ossl_x509name_to_a(VALUE self)
char long_name[512]; char long_name[512];
const char *short_name; const char *short_name;
VALUE ary, vname, ret; VALUE ary, vname, ret;
ASN1_STRING *value;
GetX509Name(self, name); GetX509Name(self, name);
entries = X509_NAME_entry_count(name); entries = X509_NAME_entry_count(name);
@ -294,7 +295,8 @@ ossl_x509name_to_a(VALUE self)
if (!(entry = X509_NAME_get_entry(name, i))) { if (!(entry = X509_NAME_get_entry(name, i))) {
ossl_raise(eX509NameError, NULL); ossl_raise(eX509NameError, NULL);
} }
if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name), entry->object)) { if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name),
X509_NAME_ENTRY_get_object(entry))) {
ossl_raise(eX509NameError, NULL); ossl_raise(eX509NameError, NULL);
} }
nid = OBJ_ln2nid(long_name); nid = OBJ_ln2nid(long_name);
@ -304,10 +306,11 @@ ossl_x509name_to_a(VALUE self)
short_name = OBJ_nid2sn(nid); short_name = OBJ_nid2sn(nid);
vname = rb_str_new2(short_name); /*do not free*/ vname = rb_str_new2(short_name); /*do not free*/
} }
value = X509_NAME_ENTRY_get_data(entry);
ary = rb_ary_new3(3, ary = rb_ary_new3(3,
vname, vname,
rb_str_new((const char *)entry->value->data, entry->value->length), rb_str_new((const char *)value->data, value->length),
INT2FIX(entry->value->type)); INT2FIX(value->type));
rb_ary_push(ret, ary); rb_ary_push(ret, ary);
} }
return ret; return ret;

View File

@ -302,6 +302,7 @@ static VALUE
ossl_x509req_get_signature_algorithm(VALUE self) ossl_x509req_get_signature_algorithm(VALUE self)
{ {
X509_REQ *req; X509_REQ *req;
X509_ALGOR *alg;
BIO *out; BIO *out;
BUF_MEM *buf; BUF_MEM *buf;
VALUE str; VALUE str;
@ -311,7 +312,8 @@ ossl_x509req_get_signature_algorithm(VALUE self)
if (!(out = BIO_new(BIO_s_mem()))) { if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eX509ReqError, NULL); ossl_raise(eX509ReqError, NULL);
} }
if (!i2a_ASN1_OBJECT(out, req->sig_alg->algorithm)) { X509_REQ_get0_signature(NULL, &alg, req);
if (!i2a_ASN1_OBJECT(out, alg->algorithm)) {
BIO_free(out); BIO_free(out);
ossl_raise(eX509ReqError, NULL); ossl_raise(eX509ReqError, NULL);
} }
@ -426,8 +428,8 @@ ossl_x509req_set_attributes(VALUE self, VALUE ary)
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Attr); OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Attr);
} }
GetX509Req(self, req); GetX509Req(self, req);
sk_X509_ATTRIBUTE_pop_free(req->req_info->attributes, X509_ATTRIBUTE_free); while ((attr = X509_REQ_delete_attr(req, 0)))
req->req_info->attributes = NULL; X509_ATTRIBUTE_free(attr);
for (i=0;i<RARRAY_LEN(ary); i++) { for (i=0;i<RARRAY_LEN(ary); i++) {
item = RARRAY_AREF(ary, i); item = RARRAY_AREF(ary, i);
attr = DupX509AttrPtr(item); attr = DupX509AttrPtr(item);

View File

@ -116,16 +116,18 @@ ossl_x509revoked_get_serial(VALUE self)
GetX509Rev(self, rev); GetX509Rev(self, rev);
return asn1integer_to_num(rev->serialNumber); return asn1integer_to_num(X509_REVOKED_get0_serialNumber(rev));
} }
static VALUE static VALUE
ossl_x509revoked_set_serial(VALUE self, VALUE num) ossl_x509revoked_set_serial(VALUE self, VALUE num)
{ {
X509_REVOKED *rev; X509_REVOKED *rev;
ASN1_INTEGER *ai;
GetX509Rev(self, rev); GetX509Rev(self, rev);
rev->serialNumber = num_to_asn1integer(num, rev->serialNumber); ai = X509_REVOKED_get0_serialNumber(rev);
X509_REVOKED_set_serialNumber(rev, num_to_asn1integer(num, ai));
return num; return num;
} }
@ -137,7 +139,7 @@ ossl_x509revoked_get_time(VALUE self)
GetX509Rev(self, rev); GetX509Rev(self, rev);
return asn1time_to_time(rev->revocationDate); return asn1time_to_time(X509_REVOKED_get0_revocationDate(rev));
} }
static VALUE static VALUE
@ -146,7 +148,7 @@ ossl_x509revoked_set_time(VALUE self, VALUE time)
X509_REVOKED *rev; X509_REVOKED *rev;
GetX509Rev(self, rev); GetX509Rev(self, rev);
if (!ossl_x509_time_adjust(rev->revocationDate, time)) if (!ossl_x509_time_adjust(X509_REVOKED_get0_revocationDate(rev), time))
ossl_raise(eX509RevError, NULL); ossl_raise(eX509RevError, NULL);
return time; return time;
@ -193,8 +195,8 @@ ossl_x509revoked_set_extensions(VALUE self, VALUE ary)
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
} }
GetX509Rev(self, rev); GetX509Rev(self, rev);
sk_X509_EXTENSION_pop_free(rev->extensions, X509_EXTENSION_free); while ((ext = X509_REVOKED_delete_ext(rev, 0)))
rev->extensions = NULL; X509_EXTENSION_free(ext);
for (i=0; i<RARRAY_LEN(ary); i++) { for (i=0; i<RARRAY_LEN(ary); i++) {
item = RARRAY_AREF(ary, i); item = RARRAY_AREF(ary, i);
ext = DupX509ExtPtr(item); ext = DupX509ExtPtr(item);

View File

@ -149,8 +149,11 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
/* BUG: This method takes any number of arguments but appears to ignore them. */ /* BUG: This method takes any number of arguments but appears to ignore them. */
GetX509Store(self, store); GetX509Store(self, store);
#if !defined(HAVE_OPAQUE_OPENSSL)
/* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */
store->ex_data.sk = NULL; store->ex_data.sk = NULL;
X509_STORE_set_verify_cb_func(store, ossl_verify_cb); #endif
X509_STORE_set_verify_cb(store, ossl_verify_cb);
ossl_x509store_set_vfy_cb(self, Qnil); ossl_x509store_set_vfy_cb(self, Qnil);
/* last verification status */ /* last verification status */
@ -382,10 +385,10 @@ static void
ossl_x509stctx_free(void *ptr) ossl_x509stctx_free(void *ptr)
{ {
X509_STORE_CTX *ctx = ptr; X509_STORE_CTX *ctx = ptr;
if(ctx->untrusted) if (X509_STORE_CTX_get0_untrusted(ctx))
sk_X509_pop_free(ctx->untrusted, X509_free); sk_X509_pop_free(X509_STORE_CTX_get0_untrusted(ctx), X509_free);
if(ctx->cert) if (X509_STORE_CTX_get0_cert(ctx))
X509_free(ctx->cert); X509_free(X509_STORE_CTX_get0_cert(ctx));
X509_STORE_CTX_free(ctx); X509_STORE_CTX_free(ctx);
} }
@ -465,7 +468,7 @@ ossl_x509stctx_get_chain(VALUE self)
VALUE ary; VALUE ary;
GetX509StCtx(self, ctx); GetX509StCtx(self, ctx);
if((chain = X509_STORE_CTX_get_chain(ctx)) == NULL){ if((chain = X509_STORE_CTX_get0_chain(ctx)) == NULL){
return Qnil; return Qnil;
} }
if((num = sk_X509_num(chain)) < 0){ if((num = sk_X509_num(chain)) < 0){
@ -538,11 +541,14 @@ static VALUE
ossl_x509stctx_get_curr_crl(VALUE self) ossl_x509stctx_get_curr_crl(VALUE self)
{ {
X509_STORE_CTX *ctx; X509_STORE_CTX *ctx;
X509_CRL *crl;
GetX509StCtx(self, ctx); GetX509StCtx(self, ctx);
if(!ctx->current_crl) return Qnil; crl = X509_STORE_CTX_get0_current_crl(ctx);
if (!crl)
return Qnil;
return ossl_x509crl_new(ctx->current_crl); return ossl_x509crl_new(crl);
} }
static VALUE static VALUE

View File

@ -36,4 +36,11 @@ class OpenSSL::TestHMAC < OpenSSL::TestCase
result = hmac.update(data).hexdigest result = hmac.update(data).hexdigest
assert_equal "a13984b929a07912e4e21c5720876a8e150d6f67f854437206e7f86547248396", result assert_equal "a13984b929a07912e4e21c5720876a8e150d6f67f854437206e7f86547248396", result
end end
def test_reset_keep_key
first = @h1.update("test").hexdigest
@h2.reset
second = @h2.update("test").hexdigest
assert_equal first, second
end
end if defined?(OpenSSL::TestUtils) end if defined?(OpenSSL::TestUtils)